welsonjs/lib/jsunit.js

1081 lines
34 KiB
JavaScript

/**
* @fileoverview
* jsUnitCore.js contains the implementation of the core JsUnit functionality: assertions, JsUnitTestSuites, and JsUnit.Failure.
* An HTML page is considered to be a JsUnit Test Page if it "includes" jsUnitCore.js, i.e. the following line is present:
* <code>
* &lt;script type="text/javascript" src="/path/to/jsUnitCore.js"&gt;&lt;/script&gt;
* </code>
* @author Edward Hieatt, edward@jsunit.net, http://www.jsunit.net
* @author Alexander Kuntashov, kuntashov@gmail.com, http://kuntashov.ru
* @author Go Namhyeon, gnh1201@gmail.com, https://catswords.re.kr/go/home
*/
var JsUnit = {};
/**
* The JsUnit version
* @version
*/
JsUnit.VERSION = 2.2;
var JSUNIT_VERSION = JsUnit.VERSION;
/**
* For convenience, a variable that equals "undefined"
*/
var JSUNIT_UNDEFINED_VALUE;
/**
* Whether or not the current test page has been (completely) loaded yet
*/
var isTestPageLoaded = false;
/**
* Predicate used for testing JavaScript == (i.e. equality excluding type)
*/
JsUnit.DOUBLE_EQUALITY_PREDICATE = function(var1, var2) {
return var1 == var2;
};
/**
* Predicate used for testing JavaScript === (i.e. equality including type)
*/
JsUnit.TRIPLE_EQUALITY_PREDICATE = function(var1, var2) {
return var1 === var2;
};
/**
* Predicate used for testing whether two obects' toStrings are equal
*/
JsUnit.TO_STRING_EQUALITY_PREDICATE = function(var1, var2) {
return var1.toString() === var2.toString();
};
/**
* Hash of predicates for testing equality by primitive type
*/
JsUnit.PRIMITIVE_EQUALITY_PREDICATES = {
'String': JsUnit.DOUBLE_EQUALITY_PREDICATE,
'Number': JsUnit.DOUBLE_EQUALITY_PREDICATE,
'Boolean': JsUnit.DOUBLE_EQUALITY_PREDICATE,
'Date': JsUnit.TRIPLE_EQUALITY_PREDICATE,
'RegExp': JsUnit.TO_STRING_EQUALITY_PREDICATE,
'Function': JsUnit.TO_STRING_EQUALITY_PREDICATE
}
/**
* Hack for NS62 bug
* @private
*/
JsUnit._fixTop = function() {
var tempTop = top;
if (!tempTop) {
tempTop = window;
while (tempTop.parent) {
tempTop = tempTop.parent;
if (tempTop.top && tempTop.top.jsUnitTestSuite) {
tempTop = tempTop.top;
break;
}
}
}
try {
window.top = tempTop;
} catch (e) {}
}
//Snegopat.
//JsUnit._fixTop();
/////Snegopat.
/**
* @param Any object
* @return String - the type of the given object
* @private
*/
JsUnit._trueTypeOf = function(something) {
var result = typeof something;
try {
switch (result) {
case 'string':
break;
case 'boolean':
break;
case 'number':
break;
case 'object':
case 'function':
switch (something.constructor) {
case new String().constructor:
result = 'String';
break;
case new Boolean().constructor:
result = 'Boolean';
break;
case new Number().constructor:
result = 'Number';
break;
case new Array().constructor:
result = 'Array';
break;
case new RegExp().constructor:
result = 'RegExp';
break;
case new Date().constructor:
result = 'Date';
break;
case Function:
result = 'Function';
break;
default:
if (something.constructor) {
var m = something.constructor.toString().match(/function\s*([^( ]+)\(/);
if (m)
result = m[1];
else
break;
} else
break;
}
break;
}
} finally {
result = result.substr(0, 1).toUpperCase() + result.substr(1);
return result;
}
}
/**
* @private
*/
JsUnit._displayStringForValue = function(aVar) {
var result = '<' + aVar + '>';
if (!(aVar === null || aVar === JSUNIT_UNDEFINED_VALUE)) {
result += ' (' + JsUnit._trueTypeOf(aVar) + ')';
}
return result;
}
/**
* @private
*/
JsUnit._argumentsIncludeComments = function(expectedNumberOfNonCommentArgs, args) {
return args.length == expectedNumberOfNonCommentArgs + 1;
}
/**
* @private
*/
JsUnit._commentArg = function(expectedNumberOfNonCommentArgs, args) {
if (JsUnit._argumentsIncludeComments(expectedNumberOfNonCommentArgs, args))
return args[0];
return null;
}
/**
* @private
*/
JsUnit._nonCommentArg = function(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) {
return JsUnit._argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ?
args[desiredNonCommentArgIndex] :
args[desiredNonCommentArgIndex - 1];
}
/**
* @private
*/
JsUnit._validateArguments = function(expectedNumberOfNonCommentArgs, args) {
if (!(args.length == expectedNumberOfNonCommentArgs ||
(args.length == expectedNumberOfNonCommentArgs + 1 && (typeof(args[0]) == 'string') || args[0] == null)))
throw new JsUnit.AssertionArgumentError('Incorrect arguments passed to assert function');
}
/**
* @private
*/
JsUnit._checkEquals = function(var1, var2) {
return var1 === var2;
}
/**
* @private
*/
JsUnit._checkNotUndefined = function(aVar) {
return aVar !== JSUNIT_UNDEFINED_VALUE;
}
/**
* @private
*/
JsUnit._checkNotNull = function(aVar) {
return aVar !== null;
}
/**
* All assertions ultimately go through this method.
* @private
*/
JsUnit._assert = function(comment, booleanValue, failureMessage) {
if (!booleanValue)
throw new JsUnit.Failure(comment, failureMessage);
}
/**
* Checks that the given boolean value is true.
* @param comment optional, displayed in the case of failure
* @value value that is expected to be true
* @throws JsUnit.Failure if the given value is not true
* @throws JsUnitInvalidAssertionArgument if the given value is not a boolean or if an incorrect number of arguments is passed
*/
function assert() {
JsUnit._validateArguments(1, arguments);
var booleanValue = JsUnit._nonCommentArg(1, 1, arguments);
if (typeof(booleanValue) != 'boolean')
throw new JsUnit.AssertionArgumentError('Bad argument to assert(boolean)');
JsUnit._assert(JsUnit._commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false');
}
/**
* Synonym for assertTrue
* @see #assert
*/
function assertTrue() {
JsUnit._validateArguments(1, arguments);
assert(JsUnit._commentArg(1, arguments), JsUnit._nonCommentArg(1, 1, arguments));
}
/**
* Checks that a boolean value is false.
* @param comment optional, displayed in the case of failure
* @value value that is expected to be false
* @throws JsUnit.Failure if value is not false
* @throws JsUnitInvalidAssertionArgument if the given value is not a boolean or if an incorrect number of arguments is passed
*/
function assertFalse() {
JsUnit._validateArguments(1, arguments);
var booleanValue = JsUnit._nonCommentArg(1, 1, arguments);
if (typeof(booleanValue) != 'boolean')
throw new JsUnit.AssertionArgumentError('Bad argument to assertFalse(boolean)');
JsUnit._assert(JsUnit._commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true');
}
/**
* Checks that two values are equal (using ===)
* @param comment optional, displayed in the case of failure
* @param expected the expected value
* @param actual the actual value
* @throws JsUnit.Failure if the values are not equal
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertEquals() {
JsUnit._validateArguments(2, arguments);
var var1 = JsUnit._nonCommentArg(1, 2, arguments);
var var2 = JsUnit._nonCommentArg(2, 2, arguments);
JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkEquals(var1, var2), 'Expected ' + JsUnit._displayStringForValue(var1) + ' but was ' + JsUnit._displayStringForValue(var2));
}
/**
* Checks that two values are not equal (using !==)
* @param comment optional, displayed in the case of failure
* @param value1 a value
* @param value2 another value
* @throws JsUnit.Failure if the values are equal
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertNotEquals() {
JsUnit._validateArguments(2, arguments);
var var1 = JsUnit._nonCommentArg(1, 2, arguments);
var var2 = JsUnit._nonCommentArg(2, 2, arguments);
JsUnit._assert(JsUnit._commentArg(2, arguments), var1 !== var2, 'Expected not to be ' + JsUnit._displayStringForValue(var2));
}
/**
* Checks that a value is null
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the value is not null
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertNull() {
JsUnit._validateArguments(1, arguments);
var aVar = JsUnit._nonCommentArg(1, 1, arguments);
JsUnit._assert(JsUnit._commentArg(1, arguments), aVar === null, 'Expected ' + JsUnit._displayStringForValue(null) + ' but was ' + JsUnit._displayStringForValue(aVar));
}
/**
* Checks that a value is not null
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the value is null
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertNotNull() {
JsUnit._validateArguments(1, arguments);
var aVar = JsUnit._nonCommentArg(1, 1, arguments);
JsUnit._assert(JsUnit._commentArg(1, arguments), JsUnit._checkNotNull(aVar), 'Expected not to be ' + JsUnit._displayStringForValue(null));
}
/**
* Checks that a value is undefined
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the value is not undefined
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertUndefined() {
JsUnit._validateArguments(1, arguments);
var aVar = JsUnit._nonCommentArg(1, 1, arguments);
JsUnit._assert(JsUnit._commentArg(1, arguments), aVar === JSUNIT_UNDEFINED_VALUE, 'Expected ' + JsUnit._displayStringForValue(JSUNIT_UNDEFINED_VALUE) + ' but was ' + JsUnit._displayStringForValue(aVar));
}
/**
* Checks that a value is not undefined
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the value is undefined
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertNotUndefined() {
JsUnit._validateArguments(1, arguments);
var aVar = JsUnit._nonCommentArg(1, 1, arguments);
JsUnit._assert(JsUnit._commentArg(1, arguments), JsUnit._checkNotUndefined(aVar), 'Expected not to be ' + JsUnit._displayStringForValue(JSUNIT_UNDEFINED_VALUE));
}
/**
* Checks that a value is NaN (Not a Number)
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the value is a number
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertNaN() {
JsUnit._validateArguments(1, arguments);
var aVar = JsUnit._nonCommentArg(1, 1, arguments);
JsUnit._assert(JsUnit._commentArg(1, arguments), isNaN(aVar), 'Expected NaN');
}
/**
* Checks that a value is not NaN (i.e. is a number)
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the value is not a number
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertNotNaN() {
JsUnit._validateArguments(1, arguments);
var aVar = JsUnit._nonCommentArg(1, 1, arguments);
JsUnit._assert(JsUnit._commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN');
}
/**
* Checks that an object is equal to another using === for primitives and their object counterparts but also desceding
* into collections and calling assertObjectEquals for each element
* @param comment optional, displayed in the case of failure
* @param value the expected value
* @param value the actual value
* @throws JsUnit.Failure if the actual value does not equal the expected value
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertObjectEquals() {
JsUnit._validateArguments(2, arguments);
var var1 = JsUnit._nonCommentArg(1, 2, arguments);
var var2 = JsUnit._nonCommentArg(2, 2, arguments);
var failureMessage = JsUnit._commentArg(2, arguments) ? JsUnit._commentArg(2, arguments) : '';
if (var1 === var2)
return;
var isEqual = false;
var typeOfVar1 = JsUnit._trueTypeOf(var1);
var typeOfVar2 = JsUnit._trueTypeOf(var2);
if (typeOfVar1 == typeOfVar2) {
var primitiveEqualityPredicate = JsUnit.PRIMITIVE_EQUALITY_PREDICATES[typeOfVar1];
if (primitiveEqualityPredicate) {
isEqual = primitiveEqualityPredicate(var1, var2);
} else {
var expectedKeys = JsUnit.Util.getKeys(var1).sort().join(", ");
var actualKeys = JsUnit.Util.getKeys(var2).sort().join(", ");
if (expectedKeys != actualKeys) {
JsUnit._assert(failureMessage, false, 'Expected keys "' + expectedKeys + '" but found "' + actualKeys + '"');
}
for (var i in var1) {
assertObjectEquals(failureMessage + ' found nested ' + typeOfVar1 + '@' + i + '\n', var1[i], var2[i]);
}
isEqual = true;
}
}
JsUnit._assert(failureMessage, isEqual, 'Expected ' + JsUnit._displayStringForValue(var1) + ' but was ' + JsUnit._displayStringForValue(var2));
}
/**
* Checks that an array is equal to another by checking that both are arrays and then comparing their elements using assertObjectEquals
* @param comment optional, displayed in the case of failure
* @param value the expected array
* @param value the actual array
* @throws JsUnit.Failure if the actual value does not equal the expected value
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertArrayEquals() {
JsUnit._validateArguments(2, arguments);
var array1 = JsUnit._nonCommentArg(1, 2, arguments);
var array2 = JsUnit._nonCommentArg(2, 2, arguments);
if (JsUnit._trueTypeOf(array1) != 'Array' || JsUnit._trueTypeOf(array2) != 'Array') {
throw new JsUnit.AssertionArgumentError('Non-array passed to assertArrayEquals');
}
assertObjectEquals(JsUnit._commentArg(2, arguments), JsUnit._nonCommentArg(1, 2, arguments), JsUnit._nonCommentArg(2, 2, arguments));
}
/**
* Checks that a value evaluates to true in the sense that value == true
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the actual value does not evaluate to true
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertEvaluatesToTrue() {
JsUnit._validateArguments(1, arguments);
var value = JsUnit._nonCommentArg(1, 1, arguments);
if (!value)
fail(JsUnit._commentArg(1, arguments));
}
/**
* Checks that a value evaluates to false in the sense that value == false
* @param comment optional, displayed in the case of failure
* @param value the value
* @throws JsUnit.Failure if the actual value does not evaluate to true
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertEvaluatesToFalse() {
JsUnit._validateArguments(1, arguments);
var value = JsUnit._nonCommentArg(1, 1, arguments);
if (value)
fail(JsUnit._commentArg(1, arguments));
}
/**
* Checks that a value is the same as an HTML string by "standardizing" both and comparing the result for equality.
* Standardizing is done by temporarily creating a DIV, setting the innerHTML of the DIV to the string, and asking for
* the innerHTML back.
* @param comment optional, displayed in the case of failure
* @param value1 the expected HTML string
* @param value2 the actual HTML string
* @throws JsUnit.Failure if the standardized actual value does not equal the standardized expected value
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertHTMLEquals() {
//Snegopat.
JsUnit.error("assertHTMLEquals() íå ïîääåðæèâàåòñÿ â Ñíåãîïàòå.");
//JsUnit._validateArguments(2, arguments);
//var var1 = JsUnit._nonCommentArg(1, 2, arguments);
//var var2 = JsUnit._nonCommentArg(2, 2, arguments);
//var var1Standardized = JsUnit.Util.standardizeHTML(var1);
//var var2Standardized = JsUnit.Util.standardizeHTML(var2);
//JsUnit._assert(JsUnit._commentArg(2, arguments), var1Standardized === var2Standardized, 'Expected ' + JsUnit._displayStringForValue(var1Standardized) + ' but was ' + JsUnit._displayStringForValue(var2Standardized));
/////Snegopat.
}
/**
* Checks that a hash is has the same contents as another by iterating over the expected hash and checking that each
* key's value is present in the actual hash and calling assertEquals on the two values, and then checking that there is
* no key in the actual hash that isn't present in the expected hash.
* @param comment optional, displayed in the case of failure
* @param value the expected hash
* @param value the actual hash
* @throws JsUnit.Failure if the actual hash does not evaluate to true
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertHashEquals() {
JsUnit._validateArguments(2, arguments);
var var1 = JsUnit._nonCommentArg(1, 2, arguments);
var var2 = JsUnit._nonCommentArg(2, 2, arguments);
for (var key in var1) {
assertNotUndefined("Expected hash had key " + key + " that was not found", var2[key]);
assertEquals(
"Value for key " + key + " mismatch - expected = " + var1[key] + ", actual = " + var2[key],
var1[key], var2[key]
);
}
for (var key in var2) {
assertNotUndefined("Actual hash had key " + key + " that was not expected", var1[key]);
}
}
/**
* Checks that two value are within a tolerance of one another
* @param comment optional, displayed in the case of failure
* @param value1 a value
* @param value1 another value
* @param tolerance the tolerance
* @throws JsUnit.Failure if the two values are not within tolerance of each other
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed
*/
function assertRoughlyEquals() {
JsUnit._validateArguments(3, arguments);
var expected = JsUnit._nonCommentArg(1, 3, arguments);
var actual = JsUnit._nonCommentArg(2, 3, arguments);
var tolerance = JsUnit._nonCommentArg(3, 3, arguments);
assertTrue(
"Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away",
Math.abs(expected - actual) < tolerance
);
}
/**
* Checks that a collection contains a value by checking that collection.indexOf(value) is not -1
* @param comment optional, displayed in the case of failure
* @param collection the collection
* @param value the value
* @throws JsUnit.Failure if the collection does not contain the value
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments are passed
*/
function assertContains() {
JsUnit._validateArguments(2, arguments);
var value = JsUnit._nonCommentArg(1, 2, arguments);
var collection = JsUnit._nonCommentArg(2, 2, arguments);
assertTrue(
"Expected '" + collection + "' to contain '" + value + "'",
collection.indexOf(value) != -1
);
}
/**
* Checks that two arrays have the same contents, ignoring the order of the contents
* @param comment optional, displayed in the case of failure
* @param array1 first array
* @param array2 second array
* @throws JsUnit.Failure if the two arrays contain different contents
* @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments are passed
*/
function assertArrayEqualsIgnoringOrder() {
JsUnit._validateArguments(2, arguments);
var var1 = JsUnit._nonCommentArg(1, 2, arguments);
var var2 = JsUnit._nonCommentArg(2, 2, arguments);
var notEqualsMessage = "Expected arrays " + JsUnit._displayStringForValue(var1) + " and " + JsUnit._displayStringForValue(var2) + " to be equal (ignoring order)";
var notArraysMessage = "Expected arguments " + JsUnit._displayStringForValue(var1) + " and " + JsUnit._displayStringForValue(var2) + " to be arrays";
JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotNull(var1), notEqualsMessage);
JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotNull(var2), notEqualsMessage);
JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var1.length), notArraysMessage);
JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var1.join), notArraysMessage);
JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var2.length), notArraysMessage);
JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var2.join), notArraysMessage);
JsUnit._assert(JsUnit._commentArg(1, arguments), JsUnit._checkEquals(var1.length, var2.length), notEqualsMessage);
for (var i = 0; i < var1.length; i++) {
var found = false;
for (var j = 0; j < var2.length; j++) {
try {
assertObjectEquals(notEqualsMessage, var1[i], var2[j]);
found = true;
} catch (ignored) {}
}
JsUnit._assert(JsUnit._commentArg(2, arguments), found, notEqualsMessage);
}
}
/**
* Synonym for assertArrayEqualsIgnoringOrder
* @see #assertArrayEqualsIgnoringOrder
*/
function assertEqualsIgnoringOrder() {
JsUnit._validateArguments(2, arguments);
assertArrayEqualsIgnoringOrder(JsUnit._commentArg(2, arguments), JsUnit._nonCommentArg(1, 2, arguments), JsUnit._nonCommentArg(2, 2, arguments));
}
/**
* Causes a failure
* @param failureMessage the message for the failure
*/
function fail(failureMessage) {
throw new JsUnit.Failure("Call to fail()", failureMessage);
}
/**
* Causes an error
* @param errorMessage the message for the error
*/
function error(errorMessage) {
throw new JsUnitError(errorMessage);
}
/**
* @class
* A JsUnit.Failure represents an assertion failure (or a call to fail()) during the execution of a Test Function
* @param comment an optional comment about the failure
* @param message the reason for the failure
*/
JsUnit.Failure = function(comment, message) {
/**
* Declaration that this is a JsUnit.Failure
* @ignore
*/
this.isJsUnitFailure = true;
/**
* An optional comment about the failure
*/
this.comment = comment;
/**
* The reason for the failure
*/
this.jsUnitMessage = message;
/**
* The stack trace at the point at which the failure was encountered
*/
this.stackTrace = JsUnit.Util.getStackTrace();
}
/**
* @deprecated
*/
JsUnitFailure = JsUnit.Failure;
/**
* @class
* A JsUnitError represents an error (an exception or a call to error()) during the execution of a Test Function
* @param description the reason for the failure
*/
JsUnit.Error = function(description) {
/**
* The description of the error
*/
this.description = description;
/**
* The stack trace at the point at which the error was encountered
*/
this.stackTrace = JsUnit.Util.getStackTrace();
}
/**
* @deprecated
*/
JsUnitError = JsUnit.Error;
/**
* @class
* A JsUnitAssertionArgumentError represents an invalid call to an assertion function - either an invalid argument type
* or an incorrect number of arguments
* @param description a description of the argument error
*/
JsUnit.AssertionArgumentError = function(description) {
/**
* A description of the argument error
*/
this.description = description;
}
function isLoaded() {
return isTestPageLoaded;
}
/**
* @private
*/
function setUp() {}
/**
* @private
*/
function tearDown() {}
function trace(message, value, marker) {
var text = message;
if (value)
text += ': ' + JsUnit._displayStringForValue(value);
WScript.Echo(text);
}
function warn() {
trace(arguments[0], arguments[1]);
}
function inform() {
trace(arguments[0], arguments[1]);
}
function info() {
trace(arguments[0], arguments[1]);
}
function debug() {
trace(arguments[0], arguments[1]);
}
/**
* @class
* A JsUnitTestSuite represents a suite of JsUnit Test Pages. Test Pages and Test Suites can be added to a
* JsUnitTestSuite
* @constructor
*/
function JsUnitTestSuite() {
/**
* Declares that this object is a JsUnitTestSuite
*/
this.isJsUnitTestSuite = true;
/**
* @private
*/
this._testPages = Array();
/**
* @private
*/
this._pageIndex = 0;
for (var i = 0; i < arguments.length; i++) {
if (arguments[i]._testPages) {
this.addTestSuite(arguments[i]);
} else {
this.addTestPage(arguments[i]);
}
}
}
/**
* Adds a Test Page to the suite
* @param pageName the path to the Test Page
*/
JsUnitTestSuite.prototype.addTestPage = function(page) {
this._testPages[this._testPages.length] = page;
}
/**
* Adds a Test Suite to the suite
* @param suite another JsUnitTestSuite object
*/
JsUnitTestSuite.prototype.addTestSuite = function(suite) {
for (var i = 0; i < suite._testPages.length; i++)
this.addTestPage(suite._testPages[i]);
}
/**
* Whether the suite contains any Test Pages
*/
JsUnitTestSuite.prototype.containsTestPages = function() {
return this._testPages.length > 0;
}
/**
* Moves the suite on to its next Test Page
*/
JsUnitTestSuite.prototype.nextPage = function() {
return this._testPages[this._pageIndex++];
}
/**
* Whether the suite has more Test Pages
*/
JsUnitTestSuite.prototype.hasMorePages = function() {
return this._pageIndex < this._testPages.length;
}
/**
* Produces a copy of the suite
*/
JsUnitTestSuite.prototype.clone = function() {
var clone = new JsUnitTestSuite();
clone._testPages = this._testPages;
return clone;
}
function setJsUnitTracer(aJsUnitTracer) {
top.tracer = aJsUnitTracer;
}
function jsUnitGetParm(name) {
return top.params.get(name);
}
JsUnit._newOnLoadEvent = function() {
isTestPageLoaded = true;
}
JsUnit._setOnLoad = function(windowRef, onloadHandler) {
JsUnit.fail("_setOnLoad() dose not supported");
}
/**
* @class
* @constructor
* Contains utility functions for the JsUnit framework
*/
JsUnit.Util = {};
/**
* Standardizes an HTML string by temporarily creating a DIV, setting its innerHTML to the string, and the asking for
* the innerHTML back
* @param html
*/
JsUnit.Util.standardizeHTML = function(html) {
JsUnit.fail("standardizeHTML() dose not supported");
}
/**
* Returns whether the given string is blank after being trimmed of whitespace
* @param string
*/
JsUnit.Util.isBlank = function(string) {
return JsUnit.Util.trim(string) == '';
}
/**
* Implemented here because the JavaScript Array.push(anObject) and Array.pop() functions are not available in IE 5.0
* @param anArray the array onto which to push
* @param anObject the object to push onto the array
*/
JsUnit.Util.push = function(anArray, anObject) {
anArray[anArray.length] = anObject;
}
/**
* Implemented here because the JavaScript Array.push(anObject) and Array.pop() functions are not available in IE 5.0
* @param anArray the array from which to pop
*/
JsUnit.Util.pop = function pop(anArray) {
if (anArray.length >= 1) {
delete anArray[anArray.length - 1];
anArray.length--;
}
}
/**
* Returns the name of the given function, or 'anonymous' if it has no name
* @param aFunction
*/
JsUnit.Util.getFunctionName = function(aFunction) {
var regexpResult = aFunction.toString().match(/function(\s*)(\w*)/);
if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) {
return regexpResult[2];
}
return 'anonymous';
}
/**
* Returns the current stack trace
*/
JsUnit.Util.getStackTrace = function() {
var result = '';
if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA
for (var a = arguments.caller; a != null; a = a.caller) {
result += '> ' + JsUnit.Util.getFunctionName(a.callee) + '\n';
if (a.caller == a) {
result += '*';
break;
}
}
} else { // Mozilla, not ECMA
// fake an exception so we can get Mozilla's error stack
try {
foo.bar;
} catch (exception) {
var stack = JsUnit.Util.parseErrorStack(exception);
for (var i = 1; i < stack.length; i++) {
result += '> ' + stack[i] + '\n';
}
}
}
return result;
}
/**
* Returns an array of stack trace elements from the given exception
* @param exception
*/
JsUnit.Util.parseErrorStack = function(exception) {
var stack = [];
var name;
if (!exception || !exception.stack) {
return stack;
}
var stacklist = exception.stack.split('\n');
for (var i = 0; i < stacklist.length - 1; i++) {
var framedata = stacklist[i];
name = framedata.match(/^(\w*)/)[1];
if (!name) {
name = 'anonymous';
}
stack[stack.length] = name;
}
// remove top level anonymous functions to match IE
while (stack.length && stack[stack.length - 1] == 'anonymous') {
stack.length = stack.length - 1;
}
return stack;
}
/**
* Strips whitespace from either end of the given string
* @param string
*/
JsUnit.Util.trim = function(string) {
if (string == null)
return null;
var startingIndex = 0;
var endingIndex = string.length - 1;
var singleWhitespaceRegex = /\s/;
while (string.substring(startingIndex, startingIndex + 1).match(singleWhitespaceRegex))
startingIndex++;
while (string.substring(endingIndex, endingIndex + 1).match(singleWhitespaceRegex))
endingIndex--;
if (endingIndex < startingIndex)
return '';
return string.substring(startingIndex, endingIndex + 1);
}
JsUnit.Util.getKeys = function(obj) {
var keys = [];
for (var key in obj) {
JsUnit.Util.push(keys, key);
}
return keys;
}
JsUnit.Util.inherit = function(superclass, subclass) {
var x = function() {};
x.prototype = superclass.prototype;
subclass.prototype = new x();
}
//Defines the top level Class
function Class() {}
Class.extend = function(def) {
var classDef = function() {
if (arguments[0] !== Class) {
this.construct.apply(this, arguments);
}
};
var _super = this.prototype;
var proto = new this(Class);
for (var n in def) {
var item = def[n];
if (typeof def[n] == "function" && /\b_super\b/.test(def[n])) {
proto[n] = (function(name, fn) {
return function() {
// 1.
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// 2.
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
// 3.
this._super = tmp;
return ret;
};
})(n, def[n]);
} else {
proto[n] = item;
}
}
classDef.prototype = proto;
// Enforce the constructor to be what we expect
classDef.prototype.constructor = Class;
//Give this new class the same static extend method
classDef.extend = this.extend;
return classDef;
};
JsUnit.Runner = {};
JsUnit.Runner.FSO = new ActiveXObject("Scripting.FileSystemObject");
JsUnit.Runner.runTest = function(path) {
var ts = JsUnit.Runner.FSO.OpenTextFile(path);
var testSource = ts.ReadAll();
ts.Close();
(function(source, jsu, cls) {
var testObj
try {
testObj = eval(source);
} catch (e) {
warn(path + ": " + e.description);
}
var re_test = /^test/;
for (var testName in testObj) {
if (re_test.test(testName)) {
JsUnit.Runner.safeRun(testObj, 'setUp');
JsUnit.Runner.safeRun(testObj, testName);
JsUnit.Runner.safeRun(testObj, 'tearDown');
}
}
})(testSource, JsUnit, Class);
}
JsUnit.Runner.safeRun = function(tObj, tName) {
if (typeof tObj[tName] == 'function') {
try {
tObj[tName].call();
} catch (e) {
var errMsg = e.comment ? e.comment : e.description;
if (e.comment) {
warn("--> " + tName + ": \n\t" + e.jsUnitMessage + "\n\t" + e.comment);
} else {
warn("--> " + tName + ": " + errMsg);
}
}
}
}
JsUnit.Runner.run = function(pathToTestDir) {
var fso = JsUnit.Runner.FSO;
var re_tests = /test.+?\.js$/i;
(function(root) {
var folder = fso.GetFolder(root);
var folders = new Enumerator(folder.SubFolders);
for (; !folders.atEnd(); folders.moveNext()) {
inform(folders.item().Path);
arguments.callee(loader, folders.item().Path);
}
var files = new Enumerator(folder.Files);
for (; !files.atEnd(); files.moveNext()) {
var file = files.item();
if (re_tests.test(file.Name)) {
inform(file.Name);
JsUnit.Runner.runTest(file.Path);
}
}
})(pathToTestDir);
}
exports.VERSIONINFO = "JSUnit Lib (jsunit.js) version 2.2";
exports.global = global;
exports.require = global.require;
exports.JsUnit = JsUnit;