Update vendors benchmark.js and qunit-extras.

This commit is contained in:
John-David Dalton
2014-03-12 09:27:51 -07:00
parent 3ca80a7bf3
commit 2e4593eee7
2 changed files with 108 additions and 79 deletions

View File

@@ -54,7 +54,7 @@
var contextProps = [
'Array', 'Date', 'Function', 'Math', 'Object', 'RegExp', 'String', '_',
'clearTimeout', 'chrome', 'chromium', 'document', 'java', 'navigator',
'performance', 'phantom', 'platform', 'process', 'runtime', 'setTimeout'
'phantom', 'platform', 'process', 'runtime', 'setTimeout'
];
/** Used to avoid hz of Infinity */
@@ -170,15 +170,6 @@
/** Used to access Wade Simmons' Node microtime module */
var microtimeObject = req('microtime');
/** Used to access the browser's high resolution timer */
var perfObject = isHostType(context, 'performance') && context.performance;
/** Used to call the browser's high resolution timer */
var perfName = perfObject && (
perfObject.now && 'now' ||
perfObject.webkitNow && 'webkitNow'
);
/** Used to access Node's high resolution timer */
var processObject = isHostType(context, 'process') && context.process;
@@ -186,7 +177,7 @@
var trash = doc && doc.createElement('div');
/** Used to integrity check compiled tests */
var uid = 'uid' + (+new Date);
var uid = 'uid' + _.now();
/** Used to avoid infinite recursion when methods call each other */
var calledBy = {};
@@ -249,7 +240,9 @@
// parentheses from Function#toString results
// http://bugzil.la/559438
support.decompilation = Function(
'return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')'
('return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')')
// avoid issues with code added by Istanbul
.replace(/__cov__[^;]+;/g, '')
)()(0).x === '1';
} catch(e) {
support.decompilation = false;
@@ -297,6 +290,14 @@
/**
* The Benchmark constructor.
*
* Note: The Benchmark constructor exposes a handful of Lo-Dash methods to
* make working with arrays, collections, and objects easier. The Lo-Dash
* methods are:
* [`each/forEach`](http://lodash.com/docs#forEach), [`forOwn`](http://lodash.com/docs#forOwn),
* [`has`](http://lodash.com/docs#has), [`indexOf`](http://lodash.com/docs#indexOf),
* [`map`](http://lodash.com/docs#map), [`pluck`](http://lodash.com/docs#pluck),
* and [`reduce`](http://lodash.com/docs#reduce)
*
* @constructor
* @param {string} name A name to identify the benchmark.
* @param {Function|string} fn The test to benchmark.
@@ -434,12 +435,18 @@
}
return (event == null || event.constructor != Event)
? new Event(type)
: _.assign(event, { 'timeStamp': +new Date }, typeof type == 'string' ? { 'type': type } : type);
: _.assign(event, { 'timeStamp': _.now() }, typeof type == 'string' ? { 'type': type } : type);
}
/**
* The Suite constructor.
*
* Note: Each Suite instance has a handful of wrapped Lo-Dash methods to
* make working with Suites easier. The wrapped Lo-Dash methods are:
* [`each/forEach`](http://lodash.com/docs#forEach), [`indexOf`](http://lodash.com/docs#indexOf),
* [`map`](http://lodash.com/docs#map), [`pluck`](http://lodash.com/docs#pluck),
* and [`reduce`](http://lodash.com/docs#reduce)
*
* @constructor
* @memberOf Benchmark
* @param {string} name A name to identify the suite.
@@ -530,7 +537,7 @@
};
// fix JaegerMonkey bug
// http://bugzil.la/639720
createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || noop)() == uid ? createFunction : Function;
createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || _.noop)() == uid ? createFunction : Function;
return createFunction.apply(null, arguments);
}
@@ -586,16 +593,15 @@
*
* @private
* @param {Function} fn The function.
* @param {string} altSource A string used when a function's source code is unretrievable.
* @returns {string} The function's source code.
*/
function getSource(fn, altSource) {
var result = altSource;
function getSource(fn) {
var result = '';
if (isStringable(fn)) {
result = String(fn);
} else if (support.decompilation) {
// escape the `{` for Firefox 1
result = (/^[^{]+\{([\s\S]*)\}\s*$/.exec(fn) || 0)[1];
result = _.result(/^[^{]+\{([\s\S]*)\}\s*$/.exec(fn), 1);
}
// trim string
result = (result || '').replace(/^\s+|\s+$/g, '');
@@ -644,16 +650,7 @@
* @returns {boolean} Returns `true` if the value can be coerced, else `false`.
*/
function isStringable(value) {
return _.has(value, 'toString') || _.isString(value);
}
/**
* A no-operation function.
*
* @private
*/
function noop() {
// no operation performed
return _.isString(value) || (_.has(value, 'toString') && _.isFunction(value.toString));
}
/**
@@ -860,7 +857,7 @@
queued,
index = -1,
eventProps = { 'currentTarget': benches },
options = { 'onStart': noop, 'onCycle': noop, 'onComplete': noop },
options = { 'onStart': _.noop, 'onCycle': _.noop, 'onComplete': _.noop },
result = _.toArray(benches);
/**
@@ -1586,7 +1583,7 @@
var bench = clone._original,
stringable = isStringable(bench.fn),
count = bench.count = clone.count,
decompilable = support.decompilation || stringable,
decompilable = stringable || (support.decompilation && (_.has(clone, 'setup') || _.has(clone, 'teardown'))),
id = bench.id,
name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id),
result = 0;
@@ -1604,7 +1601,6 @@
timer.ns = new applet.Packages.nano;
}
}
// Compile in setup/teardown functions and the test loop.
// Create a new compiled test, instead of using the cached `bench.compiled`,
// to avoid potential engine optimizations enabled over the life of the test.
@@ -1626,7 +1622,7 @@
: 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count,n#=t#.ns;${setup}\n${begin};' +
'while(i#--){${fn}\n}${end};${teardown}\nreturn{elapsed:r#,uid:"${uid}"}';
var compiled = bench.compiled = clone.compiled = createCompiled(bench, deferred, funcBody),
var compiled = bench.compiled = clone.compiled = createCompiled(bench, decompilable, deferred, funcBody),
isEmpty = !(templateData.fn || stringable);
try {
@@ -1639,7 +1635,7 @@
// pretest to determine if compiled code exits early, usually by a
// rogue `return` statement, by checking for a return object with the uid
bench.count = 1;
compiled = (compiled.call(bench, context, timer) || {}).uid == templateData.uid && compiled;
compiled = decompilable && (compiled.call(bench, context, timer) || {}).uid == templateData.uid && compiled;
bench.count = count;
}
} catch(e) {
@@ -1648,16 +1644,16 @@
bench.count = count;
}
// fallback when a test exits early or errors during pretest
if (decompilable && !compiled && !deferred && !isEmpty) {
if (!compiled && !deferred && !isEmpty) {
funcBody = (
clone.error && !stringable
? 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count'
: 'function f#(){${fn}\n}var r#,s#,m#=this,i#=m#.count'
stringable || (decompilable && !clone.error)
? 'function f#(){${fn}\n}var r#,s#,m#=this,i#=m#.count'
: 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count'
) +
',n#=t#.ns;${setup}\n${begin};m#.f#=f#;while(i#--){m#.f#()}${end};' +
'delete m#.f#;${teardown}\nreturn{elapsed:r#}';
compiled = createCompiled(bench, deferred, funcBody);
compiled = createCompiled(bench, decompilable, deferred, funcBody);
try {
// pretest one more time to check for errors
@@ -1675,7 +1671,7 @@
}
// if no errors run the full test loop
if (!clone.error) {
compiled = bench.compiled = clone.compiled = createCompiled(bench, deferred, funcBody);
compiled = bench.compiled = clone.compiled = createCompiled(bench, decompilable, deferred, funcBody);
result = compiled.call(deferred || bench, context, timer).elapsed;
}
return result;
@@ -1686,17 +1682,17 @@
/**
* Creates a compiled function from the given function `body`.
*/
function createCompiled(bench, deferred, body) {
function createCompiled(bench, decompilable, deferred, body) {
var fn = bench.fn,
fnArg = deferred ? getFirstArgument(fn) || 'deferred' : '';
templateData.uid = uid + uidCounter++;
_.assign(templateData, {
'setup': getSource(bench.setup, interpolate('m#.setup()')),
'fn': getSource(fn, interpolate('m#.fn(' + fnArg + ')')),
'setup': decompilable ? getSource(bench.setup) : interpolate('m#.setup()'),
'fn': decompilable ? getSource(fn) : interpolate('m#.fn(' + fnArg + ')'),
'fnArg': fnArg,
'teardown': getSource(bench.teardown, interpolate('m#.teardown()'))
'teardown': decompilable ? getSource(bench.teardown) : interpolate('m#.teardown()')
});
// use API of chosen timer
@@ -1719,11 +1715,6 @@
'begin': interpolate('s#=n#.start()'),
'end': interpolate('r#=n#.microseconds()/1e6')
});
} else if (perfName) {
_.assign(templateData, {
'begin': interpolate('s#=n#.' + perfName + '()'),
'end': interpolate('r#=(n#.' + perfName + '()-s#)/1e3')
});
} else {
_.assign(templateData, {
'begin': interpolate('s#=n#()'),
@@ -1731,10 +1722,16 @@
});
}
}
else if (timer.ns.now) {
_.assign(templateData, {
'begin': interpolate('s#=n#.now()'),
'end': interpolate('r#=(n#.now()-s#)/1e3')
});
}
else {
_.assign(templateData, {
'begin': interpolate('s#=new n#'),
'end': interpolate('r#=(new n#-s#)/1e3')
'begin': interpolate('s#=new n#().getTime()'),
'end': interpolate('r#=(new n#().getTime()-s#)/1e3')
});
}
// define `timer` methods
@@ -1774,9 +1771,6 @@
if (ns.stop) {
ns.start();
while (!(measured = ns.microseconds())) { }
} else if (ns[perfName]) {
divisor = 1e3;
measured = Function('n', 'var r,s=n.' + perfName + '();while(!(r=n.' + perfName + '()-s)){};return r')(ns);
} else {
begin = ns();
while (!(measured = ns() - begin)) { }
@@ -1793,9 +1787,13 @@
divisor = 1;
}
}
else if (ns.now) {
begin = ns.now();
while (!(measured = ns.now() - begin)) { }
}
else {
begin = new ns;
while (!(measured = new ns - begin)) { }
begin = new ns().getTime();
while (!(measured = new ns().getTime() - begin)) { }
}
// check for broken timers (nanoTime may have issues)
// http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/
@@ -1841,25 +1839,16 @@
}
} catch(e) { }
// detect `performance.now` microsecond resolution timer
if ((timer.ns = perfName && perfObject)) {
timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
}
// detect Node's nanosecond resolution timer available in Node >= 0.8
if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') {
timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' });
}
// detect Wade Simmons' Node microtime module
if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') {
timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
}
// pick timer with highest resolution
timer = _.reduce(timers, function(timer, other) {
return other.res < timer.res ? other : timer;
});
timer = _.min(timers, 'res');
// remove unused applet
if (timer.unit != 'ns' && applet) {
@@ -1954,7 +1943,7 @@
variance,
clone = event.target,
done = bench.aborted,
now = +new Date,
now = _.now(),
size = sample.push(clone.times.period),
maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime,
times = bench.times,
@@ -2159,7 +2148,7 @@
bench.running = true;
bench.count = bench.initCount;
bench.times.timeStamp = +new Date;
bench.times.timeStamp = _.now();
bench.emit(event);
if (!event.cancelled) {
@@ -2499,7 +2488,7 @@
* }())
* }())
*/
'setup': noop,
'setup': _.noop,
/**
* Compiled into the test and executed immediately **after** the test loop.
@@ -2507,7 +2496,7 @@
* @memberOf Benchmark
* @type {Function|string}
*/
'teardown': noop,
'teardown': _.noop,
/**
* An object of stats including mean, margin or error, and standard deviation.

View File

@@ -23,6 +23,13 @@
reExpected = /Expected: *<\/th><td><pre>([\s\S]*?)<\/pre>/,
reMessage = /^<span class='test-message'>([\s\S]*?)<\/span>/;
/** Used to associate color names with their corresponding codes */
var colorCodes = {
'blue': 34,
'green': 32,
'red': 31
};
/** Used to convert HTML entities to characters */
var htmlUnescapes = {
'&amp;': '&',
@@ -59,7 +66,7 @@
* Checks if a given value is present in an array using strict equality
* for comparisons, i.e. `===`.
*
* @oruvate
* @private
* @param {Array} array The array to iterate over.
* @param {*} value The value to check for.
* @returns {boolean} Returns `true` if the `value` is found, else `false`.
@@ -146,11 +153,29 @@
var console = context.console,
phantom = context.phantom,
process = phantom || context.process,
document = !phantom && context.document;
document = !phantom && context.document,
java = context.java;
/** Detect the OS of the platform */
var os = (function() {
if (java) {
return java.lang.System.getProperty('os.name');
}
if (phantom) {
return require('system').os.name;
}
if (process) {
return process.platform;
}
return '';
}());
/** Detects if running in a PhantomJS web page */
var isPhantomPage = typeof context.callPhantom == 'function';
/** Used to indicate if running in Windows */
var isWindows = /win/i.test(os);
/** Used to display the wait throbber */
var throbberId,
throbberDelay = 500,
@@ -239,6 +264,21 @@
/*------------------------------------------------------------------------*/
/**
* Adds text color to the terminal output of `string`.
*
* @private
* @param {string} colorName The name of the color to add.
* @param {string} string The string to add colors to.
* @returns {string} Returns the colored string.
*/
function color(colorName, string) {
var code = colorCodes[colorName];
return isWindows
? string
: ('\x1b[' + code + 'm' + string + '\x1b[0m');
}
/**
* Writes an inline message to standard output.
*
@@ -412,8 +452,8 @@
logInline('');
console.log(hr);
console.log(' PASS: ' + details.passed + ' FAIL: ' + failures + ' TOTAL: ' + details.total);
console.log(' Finished in ' + details.runtime + ' milliseconds.');
console.log(color('blue', ' PASS: ' + details.passed + ' FAIL: ' + failures + ' TOTAL: ' + details.total));
console.log(color(failures ? 'red' : 'green',' Finished in ' + details.runtime + ' milliseconds.'));
console.log(hr);
// exit out of Node.js or PhantomJS
@@ -443,13 +483,13 @@
type = typeof expected != 'undefined' ? 'EQ' : 'OK';
var message = [
result ? 'PASS' : 'FAIL',
type,
details.message || 'ok'
result ? color('green', 'PASS') : color('red', 'FAIL'),
color('blue', type),
color('blue', details.message || 'ok')
];
if (!result && type == 'EQ') {
message.push('Expected: ' + expected + ', Actual: ' + details.actual);
message.push(color('blue', 'Expected: ' + expected + ', Actual: ' + details.actual));
}
QUnit.config.extrasData.logs.push(message.join(' | '));
});
@@ -481,10 +521,10 @@
if (!modulePrinted) {
modulePrinted = true;
console.log(hr);
console.log(moduleName);
console.log(color('blue', moduleName));
console.log(hr);
}
console.log(' ' + (failures ? 'FAIL' : 'PASS') + ' - ' + testName);
console.log(' ' + (failures ? color('red', 'FAIL') : color('green', 'PASS')) + ' - ' + color('blue', testName));
if (failures) {
var index = -1,