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