2 * This file is part of reguloj. It is subject to the license terms in the LICENSE file found in the top-level
3 * directory of this distribution and at http://creativecommons.org/publicdomain/zero/1.0/. No part of reguloj,
4 * including this file, may be copied, modified, propagated, or distributed except according to the terms contained
8 package wtf
.metio
.reguloj
.shoppingcart
;
10 import java
.util
.ArrayList
;
11 import java
.util
.Collection
;
12 import java
.util
.List
;
13 import org
.junit
.jupiter
.api
.Assertions
;
14 import org
.junit
.jupiter
.api
.BeforeEach
;
15 import org
.junit
.jupiter
.api
.Test
;
16 import wtf
.metio
.reguloj
.Rule
;
17 import wtf
.metio
.reguloj
.RuleEngine
;
19 class ShoppingCartTest
{
21 private static final Product TEST_PRODUCT
= new Product("xPhone 37");
23 private Collection
<Rule
<Cart
>> rules
;
24 private RuleEngine
<Cart
> ruleEngine
;
28 final var standardPrice
= Rule
.<Cart
>called("single purchase uses standard price")
29 .when(cart
-> true) // always fires thus can be used as a fallback
30 .then(cart
-> cart
.prices().add(new Price(TEST_PRODUCT
, 100)));
31 final var reducedPrice
= Rule
.<Cart
>called("multiple purchases get reduced price")
32 .when(cart
-> cart
.topic().size() > 1) // only fires for multiple products
33 .then(cart
-> cart
.prices().add(new Price(TEST_PRODUCT
, 75 * cart
.topic().size())));
34 // the order is important here, so we use a List
35 rules
= List
.of(reducedPrice
, standardPrice
);
36 // since we control the order, we can only run the first rule that fires
37 ruleEngine
= RuleEngine
.firstWins();
41 void shouldCalculatePrice() {
43 final var cart
= new Cart(List
.of(TEST_PRODUCT
), new ArrayList
<>());
46 ruleEngine
.infer(rules
, cart
);
49 assertPrice(cart
, 100);
53 void shouldCalculatePriceForMultipleProducts() {
55 final var cart
= new Cart(List
.of(TEST_PRODUCT
, TEST_PRODUCT
), new ArrayList
<>());
58 ruleEngine
.infer(rules
, cart
);
61 assertPrice(cart
, 150);
64 private void assertPrice(final Cart cart
, final int expectedPrice
) {
65 Assertions
.assertAll("prices",
66 () -> Assertions
.assertNotNull(cart
.prices()),
67 () -> Assertions
.assertEquals(1, cart
.prices().size()),
68 () -> Assertions
.assertEquals(expectedPrice
, cart
.prices().get(0).price())