rails_generators/javascript_test/templates/assets/jsunittest.js in newjs-1.7.2 vs rails_generators/javascript_test/templates/assets/jsunittest.js in newjs-1.7.4

- old
+ new

@@ -1,6 +1,6 @@ -/* Jsunittest, version 0.7.2 +/* Jsunittest, version 0.7.3 * (c) 2008 Dr Nic Williams * * Jsunittest is freely distributable under * the terms of an MIT-style license. * For details, see the web site: http://jsunittest.rubyforge.org @@ -9,38 +9,61 @@ var JsUnitTest = { Unit: {}, inspect: function(object) { try { - if (typeof object == "undefined") return 'undefined'; - if (object === null) return 'null'; + if (typeof object == "undefined") {return 'undefined';} + if (object === null) {return 'null';} if (typeof object == "string") { var useDoubleQuotes = arguments[1]; var escapedString = this.gsub(object, /[\x00-\x1f\\]/, function(match) { - var character = String.specialChar[match[0]]; - return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + var character = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + }[match[0]]; + return character ? character : '\\u00' + JsUnitTest.toHexString(match[0].charCodeAt()); }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; + if (useDoubleQuotes) {return '"' + escapedString.replace(/"/g, '\\"') + '"';} return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - }; + } + if (JsUnitTest.getClass(object) === 'Object') { + var keys_values = new Array(), prefix = 'Object: { '; + for (property in object) { + keys_values.push(property + ': ' + object[property]); + } + return (prefix + keys_values.join(', ') + ' }'); + } return String(object); } catch (e) { - if (e instanceof RangeError) return '...'; + if (e instanceof RangeError) {return '...';} throw e; } }, - $: function(element) { + + getClass: function(object) { + return Object.prototype.toString.call(object) + .match(/^\[object\s(.*)\]$/)[1]; + }, + + $: function(element) { if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) + for (var i = 0, elements = [], length = arguments.length; i < length; i++) { elements.push(this.$(arguments[i])); + } return elements; } - if (typeof element == "string") + if (typeof element == "string") { element = document.getElementById(element); + } return element; }, - gsub: function(source, pattern, replacement) { + + gsub: function(source, pattern, replacement) { var result = '', match; replacement = arguments.callee.prepareReplacement(replacement); while (source.length > 0) { if (match = source.match(pattern)) { @@ -58,19 +81,52 @@ return String(source); }, escapeHTML: function(data) { return data.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }, + toHexString : function(n) { + var string = n.toString(16); + return '00'.substring(string.length) + string; + }, arrayfromargs: function(args) { var myarray = new Array(); var i; - for (i=0;i<args.length;i++) - myarray[i] = args[i]; + for (i=0;i<args.length;i++) { + myarray[i] = args[i]; + } return myarray; }, + + // from now we recursively zip & compare nested arrays + areArraysEqual: function(expected, actual) { + var expected_array = JsUnitTest.flattenArray(expected); + var actual_array = JsUnitTest.flattenArray(actual); + if (expected_array.length == actual_array.length) { + for (var i=0; i < expected_array.length; i++) { + if (expected_array[i] != actual_array[i]) {return false;} + } + return true; + } + return false; + }, + + areArraysNotEqual: function(expected, actual) { + return !this.areArraysEqual(expected, actual); + }, + + areHashesEqual: function(expected, actual) { + var expected_array = JsUnitTest.hashToSortedArray(expected); + var actual_array = JsUnitTest.hashToSortedArray(actual); + return this.areArraysEqual(expected_array, actual_array); + }, + + areHashesNotEqual: function(expected, actual) { + return !this.areHashesEqual(expected, actual); + }, + hashToSortedArray: function(hash) { var results = []; for (key in hash) { results.push([key, hash[key]]); } @@ -84,11 +140,11 @@ 'splice' in object && 'join' in object) { this.flattenArray(object, results); } else { results.push(object); } - }; + } return results; }, selectorMatch: function(expression, element) { var tokens = []; var patterns = { @@ -149,42 +205,45 @@ } } var match = true, name, matches; for (var i = 0, token; token = tokens[i]; i++) { - name = token[0], matches = token[1]; + name = token[0]; matches = token[1]; if (!assertions[name](element, matches)) { match = false; break; } } return match; }, + toQueryParams: function(query, separator) { var query = query || window.location.search; var match = query.replace(/^\s+/, '').replace(/\s+$/, '').match(/([^?#]*)(#.*)?$/); - if (!match) return { }; + if (!match) {return { };} var hash = {}; var parts = match[1].split(separator || '&'); for (var i=0; i < parts.length; i++) { var pair = parts[i].split('='); if (pair[0]) { var key = decodeURIComponent(pair.shift()); var value = pair.length > 1 ? pair.join('=') : pair[0]; - if (value != undefined) value = decodeURIComponent(value); + if (value != undefined) {value = decodeURIComponent(value);} if (key in hash) { var object = hash[key]; var isArray = object != null && typeof object == "object" && - 'splice' in object && 'join' in object - if (!isArray) hash[key] = [hash[key]]; + 'splice' in object && 'join' in object; + if (!isArray) {hash[key] = [hash[key]];} hash[key].push(value); } - else hash[key] = value; + else { + hash[key] = value; + } } - }; + } return hash; }, String: { interpret: function(value) { @@ -192,48 +251,49 @@ } } }; JsUnitTest.gsub.prepareReplacement = function(replacement) { - if (typeof replacement == "function") return replacement; + if (typeof replacement == "function") {return replacement;} var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; + return function(match) { return template.evaluate(match); }; }; -JsUnitTest.Version = '0.7.2'; +JsUnitTest.Version = '0.7.3'; JsUnitTest.Template = function(template, pattern) { this.template = template; //template.toString(); this.pattern = pattern || JsUnitTest.Template.Pattern; }; JsUnitTest.Template.prototype.evaluate = function(object) { - if (typeof object.toTemplateReplacements == "function") + if (typeof object.toTemplateReplacements == "function") { object = object.toTemplateReplacements(); + } return JsUnitTest.gsub(this.template, this.pattern, function(match) { - if (object == null) return ''; + if (object == null) {return '';} var before = match[1] || ''; - if (before == '\\') return match[2]; + if (before == '\\') {return match[2];} var ctx = object, expr = match[3]; var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; match = pattern.exec(expr); - if (match == null) return before; + if (match == null) {return before;} while (match != null) { var comp = (match[1].indexOf('[]') === 0) ? match[2].gsub('\\\\]', ']') : match[1]; ctx = ctx[comp]; - if (null == ctx || '' == match[3]) break; + if (null == ctx || '' == match[3]) {break;} expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); match = pattern.exec(expr); } return before + JsUnitTest.String.interpret(ctx); }); -} +}; JsUnitTest.Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; JsUnitTest.Event = {}; // written by Dean Edwards, 2005 // with input from Tino Zijdel, Matthias Miller, Diego Perini @@ -244,13 +304,13 @@ JsUnitTest.Event.addEvent = function(element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); } else { // assign each event handler a unique ID - if (!handler.$$guid) handler.$$guid = JsUnitTest.Event.addEvent.guid++; + if (!handler.$$guid) {handler.$$guid = JsUnitTest.Event.addEvent.guid++;} // create a hash table of event types for the element - if (!element.events) element.events = {}; + if (!element.events) {element.events = {};} // create a hash table of event handlers for each element/event pair var handlers = element.events[type]; if (!handlers) { handlers = element.events[type] = {}; // store the existing event handler (if there is one) @@ -307,24 +367,24 @@ this.cancelBubble = true; }; JsUnitTest.Unit.Logger = function(element) { this.element = JsUnitTest.$(element); - if (this.element) this._createLogTable(); + if (this.element) {this._createLogTable();} }; JsUnitTest.Unit.Logger.prototype.start = function(testName) { - if (!this.element) return; + if (!this.element) {return;} var tbody = this.element.getElementsByTagName('tbody')[0]; var tr = document.createElement('tr'); var td; //testname td = document.createElement('td'); td.appendChild(document.createTextNode(testName)); - tr.appendChild(td) + tr.appendChild(td); tr.appendChild(document.createElement('td'));//status tr.appendChild(document.createElement('td'));//message tbody.appendChild(tr); @@ -336,25 +396,25 @@ var statusCell = logline.getElementsByTagName('td')[1]; statusCell.appendChild(document.createTextNode(status)); }; JsUnitTest.Unit.Logger.prototype.finish = function(status, summary) { - if (!this.element) return; + if (!this.element) {return;} this.setStatus(status); this.message(summary); }; JsUnitTest.Unit.Logger.prototype.message = function(message) { - if (!this.element) return; + if (!this.element) {return;} var cell = this.getMessageCell(); // cell.appendChild(document.createTextNode(this._toHTML(message))); cell.innerHTML = this._toHTML(message); }; JsUnitTest.Unit.Logger.prototype.summary = function(summary) { - if (!this.element) return; + if (!this.element) {return;} var div = this.element.getElementsByTagName('div')[0]; div.innerHTML = this._toHTML(summary); }; JsUnitTest.Unit.Logger.prototype.getLastLogLine = function() { @@ -404,11 +464,11 @@ var results = []; for (var i=0; i < this.parts.length; i++) { var part = this.parts[i]; var result = (part == '?') ? JsUnitTest.inspect(params.shift()) : part.replace(/\\\?/, '?'); results.push(result); - }; + } return results.join(''); }; // A generic function for performming AJAX requests // It takes one argument, which is an object that contains a set of options // All of which are outline in the comments, below @@ -520,12 +580,13 @@ // the server, otherwise return the text contents returned by the server data = type == "xml" || data ? r.responseXML : r.responseText; // If the specified type is "script", execute the returned text // response as if it was JavaScript - if ( type == "script" ) + if ( type == "script" ) { eval.call( window, data ); + } // Return the response data (either an XML Document or a text string) return data; } @@ -536,185 +597,155 @@ return (message ? message + '\n' : '') + new JsUnitTest.Unit.MessageTemplate(template).evaluate(args); }, flunk: function(message) { - this.assertBlock(message || 'Flunked', function() { return false }); + this.assertBlock(message || 'Flunked', function() { return false; }); }, assertBlock: function(message, block) { try { block.call(this) ? this.pass() : this.fail(message); - } catch(e) { this.error(e) } + } catch(e) { this.error(e); } }, assert: function(expression, message) { message = this.buildMessage(message || 'assert', 'got <?>', expression); - this.assertBlock(message, function() { return expression }); + this.assertBlock(message, function() { return expression; }); }, assertEqual: function(expected, actual, message) { message = this.buildMessage(message || 'assertEqual', 'expected <?>, actual: <?>', expected, actual); - this.assertBlock(message, function() { return expected == actual }); + this.assertBlock(message, function() { return expected == actual; }); }, assertNotEqual: function(expected, actual, message) { message = this.buildMessage(message || 'assertNotEqual', 'expected <?>, actual: <?>', expected, actual); - this.assertBlock(message, function() { return expected != actual }); + this.assertBlock(message, function() { return expected != actual; }); }, assertEnumEqual: function(expected, actual, message) { message = this.buildMessage(message || 'assertEnumEqual', 'expected <?>, actual: <?>', expected, actual); - var expected_array = JsUnitTest.flattenArray(expected); - var actual_array = JsUnitTest.flattenArray(actual); - this.assertBlock(message, function() { - if (expected_array.length == actual_array.length) { - for (var i=0; i < expected_array.length; i++) { - if (expected_array[i] != actual_array[i]) return false; - }; - return true; - } - return false; - }); + this.assertBlock(message, function() { return JsUnitTest.areArraysEqual(expected, actual); }); }, assertEnumNotEqual: function(expected, actual, message) { message = this.buildMessage(message || 'assertEnumNotEqual', '<?> was the same as <?>', expected, actual); - var expected_array = JsUnitTest.flattenArray(expected); - var actual_array = JsUnitTest.flattenArray(actual); - this.assertBlock(message, function() { - if (expected_array.length == actual_array.length) { - for (var i=0; i < expected_array.length; i++) { - if (expected_array[i] != actual_array[i]) return true; - }; - return false; - } - return true; - }); + this.assertBlock(message, function() { return JsUnitTest.areArraysNotEqual(expected, actual); }); }, assertHashEqual: function(expected, actual, message) { - message = this.buildMessage(message || 'assertHashEqual', 'expected <?>, actual: <?>', expected, actual); - var expected_array = JsUnitTest.flattenArray(JsUnitTest.hashToSortedArray(expected)); - var actual_array = JsUnitTest.flattenArray(JsUnitTest.hashToSortedArray(actual)); - var block = function() { - if (expected_array.length == actual_array.length) { - for (var i=0; i < expected_array.length; i++) { - if (expected_array[i] != actual_array[i]) return false; - }; - return true; - } - return false; - }; - this.assertBlock(message, block); + message = this.buildMessage(message || 'assertHashEqual', 'expected <?>, actual: <?>', JsUnitTest.inspect(expected), JsUnitTest.inspect(actual)); + this.assertBlock(message, function() { return JsUnitTest.areHashesEqual(expected, actual); }); }, assertHashNotEqual: function(expected, actual, message) { - message = this.buildMessage(message || 'assertHashNotEqual', '<?> was the same as <?>', expected, actual); - var expected_array = JsUnitTest.flattenArray(JsUnitTest.hashToSortedArray(expected)); - var actual_array = JsUnitTest.flattenArray(JsUnitTest.hashToSortedArray(actual)); - // from now we recursively zip & compare nested arrays - var block = function() { - if (expected_array.length == actual_array.length) { - for (var i=0; i < expected_array.length; i++) { - if (expected_array[i] != actual_array[i]) return true; - }; - return false; - } - return true; - }; - this.assertBlock(message, block); + message = this.buildMessage(message || 'assertHashNotEqual', '<?> was the same as <?>', JsUnitTest.inspect(expected), JsUnitTest.inspect(actual)); + this.assertBlock(message, function() { return JsUnitTest.areHashesNotEqual(expected, actual); }); }, assertIdentical: function(expected, actual, message) { message = this.buildMessage(message || 'assertIdentical', 'expected <?>, actual: <?>', expected, actual); - this.assertBlock(message, function() { return expected === actual }); + this.assertBlock(message, function() { return expected === actual; }); }, assertNotIdentical: function(expected, actual, message) { message = this.buildMessage(message || 'assertNotIdentical', 'expected <?>, actual: <?>', expected, actual); - this.assertBlock(message, function() { return expected !== actual }); + this.assertBlock(message, function() { return expected !== actual; }); }, assertNull: function(obj, message) { message = this.buildMessage(message || 'assertNull', 'got <?>', obj); - this.assertBlock(message, function() { return obj === null }); + this.assertBlock(message, function() { return obj === null; }); }, assertNotNull: function(obj, message) { message = this.buildMessage(message || 'assertNotNull', 'got <?>', obj); - this.assertBlock(message, function() { return obj !== null }); + this.assertBlock(message, function() { return obj !== null; }); }, assertUndefined: function(obj, message) { message = this.buildMessage(message || 'assertUndefined', 'got <?>', obj); - this.assertBlock(message, function() { return typeof obj == "undefined" }); + this.assertBlock(message, function() { return typeof obj == "undefined"; }); }, assertNotUndefined: function(obj, message) { message = this.buildMessage(message || 'assertNotUndefined', 'got <?>', obj); - this.assertBlock(message, function() { return typeof obj != "undefined" }); + this.assertBlock(message, function() { return typeof obj != "undefined"; }); }, assertNullOrUndefined: function(obj, message) { message = this.buildMessage(message || 'assertNullOrUndefined', 'got <?>', obj); - this.assertBlock(message, function() { return obj == null }); + this.assertBlock(message, function() { return obj == null; }); }, assertNotNullOrUndefined: function(obj, message) { message = this.buildMessage(message || 'assertNotNullOrUndefined', 'got <?>', obj); - this.assertBlock(message, function() { return obj != null }); + this.assertBlock(message, function() { return obj != null; }); }, assertMatch: function(expected, actual, message) { message = this.buildMessage(message || 'assertMatch', 'regex <?> did not match <?>', expected, actual); - this.assertBlock(message, function() { return new RegExp(expected).exec(actual) }); + this.assertBlock(message, function() { return new RegExp(expected).exec(actual); }); }, assertNoMatch: function(expected, actual, message) { message = this.buildMessage(message || 'assertNoMatch', 'regex <?> matched <?>', expected, actual); - this.assertBlock(message, function() { return !(new RegExp(expected).exec(actual)) }); + this.assertBlock(message, function() { return !(new RegExp(expected).exec(actual)); }); }, assertHasClass: function(element, klass, message) { element = JsUnitTest.$(element); message = this.buildMessage(message || 'assertHasClass', '? doesn\'t have class <?>.', element, klass); this.assertBlock(message, function() { - return !!element.className.match(new RegExp(klass)) + var elementClassName = element.className; + return (elementClassName.length > 0 && (elementClassName == klass || + new RegExp("(^|\\s)" + klass + "(\\s|$)").test(elementClassName))); + // return !!element.className.match(new RegExp(klass)) }); }, + assertNotHasClass: function(element, klass, message) { + element = JsUnitTest.$(element); + message = this.buildMessage(message || 'assertNotHasClass', '? does have class <?>.', element, klass); + this.assertBlock(message, function() { + var elementClassName = element.className; + return !(elementClassName.length > 0 && (elementClassName == klass || + new RegExp("(^|\\s)" + klass + "(\\s|$)").test(elementClassName))); + }); + }, + assertHidden: function(element, message) { element = JsUnitTest.$(element); message = this.buildMessage(message || 'assertHidden', '? isn\'t hidden.', element); - this.assertBlock(message, function() { return !element.style.display || element.style.display == 'none' }); + this.assertBlock(message, function() { return !element.style.display || element.style.display == 'none'; }); }, assertInstanceOf: function(expected, actual, message) { message = this.buildMessage(message || 'assertInstanceOf', '<?> was not an instance of the expected type', actual); - this.assertBlock(message, function() { return actual instanceof expected }); + this.assertBlock(message, function() { return actual instanceof expected; }); }, assertNotInstanceOf: function(expected, actual, message) { message = this.buildMessage(message || 'assertNotInstanceOf', '<?> was an instance of the expected type', actual); - this.assertBlock(message, function() { return !(actual instanceof expected) }); + this.assertBlock(message, function() { return !(actual instanceof expected); }); }, assertRespondsTo: function(method, obj, message) { message = this.buildMessage(message || 'assertRespondsTo', 'object doesn\'t respond to <?>', method); - this.assertBlock(message, function() { return (method in obj && typeof obj[method] == 'function') }); + this.assertBlock(message, function() { return (method in obj && typeof obj[method] == 'function'); }); }, assertRaise: function(exceptionName, method, message) { message = this.buildMessage(message || 'assertRaise', '<?> exception expected but none was raised', exceptionName); var block = function() { try { method(); return false; } catch(e) { - if (e.name == exceptionName) return true; - else throw e; + if (e.name == exceptionName) {return true;} + else {throw e;} } }; this.assertBlock(message, block); }, @@ -728,26 +759,27 @@ } }, _isVisible: function(element) { element = JsUnitTest.$(element); - if(!element.parentNode) return true; + if(!element.parentNode) {return true;} this.assertNotNull(element); - if(element.style && (element.style.display == 'none')) + if(element.style && (element.style.display == 'none')) { return false; + } return arguments.callee.call(this, element.parentNode); }, assertVisible: function(element, message) { message = this.buildMessage(message, '? was not visible.', element); - this.assertBlock(message, function() { return this._isVisible(element) }); + this.assertBlock(message, function() { return this._isVisible(element); }); }, assertNotVisible: function(element, message) { message = this.buildMessage(message, '? was not hidden and didn\'t have a hidden parent either.', element); - this.assertBlock(message, function() { return !this._isVisible(element) }); + this.assertBlock(message, function() { return !this._isVisible(element); }); }, assertElementsMatch: function() { var pass = true, expressions = JsUnitTest.arrayfromargs(arguments); var elements = expressions.shift(); @@ -764,11 +796,11 @@ break; } message = this.buildMessage('assertElementsMatch', 'In index <?>: expected <?> but got ?', index, expression, element); this.flunk(message); pass = false; - }; + } this.assert(pass, "Expected all elements to match."); }, assertElementMatches: function(element, expression, message) { this.assertElementsMatch([element], expression); @@ -797,34 +829,35 @@ JsUnitTest.Unit.Runner.prototype.portNumber = function() { if (window.location.search.length > 0) { var matches = window.location.search.match(/\:(\d{3,5})\//); if (matches) { - return parseInt(matches[1]); + return parseInt(matches[1], 10); } } return null; }; JsUnitTest.Unit.Runner.prototype.getTests = function(testcases) { var tests = [], options = this.options; - if (this.queryParams.tests) tests = this.queryParams.tests.split(','); - else if (options.tests) tests = options.tests; - else if (options.test) tests = [option.test]; + if (this.queryParams.tests) {tests = this.queryParams.tests.split(',');} + else if (options.tests) {tests = options.tests;} + else if (options.test) {tests = [option.test];} else { for (testname in testcases) { - if (testname.match(/^test/)) tests.push(testname); + if (testname.match(/^test/)) {tests.push(testname);} } } var results = []; for (var i=0; i < tests.length; i++) { var test = tests[i]; - if (testcases[test]) + if (testcases[test]) { results.push( new JsUnitTest.Unit.Testcase(test, testcases[test], testcases.setup, testcases.teardown) ); - }; + } + } return results; }; JsUnitTest.Unit.Runner.prototype.getResult = function() { var results = { @@ -839,11 +872,11 @@ var test = this.tests[i]; results.assertions += test.assertions; results.failures += test.failures; results.errors += test.errors; results.warnings += test.warnings; - }; + } return results; }; JsUnitTest.Unit.Runner.prototype.postResults = function() { if (this.options.resultsURL) { @@ -857,19 +890,19 @@ url += "failures=" + results.failures + "&"; url += "errors=" + results.errors; JsUnitTest.ajax({ url: url, type: 'GET' - }) + }); } }; JsUnitTest.Unit.Runner.prototype.runTests = function() { var test = this.tests[this.currentTest], actions; - if (!test) return this.finish(); - if (!test.isWaiting) this.logger.start(test.name); + if (!test) {return this.finish();} + if (!test.isWaiting) {this.logger.start(test.name);} test.run(); var self = this; if(test.isWaiting) { this.logger.message("Waiting for " + test.timeToWait + "ms"); // setTimeout(this.runTests.bind(this), test.timeToWait || 1000); @@ -878,11 +911,11 @@ }, test.timeToWait || 1000); return; } this.logger.finish(test.status(), test.summary()); - if (actions = test.actions) this.logger.appendActionButtons(actions); + if (actions = test.actions) {this.logger.appendActionButtons(actions);} this.currentTest++; // tail recursive, hopefully the browser will skip the stackframe this.runTests(); }; @@ -925,21 +958,21 @@ }; JsUnitTest.Unit.Testcase.prototype.run = function(rethrow) { try { try { - if (!this.isWaiting) this.setup(); + if (!this.isWaiting) {this.setup();} this.isWaiting = false; this.test(); } finally { if(!this.isWaiting) { this.teardown(); } } } catch(e) { - if (rethrow) throw e; + if (rethrow) {throw e;} this.error(e, this); } }; JsUnitTest.Unit.Testcase.prototype.summary = function() { @@ -979,17 +1012,22 @@ this.messages.push("Info: " + message); }; JsUnitTest.Unit.Testcase.prototype.error = function(error, test) { this.errors++; - this.actions['retry with throw'] = function() { test.run(true) }; + this.actions['retry with throw'] = function() { test.run(true); }; this.messages.push(error.name + ": "+ error.message + "(" + JsUnitTest.inspect(error) + ")"); + if( typeof console != "undefined" && console.error) { + console.error("Test '" + test.name + "' died, exception and test follows"); + console.error(error); + console.error(test.test.toString()); + } }; JsUnitTest.Unit.Testcase.prototype.status = function() { - if (this.failures > 0) return 'failed'; - if (this.errors > 0) return 'error'; - if (this.warnings > 0) return 'warning'; + if (this.failures > 0) {return 'failed';} + if (this.errors > 0) {return 'error';} + if (this.warnings > 0) {return 'warning';} return 'passed'; }; JsUnitTest.Unit.Testcase.prototype.benchmark = function(operation, iterations) { var startAt = new Date(); \ No newline at end of file