001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.chain.impl;
018    
019    
020    import java.io.ByteArrayInputStream;
021    import java.io.ByteArrayOutputStream;
022    import java.io.ObjectInputStream;
023    import java.io.ObjectOutputStream;
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.HashMap;
027    import java.util.Iterator;
028    import java.util.Map;
029    import java.util.Set;
030    
031    import junit.framework.Test;
032    import junit.framework.TestCase;
033    import junit.framework.TestSuite;
034    import org.apache.commons.chain.Context;
035    import org.apache.commons.chain.web.WebContext;
036    
037    
038    
039    /**
040     * <p>Test case for the <code>ContextBase</code> class.</p>
041     *
042     * @author Craig R. McClanahan
043     * @version $Revision: 480477 $ $Date: 2006-11-29 08:34:52 +0000 (Wed, 29 Nov 2006) $
044     */
045    
046    public class ContextBaseTestCase extends TestCase {
047    
048    
049        // ---------------------------------------------------- Instance Variables
050    
051    
052        /**
053         * The {@link Context} instance under test.
054         */
055        protected Context context = null;
056    
057    
058    
059        // ---------------------------------------------------------- Constructors
060    
061        /**
062         * Construct a new instance of this test case.
063         *
064         * @param name Name of the test case
065         */
066        public ContextBaseTestCase(String name) {
067            super(name);
068        }
069    
070    
071        // -------------------------------------------------- Overall Test Methods
072    
073    
074        /**
075         * Set up instance variables required by this test case.
076         */
077        public void setUp() {
078            context = createContext();
079        }
080    
081    
082        /**
083         * Return the tests included in this test suite.
084         */
085        public static Test suite() {
086            return (new TestSuite(ContextBaseTestCase.class));
087        }
088    
089        /**
090         * Tear down instance variables required by this test case.
091         */
092        public void tearDown() {
093            context = null;
094        }
095    
096    
097        // ------------------------------------------------ Individual Test Methods
098    
099    
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    }