1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.chain.impl;
18  
19  
20  import java.io.ByteArrayInputStream;
21  import java.io.ByteArrayOutputStream;
22  import java.io.ObjectInputStream;
23  import java.io.ObjectOutputStream;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.HashMap;
27  import java.util.Iterator;
28  import java.util.Map;
29  import java.util.Set;
30  
31  import junit.framework.Test;
32  import junit.framework.TestCase;
33  import junit.framework.TestSuite;
34  import org.apache.commons.chain.Context;
35  import org.apache.commons.chain.web.WebContext;
36  
37  
38  
39  /**
40   * <p>Test case for the <code>ContextBase</code> class.</p>
41   *
42   * @author Craig R. McClanahan
43   * @version $Revision: 480477 $ $Date: 2006-11-29 08:34:52 +0000 (Wed, 29 Nov 2006) $
44   */
45  
46  public class ContextBaseTestCase extends TestCase {
47  
48  
49      // ---------------------------------------------------- Instance Variables
50  
51  
52      /**
53       * The {@link Context} instance under test.
54       */
55      protected Context context = null;
56  
57  
58  
59      // ---------------------------------------------------------- Constructors
60  
61      /**
62       * Construct a new instance of this test case.
63       *
64       * @param name Name of the test case
65       */
66      public ContextBaseTestCase(String name) {
67          super(name);
68      }
69  
70  
71      // -------------------------------------------------- Overall Test Methods
72  
73  
74      /**
75       * Set up instance variables required by this test case.
76       */
77      public void setUp() {
78          context = createContext();
79      }
80  
81  
82      /**
83       * Return the tests included in this test suite.
84       */
85      public static Test suite() {
86          return (new TestSuite(ContextBaseTestCase.class));
87      }
88  
89      /**
90       * Tear down instance variables required by this test case.
91       */
92      public void tearDown() {
93          context = null;
94      }
95  
96  
97      // ------------------------------------------------ Individual Test Methods
98  
99  
100     // Test ability to get, put, and remove attributes
101     public void testAttributes() {
102 
103         Object value = null;
104         checkAttributeCount(0);
105 
106         context.put("foo", "This is foo");
107         checkAttributeCount(1);
108         value = context.get("foo");
109         assertNotNull("Returned foo", value);
110         assertTrue("Returned foo type", value instanceof String);
111         assertEquals("Returned foo value", "This is foo",
112                      (String) value);
113 
114         context.put("bar", "This is bar");
115         checkAttributeCount(2);
116         value = context.get("bar");
117         assertNotNull("Returned bar", value);
118         assertTrue("Returned bar type", value instanceof String);
119         assertEquals("Returned bar value", "This is bar",
120                      (String) value);
121 
122         context.put("baz", "This is baz");
123         checkAttributeCount(3);
124         value = context.get("baz");
125         assertNotNull("Returned baz", value);
126         assertTrue("Returned baz type", value instanceof String);
127         assertEquals("Returned baz value", "This is baz",
128                      (String) value);
129 
130         context.put("baz", "This is new baz");
131         checkAttributeCount(3); // Replaced, not added
132         value = context.get("baz");
133         assertNotNull("Returned baz", value);
134         assertTrue("Returned baz type", value instanceof String);
135         assertEquals("Returned baz value", "This is new baz",
136                      (String) value);
137 
138         context.remove("bar");
139         checkAttributeCount(2);
140         assertNull("Did not return bar",
141                    context.get("bar"));
142         assertNotNull("Still returned foo",
143                       context.get("foo"));
144         assertNotNull("Still returned baz",
145                       context.get("baz"));
146 
147         context.clear();
148         checkAttributeCount(0);
149         assertNull("Did not return foo",
150                    context.get("foo"));
151         assertNull("Did not return bar",
152                    context.get("bar"));
153         assertNull("Did not return baz",
154                    context.get("baz"));
155 
156     }
157 
158 
159     // Test containsKey() and containsValue()
160     public void testContains() {
161 
162         assertTrue(!context.containsKey("bop"));
163         assertTrue(!context.containsValue("bop value"));
164         context.put("bop", "bop value");
165         assertTrue(context.containsKey("bop"));
166         assertTrue(context.containsValue("bop value"));
167         context.remove("bop");
168         assertTrue(!context.containsKey("bop"));
169         assertTrue(!context.containsValue("bop value"));
170 
171     }
172 
173 
174     // Test equals() and hashCode()
175     public void testEquals() {
176 
177         // Compare to self
178         assertTrue(context.equals(context));
179         assertTrue(context.hashCode() == context.hashCode());
180 
181         // Compare to equivalent instance
182         Context other = createContext();
183         assertTrue(context.equals(other));
184         assertTrue(context.hashCode() == other.hashCode());
185 
186         // Compare to non-equivalent instance - other modified
187         other.put("bop", "bop value");
188         assertTrue(!context.equals(other));
189         assertTrue(context.hashCode() != other.hashCode());
190 
191         // Compare to non-equivalent instance - self modified
192         other = createContext(); // reset to equivalence
193         context.put("bop", "bop value");
194         assertTrue(!context.equals(other));
195         assertTrue(context.hashCode() != other.hashCode());
196 
197     }
198 
199 
200     // Test keySet()
201     public void testKeySet() {
202 
203         Set keySet = null;
204         Collection all = new ArrayList();
205 
206         // Unsupported operations
207         keySet = context.keySet();
208         try {
209             keySet.add("bop");
210             fail("Should have thrown UnsupportedOperationException");
211         } catch (UnsupportedOperationException e) {
212             ; // Expected result
213         }
214         try {
215             Collection adds = new ArrayList();
216             adds.add("bop");
217             keySet.addAll(adds);
218             fail("Should have thrown UnsupportedOperationException");
219         } catch (UnsupportedOperationException e) {
220             ; // Expected result
221         }
222 
223         // Before-modification checks
224         keySet = context.keySet();
225         assertEquals(createContext().size(), keySet.size());
226         assertTrue(!keySet.contains("foo"));
227         assertTrue(!keySet.contains("bar"));
228         assertTrue(!keySet.contains("baz"));
229         assertTrue(!keySet.contains("bop"));
230 
231         // Add the new elements
232         context.put("foo", "foo value");
233         context.put("bar", "bar value");
234         context.put("baz", "baz value");
235         all.add("foo");
236         all.add("bar");
237         all.add("baz");
238 
239         // After-modification checks
240         keySet = context.keySet();
241         assertEquals(expectedAttributeCount() + 3, keySet.size());
242         assertTrue(keySet.contains("foo"));
243         assertTrue(keySet.contains("bar"));
244         assertTrue(keySet.contains("baz"));
245         assertTrue(!keySet.contains("bop"));
246         assertTrue(keySet.containsAll(all));
247 
248         // Remove a single element via remove()
249         context.remove("bar");
250         all.remove("bar");
251         keySet = context.keySet();
252         assertEquals(expectedAttributeCount() + 2, keySet.size());
253         assertTrue(keySet.contains("foo"));
254         assertTrue(!keySet.contains("bar"));
255         assertTrue(keySet.contains("baz"));
256         assertTrue(!keySet.contains("bop"));
257         assertTrue(keySet.containsAll(all));
258 
259         // Remove a single element via keySet.remove()
260         keySet.remove("baz");
261         all.remove("baz");
262         keySet = context.keySet();
263         assertEquals(expectedAttributeCount() + 1, keySet.size());
264         assertTrue(keySet.contains("foo"));
265         assertTrue(!keySet.contains("bar"));
266         assertTrue(!keySet.contains("baz"));
267         assertTrue(!keySet.contains("bop"));
268         assertTrue(keySet.containsAll(all));
269 
270         // Remove all elements via keySet.clear()
271         keySet.clear();
272         all.clear();
273         assertEquals(expectedAttributeCount(), keySet.size());
274         assertTrue(!keySet.contains("foo"));
275         assertTrue(!keySet.contains("bar"));
276         assertTrue(!keySet.contains("baz"));
277         assertTrue(!keySet.contains("bop"));
278         assertTrue(keySet.containsAll(all));
279 
280         // Add the new elements #2
281         context.put("foo", "foo value");
282         context.put("bar", "bar value");
283         context.put("baz", "baz value");
284         all.add("foo");
285         all.add("bar");
286         all.add("baz");
287 
288         // After-modification checks #2
289         keySet = context.keySet();
290         assertEquals(expectedAttributeCount() + 3, keySet.size());
291         assertTrue(keySet.contains("foo"));
292         assertTrue(keySet.contains("bar"));
293         assertTrue(keySet.contains("baz"));
294         assertTrue(!keySet.contains("bop"));
295         assertTrue(keySet.containsAll(all));
296 
297     }
298 
299 
300     // Test state of newly created instance
301     public void testPristine() {
302 
303         checkAttributeCount(0);
304         assertNull("No 'foo' attribute",
305                    context.get("foo"));
306 
307     }
308 
309 
310     // Test putAll()
311     public void testPutAll() {
312 
313         // Check preconditions
314         checkAttributeCount(0);
315         assertNull(context.get("foo"));
316         assertNull(context.get("bar"));
317         assertNull(context.get("baz"));
318         assertTrue(!context.containsKey("foo"));
319         assertTrue(!context.containsKey("bar"));
320         assertTrue(!context.containsKey("baz"));
321         assertTrue(!context.containsValue("foo value"));
322         assertTrue(!context.containsValue("bar value"));
323         assertTrue(!context.containsValue("baz value"));
324 
325         // Call putAll()
326         Map adds = new HashMap();
327         adds.put("foo", "foo value");
328         adds.put("bar", "bar value");
329         adds.put("baz", "baz value");
330         context.putAll(adds);
331 
332         // Check postconditions
333         checkAttributeCount(3);
334         assertEquals("foo value", (String) context.get("foo"));
335         assertEquals("bar value", (String) context.get("bar"));
336         assertEquals("baz value", (String) context.get("baz"));
337         assertTrue(context.containsKey("foo"));
338         assertTrue(context.containsKey("bar"));
339         assertTrue(context.containsKey("baz"));
340         assertTrue(context.containsValue("foo value"));
341         assertTrue(context.containsValue("bar value"));
342         assertTrue(context.containsValue("baz value"));
343 
344     }
345 
346 
347     // Test serialization
348     public void testSeriaization() throws Exception {
349 
350         // ContextBase is implicitly declared Serializable because it
351         // extends HashMap.  However, it is not possible to make
352         // the concrete subclasses of WebContext Serializable, because
353         // the underlying container objects that they wrap will not be.
354         // Therefore, skip testing serializability of these implementations
355         if (context instanceof WebContext) {
356             return;
357         }
358 
359         // Set up the context with some parameters
360         context.put("foo", "foo value");
361         context.put("bar", "bar value");
362         context.put("baz", "baz value");
363         checkAttributeCount(3);
364 
365         // Serialize to a byte array
366         ByteArrayOutputStream baos = new ByteArrayOutputStream();
367         ObjectOutputStream oos = new ObjectOutputStream(baos);
368         oos.writeObject(context);
369         oos.close();
370 
371         // Deserialize back to a new object
372         ByteArrayInputStream bais =
373           new ByteArrayInputStream(baos.toByteArray());
374         ObjectInputStream ois = new ObjectInputStream(bais);
375         context = (Context) ois.readObject();
376         ois.close();
377 
378         // Do some rudimentary checks to make sure we have the same contents
379         assertTrue(context.containsKey("foo"));
380         assertTrue(context.containsKey("bar"));
381         assertTrue(context.containsKey("baz"));
382         checkAttributeCount(3);
383 
384     }
385 
386 
387 
388     // -------------------------------------------------------- Support Methods
389 
390 
391     // Verify the number of defined attributes
392     protected void checkAttributeCount(int expected) {
393         int actual = 0;
394         Iterator keys = context.keySet().iterator();
395         while (keys.hasNext()) {
396             Object key = (Object) keys.next();
397             actual++;
398         }
399         assertEquals("Correct attribute count",
400                      expectedAttributeCount() + expected, actual);
401         if (expected == 0) {
402             assertTrue("Context should be empty", context.isEmpty());
403         } else {
404             assertTrue("Context should not be empty", !context.isEmpty());
405         }
406     }
407 
408 
409     // Create a new instance of the appropriate Context type for this test case
410     protected Context createContext() {
411         return (new ContextBase());
412     }
413 
414 
415     // Return the expected size() for a Context for this test case
416     protected int expectedAttributeCount() {
417         return (createContext().size());
418     }
419 
420 
421 }