spec/dummy/tmp/cache/assets/D00/F60/sprockets%2F42e279b52511c47d26c0adb125fd04e8 in teabag-0.7.1 vs spec/dummy/tmp/cache/assets/D00/F60/sprockets%2F42e279b52511c47d26c0adb125fd04e8 in teabag-0.7.2

- old
+ new

@@ -1,9 +1,9 @@ -o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1362446096.250247: @value"*Œ{I" +o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1365878954.245548: @value"¥{I" class:EFI"BundledAsset;FI"logical_path;FI"teabag/qunit.js;FI" pathname;FI"P/Users/jejacks0n/Projects/teabag/app/assets/javascripts/teabag/qunit.coffee;FI"content_type;FI"application/javascript;FI" -mtime;FI"2013-03-04T18:14:44-07:00;FI" length;FiXŠI" digest;F"%f581102d7ec85f644fd02b00724565b7I" source;FI"XŠ/** - * QUnit v1.10.0 - A JavaScript Unit Testing Framework +mtime;FI"2013-04-13T12:44:53-06:00;FI" length;Fi4£I" digest;F"%b653a83ac3b9c39341b9037ad8ad4989I" source;FI"4£/** + * QUnit v1.11.0 - A JavaScript Unit Testing Framework * * http://qunitjs.com * * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license. @@ -12,10 +12,11 @@ (function( window ) { var QUnit, + assert, config, onErrorFnPrev, testId = 0, fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), toString = Object.prototype.toString, @@ -32,10 +33,59 @@ return true; } catch( e ) { return false; } }()) + }, + /** + * Provides a normalized error string, correcting an issue + * with IE 7 (and prior) where Error.prototype.toString is + * not properly implemented + * + * Based on http://es5.github.com/#x15.11.4.4 + * + * @param {String|Error} error + * @return {String} error message + */ + errorString = function( error ) { + var name, message, + errorString = error.toString(); + if ( errorString.substring( 0, 7 ) === "[object" ) { + name = error.name ? error.name.toString() : "Error"; + message = error.message ? error.message.toString() : ""; + if ( name && message ) { + return name + ": " + message; + } else if ( name ) { + return name; + } else if ( message ) { + return message; + } else { + return "Error"; + } + } else { + return errorString; + } + }, + /** + * Makes a clone of an object using only Array or Object as base, + * and copies over the own enumerable properties. + * + * @param {Object} obj + * @return {Object} New object with only the own properties (recursively). + */ + objectValues = function( obj ) { + // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. + /*jshint newcap: false */ + var key, val, + vals = QUnit.is( "array", obj ) ? [] : {}; + for ( key in obj ) { + if ( hasOwn.call( obj, key ) ) { + val = obj[key]; + vals[key] = val === Object(val) ? objectValues(val) : val; + } + } + return vals; }; function Test( settings ) { extend( this, settings ); this.assertions = []; @@ -49,11 +99,11 @@ var a, b, li, tests = id( "qunit-tests" ); if ( tests ) { b = document.createElement( "strong" ); - b.innerHTML = this.name; + b.innerHTML = this.nameHtml; // `a` initialized at top of scope a = document.createElement( "a" ); a.innerHTML = "Rerun"; a.href = QUnit.url({ testNumber: this.testNumber }); @@ -93,10 +143,11 @@ this.testEnvironment = extend({ setup: function() {}, teardown: function() {} }, this.moduleTestEnvironment ); + this.started = +new Date(); runLoggingCallbacks( "testStart", QUnit, { name: this.testName, module: this.module }); @@ -112,35 +163,41 @@ return; } try { this.testEnvironment.setup.call( this.testEnvironment ); } catch( e ) { - QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); } }, run: function() { config.current = this; var running = id( "qunit-testresult" ); if ( running ) { - running.innerHTML = "Running: <br/>" + this.name; + running.innerHTML = "Running: <br/>" + this.nameHtml; } if ( this.async ) { QUnit.stop(); } + this.callbackStarted = +new Date(); + if ( config.notrycatch ) { this.callback.call( this.testEnvironment, QUnit.assert ); + this.callbackRuntime = +new Date() - this.callbackStarted; return; } try { this.callback.call( this.testEnvironment, QUnit.assert ); + this.callbackRuntime = +new Date() - this.callbackStarted; } catch( e ) { - QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) ); + this.callbackRuntime = +new Date() - this.callbackStarted; + + QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); // else next test will carry the responsibility saveGlobal(); // Restart the tests if they're blocking if ( config.blocking ) { @@ -149,42 +206,47 @@ } }, teardown: function() { config.current = this; if ( config.notrycatch ) { + if ( typeof this.callbackRuntime === "undefined" ) { + this.callbackRuntime = +new Date() - this.callbackStarted; + } this.testEnvironment.teardown.call( this.testEnvironment ); return; } else { try { this.testEnvironment.teardown.call( this.testEnvironment ); } catch( e ) { - QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); } } checkPollution(); }, finish: function() { config.current = this; - if ( config.requireExpects && this.expected == null ) { + if ( config.requireExpects && this.expected === null ) { QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); - } else if ( this.expected != null && this.expected != this.assertions.length ) { + } else if ( this.expected !== null && this.expected !== this.assertions.length ) { QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); - } else if ( this.expected == null && !this.assertions.length ) { + } else if ( this.expected === null && !this.assertions.length ) { QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); } - var assertion, a, b, i, li, ol, + var i, assertion, a, b, time, li, ol, test = this, good = 0, bad = 0, tests = id( "qunit-tests" ); + this.runtime = +new Date() - this.started; config.stats.all += this.assertions.length; config.moduleStats.all += this.assertions.length; if ( tests ) { ol = document.createElement( "ol" ); + ol.className = "qunit-assert-list"; for ( i = 0; i < this.assertions.length; i++ ) { assertion = this.assertions[i]; li = document.createElement( "li" ); @@ -209,40 +271,46 @@ sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); } } if ( bad === 0 ) { - ol.style.display = "none"; + addClass( ol, "qunit-collapsed" ); } // `b` initialized at top of scope b = document.createElement( "strong" ); - b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; + b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; addEvent(b, "click", function() { - var next = b.nextSibling.nextSibling, - display = next.style.display; - next.style.display = display === "none" ? "block" : "none"; + var next = b.parentNode.lastChild, + collapsed = hasClass( next, "qunit-collapsed" ); + ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); }); addEvent(b, "dblclick", function( e ) { var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { target = target.parentNode; } if ( window.location && target.nodeName.toLowerCase() === "strong" ) { window.location = QUnit.url({ testNumber: test.testNumber }); } }); + // `time` initialized at top of scope + time = document.createElement( "span" ); + time.className = "runtime"; + time.innerHTML = this.runtime + " ms"; + // `li` initialized at top of scope li = id( this.id ); li.className = bad ? "fail" : "pass"; li.removeChild( li.firstChild ); a = li.firstChild; li.appendChild( b ); - li.appendChild ( a ); + li.appendChild( a ); + li.appendChild( time ); li.appendChild( ol ); } else { for ( i = 0; i < this.assertions.length; i++ ) { if ( !this.assertions[i].result ) { @@ -256,11 +324,12 @@ runLoggingCallbacks( "testDone", QUnit, { name: this.testName, module: this.module, failed: bad, passed: this.assertions.length - bad, - total: this.assertions.length + total: this.assertions.length, + duration: this.runtime }); QUnit.reset(); config.current = undefined; @@ -322,23 +391,23 @@ QUnit.test( testName, expected, callback, true ); }, test: function( testName, expected, callback, async ) { var test, - name = "<span class='test-name'>" + escapeInnerText( testName ) + "</span>"; + nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>"; if ( arguments.length === 2 ) { callback = expected; expected = null; } if ( config.currentModule ) { - name = "<span class='module-name'>" + config.currentModule + "</span>: " + name; + nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml; } test = new Test({ - name: name, + nameHtml: nameHtml, testName: testName, expected: expected, async: async, callback: callback, module: config.currentModule, @@ -361,18 +430,32 @@ return config.current.expected; } }, start: function( count ) { + // QUnit hasn't been initialized yet. + // Note: RequireJS (et al) may delay onLoad + if ( config.semaphore === undefined ) { + QUnit.begin(function() { + // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first + setTimeout(function() { + QUnit.start( count ); + }); + }); + return; + } + config.semaphore -= count || 1; // don't start until equal number of stop-calls if ( config.semaphore > 0 ) { return; } // ignore if start is called more often then stop if ( config.semaphore < 0 ) { config.semaphore = 0; + QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) ); + return; } // A slight delay, to avoid any current callbacks if ( defined.setTimeout ) { window.setTimeout(function() { if ( config.semaphore > 0 ) { @@ -404,15 +487,18 @@ }, config.testTimeout ); } } }; +// `assert` initialized at top of scope // Asssert helpers -// All of these must call either QUnit.push() or manually do: +// All of these must either call QUnit.push() or manually do: // - runLoggingCallbacks( "log", .. ); // - config.current.assertions.push({ .. }); - QUnit.assert = { +// We attach it to the QUnit object *after* we expose the public API, +// otherwise `assert` will become a global variable in browsers (#341). + assert = { /** * Asserts rough true-ish result. * @name ok * @function * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); @@ -429,18 +515,18 @@ name: config.current.testName, result: result, message: msg }; - msg = escapeInnerText( msg || (result ? "okay" : "failed" ) ); + msg = escapeText( msg || (result ? "okay" : "failed" ) ); msg = "<span class='test-message'>" + msg + "</span>"; if ( !result ) { source = sourceFromStacktrace( 2 ); if ( source ) { details.source = source; - msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr></table>"; + msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>"; } } runLoggingCallbacks( "log", QUnit, details ); config.current.assertions.push({ result: result, @@ -454,22 +540,44 @@ * @name equal * @function * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); */ equal: function( actual, expected, message ) { + /*jshint eqeqeq:false */ QUnit.push( expected == actual, actual, expected, message ); }, /** * @name notEqual * @function */ notEqual: function( actual, expected, message ) { + /*jshint eqeqeq:false */ QUnit.push( expected != actual, actual, expected, message ); }, /** + * @name propEqual + * @function + */ + propEqual: function( actual, expected, message ) { + actual = objectValues(actual); + expected = objectValues(expected); + QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name notPropEqual + * @function + */ + notPropEqual: function( actual, expected, message ) { + actual = objectValues(actual); + expected = objectValues(expected); + QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** * @name deepEqual * @function */ deepEqual: function( actual, expected, message ) { QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); @@ -497,12 +605,13 @@ */ notStrictEqual: function( actual, expected, message ) { QUnit.push( expected !== actual, actual, expected, message ); }, - throws: function( block, expected, message ) { + "throws": function( block, expected, message ) { var actual, + expectedOutput = expected, ok = false; // 'expected' is optional if ( typeof expected === "string" ) { message = expected; @@ -519,39 +628,42 @@ if ( actual ) { // we don't want to validate thrown error if ( !expected ) { ok = true; + expectedOutput = null; // expected is a regexp } else if ( QUnit.objectType( expected ) === "regexp" ) { - ok = expected.test( actual ); + ok = expected.test( errorString( actual ) ); // expected is a constructor } else if ( actual instanceof expected ) { ok = true; // expected is a validation function which returns true is validation passed } else if ( expected.call( {}, actual ) === true ) { + expectedOutput = null; ok = true; } - QUnit.push( ok, actual, null, message ); + QUnit.push( ok, actual, expectedOutput, message ); } else { QUnit.pushFailure( message, null, 'No exception was thrown.' ); } } }; /** * @deprecate since 1.8.0 - * Kept assertion helpers in root for backwards compatibility + * Kept assertion helpers in root for backwards compatibility. */ - extend( QUnit, QUnit.assert ); + extend( QUnit, assert ); /** * @deprecated since 1.9.0 - * Kept global "raises()" for backwards compatibility + * Kept root "raises()" for backwards compatibility. + * (Note that we don't introduce assert.raises). */ - QUnit.raises = QUnit.assert.throws; + QUnit.raises = assert[ "throws" ]; /** * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 * Kept to avoid TypeErrors for undefined methods. */ @@ -623,10 +735,19 @@ testDone: [], moduleStart: [], moduleDone: [] }; +// Export global variables, unless an 'exports' object exists, +// in that case we assume we're in CommonJS (dealt with on the bottom of the script) + if ( typeof exports === "undefined" ) { + extend( window, QUnit ); + + // Expose QUnit object + window.QUnit = QUnit; + } + // Initialize more QUnit.config and QUnit.urlParams (function() { var i, location = window.location || { search: "", protocol: "file:" }, params = location.search.slice( 1 ).split( "&" ), @@ -656,22 +777,15 @@ // Figure out if we're running the tests from a server or not QUnit.isLocal = location.protocol === "file:"; }()); -// Export global variables, unless an 'exports' object exists, -// in that case we assume we're in CommonJS (dealt with on the bottom of the script) - if ( typeof exports === "undefined" ) { - extend( window, QUnit ); - - // Expose QUnit object - window.QUnit = QUnit; - } - // Extend QUnit object, // these after set here because they should not be exposed as global functions extend( QUnit, { + assert: assert, + config: config, // Initialize the configuration options init: function() { extend( config, { @@ -682,19 +796,19 @@ blocking: false, autostart: true, autorun: false, filter: "", queue: [], - semaphore: 0 + semaphore: 1 }); var tests, banner, result, qunit = id( "qunit" ); if ( qunit ) { qunit.innerHTML = - "<h1 id='qunit-header'>" + escapeInnerText( document.title ) + "</h1>" + + "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" + "<h2 id='qunit-banner'></h2>" + "<div id='qunit-testrunner-toolbar'></div>" + "<h2 id='qunit-userAgent'></h2>" + "<ol id='qunit-tests'></ol>"; } @@ -746,11 +860,11 @@ } }, // Safe object type checking is: function( type, obj ) { - return QUnit.objectType( obj ) == type; + return QUnit.objectType( obj ) === type; }, objectType: function( obj ) { if ( typeof obj === "undefined" ) { return "undefined"; @@ -758,11 +872,12 @@ } if ( obj === null ) { return "null"; } - var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || ""; + var match = toString.call( obj ).match(/^\[object\s(.*)\]$/), + type = match && match[1] || ""; switch ( type ) { case "Number": if ( isNaN(obj) ) { return "nan"; @@ -795,29 +910,29 @@ message: message, actual: actual, expected: expected }; - message = escapeInnerText( message ) || ( result ? "okay" : "failed" ); + message = escapeText( message ) || ( result ? "okay" : "failed" ); message = "<span class='test-message'>" + message + "</span>"; output = message; if ( !result ) { - expected = escapeInnerText( QUnit.jsDump.parse(expected) ); - actual = escapeInnerText( QUnit.jsDump.parse(actual) ); + expected = escapeText( QUnit.jsDump.parse(expected) ); + actual = escapeText( QUnit.jsDump.parse(actual) ); output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>"; - if ( actual != expected ) { + if ( actual !== expected ) { output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>"; output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>"; } source = sourceFromStacktrace(); if ( source ) { details.source = source; - output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>"; + output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>"; } output += "</table>"; } @@ -840,23 +955,23 @@ name: config.current.testName, result: false, message: message }; - message = escapeInnerText( message ) || "error"; + message = escapeText( message ) || "error"; message = "<span class='test-message'>" + message + "</span>"; output = message; output += "<table>"; if ( actual ) { - output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeInnerText( actual ) + "</pre></td></tr>"; + output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>"; } if ( source ) { details.source = source; - output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>"; + output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>"; } output += "</table>"; runLoggingCallbacks( "log", QUnit, details ); @@ -877,11 +992,12 @@ continue; } querystring += encodeURIComponent( key ) + "=" + encodeURIComponent( params[ key ] ) + "&"; } - return window.location.pathname + querystring.slice( 0, -1 ); + return window.location.protocol + "//" + window.location.host + + window.location.pathname + querystring.slice( 0, -1 ); }, extend: extend, id: id, addEvent: addEvent @@ -908,11 +1024,11 @@ log: registerLoggingCallback( "log" ), // testStart: { name } testStart: registerLoggingCallback( "testStart" ), - // testDone: { name, failed, passed, total } + // testDone: { name, failed, passed, total, duration } testDone: registerLoggingCallback( "testDone" ), // moduleStart: { name } moduleStart: registerLoggingCallback( "moduleStart" ), @@ -926,11 +1042,12 @@ QUnit.load = function() { runLoggingCallbacks( "begin", QUnit, {} ); // Initialize the config, saving the execution queue - var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter, + var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, + urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter, numModules = 0, moduleFilterHtml = "", urlConfigHtml = "", oldconfig = extend( {}, config ); @@ -949,18 +1066,28 @@ label: val, tooltip: "[no tooltip available]" }; } config[ val.id ] = QUnit.urlParams[ val.id ]; - urlConfigHtml += "<input id='qunit-urlconfig-" + val.id + "' name='" + val.id + "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + " title='" + val.tooltip + "'><label for='qunit-urlconfig-" + val.id + "' title='" + val.tooltip + "'>" + val.label + "</label>"; + urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) + + "' name='" + escapeText( val.id ) + + "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + + " title='" + escapeText( val.tooltip ) + + "'><label for='qunit-urlconfig-" + escapeText( val.id ) + + "' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>"; } - moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + ( config.module === undefined ? "selected" : "" ) + ">< All Modules ></option>"; + moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + + ( config.module === undefined ? "selected='selected'" : "" ) + + ">< All Modules ></option>"; + for ( i in config.modules ) { if ( config.modules.hasOwnProperty( i ) ) { numModules += 1; - moduleFilterHtml += "<option value='" + encodeURIComponent(i) + "' " + ( config.module === i ? "selected" : "" ) + ">" + i + "</option>"; + moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(i) ) + "' " + + ( config.module === i ? "selected='selected'" : "" ) + + ">" + escapeText(i) + "</option>"; } } moduleFilterHtml += "</select>"; // `userAgent` initialized at top of scope @@ -1015,24 +1142,30 @@ label.setAttribute( "for", "qunit-filter-pass" ); label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." ); label.innerHTML = "Hide passed tests"; toolbar.appendChild( label ); - urlConfigCheckboxes = document.createElement( 'span' ); - urlConfigCheckboxes.innerHTML = urlConfigHtml; - addEvent( urlConfigCheckboxes, "change", function( event ) { - var params = {}; - params[ event.target.name ] = event.target.checked ? true : undefined; + urlConfigCheckboxesContainer = document.createElement("span"); + urlConfigCheckboxesContainer.innerHTML = urlConfigHtml; + urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input"); + // For oldIE support: + // * Add handlers to the individual elements instead of the container + // * Use "click" instead of "change" + // * Fallback from event.target to event.srcElement + addEvents( urlConfigCheckboxes, "click", function( event ) { + var params = {}, + target = event.target || event.srcElement; + params[ target.name ] = target.checked ? true : undefined; window.location = QUnit.url( params ); }); - toolbar.appendChild( urlConfigCheckboxes ); + toolbar.appendChild( urlConfigCheckboxesContainer ); if (numModules > 1) { moduleFilter = document.createElement( 'span' ); moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' ); moduleFilter.innerHTML = moduleFilterHtml; - addEvent( moduleFilter, "change", function() { + addEvent( moduleFilter.lastChild, "change", function() { var selectBox = moduleFilter.getElementsByTagName("select")[0], selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } ); }); @@ -1107,11 +1240,11 @@ "Tests completed in ", runtime, " milliseconds.<br/>", "<span class='passed'>", passed, - "</span> tests of <span class='total'>", + "</span> assertions of <span class='total'>", config.stats.all, "</span> passed, <span class='failed'>", config.stats.bad, "</span> failed." ].join( "" ); @@ -1200,11 +1333,11 @@ // Later Safari and IE10 are supposed to support error.stack as well // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack function extractStacktrace( e, offset ) { offset = offset === undefined ? 3 : offset; - var stack, include, i, regex; + var stack, include, i; if ( e.stacktrace ) { // Opera return e.stacktrace.split( "\n" )[ offset + 3 ]; } else if ( e.stack ) { @@ -1214,11 +1347,11 @@ stack.shift(); } if ( fileName ) { include = []; for ( i = offset; i < stack.length; i++ ) { - if ( stack[ i ].indexOf( fileName ) != -1 ) { + if ( stack[ i ].indexOf( fileName ) !== -1 ) { break; } include.push( stack[ i ] ); } if ( include.length ) { @@ -1243,21 +1376,31 @@ } catch ( e ) { return extractStacktrace( e, offset ); } } - function escapeInnerText( s ) { + /** + * Escape text for attribute or text content. + */ + function escapeText( s ) { if ( !s ) { return ""; } s = s + ""; - return s.replace( /[\&<>]/g, function( s ) { + // Both single quotes and double quotes (for attributes) + return s.replace( /['"<>&]/g, function( s ) { switch( s ) { - case "&": return "&amp;"; - case "<": return "&lt;"; - case ">": return "&gt;"; - default: return s; + case '\'': + return '&#039;'; + case '"': + return '&quot;'; + case '<': + return '&lt;'; + case '>': + return '&gt;'; + case '&': + return '&amp;'; } }); } function synchronize( callback, last ) { @@ -1301,11 +1444,11 @@ config.pollution.push( key ); } } } - function checkPollution( name ) { + function checkPollution() { var newGlobals, deletedGlobals, old = config.pollution; saveGlobal(); @@ -1350,20 +1493,57 @@ } return a; } + /** + * @param {HTMLElement} elem + * @param {string} type + * @param {Function} fn + */ function addEvent( elem, type, fn ) { + // Standards-based browsers if ( elem.addEventListener ) { elem.addEventListener( type, fn, false ); - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, fn ); + // IE } else { - fn(); + elem.attachEvent( "on" + type, fn ); } } + /** + * @param {Array|NodeList} elems + * @param {string} type + * @param {Function} fn + */ + function addEvents( elems, type, fn ) { + var i = elems.length; + while ( i-- ) { + addEvent( elems[i], type, fn ); + } + } + + function hasClass( elem, name ) { + return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; + } + + function addClass( elem, name ) { + if ( !hasClass( elem, name ) ) { + elem.className += (elem.className ? " " : "") + name; + } + } + + function removeClass( elem, name ) { + var set = " " + elem.className + " "; + // Class name may appear multiple times + while ( set.indexOf(" " + name + " ") > -1 ) { + set = set.replace(" " + name + " " , " "); + } + // If possible, trim it for prettiness, but not neccecarily + elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set ); + } + function id( name ) { return !!( typeof document !== "undefined" && document && document.getElementById ) && document.getElementById( name ); } @@ -1373,11 +1553,10 @@ }; } // Supports deprecated method of completely overwriting logging callbacks function runLoggingCallbacks( key, scope, args ) { - //debugger; var i, callbacks; if ( QUnit.hasOwnProperty( key ) ) { QUnit[ key ].call(scope, args ); } else { callbacks = config[ key ]; @@ -1415,10 +1594,11 @@ }, callbacks = (function () { // for string, boolean, number and null function useStrictEquality( b, a ) { + /*jshint eqeqeq:false */ if ( b instanceof a.constructor || a instanceof b.constructor ) { // to catch short annotaion VS 'new' annotation of a // declaration // e.g. var i = 1; // var j = new Number(1); @@ -1611,30 +1791,29 @@ return join( "[", ret, "]" ); } var reName = /^function (\w+)/, jsDump = { - parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance + // type is used mostly internally, you can fix a (custom)type in advance + parse: function( obj, type, stack ) { stack = stack || [ ]; var inStack, res, parser = this.parsers[ type || this.typeOf(obj) ]; type = typeof parser; inStack = inArray( obj, stack ); - if ( inStack != -1 ) { + if ( inStack !== -1 ) { return "recursion(" + (inStack - stack.length) + ")"; } - //else - if ( type == "function" ) { + if ( type === "function" ) { stack.push( obj ); res = parser.call( this, obj, stack ); stack.pop(); return res; } - // else - return ( type == "string" ) ? parser : this.parsers.error; + return ( type === "string" ) ? parser : this.parsers.error; }, typeOf: function( obj ) { var type; if ( obj === null ) { type = "null"; @@ -1657,19 +1836,22 @@ toString.call( obj ) === "[object Array]" || // NodeList objects ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) ) { type = "array"; + } else if ( obj.constructor === Error.prototype.constructor ) { + type = "error"; } else { type = typeof obj; } return type; }, separator: function() { return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " "; }, - indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + // extra can be a number, shortcut for increasing-calling-decreasing + indent: function( extra ) { if ( !this.multiline ) { return ""; } var chr = this.indentChar; if ( this.HTML ) { @@ -1694,17 +1876,20 @@ _depth_: 1, // This is the list of parsers, to modify them, use jsDump.setParser parsers: { window: "[Window]", document: "[Document]", - error: "[ERROR]", //when no parser is found, shouldn"t happen + error: function(error) { + return "Error(\"" + error.message + "\")"; + }, unknown: "[Unknown]", "null": "null", "undefined": "undefined", "function": function( fn ) { var ret = "function", - name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE + // functions never have name in IE + name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; if ( name ) { ret += " " + name; } ret += "( "; @@ -1716,17 +1901,13 @@ nodelist: array, "arguments": array, object: function( map, stack ) { var ret = [ ], keys, key, val, i; QUnit.jsDump.up(); - if ( Object.keys ) { - keys = Object.keys( map ); - } else { - keys = []; - for ( key in map ) { - keys.push( key ); - } + keys = []; + for ( key in map ) { + keys.push( key ); } keys.sort(); for ( i = 0; i < keys.length; i++ ) { key = keys[ i ]; val = map[ key ]; @@ -1734,82 +1915,75 @@ } QUnit.jsDump.down(); return join( "{", ret, "}" ); }, node: function( node ) { - var a, val, + var len, i, val, open = QUnit.jsDump.HTML ? "&lt;" : "<", close = QUnit.jsDump.HTML ? "&gt;" : ">", tag = node.nodeName.toLowerCase(), - ret = open + tag; + ret = open + tag, + attrs = node.attributes; - for ( a in QUnit.jsDump.DOMAttrs ) { - val = node[ QUnit.jsDump.DOMAttrs[a] ]; - if ( val ) { - ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" ); + if ( attrs ) { + for ( i = 0, len = attrs.length; i < len; i++ ) { + val = attrs[i].nodeValue; + // IE6 includes all attributes in .attributes, even ones not explicitly set. + // Those have values like undefined, null, 0, false, "" or "inherit". + if ( val && val !== "inherit" ) { + ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" ); + } } } - return ret + close + open + "/" + tag + close; + ret += close; + + // Show content of TextNode or CDATASection + if ( node.nodeType === 3 || node.nodeType === 4 ) { + ret += node.nodeValue; + } + + return ret + open + "/" + tag + close; }, - functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function + // function calls it internally, it's the arguments part of the function + functionArgs: function( fn ) { var args, l = fn.length; if ( !l ) { return ""; } args = new Array(l); while ( l-- ) { - args[l] = String.fromCharCode(97+l);//97 is 'a' + // 97 is 'a' + args[l] = String.fromCharCode(97+l); } return " " + args.join( ", " ) + " "; }, - key: quote, //object calls it internally, the key part of an item in a map - functionCode: "[code]", //function calls it internally, it's the content of the function - attribute: quote, //node calls it internally, it's an html attribute value + // object calls it internally, the key part of an item in a map + key: quote, + // function calls it internally, it's the content of the function + functionCode: "[code]", + // node calls it internally, it's an html attribute value + attribute: quote, string: quote, date: quote, - regexp: literal, //regex + regexp: literal, number: literal, "boolean": literal }, - DOMAttrs: { - //attributes to dump from nodes, name=>realName - id: "id", - name: "name", - "class": "className" - }, - HTML: false,//if true, entities are escaped ( <, >, \t, space and \n ) - indentChar: " ",//indentation unit - multiline: true //if true, items in a collection, are separated by a \n, else just a space. + // if true, entities are escaped ( <, >, \t, space and \n ) + HTML: false, + // indentation unit + indentChar: " ", + // if true, items in a collection, are separated by a \n, else just a space. + multiline: true }; return jsDump; }()); -// from Sizzle.js - function getText( elems ) { - var i, elem, - ret = ""; - - for ( i = 0; elems[i]; i++ ) { - elem = elems[i]; - - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; - - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += getText( elem.childNodes ); - } - } - - return ret; - } - // from jquery.js function inArray( elem, array ) { if ( array.indexOf ) { return array.indexOf( elem ); } @@ -1836,27 +2010,28 @@ * Usage: QUnit.diff(expected, actual) * * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over" */ QUnit.diff = (function() { + /*jshint eqeqeq:false, eqnull:true */ function diff( o, n ) { var i, ns = {}, os = {}; for ( i = 0; i < n.length; i++ ) { - if ( ns[ n[i] ] == null ) { + if ( !hasOwn.call( ns, n[i] ) ) { ns[ n[i] ] = { rows: [], o: null }; } ns[ n[i] ].rows.push( i ); } for ( i = 0; i < o.length; i++ ) { - if ( os[ o[i] ] == null ) { + if ( !hasOwn.call( os, o[i] ) ) { os[ o[i] ] = { rows: [], n: null }; } @@ -1865,11 +2040,11 @@ for ( i in ns ) { if ( !hasOwn.call( ns, i ) ) { continue; } - if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) { + if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) { n[ ns[i].rows[0] ] = { text: n[ ns[i].rows[0] ], row: os[i].rows[0] }; o[ os[i].rows[0] ] = { @@ -1971,19 +2146,17 @@ }; }()); // for CommonJS enviroments, export everything if ( typeof exports !== "undefined" ) { - extend(exports, QUnit); + extend( exports, QUnit ); } // get at whatever the global object is, like window in browsers }( (function() {return this;}.call()) )); (function() { - this.Teabag = (function() { - function Teabag() {} Teabag.defer = false; Teabag.slow = 75; @@ -2011,10 +2184,11 @@ return new Teabag.Runner(); }; Teabag.resolveDependenciesFromParams = function(all) { var dep, deps, file, parts, path, paths, _i, _j, _len, _len1; + if (all == null) { all = []; } deps = []; if ((paths = this.location.search.match(/[\?&]file(\[\])?=[^&\?]*/gi)) === null) { @@ -2036,20 +2210,24 @@ } return deps; }; Teabag.log = function() { + var e; + this.messages.push(arguments[0]); try { return console.log.apply(console, arguments); - } catch (e) { + } catch (_error) { + e = _error; throw new Error("Unable to use console.log for logging"); } }; Teabag.getMessages = function() { var messages; + messages = this.messages; this.messages = []; return messages; }; @@ -2057,13 +2235,11 @@ })(); }).call(this); (function() { - Teabag.Runner = (function() { - Runner.run = false; function Runner() { if (this.constructor.run) { return; @@ -2074,10 +2250,11 @@ this.setup(); } Runner.prototype.getParams = function() { var name, param, params, value, _i, _len, _ref, _ref1; + params = {}; _ref = Teabag.location.search.substring(1).split("&"); for (_i = 0, _len = _ref.length; _i < _len; _i++) { param = _ref[_i]; _ref1 = param.split("="), name = _ref1[0], value = _ref1[1]; @@ -2120,10 +2297,11 @@ fixture.json = []; fixture.preload = function() { var url, urls, _i, _len, _results; + urls = 1 <= arguments.length ? __slice.call(arguments, 0) : []; _results = []; for (_i = 0, _len = urls.length; _i < _len; _i++) { url = urls[_i]; _results.push(preload(url)); @@ -2131,10 +2309,11 @@ return _results; }; fixture.load = function() { var append, index, url, urls, _i, _j, _len, _results; + urls = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), append = arguments[_i++]; if (append == null) { append = false; } if (typeof append !== "boolean") { @@ -2149,10 +2328,11 @@ return _results; }; fixture.set = function() { var append, html, htmls, index, _i, _j, _len, _results; + htmls = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), append = arguments[_i++]; if (append == null) { append = false; } if (typeof append !== "boolean") { @@ -2181,10 +2361,11 @@ return load(url, false, true); }; load = function(url, append, preload) { var cached, value; + if (preload == null) { preload = false; } if (cached = Teabag.fixture.cache[url]) { return loadComplete(url, cached.type, cached.content, append, preload); @@ -2242,40 +2423,45 @@ return Teabag.fixture.el.innerHTML += content; }; create = function() { var _ref; + Teabag.fixture.el = document.createElement("div"); if (typeof window.$ === 'function') { Teabag.fixture.$el = $(Teabag.fixture.el); } Teabag.fixture.el.id = "teabag-fixtures"; return (_ref = document.body) != null ? _ref.appendChild(Teabag.fixture.el) : void 0; }; cleanup = function() { var _base, _ref, _ref1; + (_base = Teabag.fixture).el || (_base.el = document.getElementById("teabag-fixtures")); if ((_ref = Teabag.fixture.el) != null) { if ((_ref1 = _ref.parentNode) != null) { _ref1.removeChild(Teabag.fixture.el); } } return Teabag.fixture.el = null; }; xhrRequest = function(url, callback) { + var e; + if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); - } catch (e) { + } catch (_error) { + e = _error; try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); - } catch (e) { - + } catch (_error) { + e = _error; } } } if (!xhr) { throw "Unable to make Ajax Request"; @@ -2289,13 +2475,11 @@ }).call(this); }).call(this); (function() { - Teabag.Reporters.BaseView = (function() { - function BaseView() { this.elements = {}; this.build(); } @@ -2311,32 +2495,36 @@ return this.el.appendChild(el); }; BaseView.prototype.createEl = function(type, className) { var el; + if (className == null) { className = ""; } el = document.createElement(type); el.className = className; return el; }; BaseView.prototype.findEl = function(id) { var _base; + this.elements || (this.elements = {}); return (_base = this.elements)[id] || (_base[id] = document.getElementById("teabag-" + id)); }; BaseView.prototype.setText = function(id, value) { var el; + el = this.findEl(id); return el.innerHTML = value; }; BaseView.prototype.setHtml = function(id, value, add) { var el; + if (add == null) { add = false; } el = this.findEl(id); if (add) { @@ -2346,16 +2534,18 @@ } }; BaseView.prototype.setClass = function(id, value) { var el; + el = this.findEl(id); return el.className = value; }; BaseView.prototype.htmlSafe = function(str) { var el; + el = document.createElement("div"); el.appendChild(document.createTextNode(str)); return el.innerHTML; }; @@ -2368,18 +2558,15 @@ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Teabag.Reporters.HTML = (function(_super) { - __extends(HTML, _super); function HTML() { this.toggleConfig = __bind(this.toggleConfig, this); - - this.reportRunnerResults = __bind(this.reportRunnerResults, this); - this.start = new Teabag.Date().getTime(); + this.reportRunnerResults = __bind(this.reportRunnerResults, this); this.start = new Teabag.Date().getTime(); this.config = { "use-catch": true, "build-full-report": false, "display-progress": true }; @@ -2400,10 +2587,11 @@ HTML.__super__.constructor.apply(this, arguments); } HTML.prototype.build = function() { var _ref; + this.buildLayout(); this.setText("env-info", this.envInfo()); this.setText("version", Teabag.version); this.findEl("toggles").onclick = this.toggleConfig; this.findEl("suites").innerHTML = this.buildSuiteSelect(); @@ -2417,18 +2605,20 @@ return this.buildFilters(); }; HTML.prototype.buildLayout = function() { var el; + el = this.createEl("div"); el.id = "teabag-interface"; el.innerHTML = Teabag.Reporters.HTML.template; return document.body.appendChild(el); }; HTML.prototype.buildSuiteSelect = function() { var options, suite, _i, _len, _ref; + if (Teabag.suites.all.length === 1) { return ""; } options = []; _ref = Teabag.suites.all; @@ -2501,10 +2691,11 @@ return this.setText("stats-" + name, value); }; HTML.prototype.updateStatus = function(spec) { var elapsed, result, _ref, _ref1; + spec = new Teabag.Spec(spec); result = spec.result(); if (result.skipped || result.status === "pending") { this.updateStat("skipped", this.total.skipped += 1); return; @@ -2529,10 +2720,11 @@ return this.progress.update(this.total.exist, this.total.run); }; HTML.prototype.showConfiguration = function() { var key, value, _ref, _results; + _ref = this.config; _results = []; for (key in _ref) { value = _ref[key]; _results.push(this.setClass(key, value ? "active" : "")); @@ -2544,10 +2736,11 @@ return document.body.className = "teabag-" + status; }; HTML.prototype.setFilters = function() { var link; + link = [Teabag.root, Teabag.suites.active].join('/'); if (Teabag.params["file"]) { this.filters.push("<a href='" + link + "'>remove</a> by file: " + Teabag.params["file"]); } if (Teabag.params["grep"]) { @@ -2555,17 +2748,19 @@ } }; HTML.prototype.readConfig = function() { var config; + if (config = this.cookie("teabag")) { return this.config = config; } }; HTML.prototype.toggleConfig = function(e) { var button, name; + button = e.target; if (button.tagName.toLowerCase() !== "button") { return; } name = button.getAttribute("id").replace(/^teabag-/, ""); @@ -2582,10 +2777,11 @@ return window.location.href = window.location.href; }; HTML.prototype.cookie = function(name, value) { var date, match; + if (value == null) { value = void 0; } if (value === void 0) { name = name.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1"); @@ -2602,19 +2798,20 @@ })(Teabag.Reporters.BaseView); }).call(this); (function() { - var __hasProp = {}.hasOwnProperty, + var _ref, _ref1, _ref2, + __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Teabag.Reporters.HTML.ProgressView = (function(_super) { - __extends(ProgressView, _super); function ProgressView() { - return ProgressView.__super__.constructor.apply(this, arguments); + _ref = ProgressView.__super__.constructor.apply(this, arguments); + return _ref; } ProgressView.create = function(displayProgress) { if (displayProgress == null) { displayProgress = true; @@ -2638,64 +2835,67 @@ return ProgressView; })(Teabag.Reporters.BaseView); Teabag.Reporters.HTML.SimpleProgressView = (function(_super) { - __extends(SimpleProgressView, _super); function SimpleProgressView() { - return SimpleProgressView.__super__.constructor.apply(this, arguments); + _ref1 = SimpleProgressView.__super__.constructor.apply(this, arguments); + return _ref1; } SimpleProgressView.prototype.build = function() { this.el = this.createEl("div", "simple-progress"); return this.el.innerHTML = "<em id=\"teabag-progress-percent\">0%</em>\n<span id=\"teabag-progress-span\" class=\"teabag-indicator\"></span>"; }; SimpleProgressView.prototype.update = function(total, run) { var percent; + percent = total ? Math.ceil((run * 100) / total) : 0; return this.setHtml("progress-percent", "" + percent + "%"); }; return SimpleProgressView; })(Teabag.Reporters.HTML.ProgressView); Teabag.Reporters.HTML.RadialProgressView = (function(_super) { - __extends(RadialProgressView, _super); function RadialProgressView() { - return RadialProgressView.__super__.constructor.apply(this, arguments); + _ref2 = RadialProgressView.__super__.constructor.apply(this, arguments); + return _ref2; } RadialProgressView.supported = !!document.createElement("canvas").getContext; RadialProgressView.prototype.build = function() { this.el = this.createEl("div", "teabag-indicator radial-progress"); return this.el.innerHTML = "<canvas id=\"teabag-progress-canvas\"></canvas>\n<em id=\"teabag-progress-percent\">0%</em>"; }; RadialProgressView.prototype.appendTo = function() { - var canvas; + var canvas, e; + RadialProgressView.__super__.appendTo.apply(this, arguments); this.size = 80; try { canvas = this.findEl("progress-canvas"); canvas.width = canvas.height = canvas.style.width = canvas.style.height = this.size; this.ctx = canvas.getContext("2d"); this.ctx.strokeStyle = "#fff"; return this.ctx.lineWidth = 1.5; - } catch (e) { - + } catch (_error) { + e = _error; } }; RadialProgressView.prototype.update = function(total, run) { var half, percent; + percent = total ? Math.ceil((run * 100) / total) : 0; this.setHtml("progress-percent", "" + percent + "%"); if (!this.ctx) { return; } @@ -2731,10 +2931,11 @@ SpecView.__super__.constructor.apply(this, arguments); } SpecView.prototype.build = function() { var classes; + classes = ["spec"]; if (this.spec.pending) { classes.push("state-pending"); } SpecView.__super__.build.call(this, classes.join(" ")); @@ -2743,10 +2944,11 @@ return this.parentView.append(this.el); }; SpecView.prototype.buildParent = function() { var parent, view; + parent = this.spec.parent; if (parent.viewId) { return this.views.suites[parent.viewId]; } else { view = new Teabag.Reporters.HTML.SuiteView(parent, this.reporter); @@ -2754,10 +2956,11 @@ } }; SpecView.prototype.buildErrors = function() { var div, error, html, _i, _len, _ref; + div = this.createEl("div"); html = ""; _ref = this.spec.errors(); for (_i = 0, _len = _ref.length; _i < _len; _i++) { error = _ref[_i]; @@ -2767,10 +2970,11 @@ return this.append(div); }; SpecView.prototype.updateState = function(state, elapsed) { var classes, result, _base; + result = this.spec.result(); classes = ["state-" + state]; if (elapsed > Teabag.slow) { classes.push("slow"); } @@ -2792,20 +2996,20 @@ (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Teabag.Reporters.HTML.FailureView = (function(_super) { - __extends(FailureView, _super); function FailureView(spec) { this.spec = spec; FailureView.__super__.constructor.apply(this, arguments); } FailureView.prototype.build = function() { var error, html, _i, _len, _ref; + FailureView.__super__.build.call(this, "spec"); html = "<h1 class=\"teabag-clearfix\"><a href=\"" + this.spec.link + "\">" + this.spec.fullDescription + "</a></h1>"; _ref = this.spec.errors(); for (_i = 0, _len = _ref.length; _i < _len; _i++) { error = _ref[_i]; @@ -2847,10 +3051,11 @@ return this.parentView.append(this.el); }; SuiteView.prototype.buildParent = function() { var parent, view; + parent = this.suite.parent; if (!parent) { return this.reporter; } if (parent.viewId) { @@ -2868,10 +3073,11 @@ return this.ol.appendChild(el); }; SuiteView.prototype.updateState = function(state) { var _base; + if (this.state === "failed") { return; } this.el.className = "" + (this.el.className.replace(/\s?state-\w+/, "")) + " state-" + state; if (typeof (_base = this.parentView).updateState === "function") { @@ -2884,22 +3090,19 @@ })(Teabag.Reporters.BaseView); }).call(this); (function() { - Teabag.Reporters.HTML.template = "<div class=\"teabag-clearfix\">\n <div id=\"teabag-title\">\n <h1><a href=\"\" id=\"teabag-root-link\">Teabag</a></h1>\n <ul>\n <li>version: <b id=\"teabag-version\"></b></li>\n <li id=\"teabag-env-info\"></li>\n </ul>\n </div>\n <div id=\"teabag-progress\"></div>\n <ul id=\"teabag-stats\">\n <li>passes: <b id=\"teabag-stats-passes\">0</b></li>\n <li>failures: <b id=\"teabag-stats-failures\">0</b></li>\n <li>skipped: <b id=\"teabag-stats-skipped\">0</b></li>\n <li>duration: <b id=\"teabag-stats-duration\">&infin;</b></li>\n </ul>\n</div>\n\n<div id=\"teabag-controls\" class=\"teabag-clearfix\">\n <div id=\"teabag-toggles\">\n <button id=\"teabag-use-catch\" title=\"Toggle using try/catch wrappers when possible\">Try/Catch</button>\n <button id=\"teabag-build-full-report\" title=\"Toggle building the full report\">Full Report</button>\n <button id=\"teabag-display-progress\" title=\"Toggle displaying progress as tests run\">Progress</button>\n </div>\n <div id=\"teabag-suites\"></div>\n</div>\n\n<hr/>\n\n<div id=\"teabag-filter\">\n <h1>Filtering</h1>\n <ul id=\"teabag-filter-list\"></ul>\n</div>\n\n<div id=\"teabag-report\">\n <ol id=\"teabag-report-failures\"></ol>\n <ol id=\"teabag-report-all\"></ol>\n</div>"; }).call(this); (function() { var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Teabag.Reporters.Console = (function() { - function Console() { - this.reportRunnerResults = __bind(this.reportRunnerResults, this); - this.start = new Teabag.Date(); + this.reportRunnerResults = __bind(this.reportRunnerResults, this); this.start = new Teabag.Date(); this.suites = {}; } Console.prototype.reportRunnerStarting = function(runner) { return this.log({ @@ -2909,10 +3112,11 @@ }); }; Console.prototype.reportSuites = function() { var index, suite, _i, _len, _ref, _results; + _ref = this.spec.getParents(); _results = []; for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { suite = _ref[index]; if (this.suites[suite.fullDescription]) { @@ -2928,10 +3132,11 @@ return _results; }; Console.prototype.reportSpecResults = function(spec) { var result; + this.spec = new Teabag.Spec(spec); result = this.spec.result(); if (result.skipped) { return; } @@ -2952,10 +3157,11 @@ } }; Console.prototype.trackPending = function() { var result; + result = this.spec.result(); return this.log({ type: "spec", suite: this.spec.suiteName, label: this.spec.description, @@ -2964,10 +3170,11 @@ }); }; Console.prototype.trackFailure = function() { var error, result, _i, _len, _ref, _results; + result = this.spec.result(); _ref = this.spec.errors(); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { error = _ref[_i]; @@ -3048,23 +3255,21 @@ })(Teabag.Reporters.Console); }).call(this); (function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + var _ref, _ref1, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Teabag.Reporters.HTML = (function(_super) { - __extends(HTML, _super); function HTML(env) { this.reportRunnerResults = __bind(this.reportRunnerResults, this); - - this.reportSpecResults = __bind(this.reportSpecResults, this); - HTML.__super__.constructor.apply(this, arguments); + this.reportSpecResults = __bind(this.reportSpecResults, this); HTML.__super__.constructor.apply(this, arguments); env.log(this.reportSpecResults); env.testDone(this.reportSpecResults); env.done(this.reportRunnerResults); this.currentAssertions = []; this.reportRunnerStarting(); @@ -3095,40 +3300,42 @@ HTML.__super__.readConfig.apply(this, arguments); return QUnit.config.notrycatch = this.config["use-catch"]; }; HTML.prototype.envInfo = function() { - return "qunit 1.10.0"; + return "qunit 1.11.0"; }; return HTML; })(Teabag.Reporters.HTML); Teabag.Reporters.HTML.SpecView = (function(_super) { - __extends(SpecView, _super); function SpecView() { - return SpecView.__super__.constructor.apply(this, arguments); + _ref = SpecView.__super__.constructor.apply(this, arguments); + return _ref; } SpecView.prototype.buildErrors = function() { - var div, error, html, _i, _len, _ref; + var div, error, html, _i, _len, _ref1; + div = this.createEl("div"); html = ""; - _ref = this.spec.errors(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - error = _ref[_i]; + _ref1 = this.spec.errors(); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + error = _ref1[_i]; html += "<strong>" + error.message + "</strong><br/>" + (this.htmlSafe(error.stack || "Stack trace unavailable")) + "<br/>"; } div.innerHTML = html; return this.append(div); }; SpecView.prototype.buildParent = function() { var parent, view; + parent = this.spec.parent; if (!parent) { return this.reporter; } if (this.views.suites[parent.description]) { @@ -3142,35 +3349,35 @@ return SpecView; })(Teabag.Reporters.HTML.SpecView); Teabag.Reporters.HTML.FailureView = (function(_super) { - __extends(FailureView, _super); function FailureView() { - return FailureView.__super__.constructor.apply(this, arguments); + _ref1 = FailureView.__super__.constructor.apply(this, arguments); + return _ref1; } FailureView.prototype.build = function() { - var error, html, _i, _len, _ref; + var error, html, _i, _len, _ref2; + FailureView.__super__.build.call(this, "spec"); html = "<h1 class=\"teabag-clearfix\"><a href=\"" + this.spec.link + "\">" + this.spec.fullDescription + "</a></h1>"; - _ref = this.spec.errors(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - error = _ref[_i]; + _ref2 = this.spec.errors(); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + error = _ref2[_i]; html += "<div><strong>" + error.message + "</strong><br/>" + (this.htmlSafe(error.stack || "Stack trace unavailable")) + "</div>"; } return this.el.innerHTML = html; }; return FailureView; })(Teabag.Reporters.HTML.FailureView); Teabag.Reporters.HTML.SuiteView = (function(_super) { - __extends(SuiteView, _super); function SuiteView(suite, reporter) { this.suite = suite; this.reporter = reporter; @@ -3188,11 +3395,10 @@ var env, originalReset, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Teabag.Runner = (function(_super) { - __extends(Runner, _super); function Runner() { Runner.__super__.constructor.apply(this, arguments); env.start(); @@ -3205,11 +3411,10 @@ return Runner; })(Teabag.Runner); Teabag.Spec = (function() { - function Spec(spec) { this.spec = spec; this.fullDescription = "" + this.spec.module + " " + this.spec.name; this.description = "" + this.spec.name + " (" + this.spec.failed + ", " + this.spec.passed + ", " + this.spec.total + ")"; this.link = "?grep=" + (encodeURIComponent("" + this.spec.module + ": " + this.spec.name)); @@ -3221,10 +3426,11 @@ this.pending = false; } Spec.prototype.errors = function() { var item, _i, _len, _ref, _results; + if (!this.spec.failed) { return []; } _ref = this.spec.assertions; _results = []; @@ -3248,10 +3454,11 @@ return [this.parent]; }; Spec.prototype.result = function() { var status; + status = "failed"; if (!this.spec.failed) { status = "passed"; } return { @@ -3263,11 +3470,10 @@ return Spec; })(); Teabag.Suite = (function() { - function Suite(suite) { this.suite = suite; this.fullDescription = this.suite.description; this.description = this.suite.description; this.link = "?grep=" + (encodeURIComponent(this.fullDescription)); @@ -3294,6 +3500,6 @@ originalReset(); return Teabag.fixture.cleanup(); }; }).call(this); -;TI"required_assets_digest;F"%52974d09b99d6b96e0c6627b507e414cI" _version;F"%6776f581a4329e299531e1d52aa59832 +;TI"required_assets_digest;F"%762bf7a99c1627a6d50bc9a0913c1741I" _version;F"%6776f581a4329e299531e1d52aa59832 \ No newline at end of file