1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sourceforge.domian.specification;
17
18
19 import java.util.Date;
20
21 import org.junit.Test;
22
23 import net.sourceforge.domian.entity.Entity;
24 import net.sourceforge.domian.test.domain.Customer;
25 import net.sourceforge.domian.test.domain.Order;
26 import net.sourceforge.domian.test.domain.VipCustomer;
27
28 import static net.sourceforge.domian.specification.CollectionSpecification.CollectionSpecificationScope.SIZE;
29 import static net.sourceforge.domian.specification.ParameterizedSpecification.createParameterizedSpecification;
30 import static net.sourceforge.domian.specification.SpecificationFactory.all;
31 import static net.sourceforge.domian.specification.SpecificationFactory.allInstancesOfType;
32 import static net.sourceforge.domian.specification.SpecificationFactory.allObjects;
33 import static net.sourceforge.domian.specification.SpecificationFactory.before;
34 import static net.sourceforge.domian.specification.SpecificationFactory.equalTo;
35 import static net.sourceforge.domian.specification.SpecificationFactory.exactly;
36 import static net.sourceforge.domian.specification.SpecificationFactory.greaterThanOrEqualTo;
37 import static net.sourceforge.domian.specification.SpecificationFactory.is;
38 import static net.sourceforge.domian.specification.SpecificationFactory.isAfter;
39 import static net.sourceforge.domian.specification.SpecificationFactory.isAfterOrAtTheSameTimeAs;
40 import static net.sourceforge.domian.specification.SpecificationFactory.isAtTheSameTimeAs;
41 import static net.sourceforge.domian.specification.SpecificationFactory.isBefore;
42 import static net.sourceforge.domian.specification.SpecificationFactory.isEqualTo;
43 import static net.sourceforge.domian.specification.SpecificationFactory.isGreaterThanOrEqualTo;
44 import static net.sourceforge.domian.specification.SpecificationFactory.lessThan;
45 import static net.sourceforge.domian.specification.SpecificationFactory.not;
46 import static net.sourceforge.domian.test.domain.Customer.Gender;
47 import static net.sourceforge.domian.test.domain.Customer.Gender.FEMALE;
48 import static net.sourceforge.domian.test.domain.Customer.Gender.MALE;
49 import static net.sourceforge.domian.test.domain.Testdata.today;
50 import static net.sourceforge.domian.test.domain.Testdata.tomorrow;
51 import static net.sourceforge.domian.test.domain.Testdata.twoDaysAgo;
52 import static net.sourceforge.domian.test.domain.Testdata.yesterday;
53 import static net.sourceforge.domian.util.DateUtils.getTime;
54 import static org.junit.Assert.assertEquals;
55 import static org.junit.Assert.assertFalse;
56 import static org.junit.Assert.assertTrue;
57 import static org.junit.Assert.fail;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 public class SubsumptionTest {
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 public static void assertLemma1(final CompositeSpecification specA,
117 final CompositeSpecification specB) {
118 Specification combinedSpec;
119
120 combinedSpec = specA.and(specB);
121 assertTrue(combinedSpec.isSpecialCaseOf(specA));
122 assertTrue(combinedSpec.isSpecialCaseOf(specB));
123 combinedSpec = specA.or(specB);
124 assertTrue(combinedSpec.isGeneralizationOf(specA));
125 assertTrue(combinedSpec.isGeneralizationOf(specB));
126
127 combinedSpec = specB.and(specA);
128 assertTrue(combinedSpec.isSpecialCaseOf(specA));
129 assertTrue(combinedSpec.isSpecialCaseOf(specB));
130 combinedSpec = specB.or(specA);
131 assertTrue(combinedSpec.isGeneralizationOf(specA));
132 assertTrue(combinedSpec.isGeneralizationOf(specB));
133 }
134
135
136
137
138
139
140
141
142
143
144
145
146 public static void assertLemma1_DisjunctionOnly(final CompositeSpecification specA,
147 final CompositeSpecification specB) {
148 Specification combinedSpec;
149 combinedSpec = specA.or(specB);
150 assertTrue(combinedSpec.isGeneralizationOf(specA));
151 assertTrue(combinedSpec.isGeneralizationOf(specB));
152
153 combinedSpec = specB.or(specA);
154 assertTrue(combinedSpec.isGeneralizationOf(specA));
155 assertTrue(combinedSpec.isGeneralizationOf(specB));
156 }
157
158
159
160
161
162
163
164
165
166 public static <T> boolean assertLemma2(final Specification<T> specA,
167 final Specification<T> specB,
168 final T candidateObject) {
169 if (specA.isSatisfiedBy(candidateObject) && specB.isGeneralizationOf(specA)) {
170 return specB.isSatisfiedBy(candidateObject);
171 }
172 if (specB.isSatisfiedBy(candidateObject) && specA.isGeneralizationOf(specB)) {
173 return specA.isSatisfiedBy(candidateObject);
174 }
175
176 if (specA.isSatisfiedBy(candidateObject) && !(specB.isSatisfiedBy(candidateObject))) {
177 return !(specB.isGeneralizationOf(specA));
178 }
179 if (specB.isSatisfiedBy(candidateObject) && !(specA.isSatisfiedBy(candidateObject))) {
180 return !(specA.isGeneralizationOf(specB));
181 }
182 return true;
183 }
184
185
186
187
188
189 @Test
190 public void shouldNotAcceptNull() {
191 try {
192 equalTo(101L).isGeneralizationOf(null);
193 fail("Should have thrown exception");
194
195 } catch (IllegalArgumentException e) {
196 String expectedMessage = "Specification parameter cannot be null";
197 String actualMessage = e.getMessage();
198 assertEquals(expectedMessage, actualMessage);
199 }
200 }
201
202
203 @Test
204 public void shouldBeReflexive() {
205 Specification rawDateSpec = equalTo(tomorrow);
206 Specification anotherRawDateSpec = equalTo(tomorrow);
207 assertTrue(rawDateSpec.isGeneralizationOf(rawDateSpec));
208 assertTrue(rawDateSpec.isGeneralizationOf(anotherRawDateSpec));
209
210 Specification<Integer> numberSpec = equalTo(42);
211 Specification rawNumberSpec = equalTo(42);
212 assertTrue(numberSpec.isGeneralizationOf(numberSpec));
213 assertTrue(numberSpec.isGeneralizationOf(rawNumberSpec));
214 }
215
216
217 @Test
218 public void shouldNotAcceptSpecificationOfDifferentType() {
219 Specification rawDateSpec = equalTo(new Date());
220 Specification rawNumberSpec = equalTo(42);
221 Specification rawCustomerSpec = all(Customer.class);
222
223 assertFalse(rawDateSpec.isGeneralizationOf(rawNumberSpec));
224 assertFalse(rawNumberSpec.isGeneralizationOf(rawDateSpec));
225 assertFalse(rawDateSpec.isGeneralizationOf(rawCustomerSpec));
226 assertFalse(rawNumberSpec.isGeneralizationOf(rawCustomerSpec));
227 }
228
229
230 @Test
231 public void valueBoundSpecificationCannotBeGeneralizationOfEachOther() {
232 Specification<Date> todaySpec = equalTo(today);
233 Specification<Date> yesterdaySpec = equalTo(yesterday);
234
235 assertFalse(todaySpec.isGeneralizationOf(yesterdaySpec));
236 assertFalse(yesterdaySpec.isGeneralizationOf(todaySpec));
237
238 Specification<Integer> lessThan10 = lessThan(10);
239 Specification<Integer> greaterThanOrEqualTo1000 = greaterThanOrEqualTo(1000);
240
241 assertFalse(lessThan10.isGeneralizationOf(greaterThanOrEqualTo1000));
242 assertFalse(greaterThanOrEqualTo1000.isGeneralizationOf(lessThan10));
243 }
244
245
246 @Test
247 public void checkRestOfValueBoundSpecifications() {
248 Specification<Date> todaySpec = equalTo(today);
249
250
251 Specification notNullSpec = new NotNullSpecification(Object.class);
252 assertTrue(notNullSpec.isGeneralizationOf(notNullSpec));
253 assertTrue(notNullSpec.isGeneralizationOf(todaySpec));
254
255
256 Specification<String> blankStringSpec = new DefaultValueSpecification<String>(String.class);
257 assertTrue(blankStringSpec.isGeneralizationOf(blankStringSpec));
258 assertFalse(blankStringSpec.isGeneralizationOf(exactly("Vienna")));
259
260 Specification dateStringSpec = new DateStringSpecification("20070919");
261 assertTrue(dateStringSpec.isGeneralizationOf(dateStringSpec));
262 assertFalse(dateStringSpec.isGeneralizationOf(todaySpec));
263
264 Specification enumNameStringSpec = new EnumNameStringSpecification(Gender.class);
265 assertTrue(enumNameStringSpec.isGeneralizationOf(enumNameStringSpec));
266 assertFalse(enumNameStringSpec.isGeneralizationOf(todaySpec));
267
268 Specification regularExpressionMatcherStringSpec = new RegularExpressionMatcherStringSpecification("[^abc]");
269 assertTrue(regularExpressionMatcherStringSpec.isGeneralizationOf(regularExpressionMatcherStringSpec));
270 assertFalse(regularExpressionMatcherStringSpec.isGeneralizationOf(todaySpec));
271
272 Specification wildcardExpressionMatcherStringSpec = new WildcardExpressionMatcherStringSpecification("j?h*y");
273 assertTrue(wildcardExpressionMatcherStringSpec.isGeneralizationOf(wildcardExpressionMatcherStringSpec));
274 assertFalse(wildcardExpressionMatcherStringSpec.isGeneralizationOf(todaySpec));
275
276 Specification wildcardExpressionMatcherIgnoreCaseStringSpec = new WildcardExpressionMatcherIgnoreCaseStringSpecification("j?h*y");
277 assertTrue(wildcardExpressionMatcherIgnoreCaseStringSpec.isGeneralizationOf(wildcardExpressionMatcherIgnoreCaseStringSpec));
278 assertFalse(wildcardExpressionMatcherIgnoreCaseStringSpec.isGeneralizationOf(todaySpec));
279
280 Specification parameterizedSpec = createParameterizedSpecification(Order.class, "orderId", new NotNullSpecification(Long.class));
281 assertTrue(parameterizedSpec.isGeneralizationOf(parameterizedSpec));
282 assertFalse(parameterizedSpec.isGeneralizationOf(todaySpec));
283
284 Specification collectionSpec = new CollectionSpecification(SIZE, isGreaterThanOrEqualTo(42));
285 assertTrue(collectionSpec.isGeneralizationOf(collectionSpec));
286 assertFalse(collectionSpec.isGeneralizationOf(todaySpec));
287 }
288
289
290
291
292
293 @Test
294 public void shouldNotAcceptNull_specialCaseOf() {
295 try {
296 equalTo(101L).isSpecialCaseOf(null);
297 fail("Should have thrown exception");
298
299 } catch (IllegalArgumentException e) {
300 String expectedMessage = "Specification parameter cannot be null";
301 String actualMessage = e.getMessage();
302 assertEquals(expectedMessage, actualMessage);
303 }
304 }
305
306
307 @Test
308 public void shouldBeReflexive_specialCaseOf() {
309 Date date = getTime(2008);
310 Specification rawDateSpec = equalTo(date);
311 Specification anotherRawDateSpec = equalTo(date);
312 assertTrue(rawDateSpec.isSpecialCaseOf(rawDateSpec));
313 assertTrue(rawDateSpec.isSpecialCaseOf(anotherRawDateSpec));
314
315 Specification<Integer> numberSpec = equalTo(42);
316 Specification rawNumberSpec = equalTo(42);
317 assertTrue(numberSpec.isSpecialCaseOf(numberSpec));
318 assertTrue(numberSpec.isSpecialCaseOf(rawNumberSpec));
319 }
320
321
322 @Test
323 public void shouldNotAcceptSpecificationOfDifferentType_specialCaseOf() {
324 Specification rawDateSpec = equalTo(new Date());
325 Specification rawNumberSpec = equalTo(42);
326 Specification rawCustomerSpec = all(Customer.class);
327
328 assertFalse(rawDateSpec.isSpecialCaseOf(rawNumberSpec));
329 assertFalse(rawNumberSpec.isSpecialCaseOf(rawDateSpec));
330 assertFalse(rawDateSpec.isSpecialCaseOf(rawCustomerSpec));
331 assertFalse(rawNumberSpec.isSpecialCaseOf(rawCustomerSpec));
332 }
333
334
335 @Test
336 public void valueBoundSpecificationJustCannotBeSpecialCasesOfEachOther_specialCaseOf() {
337 Specification<Date> todaySpec = equalTo(today);
338 Specification<Date> yesterdaySpec = equalTo(yesterday);
339
340 assertFalse(todaySpec.isSpecialCaseOf(yesterdaySpec));
341 assertFalse(yesterdaySpec.isSpecialCaseOf(todaySpec));
342
343 Specification<Integer> lessThan10 = lessThan(10);
344 Specification<Integer> greaterThanOrEqualTo1000 = greaterThanOrEqualTo(1000);
345
346 assertFalse(lessThan10.isSpecialCaseOf(greaterThanOrEqualTo1000));
347 assertFalse(greaterThanOrEqualTo1000.isSpecialCaseOf(lessThan10));
348 }
349
350
351 @Test
352 public void checkRestOfValueBoundSpecifications_specialCaseOf() {
353 Specification<Date> todaySpec = equalTo(today);
354
355 Specification notNullSpec = new NotNullSpecification(Object.class);
356 assertTrue(notNullSpec.isSpecialCaseOf(notNullSpec));
357 assertFalse(notNullSpec.isSpecialCaseOf(todaySpec));
358
359 Specification<String> blankStringSpec = new DefaultValueSpecification<String>(String.class);
360 assertTrue(blankStringSpec.isSpecialCaseOf(blankStringSpec));
361 assertFalse(blankStringSpec.isSpecialCaseOf(exactly("Vienna")));
362
363 Specification dateStringSpec = new DateStringSpecification("20070919");
364 assertTrue(dateStringSpec.isSpecialCaseOf(dateStringSpec));
365 assertFalse(dateStringSpec.isSpecialCaseOf(todaySpec));
366
367 Specification enumNameStringSpec = new EnumNameStringSpecification(Gender.class);
368 assertTrue(enumNameStringSpec.isSpecialCaseOf(enumNameStringSpec));
369 assertFalse(enumNameStringSpec.isSpecialCaseOf(todaySpec));
370
371 Specification regularExpressionMatcherStringSpec = new RegularExpressionMatcherStringSpecification("[^abc]");
372 assertTrue(regularExpressionMatcherStringSpec.isSpecialCaseOf(regularExpressionMatcherStringSpec));
373 assertFalse(regularExpressionMatcherStringSpec.isSpecialCaseOf(todaySpec));
374
375 Specification wildcardExpressionMatcherStringSpec = new WildcardExpressionMatcherStringSpecification("j?h*y");
376 assertTrue(wildcardExpressionMatcherStringSpec.isSpecialCaseOf(wildcardExpressionMatcherStringSpec));
377 assertFalse(wildcardExpressionMatcherStringSpec.isSpecialCaseOf(todaySpec));
378
379 Specification wildcardExpressionMatcherIgnoreCaseStringSpec = new WildcardExpressionMatcherIgnoreCaseStringSpecification("j?h*y");
380 assertTrue(wildcardExpressionMatcherIgnoreCaseStringSpec.isSpecialCaseOf(wildcardExpressionMatcherIgnoreCaseStringSpec));
381 assertFalse(wildcardExpressionMatcherIgnoreCaseStringSpec.isSpecialCaseOf(todaySpec));
382
383 Specification parameterizedSpec = createParameterizedSpecification(Order.class, "orderId", new NotNullSpecification(Long.class));
384 assertTrue(parameterizedSpec.isSpecialCaseOf(parameterizedSpec));
385 assertFalse(parameterizedSpec.isSpecialCaseOf(todaySpec));
386
387 Specification collectionSpec = new CollectionSpecification(SIZE, isGreaterThanOrEqualTo(42));
388 assertTrue(collectionSpec.isSpecialCaseOf(collectionSpec));
389 assertFalse(collectionSpec.isSpecialCaseOf(todaySpec));
390 }
391
392
393
394
395
396 @Test
397 public void shouldNotAcceptNull_compositeSpecification() {
398 try {
399 all(Customer.class).isGeneralizationOf(null);
400 fail("Should have thrown exception");
401
402 } catch (IllegalArgumentException e) {
403 String expectedMessage = "Specification parameter cannot be null";
404 String actualMessage = e.getMessage();
405 assertEquals(expectedMessage, actualMessage);
406 }
407 try {
408 all(Customer.class).isSpecialCaseOf(null);
409 fail("Should have thrown exception");
410
411 } catch (IllegalArgumentException e) {
412 String expectedMessage = "Specification parameter cannot be null";
413 String actualMessage = e.getMessage();
414 assertEquals(expectedMessage, actualMessage);
415 }
416 }
417
418
419 @Test
420 public void basicLemma4Stuff() {
421 CompositeSpecification<Customer> customerSpec1 = all(Customer.class).where("name", is("Tommy"));
422 CompositeSpecification<Customer> customerSpec2 = all(Customer.class).where("membershipDate", isBefore(yesterday));
423 assertLemma1(customerSpec1, customerSpec2);
424 customerSpec1 = all(Customer.class).where("name", is("Tommy")).or("name", is("Johnny"));
425 customerSpec2 = all(Customer.class).where("membershipDate", isBefore(yesterday)).or("name", is("Johnny"));
426 assertLemma1(customerSpec1, customerSpec2);
427 }
428
429
430 @Test
431 public void shouldBeReflexive_compositeSpecification() {
432 Specification<Integer> integerSpec = all(Integer.class);
433 Specification rawIntegerSpec = all(Integer.class);
434 assertTrue(integerSpec.isGeneralizationOf(integerSpec));
435 assertTrue(integerSpec.isGeneralizationOf(rawIntegerSpec));
436 assertTrue(integerSpec.isSpecialCaseOf(integerSpec));
437 assertTrue(integerSpec.isSpecialCaseOf(rawIntegerSpec));
438 assertLemma1((CompositeSpecification) integerSpec, (CompositeSpecification) rawIntegerSpec);
439
440 Specification rawCustomerSpec = all(Customer.class).where("name", isEqualTo("Tommy"));
441 Specification anotherRawCustomerSpec = all(Customer.class).where("name", isEqualTo("Tommy"));
442 assertTrue(rawCustomerSpec.isGeneralizationOf(rawCustomerSpec));
443 assertTrue(rawCustomerSpec.isGeneralizationOf(anotherRawCustomerSpec));
444 assertTrue(rawCustomerSpec.isSpecialCaseOf(rawCustomerSpec));
445 assertTrue(rawCustomerSpec.isSpecialCaseOf(anotherRawCustomerSpec));
446 assertLemma1((CompositeSpecification) rawCustomerSpec, (CompositeSpecification) anotherRawCustomerSpec);
447
448 Specification customerSpec = all(Customer.class).where("name", isEqualTo("Tommy"));
449 Specification anotherCustomerSpec = all(Customer.class).where("name", isEqualTo("Tommy"));
450 assertTrue(customerSpec.isGeneralizationOf(customerSpec));
451 assertTrue(customerSpec.isGeneralizationOf(anotherCustomerSpec));
452 assertTrue(customerSpec.isSpecialCaseOf(customerSpec));
453 assertTrue(customerSpec.isSpecialCaseOf(anotherCustomerSpec));
454 assertLemma1((CompositeSpecification) customerSpec, (CompositeSpecification) anotherCustomerSpec);
455 }
456
457
458 @Test
459 public void notNullSpecificationShouldBeOnTopOfEverything() {
460 assertTrue(new NotNullSpecification(Object.class).isGeneralizationOf(new NotNullSpecification(Object.class)));
461 assertTrue(new NotNullSpecification(Object.class).isSpecialCaseOf(new NotNullSpecification(Object.class)));
462
463 assertTrue(new NotNullSpecification(Order.class).isGeneralizationOf(all(Order.class)));
464 assertFalse(new NotNullSpecification(Order.class).isSpecialCaseOf(all(Order.class)));
465
466 assertTrue(new NotNullSpecification(Object.class).isGeneralizationOf(isEqualTo(1)));
467 assertFalse(new NotNullSpecification(Date.class).isSpecialCaseOf(isAfter(new Date())));
468
469 assertTrue(new NotNullSpecification<Object>(Object.class).isGeneralizationOf(new NotNullSpecification<Object>(Object.class)));
470 assertTrue(new NotNullSpecification<Object>(Object.class).isSpecialCaseOf(new NotNullSpecification<Object>(Object.class)));
471
472 assertTrue(new NotNullSpecification<Object>(Object.class).isGeneralizationOf(all(Order.class)));
473 assertFalse(new NotNullSpecification<Order>(Order.class).isSpecialCaseOf(all(Order.class)));
474
475 assertTrue(new NotNullSpecification<Object>(Object.class).isGeneralizationOf(isEqualTo(1)));
476 assertFalse(new NotNullSpecification<Date>(Date.class).isSpecialCaseOf(isAfter(new Date())));
477 }
478
479
480 @Test
481 public void entitySpecificationShouldBeOnTopOfAlmostEverything() {
482 assertTrue(allInstancesOfType(Entity.class).isGeneralizationOf(allInstancesOfType(Order.class)));
483
484 assertTrue(allInstancesOfType(Order.class).isSpecialCaseOf(allInstancesOfType(Entity.class)));
485
486
487 Specification rawEntitySpec = allInstancesOfType(Entity.class);
488 Specification rawOrderSpec = allInstancesOfType(Order.class);
489
490 assertTrue(rawEntitySpec.isGeneralizationOf(rawOrderSpec));
491 assertFalse(rawOrderSpec.isGeneralizationOf(rawEntitySpec));
492 assertFalse(rawEntitySpec.isSpecialCaseOf(rawOrderSpec));
493 assertTrue(rawOrderSpec.isSpecialCaseOf(rawEntitySpec));
494 }
495
496
497 @Test
498 public void shouldAcceptSubtypeSpecification_compositeSpecification() {
499 CompositeSpecification rawCustomerSpec = all(Customer.class).where("name", is("Tommy"));
500 CompositeSpecification rawVipCustomerSpec = all(VipCustomer.class)
501 .where("name", is("Tommy"))
502 .and("vipCustomerSince", before(yesterday));
503
504 assertTrue(rawCustomerSpec.isGeneralizationOf(rawVipCustomerSpec));
505 assertFalse(rawCustomerSpec.isSpecialCaseOf(rawVipCustomerSpec));
506 assertFalse(rawVipCustomerSpec.isGeneralizationOf(rawCustomerSpec));
507 assertTrue(rawVipCustomerSpec.isSpecialCaseOf(rawCustomerSpec));
508
509 CompositeSpecification<Customer> customerSpec = all(Customer.class).where("name", is("Tommy"));
510 CompositeSpecification<VipCustomer> vipCustomerSpec = all(VipCustomer.class)
511 .where("vipCustomerSince", before(yesterday))
512 .and("name", is("Tommy"));
513
514
515 assertTrue(customerSpec.isGeneralizationOf(vipCustomerSpec));
516 assertTrue(vipCustomerSpec.isSpecialCaseOf(customerSpec));
517
518
519 assertLemma2(rawCustomerSpec, rawVipCustomerSpec, new Customer().name("Tommy"));
520 assertLemma2(rawCustomerSpec, rawVipCustomerSpec, new VipCustomer().name("Tommy"));
521 assertLemma1(customerSpec, vipCustomerSpec);
522 }
523
524
525 @Test
526 public void shouldNotAcceptSpecificationOfDifferentType_compositeSpecification() {
527 CompositeSpecification rawCustomerSpec = all(Customer.class);
528 CompositeSpecification rawIntegerSpec = all(Integer.class);
529
530 assertFalse(rawCustomerSpec.isGeneralizationOf(rawIntegerSpec));
531 assertFalse(rawIntegerSpec.isGeneralizationOf(rawCustomerSpec));
532 assertFalse(rawCustomerSpec.isSpecialCaseOf(rawIntegerSpec));
533 assertFalse(rawIntegerSpec.isSpecialCaseOf(rawCustomerSpec));
534
535 assertLemma1_DisjunctionOnly(rawCustomerSpec, rawIntegerSpec);
536 }
537
538
539 @Test
540 public void checkSimpleFieldSpecificationVersusTypedSpecification() {
541 Specification<Customer> allCustomerSpec = all(Customer.class);
542 Specification<Customer> maleCustomerSpec = all(Customer.class).where("gender", isEqualTo(MALE));
543 Specification<Customer> femaleCustomerSpec = all(Customer.class).where("gender", isEqualTo(FEMALE));
544
545 assertTrue(allCustomerSpec.isGeneralizationOf(maleCustomerSpec));
546 assertTrue(allCustomerSpec.isGeneralizationOf(femaleCustomerSpec));
547 assertFalse(maleCustomerSpec.isGeneralizationOf(femaleCustomerSpec));
548
549 assertFalse(allCustomerSpec.isSpecialCaseOf(maleCustomerSpec));
550 assertFalse(allCustomerSpec.isSpecialCaseOf(femaleCustomerSpec));
551 assertFalse(maleCustomerSpec.isSpecialCaseOf(femaleCustomerSpec));
552
553 assertTrue(maleCustomerSpec.isSpecialCaseOf(maleCustomerSpec));
554 assertTrue(femaleCustomerSpec.isSpecialCaseOf(femaleCustomerSpec));
555 assertFalse(femaleCustomerSpec.isSpecialCaseOf(maleCustomerSpec));
556
557 assertLemma1((CompositeSpecification) allCustomerSpec, (CompositeSpecification) maleCustomerSpec);
558
559
560
561 }
562
563
564 protected final CompositeSpecification<Customer> customers = allInstancesOfType(Customer.class);
565 protected final CompositeSpecification<Customer> pioneerCustomers = customers.where("membershipDate", isBefore(twoDaysAgo));
566 protected final CompositeSpecification<Customer> newCustomers = customers.where("membershipDate", isAfterOrAtTheSameTimeAs(twoDaysAgo));
567
568 @Test
569 public void disjunctSpecificationsShouldNotBeGeneralizationNorSpecialization() {
570 assertFalse(newCustomers.isSpecialCaseOf(pioneerCustomers));
571 assertFalse(newCustomers.isGeneralizationOf(pioneerCustomers));
572 assertFalse(pioneerCustomers.isSpecialCaseOf(newCustomers));
573 assertFalse(pioneerCustomers.isGeneralizationOf(newCustomers));
574 }
575
576
577 @Test
578 public void checkSimpleConjunctionSpecifications() {
579 Specification<Customer> spec = all(Customer.class)
580 .where("gender", isEqualTo(MALE))
581 .and("name", is("John"));
582 Specification<Customer> specialCaseOfSpec = all(Customer.class)
583 .where("gender", isEqualTo(MALE))
584 .and("membershipDate", isAtTheSameTimeAs(today))
585 .and("name", is("John"));
586
587 assertTrue(spec.isGeneralizationOf(specialCaseOfSpec));
588 assertFalse(spec.isSpecialCaseOf(specialCaseOfSpec));
589
590 assertFalse(specialCaseOfSpec.isGeneralizationOf(spec));
591 assertTrue(specialCaseOfSpec.isSpecialCaseOf(spec));
592
593 assertLemma1((CompositeSpecification) spec, (CompositeSpecification) specialCaseOfSpec);
594 }
595
596
597 @Test
598 public void checkSimpleDisjunctionSpecifications() {
599 CompositeSpecification<Customer> spec = all(Customer.class)
600 .where("gender", is(MALE))
601 .and("name", is("John"));
602
603 CompositeSpecification<Customer> moreGeneralDisjunctionSpec = all(Customer.class)
604 .where("gender", is(MALE))
605 .and("name", is("John"))
606 .or("membershipDate", isAtTheSameTimeAs(today));
607
608 assertFalse(spec.isGeneralizationOf(moreGeneralDisjunctionSpec));
609 assertTrue(moreGeneralDisjunctionSpec.isGeneralizationOf(spec));
610 assertTrue(spec.isSpecialCaseOf(moreGeneralDisjunctionSpec));
611 assertFalse(moreGeneralDisjunctionSpec.isSpecialCaseOf(spec));
612 assertFalse(spec.isDisjointWith(moreGeneralDisjunctionSpec));
613 assertLemma1(spec, moreGeneralDisjunctionSpec);
614
615 CompositeSpecification<Customer> customerSpec = all(Customer.class);
616 CompositeSpecification<Customer> maleCustomerSpec = all(Customer.class).where("gender", isEqualTo(MALE));
617 CompositeSpecification<Customer> aCustomerNamedJohnSpec = all(Customer.class).where("name", is("John")).and("gender", isEqualTo(MALE));
618 CompositeSpecification<Customer> aCustomerNamedPeterSpec = all(Customer.class).where("gender", isEqualTo(MALE)).and("name", is("Peter"));
619 CompositeSpecification<Customer> aCustomerNamedJohnOrPeterSpec = aCustomerNamedJohnSpec.or(aCustomerNamedPeterSpec);
620
621 assertTrue(customerSpec.isGeneralizationOf(aCustomerNamedJohnSpec));
622 assertFalse(customerSpec.isSpecialCaseOf(aCustomerNamedJohnSpec));
623 assertTrue(customerSpec.isGeneralizationOf(aCustomerNamedJohnOrPeterSpec));
624 assertFalse(customerSpec.isSpecialCaseOf(aCustomerNamedJohnOrPeterSpec));
625
626 assertTrue(maleCustomerSpec.isGeneralizationOf(aCustomerNamedJohnSpec));
627 assertFalse(maleCustomerSpec.isSpecialCaseOf(aCustomerNamedJohnSpec));
628 assertTrue(maleCustomerSpec.isGeneralizationOf(aCustomerNamedJohnOrPeterSpec));
629 assertFalse(maleCustomerSpec.isSpecialCaseOf(aCustomerNamedJohnOrPeterSpec));
630
631 assertFalse(aCustomerNamedJohnSpec.isGeneralizationOf(aCustomerNamedJohnOrPeterSpec));
632 assertTrue(aCustomerNamedJohnSpec.isSpecialCaseOf(aCustomerNamedJohnOrPeterSpec));
633 assertFalse(aCustomerNamedJohnSpec.isGeneralizationOf(aCustomerNamedJohnOrPeterSpec));
634 assertTrue(aCustomerNamedJohnSpec.isSpecialCaseOf(aCustomerNamedJohnOrPeterSpec));
635
636 assertTrue(aCustomerNamedJohnOrPeterSpec.isGeneralizationOf(aCustomerNamedJohnSpec));
637 assertFalse(aCustomerNamedJohnOrPeterSpec.isSpecialCaseOf(aCustomerNamedJohnSpec));
638 assertTrue(aCustomerNamedJohnOrPeterSpec.isGeneralizationOf(aCustomerNamedJohnOrPeterSpec));
639 assertTrue(aCustomerNamedJohnOrPeterSpec.isSpecialCaseOf(aCustomerNamedJohnOrPeterSpec));
640
641 assertFalse(aCustomerNamedJohnOrPeterSpec.isGeneralizationOf(customerSpec));
642 assertTrue(aCustomerNamedJohnOrPeterSpec.isSpecialCaseOf(customerSpec));
643 assertFalse(aCustomerNamedJohnOrPeterSpec.isGeneralizationOf(maleCustomerSpec));
644 assertTrue(aCustomerNamedJohnOrPeterSpec.isSpecialCaseOf(maleCustomerSpec));
645
646 assertTrue(aCustomerNamedPeterSpec.isDisjointWith(aCustomerNamedJohnSpec));
647 assertFalse(aCustomerNamedPeterSpec.isDisjointWith(aCustomerNamedJohnOrPeterSpec));
648 assertFalse(aCustomerNamedJohnSpec.isDisjointWith(aCustomerNamedJohnOrPeterSpec));
649 assertLemma1(aCustomerNamedPeterSpec, aCustomerNamedJohnOrPeterSpec);
650 }
651
652
653 @Test
654 public void shouldDealWithNegatedSpecifications_1() {
655 Specification allObjects = allObjects();
656 Specification<Customer> customer = all(Customer.class);
657 Specification<Customer> notCustomer = not(customer);
658 Specification<Customer> customerNotNamedTommy = all(Customer.class).where("name", is(not("Tommy")));
659
660 assertTrue(allObjects.isGeneralizationOf(customer));
661 assertTrue(allObjects.isGeneralizationOf(notCustomer));
662 assertFalse(customer.isGeneralizationOf(allObjects));
663 assertFalse(notCustomer.isGeneralizationOf(allObjects));
664 assertFalse(allObjects.isSpecialCaseOf(customer));
665 assertFalse(allObjects.isSpecialCaseOf(notCustomer));
666 assertTrue(customer.isSpecialCaseOf(allObjects));
667 assertTrue(notCustomer.isSpecialCaseOf(allObjects));
668
669 assertFalse(notCustomer.isGeneralizationOf(customer));
670 assertFalse(notCustomer.isSpecialCaseOf(customer));
671 assertFalse(customer.isGeneralizationOf(notCustomer));
672 assertFalse(customer.isSpecialCaseOf(notCustomer));
673 assertFalse(notCustomer.isGeneralizationOf(customerNotNamedTommy));
674 assertFalse(notCustomer.isSpecialCaseOf(customerNotNamedTommy));
675 assertFalse(customerNotNamedTommy.isGeneralizationOf(notCustomer));
676 assertFalse(customerNotNamedTommy.isSpecialCaseOf(notCustomer));
677
678 assertTrue(customer.isGeneralizationOf(customerNotNamedTommy));
679 assertFalse(customerNotNamedTommy.isGeneralizationOf(customer));
680 assertFalse(customer.isSpecialCaseOf(customerNotNamedTommy));
681 assertTrue(customerNotNamedTommy.isSpecialCaseOf(customer));
682
683 assertLemma1_DisjunctionOnly((CompositeSpecification<Customer>) customer, (CompositeSpecification<Customer>) notCustomer);
684 assertLemma1_DisjunctionOnly((CompositeSpecification<Customer>) notCustomer, (CompositeSpecification<Customer>) customerNotNamedTommy);
685 }
686
687
688 @Test
689 public void shouldDealWithNegatedSpecifications_2() {
690 Specification<Customer> customer = all(Customer.class);
691 Specification<Customer> notCustomer = not(customer);
692 Specification<Customer> femaleOrMaleNotNamedTommyOrJohnnyCustomer = all(Customer.class).where("name", is(not("Tommy")).and(is(not("Johnny")))).or("gender", is(FEMALE));
693
694 assertFalse(notCustomer.isGeneralizationOf(customer));
695 assertFalse(notCustomer.isSpecialCaseOf(customer));
696 assertFalse(customer.isGeneralizationOf(notCustomer));
697 assertFalse(customer.isSpecialCaseOf(notCustomer));
698 assertFalse(notCustomer.isGeneralizationOf(femaleOrMaleNotNamedTommyOrJohnnyCustomer));
699 assertFalse(notCustomer.isSpecialCaseOf(femaleOrMaleNotNamedTommyOrJohnnyCustomer));
700 assertFalse(femaleOrMaleNotNamedTommyOrJohnnyCustomer.isGeneralizationOf(notCustomer));
701 assertFalse(femaleOrMaleNotNamedTommyOrJohnnyCustomer.isSpecialCaseOf(notCustomer));
702
703 assertTrue(customer.isGeneralizationOf(femaleOrMaleNotNamedTommyOrJohnnyCustomer));
704 assertFalse(femaleOrMaleNotNamedTommyOrJohnnyCustomer.isGeneralizationOf(customer));
705 assertFalse(customer.isSpecialCaseOf(femaleOrMaleNotNamedTommyOrJohnnyCustomer));
706 assertTrue(femaleOrMaleNotNamedTommyOrJohnnyCustomer.isSpecialCaseOf(customer));
707
708 assertLemma1((CompositeSpecification) customer, (CompositeSpecification) femaleOrMaleNotNamedTommyOrJohnnyCustomer);
709 assertLemma1_DisjunctionOnly((CompositeSpecification<Customer>) notCustomer, (CompositeSpecification<Customer>) femaleOrMaleNotNamedTommyOrJohnnyCustomer);
710 }
711
712
713 @Test
714 public void shouldDealWithNegatedSpecifications_3() {
715 Specification<Customer> notCustomer = not(all(Customer.class));
716 Specification<Customer> notCustomerNamedTommy = not(all(Customer.class).where("name", is("Tommy")));
717 Specification<Customer> notCustomerNotNamedTommy = not(all(Customer.class).where("name", is(not("Tommy"))));
718 Specification<Customer> notCustomerFromYesterday = not(all(Customer.class).where("membershipDate", isAtTheSameTimeAs(yesterday)));
719 Specification notOrder = not(all(Order.class));
720
721 assertFalse(notCustomer.isGeneralizationOf(notCustomerNamedTommy));
722 assertFalse(notCustomer.isSpecialCaseOf(notCustomerNamedTommy));
723 assertFalse(notCustomerNamedTommy.isGeneralizationOf(notCustomer));
724 assertFalse(notCustomerNamedTommy.isSpecialCaseOf(notCustomer));
725
726 assertFalse(notCustomerNamedTommy.isGeneralizationOf(notCustomerNotNamedTommy));
727 assertFalse(notCustomerNamedTommy.isSpecialCaseOf(notCustomerNotNamedTommy));
728 assertFalse(notCustomerNotNamedTommy.isGeneralizationOf(notCustomerNamedTommy));
729 assertFalse(notCustomerNotNamedTommy.isSpecialCaseOf(notCustomerNamedTommy));
730
731 assertFalse(notCustomerNamedTommy.isGeneralizationOf(notCustomerFromYesterday));
732 assertFalse(notCustomerNamedTommy.isSpecialCaseOf(notCustomerFromYesterday));
733 assertFalse(notCustomerFromYesterday.isGeneralizationOf(notCustomerNamedTommy));
734 assertFalse(notCustomerFromYesterday.isSpecialCaseOf(notCustomerNamedTommy));
735
736 assertFalse(notCustomer.isGeneralizationOf(notOrder));
737 assertFalse(notCustomer.isSpecialCaseOf(notOrder));
738 assertFalse(notOrder.isGeneralizationOf(notCustomer));
739 assertFalse(notOrder.isSpecialCaseOf(notCustomer));
740
741 assertLemma1_DisjunctionOnly((CompositeSpecification<Customer>) notCustomer, (CompositeSpecification<Customer>) notCustomerNamedTommy);
742 assertLemma1_DisjunctionOnly((CompositeSpecification<Customer>) notCustomer, (CompositeSpecification<Customer>) notCustomerNotNamedTommy);
743 assertLemma1_DisjunctionOnly((CompositeSpecification<Customer>) notCustomer, (CompositeSpecification<Customer>) notCustomerFromYesterday);
744 assertLemma1_DisjunctionOnly((CompositeSpecification<Customer>) notCustomer, (CompositeSpecification<Customer>) notOrder);
745 }
746 }