asunit4 4.2.1.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/Gemfile +5 -0
  2. data/MIT-LICENSE.txt +22 -0
  3. data/README.textile +6 -0
  4. data/air/AIR2Runner.mxml +22 -0
  5. data/air/AIR2RunnerDescriptor.xml +38 -0
  6. data/asunit4.gemspec +20 -0
  7. data/asunit4.rb +16 -0
  8. data/bin/AsUnit-4.1.pre.swc +0 -0
  9. data/bin/AsUnitRunner.swf +0 -0
  10. data/build.xml +46 -0
  11. data/lib/Reflection.swc +0 -0
  12. data/rakefile.rb +169 -0
  13. data/script/generate +21 -0
  14. data/src/asunit/asserts/assertEquals.as +5 -0
  15. data/src/asunit/asserts/assertEqualsArrays.as +5 -0
  16. data/src/asunit/asserts/assertEqualsArraysIgnoringOrder.as +5 -0
  17. data/src/asunit/asserts/assertEqualsFloat.as +5 -0
  18. data/src/asunit/asserts/assertFalse.as +5 -0
  19. data/src/asunit/asserts/assertNotNull.as +5 -0
  20. data/src/asunit/asserts/assertNotSame.as +5 -0
  21. data/src/asunit/asserts/assertNull.as +5 -0
  22. data/src/asunit/asserts/assertSame.as +5 -0
  23. data/src/asunit/asserts/assertThrows.as +5 -0
  24. data/src/asunit/asserts/assertTrue.as +5 -0
  25. data/src/asunit/asserts/fail.as +5 -0
  26. data/src/asunit/core/AsUnitCore.as +177 -0
  27. data/src/asunit/core/FlashBuilderCore.as +22 -0
  28. data/src/asunit/core/FlashDevelopCore.as +21 -0
  29. data/src/asunit/core/TextCore.as +54 -0
  30. data/src/asunit/errors/AbstractError.as +10 -0
  31. data/src/asunit/errors/AssertionFailedError.as +10 -0
  32. data/src/asunit/errors/ClassNotFoundError.as +11 -0
  33. data/src/asunit/errors/InstanceNotFoundError.as +10 -0
  34. data/src/asunit/errors/UnimplementedFeatureError.as +10 -0
  35. data/src/asunit/errors/UsageError.as +11 -0
  36. data/src/asunit/events/TimeoutCommandEvent.as +27 -0
  37. data/src/asunit/framework/Assert.as +408 -0
  38. data/src/asunit/framework/Async.as +138 -0
  39. data/src/asunit/framework/CallbackBridge.as +175 -0
  40. data/src/asunit/framework/Command.as +6 -0
  41. data/src/asunit/framework/ErrorEvent.as +20 -0
  42. data/src/asunit/framework/IAsync.as +21 -0
  43. data/src/asunit/framework/IResult.as +36 -0
  44. data/src/asunit/framework/IRunListener.as +11 -0
  45. data/src/asunit/framework/IRunner.as +15 -0
  46. data/src/asunit/framework/IRunnerFactory.as +9 -0
  47. data/src/asunit/framework/ITestFailure.as +32 -0
  48. data/src/asunit/framework/ITestListener.as +15 -0
  49. data/src/asunit/framework/ITestResult.as +21 -0
  50. data/src/asunit/framework/ITestSuccess.as +22 -0
  51. data/src/asunit/framework/ITestWarning.as +14 -0
  52. data/src/asunit/framework/InjectionDelegate.as +96 -0
  53. data/src/asunit/framework/LegacyTestIterator.as +40 -0
  54. data/src/asunit/framework/MessageBridge.as +24 -0
  55. data/src/asunit/framework/Method.as +80 -0
  56. data/src/asunit/framework/Result.as +181 -0
  57. data/src/asunit/framework/RunnerFactory.as +179 -0
  58. data/src/asunit/framework/SuiteIterator.as +71 -0
  59. data/src/asunit/framework/TestCase.as +106 -0
  60. data/src/asunit/framework/TestFailure.as +65 -0
  61. data/src/asunit/framework/TestIterator.as +282 -0
  62. data/src/asunit/framework/TestObserver.as +12 -0
  63. data/src/asunit/framework/TestSuccess.as +38 -0
  64. data/src/asunit/framework/TestWarning.as +40 -0
  65. data/src/asunit/framework/TimeoutCommand.as +103 -0
  66. data/src/asunit/printers/FlashBuilderPrinter.as +134 -0
  67. data/src/asunit/printers/FlashDevelopPrinter.as +81 -0
  68. data/src/asunit/printers/TextPrinter.as +324 -0
  69. data/src/asunit/runners/LegacyRunner.as +13 -0
  70. data/src/asunit/runners/SuiteRunner.as +125 -0
  71. data/src/asunit/runners/TestRunner.as +403 -0
  72. data/src/asunit/util/ArrayIterator.as +30 -0
  73. data/src/asunit/util/Iterator.as +10 -0
  74. data/test/AllTests.as +73 -0
  75. data/test/AsUnitRunner.as +15 -0
  76. data/test/Flex3Runner.mxml +24 -0
  77. data/test/Flex4Runner.mxml +27 -0
  78. data/test/asunit/core/AsUnitCoreTest.as +97 -0
  79. data/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as +88 -0
  80. data/test/asunit/framework/AssertEqualsArraysTest.as +102 -0
  81. data/test/asunit/framework/AssertTest.as +184 -0
  82. data/test/asunit/framework/AssertThrowsTest.as +42 -0
  83. data/test/asunit/framework/AsyncMethodTest.as +69 -0
  84. data/test/asunit/framework/AsyncTest.as +104 -0
  85. data/test/asunit/framework/CallbackBridgeTest.as +73 -0
  86. data/test/asunit/framework/InjectionDelegateTest.as +79 -0
  87. data/test/asunit/framework/MockData.xml +8 -0
  88. data/test/asunit/framework/NestedSuiteIteratorTest.as +59 -0
  89. data/test/asunit/framework/ProceedOnEventTest.as +109 -0
  90. data/test/asunit/framework/ResultTest.as +92 -0
  91. data/test/asunit/framework/RunnerFactoryTest.as +54 -0
  92. data/test/asunit/framework/SuiteIteratorTest.as +67 -0
  93. data/test/asunit/framework/TestCaseMock.as +24 -0
  94. data/test/asunit/framework/TestIteratorIgnoredMethodTest.as +62 -0
  95. data/test/asunit/framework/TestIteratorMethodByNameTest.as +50 -0
  96. data/test/asunit/framework/TestIteratorMultiMethodTest.as +186 -0
  97. data/test/asunit/framework/TestIteratorOrderedTestMethodTest.as +57 -0
  98. data/test/asunit/framework/TestIteratorSingleMethodTest.as +56 -0
  99. data/test/asunit/framework/VisualTestCaseTest.as +43 -0
  100. data/test/asunit/framework/assertAssertionFailed.as +19 -0
  101. data/test/asunit/printers/TextPrinterTest.as +122 -0
  102. data/test/asunit/runners/LegacyRunnerTest.as +40 -0
  103. data/test/asunit/runners/SuiteRunnerTest.as +40 -0
  104. data/test/asunit/runners/TestRunnerAsyncMethodTest.as +107 -0
  105. data/test/asunit/runners/TestRunnerErrorMethodTest.as +56 -0
  106. data/test/asunit/runners/TestRunnerExpectsErrorTest.as +98 -0
  107. data/test/asunit/runners/TestRunnerIgnoredMethodTest.as +42 -0
  108. data/test/asunit/runners/TestRunnerTest.as +171 -0
  109. data/test/asunit/support/AnnotatedSubClass.as +18 -0
  110. data/test/asunit/support/AnnotatedSuperClass.as +15 -0
  111. data/test/asunit/support/CustomParameters.as +13 -0
  112. data/test/asunit/support/CustomTestRunner.as +22 -0
  113. data/test/asunit/support/DoubleFailSuite.as +8 -0
  114. data/test/asunit/support/DoubleNestedSuite.as +14 -0
  115. data/test/asunit/support/ErrorInMethod.as +11 -0
  116. data/test/asunit/support/FailAssertEquals.as +29 -0
  117. data/test/asunit/support/FailAssertTrue.as +28 -0
  118. data/test/asunit/support/FakeObserver.as +42 -0
  119. data/test/asunit/support/FakeRunner.as +32 -0
  120. data/test/asunit/support/IgnoredMethod.as +26 -0
  121. data/test/asunit/support/InjectTimeoutOnAsync.as +14 -0
  122. data/test/asunit/support/InjectionFailure.as +18 -0
  123. data/test/asunit/support/InjectionVerification.as +69 -0
  124. data/test/asunit/support/LegacyTestCase.as +38 -0
  125. data/test/asunit/support/MultiMethod.as +77 -0
  126. data/test/asunit/support/OrderedTestMethod.as +36 -0
  127. data/test/asunit/support/RunWithButNoType.as +14 -0
  128. data/test/asunit/support/RunWithSuiteButNoType.as +11 -0
  129. data/test/asunit/support/SingleErrorSuite.as +7 -0
  130. data/test/asunit/support/SingleSuccessSuite.as +7 -0
  131. data/test/asunit/support/SucceedAssertTrue.as +31 -0
  132. data/test/asunit/support/SuiteOfTwoSuites.as +8 -0
  133. data/test/asunit/support/SuiteWithCustomRunner.as +12 -0
  134. data/test/asunit/support/SuiteWithOneCustomChildSuite.as +10 -0
  135. data/test/asunit/support/TestForFakeRunner.as +14 -0
  136. data/test/asunit/util/ArrayIteratorTest.as +65 -0
  137. data/vendor/as3reflection/README +7 -0
  138. data/vendor/as3reflection/p2/reflect/Reflection.as +417 -0
  139. data/vendor/as3reflection/p2/reflect/ReflectionAccessor.as +14 -0
  140. data/vendor/as3reflection/p2/reflect/ReflectionBase.as +52 -0
  141. data/vendor/as3reflection/p2/reflect/ReflectionMember.as +16 -0
  142. data/vendor/as3reflection/p2/reflect/ReflectionMetaData.as +69 -0
  143. data/vendor/as3reflection/p2/reflect/ReflectionMethod.as +36 -0
  144. data/vendor/as3reflection/p2/reflect/ReflectionMethodParameter.as +19 -0
  145. data/vendor/as3reflection/p2/reflect/ReflectionVariable.as +15 -0
  146. data/vendor/as3reflection/p2/reflect/findFirst.as +14 -0
  147. data/vendor/generators/suite/USAGE +0 -0
  148. data/vendor/generators/suite/suite_generator.rb +17 -0
  149. data/vendor/generators/suite/templates/TestSuite.as +17 -0
  150. metadata +216 -0
@@ -0,0 +1,282 @@
1
+ package asunit.framework {
2
+
3
+ import asunit.errors.UsageError;
4
+ import asunit.util.ArrayIterator;
5
+ import asunit.util.Iterator;
6
+
7
+ import p2.reflect.Reflection;
8
+ import p2.reflect.ReflectionMethod;
9
+
10
+ public class TestIterator implements Iterator {
11
+
12
+ private var _readyToTearDown:Boolean;
13
+
14
+ private var afterClassMethods:Iterator;
15
+ private var afterMethods:Iterator;
16
+ private var beforeClassMethods:Iterator;
17
+ private var beforeMethods:Iterator;
18
+ private var beforeMethodRanLastCycle:Boolean;
19
+ private var ignoredMethods:Iterator;
20
+ private var testMethodNameReceived:Boolean;
21
+ private var setUpHasRunThisCycle:Boolean;
22
+ private var testMethodHasRunThisCycle:Boolean;
23
+ private var testMethods:Iterator;
24
+
25
+ public function TestIterator(test:Object, testMethodName:String = "") {
26
+ if(test is Class) throw new ArgumentError("test argument cannot be a Class");
27
+
28
+ var testMethodsArray:Array = getTestMethods(test);
29
+ if(!testMethodsArray.length) {
30
+ setUpNullIterators();
31
+ return;
32
+ }
33
+
34
+ if(testMethodName) {
35
+ testMethodNameReceived = true;
36
+ testMethodsArray = testMethodsArray.filter(
37
+ function(item:Object, index:int, array:Array):Boolean {
38
+ return (item.name == testMethodName);
39
+ }
40
+ );
41
+ if(testMethodsArray.length == 0) {
42
+ var message:String = "Provided test method name (" + testMethodName + ") not found on provided class (" + Reflection.create(test).name + ")";
43
+ throw new UsageError(message);
44
+ }
45
+ }
46
+
47
+ testMethods = new ArrayIterator(testMethodsArray);
48
+ setUpIterators(test);
49
+ }
50
+
51
+ public function get readyToSetUp():Boolean {
52
+ return !setUpHasRunThisCycle || (!afterMethods.hasNext() && testMethodHasRunThisCycle && testMethods.hasNext());
53
+ }
54
+
55
+ public function get readyToTearDown():Boolean {
56
+ return _readyToTearDown;
57
+ }
58
+
59
+ protected function setUpNullIterators():void {
60
+ // Set up null iterators for access to length
61
+ // and other properties...
62
+ testMethods = new ArrayIterator();
63
+ beforeClassMethods = new ArrayIterator();
64
+ beforeMethods = new ArrayIterator();
65
+ afterMethods = new ArrayIterator();
66
+ afterClassMethods = new ArrayIterator();
67
+ ignoredMethods = new ArrayIterator();
68
+ }
69
+
70
+ protected function setUpIterators(test:Object):void {
71
+ if(!testMethodNameReceived) {
72
+ afterClassMethods = new ArrayIterator(getAfterClassMethods(test));
73
+ afterMethods = new ArrayIterator(getAfterMethods(test));
74
+ }
75
+ else {
76
+ afterClassMethods = new ArrayIterator([]);
77
+ afterMethods = new ArrayIterator([]);
78
+ }
79
+ beforeClassMethods = new ArrayIterator(getBeforeClassMethods(test));
80
+ beforeMethods = new ArrayIterator(getBeforeMethods(test));
81
+ ignoredMethods = new ArrayIterator(getIgnoredMethods(test));
82
+ }
83
+
84
+ public function get beforeClassIterator():Iterator {
85
+ return beforeClassMethods;
86
+ }
87
+
88
+ public function get beforeIterator():Iterator {
89
+ return beforeMethods;
90
+ }
91
+
92
+ public function get testMethodsIterator():Iterator {
93
+ return testMethods;
94
+ }
95
+
96
+ public function get afterIterator():Iterator {
97
+ return afterMethods;
98
+ }
99
+
100
+ public function get afterClassIterator():Iterator {
101
+ return afterClassMethods;
102
+ }
103
+
104
+ public function get ignoredIterator():Iterator {
105
+ return ignoredMethods;
106
+ }
107
+
108
+ /**
109
+ *
110
+ * @param test An instance of a class with methods that have [Before] metadata.
111
+ * @return An array of Method instances.
112
+ */
113
+ protected function getBeforeClassMethods(test:Object):Array {
114
+ return getMethodsWithMetadata(test["constructor"], "BeforeClass", true);
115
+ }
116
+
117
+ /**
118
+ *
119
+ * @param test An instance of a class with methods that have [Before] metadata.
120
+ * @return An array of Method instances.
121
+ */
122
+ protected function getBeforeMethods(test:Object):Array {
123
+ return getMethodsWithMetadata(test, "Before");
124
+ }
125
+
126
+ /**
127
+ *
128
+ * @param test An instance of a class with methods that have [Test] metadata,
129
+ * or have a methods that begin with 'test'.
130
+ * @return An array of Method instances.
131
+ */
132
+ protected function getTestMethods(test:Object):Array {
133
+ return getMethodsWithMetadata(test, "Test");
134
+ }
135
+
136
+ /**
137
+ *
138
+ * @param test An instance of a class with methods that have [After] metadata.
139
+ * @return An array of Method instances.
140
+ */
141
+ protected function getAfterMethods(test:Object):Array {
142
+ return getMethodsWithMetadata(test, "After");
143
+ }
144
+
145
+ /**
146
+ *
147
+ * @param test An instance of a class with methods that have [After] metadata.
148
+ * @return An array of Method instances.
149
+ */
150
+ protected function getIgnoredMethods(test:Object):Array {
151
+ return getMethodsWithMetadata(test, "Ignore");
152
+ }
153
+
154
+ /**
155
+ *
156
+ * @param test An instance of a class with methods that have [Before] metadata.
157
+ * @return An array of Method instances.
158
+ */
159
+ protected function getAfterClassMethods(test:Object):Array {
160
+ return getMethodsWithMetadata(test["constructor"], "AfterClass", true);
161
+ }
162
+
163
+ protected function getMethodsWithMetadata(instance:Object, metaDataName:String, useStatic:Boolean = false):Array {
164
+ var reflection:Reflection = Reflection.create(instance);
165
+ var methodReflections:Array = reflection.getMembersByMetaData(metaDataName);
166
+
167
+ var methods:Array = [];
168
+ var methodReflection:ReflectionMethod;
169
+ for each(methodReflection in methodReflections) {
170
+ methods.push( new Method(instance, methodReflection) );
171
+ }
172
+ methods.sortOn('name');
173
+ methods.sortOn('order');
174
+ return methods;
175
+ }
176
+
177
+ protected function countTestMethods(test:Object):uint {
178
+ return getTestMethods(test).length;
179
+ }
180
+
181
+ public function hasNext():Boolean {
182
+ if(!testMethods) return false;
183
+ return testMethods.hasNext()
184
+ || beforeMethods.hasNext()
185
+ || afterMethods.hasNext()
186
+ || beforeClassMethods.hasNext()
187
+ || afterClassMethods.hasNext();
188
+ }
189
+
190
+ public function get length():uint {
191
+ var testMethodCount:int = testMethods.length - ignoredMethods.length;
192
+ var classHelperCount:int = beforeClassMethods.length + afterClassMethods.length;
193
+ var methodHelperCount:int = beforeMethods.length + afterMethods.length;
194
+
195
+ if(methodHelperCount > 0) {
196
+ return (testMethodCount * methodHelperCount) + testMethodCount + classHelperCount;
197
+ }
198
+ else {
199
+ return testMethodCount + classHelperCount;
200
+ }
201
+ }
202
+
203
+ public function next():* {
204
+ if(!testMethods) return null;
205
+
206
+ var value:*;
207
+
208
+ _readyToTearDown = false;
209
+ beforeMethodRanLastCycle = false;
210
+ setUpHasRunThisCycle = true;
211
+
212
+ if(beforeClassMethods.hasNext()) {
213
+ value = beforeClassMethods.next();
214
+ //updateReadyToSetUp();
215
+ return value;
216
+ }
217
+
218
+
219
+ if(beforeMethods.hasNext()) {
220
+ value = beforeMethods.next();
221
+ beforeMethodRanLastCycle = true;
222
+ //updateReadyToSetUp();
223
+ return value;
224
+ }
225
+
226
+ //updateReadyToSetUp();
227
+
228
+ if(!testMethodHasRunThisCycle && testMethods.hasNext()) {
229
+ testMethodHasRunThisCycle = true;
230
+ value = testMethods.next();
231
+ updateReadyToTearDown();
232
+ return value;
233
+ }
234
+
235
+ if(afterMethods.hasNext()) {
236
+ value = afterMethods.next();
237
+ //updateReadyToSetUp();
238
+ updateReadyToTearDown();
239
+ return value;
240
+ }
241
+
242
+ if(!testMethods.hasNext()) {
243
+ if(afterClassMethods.hasNext()) {
244
+ return afterClassMethods.next();
245
+ }
246
+ return null;
247
+ }
248
+
249
+ beforeMethods.reset();
250
+ afterMethods.reset();
251
+ testMethodHasRunThisCycle = false;
252
+ setUpHasRunThisCycle = false;
253
+ return next();
254
+ }
255
+
256
+ protected function updateReadyToTearDown():void {
257
+ // Used by TestRunner to remove visual
258
+ // entities:
259
+ if(!beforeClassMethods.hasNext() &&
260
+ !beforeMethods.hasNext() &&
261
+ testMethodHasRunThisCycle &&
262
+ !afterMethods.hasNext()) {
263
+ _readyToTearDown = true;
264
+ }
265
+ }
266
+
267
+ public function reset():void {
268
+ if(!testMethods) return;
269
+
270
+ beforeClassMethods.reset();
271
+ beforeMethods.reset();
272
+ testMethods.reset();
273
+ afterMethods.reset();
274
+ afterClassMethods.reset();
275
+
276
+ _readyToTearDown = false;
277
+ setUpHasRunThisCycle = false;
278
+ testMethodHasRunThisCycle = false;
279
+ }
280
+ }
281
+ }
282
+
@@ -0,0 +1,12 @@
1
+ package asunit.framework {
2
+
3
+ /**
4
+ * TestObserver is a marker interface that usually
5
+ * indicates that a given class will have at least
6
+ * one [Inject] annotation above a public instance
7
+ * variable that implements MessageBridge.
8
+ */
9
+ public interface TestObserver {
10
+ }
11
+ }
12
+
@@ -0,0 +1,38 @@
1
+ package asunit.framework {
2
+ import flash.utils.getQualifiedClassName;
3
+
4
+ /**
5
+ * @see Result
6
+ */
7
+ public class TestSuccess implements ITestSuccess {
8
+ protected var _test:Object;
9
+ protected var _method:String;
10
+
11
+ /**
12
+ * Constructs a TestFailure with the given test and exception.
13
+ */
14
+ public function TestSuccess(test:Object, method:String) {
15
+ _test = test;
16
+ _method = method;
17
+ }
18
+
19
+ public function get feature():String {
20
+ return getQualifiedClassName(_test) + '.' + _method;
21
+ }
22
+
23
+ public function get test():Object {
24
+ return _test;
25
+ }
26
+
27
+ public function get method():String {
28
+ return _method;
29
+ }
30
+
31
+ /**
32
+ * Returns a short description of the success.
33
+ */
34
+ public function toString():String {
35
+ return "[TestSuccess " + method + "]";
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,40 @@
1
+ package asunit.framework {
2
+
3
+ public class TestWarning implements ITestWarning {
4
+
5
+ private var _message:String;
6
+ private var _method:Method;
7
+
8
+ public function TestWarning(message:String, method:Method=null) {
9
+ _message = message;
10
+ _method = method;
11
+ }
12
+
13
+ public function set message(message:String):void {
14
+ _message = message;
15
+ }
16
+
17
+ public function get message():String {
18
+ return _message;
19
+ }
20
+
21
+ public function set method(method:Method):void {
22
+ _method = method;
23
+ }
24
+
25
+ public function get method():Method {
26
+ return _method;
27
+ }
28
+
29
+ public function toString():String {
30
+ if(method) {
31
+ return "[WARNING] " + method + " : " + message;
32
+ }
33
+ else {
34
+ return "[WARNING] " + message;
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+
@@ -0,0 +1,103 @@
1
+ package asunit.framework {
2
+
3
+ import asunit.framework.Command;
4
+ import asunit.events.TimeoutCommandEvent;
5
+
6
+ import flash.events.Event;
7
+ import flash.events.EventDispatcher;
8
+ import flash.events.TimerEvent;
9
+ import flash.utils.Timer;
10
+
11
+ [Event(name="called", type="flash.events.TimeoutCommandEvent")]
12
+ [Event(name="timedOut", type="flash.events.TimeoutCommandEvent")]
13
+ public class TimeoutCommand extends EventDispatcher implements Command {
14
+
15
+ public var scope:Object;
16
+ public var handler:Function;
17
+ public var duration:Number;
18
+
19
+ protected var params:Array;
20
+ protected var timeout:Timer;
21
+ protected var failureHandler:Function;
22
+
23
+ public function TimeoutCommand(scope:Object, handler:Function=null, duration:int=0, failureHandler:Function=null) {
24
+ this.scope = scope;
25
+ this.handler = handler || function(...args):* {};
26
+ this.duration = duration;
27
+ this.failureHandler = failureHandler;
28
+
29
+ //if (duration < 0) return;
30
+ timeout = new Timer(duration, 1);
31
+ timeout.addEventListener(TimerEvent.TIMER_COMPLETE, onTimeoutComplete);
32
+ timeout.start();
33
+ }
34
+
35
+ /**
36
+ * Called by TestRunner when the TimeoutCommandEvent.CALLED event is thrown.
37
+ *
38
+ * This needs to be triggered from the Runner so that the runner can handle
39
+ * any exceptions or errors appropriately.
40
+ *
41
+ * This should NOT actually call the provided handler if the timeout has
42
+ * already been exceeded.
43
+ */
44
+ public function execute():* {
45
+ return handler.apply(scope, params);
46
+ }
47
+
48
+ /**
49
+ * Return the function handler that will be called when the Asynchronous
50
+ * feature works properly.
51
+ */
52
+ public function getCallback():Function {
53
+ return wrapHandlerWithCorrectNumberOfArgs();
54
+ }
55
+
56
+ /**
57
+ * Stop waiting for the timeout event, and don't call anything.
58
+ */
59
+ public function cancel():void {
60
+ if (timeout) timeout.stop();
61
+ }
62
+
63
+ /**
64
+ * Called by the returned closure, and dispatches the CALLED event so that
65
+ * a client (TestRunner) can call execute().
66
+ */
67
+ protected function callback(...args):* {
68
+ if (timeout) timeout.stop();
69
+ this.params = args;
70
+ var event:Event = new TimeoutCommandEvent(TimeoutCommandEvent.CALLED, this);
71
+ dispatchEvent(event);
72
+ }
73
+
74
+ protected function onTimeoutComplete(timerEvent:TimerEvent):void {
75
+ // Clobber handler so that original can no longer be called:
76
+ handler = function(...args):void {};
77
+ // Notify subscribers of the timeout:
78
+ var event:TimeoutCommandEvent = new TimeoutCommandEvent(TimeoutCommandEvent.TIMED_OUT, this);
79
+ dispatchEvent(event);
80
+ if (failureHandler != null) failureHandler(event);
81
+ }
82
+
83
+ protected function wrapHandlerWithCorrectNumberOfArgs():Function {
84
+ switch (handler.length) {
85
+ case 0: return function():* { return callback(); };
86
+ case 1: return function(a:*=null):* { return callback(a); };
87
+ case 2: return function(a:*=null, b:*=null):* { return callback(a, b); };
88
+ case 3: return function(a:*=null, b:*=null, c:*=null):* { return callback(a, b, c); };
89
+ case 4: return function(a:*=null, b:*=null, c:*=null, d:*=null):* { return callback(a, b, c, d); };
90
+ case 5: return function(a:*=null, b:*=null, c:*=null, d:*=null, e:*=null):* { return callback(a, b, c, d, e); };
91
+ case 6: return function(a:*=null, b:*=null, c:*=null, d:*=null, e:*=null, f:*=null):* { return callback(a, b, c, d, e, f); };
92
+ case 7: return function(a:*=null, b:*=null, c:*=null, d:*=null, e:*=null, f:*=null, g:*=null):* { return callback(a, b, c, d, e, f, g); };
93
+ case 8: return function(a:*=null, b:*=null, c:*=null, d:*=null, e:*=null, f:*=null, g:*=null, h:*=null):* { return callback(a, b, c, d, e, f, g, h); };
94
+ case 9: return function(a:*=null, b:*=null, c:*=null, d:*=null, e:*=null, f:*=null, g:*=null, h:*=null, i:*=null):* { return callback(a, b, c, d, e, f, g, h, i); };
95
+ }
96
+ return callback;
97
+ }
98
+
99
+ override public function toString():String {
100
+ return '[TimeoutCommand scope=' + scope + ']';;
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,134 @@
1
+ package asunit.printers {
2
+ import asunit.framework.ITestFailure;
3
+ import asunit.framework.ITestWarning;
4
+
5
+ import asunit.framework.IResult;
6
+ import asunit.framework.IRunListener;
7
+ import asunit.framework.ITestSuccess;
8
+ import asunit.framework.Method;
9
+ import asunit.framework.TestObserver;
10
+
11
+ import flash.events.Event;
12
+ import flash.events.IOErrorEvent;
13
+ import flash.events.SecurityErrorEvent;
14
+ import flash.net.XMLSocket;
15
+ import flash.utils.getQualifiedClassName;
16
+
17
+ public class FlashBuilderPrinter implements IRunListener, TestObserver {
18
+ protected var projectName:String;
19
+ protected var contextName:String;
20
+ protected var messageQueue:Array;
21
+ protected var socket:XMLSocket;
22
+
23
+ public function FlashBuilderPrinter(projectName:String = '', contextName:String = '') {
24
+ this.projectName = projectName;
25
+ this.contextName = contextName;
26
+ messageQueue = [];
27
+ socket = new XMLSocket();
28
+ socket.addEventListener(Event.CONNECT, onConnect);
29
+ socket.addEventListener(IOErrorEvent.IO_ERROR, onErrorEvent);
30
+ socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onErrorEvent);
31
+ socket.addEventListener(Event.CLOSE, onErrorEvent);
32
+ connect();
33
+ }
34
+
35
+ public function onRunStarted():void {
36
+ sendMessage("<startTestRun totalTestCount='0' projectName='" + projectName
37
+ + "' contextName='" + contextName +"' />");
38
+ }
39
+
40
+ public function onTestStarted(test:Object):void {
41
+ }
42
+
43
+ public function onTestCompleted(test:Object):void {
44
+ }
45
+
46
+ // works for both errors and failures
47
+ public function onTestFailure(failure:ITestFailure):void {
48
+ sendMessage(getFailureMessage(failure));
49
+ }
50
+
51
+ public function onTestSuccess(success:ITestSuccess):void {
52
+ var xmlMessageSuccess:String = "<testCase name='" + success.method
53
+ + "' testSuite='" + getQualifiedClassName(success.test) + "' status='success'/>";
54
+ sendMessage(xmlMessageSuccess);
55
+ }
56
+
57
+ public function onTestIgnored(method:Method):void {
58
+ var xmlMessageIgnore:String = "<testCase name='" + method.name
59
+ + "' testSuite='" + getQualifiedClassName(method.scope) + "' status='ignore'/>";
60
+ sendMessage(xmlMessageIgnore);
61
+ }
62
+
63
+ public function onWarning(warning:ITestWarning):void {
64
+ //TODO: is there any way to send a warning to Flash Builder?
65
+ }
66
+
67
+ public function onRunCompleted(result:IResult):void {
68
+ sendMessage('<endOfTestRun/>');
69
+ socket.close();
70
+ }
71
+
72
+ protected function connect(ip:String = '127.0.0.1', port:uint = 8765):void {
73
+ try {
74
+ socket.connect(ip, port);
75
+ }
76
+ catch (e:Error) {
77
+ trace('## Error connecting to Flash Builder socket: ' + e.message);
78
+ }
79
+ }
80
+
81
+ protected function onConnect(event:Event):void {
82
+ sendQueuedMessages();
83
+ }
84
+
85
+ protected function sendQueuedMessages():void {
86
+ while (messageQueue.length) {
87
+ sendMessage(messageQueue.shift());
88
+ }
89
+ }
90
+
91
+ protected function sendMessage(message:String):void {
92
+ if (!socket.connected) {
93
+ messageQueue.push(message);
94
+ return;
95
+ }
96
+ socket.send(message);
97
+ //trace('+++++++++ sendMessage() - \n' + message + '\n');
98
+ }
99
+
100
+ protected function getFailureMessage(failure:ITestFailure):String {
101
+ var status:String = failure.isFailure ? 'failure' : 'error';
102
+ var xml:String =
103
+ "<testCase name='" + failure.failedMethod
104
+ + "' testSuite='" + getQualifiedClassName(failure.failedTest)
105
+ + "' status='" + status + "'>"
106
+ + "<failure type='" + getQualifiedClassName(failure.thrownException) + "' >"
107
+
108
+ + "<messageInfo>" + xmlEscapeMessage(failure.exceptionMessage)
109
+ + "</messageInfo>"
110
+
111
+ + "<stackTraceInfo>" + xmlEscapeMessage(failure.thrownException.getStackTrace())
112
+ + "</stackTraceInfo>"
113
+
114
+ + "</failure>"
115
+ + "</testCase>";
116
+
117
+ return xml;
118
+ }
119
+
120
+ protected function onErrorEvent(event:Event):void {
121
+ trace('FlashBuilderPrinter::onErrorEvent() - event: ' + event);
122
+ //throw new Error('FlashBuilderPrinter::onErrorEvent() - event: ' + event);
123
+ }
124
+
125
+ protected static function xmlEscapeMessage(message:String):String {
126
+ if (!message) return '';
127
+
128
+ var escape:XML = <escape/>;
129
+ escape.setChildren( message );
130
+ return escape.children()[0].toXMLString();
131
+ }
132
+
133
+ }
134
+ }
@@ -0,0 +1,81 @@
1
+ package asunit.printers {
2
+
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
+ import asunit.framework.TestObserver;
10
+
11
+ public class FlashDevelopPrinter implements IRunListener, TestObserver {
12
+ protected static const localPathPattern:RegExp =
13
+ /([A-Z]:\\[^\/:\*\?<>\|]+\.\w{2,6})|(\\{2}[^\/:\*\?<>\|]+\.\w{2,6})/g;
14
+
15
+ protected static const lineNumberPattern:RegExp = /:[0-9]*\]/;
16
+
17
+ public function FlashDevelopPrinter() {
18
+ }
19
+
20
+ public function onRunStarted():void {
21
+ }
22
+
23
+ public function onTestStarted(test:Object):void {
24
+ }
25
+
26
+ public function onTestCompleted(test:Object):void {
27
+ }
28
+
29
+ // works for both errors and failures
30
+ public function onTestFailure(failure:ITestFailure):void {
31
+ sendMessage(getFailureMessage(failure));
32
+ }
33
+
34
+ public function onTestSuccess(success:ITestSuccess):void {
35
+ // don't send success to FlashDevelop Panel
36
+ }
37
+
38
+ public function onTestIgnored(method:Method):void {
39
+ // don't send ignored test to FlashDevelop Panel
40
+ }
41
+
42
+ public function onWarning(warning:ITestWarning):void {
43
+ //TODO: send warning to FlashDevelop Panel?
44
+ }
45
+
46
+ public function onRunCompleted(result:IResult):void {
47
+ }
48
+
49
+ protected function sendMessage(message:String):void {
50
+ trace(message);
51
+ }
52
+
53
+ protected function getFailureMessage(failure:ITestFailure):String {
54
+ var status:String = (failure.isFailure) ? 'F' : 'E';
55
+ var stack:String = failure.thrownException.getStackTrace();
56
+ var lines:Array = stack.split('\n');
57
+ var methodPattern:RegExp = new RegExp(failure.failedMethod);
58
+
59
+ var lineWithMethod:String = '';
60
+ for each (var line:String in lines) {
61
+ if (line.match(methodPattern)) {
62
+ lineWithMethod = line;
63
+ break;
64
+ }
65
+ }
66
+ //trace('\n' + lineWithMethod + '\n');
67
+
68
+ var filePath:String = String(lineWithMethod.match(localPathPattern)[0]);
69
+ // Find the line number between : and ], e.g. :25].
70
+ var matches:Array = lineWithMethod.match(lineNumberPattern);
71
+ var lineNumberRaw:String = matches ? matches[0] : '';
72
+ // Take off the colon and bracket (I need to get better at regex).
73
+ var lineNumber:String = lineNumberRaw.slice(1, -1);
74
+
75
+ var message:String = filePath + ':'+lineNumber+': ' + status + ' '
76
+ + (failure.failedMethod + '(): ' + failure.exceptionMessage);
77
+
78
+ return message;
79
+ }
80
+ }
81
+ }