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.Date;
20  import java.util.HashSet;
21  import java.util.Set;
22  
23  import org.junit.Test;
24  
25  import net.sourceforge.domian.test.domain.Customer;
26  import net.sourceforge.domian.test.domain.Testdata;
27  import net.sourceforge.domian.util.ReflectionUtils;
28  
29  import static net.sourceforge.domian.specification.SpecificationFactory.anyOf;
30  import static net.sourceforge.domian.specification.SpecificationFactory.isAfter;
31  import static net.sourceforge.domian.specification.SpecificationFactory.isAfterOrAtTheSameTimeAs;
32  import static net.sourceforge.domian.specification.SpecificationFactory.isBefore;
33  import static net.sourceforge.domian.specification.SpecificationFactory.isEqualTo;
34  import static net.sourceforge.domian.specification.SpecificationFactory.isGreaterThanOrEqualTo;
35  import static net.sourceforge.domian.test.domain.Testdata.maleCustomer;
36  import static net.sourceforge.domian.test.domain.Testdata.thisDate;
37  import static net.sourceforge.domian.test.domain.Testdata.thisMonth;
38  import static net.sourceforge.domian.test.domain.Testdata.thisYear;
39  import static net.sourceforge.domian.test.domain.Testdata.tomorrow;
40  import static net.sourceforge.domian.test.domain.Testdata.twentyYearsAgo;
41  import static net.sourceforge.domian.test.domain.Testdata.twoDaysAgo;
42  import static net.sourceforge.domian.test.domain.Testdata.yesterday;
43  import static net.sourceforge.domian.util.DateUtils.getTime;
44  import static org.junit.Assert.assertEquals;
45  import static org.junit.Assert.assertFalse;
46  import static org.junit.Assert.assertNotSame;
47  import static org.junit.Assert.assertSame;
48  import static org.junit.Assert.assertTrue;
49  import static org.junit.Assert.fail;
50  
51  
52  public class ValueBoundSpecificationTest {
53  
54      @Test
55      public void testShouldNotAcceptNullAsValue() {
56          try {
57              new EqualSpecification<Object>(null);
58              fail("Should have thrown exception");
59  
60          } catch (IllegalArgumentException e) {
61              String expectedMessage = "Value parameter cannot be null";
62              assertEquals(expectedMessage, e.getMessage());
63          }
64      }
65  
66  
67      @Test
68      public void testGetValue() {
69          ValueBoundSpecification<String> spec = (ValueBoundSpecification<String>) isEqualTo("myValue");
70          assertSame("myValue", spec.getValue());
71          assertSame(spec.getValue(), ((AbstractValueBoundSpecification) spec).originalValue);
72  
73          ValueBoundSpecification<Customer> customerSpec = (ValueBoundSpecification<Customer>) isEqualTo(maleCustomer);
74          assertSame(maleCustomer, customerSpec.getValue());
75          assertSame(customerSpec.getValue(), ((AbstractValueBoundSpecification) customerSpec).originalValue);
76      }
77  
78  
79      @Test
80      public void testKeepSpecificationIntegrityByCopyingValue() {
81          Date today = getTime(thisYear, thisMonth, thisDate);
82          ValueBoundSpecification<Date> spec = (ValueBoundSpecification<Date>) isAfter(today);
83          assertFalse(spec.isSatisfiedBy(null));
84          assertTrue(spec.isSatisfiedBy(tomorrow));
85          assertFalse(spec.isSatisfiedBy(Testdata.today));
86          assertFalse(spec.isSatisfiedBy(yesterday));
87          assertFalse(spec.isSatisfiedBy(twentyYearsAgo));
88  
89          Date theValue = spec.getValue();
90          // Whoops!
91          theValue.setTime(getTime(1950, 1, 1).getTime());
92  
93          // Should still hold... if object copying is activated
94          if (ReflectionUtils.DO_COPY_OBJECTS) {
95              assertFalse(spec.isSatisfiedBy(null));
96              assertTrue(spec.isSatisfiedBy(tomorrow));
97              assertFalse(spec.isSatisfiedBy(Testdata.today));
98              assertFalse(spec.isSatisfiedBy(yesterday));
99              assertFalse(spec.isSatisfiedBy(twentyYearsAgo));
100         } else { // if not, everything is screwed up
101             assertFalse(spec.isSatisfiedBy(null));
102             assertTrue(spec.isSatisfiedBy(tomorrow));
103             assertTrue(spec.isSatisfiedBy(Testdata.today));
104             assertTrue(spec.isSatisfiedBy(yesterday));
105             assertTrue(spec.isSatisfiedBy(twentyYearsAgo));
106         }
107     }
108 
109 
110     @Test
111     public void testValueDisjunction() {
112         Specification sORtORw = anyOf("s", "t", "w");
113         assertTrue(sORtORw.isSatisfiedBy("s"));
114         assertFalse(sORtORw.isSatisfiedBy("S"));
115         assertFalse(sORtORw.isSatisfiedBy(1001L));
116         assertFalse(sORtORw.isSatisfiedBy(new Object()));
117         assertFalse(sORtORw.isSatisfiedBy(new Date()));
118 
119         Specification<String> rORo = anyOf("r", "o");
120         assertTrue(rORo.isSatisfiedBy("o"));
121         //assertTrue(rORo.isSatisfiedBy('o'));            // Should not compile - OK
122         assertFalse(rORo.isSatisfiedBy("O"));
123         //assertFalse(rORo.isSatisfiedBy(1001L));         // Should not compile - OK
124         //assertFalse(rORo.isSatisfiedBy(new Object()));  // Should not compile - OK
125         //assertFalse(rORo.isSatisfiedBy(new Date()));    // Should not compile - OK
126     }
127 
128 
129     @Test
130     public void testHashCode() {
131         Specification spec1 = isEqualTo("yo!");
132         Specification spec2 = isEqualTo("yo!");
133         Set<Specification> set = new HashSet<Specification>(2);
134         set.add(spec1);
135         set.add(spec2);
136         assertEquals(1, set.size());
137     }
138 
139 
140     @Test
141     public void testEquality() {
142         Specification spec1 = isEqualTo("yo!");
143         Specification<String> spec2 = isEqualTo("yo!");
144         assertFalse(spec1.equals(null));
145         assertFalse(spec1.equals(new Integer(99)));
146         assertFalse(spec2.equals(null));
147         assertFalse(spec2.equals(new Integer(99)));
148         assertNotSame(spec1, spec2);
149         assertEquals(spec1, spec2);
150 
151         Specification spec3 = isGreaterThanOrEqualTo(42L);
152         Specification spec4 = isGreaterThanOrEqualTo(42L);
153         assertNotSame(spec3, spec4);
154         assertEquals(spec3, spec4);
155     }
156 
157 
158     @Test
159     public void sameValueButDifferentSpecificationClassShouldNotBeEqual() {
160         assertFalse(isBefore(twoDaysAgo).equals(isAfterOrAtTheSameTimeAs(twoDaysAgo)));
161         assertFalse(isAfterOrAtTheSameTimeAs(twoDaysAgo).equals(isBefore(twoDaysAgo)));
162     }
163 }