1var JSUNIT_UNDEFINED_VALUE; 2var JSUNIT_VERSION = 2.2; 3var isTestPageLoaded = false; 4 5//hack for NS62 bug 6function jsUnitFixTop() { 7 var tempTop = top; 8 if (!tempTop) { 9 tempTop = window; 10 while (tempTop.parent) { 11 tempTop = tempTop.parent; 12 if (tempTop.top && tempTop.top.jsUnitTestSuite) { 13 tempTop = tempTop.top; 14 break; 15 } 16 } 17 } 18 try { 19 window.top = tempTop; 20 } catch (e) { 21 } 22} 23 24jsUnitFixTop(); 25 26/** 27 + * A more functional typeof 28 + * @param Object o 29 + * @return String 30 + */ 31function _trueTypeOf(something) { 32 var result = typeof something; 33 try { 34 switch (result) { 35 case 'string': 36 case 'boolean': 37 case 'number': 38 break; 39 case 'object': 40 case 'function': 41 switch (something.constructor) 42 { 43 case String: 44 result = 'String'; 45 break; 46 case Boolean: 47 result = 'Boolean'; 48 break; 49 case Number: 50 result = 'Number'; 51 break; 52 case Array: 53 result = 'Array'; 54 break; 55 case RegExp: 56 result = 'RegExp'; 57 break; 58 case Function: 59 result = 'Function'; 60 break; 61 default: 62 var m = something.constructor.toString().match(/function\s*([^( ]+)\(/); 63 if (m) 64 result = m[1]; 65 else 66 break; 67 } 68 break; 69 } 70 } 71 finally { 72 result = result.substr(0, 1).toUpperCase() + result.substr(1); 73 return result; 74 } 75} 76 77function _displayStringForValue(aVar) { 78 var result = '<' + aVar + '>'; 79 if (!(aVar === null || aVar === top.JSUNIT_UNDEFINED_VALUE)) { 80 result += ' (' + _trueTypeOf(aVar) + ')'; 81 } 82 return result; 83} 84 85function fail(failureMessage) { 86 throw new JsUnitException("Call to fail()", failureMessage); 87} 88 89function error(errorMessage) { 90 var errorObject = new Object(); 91 errorObject.description = errorMessage; 92 errorObject.stackTrace = getStackTrace(); 93 throw errorObject; 94} 95 96function argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) { 97 return args.length == expectedNumberOfNonCommentArgs + 1; 98} 99 100function commentArg(expectedNumberOfNonCommentArgs, args) { 101 if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) 102 return args[0]; 103 104 return null; 105} 106 107function nonCommentArg(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) { 108 return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ? 109 args[desiredNonCommentArgIndex] : 110 args[desiredNonCommentArgIndex - 1]; 111} 112 113function _validateArguments(expectedNumberOfNonCommentArgs, args) { 114 if (!( args.length == expectedNumberOfNonCommentArgs || 115 (args.length == expectedNumberOfNonCommentArgs + 1 && typeof(args[0]) == 'string') )) 116 error('Incorrect arguments passed to assert function'); 117} 118 119function _assert(comment, booleanValue, failureMessage) { 120 if (!booleanValue) 121 throw new JsUnitException(comment, failureMessage); 122} 123 124function assert() { 125 _validateArguments(1, arguments); 126 var booleanValue = nonCommentArg(1, 1, arguments); 127 128 if (typeof(booleanValue) != 'boolean') 129 error('Bad argument to assert(boolean)'); 130 131 _assert(commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false'); 132} 133 134function assertTrue() { 135 _validateArguments(1, arguments); 136 var booleanValue = nonCommentArg(1, 1, arguments); 137 138 if (typeof(booleanValue) != 'boolean') 139 error('Bad argument to assertTrue(boolean)'); 140 141 _assert(commentArg(1, arguments), booleanValue === true, 'Call to assertTrue(boolean) with false'); 142} 143 144function assertFalse() { 145 _validateArguments(1, arguments); 146 var booleanValue = nonCommentArg(1, 1, arguments); 147 148 if (typeof(booleanValue) != 'boolean') 149 error('Bad argument to assertFalse(boolean)'); 150 151 _assert(commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true'); 152} 153 154function assertEquals() { 155 _validateArguments(2, arguments); 156 var var1 = nonCommentArg(1, 2, arguments); 157 var var2 = nonCommentArg(2, 2, arguments); 158 _assert(commentArg(2, arguments), var1 === var2, 'Expected ' + _displayStringForValue(var1) + ' but was ' + _displayStringForValue(var2)); 159} 160 161function assertNotEquals() { 162 _validateArguments(2, arguments); 163 var var1 = nonCommentArg(1, 2, arguments); 164 var var2 = nonCommentArg(2, 2, arguments); 165 _assert(commentArg(2, arguments), var1 !== var2, 'Expected not to be ' + _displayStringForValue(var2)); 166} 167 168function assertNull() { 169 _validateArguments(1, arguments); 170 var aVar = nonCommentArg(1, 1, arguments); 171 _assert(commentArg(1, arguments), aVar === null, 'Expected ' + _displayStringForValue(null) + ' but was ' + _displayStringForValue(aVar)); 172} 173 174function assertNotNull() { 175 _validateArguments(1, arguments); 176 var aVar = nonCommentArg(1, 1, arguments); 177 _assert(commentArg(1, arguments), aVar !== null, 'Expected not to be ' + _displayStringForValue(null)); 178} 179 180function assertUndefined() { 181 _validateArguments(1, arguments); 182 var aVar = nonCommentArg(1, 1, arguments); 183 _assert(commentArg(1, arguments), aVar === top.JSUNIT_UNDEFINED_VALUE, 'Expected ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE) + ' but was ' + _displayStringForValue(aVar)); 184} 185 186function assertNotUndefined() { 187 _validateArguments(1, arguments); 188 var aVar = nonCommentArg(1, 1, arguments); 189 _assert(commentArg(1, arguments), aVar !== top.JSUNIT_UNDEFINED_VALUE, 'Expected not to be ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE)); 190} 191 192function assertNaN() { 193 _validateArguments(1, arguments); 194 var aVar = nonCommentArg(1, 1, arguments); 195 _assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN'); 196} 197 198function assertNotNaN() { 199 _validateArguments(1, arguments); 200 var aVar = nonCommentArg(1, 1, arguments); 201 _assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN'); 202} 203 204function assertObjectEquals() { 205 _validateArguments(2, arguments); 206 var var1 = nonCommentArg(1, 2, arguments); 207 var var2 = nonCommentArg(2, 2, arguments); 208 var type; 209 var msg = commentArg(2, arguments)?commentArg(2, arguments):''; 210 var isSame = (var1 === var2); 211 //shortpath for references to same object 212 var isEqual = ( (type = _trueTypeOf(var1)) == _trueTypeOf(var2) ); 213 if (isEqual && !isSame) { 214 switch (type) { 215 case 'String': 216 case 'Number': 217 isEqual = (var1 == var2); 218 break; 219 case 'Boolean': 220 case 'Date': 221 isEqual = (var1 === var2); 222 break; 223 case 'RegExp': 224 case 'Function': 225 isEqual = (var1.toString() === var2.toString()); 226 break; 227 default: //Object | Array 228 var i; 229 if (isEqual = (var1.length === var2.length)) 230 for (i in var1) 231 assertObjectEquals(msg + ' found nested ' + type + '@' + i + '\n', var1[i], var2[i]); 232 } 233 _assert(msg, isEqual, 'Expected ' + _displayStringForValue(var1) + ' but was ' + _displayStringForValue(var2)); 234 } 235} 236 237assertArrayEquals = assertObjectEquals; 238 239function assertEvaluatesToTrue() { 240 _validateArguments(1, arguments); 241 var value = nonCommentArg(1, 1, arguments); 242 if (!value) 243 fail(commentArg(1, arguments)); 244} 245 246function assertEvaluatesToFalse() { 247 _validateArguments(1, arguments); 248 var value = nonCommentArg(1, 1, arguments); 249 if (value) 250 fail(commentArg(1, arguments)); 251} 252 253function assertHTMLEquals() { 254 _validateArguments(2, arguments); 255 var var1 = nonCommentArg(1, 2, arguments); 256 var var2 = nonCommentArg(2, 2, arguments); 257 var var1Standardized = standardizeHTML(var1); 258 var var2Standardized = standardizeHTML(var2); 259 260 _assert(commentArg(2, arguments), var1Standardized === var2Standardized, 'Expected ' + _displayStringForValue(var1Standardized) + ' but was ' + _displayStringForValue(var2Standardized)); 261} 262 263function assertHashEquals() { 264 _validateArguments(2, arguments); 265 var var1 = nonCommentArg(1, 2, arguments); 266 var var2 = nonCommentArg(2, 2, arguments); 267 for (var key in var1) { 268 assertNotUndefined("Expected hash had key " + key + " that was not found", var2[key]); 269 assertEquals( 270 "Value for key " + key + " mismatch - expected = " + var1[key] + ", actual = " + var2[key], 271 var1[key], var2[key] 272 ); 273 } 274 for (var key in var2) { 275 assertNotUndefined("Actual hash had key " + key + " that was not expected", var1[key]); 276 } 277} 278 279function assertRoughlyEquals() { 280 _validateArguments(3, arguments); 281 var expected = nonCommentArg(1, 3, arguments); 282 var actual = nonCommentArg(2, 3, arguments); 283 var tolerance = nonCommentArg(3, 3, arguments); 284 assertTrue( 285 "Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away", 286 Math.abs(expected - actual) < tolerance 287 ); 288} 289 290function assertContains() { 291 _validateArguments(2, arguments); 292 var contained = nonCommentArg(1, 2, arguments); 293 var container = nonCommentArg(2, 2, arguments); 294 assertTrue( 295 "Expected '" + container + "' to contain '" + contained + "'", 296 container.indexOf(contained) != -1 297 ); 298} 299 300function standardizeHTML(html) { 301 var translator = document.createElement("DIV"); 302 translator.innerHTML = html; 303 return translator.innerHTML; 304} 305 306function isLoaded() { 307 return isTestPageLoaded; 308} 309 310function setUp() { 311} 312 313function tearDown() { 314} 315 316function getFunctionName(aFunction) { 317 var regexpResult = aFunction.toString().match(/function(\s*)(\w*)/); 318 if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) { 319 return regexpResult[2]; 320 } 321 return 'anonymous'; 322} 323 324function getStackTrace() { 325 var result = ''; 326 327 if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA 328 for (var a = arguments.caller; a != null; a = a.caller) { 329 result += '> ' + getFunctionName(a.callee) + '\n'; 330 if (a.caller == a) { 331 result += '*'; 332 break; 333 } 334 } 335 } 336 else { // Mozilla, not ECMA 337 // fake an exception so we can get Mozilla's error stack 338 var testExcp; 339 try 340 { 341 foo.bar; 342 } 343 catch(testExcp) 344 { 345 var stack = parseErrorStack(testExcp); 346 for (var i = 1; i < stack.length; i++) 347 { 348 result += '> ' + stack[i] + '\n'; 349 } 350 } 351 } 352 353 return result; 354} 355 356function parseErrorStack(excp) 357{ 358 var stack = []; 359 var name; 360 361 if (!excp || !excp.stack) 362 { 363 return stack; 364 } 365 366 var stacklist = excp.stack.split('\n'); 367 368 for (var i = 0; i < stacklist.length - 1; i++) 369 { 370 var framedata = stacklist[i]; 371 372 name = framedata.match(/^(\w*)/)[1]; 373 if (!name) { 374 name = 'anonymous'; 375 } 376 377 stack[stack.length] = name; 378 } 379 // remove top level anonymous functions to match IE 380 381 while (stack.length && stack[stack.length - 1] == 'anonymous') 382 { 383 stack.length = stack.length - 1; 384 } 385 return stack; 386} 387 388function JsUnitException(comment, message) { 389 this.isJsUnitException = true; 390 this.comment = comment; 391 this.jsUnitMessage = message; 392 this.stackTrace = getStackTrace(); 393} 394 395function warn() { 396 if (top.tracer != null) 397 top.tracer.warn(arguments[0], arguments[1]); 398} 399 400function inform() { 401 if (top.tracer != null) 402 top.tracer.inform(arguments[0], arguments[1]); 403} 404 405function info() { 406 inform(arguments[0], arguments[1]); 407} 408 409function debug() { 410 if (top.tracer != null) 411 top.tracer.debug(arguments[0], arguments[1]); 412} 413 414function setJsUnitTracer(aJsUnitTracer) { 415 top.tracer = aJsUnitTracer; 416} 417 418function trim(str) { 419 if (str == null) 420 return null; 421 422 var startingIndex = 0; 423 var endingIndex = str.length - 1; 424 425 while (str.substring(startingIndex, startingIndex + 1) == ' ') 426 startingIndex++; 427 428 while (str.substring(endingIndex, endingIndex + 1) == ' ') 429 endingIndex--; 430 431 if (endingIndex < startingIndex) 432 return ''; 433 434 return str.substring(startingIndex, endingIndex + 1); 435} 436 437function isBlank(str) { 438 return trim(str) == ''; 439} 440 441// the functions push(anArray, anObject) and pop(anArray) 442// exist because the JavaScript Array.push(anObject) and Array.pop() 443// functions are not available in IE 5.0 444 445function push(anArray, anObject) { 446 anArray[anArray.length] = anObject; 447} 448function pop(anArray) { 449 if (anArray.length >= 1) { 450 delete anArray[anArray.length - 1]; 451 anArray.length--; 452 } 453} 454 455function jsUnitGetParm(name) 456{ 457 if (typeof(top.jsUnitParmHash[name]) != 'undefined') 458 { 459 return top.jsUnitParmHash[name]; 460 } 461 return null; 462} 463 464if (top && typeof(top.xbDEBUG) != 'undefined' && top.xbDEBUG.on && top.testManager) 465{ 466 top.xbDebugTraceObject('top.testManager.containerTestFrame', 'JSUnitException'); 467 // asserts 468 top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_displayStringForValue'); 469 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'error'); 470 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'argumentsIncludeComments'); 471 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'commentArg'); 472 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'nonCommentArg'); 473 top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_validateArguments'); 474 top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_assert'); 475 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assert'); 476 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertTrue'); 477 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertEquals'); 478 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotEquals'); 479 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNull'); 480 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNull'); 481 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertUndefined'); 482 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotUndefined'); 483 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNaN'); 484 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNaN'); 485 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isLoaded'); 486 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setUp'); 487 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'tearDown'); 488 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getFunctionName'); 489 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getStackTrace'); 490 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'warn'); 491 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'inform'); 492 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'debug'); 493 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setJsUnitTracer'); 494 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'trim'); 495 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isBlank'); 496 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'newOnLoadEvent'); 497 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'push'); 498 top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'pop'); 499} 500 501function newOnLoadEvent() { 502 isTestPageLoaded = true; 503} 504 505function jsUnitSetOnLoad(windowRef, onloadHandler) 506{ 507 var isKonqueror = navigator.userAgent.indexOf('Konqueror/') != -1 || 508 navigator.userAgent.indexOf('Safari/') != -1; 509 510 if (typeof(windowRef.attachEvent) != 'undefined') { 511 // Internet Explorer, Opera 512 windowRef.attachEvent("onload", onloadHandler); 513 } else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror) { 514 // Mozilla, Konqueror 515 // exclude Konqueror due to load issues 516 windowRef.addEventListener("load", onloadHandler, false); 517 } else if (typeof(windowRef.document.addEventListener) != 'undefined' && !isKonqueror) { 518 // DOM 2 Events 519 // exclude Mozilla, Konqueror due to load issues 520 windowRef.document.addEventListener("load", onloadHandler, false); 521 } else if (typeof(windowRef.onload) != 'undefined' && windowRef.onload) { 522 windowRef.jsunit_original_onload = windowRef.onload; 523 windowRef.onload = function() { 524 windowRef.jsunit_original_onload(); 525 onloadHandler(); 526 }; 527 } else { 528 // browsers that do not support windowRef.attachEvent or 529 // windowRef.addEventListener will override a page's own onload event 530 windowRef.onload = onloadHandler; 531 } 532} 533 534jsUnitSetOnLoad(window, newOnLoadEvent); 535 536top.JSUNIT_JSCORE_LOCATION = findPath('jsUnitCore.js'); 537/** 538 * return full path to the script 539 * 540 * @param {String} sname script name 541 * @return {String, Null} mixed string full path or null 542 * @scope public 543 */ 544function findPath (sname /* :String */) /* :String */{ 545 var sc = document.getElementsByTagName('script'), 546 sr = new RegExp('^(.*/|)('+sname+')([#?]|$)'); 547 for (var i=0,scL=sc.length; i<scL; i++) { 548 // matched desired script 549 var m = String(sc[i].src).match(sr); 550 if (m) { 551 /* 552 * we've matched the full path 553 */ 554 if (m[1].match(/^((https?|file)\:\/{2,}|\w:[\\])/)) return m[1]; 555 /* 556 * we've matched absolute path from the site root 557 */ 558 if (m[1].indexOf("/")==0) return m[1]; 559 b = document.getElementsByTagName('base'); 560 if (b[0] && b[0].href) return b[0].href+m[1]; 561 /* 562 * return matching part of the document location and path to js file 563 */ 564 return (document.location.pathname.match(/(.*[\/\\])/)[0]+m[1]).replace(/^\/+(?=\w:)/,""); 565 } 566 } 567 return null; 568}