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.UnaryFunction;
22 import org.apache.commons.functor.adapter.BinaryFunctionUnaryFunction;
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.ConditionalUnaryFunction;
27 import org.apache.commons.functor.core.composite.UnaryCompositeBinaryFunction;
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
49
50
51
52
53 public class SupermarketPricingExample {
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 @Test
72 public void testConstantPricePerUnit() throws Exception {
73 {
74 Product beans = new Product(
75 "Can of Beans",
76 "SKU-0001",
77 ToMoney.from(Multiply.by(65)));
78
79 assertEquals(new Money(0*65),beans.getPrice(0));
80 assertEquals(new Money(1*65),beans.getPrice(1));
81 assertEquals(new Money(2*65),beans.getPrice(2));
82 assertEquals(new Money(3*65),beans.getPrice(3));
83 }
84
85 {
86 Product beans = new Product(
87 "Can of Beans",
88 "SKU-0001",
89 65);
90
91 assertEquals(new Money(0*65),beans.getPrice(0));
92 assertEquals(new Money(1*65),beans.getPrice(1));
93 assertEquals(new Money(2*65),beans.getPrice(2));
94 assertEquals(new Money(3*65),beans.getPrice(3));
95 }
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 @Test
120 public void testFourForADollar_A() throws Exception {
121 Product banana = new Product(
122 "Banana",
123 "SKU-0002",
124 ToMoney.from(
125 new ConditionalUnaryFunction<Integer, Number>(
126 IsGreaterThan.instance(new Integer(3)),
127 Multiply.by(25),
128 Multiply.by(33))));
129
130 assertEquals(new Money(0*33),banana.getPrice(0));
131 assertEquals(new Money(1*33),banana.getPrice(1));
132 assertEquals(new Money(2*33),banana.getPrice(2));
133 assertEquals(new Money(3*33),banana.getPrice(3));
134 assertEquals(new Money(4*25),banana.getPrice(4));
135 assertEquals(new Money(5*25),banana.getPrice(5));
136 assertEquals(new Money(6*25),banana.getPrice(6));
137 assertEquals(new Money(7*25),banana.getPrice(7));
138 assertEquals(new Money(8*25),banana.getPrice(8));
139 }
140
141
142 @Test
143 public void testFourForADollar_B() throws Exception {
144 Product banana = new Product(
145 "Banana",
146 "SKU-0002",
147 ToMoney.from(
148 new BinaryFunctionUnaryFunction<Integer, Number>(
149 new UnaryCompositeBinaryFunction<Integer, Integer, Number>(
150 Add.instance(),
151 Composite.function(
152 Multiply.by(100),
153 Divide.by(4)),
154 Composite.function(
155 Multiply.by(33),
156 Mod.by(4))))));
157 assertEquals(new Money(0*33+0*25),banana.getPrice(0));
158 assertEquals(new Money(1*33+0*25),banana.getPrice(1));
159 assertEquals(new Money(2*33+0*25),banana.getPrice(2));
160 assertEquals(new Money(3*33+0*25),banana.getPrice(3));
161 assertEquals(new Money(0*33+4*25),banana.getPrice(4));
162 assertEquals(new Money(1*33+4*25),banana.getPrice(5));
163 assertEquals(new Money(2*33+4*25),banana.getPrice(6));
164 assertEquals(new Money(3*33+4*25),banana.getPrice(7));
165 assertEquals(new Money(0*33+8*25),banana.getPrice(8));
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179 @Test
180 public void testBuyTwoGetOneFree_1() throws Exception {
181 Product apple = new Product(
182 "Apple",
183 "SKU-0003",
184 ToMoney.from(
185 Composite.function(Multiply.by(40),
186 BinaryFunctionUnaryFunction.adapt(new UnaryCompositeBinaryFunction<Number, Number, Number>(Subtract.instance(),
187 new Identity<Number>(),
188 Divide.by(3))))));
189
190 assertEquals(new Money(0*40),apple.getPrice(0));
191 assertEquals(new Money(1*40),apple.getPrice(1));
192 assertEquals(new Money(2*40),apple.getPrice(2));
193 assertEquals(new Money(2*40),apple.getPrice(3));
194 assertEquals(new Money(3*40),apple.getPrice(4));
195 assertEquals(new Money(4*40),apple.getPrice(5));
196 assertEquals(new Money(4*40),apple.getPrice(6));
197 assertEquals(new Money(5*40),apple.getPrice(7));
198 assertEquals(new Money(6*40),apple.getPrice(8));
199 assertEquals(new Money(6*40),apple.getPrice(9));
200 assertEquals(new Money(7*40),apple.getPrice(10));
201 }
202
203
204
205
206
207
208
209
210
211
212 class BuyNGetMFree implements UnaryFunction<Number, Number> {
213 public BuyNGetMFree(int n, int m, int costPerUnit) {
214 this.n = n;
215 this.m = m;
216 this.costPerUnit = costPerUnit;
217 }
218
219 public Number evaluate(Number num) {
220 int quantity = num.intValue();
221 int cost = 0;
222
223 while(quantity >= n) {
224
225 cost += n * costPerUnit;
226 quantity -= n;
227
228 quantity -= Math.min(quantity,m);
229 }
230
231 cost += quantity * costPerUnit;
232
233 return new Integer(cost);
234 }
235
236 private int n, m, costPerUnit;
237 }
238
239 @Test
240 public void testBuyTwoGetOneFree_2() throws Exception {
241 Product apple = new Product(
242 "Apple",
243 "SKU-0003",
244 ToMoney.from(new BuyNGetMFree(2,1,40)));
245
246 assertEquals(new Money(0*40),apple.getPrice(0));
247 assertEquals(new Money(1*40),apple.getPrice(1));
248 assertEquals(new Money(2*40),apple.getPrice(2));
249 assertEquals(new Money(2*40),apple.getPrice(3));
250 assertEquals(new Money(3*40),apple.getPrice(4));
251 assertEquals(new Money(4*40),apple.getPrice(5));
252 assertEquals(new Money(4*40),apple.getPrice(6));
253 assertEquals(new Money(5*40),apple.getPrice(7));
254 assertEquals(new Money(6*40),apple.getPrice(8));
255 assertEquals(new Money(6*40),apple.getPrice(9));
256 assertEquals(new Money(7*40),apple.getPrice(10));
257 }
258
259 @Test
260 public void testBuyThreeGetTwoFree() throws Exception {
261 Product apple = new Product(
262 "Apple",
263 "SKU-0003",
264 ToMoney.from(new BuyNGetMFree(3,2,40)));
265
266 assertEquals(new Money(0*40),apple.getPrice(0));
267 assertEquals(new Money(1*40),apple.getPrice(1));
268 assertEquals(new Money(2*40),apple.getPrice(2));
269 assertEquals(new Money(3*40),apple.getPrice(3));
270 assertEquals(new Money(3*40),apple.getPrice(4));
271 assertEquals(new Money(3*40),apple.getPrice(5));
272 assertEquals(new Money(4*40),apple.getPrice(6));
273 assertEquals(new Money(5*40),apple.getPrice(7));
274 assertEquals(new Money(6*40),apple.getPrice(8));
275 assertEquals(new Money(6*40),apple.getPrice(9));
276 assertEquals(new Money(6*40),apple.getPrice(10));
277 assertEquals(new Money(7*40),apple.getPrice(11));
278 }
279
280 @Test
281 public void testBuyTwoGetFiveFree() throws Exception {
282 Product apple = new Product(
283 "Apple",
284 "SKU-0003",
285 ToMoney.from(new BuyNGetMFree(2,5,40)));
286
287 assertEquals(new Money(0*40),apple.getPrice(0));
288 assertEquals(new Money(1*40),apple.getPrice(1));
289 assertEquals(new Money(2*40),apple.getPrice(2));
290 assertEquals(new Money(2*40),apple.getPrice(3));
291 assertEquals(new Money(2*40),apple.getPrice(4));
292 assertEquals(new Money(2*40),apple.getPrice(5));
293 assertEquals(new Money(2*40),apple.getPrice(6));
294 assertEquals(new Money(2*40),apple.getPrice(7));
295 assertEquals(new Money(3*40),apple.getPrice(8));
296 assertEquals(new Money(4*40),apple.getPrice(9));
297 assertEquals(new Money(4*40),apple.getPrice(10));
298 assertEquals(new Money(4*40),apple.getPrice(11));
299 assertEquals(new Money(4*40),apple.getPrice(12));
300 assertEquals(new Money(4*40),apple.getPrice(13));
301 assertEquals(new Money(4*40),apple.getPrice(14));
302 assertEquals(new Money(5*40),apple.getPrice(15));
303 }
304 }