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.env.overload.Overload;
    19  import org.as2lib.env.except.IllegalArgumentException;
    20  import org.as2lib.env.reflect.PackageInfo;
    21  import org.as2lib.env.reflect.ClassInfo;
    22  import org.as2lib.env.reflect.MethodInfo;
    23  import org.as2lib.test.speed.TestSuite;
    24  import org.as2lib.test.speed.MethodTestCase;
    25  
    26  /**
    27   * {@code TestSuiteFactory} collects test suites.
    28   * 
    29   * @author Simon Wacker
    30   */
    31  class org.as2lib.test.speed.TestSuiteFactory extends BasicClass {
    32  	
    33  	/**
    34  	 * Constructs a new {@code TestSuiteFactory} instance.
    35  	 */
    36  	public function TestSuiteFactory(Void) {
    37  	}
    38  	
    39  	/**
    40  	 * @overload #collectAllTestCases
    41  	 * @overload #collectTestCasesByPackage
    42  	 * @overload #collectTestCasesByClass
    43  	 */
    44  	public function collectTestCases():TestSuite {
    45  		var o:Overload = new Overload(this);
    46  		o.addHandler([], collectAllTestCases);
    47  		o.addHandler([PackageInfo], collectTestCasesByPackage);
    48  		o.addHandler([ClassInfo], collectTestCasesByClass);
    49  		return o.forward(arguments);
    50  	}
    51  	
    52  	/**
    53  	 * Collects all methods and properties as test cases except the ones declared by
    54  	 * {@code Object}.
    55  	 * 
    56  	 * @return a test suite that contains all tests
    57  	 */
    58  	public function collectAllTestCases(Void):TestSuite {
    59  		return collectTestCases(PackageInfo.getRootPackage());
    60  	}
    61  	
    62  	/**
    63  	 * Collects all methods and properties of the given {@code package} and all
    64  	 * sub-packages as test cases except the ones declared by {@code Object}.
    65  	 * 
    66  	 * @param package the package to begin the collection at
    67  	 * @return a test suite that contains all collected tests
    68  	 */
    69  	public function collectTestCasesByPackage(package:PackageInfo):TestSuite {
    70  		if (!package) throw new IllegalArgumentException("Argument 'package' [" + package + "] must not be 'null' nor 'undefined'.", this, arguments);
    71  		var r:TestSuite = new TestSuite(package.getFullName());
    72  		var ca:Array = package.getMemberClasses();
    73  		for (var i:Number = 0; i < ca.length; i++) {
    74  			r.addTest(collectTestCasesByClass(ca[i]));
    75  		}
    76  		var pa:Array = package.getMemberPackages();
    77  		for (var i:Number = 0; i < pa.length; i++) {
    78  			r.addTest(collectTestCasesByPackage(pa[i]));
    79  		}
    80  		return r;
    81  	}
    82  	
    83  	/**
    84  	 * Collects all methods and properties of the given class as test cases.
    85  	 * Methods and properties of super-classes are not included.
    86  	 * 
    87  	 * @param clazz the class to collect the methods and properties of
    88  	 * @return a test suite that contains all collected tests
    89  	 */
    90  	public function collectTestCasesByClass(clazz:ClassInfo):TestSuite {
    91  		var r:TestSuite = new TestSuite(clazz.getFullName());
    92  		r.addTest(clazz.getConstructor());
    93  		var p = clazz.getType().prototype;
    94  		if (p.__constructor__) {
    95  			var c:Function = p.__constructor__;
    96  			var m:MethodInfo = ClassInfo(clazz.getSuperType()).getConstructor();
    97  			if (c != m.getMethod()) {
    98  				p.__constructor__ = m.getMethod();
    99  			}
   100  			// this does actually collect a refernce to the super-type's constructor that is needed for super calls
   101  			// this is thus not actually part of the class
   102  			r.addTest(new MethodTestCase(m, p, "__constructor__"));
   103  		}
   104  		var ma:Array = clazz.getMethods(true);
   105  		for (var k:Number = 0; k < ma.length; k++) {
   106  			r.addTestByMethod(ma[k]);
   107  		}
   108  		var pa:Array = clazz.getProperties(true);
   109  		for (var k:Number = 0; k < pa.length; k++) {
   110  			r.addTestByProperty(pa[k]);
   111  		}
   112  		return r;
   113  	}
   114  	
   115  }