/* appjet:version 0.1 */ /* appjet:library */ function assert() { var booleanValue = _validateArguments(1, arguments)[0]; if (typeof(booleanValue) != 'boolean') error('Bad argument to assert(boolean)'); _assert(commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false'); } function assertTrue() { var booleanValue = _validateArguments(1, arguments)[0]; if (typeof(booleanValue) != 'boolean') error('Bad argument to assertTrue(boolean)'); _assert(commentArg(1, arguments), booleanValue === true, 'Call to assertTrue(boolean) with false'); } function assertFalse() { var booleanValue = _validateArguments(1, arguments)[0]; if (typeof(booleanValue) != 'boolean') error('Bad argument to assertFalse(boolean)'); _assert(commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true'); } function assertEquals() { var args = _validateArguments(2, arguments), exp = args[0], act = args[1]; _assert(commentArg(2, arguments), exp === act, 'Expected ' + _displayStringForValue(exp) + ' but was ' + _displayStringForValue(act)); } function assertNotEquals() { var args = _validateArguments(2, arguments), exp = args[0], act = args[1]; _assert(commentArg(2, arguments), exp !== act, 'Expected not to be ' + _displayStringForValue(act)); } function assertNull() { var aVar = _validateArguments(1, arguments)[0]; _assert(commentArg(1, arguments), aVar === null, 'Expected ' + _displayStringForValue(null) + ' but was ' + _displayStringForValue(aVar)); } function assertNotNull() { var aVar = _validateArguments(1, arguments)[0]; _assert(commentArg(1, arguments), aVar !== null, 'Expected not to be ' + _displayStringForValue(null)); } function assertUndefined() { var aVar = _validateArguments(1, arguments)[0]; _assert(commentArg(1, arguments), aVar === undefined, 'Expected ' + _displayStringForValue(undefined) + ' but was ' + _displayStringForValue(aVar)); } function assertNotUndefined() { var aVar = _validateArguments(1, arguments)[0]; _assert(commentArg(1, arguments), aVar !== undefined, 'Expected not to be ' + _displayStringForValue(undefined)); } function assertNaN() { var aVar = _validateArguments(1, arguments)[0]; _assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN'); } function assertNotNaN() { var aVar = _validateArguments(1, arguments)[0]; _assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN'); } function assertHTMLEquals() { var args = _validateArguments(2, arguments), exp = args[0], act = args[1]; expStd = _standardizeHTML(exp), actStd = _standardizeHTML(act); assertEquals(commentArg(2, arguments)||"", expStd, actStd); } var _helper = null;//import({}, "lib-simple-htmlparser", "lib-xmldom"); function _standardizeHTML(html) { result = _helper.HTMLtoXML(""+html+""); xmldoc = new _helper.XMLDoc(result); result = xmldoc. getUnderlyingXMLText(); return result; } function assertObjectEquals() { var args = _validateArguments(2, arguments), exp = args[0], act = args[1]; if (exp === act) return; var comment = commentArg(2,arguments); var msg = comment ? comment : ''; var type = jsuTrueTypeOf(exp); var isEqual = type == jsuTrueTypeOf(act); if (isEqual) { switch (type) { case 'String': case 'Number': isEqual = exp == act; break; case 'Boolean': case 'Date': isEqual = exp === act; break; case 'RegExp': case 'Function': isEqual = exp.toString() === act.toString(); break; default: //Object | Array isEqual = exp.length === act.length; if (isEqual) if (comment == null) _assertRecursiveEquals(exp, act, assertObjectEquals); else _assertRecursiveEquals("Nested: "+comment, exp, act, assertObjectEquals); } } _assert(msg, isEqual, 'Expected ' + _displayStringForValue(exp) + ' but was ' + _displayStringForValue(act)); } assertArrayEquals = assertObjectEquals; function assertHashEquals() { var args = _validateArguments(2, arguments), exp = args[0], act = args[1]; var comment = commentArg(2, arguments); if (comment == null) _assertRecursiveEquals(exp, act, assertEquals); else _assertRecursiveEquals(comment, exp, act, assertEquals); } function _assertRecursiveEquals() { var args = _validateArguments(3, arguments), exp = args[0], act = args[1], compare = args[2]; var comment = commentArg(3, arguments); var comment = comment ? comment + "\n" : ""; for (var key in exp) { assertTrue(comment + "Expected had key " + key + " that was not found", key in act); compare( comment + "Value for key " + key + " mismatch - expected = " + exp[key] + ", actual = " + act[key], exp[key], act[key] ); } for (var key in act) { assertTrue(comment + "Actual had key " + key + " that was not expected", key in exp); } } function assertRoughlyEquals() { var args = _validateArguments(3, arguments), exp = args[0], act = args[1], tolerance = args[2]; assertTrue( "Expected " + exp + ", but got " + act + " which was more than " + tolerance + " away", Math.abs(exp - act) < tolerance ); } function assertContains() { var args = _validateArguments(2, arguments), contained = args[0], container = args[1]; assertTrue( "Expected '" + container + "' to contain '" + contained + "'", container.indexOf(contained) != -1 ); } function assertEvaluatesToTrue() { var value = _validateArguments(1, arguments)[0]; if (!value) fail(commentArg(1, arguments)); } function assertEvaluatesToFalse() { var value = _validateArguments(1, arguments)[0]; if (value) fail(commentArg(1, arguments)); } function _assert(comment, booleanValue, failureMessage) { if (!booleanValue) throw new JsUnitException(comment, failureMessage); } /**@ignore*/ function argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) { return args.length == expectedNumberOfNonCommentArgs + 1; } /**@ignore*/ function commentArg(expectedNumberOfNonCommentArgs, args) { if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) return args[0]; return null; } /**@ignore*/ /*function nonCommentArg(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) { return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ? args[desiredNonCommentArgIndex] : args[desiredNonCommentArgIndex - 1]; }*/ function _validateArguments(expectedNumberOfNonCommentArgs, args) { if (!( args.length == expectedNumberOfNonCommentArgs || (args.length == expectedNumberOfNonCommentArgs + 1 && typeof(args[0]) == 'string') )) error('Incorrect arguments passed to assert function'); return Array.prototype.slice.call(args, -expectedNumberOfNonCommentArgs); } /** * A more functional typeof * @param Object o * @return String */ function jsuTrueTypeOf(something) { var result = typeof something; try { switch (result) { case 'string': case 'boolean': case 'number': break; case 'object': case 'function': switch (something.constructor) { case String: result = 'String'; break; case Boolean: result = 'Boolean'; break; case Number: result = 'Number'; break; case Array: result = 'Array'; break; case RegExp: result = 'RegExp'; break; case Function: result = 'Function'; break; default: var m = something.constructor.toString().match(/function\s*([^( ]+)\(/); if (m) result = m[1]; else break; } break; } } finally { result = result.substr(0, 1).toUpperCase() + result.substr(1); return result; } } function _displayStringForValue(aVar) { var result = '<' + aVar + '>'; if (aVar != null) { result += ' (' + jsuTrueTypeOf(aVar) + ')'; } return result; } /**Call from within test to end it with failure*/ function fail(failureMessage) { throw new JsUnitException("Call to fail()", failureMessage); } /**Call from within test to end it with error*/ function error(errorMessage) { var errorObject = new Object(); errorObject.description = errorMessage; throw errorObject; } /**This exception is used by jsunit for failures.*/ function JsUnitException(comment, message) { this.isTestException = true; this.comment = comment; this.testMessage = message; } var counter = 0; /* appjet:server */ import("lib-support/jsunit"); function assertJsUnitException(comment, allegedJsUnitException) { assertNotNull(comment, allegedJsUnitException); assert(comment, allegedJsUnitException.isTestException); assertNotUndefined(comment, allegedJsUnitException.comment); } function assertNonJsUnitException(comment, allegedNonJsUnitException) { assertNotNull(comment, allegedNonJsUnitException); assertUndefined(comment, allegedNonJsUnitException.isTestUnitException); assertNotUndefined(comment, allegedNonJsUnitException.description); } page.testSuite = [ function assertWorks() { assert("true should be true", true); assert(true); }, function assertTrueWorks() { assertTrue("true should be true", true); assertTrue(true); }, function assertFalseWorks() { assertFalse("false should be false", false); assertFalse(false); }, function assertEqualsWorks() { assertEquals("1 should equal 1", 1, 1); assertEquals(1, 1); }, function assertNotEqualsWorks() { assertNotEquals("1 should not equal 2", 1, 2); assertNotEquals(1, 2); }, function assertNullWorks() { assertNull("null should be null", null); assertNull(null); }, function assertNotNullWorks() { assertNotNull("1 should not be null", 1); assertNotNull(1); }, function assertUndefinedWorks() { var myVar; assertUndefined("A declared but unassigned variable should have the undefined value", myVar); assertUndefined(myVar); }, function assertNotUndefinedWorks() { assertNotUndefined("1 should not be undefined", 1); assertNotUndefined(1); }, function assertNaNWorks() { assertNaN("a string should not be a number", "string"); assertNaN("string"); }, function assertNotNaNWorks() { assertNotNaN("1 should not be not a number", 1); assertNotNaN(1); }, function failWorks() { var excep = null; try { fail("Failure message"); } catch (e) { excep = e; } assertJsUnitException("fail(string) should throw a JsUnitException", excep); }, function tooFewArguments() { var excep = null; try { assert(); } catch (e1) { excep = e1; } assertNonJsUnitException("Calling an assertion function with too few arguments should throw an exception", excep); }, function tooManyArguments() { var excep = null; try { assertEquals("A comment", true, true, true); } catch (e2) { excep = e2; } assertNonJsUnitException("Calling an assertion function with too many arguments should throw an exception", excep); }, function invalidCommentArgumentType() { var excep = null; try { assertNull(1, true); } catch (e3) { excep = e3; } assertNonJsUnitException("Calling an assertion function with a non-string comment should throw an exception", excep); }, function invalidArgumentType() { var excep = null; try { assert("string"); } catch (e) { excep = e; } assertNonJsUnitException("Calling an assertion function with an invalid argument should throw an exception", excep); }, function assertArrayEqualsWorks() { var array1 = ["foo", "bar", "foobar"]; var array2 = ["foo", "bar", "foobar"]; var array3 = ["foo", "bar"]; var array4 = ["bar", "foo", "foobar"]; assertArrayEquals([undefined],[undefined]); assertArrayEquals(array1, array1); assertArrayEquals(array1, array2); try { assertArrayEquals(array1, undefined); fail("Should not be equal to undefined"); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.comment == "Call to fail()") fail(e.comment + e.testMessage); //tried fail is also caught } try { assertArrayEquals(array1, array3); fail("Should not be equal"); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.comment == "Call to fail()") fail(e.comment + e.testMessage); //tried fail is also caught } try { assertArrayEquals(array1, array4); fail("Should not be equal"); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.comment == "Call to fail()") fail(e.comment + e.testMessage); //tried fail is also caught } var array5 = ['foo', 'bar', ['nested', 'bar'], 'foobar']; var array6 = ['foo', 'bar', ['nested', 'bar'], 'foobar']; var array7 = ['foo', 'bar', ['nested', 'foo'], 'foobar']; assertArrayEquals('Equal nested arrays', array5, array6); try { assertArrayEquals(array5, array7); var failure = 'Differing nested arrays found to be equal'; fail(failure); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } }, function assertObjectEqualsWorksOnObjects() { var failure; assertObjectEquals(undefined, undefined); var o1 = {foo:'bar'}; var o2 = {foo:'bar'}; assertObjectEquals('Single object', o1, o1); assertObjectEquals('Same objects', o1, o2); var o3 = {foo:'foo'}; var o4 = {foo:'foo', bar: function () { this.foo = 'bar'; delete this.bar; }}; var o5 = {foo:'foo', bar: function () { this.foo = 'foo'; delete this.bar; }}; try { assertObjectEquals(o1, o3); fail(failure = 'Simple differing objects found to be the same'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testtMessage); } try { assertObjectEquals(o3, o4); fail(failure = 'Object with additional fields found to be the same with non-grown one.'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } try { assertObjectEquals(o4, o5); fail(failure = 'Objects with different methods found to be the same'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } o4.bar(); assertObjectEquals('Different objects, made to be the same', o1, o4); try { assertObjectEquals({ts:new Date()}, {ts:new Date()}); fail(failure = 'Objects with different Date attributes found to be the same'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } try { assertObjectEquals(new Date(), new Date()); fail(failure = 'Different Date objects found to be the same'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } assertObjectEquals(/a/, new RegExp('a')); assertObjectEquals(/a/i, new RegExp('a', 'i')); assertObjectEquals(function(a,b){return a+b;}, function(a,b){return a+b;}); //XXX challenge for the future //assertObjectEquals(function(a,b){return a+b}, new Function("a","b","return a+b")); try { assertObjectEquals(/a/i, new RegExp('a', 'g')); fail(failure = 'RegExp with different flags found to be the same'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } try { assertObjectEquals(/a/, new RegExp('b')); fail(failure = 'RegExp with different patterns found to be the same'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } }, function assertObjectEqualsWorksOnStrings() { var s1 = 'string1'; var s2 = 'string1'; var newS1 = new String('string1'); assertObjectEquals('Same Strings', s1, s2); assertObjectEquals('Same Strings 1 with new', s1, newS1); }, function assertObjectEqualsWorksOnNumbers() { var failure; var n1 = 1; var n2 = 1; var newN1 = new Number(1); assertObjectEquals('Same Numbers', n1, n2); assertObjectEquals('Same Numbers 1 with new', n1, newN1); var n3 = 2; var newN3 = new Number(2); try { assertObjectEquals(n1, n3); fail(failure = 'Different Numbers'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } try { assertObjectEquals(newN1, newN3); fail(failure = 'Different New Numbers'); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); if (e.testMessage == failure) fail(e.testMessage); } }, function assertEvaluatesToTrueWorks() { assertEvaluatesToTrue("foo"); assertEvaluatesToTrue(true); assertEvaluatesToTrue(1); try { assertEvaluatesToTrue(null); fail("Should have thrown a JsUnitException"); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); } }, function assertEvaluatesToFalseWorks() { assertEvaluatesToFalse(""); assertEvaluatesToFalse(null); assertEvaluatesToFalse(false); assertEvaluatesToFalse(0); try { assertEvaluatesToFalse("foo"); fail("Should have thrown a JsUnitException"); } catch (e) { assertJsUnitException("Should be a JsUnitException", e); } }, function assertHtmlEqualsWorks() { assertHTMLEquals("
foobar
", "
foobar
"); assertHTMLEquals("

", "

"); assertHTMLEquals("foo bar", "foo bar"); assertHTMLEquals("a comment", "

foo bar

", "

foo bar

"); }, function assertHashEqualsWorks() { var hash1 = new Array(); hash1["key1"] = "value1"; hash1["key2"] = "value2"; var hash2 = new Array(); try { assertHashEquals(hash1, hash2); fail(); } catch (e) { assertJsUnitException("hash2 is empty", e); } hash2["key1"] = "value1"; try { assertHashEquals(hash1, hash2); fail(); } catch (e) { assertJsUnitException("hash2 is a of a different size", e); } hash2["key2"] = "foo"; try { assertHashEquals(hash1, hash2); fail(); } catch (e) { assertJsUnitException("hash2 has different values", e); } hash2["key2"] = "value2"; assertHashEquals(hash1, hash2); }, function assertRoughlyEqualsWorks() { assertRoughlyEquals(1, 1.1, 0.5); assertRoughlyEquals(1, 5, 6); assertRoughlyEquals(-4, -5, 2); assertRoughlyEquals(-0.5, 0.1, 0.7); try { assertRoughlyEquals(1, 2, 0.5); } catch (e) { assertJsUnitException("1 and 2 are more than 0.5 apart", e); } }, function assertContainsWorks() { assertContains("foo", "foobar"); assertContains("ooba", "foobar"); assertContains("bar", "foobar"); }, ]; /**@ignore*/ function FooBarThingy() { this.foo = 'bar'; } /**@ignore*/ FooBarThingy.prototype.bar = function() { return this.foo; }; page.testSuite.push(function testTrueTypeOf() { assertEquals('Boolean', jsuTrueTypeOf(true)); assertEquals('Using new', 'Boolean', jsuTrueTypeOf(new Boolean('1'))); assertEquals('Number', jsuTrueTypeOf(1)); var GI = new Number(1); assertEquals('Using new', 'Number', jsuTrueTypeOf(GI)); assertEquals('Number', jsuTrueTypeOf(1.5)); assertEquals('String', jsuTrueTypeOf('foo')); assertEquals('Using new', 'String', jsuTrueTypeOf(new String('foo'))); assertEquals('Using new', 'Function', jsuTrueTypeOf(new Function())); assertEquals('Function', jsuTrueTypeOf(function foo() {})); assertEquals('Function', jsuTrueTypeOf(testTrueTypeOf)); assertEquals('RegExp', jsuTrueTypeOf(/foo/)); assertEquals('Using new', 'RegExp', jsuTrueTypeOf(new RegExp('foo'))); var o = {foo: 'bar'}; assertEquals('Object', jsuTrueTypeOf(o)); var o = new FooBarThingy(); assertEquals('FooBarThingy', jsuTrueTypeOf(o)); assertEquals('String', jsuTrueTypeOf(o.foo)); assertEquals('String', jsuTrueTypeOf(o.bar())); assertEquals('Function', jsuTrueTypeOf(o.bar)); assertEquals('Object without constructor', 'Object', jsuTrueTypeOf(appjet)); }); import("lib-support/runner"); runTestsByDefault();