mas01mj@732: package asunit.textui {
mas01mj@732: import asunit.framework.Test;
mas01mj@732: import asunit.framework.TestResult;
mas01mj@732:
mas01mj@732: import flash.display.MovieClip;
mas01mj@732: import flash.display.StageAlign;
mas01mj@732: import flash.display.StageScaleMode;
mas01mj@732: import flash.events.Event;
mas01mj@732: import flash.system.fscommand;
mas01mj@732: import flash.utils.clearInterval;
mas01mj@732: import flash.utils.describeType;
mas01mj@732: import flash.utils.getTimer;
mas01mj@732: import flash.utils.setInterval;
mas01mj@732: import flash.utils.Timer;
mas01mj@732: import flash.events.TimerEvent;
mas01mj@732: import flash.display.DisplayObject;
mas01mj@732:
mas01mj@732: /**
mas01mj@732: * The base class for ActionScript 3.0 test harness.
mas01mj@732: *
mas01mj@732: * The TestRunner
should be extended by your
mas01mj@732: * concrete runner for your project.
mas01mj@732: *
mas01mj@732: * If you're building a Flex application, you will need to
mas01mj@732: * extend the FlexRunner
mas01mj@732: *
mas01mj@732: * Your concrete runner will usually look like the following:
mas01mj@732: *
mas01mj@732: * package {
mas01mj@732: * import asunit.textui.TestRunner;
mas01mj@732: *
mas01mj@732: * public class MyProjectRunner extends TestRunner {
mas01mj@732: *
mas01mj@732: * public function MyProjectRunner() {
mas01mj@732: * // start(clazz:Class, methodName:String, showTrace:Boolean)
mas01mj@732: * // NOTE: sending a particular class and method name will
mas01mj@732: * // execute setUp(), the method and NOT tearDown.
mas01mj@732: * // This allows you to get visual confirmation while developing
mas01mj@732: * // visual entities
mas01mj@732: * start(AllTests, null, TestRunner.SHOW_TRACE);
mas01mj@732: * }
mas01mj@732: * }
mas01mj@732: * }
mas01mj@732: *
mas01mj@732: *
mas01mj@732: * @includeExample TestRunnerExample.as
mas01mj@732: *
mas01mj@732: * @see asunit.textui.FlexRunner
mas01mj@732: * @see asunit.textui.AirRunner
mas01mj@732: * @see asunit.textui.XMLResultPrinter
mas01mj@732: **/
mas01mj@732: public class TestRunner extends MovieClip {
mas01mj@732: public static const SUCCESS_EXIT:int = 0;
mas01mj@732: public static const FAILURE_EXIT:int = 1;
mas01mj@732: public static const EXCEPTION_EXIT:int = 2;
mas01mj@732: public static const SHOW_TRACE:Boolean = true;
mas01mj@732: protected var fPrinter:ResultPrinter;
mas01mj@732: protected var startTime:Number;
mas01mj@732: protected var result:TestResult;
mas01mj@732:
mas01mj@732: public function TestRunner() {
mas01mj@732: configureListeners();
mas01mj@732: }
mas01mj@732:
mas01mj@732: private function configureListeners():void {
mas01mj@732: addEventListener(Event.ADDED_TO_STAGE, addedHandler);
mas01mj@732: addEventListener(Event.ADDED, addedHandler);
mas01mj@732: }
mas01mj@732:
mas01mj@732: protected function addedHandler(event:Event):void {
mas01mj@732: if (!stage)
mas01mj@732: {
mas01mj@732: return;
mas01mj@732: }
mas01mj@732: if(event.target === fPrinter) {
mas01mj@732: stage.align = StageAlign.TOP_LEFT;
mas01mj@732: stage.scaleMode = StageScaleMode.NO_SCALE;
mas01mj@732: stage.addEventListener(Event.RESIZE, resizeHandler);
mas01mj@732: resizeHandler(new Event("resize"));
mas01mj@732: }
mas01mj@732: }
mas01mj@732:
mas01mj@732: private function resizeHandler(event:Event):void {
mas01mj@732: fPrinter.width = stage.stageWidth;
mas01mj@732: fPrinter.height = stage.stageHeight;
mas01mj@732: }
mas01mj@732:
mas01mj@732: /**
mas01mj@732: * Starts a test run based on the TestCase
or TestSuite
provided.
mas01mj@732: *
mas01mj@732: * If a concrete TestCase
is provided to the start
method,
mas01mj@732: * you can also provide the string name of a single test method to execute.
mas01mj@732: *
mas01mj@732: * This will run the TestCase
setUp
method, then
mas01mj@732: * the test method name that was provided, and will not run tearDown
.
mas01mj@732: *
mas01mj@732: * This is a great way to build visual components in isolation and verify that they
mas01mj@732: * behave as expected.
mas01mj@732: *
mas01mj@732: * @example The start method can accept a concrete test case and test method name:
mas01mj@732: *
mas01mj@732: * start(MyTestCase, 'myTestMethod');
mas01mj@732: *
mas01mj@732: *
mas01mj@732: * @example The start method usually accepts a test suite that includes all of your
mas01mj@732: * test methods.
mas01mj@732: *
mas01mj@732: * start(AllTests, null, TestRunner.SHOW_TRACE);
mas01mj@732: *
mas01mj@732: *
mas01mj@732: * @see TestSuite
mas01mj@732: */
mas01mj@732: public function start(testCase:Class, testMethod:String = null, showTrace:Boolean = false):TestResult {
mas01mj@732: // fscommand("showmenu", "false");
mas01mj@732: try {
mas01mj@732: var instance:Test;
mas01mj@732: if(testMethod != null) {
mas01mj@732: instance = new testCase(testMethod);
mas01mj@732: }
mas01mj@732: else {
mas01mj@732: instance = new testCase();
mas01mj@732: }
mas01mj@732: return doRun(instance, showTrace);
mas01mj@732: }
mas01mj@732: catch(e:Error) {
mas01mj@732: throw new Error("Could not create and run test suite: " + e.getStackTrace());
mas01mj@732: }
mas01mj@732: return null;
mas01mj@732: }
mas01mj@732:
mas01mj@732: public function doRun(test:Test, showTrace:Boolean = false):TestResult {
mas01mj@732:
mas01mj@732: result = new TestResult();
mas01mj@732:
mas01mj@732: if (test.getIsComplete())
mas01mj@732: return result;
mas01mj@732:
mas01mj@732: if(fPrinter == null) {
mas01mj@732: setPrinter(new ResultPrinter(showTrace));
mas01mj@732: }
mas01mj@732: else {
mas01mj@732: fPrinter.setShowTrace(showTrace);
mas01mj@732: }
mas01mj@732: result.addListener(getPrinter());
mas01mj@732: startTime = getTimer();
mas01mj@732: test.setResult(result);
mas01mj@732: test.setContext(this);
mas01mj@732: test.addEventListener(Event.COMPLETE, testCompleteHandler);
mas01mj@732: test.run();
mas01mj@732: return result;
mas01mj@732: }
mas01mj@732:
mas01mj@732: private function testCompleteHandler(event:Event):void {
mas01mj@732: var endTime:Number = getTimer();
mas01mj@732: var runTime:Number = endTime - startTime;
mas01mj@732: getPrinter().printResult(result, runTime);
mas01mj@732: }
mas01mj@732:
mas01mj@732: public function setPrinter(printer:ResultPrinter):void {
mas01mj@732: if(fPrinter is DisplayObject && getChildIndex(fPrinter)) {
mas01mj@732: removeChild(fPrinter);
mas01mj@732: }
mas01mj@732:
mas01mj@732: fPrinter = printer;
mas01mj@732: if(fPrinter is DisplayObject) {
mas01mj@732: addChild(fPrinter);
mas01mj@732: }
mas01mj@732: }
mas01mj@732:
mas01mj@732: public function getPrinter():ResultPrinter {
mas01mj@732: return fPrinter;
mas01mj@732: }
mas01mj@732: }
mas01mj@732: }