534 lines
18 KiB
JavaScript
534 lines
18 KiB
JavaScript
var JSUNIT_UNDEFINED_VALUE;
|
|
var JSUNIT_VERSION = 2.2;
|
|
var isTestPageLoaded = false;
|
|
|
|
//hack for NS62 bug
|
|
function jsUnitFixTop() {
|
|
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) {
|
|
}
|
|
}
|
|
|
|
jsUnitFixTop();
|
|
|
|
/**
|
|
+ * A more functional typeof
|
|
+ * @param Object o
|
|
+ * @return String
|
|
+ */
|
|
function _trueTypeOf(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 || aVar === top.JSUNIT_UNDEFINED_VALUE)) {
|
|
result += ' (' + _trueTypeOf(aVar) + ')';
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function fail(failureMessage) {
|
|
throw new JsUnitException("Call to fail()", failureMessage);
|
|
}
|
|
|
|
function error(errorMessage) {
|
|
var errorObject = new Object();
|
|
errorObject.description = errorMessage;
|
|
errorObject.stackTrace = getStackTrace();
|
|
throw errorObject;
|
|
}
|
|
|
|
function argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) {
|
|
return args.length == expectedNumberOfNonCommentArgs + 1;
|
|
}
|
|
|
|
function commentArg(expectedNumberOfNonCommentArgs, args) {
|
|
if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args))
|
|
return args[0];
|
|
|
|
return null;
|
|
}
|
|
|
|
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');
|
|
}
|
|
|
|
function _assert(comment, booleanValue, failureMessage) {
|
|
if (!booleanValue)
|
|
throw new JsUnitException(comment, failureMessage);
|
|
}
|
|
|
|
function assert() {
|
|
_validateArguments(1, arguments);
|
|
var booleanValue = nonCommentArg(1, 1, arguments);
|
|
|
|
if (typeof(booleanValue) != 'boolean')
|
|
error('Bad argument to assert(boolean)');
|
|
|
|
_assert(commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false');
|
|
}
|
|
|
|
function assertTrue() {
|
|
_validateArguments(1, arguments);
|
|
var booleanValue = nonCommentArg(1, 1, arguments);
|
|
|
|
if (typeof(booleanValue) != 'boolean')
|
|
error('Bad argument to assertTrue(boolean)');
|
|
|
|
_assert(commentArg(1, arguments), booleanValue === true, 'Call to assertTrue(boolean) with false');
|
|
}
|
|
|
|
function assertFalse() {
|
|
_validateArguments(1, arguments);
|
|
var booleanValue = nonCommentArg(1, 1, arguments);
|
|
|
|
if (typeof(booleanValue) != 'boolean')
|
|
error('Bad argument to assertFalse(boolean)');
|
|
|
|
_assert(commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true');
|
|
}
|
|
|
|
function assertEquals() {
|
|
_validateArguments(2, arguments);
|
|
var var1 = nonCommentArg(1, 2, arguments);
|
|
var var2 = nonCommentArg(2, 2, arguments);
|
|
_assert(commentArg(2, arguments), var1 === var2, 'Expected ' + _displayStringForValue(var1) + ' but was ' + _displayStringForValue(var2));
|
|
}
|
|
|
|
function assertNotEquals() {
|
|
_validateArguments(2, arguments);
|
|
var var1 = nonCommentArg(1, 2, arguments);
|
|
var var2 = nonCommentArg(2, 2, arguments);
|
|
_assert(commentArg(2, arguments), var1 !== var2, 'Expected not to be ' + _displayStringForValue(var2));
|
|
}
|
|
|
|
function assertNull() {
|
|
_validateArguments(1, arguments);
|
|
var aVar = nonCommentArg(1, 1, arguments);
|
|
_assert(commentArg(1, arguments), aVar === null, 'Expected ' + _displayStringForValue(null) + ' but was ' + _displayStringForValue(aVar));
|
|
}
|
|
|
|
function assertNotNull() {
|
|
_validateArguments(1, arguments);
|
|
var aVar = nonCommentArg(1, 1, arguments);
|
|
_assert(commentArg(1, arguments), aVar !== null, 'Expected not to be ' + _displayStringForValue(null));
|
|
}
|
|
|
|
function assertUndefined() {
|
|
_validateArguments(1, arguments);
|
|
var aVar = nonCommentArg(1, 1, arguments);
|
|
_assert(commentArg(1, arguments), aVar === top.JSUNIT_UNDEFINED_VALUE, 'Expected ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE) + ' but was ' + _displayStringForValue(aVar));
|
|
}
|
|
|
|
function assertNotUndefined() {
|
|
_validateArguments(1, arguments);
|
|
var aVar = nonCommentArg(1, 1, arguments);
|
|
_assert(commentArg(1, arguments), aVar !== top.JSUNIT_UNDEFINED_VALUE, 'Expected not to be ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE));
|
|
}
|
|
|
|
function assertNaN() {
|
|
_validateArguments(1, arguments);
|
|
var aVar = nonCommentArg(1, 1, arguments);
|
|
_assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN');
|
|
}
|
|
|
|
function assertNotNaN() {
|
|
_validateArguments(1, arguments);
|
|
var aVar = nonCommentArg(1, 1, arguments);
|
|
_assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN');
|
|
}
|
|
|
|
function assertObjectEquals() {
|
|
_validateArguments(2, arguments);
|
|
var var1 = nonCommentArg(1, 2, arguments);
|
|
var var2 = nonCommentArg(2, 2, arguments);
|
|
var type;
|
|
var msg = commentArg(2, arguments)?commentArg(2, arguments):'';
|
|
var isSame = (var1 === var2);
|
|
//shortpath for references to same object
|
|
var isEqual = ( (type = _trueTypeOf(var1)) == _trueTypeOf(var2) );
|
|
if (isEqual && !isSame) {
|
|
switch (type) {
|
|
case 'String':
|
|
case 'Number':
|
|
isEqual = (var1 == var2);
|
|
break;
|
|
case 'Boolean':
|
|
case 'Date':
|
|
isEqual = (var1 === var2);
|
|
break;
|
|
case 'RegExp':
|
|
case 'Function':
|
|
isEqual = (var1.toString() === var2.toString());
|
|
break;
|
|
default: //Object | Array
|
|
var i;
|
|
if (isEqual = (var1.length === var2.length))
|
|
for (i in var1)
|
|
assertObjectEquals(msg + ' found nested ' + type + '@' + i + '\n', var1[i], var2[i]);
|
|
}
|
|
_assert(msg, isEqual, 'Expected ' + _displayStringForValue(var1) + ' but was ' + _displayStringForValue(var2));
|
|
}
|
|
}
|
|
|
|
assertArrayEquals = assertObjectEquals;
|
|
|
|
function assertEvaluatesToTrue() {
|
|
_validateArguments(1, arguments);
|
|
var value = nonCommentArg(1, 1, arguments);
|
|
if (!value)
|
|
fail(commentArg(1, arguments));
|
|
}
|
|
|
|
function assertEvaluatesToFalse() {
|
|
_validateArguments(1, arguments);
|
|
var value = nonCommentArg(1, 1, arguments);
|
|
if (value)
|
|
fail(commentArg(1, arguments));
|
|
}
|
|
|
|
function assertHTMLEquals() {
|
|
_validateArguments(2, arguments);
|
|
var var1 = nonCommentArg(1, 2, arguments);
|
|
var var2 = nonCommentArg(2, 2, arguments);
|
|
var var1Standardized = standardizeHTML(var1);
|
|
var var2Standardized = standardizeHTML(var2);
|
|
|
|
_assert(commentArg(2, arguments), var1Standardized === var2Standardized, 'Expected ' + _displayStringForValue(var1Standardized) + ' but was ' + _displayStringForValue(var2Standardized));
|
|
}
|
|
|
|
function assertHashEquals() {
|
|
_validateArguments(2, arguments);
|
|
var var1 = nonCommentArg(1, 2, arguments);
|
|
var var2 = 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]);
|
|
}
|
|
}
|
|
|
|
function assertRoughlyEquals() {
|
|
_validateArguments(3, arguments);
|
|
var expected = nonCommentArg(1, 3, arguments);
|
|
var actual = nonCommentArg(2, 3, arguments);
|
|
var tolerance = nonCommentArg(3, 3, arguments);
|
|
assertTrue(
|
|
"Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away",
|
|
Math.abs(expected - actual) < tolerance
|
|
);
|
|
}
|
|
|
|
function assertContains() {
|
|
_validateArguments(2, arguments);
|
|
var contained = nonCommentArg(1, 2, arguments);
|
|
var container = nonCommentArg(2, 2, arguments);
|
|
assertTrue(
|
|
"Expected '" + container + "' to contain '" + contained + "'",
|
|
container.indexOf(contained) != -1
|
|
);
|
|
}
|
|
|
|
function standardizeHTML(html) {
|
|
var translator = document.createElement("DIV");
|
|
translator.innerHTML = html;
|
|
return translator.innerHTML;
|
|
}
|
|
|
|
function isLoaded() {
|
|
return isTestPageLoaded;
|
|
}
|
|
|
|
function setUp() {
|
|
}
|
|
|
|
function tearDown() {
|
|
}
|
|
|
|
function getFunctionName(aFunction) {
|
|
var regexpResult = aFunction.toString().match(/function(\s*)(\w*)/);
|
|
if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) {
|
|
return regexpResult[2];
|
|
}
|
|
return 'anonymous';
|
|
}
|
|
|
|
function getStackTrace() {
|
|
var result = '';
|
|
|
|
if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA
|
|
for (var a = arguments.caller; a != null; a = a.caller) {
|
|
result += '> ' + 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
|
|
var testExcp;
|
|
try
|
|
{
|
|
foo.bar;
|
|
}
|
|
catch(testExcp)
|
|
{
|
|
var stack = parseErrorStack(testExcp);
|
|
for (var i = 1; i < stack.length; i++)
|
|
{
|
|
result += '> ' + stack[i] + '\n';
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function parseErrorStack(excp)
|
|
{
|
|
var stack = [];
|
|
var name;
|
|
|
|
if (!excp || !excp.stack)
|
|
{
|
|
return stack;
|
|
}
|
|
|
|
var stacklist = excp.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;
|
|
}
|
|
|
|
function JsUnitException(comment, message) {
|
|
this.isJsUnitException = true;
|
|
this.comment = comment;
|
|
this.jsUnitMessage = message;
|
|
this.stackTrace = getStackTrace();
|
|
}
|
|
|
|
function warn() {
|
|
if (top.tracer != null)
|
|
top.tracer.warn(arguments[0], arguments[1]);
|
|
}
|
|
|
|
function inform() {
|
|
if (top.tracer != null)
|
|
top.tracer.inform(arguments[0], arguments[1]);
|
|
}
|
|
|
|
function info() {
|
|
inform(arguments[0], arguments[1]);
|
|
}
|
|
|
|
function debug() {
|
|
if (top.tracer != null)
|
|
top.tracer.debug(arguments[0], arguments[1]);
|
|
}
|
|
|
|
function setJsUnitTracer(aJsUnitTracer) {
|
|
top.tracer = aJsUnitTracer;
|
|
}
|
|
|
|
function trim(str) {
|
|
if (str == null)
|
|
return null;
|
|
|
|
var startingIndex = 0;
|
|
var endingIndex = str.length - 1;
|
|
|
|
while (str.substring(startingIndex, startingIndex + 1) == ' ')
|
|
startingIndex++;
|
|
|
|
while (str.substring(endingIndex, endingIndex + 1) == ' ')
|
|
endingIndex--;
|
|
|
|
if (endingIndex < startingIndex)
|
|
return '';
|
|
|
|
return str.substring(startingIndex, endingIndex + 1);
|
|
}
|
|
|
|
function isBlank(str) {
|
|
return trim(str) == '';
|
|
}
|
|
|
|
// the functions push(anArray, anObject) and pop(anArray)
|
|
// exist because the JavaScript Array.push(anObject) and Array.pop()
|
|
// functions are not available in IE 5.0
|
|
|
|
function push(anArray, anObject) {
|
|
anArray[anArray.length] = anObject;
|
|
}
|
|
function pop(anArray) {
|
|
if (anArray.length >= 1) {
|
|
delete anArray[anArray.length - 1];
|
|
anArray.length--;
|
|
}
|
|
}
|
|
|
|
function jsUnitGetParm(name)
|
|
{
|
|
if (typeof(top.jsUnitParmHash[name]) != 'undefined')
|
|
{
|
|
return top.jsUnitParmHash[name];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
if (top && typeof(top.xbDEBUG) != 'undefined' && top.xbDEBUG.on && top.testManager)
|
|
{
|
|
top.xbDebugTraceObject('top.testManager.containerTestFrame', 'JSUnitException');
|
|
// asserts
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_displayStringForValue');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'error');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'argumentsIncludeComments');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'commentArg');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'nonCommentArg');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_validateArguments');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_assert');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assert');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertTrue');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertEquals');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotEquals');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNull');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNull');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertUndefined');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotUndefined');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNaN');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNaN');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isLoaded');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setUp');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'tearDown');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getFunctionName');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getStackTrace');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'warn');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'inform');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'debug');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setJsUnitTracer');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'trim');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isBlank');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'newOnLoadEvent');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'push');
|
|
top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'pop');
|
|
}
|
|
|
|
function newOnLoadEvent() {
|
|
isTestPageLoaded = true;
|
|
}
|
|
|
|
function jsUnitSetOnLoad(windowRef, onloadHandler)
|
|
{
|
|
var isKonqueror = navigator.userAgent.indexOf('Konqueror/') != -1 ||
|
|
navigator.userAgent.indexOf('Safari/') != -1;
|
|
|
|
if (typeof(windowRef.attachEvent) != 'undefined') {
|
|
// Internet Explorer, Opera
|
|
windowRef.attachEvent("onload", onloadHandler);
|
|
} else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror) {
|
|
// Mozilla, Konqueror
|
|
// exclude Konqueror due to load issues
|
|
windowRef.addEventListener("load", onloadHandler, false);
|
|
} else if (typeof(windowRef.document.addEventListener) != 'undefined' && !isKonqueror) {
|
|
// DOM 2 Events
|
|
// exclude Mozilla, Konqueror due to load issues
|
|
windowRef.document.addEventListener("load", onloadHandler, false);
|
|
} else if (typeof(windowRef.onload) != 'undefined' && windowRef.onload) {
|
|
windowRef.jsunit_original_onload = windowRef.onload;
|
|
windowRef.onload = function() {
|
|
windowRef.jsunit_original_onload();
|
|
onloadHandler();
|
|
};
|
|
} else {
|
|
// browsers that do not support windowRef.attachEvent or
|
|
// windowRef.addEventListener will override a page's own onload event
|
|
windowRef.onload = onloadHandler;
|
|
}
|
|
}
|
|
|
|
jsUnitSetOnLoad(window, newOnLoadEvent); |