asunit4 4.2.2.pre → 4.2.3.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +26 -0
- data/bin/AsUnit-4.1.2.swc +0 -0
- data/bin/AsUnit-4.2.3.pre.swc +0 -0
- data/bin/AsUnitRunner.swf +0 -0
- data/bin/Flex4AsUnitRunner.swf +0 -0
- data/build.xml +42 -2
- data/lib/SwiftSuspenders-v1.5.1.swc +0 -0
- data/lib/flexUnitTasks.jar +0 -0
- data/pkg/sprout-asunit4-library-4.1.2.gem +0 -0
- data/rakefile.rb +4 -1
- data/sprout/lib/asunit4.rb +1 -1
- data/src/asunit/asserts/assertMatches.as +6 -0
- data/src/asunit/asserts/assertThrowsWithMessage.as +5 -0
- data/src/asunit/core/AsUnitCore.as +42 -88
- data/src/asunit/core/FlashBuilderCore.as +2 -2
- data/src/asunit/core/FlashDevelopCore.as +1 -1
- data/src/asunit/core/FlexUnitCICore.as +17 -0
- data/src/asunit/core/TextCore.as +36 -54
- data/src/asunit/framework/Assert.as +76 -11
- data/src/asunit/framework/Async.as +1 -1
- data/src/asunit/framework/IResult.as +1 -6
- data/src/asunit/framework/IRunListener.as +0 -3
- data/src/asunit/framework/IRunner.as +0 -3
- data/src/asunit/framework/IRunnerFactory.as +3 -3
- data/src/asunit/framework/ITestListener.as +1 -2
- data/src/asunit/framework/Method.as +82 -80
- data/src/asunit/framework/Result.as +3 -24
- data/src/asunit/framework/RunnerFactory.as +13 -34
- data/src/asunit/framework/SuiteIterator.as +28 -22
- data/src/asunit/framework/TestCase.as +8 -3
- data/src/asunit/printers/FlashBuilderPrinter.as +25 -83
- data/src/asunit/printers/FlashDevelopPrinter.as +1 -2
- data/src/asunit/printers/FlexUnitCIPrinter.as +181 -0
- data/src/asunit/printers/TextPrinter.as +17 -46
- data/src/asunit/printers/XMLPrinter.as +127 -0
- data/src/asunit/runners/LegacyRunner.as +6 -1
- data/src/asunit/runners/SuiteRunner.as +30 -66
- data/src/asunit/runners/TestRunner.as +90 -255
- data/test/AllTests.as +9 -4
- data/test/AsUnitCIRunner.as +18 -0
- data/test/AsUnitRunner.as +2 -0
- data/test/AsUnitRunnerCS3.fla +0 -0
- data/test/asunit/core/AsUnitCoreTest.as +33 -15
- data/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as +14 -0
- data/test/asunit/framework/AssertThrowsWithMessageTest.as +50 -0
- data/test/asunit/framework/AsyncTest.as +0 -4
- data/test/asunit/framework/ProceedOnEventTest.as +1 -2
- data/test/asunit/framework/ResultObserverTest.as +61 -0
- data/test/asunit/framework/RunnerFactoryTest.as +7 -9
- data/test/asunit/framework/VisualTestCaseTest.as +2 -26
- data/test/asunit/printers/FlashBuilderPrinterTest.as +18 -0
- data/test/asunit/printers/XMLPrinterTest.as +131 -0
- data/test/asunit/runners/LegacyRunnerTest.as +4 -4
- data/test/asunit/runners/SuiteRunnerTest.as +10 -7
- data/test/asunit/runners/TestRunnerAsyncMethodTest.as +9 -7
- data/test/asunit/runners/TestRunnerErrorMethodTest.as +1 -1
- data/test/asunit/runners/TestRunnerExpectsErrorTest.as +2 -2
- data/test/asunit/runners/TestRunnerExpectsErrorWithMessageTest.as +125 -0
- data/test/asunit/runners/TestRunnerIgnoredMethodTest.as +2 -3
- data/test/asunit/runners/TestRunnerTest.as +4 -27
- data/test/asunit/support/{CustomTestRunner.as → CustomSuiteRunner.as} +7 -3
- data/test/asunit/support/InjectionVerification.as +2 -30
- data/test/asunit/support/SuiteWithCustomRunner.as +1 -1
- data/vendor/as3injection/org/swiftsuspenders/InjectionConfig.as +78 -0
- data/vendor/as3injection/org/swiftsuspenders/InjectionType.as +16 -0
- data/vendor/as3injection/org/swiftsuspenders/Injector.as +376 -0
- data/vendor/as3injection/org/swiftsuspenders/InjectorError.as +17 -0
- data/vendor/as3injection/org/swiftsuspenders/Reflector.as +95 -0
- data/vendor/as3injection/org/swiftsuspenders/getConstructor.as +33 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionpoints/ConstructorInjectionPoint.as +94 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionpoints/InjectionPoint.as +35 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionpoints/MethodInjectionPoint.as +122 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionpoints/NoParamsConstructorInjectionPoint.as +24 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionpoints/PostConstructInjectionPoint.as +52 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as +62 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectClassResult.as +33 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectOtherRuleResult.as +34 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectSingletonResult.as +43 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectValueResult.as +33 -0
- data/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectionResult.as +26 -0
- metadata +44 -19
- data/bin/AsUnit-4.2.1.pre.swc +0 -0
- data/bin/AsUnit-4.2.2.pre.swc +0 -0
- data/src/asunit/framework/CallbackBridge.as +0 -175
- data/src/asunit/framework/ITestResult.as +0 -21
- data/src/asunit/framework/InjectionDelegate.as +0 -96
- data/src/asunit/framework/MessageBridge.as +0 -24
- data/src/asunit/framework/TestObserver.as +0 -12
- data/test/asunit/framework/CallbackBridgeTest.as +0 -73
- data/test/asunit/framework/InjectionDelegateTest.as +0 -79
- data/test/asunit/support/AnnotatedSubClass.as +0 -18
- data/test/asunit/support/AnnotatedSuperClass.as +0 -15
- data/test/asunit/support/FakeRunner.as +0 -32
- data/test/asunit/support/InjectTimeoutOnAsync.as +0 -14
- data/test/asunit/support/TestForFakeRunner.as +0 -14
@@ -17,28 +17,31 @@ package asunit.printers {
|
|
17
17
|
import flash.text.TextFormat;
|
18
18
|
import flash.utils.getQualifiedClassName;
|
19
19
|
import flash.utils.getTimer;
|
20
|
-
import asunit.framework.CallbackBridge;
|
21
20
|
|
22
21
|
public class TextPrinter extends Sprite implements IRunListener {
|
23
|
-
public static
|
24
|
-
public static
|
25
|
-
public static
|
26
|
-
public static
|
27
|
-
public static
|
22
|
+
public static const LOCAL_PATH_PATTERN:RegExp = /([A-Z]:\\[^\/:\*\?<>\|]+\.\w{2,6})|(\\{2}[^\/:\*\?<>\|]+\.\w{2,6})/g;
|
23
|
+
public static const DEFAULT_BACKGROUND_COLOR:uint = 0x333333;
|
24
|
+
public static const DEFAULT_HEADER:String = "AsUnit 4.0 by Luke Bayes, Ali Mills and Robert Penner\n\nFlash Player version: " + Capabilities.version
|
25
|
+
public static const DEFAULT_FOOTER:String = "";
|
26
|
+
public static const DEFAULT_FONT_SIZE:int = 12;
|
27
|
+
public static const DEFAULT_PERFORMANCE_COUNT:int = 10;
|
28
|
+
public static const DEFAULT_TEXT_COLOR:uint = 0xffffff;
|
28
29
|
|
29
|
-
public var
|
30
|
+
public var header:String = DEFAULT_HEADER;
|
31
|
+
public var footer:String = DEFAULT_FOOTER;
|
32
|
+
public var backgroundColor:uint = DEFAULT_BACKGROUND_COLOR;
|
33
|
+
public var textColor:uint = DEFAULT_TEXT_COLOR;
|
30
34
|
public var displayPerformanceDetails:Boolean = true;
|
31
|
-
public var localPathPattern:RegExp;
|
32
|
-
public var textColor:uint = TEXT_COLOR;
|
33
35
|
public var traceOnComplete:Boolean = true;
|
36
|
+
public var hideLocalPaths:Boolean = false;
|
37
|
+
public var localPathPattern:RegExp = LOCAL_PATH_PATTERN;
|
38
|
+
public var performanceCount:int = DEFAULT_PERFORMANCE_COUNT;
|
34
39
|
|
35
40
|
protected var textDisplay:TextField;
|
36
41
|
|
37
42
|
private var backgroundFill:Shape;
|
38
43
|
private var dots:Array;
|
39
44
|
private var failures:Array;
|
40
|
-
private var footer:String;
|
41
|
-
private var header:String;
|
42
45
|
private var ignores:Array;
|
43
46
|
private var resultBar:Shape;
|
44
47
|
private var resultBarHeight:uint = 3;
|
@@ -48,34 +51,6 @@ package asunit.printers {
|
|
48
51
|
private var testTimes:Array;
|
49
52
|
private var warnings:Array;
|
50
53
|
|
51
|
-
/**
|
52
|
-
* The bridge provides the connection between the printer
|
53
|
-
* and the Runner(s) that it's interested in.
|
54
|
-
*
|
55
|
-
* Generally, a bridge can observe Runners, and build up
|
56
|
-
* state over the course of a test run.
|
57
|
-
*
|
58
|
-
* If you create a custom Runner, Printer and Bridge,
|
59
|
-
* you can decide to manage notifications however you wish.
|
60
|
-
*
|
61
|
-
*/
|
62
|
-
private var _bridge:CallbackBridge;
|
63
|
-
|
64
|
-
[Inject]
|
65
|
-
public function set bridge(value:CallbackBridge):void
|
66
|
-
{
|
67
|
-
if (value !== _bridge)
|
68
|
-
{
|
69
|
-
_bridge = value;
|
70
|
-
_bridge.addObserver(this);
|
71
|
-
}
|
72
|
-
}
|
73
|
-
|
74
|
-
public function get bridge():CallbackBridge
|
75
|
-
{
|
76
|
-
return _bridge;
|
77
|
-
}
|
78
|
-
|
79
54
|
public function TextPrinter() {
|
80
55
|
initialize();
|
81
56
|
}
|
@@ -88,10 +63,6 @@ package asunit.printers {
|
|
88
63
|
testTimes = [];
|
89
64
|
warnings = [];
|
90
65
|
|
91
|
-
footer = '';
|
92
|
-
header = DEFAULT_HEADER;
|
93
|
-
localPathPattern = LOCAL_PATH_PATTERN;
|
94
|
-
|
95
66
|
if(stage) {
|
96
67
|
initializeDisplay();
|
97
68
|
} else {
|
@@ -117,7 +88,7 @@ package asunit.printers {
|
|
117
88
|
private function getFailureStackTrace(failure:ITestFailure):String {
|
118
89
|
var stack:String = "";
|
119
90
|
stack = failure.thrownException.getStackTrace();
|
120
|
-
|
91
|
+
if (hideLocalPaths) stack = stack.replace(localPathPattern, '');
|
121
92
|
stack = stack.replace(/AssertionFailedError: /, '');
|
122
93
|
stack += "\n\n";
|
123
94
|
return stack;
|
@@ -218,7 +189,7 @@ package asunit.printers {
|
|
218
189
|
println();
|
219
190
|
println('Time Summary:');
|
220
191
|
println();
|
221
|
-
var len:Number = testTimes.length;
|
192
|
+
var len:Number = Math.min(performanceCount, testTimes.length);
|
222
193
|
var total:Number = 0;
|
223
194
|
var testTime:Object;
|
224
195
|
for (var i:Number = 0; i < len; i++) {
|
@@ -310,7 +281,7 @@ package asunit.printers {
|
|
310
281
|
|
311
282
|
var format:TextFormat = textDisplay.getTextFormat();
|
312
283
|
format.font = '_sans';
|
313
|
-
format.size =
|
284
|
+
format.size = DEFAULT_FONT_SIZE;
|
314
285
|
format.leftMargin = 5;
|
315
286
|
format.rightMargin = 5;
|
316
287
|
textDisplay.defaultTextFormat = format;
|
@@ -0,0 +1,127 @@
|
|
1
|
+
|
2
|
+
package asunit.printers {
|
3
|
+
import asunit.framework.ITestFailure;
|
4
|
+
import asunit.framework.ITestWarning;
|
5
|
+
import asunit.framework.IResult;
|
6
|
+
import asunit.framework.IRunListener;
|
7
|
+
import asunit.framework.ITestSuccess;
|
8
|
+
import asunit.framework.Method;
|
9
|
+
|
10
|
+
import flash.events.Event;
|
11
|
+
import flash.events.IOErrorEvent;
|
12
|
+
import flash.events.SecurityErrorEvent;
|
13
|
+
import flash.utils.getQualifiedClassName;
|
14
|
+
|
15
|
+
/**
|
16
|
+
* The <code>XMLPrinter</code> is used to transform AsUnit test results
|
17
|
+
* to JUnit-compatible XML content.
|
18
|
+
*
|
19
|
+
* This printer will send JUnit-compatible XML content to trace output. The XML content
|
20
|
+
* will be enclosed by '<TestResults/>' tags.
|
21
|
+
**/
|
22
|
+
public class XMLPrinter implements IRunListener {
|
23
|
+
public var traceResults:Boolean = true;
|
24
|
+
|
25
|
+
protected var projectName:String;
|
26
|
+
protected var contextName:String;
|
27
|
+
protected var messageQueue:Array;
|
28
|
+
protected var testPrefix:String = "<TestResults>";
|
29
|
+
protected var testSuffix:String = "</TestResults>";
|
30
|
+
|
31
|
+
public function XMLPrinter(projectName:String = '', contextName:String = '') {
|
32
|
+
this.projectName = projectName;
|
33
|
+
this.contextName = contextName;
|
34
|
+
messageQueue = [];
|
35
|
+
}
|
36
|
+
|
37
|
+
public function onRunStarted():void {
|
38
|
+
if (testPrefix) {
|
39
|
+
sendMessage(testPrefix);
|
40
|
+
}
|
41
|
+
sendMessage("<startTestRun totalTestCount='0' projectName='" + projectName
|
42
|
+
+ "' contextName='" + contextName +"' />");
|
43
|
+
}
|
44
|
+
|
45
|
+
public function onRunCompleted(result:IResult):void {
|
46
|
+
sendMessage('<endOfTestRun />');
|
47
|
+
|
48
|
+
if (testSuffix) {
|
49
|
+
sendMessage("</TestResults>");
|
50
|
+
}
|
51
|
+
|
52
|
+
if (traceResults) {
|
53
|
+
trace(toString());
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
public function onTestStarted(test:Object):void {
|
58
|
+
}
|
59
|
+
|
60
|
+
public function onTestCompleted(test:Object):void {
|
61
|
+
}
|
62
|
+
|
63
|
+
// works for both errors and failures
|
64
|
+
public function onTestFailure(failure:ITestFailure):void {
|
65
|
+
sendMessage(getFailureMessage(failure));
|
66
|
+
}
|
67
|
+
|
68
|
+
public function onTestSuccess(success:ITestSuccess):void {
|
69
|
+
var xmlMessageSuccess:String = "<testCase name='" + success.method
|
70
|
+
+ "' testSuite='" + getQualifiedClassName(success.test) + "' status='success'/>";
|
71
|
+
sendMessage(xmlMessageSuccess);
|
72
|
+
}
|
73
|
+
|
74
|
+
public function onTestIgnored(method:Method):void {
|
75
|
+
var xmlMessageIgnore:String = "<testCase name='" + method.name
|
76
|
+
+ "' testSuite='" + getQualifiedClassName(method.scope) + "' status='ignore'/>";
|
77
|
+
sendMessage(xmlMessageIgnore);
|
78
|
+
}
|
79
|
+
|
80
|
+
public function onWarning(warning:ITestWarning):void {
|
81
|
+
var xmlMessage:String = "<testCase name='" + warning.method.name
|
82
|
+
+ "' testSuite='" + getQualifiedClassName(warning.method.scope) + "' status='warning'/>";
|
83
|
+
sendMessage(xmlMessage);
|
84
|
+
}
|
85
|
+
|
86
|
+
public function toString():String {
|
87
|
+
return messageQueue.join("\n");
|
88
|
+
}
|
89
|
+
|
90
|
+
protected function sendMessage(message:String):void {
|
91
|
+
messageQueue.push(message);
|
92
|
+
}
|
93
|
+
|
94
|
+
protected function getFailureMessage(failure:ITestFailure):String {
|
95
|
+
var status:String = failure.isFailure ? 'failure' : 'error';
|
96
|
+
var xml:String =
|
97
|
+
"<testCase name='" + failure.failedMethod
|
98
|
+
+ "' testSuite='" + getQualifiedClassName(failure.failedTest)
|
99
|
+
+ "' status='" + status + "'>"
|
100
|
+
+ "<failure type='" + getQualifiedClassName(failure.thrownException) + "' >"
|
101
|
+
|
102
|
+
+ "<messageInfo>" + xmlEscapeMessage(failure.exceptionMessage)
|
103
|
+
+ "</messageInfo>"
|
104
|
+
|
105
|
+
+ "<stackTraceInfo>" + xmlEscapeMessage(failure.thrownException.getStackTrace())
|
106
|
+
+ "</stackTraceInfo>"
|
107
|
+
|
108
|
+
+ "</failure>"
|
109
|
+
+ "</testCase>";
|
110
|
+
|
111
|
+
return xml;
|
112
|
+
}
|
113
|
+
|
114
|
+
protected static function xmlEscapeMessage(message:String):String {
|
115
|
+
if (!message) return '';
|
116
|
+
|
117
|
+
var escape:XML = <escape/>;
|
118
|
+
escape.setChildren( message );
|
119
|
+
return escape.children()[0].toXMLString();
|
120
|
+
}
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
@@ -1,11 +1,16 @@
|
|
1
1
|
package asunit.runners {
|
2
2
|
|
3
|
+
import asunit.framework.IResult;
|
3
4
|
import asunit.framework.LegacyTestIterator;
|
4
5
|
import asunit.framework.TestIterator;
|
5
6
|
|
6
7
|
public class LegacyRunner extends TestRunner {
|
7
8
|
|
8
|
-
|
9
|
+
public function LegacyRunner(result:IResult = null) {
|
10
|
+
super(result);
|
11
|
+
}
|
12
|
+
|
13
|
+
override protected function createTestIterator(test:*, testMethodName:String):TestIterator {
|
9
14
|
return new LegacyTestIterator(test, testMethodName);
|
10
15
|
}
|
11
16
|
}
|
@@ -1,41 +1,41 @@
|
|
1
1
|
package asunit.runners {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
import flash.display.DisplayObjectContainer;
|
12
|
-
import flash.events.Event;
|
13
|
-
import flash.events.EventDispatcher;
|
14
|
-
import flash.events.IEventDispatcher;
|
15
|
-
import flash.events.TimerEvent;
|
16
|
-
import flash.utils.Timer;
|
17
|
-
import flash.utils.getDefinitionByName;
|
2
|
+
|
3
|
+
import asunit.framework.IResult;
|
4
|
+
import asunit.framework.IRunner;
|
5
|
+
import asunit.framework.IRunnerFactory;
|
6
|
+
import asunit.framework.Result;
|
7
|
+
import asunit.framework.RunnerFactory;
|
8
|
+
import asunit.framework.SuiteIterator;
|
9
|
+
import asunit.util.Iterator;
|
10
|
+
import org.swiftsuspenders.Injector;
|
18
11
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
import flash.display.DisplayObjectContainer;
|
13
|
+
import flash.events.Event;
|
14
|
+
import flash.events.EventDispatcher;
|
15
|
+
import flash.events.TimerEvent;
|
16
|
+
import flash.utils.Timer;
|
17
|
+
|
18
|
+
public class SuiteRunner extends EventDispatcher implements IRunner {
|
23
19
|
|
24
|
-
|
25
|
-
public var bridge:CallbackBridge;
|
20
|
+
public var result:IResult;
|
26
21
|
|
27
|
-
protected var dispatcher:IEventDispatcher;
|
28
22
|
protected var testClasses:Iterator;
|
29
23
|
protected var timer:Timer;
|
30
24
|
protected var visualContext:DisplayObjectContainer;
|
31
25
|
protected var testMethod:String;
|
32
|
-
|
33
|
-
|
26
|
+
protected var injector:Injector;
|
27
|
+
protected var factory:IRunnerFactory;
|
34
28
|
|
35
|
-
public function SuiteRunner() {
|
36
|
-
timer
|
37
|
-
|
38
|
-
|
29
|
+
public function SuiteRunner(factory:IRunnerFactory = null, result:IResult = null, injector:Injector = null) {
|
30
|
+
timer = new Timer(0, 1);
|
31
|
+
|
32
|
+
this.injector = injector ||= new Injector();
|
33
|
+
injector.mapValue(Injector, injector);
|
34
|
+
this.result = result ||= new Result();
|
35
|
+
injector.mapValue(IResult, result);
|
36
|
+
this.factory = factory ||= injector.instantiate(RunnerFactory);
|
37
|
+
injector.mapValue(IRunnerFactory, factory);
|
38
|
+
}
|
39
39
|
|
40
40
|
public function run(suite:Class, testMethod:String=null, visualContext:DisplayObjectContainer=null):void {
|
41
41
|
this.visualContext = visualContext;
|
@@ -43,20 +43,8 @@ package asunit.runners {
|
|
43
43
|
runSuite(suite);
|
44
44
|
}
|
45
45
|
|
46
|
-
public function shouldRunTest(testClass:Class):Boolean {
|
47
|
-
return bridge.shouldRunTest(testClass);
|
48
|
-
}
|
49
|
-
|
50
|
-
public function set factory(factory:IRunnerFactory):void {
|
51
|
-
_factory = factory;
|
52
|
-
}
|
53
|
-
|
54
|
-
public function get factory():IRunnerFactory {
|
55
|
-
return _factory ||= new RunnerFactory();
|
56
|
-
}
|
57
|
-
|
58
46
|
protected function runSuite(suite:*):void {
|
59
|
-
testClasses = new SuiteIterator(suite
|
47
|
+
testClasses = new SuiteIterator(suite);
|
60
48
|
timer.addEventListener(TimerEvent.TIMER, runNextTest);
|
61
49
|
|
62
50
|
runNextTest();
|
@@ -97,29 +85,5 @@ package asunit.runners {
|
|
97
85
|
*/
|
98
86
|
protected function onRunCompleted():void {
|
99
87
|
}
|
100
|
-
|
101
|
-
// BEGIN: Implement the IEvent Dispatcher Interface:
|
102
|
-
|
103
|
-
public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void {
|
104
|
-
dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
|
105
|
-
}
|
106
|
-
|
107
|
-
public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void {
|
108
|
-
dispatcher.removeEventListener(type, listener, useCapture);
|
109
|
-
}
|
110
|
-
|
111
|
-
public function dispatchEvent(event:Event):Boolean {
|
112
|
-
return dispatcher.dispatchEvent(event);
|
113
|
-
}
|
114
|
-
|
115
|
-
public function hasEventListener(type:String):Boolean {
|
116
|
-
return dispatcher.hasEventListener(type);
|
117
|
-
}
|
118
|
-
|
119
|
-
public function willTrigger(type:String):Boolean {
|
120
|
-
return dispatcher.willTrigger(type);
|
121
|
-
}
|
122
|
-
|
123
|
-
// END: Implement the IEvent Dispatcher Interface:
|
124
88
|
}
|
125
89
|
}
|
@@ -1,63 +1,52 @@
|
|
1
1
|
package asunit.runners {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
|
3
|
+
import asunit.events.TimeoutCommandEvent;
|
4
|
+
import asunit.framework.Assert;
|
5
|
+
import asunit.framework.Async;
|
6
|
+
import asunit.framework.IResult;
|
7
|
+
import asunit.framework.Result;
|
8
|
+
import asunit.framework.IAsync;
|
9
|
+
import asunit.framework.IRunner;
|
10
10
|
import asunit.framework.IRunnerFactory;
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
import p2.reflect.ReflectionMetaData;
|
34
|
-
import p2.reflect.ReflectionVariable;
|
11
|
+
import asunit.framework.Method;
|
12
|
+
import asunit.framework.TestFailure;
|
13
|
+
import asunit.framework.TestIterator;
|
14
|
+
import asunit.framework.TestSuccess;
|
15
|
+
import asunit.framework.TestWarning;
|
16
|
+
import asunit.util.ArrayIterator;
|
17
|
+
import asunit.util.Iterator;
|
18
|
+
import flash.display.Sprite;
|
19
|
+
import org.swiftsuspenders.Injector;
|
20
|
+
|
21
|
+
import p2.reflect.Reflection;
|
22
|
+
import p2.reflect.ReflectionMetaData;
|
23
|
+
import p2.reflect.ReflectionVariable;
|
24
|
+
|
25
|
+
import flash.display.DisplayObjectContainer;
|
26
|
+
import flash.errors.IllegalOperationError;
|
27
|
+
import flash.events.Event;
|
28
|
+
import flash.events.EventDispatcher;
|
29
|
+
import flash.events.TimerEvent;
|
30
|
+
import flash.utils.Timer;
|
31
|
+
import flash.utils.getDefinitionByName;
|
32
|
+
import flash.utils.getTimer;
|
35
33
|
|
36
34
|
public class TestRunner extends EventDispatcher implements IRunner {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
* The AsUnitCore will inject the requested bridge
|
44
|
-
* based on the concrete data type.
|
45
|
-
*
|
46
|
-
* There should be a similar Injection point on
|
47
|
-
* whatever printers are interested in what this
|
48
|
-
* concrete runner will dispatch.
|
49
|
-
*/
|
50
|
-
[Inject]
|
51
|
-
public var bridge:CallbackBridge;
|
35
|
+
|
36
|
+
/**
|
37
|
+
*
|
38
|
+
*/
|
39
|
+
//TODO: perhaps add a getter for this to IRunner
|
40
|
+
public var result:IResult;
|
52
41
|
|
53
42
|
// partially exposed for unit testing
|
54
43
|
internal var currentTest:Object;
|
55
44
|
internal var async:IAsync;
|
45
|
+
/** Supplies dependencies to tests, e.g. IAsync, context Sprite. */
|
46
|
+
internal var testInjector:Injector;
|
56
47
|
|
57
|
-
protected var asyncMembers:Iterator;
|
58
48
|
protected var currentMethod:Method;
|
59
49
|
protected var currentTestReflection:Reflection;
|
60
|
-
protected var injectableMembers:Iterator;
|
61
50
|
protected var methodIsExecuting:Boolean = false;
|
62
51
|
protected var methodPassed:Boolean = true;
|
63
52
|
protected var methodTimeoutID:Number;
|
@@ -68,100 +57,80 @@ package asunit.runners {
|
|
68
57
|
protected var visualContext:DisplayObjectContainer;
|
69
58
|
protected var visualInstances:Array;
|
70
59
|
|
71
|
-
|
72
|
-
|
73
|
-
public function TestRunner() {
|
60
|
+
public function TestRunner(result:IResult = null) {
|
74
61
|
async = new Async();
|
75
|
-
|
76
|
-
|
77
|
-
|
62
|
+
this.result = result ||= new Result();
|
63
|
+
testInjector = new Injector();
|
64
|
+
testInjector.mapValue(IAsync, async);
|
65
|
+
testInjector.mapValue(Async, async);
|
66
|
+
timer = new Timer(0, 1);
|
67
|
+
timer.addEventListener(TimerEvent.TIMER, runNextMethods);
|
78
68
|
visualInstances = [];
|
79
69
|
}
|
80
70
|
|
81
|
-
public function
|
82
|
-
|
83
|
-
}
|
84
|
-
|
85
|
-
public function shouldRunTest(testClass:Class):Boolean {
|
86
|
-
return bridge.shouldRunTest(testClass);
|
87
|
-
}
|
88
|
-
|
89
|
-
// This class doesn't really use the runner factory,
|
90
|
-
// since it represents a leaf node in the test
|
91
|
-
// hierarchy...
|
92
|
-
public function set factory(factory:IRunnerFactory):void {
|
93
|
-
_factory = factory;
|
71
|
+
public function runMethodByName(testOrSuite:Class, methodName:String=null, visualContext:DisplayObjectContainer=null):void {
|
72
|
+
run(testOrSuite, methodName, visualContext);
|
94
73
|
}
|
95
74
|
|
96
|
-
public function
|
97
|
-
|
98
|
-
}
|
99
|
-
|
100
|
-
public function runMethodByName(test:Class, methodName:String=null, visualContext:DisplayObjectContainer=null):void {
|
101
|
-
currentTestReflection = Reflection.create(test);
|
75
|
+
public function run(test:Class, methodName:String=null, visualContext:DisplayObjectContainer=null):void {
|
76
|
+
currentTestReflection = Reflection.create(test);
|
102
77
|
this.visualContext = visualContext;
|
78
|
+
testInjector.mapValue(Sprite, visualContext);
|
103
79
|
currentMethod = null;
|
104
80
|
testMethodNameReceived = (methodName != null);
|
105
81
|
|
106
82
|
try {
|
107
|
-
currentTest
|
83
|
+
currentTest = testInjector.instantiate(test);
|
108
84
|
}
|
109
85
|
catch(e:VerifyError) {
|
110
86
|
warn("Unable to instantiate provided test case with: " + currentTestReflection.name);
|
111
87
|
return;
|
112
88
|
}
|
113
89
|
|
114
|
-
initializeInjectableMembers();
|
115
|
-
|
116
90
|
async.addEventListener(TimeoutCommandEvent.CALLED, onAsyncMethodCalled);
|
117
91
|
async.addEventListener(TimeoutCommandEvent.TIMED_OUT, onAsyncMethodTimedOut);
|
118
92
|
|
119
93
|
startTime = getTimer();
|
120
|
-
|
94
|
+
result.onTestStarted(currentTest);
|
121
95
|
|
122
96
|
methodsToRun = createTestIterator(currentTest, methodName);
|
123
97
|
|
124
98
|
if(methodsToRun.length == 0) {
|
125
99
|
warn(">> We were unable to find any test methods in " + currentTestReflection.name + ". Did you set the --keep-as3-metadata flag?");
|
126
100
|
}
|
127
|
-
|
101
|
+
|
102
|
+
runNextMethods();
|
128
103
|
}
|
129
104
|
|
130
105
|
protected function createTestIterator(test:*, testMethodName:String):TestIterator {
|
131
106
|
return new TestIterator(test, testMethodName);
|
132
107
|
}
|
133
108
|
|
134
|
-
protected function
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
if (testCompleted) {
|
145
|
-
onTestCompleted();
|
146
|
-
return;
|
147
|
-
}
|
148
|
-
|
149
|
-
if(methodsToRun.readyToSetUp) {
|
150
|
-
prepareForSetUp();
|
151
|
-
}
|
152
|
-
|
153
|
-
runMethod(methodsToRun.next());
|
109
|
+
protected function runNextMethods(e:TimerEvent = null):void {
|
110
|
+
// Loop through as many as possible without hitting asynchronous tests.
|
111
|
+
// This keeps the call stack small.
|
112
|
+
while (methodsToRun.hasNext()) {
|
113
|
+
var hasAsyncPending:Boolean = runMethod(methodsToRun.next());
|
114
|
+
if (hasAsyncPending) return;
|
115
|
+
}
|
116
|
+
|
117
|
+
onTestCompleted();
|
154
118
|
}
|
155
119
|
|
156
|
-
|
157
|
-
|
120
|
+
/**
|
121
|
+
*
|
122
|
+
* @param method
|
123
|
+
* @return true if asynchronous calls are pending after calling the test method.
|
124
|
+
*/
|
125
|
+
protected function runMethod(method:Method):Boolean {
|
126
|
+
if (!method) return false;
|
158
127
|
currentMethod = method;
|
159
128
|
methodPassed = true; // innocent until proven guilty by recordFailure()
|
160
129
|
|
161
130
|
if (currentMethod.ignore) {
|
162
|
-
|
131
|
+
result.onTestIgnored(currentMethod);
|
163
132
|
onMethodCompleted();
|
164
|
-
return;
|
133
|
+
return false;
|
165
134
|
}
|
166
135
|
|
167
136
|
// This is used to prevent async callbacks from triggering onMethodCompleted too early.
|
@@ -170,7 +139,13 @@ package asunit.runners {
|
|
170
139
|
if (currentMethod.expects) {
|
171
140
|
try {
|
172
141
|
var errorClass:Class = getDefinitionByName(currentMethod.expects) as Class;
|
173
|
-
|
142
|
+
var errorMessage:String = currentMethod.message;
|
143
|
+
if(errorMessage == null) {
|
144
|
+
Assert.assertThrows(errorClass, currentMethod.value);
|
145
|
+
}
|
146
|
+
else {
|
147
|
+
Assert.assertThrowsWithMessage(errorClass, errorMessage, currentMethod.value);
|
148
|
+
}
|
174
149
|
}
|
175
150
|
catch(definitionError:ReferenceError) {
|
176
151
|
// NOTE: [luke] Added ReferenceError catch here b/c I had a bad class name in my expects.
|
@@ -192,22 +167,23 @@ package asunit.runners {
|
|
192
167
|
|
193
168
|
methodIsExecuting = false;
|
194
169
|
|
195
|
-
if (async.hasPending) return;
|
170
|
+
if (async.hasPending) return true;
|
196
171
|
|
197
172
|
onMethodCompleted();
|
173
|
+
return false;
|
198
174
|
}
|
199
175
|
|
200
|
-
protected function onMethodCompleted():void {
|
176
|
+
protected function onMethodCompleted(wasAsync:Boolean = false):void {
|
201
177
|
async.cancelPending();
|
202
178
|
|
203
179
|
if (currentMethod.isTest && methodPassed && !currentMethod.ignore) {
|
204
|
-
|
180
|
+
result.onTestSuccess(new TestSuccess(currentTest, currentMethod.name));
|
205
181
|
}
|
206
182
|
|
207
|
-
|
208
|
-
|
183
|
+
if (wasAsync)
|
184
|
+
runNextMethods();
|
209
185
|
|
210
|
-
// green thread for
|
186
|
+
// green thread for runNextMethods()
|
211
187
|
// This runs much slower in Flash Player 10.1.
|
212
188
|
//timer.reset();
|
213
189
|
//timer.start();
|
@@ -231,12 +207,12 @@ package asunit.runners {
|
|
231
207
|
|
232
208
|
protected function recordFailure(error:Error):void {
|
233
209
|
methodPassed = false;
|
234
|
-
|
210
|
+
result.onTestFailure(new TestFailure(currentTest, currentMethod.name, error));
|
235
211
|
}
|
236
212
|
|
237
213
|
protected function onAsyncMethodCompleted(event:Event = null):void {
|
238
214
|
if (!methodIsExecuting && !async.hasPending) {
|
239
|
-
onMethodCompleted();
|
215
|
+
onMethodCompleted(true);
|
240
216
|
}
|
241
217
|
}
|
242
218
|
|
@@ -245,158 +221,17 @@ package asunit.runners {
|
|
245
221
|
async.removeEventListener(TimeoutCommandEvent.TIMED_OUT, onAsyncMethodTimedOut);
|
246
222
|
async.cancelPending();
|
247
223
|
|
248
|
-
|
224
|
+
result.onTestCompleted(currentTest);
|
249
225
|
|
250
226
|
dispatchEvent(new Event(Event.COMPLETE));
|
251
227
|
}
|
252
228
|
|
253
229
|
protected function get testCompleted():Boolean {
|
254
230
|
return (!methodsToRun.hasNext() && !async.hasPending);
|
255
|
-
}
|
256
|
-
|
257
|
-
protected function removeInjectedMembers():void {
|
258
|
-
var member:ReflectionVariable;
|
259
|
-
while(injectableMembers.hasNext()) {
|
260
|
-
removeInjectedMember(injectableMembers.next());
|
261
|
-
}
|
262
|
-
injectableMembers.reset();
|
263
|
-
}
|
264
|
-
|
265
|
-
protected function removeInjectedVisualInstances():void {
|
266
|
-
var visuals:Iterator = new ArrayIterator(visualInstances);
|
267
|
-
while(visuals.hasNext()) {
|
268
|
-
visualContext.removeChild(visuals.next());
|
269
|
-
}
|
270
|
-
visualInstances = [];
|
271
|
-
}
|
272
|
-
|
273
|
-
protected function removeInjectedMember(member:ReflectionVariable):void {
|
274
|
-
if(!member) return;
|
275
|
-
currentTest[member.name] = null;
|
276
|
-
}
|
277
|
-
|
278
|
-
protected function prepareForSetUp():void {
|
279
|
-
injectMembers();
|
280
|
-
}
|
281
|
-
|
282
|
-
protected function injectMembers():void {
|
283
|
-
var member:ReflectionVariable;
|
284
|
-
while(injectableMembers.hasNext()) {
|
285
|
-
injectMember(injectableMembers.next());
|
286
|
-
}
|
287
|
-
injectableMembers.reset();
|
288
|
-
}
|
289
231
|
|
290
|
-
protected function injectMember(member:ReflectionVariable):void {
|
291
|
-
if(!member) return;
|
292
|
-
var definition:Class;
|
293
|
-
try {
|
294
|
-
definition = getDefinitionByName(member.type) as Class;
|
295
|
-
}
|
296
|
-
catch(referenceError:ReferenceError) {
|
297
|
-
warn("Unable to [Inject] with " + member.type + ". Maybe this was an inner class? That makes it unavailable to external code, try putting it in it's own file.");
|
298
|
-
return;
|
299
|
-
}
|
300
|
-
var reflection:Reflection = Reflection.create(definition);
|
301
|
-
try {
|
302
|
-
var instance:* = createInstanceFromReflection(reflection);
|
303
|
-
configureInjectedInstance(member, instance);
|
304
|
-
currentTest[member.name] = instance;
|
305
|
-
}
|
306
|
-
catch(e:VerifyError) {
|
307
|
-
throw new VerifyError("Failed to instantiate " + member.type + " in order to inject public var " + member.name);
|
308
|
-
}
|
309
|
-
}
|
310
|
-
|
311
|
-
protected function configureInjectedInstance(member:ReflectionVariable, instance:*):void {
|
312
|
-
var injectTag:ReflectionMetaData = member.getMetaDataByName('Inject');
|
313
|
-
var args:Array = injectTag.args;
|
314
|
-
var arg:Object;
|
315
|
-
var len:int = args.length;
|
316
|
-
for(var i:int; i < len; i++) {
|
317
|
-
arg = args[i];
|
318
|
-
try {
|
319
|
-
instance[arg.key] = coerceArgumentType(member, arg.value);
|
320
|
-
}
|
321
|
-
catch(e:ReferenceError) {
|
322
|
-
var reflect:Reflection = Reflection.create(instance);
|
323
|
-
warn("Unable to inject attribute " + arg.key + " on " + reflect.name);
|
324
|
-
}
|
325
|
-
}
|
326
|
-
}
|
327
|
-
|
328
|
-
protected function coerceArgumentType(member:ReflectionVariable, value:String):* {
|
329
|
-
switch(value) {
|
330
|
-
case "false" :
|
331
|
-
return false;
|
332
|
-
case "true" :
|
333
|
-
return true;
|
334
|
-
}
|
335
|
-
|
336
|
-
return value;
|
337
232
|
}
|
338
|
-
|
339
|
-
protected function createInstanceFromReflection(reflection:Reflection):* {
|
340
|
-
// Return the shared async instance if they're expecting the interface
|
341
|
-
// or concrete instance, but NOT if their Inject is merely a subclass...
|
342
|
-
if(reflection.name == ASYNC_NAME || reflection.name == IASYNC_NAME) {
|
343
|
-
return async;
|
344
|
-
}
|
345
|
-
|
346
|
-
var clazz:Class = getClassReferenceFromReflection(reflection);
|
347
|
-
var constructorReflection:Reflection = Reflection.create(clazz);
|
348
|
-
try {
|
349
|
-
var instance:* = new constructorReflection.classReference();
|
350
|
-
}
|
351
|
-
catch(e:VerifyError) {
|
352
|
-
warn("Unable to instantiate: " + reflection.name + " for injection");
|
353
|
-
}
|
354
|
-
|
355
|
-
if(constructorReflection.isA(DISPLAY_OBJECT_CONTAINER)) {
|
356
|
-
// Add injected DisplayObjectContainers to a collection
|
357
|
-
// for removal, and add them to the visualContext if
|
358
|
-
// one was provided to the run() method.
|
359
|
-
if(visualContext) {
|
360
|
-
visualInstances.push(instance);
|
361
|
-
visualContext.addChild(instance);
|
362
|
-
}
|
363
|
-
else {
|
364
|
-
warn("TestRunner is injecting a DisplayObjectContainer on your Test but wasn't given a visualContext when run was called. This means your visual entity will not be attached to the Display List.");
|
365
|
-
}
|
366
|
-
}
|
367
|
-
|
368
|
-
return instance;
|
369
|
-
}
|
370
|
-
|
371
233
|
protected function warn(message:String, method:Method=null):void {
|
372
|
-
|
373
|
-
}
|
374
|
-
|
375
|
-
protected function getClassReferenceFromReflection(reflection:Reflection):Class {
|
376
|
-
// This will attempt to deal with I-prefixed interfaces - like IAsync.
|
377
|
-
if(reflection.isInterface) {
|
378
|
-
return attemptToGetClassReferenceFromReflection(reflection);
|
379
|
-
}
|
380
|
-
return reflection.classReference;
|
381
|
-
}
|
382
|
-
|
383
|
-
protected function attemptToGetClassReferenceFromReflection(reflection:Reflection):Class {
|
384
|
-
var fullName:String = reflection.name;
|
385
|
-
var parts:Array = fullName.split("::");
|
386
|
-
var interfaceName:String = parts.pop();
|
387
|
-
var expr:RegExp = /I([AZ].+)/;
|
388
|
-
var match:Object = expr.exec(interfaceName);
|
389
|
-
if(match) {
|
390
|
-
parts.push(match[1]);
|
391
|
-
var implementationName:String = parts.join("::");
|
392
|
-
return Class(getDefinitionByName(implementationName));
|
393
|
-
}
|
394
|
-
throw new VerifyError("Unable to find class instance for interface " + fullName);
|
395
|
-
}
|
396
|
-
|
397
|
-
// TODO: Implement this method:
|
398
|
-
protected function argumentFreeConstructor(reflection:Reflection):Boolean {
|
399
|
-
return true;
|
234
|
+
result.onWarning(new TestWarning(message, method));
|
400
235
|
}
|
401
236
|
}
|
402
237
|
}
|