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.core.BasicClass;
    18  import org.as2lib.data.holder.array.TypedArray;
    19  import org.as2lib.test.unit.TestResult;
    20  import org.as2lib.test.unit.TestCaseResult;
    21  import org.as2lib.test.unit.TestSuite;
    22  import org.as2lib.util.StringUtil;
    23  import org.as2lib.data.type.Time;
    24  
    25  /**
    26   * {@code TestSuiteResult} contains all informations about the execution of a {@code TestSuite}.
    27   * 
    28   * <p>{@link TestSuite} contains all states of execution of the {@code TestSuite}
    29   * and {@code TestSuiteResult} contains all informations about the execution.
    30   * 
    31   * @author Martin Heidegger.
    32   * @version 1.0
    33   * @see TestSuite
    34   */
    35  class org.as2lib.test.unit.TestSuiteResult extends BasicClass implements TestResult {
    36  
    37  	/** Related {@code TestSuite}. */
    38  	private var testSuite:TestSuite;
    39  	
    40  	/** {@code TestResults} to the {@code TestSuite}. */
    41  	private var testResults:TypedArray;
    42  
    43  	/**
    44  	 * Constructs a new {@code TestSuiteResult}.
    45  	 * 
    46  	 * @param testSuite related {@code TestSuite}
    47  	 */
    48  	public function TestSuiteResult(testSuite:TestSuite) {
    49  		this.testSuite = testSuite;
    50  		testResults = new TypedArray(TestResult);
    51  		
    52  		var tests:Array = testSuite.getTests();
    53  		for (var i:Number=0; i<tests.length; i++) {
    54  			addTest(tests[i]);
    55  		}
    56  	}
    57  	
    58  	/**
    59  	 * Adds a {@code TestResult} to the {@code TestSuiteResult}.
    60  	 * 
    61  	 * @param test {@code TestResult} to be added
    62  	 */
    63  	public function addTest(test:TestResult):Void {
    64  		testResults.unshift(test);
    65  	}
    66  	
    67  	/**
    68  	 * Returns all {@code TestResult) in a {@link TypedArray} contained in the
    69  	 * {@code TestSuite}.
    70  	 * 
    71  	 * @return list of all {@code TestResult}s
    72  	 */
    73  	public function getTests(Void):TypedArray {
    74  		return this.testResults;
    75  	}
    76  	
    77  	/**
    78  	 * Returns the percentage ({@code 0}-{@code 100}) of the added {@code Test}s.
    79  	 * 
    80  	 * @return percentage of execution
    81  	 */
    82  	public function getPercentage(Void):Number {
    83  		var result:Number = 0;
    84  		var unit:Number = 100/this.testResults.length;
    85  		for (var i:Number = this.testResults.length - 1; i >= 0; i--) {
    86  			result += (unit/100*this.testResults[i].getPercentage());
    87  		}
    88  		return result;
    89  	}
    90  	
    91  	/**
    92  	 * Returns {@code true} if the {@code TestSuite} has been finished.
    93  	 * 
    94  	 * @return {@code true} if the {@code TestSuite} has been finished
    95  	 */
    96  	public function hasFinished(Void):Boolean {
    97  		for (var i:Number = this.testResults.length - 1; i >= 0; i--) {
    98  			if (!this.testResults[i].isFinished()) {
    99  				return false;
   100  			}
   101  		}
   102  		return true;
   103  	}
   104  	
   105  	/**
   106  	 * Returns {@code true} if the {@code TestSuite} has been started.
   107  	 * 
   108  	 * @return {@code true} if the {@code TestSuite} has been started
   109  	 */
   110  	public function hasStarted(Void):Boolean {
   111  		for (var i:Number = this.testResults.length - 1; i >= 0; i--) {
   112  			if (this.testResults[i].hasStarted()) {
   113  				return true;
   114  			}
   115  		}
   116  		return false;
   117  	}
   118  		
   119  	/**
   120  	 * Returns all {@code TestResult}s for the {@code Test}s contained
   121  	 * within the related {@code TestSuite}.
   122  	 * 
   123  	 * <p>Since its possible to add more than one {@code Test} to a {@code TestSuite}
   124  	 * its necessary to get the {@code TestResult}s to all added {@code Test}s.
   125  	 *
   126  	 * <p>It flattens out all {@code TestResults}, this means it concats all
   127  	 * {@code getTestResults} of every added {@code Test}. 
   128  	 * 
   129  	 * @return all {@code TestResult}s to all contained {@code Test}s
   130  	 */
   131  	public function getTestResults(Void):TypedArray {
   132  		var result:TypedArray = new TypedArray(TestResult);
   133  		for (var i:Number=0; i<this.testResults.length; i++) {
   134  			// TODO: Bug? Why can't i use .concat ???
   135  			var testCases:Array = this.testResults[i].getTestResults();
   136  			for (var j:Number=0; j<testCases.length; j++) {
   137  				result.push(testCases[j]);
   138  			}
   139  		}
   140  		return result;
   141  	}
   142  	
   143  	/**
   144  	 * Returns all {@code TestCaseResult}s for the {@code TestCase}s contained
   145  	 * within the related {@code Test}.
   146  	 * 
   147  	 * <p>Since its possible to add more than one {@code Test} to a {@code TestSuite}
   148  	 * its necessary to get the {@code TestResult}s to all added {@code Test}s.
   149  	 * 
   150  	 * <p>{@code TestCase} represents the lowest level of {@code Test} therefor
   151  	 * its important to get all added {@code TestCaseResults} seperatly.
   152  	 *
   153  	 * <p>It flattens out all {@code TestResults}, this means it concats all
   154  	 * {@code getTestCaseResults} of every added {@code Test}. 
   155  	 * 
   156  	 * @return all {@code TestResult}s to all contained {@code Test}s
   157  	 */
   158  	public function getTestCaseResults(Void):TypedArray {
   159  		var result:TypedArray = new TypedArray(TestCaseResult);
   160  		for (var i:Number=0; i<this.testResults.length; i++) {
   161  			// TODO: Bug? Why can't i use .concat ???
   162  			var testCases:Array = this.testResults[i].getTestCaseResults();
   163  			for (var j:Number=0; j<testCases.length; j++) {
   164  				result.push(testCases[j]);
   165  			}
   166  		}
   167  		return result;
   168  	}
   169  	
   170  	/**
   171  	 * Retuns the name of the {@code TestSuite}.
   172  	 * 
   173  	 * @return name of the {@code TestSuite}
   174  	 */
   175  	public function getName(Void):String {
   176  		return this.getTestSuite().getName();
   177  	}
   178  	
   179  	/**
   180  	 * Returns the total operation time for all methods executed for the
   181  	 * related {@code TestSuite}.
   182  	 * 
   183  	 * @return total operation time of the {@code Test}
   184  	 */
   185  	public function getOperationTime(Void):Time {
   186  		var result:Number = 0;
   187  		for (var i:Number = this.testResults.length - 1; i >= 0; i--) {
   188  			result += this.testResults[i].getOperationTime();
   189  		}
   190  		return new Time(result);
   191  	}
   192  	
   193  	
   194  	/**
   195  	 * Returns {@code true} if the errors occured during the execution of the
   196  	 * related {@code Test}.
   197  	 * 
   198  	 * @return {@code true} if the errors occured during the execution of the
   199  	 * 		   related {@code Test}.
   200  	 */
   201  	public function hasErrors(Void):Boolean {
   202  		for (var i:Number = this.testResults.length - 1; i >= 0; i--) {
   203  			if (this.testResults[i].hasErrors()) {
   204  				return true;
   205  			}
   206  		}
   207  		return false;
   208  	}
   209  	
   210  	/**
   211  	 * Returns the related {@coee TestSuite}.
   212  	 * 
   213  	 * @return related {@code TestSuite}
   214  	 */
   215  	public function getTestSuite(Void):TestSuite {
   216  		return this.testSuite;
   217  	}
   218  
   219  
   220  	/**
   221  	 * Extended .toString implementation.
   222  	 * 
   223  	 * @return {@code TestSuiteResult} as well formated {@code String}
   224  	 */
   225  	public function toString():String {
   226  		var result:String;
   227  		var titleLength:Number;
   228  		result = "*** TestSuite "+getName()+" ("+testResults.length+" Tests) ["+getOperationTime()+"ms] ***";
   229  		titleLength = result.length;
   230  		for (var i:Number = 0; i < testResults.length; i++){
   231  			result += "\n"+StringUtil.addSpaceIndent(this.testResults[i].toString(), 2);
   232  		}
   233  		result += "\n"+StringUtil.multiply("*", titleLength);
   234  		return result;
   235  	}
   236  	
   237  }