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