mas01mj@732
|
1 package asunit.textui {
|
mas01mj@732
|
2 import asunit.framework.Test;
|
mas01mj@732
|
3 import asunit.framework.TestResult;
|
mas01mj@732
|
4
|
mas01mj@732
|
5 import flash.display.MovieClip;
|
mas01mj@732
|
6 import flash.display.StageAlign;
|
mas01mj@732
|
7 import flash.display.StageScaleMode;
|
mas01mj@732
|
8 import flash.events.Event;
|
mas01mj@732
|
9 import flash.system.fscommand;
|
mas01mj@732
|
10 import flash.utils.clearInterval;
|
mas01mj@732
|
11 import flash.utils.describeType;
|
mas01mj@732
|
12 import flash.utils.getTimer;
|
mas01mj@732
|
13 import flash.utils.setInterval;
|
mas01mj@732
|
14 import flash.utils.Timer;
|
mas01mj@732
|
15 import flash.events.TimerEvent;
|
mas01mj@732
|
16 import flash.display.DisplayObject;
|
mas01mj@732
|
17
|
mas01mj@732
|
18 /**
|
mas01mj@732
|
19 * The base class for ActionScript 3.0 test harness.
|
mas01mj@732
|
20 *
|
mas01mj@732
|
21 * The <code>TestRunner</code> should be extended by your
|
mas01mj@732
|
22 * concrete runner for your project.
|
mas01mj@732
|
23 *
|
mas01mj@732
|
24 * If you're building a Flex application, you will need to
|
mas01mj@732
|
25 * extend the <code>FlexRunner</code>
|
mas01mj@732
|
26 *
|
mas01mj@732
|
27 * Your concrete runner will usually look like the following:
|
mas01mj@732
|
28 * <listing>
|
mas01mj@732
|
29 * package {
|
mas01mj@732
|
30 * import asunit.textui.TestRunner;
|
mas01mj@732
|
31 *
|
mas01mj@732
|
32 * public class MyProjectRunner extends TestRunner {
|
mas01mj@732
|
33 *
|
mas01mj@732
|
34 * public function MyProjectRunner() {
|
mas01mj@732
|
35 * // start(clazz:Class, methodName:String, showTrace:Boolean)
|
mas01mj@732
|
36 * // NOTE: sending a particular class and method name will
|
mas01mj@732
|
37 * // execute setUp(), the method and NOT tearDown.
|
mas01mj@732
|
38 * // This allows you to get visual confirmation while developing
|
mas01mj@732
|
39 * // visual entities
|
mas01mj@732
|
40 * start(AllTests, null, TestRunner.SHOW_TRACE);
|
mas01mj@732
|
41 * }
|
mas01mj@732
|
42 * }
|
mas01mj@732
|
43 * }
|
mas01mj@732
|
44 * </listing>
|
mas01mj@732
|
45 *
|
mas01mj@732
|
46 * @includeExample TestRunnerExample.as
|
mas01mj@732
|
47 *
|
mas01mj@732
|
48 * @see asunit.textui.FlexRunner
|
mas01mj@732
|
49 * @see asunit.textui.AirRunner
|
mas01mj@732
|
50 * @see asunit.textui.XMLResultPrinter
|
mas01mj@732
|
51 **/
|
mas01mj@732
|
52 public class TestRunner extends MovieClip {
|
mas01mj@732
|
53 public static const SUCCESS_EXIT:int = 0;
|
mas01mj@732
|
54 public static const FAILURE_EXIT:int = 1;
|
mas01mj@732
|
55 public static const EXCEPTION_EXIT:int = 2;
|
mas01mj@732
|
56 public static const SHOW_TRACE:Boolean = true;
|
mas01mj@732
|
57 protected var fPrinter:ResultPrinter;
|
mas01mj@732
|
58 protected var startTime:Number;
|
mas01mj@732
|
59 protected var result:TestResult;
|
mas01mj@732
|
60
|
mas01mj@732
|
61 public function TestRunner() {
|
mas01mj@732
|
62 configureListeners();
|
mas01mj@732
|
63 }
|
mas01mj@732
|
64
|
mas01mj@732
|
65 private function configureListeners():void {
|
mas01mj@732
|
66 addEventListener(Event.ADDED_TO_STAGE, addedHandler);
|
mas01mj@732
|
67 addEventListener(Event.ADDED, addedHandler);
|
mas01mj@732
|
68 }
|
mas01mj@732
|
69
|
mas01mj@732
|
70 protected function addedHandler(event:Event):void {
|
mas01mj@732
|
71 if (!stage)
|
mas01mj@732
|
72 {
|
mas01mj@732
|
73 return;
|
mas01mj@732
|
74 }
|
mas01mj@732
|
75 if(event.target === fPrinter) {
|
mas01mj@732
|
76 stage.align = StageAlign.TOP_LEFT;
|
mas01mj@732
|
77 stage.scaleMode = StageScaleMode.NO_SCALE;
|
mas01mj@732
|
78 stage.addEventListener(Event.RESIZE, resizeHandler);
|
mas01mj@732
|
79 resizeHandler(new Event("resize"));
|
mas01mj@732
|
80 }
|
mas01mj@732
|
81 }
|
mas01mj@732
|
82
|
mas01mj@732
|
83 private function resizeHandler(event:Event):void {
|
mas01mj@732
|
84 fPrinter.width = stage.stageWidth;
|
mas01mj@732
|
85 fPrinter.height = stage.stageHeight;
|
mas01mj@732
|
86 }
|
mas01mj@732
|
87
|
mas01mj@732
|
88 /**
|
mas01mj@732
|
89 * Starts a test run based on the <code>TestCase</code> or <code>TestSuite</code> provided.
|
mas01mj@732
|
90 *
|
mas01mj@732
|
91 * If a concrete <code>TestCase</code> is provided to the <code>start</code> method,
|
mas01mj@732
|
92 * you can also provide the string name of a single test method to execute.
|
mas01mj@732
|
93 *
|
mas01mj@732
|
94 * This will run the <code>TestCase</code> <code>setUp</code> method, then
|
mas01mj@732
|
95 * the test method name that was provided, and will <em>not</em> run <code>tearDown</code>.
|
mas01mj@732
|
96 *
|
mas01mj@732
|
97 * This is a great way to build visual components in isolation and verify that they
|
mas01mj@732
|
98 * behave as expected.
|
mas01mj@732
|
99 *
|
mas01mj@732
|
100 * @example The start method can accept a concrete test case and test method name:
|
mas01mj@732
|
101 * <listing>
|
mas01mj@732
|
102 * start(MyTestCase, 'myTestMethod');
|
mas01mj@732
|
103 * </listing>
|
mas01mj@732
|
104 *
|
mas01mj@732
|
105 * @example The start method usually accepts a test suite that includes all of your
|
mas01mj@732
|
106 * test methods.
|
mas01mj@732
|
107 * <listing>
|
mas01mj@732
|
108 * start(AllTests, null, TestRunner.SHOW_TRACE);
|
mas01mj@732
|
109 * </listing>
|
mas01mj@732
|
110 *
|
mas01mj@732
|
111 * @see TestSuite
|
mas01mj@732
|
112 */
|
mas01mj@732
|
113 public function start(testCase:Class, testMethod:String = null, showTrace:Boolean = false):TestResult {
|
mas01mj@732
|
114 // fscommand("showmenu", "false");
|
mas01mj@732
|
115 try {
|
mas01mj@732
|
116 var instance:Test;
|
mas01mj@732
|
117 if(testMethod != null) {
|
mas01mj@732
|
118 instance = new testCase(testMethod);
|
mas01mj@732
|
119 }
|
mas01mj@732
|
120 else {
|
mas01mj@732
|
121 instance = new testCase();
|
mas01mj@732
|
122 }
|
mas01mj@732
|
123 return doRun(instance, showTrace);
|
mas01mj@732
|
124 }
|
mas01mj@732
|
125 catch(e:Error) {
|
mas01mj@732
|
126 throw new Error("Could not create and run test suite: " + e.getStackTrace());
|
mas01mj@732
|
127 }
|
mas01mj@732
|
128 return null;
|
mas01mj@732
|
129 }
|
mas01mj@732
|
130
|
mas01mj@732
|
131 public function doRun(test:Test, showTrace:Boolean = false):TestResult {
|
mas01mj@732
|
132
|
mas01mj@732
|
133 result = new TestResult();
|
mas01mj@732
|
134
|
mas01mj@732
|
135 if (test.getIsComplete())
|
mas01mj@732
|
136 return result;
|
mas01mj@732
|
137
|
mas01mj@732
|
138 if(fPrinter == null) {
|
mas01mj@732
|
139 setPrinter(new ResultPrinter(showTrace));
|
mas01mj@732
|
140 }
|
mas01mj@732
|
141 else {
|
mas01mj@732
|
142 fPrinter.setShowTrace(showTrace);
|
mas01mj@732
|
143 }
|
mas01mj@732
|
144 result.addListener(getPrinter());
|
mas01mj@732
|
145 startTime = getTimer();
|
mas01mj@732
|
146 test.setResult(result);
|
mas01mj@732
|
147 test.setContext(this);
|
mas01mj@732
|
148 test.addEventListener(Event.COMPLETE, testCompleteHandler);
|
mas01mj@732
|
149 test.run();
|
mas01mj@732
|
150 return result;
|
mas01mj@732
|
151 }
|
mas01mj@732
|
152
|
mas01mj@732
|
153 private function testCompleteHandler(event:Event):void {
|
mas01mj@732
|
154 var endTime:Number = getTimer();
|
mas01mj@732
|
155 var runTime:Number = endTime - startTime;
|
mas01mj@732
|
156 getPrinter().printResult(result, runTime);
|
mas01mj@732
|
157 }
|
mas01mj@732
|
158
|
mas01mj@732
|
159 public function setPrinter(printer:ResultPrinter):void {
|
mas01mj@732
|
160 if(fPrinter is DisplayObject && getChildIndex(fPrinter)) {
|
mas01mj@732
|
161 removeChild(fPrinter);
|
mas01mj@732
|
162 }
|
mas01mj@732
|
163
|
mas01mj@732
|
164 fPrinter = printer;
|
mas01mj@732
|
165 if(fPrinter is DisplayObject) {
|
mas01mj@732
|
166 addChild(fPrinter);
|
mas01mj@732
|
167 }
|
mas01mj@732
|
168 }
|
mas01mj@732
|
169
|
mas01mj@732
|
170 public function getPrinter():ResultPrinter {
|
mas01mj@732
|
171 return fPrinter;
|
mas01mj@732
|
172 }
|
mas01mj@732
|
173 }
|
mas01mj@732
|
174 } |