1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.functor.example.kata.one;
18
19 import static org.junit.Assert.assertEquals;
20
21 import org.apache.commons.functor.Function;
22 import org.apache.commons.functor.adapter.BinaryFunctionFunction;
23 import org.apache.commons.functor.core.Identity;
24 import org.apache.commons.functor.core.comparator.IsGreaterThan;
25 import org.apache.commons.functor.core.composite.Composite;
26 import org.apache.commons.functor.core.composite.ConditionalFunction;
27 import org.apache.commons.functor.core.composite.CompositeBinaryFunction;
28 import org.junit.Test;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class SupermarketPricingExample {
49
50
51
52
53
54
55
56
57
58
59
60
61
62 @Test
63 public void testConstantPricePerUnit() throws Exception {
64 {
65 Product beans = new Product("Can of Beans", "SKU-0001", ToMoney.from(Multiply.by(65)));
66
67 assertEquals(new Money(0 * 65), beans.getPrice(0));
68 assertEquals(new Money(1 * 65), beans.getPrice(1));
69 assertEquals(new Money(2 * 65), beans.getPrice(2));
70 assertEquals(new Money(3 * 65), beans.getPrice(3));
71 }
72
73 {
74 Product beans = new Product("Can of Beans", "SKU-0001", 65);
75
76 assertEquals(new Money(0 * 65), beans.getPrice(0));
77 assertEquals(new Money(1 * 65), beans.getPrice(1));
78 assertEquals(new Money(2 * 65), beans.getPrice(2));
79 assertEquals(new Money(3 * 65), beans.getPrice(3));
80 }
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 @Test
100 public void testFourForADollar_A() throws Exception {
101 Product banana =
102 new Product("Banana", "SKU-0002", ToMoney.from(new ConditionalFunction<Integer, Number>(IsGreaterThan
103 .instance(Integer.valueOf(3)), Multiply.by(25), Multiply.by(33))));
104
105 assertEquals(new Money(0 * 33), banana.getPrice(0));
106 assertEquals(new Money(1 * 33), banana.getPrice(1));
107 assertEquals(new Money(2 * 33), banana.getPrice(2));
108 assertEquals(new Money(3 * 33), banana.getPrice(3));
109 assertEquals(new Money(4 * 25), banana.getPrice(4));
110 assertEquals(new Money(5 * 25), banana.getPrice(5));
111 assertEquals(new Money(6 * 25), banana.getPrice(6));
112 assertEquals(new Money(7 * 25), banana.getPrice(7));
113 assertEquals(new Money(8 * 25), banana.getPrice(8));
114 }
115
116 @Test
117 public void testFourForADollar_B() throws Exception {
118 Product banana =
119 new Product("Banana", "SKU-0002", ToMoney.from(new BinaryFunctionFunction<Integer, Number>(
120 new CompositeBinaryFunction<Integer, Integer, Number>(Add.instance(), Composite.function(
121 Multiply.by(100), Divide.by(4)), Composite.function(Multiply.by(33), Mod.by(4))))));
122 assertEquals(new Money(0 * 33 + 0 * 25), banana.getPrice(0));
123 assertEquals(new Money(1 * 33 + 0 * 25), banana.getPrice(1));
124 assertEquals(new Money(2 * 33 + 0 * 25), banana.getPrice(2));
125 assertEquals(new Money(3 * 33 + 0 * 25), banana.getPrice(3));
126 assertEquals(new Money(0 * 33 + 4 * 25), banana.getPrice(4));
127 assertEquals(new Money(1 * 33 + 4 * 25), banana.getPrice(5));
128 assertEquals(new Money(2 * 33 + 4 * 25), banana.getPrice(6));
129 assertEquals(new Money(3 * 33 + 4 * 25), banana.getPrice(7));
130 assertEquals(new Money(0 * 33 + 8 * 25), banana.getPrice(8));
131 }
132
133
134
135
136
137
138
139
140 @Test
141 public void testBuyTwoGetOneFree_1() throws Exception {
142 Product apple =
143 new Product("Apple", "SKU-0003", ToMoney.from(Composite.function(Multiply.by(40), BinaryFunctionFunction
144 .adapt(new CompositeBinaryFunction<Number, Number, Number>(Subtract.instance(), new Identity<Number>(),
145 Divide.by(3))))));
146
147 assertEquals(new Money(0 * 40), apple.getPrice(0));
148 assertEquals(new Money(1 * 40), apple.getPrice(1));
149 assertEquals(new Money(2 * 40), apple.getPrice(2));
150 assertEquals(new Money(2 * 40), apple.getPrice(3));
151 assertEquals(new Money(3 * 40), apple.getPrice(4));
152 assertEquals(new Money(4 * 40), apple.getPrice(5));
153 assertEquals(new Money(4 * 40), apple.getPrice(6));
154 assertEquals(new Money(5 * 40), apple.getPrice(7));
155 assertEquals(new Money(6 * 40), apple.getPrice(8));
156 assertEquals(new Money(6 * 40), apple.getPrice(9));
157 assertEquals(new Money(7 * 40), apple.getPrice(10));
158 }
159
160
161
162
163
164
165
166
167 class BuyNGetMFree implements Function<Number, Number> {
168 public BuyNGetMFree(int n, int m, int costPerUnit) {
169 this.n = n;
170 this.m = m;
171 this.costPerUnit = costPerUnit;
172 }
173
174 public Number evaluate(Number num) {
175 int quantity = num.intValue();
176 int cost = 0;
177
178 while (quantity >= n) {
179
180 cost += n * costPerUnit;
181 quantity -= n;
182
183 quantity -= Math.min(quantity, m);
184 }
185
186 cost += quantity * costPerUnit;
187
188 return Integer.valueOf(cost);
189 }
190
191 private int n, m, costPerUnit;
192 }
193
194 @Test
195 public void testBuyTwoGetOneFree_2() throws Exception {
196 Product apple = new Product("Apple", "SKU-0003", ToMoney.from(new BuyNGetMFree(2, 1, 40)));
197
198 assertEquals(new Money(0 * 40), apple.getPrice(0));
199 assertEquals(new Money(1 * 40), apple.getPrice(1));
200 assertEquals(new Money(2 * 40), apple.getPrice(2));
201 assertEquals(new Money(2 * 40), apple.getPrice(3));
202 assertEquals(new Money(3 * 40), apple.getPrice(4));
203 assertEquals(new Money(4 * 40), apple.getPrice(5));
204 assertEquals(new Money(4 * 40), apple.getPrice(6));
205 assertEquals(new Money(5 * 40), apple.getPrice(7));
206 assertEquals(new Money(6 * 40), apple.getPrice(8));
207 assertEquals(new Money(6 * 40), apple.getPrice(9));
208 assertEquals(new Money(7 * 40), apple.getPrice(10));
209 }
210
211 @Test
212 public void testBuyThreeGetTwoFree() throws Exception {
213 Product apple = new Product("Apple", "SKU-0003", ToMoney.from(new BuyNGetMFree(3, 2, 40)));
214
215 assertEquals(new Money(0 * 40), apple.getPrice(0));
216 assertEquals(new Money(1 * 40), apple.getPrice(1));
217 assertEquals(new Money(2 * 40), apple.getPrice(2));
218 assertEquals(new Money(3 * 40), apple.getPrice(3));
219 assertEquals(new Money(3 * 40), apple.getPrice(4));
220 assertEquals(new Money(3 * 40), apple.getPrice(5));
221 assertEquals(new Money(4 * 40), apple.getPrice(6));
222 assertEquals(new Money(5 * 40), apple.getPrice(7));
223 assertEquals(new Money(6 * 40), apple.getPrice(8));
224 assertEquals(new Money(6 * 40), apple.getPrice(9));
225 assertEquals(new Money(6 * 40), apple.getPrice(10));
226 assertEquals(new Money(7 * 40), apple.getPrice(11));
227 }
228
229 @Test
230 public void testBuyTwoGetFiveFree() throws Exception {
231 Product apple = new Product("Apple", "SKU-0003", ToMoney.from(new BuyNGetMFree(2, 5, 40)));
232
233 assertEquals(new Money(0 * 40), apple.getPrice(0));
234 assertEquals(new Money(1 * 40), apple.getPrice(1));
235 assertEquals(new Money(2 * 40), apple.getPrice(2));
236 assertEquals(new Money(2 * 40), apple.getPrice(3));
237 assertEquals(new Money(2 * 40), apple.getPrice(4));
238 assertEquals(new Money(2 * 40), apple.getPrice(5));
239 assertEquals(new Money(2 * 40), apple.getPrice(6));
240 assertEquals(new Money(2 * 40), apple.getPrice(7));
241 assertEquals(new Money(3 * 40), apple.getPrice(8));
242 assertEquals(new Money(4 * 40), apple.getPrice(9));
243 assertEquals(new Money(4 * 40), apple.getPrice(10));
244 assertEquals(new Money(4 * 40), apple.getPrice(11));
245 assertEquals(new Money(4 * 40), apple.getPrice(12));
246 assertEquals(new Money(4 * 40), apple.getPrice(13));
247 assertEquals(new Money(4 * 40), apple.getPrice(14));
248 assertEquals(new Money(5 * 40), apple.getPrice(15));
249 }
250 }