it
Version:
A testing framework for node
1,600 lines (1,361 loc) • 416 kB
JavaScript
;(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){
(function(global){(function () {
"use strict";
function __defineIt() {
var _ = require("../extended"),
merge = _.merge,
interfaces = require("../interfaces"),
Reporter = require("../formatters/reporter");
require("./formatters/html");
require("../formatters/tap");
var reporter;
var it = {
assert: require("../extension"),
reporter: function (r, args) {
if (r) {
reporter = Reporter.getInstance(r, args);
} else {
return reporter;
}
},
/**@lends it*/
printSummary: function printSummary() {
interfaces.printSummary();
},
/**
* Run all tests that are currently registered.
* @return {comb.Promise} a promise that is resolved once all tests are done running.
*/
run: function run(filter) {
if (typeof window !== "undefined") {
try {
it.reporter("html", "it");
} catch (e) {
it.reporter("tap");
}
var paramStr = window.location.search.substring(1);
var params = {};
if (paramStr.length > 0) {
_(paramStr.split('&')).forEach(function (part) {
var p = part.split('=');
params[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
});
}
if (params.hasOwnProperty("filter")) {
filter = params.filter;
}
} else {
it.reporter("tap");
}
return interfaces.run(filter);
}
};
_(interfaces).forEach(function (val) {
it = merge({}, val, it);
});
/**
* Entry point for writing tests with it.
* @namespace
* @name it
* @ignoreCode code
*/
return it;
}
if ("function" === typeof this.define && this.define.amd) {
define([], function () {
return __defineIt();
});
} else {
this.it = __defineIt();
}
}).call(typeof window !== "undefined" ? window : global);
})(window)
},{"../extended":2,"../formatters/reporter":3,"./formatters/html":4,"../formatters/tap":5,"../extension":6,"../interfaces":7}],8:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
process.nextTick = (function () {
var canSetImmediate = typeof window !== 'undefined'
&& window.setImmediate;
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener
;
if (canSetImmediate) {
return function (f) { return window.setImmediate(f) };
}
if (canPost) {
var queue = [];
window.addEventListener('message', function (ev) {
var source = ev.source;
if ((source === window || source === null) && ev.data === 'process-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
return function nextTick(fn) {
queue.push(fn);
window.postMessage('process-tick', '*');
};
}
return function nextTick(fn) {
setTimeout(fn, 0);
};
})();
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.binding = function (name) {
throw new Error('process.binding is not supported');
}
// TODO(shtylman)
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
},{}],9:[function(require,module,exports){
(function(process){if (!process.EventEmitter) process.EventEmitter = function () {};
var EventEmitter = exports.EventEmitter = process.EventEmitter;
var isArray = typeof Array.isArray === 'function'
? Array.isArray
: function (xs) {
return Object.prototype.toString.call(xs) === '[object Array]'
}
;
function indexOf (xs, x) {
if (xs.indexOf) return xs.indexOf(x);
for (var i = 0; i < xs.length; i++) {
if (x === xs[i]) return i;
}
return -1;
}
// By default EventEmitters will print a warning if more than
// 10 listeners are added to it. This is a useful default which
// helps finding memory leaks.
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) {
if (!this._events) this._events = {};
this._events.maxListeners = n;
};
EventEmitter.prototype.emit = function(type) {
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
(isArray(this._events.error) && !this._events.error.length))
{
if (arguments[1] instanceof Error) {
throw arguments[1]; // Unhandled 'error' event
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
return false;
}
}
if (!this._events) return false;
var handler = this._events[type];
if (!handler) return false;
if (typeof handler == 'function') {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
var args = Array.prototype.slice.call(arguments, 1);
handler.apply(this, args);
}
return true;
} else if (isArray(handler)) {
var args = Array.prototype.slice.call(arguments, 1);
var listeners = handler.slice();
for (var i = 0, l = listeners.length; i < l; i++) {
listeners[i].apply(this, args);
}
return true;
} else {
return false;
}
};
// EventEmitter is defined in src/node_events.cc
// EventEmitter.prototype.emit() is also defined there.
EventEmitter.prototype.addListener = function(type, listener) {
if ('function' !== typeof listener) {
throw new Error('addListener only takes instances of Function');
}
if (!this._events) this._events = {};
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {
// Check for listener leak
if (!this._events[type].warned) {
var m;
if (this._events.maxListeners !== undefined) {
m = this._events.maxListeners;
} else {
m = defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
}
// If we've already got an array, just append.
this._events[type].push(listener);
} else {
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
var self = this;
self.on(type, function g() {
self.removeListener(type, g);
listener.apply(this, arguments);
});
return this;
};
EventEmitter.prototype.removeListener = function(type, listener) {
if ('function' !== typeof listener) {
throw new Error('removeListener only takes instances of Function');
}
// does not use listeners(), so no side effect of creating _events[type]
if (!this._events || !this._events[type]) return this;
var list = this._events[type];
if (isArray(list)) {
var i = indexOf(list, listener);
if (i < 0) return this;
list.splice(i, 1);
if (list.length == 0)
delete this._events[type];
} else if (this._events[type] === listener) {
delete this._events[type];
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
if (arguments.length === 0) {
this._events = {};
return this;
}
// does not use listeners(), so no side effect of creating _events[type]
if (type && this._events && this._events[type]) this._events[type] = null;
return this;
};
EventEmitter.prototype.listeners = function(type) {
if (!this._events) this._events = {};
if (!this._events[type]) this._events[type] = [];
if (!isArray(this._events[type])) {
this._events[type] = [this._events[type]];
}
return this._events[type];
};
})(require("__browserify_process"))
},{"__browserify_process":8}],10:[function(require,module,exports){
(function(){// UTILITY
var util = require('util');
var Buffer = require("buffer").Buffer;
var pSlice = Array.prototype.slice;
function objectKeys(object) {
if (Object.keys) return Object.keys(object);
var result = [];
for (var name in object) {
if (Object.prototype.hasOwnProperty.call(object, name)) {
result.push(name);
}
}
return result;
}
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.
var assert = module.exports = ok;
// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
// actual: actual,
// expected: expected })
assert.AssertionError = function AssertionError(options) {
this.name = 'AssertionError';
this.message = options.message;
this.actual = options.actual;
this.expected = options.expected;
this.operator = options.operator;
var stackStartFunction = options.stackStartFunction || fail;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, stackStartFunction);
}
};
util.inherits(assert.AssertionError, Error);
function replacer(key, value) {
if (value === undefined) {
return '' + value;
}
if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
return value.toString();
}
if (typeof value === 'function' || value instanceof RegExp) {
return value.toString();
}
return value;
}
function truncate(s, n) {
if (typeof s == 'string') {
return s.length < n ? s : s.slice(0, n);
} else {
return s;
}
}
assert.AssertionError.prototype.toString = function() {
if (this.message) {
return [this.name + ':', this.message].join(' ');
} else {
return [
this.name + ':',
truncate(JSON.stringify(this.actual, replacer), 128),
this.operator,
truncate(JSON.stringify(this.expected, replacer), 128)
].join(' ');
}
};
// assert.AssertionError instanceof Error
assert.AssertionError.__proto__ = Error.prototype;
// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.
// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided. All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.
function fail(actual, expected, message, operator, stackStartFunction) {
throw new assert.AssertionError({
message: message,
actual: actual,
expected: expected,
operator: operator,
stackStartFunction: stackStartFunction
});
}
// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;
// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.
function ok(value, message) {
if (!!!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;
// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);
assert.equal = function equal(actual, expected, message) {
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};
// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);
assert.notEqual = function notEqual(actual, expected, message) {
if (actual == expected) {
fail(actual, expected, message, '!=', assert.notEqual);
}
};
// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);
assert.deepEqual = function deepEqual(actual, expected, message) {
if (!_deepEqual(actual, expected)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};
function _deepEqual(actual, expected) {
// 7.1. All identical values are equivalent, as determined by ===.
if (actual === expected) {
return true;
} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
if (actual.length != expected.length) return false;
for (var i = 0; i < actual.length; i++) {
if (actual[i] !== expected[i]) return false;
}
return true;
// 7.2. If the expected value is a Date object, the actual value is
// equivalent if it is also a Date object that refers to the same time.
} else if (actual instanceof Date && expected instanceof Date) {
return actual.getTime() === expected.getTime();
// 7.3. Other pairs that do not both pass typeof value == 'object',
// equivalence is determined by ==.
} else if (typeof actual != 'object' && typeof expected != 'object') {
return actual == expected;
// 7.4. For all other Object pairs, including Array objects, equivalence is
// determined by having the same number of owned properties (as verified
// with Object.prototype.hasOwnProperty.call), the same set of keys
// (although not necessarily the same order), equivalent values for every
// corresponding key, and an identical 'prototype' property. Note: this
// accounts for both named and indexed properties on Arrays.
} else {
return objEquiv(actual, expected);
}
}
function isUndefinedOrNull(value) {
return value === null || value === undefined;
}
function isArguments(object) {
return Object.prototype.toString.call(object) == '[object Arguments]';
}
function objEquiv(a, b) {
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
return false;
// an identical 'prototype' property.
if (a.prototype !== b.prototype) return false;
//~~~I've managed to break Object.keys through screwy arguments passing.
// Converting to array solves the problem.
if (isArguments(a)) {
if (!isArguments(b)) {
return false;
}
a = pSlice.call(a);
b = pSlice.call(b);
return _deepEqual(a, b);
}
try {
var ka = objectKeys(a),
kb = objectKeys(b),
key, i;
} catch (e) {//happens when one is a string literal and the other isn't
return false;
}
// having the same number of owned properties (keys incorporates
// hasOwnProperty)
if (ka.length != kb.length)
return false;
//the same set of keys (although not necessarily the same order),
ka.sort();
kb.sort();
//~~~cheap key test
for (i = ka.length - 1; i >= 0; i--) {
if (ka[i] != kb[i])
return false;
}
//equivalent values for every corresponding key, and
//~~~possibly expensive deep test
for (i = ka.length - 1; i >= 0; i--) {
key = ka[i];
if (!_deepEqual(a[key], b[key])) return false;
}
return true;
}
// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
if (_deepEqual(actual, expected)) {
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
}
};
// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);
assert.strictEqual = function strictEqual(actual, expected, message) {
if (actual !== expected) {
fail(actual, expected, message, '===', assert.strictEqual);
}
};
// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
if (actual === expected) {
fail(actual, expected, message, '!==', assert.notStrictEqual);
}
};
function expectedException(actual, expected) {
if (!actual || !expected) {
return false;
}
if (expected instanceof RegExp) {
return expected.test(actual);
} else if (actual instanceof expected) {
return true;
} else if (expected.call({}, actual) === true) {
return true;
}
return false;
}
function _throws(shouldThrow, block, expected, message) {
var actual;
if (typeof expected === 'string') {
message = expected;
expected = null;
}
try {
block();
} catch (e) {
actual = e;
}
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
(message ? ' ' + message : '.');
if (shouldThrow && !actual) {
fail('Missing expected exception' + message);
}
if (!shouldThrow && expectedException(actual, expected)) {
fail('Got unwanted exception' + message);
}
if ((shouldThrow && actual && expected &&
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
throw actual;
}
}
// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);
assert.throws = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [true].concat(pSlice.call(arguments)));
};
// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments)));
};
assert.ifError = function(err) { if (err) {throw err;}};
})()
},{"util":11,"buffer":12}],3:[function(require,module,exports){
"use strict";
var _ = require("../extended"),
style = _.style,
format = _.format;
_.declare({
instance: {
numActions: 0,
constructor: function () {
this.errors = [];
_.bindAll(this, ["startTests", "testError", "_testError", "printFinalSummary", "listenTest", "listenAction", "testRun",
"testEnd", "testsDone", "actionError", "_actionError", "actionSuccess", "actionPending", "actionSkipped",
"printDuplicateActions"]);
_.bus.on("start", this.startTests);
_.bus.on("error", this._testError);
_.bus.on("done", this.testsDone);
_.bus.on("test", this.listenTest);
_.bus.on("printDuplicateActions", this.printDuplicateActions);
},
listenTest: function listenTest(test) {
test.on("test", this.listenTest);
test.on("action", this.listenAction);
test.on("run", this.testRun);
test.on("error", this._testError);
test.on("done", this.testEnd);
},
listenAction: function listenAction(action) {
this.numActions++;
action.on("error", this._actionError);
action.on("success", this.actionSuccess);
action.on("pending", this.actionPending);
action.on("skipped", this.actionSkipped);
},
formatMs: function formatMs(ms) {
return format("% 6ds", ms / 1000);
},
startTests: function () {
},
testRun: function printTitle() {
},
actionSuccess: function printSuccess() {
},
actionPending: function printPending() {
},
actionSkipped: function printSkipped() {
},
actionError: function actionError() {
},
testError: function printError(test) {
},
printDuplicateActions: function printDuplicateActions(duplicateActionErrors) {
this._static.list(duplicateActionErrors);
},
_actionError: function printError(action) {
var error = action.get("summary").error;
this.errors.push({error: error, test: action});
return this.actionError.apply(this, arguments);
},
_testError: function _testError(test) {
this.errors.push({error: test.error, test: test});
return this.testError.apply(this, arguments);
},
processSummary: function processSummary(summary) {
if (summary.hasOwnProperty("summaries")) {
summary = summary.summaries;
}
var errCount = 0, successCount = 0, skippedCount = 0, pendingCount = 0, pendingActions = [], errors = {}, duration = 0;
_(summary).forEach(function (sum) {
duration += sum.duration;
});
(function total(summary) {
_(summary).forEach(function (sum, i) {
if (sum.hasOwnProperty("summaries")) {
total(sum.summaries);
} else if (sum.status === "passed") {
successCount++;
} else if (sum.status === "pending") {
pendingCount++;
pendingActions.push(sum.parentFullName + ": " + sum.description);
} else if (sum.status === "skipped") {
skippedCount++;
} else {
errors[i] = sum.error;
errCount++;
}
});
})(summary);
return {
totalCount: this.numActions,
errCount: errCount,
successCount: successCount,
skippedCount: skippedCount,
pendingCount: pendingCount,
pendingActions: pendingActions,
errors: errors,
duration: duration
};
},
testEnd: function () {
},
testsDone: function (tests) {
this.printFinalSummary(tests);
},
returnCode: function returnCode(stats) {
return this.errors.length || stats.errCount || stats.totalCount !== (stats.successCount + stats.skippedCount) ? 1 : 0;
},
printFinalSummary: function (test) {
this.testEnd.apply(this, arguments);
console.log("\nSummary");
var stats = this.processSummary(test.summary || test.get("summary"));
var totalCount = stats.totalCount,
errCount = stats.errCount,
successCount = stats.successCount,
pendingCount = stats.pendingCount,
skippedCount = stats.skippedCount,
duration = stats.duration;
console.log(format("Finished in %s", this.formatMs(duration)));
var out = [
totalCount + " total",
successCount + " passed",
errCount + " failed",
skippedCount + " skipped",
pendingCount + " pending"
];
var color = 'green';
if (errCount > 0 || pendingCount > 0) {
color = 'red';
} else if (skippedCount > 0) {
color = 'cyan';
}
console.log(style(out.join(", "), color));
this._static.list(this.errors);
this._static.listPending(stats.pendingActions);
return this.returnCode(stats);
}
},
"static": {
reporters: {},
registerType: function (type) {
type = type.toLowerCase();
if (!this.reporters.hasOwnProperty(type)) {
this.reporters[type] = this;
}
return this;
},
getInstance: function (type, args) {
type = type.toLowerCase();
if (this.reporters.hasOwnProperty(type)) {
return new this.reporters[type](args || {});
} else {
throw new Error("Invalid Reporter type");
}
},
listPending: function (pendingActions) {
if (pendingActions.length) {
console.log("" + pendingActions.length + " pending actions");
var more = false;
if (pendingActions.length > 10) {
pendingActions = pendingActions.slice(0, 10);
more = true;
}
pendingActions.forEach(function (name) {
console.log(style('\t%s', ["red", "bold"]), name);
});
if (more) {
console.log(style('\t...', ["red", "bold"]));
}
}
},
list: function (errors) {
console.log();
errors.forEach(function (test, i) {
// format
var fmt = ' %s.%d) %s:\n' + style(' %s', "red") + style('\n%s\n', ["red", "bold"]);
// msg
var errs = test.error;
_((_.isArray(errs) ? errs : [errs])).forEach(function (err, j) {
if (err) {
var message = err.message || '',
stack = err.stack || message,
index = stack.indexOf(message) + message.length,
msg = stack.slice(0, index);
// indent stack trace without msg
stack = stack.slice(index ? index + 1 : index)
.replace(/^/gm, ' ');
console.log(fmt, (i + 1), j, test.test.get("fullName"), msg, stack);
}
});
});
}
}
}).as(module);
},{"../extended":2}],6:[function(require,module,exports){
var assert = require("assert"),
_ = require("./extended"),
format = _.format;
assert.lengthOf = function (arr, length, message) {
if (arr.length !== length) {
assert.fail(arr.length, length, message || format("expected %s, to have %d elements", [arr, length]), assert.lengthOf);
}
};
assert.truthy = function (val, message) {
if (!val) {
assert.fail(val, true, message || format("expected %s to be truthy", val), assert.truthy);
}
};
assert.falsy = function (val, message) {
if (val) {
assert.fail(val, false, message || format("expected %s to be falsy", val), assert.truthy);
}
};
assert.isRegExp = function (val, message) {
if (!_.isRegExp(val)) {
assert.fail(val, 0, message || format("expected %s, to be a regex", val), assert.isRexExp);
}
};
_.forEach([
["isTrue", "true"],
["isFalse", "false"],
["isArray", "an array"],
["isNull", "null"],
["isNotNull", "not null"],
["isNumber", "a number"],
["isHash", "a hash"],
["isObject", "an object"],
["isDate", "a date"],
["isBoolean", "a boolean"],
["isString", "a string"],
["isUndefined", "undefined"],
["isUndefinedOrNull", "undefined or null"],
["isPromiseLike", "a promise"],
["isFunction", "a function"],
["isEmpty", "empty"]
], function (i) {
var k = i[0], extra = i[1];
assert[k] = function (val, message) {
if (!_[k](val)) {
assert.fail(val, 0, message || format("expected %s, to be " + extra, val), assert[k]);
}
};
});
assert.instanceOf = function (val, cls, message) {
if (!_.instanceOf(val, cls)) {
assert.fail(val, cls, message || format("expected %j to be instanceof %s", [val, cls]), "===", assert.isNotNull);
}
};
module.exports = assert;
},{"assert":10,"./extended":2}],11:[function(require,module,exports){
var events = require('events');
exports.isArray = isArray;
exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'};
exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'};
exports.print = function () {};
exports.puts = function () {};
exports.debug = function() {};
exports.inspect = function(obj, showHidden, depth, colors) {
var seen = [];
var stylize = function(str, styleType) {
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
var styles =
{ 'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'inverse' : [7, 27],
'white' : [37, 39],
'grey' : [90, 39],
'black' : [30, 39],
'blue' : [34, 39],
'cyan' : [36, 39],
'green' : [32, 39],
'magenta' : [35, 39],
'red' : [31, 39],
'yellow' : [33, 39] };
var style =
{ 'special': 'cyan',
'number': 'blue',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red' }[styleType];
if (style) {
return '\033[' + styles[style][0] + 'm' + str +
'\033[' + styles[style][1] + 'm';
} else {
return str;
}
};
if (! colors) {
stylize = function(str, styleType) { return str; };
}
function format(value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (value && typeof value.inspect === 'function' &&
// Filter out the util module, it's inspect function is special
value !== exports &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
return value.inspect(recurseTimes);
}
// Primitive types cannot have properties
switch (typeof value) {
case 'undefined':
return stylize('undefined', 'undefined');
case 'string':
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return stylize(simple, 'string');
case 'number':
return stylize('' + value, 'number');
case 'boolean':
return stylize('' + value, 'boolean');
}
// For some reason typeof null is "object", so special case here.
if (value === null) {
return stylize('null', 'null');
}
// Look up the keys of the object.
var visible_keys = Object_keys(value);
var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys;
// Functions without properties can be shortcutted.
if (typeof value === 'function' && keys.length === 0) {
if (isRegExp(value)) {
return stylize('' + value, 'regexp');
} else {
var name = value.name ? ': ' + value.name : '';
return stylize('[Function' + name + ']', 'special');
}
}
// Dates without properties can be shortcutted
if (isDate(value) && keys.length === 0) {
return stylize(value.toUTCString(), 'date');
}
var base, type, braces;
// Determine the object type
if (isArray(value)) {
type = 'Array';
braces = ['[', ']'];
} else {
type = 'Object';
braces = ['{', '}'];
}
// Make functions say that they are functions
if (typeof value === 'function') {
var n = value.name ? ': ' + value.name : '';
base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';
} else {
base = '';
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + value.toUTCString();
}
if (keys.length === 0) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return stylize('' + value, 'regexp');
} else {
return stylize('[Object]', 'special');
}
}
seen.push(value);
var output = keys.map(function(key) {
var name, str;
if (value.__lookupGetter__) {
if (value.__lookupGetter__(key)) {
if (value.__lookupSetter__(key)) {
str = stylize('[Getter/Setter]', 'special');
} else {
str = stylize('[Getter]', 'special');
}
} else {
if (value.__lookupSetter__(key)) {
str = stylize('[Setter]', 'special');
}
}
}
if (visible_keys.indexOf(key) < 0) {
name = '[' + key + ']';
}
if (!str) {
if (seen.indexOf(value[key]) < 0) {
if (recurseTimes === null) {
str = format(value[key]);
} else {
str = format(value[key], recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (isArray(value)) {
str = str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = stylize('[Circular]', 'special');
}
}
if (typeof name === 'undefined') {
if (type === 'Array' && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'");
name = stylize(name, 'string');
}
}
return name + ': ' + str;
});
seen.pop();
var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.length + 1;
}, 0);
if (length > 50) {
output = braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
} else {
output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
return output;
}
return format(obj, (typeof depth === 'undefined' ? 2 : depth));
};
function isArray(ar) {
return ar instanceof Array ||
Array.isArray(ar) ||
(ar && ar !== Object.prototype && isArray(ar.__proto__));
}
function isRegExp(re) {
return re instanceof RegExp ||
(typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]');
}
function isDate(d) {
if (d instanceof Date) return true;
if (typeof d !== 'object') return false;
var properties = Date.prototype && Object_getOwnPropertyNames(Date.prototype);
var proto = d.__proto__ && Object_getOwnPropertyNames(d.__proto__);
return JSON.stringify(proto) === JSON.stringify(properties);
}
function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
// 26 Feb 16:19:34
function timestamp() {
var d = new Date();
var time = [pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds())].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
}
exports.log = function (msg) {};
exports.pump = null;
var Object_keys = Object.keys || function (obj) {
var res = [];
for (var key in obj) res.push(key);
return res;
};
var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) {
var res = [];
for (var key in obj) {
if (Object.hasOwnProperty.call(obj, key)) res.push(key);
}
return res;
};
var Object_create = Object.create || function (prototype, properties) {
// from es5-shim
var object;
if (prototype === null) {
object = { '__proto__' : null };
}
else {
if (typeof prototype !== 'object') {
throw new TypeError(
'typeof prototype[' + (typeof prototype) + '] != \'object\''
);
}
var Type = function () {};
Type.prototype = prototype;
object = new Type();
object.__proto__ = prototype;
}
if (typeof properties !== 'undefined' && Object.defineProperties) {
Object.defineProperties(object, properties);
}
return object;
};
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object_create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
if (typeof f !== 'string') {
var objects = [];
for (var i = 0; i < arguments.length; i++) {
objects.push(exports.inspect(arguments[i]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function(x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j': return JSON.stringify(args[i++]);
default:
return x;
}
});
for(var x = args[i]; i < len; x = args[++i]){
if (x === null || typeof x !== 'object') {
str += ' ' + x;
} else {
str += ' ' + exports.inspect(x);
}
}
return str;
};
},{"events":9}],5:[function(require,module,exports){
"use strict";
var _ = require("../extended"),
format = _.format,
Reporter = require("./reporter");
function getActionName(action) {
return action.get("fullName").replace(/#/g, '');
}
Reporter.extend({
instance: {
ran: 0,
startTests: function (tests) {
console.log(format('%d..%d', 1, (tests.numActions)));
},
actionSuccess: function printSuccess(action) {
console.log(format('ok %d %s', ++this.ran, getActionName(action)));
},
actionSkipped: function printSkipped(action) {
console.log(format('ok %d %s # SKIP -', ++this.ran, getActionName(action)));
},
actionError: function printError(action) {
var summary = action.get("summary"), err = summary.error;
console.log(format('not ok %d %s', ++this.ran, getActionName(action)));
_((_.isArray(err) ? err : [err])).forEach(function (err) {
if (err) {
if (err.stack) {
console.log(err.stack.replace(/^/gm, ' '));
} else if (err.message) {
console.log(err.message);
} else {
console.log(err);
}
}
});
},
printFinalSummary: function (test) {
var summary = this.processSummary(test.summary);
console.log('# total ' + this.numActions);
console.log('# passed ' + summary.successCount);
console.log('# failed ' + summary.errCount);
console.log('# skipped ' + summary.skippedCount);
console.log('# pending ' + summary.pendingCount);
this._static.list(this.errors);
this._static.listPending(summary.pendingActions);
return this.returnCode(summary);
}
}
}).as(module).registerType("tap");
},{"../extended":2,"./reporter":3}],4:[function(require,module,exports){
"use strict";
var _ = require("../../extended"),
AssertionError = require("assert").AssertionError,
Reporter = require("../../formatters/reporter"),
format = _.format,
arraySlice = Array.prototype.slice;
var pluralize = function (count, str) {
return count !== 1 ? str + "s" : str;
};
function getSpacing(action) {
return action.level * 2.5 + "em";
}
function createDom(type, attrs) {
var el = document.createElement(type);
_(arraySlice.call(arguments, 2)).forEach(function (child) {
if (_.isString(child)) {
el.appendChild(document.createTextNode(child));
} else if (child) {
el.appendChild(child);
}
});
_(attrs || {}).forEach(function (attrs, attr) {
if (attr === "className") {
el[attr] = attrs;
} else {
el.setAttribute(attr, attrs);
}
});
return el;
}
function updateActionStatus(action, status) {
var els = document.querySelectorAll('[data-it-actionName="' + action.get("fullName") + '"]');
for (var i = 0, l = els.length; i < l; i++) {
var el = els.item(i), className = el.className;
el.className = className.replace(/(not-run|pending|error|passed) */ig, "") + " " + status;
}
}
Reporter.extend({
instance: {
constructor: function (el) {
this._super(arguments);
this.el = document.getElementById(el);
this.header = this.el.appendChild(createDom("div", {className: "header"}, createDom("h1", {}, createDom("a", {href: "?"}, "It"))));
this.summary = this.header.appendChild(createDom("div", {className: "summary"}));
this.progress = this.el.appendChild(createDom("ul", {className: "progress"}));
this.actions = this.el.appendChild(createDom("div", {className: "actions"}));
this.errors = [];
if (!this.el) {
throw new Error("Unable to find el with id #" + el);
}
},
listenAction: function (action) {
this._super(arguments);
var actionName = action.get("fullName");
this.progress.appendChild(createDom("li", {className: "not-run", "data-it-actionName": actionName}));
},
testRun: function printTitle(action) {
if (action.description) {
this.actions.appendChild(createDom("div",
{className: "header", style: "padding-left:" + getSpacing(action), "data-it-actionName": action.get("fullName")},
createDom("a", {
href: "?filter=" + encodeURIComponent(action.get("fullName"))
}, action.description)
));
}
},
__addAction: function (action) {
var summary = action.get("summary");
this.actions.appendChild(createDom("div",
{className: "pending", style: "padding-left:" + getSpacing(action), "data-it-actionName": action.get("fullName")},
createDom("a", {
href: "?filter=" + encodeURIComponent(action.get("fullName"))
}, format(" %s, (%dms)", action.description, summary.duration))
));
updateActionStatus(action, summary.status);
return this;
},
__formatError: function (error) {
var str = error.stack || error.toString();
if (error instanceof AssertionError) {
str = error.toString() + "\n" + (error.stack || "").replace(/AssertionError.*\n/, "");
}
if (error.message) {
// FF / Opera do not add the message
if (!~str.indexOf(error.message)) {
str = error.message + '\n' + str;
}
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
// check for the result of the stringifying.
if ('[object Error]' === str) {
str = error.message;
}
}
// Safari doesn't give you a stack. Let's at least provide a source line.
if (!error.stack && error.sourceURL && error.line !== undefined) {
str += "\n(" + error.sourceURL + ":" + error.line + ")";
}
return str;
},
actionSuccess: function (action) {
this.__addAction(action);
},
actionSkipped: function (action) {
this.__addAction(action);
},
actionPending: function (action) {
this.__addAction(action);
},
actionError: function printError(action) {
this._super(arguments);
this.__addAction(action);
},
printErrors: function () {
if (this.errors.length) {
//clear all actions
this.actions.innerHTML = "";
_(this.errors).forEach(function (test, i) {
var error = test.error, action = test.test;
this.actions.appendChild(createDom("pre",
{className: "failed"},
format(' %s) %s:', i, action.get("fullName")),
createDom("br"),
this.__formatError(error).replace(/^/gm, ' ')
));
}, this);
}
},
printFinalSummary: function (test) {
var summary = test.summary;
var stats = this.processSummary(summary);
var errCount = stats.errCount, successCount = stats.successCount, pendingCount = stats.pendingCount, duration = stats.duration;
var out = [
"Duration " + this.formatMs(duration),
successCount + pluralize(successCount, " example"),
errCount + pluralize(errCount, " error"),
pendingCount + " pending"
];
this.summary.appendChild(createDom("div",
{className: pendingCount > 0 ? "pending" : errCount > 0 ? "failed" : "success"},
out.join(", ")));
this.printErrors();
return errCount ? 1 : 0;
}
}
}).as(module).registerType("html");
},{"assert":10,"../../extended":2,"../../formatters/reporter":3}],7:[function(require,module,exports){
"use strict";
var Test = require("./common").Test,
bdd = require("./bdd"),
tdd = require("./tdd");
module.exports = {
Test: Test,
bdd: bdd,
tdd: tdd,
reporter: function reporter(r) {
Test.reporter = r;
bdd.reporter(r);
tdd.reporter(r);
},
printSummary: function printSummary() {
return Test.printSummary();
},
run: function run(filter) {
return Test.run(filter);
}
};
},{"./bdd":13,"./tdd":14,"./common":15}],2:[function(require,module,exports){
module.exports = require("extended")()
.register(require("array-extended"))
.register(require("date-extended"))
.register(require("object-extended"))
.register(require("string-extended"))
.register(require("promise-extended"))
.register(require("function-extended"))
.register(require("is-extended"))
.register("declare", require("declare.js"))
.register("bus", new (require("events").EventEmitter)());
},{"events":9,"extended":16,"array-extended":17,"date-extended":18,"object-extended":19,"string-extended":20,"promise-extended":21,"function-extended":22,"declare.js":23,"is-extended":24}],25:[function(require,module,exports){
exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) {
var e, m,
eLen = nBytes * 8 - mLen - 1,
eMax = (1 << eLen) - 1,
eBias = eMax >> 1,
nBits = -7,
i = isBE ? 0 : (nBytes - 1),
d = isBE ? 1 : -1,
s = buffer[offset + i];
i += d;
e = s & ((1 << (-nBits)) - 1);
s >>= (-nBits);
nBits += eLen;
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
m = e & ((1 << (-nBits)) - 1);
e >>= (-nBits);
nBits += mLen;
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
if (e === 0) {
e = 1 - eBias;
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity);
} else {
m = m + Math.pow(2, mLen);
e = e - eBias;
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
};
exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) {
var e, m, c,
eLen = nBytes * 8 - mLen - 1,
eMax = (1 << eLen) - 1,
eBias = eMax >> 1,
rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
i = isBE ? (nBytes - 1) : 0,
d = isBE ? -1 : 1,
s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
value = Math.abs(value);
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0;
e = eMax;
} else {
e = Math.floor(Math.log