From: <i_t...@us...> - 2008-07-12 18:31:38
|
Revision: 191 http://asunit.svn.sourceforge.net/asunit/?rev=191&view=rev Author: i_tyrrell Date: 2008-07-12 11:31:34 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Applied patch to allow multiple Asynchronous operations to occur within each test method or setup. Tidied code to reduce FDT errors/warnings. Modified Paths: -------------- branches/ityrrell/framework/as3/asunit/framework/Assert.as branches/ityrrell/framework/as3/asunit/framework/AsynchronousTestCase.as branches/ityrrell/framework/as3/asunit/framework/TestCase.as branches/ityrrell/framework/as3/asunit/textui/ResultPrinter.as branches/ityrrell/framework/as3/asunit/textui/TestRunner.as branches/ityrrell/framework/as3/asunit/textui/XMLResultPrinter.as branches/ityrrell/framework-test/as3/asunit/framework/AssertTest.as branches/ityrrell/framework-test/as3/asunit/framework/AsyncMethodTest.as branches/ityrrell/framework-test/as3/asunit/framework/TestCaseMock.as branches/ityrrell/framework-test/as3/asunit/framework/TestCaseTest.as branches/ityrrell/framework-test/as3/asunit/textui/TestRunnerTest.as Added Paths: ----------- branches/ityrrell/framework-test/as3/asunit/framework/AllTests.as Property Changed: ---------------- branches/ityrrell/ Property changes on: branches/ityrrell ___________________________________________________________________ Name: svn:ignore + .settings .as3_classpath .project bin Modified: branches/ityrrell/framework/as3/asunit/framework/Assert.as =================================================================== --- branches/ityrrell/framework/as3/asunit/framework/Assert.as 2008-07-12 17:39:57 UTC (rev 190) +++ branches/ityrrell/framework/as3/asunit/framework/Assert.as 2008-07-12 18:31:34 UTC (rev 191) @@ -1,271 +1,270 @@ -package asunit.framework { - import asunit.errors.AssertionFailedError; - - import flash.errors.IllegalOperationError; - import flash.events.EventDispatcher; - import flash.utils.Proxy; - - /** - * A set of assert methods. Messages are only displayed when an assert fails. - */ - - public class Assert extends EventDispatcher { - /** - * Protect constructor since it is a static only class - */ - public function Assert() { - } - - /** - * Asserts that a condition is true. If it isn't it throws - * an AssertionFailedError with the given message. - */ - static public function assertTrue(...args:Array):void { - var message:String; - var condition:Boolean; - - if(args.length == 1) { - message = ""; - condition = Boolean(args[0]); - } - else if(args.length == 2) { - message = args[0]; - condition = Boolean(args[1]); - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - - if(!condition) { - fail(message); - } - } - /** - * Asserts that a condition is false. If it isn't it throws - * an AssertionFailedError with the given message. - */ - static public function assertFalse(...args:Array):void { - var message:String; - var condition:Boolean; - - if(args.length == 1) { - message = ""; - condition = Boolean(args[0]); - } - else if(args.length == 2) { - message = args[0]; - condition = Boolean(args[1]); - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - - assertTrue(message, !condition); - } - /** - * Fails a test with the given message. - */ - static public function fail(message:String):void { - throw new AssertionFailedError(message); - } - /** - * Asserts that two objects are equal. If they are not - * an AssertionFailedError is thrown with the given message. - */ - static public function assertEquals(...args:Array):void { - var message:String; - var expected:Object; - var actual:Object; - - if(args.length == 2) { - message = ""; - expected = args[0]; - actual = args[1]; - } - else if(args.length == 3) { - message = args[0]; - expected = args[1]; - actual = args[2]; - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - - if(expected == null && actual == null) { - return; - } - - try { - if(expected != null && expected.equals(actual)) { - return; - } - } - catch(e:Error) { - if(expected != null && expected == actual) { - return; - } - } - - failNotEquals(message, expected, actual); - } - /** - * Asserts that an object isn't null. If it is - * an AssertionFailedError is thrown with the given message. - */ - static public function assertNotNull(...args:Array):void { - var message:String; - var object:Object; - - if(args.length == 1) { - message = ""; - object = args[0]; - } - else if(args.length == 2) { - message = args[0]; - object = args[1]; - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - - assertTrue(message, object != null); - } - /** - * Asserts that an object is null. If it is not - * an AssertionFailedError is thrown with the given message. - */ - static public function assertNull(...args:Array):void { - var message:String; - var object:Object; - - if(args.length == 1) { - message = ""; - object = args[0]; - } - else if(args.length == 2) { - message = args[0]; - object = args[1]; - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - - assertTrue(message, object == null); - } - /** - * Asserts that two objects refer to the same object. If they are not - * an AssertionFailedError is thrown with the given message. - */ - static public function assertSame(...args:Array):void { - var message:String; - var expected:Object; - var actual:Object; - - if(args.length == 2) { - message = ""; - expected = args[0]; - actual = args[1]; - } - else if(args.length == 3) { - message = args[0]; - expected = args[1]; - actual = args[2]; - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - - if(expected === actual) { - return; - } - failNotSame(message, expected, actual); - } - /** - * Asserts that two objects do not refer to the same object. If they do, - * an AssertionFailedError is thrown with the given message. - */ - static public function assertNotSame(...args:Array):void { - var message:String; - var expected:Object; - var actual:Object; - - if(args.length == 2) { - message = ""; - expected = args[0]; - actual = args[1]; - } - else if(args.length == 3) { - message = args[0]; - expected = args[1]; - actual = args[2]; - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - - if(expected === actual) - failSame(message); - } - - /** - * Asserts that two numerical values are equal within a tolerance range. - * If they are not an AssertionFailedError is thrown with the given message. - */ - static public function assertEqualsFloat(...args:Array):void { - var message:String; - var expected:Number; - var actual:Number; - var tolerance:Number = 0; - - if(args.length == 3) { - message = ""; - expected = args[0]; - actual = args[1]; - tolerance = args[2]; - } - else if(args.length == 4) { - message = args[0]; - expected = args[1]; - actual = args[2]; - tolerance = args[3]; - } - else { - throw new IllegalOperationError("Invalid argument count"); - } - if (isNaN(tolerance)) tolerance = 0; - if(Math.abs(expected - actual) <= tolerance) { - return; - } - failNotEquals(message, expected, actual); - } - - - static private function failSame(message:String):void { - var formatted:String = ""; - if(message != null) { - formatted = message + " "; - } - fail(formatted + "expected not same"); - } - - static private function failNotSame(message:String, expected:Object, actual:Object):void { - var formatted:String = ""; - if(message != null) { - formatted = message + " "; - } - fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">"); - } - - static private function failNotEquals(message:String, expected:Object, actual:Object):void { - fail(format(message, expected, actual)); - } - - static private function format(message:String, expected:Object, actual:Object):String { - var formatted:String = ""; - if(message != null) { - formatted = message + " "; - } - return formatted + "expected:<" + expected + "> but was:<" + actual + ">"; - } - } -} \ No newline at end of file +package asunit.framework { + import asunit.errors.AssertionFailedError; + + import flash.errors.IllegalOperationError; + import flash.events.EventDispatcher; + + /** + * A set of assert methods. Messages are only displayed when an assert fails. + */ + + public class Assert extends EventDispatcher { + /** + * Protect constructor since it is a static only class + */ + public function Assert() { + } + + /** + * Asserts that a condition is true. If it isn't it throws + * an AssertionFailedError with the given message. + */ + static public function assertTrue(...args:Array):void { + var message:String; + var condition:Boolean; + + if(args.length == 1) { + message = ""; + condition = Boolean(args[0]); + } + else if(args.length == 2) { + message = args[0]; + condition = Boolean(args[1]); + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + if(!condition) { + fail(message); + } + } + /** + * Asserts that a condition is false. If it isn't it throws + * an AssertionFailedError with the given message. + */ + static public function assertFalse(...args:Array):void { + var message:String; + var condition:Boolean; + + if(args.length == 1) { + message = ""; + condition = Boolean(args[0]); + } + else if(args.length == 2) { + message = args[0]; + condition = Boolean(args[1]); + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + assertTrue(message, !condition); + } + /** + * Fails a test with the given message. + */ + static public function fail(message:String):void { + throw new AssertionFailedError(message); + } + /** + * Asserts that two objects are equal. If they are not + * an AssertionFailedError is thrown with the given message. + */ + static public function assertEquals(...args:Array):void { + var message:String; + var expected:Object; + var actual:Object; + + if(args.length == 2) { + message = ""; + expected = args[0]; + actual = args[1]; + } + else if(args.length == 3) { + message = args[0]; + expected = args[1]; + actual = args[2]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + if(expected == null && actual == null) { + return; + } + + try { + if(expected != null && expected.equals(actual)) { + return; + } + } + catch(e:Error) { + if(expected != null && expected == actual) { + return; + } + } + + failNotEquals(message, expected, actual); + } + /** + * Asserts that an object isn't null. If it is + * an AssertionFailedError is thrown with the given message. + */ + static public function assertNotNull(...args:Array):void { + var message:String; + var object:Object; + + if(args.length == 1) { + message = ""; + object = args[0]; + } + else if(args.length == 2) { + message = args[0]; + object = args[1]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + assertTrue(message, object != null); + } + /** + * Asserts that an object is null. If it is not + * an AssertionFailedError is thrown with the given message. + */ + static public function assertNull(...args:Array):void { + var message:String; + var object:Object; + + if(args.length == 1) { + message = ""; + object = args[0]; + } + else if(args.length == 2) { + message = args[0]; + object = args[1]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + assertTrue(message, object == null); + } + /** + * Asserts that two objects refer to the same object. If they are not + * an AssertionFailedError is thrown with the given message. + */ + static public function assertSame(...args:Array):void { + var message:String; + var expected:Object; + var actual:Object; + + if(args.length == 2) { + message = ""; + expected = args[0]; + actual = args[1]; + } + else if(args.length == 3) { + message = args[0]; + expected = args[1]; + actual = args[2]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + if(expected === actual) { + return; + } + failNotSame(message, expected, actual); + } + /** + * Asserts that two objects do not refer to the same object. If they do, + * an AssertionFailedError is thrown with the given message. + */ + static public function assertNotSame(...args:Array):void { + var message:String; + var expected:Object; + var actual:Object; + + if(args.length == 2) { + message = ""; + expected = args[0]; + actual = args[1]; + } + else if(args.length == 3) { + message = args[0]; + expected = args[1]; + actual = args[2]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + if(expected === actual) + failSame(message); + } + + /** + * Asserts that two numerical values are equal within a tolerance range. + * If they are not an AssertionFailedError is thrown with the given message. + */ + static public function assertEqualsFloat(...args:Array):void { + var message:String; + var expected:Number; + var actual:Number; + var tolerance:Number = 0; + + if(args.length == 3) { + message = ""; + expected = args[0]; + actual = args[1]; + tolerance = args[2]; + } + else if(args.length == 4) { + message = args[0]; + expected = args[1]; + actual = args[2]; + tolerance = args[3]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + if (isNaN(tolerance)) tolerance = 0; + if(Math.abs(expected - actual) <= tolerance) { + return; + } + failNotEquals(message, expected, actual); + } + + + static private function failSame(message:String):void { + var formatted:String = ""; + if(message != null) { + formatted = message + " "; + } + fail(formatted + "expected not same"); + } + + static private function failNotSame(message:String, expected:Object, actual:Object):void { + var formatted:String = ""; + if(message != null) { + formatted = message + " "; + } + fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">"); + } + + static private function failNotEquals(message:String, expected:Object, actual:Object):void { + fail(format(message, expected, actual)); + } + + static private function format(message:String, expected:Object, actual:Object):String { + var formatted:String = ""; + if(message != null) { + formatted = message + " "; + } + return formatted + "expected:<" + expected + "> but was:<" + actual + ">"; + } + } +} Modified: branches/ityrrell/framework/as3/asunit/framework/AsynchronousTestCase.as =================================================================== --- branches/ityrrell/framework/as3/asunit/framework/AsynchronousTestCase.as 2008-07-12 17:39:57 UTC (rev 190) +++ branches/ityrrell/framework/as3/asunit/framework/AsynchronousTestCase.as 2008-07-12 18:31:34 UTC (rev 191) @@ -1,52 +1,51 @@ -package asunit.framework { - import flash.net.URLRequest; - import flash.net.URLLoader; - import flash.events.*; - import flash.errors.IllegalOperationError; - - /** - * Extend this class if you have a TestCase that requires the - * asynchronous load of external data. - */ - public class AsynchronousTestCase extends TestCase { - - public function AsynchronousTestCase(testMethod:String = null) { - super(testMethod); - } - - protected function configureListeners(loader:URLLoader):void { - loader.addEventListener(Event.COMPLETE, completeHandler); - loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler); - loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); - loader.addEventListener(Event.OPEN, openHandler); - loader.addEventListener(ProgressEvent.PROGRESS, progressHandler); - loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); - } - - // override this method and implement your own completeHandler - // you should be sure to call super.run() from the body of - // this override. - protected function completeHandler(event:Event):void { - } - - // TODO: add support for failing status events... - protected function httpStatusHandler(event:HTTPStatusEvent):void { - } - - protected function ioErrorHandler(event:IOErrorEvent):void { - result.addError(this, new IllegalOperationError(event.toString())); - isComplete = true; - } - - protected function openHandler(event:Event):void { - } - - protected function progressHandler(event:ProgressEvent):void { - } - - protected function securityErrorHandler(event:SecurityErrorEvent):void { - result.addError(this, new IllegalOperationError(event.toString())); - isComplete = true; - } - } -} \ No newline at end of file +package asunit.framework { + import flash.net.URLLoader; + import flash.events.*; + import flash.errors.IllegalOperationError; + + /** + * Extend this class if you have a TestCase that requires the + * asynchronous load of external data. + */ + public class AsynchronousTestCase extends TestCase { + + public function AsynchronousTestCase(testMethod:String = null) { + super(testMethod); + } + + protected function configureListeners(loader:URLLoader):void { + loader.addEventListener(Event.COMPLETE, completeHandler); + loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler); + loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); + loader.addEventListener(Event.OPEN, openHandler); + loader.addEventListener(ProgressEvent.PROGRESS, progressHandler); + loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); + } + + // override this method and implement your own completeHandler + // you should be sure to call super.run() from the body of + // this override. + protected function completeHandler(event:Event):void { + } + + // TODO: add support for failing status events... + protected function httpStatusHandler(event:HTTPStatusEvent):void { + } + + protected function ioErrorHandler(event:IOErrorEvent):void { + result.addError(this, new IllegalOperationError(event.toString())); + isComplete = true; + } + + protected function openHandler(event:Event):void { + } + + protected function progressHandler(event:ProgressEvent):void { + } + + protected function securityErrorHandler(event:SecurityErrorEvent):void { + result.addError(this, new IllegalOperationError(event.toString())); + isComplete = true; + } + } +} Modified: branches/ityrrell/framework/as3/asunit/framework/TestCase.as =================================================================== --- branches/ityrrell/framework/as3/asunit/framework/TestCase.as 2008-07-12 17:39:57 UTC (rev 190) +++ branches/ityrrell/framework/as3/asunit/framework/TestCase.as 2008-07-12 18:31:34 UTC (rev 191) @@ -1,386 +1,372 @@ -package asunit.framework { - import asunit.errors.AssertionFailedError; - import asunit.util.ArrayIterator; - import asunit.util.Iterator; - - import flash.display.DisplayObject; - import flash.display.DisplayObjectContainer; - import flash.errors.IllegalOperationError; - import flash.events.Event; - import flash.events.TimerEvent; - import flash.utils.Timer; - import flash.utils.describeType; - import flash.utils.getDefinitionByName; - import flash.utils.setTimeout; - - /** - * A test case defines the fixture to run multiple tests. To define a test case<br> - * 1) implement a subclass of TestCase<br> - * 2) define instance variables that store the state of the fixture<br> - * 3) initialize the fixture state by overriding <code>setUp</code><br> - * 4) clean-up after a test by overriding <code>tearDown</code>.<br> - * Each test runs in its own fixture so there - * can be no side effects among test runs. - * Here is an example: - * <pre> - * public class MathTest extends TestCase { - * protected double fValue1; - * protected double fValue2; - * - * protected void setUp() { - * fValue1= 2.0; - * fValue2= 3.0; - * } - * } - * </pre> - * - * For each test implement a method which interacts - * with the fixture. Verify the expected results with assertions specified - * by calling <code>assertTrue</code> with a boolean. - * <pre> - * public void testAdd() { - * double result= fValue1 + fValue2; - * assertTrue(result == 5.0); - * } - * </pre> - * Once the methods are defined you can run them. The framework supports - * both a static type safe and more dynamic way to run a test. - * In the static way you override the runTest method and define the method to - * be invoked. A convenient way to do so is with an anonymous inner class. - * <pre> - * TestCase test= new MathTest("add") { - * public void runTest() { - * testAdd(); - * } - * }; - * test.run(); - * </pre> - * The dynamic way uses reflection to implement <code>runTest</code>. It dynamically finds - * and invokes a method. - * In this case the name of the test case has to correspond to the test method - * to be run. - * <pre> - * TestCase= new MathTest("testAdd"); - * test.run(); - * </pre> - * The tests to be run can be collected into a TestSuite. JUnit provides - * different <i>test runners</i> which can run a test suite and collect the results. - * A test runner either expects a static method <code>suite</code> as the entry - * point to get a test to run or it will extract the suite automatically. - * <pre> - * public static Test suite() { - * suite.addTest(new MathTest("testAdd")); - * suite.addTest(new MathTest("testDivideByZero")); - * return suite; - * } - * </pre> - * @see TestResult - * @see TestSuite - */ - public class TestCase extends Assert implements Test { - protected static const PRE_SET_UP:int = 0; - protected static const SET_UP:int = 1; - protected static const RUN_METHOD:int = 2; - protected static const TEAR_DOWN:int = 3; - protected static const DEFAULT_TIMEOUT:int = 1000; - protected var fName:String; - protected var result:TestListener; - protected var testMethods:Array; - protected var isComplete:Boolean; - protected var context:DisplayObjectContainer; - protected var methodIsAsynchronous:Boolean; - protected var timeout:Timer; - private var setUpIsAsynchronous:Boolean; - private var currentMethod:String; - private var runSingle:Boolean; - private var methodIterator:Iterator; - private var layoutManager:Object; - private var currentState:int; - - /** - * Constructs a test case with the given name. - */ - public function TestCase(testMethod:String = null) { - var description:XML = describeType(this); - var className:Object = description.@name; - var methods:XMLList = description..method.(@name.match("^test")); - if(testMethod != null) { - testMethods = testMethod.split(", ").join(",").split(","); - if(testMethods.length == 1) { - runSingle = true; - } - } else { - setTestMethods(methods); - } - setName(className.toString()); - resolveLayoutManager(); - } - - private function resolveLayoutManager():void { - // Avoid creating import dependencies on flex framework - // If you have the framework.swc in your classpath, - // the layout manager will be found, if not, a mcok - // will be used. - try { - var manager:Class = getDefinitionByName("mx.managers.LayoutManager") as Class; - layoutManager = manager["getInstance"](); - if(!layoutManager.hasOwnProperty("resetAll")) { - throw new Error("TestCase :: mx.managers.LayoutManager missing resetAll method"); - } - } - catch(e:Error) { - layoutManager = new Object(); - layoutManager.resetAll = function():void { - } - } - } - - /** - * Sets the name of a TestCase - * @param name The name to set - */ - public function setName(name:String):void { - fName = name; - } - - protected function setTestMethods(methodNodes:XMLList):void { - testMethods = new Array(); - var methodNames:Object = methodNodes.@name; - var name:String; - for each(var item:Object in methodNames) { - name = item.toString(); - testMethods.push(name); - } - } - - public function getTestMethods():Array { - return testMethods; - } - - /** - * Counts the number of test cases executed by run(TestResult result). - */ - public function countTestCases():int { - return testMethods.length; - } - - /** - * Creates a default TestResult object - * - * @see TestResult - */ - protected function createResult():TestResult { - return new TestResult(); - } - - /** - * A convenience method to run this test, collecting the results with - * either the TestResult provided or a default, new TestResult object. - * Expects either: - * run():void // will return the newly created TestResult - * run(result:TestResult):TestResult // will use the TestResult - * that was passed in. - * - * @see TestResult - */ - public function run():void { - getResult().run(this); - } - - public function setResult(result:TestListener):void { - this.result = result; - } - - protected function getResult():TestListener { - return (result == null) ? createResult() : result; - } - - /** - * Runs the bare test sequence. - * @exception Error if any exception is thrown - * throws Error - */ - public function runBare():void { - if(isComplete) { - return; - } - var name:String; - var itr:Iterator = getMethodIterator(); - if(itr.hasNext()) { - name = String(itr.next()); - currentState = PRE_SET_UP; - runMethod(name); - } - else { - cleanUp(); - getResult().endTest(this); - isComplete = true; - dispatchEvent(new Event(Event.COMPLETE)); - } - } - - private function getMethodIterator():Iterator { - if(methodIterator == null) { - methodIterator = new ArrayIterator(testMethods); - } - return methodIterator; - } - - // Override this method in Asynchronous test cases - // or any other time you want to perform additional - // member cleanup after all test methods have run - protected function cleanUp():void { - } - - private function runMethod(methodName:String):void { - try { - methodIsAsynchronous = false; - if(currentState == PRE_SET_UP) { - currentState = SET_UP; - getResult().startTestMethod(this, methodName); - setUp(); // setUp may be async and change the state of methodIsAsynchronous - } - currentMethod = methodName; - if(!methodIsAsynchronous) { - currentState = RUN_METHOD; - this[methodName](); - } - else { - setUpIsAsynchronous = true; - } - } - catch(assertionFailedError:AssertionFailedError) { - getResult().addFailure(this, assertionFailedError); - } - catch(unknownError:Error) { - getResult().addError(this, unknownError); - } - finally { - if(!methodIsAsynchronous) { - runTearDown(); - } - } - } - - /** - * Sets up the fixture, for example, instantiate a mock object. - * This method is called before each test is executed. - * throws Exception on error - */ - protected function setUp():void { - } - /** - * Tears down the fixture, for example, delete mock object. - * This method is called after a test is executed. - * throws Exception on error - */ - protected function tearDown():void { - } - /** - * Returns a string representation of the test case - */ - override public function toString():String { - if(getCurrentMethod()) { - return getName() + "." + getCurrentMethod() + "()"; - } - else { - return getName(); - } - } - /** - * Gets the name of a TestCase - * @return returns a String - */ - public function getName():String { - return fName; - } - - public function getCurrentMethod():String { - return currentMethod; - } - - public function getIsComplete():Boolean { - return isComplete; - } - - public function setContext(context:DisplayObjectContainer):void { - this.context = context; - } - - public function getContext():DisplayObjectContainer { - return context; - } - - protected function addAsync(handler:Function = null, duration:Number=DEFAULT_TIMEOUT):Function { - if(handler == null) { - handler = function(args:*):* {}; - } - methodIsAsynchronous = true; - timeout = new Timer(duration, 1); - timeout.addEventListener(TimerEvent.TIMER_COMPLETE, getTimeoutComplete(duration)); - timeout.start(); - // try ..args - var context:TestCase = this; - return function(args:*):* { - context.timeout.stop(); - try { - handler.apply(context, arguments); - } - catch(e:AssertionFailedError) { - context.getResult().addFailure(context, e); - } - catch(ioe:IllegalOperationError) { - context.getResult().addError(context, ioe); - } - finally { - context.asyncMethodComplete(); - } - } - } - - private function getTimeoutComplete(duration:Number):Function { - var context:TestCase = this; - return function(event:Event):void { - context.getResult().addError(context, new IllegalOperationError("TestCase.timeout (" + duration + "ms) exceeded on an asynchronous test method.")); - context.asyncMethodComplete(); - } - } - - protected function asyncMethodComplete():void { - if(currentState == SET_UP) { - runMethod(currentMethod); - } - else if(currentState == RUN_METHOD) { - runTearDown(); - } - } - - protected function runTearDown():void { - currentState = TEAR_DOWN; - if(isComplete) { - return; - } - if(!runSingle) { - getResult().endTestMethod(this, currentMethod); - tearDown(); - layoutManager.resetAll(); - } - setTimeout(runBare, 5); - } - - protected function addChild(child:DisplayObject):DisplayObject { - return getContext().addChild(child); - } - - protected function removeChild(child:DisplayObject):DisplayObject { - if(child == null) { - throw new IllegalOperationError("TestCase.removeChild must have non-null parameter child"); - } - return getContext().removeChild(child); - } - -// public function fail(message:String):void { -// result.addFailure(this, new AssertionFailedError(message)); -// } - } -} \ No newline at end of file +package asunit.framework { + import asunit.errors.AssertionFailedError; + import asunit.util.ArrayIterator; + import asunit.util.Iterator; + + import flash.display.DisplayObject; + import flash.display.DisplayObjectContainer; + import flash.errors.IllegalOperationError; + import flash.events.Event; + import flash.events.TimerEvent; + import flash.utils.Timer; + import flash.utils.describeType; + import flash.utils.getDefinitionByName; + import flash.utils.setTimeout; + + /** + * A test case defines the fixture to run multiple tests. To define a test case<br> + * 1) implement a subclass of TestCase<br> + * 2) define instance variables that store the state of the fixture<br> + * 3) initialize the fixture state by overriding <code>setUp</code><br> + * 4) clean-up after a test by overriding <code>tearDown</code>.<br> + * Each test runs in its own fixture so there + * can be no side effects among test runs. + * Here is an example: + * <pre> + * public class MathTest extends TestCase { + * protected double fValue1; + * protected double fValue2; + * + * protected void setUp() { + * fValue1= 2.0; + * fValue2= 3.0; + * } + * } + * </pre> + * + * For each test implement a method which interacts + * with the fixture. Verify the expected results with assertions specified + * by calling <code>assertTrue</code> with a boolean. + * <pre> + * public void testAdd() { + * double result= fValue1 + fValue2; + * assertTrue(result == 5.0); + * } + * </pre> + * Once the methods are defined you can run them. The framework supports + * both a static type safe and more dynamic way to run a test. + * In the static way you override the runTest method and define the method to + * be invoked. A convenient way to do so is with an anonymous inner class. + * <pre> + * TestCase test= new MathTest("add") { + * public void runTest() { + * testAdd(); + * } + * }; + * test.run(); + * </pre> + * The dynamic way uses reflection to implement <code>runTest</code>. It dynamically finds + * and invokes a method. + * In this case the name of the test case has to correspond to the test method + * to be run. + * <pre> + * TestCase= new MathTest("testAdd"); + * test.run(); + * </pre> + * The tests to be run can be collected into a TestSuite. JUnit provides + * different <i>test runners</i> which can run a test suite and collect the results. + * A test runner either expects a static method <code>suite</code> as the entry + * point to get a test to run or it will extract the suite automatically. + * <pre> + * public static Test suite() { + * suite.addTest(new MathTest("testAdd")); + * suite.addTest(new MathTest("testDivideByZero")); + * return suite; + * } + * </pre> + * @see TestResult + * @see TestSuite + */ + public class TestCase extends Assert implements Test { + protected static const PRE_SET_UP:int = 0; + protected static const SET_UP:int = 1; + protected static const RUN_METHOD:int = 2; + protected static const TEAR_DOWN:int = 3; + protected static const DEFAULT_TIMEOUT:int = 1000; + protected var fName:String; + protected var result:TestListener; + protected var testMethods:Array; + protected var isComplete:Boolean; + protected var context:DisplayObjectContainer; +// protected var methodIsAsynchronous:Boolean; +// protected var timeout:Timer; +// private var setUpIsAsynchronous:Boolean; + private var asyncQueue:Array; + private var currentMethod:String; + private var runSingle:Boolean; + private var methodIterator:Iterator; + private var layoutManager:Object; + private var currentState:int; + + /** + * Constructs a test case with the given name. + */ + public function TestCase(testMethod:String = null) { + var description:XML = describeType(this); + var className:Object = description.@name; + var methods:XMLList = description..method.(@name.match("^test")); + if(testMethod != null) { + testMethods = testMethod.split(", ").join(",").split(","); + if(testMethods.length == 1) { + runSingle = true; + } + } else { + setTestMethods(methods); + } + setName(className.toString()); + resolveLayoutManager(); + asyncQueue = []; + } + + private function resolveLayoutManager():void { + // Avoid creating import dependencies on flex framework + // If you have the framework.swc in your classpath, + // the layout manager will be found, if not, a mcok + // will be used. + try { + var manager:Class = getDefinitionByName("mx.managers.LayoutManager") as Class; + layoutManager = manager["getInstance"](); + if(!layoutManager.hasOwnProperty("resetAll")) { + throw new Error("TestCase :: mx.managers.LayoutManager missing resetAll method"); + } + } + catch(e:Error) { + layoutManager = new Object(); + layoutManager.resetAll = function():void { + }; + } + } + + /** + * Sets the name of a TestCase + * @param name The name to set + */ + public function setName(name:String):void { + fName = name; + } + + protected function setTestMethods(methodNodes:XMLList):void { + testMethods = new Array(); + var methodNames:Object = methodNodes.@name; + var name:String; + for each(var item:Object in methodNames) { + name = item.toString(); + testMethods.push(name); + } + } + + public function getTestMethods():Array { + return testMethods; + } + + /** + * Counts the number of test cases executed by run(TestResult result). + */ + public function countTestCases():int { + return testMethods.length; + } + + /** + * Creates a default TestResult object + * + * @see TestResult + */ + protected function createResult():TestResult { + return new TestResult(); + } + + /** + * A convenience method to run this test, collecting the results with + * either the TestResult provided or a default, new TestResult object. + * Expects either: + * run():void // will return the newly created TestResult + * run(result:TestResult):TestResult // will use the TestResult + * that was passed in. + * + * @see TestResult + */ + public function run():void { + getResult().run(this); + } + + public function setResult(result:TestListener):void { + this.result = result; + } + + internal function getResult():TestListener { + return (result == null) ? createResult() : result; + } + + /** + * Runs the bare test sequence. + * @exception Error if any exception is thrown + * throws Error + */ + public function runBare():void { + if(isComplete) { + return; + } + var name:String; + var itr:Iterator = getMethodIterator(); + if(itr.hasNext()) { + name = String(itr.next()); + currentState = PRE_SET_UP; + runMethod(name); + } + else { + cleanUp(); + getResult().endTest(this); + isComplete = true; + dispatchEvent(new Event(Event.COMPLETE)); + } + } + + private function getMethodIterator():Iterator { + if(methodIterator == null) { + methodIterator = new ArrayIterator(testMethods); + } + return methodIterator; + } + + // Override this method in Asynchronous test cases + // or any other time you want to perform additional + // member cleanup after all test methods have run + protected function cleanUp():void { + } + + private function runMethod(methodName:String):void { + try { + if(currentState == PRE_SET_UP) { + currentState = SET_UP; + getResult().startTestMethod(this, methodName); + setUp(); // setUp may be async and change the state of methodIsAsynchronous + } + currentMethod = methodName; + if(!waitForAsync()) { + currentState = RUN_METHOD; + this[methodName](); + } + } + catch(assertionFailedError:AssertionFailedError) { + getResult().addFailure(this, assertionFailedError); + } + catch(unknownError:Error) { + getResult().addError(this, unknownError); + } + finally { + if(!waitForAsync()) { + runTearDown(); + } + } + } + + /** + * Sets up the fixture, for example, instantiate a mock object. + * This method is called before each test is executed. + * throws Exception on error + */ + protected function setUp():void { + } + /** + * Tears down the fixture, for example, delete mock object. + * This method is called after a test is executed. + * throws Exception on error + */ + protected function tearDown():void { + } + /** + * Returns a string representation of the test case + */ + override public function toString():String { + if(getCurrentMethod()) { + return getName() + "." + getCurrentMethod() + "()"; + } + else { + return getName(); + } + } + /** + * Gets the name of a TestCase + * @return returns a String + */ + public function getName():String { + return fName; + } + + public function getCurrentMethod():String { + return currentMethod; + } + + public function getIsComplete():Boolean { + return isComplete; + } + + public function setContext(context:DisplayObjectContainer):void { + this.context = context; + } + + public function getContext():DisplayObjectContainer { + return context; + } + + protected function addAsync(handler:Function = null, duration:Number=DEFAULT_TIMEOUT):Function { + if(handler == null) { + handler = function(args:*):* {return;}; + } + var async:AsyncOperation = new AsyncOperation(this, handler, duration); + asyncQueue.push(async); + return async.getCallback(); + } + + internal function asyncOperationTimeout(async:AsyncOperation, duration:Number):void{ + getResult().addError(this, new IllegalOperationError("TestCase.timeout (" + duration + "ms) exceeded on an asynchronous operation.")) + asyncOperationComplete(async); + } + + internal function asyncOperationComplete(async:AsyncOperation):void{ + // remove operation from queue + var i:int = asyncQueue.indexOf(async); + asyncQueue.splice(i,1); + // if we still need to wait, return + if(waitForAsync()) return; + if(currentState == SET_UP) { + runMethod(currentMethod); + } + else if(currentState == RUN_METHOD) { + runTearDown(); + } + } + + private function waitForAsync():Boolean{ + return asyncQueue.length > 0; + } + + protected function runTearDown():void { + currentState = TEAR_DOWN; + if(isComplete) { + return; + } + if(!runSingle) { + getResult().endTestMethod(this, currentMethod); + tearDown(); + layoutManager.resetAll(); + } + setTimeout(runBare, 5); + } + + protected function addChild(child:DisplayObject):DisplayObject { + return getContext().addChild(child); + } + + protected function removeChild(child:DisplayObject):DisplayObject { + if(child == null) { + throw new IllegalOperationError("TestCase.removeChild must have non-null parameter child"); + } + return getContext().removeChild(child); + } + +// public function fail(message:String):void { +// result.addFailure(this, new AssertionFailedError(message)); +// } + } +} Modified: branches/ityrrell/framework/as3/asunit/textui/ResultPrinter.as =================================================================== --- branches/ityrrell/framework/as3/asunit/textui/ResultPrinter.as 2008-07-12 17:39:57 UTC (rev 190) +++ branches/ityrrell/framework/as3/asunit/textui/ResultPrinter.as 2008-07-12 18:31:34 UTC (rev 191) @@ -1,257 +1,256 @@ -package asunit.textui { - import asunit.errors.AssertionFailedError; - import asunit.framework.Test; - import asunit.framework.TestFailure; - import asunit.framework.TestListener; - import asunit.framework.TestResult; - import asunit.runner.BaseTestRunner; - import asunit.runner.Version; - - import flash.display.Sprite; - import flash.events.*; - import flash.text.TextField; - import flash.text.TextFormat; - import flash.utils.setTimeout; - - public class ResultPrinter extends Sprite implements TestListener { - private var fColumn:int = 0; - private var textArea:TextField; - private var gutter:uint = 0; - private var backgroundColor:uint = 0x333333; - private var bar:SuccessBar; - private var barHeight:Number = 3; - private var showTrace:Boolean; - - public function ResultPrinter(showTrace:Boolean = false) { - this.showTrace = showTrace; - configureAssets(); - println(); - } - - private function configureAssets():void { - textArea = new TextField(); - textArea.background = true; - textArea.backgroundColor = backgroundColor; - textArea.border = true; - textArea.wordWrap = true; - var format:TextFormat = new TextFormat(); - format.font = "Verdana"; - format.size = 10; - format.color = 0xFFFFFF; - textArea.defaultTextFormat = format; - addChild(textArea); - println("AsUnit " + Version.id() + " by Luke Bayes and Ali Mills"); - - bar = new SuccessBar(); - addChild(bar); - } - - public function setShowTrace(showTrace:Boolean):void { - this.showTrace = showTrace; - } - - public override function set width(w:Number):void { - textArea.x = gutter; - textArea.width = w - gutter*2; - bar.x = gutter; - bar.width = textArea.width; - } - - public override function set height(h:Number):void { - textArea.height = h - ((gutter*2) + barHeight); - textArea.y = gutter; - bar.y = h - (gutter + barHeight); - bar.height = barHeight; - } - - public function println(...args:Array):void { - textArea.appendText(args.toString() + "\n"); - } - - public function print(...args:Array):void { - textArea.appendText(args.toString()); - } - - /** - * API for use by textui.TestRunner - */ - - public function run(test:Test):void { - } - - public function printResult(result:TestResult, runTime:Number):void { - printHeader(runTime); - printErrors(result); - printFailures(result); - printFooter(result); - - bar.setSuccess(result.wasSuccessful()); - if(showTrace) { - trace(textArea.text.split("\r").join("\n")); - } - } - - /* Internal methods - */ - protected function printHeader(runTime:Number):void { - println(); - println(); - println("Time: " + elapsedTimeAsString(runTime)); - } - - protected function printErrors(result:TestResult):void { - printDefects(result.errors(), result.errorCount(), "error"); - } - - protected function printFailures(result:TestResult):void { - printDefects(result.failures(), result.failureCount(), "failure"); - } - - protected function printDefects(booBoos:Object, count:int, type:String):void { - if (count == 0) { - return; - } - if (count == 1) { - println("There was " + count + " " + type + ":"); - } - else { - println("There were " + count + " " + type + "s:"); - } - var i:uint; - for each (var item:TestFailure in booBoos) { - printDefect(TestFailure(item), i); - i++; - } - } - - public function printDefect(booBoo:TestFailure, count:int ):void { // only public for testing purposes - printDefectHeader(booBoo, count); - printDefectTrace(booBoo); - } - - protected function printDefectHeader(booBoo:TestFailure, count:int):void { - // I feel like making this a println, then adding a line giving the throwable a chance to print something - // before we get to the stack trace. - var startIndex:uint = textArea.text.length; - println(count + ") " + booBoo.failedFeature()); - var endIndex:uint = textArea.text.length; - - var format:TextFormat = textArea.getTextFormat(); - format.bold = true; - - // GROSS HACK because of bug in flash player - TextField isn't accepting formats... - setTimeout(onFormatTimeout, 1, format, startIndex, endIndex); - } - - public function onFormatTimeout(format:TextFormat, startIndex:uint, endIndex:uint):void { - textArea.setTextFormat(format, startIndex, endIndex); - } - - protected function printDefectTrace(booBoo:TestFailure):void { - println(BaseTestRunner.getFilteredTrace(booBoo.thrownException().getStackTrace())); - } - - protected function printFooter(result:TestResult):void { - println(); - if (result.wasSuccessful()) { - print("OK"); - println (" (" + result.runCount() + " test" + (result.runCount() == 1 ? "": "s") + ")"); - } else { - println("FAILURES!!!"); - println("Tests run: " + result.runCount()+ - ", Failures: "+result.failureCount()+ - ", Errors: "+result.errorCount()); - } - println(); - } - - /** - * Returns the formatted string of the elapsed time. - * Duplicated from BaseTestRunner. Fix it. - */ - protected function elapsedTimeAsString(runTime:Number):String { - return Number(runTime/1000).toString(); - } - - /** - * @see asunit.framework.TestListener#addError(Test, Throwable) - */ - public function addError(test:Test, t:Error):void { - print("E"); - } - - /** - * @see asunit.framework.TestListener#addFailure(Test, AssertionFailedError) - */ - public function addFailure(test:Test, t:AssertionFailedError):void { - print("F"); - } - - /** - * @see asunit.framework.TestListener#endTestMethod(test, testMethod); - */ - public function startTestMethod(test:Test, methodName:String):void { - } - - /** - * @see asunit.framework.TestListener#endTestMethod(test, testMethod); - */ - public function endTestMethod(test:Test, methodName:String):void { - } - - /** - * @see asunit.framework.TestListener#endTest(Test) - */ - public function endTest(test:Test):void { - } - - /** - * @see asunit.framework.TestListener#startTest(Test) - */ - public function startTest(test:Test):void { - var count:uint = test.countTestCases(); - for(var i:uint; i < count; i++) { - print("."); - if (fColumn++ >= 80) { - println(); - fColumn = 0; - } - } - } - } -} - -import flash.display.Sprite; - -class SuccessBar extends Sprite { - private var myWidth:uint; - private var myHeight:uint; - private var bgColor:uint; - private var passingColor:uint = 0x00FF00; - private var failingColor:uint = 0xFD0000; - - public function SuccessBar() { - } - - public function setSuccess(success:Boolean):void { - bgColor = (success) ? passingColor : failingColor; - draw(); - } - - public override function set width(num:Number):void { - myWidth = num; - draw(); - } - - public override function set height(num:Number):void { - myHeight = num; - draw(); - } - - private function draw():void { - graphics.clear(); - graphics.beginFill(bgColor); - graphics.drawRect(0, 0, myWidth, myHeight); - graphics.endFill(); - } -} +package asunit.textui { + import asunit.errors.AssertionFailedError; + import asunit.framework.Test; + import asunit.framework.TestFailure; + import asunit.framework.TestListener; + import asunit.framework.TestResult; + import asunit.runner.BaseTestRunner; + import asunit.runner.Version; + + import flash.display.Sprite; + import flash.text.TextField; + import flash.text.TextFormat; + import flash.utils.setTimeout; + + public class ResultPrinter extends Sprite implements TestListener { + private var fColumn:int = 0; + private var textArea:TextField; + private var gutter:uint = 0; + private var backgroundColor:uint = 0x333333; + private var bar:SuccessBar; + private var barHeight:Number = 3; + private var showTrace:Boolean; + + public function ResultPrinter(showTrace:Boolean = false) { + this.showTrace = showTrace; + configureAssets(); + println(); + } + + private function configureAssets():void { + textArea = new TextField(); + textArea.background = true; + textArea.backgroundColor = backgroundColor; + textArea.border = true; + textArea.wordWrap = true; + var format:TextFormat = new TextFormat(); + format.font = "Verdana"; + format.size = 10; + format.color = 0xFFFFFF; + textArea.defaultTextFormat = format; + addChild(textArea); + println("AsUnit " + Version.id() + " by Luke Bayes and Ali Mills"); + + bar = new SuccessBar(); + addChild(bar); + } + + public function setShowTrace(showTrace:Boolean):void { + this.showTrace = showTrace; + } + + public override function set width(w:Number):void { + textArea.x = gutter; + textArea.width = w - gutter*2; + bar.x = gutter; + bar.width = textArea.width; + } + + public override function set height(h:Number):void { + textArea.height = h - ((gutter*2) + barHeight); + textArea.y = gutter; + bar.y = h - (gutter + barHeight); + bar.height = barHeight; + } + + public function println(...args:Array):void { + textArea.appendText(args.toString() + "\n"); + } + + public function print(...args:Array):void { + textArea.appendText(args.toString()); + } + + /** + * API for use by textui.TestRunner + */ + + public function run(test:Test):void { + } + + public function printResult(result:TestResult, runTime:Number):void { + printHeader(runTime); + printErrors(result); + printFailures(result); + printFooter(result); + + bar.setSuccess(result.wasSuccessful()); + if(showTrace) { + trace(textArea.text.split("\r").join("\n")); + } + } + + /* Internal methods + */ + protected function printHeader(runTime:Number):void { + println(); + println(); + println("Time: " + elapsedTimeAsString(runTime)); + } + + protected function printErrors(result:TestResult):void { + printDefects(result.errors(), result.errorCount(), "error"); + } + + protected function printFailures(result:TestResult):void { + printDefects(result.failures(), result.failureCount(), "failure"); + } + + protected function printDefects(booBoos:Object, count:int, type:String):void { + if (count == 0) { + return; + } + if (count == 1) { + println("There was " + count + " " + type + ":"); + } + else { + println("There were " + count + " " + type + "s:"); + } + var i:uint; + for each (var item:TestFailure in booBoos) { + printDefect(TestFailure(item), i); + i++; + } + } + + public function printDefect(booBoo:TestFailure, count:int ):void { // only public for testing purposes + printDefectHeader(booBoo, count); + printDefectTrace(booBoo); + } + + protected function printDefectHeader(booBoo:TestFailure, count:int):void { + // I feel like making this a println, then adding a line giving the throwable a chance to print something + // before we get to the stack trace. + var startIndex:uint = textArea.text.length; + println(count + ") " + booBoo.failedFeature()); + var endIndex:uint = textArea.text.length; + + var format:TextFormat = textArea.getTextFormat(); + format.bold = true; + + // GROSS HACK because of bug in flash player - TextField isn't accepting formats... + setTimeout(onFormatTimeout, 1, format, startIndex, endIndex); + } + + public function onFormatTimeout(format:TextFormat, startIndex:uint, endIndex:uint):void { + textArea.setTextFormat(format, startIndex, endIndex); + } + + protected function printDefectTrace(booBoo:TestFailure):void { + println(BaseTestRunner.getFilteredTrace(booBoo.thrownException().getStackTrace())); + } + + protected function printFooter(result:TestResult):void { + println(); + if (result.wasSuccessful()) { + print("OK"); + println (" (" + result.runCount() + " test" + (result.runCount() == 1 ? "": "s") + ")"); + } else { + println("FAILURES!!!"); + println("Tests run: " + result.runCount()+ + ", Failures: "+result.failureCount()+ + ", Errors: "+result.errorCount()); + } + println(); + } + + /** + * Returns the formatted string of the elapsed time. + * Duplicated from BaseTestRunner. Fix it. + */ + protected function elapsedTimeAsString(runTime:Number):String { + return Number(runTime/1000).toString(); + } + + /** + * @see asunit.framework.TestListener#addError(Test, Throwable) + */ + public function addError(test:Test, t:Error):void { + print("E"); + } + + /** + * @see asunit.framework.TestListener#addFailure(Test, AssertionFailedError) + */ + public function addFailure(test:Test, t:AssertionFailedError):void { + print("F"); + } + + /** + * @see asunit.framework.TestListener#endTestMethod(test, testMethod); + */ + public function startTestMethod(test:Test, methodName:String):void { + } + + /** + * @see asunit.framework.TestListener#endTestMethod(test, testMethod); + */ + public function endTestMethod(test:Test, methodName:String):void { + } + + /** + * @see asunit.framework.TestListener#endTest(Test) + */ + public function endTest(test:Test):void { + } + + /** + * @see asunit.framework.TestListener#startTest(Test) + */ + public function startTest(test:Test):void { + var count:uint = test.countTestCases(); + for(var i:uint; i < count; i++) { + print("."); + if (fColumn++ >= 80) { + println(); + fColumn = 0; + } + } + } + } +} + +import flash.display.Sprite; + +class SuccessBar extends Sprite { + private var myWidth:uint; + private var myHeight:uint; + private var bgColor:uint; + private var passingColor:uint = 0x00FF00; + private var failingColor:uint = 0xFD0000; + + public function SuccessBar() { + } + + public function setSuccess(success:Boolean):void { + bgColor = (success) ? passingColor : failingColor; + draw(); + } + + public override function set width(num:Number):void { + myWidth = num; + draw(); + } + + public override function set height(num:Number):void { + myHeight = num; + draw(); + } + + private function draw():void { + graphics.clear(); + graphics.beginFill(bgColor); + graphics.drawRect(0, 0, myWidth, myHeight); + graphics.endFill(); + } +} Modified: branches/ityrrell/framework/as3/asunit/textui/TestRunner.as =================================================================== --- branches/ityrrell/framework/as3/asunit/textui/TestRunner.as 2008-07-12 17:39:57 UTC (rev 190) +++ branches/ityrrell/framework/as3/asunit/textui/TestRunner.as 2008-07-12 18:31:34 UTC (rev 191) @@ -1,125 +1,119 @@ -package asunit.textui { - import asunit.framework.Test; - import asunit.framework.TestResult; - - import flash.display.Sprite; - import flash.display.StageAlign; - import flash.display.StageScaleMode; - import flash.events.Event; - import flash.system.fscommand; - import flash.utils.clearInterval; - import flash.utils.describeType; - import flash.utils.getTimer; - import flash.utils.setInterval; - import flash.utils.Timer; - import flash.events.TimerEvent; - import flash.display.DisplayObject; - - /** - * A command line based tool to run tests. - * <pre> - * java junit.textui.TestRunner TestCaseClass - * </pre> - * TestRunner expects the name of a TestCase class as argument. - * If this class defines a static <code>suite</code> method it - * will be invoked and the returned test is run. Otherwise all - * the methods starting with "test" having no arguments are run. - * <p> - * TestRunner prints a trace as the tests are executed followed by a - * summary at the end. - */ - public class TestRunner extends Sprite { - public static const SUCCESS_EXIT:int = 0; - public static const FAILURE_EXIT:int = 1; - public static const EXCEPTION_EXIT:int = 2; - public static const SHOW_TRACE:Boolean = true; - protected var fPrinter:ResultPrinter; - protected var startTime:Number; - protected var result:TestResult; - - public function TestRunner() { - configureListeners(); - } - - private function configureListeners():void { - addEventListener(Event.ADDED_TO_STAGE, addedHandler); - addEventListener(Event.ADDED, addedHandler); - } - - protected function addedHandler(event:Event):void { - if(event.target === fPrinter) { - stage.align = StageAlign.TOP_LEFT; - stage.scaleMode = StageScaleMode.NO_SCALE; - stage.addEventListener(Event.RESIZE, resizeHandler); - resizeHandler(new Event("resize")); - } - } - - private function resizeHandler(event:Event):void { - fPrinter.width = stage.stageWidth; - fPrinter.height = stage.stageHeight; - } - - /** - * Starts a test run based on the TestCase/TestSuite provided - * Create a new custom class that extends TestRunner - * and call start(TestCaseClass) from within the - * constructor. - */ - public function start(testCase:Class, testMethod:String = null, showTrace:Boolean = false):TestResult { -// fscommand("showmenu", "false"); - try { - var instance:Test; - if(testMethod != null) { - instance = new testCase(testMethod); - } - else { - instance = new testCase(); - } - return doRun(instance, showTrace); - } - catch(e:Error) { - throw new Error("Could not create and run test suite: " + e.getStackTrace()); - } - return null; - } - - public function doRun(test:Test, showTrace:Boolean = false):TestResult { - result = new TestResult(); - if(fPrinter == null) { - setPrinter(new ResultPrinter(showTrace)); - } - else { - fPrinter.setShowTrace(showTrace); - } - result.addListener(getPrinter()); - startTime = getTimer(); - test.setResult(result); - test.setContext(this); - test.addEventListener(Event.COMPLETE, testCompleteHandler); - test.run(); - return result; - } - - private function testCompleteHandler(event:Event):void { - var endTime:Number = getTimer(); - var runTime:Number = endTime - startTime; - getPrinter().printResult(result, runTime); - } - - public function setPrinter(printer:ResultPrinter):void { - if(fPrinter is DisplayObject && getChildIndex(fPrinter)) { - removeChild(fPrinter); - } - - fPrinter = printer; - if(fPrinter is DisplayObject) { - addChild(fPrinter); - } - } - - public function getPrinter():ResultPrinter { - return fPrinter; - } - } -} \ No newline at end of file +package asunit.textui { + import asunit.framework.Test; + import asunit.framework.TestResult; + + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import ... [truncated message content] |
From: <i_t...@us...> - 2008-07-13 19:23:39
|
Revision: 194 http://asunit.svn.sourceforge.net/asunit/?rev=194&view=rev Author: i_tyrrell Date: 2008-07-13 12:23:44 -0700 (Sun, 13 Jul 2008) Log Message: ----------- First cut of porting asunit3 > asunit25. Checking in for safe keeping, not functional. Modified Paths: -------------- branches/ityrrell/framework/as25/asunit/framework/Assert.as branches/ityrrell/framework/as25/asunit/framework/Test.as branches/ityrrell/framework/as25/asunit/framework/TestCase.as branches/ityrrell/framework/as25/asunit/framework/TestFailure.as branches/ityrrell/framework/as25/asunit/framework/TestResult.as branches/ityrrell/framework/as25/asunit/framework/TestSuite.as branches/ityrrell/framework/as25/asunit/runner/BaseTestRunner.as branches/ityrrell/framework/as25/asunit/textui/ResultPrinter.as branches/ityrrell/framework/as25/asunit/textui/SuccessBar.as branches/ityrrell/framework/as25/asunit/textui/TestRunner.as branches/ityrrell/framework/as25/asunit/util/ArrayIterator.as branches/ityrrell/framework/as25/asunit/util/Iterator.as Added Paths: ----------- branches/ityrrell/.as2_classpath branches/ityrrell/framework/as25/asunit/errors/ClassNameUndefinedError.as branches/ityrrell/framework/as25/asunit/flash/ branches/ityrrell/framework/as25/asunit/flash/errors/ branches/ityrrell/framework/as25/asunit/flash/errors/IllegalOperationError.as branches/ityrrell/framework/as25/asunit/flash/events/ branches/ityrrell/framework/as25/asunit/flash/events/Event.as branches/ityrrell/framework/as25/asunit/flash/events/EventDispatcher.as branches/ityrrell/framework/as25/asunit/flash/events/IEventDispatcher.as branches/ityrrell/framework/as25/asunit/flash/events/TimerEvent.as branches/ityrrell/framework/as25/asunit/flash/utils/ branches/ityrrell/framework/as25/asunit/flash/utils/Timer.as branches/ityrrell/framework/as25/asunit/framework/AsyncOperation.as branches/ityrrell/framework/as25/asunit/framework/TestCaseExample.as branches/ityrrell/framework/as25/asunit/framework/TestListener.as branches/ityrrell/framework/as25/asunit/framework/TestMethod.as branches/ityrrell/framework/as25/asunit/runner/TestSuiteLoader.as branches/ityrrell/framework/as25/asunit/runner/Version.as branches/ityrrell/framework/as25/asunit/textui/XMLResultPrinter.as branches/ityrrell/framework/as25/asunit/textui/XMLTestResult.as branches/ityrrell/framework/as25/asunit/util/ArrayUtil.as branches/ityrrell/framework/as25/asunit/util/Properties.as branches/ityrrell/framework-test/as25/ branches/ityrrell/framework-test/as25/AllTests.as branches/ityrrell/framework-test/as25/AsUnitTestRunner.as branches/ityrrell/framework-test/as25/asunit/ branches/ityrrell/framework-test/as25/asunit/AllTests.as branches/ityrrell/framework-test/as25/asunit/framework/ branches/ityrrell/framework-test/as25/asunit/framework/AllTests.as branches/ityrrell/framework-test/as25/asunit/framework/AssertTest.as branches/ityrrell/framework-test/as25/asunit/framework/AsyncMethodTest.as branches/ityrrell/framework-test/as25/asunit/framework/MockData.xml branches/ityrrell/framework-test/as25/asunit/framework/TestCaseMock.as branches/ityrrell/framework-test/as25/asunit/framework/TestCaseTest.as branches/ityrrell/framework-test/as25/asunit/framework/TestFailureTest.as branches/ityrrell/framework-test/as25/asunit/framework/VisualTestCaseTest.as branches/ityrrell/framework-test/as25/asunit/runner/ branches/ityrrell/framework-test/as25/asunit/runner/BaseTestRunnerMock.as branches/ityrrell/framework-test/as25/asunit/textui/ branches/ityrrell/framework-test/as25/asunit/textui/AllTests.as branches/ityrrell/framework-test/as25/asunit/textui/TestRunnerTest.as branches/ityrrell/framework-test/as25/asunit/textui/TestRunnerTestCaseMock.as branches/ityrrell/framework-test/as25/asunit/util/ branches/ityrrell/framework-test/as25/asunit/util/AllTests.as branches/ityrrell/framework-test/as25/asunit/util/ArrayIteratorTest.as Removed Paths: ------------- branches/ityrrell/framework/as25/AsUnitTestRunner.as branches/ityrrell/framework/as25/asunit/errors/AssertionPassedError.as branches/ityrrell/framework/as25/asunit/errors/IllegalOperationError.as branches/ityrrell/framework/as25/asunit/errors/InvocationTargetError.as branches/ityrrell/framework/as25/asunit/framework/AssertMock.as branches/ityrrell/framework/as25/asunit/framework/AssertTest.as branches/ityrrell/framework/as25/asunit/framework/TestCaseTest.as branches/ityrrell/framework/as25/asunit/framework/TestCaseXml.as Added: branches/ityrrell/.as2_classpath =================================================================== --- branches/ityrrell/.as2_classpath (rev 0) +++ branches/ityrrell/.as2_classpath 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<AS2Classpath> +<AS2Classpath generateProblems="true" type="source" useAsSharedCode="false">core</AS2Classpath> +<AS2Classpath generateProblems="true" type="source" useAsSharedCode="false">framework/as25</AS2Classpath> +<AS2Classpath generateProblems="true" type="source" useAsSharedCode="false">framework-test/as25</AS2Classpath> +</AS2Classpath> Deleted: branches/ityrrell/framework/as25/AsUnitTestRunner.as =================================================================== --- branches/ityrrell/framework/as25/AsUnitTestRunner.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/AsUnitTestRunner.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,13 +0,0 @@ -import asunit.textui.TestRunner; - -class AsUnitTestRunner extends TestRunner { - - public function AsUnitTestRunner() { - fscommand("fullscreen", "true"); - start(AllTests); - } - - public static function main():Void { - var runner = new AsUnitTestRunner(); - } -} Deleted: branches/ityrrell/framework/as25/asunit/errors/AssertionPassedError.as =================================================================== --- branches/ityrrell/framework/as25/asunit/errors/AssertionPassedError.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/errors/AssertionPassedError.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,7 +0,0 @@ - -class asunit.errors.AssertionPassedError extends Error { - - public function AssertionPassedError(msg:String) { - super(msg); - } -} \ No newline at end of file Added: branches/ityrrell/framework/as25/asunit/errors/ClassNameUndefinedError.as =================================================================== --- branches/ityrrell/framework/as25/asunit/errors/ClassNameUndefinedError.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/errors/ClassNameUndefinedError.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,9 @@ +class asunit.errors.ClassNameUndefinedError extends Error { + + public var fqcn:String = "ClassNameUndefinedError"; + + public function ClassNameUndefinedError(message : String){ + super(message); + name = "ClassNameUndefinedError"; + } +} Deleted: branches/ityrrell/framework/as25/asunit/errors/IllegalOperationError.as =================================================================== --- branches/ityrrell/framework/as25/asunit/errors/IllegalOperationError.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/errors/IllegalOperationError.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,7 +0,0 @@ - -class asunit.errors.IllegalOperationError extends Error { - - public function IllegalOperationError(msg:String) { - super(msg); - } -} \ No newline at end of file Deleted: branches/ityrrell/framework/as25/asunit/errors/InvocationTargetError.as =================================================================== --- branches/ityrrell/framework/as25/asunit/errors/InvocationTargetError.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/errors/InvocationTargetError.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,7 +0,0 @@ - -class asunit.errors.InvocationTargetError extends Error { - - public function InvocationTargetError(msg:String) { - super(msg); - } -} \ No newline at end of file Added: branches/ityrrell/framework/as25/asunit/flash/errors/IllegalOperationError.as =================================================================== --- branches/ityrrell/framework/as25/asunit/flash/errors/IllegalOperationError.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/flash/errors/IllegalOperationError.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,10 @@ +class asunit.flash.errors.IllegalOperationError extends Error { + + public var fqcn:String = "asunit.flash.errors.IllegalOperationError"; + + public function IllegalOperationError(message : String) { + super(message); + name = "IllegalOperationError"; + } + +} Added: branches/ityrrell/framework/as25/asunit/flash/events/Event.as =================================================================== --- branches/ityrrell/framework/as25/asunit/flash/events/Event.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/flash/events/Event.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,19 @@ +class asunit.flash.events.Event { + + public static var COMPLETE:String = "complete"; + public static var CHANGE:String = "change"; + + private var _type:String; + private var _target:Object; + + public function Event(type:String, target:Object) { + trace("Event::constructor: type: " + type); + _type = type; + _target = target==undefined ? null : target; + } + + public function get type():String{ + return _type; + } + +} Added: branches/ityrrell/framework/as25/asunit/flash/events/EventDispatcher.as =================================================================== --- branches/ityrrell/framework/as25/asunit/flash/events/EventDispatcher.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/flash/events/EventDispatcher.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,40 @@ +import asunit.util.ArrayUtil; +import asunit.flash.events.Event; +import asunit.flash.events.IEventDispatcher; + +/* + * Minimal implementation of AS3 flash.events.EventDispatcher as required by asunit3 + */ +class asunit.flash.events.EventDispatcher implements IEventDispatcher{ + + private var listeners:Object; + + public function EventDispatcher() { + listeners = {}; + } + + public function addEventListener(type:String, listener:Function, scope:Object):Void { + var l:Object = {s:scope, c:listener}; + if(listeners[type] instanceof Array){ + listeners[type].push(l); + }else{ + trace("create new listener"); + listeners[type] = [l]; + } + } + + public function dispatchEvent(event : Event) : Void { + trace("EventDispatcher::dispatchEvent: type: " + event.type); + if(listeners[event.type] instanceof Array){ + trace("listerner is array") + ArrayUtil.forEach(listeners[event.type], + function(listener:Object):Void{ + trace("dispatching event..."); + var callback:Function = listener.c; + var scope:Object = listener.s; + callback.call(scope, event); + } + ); + } + } +} Added: branches/ityrrell/framework/as25/asunit/flash/events/IEventDispatcher.as =================================================================== --- branches/ityrrell/framework/as25/asunit/flash/events/IEventDispatcher.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/flash/events/IEventDispatcher.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,6 @@ +import asunit.flash.events.Event; + +interface asunit.flash.events.IEventDispatcher { + public function addEventListener(type:String, listener:Function, scope:Object):Void; + public function dispatchEvent(event:Event):Void; +} Added: branches/ityrrell/framework/as25/asunit/flash/events/TimerEvent.as =================================================================== --- branches/ityrrell/framework/as25/asunit/flash/events/TimerEvent.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/flash/events/TimerEvent.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,12 @@ +import asunit.flash.events.Event; + +class asunit.flash.events.TimerEvent extends Event { + + public static var TIMER_COMPLETE:String = "timerComplete"; + + public function TimerEvent(type:String, target:Object) { + super(type, target); + } + + +} Added: branches/ityrrell/framework/as25/asunit/flash/utils/Timer.as =================================================================== --- branches/ityrrell/framework/as25/asunit/flash/utils/Timer.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/flash/utils/Timer.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,74 @@ +import asunit.flash.events.TimerEvent; +import asunit.flash.events.EventDispatcher; + +class asunit.flash.utils.Timer extends EventDispatcher { + + private static var STOPPED:Number = 0; + private static var RUNNING:Number = 1; + + private var _intervalID : Number; + private var _delay : Number; + private var _repeatCount : Number; + private var _currentCount : Number; + + private var state:Number; + + public function Timer(delay:Number, repeatCount:Number) { + trace("new Timer"); + if(repeatCount==undefined) repeatCount=0; + _delay = delay; + _repeatCount = repeatCount; + _currentCount = 0; + } + + public function start() : Void { + if(state==RUNNING) return; + state = RUNNING; + _intervalID = setInterval(this, "onInterval", _delay); + } + + public function stop() : Void { + if(state==STOPPED) return; + clear(); + state = STOPPED; + } + + public function reset() : Void { + clear(); + state = STOPPED; + _currentCount = 0; + } + + private function clear() : Void{ + if(_intervalID!=null) clearInterval(_intervalID); + } + + private function onInterval():Void{ + trace("Timer::onInterval"); + _currentCount++; + if(_currentCount==_repeatCount) { + stop(); + dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE, this)); + } + } + + public function get currentCount():Number{ + return _currentCount; + } + + /* + * _global.setTimeout() is only available in FP8+ + */ + public static function setTimeout(scope:Object, callback:Object, duration:Number):Void{ + trace("Timer::setTimeout"); + var t:Timer = new Timer(duration, 1); + var args:Array = arguments.length > 3 ? arguments.slice(3) : []; + // normalise callback as Function + if(callback instanceof String) callback = scope[callback]; + t.addEventListener(TimerEvent.TIMER_COMPLETE, + function():Void{ + Function(callback).apply(scope, args); + }); + t.start(); + } +} Modified: branches/ityrrell/framework/as25/asunit/framework/Assert.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/Assert.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/framework/Assert.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,376 +1,268 @@ import asunit.errors.AssertionFailedError; -import asunit.errors.IllegalOperationError; +import asunit.flash.errors.IllegalOperationError; +import asunit.flash.events.EventDispatcher; + /** - * Provides assert methods and other utility methods which are inherited by - * the {@link TestCase} subclass. Since all user-defined test cases should - * extend {@link TestCase} you should never have to use this class - * directly. - * - * @see TestCase + * A set of assert methods. Messages are only displayed when an assert fails. */ -class asunit.framework.Assert { - private static var defaultClassName:String = "[ClassName Unknown]"; - private static var lastDepth:Number = 10; - private function Assert() { - } - +class asunit.framework.Assert extends EventDispatcher { /** - * Returns the next available depth for attaching a MovieClip. - * - * @return - * Number of next available depth. + * Protect constructor since it is a static only class */ - public static function nextDepth():Number { - return Assert.lastDepth++; + public function Assert() { } /** - * Appends a test result to the {@link TestRunner} which manages test - * result output. This method is intended for use by the AsUnit - * framework and should never have to be called directly. - * - * @param msg - * The message associated with the assertion. - * @param assertType - * The assertion type. - * @param passFail - * Indicates whether the test passed (<code>true</code>) or - * failed (<code>false</code>). - * + * Asserts that a condition is true. If it isn't it throws + * an AssertionFailedError with the given message. */ - public static function addTestResult(msg:String, assertType:String, passed:Boolean) { - if(!passed) { - var str:String = ""; - if(msg != "") { - str += assertType + ".message: " + msg; - } - fail(str); + static public function assertTrue():Void { + var message:String; + var condition:Boolean; + + if(arguments.length == 1) { + message = ""; + condition = Boolean(arguments[0]); } - } + else if(arguments.length == 2) { + message = arguments[0]; + condition = Boolean(arguments[1]); + } + else { + throw new IllegalOperationError("Invalid argument count"); + } - /** - * Returns a reference to the {@link TestRunner} instance which manages - * the output of test results. This method is intended for use by the - * AsUnit framework and should never have to be called directly. - private static function getTestRunner():TestRunner { - if(testRunner == null) { - testRunner = new TestRunner(); + if(!condition) { + fail(message); } - return testRunner; } + /** + * Asserts that a condition is false. If it isn't it throws + * an AssertionFailedError with the given message. */ + static public function assertFalse():Void { + var message:String; + var condition:Boolean; - /** - * Returns the number of {@link TestCases} that have completed. - public static function countTestCases():Number { - return testRunner.length; + if(arguments.length == 1) { + message = ""; + condition = Boolean(arguments[0]); + } + else if(arguments.length == 2) { + message = arguments[0]; + condition = Boolean(arguments[1]); + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + assertTrue(message, !condition); } + /** + * Fails a test with the given message. */ - + static public function fail(message:String):Void { + throw new AssertionFailedError(message); + } /** - * Asserts that two objects are equal. If either of the - * objects provides an <code>equals()</code> method it will be used to - * determine equality. Otherwise, equality will be evaluated using the - * strict equality operator (<code>===</code>).<br /> - * <br /> - * The method below tests the <code>getFullName()</code> method of the - * <code>Person</code> class to make sure that the formatting of its - * return value is correct.<br /> - * - * <pre> - * public function testGetFullName():Void { - * var person:Person = new Person("John", "Alan", "Smith"); - * assertEquals("full name should be formatted: [first] [middleInitial]. [last]", - * "John A. Smith", - * person.getFullName()); - * } - * </pre> - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param assertion1 - * First object to use in evaluation. - * @param assertion2 - * Second object to use in evaluation. + * Asserts that two objects are equal. If they are not + * an AssertionFailedError is thrown with the given message. */ - public static function assertEquals(msg:Object, assertion1:Object, assertion2:Object):Void { + static public function assertEquals():Void { + var message:String; + var expected:Object; + var actual:Object; + if(arguments.length == 2) { - assertion2 = assertion1; - assertion1 = msg; - msg = ""; + message = ""; + expected = arguments[0]; + actual = arguments[1]; } - if(assertion1["equals"] instanceof Function) { - addTestResult(String(msg), "assertEquals", assertion1["equals"](assertion2)); - } else if(assertion2["equals"] != undefined) { - addTestResult(String(msg), "assertEquals", assertion2["equals"](assertion1)); - } else { - addTestResult(format(String(msg), assertion1, assertion2), "assertEquals", assertion1 == assertion2); + else if(arguments.length == 3) { + message = arguments[0]; + expected = arguments[1]; + actual = arguments[2]; } + else { + throw new IllegalOperationError("Invalid argument count"); + } - } + if(expected == null && actual == null) { + return; + } - /** - * Asserts that a value is <code>null</code>.<br /> - * <br /> - * The method below tests to confirm that the parameter passed to the - * <code>getProductBySku</code> method of the - * <code>ProductCatalog</code> is treated as case sensitive.<br /> - * - * <pre> - * public function testGetProductBySku():Void { - * // Set up a fixture to test against. - * var productCatalog:ProductCatalog = new ProductCatalog(); - * productCatalog.addProduct(new Product("sku123a")); - * - * // Try retrieving a product using improper text case. - * var product:Product = productCatalog.getProductBySku("SKU123A"); - * assertNull("the SKU parameter should be case sensitive", - * product); - * } - * </pre> - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param assertion - * Object to be evaluated. - */ - public static function assertNull(msg:Object, assertion:Object):Void { - if(arguments.length == 1) { - assertion = msg; - msg = ""; + try { + if(expected != null && expected.equals(actual)) { + return; + } } - addTestResult(String(msg), "assertNull", (assertion === null)); - } + catch(e:Error) { + if(expected != null && expected == actual) { + return; + } + } + failNotEquals(message, expected, actual); + } /** - * Asserts that a value is not <code>null</code>.<br /> - * <br /> - * The method below tests to confirm that the parameter passed to the - * <code>getColorByName</code> method of the <code>ColorManager</code> - * class is treated as case insensitive.<br /> - * - * <pre> - * public function testGetColorByName():Void { - * // Set up a fixture to test against. - * var colorManager:ColorManager = new ColorManager(); - * colorManager.addColor(new Color("blue")); - * - * // Try retrieving a color using alternate text case. - * var color:Color = colorManager.getColorByName("Blue"); - * assertNotNull("color name parameter should not be case sensitive", - * color); - * } - * </pre> - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param assertion - * Object to be evaluated. + * Asserts that an object isn't null. If it is + * an AssertionFailedError is thrown with the given message. */ - public static function assertNotNull(msg:Object, assertion:Object):Void { + static public function assertNotNull():Void { + var message:String; + var object:Object; + if(arguments.length == 1) { - assertion = msg; - msg = ""; + message = ""; + object = arguments[0]; } - addTestResult(String(msg), "assertNotNull", (assertion !== null)); - } + else if(arguments.length == 2) { + message = arguments[0]; + object = arguments[1]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + assertTrue(message, object != null); + } /** - * Asserts that a value is <code>undefined</code>. - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param assertion - * Object to be evaluated. + * Asserts that an object is null. If it is not + * an AssertionFailedError is thrown with the given message. */ - public static function assertUndefined(msg:Object, assertion:Object):Void { + static public function assertNull():Void { + var message:String; + var object:Object; + if(arguments.length == 1) { - assertion = msg; - msg = ""; + message = ""; + object = arguments[0]; } - addTestResult(String(msg), "assertUndefined", (assertion === undefined)); - } + else if(arguments.length == 2) { + message = arguments[0]; + object = arguments[1]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + assertTrue(message, object == null); + } /** - * Asserts that a value is not <code>undefined</code>. - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param assertion - * Object to be evaluated. + * Asserts that two objects refer to the same object. If they are not + * an AssertionFailedError is thrown with the given message. */ - public static function assertNotUndefined(msg:Object, assertion:Object):Void { - if(arguments.length == 1) { - assertion = msg; - msg = ""; + static public function assertSame():Void { + var message:String; + var expected:Object; + var actual:Object; + + if(arguments.length == 2) { + message = ""; + expected = arguments[0]; + actual = arguments[1]; } - addTestResult(String(msg), "assertNotUndefined", (assertion !== undefined)); + else if(arguments.length == 3) { + message = arguments[0]; + expected = arguments[1]; + actual = arguments[2]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + if(expected === actual) { + return; + } + failNotSame(message, expected, actual); } + /** + * Asserts that two objects do not refer to the same object. If they do, + * an AssertionFailedError is thrown with the given message. + */ + static public function assertNotSame():Void { + var message:String; + var expected:Object; + var actual:Object; - /** - * Asserts that two variables are pointing to the same object in - * memory.<br /> - * <br /> - * The method below tests to confirm that the static - * <code>getInstance()</code> method of the <code>ServiceLocator</code> - * class always returns a reference to the same instance of - * <code>ServiceLocator</code>.<br /> - * - * <pre> - * public function testGetInstance():Void { - * var instance1:ServiceLocator = ServiceLocator.getInstance(); - * var instance2:ServiceLocator = ServiceLocator.getInstance(); - * assertSame("getInstance() should always return the same ServiceLocator instance", - * instance1, - * instance2); - * } - * </code> - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param object1 - * First object to use in evaluation. - * @param object2 - * Second object to use in evaluation. - */ - public static function assertSame(msg:Object, object1:Object, object2:Object):Void { if(arguments.length == 2) { - object2 = object1; - object1 = msg; - msg = ""; + message = ""; + expected = arguments[0]; + actual = arguments[1]; } - addTestResult(String(msg), "assertSame", (object1 === object2)); + else if(arguments.length == 3) { + message = arguments[0]; + expected = arguments[1]; + actual = arguments[2]; + } + else { + throw new IllegalOperationError("Invalid argument count"); + } + + if(expected === actual) + failSame(message); } /** - * Asserts that a statement evaluates to <code>true</code>. Since this - * method lets you pass in any expression that evaluates to a boolean - * value, it is a good method to fall back on when the other - * <code>assert<i>XXX</i></code> methods don't provide the kind of - * functionality your test requires.<br /> - * <br /> - * The method below test to confirm that new <code>Product</code> objects - * are assigned ascending catalog numbers when created by the - * <code>ProductGenerator</code> class.<br /> - * - * <pre> - * public function testMakeProductCatalogNumberAssignement():Void { - * var generator:ProductGenerator = ProductGenerator.getInstance(); - * var product1:Product = generator.makeProduct("sku123"); - * var product2:Product = generator.makeProduct("sku456"); - * assertTrue("products should be assigned ascending catalog numbers", - * product1.catNumber < product2.catNumber); - * } - * </code> - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param assertion - * A statement that evaluates to a boolean value. + * Asserts that two numerical values are equal within a tolerance range. + * If they are not an AssertionFailedError is thrown with the given message. */ - public static function assertTrue(msg:Object, assertion:Boolean):Void { - if(arguments.length == 1) { - assertion = Boolean(msg); - msg = ""; + static public function assertEqualsFloat():Void { + var message:String; + var expected:Number; + var actual:Number; + var tolerance:Number = 0; + + if(arguments.length == 3) { + message = ""; + expected = arguments[0]; + actual = arguments[1]; + tolerance = arguments[2]; } - - if(arguments.length > 2) { - failError("Argument Count Exceeded " + String(msg), "assertTrue"); + else if(arguments.length == 4) { + message = arguments[0]; + expected = arguments[1]; + actual = arguments[2]; + tolerance = arguments[3]; } - addTestResult(String(msg), "assertTrue", assertion); + else { + throw new IllegalOperationError("Invalid argument count"); + } + if (isNaN(tolerance)) tolerance = 0; + if(Math.abs(expected - actual) <= tolerance) { + return; + } + failNotEquals(message, expected, actual); } - /** - * Asserts that a statement evaluates to <code>false</code>. Since this - * method lets you pass in any expression that evaluates to a boolean - * value, it is a good method to fall back on when the other - * <code>assert<i>XXX</i></code> methods don't provide the kind of - * functionality your test requires.<br /> - * <br /> - * The method below tests to confirm that the return value of the - * <code>truncate()</code> method of the <code>TextUtil</code> - * class is no longer than the specified limit<br /> - * - * <pre> - * public function testTruncate():Void { - * var limit:Number = 30; - * var text:String = "As a reviewer, I got an early opportunity to read the book you are holding."; - * var clippedText:String = TextUtil.truncate(text, limit); - * assertFalse("return value should be no more than 30 characters", - * clippedText.length > 30); - * } - * </code> - * - * @param msg - * Optional; Message to display should the test fail. It is - * recommended that this message describe what is asserted to be - * true rather than describing what went wrong. - * @param assertion - * A statement that evaluates to a boolean value. - */ - public static function assertFalse(msg:Object, assertion:Boolean):Void { - if(arguments.length == 1) { - assertion = Boolean(msg); - msg = ""; + + static private function failSame(message:String):Void { + var formatted:String = ""; + if(message != null) { + formatted = message + " "; + } + fail(formatted + "expected not same"); + } + + static private function failNotSame(message:String, expected:Object, actual:Object):Void { + var formatted:String = ""; + if(message != null) { + formatted = message + " "; } - addTestResult(String(msg), "assertFalse", !assertion); + fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">"); } - /** - * Forces a failing test result to be recorded. This method is useful - * in the rare circumstances where the <code>assert<i>XXX</i></code> - * methods can not be used, for example, when testing error - * handling.<br> - * <br /> - * The method below tests to confirm that a "gifts" product category can - * be accessed through a <code>Catalog</code> instance.<br /> - * - * <pre> - * public function testGiftsProductCategoryAccess():Void { - * var catalog:ProductCatalog = CatalogFactory.getCatalog("fall2005"); - * - * // Try accessing the "gifts" product category. - * try { - * var products:Array = catalog.getProducts("gifts"); - * } catch (error:com.mycompany.errors.InvalidProductCategoryError) { - * fail("catalog should contain 'gifts' products"); - * } - * } - * </pre> - */ - public static function fail(msg:String):Void { - throw new AssertionFailedError(msg); + static private function failNotEquals(message:String, expected:Object, actual:Object):Void { + fail(format(message, expected, actual)); } - -// private static function failNotEquals(message:String, expected:Object, actual:Object):Void { -// fail(format(message, expected, actual)); -// } - private static function format(message:String, expected:Object, actual:Object):String { + static private function format(message:String, expected:Object, actual:Object):String { var formatted:String = ""; if(message != null) { formatted = message + " "; } return formatted + "expected:<" + expected + "> but was:<" + actual + ">"; } - - public static function failError(msg:String):Void { - throw new IllegalOperationError(msg); - } -} \ No newline at end of file +} Deleted: branches/ityrrell/framework/as25/asunit/framework/AssertMock.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/AssertMock.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/framework/AssertMock.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,15 +0,0 @@ -import asunit.framework.Assert; - -class asunit.framework.AssertMock extends Assert { - - public function AssertMock() { - } - - public function assertTrue():Void { - Assert.assertTrue.apply(Assert, arguments); - } - - public function assertEquals():Void { - Assert.assertEquals.apply(arguments); - } -} \ No newline at end of file Deleted: branches/ityrrell/framework/as25/asunit/framework/AssertTest.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/AssertTest.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/framework/AssertTest.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,59 +0,0 @@ - -import asunit.framework.Assert; -import asunit.framework.TestCase; -import asunit.errors.AssertionFailedError; -import asunit.framework.AssertMock; -import asunit.errors.IllegalOperationError; - -class asunit.framework.AssertTest extends TestCase { - private var className:String = "asunit.framework.AssertTest"; - private var instance:AssertMock; - - public function AssertTest(testMethod:String) { - super(testMethod); - } - - public function setUp():Void { - instance = new AssertMock(); - } - - public function tearDown():Void { - delete instance; - } - - public function testAssertTrueFailureA():Void { - try { - instance.assertTrue(false); - fail("assertTrue(false) should throw"); - } - catch(e) { - if(!(e instanceof AssertionFailedError)) { - fail("assertTrue should have thrown an AssertionFailedError"); - } - } - } - -// instance.assertTrue("faux message", false); - - public function testAssertTrueTooManyArgs():Void { - try { - instance.assertTrue("faux message", false, false); - fail("assertTrue should have failed with too many args"); - } - catch(e) { - if(!(e instanceof IllegalOperationError)) { - fail(e.toString()); - } - } - } - - public function testAssertTrueSuccess():Void { - try { - instance.assertTrue(true); - instance.assertTrue("faux message", true); - } - catch(e) { - fail("assertTrue should not have thrown"); - } - } -} Added: branches/ityrrell/framework/as25/asunit/framework/AsyncOperation.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/AsyncOperation.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/framework/AsyncOperation.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,48 @@ +import asunit.errors.AssertionFailedError; +import asunit.flash.errors.IllegalOperationError; +import asunit.flash.events.TimerEvent; +import asunit.flash.utils.Timer; +import asunit.framework.TestCase; + +class asunit.framework.AsyncOperation{ + + private var timeout:Timer; + private var testCase:TestCase; + private var callback:Function; + private var duration:Number; + + public function AsyncOperation(testCase:TestCase, handler:Function, duration:Number){ + this.testCase = testCase; + this.duration = duration; + timeout = new Timer(duration, 1); + timeout.addEventListener(TimerEvent.TIMER_COMPLETE, onTimeoutComplete, this); + timeout.start(); + if(handler == null) { + handler = function():Void{}; + } + var context:AsyncOperation = this; + callback = function():Void{ + context.timeout.stop(); + try { + handler.apply(testCase, arguments); + } + catch(e:AssertionFailedError) { + testCase.getResult().addFailure(testCase, e); + } + catch(ioe:IllegalOperationError) { + testCase.getResult().addError(testCase, ioe); + } + finally { + testCase.asyncOperationComplete(context); + } + }; + } + + public function getCallback():Function{ + return callback; + } + + private function onTimeoutComplete(event:TimerEvent):Void{ + testCase.asyncOperationTimeout(this, duration); + } +} Modified: branches/ityrrell/framework/as25/asunit/framework/Test.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/Test.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/framework/Test.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,11 +1,17 @@ -import asunit.framework.TestResult; - -interface asunit.framework.Test { - - public function testsComplete():Boolean; - public function setResult(result:TestResult):Void; - public function setContext(context:MovieClip):Void; - public function run():Void; - public function countTestCases():Number; - public function toString():String; +import asunit.framework.TestListener; + +import asunit.flash.events.IEventDispatcher; + +interface asunit.framework.Test extends IEventDispatcher{ + function countTestCases():Number; + function getName():String; + function getTestMethods():Array; + function toString():String; + function setResult(result : TestListener) : Void; + function run():Void; + function runBare():Void; + function getCurrentMethod():String; + function getIsComplete():Boolean; + function setContext(context:MovieClip):Void; + function getContext():MovieClip; } \ No newline at end of file Modified: branches/ityrrell/framework/as25/asunit/framework/TestCase.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/TestCase.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/framework/TestCase.as 2008-07-13 19:23:44 UTC (rev 194) @@ -1,278 +1,373 @@ -import asunit.framework.Assert; -import asunit.framework.Test; -import asunit.framework.TestResult; -import asunit.errors.AssertionFailedError; -import asunit.errors.AssertionPassedError; - +import asunit.flash.utils.Timer; +import asunit.errors.ClassNameUndefinedError; +import asunit.util.ArrayUtil; +import asunit.framework.AsyncOperation; +import asunit.framework.TestResult; + +import asunit.framework.TestListener; +import asunit.framework.Test; +import asunit.framework.Assert; +import asunit.flash.errors.IllegalOperationError; +import asunit.flash.events.Event; + +import asunit.errors.AssertionFailedError; +import asunit.util.ArrayIterator; +import asunit.util.Iterator; + +/** + * A test case defines the fixture to run multiple tests. To define a test case<br> + * 1) implement a subclass of TestCase<br> + * 2) define instance variables that store the state of the fixture<br> + * 3) initialize the fixture state by overriding <code>setUp</code><br> + * 4) clean-up after a test by overriding <code>tearDown</code>.<br> + * Each test runs in its own fixture so there + * can be no side effects among test runs. + * Here is an example: + * <pre> + * public class MathTest extends TestCase { + * protected double fValue1; + * protected double fValue2; + * + * protected void setUp() { + * fValue1= 2.0; + * fValue2= 3.0; + * } + * } + * </pre> + * + * For each test implement a method which interacts + * with the fixture. Verify the expected results with assertions specified + * by calling <code>assertTrue</code> with a boolean. + * <pre> + * public void testAdd() { + * double result= fValue1 + fValue2; + * assertTrue(result == 5.0); + * } + * </pre> + * Once the methods are defined you can run them. The framework supports + * both a static type safe and more dynamic way to run a test. + * In the static way you override the runTest method and define the method to + * be invoked. A convenient way to do so is with an anonymous inner class. + * <pre> + * TestCase test= new MathTest("add") { + * public void runTest() { + * testAdd(); + * } + * }; + * test.run(); + * </pre> + * The dynamic way uses reflection to implement <code>runTest</code>. It dynamically finds + * and invokes a method. + * In this case the name of the test case has to correspond to the test method + * to be run. + * <pre> + * TestCase= new MathTest("testAdd"); + * test.run(); + * </pre> + * The tests to be run can be collected into a TestSuite. JUnit provides + * different <i>test runners</i> which can run a test suite and collect the results. + * A test runner either expects a static method <code>suite</code> as the entry + * point to get a test to run or it will extract the suite automatically. + * <pre> + * public static Test suite() { + * suite.addTest(new MathTest("testAdd")); + * suite.addTest(new MathTest("testDivideByZero")); + * return suite; + * } + * </pre> + * @see TestResult + * @see TestSuite + */ class asunit.framework.TestCase extends Assert implements Test { - private var className:String = "[default]"; - - private var testMethodsExecuted:Number = 0; - private var result:TestResult; - private var context:MovieClip; + private static var PRE_SET_UP:Number = 0; + private static var SET_UP:Number = 1; + private static var RUN_METHOD:Number = 2; + private static var TEAR_DOWN:Number = 3; + private static var DEFAULT_TIMEOUT:Number = 1000; + private var className:String; + private var fName:String; + private var result : TestListener; + private var testMethods:Array; + private var isComplete:Boolean; + private var context : MovieClip; + private var asyncQueue:Array; private var currentMethod:String; private var runSingle:Boolean; - private var isComplete:Boolean; + private var methodIterator:Iterator; + private var layoutManager:Object; + private var currentState:Number; - public function TestCase(testMethod:String) { - if(testMethod != undefined) { - runSingle = true; - currentMethod = testMethod; + /** + * Constructs a test case with the given name. + */ + public function TestCase(testMethod:String) { + if(testMethod==undefined) testMethod=null; + if(testMethod != null) { + testMethods = testMethod.split(", ").join(",").split(","); + if(testMethods.length == 1) { + runSingle = true; + } + } else { + setTestMethods(this); } + setName(className); + // I don't think this is necessary for as2 +// resolveLayoutManager(); + asyncQueue = []; } - /* - * You can choose to override this method when implementing - * asynchronous test cases. - * By default, the TestCaseXml object will call back to this - * method and begin execution of the test case. - */ - public function onXmlLoaded(node:XMLNode):Void { - runNow(); +/* private function resolveLayoutManager():Void { + // Avoid creating import dependencies on flex framework + // If you have the framework.swc in your classpath, + // the layout manager will be found, if not, a mcok + // will be used. + try { + var manager:Class = getDefinitionByName("mx.managers.LayoutManager") as Class; + layoutManager = manager["getInstance"](); + if(!layoutManager.hasOwnProperty("resetAll")) { + throw new Error("TestCase :: mx.managers.LayoutManager missing resetAll method"); + } + } + catch(e:Error) { + layoutManager = new Object(); + layoutManager.resetAll = function():Void { + }; + } } - - /* - * By default, this method will be triggered from - * a TestCaseXml instance. If there is a problem - * an error will be shown in the output. +*/ + /** + * Sets the name of a TestCase + * @param name The name to set */ - public function onXmlFailure(node:XML):Void { - currentMethod = "onXmlFailure"; - getResult().addError(this, new Error("TestCaseXml failed to load successfully: " + node.toString())); - runNow(); + public function setName(name:String):Void { + if(name==undefined || name==null){ + throw new ClassNameUndefinedError("You must assign a ClassName for your TestCase subclass.") + } + fName = name; } - public function testsComplete():Boolean { - return (getTestMethods().length == testMethodsExecuted); + private function setTestMethods(obj:Object):Void { + testMethods = []; + for(var prop:String in obj) { + // look for functions starting with "test" + if((prop.indexOf("test")==0) && (obj[prop] instanceof Function)){ + testMethods.push(prop); + } + } } - - public function countTestCases():Number { - return getTestMethods().length; + + public function getTestMethods():Array { + return testMethods; } - /* - * setUp() is called before each method that begins with "test*" - * This method should used to instantiate common fixtures + /** + * Counts the number of test cases executed by run(TestResult result). */ - private function setUp():Void { + public function countTestCases():Number { + return testMethods.length; } - /* - * tearDown() is called after each method that begins with "test*" - * This method should be used to destroy any objects created from - * the setUp() method call + /** + * Creates a default TestResult object + * + * @see TestResult */ - private function tearDown():Void { + private function createResult():TestResult { + return new TestResult(); } - /* cleanUp() is called one time after all test methods have completed - * in a single TestCase. This is typically overridden and used to - * clean up after an Asynchronous TestCase has completed. + /** + * A convenience method to run this test, collecting the results with + * either the TestResult provided or a default, new TestResult object. + * Expects either: + * run():Void // will return the newly created TestResult + * run(result:TestResult):TestResult // will use the TestResult + * that was passed in. + * + * @see TestResult */ - private function cleanUp():Void { + public function run():Void { + getResult().run(this); } - public function setResult(result:TestResult):Void { + public function setResult(result:TestListener):Void { this.result = result; } - private function getResult():TestResult { - return result; + public function getResult():TestListener { + return (result == null) ? createResult() : result; } - public function setContext(context:MovieClip):Void { - this.context = context; - } - - public function getContext():MovieClip { - return context; - } - - public function run():Void { - runNow(); - } - - private function runNow():Void { - var result:TestResult = getResult(); - result.run(this); - } - + /** + * Runs the bare test sequence. + * @exception Error if any exception is thrown + * throws Error + */ public function runBare():Void { - var methods:Array = getTestMethods(); + if(isComplete) { + return; + } var name:String; - try { - var len:Number = methods.length; - for(var i:Number = 0; i < len; i++) { - name = methods[i]; - try { - runMethod(name); - } - catch(e:Error) { - if(e instanceof AssertionFailedError) { - result.addFailure(this, AssertionFailedError(e)); - } - else if(!(e instanceof AssertionPassedError)) { - result.addError(this, e); - } - } - } + var itr:Iterator = getMethodIterator(); + if(itr.hasNext()) { + name = String(itr.next()); + currentState = PRE_SET_UP; + runMethod(name); } - finally { - if(!runSingle) { - cleanUp(); - } + else { + cleanUp(); + getResult().endTest(this); + isComplete = true; + dispatchEvent(new Event(Event.COMPLETE)); } + } + + private function getMethodIterator():Iterator { + if(methodIterator == null) { + methodIterator = new ArrayIterator(testMethods); + } + return methodIterator; + } - isComplete = true; + // Override this method in Asynchronous test cases + // or any other time you want to perform additional + // member cleanup after all test methods have run + private function cleanUp():Void { } - + private function runMethod(methodName:String):Void { - currentMethod = methodName; try { - setUp(); - this[methodName](); + if(currentState == PRE_SET_UP) { + currentState = SET_UP; + getResult().startTestMethod(this, methodName); + setUp(); // setUp may be async and change the state of methodIsAsynchronous + } + currentMethod = methodName; + if(!waitForAsync()) { + currentState = RUN_METHOD; + this[methodName](); + } } + catch(assertionFailedError:AssertionFailedError) { + getResult().addFailure(this, assertionFailedError); + } + catch(unknownError:Error) { + getResult().addError(this, unknownError); + } finally { - if(!runSingle) { - tearDown(); + if(!waitForAsync()) { + runTearDown(); } - testMethodsExecuted++; } } - private function getTestMethods():Array { - if(runSingle) { - return new Array(currentMethod); + /** + * Sets up the fixture, for example, instantiate a mock object. + * This method is called before each test is executed. + * throws Exception on error + */ + private function setUp():Void { + } + /** + * Tears down the fixture, for example, delete mock object. + * This method is called after a test is executed. + * throws Exception on error + */ + private function tearDown():Void { + } + /** + * Returns a string representation of the test case + */ + public function toString():String { + if(getCurrentMethod()) { + return getName() + "." + getCurrentMethod() + "()"; } - var methods:Array = new Array(); - _global.ASSetPropFlags(this.__proto__, null, 6, true); - for(var i:String in this) { - if(i.indexOf("test") == 0 && this[i] instanceof Function) { - methods.push(i); - } + else { + return getName(); } - _global.ASSetPropFlags(this.__proto__, null, 1, true); - methods.reverse(); - return methods; } - /** - * Returns the name of the currently running test method. This - * method is intended for use by the AsUnit framework and should never - * have to be called directly. - * - * @return - * A method name. Ex. <code>"testGetValue"</code>. + * Gets the name of a TestCase + * @return returns a String */ + public function getName():String { + return fName; + } + public function getCurrentMethod():String { return currentMethod; } - public function toString():String { - return getName() + "." + getCurrentMethod() + "()"; + public function getIsComplete():Boolean { + return isComplete; } - public function getName():String { - return className; + public function setContext(context:MovieClip):Void { + this.context = context; } - private function createEmptyMovieClip(name:String, depth:Number):MovieClip { - return getContext().createEmptyMovieClip(name, depth); + public function getContext():MovieClip { + return context; } - private function createTextField(name:String, depth:Number, x:Number, y:Number, width:Number, height:Number):TextField { - getContext().createTextField(name, depth, x, y, width, height); - return TextField(getContext()[name]); + private function addAsync(handler:Function, duration:Number):Function { + if(handler == undefined) { + handler = function():Void{}; + } + if(duration == undefined) { + duration = DEFAULT_TIMEOUT; + } + var async:AsyncOperation = new AsyncOperation(this, handler, duration); + asyncQueue.push(async); + return async.getCallback(); } - private function getNextHighestDepth():Number { - return getContext().getNextHighestDepth(); + public function asyncOperationTimeout(async:AsyncOperation, duration:Number):Void{ + getResult().addError(this, new IllegalOperationError("TestCase.timeout (" + duration + "ms) exceeded on an asynchronous operation.")); + asyncOperationComplete(async); } - /* - * This helper method will support the following method signatures: - * - * attachMovie(linkageId:String):MovieClip; - * attachMovie(linkageId:String, initObject:Object):MovieClip; - * attachMovie(linkageId:String, name:String, depth:Number):MovieClip; - * attachMovie(linkageId:String, name:String, depth:Number, initObject:Object):MovieClip; - * - * @return - * MovieClip - */ - private function attachMovie():MovieClip { - var linkageId:String = arguments[0]; - var name:String; - var depth:Number; - var initObj:Object = new Object(); - - switch(arguments.length) { - case 1 : - case 2 : - name = getValidName(getContext(), name); - depth = getValidDepth(getContext()); - initObj = arguments[1]; - break; - case 3 : - case 4 : - name = arguments[1]; - depth = arguments[2]; - initObj = arguments[3]; - break; + public function asyncOperationComplete(async:AsyncOperation):Void{ + // remove operation from queue + var i:Number = ArrayUtil.indexOf(asyncQueue, async); + asyncQueue.splice(i,1); + // if we still need to wait, return + if(waitForAsync()) return; + if(currentState == SET_UP) { + runMethod(currentMethod); } - return getContext().attachMovie(linkageId, name, depth, initObj); - } - - public function getUpperEmptyDepth(parent:MovieClip, depth:Number):Number { - if(depth == undefined || !isValidDepth(parent, depth)) { - var high:Number = (depth == undefined) ? 1 : depth; - for(var i:String in parent) { - if(parent[i] instanceof MovieClip && parent[i].getDepth() != undefined) { - high = Math.max(parent[i].getDepth()+1, high); - } - } - return high; + else if(currentState == RUN_METHOD) { + runTearDown(); } - return depth; } - private function getValidName(parent:MovieClip, nm:Object):String { - var incr:Number = 1; + private function waitForAsync():Boolean{ + return asyncQueue.length > 0; + } - var name:String = (nm == undefined || nm instanceof Object) ? "item" : nm.toString(); - var ref:MovieClip = parent[name]; - - var name2:String = name; - while(ref != undefined && incr < 100) { - name2 = name + "-" + (incr++); - ref = parent[name2]; + private function runTearDown():Void { + currentState = TEAR_DOWN; + if(isComplete) { + return; } - return name2; + if(!runSingle) { + getResult().endTestMethod(this, currentMethod); + tearDown(); +// layoutManager.resetAll(); + } + Timer.setTimeout(this, runBare, 5); } - - private function isValidDepth(parent:MovieClip, depth:Number):Boolean { - var item:MovieClip = getItemByDepth(parent, depth); - return (item == null) ? true : false; + +/* private function addChild(child:DisplayObject):DisplayObject { + return getContext().addChild(child); } - private function getItemByDepth(parent:MovieClip, depth:Number):MovieClip { - for(var i:String in parent) { - if(parent[i].getDepth() == depth) { - return parent[i]; - } + private function removeChild(child:DisplayObject):DisplayObject { + if(child == null) { + throw new IllegalOperationError("TestCase.removeChild must have non-null parameter child"); } - return null; - } + return getContext().removeChild(child); + } +*/ - private function getValidDepth(mc:MovieClip):Number { - var mcDepth:Number; - var dp:Number = nextDepth(); - for(var i:String in mc) { - mcDepth = mc[i].getDepth(); - if(mc[i] instanceof MovieClip && mcDepth < 10000) { - dp = Math.max(mcDepth, dp); - } - } - return ++dp; - } -} \ No newline at end of file +} Added: branches/ityrrell/framework/as25/asunit/framework/TestCaseExample.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/TestCaseExample.as (rev 0) +++ branches/ityrrell/framework/as25/asunit/framework/TestCaseExample.as 2008-07-13 19:23:44 UTC (rev 194) @@ -0,0 +1,70 @@ +import asunit.framework.TestCase; +import asunit.flash.events.Event; +import asunit.flash.events.IEventDispatcher; +import asunit.flash.events.EventDispatcher; +import asunit.flash.utils.Timer; + +// TestCase subclasses should always end with 'Test', the example +// doesn't because we don't want TestSuites in this directory. +class asunit.framework.TestCaseExample extends TestCase { + private var date:Date; + + // TestCase constructors must be implemented as follows + // so that we can execute a single method on them from + // the TestRunner + public function TestCaseExample(testMethod:String) { + if(testMethod==undefined) testMethod=null; + super(testMethod); + } + + // This method will be called before every test method + private function setUp():Void { + date = new Date(); +// sprite = new Sprite(); +// addChild(sprite); + } + + // This method will be called after every test method + // but only if we're executing the entire TestCase, + // the tearDown method won't be called if we're + // calling start(MyTestCase, "someMethod"); + private function tearDown():Void { +// removeChild(sprite); +// sprite = null; + date = null; + } + + // This is auto-created by the XULUI and ensures that + // our objects are actually created as we expect. + public function testInstantiated():Void { + assertTrue("Date instantiated", date instanceof Date); +// assertTrue("Sprite instantiated", sprite is Sprite); + } + + // This is an example of a typical test method + public function testMonthGetterSetter():Void { + date.setMonth(1); + assertEquals(1, date.getMonth()); + } + + // This is an asynchronous test method + public function testAsyncFeature():Void { + // create a new object that dispatches events... + var dispatcher:IEventDispatcher = new EventDispatcher(); + // get a TestCase async event handler reference + // the 2nd arg is an optional timeout in ms. (default=1000ms ) + var handler:Function = addAsync(changeHandler, 2000); + // subscribe to your event dispatcher using the returned handler + dispatcher.addEventListener(Event.CHANGE, handler, this); + // cause the event to be dispatched. + // either immediately: + //dispatcher.dispatchEvent(new Event(Event.CHANGE)); + // or in the future < your assigned timeout + Timer.setTimeout( dispatcher, dispatchEvent, 200, new Event(Event.CHANGE)); + } + + private function changeHandler(event:Event):Void { + // perform assertions in your handler + assertEquals(Event.CHANGE, event.type); + } +} \ No newline at end of file Deleted: branches/ityrrell/framework/as25/asunit/framework/TestCaseTest.as =================================================================== --- branches/ityrrell/framework/as25/asunit/framework/TestCaseTest.as 2008-07-12 18:38:30 UTC (rev 193) +++ branches/ityrrell/framework/as25/asunit/framework/TestCaseTest.as 2008-07-13 19:23:44 UTC (rev 194) @@... [truncated message content] |