mas01mj@732: package asunit.framework { mas01mj@732: import asunit.errors.AssertionFailedError; mas01mj@732: mas01mj@732: import flash.utils.getQualifiedClassName; mas01mj@732: mas01mj@732: import flash.errors.IllegalOperationError; mas01mj@732: import flash.events.EventDispatcher; mas01mj@732: mas01mj@732: /** mas01mj@732: * A set of assert methods. Messages are only displayed when an assert fails. mas01mj@732: */ mas01mj@732: mas01mj@732: public class Assert extends EventDispatcher { mas01mj@732: /** mas01mj@732: * Protect constructor since it is a static only class mas01mj@732: */ mas01mj@732: public function Assert() { mas01mj@732: } mas01mj@732: mas01mj@732: /** mas01mj@732: * Asserts that a condition is true. If it isn't it throws mas01mj@732: * an AssertionFailedError with the given message. mas01mj@732: */ mas01mj@732: static public function assertTrue(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var condition:Boolean; mas01mj@732: mas01mj@732: if(args.length == 1) { mas01mj@732: message = ""; mas01mj@732: condition = Boolean(args[0]); mas01mj@732: } mas01mj@732: else if(args.length == 2) { mas01mj@732: message = args[0]; mas01mj@732: condition = Boolean(args[1]); mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: if(!condition) { mas01mj@732: fail(message); mas01mj@732: } mas01mj@732: } mas01mj@732: /** mas01mj@732: * Asserts that a condition is false. If it isn't it throws mas01mj@732: * an AssertionFailedError with the given message. mas01mj@732: */ mas01mj@732: static public function assertFalse(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var condition:Boolean; mas01mj@732: mas01mj@732: if(args.length == 1) { mas01mj@732: message = ""; mas01mj@732: condition = Boolean(args[0]); mas01mj@732: } mas01mj@732: else if(args.length == 2) { mas01mj@732: message = args[0]; mas01mj@732: condition = Boolean(args[1]); mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: assertTrue(message, !condition); mas01mj@732: } mas01mj@732: /** mas01mj@732: * Fails a test with the given message. mas01mj@732: * mas01mj@732: * @example This method can be called anytime you want to break out and fail mas01mj@732: * the current test. mas01mj@732: * mas01mj@732: * mas01mj@732: * public function testSomething():void { mas01mj@732: * var instance:MyClass = new MyClass(); mas01mj@732: * if(instance.foo()) { mas01mj@732: * fail('The foo should not have been there'); mas01mj@732: * } mas01mj@732: * } mas01mj@732: * mas01mj@732: */ mas01mj@732: static public function fail(message:String):void { mas01mj@732: throw new AssertionFailedError(message); mas01mj@732: } mas01mj@732: mas01mj@732: /** mas01mj@732: * Asserts that the provided block throws an exception that matches mas01mj@732: * the type provided. mas01mj@732: * mas01mj@732: * mas01mj@732: * public function testFailingCode():void { mas01mj@732: * assertThrows(CustomError, function():void { mas01mj@732: * var instance:Sprite = new Sprite(); mas01mj@732: * instance.callMethodThatThrows(); mas01mj@732: * }); mas01mj@732: * } mas01mj@732: * mas01mj@732: **/ mas01mj@732: static public function assertThrows(errorType:Class, block:Function):void { mas01mj@732: try { mas01mj@732: block.call(); mas01mj@732: fail("assertThrows block did not throw an expected exception"); mas01mj@732: } mas01mj@732: catch(e:Error) { mas01mj@732: if(!(e is errorType)) { mas01mj@732: fail("assertThrows did not throw the expected error type, instead threw: " + getQualifiedClassName(e)); mas01mj@732: } mas01mj@732: } mas01mj@732: } mas01mj@732: mas01mj@732: /** mas01mj@732: * Asserts that two objects are equal. If they are not mas01mj@732: * an AssertionFailedError is thrown with the given message. mas01mj@732: * mas01mj@732: * This assertion should be (by far) the one you use the most. mas01mj@732: * It automatically provides useful information about what mas01mj@732: * the failing values were. mas01mj@732: * mas01mj@732: * mas01mj@732: * public function testNames():void { mas01mj@732: * var name1:String = "Federico Aubele"; mas01mj@732: * var name2:String = "Frederico Aubele"; mas01mj@732: * mas01mj@732: * assertEquals(name1, name2); mas01mj@732: * } mas01mj@732: * mas01mj@732: */ mas01mj@732: static public function assertEquals(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var expected:Object; mas01mj@732: var actual:Object; mas01mj@732: mas01mj@732: if(args.length == 2) { mas01mj@732: message = ""; mas01mj@732: expected = args[0]; mas01mj@732: actual = args[1]; mas01mj@732: } mas01mj@732: else if(args.length == 3) { mas01mj@732: message = args[0]; mas01mj@732: expected = args[1]; mas01mj@732: actual = args[2]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: if(expected == null && actual == null) { mas01mj@732: return; mas01mj@732: } mas01mj@732: mas01mj@732: try { mas01mj@732: if(expected != null && expected.equals(actual)) { mas01mj@732: return; mas01mj@732: } mas01mj@732: } mas01mj@732: catch(e:Error) { mas01mj@732: if(expected != null && expected == actual) { mas01mj@732: return; mas01mj@732: } mas01mj@732: } mas01mj@732: mas01mj@732: failNotEquals(message, expected, actual); mas01mj@732: } mas01mj@732: /** mas01mj@732: * Asserts that an object isn't null. If it is mas01mj@732: * an AssertionFailedError is thrown with the given message. mas01mj@732: */ mas01mj@732: static public function assertNotNull(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var object:Object; mas01mj@732: mas01mj@732: if(args.length == 1) { mas01mj@732: message = ""; mas01mj@732: object = args[0]; mas01mj@732: } mas01mj@732: else if(args.length == 2) { mas01mj@732: message = args[0]; mas01mj@732: object = args[1]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: assertTrue(message, object != null); mas01mj@732: } mas01mj@732: /** mas01mj@732: * Asserts that an object is null. If it is not mas01mj@732: * an AssertionFailedError is thrown with the given message. mas01mj@732: */ mas01mj@732: static public function assertNull(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var object:Object; mas01mj@732: mas01mj@732: if(args.length == 1) { mas01mj@732: message = ""; mas01mj@732: object = args[0]; mas01mj@732: } mas01mj@732: else if(args.length == 2) { mas01mj@732: message = args[0]; mas01mj@732: object = args[1]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: assertTrue(message, object == null); mas01mj@732: } mas01mj@732: /** mas01mj@732: * Asserts that two objects refer to the same object. If they are not mas01mj@732: * an AssertionFailedError is thrown with the given message. mas01mj@732: */ mas01mj@732: static public function assertSame(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var expected:Object; mas01mj@732: var actual:Object; mas01mj@732: mas01mj@732: if(args.length == 2) { mas01mj@732: message = ""; mas01mj@732: expected = args[0]; mas01mj@732: actual = args[1]; mas01mj@732: } mas01mj@732: else if(args.length == 3) { mas01mj@732: message = args[0]; mas01mj@732: expected = args[1]; mas01mj@732: actual = args[2]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: if(expected === actual) { mas01mj@732: return; mas01mj@732: } mas01mj@732: failNotSame(message, expected, actual); mas01mj@732: } mas01mj@732: /** mas01mj@732: * Asserts that two objects do not refer to the same object. If they do, mas01mj@732: * an AssertionFailedError is thrown with the given message. mas01mj@732: */ mas01mj@732: static public function assertNotSame(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var expected:Object; mas01mj@732: var actual:Object; mas01mj@732: mas01mj@732: if(args.length == 2) { mas01mj@732: message = ""; mas01mj@732: expected = args[0]; mas01mj@732: actual = args[1]; mas01mj@732: } mas01mj@732: else if(args.length == 3) { mas01mj@732: message = args[0]; mas01mj@732: expected = args[1]; mas01mj@732: actual = args[2]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: if(expected === actual) mas01mj@732: failSame(message); mas01mj@732: } mas01mj@732: mas01mj@732: /** mas01mj@732: * Asserts that two numerical values are equal within a tolerance range. mas01mj@732: * If they are not an AssertionFailedError is thrown with the given message. mas01mj@732: */ mas01mj@732: static public function assertEqualsFloat(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var expected:Number; mas01mj@732: var actual:Number; mas01mj@732: var tolerance:Number = 0; mas01mj@732: mas01mj@732: if(args.length == 3) { mas01mj@732: message = ""; mas01mj@732: expected = args[0]; mas01mj@732: actual = args[1]; mas01mj@732: tolerance = args[2]; mas01mj@732: } mas01mj@732: else if(args.length == 4) { mas01mj@732: message = args[0]; mas01mj@732: expected = args[1]; mas01mj@732: actual = args[2]; mas01mj@732: tolerance = args[3]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: if (isNaN(tolerance)) tolerance = 0; mas01mj@732: if(Math.abs(expected - actual) <= tolerance) { mas01mj@732: return; mas01mj@732: } mas01mj@732: failNotEquals(message, expected, actual); mas01mj@732: } mas01mj@732: mas01mj@732: /** mas01mj@732: * Asserts that two arrays have the same length and contain the same mas01mj@732: * objects in the same order. If the arrays are not equal by this mas01mj@732: * definition an AssertionFailedError is thrown with the given message. mas01mj@732: */ mas01mj@732: static public function assertEqualsArrays(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var expected:Array; mas01mj@732: var actual:Array; mas01mj@732: mas01mj@732: if(args.length == 2) { mas01mj@732: message = ""; mas01mj@732: expected = args[0]; mas01mj@732: actual = args[1]; mas01mj@732: } mas01mj@732: else if(args.length == 3) { mas01mj@732: message = args[0]; mas01mj@732: expected = args[1]; mas01mj@732: actual = args[2]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: if (expected == null && actual == null) { mas01mj@732: return; mas01mj@732: } mas01mj@732: if ((expected == null && actual != null) || (expected != null && actual == null)) { mas01mj@732: failNotEquals(message, expected, actual); mas01mj@732: } mas01mj@732: // from here on: expected != null && actual != null mas01mj@732: if (expected.length != actual.length) { mas01mj@732: failNotEquals(message, expected, actual); mas01mj@732: } mas01mj@732: for (var i : int = 0; i < expected.length; i++) { mas01mj@732: assertEquals(expected[i], actual[i]); mas01mj@732: } mas01mj@732: } mas01mj@732: mas01mj@732: /** mas01mj@732: * Asserts that two arrays have the same length and contain the same mas01mj@732: * objects. The order of the objects in the arrays is ignored. If they mas01mj@732: * are not equal by this definition an AssertionFailedError is thrown mas01mj@732: * with the given message. mas01mj@732: */ mas01mj@732: static public function assertEqualsArraysIgnoringOrder(...args:Array):void { mas01mj@732: var message:String; mas01mj@732: var expected:Array; mas01mj@732: var actual:Array; mas01mj@732: mas01mj@732: if(args.length == 2) { mas01mj@732: message = ""; mas01mj@732: expected = args[0]; mas01mj@732: actual = args[1]; mas01mj@732: } mas01mj@732: else if(args.length == 3) { mas01mj@732: message = args[0]; mas01mj@732: expected = args[1]; mas01mj@732: actual = args[2]; mas01mj@732: } mas01mj@732: else { mas01mj@732: throw new IllegalOperationError("Invalid argument count"); mas01mj@732: } mas01mj@732: mas01mj@732: if (expected == null && actual == null) { mas01mj@732: return; mas01mj@732: } mas01mj@732: if ((expected == null && actual != null) || (expected != null && actual == null)) { mas01mj@732: failNotEquals(message, expected, actual); mas01mj@732: } mas01mj@732: // from here on: expected != null && actual != null mas01mj@732: if (expected.length != actual.length) { mas01mj@732: failNotEquals(message, expected, actual); mas01mj@732: } mas01mj@732: for (var i : int = 0; i < expected.length; i++) { mas01mj@732: var foundMatch : Boolean = false; mas01mj@732: var expectedMember : Object = expected[i]; mas01mj@732: for (var j : int = 0; j < actual.length; j++) { mas01mj@732: var actualMember : Object = actual[j]; mas01mj@732: try { mas01mj@732: assertEquals(expectedMember, actualMember); mas01mj@732: foundMatch = true; mas01mj@732: break; mas01mj@732: } mas01mj@732: catch (e : AssertionFailedError) { mas01mj@732: // no match, try next mas01mj@732: } mas01mj@732: } mas01mj@732: if (!foundMatch) { mas01mj@732: failNotEquals("Found no match for " + expectedMember + ";", expected, actual); mas01mj@732: } mas01mj@732: } mas01mj@732: } mas01mj@732: mas01mj@732: mas01mj@732: static private function failSame(message:String):void { mas01mj@732: var formatted:String = ""; mas01mj@732: if(message != null) { mas01mj@732: formatted = message + " "; mas01mj@732: } mas01mj@732: fail(formatted + "expected not same"); mas01mj@732: } mas01mj@732: mas01mj@732: static private function failNotSame(message:String, expected:Object, actual:Object):void { mas01mj@732: var formatted:String = ""; mas01mj@732: if(message != null) { mas01mj@732: formatted = message + " "; mas01mj@732: } mas01mj@732: fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">"); mas01mj@732: } mas01mj@732: mas01mj@732: static private function failNotEquals(message:String, expected:Object, actual:Object):void { mas01mj@732: fail(format(message, expected, actual)); mas01mj@732: } mas01mj@732: mas01mj@732: static private function format(message:String, expected:Object, actual:Object):String { mas01mj@732: var formatted:String = ""; mas01mj@732: if(message != null) { mas01mj@732: formatted = message + " "; mas01mj@732: } mas01mj@732: return formatted + "expected:<" + expected + "> but was:<" + actual + ">"; mas01mj@732: } mas01mj@732: } mas01mj@732: }