From 9ecbcd0075216043c0725737f30f42155292fe5b Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 10 Feb 2013 23:42:09 -0800 Subject: [PATCH] Update vendor/qunit-clib and tests to work with Ringo 0.9 and PhantomJS. Former-commit-id: e6906e4b9f6afdee598902d6939356bf33302909 --- perf/perf.js | 43 ++- perf/run-perf.sh | 15 +- test/run-test.sh | 7 +- test/test.js | 43 ++- vendor/qunit-clib/LICENSE.txt | 2 +- vendor/qunit-clib/README.md | 13 +- vendor/qunit-clib/qunit-clib.js | 513 ++++++++++++++------------------ 7 files changed, 313 insertions(+), 323 deletions(-) diff --git a/perf/perf.js b/perf/perf.js index 769056774..4ff9cf5bc 100644 --- a/perf/perf.js +++ b/perf/perf.js @@ -1,8 +1,28 @@ (function(window) { - /** Use a single load function */ + /** Use a single "load" function */ var load = typeof require == 'function' ? require : window.load; + /** The file path of the Lo-Dash file to test */ + var filePath = (function() { + var min = 0; + var result = window.phantom + ? phantom.args + : (window.system + ? (min = 1, system.args) + : (window.process ? (min = 2, process.argv) : (window.arguments || [])) + ); + + var last = result[result.length - 1]; + result = (result.length > min && last != 'test.js') ? last : '../lodash.js'; + + try { + result = require('fs').realpathSync(result); + } catch(e) { } + + return result; + }()); + /** Load Benchmark.js */ var Benchmark = window.Benchmark || ( @@ -13,7 +33,7 @@ /** Load Lo-Dash */ var lodash = window.lodash || ( - lodash = load('../dist/lodash.js') || window._, + lodash = load(filePath) || window._, lodash = lodash._ || lodash, lodash.noConflict() ); @@ -35,22 +55,27 @@ var suites = []; /** The `ui` object */ - var ui = window.ui || {}; + var ui = window.ui || { + 'buildPath': basename(filePath, '.js'), + 'otherPath': 'underscore' + }; /** The Lo-Dash build basename */ - var buildName = basename(ui.buildPath || 'lodash', '.js'); + var buildName = basename(ui.buildPath, '.js'); /** The other library basename */ - var otherName = basename(ui.otherPath || 'underscore', '.js'); - - /** Add `console.log()` support for Narwhal and RingoJS */ - window.console || (window.console = { 'log': window.print }); + var otherName = basename(ui.otherPath, '.js'); /** Expose functions to the global object */ window._ = _; window.Benchmark = Benchmark; window.lodash = lodash; + /** Add `console.log()` support for Narwhal and RingoJS */ + if (!window.console && window.print) { + window.console = { 'log': window.print }; + } + /*--------------------------------------------------------------------------*/ /** @@ -1691,7 +1716,7 @@ } // in the browser, expose `run` to be called later - if (window.document) { + if (window.document && !window.phantom) { window.run = run; } else { run(); diff --git a/perf/run-perf.sh b/perf/run-perf.sh index 02141a5d9..8593cd6bd 100755 --- a/perf/run-perf.sh +++ b/perf/run-perf.sh @@ -1,9 +1,14 @@ cd "$(dirname "$0")" -for cmd in node narwhal ringo rhino; do - echo "" - echo "Running performance suite in $cmd..." - $cmd perf.js + +echo "Running performance suite in node..." +node perf.js ../dist/lodash.js && node perf.js ../dist/lodash.min.js + +for cmd in rhino narwhal ringo phantomjs; do + echo "" + echo "Running performance suite in $cmd..." + $cmd perf.js ../dist/lodash.compat.js && $cmd perf.js ../dist/lodash.compat.min.js done + echo "" echo "Running performance suite in a browser..." -open index.html \ No newline at end of file +open index.html diff --git a/test/run-test.sh b/test/run-test.sh index 5e8962e12..8bcee20da 100755 --- a/test/run-test.sh +++ b/test/run-test.sh @@ -1,14 +1,15 @@ cd "$(dirname "$0")" -for cmd in rhino ringo narwhal; do - echo "" + +for cmd in rhino narwhal ringo phantomjs; do echo "Testing in $cmd..." $cmd test.js ../dist/lodash.compat.js && $cmd test.js ../dist/lodash.compat.min.js + echo "" done -echo "" echo "Testing in node..." node test.js ../dist/lodash.js && node test.js ../dist/lodash.min.js +echo "" echo "Testing build..." node test-build.js diff --git a/test/test.js b/test/test.js index df186479d..58352819e 100644 --- a/test/test.js +++ b/test/test.js @@ -1,19 +1,21 @@ ;(function(window, undefined) { 'use strict'; - /** Use a single load function */ + /** Use a single "load" function */ var load = typeof require == 'function' ? require : window.load; /** The file path of the Lo-Dash file to test */ var filePath = (function() { var min = 0; - var result = window.system - ? (min = 1, system.args) - : (window.process ? (min = 2, process.argv) : (window.arguments || [])); + var result = window.phantom + ? phantom.args + : (window.system + ? (min = 1, system.args) + : (window.process ? (min = 2, process.argv) : (window.arguments || [])) + ); - result = result.length > min - ? result[result.length - 1] - : '../lodash.js'; + var last = result[result.length - 1]; + result = (result.length > min && last != 'test.js') ? last : '../lodash.js'; try { result = require('fs').realpathSync(result); @@ -35,7 +37,7 @@ var QUnit = window.QUnit || ( window.addEventListener || (window.addEventListener = Function.prototype), - window.setTimeout || (window.setTimeout = / /), + window.setTimeout || (window.setTimeout = Function.prototype), window.QUnit = load('../vendor/qunit/qunit/qunit.js') || window.QUnit, load('../vendor/qunit-clib/qunit-clib.js'), window.addEventListener === Function.prototype && delete window.addEventListener, @@ -114,7 +116,7 @@ // add object from iframe (function() { - if (!window.document) { + if (!window.document || window.phantom) { return; } var body = document.body, @@ -135,7 +137,7 @@ (function() { test('supports loading ' + basename + ' as the "lodash" module', function() { - if (window.document && window.require) { + if (window.document && window.define && define.amd) { equal((lodashModule || {}).moduleName, 'lodash'); } else { skipTest(); @@ -143,7 +145,7 @@ }); test('supports loading ' + basename + ' with the Require.js "shim" configuration option', function() { - if (window.document && window.require) { + if (window.document && window.define && define.amd) { equal((shimmedModule || {}).moduleName, 'shimmed'); } else { skipTest(); @@ -151,7 +153,7 @@ }); test('supports loading ' + basename + ' as the "underscore" module', function() { - if (window.document && window.require) { + if (window.document && window.define && define.amd) { equal((underscoreModule || {}).moduleName, 'underscore'); } else { skipTest(); @@ -159,7 +161,7 @@ }); test('avoids overwritten native methods', function() { - if (window.document) { + if (window.document && !window.phantom) { notDeepEqual(lodashBadShim.keys({ 'a': 1 }), []); } else { skipTest(); @@ -2653,6 +2655,9 @@ (function() { test('should allow falsey arguments', function() { + var isExported = '_' in window, + oldDash = window._; + var returnArrays = [ 'filter', 'invoke', @@ -2699,6 +2704,13 @@ } }); + if (methodName == 'noConflict') { + if (isExported) { + window._ = oldDash; + } else { + delete window._; + } + } if (_.indexOf(returnArrays, methodName) > -1) { deepEqual(actual, expected, '_.' + methodName + ' returns an array'); } @@ -2763,8 +2775,9 @@ /*--------------------------------------------------------------------------*/ - // explicitly call `QUnit.start()` for Narwhal, Node.js, Rhino, and RingoJS - if (!window.document) { + // configure QUnit and call `QUnit.start()` for Narwhal, Node.js, PhantomJS, Rhino, and RingoJS + if (!window.document || window.phantom) { + QUnit.config.noglobals = true; QUnit.start(); } }(typeof global == 'object' && global || this)); diff --git a/vendor/qunit-clib/LICENSE.txt b/vendor/qunit-clib/LICENSE.txt index dadad22fa..a7501f98d 100644 --- a/vendor/qunit-clib/LICENSE.txt +++ b/vendor/qunit-clib/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright 2011-2012 John-David Dalton +Copyright 2011-2013 John-David Dalton Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/vendor/qunit-clib/README.md b/vendor/qunit-clib/README.md index b84a21c98..7c2edfa8f 100644 --- a/vendor/qunit-clib/README.md +++ b/vendor/qunit-clib/README.md @@ -1,4 +1,4 @@ -# QUnit CLIB v1.0.0 +# QUnit CLIB v1.2.0 ## command-line interface boilerplate QUnit CLIB helps extend QUnit's CLI support to many common CLI environments. @@ -9,23 +9,24 @@ QUnit CLIB helps extend QUnit's CLI support to many common CLI environments. ## Support -QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, RingoJS v0.8.0, and Rhino v1.7RC3-RC5. +QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.19, Narwhal v0.3.2, PhantomJS 1.8.1, RingoJS v0.9, and Rhino v1.7RC5. ## Usage ```js (function(window) { - // use a single load function + // use a single "load" function var load = typeof require == 'function' ? require : window.load; // load QUnit and CLIB if needed var QUnit = window.QUnit || ( - window.setTimeout || (window.addEventListener = window.setTimeout = / /), + window.addEventListener || (window.addEventListener = Function.prototype), + window.setTimeout || (window.setTimeout = Function.prototype), window.QUnit = load('path/to/qunit.js') || window.QUnit, load('path/to/qunit-clib.js'), - (window.addEventListener || 0).test && delete window.addEventListener, + window.addEventListener === Function.prototype && delete window.addEventListener, window.QUnit ); @@ -38,7 +39,7 @@ QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, Ring }); // must call `QUnit.start()` if using QUnit < 1.3.0 with Node.js or any - // version of QUnit with Narwhal, Rhino, or RingoJS + // version of QUnit with Narwhal, PhantomJS, Rhino, or RingoJS if (!window.document) { QUnit.start(); } diff --git a/vendor/qunit-clib/qunit-clib.js b/vendor/qunit-clib/qunit-clib.js index 14a3da825..7174febe1 100644 --- a/vendor/qunit-clib/qunit-clib.js +++ b/vendor/qunit-clib/qunit-clib.js @@ -1,324 +1,269 @@ /*! - * QUnit CLI Boilerplate v1.0.0 + * QUnit CLI Boilerplate v1.2.0 * Copyright 2011-2012 John-David Dalton * Based on a gist by Jörn Zaefferer * Available under MIT license */ -;(function(global) { +;(function(window) { 'use strict'; - /** Add `console.log()` support for Narwhal, Rhino, and RingoJS */ - global.console || (global.console = { 'log': global.print }); - - /** Reduce global.QUnit.QUnit -> global.QUnit */ - global.QUnit && (QUnit = QUnit.QUnit || QUnit); - - /*--------------------------------------------------------------------------*/ - - /** Used as a horizontal rule in console output */ - var hr = '----------------------------------------'; - - /** Shortcut used to convert array-like objects to arrays */ - var slice = [].slice; - - /** Used to resolve a value's internal [[Class]] */ - var toString = {}.toString; - - /** Used by timer methods */ - var doneCalled, - timer, - counter = 0, - ids = {}; - - /*--------------------------------------------------------------------------*/ - - /** - * An iteration utility for arrays. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(array, callback) { - var index = -1, - length = array.length; - - while (++index < length) { - callback(array[index], index, array); - } - } - - /** - * Checks if the specified `value` is a function. - * - * @private - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if `value` is a function, else `false`. - */ - function isFunction(value) { - return toString.call(value) == '[object Function]'; - } - - /*--------------------------------------------------------------------------*/ - /** * Timeout fallbacks based on the work of Andrea Giammarchi and Weston C. * https://github.com/WebReflection/wru/blob/master/src/rhinoTimers.js * http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout */ + (function() { - /** - * Clears the delay set by `setInterval` or `setTimeout`. - * - * @memberOf global - * @param {Number} id The ID of the timeout to be cleared. - */ - function clearTimer(id) { - if (ids[id]) { - ids[id].cancel(); - timer.purge(); - delete ids[id]; - } - } - - /** - * Schedules timer-based callbacks. - * - * @private - * @param {Function} fn The function to call. - * @oaram {Number} delay The number of milliseconds to delay the `fn` call. - * @param [arg1, arg2, ...] Arguments to invoke `fn` with. - * @param {Boolean} repeated A flag to specify whether `fn` is called repeatedly. - * @returns {Number} The the ID of the timeout. - */ - function schedule(fn, delay, args, repeated) { - // Rhino 1.7RC4 will error assigning `task` below - // https://bugzilla.mozilla.org/show_bug.cgi?id=775566 - var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, { - 'run': function() { - fn.apply(global, args); + /** + * Schedules timer-based callbacks. + * + * @private + * @param {Function|String} fn The function to call. + * @oaram {Number} delay The number of milliseconds to delay the `fn` call. + * @param [arg1, arg2, ...] Arguments to invoke `fn` with. + * @param {Boolean} repeated A flag to specify whether `fn` is called repeatedly. + * @returns {Number} The the ID of the timeout. + */ + function schedule(fn, delay, args, repeated) { + // Rhino 1.7RC4 will error assigning `task` below + // https://bugzilla.mozilla.org/show_bug.cgi?id=775566 + var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, { + 'run': function() { + fn.apply(window, args); + } + }); + // support non-functions + if (typeof fn != 'function') { + fn = (function(code) { + code = String(code); + return function() { eval(code); }; + }(fn)); } - }); - // support non-functions - if (!isFunction(fn)) { - fn = (function(code) { - code = String(code); - return function() { eval(code); }; - }(fn)); + // used by setInterval + if (repeated) { + timer.schedule(task, delay, delay); + } + // used by setTimeout + else { + timer.schedule(task, delay); + } + return counter; } - // used by setInterval - if (repeated) { - timer.schedule(task, delay, delay); - } - // used by setTimeout - else { - timer.schedule(task, delay); - } - return counter; - } - /** - * Executes a code snippet or function repeatedly, with a delay between each call. - * - * @memberOf global - * @param {Function|String} fn The function to call or string to evaluate. - * @oaram {Number} delay The number of milliseconds to delay each `fn` call. - * @param [arg1, arg2, ...] Arguments to invoke `fn` with. - * @returns {Number} The the ID of the timeout. - */ - function setInterval(fn, delay) { - return schedule(fn, delay, slice.call(arguments, 2), true); - } + /** + * Clears the delay set by `setInterval` or `setTimeout`. + * + * @memberOf window + * @param {Number} id The ID of the timeout to be cleared. + */ + function clearTimer(id) { + if (ids[id]) { + ids[id].cancel(); + timer.purge(); + delete ids[id]; + } + } - /** - * Executes a code snippet or a function after specified delay. - * - * @memberOf global - * @param {Function|String} fn The function to call or string to evaluate. - * @oaram {Number} delay The number of milliseconds to delay the `fn` call. - * @param [arg1, arg2, ...] Arguments to invoke `fn` with. - * @returns {Number} The the ID of the timeout. - */ - function setTimeout(fn, delay) { - return schedule(fn, delay, slice.call(arguments, 2)); - } + /** + * Executes a code snippet or function repeatedly, with a delay between each call. + * + * @memberOf window + * @param {Function|String} fn The function to call or string to evaluate. + * @oaram {Number} delay The number of milliseconds to delay each `fn` call. + * @param [arg1, arg2, ...] Arguments to invoke `fn` with. + * @returns {Number} The the ID of the timeout. + */ + function setInterval(fn, delay) { + return schedule(fn, delay, slice.call(arguments, 2), true); + } + + /** + * Executes a code snippet or a function after specified delay. + * + * @memberOf window + * @param {Function|String} fn The function to call or string to evaluate. + * @oaram {Number} delay The number of milliseconds to delay the `fn` call. + * @param [arg1, arg2, ...] Arguments to invoke `fn` with. + * @returns {Number} The the ID of the timeout. + */ + function setTimeout(fn, delay) { + return schedule(fn, delay, slice.call(arguments, 2)); + } + + try { + var counter = 0, + ids = {}, + slice = Array.prototype.slice, + timer = new java.util.Timer; + + window.clearInterval = + window.clearTimeout = clearTimer; + window.setInterval = setInterval; + window.setTimeout = setTimeout; + } catch(e) { } + }()); /*--------------------------------------------------------------------------*/ - /** - * A logging callback triggered when all testing is completed. - * - * @memberOf QUnit - * @param {Object} details An object with properties `failed`, `passed`, - * `runtime`, and `total`. - */ - function done(details) { - // stop `asyncTest()` from erroneously calling `done()` twice in - // environments w/o timeouts - if (doneCalled) { - return; - } - doneCalled = true; - console.log(hr); - console.log(' PASS: ' + details.passed + ' FAIL: ' + details.failed + ' TOTAL: ' + details.total); - console.log(' Finished in ' + details.runtime + ' milliseconds.'); - console.log(hr); + (function() { - // exit out of Rhino - try { - quit(); - } catch(e) { } + /** Used as a horizontal rule in console output */ + var hr = '----------------------------------------'; - // exit out of Node.js - try { - if (details.failed) { - console.error('Error: ' + details.failed + ' of ' + details.total + ' tests failed.'); - process.exit(1); - } else { - process.exit(0); + /** Shorten `window.QUnit.QUnit` to `window.QUnit` */ + window.QUnit && (QUnit = QUnit.QUnit || QUnit); + + /** + * A logging callback triggered when all testing is completed. + * + * @memberOf QUnit + * @param {Object} details An object with properties `failed`, `passed`, `runtime`, and `total`. + */ + QUnit.done(function() { + var ran; + return function(details) { + // stop `asyncTest()` from erroneously calling `done()` twice in + // environments w/o timeouts + if (ran) { + return; + } + ran = true; + + console.log(hr); + console.log(' PASS: ' + details.passed + ' FAIL: ' + details.failed + ' TOTAL: ' + details.total); + console.log(' Finished in ' + details.runtime + ' milliseconds.'); + console.log(hr); + + // exit out of Rhino + try { + quit(); + } catch(e) { } + + // exit out of Node.js or PhantomJS + try { + var process = window.process || window.phantom; + if (details.failed) { + console.error('Error: ' + details.failed + ' of ' + details.total + ' tests failed.'); + process.exit(1); + } else { + process.exit(0); + } + } catch(e) { } + }; + }()); + + /** + * A logging callback triggered after every assertion. + * + * @memberOf QUnit + * @param {Object} details An object with properties `actual`, `expected`, `message`, and `result`. + */ + QUnit.log(function(details) { + var expected = details.expected, + result = details.result, + type = typeof expected != 'undefined' ? 'EQ' : 'OK'; + + var assertion = [ + result ? 'PASS' : 'FAIL', + type, + details.message || 'ok' + ]; + + if (!result && type == 'EQ') { + assertion.push('Expected: ' + expected + ', Actual: ' + details.actual); } - } catch(e) { } - } + QUnit.config.testStats.assertions.push(assertion.join(' | ')); + }); - /** - * A logging callback triggered after every assertion. - * - * @memberOf QUnit - * @param {Object} details An object with properties `actual`, `expected`, - * `message`, and `result`. - */ - function log(details) { - var expected = details.expected, - result = details.result, - type = typeof expected != 'undefined' ? 'EQ' : 'OK'; + /** + * A logging callback triggered at the start of every test module. + * + * @memberOf QUnit + * @param {Object} details An object with property `name`. + */ + QUnit.moduleStart(function(details) { + console.log(hr); + console.log(details.name); + console.log(hr); + }); - var assertion = [ - result ? 'PASS' : 'FAIL', - type, - details.message || 'ok' - ]; + /** + * Converts an object into a string representation. + * + * @memberOf QUnit + * @type Function + * @param {Object} object The object to stringify. + * @returns {String} The result string. + */ + QUnit.jsDump.parsers.object = (function() { + var func = QUnit.jsDump.parsers.object; + return function(object) { + // fork to support Rhino's error objects + if (typeof object.rhinoException == 'object') { + return object.name + + ' { message: "' + object.message + + '", fileName: "' + object.fileName + + '", lineNumber: ' + object.lineNumber + ' }'; + } + return func(object); + }; + }()); - if (!result && type == 'EQ') { - assertion.push('Expected: ' + expected + ', Actual: ' + details.actual); - } - QUnit.config.testStats.assertions.push(assertion.join(' | ')); - } + /** + * A logging callback triggered after a test is completed. + * + * @memberOf QUnit + * @param {Object} details An object with properties `failed`, `name`, `passed`, and `total`. + */ + QUnit.testDone(function(details) { + var assertions = QUnit.config.testStats.assertions, + testName = details.name; - /** - * A logging callback triggered at the start of every test module. - * - * @memberOf QUnit - * @param {Object} details An object with property `name`. - */ - function moduleStart(details) { - console.log(hr); - console.log(details.name); - console.log(hr); - } - - /** - * Converts an object into a string representation. - * - * @memberOf QUnit - * @type Function - * @param {Object} object The object to stringify. - * @returns {String} The result string. - */ - var parseObject = (function() { - var func = QUnit.jsDump.parsers.object; - return function(object) { - // fork to support Rhino's error objects - if (typeof object.rhinoException == 'object') { - return object.name + - ' { message: "' + object.message + - '", fileName: "' + object.fileName + - '", lineNumber: ' + object.lineNumber + ' }'; + if (details.failed > 0) { + console.log(' FAIL - '+ testName); + assertions.forEach(function(value) { + console.log(' ' + value); + }); } - return func(object); + else { + console.log(' PASS - ' + testName); + } + assertions.length = 0; + }); + + /** + * An object used to hold information about the current running test. + * + * @memberOf QUnit.config + * @type Object + */ + QUnit.config.testStats = { + + /** + * An array of test summaries (pipe separated). + * + * @memberOf QUnit.config.testStats + * @type Array + */ + 'assertions': [] }; }()); - /** - * A logging callback triggered after a test is completed. - * - * @memberOf QUnit - * @param {Object} details An object with properties `failed`, `name`, - * `passed`, and `total`. - */ - function testDone(details) { - var assertions = QUnit.config.testStats.assertions, - testName = details.name; - - if (details.failed > 0) { - console.log(' FAIL - '+ testName); - each(assertions, function(value) { - console.log(' ' + value); - }); - } - else { - console.log(' PASS - ' + testName); - } - assertions.length = 0; - } - /*--------------------------------------------------------------------------*/ - /** - * An object used to hold information about the current running test. - * - * @memberOf QUnit.config - * @type Object - */ - QUnit.config.testStats = { - - /** - * An array of test summaries (pipe separated). - * - * @memberOf QUnit.config.testStats - * @type Array - */ - 'assertions': [] - }; - - // add shortcuts to the global + // expose shortcuts // exclude `module` because some environments have it as a built-in object - each(['asyncTest', 'deepEqual', 'equal', 'equals', 'expect', 'notDeepEqual', - 'notEqual', 'notStrictEqual', 'ok', 'raises', 'same', 'start', 'stop', - 'strictEqual', 'test', 'throws'], function(funcName) { - var func = QUnit[funcName]; - if (func) { - global[funcName] = func; - } + ('asyncTest deepEqual equal equals expect notDeepEqual notEqual notStrictEqual ' + + 'ok raises same start stop strictEqual test throws').replace(/\S+/g, function(methodName) { + window[methodName] = QUnit[methodName]; }); - // expose timer methods to global - try { - timer = new java.util.Timer; - if (!isFunction(global.clearInterval)) { - global.clearInterval = clearTimer; - } - if (!isFunction(global.clearTimeout)) { - global.clearTimeout = clearTimer; - } - if (!isFunction(global.setInterval)) { - global.setInterval = setInterval; - } - if (!isFunction(global.setTimeout)) { - global.setTimeout = setTimeout; - } - } catch(e) { } - - // add callbacks - QUnit.done(done); - QUnit.log(log); - QUnit.moduleStart(moduleStart); - QUnit.testDone(testDone); - - // add wrapped function - QUnit.jsDump.parsers.object = parseObject; - + // add `console.log()` support for Narwhal, Rhino, and RingoJS + if (!window.console && window.print) { + window.console = { 'log': window.print }; + } // must call `QUnit.start()` in the test file if using QUnit < 1.3.0 with - // Node.js or any version of QUnit with Narwhal, Rhino, or RingoJS + // Node.js or any version of QUnit with Narwhal, PhantomJS, Rhino, or RingoJS QUnit.init(); }(typeof global == 'object' && global || this));