UNPKG

it

Version:

A testing framework for node

1,600 lines (1,361 loc) 416 kB
;(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