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 junit.framework.Test;
021    import junit.framework.TestCase;
022    import junit.framework.TestSuite;
023    import org.apache.commons.chain.Chain;
024    import org.apache.commons.chain.Command;
025    import org.apache.commons.chain.Context;
026    
027    
028    /**
029     * <p>Test case for the <code>ChainBase</code> class.</p>
030     *
031     * @author Craig R. McClanahan
032     * @version $Revision: 480477 $ $Date: 2006-11-29 08:34:52 +0000 (Wed, 29 Nov 2006) $
033     */
034    
035    public class ChainBaseTestCase extends TestCase {
036    
037    
038        // ---------------------------------------------------- Instance Variables
039    
040    
041        /**
042         * The {@link Chain} instance under test.
043         */
044        protected Chain chain = null;
045    
046    
047        /**
048         * The {@link Context} instance on which to execute the chain.
049         */
050        protected Context context = null;
051    
052    
053        // ---------------------------------------------------------- Constructors
054    
055        /**
056         * Construct a new instance of this test case.
057         *
058         * @param name Name of the test case
059         */
060        public ChainBaseTestCase(String name) {
061            super(name);
062        }
063    
064    
065        // -------------------------------------------------- Overall Test Methods
066    
067    
068        /**
069         * Set up instance variables required by this test case.
070         */
071        public void setUp() {
072            chain = new ChainBase();
073            context = new ContextBase();
074        }
075    
076    
077        /**
078         * Return the tests included in this test suite.
079         */
080        public static Test suite() {
081            return (new TestSuite(ChainBaseTestCase.class));
082        }
083    
084        /**
085         * Tear down instance variables required by this test case.
086         */
087        public void tearDown() {
088            chain = null;
089            context = null;
090        }
091    
092    
093        // ------------------------------------------------ Individual Test Methods
094    
095    
096        // Test the ability to add commands
097        public void testCommands() {
098    
099            checkCommandCount(0);
100    
101            Command command1 = new NonDelegatingCommand("1");
102            chain.addCommand(command1);
103            checkCommandCount(1);
104    
105            Command command2 = new DelegatingCommand("2");
106            chain.addCommand(command2);
107            checkCommandCount(2);
108    
109            Command command3 = new ExceptionCommand("3");
110            chain.addCommand(command3);
111            checkCommandCount(3);
112    
113        }
114    
115    
116        // Test execution of a single non-delegating command
117        public void testExecute1a() {
118            chain.addCommand(new NonDelegatingCommand("1"));
119            try {
120                assertTrue("Chain returned true",
121                           chain.execute(context));
122            } catch (Exception e) {
123                fail("Threw exception: " + e);
124            }
125            checkExecuteLog("1");
126        }
127    
128    
129        // Test execution of a single delegating command
130        public void testExecute1b() {
131            chain.addCommand(new DelegatingCommand("1"));
132            try {
133                assertTrue("Chain returned false",
134                           !chain.execute(context));
135            } catch (Exception e) {
136                fail("Threw exception: " + e);
137            }
138            checkExecuteLog("1");
139        }
140    
141    
142        // Test execution of a single exception-throwing command
143        public void testExecute1c() {
144            chain.addCommand(new ExceptionCommand("1"));
145            try {
146                chain.execute(context);
147            } catch (ArithmeticException e) {
148                assertEquals("Correct exception id", "1", e.getMessage());
149            } catch (Exception e) {
150                fail("Threw exception: " + e);
151            }
152            checkExecuteLog("1");
153        }
154    
155    
156        // Test execution of an attempt to add a new Command while executing
157        public void testExecute1d() {
158            chain.addCommand(new AddingCommand("1", chain));
159            try {
160                chain.execute(context);
161            } catch (IllegalStateException e) {
162                ; // Expected result
163            } catch (Exception e) {
164                fail("Threw exception: " + e);
165            }
166            checkExecuteLog("1");
167        }
168    
169    
170        // Test execution of a chain that should return true
171        public void testExecute2a() {
172            chain.addCommand(new DelegatingCommand("1"));
173            chain.addCommand(new DelegatingCommand("2"));
174            chain.addCommand(new NonDelegatingCommand("3"));
175            try {
176                assertTrue("Chain returned true",
177                           chain.execute(context));
178            } catch (Exception e) {
179                fail("Threw exception: " + e);
180            }
181            checkExecuteLog("1/2/3");
182        }
183    
184    
185        // Test execution of a chain that should return false
186        public void testExecute2b() {
187            chain.addCommand(new DelegatingCommand("1"));
188            chain.addCommand(new DelegatingCommand("2"));
189            chain.addCommand(new DelegatingCommand("3"));
190            try {
191                assertTrue("Chain returned false",
192                           !chain.execute(context));
193            } catch (Exception e) {
194                fail("Threw exception: " + e);
195            }
196            checkExecuteLog("1/2/3");
197        }
198    
199    
200        // Test execution of a chain that should throw an exception
201        public void testExecute2c() {
202            chain.addCommand(new DelegatingCommand("1"));
203            chain.addCommand(new DelegatingCommand("2"));
204            chain.addCommand(new ExceptionCommand("3"));
205            try {
206                chain.execute(context);
207            } catch (ArithmeticException e) {
208                assertEquals("Correct exception id", "3", e.getMessage());
209            } catch (Exception e) {
210                fail("Threw exception: " + e);
211            }
212            checkExecuteLog("1/2/3");
213        }
214    
215    
216        // Test execution of a chain that should throw an exception in the middle
217        public void testExecute2d() {
218            chain.addCommand(new DelegatingCommand("1"));
219            chain.addCommand(new ExceptionCommand("2"));
220            chain.addCommand(new NonDelegatingCommand("3"));
221            try {
222                chain.execute(context);
223            } catch (ArithmeticException e) {
224                assertEquals("Correct exception id", "2", e.getMessage());
225            } catch (Exception e) {
226                fail("Threw exception: " + e);
227            }
228            checkExecuteLog("1/2");
229        }
230    
231    
232        // Test execution of a single non-delegating filter
233        public void testExecute3a() {
234            chain.addCommand(new NonDelegatingFilter("1", "a"));
235            try {
236                assertTrue("Chain returned true",
237                           chain.execute(context));
238            } catch (Exception e) {
239                fail("Threw exception: " + e);
240            }
241            checkExecuteLog("1/a");
242        }
243    
244    
245        // Test execution of a single delegating filter
246        public void testExecute3b() {
247            chain.addCommand(new DelegatingFilter("1", "a"));
248            try {
249                assertTrue("Chain returned false",
250                           !chain.execute(context));
251            } catch (Exception e) {
252                fail("Threw exception: " + e);
253            }
254            checkExecuteLog("1/a");
255        }
256    
257    
258        // Test execution of a single exception-throwing filter
259        public void testExecute3c() {
260            chain.addCommand(new ExceptionFilter("1", "a"));
261            try {
262                chain.execute(context);
263            } catch (ArithmeticException e) {
264                assertEquals("Correct exception id", "1", e.getMessage());
265            } catch (Exception e) {
266                fail("Threw exception: " + e);
267            }
268            checkExecuteLog("1/a");
269        }
270    
271    
272        // Test execution of a chain that should return true
273        public void testExecute4a() {
274            chain.addCommand(new DelegatingFilter("1", "a"));
275            chain.addCommand(new DelegatingCommand("2"));
276            chain.addCommand(new NonDelegatingFilter("3", "c"));
277            try {
278                assertTrue("Chain returned true",
279                           chain.execute(context));
280            } catch (Exception e) {
281                fail("Threw exception: " + e);
282            }
283            checkExecuteLog("1/2/3/c/a");
284        }
285    
286    
287        // Test execution of a chain that should return false
288        public void testExecute4b() {
289            chain.addCommand(new DelegatingCommand("1"));
290            chain.addCommand(new DelegatingFilter("2", "b"));
291            chain.addCommand(new DelegatingCommand("3"));
292            try {
293                assertTrue("Chain returned false",
294                           !chain.execute(context));
295            } catch (Exception e) {
296                fail("Threw exception: " + e);
297            }
298            checkExecuteLog("1/2/3/b");
299        }
300    
301    
302        // Test execution of a chain that should throw an exception
303        public void testExecute4c() {
304            chain.addCommand(new DelegatingFilter("1", "a"));
305            chain.addCommand(new DelegatingFilter("2", "b"));
306            chain.addCommand(new ExceptionFilter("3", "c"));
307            try {
308                chain.execute(context);
309            } catch (ArithmeticException e) {
310                assertEquals("Correct exception id", "3", e.getMessage());
311            } catch (Exception e) {
312                fail("Threw exception: " + e);
313            }
314            checkExecuteLog("1/2/3/c/b/a");
315        }
316    
317    
318        // Test execution of a chain that should throw an exception in the middle
319        public void testExecute4d() {
320            chain.addCommand(new DelegatingFilter("1", "a"));
321            chain.addCommand(new ExceptionFilter("2", "b"));
322            chain.addCommand(new NonDelegatingFilter("3", "c"));
323            try {
324                chain.execute(context);
325            } catch (ArithmeticException e) {
326                assertEquals("Correct exception id", "2", e.getMessage());
327            } catch (Exception e) {
328                fail("Threw exception: " + e);
329            }
330            checkExecuteLog("1/2/b/a");
331        }
332    
333    
334        // Test state of newly created instance
335        public void testNewInstance() {
336            checkCommandCount(0);
337        }
338    
339    
340        // -------------------------------------------------------- Support Methods
341    
342    
343        // Verify the number of configured commands
344        protected void checkCommandCount(int expected) {
345            if (chain instanceof ChainBase) {
346                Command commands[] = ((ChainBase) chain).getCommands();
347                assertNotNull("getCommands() returned a non-null array",
348                              commands);
349                assertEquals("Correct command count", expected, commands.length);
350            }
351        }
352    
353    
354        // Verify the contents of the execution log
355        protected void checkExecuteLog(String expected) {
356            StringBuffer log = (StringBuffer) context.get("log");
357            assertNotNull("Context failed to return log", log);
358            assertEquals("Context returned correct log",
359                         expected, log.toString());
360        }
361    
362    
363    }