1   /*
2    * Copyright 2006-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sourceforge.domian.specification;
17  
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Date;
22  import java.util.HashSet;
23  import java.util.Stack;
24  import java.util.TreeSet;
25  import java.util.Vector;
26  import java.util.concurrent.ConcurrentLinkedQueue;
27  
28  import org.junit.Before;
29  import org.junit.Test;
30  
31  import static net.sourceforge.domian.specification.CollectionSpecification.CollectionSpecificationScope;
32  import static net.sourceforge.domian.specification.SpecificationFactory.an;
33  import static net.sourceforge.domian.specification.SpecificationFactory.greaterThanOrEqualTo;
34  import static net.sourceforge.domian.specification.SpecificationFactory.not;
35  import static org.junit.Assert.assertEquals;
36  import static org.junit.Assert.assertFalse;
37  import static org.junit.Assert.assertTrue;
38  import static org.junit.Assert.fail;
39  
40  
41  public class CollectionSpecificationTest {
42  
43      Collection<Integer> integerCollection = new ArrayList<Integer>(10);
44  
45      CollectionSpecification<Integer> collectionWithTenElements =
46              new CollectionSpecification<Integer>(CollectionSpecificationScope.SIZE,
47                                                   new EqualSpecification<Integer>(10));
48  
49      CollectionSpecification<Integer> collectionWithNotTenElements =
50              new CollectionSpecification<Integer>(CollectionSpecificationScope.SIZE,
51                                                   not(new EqualSpecification<Integer>(10)));
52  
53      CollectionSpecification<Integer> collectionWithLessThanElevenElements =
54              new CollectionSpecification<Integer>(CollectionSpecificationScope.SIZE,
55                                                   new LessThanSpecification<Integer>(11));
56  
57      CollectionSpecification<Integer> collectionWithMoreThanEightElements =
58              new CollectionSpecification<Integer>(CollectionSpecificationScope.SIZE,
59                                                   greaterThanOrEqualTo(9),
60                                                   (Specification<Integer>) null);
61  
62      CollectionSpecification<Integer> collectionWithLessThanTwoElementsGreaterThanFive =
63              new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
64                                                   new LessThanSpecification<Integer>(2),
65                                                   new GreaterThanSpecification<Integer>(5));
66  
67      CollectionSpecification<Integer> collectionWithNineOrMoreElementsGreaterThanZero =
68              new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
69                                                   new GreaterThanSpecification<Integer>(8),
70                                                   new GreaterThanSpecification<Integer>(0));
71  
72      CollectionSpecification<Integer> collectionWithOneElementEqualToThree =
73              new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
74                                                   new EqualSpecification<Integer>(1),
75                                                   new EqualSpecification<Integer>(3));
76  
77      CollectionSpecification<Integer> collectionWithTwoElementsEqualToThree =
78              new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
79                                                   new EqualSpecification<Integer>(2),
80                                                   new EqualSpecification<Integer>(3));
81  
82      CollectionSpecification<Date> collectionWithOneElementEqualToTodayDate =
83              new CollectionSpecification<Date>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
84                                                new EqualSpecification<Integer>(1),
85                                                new EqualSpecification<Date>(new Date()));
86  
87      CollectionSpecification<Integer> collectionWithMoreThanFiftyPercentOfElementsLessThanThree =
88              new CollectionSpecification<Integer>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
89                                                   new GreaterThanSpecification<Integer>(50),
90                                                   new LessThanSpecification<Integer>(3));
91  
92      CollectionSpecification<Integer> collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree =
93              new CollectionSpecification<Integer>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
94                                                   not(new GreaterThanSpecification<Integer>(50)),
95                                                   (new LessThanSpecification<Integer>(3)));
96  
97      CollectionSpecification<Integer> collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree =
98              new CollectionSpecification<Integer>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
99                                                   not(new GreaterThanSpecification<Integer>(50)),
100                                                  not((new LessThanSpecification<Integer>(3))));
101 
102     CollectionSpecification<Date> collectionWithMoreThanFifteenPercentOfElementsEqualToNow =
103             new CollectionSpecification<Date>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
104                                               new GreaterThanSpecification<Integer>(15),
105                                               new EqualSpecification<Date>(new Date()));
106 
107     @Before
108     public void before() {
109         integerCollection.add(0);
110         integerCollection.add(1);
111         integerCollection.add(2);
112         integerCollection.add(3);
113         integerCollection.add(4);
114         integerCollection.add(5);
115         integerCollection.add(6);
116         integerCollection.add(7);
117         integerCollection.add(8);
118         integerCollection.add(9);
119     }
120 
121     @Test
122     public void collectionSpecificationsDoNeedASpecificationScope() {
123         try {
124             new CollectionSpecification<Integer>(null,
125                                                  new EqualSpecification<Integer>(integerCollection.size()),
126                                                  new EqualSpecification<Integer>(10));
127             fail("Should have thrown exception");
128 
129         } catch (IllegalArgumentException e) {
130             String expectedMessage = "Collection specification scope parameter cannot be null";
131             assertEquals(expectedMessage, e.getMessage());
132         }
133     }
134 
135     ///////////////////////////////////////////////////////////////////////////
136     //
137     //  CollectionSpecificationScope.SIZE
138     //
139     ///////////////////////////////////////////////////////////////////////////
140 
141     @Test
142     public void numberOfElementsCollectionSpecificationsDoNeedACollectionSpecification() {
143         try {
144             new CollectionSpecification<Integer>(CollectionSpecificationScope.SIZE,
145                                                  null,
146                                                  new EqualSpecification<Integer>(10));
147             fail("Should have thrown exception");
148 
149         } catch (IllegalArgumentException e) {
150             String expectedMessage = "Collection specification parameter cannot be null";
151             assertEquals(expectedMessage, e.getMessage());
152         }
153     }
154 
155     @Test
156     public void numberOfElementscollectionSpecificationsDoNotNeedAnElementSpecification() {
157         new CollectionSpecification<Integer>(CollectionSpecificationScope.SIZE,
158                                              new EqualSpecification<Integer>(integerCollection.size()),
159                                              (Specification<Integer>) null);
160     }
161 
162     @Test
163     public void testCollectionSizeEquality() {
164         assertFalse(collectionWithTenElements.isSatisfiedBy(null));
165         //assertFalse(collectionWithTenElements.isSatisfiedBy(Collections.emptyMap()));
166         //assertFalse(collectionWithTenElements.isSatisfiedBy(Collections.emptySet()));
167         assertFalse(collectionWithTenElements.isSatisfiedBy(new ArrayList()));
168         assertFalse(collectionWithTenElements.isSatisfiedBy(new ArrayList<Integer>()));
169         assertFalse(collectionWithTenElements.isSatisfiedBy(new HashSet(100)));
170         assertFalse(collectionWithTenElements.isSatisfiedBy(new HashSet<Integer>(100)));
171 
172         assertEquals(10, integerCollection.size());
173         assertTrue(collectionWithTenElements.isSatisfiedBy(integerCollection));
174         assertTrue(new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
175                                                         new EqualSpecification<Integer>(integerCollection.size()),
176                                                         an(Integer.class))
177                 .isSatisfiedBy(integerCollection));
178     }
179 
180     @Test
181     public void testCollectionSizeNotEquality() {
182         assertFalse(collectionWithNotTenElements.isSatisfiedBy(null));
183         assertTrue(collectionWithNotTenElements.isSatisfiedBy(new ArrayList()));
184         assertTrue(collectionWithNotTenElements.isSatisfiedBy(new ArrayList<Integer>()));
185         assertTrue(collectionWithNotTenElements.isSatisfiedBy(new HashSet(100)));
186         assertTrue(collectionWithNotTenElements.isSatisfiedBy(new HashSet<Integer>(100)));
187         Collection collection = new ArrayList(9);
188         collection.add(1);
189         collection.add(2);
190         collection.add(3);
191         collection.add(4);
192         collection.add(5);
193         collection.add(6);
194         collection.add(7);
195         collection.add(8);
196         collection.add(9);
197         assertTrue(collectionWithNotTenElements.isSatisfiedBy(collection));
198         collection.add(10);
199         assertFalse(collectionWithNotTenElements.isSatisfiedBy(collection));
200         collection.add(11);
201         assertTrue(collectionWithNotTenElements.isSatisfiedBy(collection));
202     }
203 
204     @Test
205     public void testCollectionSizeLessThan() {
206         assertFalse(collectionWithLessThanElevenElements.isSatisfiedBy(null));
207         assertTrue(collectionWithLessThanElevenElements.isSatisfiedBy(new ArrayList(100)));
208 
209         assertTrue(integerCollection.size() < 11);
210         assertTrue(collectionWithLessThanElevenElements.isSatisfiedBy(integerCollection));
211         assertTrue(new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
212                                                         new LessThanSpecification<Integer>(integerCollection.size() + 1),
213                                                         an(Integer.class))
214                 .isSatisfiedBy(integerCollection));
215     }
216 
217     @Test
218     public void testCollectionSizeGreaterThanOrEqual() {
219         assertFalse(collectionWithMoreThanEightElements.isSatisfiedBy(null));
220         assertFalse(collectionWithMoreThanEightElements.isSatisfiedBy(new Stack()));
221 
222         assertTrue(integerCollection.size() >= 9);
223         assertTrue(collectionWithMoreThanEightElements.isSatisfiedBy(integerCollection));
224         assertTrue(new CollectionSpecification(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
225                                                greaterThanOrEqualTo(integerCollection.size() - 1),
226                                                an(Integer.class))
227                 .isSatisfiedBy(integerCollection));
228     }
229 
230     ///////////////////////////////////////////////////////////////////////////
231     //
232     //  CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS
233     //
234     ///////////////////////////////////////////////////////////////////////////
235 
236     @Test
237     public void numberOfApprovedElementsCollectionSpecificationsDoNeedACollectionSpecification() {
238         try {
239             new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
240                                                  null,
241                                                  new EqualSpecification<Integer>(10));
242             fail("Should have thrown exception");
243 
244         } catch (IllegalArgumentException e) {
245             String expectedMessage = "Collection specification parameter cannot be null";
246             assertEquals(expectedMessage, e.getMessage());
247         }
248     }
249 
250     @Test
251     public void numberOfApprovedElementsCollectionSpecificationsDoNeedAnElementSpecification() {
252         try {
253             new CollectionSpecification<Integer>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS,
254                                                  new EqualSpecification<Integer>(integerCollection.size()),
255                                                  (Specification<Integer>) null);
256             fail("Should have thrown exception");
257 
258         } catch (IllegalArgumentException e) {
259             String expectedMessage = "Element specification parameter cannot be null";
260             assertEquals(expectedMessage, e.getMessage());
261         }
262     }
263 
264     @Test
265     public void testAnyCollectionWithLessThanTwoElementsGreaterThanFive() {
266         assertFalse(collectionWithLessThanTwoElementsGreaterThanFive.isSatisfiedBy(null));
267         assertTrue(collectionWithLessThanTwoElementsGreaterThanFive.isSatisfiedBy(new Vector()));
268 
269         assertFalse(collectionWithLessThanTwoElementsGreaterThanFive.isSatisfiedBy(integerCollection));
270     }
271 
272     @Test
273     public void testAnyCollectionWithNineOrMoreElementsGreaterThanZero() {
274         assertFalse(collectionWithNineOrMoreElementsGreaterThanZero.isSatisfiedBy(null));
275         assertFalse(collectionWithNineOrMoreElementsGreaterThanZero.isSatisfiedBy(new TreeSet()));
276 
277         assertTrue(collectionWithNineOrMoreElementsGreaterThanZero.isSatisfiedBy(integerCollection));
278     }
279 
280     @Test
281     public void testIntegerCollectionWithElementsEqualToThree() {
282         assertFalse(collectionWithOneElementEqualToThree.isSatisfiedBy(null));
283         assertFalse(collectionWithOneElementEqualToThree.isSatisfiedBy(new ConcurrentLinkedQueue()));
284 
285         assertTrue(collectionWithOneElementEqualToThree.isSatisfiedBy(integerCollection));
286 
287         assertFalse(collectionWithTwoElementsEqualToThree.isSatisfiedBy(null));
288         assertFalse(collectionWithTwoElementsEqualToThree.isSatisfiedBy(new Vector()));
289 
290         assertFalse(collectionWithTwoElementsEqualToThree.isSatisfiedBy(integerCollection));
291     }
292 
293     /* Deals with ClassCastExceptions */
294     @Test
295     public void testIntegerCollectionWithOneElementEqualToTodayDate() {
296         assertFalse(collectionWithOneElementEqualToTodayDate.isSatisfiedBy(null));
297         assertFalse(collectionWithOneElementEqualToTodayDate.isSatisfiedBy(new ConcurrentLinkedQueue()));
298         assertFalse(collectionWithOneElementEqualToTodayDate.isSatisfiedBy(new ConcurrentLinkedQueue<Date>()));
299     }
300 
301     ///////////////////////////////////////////////////////////////////////////
302     //
303     //  CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS
304     //
305     ///////////////////////////////////////////////////////////////////////////
306 
307 
308     @Test
309     public void percentageOfApprovedElementsCollectionSpecificationsDoNeedACollectionSpecification() {
310         try {
311             new CollectionSpecification<Integer>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
312                                                  null,
313                                                  new EqualSpecification<Integer>(10));
314             fail("Should have thrown exception");
315 
316         } catch (IllegalArgumentException e) {
317             String expectedMessage = "Collection specification parameter cannot be null";
318             assertEquals(expectedMessage, e.getMessage());
319         }
320     }
321 
322     @Test
323     public void percentageOfApprovedElementsCollectionSpecificationsDoNeedAnElementSpecification() {
324         try {
325             new CollectionSpecification<Integer>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
326                                                  new EqualSpecification<Integer>(integerCollection.size()),
327                                                  (Specification<Integer>) null);
328             fail("Should have thrown exception");
329 
330         } catch (IllegalArgumentException e) {
331             String expectedMessage = "Element specification parameter cannot be null";
332             assertEquals(expectedMessage, e.getMessage());
333         }
334     }
335 
336     @Test
337     public void testIntegerCollectionWithMoreThanFiftyPercentOfElementsLessThanThree() {
338         assertFalse(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(null));
339         assertFalse(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(new ConcurrentLinkedQueue()));
340         assertFalse(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(new ConcurrentLinkedQueue<Integer>()));
341         Collection<Integer> collection = new ArrayList<Integer>(9);
342         assertFalse(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
343         collection.add(2);
344         assertTrue(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
345         collection.add(2);
346         assertTrue(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
347         collection.add(3);
348         assertTrue(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
349         collection.add(3);
350         assertFalse(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
351         collection.add(3);
352         assertFalse(collectionWithMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
353     }
354 
355     @Test
356     public void testIntegerCollectionWithNotMoreThanFiftyPercentOfElementsLessThanThree() {
357         assertFalse(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(null));
358         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(new ConcurrentLinkedQueue()));
359         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(new ConcurrentLinkedQueue<Integer>()));
360         Collection<Integer> collection = new ArrayList<Integer>(9);
361         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
362         collection.add(3);
363         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
364         collection.add(3);
365         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
366         collection.add(2);
367         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
368         collection.add(2);
369         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
370         collection.add(2);
371         assertFalse(collectionWithNotMoreThanFiftyPercentOfElementsLessThanThree.isSatisfiedBy(collection));
372     }
373 
374     @Test
375     public void testIntegerCollectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree() {
376         // ->       testIntegerCollectionWithLessThanOrEqualToFiftyPercentOfElementsEqualOrGreaterThanThree() {
377         assertFalse(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(null));
378         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(new ConcurrentLinkedQueue()));
379         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(new ConcurrentLinkedQueue<Integer>()));
380         Collection<Integer> collection = new ArrayList<Integer>(9);
381         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(collection));
382         collection.add(2);
383         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(collection));
384         collection.add(2);
385         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(collection));
386         collection.add(3);
387         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(collection));
388         collection.add(3);
389         assertTrue(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(collection));
390         collection.add(3);
391         assertFalse(collectionWithNotMoreThanFiftyPercentOfElementsNotLessThanThree.isSatisfiedBy(collection));
392     }
393 
394     /* Deals with ClassCastExceptions */
395     @Test
396     public void testCollectionWithMoreThanFifteenPercentOfElementsEqualToNow() {
397         assertFalse(collectionWithMoreThanFifteenPercentOfElementsEqualToNow.isSatisfiedBy(null));
398         assertFalse(collectionWithMoreThanFifteenPercentOfElementsEqualToNow.isSatisfiedBy(new ConcurrentLinkedQueue()));
399         assertFalse(collectionWithMoreThanFifteenPercentOfElementsEqualToNow.isSatisfiedBy(new ConcurrentLinkedQueue<Date>()));
400     }
401 
402     @Test
403     public void testPercentageLowerThanZeroAndGreaterThanOneHundred() {
404         try {
405             new CollectionSpecification<Date>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
406                                               new GreaterThanSpecification<Integer>(101),
407                                               new EqualSpecification<Date>(new Date()));
408             fail("Should have thrown exception");
409 
410         } catch (IllegalArgumentException e) {
411             String expectedMessage = "The percentage must be an integer from 0 to 100";
412             assertEquals(expectedMessage, e.getMessage());
413         }
414         try {
415             new CollectionSpecification<Date>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS,
416                                               new GreaterThanSpecification<Integer>(-1),
417                                               new EqualSpecification<Date>(new Date()));
418             fail("Should have thrown exception");
419 
420         } catch (IllegalArgumentException e) {
421             String expectedMessage = "The percentage must be an integer from 0 to 100";
422             assertEquals(expectedMessage, e.getMessage());
423         }
424     }
425 }