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: }