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 junit.framework.Test;
20  import junit.framework.TestCase;
21  import junit.framework.TestSuite;
22  import org.apache.commons.chain.Chain;
23  import org.apache.commons.chain.Command;
24  import org.apache.commons.chain.Context;
25  
26  
27  /***
28   * <p>Test case for the <code>ChainBase</code> class.</p>
29   *
30   * @author Craig R. McClanahan
31   * @version $Revision: 1.5 $ $Date: 2004/02/25 00:01:05 $
32   */
33  
34  public class ChainBaseTestCase extends TestCase {
35  
36  
37      // ---------------------------------------------------- Instance Variables
38  
39  
40      /***
41       * The {@link Chain} instance under test.
42       */
43      protected Chain chain = null;
44  
45  
46      /***
47       * The {@link Context} instance on which to execute the chain.
48       */
49      protected Context context = null;
50  
51  
52      // ---------------------------------------------------------- Constructors
53  
54      /***
55       * Construct a new instance of this test case.
56       *
57       * @param name Name of the test case
58       */
59      public ChainBaseTestCase(String name) {
60          super(name);
61      }
62  
63  
64      // -------------------------------------------------- Overall Test Methods
65  
66  
67      /***
68       * Set up instance variables required by this test case.
69       */
70      public void setUp() {
71          chain = new ChainBase();
72          context = new ContextBase();
73      }
74  
75  
76      /***
77       * Return the tests included in this test suite.
78       */
79      public static Test suite() {
80          return (new TestSuite(ChainBaseTestCase.class));
81      }
82  
83      /***
84       * Tear down instance variables required by this test case.
85       */
86      public void tearDown() {
87          chain = null;
88          context = null;
89      }
90  
91  
92      // ------------------------------------------------ Individual Test Methods
93  
94  
95      // Test the ability to add commands
96      public void testCommands() {
97  
98          checkCommandCount(0);
99  
100         Command command1 = new NonDelegatingCommand("1");
101         chain.addCommand(command1);
102         checkCommandCount(1);
103 
104         Command command2 = new DelegatingCommand("2");
105         chain.addCommand(command2);
106         checkCommandCount(2);
107 
108         Command command3 = new ExceptionCommand("3");
109         chain.addCommand(command3);
110         checkCommandCount(3);
111 
112     }
113 
114 
115     // Test execution of a single non-delegating command
116     public void testExecute1a() {
117         chain.addCommand(new NonDelegatingCommand("1"));
118         try {
119             assertTrue("Chain returned true",
120                        chain.execute(context));
121         } catch (Exception e) {
122             fail("Threw exception: " + e);
123         }
124         checkExecuteLog("1");
125     }
126 
127 
128     // Test execution of a single delegating command
129     public void testExecute1b() {
130         chain.addCommand(new DelegatingCommand("1"));
131         try {
132             assertTrue("Chain returned false",
133                        !chain.execute(context));
134         } catch (Exception e) {
135             fail("Threw exception: " + e);
136         }
137         checkExecuteLog("1");
138     }
139 
140 
141     // Test execution of a single exception-throwing command
142     public void testExecute1c() {
143         chain.addCommand(new ExceptionCommand("1"));
144         try {
145             chain.execute(context);
146         } catch (ArithmeticException e) {
147             assertEquals("Correct exception id", "1", e.getMessage());
148         } catch (Exception e) {
149             fail("Threw exception: " + e);
150         }
151         checkExecuteLog("1");
152     }
153 
154 
155     // Test execution of an attempt to add a new Command while executing
156     public void testExecute1d() {
157         chain.addCommand(new AddingCommand("1", chain));
158         try {
159             chain.execute(context);
160         } catch (IllegalStateException e) {
161             ; // Expected result
162         } catch (Exception e) {
163             fail("Threw exception: " + e);
164         }
165         checkExecuteLog("1");
166     }
167 
168 
169     // Test execution of a chain that should return true
170     public void testExecute2a() {
171         chain.addCommand(new DelegatingCommand("1"));
172         chain.addCommand(new DelegatingCommand("2"));
173         chain.addCommand(new NonDelegatingCommand("3"));
174         try {
175             assertTrue("Chain returned true",
176                        chain.execute(context));
177         } catch (Exception e) {
178             fail("Threw exception: " + e);
179         }
180         checkExecuteLog("1/2/3");
181     }
182 
183 
184     // Test execution of a chain that should return false
185     public void testExecute2b() {
186         chain.addCommand(new DelegatingCommand("1"));
187         chain.addCommand(new DelegatingCommand("2"));
188         chain.addCommand(new DelegatingCommand("3"));
189         try {
190             assertTrue("Chain returned false",
191                        !chain.execute(context));
192         } catch (Exception e) {
193             fail("Threw exception: " + e);
194         }
195         checkExecuteLog("1/2/3");
196     }
197 
198 
199     // Test execution of a chain that should throw an exception
200     public void testExecute2c() {
201         chain.addCommand(new DelegatingCommand("1"));
202         chain.addCommand(new DelegatingCommand("2"));
203         chain.addCommand(new ExceptionCommand("3"));
204         try {
205             chain.execute(context);
206         } catch (ArithmeticException e) {
207             assertEquals("Correct exception id", "3", e.getMessage());
208         } catch (Exception e) {
209             fail("Threw exception: " + e);
210         }
211         checkExecuteLog("1/2/3");
212     }
213 
214 
215     // Test execution of a chain that should throw an exception in the middle
216     public void testExecute2d() {
217         chain.addCommand(new DelegatingCommand("1"));
218         chain.addCommand(new ExceptionCommand("2"));
219         chain.addCommand(new NonDelegatingCommand("3"));
220         try {
221             chain.execute(context);
222         } catch (ArithmeticException e) {
223             assertEquals("Correct exception id", "2", e.getMessage());
224         } catch (Exception e) {
225             fail("Threw exception: " + e);
226         }
227         checkExecuteLog("1/2");
228     }
229 
230 
231     // Test execution of a single non-delegating filter
232     public void testExecute3a() {
233         chain.addCommand(new NonDelegatingFilter("1", "a"));
234         try {
235             assertTrue("Chain returned true",
236                        chain.execute(context));
237         } catch (Exception e) {
238             fail("Threw exception: " + e);
239         }
240         checkExecuteLog("1/a");
241     }
242 
243 
244     // Test execution of a single delegating filter
245     public void testExecute3b() {
246         chain.addCommand(new DelegatingFilter("1", "a"));
247         try {
248             assertTrue("Chain returned false",
249                        !chain.execute(context));
250         } catch (Exception e) {
251             fail("Threw exception: " + e);
252         }
253         checkExecuteLog("1/a");
254     }
255 
256 
257     // Test execution of a single exception-throwing filter
258     public void testExecute3c() {
259         chain.addCommand(new ExceptionFilter("1", "a"));
260         try {
261             chain.execute(context);
262         } catch (ArithmeticException e) {
263             assertEquals("Correct exception id", "1", e.getMessage());
264         } catch (Exception e) {
265             fail("Threw exception: " + e);
266         }
267         checkExecuteLog("1/a");
268     }
269 
270 
271     // Test execution of a chain that should return true
272     public void testExecute4a() {
273         chain.addCommand(new DelegatingFilter("1", "a"));
274         chain.addCommand(new DelegatingCommand("2"));
275         chain.addCommand(new NonDelegatingFilter("3", "c"));
276         try {
277             assertTrue("Chain returned true",
278                        chain.execute(context));
279         } catch (Exception e) {
280             fail("Threw exception: " + e);
281         }
282         checkExecuteLog("1/2/3/c/a");
283     }
284 
285 
286     // Test execution of a chain that should return false
287     public void testExecute4b() {
288         chain.addCommand(new DelegatingCommand("1"));
289         chain.addCommand(new DelegatingFilter("2", "b"));
290         chain.addCommand(new DelegatingCommand("3"));
291         try {
292             assertTrue("Chain returned false",
293                        !chain.execute(context));
294         } catch (Exception e) {
295             fail("Threw exception: " + e);
296         }
297         checkExecuteLog("1/2/3/b");
298     }
299 
300 
301     // Test execution of a chain that should throw an exception
302     public void testExecute4c() {
303         chain.addCommand(new DelegatingFilter("1", "a"));
304         chain.addCommand(new DelegatingFilter("2", "b"));
305         chain.addCommand(new ExceptionFilter("3", "c"));
306         try {
307             chain.execute(context);
308         } catch (ArithmeticException e) {
309             assertEquals("Correct exception id", "3", e.getMessage());
310         } catch (Exception e) {
311             fail("Threw exception: " + e);
312         }
313         checkExecuteLog("1/2/3/c/b/a");
314     }
315 
316 
317     // Test execution of a chain that should throw an exception in the middle
318     public void testExecute4d() {
319         chain.addCommand(new DelegatingFilter("1", "a"));
320         chain.addCommand(new ExceptionFilter("2", "b"));
321         chain.addCommand(new NonDelegatingFilter("3", "c"));
322         try {
323             chain.execute(context);
324         } catch (ArithmeticException e) {
325             assertEquals("Correct exception id", "2", e.getMessage());
326         } catch (Exception e) {
327             fail("Threw exception: " + e);
328         }
329         checkExecuteLog("1/2/b/a");
330     }
331 
332 
333     // Test state of newly created instance
334     public void testNewInstance() {
335         checkCommandCount(0);
336     }
337 
338 
339     // -------------------------------------------------------- Support Methods
340 
341 
342     // Verify the number of configured commands
343     protected void checkCommandCount(int expected) {
344         if (chain instanceof ChainBase) {
345             Command commands[] = ((ChainBase) chain).getCommands();
346             assertNotNull("getCommands() returned a non-null array",
347                           commands);
348             assertEquals("Correct command count", expected, commands.length);
349         }
350     }
351 
352 
353     // Verify the contents of the execution log
354     protected void checkExecuteLog(String expected) {
355         StringBuffer log = (StringBuffer) context.get("log");
356         assertNotNull("Context returned log");
357         assertEquals("Context returned correct log",
358                      expected, log.toString());
359     }
360 
361 
362 }