1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sourceforge.domian.specification.client;
17
18
19 import java.util.Calendar;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Date;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.LinkedList;
26 import java.util.Map;
27 import java.util.TreeSet;
28 import java.util.concurrent.ConcurrentLinkedQueue;
29
30 import net.sourceforge.domian.specification.CompositeSpecification;
31 import net.sourceforge.domian.specification.Specification;
32 import net.sourceforge.domian.specification.SpecificationFactory;
33 import net.sourceforge.domian.test.domain.Customer;
34 import net.sourceforge.domian.test.domain.Order;
35 import net.sourceforge.domian.test.domain.OrderLine;
36 import net.sourceforge.domian.test.domain.Testdata;
37 import net.sourceforge.domian.test.domain.VipCustomer;
38
39 import junit.framework.TestCase;
40
41 import static net.sourceforge.domian.specification.SpecificationFactory.a;
42 import static net.sourceforge.domian.specification.SpecificationFactory.all;
43 import static net.sourceforge.domian.specification.SpecificationFactory.allInstancesOfType;
44 import static net.sourceforge.domian.specification.SpecificationFactory.allObjects;
45 import static net.sourceforge.domian.specification.SpecificationFactory.allOf;
46 import static net.sourceforge.domian.specification.SpecificationFactory.an;
47 import static net.sourceforge.domian.specification.SpecificationFactory.anyOf;
48 import static net.sourceforge.domian.specification.SpecificationFactory.atLeast;
49 import static net.sourceforge.domian.specification.SpecificationFactory.atMost;
50 import static net.sourceforge.domian.specification.SpecificationFactory.before;
51 import static net.sourceforge.domian.specification.SpecificationFactory.both;
52 import static net.sourceforge.domian.specification.SpecificationFactory.createEqualSpecification;
53 import static net.sourceforge.domian.specification.SpecificationFactory.createNotNullSpecification;
54 import static net.sourceforge.domian.specification.SpecificationFactory.createSpecificationFor;
55 import static net.sourceforge.domian.specification.SpecificationFactory.eitherOf;
56 import static net.sourceforge.domian.specification.SpecificationFactory.equalTo;
57 import static net.sourceforge.domian.specification.SpecificationFactory.greaterThan;
58 import static net.sourceforge.domian.specification.SpecificationFactory.haveSize;
59 import static net.sourceforge.domian.specification.SpecificationFactory.include;
60 import static net.sourceforge.domian.specification.SpecificationFactory.includeAPercentageOf;
61 import static net.sourceforge.domian.specification.SpecificationFactory.instancesOfType;
62 import static net.sourceforge.domian.specification.SpecificationFactory.is;
63 import static net.sourceforge.domian.specification.SpecificationFactory.isA;
64 import static net.sourceforge.domian.specification.SpecificationFactory.isAfter;
65 import static net.sourceforge.domian.specification.SpecificationFactory.isAllOf;
66 import static net.sourceforge.domian.specification.SpecificationFactory.isAtTheSameTimeAs;
67 import static net.sourceforge.domian.specification.SpecificationFactory.isBefore;
68 import static net.sourceforge.domian.specification.SpecificationFactory.isBeforeOrAtTheSameTimeAs;
69 import static net.sourceforge.domian.specification.SpecificationFactory.isBoth;
70 import static net.sourceforge.domian.specification.SpecificationFactory.isEither;
71 import static net.sourceforge.domian.specification.SpecificationFactory.isEitherOf;
72 import static net.sourceforge.domian.specification.SpecificationFactory.isEqualTo;
73 import static net.sourceforge.domian.specification.SpecificationFactory.isNotNull;
74 import static net.sourceforge.domian.specification.SpecificationFactory.isSatisfiedBy;
75 import static net.sourceforge.domian.specification.SpecificationFactory.matchesRegularExpression;
76 import static net.sourceforge.domian.specification.SpecificationFactory.matchesWildcardExpression;
77 import static net.sourceforge.domian.specification.SpecificationFactory.matchesWildcardExpressionIgnoringCase;
78 import static net.sourceforge.domian.specification.SpecificationFactory.neitherOf;
79 import static net.sourceforge.domian.specification.SpecificationFactory.not;
80 import static net.sourceforge.domian.specification.SpecificationFactory.shouldBe;
81 import static net.sourceforge.domian.specification.SpecificationFactory.shouldBeBoth;
82 import static net.sourceforge.domian.specification.SpecificationFactory.specify;
83 import static net.sourceforge.domian.test.domain.Customer.Gender.FEMALE;
84 import static net.sourceforge.domian.test.domain.Customer.Gender.MALE;
85 import static net.sourceforge.domian.test.domain.Testdata.childFemaleCustomer;
86 import static net.sourceforge.domian.test.domain.Testdata.childMaleCustomer;
87 import static net.sourceforge.domian.test.domain.Testdata.customer12;
88 import static net.sourceforge.domian.test.domain.Testdata.customer13;
89 import static net.sourceforge.domian.test.domain.Testdata.femaleCustomer;
90 import static net.sourceforge.domian.test.domain.Testdata.maleCustomer;
91 import static net.sourceforge.domian.test.domain.Testdata.maleVipCustomer;
92 import static net.sourceforge.domian.test.domain.Testdata.oldFemaleCustomer;
93 import static net.sourceforge.domian.test.domain.Testdata.oldMaleCustomer;
94 import static net.sourceforge.domian.test.domain.Testdata.order22;
95 import static net.sourceforge.domian.test.domain.Testdata.order23;
96 import static net.sourceforge.domian.test.domain.Testdata.order24;
97 import static net.sourceforge.domian.test.domain.Testdata.orderWithNoCustomer;
98 import static net.sourceforge.domian.test.domain.Testdata.teenagerFemaleCustomer;
99 import static net.sourceforge.domian.test.domain.Testdata.teenagerMaleCustomer;
100 import static net.sourceforge.domian.test.domain.Testdata.thirtyYearsAgo;
101 import static net.sourceforge.domian.test.domain.Testdata.today;
102 import static net.sourceforge.domian.test.domain.Testdata.twentyYearsAgo;
103 import static net.sourceforge.domian.test.domain.Testdata.twoDaysAgo;
104 import static net.sourceforge.domian.test.domain.Testdata.yesterday;
105
106
107
108 public class SpecificationFactoryTest extends TestCase {
109
110
111
112
113
114
115
116
117 public void testNullSpecificationsShouldAcceptEverything() {
118 Specification rawSpec = createSpecificationFor(null);
119 assertNotNull(rawSpec);
120 assertFalse(rawSpec.isSatisfiedBy(null));
121 assertTrue(rawSpec.isSatisfiedBy(0));
122 assertTrue(rawSpec.isSatisfiedBy(100L));
123 assertTrue(rawSpec.isSatisfiedBy("yo"));
124 assertTrue(rawSpec.isSatisfiedBy(order22));
125 assertTrue(rawSpec.isSatisfiedBy(order23));
126 assertTrue(rawSpec.isSatisfiedBy(customer12));
127
128 Specification<? super Object> spec = (Specification) createSpecificationFor(null);
129 assertNotNull(spec);
130 assertFalse(spec.isSatisfiedBy(null));
131 assertTrue(spec.isSatisfiedBy(0));
132 assertTrue(spec.isSatisfiedBy(100L));
133 assertTrue(spec.isSatisfiedBy("yo"));
134 assertTrue(spec.isSatisfiedBy(order22));
135 assertTrue(spec.isSatisfiedBy(order23));
136 assertTrue(spec.isSatisfiedBy(customer12));
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 }
160
161
162 public void testRawSpecificationsWithOnlyTypeShouldBeSatisfiedByAllObjectsOfThatType() {
163 Specification orderSpec = createSpecificationFor(Order.class);
164 assertNotNull(orderSpec);
165 assertFalse(orderSpec.isSatisfiedBy(null));
166 assertFalse(orderSpec.isSatisfiedBy(0));
167 assertFalse(orderSpec.isSatisfiedBy(100L));
168 assertFalse(orderSpec.isSatisfiedBy("yo"));
169 assertTrue(orderSpec.isSatisfiedBy(order22));
170 assertTrue(orderSpec.isSatisfiedBy(order23));
171 assertFalse(orderSpec.isSatisfiedBy(customer12));
172 }
173
174
175 public void testSpecificationsWithoutTypeShouldBeSatisfiedByAllObjects() {
176
177 Specification rawOrderSpec = createSpecificationFor(Order.class).and((Specification<Order>) isNotNull());
178 assertNotNull(rawOrderSpec);
179 assertFalse(rawOrderSpec.isSatisfiedBy(null));
180 assertFalse(rawOrderSpec.isSatisfiedBy(0));
181 assertFalse(rawOrderSpec.isSatisfiedBy(100L));
182 assertFalse(rawOrderSpec.isSatisfiedBy("yo"));
183 assertTrue(rawOrderSpec.isSatisfiedBy(order22));
184 assertTrue(rawOrderSpec.isSatisfiedBy(order23));
185 assertFalse(rawOrderSpec.isSatisfiedBy(customer12));
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 rawOrderSpec = createSpecificationFor(Order.class).or((Specification<Order>) isNotNull());
213 assertNotNull(rawOrderSpec);
214 assertFalse(rawOrderSpec.isSatisfiedBy(null));
215 assertTrue(rawOrderSpec.isSatisfiedBy(0));
216 assertTrue(rawOrderSpec.isSatisfiedBy(100L));
217 assertTrue(rawOrderSpec.isSatisfiedBy("yo"));
218 assertTrue(rawOrderSpec.isSatisfiedBy(order22));
219 assertTrue(rawOrderSpec.isSatisfiedBy(order23));
220 assertTrue(rawOrderSpec.isSatisfiedBy(customer12));
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 }
256
257
258 public void testShouldCreateSimpleSpecifications() {
259 CompositeSpecification<Order> orderSpec = createSpecificationFor(Order.class);
260
261
262 orderSpec.where("orderId", isEqualTo(23L));
263 assertNotNull(orderSpec);
264 assertFalse(orderSpec.isSatisfiedBy(null));
265
266
267
268 assertTrue(orderSpec.isSatisfiedBy(order22));
269 assertTrue(orderSpec.isSatisfiedBy(order23));
270
271
272
273 orderSpec = orderSpec.where("orderId", isEqualTo(23L));
274 assertNotNull(orderSpec);
275 assertFalse(orderSpec.isSatisfiedBy(null));
276 assertFalse(orderSpec.isSatisfiedBy(order22));
277 assertTrue(orderSpec.isSatisfiedBy(order23));
278
279
280 orderSpec.or("orderId", isEqualTo(22L));
281 assertNotNull(orderSpec);
282 assertFalse(orderSpec.isSatisfiedBy(null));
283 assertFalse(orderSpec.isSatisfiedBy(order22));
284 assertTrue(orderSpec.isSatisfiedBy(order23));
285
286
287 orderSpec = orderSpec.or("orderId", isEqualTo(22L));
288 assertNotNull(orderSpec);
289 assertFalse(orderSpec.isSatisfiedBy(null));
290 assertTrue(orderSpec.isSatisfiedBy(order22));
291 assertTrue(orderSpec.isSatisfiedBy(order23));
292 }
293
294
295 public void testShouldCreateDisjunctiveSpecifications() {
296 Specification<Order> orderSpec = createSpecificationFor(Order.class)
297 .where("orderId", isEqualTo(22L))
298 .or("orderId", isEqualTo(23L));
299 assertNotNull(orderSpec);
300 assertFalse(orderSpec.isSatisfiedBy(null));
301 assertTrue(orderSpec.isSatisfiedBy(order22));
302 assertTrue(orderSpec.isSatisfiedBy(order23));
303 assertFalse(orderSpec.isSatisfiedBy(order24));
304
305
306 orderSpec = createSpecificationFor(Order.class)
307 .where("orderId", isSatisfiedBy(anyOf(isEqualTo(22L), isEqualTo(23L))));
308 assertNotNull(orderSpec);
309 assertFalse(orderSpec.isSatisfiedBy(null));
310 assertTrue(orderSpec.isSatisfiedBy(order22));
311 assertTrue(orderSpec.isSatisfiedBy(order23));
312 assertFalse(orderSpec.isSatisfiedBy(order24));
313
314
315 Specification<Long> long22 = isEqualTo(22L);
316 Specification<Long> long23 = isEqualTo(23L);
317
318 orderSpec = allInstancesOfType(Order.class).where("orderId", isSatisfiedBy(anyOf(long22, long23)));
319 assertNotNull(orderSpec);
320 assertFalse(orderSpec.isSatisfiedBy(null));
321 assertTrue(orderSpec.isSatisfiedBy(order22));
322 assertTrue(orderSpec.isSatisfiedBy(order23));
323 assertFalse(orderSpec.isSatisfiedBy(order24));
324
325
326 orderSpec = an(Order.class).where("orderId", isEither(long22, long23));
327 assertNotNull(orderSpec);
328 assertFalse(orderSpec.isSatisfiedBy(null));
329 assertTrue(orderSpec.isSatisfiedBy(order22));
330 assertTrue(orderSpec.isSatisfiedBy(order23));
331 assertFalse(orderSpec.isSatisfiedBy(order24));
332 }
333
334
335 public void testShouldCreateConjunctiveSpecifications_asymmetrical() {
336
337 CompositeSpecification<Order> orderSpec = createSpecificationFor(Order.class)
338 .where("orderId", isEqualTo(22L))
339 .or("orderId", isEqualTo(23L))
340 .and("orderDate", isAfter(yesterday));
341
342 assertNotNull(orderSpec);
343 assertFalse(orderSpec.isSatisfiedBy(null));
344 assertFalse(orderSpec.isSatisfiedBy(order22));
345 assertTrue(orderSpec.isSatisfiedBy(order23));
346
347 Specification<Order> orderSpec2 = orderSpec.or("customer", isNotNull());
348 assertNotNull(orderSpec2);
349 assertFalse(orderSpec2.isSatisfiedBy(null));
350 assertTrue(orderSpec2.isSatisfiedBy(order22));
351 assertTrue(orderSpec2.isSatisfiedBy(order23));
352
353
354 assertNotNull(orderSpec);
355 assertFalse(orderSpec.isSatisfiedBy(null));
356 assertFalse(orderSpec.isSatisfiedBy(order22));
357 assertTrue(orderSpec.isSatisfiedBy(order23));
358 }
359
360
361 public void testShouldCreateConjunctiveSpecifications_symmetrical() {
362
363 CompositeSpecification<Order> orderSpec = createSpecificationFor(Order.class)
364 .where("orderId", isSatisfiedBy(anyOf(isEqualTo(22L), isEqualTo(23L))))
365 .and("orderDate", isAfter(yesterday));
366
367 assertNotNull(orderSpec);
368 assertFalse(orderSpec.isSatisfiedBy(null));
369 assertFalse(orderSpec.isSatisfiedBy(order22));
370 assertTrue(orderSpec.isSatisfiedBy(order23));
371
372 Specification<Order> orderSpec2 = orderSpec.or("customer", isNotNull());
373 assertNotNull(orderSpec2);
374 assertFalse(orderSpec.isSatisfiedBy(null));
375 assertTrue(orderSpec2.isSatisfiedBy(order22));
376 assertTrue(orderSpec2.isSatisfiedBy(order23));
377
378
379 assertNotNull(orderSpec);
380 assertFalse(orderSpec.isSatisfiedBy(null));
381 assertFalse(orderSpec.isSatisfiedBy(order22));
382 assertTrue(orderSpec.isSatisfiedBy(order23));
383
384
385 Specification<Long> long22 = createEqualSpecification(22L);
386 Specification<Long> long23 = createEqualSpecification(23L);
387 orderSpec = allInstancesOfType(Order.class).where("orderId", isEitherOf(long22, long23)).and("orderDate", isAfter(yesterday));
388
389 assertNotNull(orderSpec);
390 assertFalse(orderSpec.isSatisfiedBy(null));
391 assertFalse(orderSpec.isSatisfiedBy(order22));
392 assertTrue(orderSpec.isSatisfiedBy(order23));
393
394 orderSpec2 = orderSpec.or("customer", isNotNull());
395 assertNotNull(orderSpec2);
396 assertFalse(orderSpec.isSatisfiedBy(null));
397 assertTrue(orderSpec2.isSatisfiedBy(order22));
398 assertTrue(orderSpec2.isSatisfiedBy(order23));
399
400
401 assertNotNull(orderSpec);
402 assertFalse(orderSpec.isSatisfiedBy(null));
403 assertFalse(orderSpec.isSatisfiedBy(order22));
404 assertTrue(orderSpec.isSatisfiedBy(order23));
405 }
406
407
408 public void testShouldCreateSimpleRecursiveSpecifications() {
409 Specification<Customer> customersWhoHasBeenMembersForTwoDaysOrMore = createSpecificationFor(Customer.class)
410 .where("membershipDate", isBeforeOrAtTheSameTimeAs(twoDaysAgo));
411
412 Specification<Order> orderSpec = createSpecificationFor(Order.class)
413 .where("customer", isSatisfiedBy(customersWhoHasBeenMembersForTwoDaysOrMore));
414
415 assertNotNull(orderSpec);
416 assertFalse(orderSpec.isSatisfiedBy(null));
417 assertTrue(orderSpec.isSatisfiedBy(order22));
418 assertFalse(orderSpec.isSatisfiedBy(order23));
419
420 orderSpec = createSpecificationFor(Order.class)
421 .where("customer", isSatisfiedBy(customersWhoHasBeenMembersForTwoDaysOrMore))
422 .and("orderDate", isAfter(today));
423
424 assertNotNull(orderSpec);
425 assertFalse(orderSpec.isSatisfiedBy(null));
426 assertFalse(orderSpec.isSatisfiedBy(order22));
427 assertFalse(orderSpec.isSatisfiedBy(order23));
428
429 orderSpec = createSpecificationFor(Order.class)
430 .where("customer", isSatisfiedBy(customersWhoHasBeenMembersForTwoDaysOrMore))
431 .or("orderDate", isBeforeOrAtTheSameTimeAs(today));
432
433 assertNotNull(orderSpec);
434 assertFalse(orderSpec.isSatisfiedBy(null));
435 assertTrue(orderSpec.isSatisfiedBy(order22));
436 assertTrue(orderSpec.isSatisfiedBy(order23));
437 }
438
439
440 public void testShouldCreateDoubleRecursiveSpecifications() {
441 Specification<Customer> allCustomers = allInstancesOfType(Customer.class);
442
443 Specification<Customer> customersWhoHasBeenMembersForTwoDaysOrMore = createSpecificationFor(Customer.class)
444 .where("membershipDate", isBeforeOrAtTheSameTimeAs(twoDaysAgo));
445
446 Specification<Order> orderSpec = createSpecificationFor(Order.class)
447 .where("customer", isSatisfiedBy(anyOf(customersWhoHasBeenMembersForTwoDaysOrMore, allCustomers)));
448
449 assertNotNull(orderSpec);
450 assertFalse(orderSpec.isSatisfiedBy(null));
451 assertTrue(orderSpec.isSatisfiedBy(order22));
452 assertTrue(orderSpec.isSatisfiedBy(order23));
453 assertFalse(orderSpec.isSatisfiedBy(orderWithNoCustomer));
454
455 orderSpec = createSpecificationFor(Order.class)
456 .where("customer", isSatisfiedBy(allOf(customersWhoHasBeenMembersForTwoDaysOrMore, allCustomers)));
457
458 assertNotNull(orderSpec);
459 assertFalse(orderSpec.isSatisfiedBy(null));
460 assertTrue(orderSpec.isSatisfiedBy(order22));
461 assertFalse(orderSpec.isSatisfiedBy(order23));
462 assertFalse(orderSpec.isSatisfiedBy(orderWithNoCustomer));
463
464
465 orderSpec = createSpecificationFor(Order.class)
466 .where("customer", isEitherOf(customersWhoHasBeenMembersForTwoDaysOrMore, allCustomers));
467
468 assertNotNull(orderSpec);
469 assertFalse(orderSpec.isSatisfiedBy(null));
470 assertTrue(orderSpec.isSatisfiedBy(order22));
471 assertTrue(orderSpec.isSatisfiedBy(order23));
472 assertFalse(orderSpec.isSatisfiedBy(orderWithNoCustomer));
473
474 orderSpec = createSpecificationFor(Order.class)
475 .where("customer", isAllOf(customersWhoHasBeenMembersForTwoDaysOrMore, allCustomers));
476
477 assertNotNull(orderSpec);
478 assertFalse(orderSpec.isSatisfiedBy(null));
479 assertTrue(orderSpec.isSatisfiedBy(order22));
480 assertFalse(orderSpec.isSatisfiedBy(order23));
481 assertFalse(orderSpec.isSatisfiedBy(orderWithNoCustomer));
482 }
483
484
485 public void testShouldCreateSpecificationsWithSpecificationVarargParameters() {
486 Specification<Customer> maleCustomer_1 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(childMaleCustomer.getCustomerId()));
487 Specification<Customer> maleCustomer_2 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(teenagerMaleCustomer.getCustomerId()));
488 Specification<Customer> maleCustomer_3 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(maleCustomer.getCustomerId()));
489 Specification<Customer> maleCustomer_4 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(oldMaleCustomer.getCustomerId()));
490
491 Specification<Customer> femaleCustomer_1 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(childFemaleCustomer.getCustomerId()));
492 Specification<Customer> femaleCustomer_2 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(teenagerFemaleCustomer.getCustomerId()));
493 Specification<Customer> femaleCustomer_3 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(femaleCustomer.getCustomerId()));
494 Specification<Customer> femaleCustomer_4 = createSpecificationFor(Customer.class).where("customerId", isEqualTo(oldFemaleCustomer.getCustomerId()));
495
496 Specification<Customer> maleCustomer = createSpecificationFor(Customer.class).where("gender", is(MALE));
497 Specification<Customer> femaleCustomer = createSpecificationFor(Customer.class).where("gender", is(FEMALE));
498
499 Specification<Customer> customer = createSpecificationFor(Customer.class);
500
501 Specification allObjects = allObjects();
502
503 Order maleCustomer_1_Order = new Order(1001L, today, childMaleCustomer, Collections.<OrderLine>emptyList());
504 Order maleCustomer_2_Order = new Order(1002L, today, teenagerMaleCustomer, Collections.<OrderLine>emptyList());
505 Order maleCustomer_3_Order = new Order(1003L, yesterday, Testdata.maleCustomer, Collections.<OrderLine>emptyList());
506 Order maleCustomer_4_Order = new Order(1004L, yesterday, oldMaleCustomer, Collections.<OrderLine>emptyList());
507 Order femaleCustomer_1_Order = new Order(2001L, today, childFemaleCustomer, Collections.<OrderLine>emptyList());
508 Order femaleCustomer_2_Order = new Order(2002L, today, teenagerFemaleCustomer, Collections.<OrderLine>emptyList());
509 Order femaleCustomer_3_Order = new Order(2003L, yesterday, Testdata.femaleCustomer, Collections.<OrderLine>emptyList());
510 Order femaleCustomer_4_Order = new Order(2004L, yesterday, oldFemaleCustomer, Collections.<OrderLine>emptyList());
511
512 Specification<Order> orderSpec;
513
514
515 orderSpec = createSpecificationFor(Order.class).where("customer", isEitherOf(maleCustomer_1, maleCustomer_2, maleCustomer_3));
516
517 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_1_Order));
518 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_2_Order));
519 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_3_Order));
520 assertFalse(orderSpec.isSatisfiedBy(maleCustomer_4_Order));
521 assertFalse(orderSpec.isSatisfiedBy(femaleCustomer_1_Order));
522 assertFalse(orderSpec.isSatisfiedBy(femaleCustomer_2_Order));
523 assertFalse(orderSpec.isSatisfiedBy(femaleCustomer_3_Order));
524 assertFalse(orderSpec.isSatisfiedBy(femaleCustomer_4_Order));
525
526 orderSpec = createSpecificationFor(Order.class).where("customer", isEitherOf(femaleCustomer_1, femaleCustomer_3, allObjects));
527
528 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_1_Order));
529 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_2_Order));
530 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_3_Order));
531 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_4_Order));
532 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_1_Order));
533 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_2_Order));
534 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_3_Order));
535 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_4_Order));
536
537
538 orderSpec = createSpecificationFor(Order.class).where("customer", isSatisfiedBy(eitherOf(maleCustomer_1, maleCustomer_2, maleCustomer_3, femaleCustomer)));
539
540 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_1_Order));
541 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_2_Order));
542 assertTrue(orderSpec.isSatisfiedBy(maleCustomer_3_Order));
543 assertFalse(orderSpec.isSatisfiedBy(maleCustomer_4_Order));
544 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_1_Order));
545 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_2_Order));
546 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_3_Order));
547 assertTrue(orderSpec.isSatisfiedBy(femaleCustomer_4_Order));
548 }
549
550
551
552 public void testShouldCreateCompositeSpecifications_1() {
553 Specification<Customer> femaleTeenagerSpec = specify(Customer.class)
554 .where("birthDate", isAfter(thirtyYearsAgo))
555 .and("gender", is(FEMALE));
556
557 assertFalse(femaleTeenagerSpec.isSatisfiedBy(null));
558 assertFalse(femaleTeenagerSpec.isSatisfiedBy(teenagerMaleCustomer));
559 assertFalse(femaleTeenagerSpec.isSatisfiedBy(maleCustomer));
560 assertFalse(femaleTeenagerSpec.isSatisfiedBy(oldMaleCustomer));
561 assertTrue(femaleTeenagerSpec.isSatisfiedBy(teenagerFemaleCustomer));
562 assertFalse(femaleTeenagerSpec.isSatisfiedBy(femaleCustomer));
563 assertFalse(femaleTeenagerSpec.isSatisfiedBy(oldFemaleCustomer));
564 }
565
566
567 public void testShouldCreateCompositeSpecifications_2() {
568
569
570
571
572
573
574
575
576
577
578
579
580
581 Specification<Customer.Gender> femaleSpec = is(FEMALE);
582 Specification<Customer.Gender> maleSpec = is(MALE);
583 Specification<Date> teenagerSpec = isAfter(twentyYearsAgo);
584
585 Specification<Customer> spec = specify(Customer.class)
586 .where("birthDate", isSatisfiedBy(teenagerSpec))
587 .and("gender", isSatisfiedBy(femaleSpec))
588 .or("gender", isSatisfiedBy(maleSpec));
589
590 assertFalse(spec.isSatisfiedBy(null));
591 assertTrue(spec.isSatisfiedBy(teenagerMaleCustomer));
592 assertTrue(spec.isSatisfiedBy(maleCustomer));
593 assertTrue(spec.isSatisfiedBy(oldMaleCustomer));
594 assertTrue(spec.isSatisfiedBy(teenagerFemaleCustomer));
595 assertFalse(spec.isSatisfiedBy(femaleCustomer));
596 assertFalse(spec.isSatisfiedBy(oldFemaleCustomer));
597 }
598
599
600 public void testShouldCreateCompositeSpecifications_3() {
601 Specification<Customer.Gender> femaleSpec = is(FEMALE);
602 Specification<Customer.Gender> maleSpec = is(MALE);
603 Specification<Date> teenagerSpec = isAfter(twentyYearsAgo);
604
605 Specification<Customer> femaleCustomer = a(Customer.class).where("gender", isSatisfiedBy(femaleSpec));
606 Specification<Customer> maleCustomer = a(Customer.class).where("gender", isSatisfiedBy(maleSpec));
607 Specification<Customer> teenagerCustomer = a(Customer.class).where("birthDate", isSatisfiedBy(teenagerSpec));
608 Specification<Customer> teenageFemaleCustomer = isBoth(femaleCustomer, teenagerCustomer);
609
610
611
612 Specification<Customer> spec = shouldBeBoth(femaleCustomer, teenagerCustomer).or(a(maleCustomer));
613
614
615
616
617 assertFalse(spec.isSatisfiedBy(null));
618 assertTrue(spec.isSatisfiedBy(teenagerMaleCustomer));
619 assertTrue(spec.isSatisfiedBy(Testdata.maleCustomer));
620 assertTrue(spec.isSatisfiedBy(oldMaleCustomer));
621 assertTrue(spec.isSatisfiedBy(teenagerFemaleCustomer));
622 assertFalse(spec.isSatisfiedBy(Testdata.femaleCustomer));
623 assertFalse(spec.isSatisfiedBy(oldFemaleCustomer));
624
625
626 spec = teenageFemaleCustomer.or(maleCustomer);
627 assertFalse(spec.isSatisfiedBy(null));
628 assertTrue(spec.isSatisfiedBy(teenagerMaleCustomer));
629 assertTrue(spec.isSatisfiedBy(Testdata.maleCustomer));
630 assertTrue(spec.isSatisfiedBy(oldMaleCustomer));
631 assertTrue(spec.isSatisfiedBy(teenagerFemaleCustomer));
632 assertFalse(spec.isSatisfiedBy(Testdata.femaleCustomer));
633 assertFalse(spec.isSatisfiedBy(oldFemaleCustomer));
634
635
636 spec = eitherOf(maleCustomer, teenageFemaleCustomer);
637 assertFalse(spec.isSatisfiedBy(null));
638 assertTrue(spec.isSatisfiedBy(teenagerMaleCustomer));
639 assertTrue(spec.isSatisfiedBy(Testdata.maleCustomer));
640 assertTrue(spec.isSatisfiedBy(oldMaleCustomer));
641 assertTrue(spec.isSatisfiedBy(teenagerFemaleCustomer));
642 assertFalse(spec.isSatisfiedBy(Testdata.femaleCustomer));
643 assertFalse(spec.isSatisfiedBy(oldFemaleCustomer));
644
645
646 spec = shouldBe(eitherOf(maleCustomer, both(femaleCustomer, teenagerCustomer)));
647 assertFalse(spec.isSatisfiedBy(null));
648 assertTrue(spec.isSatisfiedBy(teenagerMaleCustomer));
649 assertTrue(spec.isSatisfiedBy(Testdata.maleCustomer));
650 assertTrue(spec.isSatisfiedBy(oldMaleCustomer));
651 assertTrue(spec.isSatisfiedBy(teenagerFemaleCustomer));
652 assertFalse(spec.isSatisfiedBy(Testdata.femaleCustomer));
653 assertFalse(spec.isSatisfiedBy(oldFemaleCustomer));
654
655
656 spec = shouldBe(a(maleCustomer)).or(both(femaleCustomer, teenagerCustomer));
657
658
659
660
661
662 assertFalse(spec.isSatisfiedBy(null));
663 assertTrue(spec.isSatisfiedBy(teenagerMaleCustomer));
664 assertTrue(spec.isSatisfiedBy(Testdata.maleCustomer));
665 assertTrue(spec.isSatisfiedBy(oldMaleCustomer));
666 assertTrue(spec.isSatisfiedBy(teenagerFemaleCustomer));
667 assertFalse(spec.isSatisfiedBy(Testdata.femaleCustomer));
668 assertFalse(spec.isSatisfiedBy(oldFemaleCustomer));
669 }
670
671
672 public void testShouldCreateCompositeSpecifications_4() {
673 Specification<Customer> customer = SpecificationFactory.allInstancesOfType(Customer.class);
674 Specification<Customer> femaleCustomer = isA(Customer.class).where("gender", is(FEMALE));
675 Specification<Customer> maleCustomer = isA(Customer.class).where("gender", is(MALE));
676 Specification<Customer> teenagerCustomer = a(Customer.class).where("birthDate", isAfter(twentyYearsAgo));
677
678
679 Specification<Customer> spec = shouldBe(a(maleCustomer)).or(both(femaleCustomer, teenagerCustomer)).or(customer);
680
681 assertFalse(spec.isSatisfiedBy(null));
682 assertTrue(spec.isSatisfiedBy(teenagerMaleCustomer));
683 assertTrue(spec.isSatisfiedBy(Testdata.maleCustomer));
684 assertTrue(spec.isSatisfiedBy(oldMaleCustomer));
685 assertTrue(spec.isSatisfiedBy(teenagerFemaleCustomer));
686 assertTrue(spec.isSatisfiedBy(Testdata.femaleCustomer));
687 assertTrue(spec.isSatisfiedBy(oldFemaleCustomer));
688 }
689
690
691 public void testShouldConvertWildcardExpressionsToRegularExpressions() {
692
693 Specification<String> stringsStartingWithIgnoreCaseESpec = matchesRegularExpression("[eE]\\S*");
694 assertFalse(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy(null));
695 assertFalse(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy(""));
696 assertFalse(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy(" "));
697 assertFalse(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy("Peer"));
698 assertTrue(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy("e"));
699 assertTrue(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy("eirik"));
700 assertTrue(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy("E"));
701 assertTrue(stringsStartingWithIgnoreCaseESpec.isSatisfiedBy("Eirik"));
702
703
704 Specification<String> convertedStringsStartingWithESpec = matchesWildcardExpression("e*");
705 assertFalse(convertedStringsStartingWithESpec.isSatisfiedBy(null));
706 assertFalse(convertedStringsStartingWithESpec.isSatisfiedBy(""));
707 assertFalse(convertedStringsStartingWithESpec.isSatisfiedBy(" "));
708 assertFalse(convertedStringsStartingWithESpec.isSatisfiedBy("Peer"));
709 assertTrue(convertedStringsStartingWithESpec.isSatisfiedBy("e"));
710 assertTrue(convertedStringsStartingWithESpec.isSatisfiedBy("eirik"));
711 assertFalse(convertedStringsStartingWithESpec.isSatisfiedBy("E"));
712 assertFalse(convertedStringsStartingWithESpec.isSatisfiedBy("Eirik"));
713
714 Specification<String> convertedStringsStartingWithEIgnoringCaseSpec = matchesWildcardExpressionIgnoringCase("e*");
715 assertFalse(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy(null));
716 assertFalse(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy(""));
717 assertFalse(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy(" "));
718 assertFalse(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy("Peer"));
719 assertTrue(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy("e"));
720 assertTrue(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy("eirik"));
721 assertTrue(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy("E"));
722 assertTrue(convertedStringsStartingWithEIgnoringCaseSpec.isSatisfiedBy("Eirik"));
723 }
724
725
726 public void testNegatedSpecification_1() {
727 Specification<Integer> int42 = isEqualTo(42);
728 Specification<Integer> notInt42 = not(int42);
729 Specification<Integer> notNotNotInt42 = not(not(not(int42)));
730 Specification<Integer> notNotNotNotInt42 = not(not(not(not(int42))));
731
732 assertTrue(int42.isSatisfiedBy(42));
733 assertFalse(int42.isSatisfiedBy(43));
734
735 assertFalse(notInt42.isSatisfiedBy(42));
736 assertTrue(notInt42.isSatisfiedBy(41));
737
738 assertFalse(notNotNotInt42.isSatisfiedBy(42));
739 assertTrue(notNotNotInt42.isSatisfiedBy(43));
740
741 assertTrue(notNotNotNotInt42.isSatisfiedBy(42));
742 assertFalse(notNotNotNotInt42.isSatisfiedBy(41));
743 }
744
745
746 public void testNegatedSpecification_2() {
747 Specification<Customer> female = a(Customer.class).where("gender", is(FEMALE));
748 Specification<Customer> teenager = a(Customer.class).where("birthDate", isAfter(twentyYearsAgo));
749
750 Specification<Customer> spec = shouldBe(a(female)).and(not(a(teenager)));
751
752 assertFalse(spec.isSatisfiedBy(null));
753 assertFalse(spec.isSatisfiedBy(teenagerMaleCustomer));
754 assertFalse(spec.isSatisfiedBy(Testdata.maleCustomer));
755 assertFalse(spec.isSatisfiedBy(oldMaleCustomer));
756 assertFalse(spec.isSatisfiedBy(teenagerFemaleCustomer));
757 assertTrue(spec.isSatisfiedBy(Testdata.femaleCustomer));
758 assertTrue(spec.isSatisfiedBy(oldFemaleCustomer));
759 }
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820 public void testCollectionSpecificationHaveSize() {
821 customer12.addOrder(order22);
822 customer13.addOrder(order23);
823 customer13.addOrder(order24);
824
825 Specification<Customer> customersWithMoreThanOneOrderSpec = createSpecificationFor(Customer.class).where("orders", haveSize(greaterThan(1)));
826 assertNotNull(customersWithMoreThanOneOrderSpec);
827 assertFalse(customersWithMoreThanOneOrderSpec.isSatisfiedBy(customer12));
828 assertTrue(customersWithMoreThanOneOrderSpec.isSatisfiedBy(customer13));
829
830 customer12.clearOrders();
831 customer13.clearOrders();
832 }
833
834
835 public void testCollectionSpecificationInclude() {
836 customer12.addOrder(order22);
837 customer13.addOrder(order23);
838 customer13.addOrder(order24);
839
840 Specification<Order> orderFromBeforeToday = an(Order.class).where("orderDate", isBefore(today));
841
842 Specification<Customer> customersWithAtLeastOneOrderFromBeforeTodaySpec =
843 createSpecificationFor(Customer.class).where("orders", include(atLeast(1), orderFromBeforeToday));
844 assertTrue(customersWithAtLeastOneOrderFromBeforeTodaySpec.isSatisfiedBy(customer12));
845 assertFalse(customersWithAtLeastOneOrderFromBeforeTodaySpec.isSatisfiedBy(customer13));
846
847 customer12.clearOrders();
848 customer13.clearOrders();
849 }
850
851
852 public void testCollectionSpecificationIncludeAPercentageOf() {
853 customer12.addOrder(order22);
854 customer13.addOrder(order23);
855 customer13.addOrder(order24);
856
857 Specification<Order> ordersFromToday = an(Order.class).where("orderDate", isAtTheSameTimeAs(today));
858
859 Specification<Customer> customersWithAtMost5PercentOfOrdersAreFromTodaySpec =
860 createSpecificationFor(Customer.class).where("orders", includeAPercentageOf(atMost(5), ordersFromToday));
861 assertTrue(customersWithAtMost5PercentOfOrdersAreFromTodaySpec.isSatisfiedBy(customer12));
862 assertFalse(customersWithAtMost5PercentOfOrdersAreFromTodaySpec.isSatisfiedBy(customer13));
863
864 Specification<Customer> customersWithMoreThan90PercentOfOrdersAreFromTodaySpec =
865 createSpecificationFor(Customer.class).where("orders", includeAPercentageOf(atLeast(90), ordersFromToday));
866 assertFalse(customersWithMoreThan90PercentOfOrdersAreFromTodaySpec.isSatisfiedBy(customer12));
867 assertTrue(customersWithMoreThan90PercentOfOrdersAreFromTodaySpec.isSatisfiedBy(customer13));
868
869 customer12.clearOrders();
870 customer13.clearOrders();
871 }
872
873
874 public void testCompositeCollectionSpecification() {
875 customer12.addOrder(order22);
876 customer13.addOrder(order23);
877 customer13.addOrder(order24);
878
879 Specification<Order> ordersFromAfterTwoDaysAgo = all(Order.class).where("orderDate", isAfter(twoDaysAgo));
880
881 Specification<Customer> customersWithMoreThanOneOrder =
882 createSpecificationFor(Customer.class).where("orders", haveSize(greaterThan(1)));
883 assertFalse(customersWithMoreThanOneOrder.isSatisfiedBy(customer12));
884 assertTrue(customersWithMoreThanOneOrder.isSatisfiedBy(customer13));
885
886 Specification<Customer> customersWithAtLeastOneOrderMoreRecentThanTwoDaysAgo = createSpecificationFor(Customer.class)
887 .where("orders", include(atLeast(1), ordersFromAfterTwoDaysAgo));
888 assertTrue(customersWithAtLeastOneOrderMoreRecentThanTwoDaysAgo.isSatisfiedBy(customer12));
889 assertTrue(customersWithAtLeastOneOrderMoreRecentThanTwoDaysAgo.isSatisfiedBy(customer13));
890
891 Specification<Customer> customersWithAtLeastTwoOrdersMoreRecentThanTwoDaysAgo = createSpecificationFor(Customer.class)
892 .where("orders", haveSize(greaterThan(1)))
893 .and("orders", include(atLeast(2), ordersFromAfterTwoDaysAgo));
894 assertFalse(customersWithAtLeastTwoOrdersMoreRecentThanTwoDaysAgo.isSatisfiedBy(customer12));
895 assertTrue(customersWithAtLeastTwoOrdersMoreRecentThanTwoDaysAgo.isSatisfiedBy(customer13));
896
897 customer12.clearOrders();
898 customer13.clearOrders();
899 }
900
901
902 public void testDirectDateStringSpecifications() {
903 String errorMsg = " is not recognized as a valid date string -" +
904 " use a method with java.util.Date as parameter type to see whether the provided date parameter is actually illegal," +
905 " or expressed in a not-supported format";
906 try {
907 before("20077-10-10");
908 fail("Should have thrown exception");
909
910 } catch (IllegalArgumentException e) {
911 String expectedMessage = "\"20077-10-10\"" + errorMsg;
912 assertEquals(expectedMessage, e.getMessage());
913 }
914 try {
915 before("10252007");
916 fail("Should have thrown exception");
917
918 } catch (IllegalArgumentException e) {
919 String expectedMessage = "\"10252007\"" + errorMsg;
920 assertEquals(expectedMessage, e.getMessage());
921 }
922 try {
923 before("10.25.2007");
924 fail("Should have thrown exception");
925
926 } catch (IllegalArgumentException e) {
927 String expectedMessage = "\"10.25.2007\"" + errorMsg;
928 assertEquals(expectedMessage, e.getMessage());
929 }
930 try {
931 before("10-25-2007");
932 fail("Should have thrown exception");
933
934 } catch (IllegalArgumentException e) {
935 String expectedMessage = "\"10-25-2007\"" + errorMsg;
936 assertEquals(expectedMessage, e.getMessage());
937 }
938 Calendar cal = Calendar.getInstance();
939 cal.set(2007, Calendar.OCTOBER, 25, 0, 0, 0);
940 long milliSec = cal.getTime().getTime();
941 milliSec = milliSec / 1000 * 1000;
942 Date startOf25Oct2007 = new Date(milliSec);
943 Specification<Date> expectedSpec = before(startOf25Oct2007);
944
945 Specification<Date> spec = before("20071025");
946 assertEquals(expectedSpec, spec);
947
948 spec = before("2007.10.25");
949 assertEquals(expectedSpec, spec);
950
951 spec = before("25.10.2007");
952 assertEquals(expectedSpec, spec);
953
954 spec = before("2007-10-25");
955 assertEquals(expectedSpec, spec);
956
957 spec = before("25-10-2007");
958 assertEquals(expectedSpec, spec);
959
960 spec = before("2007/10/25");
961 assertEquals(expectedSpec, spec);
962
963 spec = before("25/10/2007");
964 assertEquals(expectedSpec, spec);
965 }
966
967
968
969
970
971
972
973
974 public void testShouldNotAcceptWhereClauseMoreThanOnce() {
975 try {
976 CompositeSpecification<Order> orderSpec = createSpecificationFor(Order.class).where("orderId", isEqualTo(23L));
977 orderSpec.where(null, null);
978 fail("Should have thrown exception");
979
980 } catch (UnsupportedOperationException e) {
981 String expectedMessage = "The \"where\" clause can only be invoked once in specification expressions";
982 assertEquals(expectedMessage, e.getMessage());
983 }
984 }
985
986
987 public void testShouldNotAcceptAndOrAsFirstParameterizedClause() {
988 try {
989 createSpecificationFor(Order.class).and("orderId", isEqualTo(23L));
990 fail("Should have thrown exception");
991
992 } catch (UnsupportedOperationException e) {
993 String expectedMessage = "The \"where\" clause must be invoked before \"and\"/\"or\" in parameterized specification expressions";
994 assertEquals(expectedMessage, e.getMessage());
995 }
996 try {
997 createSpecificationFor(Order.class).or("orderId", isEqualTo(23L));
998 fail("Should have thrown exception");
999
1000 } catch (UnsupportedOperationException e) {
1001 String expectedMessage = "The \"where\" clause must be invoked before \"and\"/\"or\" in parameterized specification expressions";
1002 assertEquals(expectedMessage, e.getMessage());
1003 }
1004 }
1005
1006
1007 public void testShouldNotAcceptNullAsAccessibleObjectNameArgument() {
1008 try {
1009 createSpecificationFor(Order.class).where(null, null);
1010 fail("Should have thrown exception");
1011
1012 } catch (IllegalArgumentException e) {
1013 String expectedMessage = "Accessible object name parameter cannot be null";
1014 assertEquals(expectedMessage, e.getMessage());
1015 }
1016 }
1017
1018
1019 public void testShouldNotAcceptBlankAccessibleObjectNameArgument() {
1020 try {
1021 createSpecificationFor(Order.class).where("", isEqualTo(42L));
1022 fail("Should have thrown exception");
1023
1024 } catch (IllegalArgumentException e) {
1025 String expectedMessage = "Accessible object name parameter \"\" is neither a valid method name, nor a valid field name";
1026 assertEquals(expectedMessage, e.getMessage());
1027 }
1028 try {
1029 createSpecificationFor(Order.class).where(" ", null);
1030 fail("Should have thrown exception");
1031
1032 } catch (IllegalArgumentException e) {
1033 String expectedMessage = "Accessible object name parameter \" \" is neither a valid method name, nor a valid field name";
1034 assertEquals(expectedMessage, e.getMessage());
1035 }
1036 }
1037
1038
1039 public void testShouldNotAcceptIllegalAccessibleObjectName() {
1040 try {
1041 createSpecificationFor(Order.class).where("nonExistingAccessibleObject", isEqualTo(23L));
1042 fail("Should have thrown exception");
1043
1044 } catch (IllegalArgumentException e) {
1045 String expectedMessage = "Neither a field nor a method (with no formal parameters) named \"nonExistingAccessibleObject\" found in class net.sourceforge.domian.test.domain.Order";
1046 assertEquals(expectedMessage, e.getMessage());
1047 }
1048 }
1049
1050
1051 public void testShouldNotAcceptTypeMismatchBetweenFieldAndValueBoundedSpecification_1() {
1052 Specification<Customer> customersWhoHasBeenMembersForTwoDaysOrMore =
1053 specify(Customer.class).where("membershipDate", isBeforeOrAtTheSameTimeAs(twoDaysAgo));
1054 try {
1055 createSpecificationFor(Order.class)
1056 .where("customer", isSatisfiedBy(customersWhoHasBeenMembersForTwoDaysOrMore))
1057 .and("customer", isAfter(today));
1058 fail("Should have thrown exception");
1059
1060 } catch (IllegalArgumentException e) {
1061 String expectedMessage = "Field \"customer\" of type net.sourceforge.domian.test.domain.Customer [in class net.sourceforge.domian.test.domain.Order], cannot be specified by a Specification<java.util.Date>";
1062 assertEquals(expectedMessage, e.getMessage());
1063 }
1064 }
1065
1066
1067 public void testShouldNotAcceptTypeMismatchBetweenFieldAndValueBoundedSpecification_2() {
1068 Specification<Date> today = createEqualSpecification(Testdata.today);
1069 Specification<Date> tomorrow = createEqualSpecification(Testdata.tomorrow);
1070
1071 try {
1072 createSpecificationFor(Order.class).where("orderId", isEither(today, tomorrow));
1073 fail("Should have thrown exception");
1074
1075 } catch (IllegalArgumentException e) {
1076 String expectedMessage = "Field \"orderId\" of type java.lang.Long [in class net.sourceforge.domian.test.domain.Order], cannot be specified by a Specification<java.util.Date>";
1077 assertEquals(expectedMessage, e.getMessage());
1078 }
1079
1080
1081
1082
1083 }
1084
1085
1086 public void testShouldNotAcceptNullOrEmptySpecificationVarargs() {
1087
1088 try {
1089 allOf((Specification) null);
1090 fail("Should have thrown exception");
1091
1092 } catch (Exception e) {
1093 String expectedMessage = "Specification varargs cannot be null";
1094 assertEquals(expectedMessage, e.getMessage());
1095 }
1096
1097 try {
1098 allOf((Specification[]) null);
1099 fail("Should have thrown exception");
1100
1101 } catch (Exception e) {
1102 String expectedMessage = "Specification varargs cannot be null";
1103 assertEquals(expectedMessage, e.getMessage());
1104 }
1105
1106 try {
1107 allOf((Specification[]) new Specification[]{});
1108 fail("Should have thrown exception");
1109
1110 } catch (Exception e) {
1111 String expectedMessage = "Specification varargs cannot be empty";
1112 assertEquals(expectedMessage, e.getMessage());
1113 }
1114
1115 allOf((Specification[]) new Specification[]{createNotNullSpecification(Object.class)});
1116
1117
1118 try {
1119 anyOf((Specification) null);
1120 fail("Should have thrown exception");
1121
1122 } catch (Exception e) {
1123 String expectedMessage = "Specification varargs cannot be null";
1124 assertEquals(expectedMessage, e.getMessage());
1125 }
1126
1127 try {
1128 anyOf((Specification[]) null);
1129 fail("Should have thrown exception");
1130
1131 } catch (Exception e) {
1132 String expectedMessage = "Specification varargs cannot be null";
1133 assertEquals(expectedMessage, e.getMessage());
1134 }
1135
1136 try {
1137 anyOf((Specification[]) new Specification[]{});
1138 fail("Should have thrown exception");
1139
1140 } catch (Exception e) {
1141 String expectedMessage = "Specification varargs cannot be empty";
1142 assertEquals(expectedMessage, e.getMessage());
1143 }
1144
1145
1146 try {
1147 neitherOf((Specification) null);
1148 fail("Should have thrown exception");
1149
1150 } catch (Exception e) {
1151 String expectedMessage = "Specification varargs cannot be null";
1152 assertEquals(expectedMessage, e.getMessage());
1153 }
1154
1155 try {
1156 neitherOf((Specification[]) null);
1157 fail("Should have thrown exception");
1158
1159 } catch (Exception e) {
1160 String expectedMessage = "Specification varargs cannot be null";
1161 assertEquals(expectedMessage, e.getMessage());
1162 }
1163
1164 try {
1165 neitherOf((Specification[]) new Specification[]{});
1166 fail("Should have thrown exception");
1167
1168 } catch (Exception e) {
1169 String expectedMessage = "Specification varargs cannot be empty";
1170 assertEquals(expectedMessage, e.getMessage());
1171 }
1172
1173 anyOf((Specification[]) new Specification[]{createNotNullSpecification(Object.class)});
1174 }
1175
1176
1177 public void testCollectionWithNonCollectionTypeField() {
1178 try {
1179 createSpecificationFor(Customer.class).where("membershipDate", haveSize(greaterThan(1), Long.class));
1180 fail("Should have thrown exception");
1181
1182 } catch (Exception e) {
1183 String expectedMessage = "Field \"membershipDate\" of type java.util.Date [in class net.sourceforge.domian.test.domain.Customer], cannot be specified by a net.sourceforge.domian.specification.CollectionSpecification";
1184 assertEquals(expectedMessage, e.getMessage());
1185 }
1186
1187 createSpecificationFor(TestClass.class).where("rawHashSetField", haveSize(greaterThan(8)));
1188 createSpecificationFor(TestClass.class).where("rawLinkedListField", haveSize(greaterThan(8)));
1189 createSpecificationFor(TestClass.class).where("rawConcurrentLinkedQueueField", haveSize(greaterThan(8)));
1190 createSpecificationFor(TestClass.class).where("rawSubClassedTreeSetField", haveSize(greaterThan(8)));
1191 createSpecificationFor(TestClass.class).where("hashSetField", haveSize(greaterThan(8)));
1192 createSpecificationFor(TestClass.class).where("linkedListField", haveSize(greaterThan(8)));
1193 createSpecificationFor(TestClass.class).where("concurrentLinkedQueueField", haveSize(greaterThan(8)));
1194 createSpecificationFor(TestClass.class).where("subClassedTreeSetField", haveSize(greaterThan(8)));
1195
1196 try {
1197 createSpecificationFor(TestClass.class).where("rawHashMapField", haveSize(greaterThan(8)));
1198 fail("Should have thrown exception");
1199
1200 } catch (Exception e) {
1201 String expectedMessage = "Field \"rawHashMapField\" of type java.util.Map [in class net.sourceforge.domian.specification.client.SpecificationFactoryTest$TestClass], cannot be specified by a net.sourceforge.domian.specification.CollectionSpecification";
1202 assertEquals(expectedMessage, e.getMessage());
1203 }
1204 try {
1205 createSpecificationFor(TestClass.class).where("hashMapField", haveSize(greaterThan(8)));
1206 fail("Should have thrown exception");
1207
1208 } catch (Exception e) {
1209 String expectedMessage = "Field \"hashMapField\" of type java.util.Map [in class net.sourceforge.domian.specification.client.SpecificationFactoryTest$TestClass], cannot be specified by a net.sourceforge.domian.specification.CollectionSpecification";
1210 assertEquals(expectedMessage, e.getMessage());
1211 }
1212 }
1213
1214
1215 public void testCannotCreateConjunctionOutOfDisjointSpecifications() {
1216 CompositeSpecification<Customer> customers = allInstancesOfType(Customer.class);
1217 try {
1218 customers.and(not(customers));
1219 fail("Should have thrown exception");
1220
1221 } catch (IllegalArgumentException e) {
1222 String expectedMessage = "Cannot create a conjunction out of two disjoint specifications";
1223 assertEquals(expectedMessage, e.getMessage());
1224 }
1225
1226 try {
1227 not(customers).and(customers);
1228 fail("Should have thrown exception");
1229
1230 } catch (IllegalArgumentException e) {
1231 String expectedMessage = "Cannot create a conjunction out of two disjoint specifications";
1232 assertEquals(expectedMessage, e.getMessage());
1233 }
1234
1235 try {
1236 CompositeSpecification<Customer> notCustomer = (CompositeSpecification<Customer>) not(customers);
1237 Specification<Customer> customersNotNamedTommy = all(Customer.class).where("name", is(not("Tommy")));
1238 notCustomer.and(customersNotNamedTommy);
1239 fail("Should have thrown exception");
1240
1241 } catch (IllegalArgumentException e) {
1242 String expectedMessage = "Cannot create a conjunction out of two disjoint specifications";
1243 assertEquals(expectedMessage, e.getMessage());
1244 }
1245
1246 try {
1247 CompositeSpecification<Customer> notCustomer = (CompositeSpecification<Customer>) not(customers);
1248 CompositeSpecification<Customer> customersNotNamedTommy = all(Customer.class).where("name", is(not("Tommy")));
1249 customersNotNamedTommy.and(notCustomer);
1250 fail("Should have thrown exception");
1251
1252 } catch (IllegalArgumentException e) {
1253 String expectedMessage = "Cannot create a conjunction out of two disjoint specifications";
1254 assertEquals(expectedMessage, e.getMessage());
1255 }
1256
1257
1258 Specification<Customer> customersNamedJohnny = all(Customer.class).where("name", is("Johnny"));
1259 Specification<Customer> customersNotNamedJohnny = not(customersNamedJohnny);
1260 Specification<Customer> customersNotNamedTommy = all(Customer.class).where("name", is(not("Tommy")));
1261 customersNotNamedTommy.and(customersNotNamedJohnny);
1262 }
1263
1264
1265 public void testShouldNotApproveOfWhereClauseFromLeafSpecification() {
1266 try {
1267 Specification<Integer> greaterThan12 = greaterThan(12).where("value", is(not(equalTo(12))));
1268 assertTrue(greaterThan12.isSatisfiedBy(13));
1269 assertFalse(greaterThan12.isSatisfiedBy(12));
1270
1271 } catch (UnsupportedOperationException e) {
1272 String expectedMessage = "'where' clause is applicable only for CompositeSpecification instances";
1273 assertEquals(expectedMessage, e.getMessage());
1274 }
1275 }
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285 public void testShouldHandleReadyMadeFieldParametersAsWell() {}
1286
1287
1288
1289
1290
1291
1292
1293
1294 class TestClass {
1295 Collection rawHashSetField = new HashSet();
1296 Collection rawLinkedListField = new LinkedList();
1297 Collection rawConcurrentLinkedQueueField = new ConcurrentLinkedQueue();
1298 Collection rawSubClassedTreeSetField = new TreeSet() {
1299
1300 };
1301 Map rawHashMapField = new HashMap();
1302 Collection hashSetField = new HashSet<Integer>();
1303 Collection linkedListField = new LinkedList<String>();
1304 Collection concurrentLinkedQueueField = new ConcurrentLinkedQueue<OrderLine>();
1305 Collection subClassedTreeSetField = new TreeSet<Collection<Customer>>() {
1306
1307 };
1308 Map hashMapField = new HashMap<Integer, Collection>();
1309 }
1310 }