1 /** 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (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.mozilla.org/MPL/MPL-1.1.html 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 17 import org.as2lib.data.holder.array.TypedArray; 18 import org.as2lib.app.exec.BatchProcess; 19 import org.as2lib.test.unit.Test; 20 import org.as2lib.test.unit.TestResult; 21 import org.as2lib.test.unit.TestRunner; 22 import org.as2lib.env.except.IllegalArgumentException; 23 import org.as2lib.test.unit.TestSuiteResult; 24 import org.as2lib.app.exec.Process; 25 import org.as2lib.test.unit.TestCaseResult; 26 import org.as2lib.test.unit.TestCaseMethodInfo; 27 28 /** 29 * {@code TestSuite} is a composite implementation of {@link Test}. 30 * 31 * <p>A {@code TestSuite} is a collection of {@code Test}s. A {@code TestSuite} 32 * does not contain any executable code but it may contain different {@code Test}s 33 * that can be added with {@link #addTest}. 34 * 35 * <p>In contrast to {@code TestCase} the {@code TestSuite} has no external 36 * {@code TestRunner}. {@code TestSuite} is its own implementation of 37 * {@code TestRunner}. 38 * 39 * @author Martin Heidegger 40 * @version 2.0 41 * @see org.as2lib.test.unit.TestSuiteFactory 42 */ 43 class org.as2lib.test.unit.TestSuite extends BatchProcess implements Test, TestRunner { 44 45 /** 46 * Blocks the collection of 47 * {@code org.as2lib.test.unit.TestSuiteFactory#collectAllTestCases}. 48 * 49 * @return {@code true} to block the collection 50 */ 51 public static function blockCollecting(Void):Boolean { 52 return true; 53 } 54 55 /** All test contained within the TestSuite. */ 56 private var tests:TypedArray; 57 58 /** Name of the TestSuite. */ 59 private var name:String; 60 61 /** Result for the execution of the TestSuite. */ 62 private var testResult:TestSuiteResult; 63 64 /** 65 * Constructs a new {@code TestSuite}. 66 * 67 * @param name name of the {@code TestSuite} 68 */ 69 public function TestSuite(name:String) { 70 this.tests = new TypedArray(TestRunner); 71 testResult = new TestSuiteResult(this); 72 this.name = name; 73 } 74 75 /** 76 * Helper to validate if the added {@code Test} contains the current testsuite. 77 * 78 * <p>Since its possible to add any {@code Test} to this suite it could be 79 * possible to add this {@code TestSuite} instance. That would result in a 80 * endless recursion. 81 * 82 * @param test test to be validated 83 * @throws IllegalArgumentException if the passed-in {@code Test} contains this 84 * instance as child. 85 */ 86 private function checkRecursion(test:TestResult) { 87 if (test === testResult) { 88 throw new IllegalArgumentException( 89 "The test "+test+" contains or is the current test", 90 this, arguments); 91 } 92 var content:Array = test.getTestResults(); 93 for (var i=0; i<content.length; i++) { 94 if (content[i] != test) { 95 checkRecursion(content[i]); 96 } 97 } 98 } 99 100 /** 101 * Adds a process to the {@code TestSuite}. 102 * 103 * <p>{@code TestSuite} does only allow {@code TestRunner} as sub processes. 104 * 105 * <p>Overrides the implementation in {@link BatchProcess#addProcess}. 106 * 107 * @param p {@code Process} to be added to the {@code TestSuite} 108 * @throws IllegalArgumentException if the passed-in {@code p} contains this 109 * instance as child. 110 */ 111 public function addProcess(p:Process):Void { 112 var eP:TestRunner = TestRunner(p); 113 if (eP) { 114 checkRecursion(eP.getTestResult()); 115 testResult.addTest(eP.getTestResult()); 116 tests.push(p); 117 super.addProcess(p); 118 } else { 119 throw new IllegalArgumentException("Only Tests are allowed for processing", this, arguments); 120 } 121 } 122 123 /** 124 * Adds a {@code Test} to the {@code TestSuite}. 125 * 126 * @param test {@code Test} to be added 127 * @throws IllegalArgumentException if the passed-in {@code Test} contains this 128 * instance as child. 129 */ 130 public function addTest(test:Test):Void { 131 addProcess(test.getTestRunner()); 132 } 133 134 /** 135 * Returns the name of the {@code TestSuite}. 136 * 137 * @return name of the {@code TestSuite}. 138 */ 139 public function getName(Void):String { 140 if(!name) { 141 return ""; 142 } 143 return name; 144 } 145 146 /** 147 * Runs the {@code TestSuite}. 148 * 149 * @return {@code TestRunner} that run this test 150 */ 151 public function run(Void):TestRunner { 152 start(); 153 return this; 154 } 155 156 /** 157 * Returns the {@code TestRunner} that executes this {@code TestSuite}. 158 * 159 * @return {@code TestRunner} that executes this {@code TestSuite} 160 */ 161 public function getTestRunner(Void):TestRunner { 162 return this; 163 } 164 165 /** 166 * Returns all {@code Tests} contained within this {@code TestSuite}. 167 * 168 * @return {@link TypedArray} that contains all {@code Test}s of this {@code TestSuite}. 169 */ 170 public function getTests(Void):TypedArray { 171 return this.tests; 172 } 173 174 /** 175 * Event handling for a error during a proces. 176 * 177 * @param process {@code Process} that throws the error 178 * @return {@code false} to stop further execution 179 */ 180 public function onProcessError(process:Process, error):Boolean { 181 return false; 182 } 183 184 /** 185 * Returns the {@code TestResult} to the {@code TestSuite}. 186 * 187 * <p>The returned {@code TestResult} may not be complete. This is the case 188 * if the test has not been executed or has not finished yet. 189 * 190 * @return {@link TestResult} for the {@code TestSuite} that contains all informations 191 */ 192 public function getTestResult(Void):TestResult { 193 return testResult; 194 } 195 196 /** 197 * Returns the current executing {@code TestCaseResult}. 198 * 199 * <p>It is necessary to get the {@code TestCaseResult} for the {@code TestCase} 200 * that just gets executed because there can be more than one {@code TestCase} 201 * available within a {@code TestResult}. 202 * 203 * @return {@code TestResult} to the current executing {@code TestCase} 204 */ 205 public function getCurrentTestCase(Void):TestCaseResult { 206 return list[current].getCurrentTestCase(); 207 } 208 209 /** 210 * Returns the current executing {@code TestCaseMethodInfo}. 211 * 212 * <p>It is necessary to get the {@code TestCaseMethodInfo} for the method 213 * that just gets executed because there can be more than one methods available 214 * within a {@code TestCaseResult}. 215 * 216 * @return informations about the current executing method 217 * @see #getCurrentTestCase 218 */ 219 public function getCurrentTestCaseMethodInfo(Void):TestCaseMethodInfo { 220 return list[current].getCurrentTestCaseMethodInfo(); 221 } 222 }