diff --git a/.gitignore b/.gitignore index 3075ab1..eed7d37 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ asunit-3.0/obj asunit-4.0/bin asunit-4.0/bin-debug asunit-4.0/obj +asunit-4.0/report html-template .DS_Store .actionScriptProperties diff --git a/asunit-3.0/src/asunit/framework/Assert.as b/asunit-3.0/src/asunit/framework/Assert.as index 4ef249f..84166f5 100644 --- a/asunit-3.0/src/asunit/framework/Assert.as +++ b/asunit-3.0/src/asunit/framework/Assert.as @@ -147,22 +147,29 @@ package asunit.framework { throw new IllegalOperationError("Invalid argument count"); } - if(expected == null && actual == null) { + if(bothNull(expected, actual)) { return; } - try { - if(expected != null && expected.equals(actual)) { + if(eitherNull(expected, actual)) { + throw new AssertionFailedError(format(message, expected, actual)); + } + + // now we know both are not null + + try { + if(expected.equals(actual)) { return; } } catch(e:Error) { - if(expected != null && expected == actual) { + if(expected == actual) { return; } } - throw new AssertionFailedError(format(message, expected, actual)); + throw new AssertionFailedError(format(message, expected, actual)); + } /** * Asserts that an object isn't null. If it is @@ -323,17 +330,18 @@ package asunit.framework { throw new IllegalOperationError("Invalid argument count"); } - if (expected == null && actual == null) { + if (bothNull(expected, actual)) { return; } - if ((expected == null && actual != null) || (expected != null && actual == null)) { + if (eitherNull(expected, actual)) { failNotEquals(message, expected, actual); } // from here on: expected != null && actual != null - if (expected.length != actual.length) { + if (differentLengths(expected, actual)) { failNotEquals(message, expected, actual); } - for (var i : int = 0; i < expected.length; i++) { + var iLength:uint = expected.length; + for (var i : int = 0; i < iLength; i++) { assertEquals(expected[i], actual[i]); } } @@ -363,36 +371,47 @@ package asunit.framework { throw new IllegalOperationError("Invalid argument count"); } - if (expected == null && actual == null) { + if (bothNull(expected, actual)) { return; } - if ((expected == null && actual != null) || (expected != null && actual == null)) { + if (eitherNull(expected, actual)) { failNotEquals(message, expected, actual); } // from here on: expected != null && actual != null - if (expected.length != actual.length) { + if (differentLengths(expected, actual)) { failNotEquals(message, expected, actual); } - for (var i : int = 0; i < expected.length; i++) { - var foundMatch : Boolean = false; - var expectedMember : Object = expected[i]; - for (var j : int = 0; j < actual.length; j++) { - var actualMember : Object = actual[j]; + + var unusedPotentialMatches:Array = actual.slice(); + + var iLength:uint = expected.length; + var jLength:uint; + + searchingForExpectedItems: + for (var i:int = 0; i < iLength; i++) + { + var expectedMember : Object = expected[i]; + jLength = unusedPotentialMatches.length; + + checkingAgainstActualItems: + for (var j : int = 0; j < jLength; j++) { + var actualMember : Object = unusedPotentialMatches[j]; try { assertEquals(expectedMember, actualMember); - foundMatch = true; - break; + unusedPotentialMatches.splice(j, 1); + continue searchingForExpectedItems; } catch (e : AssertionFailedError) { // no match, try next } } - if (!foundMatch) { - failNotEquals("Found no match for " + expectedMember + ";", expected, actual); - } - } + + failNotEquals("Found no match for " + expectedMember + ";", expected, actual); + + } } - + + static private function failNotEquals(message:String, expected:Object, actual:Object):void { fail(format(message, expected, actual)); } @@ -404,5 +423,20 @@ package asunit.framework { } return formatted + "expected:<" + expected + "> but was:<" + actual + ">"; } + + static public function bothNull(v1:*, v2:*):Boolean + { + return ((v1==null)&&(v2==null)); + } + + static public function eitherNull(v1:*, v2:*):Boolean + { + return ((v1==null)||(v2==null)); + } + + static public function differentLengths(v1:*, v2:*):Boolean + { + return (v1.length != v2.length); + } } } diff --git a/asunit-3.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as b/asunit-3.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as index daa4a70..8a383b8 100755 --- a/asunit-3.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as +++ b/asunit-3.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as @@ -1,92 +1,106 @@ -package asunit.framework -{ - import asunit.errors.AssertionFailedError; - import asunit.framework.TestCase; - import asunit.framework.Assert; - - /** - * Tests assertEqualsArraysIgnoringOrder - * - * @author Bastian Krol - */ - public class AssertEqualsArraysIgnoringOrderTest extends TestCase { - - public function AssertEqualsArraysIgnoringOrderTest(testMethod:String = null) { - super(testMethod); - } - - public function testNullEqualsNull():void { - assertEqualsArraysIgnoringOrder(Assert.assertEqualsArraysIgnoringOrder, null, null); - } - - public function testNullDoesNotEqualNotNull():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, null, []); - } - - public function testNotNullDoesNotEqualNull():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [], null); - } - - public function testEmptyArrayEqualsEmptyArray():void { - assertEqualsArraysIgnoringOrder([], []); - } - - public function testArrayWithOneStringEquals():void { - assertEqualsArraysIgnoringOrder(["abcdefg"], ["abcdefg"]); - } - - public function testArrayWithOneStringNotEquals():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abcdefg"], ["12345"]); - } - - public function testArrayWithOneFunctionEquals():void { - assertEqualsArraysIgnoringOrder([tearDown], [tearDown]); - } - - public function testArrayWithOneFunctionNotEquals():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [setUp], [tearDown]); - } - - public function testArrayWithOneNullMemberEquals():void { - assertEqualsArraysIgnoringOrder([null], [null]); - } - - public function testArrayWithOneNullMemberNotEquals1():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["..."], [null]); - } - - public function testArrayWithOneNullMemberNotEquals2():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [null], ["..."]); - } - - public function testArrayEqualsSameOrder():void { - assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["abc", "def", "ghi"]); - } - - public function testArrayNotEquals():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "xyz", "ghi"]); - } - - public function testArrayEqualsDifferentOrder1():void { - assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["def", "abc", "ghi"]); - } - - public function testArrayEqualsDifferentOrder2():void { - assertEqualsArraysIgnoringOrder([setUp, tearDown, cleanUp], [cleanUp, tearDown, setUp]); - } - - public function testArrayEqualsDifferentTypes():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, - ["abc", "def", "ghi"], - ["abc", setUp, "ghi"]); - } - - public function testArrayDifferentLength1():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "def"]); - } - - public function testArrayDifferentLength2():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def"], ["abc", "def", "ghi"]); - } - } +package asunit.framework +{ + import asunit.errors.AssertionFailedError; + import asunit.framework.TestCase; + import asunit.framework.Assert; + import flash.display.Sprite; + + /** + * Tests assertEqualsArraysIgnoringOrder + * + * @author Bastian Krol + */ + public class AssertEqualsArraysIgnoringOrderTest extends TestCase { + + public function AssertEqualsArraysIgnoringOrderTest(testMethod:String = null) { + super(testMethod); + } + + public function testNullEqualsNull():void { + assertEqualsArraysIgnoringOrder(Assert.assertEqualsArraysIgnoringOrder, null, null); + } + + public function testNullDoesNotEqualNotNull():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, null, []); + } + + public function testNotNullDoesNotEqualNull():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [], null); + } + + public function testEmptyArrayEqualsEmptyArray():void { + assertEqualsArraysIgnoringOrder([], []); + } + + public function testArrayWithOneStringEquals():void { + assertEqualsArraysIgnoringOrder(["abcdefg"], ["abcdefg"]); + } + + public function testArrayWithOneStringNotEquals():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abcdefg"], ["12345"]); + } + + public function testArrayWithOneFunctionEquals():void { + assertEqualsArraysIgnoringOrder([tearDown], [tearDown]); + } + + public function testArrayWithOneFunctionNotEquals():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [setUp], [tearDown]); + } + + public function testArrayWithOneNullMemberEquals():void { + assertEqualsArraysIgnoringOrder([null], [null]); + } + + public function testArrayWithOneNullMemberNotEquals1():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["..."], [null]); + } + + public function testArrayWithOneNullMemberNotEquals2():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [null], ["..."]); + } + + public function testArrayEqualsSameOrder():void { + assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["abc", "def", "ghi"]); + } + + public function testArrayNotEquals():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "xyz", "ghi"]); + } + + public function testArrayEqualsDifferentOrder1():void { + assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["def", "abc", "ghi"]); + } + + public function testArrayEqualsDifferentOrder2():void { + assertEqualsArraysIgnoringOrder([setUp, tearDown, cleanUp], [cleanUp, tearDown, setUp]); + } + + public function testArrayEqualsDifferentTypes():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, + ["abc", "def", "ghi"], + ["abc", setUp, "ghi"]); + } + + public function testArrayDifferentLength1():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "def"]); + } + + public function testArrayDifferentLength2():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def"], ["abc", "def", "ghi"]); + } + + public function testArrayWithRepeatedItems():void { + var spr1:Sprite = new Sprite(); + var spr2:Sprite = new Sprite(); + var spr3:Sprite = new Sprite(); + + var controlArray:Array = [spr1, spr2, spr3, spr1]; + var matchingArray:Array = [spr1, spr2, spr1, spr3]; + var nonMatchingArray:Array = [spr1, spr2, spr3, spr2]; + + assertEqualsArraysIgnoringOrder('these arrays should match', controlArray, matchingArray); + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, controlArray, nonMatchingArray); + } + } } \ No newline at end of file diff --git a/asunit-4.0/build.xml b/asunit-4.0/build.xml index 9edd3ca..81a37cd 100644 --- a/asunit-4.0/build.xml +++ b/asunit-4.0/build.xml @@ -1,46 +1,86 @@ - - - - - - - - - - - - - - - - - - - Using Flex SDK at: ${FLEX_HOME} - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Using Flex SDK at: ${FLEX_HOME} + + + + + + + + + + + + + + + + + + + + + + + + + [test] Running Unit Tests + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asunit-4.0/lib/SwiftSuspenders-v1.5.1.swc b/asunit-4.0/lib/SwiftSuspenders-v1.5.1.swc new file mode 100644 index 0000000..293febf Binary files /dev/null and b/asunit-4.0/lib/SwiftSuspenders-v1.5.1.swc differ diff --git a/asunit-4.0/lib/flexUnitTasks.jar b/asunit-4.0/lib/flexUnitTasks.jar new file mode 100644 index 0000000..79c5339 Binary files /dev/null and b/asunit-4.0/lib/flexUnitTasks.jar differ diff --git a/asunit-4.0/rakefile.rb b/asunit-4.0/rakefile.rb index 1758cce..a767a33 100644 --- a/asunit-4.0/rakefile.rb +++ b/asunit-4.0/rakefile.rb @@ -41,6 +41,7 @@ def configure_test_task(t) t.default_size = '1000,600' t.source_path << 'src' t.library_path << 'lib/Reflection.swc' + t.library_path << 'lib/SwiftSuspenders-v1.5.1.swc' t.debug = true t.static_link_runtime_shared_libraries = true apply_as3_meta_data_args(t) @@ -133,10 +134,12 @@ def configure_test_task(t) t.include_sources << 'src' t.source_path << 'src' t.library_path << 'lib/Reflection.swc' + t.library_path << 'lib/SwiftSuspenders-v1.5.1.swc' t.static_link_runtime_shared_libraries = true apply_as3_meta_data_args(t) end +desc "Build the SWC file for #{AsUnit::VERSION}" task :swc => "bin/AsUnit-#{AsUnit::VERSION}.swc" ########################################## @@ -171,7 +174,7 @@ def configure_test_task(t) desc "Create the gem package" -task :package_gem => :swc do +task :package => :swc do sh "gem build asunit4.gemspec" end diff --git a/asunit-4.0/sprout/lib/asunit4.rb b/asunit-4.0/sprout/lib/asunit4.rb index 1132778..e8ba9b0 100644 --- a/asunit-4.0/sprout/lib/asunit4.rb +++ b/asunit-4.0/sprout/lib/asunit4.rb @@ -4,7 +4,7 @@ module AsUnit NAME = 'asunit4' - VERSION = '4.2.2.pre' + VERSION = '4.2.3.pre' end require 'asunit4/test_class_generator' diff --git a/asunit-4.0/src/asunit/asserts/assertMatches.as b/asunit-4.0/src/asunit/asserts/assertMatches.as new file mode 100644 index 0000000..dcdcb1a --- /dev/null +++ b/asunit-4.0/src/asunit/asserts/assertMatches.as @@ -0,0 +1,6 @@ + +package asunit.asserts { + import asunit.framework.Assert; + + public const assertMatches:Function = Assert.assertMatches; +} diff --git a/asunit-4.0/src/asunit/asserts/assertNull.as b/asunit-4.0/src/asunit/asserts/assertNull.as index 31cbaa1..56a048a 100644 --- a/asunit-4.0/src/asunit/asserts/assertNull.as +++ b/asunit-4.0/src/asunit/asserts/assertNull.as @@ -1,5 +1,5 @@ -package asunit.asserts { - import asunit.framework.Assert; - - public var assertNull:Function = Assert.assertNull; -} +package asunit.asserts { + import asunit.framework.Assert; + + public var assertNull:Function = Assert.assertNull; +} diff --git a/asunit-4.0/src/asunit/asserts/assertSame.as b/asunit-4.0/src/asunit/asserts/assertSame.as index 4535456..39d23ff 100644 --- a/asunit-4.0/src/asunit/asserts/assertSame.as +++ b/asunit-4.0/src/asunit/asserts/assertSame.as @@ -1,5 +1,5 @@ -package asunit.asserts { - import asunit.framework.Assert; - - public var assertSame:Function = Assert.assertSame; -} +package asunit.asserts { + import asunit.framework.Assert; + + public var assertSame:Function = Assert.assertSame; +} diff --git a/asunit-4.0/src/asunit/asserts/assertThrowsWithMessage.as b/asunit-4.0/src/asunit/asserts/assertThrowsWithMessage.as new file mode 100644 index 0000000..1b000f5 --- /dev/null +++ b/asunit-4.0/src/asunit/asserts/assertThrowsWithMessage.as @@ -0,0 +1,5 @@ +package asunit.asserts { + import asunit.framework.Assert; + + public var assertThrowsWithMessage:Function = Assert.assertThrowsWithMessage; +} diff --git a/asunit-4.0/src/asunit/asserts/assertTrue.as b/asunit-4.0/src/asunit/asserts/assertTrue.as index 2edba6f..0a75f29 100644 --- a/asunit-4.0/src/asunit/asserts/assertTrue.as +++ b/asunit-4.0/src/asunit/asserts/assertTrue.as @@ -1,5 +1,5 @@ -package asunit.asserts { - import asunit.framework.Assert; - - public var assertTrue:Function = Assert.assertTrue; -} +package asunit.asserts { + import asunit.framework.Assert; + + public var assertTrue:Function = Assert.assertTrue; +} diff --git a/asunit-4.0/src/asunit/core/AsUnitCore.as b/asunit-4.0/src/asunit/core/AsUnitCore.as index dccd7df..666e0ca 100644 --- a/asunit-4.0/src/asunit/core/AsUnitCore.as +++ b/asunit-4.0/src/asunit/core/AsUnitCore.as @@ -1,47 +1,41 @@ package asunit.core { - - import asunit.framework.IResult; - import asunit.framework.IRunListener; - import asunit.framework.IRunner; - import asunit.framework.Result; - import asunit.framework.RunnerFactory; - import asunit.framework.TestObserver; - import asunit.runners.LegacyRunner; - - import flash.display.DisplayObjectContainer; - import flash.events.Event; - import flash.events.EventDispatcher; - import flash.events.IEventDispatcher; - import asunit.framework.InjectionDelegate; - import asunit.framework.CallbackBridge; - public class AsUnitCore implements IEventDispatcher { + import asunit.framework.IResult; + import asunit.framework.IRunnerFactory; + import asunit.framework.Result; + import asunit.framework.IRunner; + import asunit.framework.RunnerFactory; + import asunit.framework.IRunListener; + import asunit.runners.LegacyRunner; + import org.swiftsuspenders.Injector; + + import flash.display.DisplayObjectContainer; + import flash.events.Event; + import flash.events.EventDispatcher; + + public class AsUnitCore extends EventDispatcher { - [Inject] - public var bridge:CallbackBridge; + internal var result:IResult; - protected var bridgeInjector:InjectionDelegate; - protected var dispatcher:IEventDispatcher; + protected var injector:Injector; protected var legacyRunnerReference:LegacyRunner; - protected var observers:Array; protected var runner:IRunner; protected var _visualContext:DisplayObjectContainer; public function AsUnitCore() { super(); - initializeBridgeInjector(); - initializeDispatcher(); + initializeInjector(); initializeObservers(); initialize(); } - protected function initializeBridgeInjector():void { - bridgeInjector = new InjectionDelegate(); + protected function initializeInjector():void { + injector = new Injector(); + injector.mapValue(Injector, injector); + injector.mapClass(IRunnerFactory, RunnerFactory); + result = new Result(); + injector.mapValue(IResult, result); } - - protected function initializeDispatcher():void { - dispatcher = new EventDispatcher(); - } /** * Template method for subclasses to override, @@ -60,18 +54,8 @@ package asunit.core { } /** - * Add a new Observer instance to this test run. - * - * The TestObserver interface is simply a marker interface - * that indicates your observer has at least one [Inject] - * variable where a bridge will be injected. - * - * Concrete observers are coupled to concrete runners - * by using [Inject] metadata and Bridges for message passing. + * Add a listener to this test run. * - * The primary TestRunner, CallbackBridge and TextPrinter - * are good examples of how to build this relationship. - * * To use a different TestRunner on a Suite or Test, simply set: * * [RunWith("fully.qualified.ClassName")] @@ -85,9 +69,9 @@ package asunit.core { * provided by a couple of concrete runners. * */ - public function addObserver(observer:TestObserver):void { - bridgeInjector.updateInjectionPoints(observer, InjectionDelegate.THROW_ERROR_ON_MISSING_INJECTION_POINT); - } + public function addListener(listener:IRunListener):void { + result.addListener(listener); + } /** * Set the visual context that will parent all injected @@ -119,59 +103,29 @@ package asunit.core { */ public function start(testOrSuite:Class, testMethodName:String=null, visualContext:DisplayObjectContainer=null):void { - // Will instantiate a new CallbackBridge: - // and set it on this instance - but share it - // with any Runners or Observers that also - // use the CallbackBridge. - bridgeInjector.updateInjectionPoints(this, InjectionDelegate.THROW_ERROR_ON_MISSING_INJECTION_POINT); - // Must use the accessor, not the _ value: - if(visualContext) this.visualContext = visualContext; + // Must use the accessor, not the _ value: + if(visualContext) this.visualContext = visualContext; - var factory:RunnerFactory = new RunnerFactory(); - factory.injector = bridgeInjector; - runner = factory.runnerFor(testOrSuite); - runner.addEventListener(Event.COMPLETE, runCompleteHandler); - bridge.onRunStarted(); - runner.run(testOrSuite, testMethodName, this.visualContext); - } + var factory:IRunnerFactory = injector.getInstance(IRunnerFactory); + runner = factory.runnerFor(testOrSuite); + runner.addEventListener(Event.COMPLETE, onRunnerComplete); + result.onRunStarted(); + runner.run(testOrSuite, testMethodName, this.visualContext); + } - private function runCompleteHandler(event:Event):void { + protected function onRunnerComplete(event:Event):void { runner.removeEventListener(Event.COMPLETE, onRunCompleted); - bridge.onRunCompleted(bridge); - onRunCompleted(); + result.onRunCompleted(result); + onRunCompleted(); dispatchEvent(event); } - - - /** - * Template method that subclasses can override to perform some + + /** + * Subclasses can override to perform some * operation when the run is complete. */ protected function onRunCompleted():void { + } - - // BEGIN: Implement the IEvent Dispatcher Interface: - - public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { - dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); - } - - public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void { - dispatcher.removeEventListener(type, listener, useCapture); - } - - public function dispatchEvent(event:Event):Boolean { - return dispatcher.dispatchEvent(event); - } - - public function hasEventListener(type:String):Boolean { - return dispatcher.hasEventListener(type); - } - - public function willTrigger(type:String):Boolean { - return dispatcher.willTrigger(type); - } - - // END: Implement the IEvent Dispatcher Interface: } } diff --git a/asunit-4.0/src/asunit/core/FlashBuilderCore.as b/asunit-4.0/src/asunit/core/FlashBuilderCore.as index f5b5da8..46b8831 100644 --- a/asunit-4.0/src/asunit/core/FlashBuilderCore.as +++ b/asunit-4.0/src/asunit/core/FlashBuilderCore.as @@ -8,10 +8,10 @@ package asunit.core { override protected function initializeObservers():void { super.initializeObservers(); - var projectName:String = 'SomeProject'; - addObserver(new FlashBuilderPrinter(projectName)); + addListener(new FlashBuilderPrinter(projectName)); } + override protected function onRunCompleted():void { super.onRunCompleted(); fscommand('quit'); // fails silently if not in debug player diff --git a/asunit-4.0/src/asunit/core/FlashDevelopCore.as b/asunit-4.0/src/asunit/core/FlashDevelopCore.as index 088e565..6db7815 100644 --- a/asunit-4.0/src/asunit/core/FlashDevelopCore.as +++ b/asunit-4.0/src/asunit/core/FlashDevelopCore.as @@ -8,7 +8,7 @@ package asunit.core { override protected function initializeObservers():void { super.initializeObservers(); - addObserver(new FlashDevelopPrinter()); + addListener(new FlashDevelopPrinter()); } override protected function onRunCompleted():void { diff --git a/asunit-4.0/src/asunit/core/FlexUnitCICore.as b/asunit-4.0/src/asunit/core/FlexUnitCICore.as new file mode 100644 index 0000000..57ec3a2 --- /dev/null +++ b/asunit-4.0/src/asunit/core/FlexUnitCICore.as @@ -0,0 +1,17 @@ +package asunit.core { + + import asunit.printers.FlexUnitCIPrinter; + + public class FlexUnitCICore extends TextCore { + + override protected function initializeObservers():void { + super.initializeObservers(); + addListener(new FlexUnitCIPrinter()); + } + + override protected function onRunCompleted():void { + super.onRunCompleted(); + // The FlexUnitCIPrinter will close Flash Player when the socket acknowledges the end. + } + } +} diff --git a/asunit-4.0/src/asunit/core/TextCore.as b/asunit-4.0/src/asunit/core/TextCore.as index ab02faa..352c357 100644 --- a/asunit-4.0/src/asunit/core/TextCore.as +++ b/asunit-4.0/src/asunit/core/TextCore.as @@ -1,9 +1,10 @@ package asunit.core { - import asunit.printers.TextPrinter; - - import flash.display.DisplayObjectContainer; + import asunit.printers.ColorTracePrinter; + import asunit.printers.TextPrinter; + import flash.display.DisplayObjectContainer; + /** * TextCore is just a simple helper class that * configures the base class AsUnitCore to use the @@ -17,32 +18,17 @@ package asunit.core { */ public class TextCore extends AsUnitCore { - private var textPrinter:TextPrinter; + public var textPrinter:TextPrinter; override protected function initializeObservers():void { super.initializeObservers(); textPrinter = new TextPrinter(); - addObserver(textPrinter); - } - - /* Delegate some configuration to the TextPrinter */ - public function set displayPerformanceDetails(show:Boolean):void { - textPrinter.displayPerformanceDetails = show; - } - - public function get displayPerformanceDetails():Boolean { - return textPrinter.displayPerformanceDetails; - } - - public function set traceOnComplete(should:Boolean):void { - textPrinter.traceOnComplete = should; - } + textPrinter.traceOnComplete = false; + addListener(textPrinter); - public function get traceOnComplete():Boolean { - return textPrinter.traceOnComplete; + addListener(new ColorTracePrinter()); } - override public function set visualContext(context:DisplayObjectContainer):void { super.visualContext = context; diff --git a/asunit-4.0/src/asunit/framework/Assert.as b/asunit-4.0/src/asunit/framework/Assert.as index 4ef249f..29cd403 100644 --- a/asunit-4.0/src/asunit/framework/Assert.as +++ b/asunit-4.0/src/asunit/framework/Assert.as @@ -111,6 +111,37 @@ package asunit.framework { throw new AssertionFailedError("expected error type:<" + getQualifiedClassName(errorType) + "> but none was thrown." ); } + /** + * Asserts that the provided block throws an exception that matches + * the type and message provided. + * + * + * public function testFailingCode():void { + * assertThrows(CustomError, "Invalid state", function():void { + * var instance:Sprite = new Sprite(); + * instance.callMethodThatThrows(); + * }); + * } + * + **/ + static public function assertThrowsWithMessage(errorType:Class, errorMessage:String, block:Function):void { + try { + block.call(); + } + catch(e:Error) { + if(!(e is errorType)) { + throw new AssertionFailedError("expected error type:<" + getQualifiedClassName(errorType) + +"> but was:<" + getQualifiedClassName(e) + ">"); + } + if(e.message != errorMessage) { + throw new AssertionFailedError("expected error message:<" + errorMessage + +"> but was:<" + e.message + ">"); + } + return; + } + throw new AssertionFailedError("expected error type:<" + getQualifiedClassName(errorType) + "> with message:<" + errorMessage + "> but none was thrown." ); + } + /** * Asserts that two objects are equal. If they are not * an AssertionFailedError is thrown with the given message. @@ -188,6 +219,30 @@ package asunit.framework { throw new AssertionFailedError(message + "expected not null but was:<" + actual + ">"); } } + + static public function assertMatches(...args:Array):void { + var message:String; + var expr:RegExp; + var content:String; + + if(args.length == 2) { + message = ""; + expr = args[0]; + content = args[1]; + } + else if(args.length == 3) { + message = args[0]; + expr = args[1]; + content = args[2]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + if(!content.match(expr)) { + fail("Unable to match [" + expr + "] in content: [" + content + "]"); + } + } + /** * Asserts that an object is null. If it is not * an AssertionFailedError is thrown with the given message. @@ -373,24 +428,34 @@ package asunit.framework { if (expected.length != actual.length) { failNotEquals(message, expected, actual); } - for (var i : int = 0; i < expected.length; i++) { - var foundMatch : Boolean = false; - var expectedMember : Object = expected[i]; - for (var j : int = 0; j < actual.length; j++) { - var actualMember : Object = actual[j]; + + var unusedPotentialMatches:Array = actual.slice(); + + var iLength:uint = expected.length; + var jLength:uint; + + searchingForExpectedItems: + for (var i:int = 0; i < iLength; i++) + { + var expectedMember : Object = expected[i]; + jLength = unusedPotentialMatches.length; + + checkingAgainstActualItems: + for (var j : int = 0; j < jLength; j++) { + var actualMember : Object = unusedPotentialMatches[j]; try { assertEquals(expectedMember, actualMember); - foundMatch = true; - break; + unusedPotentialMatches.splice(j, 1); + continue searchingForExpectedItems; } catch (e : AssertionFailedError) { // no match, try next } } - if (!foundMatch) { - failNotEquals("Found no match for " + expectedMember + ";", expected, actual); - } - } + + failNotEquals("Found no match for " + expectedMember + ";", expected, actual); + + } } static private function failNotEquals(message:String, expected:Object, actual:Object):void { diff --git a/asunit-4.0/src/asunit/framework/Async.as b/asunit-4.0/src/asunit/framework/Async.as index 336f2e9..8dd6c6e 100644 --- a/asunit-4.0/src/asunit/framework/Async.as +++ b/asunit-4.0/src/asunit/framework/Async.as @@ -1,138 +1,138 @@ -package asunit.framework { - - import asunit.framework.ErrorEvent; - - import asunit.events.TimeoutCommandEvent; - - import flash.events.Event; - import flash.events.EventDispatcher; - import flash.events.IEventDispatcher; - - public class Async extends EventDispatcher implements IAsync { - - public static var DEFAULT_TIMEOUT:uint = 50; - - private var _timeout:int = DEFAULT_TIMEOUT; - protected var pending:Array; - - /** - * Asynchronous handler class. - * - * This class give you the ability to create Asynchronous event handlers - * and pause test execution until those handlers are triggered. - * - * To take advantage of Asynchronous features, add a member variable - * to your test like: - * - * [Inject] - * public var async:IAsync; - * - * This public property will be injected with an IAsync instance - * before each test method. - * - * Within your test methods, you can add Async callbacks with: - * - * [Test] - * public function verifySomething():void { - * async.add(handler); - * } - * - * In the previous example, test execution will be halted until the - * +handler+ method is called. - * - * It's worth noting that AsUnit does not store any state related - * to the playback of your test harness in global variables. - * - */ - public function Async() { - pending = []; - } - - public function get hasPending():Boolean { - return pending.length > 0; - } - - public function set timeout(timeout:int):void { - _timeout = timeout; - } - - public function get timeout():int { - return _timeout; - } - - /** - * Returns a new async handler that should be used as the observer of some - * presumably asynchronous event. - * - * You can optionally pass a function closure that you would like to have - * executed when the provided handler is called. If this closure includes - * assertions, they will display in the test result. - * - * You can also override the default timeout (50ms) with a new value for - * this particular handler. - * - * This method may be called any number of times in a given [Test], [BeforeClass], - * or [Before] method. - * - * Test execution will be paused until all async handlers have returned - * or timed out. - * - * One way to use this method, is to simply send it to an event that you - * expect to have dispatched within a given time. - * - * instance.addEventListener(Event.COMPLETE, addAsync()); - * - * In this example, you will receive a timeout error if the COMPLETE - * event is not dispatched within 50ms. - * - */ - public function add(handler:Function=null, duration:int=-1):Function { - if (duration == -1) duration = timeout; - handler ||= function(...args):* {}; - var command:TimeoutCommand = new TimeoutCommand(null, handler, duration); - addPending(command); - return command.getCallback(); - } - - public function proceedOnEvent(target:IEventDispatcher, eventName:String, timeout:int=500, timeoutHandler:Function=null):void { - var asyncHandler:Function = add(null, timeout); - target.addEventListener(eventName, asyncHandler, false, 0, true); - } - - public function cancelPending():void { - for (var i:uint = pending.length; i--; ) { - var command:TimeoutCommand = TimeoutCommand(pending.pop()); - command.cancel(); - command.removeEventListener(TimeoutCommandEvent.CALLED, onTestResult); - command.removeEventListener(TimeoutCommandEvent.TIMED_OUT, onTestResult); - } - } - - // Partially opened for testing purposes. - public function getPending():Array { - // Clone to prevent changing by reference. - return pending.slice(); - } - - protected function addPending(command:TimeoutCommand):void { - pending.push(command); - command.addEventListener(TimeoutCommandEvent.CALLED, onTestResult); - command.addEventListener(TimeoutCommandEvent.TIMED_OUT, onTestResult); - command.addEventListener(ErrorEvent.ERROR, onTestResult); - dispatchEvent(new TimeoutCommandEvent(TimeoutCommandEvent.ADDED, command)); - } - - protected function onTestResult(e:Event):void { - var command:TimeoutCommand = TimeoutCommand(e.currentTarget); - command.removeEventListener(TimeoutCommandEvent.CALLED, onTestResult); - command.removeEventListener(TimeoutCommandEvent.TIMED_OUT, onTestResult); - removePending(command); - dispatchEvent(e); - } - - protected function removePending(command:TimeoutCommand):void { - pending.splice(pending.indexOf(command), 1); - } - } -} - +package asunit.framework { + + import asunit.framework.ErrorEvent; + + import asunit.events.TimeoutCommandEvent; + + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.IEventDispatcher; + + public class Async extends EventDispatcher implements IAsync { + + public static var DEFAULT_TIMEOUT:uint = 50; + + private var _timeout:int = DEFAULT_TIMEOUT; + protected var pending:Array; + + /** + * Asynchronous handler class. + * + * This class give you the ability to create Asynchronous event handlers + * and pause test execution until those handlers are triggered. + * + * To take advantage of Asynchronous features, add a member variable + * to your test like: + * + * [Inject] + * public var async:IAsync; + * + * This public property will be injected with an IAsync instance + * before each test method. + * + * Within your test methods, you can add Async callbacks with: + * + * [Test] + * public function verifySomething():void { + * async.add(handler); + * } + * + * In the previous example, test execution will be halted until the + * +handler+ method is called. + * + * It's worth noting that AsUnit does not store any state related + * to the playback of your test harness in global variables. + * + */ + public function Async() { + pending = []; + } + + public function get hasPending():Boolean { + return pending.length > 0; + } + + public function set timeout(timeout:int):void { + _timeout = timeout; + } + + public function get timeout():int { + return _timeout; + } + + /** + * Returns a new async handler that should be used as the listener of some + * presumably asynchronous event. + * + * You can optionally pass a function closure that you would like to have + * executed when the provided handler is called. If this closure includes + * assertions, they will display in the test result. + * + * You can also override the default timeout (50ms) with a new value for + * this particular handler. + * + * This method may be called any number of times in a given [Test], [BeforeClass], + * or [Before] method. + * + * Test execution will be paused until all async handlers have returned + * or timed out. + * + * One way to use this method, is to simply send it to an event that you + * expect to have dispatched within a given time. + * + * instance.addEventListener(Event.COMPLETE, addAsync()); + * + * In this example, you will receive a timeout error if the COMPLETE + * event is not dispatched within 50ms. + * + */ + public function add(handler:Function=null, duration:int=-1):Function { + if (duration == -1) duration = timeout; + handler ||= function(...args):* {}; + var command:TimeoutCommand = new TimeoutCommand(null, handler, duration); + addPending(command); + return command.getCallback(); + } + + public function proceedOnEvent(target:IEventDispatcher, eventName:String, timeout:int=500, timeoutHandler:Function=null):void { + var asyncHandler:Function = add(null, timeout); + target.addEventListener(eventName, asyncHandler, false, 0, true); + } + + public function cancelPending():void { + for (var i:uint = pending.length; i--; ) { + var command:TimeoutCommand = TimeoutCommand(pending.pop()); + command.cancel(); + command.removeEventListener(TimeoutCommandEvent.CALLED, onTestResult); + command.removeEventListener(TimeoutCommandEvent.TIMED_OUT, onTestResult); + } + } + + // Partially opened for testing purposes. + public function getPending():Array { + // Clone to prevent changing by reference. + return pending.slice(); + } + + protected function addPending(command:TimeoutCommand):void { + pending.push(command); + command.addEventListener(TimeoutCommandEvent.CALLED, onTestResult); + command.addEventListener(TimeoutCommandEvent.TIMED_OUT, onTestResult); + command.addEventListener(ErrorEvent.ERROR, onTestResult); + dispatchEvent(new TimeoutCommandEvent(TimeoutCommandEvent.ADDED, command)); + } + + protected function onTestResult(e:Event):void { + var command:TimeoutCommand = TimeoutCommand(e.currentTarget); + command.removeEventListener(TimeoutCommandEvent.CALLED, onTestResult); + command.removeEventListener(TimeoutCommandEvent.TIMED_OUT, onTestResult); + removePending(command); + dispatchEvent(e); + } + + protected function removePending(command:TimeoutCommand):void { + pending.splice(pending.indexOf(command), 1); + } + } +} + diff --git a/asunit-4.0/src/asunit/framework/CallbackBridge.as b/asunit-4.0/src/asunit/framework/CallbackBridge.as deleted file mode 100644 index 272af04..0000000 --- a/asunit-4.0/src/asunit/framework/CallbackBridge.as +++ /dev/null @@ -1,175 +0,0 @@ -package asunit.framework { - - public class CallbackBridge implements IResult { - - private var listeners:Array; - - [Inject] - public var model:Result; - - public function CallbackBridge() { - initialize(); - } - - protected function initialize():void - { - listeners = []; - model = new Result(); - } - - public function get length():int { - return listeners.length; - } - - public function onRunStarted():void { - model.onRunStarted(); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onRunStarted(); - }); - } - - public function onRunCompleted(result:IResult):void { - model.onRunCompleted(result); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onRunCompleted(result); - }); - } - - public function onTestStarted(test:Object):void { - model.onTestStarted(test); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onTestStarted(test); - }); - } - - public function onTestCompleted(test:Object):void { - model.onTestCompleted(test); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onTestCompleted(test); - }); - } - - public function onTestFailure(failure:ITestFailure):void { - model.onTestFailure(failure); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onTestFailure(failure); - }); - } - - public function onTestSuccess(success:ITestSuccess):void { - model.onTestSuccess(success); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onTestSuccess(success); - }); - } - - public function onTestIgnored(method:Method):void { - model.onTestIgnored(method); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onTestIgnored(method); - }); - } - - public function onWarning(warning:ITestWarning):void { - model.onWarning(warning); - listeners.forEach(function(listener:IRunListener, index:int, items:Array):void { - listener.onWarning(warning); - }); - } - - //--------------------------------------- - // IResult Implementation - //--------------------------------------- - - public function get errors():Array - { - return model.errors; - } - - public function get errorCount():uint - { - return model.errorCount; - } - - public function get failures():Array - { - return model.failures; - } - - public function get failureCount():uint - { - return model.failureCount; - } - - public function get successes():Array - { - return model.successes; - } - - public function get successCount():uint - { - return model.successCount; - } - - public function get warnings():Array - { - return model.warnings; - } - - public function get ignoredTests():Array - { - return model.ignoredTests; - } - - public function get ignoredTestCount():uint - { - return model.ignoredTestCount; - } - - public function get runCount():uint - { - return model.runCount; - } - - public function get failureEncountered():Boolean - { - return model.failureEncountered; - } - - public function get wasSuccessful():Boolean - { - return model.wasSuccessful; - } - - public function get runTime():Number - { - return model.runTime; - } - - public function set runTime(value:Number):void - { - model.runTime = value; - } - - public function addListener(listener:IRunListener):void - { - model.addListener(listener); - listeners.push(listener); - } - - public function removeListener(listener:IRunListener):void - { - model.removeListener(listener); - } - - public function addObserver(observer:TestObserver):void - { - model.addObserver(observer); - } - - public function shouldRunTest(testClass:Class):Boolean - { - return model.shouldRunTest(testClass); - } - } -} \ No newline at end of file diff --git a/asunit-4.0/src/asunit/framework/Command.as b/asunit-4.0/src/asunit/framework/Command.as index 74a6400..2bca187 100644 --- a/asunit-4.0/src/asunit/framework/Command.as +++ b/asunit-4.0/src/asunit/framework/Command.as @@ -1,6 +1,6 @@ -package asunit.framework { - - public interface Command { - function execute():*; - } -} +package asunit.framework { + + public interface Command { + function execute():*; + } +} diff --git a/asunit-4.0/src/asunit/framework/IResult.as b/asunit-4.0/src/asunit/framework/IResult.as index 82c7e4c..49b9b6c 100644 --- a/asunit-4.0/src/asunit/framework/IResult.as +++ b/asunit-4.0/src/asunit/framework/IResult.as @@ -1,36 +1,31 @@ -package asunit.framework { - - import asunit.framework.ITestFailure; - - public interface IResult extends MessageBridge, IRunListener, ITestListener { - - function addListener(listener:IRunListener):void; - function removeListener(listener:IRunListener):void; - - function addObserver(observer:TestObserver):void; - function shouldRunTest(testClass:Class):Boolean; - - function get errors():Array; - function get errorCount():uint; - - function get failures():Array; - function get failureCount():uint; - - function get successes():Array; - function get successCount():uint; - - function get warnings():Array; - - function get ignoredTests():Array; - function get ignoredTestCount():uint; - - function get runCount():uint; - - function get failureEncountered():Boolean; - function get wasSuccessful():Boolean; - - function get runTime():Number; - function set runTime(value:Number):void; - } -} - +package asunit.framework { + + public interface IResult extends IRunListener, ITestListener { + + function addListener(listener:IRunListener):void; + function removeListener(listener:IRunListener):void; + + function get errors():Array; + function get errorCount():uint; + + function get failures():Array; + function get failureCount():uint; + + function get successes():Array; + function get successCount():uint; + + function get warnings():Array; + + function get ignoredTests():Array; + function get ignoredTestCount():uint; + + function get runCount():uint; + + function get failureEncountered():Boolean; + function get wasSuccessful():Boolean; + + function get runTime():Number; + function set runTime(value:Number):void; + } +} + diff --git a/asunit-4.0/src/asunit/framework/IRunListener.as b/asunit-4.0/src/asunit/framework/IRunListener.as index 84ade87..f9c4fde 100644 --- a/asunit-4.0/src/asunit/framework/IRunListener.as +++ b/asunit-4.0/src/asunit/framework/IRunListener.as @@ -1,8 +1,5 @@ package asunit.framework { - import asunit.framework.ITestFailure; - import asunit.framework.IResult; - public interface IRunListener extends ITestListener { function onRunStarted():void; function onRunCompleted(result:IResult):void; diff --git a/asunit-4.0/src/asunit/framework/IRunner.as b/asunit-4.0/src/asunit/framework/IRunner.as index 0db5a2f..a4cb190 100644 --- a/asunit-4.0/src/asunit/framework/IRunner.as +++ b/asunit-4.0/src/asunit/framework/IRunner.as @@ -6,10 +6,7 @@ package asunit.framework { public interface IRunner extends IEventDispatcher { function run(testOrSuite:Class, testMethodName:String=null, visualContext:DisplayObjectContainer=null):void; - function shouldRunTest(testClass:Class):Boolean; - function set factory(factory:IRunnerFactory):void; - function get factory():IRunnerFactory; } } diff --git a/asunit-4.0/src/asunit/framework/IRunnerFactory.as b/asunit-4.0/src/asunit/framework/IRunnerFactory.as index 5c42e74..29146db 100644 --- a/asunit-4.0/src/asunit/framework/IRunnerFactory.as +++ b/asunit-4.0/src/asunit/framework/IRunnerFactory.as @@ -1,9 +1,9 @@ package asunit.framework { - + import org.swiftsuspenders.Injector; public interface IRunnerFactory { - function get injector():InjectionDelegate; - function set injector(value:InjectionDelegate):void; + function get injector():Injector; + function set injector(value:Injector):void; function runnerFor(testOrSuite:Class):IRunner; } } \ No newline at end of file diff --git a/asunit-4.0/src/asunit/framework/ITestListener.as b/asunit-4.0/src/asunit/framework/ITestListener.as index 9a2287b..761393d 100644 --- a/asunit-4.0/src/asunit/framework/ITestListener.as +++ b/asunit-4.0/src/asunit/framework/ITestListener.as @@ -1,9 +1,8 @@ package asunit.framework { import asunit.framework.ITestFailure; - import asunit.framework.TestObserver; - public interface ITestListener extends TestObserver { + public interface ITestListener { function onTestStarted(test:Object):void; function onTestCompleted(test:Object):void; function onTestFailure(failure:ITestFailure):void; diff --git a/asunit-4.0/src/asunit/framework/ITestResult.as b/asunit-4.0/src/asunit/framework/ITestResult.as deleted file mode 100644 index 68a570e..0000000 --- a/asunit-4.0/src/asunit/framework/ITestResult.as +++ /dev/null @@ -1,21 +0,0 @@ -package asunit.framework { - - public interface ITestResult { - - function addFailure(failure:ITestFailure):void; - - function get errors():Array; - function get errorCount():uint; - - function get failures():Array; - function get failureCount():uint; - - function get runCount():uint; - function set runCount(value:uint):void; - - function get wasSuccessful():Boolean; - - function addListener(listener:ITestListener):void; - function removeListener(listener:ITestListener):void; - } -} diff --git a/asunit-4.0/src/asunit/framework/InjectionDelegate.as b/asunit-4.0/src/asunit/framework/InjectionDelegate.as deleted file mode 100644 index 581d783..0000000 --- a/asunit-4.0/src/asunit/framework/InjectionDelegate.as +++ /dev/null @@ -1,96 +0,0 @@ -package asunit.framework { - - import p2.reflect.ReflectionMetaData; - import p2.reflect.Reflection; - - import flash.utils.Dictionary; - import asunit.errors.UsageError; - import p2.reflect.ReflectionVariable; - import p2.reflect.ReflectionMember; - import flash.utils.getDefinitionByName; - - public class InjectionDelegate { - //--------------------------------------- - // CLASS CONSTANTS - //--------------------------------------- - - public static const THROW_ERROR_ON_MISSING_INJECTION_POINT:Boolean = true; - public static const INJECT_ANNOTATION:String = "Inject"; - - private var entities:Dictionary; - - public function InjectionDelegate() - { - entities = new Dictionary(); - } - - /** - * @param addict * an entity with at least one [Inject] annotation - */ - public function updateInjectionPoints(addict:*, throwErrorOnMissingInjection:Boolean=false):void { - var reflection:Reflection = Reflection.create(addict); - var members:Array = reflection.getMembersByMetaData(INJECT_ANNOTATION); - var addictName:String = reflection.name - if (throwErrorOnMissingInjection) - { - validateMembers(members, addictName); - } - var reflectionVariable:ReflectionVariable; - var injectionPointFound:Boolean; - members.forEach(function(member:ReflectionMember, index:int, items:Array):void { - reflectionVariable = member as ReflectionVariable; - if (reflectionVariable) - { - updateInjectionPoint(addict, reflectionVariable); - injectionPointFound = true; - } - }); - - if (!injectionPointFound && throwErrorOnMissingInjection) - { - throw new UsageError("InjectionDelegate expected at least one [Inject] annotation on a variable or accessor on" + addictName); - } - - } - - /** - * For each inject annotation we call this method - * @private - * @return - */ - private function updateInjectionPoint(addict:*, member:ReflectionVariable):void { - //FIXME: This actually could be a getter. If someone has their head up their booty. - var instance:* = getInstanceFromTypeName(member.type); - addict[member.name] = instance; - } - - private function getInstanceFromTypeName(name:String):* { - var clazz:Class = getDefinitionByName(name) as Class; - return getOrCacheInstanceFromClass(clazz); - } - - private function getOrCacheInstanceFromClass(clazz:Class):* { - if (!entities[clazz]) - { - //FIXME: This will choke if given a class with constructor arguments! - entities[clazz] = new clazz(); - updateInjectionPoints(entities[clazz]); - } - - return entities[clazz]; - } - - /** - * @private - */ - private function validateMembers(members:Array, name:String):void - { - if (!members || members.length == 0) - { - throw new UsageError("InjectionDelegate expects at least one [Inject] annotation on " + name); - } - - } - - } -} \ No newline at end of file diff --git a/asunit-4.0/src/asunit/framework/MessageBridge.as b/asunit-4.0/src/asunit/framework/MessageBridge.as deleted file mode 100644 index e319527..0000000 --- a/asunit-4.0/src/asunit/framework/MessageBridge.as +++ /dev/null @@ -1,24 +0,0 @@ -package asunit.framework { - - /** - * MessageBridge is a marker interface that is used - * by AsUnit core in order to support custom messaging - * schemes between TestObservers and IRunners. - * - * The idea is that you [Inject] one or more entities - * into your concrete IRunner and related TestObservers. - * - * The contract is between the concrete MessageBridge, - * and the other actors that [Inject] it into. - * - * This implementation gives AsUnit the ability to support - * a variety of messaging protocols including native - * Flash EventDispatchers, callbacks, and even progressive - * systems like AS3Signals. The decision as to which - * messaging system to use is made by the person creating - * the concrete Runner and Observer. - */ - public interface MessageBridge { - } -} - diff --git a/asunit-4.0/src/asunit/framework/Method.as b/asunit-4.0/src/asunit/framework/Method.as index 93a642d..6135ccd 100644 --- a/asunit-4.0/src/asunit/framework/Method.as +++ b/asunit-4.0/src/asunit/framework/Method.as @@ -1,80 +1,82 @@ -package asunit.framework { - - import p2.reflect.Reflection; - import p2.reflect.ReflectionMethod; - import p2.reflect.ReflectionMetaData; - - public class Method { - - private var _scopeName:String; - - public var expects:String; - public var ignore:Boolean; - public var ignoreDescription:String; - public var metadata:ReflectionMetaData; - public var name:String; - public var order:int = 0; - public var scope:Object; - public var timeout:int = -1; - public var value:Function; - - public function Method(scope:Object, reflection:ReflectionMethod) { - this.scope = scope; - this.name = reflection.name; - this.value = scope[reflection.name]; - - metadata = reflection.getMetaDataByName('Test'); - - if(metadata != null) { - var ignoreReflection:ReflectionMetaData = reflection.getMetaDataByName('Ignore'); - if(ignoreReflection) { - ignore = true; - ignoreDescription = ignoreReflection.getValueFor('description'); - } - - handleTimeoutMetaData(); - applyMetaData('expects'); - applyMetaData('order'); - } - } - - public function get scopeName():String { - return _scopeName ||= Reflection.create(scope).name - } - - private function handleTimeoutMetaData():void { - var value:* = metadata.getValueFor('timeout'); - if(value != null) { - var message:String = "It seems you're using [Test(timeout=n)] for " + name + ", but this has been deprecated.\n"; - message += "If you'd like to set a different timeout value, please send it to your Async instance methods like: async.add(null, timeoutInMilliseconds)"; - trace("[DEPRECATION WARNING] " + message); - } - } - - // The null response for timeout was updating the - // int field to zero when it needs to be -1... - private function applyMetaData(name:String):void { - var value:* = metadata.getValueFor(name); - if(value != null) { - this[name] = value; - } - } - - public function execute():void { - value.call(scope); - } - - public function get isTest():Boolean { - return (metadata != null || isLegacyTest); - } - - public function get isLegacyTest():Boolean { - return (metadata == null && name.match(/^test/)); - } - - public function toString():String { - return name; - } - } -} - +package asunit.framework { + + import p2.reflect.Reflection; + import p2.reflect.ReflectionMethod; + import p2.reflect.ReflectionMetaData; + + public class Method { + + private var _scopeName:String; + + public var expects:String; + public var message:String; + public var ignore:Boolean; + public var ignoreDescription:String; + public var metadata:ReflectionMetaData; + public var name:String; + public var order:int = 0; + public var scope:Object; + public var timeout:int = -1; + public var value:Function; + + public function Method(scope:Object, reflection:ReflectionMethod) { + this.scope = scope; + this.name = reflection.name; + this.value = scope[reflection.name]; + + metadata = reflection.getMetaDataByName('Test'); + + if(metadata != null) { + var ignoreReflection:ReflectionMetaData = reflection.getMetaDataByName('Ignore'); + if(ignoreReflection) { + ignore = true; + ignoreDescription = ignoreReflection.getValueFor('description'); + } + + handleTimeoutMetaData(); + applyMetaData('expects'); + applyMetaData('message'); + applyMetaData('order'); + } + } + + public function get scopeName():String { + return _scopeName ||= Reflection.create(scope).name + } + + private function handleTimeoutMetaData():void { + var value:* = metadata.getValueFor('timeout'); + if(value != null) { + var message:String = "It seems you're using [Test(timeout=n)] for " + name + ", but this has been deprecated.\n"; + message += "If you'd like to set a different timeout value, please send it to your Async instance methods like: async.add(null, timeoutInMilliseconds)"; + trace("[DEPRECATION WARNING] " + message); + } + } + + // The null response for timeout was updating the + // int field to zero when it needs to be -1... + private function applyMetaData(name:String):void { + var value:* = metadata.getValueFor(name); + if(value != null) { + this[name] = value; + } + } + + public function execute():void { + value.call(scope); + } + + public function get isTest():Boolean { + return (metadata != null || isLegacyTest); + } + + public function get isLegacyTest():Boolean { + return (metadata == null && name.match(/^test/)); + } + + public function toString():String { + return name; + } + } +} + diff --git a/asunit-4.0/src/asunit/framework/Result.as b/asunit-4.0/src/asunit/framework/Result.as index 0734412..d6e12cb 100644 --- a/asunit-4.0/src/asunit/framework/Result.as +++ b/asunit-4.0/src/asunit/framework/Result.as @@ -1,181 +1,160 @@ -package asunit.framework { - - import asunit.errors.UsageError; - import asunit.framework.ITestFailure; - - import flash.events.EventDispatcher; - import flash.utils.Dictionary; - - /** - * A Result collects the results of executing - * a test case. It is an instance of the Collecting Parameter pattern. - * The test framework distinguishes between failures and errors. - * A failure is anticipated and checked for with assertions. Errors are - * unanticipated problems like an ArrayIndexOutOfBoundsException. - * - * @see Test - */ - public class Result extends EventDispatcher implements IResult { - - protected var _runCount:uint = 0; - protected var _runTime:Number; - protected var _errors:Array; - protected var _failures:Array; - protected var _ignoredTests:Array; - protected var _successes:Array; - protected var _warnings:Array; - - protected var listeners:Array; - protected var runComplete:Boolean; - protected var knownTests:Dictionary; - - public function Result() { - _errors = []; - _failures = []; - _ignoredTests = []; - _successes = []; - _warnings = []; - listeners = []; - knownTests = new Dictionary(); - } - - public function get errors():Array { return _errors; } - - /** - * Gets the number of detected errors. - */ - public function get errorCount():uint { return _errors.length; } - - /** - * - */ - public function get failures():Array { return _failures; } - - /** - * Gets the number of detected failures. - */ - public function get failureCount():uint { return _failures.length; } - - public function get successes():Array { return _successes; } - - public function get successCount():uint { return _successes.length; } - - public function get warnings():Array { return _warnings; } - - public function get ignoredTests():Array { return _ignoredTests; } - - public function get ignoredTestCount():uint { return _ignoredTests.length; } - - public function get runCount():uint { - return errorCount + failureCount + successCount; - } - - public function get runTime():Number { return _runTime; } - public function set runTime(value:Number):void { _runTime = value; } - - public function shouldRunTest(testClass:Class):Boolean { - if(!knownTests[testClass]) { - knownTests[testClass] = testClass; - return true; - } - return false; - } - - public function addObserver(observer:TestObserver):void { - if(!(observer is IRunListener)) { - throw new UsageError("Result.addObserver called with an instance that wasn't an IRunListener. This should work soon, but doesn't yet..."); - } - addListener(IRunListener(observer)); - } - - public function addListener(listener:IRunListener):void { - if (listeners.indexOf(listener) >= 0) return; - listeners.push(listener); - } - - public function removeListener(listener:IRunListener):void { - listeners.splice(listeners.indexOf(listener), 1); - } - - public function onRunStarted():void { - for each (var listener:IRunListener in listeners) { - listener.onRunStarted(); - } - } - - public function onRunCompleted(result:IResult):void { - runComplete = true; - for each (var listener:IRunListener in listeners) { - listener.onRunCompleted(this); - } - } - - public function onTestStarted(test:Object):void { - for each (var listener:IRunListener in listeners) { - listener.onTestStarted(test); - } - } - - public function onTestCompleted(test:Object):void { - for each (var listener:IRunListener in listeners) { - listener.onTestCompleted(test); - } - } - - /** - * Adds a failure to the list of failures. The passed in exception - * caused the failure. - */ - public function onTestFailure(failure:ITestFailure):void { - if (failure.isFailure) - _failures.push(failure); - else - _errors.push(failure); - - for each (var listener:IRunListener in listeners) { - listener.onTestFailure(failure); - } - } - - public function onTestSuccess(success:ITestSuccess):void { - _successes.push(success); - - for each (var listener:IRunListener in listeners) { - listener.onTestSuccess(success); - } - } - - public function onTestIgnored(method:Method):void { - _ignoredTests.push(method); - - for each (var listener:IRunListener in listeners) { - listener.onTestIgnored(method); - } - } - - public function onWarning(warning:ITestWarning):void { - _warnings.push(warning); - - for each (var listener:IRunListener in listeners) { - listener.onWarning(warning); - } - } - - /** - * Returns whether or not we have yet encountered a failure or error. - * Will be accurate when checked at any time during test run. - */ - public function get failureEncountered():Boolean { - return (failureCount > 0 || errorCount > 0); - } - - /** - * Returns whether or not the entire test was successful. - * Will only return true after +onRunCompleted+ called. - */ - public function get wasSuccessful():Boolean { - return (runComplete && !failureEncountered); - } - - } -} +package asunit.framework { + + import asunit.errors.UsageError; + + /** + * A Result collects the results of executing + * a test case. It is an instance of the Collecting Parameter pattern. + * The test framework distinguishes between failures and errors. + * A failure is anticipated and checked for with assertions. Errors are + * unanticipated problems like an ArrayIndexOutOfBoundsException. + * + * @see Test + */ + public class Result implements IResult { + + protected var _runCount:uint = 0; + protected var _runTime:Number; + protected var _errors:Array; + protected var _failures:Array; + protected var _ignoredTests:Array; + protected var _successes:Array; + protected var _warnings:Array; + + protected var listeners:Array; + protected var runComplete:Boolean; + + public function Result() { + _errors = []; + _failures = []; + _ignoredTests = []; + _successes = []; + _warnings = []; + listeners = []; + } + + public function get errors():Array { return _errors; } + + /** + * Gets the number of detected errors. + */ + public function get errorCount():uint { return _errors.length; } + + /** + * + */ + public function get failures():Array { return _failures; } + + /** + * Gets the number of detected failures. + */ + public function get failureCount():uint { return _failures.length; } + + public function get successes():Array { return _successes; } + + public function get successCount():uint { return _successes.length; } + + public function get warnings():Array { return _warnings; } + + public function get ignoredTests():Array { return _ignoredTests; } + + public function get ignoredTestCount():uint { return _ignoredTests.length; } + + public function get runCount():uint { + return errorCount + failureCount + successCount; + } + + public function get runTime():Number { return _runTime; } + public function set runTime(value:Number):void { _runTime = value; } + + public function addListener(listener:IRunListener):void { + if (listeners.indexOf(listener) >= 0) return; + listeners.push(listener); + } + + public function removeListener(listener:IRunListener):void { + listeners.splice(listeners.indexOf(listener), 1); + } + + public function onRunStarted():void { + for each (var listener:IRunListener in listeners) { + listener.onRunStarted(); + } + } + + public function onRunCompleted(result:IResult):void { + runComplete = true; + for each (var listener:IRunListener in listeners) { + listener.onRunCompleted(this); + } + } + + public function onTestStarted(test:Object):void { + for each (var listener:IRunListener in listeners) { + listener.onTestStarted(test); + } + } + + public function onTestCompleted(test:Object):void { + for each (var listener:IRunListener in listeners) { + listener.onTestCompleted(test); + } + } + + /** + * Adds a failure to the list of failures. The passed in exception + * caused the failure. + */ + public function onTestFailure(failure:ITestFailure):void { + if (failure.isFailure) + _failures.push(failure); + else + _errors.push(failure); + + for each (var listener:IRunListener in listeners) { + listener.onTestFailure(failure); + } + } + + public function onTestSuccess(success:ITestSuccess):void { + _successes.push(success); + + for each (var listener:IRunListener in listeners) { + listener.onTestSuccess(success); + } + } + + public function onTestIgnored(method:Method):void { + _ignoredTests.push(method); + + for each (var listener:IRunListener in listeners) { + listener.onTestIgnored(method); + } + } + + public function onWarning(warning:ITestWarning):void { + _warnings.push(warning); + + for each (var listener:IRunListener in listeners) { + listener.onWarning(warning); + } + } + + /** + * Returns whether or not we have yet encountered a failure or error. + * Will be accurate when checked at any time during test run. + */ + public function get failureEncountered():Boolean { + return (failureCount > 0 || errorCount > 0); + } + + /** + * Returns whether or not the entire test was successful. + * Will only return true after +onRunCompleted+ called. + */ + public function get wasSuccessful():Boolean { + return (runComplete && !failureEncountered); + } + + } +} diff --git a/asunit-4.0/src/asunit/framework/RunnerFactory.as b/asunit-4.0/src/asunit/framework/RunnerFactory.as index 198b87b..5a6f1f7 100644 --- a/asunit-4.0/src/asunit/framework/RunnerFactory.as +++ b/asunit-4.0/src/asunit/framework/RunnerFactory.as @@ -9,7 +9,7 @@ package asunit.framework { import p2.reflect.Reflection; import p2.reflect.ReflectionMetaData; - import asunit.framework.InjectionDelegate; + import org.swiftsuspenders.Injector; public class RunnerFactory implements IRunnerFactory { @@ -34,21 +34,20 @@ package asunit.framework { */ public var DefaultSuiteRunner:Class; - public function RunnerFactory() { + public function RunnerFactory(injector:Injector = null) { DefaultSuiteRunner = DEFAULT_SUITE_RUNNER; DefaultTestRunner = DEFAULT_TEST_RUNNER; - injector = new InjectionDelegate(); + this.injector = injector ||= new Injector(); + injector.mapValue(Injector, injector); } - private var _injector:InjectionDelegate; + private var _injector:Injector; - public function get injector():InjectionDelegate - { + public function get injector():Injector { return _injector; } - public function set injector(value:InjectionDelegate):void - { + public function set injector(value:Injector):void { _injector = value; } @@ -56,7 +55,6 @@ package asunit.framework { * runnerFor is the primary inerface to the RunnerFactory */ public function runnerFor(testOrSuite:Class):IRunner { - //trace(">> runnerFor: " + testOrSuite + " with current default of: " + DefaultTestRunner); validate(testOrSuite); return getRunnerForTestOrSuite(testOrSuite); } @@ -84,31 +82,21 @@ package asunit.framework { } protected function getRunnerForSuite(reflection:Reflection):IRunner { - // First update the DefaultTestRunner with the provided RunWith - // if necessary... - var Constructor:Class = getRunWithConstructor(reflection); - if(Constructor) { - DefaultTestRunner = Constructor; - } - // Always return the default Suite Runner: - var runner:IRunner = new DefaultSuiteRunner(); - configureRunner(runner); + // Use the provided RunWith class, or the DefaultSuiteRunner + var Constructor:Class = getRunWithConstructor(reflection) || DefaultSuiteRunner; + var runner:IRunner = injector.instantiate(Constructor); return runner; } protected function getLegacyRunnerForTest(reflection:Reflection):IRunner { - var runner:IRunner = new LegacyRunner(); - configureRunner(runner); + var runner:IRunner = injector.instantiate(LegacyRunner); return runner; } protected function getRunnerForTest(reflection:Reflection):IRunner { - // Use the provided RunWith class, or the DefaultTestRunner (this may - // have been overridden by a parent Suite + // Use the provided RunWith class, or the DefaultTestRunner var Constructor:Class = getRunWithConstructor(reflection) || DefaultTestRunner; - //FIXME: This will choke if given a class with constructor arguments! - var runner:IRunner = new Constructor(); - configureRunner(runner); + var runner:IRunner = injector.instantiate(Constructor); return runner; } @@ -152,15 +140,6 @@ package asunit.framework { } return null; } - - /** - * @private - */ - protected function configureRunner(runner:IRunner):void - { - runner.factory = this; - injector.updateInjectionPoints(runner, InjectionDelegate.THROW_ERROR_ON_MISSING_INJECTION_POINT); - } public static function isSuite(reflection:Reflection):Boolean { return (reflection.getMetaDataByName('Suite') != null); diff --git a/asunit-4.0/src/asunit/framework/SuiteIterator.as b/asunit-4.0/src/asunit/framework/SuiteIterator.as index 4d34aa5..275bced 100644 --- a/asunit-4.0/src/asunit/framework/SuiteIterator.as +++ b/asunit-4.0/src/asunit/framework/SuiteIterator.as @@ -1,26 +1,22 @@ -package asunit.framework { - - import asunit.util.Iterator; - - import flash.utils.getDefinitionByName; - - import p2.reflect.Reflection; - import p2.reflect.ReflectionVariable; - import p2.reflect.ReflectionMetaData; +package asunit.framework { + import asunit.util.Iterator; + + import p2.reflect.Reflection; + import p2.reflect.ReflectionVariable; + + import flash.utils.getDefinitionByName; public class SuiteIterator implements Iterator { protected var index:int; protected var list:Array; - public function SuiteIterator(Suite:Class, bridge:CallbackBridge=null) { - list = getTestClasses(Suite, bridge); + public function SuiteIterator(Suite:Class) { + list = getTestClasses(Suite); } - private function getTestClasses(Suite:Class, bridge:CallbackBridge=null):Array { - if(bridge == null) bridge = new CallbackBridge(); - - var reflection:Reflection = Reflection.create(Suite); + private function getTestClasses(Suite:Class):Array { + var reflection:Reflection = Reflection.create(Suite); if(!isSuite(reflection) && isTest(reflection)) { return [Suite]; @@ -31,16 +27,24 @@ package asunit.framework { var response:Array = []; for each(variable in reflection.variables) { TestConstructor = Class(getDefinitionByName(variable.type)); - if(isSuite(Reflection.create(TestConstructor))) { - response = response.concat( getTestClasses(TestConstructor, bridge) ); - } - else if(bridge.shouldRunTest(TestConstructor)) { - response.push(TestConstructor); + if(isSuite(Reflection.create(TestConstructor))) { + var testClasses:Array = getTestClasses(TestConstructor); + for each(var testClass:Class in testClasses) { + pushIfNotInArray(testClass, response); + } + } + else { + pushIfNotInArray(TestConstructor, response) } } response.sort(); return response; - } + } + + private function pushIfNotInArray(item:Object, array:Array):void { + if (array.indexOf(item) >= 0) return; + array[array.length] = item; + } public function get length():uint { return list.length; @@ -58,7 +62,9 @@ package asunit.framework { return list[index] != null; } - // Returns a Class reference: + /** + * Returns a test Class. + */ public function next():* { return list[index++]; } diff --git a/asunit-4.0/src/asunit/framework/TestCase.as b/asunit-4.0/src/asunit/framework/TestCase.as index 50e4e16..6f3c6c9 100644 --- a/asunit-4.0/src/asunit/framework/TestCase.as +++ b/asunit-4.0/src/asunit/framework/TestCase.as @@ -44,8 +44,7 @@ package asunit.framework { } protected function addChild(child:DisplayObject):DisplayObject { - context.addChild(child); - return child; + return context.addChild(child); } protected function removeChild(child:DisplayObject):DisplayObject { @@ -71,6 +70,12 @@ package asunit.framework { Assert.assertThrows(errorType, block); } + protected function assertThrowsWithMessage(errorType:Class, + errorMessage:String, + block:Function):void { + Assert.assertThrowsWithMessage(errorType, errorMessage, block); + } + protected function assertEquals(...args:Array):void { Assert.assertEquals.apply(null, args); } @@ -92,7 +97,7 @@ package asunit.framework { } protected function assertEqualsFloat(...args:Array):void { - Assert.assertEquals.apply(null, args); + Assert.assertEqualsFloat.apply(null, args); } protected function assertEqualsArrays(...args:Array):void { diff --git a/asunit-4.0/src/asunit/framework/TestObserver.as b/asunit-4.0/src/asunit/framework/TestObserver.as deleted file mode 100644 index 8331621..0000000 --- a/asunit-4.0/src/asunit/framework/TestObserver.as +++ /dev/null @@ -1,12 +0,0 @@ -package asunit.framework { - - /** - * TestObserver is a marker interface that usually - * indicates that a given class will have at least - * one [Inject] annotation above a public instance - * variable that implements MessageBridge. - */ - public interface TestObserver { - } -} - diff --git a/asunit-4.0/src/asunit/printers/ColorTracePrinter.as b/asunit-4.0/src/asunit/printers/ColorTracePrinter.as new file mode 100644 index 0000000..4f2cb9f --- /dev/null +++ b/asunit-4.0/src/asunit/printers/ColorTracePrinter.as @@ -0,0 +1,290 @@ +package asunit.printers { + + import asunit.framework.IResult; + import asunit.framework.IRunListener; + import asunit.framework.ITestFailure; + import asunit.framework.ITestSuccess; + import asunit.framework.ITestWarning; + import asunit.framework.Method; + + import flash.system.Capabilities; + import flash.utils.getQualifiedClassName; + import flash.utils.getTimer; + + public class ColorTracePrinter implements IRunListener { + public static const LOCAL_PATH_PATTERN:RegExp = /([A-Z]:\\[^\/:\*\?<>\|]+\.\w{2,6})|(\\{2}[^\/:\*\?<>\|]+\.\w{2,6})/g; + public static const DEFAULT_HEADER:String = "AsUnit 4.0 by Luke Bayes, Ali Mills and Robert Penner\n\nFlash Player version: " + Capabilities.version + public static const DEFAULT_FOOTER:String = ""; + public static const DEFAULT_PERFORMANCE_COUNT:int = 10; + + public var header:String = DEFAULT_HEADER; + public var footer:String = DEFAULT_FOOTER; + public var displayPerformanceDetails:Boolean = true; + public var hideLocalPaths:Boolean = false; + public var localPathPattern:RegExp = LOCAL_PATH_PATTERN; + public var performanceCount:int = DEFAULT_PERFORMANCE_COUNT; + + private var dots:Array; + private var failures:Array; + private var ignores:Array; + private var runCompleted:Boolean; + private var startTime:Number; + private var successes:Array; + private var testTimes:Array; + private var warnings:Array; + + public function ColorTracePrinter() { + initialize(); + } + + private function initialize():void { + dots = []; + failures = []; + ignores = []; + successes = []; + testTimes = []; + warnings = []; + } + + public function onRunStarted():void { + } + + public function onTestFailure(failure:ITestFailure):void { + var s:String = ''; + s += red(getQualifiedClassName(failure.failedTest)); + s += red('.' + failure.failedMethod) + ' : '; + s += getFailureStackTrace(failure); + + failures.push(s); + dots.push(failure.isFailure ? red('F') : red('E')); + } + + private function getFailureStackTrace(failure:ITestFailure):String { + var stack:String = ""; + stack = failure.thrownException.getStackTrace(); + if (hideLocalPaths) + stack = stack.replace(localPathPattern, ''); + stack = stack.replace(/AssertionFailedError: /, ''); + stack += "\n\n"; + return stack; + } + + public function onTestSuccess(success:ITestSuccess):void { + dots.push('.'); + } + + public function onTestIgnored(method:Method):void { + dots.push(yellow('I')); + ignores.push(getIgnoreFromMethod(method)); + } + + private function getIgnoreFromMethod(method:Method):String { + var message:String + = "[" + yellow("Ignore") + "] " + + yellow(method.scopeName + "." + method.toString()); + + if (method.ignoreDescription) { + message += " (" + method.ignoreDescription + ")"; + } + return message; + } + + public function onWarning(warning:ITestWarning):void { + warnings.push(getWarning(warning)); + } + + private function getWarning(warning:ITestWarning):String { + var message:String + = "[" + yellow("Warning") + "] " + + (warning.method ? yellow(warning.method.scopeName + "." + warning.method.toString()) : "") + + warning.message; + return message; + } + + public function onTestStarted(test:Object):void { + startTime = getTimer(); + } + + public function onTestCompleted(test:Object):void { + var duration:Number = getTimer() - startTime; + testTimes.push({test:test, duration:duration}); + } + + public function onRunCompleted(result:IResult):void { + runCompleted = true; + printRunSummary(result); + printTimeSummary(); + printPerformanceDetails(); + logResult(); + } + + protected function logResult():void { + trace(toString()); + } + + private function print(str:String):void { + footer += str; + } + + private function println(str:String = ""):void { + print(str + "\n"); + } + + private function printRunSummary(result:IResult):void { + if (result.runCount == 0) { + println(yellow("[WARNING] No tests were found or executed.")); + println(); + return; + } + + if (result.wasSuccessful) { + println("[ " + green("OK") + " ]"); + println(); + println("Tests run: " + result.runCount); + } + else { + println("[ " + red("FAILURE") + " ]"); + println(); + println("Tests run: " + result.runCount + + ", Failures: " + result.failureCount + + ", Errors: " + result.errorCount + + ", Ignored: " + result.ignoredTestCount + ); + } + } + + private function printTimeSummary():void { + testTimes.sortOn('duration', Array.NUMERIC | Array.DESCENDING); + var totalTime:Number = 0; + var len:Number = testTimes.length; + for (var i:uint; i < len; i++) { + totalTime += testTimes[i].duration; + } + println("Total Time: " + totalTime + ' ms'); + println(); + } + + private function printPerformanceDetails():void { + if (!displayPerformanceDetails) + return; + + testTimes.sortOn('duration', Array.NUMERIC | Array.DESCENDING); + println('Time Summary:'); + println(); + var len:Number = Math.min(performanceCount, testTimes.length); + var total:Number = 0; + var testTime:Object; + for (var i:Number = 0; i < len; i++) { + testTime = testTimes[i]; + println(testTime.duration + ' ms : ' + cyan(getQualifiedClassName(testTime.test))); + } + } + + public function toString():String { + var parts:Array = []; + parts.push(header); + var len:int = dots.length; + var str:String = ''; + for (var i:int; i < len; i++) { + str += dots[i]; + } + parts.push(str); + + if (runCompleted) { + if (failures.length > 0) { + parts = parts.concat(failures); + } + if (warnings.length > 0) { + parts = parts.concat(warnings); + } + if (ignores.length > 0) { + // Tighten up the ignores line breaks: + parts.push(ignores.join("\n")); + } + parts.push(footer); + } + return parts.join("\n\n") + "\n\n"; + } + } +} + +import flash.system.Capabilities; + +// foreground +// +// 31 red +// 32 green +// 33 yellow +// 34 blue +// 35 purple +// 36 cyan +// 37 gray +// +// background +// +// 40 black +// 41 red +// 42 green +// 43 yellow +// 44 blue +// 45 purple +// 46 cyan +// 47 gray +// +// modifiers +// +// \e[1;{fg};{bg}m bold fg +// \e[4;{fg};{bg}m bold bg +// \e[5;{fg};{bg}m bold fg bg +// +// see http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/ +internal const ASCII_ESCAPE_CHARACTER:String = String.fromCharCode(27); + +internal const RESET:String = "0"; +internal const RED:String = "31"; +internal const GREEN:String = "32"; +internal const YELLOW:String = "33"; +internal const BLUE:String = "34"; +internal const PURPLE:String = "35"; +internal const CYAN:String = "36"; +internal const colorise:Boolean = (!Capabilities.os.match(/Windows/)); + +internal function color(value:String):String +{ + return colorise ? ASCII_ESCAPE_CHARACTER + "[" + value + "m" : ""; +} + +internal function reset():String +{ + return color(RESET); +} + +internal function red(message:String):String +{ + return color(RED) + message + color(RESET); +} + +internal function green(message:String):String +{ + return color(GREEN) + message + color(RESET); +} + +internal function yellow(message:String):String +{ + return color(YELLOW) + message + color(RESET); +} + +internal function blue(message:String):String +{ + return color(BLUE) + message + color(RESET); +} + +internal function purple(message:String):String +{ + return color(PURPLE) + message + color(RESET); +} + +internal function cyan(message:String):String +{ + return color(CYAN) + message + color(RESET); +} \ No newline at end of file diff --git a/asunit-4.0/src/asunit/printers/FlashBuilderPrinter.as b/asunit-4.0/src/asunit/printers/FlashBuilderPrinter.as index 86fdc88..951cb4e 100644 --- a/asunit-4.0/src/asunit/printers/FlashBuilderPrinter.as +++ b/asunit-4.0/src/asunit/printers/FlashBuilderPrinter.as @@ -1,29 +1,34 @@ package asunit.printers { import asunit.framework.ITestFailure; import asunit.framework.ITestWarning; - import asunit.framework.IResult; import asunit.framework.IRunListener; import asunit.framework.ITestSuccess; import asunit.framework.Method; - import asunit.framework.TestObserver; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; - import flash.net.XMLSocket; import flash.utils.getQualifiedClassName; + import flash.net.XMLSocket; - public class FlashBuilderPrinter implements IRunListener, TestObserver { - protected var projectName:String; - protected var contextName:String; - protected var messageQueue:Array; + /** + * FlashBuilderPrinter should connect to the running Flash Builder test result + * view over an XMLSocket and send it test results as they accumulate. + */ + public class FlashBuilderPrinter extends XMLPrinter { + protected var socket:XMLSocket; - + public function FlashBuilderPrinter(projectName:String = '', contextName:String = '') { - this.projectName = projectName; - this.contextName = contextName; - messageQueue = []; + testPrefix = null; + testSuffix = null; + traceResults = false; + super(projectName, contextName); + connectToSocket(); + } + + protected function connectToSocket():void { socket = new XMLSocket(); socket.addEventListener(Event.CONNECT, onConnect); socket.addEventListener(IOErrorEvent.IO_ERROR, onErrorEvent); @@ -32,41 +37,8 @@ package asunit.printers { connect(); } - public function onRunStarted():void { - sendMessage(""); - } - - public function onTestStarted(test:Object):void { - } - - public function onTestCompleted(test:Object):void { - } - - // works for both errors and failures - public function onTestFailure(failure:ITestFailure):void { - sendMessage(getFailureMessage(failure)); - } - - public function onTestSuccess(success:ITestSuccess):void { - var xmlMessageSuccess:String = ""; - sendMessage(xmlMessageSuccess); - } - - public function onTestIgnored(method:Method):void { - var xmlMessageIgnore:String = ""; - sendMessage(xmlMessageIgnore); - } - - public function onWarning(warning:ITestWarning):void { - //TODO: is there any way to send a warning to Flash Builder? - } - - public function onRunCompleted(result:IResult):void { - sendMessage(''); - socket.close(); + protected function onErrorEvent(event:Event):void { + trace('FlashBuilderPrinter::onErrorEvent() - event: ' + event); } protected function connect(ip:String = '127.0.0.1', port:uint = 8765):void { @@ -77,6 +49,11 @@ package asunit.printers { trace('## Error connecting to Flash Builder socket: ' + e.message); } } + + override public function onRunCompleted(result:IResult):void { + super.onRunCompleted(result); + socket.close(); + } protected function onConnect(event:Event):void { sendQueuedMessages(); @@ -88,47 +65,12 @@ package asunit.printers { } } - protected function sendMessage(message:String):void { + override protected function sendMessage(message:String):void { if (!socket.connected) { messageQueue.push(message); return; } socket.send(message); - //trace('+++++++++ sendMessage() - \n' + message + '\n'); } - - protected function getFailureMessage(failure:ITestFailure):String { - var status:String = failure.isFailure ? 'failure' : 'error'; - var xml:String = - "" - + "" - - + "" + xmlEscapeMessage(failure.exceptionMessage) - + "" - - + "" + xmlEscapeMessage(failure.thrownException.getStackTrace()) - + "" - - + "" - + ""; - - return xml; - } - - protected function onErrorEvent(event:Event):void { - trace('FlashBuilderPrinter::onErrorEvent() - event: ' + event); - //throw new Error('FlashBuilderPrinter::onErrorEvent() - event: ' + event); - } - - protected static function xmlEscapeMessage(message:String):String { - if (!message) return ''; - - var escape:XML = ; - escape.setChildren( message ); - return escape.children()[0].toXMLString(); - } - - } + } } diff --git a/asunit-4.0/src/asunit/printers/FlashDevelopPrinter.as b/asunit-4.0/src/asunit/printers/FlashDevelopPrinter.as index bb87a82..6854696 100644 --- a/asunit-4.0/src/asunit/printers/FlashDevelopPrinter.as +++ b/asunit-4.0/src/asunit/printers/FlashDevelopPrinter.as @@ -6,9 +6,8 @@ package asunit.printers { import asunit.framework.IRunListener; import asunit.framework.ITestSuccess; import asunit.framework.Method; - import asunit.framework.TestObserver; - public class FlashDevelopPrinter implements IRunListener, TestObserver { + public class FlashDevelopPrinter implements IRunListener { protected static const localPathPattern:RegExp = /([A-Z]:\\[^\/:\*\?<>\|]+\.\w{2,6})|(\\{2}[^\/:\*\?<>\|]+\.\w{2,6})/g; diff --git a/asunit-4.0/src/asunit/printers/FlexUnitCIPrinter.as b/asunit-4.0/src/asunit/printers/FlexUnitCIPrinter.as new file mode 100644 index 0000000..463ad6e --- /dev/null +++ b/asunit-4.0/src/asunit/printers/FlexUnitCIPrinter.as @@ -0,0 +1,197 @@ +package asunit.printers { + import asunit.framework.IResult; + import asunit.framework.IRunListener; + import asunit.framework.ITestFailure; + import asunit.framework.ITestSuccess; + import asunit.framework.ITestWarning; + import asunit.framework.Method; + + import flash.events.DataEvent; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.IOErrorEvent; + import flash.events.SecurityErrorEvent; + import flash.events.TimerEvent; + import flash.net.XMLSocket; + import flash.system.fscommand; + import flash.utils.Timer; + import flash.utils.getQualifiedClassName; + import flash.utils.getTimer; + + public class FlexUnitCIPrinter extends EventDispatcher implements IRunListener + { + protected static const DEFAULT_SERVER:String = "127.0.0.1"; + protected static const DEFAULT_PORT:uint = 1024; + + public var port:uint; + public var server:String; //this is local host. same machine + + private static const SUCCESS:String = "success"; + private static const ERROR:String = "error"; + private static const FAILURE:String = "failure"; + private static const IGNORE:String = "ignore"; + + private static const END_OF_TEST_ACK: String =""; + private static const END_OF_TEST_RUN: String = ""; + private static const START_OF_TEST_RUN_ACK: String = ""; + + private var socket:XMLSocket; + private var connectTimeout:Timer; + + protected var messageQueue:Array; + + private var startTime : int; + + public function FlexUnitCIPrinter() + { + this.port = port; + this.server = server; + messageQueue = []; + + socket = new XMLSocket(); + socket.addEventListener(Event.CONNECT, onConnect); + socket.addEventListener(DataEvent.DATA, onData); + socket.addEventListener(IOErrorEvent.IO_ERROR, onErrorEvent); + socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onErrorEvent); + socket.addEventListener(Event.CLOSE, onErrorEvent); + + connectTimeout = new Timer(5000, 1); + connectTimeout.addEventListener(TimerEvent.TIMER_COMPLETE, onConnectTimeout); + connectTimeout.start(); + + connect(); + } + + protected function connect(ip:String = DEFAULT_SERVER, port:uint = DEFAULT_PORT):void { + try { + socket.connect(ip, port); + } + catch (e:Error) { + trace('## Error connecting to socket: ' + e.message); + } + } + + private function onConnectTimeout(event:TimerEvent):void { + throw new Error('Timed out waiting to connect to socket.'); + } + + public function onTestIgnored(method:Method):void { + var xmlMessageIgnore:String = "" + + "" + + ""; + sendMessage(xmlMessageIgnore); + } + + protected static function xmlEscapeMessage(message:String):String { + if (!message) return ''; + + var escape:XML = ; + escape.setChildren( message ); + return escape.children()[0].toXMLString(); + } + + public function onTestFailure(failure:ITestFailure):void { + sendMessage(getFailureMessage(failure)); + } + + protected function getFailureMessage(failure:ITestFailure):String { + var status:String = failure.isFailure ? FAILURE : ERROR; +// var stackTrace:String = xmlEscapeMessage(failure.thrownException.getStackTrace()); + var stackTrace:String = failure.thrownException.getStackTrace(); + var xml:String = + "" + + + "" + + "" + + "" + + + ""; + + return xml; + } + + protected function sendMessage(message:String):void { + if (!socket.connected) { + messageQueue.push(message); + return; + } + + socket.send(message); + trace(message); + } + + protected function onConnect(event:Event):void { + connectTimeout.stop(); + } + + protected function sendQueuedMessages():void { + trace("sendQueuedMessages()"); + while (messageQueue.length) { + sendMessage(messageQueue.shift()); + } + } + + protected function serverReady(): void + { + // now that we are connectd lets send all the test results which are already available + sendQueuedMessages(); + } + + private function onData( event : DataEvent ) : void + { + var data : String = event.data; + + // If we received an acknowledgement on startup, the java server is read and we can start sending. + if ( data == START_OF_TEST_RUN_ACK ) { + serverReady(); + } else if ( data == END_OF_TEST_ACK ) { + // If we received an acknowledgement finish-up. + // Close the socket. + socket.close(); + exit(); + } + } + + protected function onErrorEvent(event:Event):void { + trace('FlexUnitCIPrinter::onErrorEvent() - event: ' + event); + //throw new Error('FlashBuilderPrinter::onErrorEvent() - event: ' + event); + } + + public function onRunStarted():void { + } + + public function onTestStarted(test:Object):void { + startTime = getTimer(); + } + + public function onTestCompleted(test:Object):void { +// testTimes.push({test:test, duration:duration}); + } + + public function onTestSuccess(success:ITestSuccess):void + { + //TODO: move test time into ITestSuccess + var testTime:Number = (getTimer() - startTime); // flexunit doesn't accept float numbers + var className: String = getQualifiedClassName(success.test); + var methodName: String = success.method; + var xmlMessageSuccess:String = ""; + sendMessage(xmlMessageSuccess); + } + + public function onRunCompleted(result:IResult):void { + sendMessage(END_OF_TEST_RUN); + } + + protected function exit():void + { + fscommand("quit"); + } + + public function onWarning(warning:ITestWarning) : void { + } + } +} \ No newline at end of file diff --git a/asunit-4.0/src/asunit/printers/TextPrinter.as b/asunit-4.0/src/asunit/printers/TextPrinter.as index 6661c48..f3a1721 100644 --- a/asunit-4.0/src/asunit/printers/TextPrinter.as +++ b/asunit-4.0/src/asunit/printers/TextPrinter.as @@ -17,28 +17,31 @@ package asunit.printers { import flash.text.TextFormat; import flash.utils.getQualifiedClassName; import flash.utils.getTimer; - import asunit.framework.CallbackBridge; public class TextPrinter extends Sprite implements IRunListener { - public static var LOCAL_PATH_PATTERN:RegExp = /([A-Z]:\\[^\/:\*\?<>\|]+\.\w{2,6})|(\\{2}[^\/:\*\?<>\|]+\.\w{2,6})/g; - public static var BACKGROUND_COLOR:uint = 0x333333; - public static var DEFAULT_HEADER:String = "AsUnit 4.0 by Luke Bayes, Ali Mills and Robert Penner\n\nFlash Player version: " + Capabilities.version - public static var FONT_SIZE:int = 12; - public static var TEXT_COLOR:uint = 0xffffff; + public static const LOCAL_PATH_PATTERN:RegExp = /([A-Z]:\\[^\/:\*\?<>\|]+\.\w{2,6})|(\\{2}[^\/:\*\?<>\|]+\.\w{2,6})/g; + public static const DEFAULT_BACKGROUND_COLOR:uint = 0x333333; + public static const DEFAULT_HEADER:String = "AsUnit 4.0 by Luke Bayes, Ali Mills and Robert Penner\n\nFlash Player version: " + Capabilities.version + public static const DEFAULT_FOOTER:String = ""; + public static const DEFAULT_FONT_SIZE:int = 12; + public static const DEFAULT_PERFORMANCE_COUNT:int = 10; + public static const DEFAULT_TEXT_COLOR:uint = 0xffffff; - public var backgroundColor:uint = BACKGROUND_COLOR; + public var header:String = DEFAULT_HEADER; + public var footer:String = DEFAULT_FOOTER; + public var backgroundColor:uint = DEFAULT_BACKGROUND_COLOR; + public var textColor:uint = DEFAULT_TEXT_COLOR; public var displayPerformanceDetails:Boolean = true; - public var localPathPattern:RegExp; - public var textColor:uint = TEXT_COLOR; public var traceOnComplete:Boolean = true; + public var hideLocalPaths:Boolean = false; + public var localPathPattern:RegExp = LOCAL_PATH_PATTERN; + public var performanceCount:int = DEFAULT_PERFORMANCE_COUNT; protected var textDisplay:TextField; private var backgroundFill:Shape; private var dots:Array; private var failures:Array; - private var footer:String; - private var header:String; private var ignores:Array; private var resultBar:Shape; private var resultBarHeight:uint = 3; @@ -48,34 +51,6 @@ package asunit.printers { private var testTimes:Array; private var warnings:Array; - /** - * The bridge provides the connection between the printer - * and the Runner(s) that it's interested in. - * - * Generally, a bridge can observe Runners, and build up - * state over the course of a test run. - * - * If you create a custom Runner, Printer and Bridge, - * you can decide to manage notifications however you wish. - * - */ - private var _bridge:CallbackBridge; - - [Inject] - public function set bridge(value:CallbackBridge):void - { - if (value !== _bridge) - { - _bridge = value; - _bridge.addObserver(this); - } - } - - public function get bridge():CallbackBridge - { - return _bridge; - } - public function TextPrinter() { initialize(); } @@ -88,10 +63,6 @@ package asunit.printers { testTimes = []; warnings = []; - footer = ''; - header = DEFAULT_HEADER; - localPathPattern = LOCAL_PATH_PATTERN; - if(stage) { initializeDisplay(); } else { @@ -117,7 +88,7 @@ package asunit.printers { private function getFailureStackTrace(failure:ITestFailure):String { var stack:String = ""; stack = failure.thrownException.getStackTrace(); - //stack = stack.replace(localPathPattern, ''); + if (hideLocalPaths) stack = stack.replace(localPathPattern, ''); stack = stack.replace(/AssertionFailedError: /, ''); stack += "\n\n"; return stack; @@ -218,7 +189,7 @@ package asunit.printers { println(); println('Time Summary:'); println(); - var len:Number = testTimes.length; + var len:Number = Math.min(performanceCount, testTimes.length); var total:Number = 0; var testTime:Object; for (var i:Number = 0; i < len; i++) { @@ -310,7 +281,7 @@ package asunit.printers { var format:TextFormat = textDisplay.getTextFormat(); format.font = '_sans'; - format.size = FONT_SIZE; + format.size = DEFAULT_FONT_SIZE; format.leftMargin = 5; format.rightMargin = 5; textDisplay.defaultTextFormat = format; diff --git a/asunit-4.0/src/asunit/printers/XMLPrinter.as b/asunit-4.0/src/asunit/printers/XMLPrinter.as new file mode 100644 index 0000000..7ab054d --- /dev/null +++ b/asunit-4.0/src/asunit/printers/XMLPrinter.as @@ -0,0 +1,127 @@ + +package asunit.printers { + import asunit.framework.ITestFailure; + import asunit.framework.ITestWarning; + import asunit.framework.IResult; + import asunit.framework.IRunListener; + import asunit.framework.ITestSuccess; + import asunit.framework.Method; + + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.events.SecurityErrorEvent; + import flash.utils.getQualifiedClassName; + + /** + * The XMLPrinter is used to transform AsUnit test results + * to JUnit-compatible XML content. + * + * This printer will send JUnit-compatible XML content to trace output. The XML content + * will be enclosed by '<TestResults/>' tags. + **/ + public class XMLPrinter implements IRunListener { + public var traceResults:Boolean = true; + + protected var projectName:String; + protected var contextName:String; + protected var messageQueue:Array; + protected var testPrefix:String = ""; + protected var testSuffix:String = ""; + + public function XMLPrinter(projectName:String = '', contextName:String = '') { + this.projectName = projectName; + this.contextName = contextName; + messageQueue = []; + } + + public function onRunStarted():void { + if (testPrefix) { + sendMessage(testPrefix); + } + sendMessage(""); + } + + public function onRunCompleted(result:IResult):void { + sendMessage(''); + + if (testSuffix) { + sendMessage(""); + } + + if (traceResults) { + trace(toString()); + } + } + + public function onTestStarted(test:Object):void { + } + + public function onTestCompleted(test:Object):void { + } + + // works for both errors and failures + public function onTestFailure(failure:ITestFailure):void { + sendMessage(getFailureMessage(failure)); + } + + public function onTestSuccess(success:ITestSuccess):void { + var xmlMessageSuccess:String = ""; + sendMessage(xmlMessageSuccess); + } + + public function onTestIgnored(method:Method):void { + var xmlMessageIgnore:String = ""; + sendMessage(xmlMessageIgnore); + } + + public function onWarning(warning:ITestWarning):void { + var xmlMessage:String = ""; + sendMessage(xmlMessage); + } + + public function toString():String { + return messageQueue.join("\n"); + } + + protected function sendMessage(message:String):void { + messageQueue.push(message); + } + + protected function getFailureMessage(failure:ITestFailure):String { + var status:String = failure.isFailure ? 'failure' : 'error'; + var xml:String = + "" + + "" + + + "" + xmlEscapeMessage(failure.exceptionMessage) + + "" + + + "" + xmlEscapeMessage(failure.thrownException.getStackTrace()) + + "" + + + "" + + ""; + + return xml; + } + + protected static function xmlEscapeMessage(message:String):String { + if (!message) return ''; + + var escape:XML = ; + escape.setChildren( message ); + return escape.children()[0].toXMLString(); + } + } +} + + + + + diff --git a/asunit-4.0/src/asunit/runners/LegacyRunner.as b/asunit-4.0/src/asunit/runners/LegacyRunner.as index cc33efa..3dbd263 100644 --- a/asunit-4.0/src/asunit/runners/LegacyRunner.as +++ b/asunit-4.0/src/asunit/runners/LegacyRunner.as @@ -1,11 +1,16 @@ package asunit.runners { + import asunit.framework.IResult; import asunit.framework.LegacyTestIterator; import asunit.framework.TestIterator; public class LegacyRunner extends TestRunner { - override protected function createTestIterator(test:*, testMethodName:String):TestIterator { + public function LegacyRunner(result:IResult = null) { + super(result); + } + + override protected function createTestIterator(test:*, testMethodName:String):TestIterator { return new LegacyTestIterator(test, testMethodName); } } diff --git a/asunit-4.0/src/asunit/runners/SuiteRunner.as b/asunit-4.0/src/asunit/runners/SuiteRunner.as index 214f687..16eda19 100644 --- a/asunit-4.0/src/asunit/runners/SuiteRunner.as +++ b/asunit-4.0/src/asunit/runners/SuiteRunner.as @@ -1,125 +1,89 @@ -package asunit.runners { - - import asunit.framework.CallbackBridge; - import asunit.framework.IResult; - import asunit.framework.IRunner; - import asunit.framework.IRunnerFactory; - import asunit.framework.RunnerFactory; - import asunit.util.Iterator; - import asunit.framework.SuiteIterator; - - import flash.display.DisplayObjectContainer; - import flash.events.Event; - import flash.events.EventDispatcher; - import flash.events.IEventDispatcher; - import flash.events.TimerEvent; - import flash.utils.Timer; - import flash.utils.getDefinitionByName; - - import p2.reflect.Reflection; - import p2.reflect.ReflectionMetaData; - - public class SuiteRunner implements IEventDispatcher, IRunner { - - [Inject] - public var bridge:CallbackBridge; - - protected var dispatcher:IEventDispatcher; - protected var testClasses:Iterator; - protected var timer:Timer; - protected var visualContext:DisplayObjectContainer; - protected var testMethod:String; - - private var _factory:IRunnerFactory; - - public function SuiteRunner() { - timer = new Timer(0, 1); - dispatcher = new EventDispatcher(); - } - - public function run(suite:Class, testMethod:String=null, visualContext:DisplayObjectContainer=null):void { - this.visualContext = visualContext; - this.testMethod = testMethod; - runSuite(suite); - } - - public function shouldRunTest(testClass:Class):Boolean { - return bridge.shouldRunTest(testClass); - } - - public function set factory(factory:IRunnerFactory):void { - _factory = factory; - } - - public function get factory():IRunnerFactory { - return _factory ||= new RunnerFactory(); - } - - protected function runSuite(suite:*):void { - testClasses = new SuiteIterator(suite, bridge); - timer.addEventListener(TimerEvent.TIMER, runNextTest); - - runNextTest(); - } - - protected function runNextTest(e:TimerEvent = null):void{ - if (!testClasses.hasNext()) { - onSuiteCompleted(); - return; - } - - var testClass:Class = testClasses.next(); - // [luke] TODO: This runnerFor call can throw exceptions, - // we need to handle them in some way. - var runner:IRunner = factory.runnerFor(testClass); - runner.addEventListener(Event.COMPLETE, onTestCompleted); - // [luke] TODO: There should be a clear search, - // and clear failure when testMethod is provided, - // but not found... - runner.run(testClass, testMethod, visualContext); - } - - protected function onTestCompleted(e:Event):void { - e.target.removeEventListener(Event.COMPLETE, onTestCompleted); - // Start a new green thread. - timer.reset(); - timer.start(); - } - - protected function onSuiteCompleted():void { - timer.removeEventListener(TimerEvent.TIMER, runNextTest); - dispatchEvent(new Event(Event.COMPLETE)); - } - - /** - * Template method that subclasses can override to perform some - * operation when the run is complete. - */ - protected function onRunCompleted():void { - } - - // BEGIN: Implement the IEvent Dispatcher Interface: - - public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { - dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); - } - - public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void { - dispatcher.removeEventListener(type, listener, useCapture); - } - - public function dispatchEvent(event:Event):Boolean { - return dispatcher.dispatchEvent(event); - } - - public function hasEventListener(type:String):Boolean { - return dispatcher.hasEventListener(type); - } - - public function willTrigger(type:String):Boolean { - return dispatcher.willTrigger(type); - } - - // END: Implement the IEvent Dispatcher Interface: - } -} +package asunit.runners { + + import asunit.framework.IResult; + import asunit.framework.IRunner; + import asunit.framework.IRunnerFactory; + import asunit.framework.Result; + import asunit.framework.RunnerFactory; + import asunit.framework.SuiteIterator; + import asunit.util.Iterator; + import org.swiftsuspenders.Injector; + + import flash.display.DisplayObjectContainer; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.TimerEvent; + import flash.utils.Timer; + + public class SuiteRunner extends EventDispatcher implements IRunner { + + public var result:IResult; + + protected var testClasses:Iterator; + protected var timer:Timer; + protected var visualContext:DisplayObjectContainer; + protected var testMethod:String; + protected var injector:Injector; + protected var factory:IRunnerFactory; + + public function SuiteRunner(factory:IRunnerFactory = null, result:IResult = null, injector:Injector = null) { + timer = new Timer(0, 1); + + this.injector = injector ||= new Injector(); + injector.mapValue(Injector, injector); + this.result = result ||= new Result(); + injector.mapValue(IResult, result); + this.factory = factory ||= injector.instantiate(RunnerFactory); + injector.mapValue(IRunnerFactory, factory); + } + + public function run(suite:Class, testMethod:String=null, visualContext:DisplayObjectContainer=null):void { + this.visualContext = visualContext; + this.testMethod = testMethod; + runSuite(suite); + } + + protected function runSuite(suite:*):void { + testClasses = new SuiteIterator(suite); + timer.addEventListener(TimerEvent.TIMER, runNextTest); + + runNextTest(); + } + + protected function runNextTest(e:TimerEvent = null):void{ + if (!testClasses.hasNext()) { + onSuiteCompleted(); + return; + } + + var testClass:Class = testClasses.next(); + // [luke] TODO: This runnerFor call can throw exceptions, + // we need to handle them in some way. + var runner:IRunner = factory.runnerFor(testClass); + runner.addEventListener(Event.COMPLETE, onTestCompleted); + // [luke] TODO: There should be a clear search, + // and clear failure when testMethod is provided, + // but not found... + runner.run(testClass, testMethod, visualContext); + } + + protected function onTestCompleted(e:Event):void { + e.target.removeEventListener(Event.COMPLETE, onTestCompleted); + // Start a new green thread. + timer.reset(); + timer.start(); + } + + protected function onSuiteCompleted():void { + timer.removeEventListener(TimerEvent.TIMER, runNextTest); + dispatchEvent(new Event(Event.COMPLETE)); + } + + /** + * Template method that subclasses can override to perform some + * operation when the run is complete. + */ + protected function onRunCompleted():void { + } + } +} diff --git a/asunit-4.0/src/asunit/runners/TestRunner.as b/asunit-4.0/src/asunit/runners/TestRunner.as index d283eba..3db00f0 100644 --- a/asunit-4.0/src/asunit/runners/TestRunner.as +++ b/asunit-4.0/src/asunit/runners/TestRunner.as @@ -1,63 +1,52 @@ package asunit.runners { - - import asunit.events.TimeoutCommandEvent; - import asunit.framework.Assert; - import asunit.framework.Async; - import asunit.framework.CallbackBridge; - import asunit.framework.IAsync; - import asunit.framework.IResult; - import asunit.framework.IRunner; + + import asunit.events.TimeoutCommandEvent; + import asunit.framework.Assert; + import asunit.framework.Async; + import asunit.framework.IResult; + import asunit.framework.Result; + import asunit.framework.IAsync; + import asunit.framework.IRunner; import asunit.framework.IRunnerFactory; - import asunit.framework.Method; - import asunit.framework.TestFailure; - import asunit.framework.TestIterator; - import asunit.framework.TestSuccess; - import asunit.framework.TestWarning; - import asunit.util.ArrayIterator; - import asunit.util.Iterator; - - import flash.display.DisplayObjectContainer; - import flash.errors.IllegalOperationError; - import flash.events.Event; - import flash.events.EventDispatcher; - import flash.events.IEventDispatcher; - import flash.events.TimerEvent; - import flash.utils.Timer; - import flash.utils.clearTimeout; - import flash.utils.getDefinitionByName; - import flash.utils.getTimer; - import flash.utils.setTimeout; - - import p2.reflect.Reflection; - import p2.reflect.ReflectionMember; - import p2.reflect.ReflectionMetaData; - import p2.reflect.ReflectionVariable; + import asunit.framework.Method; + import asunit.framework.TestFailure; + import asunit.framework.TestIterator; + import asunit.framework.TestSuccess; + import asunit.framework.TestWarning; + import asunit.util.ArrayIterator; + import asunit.util.Iterator; + import flash.display.Sprite; + import org.swiftsuspenders.Injector; + + import p2.reflect.Reflection; + import p2.reflect.ReflectionMetaData; + import p2.reflect.ReflectionVariable; + + import flash.display.DisplayObjectContainer; + import flash.errors.IllegalOperationError; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.TimerEvent; + import flash.utils.Timer; + import flash.utils.getDefinitionByName; + import flash.utils.getTimer; public class TestRunner extends EventDispatcher implements IRunner { - public static var ASYNC_NAME:String = 'asunit.framework::Async'; - public static var IASYNC_NAME:String = 'asunit.framework::IAsync'; - public static var DISPLAY_OBJECT_CONTAINER:String = 'flash.display::DisplayObjectContainer'; - - /** - * This is how the Runner connects to a printer. - * The AsUnitCore will inject the requested bridge - * based on the concrete data type. - * - * There should be a similar Injection point on - * whatever printers are interested in what this - * concrete runner will dispatch. - */ - [Inject] - public var bridge:CallbackBridge; + + /** + * + */ + //TODO: perhaps add a getter for this to IRunner + public var result:IResult; // partially exposed for unit testing internal var currentTest:Object; internal var async:IAsync; + /** Supplies dependencies to tests, e.g. IAsync, context Sprite. */ + internal var testInjector:Injector; - protected var asyncMembers:Iterator; protected var currentMethod:Method; protected var currentTestReflection:Reflection; - protected var injectableMembers:Iterator; protected var methodIsExecuting:Boolean = false; protected var methodPassed:Boolean = true; protected var methodTimeoutID:Number; @@ -68,100 +57,80 @@ package asunit.runners { protected var visualContext:DisplayObjectContainer; protected var visualInstances:Array; - private var _factory:IRunnerFactory; - - public function TestRunner() { + public function TestRunner(result:IResult = null) { async = new Async(); - bridge = new CallbackBridge(); - timer = new Timer(0, 1); - timer.addEventListener(TimerEvent.TIMER, runNextMethod); + this.result = result ||= new Result(); + testInjector = new Injector(); + testInjector.mapValue(IAsync, async); + testInjector.mapValue(Async, async); + timer = new Timer(0, 1); + timer.addEventListener(TimerEvent.TIMER, runNextMethods); visualInstances = []; } - public function run(testOrSuite:Class, methodName:String=null, visualContext:DisplayObjectContainer=null):void { - runMethodByName(testOrSuite, methodName, visualContext); - } - - public function shouldRunTest(testClass:Class):Boolean { - return bridge.shouldRunTest(testClass); - } - - // This class doesn't really use the runner factory, - // since it represents a leaf node in the test - // hierarchy... - public function set factory(factory:IRunnerFactory):void { - _factory = factory; + public function runMethodByName(testOrSuite:Class, methodName:String=null, visualContext:DisplayObjectContainer=null):void { + run(testOrSuite, methodName, visualContext); } - public function get factory():IRunnerFactory { - return _factory; - } - - public function runMethodByName(test:Class, methodName:String=null, visualContext:DisplayObjectContainer=null):void { - currentTestReflection = Reflection.create(test); + public function run(test:Class, methodName:String=null, visualContext:DisplayObjectContainer=null):void { + currentTestReflection = Reflection.create(test); this.visualContext = visualContext; + testInjector.mapValue(Sprite, visualContext); currentMethod = null; testMethodNameReceived = (methodName != null); try { - currentTest = new test(); + currentTest = testInjector.instantiate(test); } catch(e:VerifyError) { warn("Unable to instantiate provided test case with: " + currentTestReflection.name); return; } - initializeInjectableMembers(); - async.addEventListener(TimeoutCommandEvent.CALLED, onAsyncMethodCalled); async.addEventListener(TimeoutCommandEvent.TIMED_OUT, onAsyncMethodTimedOut); startTime = getTimer(); - bridge.onTestStarted(currentTest); + result.onTestStarted(currentTest); methodsToRun = createTestIterator(currentTest, methodName); if(methodsToRun.length == 0) { warn(">> We were unable to find any test methods in " + currentTestReflection.name + ". Did you set the --keep-as3-metadata flag?"); } - runNextMethod(); + + runNextMethods(); } protected function createTestIterator(test:*, testMethodName:String):TestIterator { return new TestIterator(test, testMethodName); } - protected function initializeInjectableMembers():void { - injectableMembers = new ArrayIterator(currentTestReflection.getMembersByMetaData('Inject')); - } - - protected function runNextMethod(e:TimerEvent = null):void { - if(!testMethodNameReceived && methodsToRun.readyToTearDown) { - removeInjectedMembers(); - removeInjectedVisualInstances(); - } - - if (testCompleted) { - onTestCompleted(); - return; - } - - if(methodsToRun.readyToSetUp) { - prepareForSetUp(); - } - - runMethod(methodsToRun.next()); + protected function runNextMethods(e:TimerEvent = null):void { + // Loop through as many as possible without hitting asynchronous tests. + // This keeps the call stack small. + while (methodsToRun.hasNext()) { + var hasAsyncPending:Boolean = runMethod(methodsToRun.next()); + if (hasAsyncPending) return; + } + + onTestCompleted(); } - protected function runMethod(method:Method):void { - if (!method) return; + /** + * + * @param method + * @return true if asynchronous calls are pending after calling the test method. + */ + protected function runMethod(method:Method):Boolean { + if (!method) return false; currentMethod = method; methodPassed = true; // innocent until proven guilty by recordFailure() if (currentMethod.ignore) { - bridge.onTestIgnored(currentMethod); + result.onTestIgnored(currentMethod); onMethodCompleted(); - return; + return false; } // This is used to prevent async callbacks from triggering onMethodCompleted too early. @@ -170,7 +139,13 @@ package asunit.runners { if (currentMethod.expects) { try { var errorClass:Class = getDefinitionByName(currentMethod.expects) as Class; - Assert.assertThrows(errorClass, currentMethod.value); + var errorMessage:String = currentMethod.message; + if(errorMessage == null) { + Assert.assertThrows(errorClass, currentMethod.value); + } + else { + Assert.assertThrowsWithMessage(errorClass, errorMessage, currentMethod.value); + } } catch(definitionError:ReferenceError) { // NOTE: [luke] Added ReferenceError catch here b/c I had a bad class name in my expects. @@ -192,22 +167,23 @@ package asunit.runners { methodIsExecuting = false; - if (async.hasPending) return; + if (async.hasPending) return true; onMethodCompleted(); + return false; } - protected function onMethodCompleted():void { + protected function onMethodCompleted(wasAsync:Boolean = false):void { async.cancelPending(); if (currentMethod.isTest && methodPassed && !currentMethod.ignore) { - bridge.onTestSuccess(new TestSuccess(currentTest, currentMethod.name)); + result.onTestSuccess(new TestSuccess(currentTest, currentMethod.name)); } - // Calling synchronously is faster but keeps adding to the call stack. - runNextMethod(); + if (wasAsync) + runNextMethods(); - // green thread for runNextMethod() + // green thread for runNextMethods() // This runs much slower in Flash Player 10.1. //timer.reset(); //timer.start(); @@ -231,12 +207,12 @@ package asunit.runners { protected function recordFailure(error:Error):void { methodPassed = false; - bridge.onTestFailure(new TestFailure(currentTest, currentMethod.name, error)); + result.onTestFailure(new TestFailure(currentTest, currentMethod.name, error)); } protected function onAsyncMethodCompleted(event:Event = null):void { if (!methodIsExecuting && !async.hasPending) { - onMethodCompleted(); + onMethodCompleted(true); } } @@ -245,158 +221,17 @@ package asunit.runners { async.removeEventListener(TimeoutCommandEvent.TIMED_OUT, onAsyncMethodTimedOut); async.cancelPending(); - bridge.onTestCompleted(currentTest); + result.onTestCompleted(currentTest); dispatchEvent(new Event(Event.COMPLETE)); } protected function get testCompleted():Boolean { return (!methodsToRun.hasNext() && !async.hasPending); - } - - protected function removeInjectedMembers():void { - var member:ReflectionVariable; - while(injectableMembers.hasNext()) { - removeInjectedMember(injectableMembers.next()); - } - injectableMembers.reset(); - } - - protected function removeInjectedVisualInstances():void { - var visuals:Iterator = new ArrayIterator(visualInstances); - while(visuals.hasNext()) { - visualContext.removeChild(visuals.next()); - } - visualInstances = []; - } - - protected function removeInjectedMember(member:ReflectionVariable):void { - if(!member) return; - currentTest[member.name] = null; - } - - protected function prepareForSetUp():void { - injectMembers(); - } - - protected function injectMembers():void { - var member:ReflectionVariable; - while(injectableMembers.hasNext()) { - injectMember(injectableMembers.next()); - } - injectableMembers.reset(); - } - protected function injectMember(member:ReflectionVariable):void { - if(!member) return; - var definition:Class; - try { - definition = getDefinitionByName(member.type) as Class; - } - catch(referenceError:ReferenceError) { - 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."); - return; - } - var reflection:Reflection = Reflection.create(definition); - try { - var instance:* = createInstanceFromReflection(reflection); - configureInjectedInstance(member, instance); - currentTest[member.name] = instance; - } - catch(e:VerifyError) { - throw new VerifyError("Failed to instantiate " + member.type + " in order to inject public var " + member.name); - } - } - - protected function configureInjectedInstance(member:ReflectionVariable, instance:*):void { - var injectTag:ReflectionMetaData = member.getMetaDataByName('Inject'); - var args:Array = injectTag.args; - var arg:Object; - var len:int = args.length; - for(var i:int; i < len; i++) { - arg = args[i]; - try { - instance[arg.key] = coerceArgumentType(member, arg.value); - } - catch(e:ReferenceError) { - var reflect:Reflection = Reflection.create(instance); - warn("Unable to inject attribute " + arg.key + " on " + reflect.name); - } - } - } - - protected function coerceArgumentType(member:ReflectionVariable, value:String):* { - switch(value) { - case "false" : - return false; - case "true" : - return true; - } - - return value; } - - protected function createInstanceFromReflection(reflection:Reflection):* { - // Return the shared async instance if they're expecting the interface - // or concrete instance, but NOT if their Inject is merely a subclass... - if(reflection.name == ASYNC_NAME || reflection.name == IASYNC_NAME) { - return async; - } - - var clazz:Class = getClassReferenceFromReflection(reflection); - var constructorReflection:Reflection = Reflection.create(clazz); - try { - var instance:* = new constructorReflection.classReference(); - } - catch(e:VerifyError) { - warn("Unable to instantiate: " + reflection.name + " for injection"); - } - - if(constructorReflection.isA(DISPLAY_OBJECT_CONTAINER)) { - // Add injected DisplayObjectContainers to a collection - // for removal, and add them to the visualContext if - // one was provided to the run() method. - if(visualContext) { - visualInstances.push(instance); - visualContext.addChild(instance); - } - else { - 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."); - } - } - - return instance; - } - protected function warn(message:String, method:Method=null):void { - bridge.onWarning(new TestWarning(message, method)); - } - - protected function getClassReferenceFromReflection(reflection:Reflection):Class { - // This will attempt to deal with I-prefixed interfaces - like IAsync. - if(reflection.isInterface) { - return attemptToGetClassReferenceFromReflection(reflection); - } - return reflection.classReference; - } - - protected function attemptToGetClassReferenceFromReflection(reflection:Reflection):Class { - var fullName:String = reflection.name; - var parts:Array = fullName.split("::"); - var interfaceName:String = parts.pop(); - var expr:RegExp = /I([AZ].+)/; - var match:Object = expr.exec(interfaceName); - if(match) { - parts.push(match[1]); - var implementationName:String = parts.join("::"); - return Class(getDefinitionByName(implementationName)); - } - throw new VerifyError("Unable to find class instance for interface " + fullName); - } - - // TODO: Implement this method: - protected function argumentFreeConstructor(reflection:Reflection):Boolean { - return true; + result.onWarning(new TestWarning(message, method)); } } } diff --git a/asunit-4.0/test/AllTests.as b/asunit-4.0/test/AllTests.as index feb0085..eeb0dbe 100644 --- a/asunit-4.0/test/AllTests.as +++ b/asunit-4.0/test/AllTests.as @@ -11,12 +11,12 @@ package { import asunit.framework.AssertEqualsArraysTest; import asunit.framework.AssertTest; import asunit.framework.AssertThrowsTest; + import asunit.framework.AssertThrowsWithMessageTest; import asunit.framework.AsyncMethodTest; import asunit.framework.AsyncTest; - import asunit.framework.CallbackBridgeTest; - import asunit.framework.InjectionDelegateTest; import asunit.framework.NestedSuiteIteratorTest; import asunit.framework.ProceedOnEventTest; + import asunit.framework.ResultObserverTest; import asunit.framework.ResultTest; import asunit.framework.RunnerFactoryTest; import asunit.framework.SuiteIteratorTest; @@ -26,12 +26,16 @@ package { import asunit.framework.TestIteratorOrderedTestMethodTest; import asunit.framework.TestIteratorSingleMethodTest; import asunit.framework.VisualTestCaseTest; + import asunit.printers.ColorTracePrinterTest; import asunit.printers.TextPrinterTest; + import asunit.printers.XMLPrinterTest; + import asunit.printers.FlashBuilderPrinterTest; import asunit.runners.LegacyRunnerTest; import asunit.runners.SuiteRunnerTest; import asunit.runners.TestRunnerAsyncMethodTest; import asunit.runners.TestRunnerErrorMethodTest; import asunit.runners.TestRunnerExpectsErrorTest; + import asunit.runners.TestRunnerExpectsErrorWithMessageTest; import asunit.runners.TestRunnerIgnoredMethodTest; import asunit.runners.TestRunnerTest; import asunit.util.ArrayIteratorTest; @@ -43,13 +47,13 @@ package { public var asunit_framework_AssertEqualsArraysIgnoringOrderTest:asunit.framework.AssertEqualsArraysIgnoringOrderTest; public var asunit_framework_AssertEqualsArraysTest:asunit.framework.AssertEqualsArraysTest; public var asunit_framework_AssertTest:asunit.framework.AssertTest; + public var asunit_framework_AssertThrowsWithMessageTest:asunit.framework.AssertThrowsWithMessageTest; public var asunit_framework_AssertThrowsTest:asunit.framework.AssertThrowsTest; public var asunit_framework_AsyncMethodTest:asunit.framework.AsyncMethodTest; public var asunit_framework_AsyncTest:asunit.framework.AsyncTest; - public var asunit_framework_CallbackBridgeTest:asunit.framework.CallbackBridgeTest; - public var asunit_framework_InjectionDelegateTest:asunit.framework.InjectionDelegateTest; public var asunit_framework_NestedSuiteIteratorTest:asunit.framework.NestedSuiteIteratorTest; public var asunit_framework_ProceedOnEventTest:asunit.framework.ProceedOnEventTest; + public var asunit_framework_ResultObserverTest:asunit.framework.ResultObserverTest; public var asunit_framework_ResultTest:asunit.framework.ResultTest; public var asunit_framework_RunnerFactoryTest:asunit.framework.RunnerFactoryTest; public var asunit_framework_SuiteIteratorTest:asunit.framework.SuiteIteratorTest; @@ -60,11 +64,14 @@ package { public var asunit_framework_TestIteratorSingleMethodTest:asunit.framework.TestIteratorSingleMethodTest; public var asunit_framework_VisualTestCaseTest:asunit.framework.VisualTestCaseTest; public var asunit_printers_TextPrinterTest:asunit.printers.TextPrinterTest; + public var asunit_printers_FlashBuilderPrinterTest:asunit.printers.FlashBuilderPrinterTest; + public var asunit_printers_ColorTracePrinterTest:asunit.printers.ColorTracePrinterTest; public var asunit_runners_LegacyRunnerTest:asunit.runners.LegacyRunnerTest; public var asunit_runners_SuiteRunnerTest:asunit.runners.SuiteRunnerTest; public var asunit_runners_TestRunnerAsyncMethodTest:asunit.runners.TestRunnerAsyncMethodTest; public var asunit_runners_TestRunnerErrorMethodTest:asunit.runners.TestRunnerErrorMethodTest; public var asunit_runners_TestRunnerExpectsErrorTest:asunit.runners.TestRunnerExpectsErrorTest; + public var asunit_runners_TestRunnerExpectsErrorWithMessageTest:asunit.runners.TestRunnerExpectsErrorWithMessageTest; public var asunit_runners_TestRunnerIgnoredMethodTest:asunit.runners.TestRunnerIgnoredMethodTest; public var asunit_runners_TestRunnerTest:asunit.runners.TestRunnerTest; public var asunit_util_ArrayIteratorTest:asunit.util.ArrayIteratorTest; diff --git a/asunit-4.0/test/AsUnitCIRunner.as b/asunit-4.0/test/AsUnitCIRunner.as new file mode 100644 index 0000000..81a4517 --- /dev/null +++ b/asunit-4.0/test/AsUnitCIRunner.as @@ -0,0 +1,18 @@ +package { + + import asunit.core.FlexUnitCICore; + import asunit.core.TextCore; + + import flash.display.MovieClip; + + [SWF(width="1024", height="640", backgroundColor="#000000", frameRate="61")] + public class AsUnitCIRunner extends MovieClip { + + private var core:TextCore; + + public function AsUnitCIRunner() { + core = new FlexUnitCICore(); + core.start(AllTests, null, this); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/test/AsUnitRunner.as b/asunit-4.0/test/AsUnitRunner.as index 558889d..b659fdb 100755 --- a/asunit-4.0/test/AsUnitRunner.as +++ b/asunit-4.0/test/AsUnitRunner.as @@ -1,15 +1,17 @@ -package { - - import asunit.core.TextCore; - import flash.display.MovieClip; - - public class AsUnitRunner extends MovieClip { - - private var core:TextCore; - - public function AsUnitRunner() { - core = new TextCore(); - core.start(AllTests, null, this); - } - } +package { + + import asunit.core.TextCore; + import flash.display.MovieClip; + + [SWF(width="1024", height="640", backgroundColor="#000000", frameRate="61")] + public class AsUnitRunner extends MovieClip { + + private var core:TextCore; + + public function AsUnitRunner() { + core = new TextCore(); + core.textPrinter.hideLocalPaths = true; + core.start(AllTests, null, this); + } + } } \ No newline at end of file diff --git a/asunit-4.0/test/AsUnitRunnerCS3.fla b/asunit-4.0/test/AsUnitRunnerCS3.fla new file mode 100644 index 0000000..55d4a4a Binary files /dev/null and b/asunit-4.0/test/AsUnitRunnerCS3.fla differ diff --git a/asunit-4.0/test/asunit/core/AsUnitCoreTest.as b/asunit-4.0/test/asunit/core/AsUnitCoreTest.as index c60a840..9872bd8 100644 --- a/asunit-4.0/test/asunit/core/AsUnitCoreTest.as +++ b/asunit-4.0/test/asunit/core/AsUnitCoreTest.as @@ -1,12 +1,11 @@ package asunit.core { import asunit.asserts.*; - import asunit.framework.CallbackBridge; import asunit.framework.IAsync; import asunit.framework.IResult; import asunit.framework.Result; import asunit.printers.TextPrinter; - import asunit.support.CustomTestRunner; + import asunit.support.CustomSuiteRunner; import asunit.support.SuiteWithCustomRunner; import asunit.support.SuiteWithOneCustomChildSuite; import asunit.support.SucceedAssertTrue; @@ -19,15 +18,16 @@ package asunit.core { [Inject] public var async:IAsync; - [Inject] - public var core:AsUnitCore; + private var core:AsUnitCore; - [Inject] - public var context:Sprite; + [Before] + public function setUp():void { + core = new AsUnitCore(); + } [After] public function cleanUpStatics():void { - CustomTestRunner.runCalledCount = 0; + CustomSuiteRunner.runCalledCount = 0; } [Test] @@ -39,18 +39,36 @@ package asunit.core { public function startShouldWork():void { core.start(SucceedAssertTrue); } + + [Test] + public function shouldDispatchSelfAsCurrentTarget():void { + var handlerCalled:Boolean = false; + var handler:Function = function(event:Event):void { + assertSame("currentTarget should be the core", core, event.currentTarget); + handlerCalled = true; + core.removeEventListener(event.type, arguments.callee); + } + + var eventType:String = "foo"; + core.addEventListener(eventType, handler); + // when + core.dispatchEvent(new Event(eventType)); + // then + assertTrue("handler called", handlerCalled); + } [Test] public function setVisualContextShouldWork():void { + var context:Sprite = new Sprite(); core.visualContext = context; - assertEquals(context, core.visualContext); + assertSame(context, core.visualContext); } [Test] public function textPrinterShouldWork():void { var printer:TextPrinter = new TextPrinter(); printer.traceOnComplete = false; - core.addObserver(printer); + core.addListener(printer); // Wait for the complete event: var handler:Function = function(event:Event):void { @@ -66,11 +84,11 @@ package asunit.core { private function verifyRunWithOnASuite(Suite:Class, testCaseCount:int, testMethodCount:int):void { var handler:Function = function(event:Event):void { - var message:String = "CustomRunner.run was NOT called with correct count"; + var message:String = "CustomSuiteRunner.run was NOT called with correct count"; // This is the number of Tests that will used the custom Runner: - assertEquals(message, testCaseCount, CustomTestRunner.runCalledCount); + assertEquals(message, testCaseCount, CustomSuiteRunner.runCalledCount); // This is the number of test methods: - assertEquals("Total Test Count", testMethodCount, core.bridge.runCount); + assertEquals("Total Test Count", testMethodCount, core.result.runCount); } core.addEventListener(Event.COMPLETE, async.add(handler, 200)); @@ -78,9 +96,9 @@ package asunit.core { } [Test] - public function shouldAssignRunWithUsingOuterSuite():void { - // This will work b/c the RunWith is on the outer Suite: - var testCaseCount:int = 2; + public function shouldUseRunWithOnlyOnItsSuiteNotChildren():void { + // TheRunWith is on the outer Suite: + var testCaseCount:int = 1; var testMethodCount:int = 4; verifyRunWithOnASuite(SuiteWithCustomRunner, testCaseCount, testMethodCount); } diff --git a/asunit-4.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as b/asunit-4.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as old mode 100644 new mode 100755 index f5ef4b0..cb6c619 --- a/asunit-4.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as +++ b/asunit-4.0/test/asunit/framework/AssertEqualsArraysIgnoringOrderTest.as @@ -1,88 +1,102 @@ -package asunit.framework -{ - import asunit.errors.AssertionFailedError; - import asunit.framework.TestCase; - import asunit.framework.Assert; - - /** - * Tests assertEqualsArraysIgnoringOrder - * - * @author Bastian Krol - */ - public class AssertEqualsArraysIgnoringOrderTest extends TestCase { - - public function AssertEqualsArraysIgnoringOrderTest(testMethod:String = null) { - super(testMethod); - } - - public function testNullEqualsNull():void { - assertEqualsArraysIgnoringOrder(Assert.assertEqualsArraysIgnoringOrder, null, null); - } - - public function testNullDoesNotEqualNotNull():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, null, []); - } - - public function testNotNullDoesNotEqualNull():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [], null); - } - - public function testEmptyArrayEqualsEmptyArray():void { - assertEqualsArraysIgnoringOrder([], []); - } - - public function testArrayWithOneStringEquals():void { - assertEqualsArraysIgnoringOrder(["abcdefg"], ["abcdefg"]); - } - - public function testArrayWithOneStringNotEquals():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abcdefg"], ["12345"]); - } - - public function testArrayWithOneFunctionEquals():void { - assertEqualsArraysIgnoringOrder([tearDown], [tearDown]); - } - - public function testArrayWithOneFunctionNotEquals():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [setUp], [tearDown]); - } - - public function testArrayWithOneNullMemberEquals():void { - assertEqualsArraysIgnoringOrder([null], [null]); - } - - public function testArrayWithOneNullMemberNotEquals1():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["..."], [null]); - } - - public function testArrayWithOneNullMemberNotEquals2():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [null], ["..."]); - } - - public function testArrayEqualsSameOrder():void { - assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["abc", "def", "ghi"]); - } - - public function testArrayNotEquals():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "xyz", "ghi"]); - } - - public function testArrayEqualsDifferentOrder1():void { - assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["def", "abc", "ghi"]); - } - - public function testArrayEqualsDifferentTypes():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, - ["abc", "def", "ghi"], - ["abc", setUp, "ghi"]); - } - - public function testArrayDifferentLength1():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "def"]); - } - - public function testArrayDifferentLength2():void { - assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def"], ["abc", "def", "ghi"]); - } - } +package asunit.framework +{ + import asunit.errors.AssertionFailedError; + import asunit.framework.TestCase; + import asunit.framework.Assert; + import flash.display.Sprite; + + /** + * Tests assertEqualsArraysIgnoringOrder + * + * @author Bastian Krol + */ + public class AssertEqualsArraysIgnoringOrderTest extends TestCase { + + public function AssertEqualsArraysIgnoringOrderTest(testMethod:String = null) { + super(testMethod); + } + + public function testNullEqualsNull():void { + assertEqualsArraysIgnoringOrder(Assert.assertEqualsArraysIgnoringOrder, null, null); + } + + public function testNullDoesNotEqualNotNull():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, null, []); + } + + public function testNotNullDoesNotEqualNull():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [], null); + } + + public function testEmptyArrayEqualsEmptyArray():void { + assertEqualsArraysIgnoringOrder([], []); + } + + public function testArrayWithOneStringEquals():void { + assertEqualsArraysIgnoringOrder(["abcdefg"], ["abcdefg"]); + } + + public function testArrayWithOneStringNotEquals():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abcdefg"], ["12345"]); + } + + public function testArrayWithOneFunctionEquals():void { + assertEqualsArraysIgnoringOrder([tearDown], [tearDown]); + } + + public function testArrayWithOneFunctionNotEquals():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [setUp], [tearDown]); + } + + public function testArrayWithOneNullMemberEquals():void { + assertEqualsArraysIgnoringOrder([null], [null]); + } + + public function testArrayWithOneNullMemberNotEquals1():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["..."], [null]); + } + + public function testArrayWithOneNullMemberNotEquals2():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, [null], ["..."]); + } + + public function testArrayEqualsSameOrder():void { + assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["abc", "def", "ghi"]); + } + + public function testArrayNotEquals():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "xyz", "ghi"]); + } + + public function testArrayEqualsDifferentOrder1():void { + assertEqualsArraysIgnoringOrder(["abc", "def", "ghi"], ["def", "abc", "ghi"]); + } + + public function testArrayEqualsDifferentTypes():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, + ["abc", "def", "ghi"], + ["abc", setUp, "ghi"]); + } + + public function testArrayDifferentLength1():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def", "ghi"], ["abc", "def"]); + } + + public function testArrayDifferentLength2():void { + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, ["abc", "def"], ["abc", "def", "ghi"]); + } + + public function testArrayWithRepeatedItems():void { + var spr1:Sprite = new Sprite(); + var spr2:Sprite = new Sprite(); + var spr3:Sprite = new Sprite(); + + var controlArray:Array = [spr1, spr2, spr3, spr1]; + var matchingArray:Array = [spr1, spr2, spr1, spr3]; + var nonMatchingArray:Array = [spr1, spr2, spr3, spr2]; + + assertEqualsArraysIgnoringOrder('these arrays should match', controlArray, matchingArray); + assertAssertionFailed(Assert.assertEqualsArraysIgnoringOrder, controlArray, nonMatchingArray); + } + } } \ No newline at end of file diff --git a/asunit-4.0/test/asunit/framework/AssertThrowsWithMessageTest.as b/asunit-4.0/test/asunit/framework/AssertThrowsWithMessageTest.as new file mode 100644 index 0000000..5d3f66c --- /dev/null +++ b/asunit-4.0/test/asunit/framework/AssertThrowsWithMessageTest.as @@ -0,0 +1,50 @@ +package asunit.framework { + + import asunit.asserts.*; + import asunit.errors.AssertionFailedError; + + public class AssertThrowsWithMessageTest { + + [Test] + public function throwingExpectedErrorShouldPass():void { + assertThrowsWithMessage(ArgumentError, "foo", function():void { throw new ArgumentError("foo"); } ); + } + + [Test] + public function throwingUnexpectedErrorShouldFail():void { + try { + assertThrowsWithMessage(ArgumentError, "wrong error type", function():void { throw new Error("wrong error type"); } ); + } + catch (e:AssertionFailedError) { + assertEquals("expected error type: but was:", e.message) + return; + } + fail('failed assertThrowsWithMessage() should have thrown AssertionFailedError'); + } + + [Test] + public function throwingNoErrorShouldFailWithMessage():void { + try { + assertThrowsWithMessage(ArgumentError, "foo", function():void { } ); + } + catch (e:AssertionFailedError) { + assertEquals("expected error type: with message: but none was thrown.", e.message) + return; + } + fail('failed assertThrowsWithMessage() should have thrown AssertionFailedError'); + } + + [Test] + public function throwingErrorWithUnexpectedMessageShouldFail():void { + try { + assertThrowsWithMessage(Error, "foo", function():void { throw new Error("bar"); } ); + } + catch (e:AssertionFailedError) { + assertEquals("expected error message: but was:", e.message) + return; + } + fail('failed assertThrowsWithMessage() should have thrown AssertionFailedError'); + } + } +} + diff --git a/asunit-4.0/test/asunit/framework/AsyncTest.as b/asunit-4.0/test/asunit/framework/AsyncTest.as index 24b1ade..5466678 100644 --- a/asunit-4.0/test/asunit/framework/AsyncTest.as +++ b/asunit-4.0/test/asunit/framework/AsyncTest.as @@ -1,104 +1,100 @@ -package asunit.framework { - - import asunit.asserts.*; - import asunit.events.TimeoutCommandEvent; - import asunit.framework.Async; - import asunit.framework.IAsync; - import asunit.framework.TestCase; - - import flash.events.Event; - import flash.events.EventDispatcher; - import flash.utils.setTimeout; - - public class AsyncTest { - - [Inject] - public var async:IAsync; - - [Inject] - public var dispatcher:EventDispatcher; - - private var orphanAsync:IAsync; - private var command:TimeoutCommand; - - [Before] - public function createOrphanAsync():void { - orphanAsync = new Async(); - } - - [After] - public function destroyOrphanAsync():void { - orphanAsync = null; - } - - [Test] - public function asyncHandlerCanBeRetrievedByTestInstance():void { - var cancelTimeout:Function = async.add(foo); - - var commands:Array = async.getPending(); - assertEquals("one command for test after addAsync()", 1, commands.length); - - var command:TimeoutCommand = commands[0]; - assertSame("handler is the same function passed to addAsync", foo, command.handler); - - cancelTimeout(); - - assertEquals("no commands for test after handler called", 0, async.getPending().length); - } - - [Test] - public function addAsyncShouldSendCALLEDEventIfDelegateCalledInTime():void { - var cancelTimeout:Function = async.add(foo, 50); - - command = async.getPending()[0]; - - // Use AsUnit 3's addAsync() to verify onAsyncMethodCalled is called. - command.addEventListener(TimeoutCommandEvent.CALLED, async.add(onAsyncMethodCalled)); - - // If all goes well, the ErrorEvent won't be dispatched. - command.addEventListener(TimeoutCommandEvent.TIMED_OUT, failIfCalled); - - // cancelTimeout is called faster than async.add duration - setTimeout(cancelTimeout, 0); - } - - private function onAsyncMethodCalled(e:Event):void { - assertEquals("event type", TimeoutCommandEvent.CALLED, e.type); - } - - [Ignore(description="Async failure, but I'm no longer convinced that there is any value in this test case. Do we care if the TimeoutCommand can throw events? So long as we verify our failure state from the runner?")] - [Test] - public function addAsyncShouldSendErrorEventIfDelegateNotCalledInTime():void { - - // This should be called by the orphanAsync instance when the timeout is exceeded: - var asyncMethodFailedHandler:Function = function(event:TimeoutCommandEvent):void { - assertEquals("event type", TimeoutCommandEvent.TIMED_OUT, event.type); - command.removeEventListener(TimeoutCommandEvent.CALLED, failIfCalled); - command.removeEventListener(TimeoutCommandEvent.TIMED_OUT, asyncMethodFailedHandler); - } - - var timeoutHandler:Function = orphanAsync.add(null, 1); - // Set a timeout on the orphanAsync, but also pass this - // to the actual, outer test run async - when this is called, - // the outer test run can continue. - var cancelTimeout:Function = async.add(timeoutHandler, 500); - - // Add subscriptions to the timeout command: - command = orphanAsync.getPending()[0]; - command.addEventListener(TimeoutCommandEvent.CALLED, failIfCalled); - command.addEventListener(TimeoutCommandEvent.TIMED_OUT, orphanAsync.add(asyncMethodFailedHandler)); - - // we should attempt to call the async handler AFTER the timeout - // has already expired. The handler should NOT get called... - setTimeout(cancelTimeout, 10); - } - - - private function failIfCalled(event:Event=null):void { - fail("AsyncTest: This function should not have been called"); - } - //TODO: You might want to delete this since it is basically a no-op handler. You could send instead now. - private function foo():void {}; - } -} - +package asunit.framework { + + import asunit.asserts.*; + import asunit.events.TimeoutCommandEvent; + import asunit.framework.Async; + import asunit.framework.IAsync; + import asunit.framework.TestCase; + + import flash.events.Event; + import flash.utils.setTimeout; + + public class AsyncTest { + + [Inject] + public var async:IAsync; + + private var orphanAsync:IAsync; + private var command:TimeoutCommand; + + [Before] + public function createOrphanAsync():void { + orphanAsync = new Async(); + } + + [After] + public function destroyOrphanAsync():void { + orphanAsync = null; + } + + [Test] + public function asyncHandlerCanBeRetrievedByTestInstance():void { + var cancelTimeout:Function = async.add(foo); + + var commands:Array = async.getPending(); + assertEquals("one command for test after addAsync()", 1, commands.length); + + var command:TimeoutCommand = commands[0]; + assertSame("handler is the same function passed to addAsync", foo, command.handler); + + cancelTimeout(); + + assertEquals("no commands for test after handler called", 0, async.getPending().length); + } + + [Test] + public function addAsyncShouldSendCALLEDEventIfDelegateCalledInTime():void { + var cancelTimeout:Function = async.add(foo, 50); + + command = async.getPending()[0]; + + // Use AsUnit 3's addAsync() to verify onAsyncMethodCalled is called. + command.addEventListener(TimeoutCommandEvent.CALLED, async.add(onAsyncMethodCalled)); + + // If all goes well, the ErrorEvent won't be dispatched. + command.addEventListener(TimeoutCommandEvent.TIMED_OUT, failIfCalled); + + // cancelTimeout is called faster than async.add duration + setTimeout(cancelTimeout, 0); + } + + private function onAsyncMethodCalled(e:Event):void { + assertEquals("event type", TimeoutCommandEvent.CALLED, e.type); + } + + [Ignore(description="Async failure, but I'm no longer convinced that there is any value in this test case. Do we care if the TimeoutCommand can throw events? So long as we verify our failure state from the runner?")] + [Test] + public function addAsyncShouldSendErrorEventIfDelegateNotCalledInTime():void { + + // This should be called by the orphanAsync instance when the timeout is exceeded: + var asyncMethodFailedHandler:Function = function(event:TimeoutCommandEvent):void { + assertEquals("event type", TimeoutCommandEvent.TIMED_OUT, event.type); + command.removeEventListener(TimeoutCommandEvent.CALLED, failIfCalled); + command.removeEventListener(TimeoutCommandEvent.TIMED_OUT, asyncMethodFailedHandler); + } + + var timeoutHandler:Function = orphanAsync.add(null, 1); + // Set a timeout on the orphanAsync, but also pass this + // to the actual, outer test run async - when this is called, + // the outer test run can continue. + var cancelTimeout:Function = async.add(timeoutHandler, 500); + + // Add subscriptions to the timeout command: + command = orphanAsync.getPending()[0]; + command.addEventListener(TimeoutCommandEvent.CALLED, failIfCalled); + command.addEventListener(TimeoutCommandEvent.TIMED_OUT, orphanAsync.add(asyncMethodFailedHandler)); + + // we should attempt to call the async handler AFTER the timeout + // has already expired. The handler should NOT get called... + setTimeout(cancelTimeout, 10); + } + + + private function failIfCalled(event:Event=null):void { + fail("AsyncTest: This function should not have been called"); + } + //TODO: You might want to delete this since it is basically a no-op handler. You could send instead now. + private function foo():void {}; + } +} + diff --git a/asunit-4.0/test/asunit/framework/CallbackBridgeTest.as b/asunit-4.0/test/asunit/framework/CallbackBridgeTest.as deleted file mode 100644 index 3dd4579..0000000 --- a/asunit-4.0/test/asunit/framework/CallbackBridgeTest.as +++ /dev/null @@ -1,73 +0,0 @@ -package asunit.framework { - - import asunit.asserts.*; - import asunit.support.FakeObserver; - import asunit.framework.Result; - import asunit.framework.CallbackBridge; - - public class CallbackBridgeTest { - - private var bridge:CallbackBridge; - - private var observer:FakeObserver; - - [Before] - public function createObserver():void { - observer = new FakeObserver(); - bridge = new CallbackBridge(); - bridge.addListener(observer); - } - - [After] - public function destroyObserver():void { - observer = null; - } - - [Test] - public function canInstantiate():void { - assertTrue("instance is CallbackBridge", bridge is CallbackBridge); - } - - [Test] - public function addListenerWorked():void { - assertEquals(1, bridge.length); - } - - [Test] - public function addedListenerReceivesOnRunStarted():void { - bridge.onRunStarted(); - assertTrue(observer.onRunStartedCalled); - } - - [Test] - public function addedListenerReceivesOnTestStarted():void { - bridge.onTestStarted(null); - assertTrue(observer.onTestStartedCalled); - } - - [Test] - public function shouldHaveDefaultRunCount():void - { - assertEquals(0, bridge.runCount); - } - - [Test] - public function shouldHaveCumulativeRunCount():void - { - /* - function onTestStarted(test:Object):void; - function onTestCompleted(test:Object):void; - function onTestFailure(failure:ITestFailure):void; - function onTestSuccess(success:ITestSuccess):void; - */ - bridge.onTestStarted(null); - bridge.onTestSuccess(null); - bridge.onTestCompleted(null); - bridge.onTestStarted(null); - bridge.onTestSuccess(null); - bridge.onTestCompleted(null); - assertEquals(2, bridge.runCount); - } - - } -} \ No newline at end of file diff --git a/asunit-4.0/test/asunit/framework/InjectionDelegateTest.as b/asunit-4.0/test/asunit/framework/InjectionDelegateTest.as deleted file mode 100644 index 242ca1d..0000000 --- a/asunit-4.0/test/asunit/framework/InjectionDelegateTest.as +++ /dev/null @@ -1,79 +0,0 @@ -package asunit.framework { - - import asunit.asserts.*; - - public class InjectionDelegateTest { - - [Inject] - public var injector:InjectionDelegate; - - [Test] - public function testInstantiated():void { - assertTrue("instance is InjectionDelegate", injector is InjectionDelegate); - } - - [Test] - public function testUpdateInjectionPoints():void { - var addict:Addict = new Addict(); - injector.updateInjectionPoints(addict); - assertNotNull(addict.array); - } - - [Test] - public function injectedInstancesShouldBeCached():void { - var addict:Addict = new Addict(); - var addict2:Addict = new Addict(); - - injector.updateInjectionPoints(addict); - injector.updateInjectionPoints(addict2); - - assertSame(addict.array, addict2.array); - - } - - [Test(expects="asunit.errors.UsageError")] - public function shouldThrowUsageErrorOnInvalidAddict():void - { - var invalidAddict:AddictWithNoInjections = new AddictWithNoInjections(); - injector.updateInjectionPoints(invalidAddict, InjectionDelegate.THROW_ERROR_ON_MISSING_INJECTION_POINT); - } - - [Test(expects="asunit.errors.UsageError")] - public function shouldThrowUsageErrorIfNoVariableInjectionsFound():void - { - var invalidAddict:AddictWithOnlyMethodInjection = new AddictWithOnlyMethodInjection(); - injector.updateInjectionPoints(invalidAddict, InjectionDelegate.THROW_ERROR_ON_MISSING_INJECTION_POINT); - } - - [Test] - public function shouldNotThrowUsageErrorOnInvalidAddict():void - { - var invalidAddict:AddictWithNoInjections = new AddictWithNoInjections(); - injector.updateInjectionPoints(invalidAddict); - } - - [Test] - public function shouldNotThrowUsageErrorIfNoVariableInjectionsFound():void - { - var invalidAddict:AddictWithOnlyMethodInjection = new AddictWithOnlyMethodInjection(); - injector.updateInjectionPoints(invalidAddict); - } - - } -} - -//An addict that has no inject annotations -class AddictWithNoInjections {} - -class AddictWithOnlyMethodInjection { - [Inject] - public function pleaseInjectMe(array:Array):void{}; -} - -class Addict { - [Inject] - public var array:Array; - - [Inject] - public function pleaseInjectMe(array:Array):void{}; -} \ No newline at end of file diff --git a/asunit-4.0/test/asunit/framework/ProceedOnEventTest.as b/asunit-4.0/test/asunit/framework/ProceedOnEventTest.as index 48f10d3..99ce4f6 100644 --- a/asunit-4.0/test/asunit/framework/ProceedOnEventTest.as +++ b/asunit-4.0/test/asunit/framework/ProceedOnEventTest.as @@ -1,109 +1,108 @@ -package asunit.framework { - - import asunit.asserts.*; - import asunit.events.TimeoutCommandEvent; - import asunit.framework.ErrorEvent; - import asunit.framework.TestCase; - - import flash.events.Event; - import flash.events.EventDispatcher; - import flash.events.IEventDispatcher; - import flash.utils.clearTimeout; - import flash.utils.setTimeout; - - public class ProceedOnEventTest { - - [Inject] - public var async:IAsync; - - [Inject] - public var dispatcher:EventDispatcher; - - private var orphanAsync:IAsync; - private var command:TimeoutCommand; - private var timeoutID:int = -1; - - [Before] - public function setUp():void { - orphanAsync = new Async(); - } - - [After] - public function tearDown():void { - command = null; - orphanAsync = null; - timeoutID = -1; - } - - protected function foo():void { } - - [Test] - public function proceedOnEventShouldDispatchCorrectEventAndClearPendingCommands():void { - orphanAsync.proceedOnEvent(dispatcher, Event.COMPLETE, 10); - - var commands:Array = orphanAsync.getPending(); - assertEquals("one pending command for test after proceedOnEvent()", 1, commands.length); - - // send the correct event synchronously - dispatchCompleteEvent(); - - var message:String = "No pending commands for test after correct Event dispatched."; - assertEquals(message, 0, orphanAsync.getPending().length); - } - - protected function dispatchCompleteEvent():void { - dispatcher.dispatchEvent(new Event(Event.COMPLETE)); - } - - [Test] - public function proceedOnEventShouldTimeoutAppropriately():void { - - // Grab a reference to the Dispatcher so that we still have - // it after the test run (Fixing uncaught RTE null pointer exception) - var source:IEventDispatcher = dispatcher; - - // This is the initial setup, we want test execution to pause - // for 1ms OR until the COMPLETE event fires: - orphanAsync.proceedOnEvent(source, Event.COMPLETE, 1); - - // Get the Command so that we can just wait for the TIMED_OUT event: - var commands:Array = orphanAsync.getPending(); - var command:TimeoutCommand = commands[0]; - command.addEventListener(TimeoutCommandEvent.TIMED_OUT, async.add(onAsyncMethodFailed, 500)); - - // send the correct event too slowly - timeoutID = setTimeout(function():void { - source.dispatchEvent(new Event(Event.COMPLETE)); - }, 10); - } - - protected function onAsyncMethodFailed(event:TimeoutCommandEvent):void { - assertEquals("event type", TimeoutCommandEvent.TIMED_OUT, event.type); - clearTimeout(timeoutID); - } - - [Test] - public function proceedOnEventShouldSendCALLEDEventAsExpected():void { - orphanAsync.proceedOnEvent(dispatcher, Event.COMPLETE, 10); - - command = orphanAsync.getPending()[0]; - - // Use AsUnit 3's orphanAsync.add() to verify onAsyncMethodCalled is called. - command.addEventListener(TimeoutCommandEvent.CALLED, async.add(onAsyncMethodCalled)); - - // If all goes well, the ErrorEvent won't be dispatched. - command.addEventListener(ErrorEvent.ERROR, failIfCalled); - - // send the correct event faster than orphanAsync.proceedOnEvent duration - setTimeout(dispatchCompleteEvent, 0); - } - - protected function onAsyncMethodCalled(e:Event):void { - assertEquals("event type", TimeoutCommandEvent.CALLED, e.type); - } - - protected function failIfCalled(e:Event = null):void { - fail("ProceedOnEventTest: This function should not have been called"); - } - } -} +package asunit.framework { + + import asunit.asserts.*; + import asunit.events.TimeoutCommandEvent; + import asunit.framework.ErrorEvent; + import asunit.framework.TestCase; + + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.IEventDispatcher; + import flash.utils.clearTimeout; + import flash.utils.setTimeout; + + public class ProceedOnEventTest { + + [Inject] + public var async:IAsync; + public var dispatcher:EventDispatcher; + + private var orphanAsync:IAsync; + private var command:TimeoutCommand; + private var timeoutID:int = -1; + + [Before] + public function setUp():void { + orphanAsync = new Async(); + dispatcher = new EventDispatcher(); + } + + [After] + public function tearDown():void { + command = null; + orphanAsync = null; + timeoutID = -1; + } + + protected function foo():void { } + + [Test] + public function proceedOnEventShouldDispatchCorrectEventAndClearPendingCommands():void { + orphanAsync.proceedOnEvent(dispatcher, Event.COMPLETE, 10); + + var commands:Array = orphanAsync.getPending(); + assertEquals("one pending command for test after proceedOnEvent()", 1, commands.length); + + // send the correct event synchronously + dispatchCompleteEvent(); + + var message:String = "No pending commands for test after correct Event dispatched."; + assertEquals(message, 0, orphanAsync.getPending().length); + } + + protected function dispatchCompleteEvent():void { + dispatcher.dispatchEvent(new Event(Event.COMPLETE)); + } + + [Test] + public function proceedOnEventShouldTimeoutAppropriately():void { + + // Grab a reference to the Dispatcher so that we still have + // it after the test run (Fixing uncaught RTE null pointer exception) + var source:IEventDispatcher = dispatcher; + + // This is the initial setup, we want test execution to pause + // for 1ms OR until the COMPLETE event fires: + orphanAsync.proceedOnEvent(source, Event.COMPLETE, 1); + + // Get the Command so that we can just wait for the TIMED_OUT event: + var commands:Array = orphanAsync.getPending(); + var command:TimeoutCommand = commands[0]; + command.addEventListener(TimeoutCommandEvent.TIMED_OUT, async.add(onAsyncMethodFailed, 500)); + + // send the correct event too slowly + timeoutID = setTimeout(function():void { + source.dispatchEvent(new Event(Event.COMPLETE)); + }, 10); + } + + protected function onAsyncMethodFailed(event:TimeoutCommandEvent):void { + assertEquals("event type", TimeoutCommandEvent.TIMED_OUT, event.type); + clearTimeout(timeoutID); + } + + [Test] + public function proceedOnEventShouldSendCALLEDEventAsExpected():void { + orphanAsync.proceedOnEvent(dispatcher, Event.COMPLETE, 10); + + command = orphanAsync.getPending()[0]; + + // Use AsUnit 3's orphanAsync.add() to verify onAsyncMethodCalled is called. + command.addEventListener(TimeoutCommandEvent.CALLED, async.add(onAsyncMethodCalled)); + + // If all goes well, the ErrorEvent won't be dispatched. + command.addEventListener(ErrorEvent.ERROR, failIfCalled); + + // send the correct event faster than orphanAsync.proceedOnEvent duration + setTimeout(dispatchCompleteEvent, 0); + } + + protected function onAsyncMethodCalled(e:Event):void { + assertEquals("event type", TimeoutCommandEvent.CALLED, e.type); + } + + protected function failIfCalled(e:Event = null):void { + fail("ProceedOnEventTest: This function should not have been called"); + } + } +} diff --git a/asunit-4.0/test/asunit/framework/ResultObserverTest.as b/asunit-4.0/test/asunit/framework/ResultObserverTest.as new file mode 100644 index 0000000..1af088f --- /dev/null +++ b/asunit-4.0/test/asunit/framework/ResultObserverTest.as @@ -0,0 +1,61 @@ +package asunit.framework { + + import asunit.asserts.*; + import asunit.support.FakeObserver; + import asunit.framework.Result; + + public class ResultObserverTest { + + private var result:Result; + + private var listener:FakeObserver; + + [Before] + public function createObserver():void { + listener = new FakeObserver(); + result = new Result(); + result.addListener(listener); + } + + [After] + public function destroyObserver():void { + listener = null; + } + + [Test] + public function canInstantiate():void { + assertTrue("instance is Result", result is Result); + } + + [Test] + public function addedListenerReceivesOnRunStarted():void { + result.onRunStarted(); + assertTrue(listener.onRunStartedCalled); + } + + [Test] + public function addedListenerReceivesOnTestStarted():void { + result.onTestStarted(null); + assertTrue(listener.onTestStartedCalled); + } + + [Test] + public function shouldHaveDefaultRunCount():void + { + assertEquals(0, result.runCount); + } + + [Test] + public function shouldHaveCumulativeRunCount():void + { + result.onTestStarted(null); + result.onTestSuccess(null); + result.onTestCompleted(null); + result.onTestStarted(null); + result.onTestSuccess(null); + result.onTestCompleted(null); + assertEquals(2, result.runCount); + } + + } +} \ No newline at end of file diff --git a/asunit-4.0/test/asunit/framework/RunnerFactoryTest.as b/asunit-4.0/test/asunit/framework/RunnerFactoryTest.as index c065b7b..b2c553c 100644 --- a/asunit-4.0/test/asunit/framework/RunnerFactoryTest.as +++ b/asunit-4.0/test/asunit/framework/RunnerFactoryTest.as @@ -14,9 +14,13 @@ package asunit.framework { public class RunnerFactoryTest { - [Inject] - public var factory:RunnerFactory; - + private var factory:IRunnerFactory; + + [Before] + public function before():void { + factory = new RunnerFactory(); + } + [Test] public function shouldCreateDefaultRunner():void { var result:IRunner = factory.runnerFor(SucceedAssertTrue); @@ -29,12 +33,6 @@ package asunit.framework { assertTrue(result is SuiteRunner); } - [Test] - public function shouldAssignFactoryOnCreation():void { - var result:IRunner = factory.runnerFor(SingleSuccessSuite); - assertSame(factory, result.factory); - } - [Test(expects="asunit.errors.UsageError")] public function shouldFailWhenGivenANonTestOrSuite():void { factory.runnerFor(Sprite); diff --git a/asunit-4.0/test/asunit/framework/VisualTestCaseTest.as b/asunit-4.0/test/asunit/framework/VisualTestCaseTest.as index 909c16b..f7ac4e3 100644 --- a/asunit-4.0/test/asunit/framework/VisualTestCaseTest.as +++ b/asunit-4.0/test/asunit/framework/VisualTestCaseTest.as @@ -1,43 +1,19 @@ -package asunit.framework { - - import asunit.asserts.*; - - import flash.display.Sprite; - - public class VisualTestCaseTest { - - [Inject] - public var sprite:Sprite; - - [Test] - public function instantiated():void { - assertTrue(sprite is Sprite); - } - - [Test] - public function testSize():void { - assertTrue(sprite.width == 0); - assertTrue(sprite.height == 0); - } - - [Test] - public function testDrawnSize():void { - sprite.x = 110; - sprite.y = 115; - sprite.graphics.beginFill(0xFF0000); - sprite.graphics.drawRect(0, 0, 100, 200); - - assertEquals(100, sprite.width); - assertEquals(200, sprite.height); - assertEquals(110, sprite.x); - assertEquals(115, sprite.y); - } - - [Test] - public function testSecondSize():void { - assertTrue(sprite.width == 0); - assertTrue(sprite.height == 0); - } - } -} - +package asunit.framework { + + import asunit.asserts.*; + + import flash.display.Sprite; + + public class VisualTestCaseTest { + + [Inject] + public var context:Sprite; + + [Test] + public function instantiated():void { + assertTrue(context is Sprite); + } + + } +} + diff --git a/asunit-4.0/test/asunit/printers/ColorTracePrinterTest.as b/asunit-4.0/test/asunit/printers/ColorTracePrinterTest.as new file mode 100644 index 0000000..10d3e14 --- /dev/null +++ b/asunit-4.0/test/asunit/printers/ColorTracePrinterTest.as @@ -0,0 +1,121 @@ +package asunit.printers { + + import asunit.framework.ITestFailure; + import asunit.framework.TestCase; + + import asunit.framework.IResult; + import asunit.framework.ITestSuccess; + import asunit.framework.ITestWarning; + import asunit.framework.Result; + import asunit.framework.TestFailure; + import asunit.framework.TestSuccess; + import asunit.framework.TestWarning; + + public class ColorTracePrinterTest extends TestCase { + + private var printer:FakeTextPrinter; + private var test:*; + private var success:ITestSuccess; + private var failure:ITestFailure; + private var testResult:IResult; + + public function ColorTracePrinterTest(method:String=null) { + super(method); + } + + override protected function setUp():void { + super.setUp(); + printer = new FakeTextPrinter(); + + testResult = new Result(); + test = new TestCase(); + failure = new TestFailure(test, 'testSomethingThatFails', new Error('Fake Failure')); + success = new TestSuccess(test, 'testSomethingThatSucceeds'); + testResult.addListener(printer); + } + + override protected function tearDown():void { + super.tearDown(); + failure = null; + printer = null; + testResult = null; + success = null; + test = null; + } + + private function executeASucceedingTest():void { + testResult.onRunStarted(); + testResult.onTestStarted(test); + testResult.onTestSuccess(success); + testResult.onTestCompleted(test); + testResult.onRunCompleted(null); + } + + private function executeASucceedingTestWithWarning(warning:ITestWarning):void { + testResult.onRunStarted(); + testResult.onTestStarted(test); + testResult.onWarning(warning); + testResult.onTestSuccess(success); + testResult.onTestCompleted(test); + testResult.onRunCompleted(null); + } + + private function executeAFailingTest():void { + testResult.onRunStarted(); + testResult.onTestStarted(test); + testResult.onTestFailure(failure); + testResult.onTestCompleted(test); + testResult.onRunCompleted(null); + } + + public function testPrinterOnTestSuccess():void { + executeASucceedingTest(); + var actual:String = printer.toString(); + const GREEN:String = String.fromCharCode(27) + "[32m"; + const RESET:String = String.fromCharCode(27) + "[0m" + + assertTrue("Printer should print OK in green", actual.indexOf( GREEN + 'OK' + RESET ) > -1); + assertTrue("Printer should include Tests run: ", actual.match(/Tests run: 1/)); + } + + public function testPrinterFailure():void { + executeAFailingTest(); + var expected:String = "Fake Failure"; + var actual:String = printer.toString(); + const RED:String = String.fromCharCode(27) + "[31m"; + const RESET:String = String.fromCharCode(27) + "[0m" + + assertTrue("Printer should print FAILURE in red", actual.indexOf(RED + 'FAILURE' + RESET) > -1); + assertTrue("Printer should fail", actual.indexOf(expected) > -1); + assertTrue("Printer should include Test Duration: ", actual.match(/Total Time: \d/)); + } + + public function testPrinterWithNoTests():void { + testResult.onRunStarted(); + testResult.onRunCompleted(null); + assertTrue("Printer should include Warning for no tests", printer.toString().indexOf("[WARNING]") > -1); + } + + public function testDisplaysWarnings():void { + var message:String = "problem" + executeASucceedingTestWithWarning(new TestWarning(message)); + + var actual:String = printer.toString(); + + const YELLOW:String = String.fromCharCode(27) + "[33m"; + const RESET:String = String.fromCharCode(27) + "[0m" + assertTrue("Printer should print Warning in yellow", actual.indexOf(YELLOW + 'Warning' + RESET) > -1); + assertTrue("Printer displays warnings", actual.indexOf(message) > -1); + } + } +} + +import asunit.printers.ColorTracePrinter; + +class FakeTextPrinter extends ColorTracePrinter { + + // Prevent the printer from tracing results: + override protected function logResult():void { + } +} + diff --git a/asunit-4.0/test/asunit/printers/FlashBuilderPrinterTest.as b/asunit-4.0/test/asunit/printers/FlashBuilderPrinterTest.as new file mode 100644 index 0000000..bf0e5e6 --- /dev/null +++ b/asunit-4.0/test/asunit/printers/FlashBuilderPrinterTest.as @@ -0,0 +1,18 @@ + +package asunit.printers { + + import asunit.asserts.*; + import asunit.framework.TestCase; + + public class FlashBuilderPrinterTest extends TestCase { + + public function FlashBuilderPrinterTest(method:String=null) { + super(method); + } + + private function testInstantiable():void { + var printer:FlashBuilderPrinter = new FlashBuilderPrinter(); + } + } +} + diff --git a/asunit-4.0/test/asunit/printers/XMLPrinterTest.as b/asunit-4.0/test/asunit/printers/XMLPrinterTest.as new file mode 100644 index 0000000..0685508 --- /dev/null +++ b/asunit-4.0/test/asunit/printers/XMLPrinterTest.as @@ -0,0 +1,131 @@ +package asunit.printers { + + import asunit.asserts.*; + import asunit.errors.AssertionFailedError; + import asunit.framework.ITestFailure; + import asunit.framework.TestCase; + + import asunit.framework.IResult; + import asunit.framework.ITestSuccess; + import asunit.framework.ITestWarning; + import asunit.framework.Method; + import asunit.framework.Result; + import asunit.framework.TestFailure; + import asunit.framework.TestSuccess; + import asunit.framework.TestWarning; + + import p2.reflect.Reflection; + import p2.reflect.ReflectionMethod; + + + public class XMLPrinterTest extends TestCase { + + private var printer:XMLPrinter; + private var test:*; + private var testSuccess:ITestSuccess; + private var testError:ITestFailure; + private var testFailure:ITestFailure; + private var testResult:IResult; + private var testWarning:ITestWarning; + + public function XMLPrinterTest(method:String=null) { + super(method); + } + + override protected function setUp():void { + super.setUp(); + printer = new XMLPrinter(); + printer.traceResults = false; + + test = new FakeTestCase(); + var reflect:Reflection = Reflection.create(test); + var methodReflection:ReflectionMethod = reflect.methods[0]; + var method:Method = new Method(test, methodReflection); + + testResult = new Result(); + testError = new TestFailure(test, 'testSomethingThatErrors', new Error('Fake Error')); + testFailure = new TestFailure(test, 'testSomethingThatFails', new AssertionFailedError('Fake Failure')); + testSuccess = new TestSuccess(test, 'testSomethingThatSucceeds'); + testWarning = new TestWarning(test, method); + testResult.addListener(printer); + } + + private function executeTestWith(handler:Function):void { + testResult.onRunStarted(); + testResult.onTestStarted(test); + handler.call(this); + testResult.onTestCompleted(test); + testResult.onRunCompleted(null); + } + + private function executeASucceedingTest():String { + executeTestWith(function():void { + testResult.onTestSuccess(testSuccess); + }); + return printer.toString(); + } + + private function executeASucceedingTestWithWarning():String { + executeTestWith(function():void { + testResult.onWarning(testWarning); + testResult.onTestSuccess(testSuccess); + }); + testResult.onRunStarted(); + testResult.onTestStarted(test); + testResult.onTestCompleted(test); + testResult.onRunCompleted(null); + return printer.toString(); + } + + private function executeAFailingTest():String { + executeTestWith(function():void { + testResult.onTestFailure(testFailure); + }); + return printer.toString(); + } + + private function executeAnErrorTest():String { + executeTestWith(function():void { + testResult.onTestFailure(testError); + }); + return printer.toString(); + } + + public function testPrinterStartAndFinish():void { + var actual:String = executeASucceedingTest(); + assertMatches(//, actual); + assertMatches(/startTestRun/, actual); + assertMatches(//, actual); + assertMatches(/<\/TestResults>/, actual); + + assertMatches(/status='success'/, actual); + } + + public function testPrinterFailure():void { + var actual:String = executeAFailingTest(); + assertMatches(/status='failure'/, actual); + assertMatches(/stackTraceInfo/, actual); + assertMatches(/asunit\/printers\/XMLPrinterTest.as/, actual); + } + + public function testPrinterError():void { + var actual:String = executeAnErrorTest(); + assertMatches(/status='error'/, actual); + assertMatches(/stackTraceInfo/, actual); + assertMatches(/asunit\/printers\/XMLPrinterTest.as/, actual); + } + + public function testPrinterWarning():void { + var actual:String = executeASucceedingTestWithWarning(); + assertMatches(/status='warning'/, actual); + assertMatches(/status='success'/, actual); + } + } +} + +class FakeTestCase { + + [Test] + public function testSomething():void { + } +} diff --git a/asunit-4.0/test/asunit/runners/LegacyRunnerTest.as b/asunit-4.0/test/asunit/runners/LegacyRunnerTest.as index 2639a40..726280b 100644 --- a/asunit-4.0/test/asunit/runners/LegacyRunnerTest.as +++ b/asunit-4.0/test/asunit/runners/LegacyRunnerTest.as @@ -5,9 +5,9 @@ package asunit.runners { import asunit.framework.Result; import asunit.framework.TestCase; import asunit.support.LegacyTestCase; + import flash.display.Sprite; import flash.events.Event; - import asunit.framework.CallbackBridge; public class LegacyRunnerTest extends TestCase { @@ -30,11 +30,11 @@ package asunit.runners { public function testSimpleSubclass():void { var handler:Function = function(event:Event):void { - assertEquals(0, testRunner.bridge.failureCount); - assertEquals(2, testRunner.bridge.runCount); + assertEquals(0, testRunner.result.failureCount); + assertEquals(2, testRunner.result.runCount); }; testRunner.addEventListener(Event.COMPLETE, addAsync(handler)); - testRunner.run(LegacyTestCase); + testRunner.run(LegacyTestCase, null, new Sprite()); } } } diff --git a/asunit-4.0/test/asunit/runners/SuiteRunnerTest.as b/asunit-4.0/test/asunit/runners/SuiteRunnerTest.as index ebfbea7..36f2973 100644 --- a/asunit-4.0/test/asunit/runners/SuiteRunnerTest.as +++ b/asunit-4.0/test/asunit/runners/SuiteRunnerTest.as @@ -5,6 +5,7 @@ package asunit.runners { import asunit.framework.Result; import asunit.support.DoubleFailSuite; import asunit.support.InjectionVerification; + import flash.display.Sprite; import flash.events.Event; @@ -12,12 +13,14 @@ package asunit.runners { [Inject] public var async:IAsync; - - [Inject] - public var suiteRunner:SuiteRunner; - - [Inject] - public var runnerResult:Result; + private var suiteRunner:SuiteRunner; + private var runnerResult:Result; + + [Before] + public function setUp():void { + runnerResult = new Result(); + suiteRunner = new SuiteRunner(null, runnerResult); + } public function testRunTriggersCompleteEvent():void { suiteRunner.addEventListener(Event.COMPLETE, async.add(checkResultWasNotSuccessful)); @@ -31,7 +34,7 @@ package asunit.runners { [Test] public function testCanHandATestToSuiteRunner():void { suiteRunner.addEventListener(Event.COMPLETE, async.add()); - suiteRunner.run(InjectionVerification); + suiteRunner.run(InjectionVerification, null, new Sprite()); assertFalse(runnerResult.wasSuccessful); } } diff --git a/asunit-4.0/test/asunit/runners/TestRunnerAsyncMethodTest.as b/asunit-4.0/test/asunit/runners/TestRunnerAsyncMethodTest.as index aa4c807..7238b5a 100644 --- a/asunit-4.0/test/asunit/runners/TestRunnerAsyncMethodTest.as +++ b/asunit-4.0/test/asunit/runners/TestRunnerAsyncMethodTest.as @@ -1,7 +1,6 @@ package asunit.runners { import asunit.asserts.*; - import asunit.framework.CallbackBridge; import asunit.framework.TestCase; import asunit.util.Iterator; @@ -18,9 +17,12 @@ package asunit.runners { [Inject] public var async:IAsync; - - [Inject] - public var runner:TestRunner; + private var runner:TestRunner; + + [Before] + public function before():void { + runner = new TestRunner(); + } [Test] public function asyncShouldWork():void { @@ -35,7 +37,7 @@ package asunit.runners { } private function ensureRunnerHasNotYetFailed(e:Event):void { - assertFalse('runner result has not failed', runner.bridge.failureEncountered); + assertFalse('runner result has not failed', runner.result.failureEncountered); } [Test] @@ -45,8 +47,8 @@ package asunit.runners { } private function checkResultForIllegalOperationError(e:Event):void { - assertEquals('number of errors', 1, runner.bridge.errors.length); - var failure0:TestFailure = runner.bridge.errors[0] as TestFailure; + assertEquals('number of errors', 1, runner.result.errors.length); + var failure0:TestFailure = runner.result.errors[0] as TestFailure; assertEquals('exception type', 'flash.errors::IllegalOperationError', getQualifiedClassName(failure0.thrownException)); assertEquals('failed method name', 'shouldFailForBeingTooSlow', failure0.failedMethod); } diff --git a/asunit-4.0/test/asunit/runners/TestRunnerErrorMethodTest.as b/asunit-4.0/test/asunit/runners/TestRunnerErrorMethodTest.as index 16b5058..d93ff8a 100644 --- a/asunit-4.0/test/asunit/runners/TestRunnerErrorMethodTest.as +++ b/asunit-4.0/test/asunit/runners/TestRunnerErrorMethodTest.as @@ -40,7 +40,7 @@ package asunit.runners { } private function check_Result_has_one_error(e:Event):void { - var runnerResult:IResult = runner.bridge; + var runnerResult:IResult = runner.result; assertFalse('runnerResult.wasSuccessful', runnerResult.wasSuccessful); assertEquals('one error in testResult', 1, runnerResult.errorCount); diff --git a/asunit-4.0/test/asunit/runners/TestRunnerExpectsErrorTest.as b/asunit-4.0/test/asunit/runners/TestRunnerExpectsErrorTest.as index c4943de..c30cc8d 100644 --- a/asunit-4.0/test/asunit/runners/TestRunnerExpectsErrorTest.as +++ b/asunit-4.0/test/asunit/runners/TestRunnerExpectsErrorTest.as @@ -42,7 +42,7 @@ package asunit.runners { } private function check_Result_has_no_errors(e:Event):void { - var runnerResult:IResult = runner.bridge; + var runnerResult:IResult = runner.result; assertEquals('no errors in testResult', 0, runnerResult.errorCount); assertEquals('no failures in testResult', 0, runnerResult.failureCount); } @@ -53,7 +53,7 @@ package asunit.runners { } private function check_Result_has_one_assertion_failure(e:Event):void { - var runnerResult:IResult = runner.bridge; + var runnerResult:IResult = runner.result; assertFalse(runnerResult.wasSuccessful); assertEquals('one failure in testResult', 1, runnerResult.failureCount); diff --git a/asunit-4.0/test/asunit/runners/TestRunnerExpectsErrorWithMessageTest.as b/asunit-4.0/test/asunit/runners/TestRunnerExpectsErrorWithMessageTest.as new file mode 100644 index 0000000..a3a80a1 --- /dev/null +++ b/asunit-4.0/test/asunit/runners/TestRunnerExpectsErrorWithMessageTest.as @@ -0,0 +1,125 @@ +package asunit.runners { + + import asunit.errors.AssertionFailedError; + import asunit.framework.TestCase; + + import asunit.framework.IResult; + import asunit.framework.Result; + import asunit.framework.TestFailure; + + import flash.events.Event; + + public class TestRunnerExpectsErrorWithMessageTest extends TestCase { + + private var runner:TestRunner; + private var successTest:Class; + private var throwNothingTest:Class; + private var throwWrongErrorTest:Class; + private var throwWrongMessageTest:Class; + + private var failedTest:Class; + private var failedMethod:String; + + public function TestRunnerExpectsErrorWithMessageTest(testMethod:String = null) { + super(testMethod); + } + + protected override function setUp():void { + super.setUp(); + runner = new TestRunner(); + successTest = TestExpectsArgumentErrorAndThrowsIt; + throwNothingTest = TestExpectsArgumentErrorButThrowsNothing; + throwWrongErrorTest = TestExpectsArgumentErrorButThrowsWrongError; + throwWrongMessageTest = TestExpectsArgumentErrorButThrowsWrongMessage; + } + + protected override function tearDown():void { + super.tearDown(); + runner = null; + successTest = null; + throwNothingTest = null; + throwWrongErrorTest = null; + throwWrongMessageTest = null; + failedTest = null; + failedMethod = null; + } + + public function test_method_expects_specific_error_and_throws_it_yields_successful_test_result():void { + runner.addEventListener(Event.COMPLETE, addAsync(check_Result_has_no_errors, 100)); + runner.run(successTest); + } + + public function test_method_expects_specific_error_but_nothing_thrown_yields_assertion_failure():void { + failedTest = throwNothingTest; + failedMethod = "fail_by_throwing_nothing"; + runner.addEventListener(Event.COMPLETE, addAsync(check_Result_has_one_assertion_failure, 100)); + runner.run(throwNothingTest); + } + + public function test_method_expects_specific_error_but_wrong_one_thrown_yields_assertion_failure():void { + failedTest = throwWrongErrorTest; + failedMethod = "fail_by_throwing_wrong_error"; + runner.addEventListener(Event.COMPLETE, addAsync(check_Result_has_one_assertion_failure, 100)); + runner.run(throwWrongErrorTest); + } + + public function test_method_expects_specific_message_but_wrong_one_thrown_yields_assertion_failure():void { + failedTest = throwWrongMessageTest; + failedMethod = "fail_by_throwing_wrong_message"; + runner.addEventListener(Event.COMPLETE, addAsync(check_Result_has_one_assertion_failure, 100)); + runner.run(throwWrongMessageTest); + } + + + private function check_Result_has_no_errors(e:Event):void { + var runnerResult:IResult = runner.result; + assertEquals('no errors in testResult', 0, runnerResult.errorCount); + assertEquals('no failures in testResult', 0, runnerResult.failureCount); + } + + private function check_Result_has_one_assertion_failure(e:Event):void { + var runnerResult:IResult = runner.result; + assertFalse(runnerResult.wasSuccessful); + + assertEquals('one failure in testResult', 1, runnerResult.failureCount); + assertEquals('no errors in testResult', 0, runnerResult.errorCount); + + var failure0:TestFailure = runnerResult.failures[0] as TestFailure; + assertTrue('thrownException is correct type', failure0.thrownException is AssertionFailedError); + assertTrue('failedTest is instance of the test class', failure0.failedTest is failedTest); + assertSame('failedMethod name', failedMethod, failure0.failedMethod); + } + } +} + +class TestExpectsArgumentErrorAndThrowsIt { + + [Test(expects="ArgumentError", message="generated by TestExpectsArgumentError")] + public function throwArgumentError():void { + throw new ArgumentError('generated by TestExpectsArgumentError'); + } +} + +class TestExpectsArgumentErrorButThrowsNothing { + + [Test(expects="ArgumentError", message="generated by TestExpectsArgumentErrorButThrowsNothing")] + public function fail_by_throwing_nothing():void { + } +} + +class TestExpectsArgumentErrorButThrowsWrongError { + + [Test(expects="ArgumentError", message="generated by TestExpectsArgumentErrorButThrowsWrongError")] + public function fail_by_throwing_wrong_error():void { + throw new Error('generated by TestExpectsArgumentErrorButThrowsWrongError'); + } +} + +class TestExpectsArgumentErrorButThrowsWrongMessage { + + [Test(expects="Error", message="foo")] + public function fail_by_throwing_wrong_message():void { + throw new Error('bar'); + } +} + diff --git a/asunit-4.0/test/asunit/runners/TestRunnerIgnoredMethodTest.as b/asunit-4.0/test/asunit/runners/TestRunnerIgnoredMethodTest.as index 038a57d..0e317b4 100644 --- a/asunit-4.0/test/asunit/runners/TestRunnerIgnoredMethodTest.as +++ b/asunit-4.0/test/asunit/runners/TestRunnerIgnoredMethodTest.as @@ -2,7 +2,6 @@ package asunit.runners { import asunit.framework.TestCase; - import asunit.framework.Result; import asunit.support.IgnoredMethod; import flash.events.Event; @@ -34,8 +33,8 @@ package asunit.runners { } private function checkResultHasOneIgnoredMethod(e:Event):void { - assertFalse('runnerResult.failureEncountered', runner.bridge.failureEncountered); - assertEquals('one ignored test in result', 1, runner.bridge.ignoredTests.length); + assertFalse('runnerResult.failureEncountered', runner.result.failureEncountered); + assertEquals('one ignored test in result', 1, runner.result.ignoredTests.length); } } } diff --git a/asunit-4.0/test/asunit/runners/TestRunnerTest.as b/asunit-4.0/test/asunit/runners/TestRunnerTest.as index 30b78fc..69549c0 100644 --- a/asunit-4.0/test/asunit/runners/TestRunnerTest.as +++ b/asunit-4.0/test/asunit/runners/TestRunnerTest.as @@ -8,8 +8,6 @@ package asunit.runners { import asunit.framework.Result; import asunit.framework.TestCase; import asunit.framework.TestFailure; - import asunit.support.AnnotatedSubClass; - import asunit.support.InjectTimeoutOnAsync; import asunit.support.InjectionFailure; import asunit.support.InjectionVerification; import asunit.support.MultiMethod; @@ -97,10 +95,10 @@ package asunit.runners { } private function checkResultWasNotSuccessful(e:Event):void { - assertTrue(runner.bridge.failureEncountered); - assertFalse(runner.bridge.wasSuccessful); + assertTrue(runner.result.failureEncountered); + assertFalse(runner.result.wasSuccessful); - var failures:Array = runner.bridge.failures; + var failures:Array = runner.result.failures; assertEquals('one failure in testResult', 1, failures.length); var failure0:ITestFailure = failures[0] as TestFailure; @@ -143,28 +141,7 @@ package asunit.runners { [Test] public function shouldInjectTypes():void { runner.run(InjectionVerification, null, context); - assertFalse("Should not have encountered failures: " + runner.bridge.failures.join("\n\n"), runner.bridge.failureEncountered); - } - - [Test] - public function shouldInjectWithUnknownAttribute():void { - runner.run(InjectionFailure); - var warnings:Array = runner.bridge.warnings; - assertEquals(1, warnings.length); - } - - [Test] - public function shouldInjectAsyncTimeout():void { - var async:IAsync = runner.async; - assertEquals(Async.DEFAULT_TIMEOUT, async.timeout); - runner.run(InjectTimeoutOnAsync); - assertEquals(5, async.timeout); - } - - [Test] - public function annotationsOnSuperClassShouldBeRespected():void { - runner.run(AnnotatedSubClass); - assertFalse("Should not have failures: " + runner.bridge.failures.join("\n\n"), runner.bridge.failureEncountered); + assertFalse("Should not have encountered failures: " + runner.result.failures.join("\n\n"), runner.result.failureEncountered); } } } diff --git a/asunit-4.0/test/asunit/support/AnnotatedSubClass.as b/asunit-4.0/test/asunit/support/AnnotatedSubClass.as deleted file mode 100644 index 0e20203..0000000 --- a/asunit-4.0/test/asunit/support/AnnotatedSubClass.as +++ /dev/null @@ -1,18 +0,0 @@ -package asunit.support { - - import asunit.asserts.*; - - public class AnnotatedSubClass extends AnnotatedSuperClass { - - [Test] - public function verifyDictionary():void { - assertNotNull(dictionary); - } - - [Test] - public function verifyAsync():void { - assertNotNull(async); - } - } -} - diff --git a/asunit-4.0/test/asunit/support/AnnotatedSuperClass.as b/asunit-4.0/test/asunit/support/AnnotatedSuperClass.as deleted file mode 100644 index 658df28..0000000 --- a/asunit-4.0/test/asunit/support/AnnotatedSuperClass.as +++ /dev/null @@ -1,15 +0,0 @@ -package asunit.support { - - import asunit.asserts.*; - import asunit.framework.IAsync; - import flash.utils.Dictionary; - - public class AnnotatedSuperClass { - - [Inject] - public var async:IAsync; - - [Inject] - public var dictionary:Dictionary; - } -} diff --git a/asunit-4.0/test/asunit/support/CustomTestRunner.as b/asunit-4.0/test/asunit/support/CustomSuiteRunner.as similarity index 68% rename from asunit-4.0/test/asunit/support/CustomTestRunner.as rename to asunit-4.0/test/asunit/support/CustomSuiteRunner.as index 96060db..e8cfcc8 100644 --- a/asunit-4.0/test/asunit/support/CustomTestRunner.as +++ b/asunit-4.0/test/asunit/support/CustomSuiteRunner.as @@ -1,17 +1,21 @@ package asunit.support { - import asunit.framework.CallbackBridge; import asunit.framework.IResult; - import asunit.runners.TestRunner; + import asunit.framework.IRunnerFactory; + import asunit.runners.SuiteRunner; import flash.display.DisplayObjectContainer; - public class CustomTestRunner extends TestRunner { + public class CustomSuiteRunner extends SuiteRunner { // Used so that test cases can // verify that this custom runner // worked. public static var runCalledCount:int; + + public function CustomSuiteRunner(factory:IRunnerFactory = null) { + super(factory); + } override public function run(testClass:Class, testMethod:String=null, visualContext:DisplayObjectContainer=null):void { runCalledCount++; diff --git a/asunit-4.0/test/asunit/support/FakeRunner.as b/asunit-4.0/test/asunit/support/FakeRunner.as deleted file mode 100644 index 307ad7b..0000000 --- a/asunit-4.0/test/asunit/support/FakeRunner.as +++ /dev/null @@ -1,32 +0,0 @@ -package asunit.support { - - import asunit.framework.IRunner; - import asunit.framework.IResult; - import asunit.framework.TestSuccess; - import asunit.framework.IRunnerFactory; - - import flash.events.EventDispatcher; - import flash.display.DisplayObjectContainer; - - public class FakeRunner extends EventDispatcher implements IRunner { - - public function run(testOrSuite:Class, result:IResult, testMethod:String=null, visualContext:DisplayObjectContainer=null):void { - var currentTest:TestForFakeRunner = new testOrSuite() as TestForFakeRunner; - - result.onTestStarted(currentTest); - result.onTestSuccess(new TestSuccess(currentTest, 'customTestMethod')); - result.onTestCompleted(currentTest); - } - - public function shouldRunTest(testClass:Class):Boolean { - return true; - } - - public function set factory(factory:IRunnerFactory):void { - } - - public function get factory():IRunnerFactory { - } - } -} - diff --git a/asunit-4.0/test/asunit/support/InjectTimeoutOnAsync.as b/asunit-4.0/test/asunit/support/InjectTimeoutOnAsync.as deleted file mode 100644 index 16b3b56..0000000 --- a/asunit-4.0/test/asunit/support/InjectTimeoutOnAsync.as +++ /dev/null @@ -1,14 +0,0 @@ -package asunit.support { - - import asunit.framework.IAsync; - - public class InjectTimeoutOnAsync { - - [Inject(timeout=5)] - public var async:IAsync; - - [Test] - public function verifyNothing():void { - } - } -} diff --git a/asunit-4.0/test/asunit/support/InjectionVerification.as b/asunit-4.0/test/asunit/support/InjectionVerification.as index b293d8d..6fc7286 100644 --- a/asunit-4.0/test/asunit/support/InjectionVerification.as +++ b/asunit-4.0/test/asunit/support/InjectionVerification.as @@ -17,42 +17,14 @@ package asunit.support { [Inject] public var context:Sprite; - [Inject(someString="stringValue", someBoolean=false, someNumber=23.4, someInt=-23, someUInt=25)] - public var custom:CustomParameters; - - [Test] - public function injectedShouldReceiveUIntValue():void { - assertSame(25, custom.someUInt); - } - - [Test] - public function injectedShouldReceiveIntegerValue():void { - assertSame(-23, custom.someInt); - } - - [Test] - public function injectedShouldReceiveNumberValue():void { - assertSame(23.4, custom.someNumber); - } - - [Test] - public function injectedShouldReceiveBooleanValue():void { - assertSame(false, custom.someBoolean); - } - - [Test] - public function injectedShouldReceiveStringValue():void { - assertEquals("stringValue", custom.someString); - } - [Test] public function verifyDisplayObjectInjection():void { - assertNotNull("DisplayObject should exiset", context); + assertNotNull("DisplayObject should exist", context); } [Test] public function verifyDisplayObjectAttachedToStage():void { - assertNotNull("DisplayObjects hould be attached", context.stage); + assertNotNull("DisplayObjects should be attached to stage", context.stage); } [Test] diff --git a/asunit-4.0/test/asunit/support/SingleSuccessSuite.as b/asunit-4.0/test/asunit/support/SingleSuccessSuite.as index 588d3ee..6ee5780 100644 --- a/asunit-4.0/test/asunit/support/SingleSuccessSuite.as +++ b/asunit-4.0/test/asunit/support/SingleSuccessSuite.as @@ -1,7 +1,7 @@ -package asunit.support { - - [Suite] - public class SingleSuccessSuite { - public var succeedAssertTrue:SucceedAssertTrue; - } -} +package asunit.support { + + [Suite] + public class SingleSuccessSuite { + public var succeedAssertTrue:SucceedAssertTrue; + } +} diff --git a/asunit-4.0/test/asunit/support/SuiteOfTwoSuites.as b/asunit-4.0/test/asunit/support/SuiteOfTwoSuites.as index c6cb5f3..392fe1c 100644 --- a/asunit-4.0/test/asunit/support/SuiteOfTwoSuites.as +++ b/asunit-4.0/test/asunit/support/SuiteOfTwoSuites.as @@ -1,8 +1,8 @@ -package asunit.support { - - [Suite] - public class SuiteOfTwoSuites { - public var singleSuccessSuite:SingleSuccessSuite; - public var doubleFailSuite:DoubleFailSuite; - } -} +package asunit.support { + + [Suite] + public class SuiteOfTwoSuites { + public var singleSuccessSuite:SingleSuccessSuite; + public var doubleFailSuite:DoubleFailSuite; + } +} diff --git a/asunit-4.0/test/asunit/support/SuiteWithCustomRunner.as b/asunit-4.0/test/asunit/support/SuiteWithCustomRunner.as index a20c3fc..52b0e08 100644 --- a/asunit-4.0/test/asunit/support/SuiteWithCustomRunner.as +++ b/asunit-4.0/test/asunit/support/SuiteWithCustomRunner.as @@ -1,7 +1,7 @@ package asunit.support { [Suite] - [RunWith("asunit.support.CustomTestRunner")] + [RunWith("asunit.support.CustomSuiteRunner")] public class SuiteWithCustomRunner { public var succeedAssertTrue:SucceedAssertTrue; diff --git a/asunit-4.0/test/asunit/support/TestForFakeRunner.as b/asunit-4.0/test/asunit/support/TestForFakeRunner.as deleted file mode 100644 index 2aa6916..0000000 --- a/asunit-4.0/test/asunit/support/TestForFakeRunner.as +++ /dev/null @@ -1,14 +0,0 @@ -package asunit.support { - - // Declare a fully-qualified runner for this test case: - [RunWith("asunit.support::FakeRunner")] - public class TestForFakeRunner { - - private var runnerReference:FakeRunner; - - public function customTestMethod():int { - throw new Error("This method shouldn't really get called"); - } - } -} - diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectionConfig.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectionConfig.as new file mode 100644 index 0000000..4eba00b --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectionConfig.as @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2009 the original author or authors +* +* Permission is hereby granted to use, modify, and distribute this file +* in accordance with the terms of the license agreement accompanying it. +*/ + +package org.swiftsuspenders +{ + import org.swiftsuspenders.injectionresults.InjectionResult; + + public class InjectionConfig + { + /******************************************************************************************* + * public properties * + *******************************************************************************************/ + public var request : Class; + public var injectionName : String; + + + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + private var m_injector : Injector; + private var m_result : InjectionResult; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function InjectionConfig(request : Class, injectionName : String) + { + this.request = request; + this.injectionName = injectionName; + } + + public function getResponse(injector : Injector) : Object + { + if (m_result) + { + return m_result.getResponse(m_injector || injector); + } + var parentConfig : InjectionConfig = + (m_injector || injector).getAncestorMapping(request, injectionName); + if (parentConfig) + { + return parentConfig.getResponse(injector); + } + return null; + } + + public function hasResponse(injector : Injector) : Boolean + { + if (m_result) + { + return true; + } + var parentConfig : InjectionConfig = + (m_injector || injector).getAncestorMapping(request, injectionName); + return parentConfig != null; + } + + public function hasOwnResponse() : Boolean + { + return m_result != null; + } + + public function setResult(result : InjectionResult) : void + { + m_result = result; + } + + public function setInjector(injector : Injector) : void + { + m_injector = injector; + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectionType.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectionType.as new file mode 100644 index 0000000..0994dbb --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectionType.as @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2009 the original author or authors +* +* Permission is hereby granted to use, modify, and distribute this file +* in accordance with the terms of the license agreement accompanying it. +*/ + +package org.swiftsuspenders +{ + public class InjectionType + { + public static const VALUE : int = 0; + public static const CLASS : int = 1; + public static const SINGLETON : int = 2; + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/Injector.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/Injector.as new file mode 100644 index 0000000..ce98088 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/Injector.as @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2009-2010 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders +{ + import flash.system.ApplicationDomain; + import flash.utils.Dictionary; + import flash.utils.Proxy; + import flash.utils.describeType; + import flash.utils.getDefinitionByName; + import flash.utils.getQualifiedClassName; + + import org.swiftsuspenders.injectionpoints.ConstructorInjectionPoint; + import org.swiftsuspenders.injectionpoints.InjectionPoint; + import org.swiftsuspenders.injectionpoints.MethodInjectionPoint; + import org.swiftsuspenders.injectionpoints.NoParamsConstructorInjectionPoint; + import org.swiftsuspenders.injectionpoints.PostConstructInjectionPoint; + import org.swiftsuspenders.injectionpoints.PropertyInjectionPoint; + import org.swiftsuspenders.injectionresults.InjectClassResult; + import org.swiftsuspenders.injectionresults.InjectOtherRuleResult; + import org.swiftsuspenders.injectionresults.InjectSingletonResult; + import org.swiftsuspenders.injectionresults.InjectValueResult; + + public class Injector + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + private var m_parentInjector : Injector; + private var m_applicationDomain:ApplicationDomain; + private var m_mappings : Dictionary; + private var m_injectionPointLists : Dictionary; + private var m_constructorInjectionPoints : Dictionary; + private var m_attendedToInjectees : Dictionary; + private var m_xmlMetadata : XML; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function Injector(xmlConfig : XML = null) + { + m_mappings = new Dictionary(); + m_injectionPointLists = new Dictionary(); + m_constructorInjectionPoints = new Dictionary(); + m_attendedToInjectees = new Dictionary(true); + m_xmlMetadata = xmlConfig; + } + + public function mapValue(whenAskedFor : Class, useValue : Object, named : String = "") : * + { + var config : InjectionConfig = getMapping(whenAskedFor, named); + config.setResult(new InjectValueResult(useValue)); + return config; + } + + public function mapClass( + whenAskedFor : Class, instantiateClass : Class, named : String = "") : * + { + var config : InjectionConfig = getMapping(whenAskedFor, named); + config.setResult(new InjectClassResult(instantiateClass)); + return config; + } + + public function mapSingleton(whenAskedFor : Class, named : String = "") : * + { + return mapSingletonOf(whenAskedFor, whenAskedFor, named); + } + + public function mapSingletonOf( + whenAskedFor : Class, useSingletonOf : Class, named : String = "") : * + { + var config : InjectionConfig = getMapping(whenAskedFor, named); + config.setResult(new InjectSingletonResult(useSingletonOf)); + return config; + } + + public function mapRule(whenAskedFor : Class, useRule : *, named : String = "") : * + { + var config : InjectionConfig = getMapping(whenAskedFor, named); + config.setResult(new InjectOtherRuleResult(useRule)); + return useRule; + } + + public function getMapping(whenAskedFor : Class, named : String = "") : InjectionConfig + { + var requestName : String = getQualifiedClassName(whenAskedFor); + var config : InjectionConfig = m_mappings[requestName + '#' + named]; + if (!config) + { + config = m_mappings[requestName + '#' + named] = + new InjectionConfig(whenAskedFor, named); + } + return config; + } + + public function injectInto(target : Object) : void + { + if (m_attendedToInjectees[target]) + { + return; + } + m_attendedToInjectees[target] = true; + + //get injection points or cache them if this target's class wasn't encountered before + var injectionPoints : Array; + + var ctor : Class = getConstructor(target); + + injectionPoints = m_injectionPointLists[ctor] || getInjectionPoints(ctor); + + var length : int = injectionPoints.length; + for (var i : int = 0; i < length; i++) + { + var injectionPoint : InjectionPoint = injectionPoints[i]; + injectionPoint.applyInjection(target, this); + } + + } + + public function instantiate(clazz:Class):* + { + var injectionPoint : InjectionPoint = m_constructorInjectionPoints[clazz]; + if (!injectionPoint) + { + getInjectionPoints(clazz); + injectionPoint = m_constructorInjectionPoints[clazz]; + } + var instance : * = injectionPoint.applyInjection(clazz, this); + injectInto(instance); + return instance; + } + + public function unmap(clazz : Class, named : String = "") : void + { + var mapping : InjectionConfig = getConfigurationForRequest(clazz, named); + if (!mapping) + { + throw new InjectorError('Error while removing an injector mapping: ' + + 'No mapping defined for class ' + getQualifiedClassName(clazz) + + ', named "' + named + '"'); + } + mapping.setResult(null); + } + + public function hasMapping(clazz : Class, named : String = '') : Boolean + { + var mapping : InjectionConfig = getConfigurationForRequest(clazz, named); + if (!mapping) + { + return false; + } + return mapping.hasResponse(this); + } + + public function getInstance(clazz : Class, named : String = '') : * + { + var mapping : InjectionConfig = getConfigurationForRequest(clazz, named); + if (!mapping || !mapping.hasResponse(this)) + { + throw new InjectorError('Error while getting mapping response: ' + + 'No mapping defined for class ' + getQualifiedClassName(clazz) + + ', named "' + named + '"'); + } + return mapping.getResponse(this); + } + + public function createChildInjector(applicationDomain:ApplicationDomain=null) : Injector + { + var injector : Injector = new Injector(); + injector.setApplicationDomain(applicationDomain); + injector.setParentInjector(this); + return injector; + } + + public function setApplicationDomain(applicationDomain:ApplicationDomain):void + { + m_applicationDomain = applicationDomain; + } + + public function getApplicationDomain():ApplicationDomain + { + return m_applicationDomain ? m_applicationDomain : ApplicationDomain.currentDomain; + } + + public function setParentInjector(parentInjector : Injector) : void + { + //restore own map of worked injectees if parent injector is removed + if (m_parentInjector && !parentInjector) + { + m_attendedToInjectees = new Dictionary(true); + } + m_parentInjector = parentInjector; + //use parent's map of worked injectees + if (parentInjector) + { + m_attendedToInjectees = parentInjector.attendedToInjectees; + } + } + + public function getParentInjector() : Injector + { + return m_parentInjector; + } + + + /******************************************************************************************* + * internal methods * + *******************************************************************************************/ + internal function getAncestorMapping( + whenAskedFor : Class, named : String = null) : InjectionConfig + { + var parent : Injector = m_parentInjector; + while (parent) + { + var parentConfig : InjectionConfig = + parent.getConfigurationForRequest(whenAskedFor, named, false); + if (parentConfig && parentConfig.hasOwnResponse()) + { + return parentConfig; + } + parent = parent.getParentInjector(); + } + return null; + } + + internal function get attendedToInjectees() : Dictionary + { + return m_attendedToInjectees; + } + + + /******************************************************************************************* + * private methods * + *******************************************************************************************/ + private function getInjectionPoints(clazz : Class) : Array + { + var description : XML = describeType(clazz); + var injectionPoints : Array = []; + m_injectionPointLists[clazz] = injectionPoints; + m_injectionPointLists[description.@name.toString()] = injectionPoints; + var node : XML; + + // This is where we have to wire in the XML... + if(m_xmlMetadata) + { + createInjectionPointsFromConfigXML(description); + addParentInjectionPoints(description, injectionPoints); + } + + var injectionPoint : InjectionPoint; + //get constructor injections + node = description.factory.constructor[0]; + if (node) + { + m_constructorInjectionPoints[clazz] = + new ConstructorInjectionPoint(node, clazz, this); + } + else + { + m_constructorInjectionPoints[clazz] = new NoParamsConstructorInjectionPoint(); + } + //get injection points for variables + for each (node in description.factory.*. + (name() == 'variable' || name() == 'accessor').metadata.(@name == 'Inject')) + { + injectionPoint = new PropertyInjectionPoint(node, this); + injectionPoints.push(injectionPoint); + } + + //get injection points for methods + for each (node in description.factory.method.metadata.(@name == 'Inject')) + { + injectionPoint = new MethodInjectionPoint(node, this); + injectionPoints.push(injectionPoint); + } + + //get post construct methods + var postConstructMethodPoints : Array = []; + for each (node in description.factory.method.metadata.(@name == 'PostConstruct')) + { + injectionPoint = new PostConstructInjectionPoint(node, this); + postConstructMethodPoints.push(injectionPoint); + } + if (postConstructMethodPoints.length > 0) + { + postConstructMethodPoints.sortOn("order", Array.NUMERIC); + injectionPoints.push.apply(injectionPoints, postConstructMethodPoints); + } + + return injectionPoints; + } + + private function getConfigurationForRequest( + clazz : Class, named : String, traverseAncestors : Boolean = true) : InjectionConfig + { + var requestName : String = getQualifiedClassName(clazz); + var config:InjectionConfig = m_mappings[requestName + '#' + named]; + if(!config && traverseAncestors && + m_parentInjector && m_parentInjector.hasMapping(clazz, named)) + { + config = getAncestorMapping(clazz, named); + } + return config; + } + + private function createInjectionPointsFromConfigXML(description : XML) : void + { + var node : XML; + //first, clear out all "Inject" metadata, we want a clean slate to have the result + //work the same in the Flash IDE and MXMLC + for each (node in description..metadata.(@name=='Inject' || @name=='PostConstruct')) + { + delete node.parent().metadata.(@name=='Inject' || @name=='PostConstruct')[0]; + } + + //now, we create the new injection points based on the given xml file + var className:String = description.factory.@type; + for each (node in m_xmlMetadata.type.(@name == className).children()) + { + var metaNode : XML = ; + if (node.name() == 'postconstruct') + { + metaNode.@name = 'PostConstruct'; + if (node.@order.length()) + { + metaNode.appendChild(); + } + } + else + { + metaNode.@name = 'Inject'; + if (node.@injectionname.length()) + { + metaNode.appendChild(); + } + for each (var arg : XML in node.arg) + { + metaNode.appendChild(); + } + } + var typeNode : XML; + if (node.name() == 'constructor') + { + typeNode = description.factory[0]; + } + else + { + typeNode = description.factory.*.(attribute('name') == node.@name)[0]; + if (!typeNode) + { + throw new InjectorError('Error in XML configuration: Class "' + className + + '" doesn\'t contain the instance member "' + node.@name + '"'); + } + } + typeNode.appendChild(metaNode); + } + } + + private function addParentInjectionPoints(description : XML, injectionPoints : Array) : void + { + var parentClassName : String = description.factory.extendsClass.@type[0]; + if (!parentClassName) + { + return; + } + var parentInjectionPoints : Array = m_injectionPointLists[parentClassName] || + getInjectionPoints(Class(getDefinitionByName(parentClassName))); + injectionPoints.push.apply(injectionPoints, parentInjectionPoints); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectorError.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectorError.as new file mode 100644 index 0000000..94ad2fd --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/InjectorError.as @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2009 the original author or authors +* +* Permission is hereby granted to use, modify, and distribute this file +* in accordance with the terms of the license agreement accompanying it. +*/ + +package org.swiftsuspenders +{ + public class InjectorError extends Error + { + public function InjectorError(message:*="", id:*=0) + { + super(message, id); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/Reflector.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/Reflector.as new file mode 100644 index 0000000..afb1d33 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/Reflector.as @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders +{ + import flash.system.ApplicationDomain; + import flash.utils.describeType; + import flash.utils.getDefinitionByName; + import flash.utils.getQualifiedClassName; + + /** + * @author tschneidereit + */ + public class Reflector + { + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function Reflector() + { + } + + public function classExtendsOrImplements(classOrClassName : Object, + superclass : Class, application : ApplicationDomain = null) : Boolean + { + var actualClass : Class; + + if (classOrClassName is Class) + { + actualClass = Class(classOrClassName); + } + else if (classOrClassName is String) + { + try + { + actualClass = Class(getDefinitionByName(classOrClassName as String)); + } + catch (e : Error) + { + throw new Error("The class name " + classOrClassName + + " is not valid because of " + e + "\n" + e.getStackTrace()); + } + } + + if (!actualClass) + { + throw new Error("The parameter classOrClassName must be a valid Class " + + "instance or fully qualified class name."); + } + + if (actualClass == superclass) + return true; + + var factoryDescription : XML = describeType(actualClass).factory[0]; + + return (factoryDescription.children().( + name() == "implementsInterface" || name() == "extendsClass").( + attribute("type") == getQualifiedClassName(superclass)).length() > 0); + } + + public function getClass(value : *, applicationDomain : ApplicationDomain = null) : Class + { + if (value is Class) + { + return value; + } + return getConstructor(value); + } + + public function getFQCN(value : *, replaceColons : Boolean = false) : String + { + var fqcn:String; + if (value is String) + { + fqcn = value; + // Add colons if missing and desired. + if (!replaceColons && fqcn.indexOf('::') == -1) + { + var lastDotIndex:int = fqcn.lastIndexOf('.'); + if (lastDotIndex == -1) return fqcn; + return fqcn.substring(0, lastDotIndex) + '::' + fqcn.substring(lastDotIndex + 1); + } + } + else + { + fqcn = getQualifiedClassName(value); + } + return replaceColons ? fqcn.replace('::', '.') : fqcn; + } + } +} diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/getConstructor.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/getConstructor.as new file mode 100644 index 0000000..266166e --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/getConstructor.as @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders +{ + import flash.utils.Proxy; + import flash.utils.getDefinitionByName; + import flash.utils.getQualifiedClassName; + + internal function getConstructor(value : Object) : Class + { + /* + There are several types for which the 'constructor' property doesn't work: + - instances of Proxy, XML and XMLList throw exceptions when trying to access 'constructor' + - int and uint return Number as their constructor + For these, we have to fall back to more verbose ways of getting the constructor. + + Additionally, Vector instances always return Vector.<*> when queried for their constructor. + Ideally, that would also be resolved, but the SwiftSuspenders wouldn't be compatible with + Flash Player < 10, anymore. + */ + if (value is Proxy || value is Number || value is XML || value is XMLList) + { + var fqcn : String = getQualifiedClassName(value); + return Class(getDefinitionByName(fqcn)); + } + return value.constructor; + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/ConstructorInjectionPoint.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/ConstructorInjectionPoint.as new file mode 100644 index 0000000..4369195 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/ConstructorInjectionPoint.as @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2009 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders.injectionpoints +{ + import flash.utils.describeType; + + import org.swiftsuspenders.Injector; + + public class ConstructorInjectionPoint extends MethodInjectionPoint + { + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function ConstructorInjectionPoint(node : XML, clazz : Class, injector : Injector) + { + /* + In many cases, the flash player doesn't give us type information for constructors until + the class has been instantiated at least once. Therefore, we do just that if we don't get + type information for at least one parameter. + */ + if (node.parameter.(@type == '*').length() == node.parameter.@type.length()) + { + createDummyInstance(node, clazz); + } + super(node, injector); + } + + override public function applyInjection(target : Object, injector : Injector) : Object + { + var p : Array = gatherParameterValues(target, injector); + //the only way to implement ctor injections, really! + switch (p.length) + { + case 0 : return (new target()); + case 1 : return (new target(p[0])); + case 2 : return (new target(p[0], p[1])); + case 3 : return (new target(p[0], p[1], p[2])); + case 4 : return (new target(p[0], p[1], p[2], p[3])); + case 5 : return (new target(p[0], p[1], p[2], p[3], p[4])); + case 6 : return (new target(p[0], p[1], p[2], p[3], p[4], p[5])); + case 7 : return (new target(p[0], p[1], p[2], p[3], p[4], p[5], p[6])); + case 8 : return (new target(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7])); + case 9 : return (new target(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8])); + case 10 : return (new target(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9])); + } + return null; + } + + /******************************************************************************************* + * protected methods * + *******************************************************************************************/ + override protected function initializeInjection(node : XML, injector : Injector) : void + { + var nameArgs : XMLList = node.parent().metadata.(@name == 'Inject').arg.(@key == 'name'); + methodName = 'constructor'; + + gatherParameters(node, nameArgs, injector); + } + + /******************************************************************************************* + * private methods * + *******************************************************************************************/ + private function createDummyInstance(constructorNode : XML, clazz : Class) : void + { + try + { + switch (constructorNode.children().length()) + { + case 0 : (new clazz()); break; + case 1 : (new clazz(null)); break; + case 2 : (new clazz(null, null)); break; + case 3 : (new clazz(null, null, null)); break; + case 4 : (new clazz(null, null, null, null)); break; + case 5 : (new clazz(null, null, null, null, null)); break; + case 6 : (new clazz(null, null, null, null, null, null)); break; + case 7 : (new clazz(null, null, null, null, null, null, null)); break; + case 8 : (new clazz(null, null, null, null, null, null, null, null)); break; + case 9 : (new clazz(null, null, null, null, null, null, null, null, null)); break; + case 10 : (new clazz(null, null, null, null, null, null, null, null, null, null)); break; + } + } + catch (error : Error) + { + trace(error); + } + constructorNode.setChildren(describeType(clazz).factory.constructor[0].children()); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/InjectionPoint.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/InjectionPoint.as new file mode 100644 index 0000000..681e55c --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/InjectionPoint.as @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2009 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders.injectionpoints +{ + import org.swiftsuspenders.Injector; + + public class InjectionPoint + { + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function InjectionPoint(node : XML, injector : Injector) + { + initializeInjection(node, injector); + } + + public function applyInjection(target : Object, injector : Injector) : Object + { + return target; + } + + + /******************************************************************************************* + * protected methods * + *******************************************************************************************/ + protected function initializeInjection(node : XML, injector : Injector) : void + { + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/MethodInjectionPoint.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/MethodInjectionPoint.as new file mode 100644 index 0000000..c716295 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/MethodInjectionPoint.as @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2009 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders.injectionpoints +{ + import flash.utils.getDefinitionByName; + import flash.utils.getQualifiedClassName; + + import org.swiftsuspenders.InjectionConfig; + import org.swiftsuspenders.Injector; + import org.swiftsuspenders.InjectorError; + + public class MethodInjectionPoint extends InjectionPoint + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + protected var methodName : String; + protected var m_injectionConfigs : Array; + protected var requiredParameters : int = 0; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function MethodInjectionPoint(node : XML, injector : Injector) + { + super(node, injector); + } + + override public function applyInjection(target : Object, injector : Injector) : Object + { + var parameters : Array = gatherParameterValues(target, injector); + var method : Function = target[methodName]; + method.apply(target, parameters); + return target; + } + + + /******************************************************************************************* + * protected methods * + *******************************************************************************************/ + override protected function initializeInjection(node : XML, injector : Injector) : void + { + var nameArgs : XMLList = node.arg.(@key == 'name'); + var methodNode : XML = node.parent(); + methodName = methodNode.@name.toString(); + + gatherParameters(methodNode, nameArgs, injector); + } + + protected function gatherParameters( + methodNode : XML, nameArgs : XMLList, injector : Injector) : void + { + m_injectionConfigs = []; + var i : int = 0; + for each (var parameter : XML in methodNode.parameter) + { + var injectionName : String = ''; + if (nameArgs[i]) + { + injectionName = nameArgs[i].@value.toString(); + } + var parameterTypeName : String = parameter.@type.toString(); + var parameterType : Class; + if (parameterTypeName == '*') + { + if (parameter.@optional.toString() == 'false') + { + //TODO: Find a way to trace name of affected class here + throw new Error('Error in method definition of injectee. Required ' + + 'parameters can\'t have type "*".'); + } + else + { + parameterTypeName = null; + } + } + else + { + parameterType = Class(injector.getApplicationDomain().getDefinition(parameterTypeName)); + } + m_injectionConfigs.push(injector.getMapping(parameterType, injectionName)); + if (parameter.@optional.toString() == 'false') + { + requiredParameters++; + } + i++; + } + } + + protected function gatherParameterValues(target : Object, injector : Injector) : Array + { + var parameters : Array = []; + var length : int = m_injectionConfigs.length; + for (var i : int = 0; i < length; i++) + { + var config : InjectionConfig = m_injectionConfigs[i]; + var injection : Object = config.getResponse(injector); + if (injection == null) + { + if (i >= requiredParameters) + { + break; + } + throw(new InjectorError( + 'Injector is missing a rule to handle injection into target ' + target + + '. Target dependency: ' + getQualifiedClassName(config.request) + + ', method: ' + methodName + ', parameter: ' + (i + 1) + )); + } + + parameters[i] = injection; + } + return parameters; + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/NoParamsConstructorInjectionPoint.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/NoParamsConstructorInjectionPoint.as new file mode 100644 index 0000000..4aa6066 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/NoParamsConstructorInjectionPoint.as @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders.injectionpoints +{ + import org.swiftsuspenders.Injector; + + public class NoParamsConstructorInjectionPoint extends InjectionPoint + { + public function NoParamsConstructorInjectionPoint() + { + super(null, null); + } + + override public function applyInjection(target : Object, injector : Injector) : Object + { + return new target(); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/PostConstructInjectionPoint.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/PostConstructInjectionPoint.as new file mode 100644 index 0000000..d7f45f2 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/PostConstructInjectionPoint.as @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2009 the original author or authors +* +* Permission is hereby granted to use, modify, and distribute this file +* in accordance with the terms of the license agreement accompanying it. +*/ + +package org.swiftsuspenders.injectionpoints +{ + import org.swiftsuspenders.Injector; + + public class PostConstructInjectionPoint extends InjectionPoint + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + protected var methodName : String; + protected var orderValue:int; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function PostConstructInjectionPoint(node:XML, injector : Injector) + { + super(node, injector); + } + + public function get order():int + { + return orderValue; + } + + override public function applyInjection(target : Object, injector : Injector) : Object + { + target[methodName](); + return target; + } + + + /******************************************************************************************* + * protected methods * + *******************************************************************************************/ + override protected function initializeInjection(node : XML, injector : Injector) : void + { + var orderArg : XMLList = node.arg.(@key == 'order'); + var methodNode : XML = node.parent(); + orderValue = int(orderArg.@value); + methodName = methodNode.@name.toString(); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as new file mode 100644 index 0000000..d7a3405 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders.injectionpoints +{ + import flash.utils.getDefinitionByName; + + import org.swiftsuspenders.InjectionConfig; + import org.swiftsuspenders.Injector; + import org.swiftsuspenders.InjectorError; + + public class PropertyInjectionPoint extends InjectionPoint + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + private var propertyName : String; + private var propertyType : String; + private var m_injectionConfig : InjectionConfig; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function PropertyInjectionPoint(node : XML, injector : Injector) + { + super(node, injector); + } + + override public function applyInjection(target : Object, injector : Injector) : Object + { + var injection : Object = m_injectionConfig.getResponse(injector); + if (injection == null) + { + throw( + new InjectorError( + 'Injector is missing a rule to handle injection into target ' + target + + '. Target dependency: ' + propertyType + ) + ); + } + target[propertyName] = injection; + return target; + } + + + /******************************************************************************************* + * protected methods * + *******************************************************************************************/ + override protected function initializeInjection(node : XML, injector : Injector) : void + { + propertyType = node.parent().@type.toString(); + propertyName = node.parent().@name.toString(); + m_injectionConfig = injector.getMapping(Class(injector.getApplicationDomain().getDefinition(propertyType)), + node.arg.attribute('value').toString()); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectClassResult.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectClassResult.as new file mode 100644 index 0000000..06cea28 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectClassResult.as @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2009 the original author or authors +* +* Permission is hereby granted to use, modify, and distribute this file +* in accordance with the terms of the license agreement accompanying it. +*/ + +package org.swiftsuspenders.injectionresults +{ + import org.swiftsuspenders.Injector; + + public class InjectClassResult extends InjectionResult + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + private var m_responseType : Class; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function InjectClassResult(responseType : Class) + { + m_responseType = responseType; + } + + override public function getResponse(injector : Injector) : Object + { + return injector.instantiate(m_responseType); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectOtherRuleResult.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectOtherRuleResult.as new file mode 100644 index 0000000..ecdeea0 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectOtherRuleResult.as @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders.injectionresults +{ + import org.swiftsuspenders.InjectionConfig; + import org.swiftsuspenders.Injector; + + public class InjectOtherRuleResult extends InjectionResult + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + private var m_rule : InjectionConfig; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function InjectOtherRuleResult(rule : InjectionConfig) + { + m_rule = rule; + } + + override public function getResponse(injector : Injector) : Object + { + return m_rule.getResponse(injector); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectSingletonResult.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectSingletonResult.as new file mode 100644 index 0000000..4a371ad --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectSingletonResult.as @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2009 the original author or authors +* +* Permission is hereby granted to use, modify, and distribute this file +* in accordance with the terms of the license agreement accompanying it. +*/ + +package org.swiftsuspenders.injectionresults +{ + import org.swiftsuspenders.Injector; + + public class InjectSingletonResult extends InjectionResult + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + private var m_responseType : Class; + private var m_response : Object; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function InjectSingletonResult(responseType : Class) + { + m_responseType = responseType; + } + + override public function getResponse(injector : Injector) : Object + { + return m_response ||= createResponse(injector); + } + + + /******************************************************************************************* + * private methods * + *******************************************************************************************/ + private function createResponse(injector : Injector) : Object + { + return injector.instantiate(m_responseType); + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectValueResult.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectValueResult.as new file mode 100644 index 0000000..e31a339 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectValueResult.as @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2009 the original author or authors +* +* Permission is hereby granted to use, modify, and distribute this file +* in accordance with the terms of the license agreement accompanying it. +*/ + +package org.swiftsuspenders.injectionresults +{ + import org.swiftsuspenders.Injector; + + public class InjectValueResult extends InjectionResult + { + /******************************************************************************************* + * private properties * + *******************************************************************************************/ + private var m_value : Object; + + + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function InjectValueResult(value : Object) + { + m_value = value; + } + + override public function getResponse(injector : Injector) : Object + { + return m_value; + } + } +} \ No newline at end of file diff --git a/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectionResult.as b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectionResult.as new file mode 100644 index 0000000..db56073 --- /dev/null +++ b/asunit-4.0/vendor/as3injection/org/swiftsuspenders/injectionresults/InjectionResult.as @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 the original author or authors + * + * Permission is hereby granted to use, modify, and distribute this file + * in accordance with the terms of the license agreement accompanying it. + */ + +package org.swiftsuspenders.injectionresults +{ + import org.swiftsuspenders.Injector; + + public class InjectionResult + { + /******************************************************************************************* + * public methods * + *******************************************************************************************/ + public function InjectionResult() + { + } + + public function getResponse(injector : Injector) : Object + { + return null; + } + } +} \ No newline at end of file