1 define([], function() {
6 var path
= require
.resolve(p
),
7 mod
= require
.modules
[path
];
8 if (!mod
) throw new Error('failed to require "' + p
+ '"');
11 mod
.call(mod
.exports
, mod
, mod
.exports
, require
.relative(path
));
18 require
.resolve = function(path
) {
21 index
= path
+ '/index.js';
22 return (require
.modules
[reg
] && reg
) || (require
.modules
[index
] && index
) || orig
;
25 require
.register = function(path
, fn
) {
26 require
.modules
[path
] = fn
;
29 require
.relative = function(parent
) {
31 if ('.' != p
.charAt(0)) return require(p
);
33 var path
= parent
.split('/'),
37 for (var i
= 0; i
< segs
.length
; i
++) {
39 if ('..' == seg
) path
.pop();
40 else if ('.' != seg
) path
.push(seg
);
43 return require(path
.join('/'));
47 require
.register('browser/debug.js', function(module
, exports
, require
) {
48 module
.exports = function(type
) {
51 }); // module: browser/debug.js
53 require
.register('browser/diff.js', function(module
, exports
, require
) {
54 /* See license.txt for terms of usage */
57 * Text diff implementation.
59 * This library supports the following APIS:
60 * JsDiff.diffChars: Character by character diff
61 * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
62 * JsDiff.diffLines: Line based diff
64 * JsDiff.diffCss: Diff targeted at CSS content
66 * These methods are based on the implementation proposed in
67 * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
68 * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
70 var JsDiff
= (function() {
71 function clonePath(path
) {
72 return { newPos
: path
.newPos
, components
: path
.components
.slice(0) };
74 function removeEmpty(array
) {
76 for (var i
= 0; i
< array
.length
; i
++) {
83 function escapeHTML(s
) {
85 n
= n
.replace(/&/g
, '&');
86 n
= n
.replace(/</g
, '<');
87 n
= n
.replace(/>/g
, '>');
88 n
= n
.replace(/"/g, '"');
93 var fbDiff = function(ignoreWhitespace) {
94 this.ignoreWhitespace = ignoreWhitespace;
97 diff: function(oldString, newString) {
98 // Handle the identity case (this is due to unrolling editLength == 0
99 if (newString == oldString) {
100 return [{ value: newString }];
103 return [{ value: oldString, removed: true }];
106 return [{ value: newString, added: true }];
109 newString = this.tokenize(newString);
110 oldString = this.tokenize(oldString);
112 var newLen = newString.length,
113 oldLen = oldString.length;
114 var maxEditLength = newLen + oldLen;
115 var bestPath = [{ newPos: -1, components: [] }];
117 // Seed editLength = 0
118 var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
119 if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
120 return bestPath[0].components;
123 for (var editLength = 1; editLength <= maxEditLength; editLength++) {
125 var diagonalPath = -1 * editLength;
126 diagonalPath <= editLength;
130 var addPath = bestPath[diagonalPath - 1],
131 removePath = bestPath[diagonalPath + 1];
132 oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
134 // No one else is going to attempt to use this value, clear it
135 bestPath[diagonalPath - 1] = undefined;
138 var canAdd = addPath && addPath.newPos + 1 < newLen;
139 var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
140 if (!canAdd && !canRemove) {
141 bestPath[diagonalPath] = undefined;
145 // Select the diagonal that we want to branch from. We select the prior
146 // path whose position in the new string is the farthest from the origin
147 // and does not pass the bounds of the diff graph
148 if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
149 basePath = clonePath(removePath);
150 this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
152 basePath = clonePath(addPath);
156 newString[basePath.newPos],
162 var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
164 if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
165 return basePath.components;
167 bestPath[diagonalPath] = basePath;
173 pushComponent: function(components, value, added, removed) {
174 var last = components[components.length - 1];
175 if (last && last.added === added && last.removed === removed) {
176 // We need to clone here as the component clone operation is just
177 // as shallow array clone
178 components[components.length - 1] = {
179 value: this.join(last.value, value),
184 components.push({ value: value, added: added, removed: removed });
187 extractCommon: function(basePath, newString, oldString, diagonalPath) {
188 var newLen = newString.length,
189 oldLen = oldString.length,
190 newPos = basePath.newPos,
191 oldPos = newPos - diagonalPath;
193 newPos + 1 < newLen &&
194 oldPos + 1 < oldLen &&
195 this.equals(newString[newPos + 1], oldString[oldPos + 1])
200 this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
202 basePath.newPos = newPos;
206 equals: function(left, right) {
207 var reWhitespace = /\S/;
208 if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
211 return left == right;
214 join: function(left, right) {
217 tokenize: function(value) {
222 var CharDiff = new fbDiff();
224 var WordDiff = new fbDiff(true);
225 WordDiff.tokenize = function(value) {
226 return removeEmpty(value.split(/(\s+|\b)/));
229 var CssDiff = new fbDiff(true);
230 CssDiff.tokenize = function(value) {
231 return removeEmpty(value.split(/([{}:;,]|\s+)/));
234 var LineDiff = new fbDiff();
235 LineDiff.tokenize = function(value) {
236 return value.split(/^/m);
240 diffChars: function(oldStr, newStr) {
241 return CharDiff.diff(oldStr, newStr);
243 diffWords: function(oldStr, newStr) {
244 return WordDiff.diff(oldStr, newStr);
246 diffLines: function(oldStr, newStr) {
247 return LineDiff.diff(oldStr, newStr);
250 diffCss: function(oldStr, newStr) {
251 return CssDiff.diff(oldStr, newStr);
254 createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
257 ret.push('Index: ' + fileName);
258 ret.push('===================================================================');
260 '--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader)
263 '+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader)
266 var diff = LineDiff.diff(oldStr, newStr);
267 if (!diff[diff.length - 1].value) {
268 diff.pop(); // Remove trailing newline add
270 diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier
272 function contextLines(lines) {
273 return lines.map(function(entry) {
277 function eofNL(curRange, i, current) {
278 var last = diff[diff.length - 2],
279 isLast = i === diff.length - 2,
281 i === diff.length - 3 &&
282 (current.added === !last.added || current.removed === !last.removed);
284 // Figure out if this is the last line for the given file and missing NL
285 if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
286 curRange.push('\\ No newline at end of file');
290 var oldRangeStart = 0,
295 for (var i = 0; i < diff.length; i++) {
296 var current = diff[i],
297 lines = current.lines || current.value.replace(/\n$/, '').split('\n');
298 current.lines = lines;
300 if (current.added || current.removed) {
301 if (!oldRangeStart) {
302 var prev = diff[i - 1];
303 oldRangeStart = oldLine;
304 newRangeStart = newLine;
307 curRange = contextLines(prev.lines.slice(-4));
308 oldRangeStart -= curRange.length;
309 newRangeStart -= curRange.length;
314 lines.map(function(entry) {
315 return (current.added ? '+' : '-') + entry;
318 eofNL(curRange, i, current);
321 newLine += lines.length;
323 oldLine += lines.length;
327 // Close out any changes that have been output (or join overlapping)
328 if (lines.length <= 8 && i < diff.length - 2) {
330 curRange.push.apply(curRange, contextLines(lines));
332 // end the range and output
333 var contextSize = Math.min(lines.length, 4);
338 (oldLine - oldRangeStart + contextSize) +
342 (newLine - newRangeStart + contextSize) +
345 ret.push.apply(ret, curRange);
346 ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
347 if (lines.length <= 4) {
348 eofNL(ret, i, current);
356 oldLine += lines.length;
357 newLine += lines.length;
361 return ret.join('\n') + '\n';
364 convertChangesToXML: function(changes) {
366 for (var i = 0; i < changes.length; i++) {
367 var change = changes[i];
370 } else if (change.removed) {
374 ret.push(escapeHTML(change.value));
378 } else if (change.removed) {
387 if (typeof module !== 'undefined') {
388 module.exports = JsDiff;
390 }); // module: browser/diff.js
392 require.register('browser/events.js', function(module, exports, require) {
397 exports.EventEmitter = EventEmitter;
400 * Check if `obj` is an array.
403 function isArray(obj) {
404 return '[object Array]' == {}.toString.call(obj);
408 * Event emitter constructor.
413 function EventEmitter() {}
421 EventEmitter.prototype.on = function(name, fn) {
426 if (!this.$events[name]) {
427 this.$events[name] = fn;
428 } else if (isArray(this.$events[name])) {
429 this.$events[name].push(fn);
431 this.$events[name] = [this.$events[name], fn];
437 EventEmitter.prototype.addListener = EventEmitter.prototype.on;
440 * Adds a volatile listener.
445 EventEmitter.prototype.once = function(name, fn) {
449 self.removeListener(name, on);
450 fn.apply(this, arguments);
460 * Removes a listener.
465 EventEmitter.prototype.removeListener = function(name, fn) {
466 if (this.$events && this.$events[name]) {
467 var list = this.$events[name];
472 for (var i = 0, l = list.length; i < l; i++) {
473 if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
486 delete this.$events[name];
488 } else if (list === fn || (list.listener && list.listener === fn)) {
489 delete this.$events[name];
497 * Removes all listeners for an event.
502 EventEmitter.prototype.removeAllListeners = function(name) {
503 if (name === undefined) {
508 if (this.$events && this.$events[name]) {
509 this.$events[name] = null;
516 * Gets all listeners for a certain event.
521 EventEmitter.prototype.listeners = function(name) {
526 if (!this.$events[name]) {
527 this.$events[name] = [];
530 if (!isArray(this.$events[name])) {
531 this.$events[name] = [this.$events[name]];
534 return this.$events[name];
543 EventEmitter.prototype.emit = function(name) {
548 var handler = this.$events[name];
554 var args = [].slice.call(arguments, 1);
556 if ('function' == typeof handler) {
557 handler.apply(this, args);
558 } else if (isArray(handler)) {
559 var listeners = handler.slice();
561 for (var i = 0, l = listeners.length; i < l; i++) {
562 listeners[i].apply(this, args);
570 }); // module: browser/events.js
572 require.register('browser/fs.js', function(module, exports, require) {}); // module: browser/fs.js
574 require.register('browser/path.js', function(module, exports, require) {}); // module: browser/path.js
576 require.register('browser/progress.js', function(module, exports, require) {
581 module.exports = Progress;
584 * Initialize a new `Progress` indicator.
587 function Progress() {
591 this.font('helvetica, arial, sans-serif');
595 * Set progress size to `n`.
598 * @return {Progress} for chaining
602 Progress.prototype.size = function(n) {
610 * @param {String} str
611 * @return {Progress} for chaining
615 Progress.prototype.text = function(str) {
621 * Set font size to `n`.
624 * @return {Progress} for chaining
628 Progress.prototype.fontSize = function(n) {
636 * @param {String} family
637 * @return {Progress} for chaining
640 Progress.prototype.font = function(family) {
646 * Update percentage to `n`.
649 * @return {Progress} for chaining
652 Progress.prototype.update = function(n) {
660 * @param {CanvasRenderingContext2d} ctx
661 * @return {Progress} for chaining
664 Progress.prototype.draw = function(ctx) {
665 var percent = Math.min(this.percent, 100),
671 fontSize = this._fontSize;
673 ctx.font = fontSize + 'px ' + this._font;
675 var angle = Math.PI * 2 * (percent / 100);
676 ctx.clearRect(0, 0, size, size);
679 ctx.strokeStyle = '#9f9f9f';
681 ctx.arc(x, y, rad, 0, angle, false);
685 ctx.strokeStyle = '#eee';
687 ctx.arc(x, y, rad - 1, 0, angle, true);
691 var text = this._text || (percent | 0) + '%',
692 w = ctx.measureText(text).width;
694 ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);
698 }); // module: browser/progress.js
700 require.register('browser/tty.js', function(module, exports, require) {
701 exports.isatty = function() {
705 exports.getWindowSize = function() {
706 return [window.innerHeight, window.innerWidth];
708 }); // module: browser/tty.js
710 require.register('context.js', function(module, exports, require) {
715 module.exports = Context;
718 * Initialize a new `Context`.
723 function Context() {}
726 * Set or get the context `Runnable` to `runnable`.
728 * @param {Runnable} runnable
733 Context.prototype.runnable = function(runnable) {
734 if (0 == arguments.length) return this._runnable;
735 this.test = this._runnable = runnable;
740 * Set test timeout `ms`.
743 * @return {Context} self
747 Context.prototype.timeout = function(ms) {
748 this.runnable().timeout(ms);
753 * Set test slowness threshold `ms`.
756 * @return {Context} self
760 Context.prototype.slow = function(ms) {
761 this.runnable().slow(ms);
766 * Inspect the context void of `._runnable`.
772 Context.prototype.inspect = function() {
773 return JSON.stringify(
776 if ('_runnable' == key) return;
777 if ('test' == key) return;
783 }); // module: context.js
785 require.register('hook.js', function(module, exports, require) {
787 * Module dependencies.
790 var Runnable = require('./runnable');
796 module.exports = Hook;
799 * Initialize a new `Hook` with the given `title` and callback `fn`.
801 * @param {String} title
802 * @param {Function} fn
806 function Hook(title, fn) {
807 Runnable.call(this, title, fn);
812 * Inherit from `Runnable.prototype`.
816 F.prototype = Runnable.prototype;
817 Hook.prototype = new F();
818 Hook.prototype.constructor = Hook;
821 * Get or set the test `err`.
828 Hook.prototype.error = function(err) {
829 if (0 == arguments.length) {
830 var err = this._error;
837 }); // module: hook.js
839 require.register('interfaces/bdd.js', function(module, exports, require) {
841 * Module dependencies.
844 var Suite = require('../suite'),
845 Test = require('../test');
848 * BDD-style interface:
850 * describe('Array', function(){
851 * describe('#indexOf()', function(){
852 * it('should return -1 when not present', function(){
856 * it('should return the index when present', function(){
864 module.exports = function(suite) {
865 var suites = [suite];
867 suite.on('pre-require', function(context, file, mocha) {
869 * Execute before running tests.
872 context.before = function(fn) {
873 suites[0].beforeAll(fn);
877 * Execute after running tests.
880 context.after = function(fn) {
881 suites[0].afterAll(fn);
885 * Execute before each test case.
888 context.beforeEach = function(fn) {
889 suites[0].beforeEach(fn);
893 * Execute after each test case.
896 context.afterEach = function(fn) {
897 suites[0].afterEach(fn);
901 * Describe a "suite
" with the given `title`
902 * and callback `fn` containing nested suites
906 context.describe = context.context = function(title, fn) {
907 var suite = Suite.create(suites[0], title);
908 suites.unshift(suite);
918 context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {
919 var suite = Suite.create(suites[0], title);
920 suite.pending = true;
921 suites.unshift(suite);
930 context.describe.only = function(title, fn) {
931 var suite = context.describe(title, fn);
932 mocha.grep(suite.fullTitle());
936 * Describe a specification or test-case
937 * with the given `title` and callback `fn`
941 context.it = context.specify = function(title, fn) {
942 var suite = suites[0];
943 if (suite.pending) var fn = null;
944 var test = new Test(title, fn);
950 * Exclusive test-case.
953 context.it.only = function(title, fn) {
954 var test = context.it(title, fn);
955 mocha.grep(test.fullTitle());
962 context.xit = context.xspecify = context.it.skip = function(title) {
967 }); // module: interfaces/bdd.js
969 require.register('interfaces/exports.js', function(module, exports, require) {
971 * Module dependencies.
974 var Suite = require('../suite'),
975 Test = require('../test');
978 * TDD-style interface:
982 * 'should return -1 when the value is not present': function(){
986 * 'should return the correct index when the value is present': function(){
994 module.exports = function(suite) {
995 var suites = [suite];
997 suite.on('require', visit);
999 function visit(obj) {
1001 for (var key in obj) {
1002 if ('function' == typeof obj[key]) {
1006 suites[0].beforeAll(fn);
1009 suites[0].afterAll(fn);
1012 suites[0].beforeEach(fn);
1015 suites[0].afterEach(fn);
1018 suites[0].addTest(new Test(key, fn));
1021 var suite = Suite.create(suites[0], key);
1022 suites.unshift(suite);
1029 }); // module: interfaces/exports.js
1031 require.register('interfaces/index.js', function(module, exports, require) {
1032 exports.bdd = require('./bdd');
1033 exports.tdd = require('./tdd');
1034 exports.qunit = require('./qunit');
1035 exports.exports = require('./exports');
1036 }); // module: interfaces/index.js
1038 require.register('interfaces/qunit.js', function(module, exports, require) {
1040 * Module dependencies.
1043 var Suite = require('../suite'),
1044 Test = require('../test');
1047 * QUnit-style interface:
1051 * test('#length', function(){
1052 * var arr = [1,2,3];
1053 * ok(arr.length == 3);
1056 * test('#indexOf()', function(){
1057 * var arr = [1,2,3];
1058 * ok(arr.indexOf(1) == 0);
1059 * ok(arr.indexOf(2) == 1);
1060 * ok(arr.indexOf(3) == 2);
1065 * test('#length', function(){
1066 * ok('foo'.length == 3);
1071 module.exports = function(suite) {
1072 var suites = [suite];
1074 suite.on('pre-require', function(context) {
1076 * Execute before running tests.
1079 context.before = function(fn) {
1080 suites[0].beforeAll(fn);
1084 * Execute after running tests.
1087 context.after = function(fn) {
1088 suites[0].afterAll(fn);
1092 * Execute before each test case.
1095 context.beforeEach = function(fn) {
1096 suites[0].beforeEach(fn);
1100 * Execute after each test case.
1103 context.afterEach = function(fn) {
1104 suites[0].afterEach(fn);
1108 * Describe a "suite
" with the given `title`.
1111 context.suite = function(title) {
1112 if (suites.length > 1) suites.shift();
1113 var suite = Suite.create(suites[0], title);
1114 suites.unshift(suite);
1118 * Describe a specification or test-case
1119 * with the given `title` and callback `fn`
1120 * acting as a thunk.
1123 context.test = function(title, fn) {
1124 suites[0].addTest(new Test(title, fn));
1128 }); // module: interfaces/qunit.js
1130 require.register('interfaces/tdd.js', function(module, exports, require) {
1132 * Module dependencies.
1135 var Suite = require('../suite'),
1136 Test = require('../test');
1139 * TDD-style interface:
1141 * suite('Array', function(){
1142 * suite('#indexOf()', function(){
1143 * suiteSetup(function(){
1147 * test('should return -1 when not present', function(){
1151 * test('should return the index when present', function(){
1155 * suiteTeardown(function(){
1163 module.exports = function(suite) {
1164 var suites = [suite];
1166 suite.on('pre-require', function(context, file, mocha) {
1168 * Execute before each test case.
1171 context.setup = function(fn) {
1172 suites[0].beforeEach(fn);
1176 * Execute after each test case.
1179 context.teardown = function(fn) {
1180 suites[0].afterEach(fn);
1184 * Execute before the suite.
1187 context.suiteSetup = function(fn) {
1188 suites[0].beforeAll(fn);
1192 * Execute after the suite.
1195 context.suiteTeardown = function(fn) {
1196 suites[0].afterAll(fn);
1200 * Describe a "suite
" with the given `title`
1201 * and callback `fn` containing nested suites
1205 context.suite = function(title, fn) {
1206 var suite = Suite.create(suites[0], title);
1207 suites.unshift(suite);
1214 * Exclusive test-case.
1217 context.suite.only = function(title, fn) {
1218 var suite = context.suite(title, fn);
1219 mocha.grep(suite.fullTitle());
1223 * Describe a specification or test-case
1224 * with the given `title` and callback `fn`
1225 * acting as a thunk.
1228 context.test = function(title, fn) {
1229 var test = new Test(title, fn);
1230 suites[0].addTest(test);
1235 * Exclusive test-case.
1238 context.test.only = function(title, fn) {
1239 var test = context.test(title, fn);
1240 mocha.grep(test.fullTitle());
1244 * Pending test case.
1247 context.test.skip = function(title) {
1248 context.test(title);
1252 }); // module: interfaces/tdd.js
1254 require.register('mocha.js', function(module, exports, require) {
1257 * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
1262 * Module dependencies.
1265 var path = require('browser/path'),
1266 utils = require('./utils');
1272 exports = module.exports = Mocha;
1278 exports.utils = utils;
1279 exports.interfaces = require('./interfaces');
1280 exports.reporters = require('./reporters');
1281 exports.Runnable = require('./runnable');
1282 exports.Context = require('./context');
1283 exports.Runner = require('./runner');
1284 exports.Suite = require('./suite');
1285 exports.Hook = require('./hook');
1286 exports.Test = require('./test');
1289 * Return image `name` path.
1291 * @param {String} name
1296 function image(name) {
1297 return __dirname + '/../images/' + name + '.png';
1301 * Setup mocha with `options`.
1305 * - `ui` name "bdd
", "tdd
", "exports
" etc
1306 * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
1307 * - `globals` array of accepted globals
1308 * - `timeout` timeout in milliseconds
1309 * - `bail` bail on the first test failure
1310 * - `slow` milliseconds to wait before considering a test slow
1311 * - `ignoreLeaks` ignore global leaks
1312 * - `grep` string or regexp to filter tests with
1314 * @param {Object} options
1318 function Mocha(options) {
1319 options = options || {};
1321 this.options = options;
1322 this.grep(options.grep);
1323 this.suite = new exports.Suite('', new exports.Context());
1324 this.ui(options.ui);
1325 this.bail(options.bail);
1326 this.reporter(options.reporter);
1327 if (options.timeout) this.timeout(options.timeout);
1328 if (options.slow) this.slow(options.slow);
1332 * Enable or disable bailing on the first failure.
1334 * @param {Boolean} [bail]
1338 Mocha.prototype.bail = function(bail) {
1339 if (0 == arguments.length) bail = true;
1340 this.suite.bail(bail);
1347 * @param {String} file
1351 Mocha.prototype.addFile = function(file) {
1352 this.files.push(file);
1357 * Set reporter to `reporter`, defaults to "dot
".
1359 * @param {String|Function} reporter name or constructor
1363 Mocha.prototype.reporter = function(reporter) {
1364 if ('function' == typeof reporter) {
1365 this._reporter = reporter;
1367 reporter = reporter || 'dot';
1369 this._reporter = require('./reporters/' + reporter);
1371 this._reporter = require(reporter);
1373 if (!this._reporter) throw new Error('invalid reporter "' + reporter + '"');
1379 * Set test UI `name`, defaults to "bdd
".
1381 * @param {String} bdd
1385 Mocha.prototype.ui = function(name) {
1386 name = name || 'bdd';
1387 this._ui = exports.interfaces[name];
1388 if (!this._ui) throw new Error('invalid interface "' + name + '"');
1389 this._ui = this._ui(this.suite);
1394 * Load registered files.
1399 Mocha.prototype.loadFiles = function(fn) {
1401 var suite = this.suite;
1402 var pending = this.files.length;
1403 this.files.forEach(function(file) {
1404 file = path.resolve(file);
1405 suite.emit('pre-require', global, file, self);
1406 suite.emit('require', require(file), file, self);
1407 suite.emit('post-require', global, file, self);
1408 --pending || (fn && fn());
1413 * Enable growl support.
1418 Mocha.prototype._growl = function(runner, reporter) {
1419 var notify = require('growl');
1421 runner.on('end', function() {
1422 var stats = reporter.stats;
1423 if (stats.failures) {
1424 var msg = stats.failures + ' of ' + runner.total + ' tests failed';
1425 notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
1427 notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
1437 * Add regexp to grep, if `re` is a string it is escaped.
1439 * @param {RegExp|String} re
1444 Mocha.prototype.grep = function(re) {
1445 this.options.grep = 'string' == typeof re ? new RegExp(utils.escapeRegexp(re)) : re;
1450 * Invert `.grep()` matches.
1456 Mocha.prototype.invert = function() {
1457 this.options.invert = true;
1462 * Ignore global leaks.
1468 Mocha.prototype.ignoreLeaks = function() {
1469 this.options.ignoreLeaks = true;
1474 * Enable global leak checking.
1480 Mocha.prototype.checkLeaks = function() {
1481 this.options.ignoreLeaks = false;
1486 * Enable growl support.
1492 Mocha.prototype.growl = function() {
1493 this.options.growl = true;
1498 * Ignore `globals` array or string.
1500 * @param {Array|String} globals
1505 Mocha.prototype.globals = function(globals) {
1506 this.options.globals = (this.options.globals || []).concat(globals);
1511 * Set the timeout in milliseconds.
1513 * @param {Number} timeout
1518 Mocha.prototype.timeout = function(timeout) {
1519 this.suite.timeout(timeout);
1524 * Set slowness threshold in milliseconds.
1526 * @param {Number} slow
1531 Mocha.prototype.slow = function(slow) {
1532 this.suite.slow(slow);
1537 * Makes all tests async (accepting a callback)
1543 Mocha.prototype.asyncOnly = function() {
1544 this.options.asyncOnly = true;
1549 * Run tests and invoke `fn()` when complete.
1551 * @param {Function} fn
1556 Mocha.prototype.run = function(fn) {
1557 if (this.files.length) this.loadFiles();
1558 var suite = this.suite;
1559 var options = this.options;
1560 var runner = new exports.Runner(suite);
1561 var reporter = new this._reporter(runner);
1562 runner.ignoreLeaks = false !== options.ignoreLeaks;
1563 runner.asyncOnly = options.asyncOnly;
1564 if (options.grep) runner.grep(options.grep, options.invert);
1565 if (options.globals) runner.globals(options.globals);
1566 if (options.growl) this._growl(runner, reporter);
1567 return runner.run(fn);
1569 }); // module: mocha.js
1571 require.register('ms.js', function(module, exports, require) {
1582 * Parse or format the given `val`.
1584 * @param {String|Number} val
1585 * @return {String|Number}
1589 module.exports = function(val) {
1590 if ('string' == typeof val) return parse(val);
1595 * Parse the given `str` and return milliseconds.
1597 * @param {String} str
1602 function parse(str) {
1603 var m = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(
1607 var n = parseFloat(m[1]);
1608 var type = (m[2] || 'ms').toLowerCase();
1613 return n * 31557600000;
1617 return n * 86400000;
1636 * Format the given `ms`.
1638 * @param {Number} ms
1643 function format(ms) {
1644 if (ms == d) return Math.round(ms / d) + ' day';
1645 if (ms > d) return Math.round(ms / d) + ' days';
1646 if (ms == h) return Math.round(ms / h) + ' hour';
1647 if (ms > h) return Math.round(ms / h) + ' hours';
1648 if (ms == m) return Math.round(ms / m) + ' minute';
1649 if (ms > m) return Math.round(ms / m) + ' minutes';
1650 if (ms == s) return Math.round(ms / s) + ' second';
1651 if (ms > s) return Math.round(ms / s) + ' seconds';
1654 }); // module: ms.js
1656 require.register('reporters/base.js', function(module, exports, require) {
1658 * Module dependencies.
1661 var tty = require('browser/tty'),
1662 diff = require('browser/diff'),
1663 ms = require('../ms');
1666 * Save timer references to avoid Sinon interfering (see GH-237).
1669 var Date = global.Date,
1670 setTimeout = global.setTimeout,
1671 setInterval = global.setInterval,
1672 clearTimeout = global.clearTimeout,
1673 clearInterval = global.clearInterval;
1676 * Check if both stdio streams are associated with a tty.
1679 var isatty = tty.isatty(1) && tty.isatty(2);
1685 exports = module.exports = Base;
1688 * Enable coloring by default.
1691 exports.useColors = isatty;
1694 * Default color map.
1702 'bright yellow': 93,
1706 'error message': 31,
1720 * Default symbol map.
1729 // With node.js on Windows: use symbols available in terminal default fonts
1730 if ('win32' == process.platform) {
1731 exports.symbols.ok = '\u221A';
1732 exports.symbols.err = '\u00D7';
1733 exports.symbols.dot = '.';
1737 * Color `str` with the given `type`,
1738 * allowing colors to be disabled,
1739 * as well as user-defined color
1742 * @param {String} type
1743 * @param {String} str
1748 var color = (exports.color = function(type, str) {
1749 if (!exports.useColors) return str;
1750 return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
1754 * Expose term window size, with some
1755 * defaults for when stderr is not a tty.
1760 ? process.stdout.getWindowSize
1761 ? process.stdout.getWindowSize(1)[0]
1762 : tty.getWindowSize()[1]
1767 * Expose some basic cursor interactions
1768 * that are common among reporters.
1773 process.stdout.write('\u001b[?25l');
1777 process.stdout.write('\u001b[?25h');
1780 deleteLine: function() {
1781 process.stdout.write('\u001b[2K');
1784 beginningOfLine: function() {
1785 process.stdout.write('\u001b[0G');
1789 exports.cursor.deleteLine();
1790 exports.cursor.beginningOfLine();
1795 * Outut the given `failures` as a list.
1797 * @param {Array} failures
1801 exports.list = function(failures) {
1803 failures.forEach(function(test, i) {
1806 color('error title', ' %s) %s:\n') +
1807 color('error message', ' %s') +
1808 color('error stack', '\n%s\n');
1812 message = err.message || '',
1813 stack = err.stack || message,
1814 index = stack.indexOf(message) + message.length,
1815 msg = stack.slice(0, index),
1816 actual = err.actual,
1817 expected = err.expected,
1820 // explicitly show diff
1823 err.actual = actual = JSON.stringify(actual, null, 2);
1824 err.expected = expected = JSON.stringify(expected, null, 2);
1827 // actual / expected diff
1828 if ('string' == typeof actual && 'string' == typeof expected) {
1829 var len = Math.max(actual.length, expected.length);
1831 if (len < 20) msg = errorDiff(err, 'Chars', escape);
1832 else msg = errorDiff(err, 'Words', escape);
1835 var lines = msg.split('\n');
1836 if (lines.length > 4) {
1837 var width = String(lines.length).length;
1839 .map(function(str, i) {
1840 return pad(++i, width) + ' |' + ' ' + str;
1848 color('diff removed', 'actual') +
1850 color('diff added', 'expected') +
1856 msg = msg.replace(/^/gm, ' ');
1858 fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
1861 // indent stack trace without msg
1862 stack = stack.slice(index ? index + 1 : index).replace(/^/gm, ' ');
1864 console.error(fmt, i + 1, test.fullTitle(), msg, stack);
1869 * Initialize a new `Base` reporter.
1871 * All other reporters generally
1872 * inherit from this reporter, providing
1873 * stats such as test duration, number
1874 * of tests passed / failed etc.
1876 * @param {Runner} runner
1880 function Base(runner) {
1882 stats = (this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }),
1883 failures = (this.failures = []);
1885 if (!runner) return;
1886 this.runner = runner;
1888 runner.stats = stats;
1890 runner.on('start', function() {
1891 stats.start = new Date();
1894 runner.on('suite', function(suite) {
1895 stats.suites = stats.suites || 0;
1896 suite.root || stats.suites++;
1899 runner.on('test end', function(test) {
1900 stats.tests = stats.tests || 0;
1904 runner.on('pass', function(test) {
1905 stats.passes = stats.passes || 0;
1907 var medium = test.slow() / 2;
1909 test.duration > test.slow() ? 'slow' : test.duration > medium ? 'medium' : 'fast';
1914 runner.on('fail', function(test, err) {
1915 stats.failures = stats.failures || 0;
1918 failures.push(test);
1921 runner.on('end', function() {
1922 stats.end = new Date();
1923 stats.duration = new Date() - stats.start;
1926 runner.on('pending', function() {
1932 * Output common epilogue used by many of
1933 * the bundled reporters.
1938 Base.prototype.epilogue = function() {
1939 var stats = this.stats,
1945 function pluralize(n) {
1946 return 1 == n ? 'test' : 'tests';
1950 if (stats.failures) {
1952 color('bright fail', ' ' + exports.symbols.err) +
1953 color('fail', ' %d of %d %s failed') +
1954 color('light', ':');
1956 console.error(fmt, stats.failures, this.runner.total, pluralize(this.runner.total));
1958 Base.list(this.failures);
1965 color('bright pass', ' ') + color('green', ' %d %s complete') + color('light', ' (%s)');
1967 console.log(fmt, stats.tests || 0, pluralize(stats.tests), ms(stats.duration));
1970 if (stats.pending) {
1971 fmt = color('pending', ' ') + color('pending', ' %d %s pending');
1973 console.log(fmt, stats.pending, pluralize(stats.pending));
1980 * Pad the given `str` to `len`.
1982 * @param {String} str
1983 * @param {String} len
1988 function pad(str, len) {
1990 return Array(len - str.length + 1).join(' ') + str;
1994 * Return a character diff for `err`.
1996 * @param {Error} err
2001 function errorDiff(err, type, escape) {
2002 return diff['diff' + type](err.actual, err.expected)
2003 .map(function(str) {
2005 str.value = str.value
2006 .replace(/\t/g, '<tab>')
2007 .replace(/\r/g, '<CR>')
2008 .replace(/\n/g, '<LF>\n');
2010 if (str.added) return colorLines('diff added', str.value);
2011 if (str.removed) return colorLines('diff removed', str.value);
2018 * Color lines for `str`, using the color `name`.
2020 * @param {String} name
2021 * @param {String} str
2026 function colorLines(name, str) {
2029 .map(function(str) {
2030 return color(name, str);
2034 }); // module: reporters/base.js
2036 require.register('reporters/doc.js', function(module, exports, require) {
2038 * Module dependencies.
2041 var Base = require('./base'),
2042 utils = require('../utils');
2048 exports = module.exports = Doc;
2051 * Initialize a new `Doc` reporter.
2053 * @param {Runner} runner
2057 function Doc(runner) {
2058 Base.call(this, runner);
2062 total = runner.total,
2066 return Array(indents).join(' ');
2069 runner.on('suite', function(suite) {
2070 if (suite.root) return;
2072 console.log('%s<section class="suite
">', indent());
2074 console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
2075 console.log('%s<dl>', indent());
2078 runner.on('suite end', function(suite) {
2079 if (suite.root) return;
2080 console.log('%s</dl>', indent());
2082 console.log('%s</section>', indent());
2086 runner.on('pass', function(test) {
2087 console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
2088 var code = utils.escape(utils.clean(test.fn.toString()));
2089 console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
2092 }); // module: reporters/doc.js
2094 require.register('reporters/dot.js', function(module, exports, require) {
2096 * Module dependencies.
2099 var Base = require('./base'),
2106 exports = module.exports = Dot;
2109 * Initialize a new `Dot` matrix test reporter.
2111 * @param {Runner} runner
2115 function Dot(runner) {
2116 Base.call(this, runner);
2120 width = (Base.window.width * 0.75) | 0,
2123 runner.on('start', function() {
2124 process.stdout.write('\n ');
2127 runner.on('pending', function(test) {
2128 process.stdout.write(color('pending', Base.symbols.dot));
2131 runner.on('pass', function(test) {
2132 if (++n % width == 0) process.stdout.write('\n ');
2133 if ('slow' == test.speed) {
2134 process.stdout.write(color('bright yellow', Base.symbols.dot));
2136 process.stdout.write(color(test.speed, Base.symbols.dot));
2140 runner.on('fail', function(test, err) {
2141 if (++n % width == 0) process.stdout.write('\n ');
2142 process.stdout.write(color('fail', Base.symbols.dot));
2145 runner.on('end', function() {
2152 * Inherit from `Base.prototype`.
2156 F.prototype = Base.prototype;
2157 Dot.prototype = new F();
2158 Dot.prototype.constructor = Dot;
2159 }); // module: reporters/dot.js
2161 require.register('reporters/html-cov.js', function(module, exports, require) {
2163 * Module dependencies.
2166 var JSONCov = require('./json-cov'),
2167 fs = require('browser/fs');
2173 exports = module.exports = HTMLCov;
2176 * Initialize a new `JsCoverage` reporter.
2178 * @param {Runner} runner
2182 function HTMLCov(runner) {
2183 var jade = require('jade'),
2184 file = __dirname + '/templates/coverage.jade',
2185 str = fs.readFileSync(file, 'utf8'),
2186 fn = jade.compile(str, { filename: file }),
2189 JSONCov.call(this, runner, false);
2191 runner.on('end', function() {
2192 process.stdout.write(
2195 coverageClass: coverageClass
2202 * Return coverage class for `n`.
2208 function coverageClass(n) {
2209 if (n >= 75) return 'high';
2210 if (n >= 50) return 'medium';
2211 if (n >= 25) return 'low';
2214 }); // module: reporters/html-cov.js
2216 require.register('reporters/html.js', function(module, exports, require) {
2218 * Module dependencies.
2221 var Base = require('./base'),
2222 utils = require('../utils'),
2223 Progress = require('../browser/progress'),
2224 escape = utils.escape;
2227 * Save timer references to avoid Sinon interfering (see GH-237).
2230 var Date = global.Date,
2231 setTimeout = global.setTimeout,
2232 setInterval = global.setInterval,
2233 clearTimeout = global.clearTimeout,
2234 clearInterval = global.clearInterval;
2240 exports = module.exports = HTML;
2247 '<ul id="mocha
-stats
">' +
2248 '<li class="progress
"><canvas width="40" height="40"></canvas></li>' +
2249 '<li class="passes
"><a href="#">passes:</a> <em>0</em></li>' +
2250 '<li class="failures
"><a href="#">failures:</a> <em>0</em></li>' +
2251 '<li class="duration
">duration: <em>0</em>s</li>' +
2255 * Initialize a new `Doc` reporter.
2257 * @param {Runner} runner
2261 function HTML(runner, root) {
2262 Base.call(this, runner);
2266 total = runner.total,
2267 stat = fragment(statsTemplate),
2268 items = stat.getElementsByTagName('li'),
2269 passes = items[1].getElementsByTagName('em')[0],
2270 passesLink = items[1].getElementsByTagName('a')[0],
2271 failures = items[2].getElementsByTagName('em')[0],
2272 failuresLink = items[2].getElementsByTagName('a')[0],
2273 duration = items[3].getElementsByTagName('em')[0],
2274 canvas = stat.getElementsByTagName('canvas')[0],
2275 report = fragment('<ul id="mocha
-report
"></ul>'),
2280 root = root || document.getElementById('mocha');
2282 if (canvas.getContext) {
2283 var ratio = window.devicePixelRatio || 1;
2284 canvas.style.width = canvas.width;
2285 canvas.style.height = canvas.height;
2286 canvas.width *= ratio;
2287 canvas.height *= ratio;
2288 ctx = canvas.getContext('2d');
2289 ctx.scale(ratio, ratio);
2290 progress = new Progress();
2293 if (!root) return error('#mocha div missing, add it to your document');
2296 on(passesLink, 'click', function() {
2298 var name = /pass/.test(report.className) ? '' : ' pass';
2299 report.className = report.className.replace(/fail|pass/g, '') + name;
2300 if (report.className.trim()) hideSuitesWithout('test pass');
2304 on(failuresLink, 'click', function() {
2306 var name = /fail/.test(report.className) ? '' : ' fail';
2307 report.className = report.className.replace(/fail|pass/g, '') + name;
2308 if (report.className.trim()) hideSuitesWithout('test fail');
2311 root.appendChild(stat);
2312 root.appendChild(report);
2314 if (progress) progress.size(40);
2316 runner.on('suite', function(suite) {
2317 if (suite.root) return;
2320 var url = '?grep=' + encodeURIComponent(suite.fullTitle());
2322 '<li class="suite
"><h1><a href="%s
">%s</a></h1></li>',
2328 stack[0].appendChild(el);
2329 stack.unshift(document.createElement('ul'));
2330 el.appendChild(stack[0]);
2333 runner.on('suite end', function(suite) {
2334 if (suite.root) return;
2338 runner.on('fail', function(test, err) {
2339 if ('hook' == test.type) runner.emit('test end', test);
2342 runner.on('test end', function(test) {
2343 // TODO: add to stats
2344 var percent = ((stats.tests / this.total) * 100) | 0;
2345 if (progress) progress.update(percent).draw(ctx);
2348 var ms = new Date() - stats.start;
2349 text(passes, stats.passes);
2350 text(failures, stats.failures);
2351 text(duration, (ms / 1000).toFixed(2));
2354 if ('passed' == test.state) {
2356 '<li class="test pass
%e
"><h2>%e<span class="duration
">%ems</span> <a href="?grep
=%e
" class="replay
">‣</a></h2></li>',
2360 encodeURIComponent(test.fullTitle())
2362 } else if (test.pending) {
2363 var el = fragment('<li class="test pass pending
"><h2>%e</h2></li>', test.title);
2366 '<li class="test fail
"><h2>%e <a href="?grep
=%e
" class="replay
">‣</a></h2></li>',
2368 encodeURIComponent(test.fullTitle())
2370 var str = test.err.stack || test.err.toString();
2372 // FF / Opera do not add the message
2373 if (!~str.indexOf(test.err.message)) {
2374 str = test.err.message + '\n' + str;
2377 // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
2378 // check for the result of the stringifying.
2379 if ('[object Error]' == str) str = test.err.message;
2381 // Safari doesn't give you a stack. Let's at least provide a source line.
2382 if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
2383 str += '\n(' + test.err.sourceURL + ':' + test.err.line + ')';
2386 el.appendChild(fragment('<pre class="error
">%e</pre>', str));
2391 if (!test.pending) {
2392 var h2 = el.getElementsByTagName('h2')[0];
2394 on(h2, 'click', function() {
2395 pre.style.display = 'none' == pre.style.display ? 'block' : 'none';
2398 var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
2399 el.appendChild(pre);
2400 pre.style.display = 'none';
2403 // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
2404 if (stack[0]) stack[0].appendChild(el);
2409 * Display error `msg`.
2412 function error(msg) {
2413 document.body.appendChild(fragment('<div id="mocha
-error
">%s</div>', msg));
2417 * Return a DOM fragment from `html`.
2420 function fragment(html) {
2421 var args = arguments,
2422 div = document.createElement('div'),
2425 div.innerHTML = html.replace(/%([se])/g, function(_, type) {
2428 return String(args[i++]);
2430 return escape(args[i++]);
2434 return div.firstChild;
2438 * Check for suites that do not have elements
2439 * with `classname`, and hide them.
2442 function hideSuitesWithout(classname) {
2443 var suites = document.getElementsByClassName('suite');
2444 for (var i = 0; i < suites.length; i++) {
2445 var els = suites[i].getElementsByClassName(classname);
2446 if (0 == els.length) suites[i].className += ' hidden';
2451 * Unhide .hidden suites.
2455 var els = document.getElementsByClassName('suite hidden');
2456 for (var i = 0; i < els.length; ++i) {
2457 els[i].className = els[i].className.replace('suite hidden', 'suite');
2462 * Set `el` text to `str`.
2465 function text(el, str) {
2466 if (el.textContent) {
2467 el.textContent = str;
2474 * Listen on `event` with callback `fn`.
2477 function on(el, event, fn) {
2478 if (el.addEventListener) {
2479 el.addEventListener(event, fn, false);
2481 el.attachEvent('on' + event, fn);
2484 }); // module: reporters/html.js
2486 require.register('reporters/index.js', function(module, exports, require) {
2487 exports.Base = require('./base');
2488 exports.Dot = require('./dot');
2489 exports.Doc = require('./doc');
2490 exports.TAP = require('./tap');
2491 exports.JSON = require('./json');
2492 exports.HTML = require('./html');
2493 exports.List = require('./list');
2494 exports.Min = require('./min');
2495 exports.Spec = require('./spec');
2496 exports.Nyan = require('./nyan');
2497 exports.XUnit = require('./xunit');
2498 exports.Markdown = require('./markdown');
2499 exports.Progress = require('./progress');
2500 exports.Landing = require('./landing');
2501 exports.JSONCov = require('./json-cov');
2502 exports.HTMLCov = require('./html-cov');
2503 exports.JSONStream = require('./json-stream');
2504 exports.Teamcity = require('./teamcity');
2505 }); // module: reporters/index.js
2507 require.register('reporters/json-cov.js', function(module, exports, require) {
2509 * Module dependencies.
2512 var Base = require('./base');
2518 exports = module.exports = JSONCov;
2521 * Initialize a new `JsCoverage` reporter.
2523 * @param {Runner} runner
2524 * @param {Boolean} output
2528 function JSONCov(runner, output) {
2530 output = 1 == arguments.length ? true : output;
2532 Base.call(this, runner);
2538 runner.on('test end', function(test) {
2542 runner.on('pass', function(test) {
2546 runner.on('fail', function(test) {
2547 failures.push(test);
2550 runner.on('end', function() {
2551 var cov = global._$jscoverage || {};
2552 var result = (self.cov = map(cov));
2553 result.stats = self.stats;
2554 result.tests = tests.map(clean);
2555 result.failures = failures.map(clean);
2556 result.passes = passes.map(clean);
2557 if (!output) return;
2558 process.stdout.write(JSON.stringify(result, null, 2));
2563 * Map jscoverage data to a JSON structure
2564 * suitable for reporting.
2566 * @param {Object} cov
2573 instrumentation: 'node-jscoverage',
2581 for (var filename in cov) {
2582 var data = coverage(filename, cov[filename]);
2583 ret.files.push(data);
2584 ret.hits += data.hits;
2585 ret.misses += data.misses;
2586 ret.sloc += data.sloc;
2589 ret.files.sort(function(a, b) {
2590 return a.filename.localeCompare(b.filename);
2594 ret.coverage = (ret.hits / ret.sloc) * 100;
2601 * Map jscoverage data for a single source file
2602 * to a JSON structure suitable for reporting.
2604 * @param {String} filename name of the source file
2605 * @param {Object} data jscoverage coverage data
2610 function coverage(filename, data) {
2620 data.source.forEach(function(line, num) {
2623 if (data[num] === 0) {
2626 } else if (data[num] !== undefined) {
2633 coverage: data[num] === undefined ? '' : data[num]
2637 ret.coverage = (ret.hits / ret.sloc) * 100;
2643 * Return a plain-object representation of `test`
2644 * free of cyclic properties etc.
2646 * @param {Object} test
2651 function clean(test) {
2654 fullTitle: test.fullTitle(),
2655 duration: test.duration
2658 }); // module: reporters/json-cov.js
2660 require.register('reporters/json-stream.js', function(module, exports, require) {
2662 * Module dependencies.
2665 var Base = require('./base'),
2672 exports = module.exports = List;
2675 * Initialize a new `List` test reporter.
2677 * @param {Runner} runner
2681 function List(runner) {
2682 Base.call(this, runner);
2686 total = runner.total;
2688 runner.on('start', function() {
2689 console.log(JSON.stringify(['start', { total: total }]));
2692 runner.on('pass', function(test) {
2693 console.log(JSON.stringify(['pass', clean(test)]));
2696 runner.on('fail', function(test, err) {
2697 console.log(JSON.stringify(['fail', clean(test)]));
2700 runner.on('end', function() {
2701 process.stdout.write(JSON.stringify(['end', self.stats]));
2706 * Return a plain-object representation of `test`
2707 * free of cyclic properties etc.
2709 * @param {Object} test
2714 function clean(test) {
2717 fullTitle: test.fullTitle(),
2718 duration: test.duration
2721 }); // module: reporters/json-stream.js
2723 require.register('reporters/json.js', function(module, exports, require) {
2725 * Module dependencies.
2728 var Base = require('./base'),
2729 cursor = Base.cursor,
2736 exports = module.exports = JSONReporter;
2739 * Initialize a new `JSON` reporter.
2741 * @param {Runner} runner
2745 function JSONReporter(runner) {
2747 Base.call(this, runner);
2753 runner.on('test end', function(test) {
2757 runner.on('pass', function(test) {
2761 runner.on('fail', function(test) {
2762 failures.push(test);
2765 runner.on('end', function() {
2768 tests: tests.map(clean),
2769 failures: failures.map(clean),
2770 passes: passes.map(clean)
2773 process.stdout.write(JSON.stringify(obj, null, 2));
2778 * Return a plain-object representation of `test`
2779 * free of cyclic properties etc.
2781 * @param {Object} test
2786 function clean(test) {
2789 fullTitle: test.fullTitle(),
2790 duration: test.duration
2793 }); // module: reporters/json.js
2795 require.register('reporters/landing.js', function(module, exports, require) {
2797 * Module dependencies.
2800 var Base = require('./base'),
2801 cursor = Base.cursor,
2808 exports = module.exports = Landing;
2814 Base.colors.plane = 0;
2817 * Airplane crash color.
2820 Base.colors['plane crash'] = 31;
2826 Base.colors.runway = 90;
2829 * Initialize a new `Landing` reporter.
2831 * @param {Runner} runner
2835 function Landing(runner) {
2836 Base.call(this, runner);
2840 width = (Base.window.width * 0.75) | 0,
2841 total = runner.total,
2842 stream = process.stdout,
2843 plane = color('plane', '✈'),
2848 var buf = Array(width).join('-');
2849 return ' ' + color('runway', buf);
2852 runner.on('start', function() {
2853 stream.write('\n ');
2857 runner.on('test end', function(test) {
2858 // check if the plane crashed
2859 var col = -1 == crashed ? ((width * ++n) / total) | 0 : crashed;
2862 if ('failed' == test.state) {
2863 plane = color('plane crash', '✈');
2867 // render landing strip
2868 stream.write('\u001b[4F\n\n');
2869 stream.write(runway());
2870 stream.write('\n ');
2871 stream.write(color('runway', Array(col).join('â‹…')));
2872 stream.write(plane);
2873 stream.write(color('runway', Array(width - col).join('â‹…') + '\n'));
2874 stream.write(runway());
2875 stream.write('\u001b[0m');
2878 runner.on('end', function() {
2886 * Inherit from `Base.prototype`.
2890 F.prototype = Base.prototype;
2891 Landing.prototype = new F();
2892 Landing.prototype.constructor = Landing;
2893 }); // module: reporters/landing.js
2895 require.register('reporters/list.js', function(module, exports, require) {
2897 * Module dependencies.
2900 var Base = require('./base'),
2901 cursor = Base.cursor,
2908 exports = module.exports = List;
2911 * Initialize a new `List` test reporter.
2913 * @param {Runner} runner
2917 function List(runner) {
2918 Base.call(this, runner);
2924 runner.on('start', function() {
2928 runner.on('test', function(test) {
2929 process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
2932 runner.on('pending', function(test) {
2933 var fmt = color('checkmark', ' -') + color('pending', ' %s');
2934 console.log(fmt, test.fullTitle());
2937 runner.on('pass', function(test) {
2939 color('checkmark', ' ' + Base.symbols.dot) +
2940 color('pass', ' %s: ') +
2941 color(test.speed, '%dms');
2943 console.log(fmt, test.fullTitle(), test.duration);
2946 runner.on('fail', function(test, err) {
2948 console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
2951 runner.on('end', self.epilogue.bind(self));
2955 * Inherit from `Base.prototype`.
2959 F.prototype = Base.prototype;
2960 List.prototype = new F();
2961 List.prototype.constructor = List;
2962 }); // module: reporters/list.js
2964 require.register('reporters/markdown.js', function(module, exports, require) {
2966 * Module dependencies.
2969 var Base = require('./base'),
2970 utils = require('../utils');
2973 * Expose `Markdown`.
2976 exports = module.exports = Markdown;
2979 * Initialize a new `Markdown` reporter.
2981 * @param {Runner} runner
2985 function Markdown(runner) {
2986 Base.call(this, runner);
2993 function title(str) {
2994 return Array(level).join('#') + ' ' + str;
2998 return Array(level).join(' ');
3001 function mapTOC(suite, obj) {
3003 obj = obj[suite.title] = obj[suite.title] || { suite: suite };
3004 suite.suites.forEach(function(suite) {
3010 function stringifyTOC(obj, level) {
3014 for (var key in obj) {
3015 if ('suite' == key) continue;
3016 if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
3017 if (key) buf += Array(level).join(' ') + link;
3018 buf += stringifyTOC(obj[key], level);
3024 function generateTOC(suite) {
3025 var obj = mapTOC(suite, {});
3026 return stringifyTOC(obj, 0);
3029 generateTOC(runner.suite);
3031 runner.on('suite', function(suite) {
3033 var slug = utils.slug(suite.fullTitle());
3034 buf += '<a name="' + slug + '"></a>' + '\n';
3035 buf += title(suite.title) + '\n';
3038 runner.on('suite end', function(suite) {
3042 runner.on('pass', function(test) {
3043 var code = utils.clean(test.fn.toString());
3044 buf += test.title + '.\n';
3050 runner.on('end', function() {
3051 process.stdout.write('# TOC\n');
3052 process.stdout.write(generateTOC(runner.suite));
3053 process.stdout.write(buf);
3056 }); // module: reporters/markdown.js
3058 require.register('reporters/min.js', function(module, exports, require) {
3060 * Module dependencies.
3063 var Base = require('./base');
3069 exports = module.exports = Min;
3072 * Initialize a new `Min` minimal test reporter (best used with --watch).
3074 * @param {Runner} runner
3078 function Min(runner) {
3079 Base.call(this, runner);
3081 runner.on('start', function() {
3083 process.stdout.write('\u001b[2J');
3084 // set cursor position
3085 process.stdout.write('\u001b[1;3H');
3088 runner.on('end', this.epilogue.bind(this));
3092 * Inherit from `Base.prototype`.
3096 F.prototype = Base.prototype;
3097 Min.prototype = new F();
3098 Min.prototype.constructor = Min;
3099 }); // module: reporters/min.js
3101 require.register('reporters/nyan.js', function(module, exports, require) {
3103 * Module dependencies.
3106 var Base = require('./base'),
3113 exports = module.exports = NyanCat;
3116 * Initialize a new `Dot` matrix test reporter.
3118 * @param {Runner} runner
3122 function NyanCat(runner) {
3123 Base.call(this, runner);
3127 width = (Base.window.width * 0.75) | 0,
3128 rainbowColors = (this.rainbowColors = self.generateColors()),
3129 colorIndex = (this.colorIndex = 0),
3130 numerOfLines = (this.numberOfLines = 4),
3131 trajectories = (this.trajectories = [[], [], [], []]),
3132 nyanCatWidth = (this.nyanCatWidth = 11),
3133 trajectoryWidthMax = (this.trajectoryWidthMax = width - nyanCatWidth),
3134 scoreboardWidth = (this.scoreboardWidth = 5),
3135 tick = (this.tick = 0),
3138 runner.on('start', function() {
3143 runner.on('pending', function(test) {
3144 self.draw('pending');
3147 runner.on('pass', function(test) {
3151 runner.on('fail', function(test, err) {
3155 runner.on('end', function() {
3157 for (var i = 0; i < self.numberOfLines; i++) write('\n');
3163 * Draw the nyan cat with runner `status`.
3165 * @param {String} status
3169 NyanCat.prototype.draw = function(status) {
3170 this.appendRainbow();
3171 this.drawScoreboard();
3173 this.drawNyanCat(status);
3174 this.tick = !this.tick;
3178 * Draw the "scoreboard
" showing the number
3179 * of passes, failures and pending tests.
3184 NyanCat.prototype.drawScoreboard = function() {
3185 var stats = this.stats;
3186 var colors = Base.colors;
3188 function draw(color, n) {
3190 write('\u001b[' + color + 'm' + n + '\u001b[0m');
3194 draw(colors.green, stats.passes);
3195 draw(colors.fail, stats.failures);
3196 draw(colors.pending, stats.pending);
3199 this.cursorUp(this.numberOfLines);
3203 * Append the rainbow.
3208 NyanCat.prototype.appendRainbow = function() {
3209 var segment = this.tick ? '_' : '-';
3210 var rainbowified = this.rainbowify(segment);
3212 for (var index = 0; index < this.numberOfLines; index++) {
3213 var trajectory = this.trajectories[index];
3214 if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
3215 trajectory.push(rainbowified);
3225 NyanCat.prototype.drawRainbow = function() {
3228 this.trajectories.forEach(function(line, index) {
3229 write('\u001b[' + self.scoreboardWidth + 'C');
3230 write(line.join(''));
3234 this.cursorUp(this.numberOfLines);
3238 * Draw the nyan cat with `status`.
3240 * @param {String} status
3244 NyanCat.prototype.drawNyanCat = function(status) {
3246 var startWidth = this.scoreboardWidth + this.trajectories[0].length;
3247 var color = '\u001b[' + startWidth + 'C';
3255 padding = self.tick ? ' ' : ' ';
3256 write('_|' + padding + '/\\_/\\ ');
3260 padding = self.tick ? '_' : '__';
3261 var tail = self.tick ? '~' : '^';
3273 write(tail + '|' + padding + face + ' ');
3277 padding = self.tick ? ' ' : ' ';
3278 write(padding + '"" "" ');
3281 this.cursorUp(this.numberOfLines);
3285 * Move cursor up `n`.
3291 NyanCat.prototype.cursorUp = function(n) {
3292 write('\u001b[' + n + 'A');
3296 * Move cursor down `n`.
3302 NyanCat.prototype.cursorDown = function(n) {
3303 write('\u001b[' + n + 'B');
3307 * Generate rainbow colors.
3313 NyanCat.prototype.generateColors = function() {
3316 for (var i = 0; i < 6 * 7; i++) {
3317 var pi3 = Math.floor(Math.PI / 3);
3318 var n = i * (1.0 / 6);
3319 var r = Math.floor(3 * Math.sin(n) + 3);
3320 var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
3321 var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
3322 colors.push(36 * r + 6 * g + b + 16);
3329 * Apply rainbow to the given `str`.
3331 * @param {String} str
3336 NyanCat.prototype.rainbowify = function(str) {
3337 var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
3338 this.colorIndex += 1;
3339 return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
3346 function write(string) {
3347 process.stdout.write(string);
3351 * Inherit from `Base.prototype`.
3355 F.prototype = Base.prototype;
3356 NyanCat.prototype = new F();
3357 NyanCat.prototype.constructor = NyanCat;
3358 }); // module: reporters/nyan.js
3360 require.register('reporters/progress.js', function(module, exports, require) {
3362 * Module dependencies.
3365 var Base = require('./base'),
3366 cursor = Base.cursor,
3370 * Expose `Progress`.
3373 exports = module.exports = Progress;
3376 * General progress bar color.
3379 Base.colors.progress = 90;
3382 * Initialize a new `Progress` bar test reporter.
3384 * @param {Runner} runner
3385 * @param {Object} options
3389 function Progress(runner, options) {
3390 Base.call(this, runner);
3393 options = options || {},
3395 width = (Base.window.width * 0.5) | 0,
3396 total = runner.total,
3401 options.open = options.open || '[';
3402 options.complete = options.complete || 'â–¬';
3403 options.incomplete = options.incomplete || Base.symbols.dot;
3404 options.close = options.close || ']';
3405 options.verbose = false;
3408 runner.on('start', function() {
3414 runner.on('test end', function() {
3416 var incomplete = total - complete,
3417 percent = complete / total,
3418 n = (width * percent) | 0,
3422 process.stdout.write('\u001b[J');
3423 process.stdout.write(color('progress', ' ' + options.open));
3424 process.stdout.write(Array(n).join(options.complete));
3425 process.stdout.write(Array(i).join(options.incomplete));
3426 process.stdout.write(color('progress', options.close));
3427 if (options.verbose) {
3428 process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
3432 // tests are complete, output some stats
3433 // and the failures if any
3434 runner.on('end', function() {
3442 * Inherit from `Base.prototype`.
3446 F.prototype = Base.prototype;
3447 Progress.prototype = new F();
3448 Progress.prototype.constructor = Progress;
3449 }); // module: reporters/progress.js
3451 require.register('reporters/spec.js', function(module, exports, require) {
3453 * Module dependencies.
3456 var Base = require('./base'),
3457 cursor = Base.cursor,
3464 exports = module.exports = Spec;
3467 * Initialize a new `Spec` test reporter.
3469 * @param {Runner} runner
3473 function Spec(runner) {
3474 Base.call(this, runner);
3482 return Array(indents).join(' ');
3485 runner.on('start', function() {
3489 runner.on('suite', function(suite) {
3491 console.log(color('suite', '%s%s'), indent(), suite.title);
3494 runner.on('suite end', function(suite) {
3496 if (1 == indents) console.log();
3499 runner.on('test', function(test) {
3500 process.stdout.write(indent() + color('pass', ' â—¦ ' + test.title + ': '));
3503 runner.on('pending', function(test) {
3504 var fmt = indent() + color('pending', ' - %s');
3505 console.log(fmt, test.title);
3508 runner.on('pass', function(test) {
3509 if ('fast' == test.speed) {
3510 var fmt = indent() + color('checkmark', ' ' + Base.symbols.ok) + color('pass', ' %s ');
3512 console.log(fmt, test.title);
3516 color('checkmark', ' ' + Base.symbols.ok) +
3517 color('pass', ' %s ') +
3518 color(test.speed, '(%dms)');
3520 console.log(fmt, test.title, test.duration);
3524 runner.on('fail', function(test, err) {
3526 console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
3529 runner.on('end', self.epilogue.bind(self));
3533 * Inherit from `Base.prototype`.
3537 F.prototype = Base.prototype;
3538 Spec.prototype = new F();
3539 Spec.prototype.constructor = Spec;
3540 }); // module: reporters/spec.js
3542 require.register('reporters/tap.js', function(module, exports, require) {
3544 * Module dependencies.
3547 var Base = require('./base'),
3548 cursor = Base.cursor,
3555 exports = module.exports = TAP;
3558 * Initialize a new `TAP` reporter.
3560 * @param {Runner} runner
3564 function TAP(runner) {
3565 Base.call(this, runner);
3573 runner.on('start', function() {
3574 var total = runner.grepTotal(runner.suite);
3575 console.log('%d..%d', 1, total);
3578 runner.on('test end', function() {
3582 runner.on('pending', function(test) {
3583 console.log('ok %d %s # SKIP -', n, title(test));
3586 runner.on('pass', function(test) {
3588 console.log('ok %d %s', n, title(test));
3591 runner.on('fail', function(test, err) {
3593 console.log('not ok %d %s', n, title(test));
3594 if (err.stack) console.log(err.stack.replace(/^/gm, ' '));
3597 runner.on('end', function() {
3598 console.log('# tests ' + (passes + failures));
3599 console.log('# pass ' + passes);
3600 console.log('# fail ' + failures);
3605 * Return a TAP-safe title of `test`
3607 * @param {Object} test
3612 function title(test) {
3613 return test.fullTitle().replace(/#/g, '');
3615 }); // module: reporters/tap.js
3617 require.register('reporters/teamcity.js', function(module, exports, require) {
3619 * Module dependencies.
3622 var Base = require('./base');
3625 * Expose `Teamcity`.
3628 exports = module.exports = Teamcity;
3631 * Initialize a new `Teamcity` reporter.
3633 * @param {Runner} runner
3637 function Teamcity(runner) {
3638 Base.call(this, runner);
3639 var stats = this.stats;
3641 runner.on('start', function() {
3642 console.log("##teamcity
[testSuiteStarted name
='mocha.suite']");
3645 runner.on('test', function(test) {
3646 console.log("##teamcity
[testStarted name
='" + escape(test.fullTitle()) + "']");
3649 runner.on('fail', function(test, err) {
3651 "##teamcity
[testFailed name
='" +
3652 escape(test.fullTitle()) +
3654 escape(err.message) +
3659 runner.on('pending', function(test) {
3661 "##teamcity
[testIgnored name
='" + escape(test.fullTitle()) + "' message
='pending']"
3665 runner.on('test end', function(test) {
3667 "##teamcity
[testFinished name
='" +
3668 escape(test.fullTitle()) +
3675 runner.on('end', function() {
3677 "##teamcity
[testSuiteFinished name
='mocha.suite' duration
='" + stats.duration + "']"
3683 * Escape the given `str`.
3686 function escape(str) {
3688 .replace(/\|/g, '||')
3689 .replace(/\n/g, '|n')
3690 .replace(/\r/g, '|r')
3691 .replace(/\[/g, '|[')
3692 .replace(/\]/g, '|]')
3693 .replace(/\u0085/g, '|x')
3694 .replace(/\u2028/g, '|l')
3695 .replace(/\u2029/g, '|p')
3696 .replace(/'/g, "|'");
3698 }); // module: reporters/teamcity.js
3700 require.register('reporters
/xunit
.js
', function(module, exports, require) {
3702 * Module dependencies.
3705 var Base = require('./base
'),
3706 utils = require('../utils
'),
3707 escape = utils.escape;
3710 * Save timer references to avoid Sinon interfering (see GH-237).
3713 var Date = global.Date,
3714 setTimeout = global.setTimeout,
3715 setInterval = global.setInterval,
3716 clearTimeout = global.clearTimeout,
3717 clearInterval = global.clearInterval;
3723 exports = module.exports = XUnit;
3726 * Initialize a new `XUnit` reporter.
3728 * @param {Runner} runner
3732 function XUnit(runner) {
3733 Base.call(this, runner);
3734 var stats = this.stats,
3738 runner.on('pass
', function(test) {
3742 runner.on('fail
', function(test) {
3746 runner.on('end
', function() {
3751 name: 'Mocha Tests
',
3753 failures: stats.failures,
3754 errors: stats.failures,
3755 skip: stats.tests - stats.failures - stats.passes,
3756 timestamp: new Date().toUTCString(),
3757 time: stats.duration / 1000
3763 tests.forEach(test);
3764 console.log('</testsuite
>');
3769 * Inherit from `Base.prototype`.
3773 F.prototype = Base.prototype;
3774 XUnit.prototype = new F();
3775 XUnit.prototype.constructor = XUnit;
3778 * Output tag for the given `test.`
3781 function test(test) {
3783 classname: test.parent.fullTitle(),
3785 time: test.duration / 1000
3788 if ('failed
' == test.state) {
3790 attrs.message = escape(err.message);
3792 tag('testcase
', attrs, false, tag('failure
', attrs, false, cdata(err.stack)))
3794 } else if (test.pending) {
3795 console.log(tag('testcase
', attrs, false, tag('skipped
', {}, true)));
3797 console.log(tag('testcase
', attrs, true));
3805 function tag(name, attrs, close, content) {
3806 var end = close ? '/>' : '>',
3810 for (var key in attrs) {
3811 pairs.push(key + '="' + escape(attrs[key]) + '"');
3814 tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
3815 if (content) tag += content + '</' + name + end;
3820 * Return cdata escaped CDATA `str`.
3823 function cdata(str) {
3824 return '<![CDATA
[' + escape(str) + ']]>';
3826 }); // module: reporters/xunit.js
3828 require.register('runnable
.js
', function(module, exports, require) {
3830 * Module dependencies.
3833 var EventEmitter = require('browser
/events
').EventEmitter,
3834 debug = require('browser
/debug
')('mocha
:runnable
'),
3835 milliseconds = require('./ms
');
3838 * Save timer references to avoid Sinon interfering (see GH-237).
3841 var Date = global.Date,
3842 setTimeout = global.setTimeout,
3843 setInterval = global.setInterval,
3844 clearTimeout = global.clearTimeout,
3845 clearInterval = global.clearInterval;
3848 * Object#toString().
3851 var toString = Object.prototype.toString;
3854 * Expose `Runnable`.
3857 module.exports = Runnable;
3860 * Initialize a new `Runnable` with the given `title` and callback `fn`.
3862 * @param {String} title
3863 * @param {Function} fn
3867 function Runnable(title, fn) {
3870 this.async = fn && fn.length;
3871 this.sync = !this.async;
3872 this._timeout = 2000;
3874 this.timedOut = false;
3878 * Inherit from `EventEmitter.prototype`.
3882 F.prototype = EventEmitter.prototype;
3883 Runnable.prototype = new F();
3884 Runnable.prototype.constructor = Runnable;
3887 * Set & get timeout `ms`.
3889 * @param {Number|String} ms
3890 * @return {Runnable|Number} ms or self
3894 Runnable.prototype.timeout = function(ms) {
3895 if (0 == arguments.length) return this._timeout;
3896 if ('string
' == typeof ms) ms = milliseconds(ms);
3897 debug('timeout
%d
', ms);
3899 if (this.timer) this.resetTimeout();
3904 * Set & get slow `ms`.
3906 * @param {Number|String} ms
3907 * @return {Runnable|Number} ms or self
3911 Runnable.prototype.slow = function(ms) {
3912 if (0 === arguments.length) return this._slow;
3913 if ('string
' == typeof ms) ms = milliseconds(ms);
3914 debug('timeout
%d
', ms);
3920 * Return the full title generated by recursively
3921 * concatenating the parent's full title
.
3927 Runnable
.prototype.fullTitle = function() {
3928 return this.parent
.fullTitle() + ' ' + this.title
;
3932 * Clear the timeout.
3937 Runnable
.prototype.clearTimeout = function() {
3938 clearTimeout(this.timer
);
3942 * Inspect the runnable void of private properties.
3948 Runnable
.prototype.inspect = function() {
3949 return JSON
.stringify(
3951 function(key
, val
) {
3952 if ('_' == key
[0]) return;
3953 if ('parent' == key
) return '#<Suite>';
3954 if ('ctx' == key
) return '#<Context>';
3962 * Reset the timeout.
3967 Runnable
.prototype.resetTimeout = function() {
3969 ms
= this.timeout();
3971 this.clearTimeout();
3973 this.timer
= setTimeout(function() {
3974 self
.callback(new Error('timeout of ' + ms
+ 'ms exceeded'));
3975 self
.timedOut
= true;
3981 * Run the test and invoke `fn(err)`.
3983 * @param {Function} fn
3987 Runnable
.prototype.run = function(fn
) {
3989 ms
= this.timeout(),
3995 if (ctx
) ctx
.runnable(this);
4000 this.timer
= setTimeout(function() {
4001 done(new Error('timeout of ' + ms
+ 'ms exceeded'));
4002 self
.timedOut
= true;
4007 // called multiple times
4008 function multiple(err
) {
4009 if (emitted
) return;
4011 self
.emit('error', err
|| new Error('done() called multiple times'));
4015 function done(err
) {
4016 if (self
.timedOut
) return;
4017 if (finished
) return multiple(err
);
4018 self
.clearTimeout();
4019 self
.duration
= new Date() - start
;
4024 // for .resetTimeout()
4025 this.callback
= done
;
4030 this.fn
.call(ctx
, function(err
) {
4031 if (err
instanceof Error
|| toString
.call(err
) === '[object Error]') return done(err
);
4032 if (null != err
) return done(new Error('done() invoked with non-Error: ' + err
));
4041 if (this.asyncOnly
) {
4042 return done(new Error('--async-only option in use without declaring `done()`'));
4047 if (!this.pending
) this.fn
.call(ctx
);
4048 this.duration
= new Date() - start
;
4054 }); // module: runnable.js
4056 require
.register('runner.js', function(module
, exports
, require
) {
4058 * Module dependencies.
4061 var EventEmitter
= require('browser/events').EventEmitter
,
4062 debug
= require('browser/debug')('mocha:runner'),
4063 Test
= require('./test'),
4064 utils
= require('./utils'),
4065 filter
= utils
.filter
,
4069 * Non-enumerable globals.
4085 module
.exports
= Runner
;
4088 * Initialize a `Runner` for the given `suite`.
4092 * - `start` execution started
4093 * - `end` execution complete
4094 * - `suite` (suite) test suite execution started
4095 * - `suite end` (suite) all tests (and sub-suites) have finished
4096 * - `test` (test) test execution started
4097 * - `test end` (test) test completed
4098 * - `hook` (hook) hook execution started
4099 * - `hook end` (hook) hook complete
4100 * - `pass` (test) test passed
4101 * - `fail` (test, err) test failed
4106 function Runner(suite
) {
4110 this.total
= suite
.total();
4112 this.on('test end', function(test
) {
4113 self
.checkGlobals(test
);
4115 this.on('hook end', function(hook
) {
4116 self
.checkGlobals(hook
);
4119 this.globals(this.globalProps().concat(['errno']));
4123 * Wrapper for setImmediate, process.nextTick, or browser polyfill.
4125 * @param {Function} fn
4129 Runner
.immediately
= global
.setImmediate
|| process
.nextTick
;
4132 * Inherit from `EventEmitter.prototype`.
4136 F
.prototype = EventEmitter
.prototype;
4137 Runner
.prototype = new F();
4138 Runner
.prototype.constructor = Runner
;
4141 * Run tests with full titles matching `re`. Updates runner.total
4142 * with number of tests matched.
4144 * @param {RegExp} re
4145 * @param {Boolean} invert
4146 * @return {Runner} for chaining
4150 Runner
.prototype.grep = function(re
, invert
) {
4151 debug('grep %s', re
);
4153 this._invert
= invert
;
4154 this.total
= this.grepTotal(this.suite
);
4159 * Returns the number of tests matching the grep search for the
4162 * @param {Suite} suite
4167 Runner
.prototype.grepTotal = function(suite
) {
4171 suite
.eachTest(function(test
) {
4172 var match
= self
._grep
.test(test
.fullTitle());
4173 if (self
._invert
) match
= !match
;
4181 * Return a list of global properties.
4187 Runner
.prototype.globalProps = function() {
4188 var props
= utils
.keys(global
);
4191 for (var i
= 0; i
< globals
.length
; ++i
) {
4192 if (~utils
.indexOf(props
, globals
[i
])) continue;
4193 props
.push(globals
[i
]);
4200 * Allow the given `arr` of globals.
4202 * @param {Array} arr
4203 * @return {Runner} for chaining
4207 Runner
.prototype.globals = function(arr
) {
4208 if (0 == arguments
.length
) return this._globals
;
4209 debug('globals %j', arr
);
4213 this._globals
.push(arr
);
4221 * Check for global variable leaks.
4226 Runner
.prototype.checkGlobals = function(test
) {
4227 if (this.ignoreLeaks
) return;
4228 var ok
= this._globals
;
4229 var globals
= this.globalProps();
4230 var isNode
= process
.kill
;
4233 // check length - 2 ('errno' and 'location' globals)
4234 if (isNode
&& 1 == ok
.length
- globals
.length
) return;
4235 else if (2 == ok
.length
- globals
.length
) return;
4237 leaks
= filterLeaks(ok
, globals
);
4238 this._globals
= this._globals
.concat(leaks
);
4240 if (leaks
.length
> 1) {
4241 this.fail(test
, new Error('global leaks detected: ' + leaks
.join(', ') + ''));
4242 } else if (leaks
.length
) {
4243 this.fail(test
, new Error('global leak detected: ' + leaks
[0]));
4248 * Fail the given `test`.
4250 * @param {Test} test
4251 * @param {Error} err
4255 Runner
.prototype.fail = function(test
, err
) {
4257 test
.state
= 'failed';
4259 if ('string' == typeof err
) {
4260 err
= new Error('the string "' + err
+ '" was thrown, throw an Error :)');
4263 this.emit('fail', test
, err
);
4267 * Fail the given `hook` with `err`.
4269 * Hook failures (currently) hard-end due
4270 * to that fact that a failing hook will
4271 * surely cause subsequent tests to fail,
4272 * causing jumbled reporting.
4274 * @param {Hook} hook
4275 * @param {Error} err
4279 Runner
.prototype.failHook = function(hook
, err
) {
4280 this.fail(hook
, err
);
4285 * Run hook `name` callbacks and then invoke `fn()`.
4287 * @param {String} name
4288 * @param {Function} function
4292 Runner
.prototype.hook = function(name
, fn
) {
4293 var suite
= this.suite
,
4294 hooks
= suite
['_' + name
],
4299 var hook
= hooks
[i
];
4300 if (!hook
) return fn();
4301 self
.currentRunnable
= hook
;
4303 self
.emit('hook', hook
);
4305 hook
.on('error', function(err
) {
4306 self
.failHook(hook
, err
);
4309 hook
.run(function(err
) {
4310 hook
.removeAllListeners('error');
4311 var testError
= hook
.error();
4312 if (testError
) self
.fail(self
.test
, testError
);
4313 if (err
) return self
.failHook(hook
, err
);
4314 self
.emit('hook end', hook
);
4319 Runner
.immediately(function() {
4325 * Run hook `name` for the given array of `suites`
4326 * in order, and callback `fn(err)`.
4328 * @param {String} name
4329 * @param {Array} suites
4330 * @param {Function} fn
4334 Runner
.prototype.hooks = function(name
, suites
, fn
) {
4338 function next(suite
) {
4346 self
.hook(name
, function(err
) {
4360 * Run hooks from the top level down.
4362 * @param {String} name
4363 * @param {Function} fn
4367 Runner
.prototype.hookUp = function(name
, fn
) {
4368 var suites
= [this.suite
].concat(this.parents()).reverse();
4369 this.hooks(name
, suites
, fn
);
4373 * Run hooks from the bottom up.
4375 * @param {String} name
4376 * @param {Function} fn
4380 Runner
.prototype.hookDown = function(name
, fn
) {
4381 var suites
= [this.suite
].concat(this.parents());
4382 this.hooks(name
, suites
, fn
);
4386 * Return an array of parent Suites from
4387 * closest to furthest.
4393 Runner
.prototype.parents = function() {
4394 var suite
= this.suite
,
4396 while ((suite
= suite
.parent
)) suites
.push(suite
);
4401 * Run the current test and callback `fn(err)`.
4403 * @param {Function} fn
4407 Runner
.prototype.runTest = function(fn
) {
4408 var test
= this.test
,
4411 if (this.asyncOnly
) test
.asyncOnly
= true;
4414 test
.on('error', function(err
) {
4415 self
.fail(test
, err
);
4424 * Run tests in the given `suite` and invoke
4425 * the callback `fn()` when complete.
4427 * @param {Suite} suite
4428 * @param {Function} fn
4432 Runner
.prototype.runTests = function(suite
, fn
) {
4434 tests
= suite
.tests
.slice(),
4437 function next(err
) {
4438 // if we bail after first err
4439 if (self
.failures
&& suite
._bail
) return fn();
4442 test
= tests
.shift();
4445 if (!test
) return fn();
4448 var match
= self
._grep
.test(test
.fullTitle());
4449 if (self
._invert
) match
= !match
;
4450 if (!match
) return next();
4454 self
.emit('pending', test
);
4455 self
.emit('test end', test
);
4459 // execute test and hook(s)
4460 self
.emit('test', (self
.test
= test
));
4461 self
.hookDown('beforeEach', function() {
4462 self
.currentRunnable
= self
.test
;
4463 self
.runTest(function(err
) {
4467 self
.fail(test
, err
);
4468 self
.emit('test end', test
);
4469 return self
.hookUp('afterEach', next
);
4472 test
.state
= 'passed';
4473 self
.emit('pass', test
);
4474 self
.emit('test end', test
);
4475 self
.hookUp('afterEach', next
);
4485 * Run the given `suite` and invoke the
4486 * callback `fn()` when complete.
4488 * @param {Suite} suite
4489 * @param {Function} fn
4493 Runner
.prototype.runSuite = function(suite
, fn
) {
4494 var total
= this.grepTotal(suite
),
4498 debug('run suite %s', suite
.fullTitle());
4500 if (!total
) return fn();
4502 this.emit('suite', (this.suite
= suite
));
4505 var curr
= suite
.suites
[i
++];
4506 if (!curr
) return done();
4507 self
.runSuite(curr
, next
);
4512 self
.hook('afterAll', function() {
4513 self
.emit('suite end', suite
);
4518 this.hook('beforeAll', function() {
4519 self
.runTests(suite
, next
);
4524 * Handle uncaught exceptions.
4526 * @param {Error} err
4530 Runner
.prototype.uncaught = function(err
) {
4531 debug('uncaught exception %s', err
.message
);
4532 var runnable
= this.currentRunnable
;
4533 if (!runnable
|| 'failed' == runnable
.state
) return;
4534 runnable
.clearTimeout();
4535 err
.uncaught
= true;
4536 this.fail(runnable
, err
);
4538 // recover from test
4539 if ('test' == runnable
.type
) {
4540 this.emit('test end', runnable
);
4541 this.hookUp('afterEach', this.next
);
4550 * Run the root suite and invoke `fn(failures)`
4553 * @param {Function} fn
4554 * @return {Runner} for chaining
4558 Runner
.prototype.run = function(fn
) {
4560 fn
= fn
|| function() {};
4562 function uncaught(err
) {
4569 this.on('end', function() {
4571 process
.removeListener('uncaughtException', uncaught
);
4577 this.runSuite(this.suite
, function() {
4578 debug('finished running');
4582 // uncaught exception
4583 process
.on('uncaughtException', uncaught
);
4589 * Filter leaks with the given globals flagged as `ok`.
4592 * @param {Array} globals
4597 function filterLeaks(ok
, globals
) {
4598 return filter(globals
, function(key
) {
4599 var matched
= filter(ok
, function(ok
) {
4600 if (~ok
.indexOf('*')) return 0 == key
.indexOf(ok
.split('*')[0]);
4601 // Opera and IE expose global variables for HTML element IDs (issue #243)
4602 if (/^mocha-/.test(key
)) return true;
4605 return matched
.length
== 0 && (!global
.navigator
|| 'onerror' !== key
);
4608 }); // module: runner.js
4610 require
.register('suite.js', function(module
, exports
, require
) {
4612 * Module dependencies.
4615 var EventEmitter
= require('browser/events').EventEmitter
,
4616 debug
= require('browser/debug')('mocha:suite'),
4617 milliseconds
= require('./ms'),
4618 utils
= require('./utils'),
4619 Hook
= require('./hook');
4625 exports
= module
.exports
= Suite
;
4628 * Create a new `Suite` with the given `title`
4629 * and parent `Suite`. When a suite with the
4630 * same title is already present, that suite
4631 * is returned to provide nicer reporter
4632 * and more flexible meta-testing.
4634 * @param {Suite} parent
4635 * @param {String} title
4640 exports
.create = function(parent
, title
) {
4641 var suite
= new Suite(title
, parent
.ctx
);
4642 suite
.parent
= parent
;
4643 if (parent
.pending
) suite
.pending
= true;
4644 title
= suite
.fullTitle();
4645 parent
.addSuite(suite
);
4650 * Initialize a new `Suite` with the given
4651 * `title` and `ctx`.
4653 * @param {String} title
4654 * @param {Context} ctx
4658 function Suite(title
, ctx
) {
4663 this.pending
= false;
4664 this._beforeEach
= [];
4665 this._beforeAll
= [];
4666 this._afterEach
= [];
4667 this._afterAll
= [];
4669 this._timeout
= 2000;
4675 * Inherit from `EventEmitter.prototype`.
4679 F
.prototype = EventEmitter
.prototype;
4680 Suite
.prototype = new F();
4681 Suite
.prototype.constructor = Suite
;
4684 * Return a clone of this `Suite`.
4690 Suite
.prototype.clone = function() {
4691 var suite
= new Suite(this.title
);
4693 suite
.ctx
= this.ctx
;
4694 suite
.timeout(this.timeout());
4695 suite
.slow(this.slow());
4696 suite
.bail(this.bail());
4701 * Set timeout `ms` or short-hand such as "2s".
4703 * @param {Number|String} ms
4704 * @return {Suite|Number} for chaining
4708 Suite
.prototype.timeout = function(ms
) {
4709 if (0 == arguments
.length
) return this._timeout
;
4710 if ('string' == typeof ms
) ms
= milliseconds(ms
);
4711 debug('timeout %d', ms
);
4712 this._timeout
= parseInt(ms
, 10);
4717 * Set slow `ms` or short-hand such as "2s".
4719 * @param {Number|String} ms
4720 * @return {Suite|Number} for chaining
4724 Suite
.prototype.slow = function(ms
) {
4725 if (0 === arguments
.length
) return this._slow
;
4726 if ('string' == typeof ms
) ms
= milliseconds(ms
);
4727 debug('slow %d', ms
);
4733 * Sets whether to bail after first error.
4735 * @parma {Boolean} bail
4736 * @return {Suite|Number} for chaining
4740 Suite
.prototype.bail = function(bail
) {
4741 if (0 == arguments
.length
) return this._bail
;
4742 debug('bail %s', bail
);
4748 * Run `fn(test[, done])` before running tests.
4750 * @param {Function} fn
4751 * @return {Suite} for chaining
4755 Suite
.prototype.beforeAll = function(fn
) {
4756 if (this.pending
) return this;
4757 var hook
= new Hook('"before all" hook', fn
);
4759 hook
.timeout(this.timeout());
4760 hook
.slow(this.slow());
4761 hook
.ctx
= this.ctx
;
4762 this._beforeAll
.push(hook
);
4763 this.emit('beforeAll', hook
);
4768 * Run `fn(test[, done])` after running tests.
4770 * @param {Function} fn
4771 * @return {Suite} for chaining
4775 Suite
.prototype.afterAll = function(fn
) {
4776 if (this.pending
) return this;
4777 var hook
= new Hook('"after all" hook', fn
);
4779 hook
.timeout(this.timeout());
4780 hook
.slow(this.slow());
4781 hook
.ctx
= this.ctx
;
4782 this._afterAll
.push(hook
);
4783 this.emit('afterAll', hook
);
4788 * Run `fn(test[, done])` before each test case.
4790 * @param {Function} fn
4791 * @return {Suite} for chaining
4795 Suite
.prototype.beforeEach = function(fn
) {
4796 if (this.pending
) return this;
4797 var hook
= new Hook('"before each" hook', fn
);
4799 hook
.timeout(this.timeout());
4800 hook
.slow(this.slow());
4801 hook
.ctx
= this.ctx
;
4802 this._beforeEach
.push(hook
);
4803 this.emit('beforeEach', hook
);
4808 * Run `fn(test[, done])` after each test case.
4810 * @param {Function} fn
4811 * @return {Suite} for chaining
4815 Suite
.prototype.afterEach = function(fn
) {
4816 if (this.pending
) return this;
4817 var hook
= new Hook('"after each" hook', fn
);
4819 hook
.timeout(this.timeout());
4820 hook
.slow(this.slow());
4821 hook
.ctx
= this.ctx
;
4822 this._afterEach
.push(hook
);
4823 this.emit('afterEach', hook
);
4828 * Add a test `suite`.
4830 * @param {Suite} suite
4831 * @return {Suite} for chaining
4835 Suite
.prototype.addSuite = function(suite
) {
4836 suite
.parent
= this;
4837 suite
.timeout(this.timeout());
4838 suite
.slow(this.slow());
4839 suite
.bail(this.bail());
4840 this.suites
.push(suite
);
4841 this.emit('suite', suite
);
4846 * Add a `test` to this suite.
4848 * @param {Test} test
4849 * @return {Suite} for chaining
4853 Suite
.prototype.addTest = function(test
) {
4855 test
.timeout(this.timeout());
4856 test
.slow(this.slow());
4857 test
.ctx
= this.ctx
;
4858 this.tests
.push(test
);
4859 this.emit('test', test
);
4864 * Return the full title generated by recursively
4865 * concatenating the parent's full title.
4871 Suite
.prototype.fullTitle = function() {
4873 var full
= this.parent
.fullTitle();
4874 if (full
) return full
+ ' ' + this.title
;
4880 * Return the total number of tests.
4886 Suite
.prototype.total = function() {
4890 function(sum
, suite
) {
4891 return sum
+ suite
.total();
4894 ) + this.tests
.length
4899 * Iterates through each suite recursively to find
4900 * all tests. Applies a function in the format
4903 * @param {Function} fn
4908 Suite
.prototype.eachTest = function(fn
) {
4909 utils
.forEach(this.tests
, fn
);
4910 utils
.forEach(this.suites
, function(suite
) {
4915 }); // module: suite.js
4917 require
.register('test.js', function(module
, exports
, require
) {
4919 * Module dependencies.
4922 var Runnable
= require('./runnable');
4928 module
.exports
= Test
;
4931 * Initialize a new `Test` with the given `title` and callback `fn`.
4933 * @param {String} title
4934 * @param {Function} fn
4938 function Test(title
, fn
) {
4939 Runnable
.call(this, title
, fn
);
4945 * Inherit from `Runnable.prototype`.
4949 F
.prototype = Runnable
.prototype;
4950 Test
.prototype = new F();
4951 Test
.prototype.constructor = Test
;
4952 }); // module: test.js
4954 require
.register('utils.js', function(module
, exports
, require
) {
4956 * Module dependencies.
4959 var fs
= require('browser/fs'),
4960 path
= require('browser/path'),
4962 debug
= require('browser/debug')('mocha:watch');
4965 * Ignored directories.
4968 var ignore
= ['node_modules', '.git'];
4971 * Escape special characters in the given string of html.
4973 * @param {String} html
4978 exports
.escape = function(html
) {
4980 .replace(/&/g
, '&')
4981 .replace(/"/g, '"')
4982 .replace(/</g, '<')
4983 .replace(/>/g, '>');
4987 * Array#forEach (<=IE8)
4989 * @param {Array} array
4990 * @param {Function} fn
4991 * @param {Object} scope
4995 exports.forEach = function(arr, fn, scope) {
4996 for (var i = 0, l = arr.length; i < l; i++) fn.call(scope, arr[i], i);
5000 * Array#indexOf (<=IE8)
5002 * @parma {Array} arr
5003 * @param {Object} obj to find index of
5004 * @param {Number} start
5008 exports.indexOf = function(arr, obj, start) {
5009 for (var i = start || 0, l = arr.length; i < l; i++) {
5010 if (arr[i] === obj) return i;
5016 * Array#reduce (<=IE8)
5018 * @param {Array} array
5019 * @param {Function} fn
5020 * @param {Object} initial value
5024 exports.reduce = function(arr, fn, val) {
5027 for (var i = 0, l = arr.length; i < l; i++) {
5028 rval = fn(rval, arr[i], i, arr);
5035 * Array#filter (<=IE8)
5037 * @param {Array} array
5038 * @param {Function} fn
5042 exports.filter = function(arr, fn) {
5045 for (var i = 0, l = arr.length; i < l; i++) {
5047 if (fn(val, i, arr)) ret.push(val);
5054 * Object.keys (<=IE8)
5056 * @param {Object} obj
5057 * @return {Array} keys
5065 has = Object.prototype.hasOwnProperty; // for `window` on <=IE8
5067 for (var key in obj) {
5068 if (has.call(obj, key)) {
5077 * Watch the given `files` for changes
5078 * and invoke `fn(file)` on modification.
5080 * @param {Array} files
5081 * @param {Function} fn
5085 exports.watch = function(files, fn) {
5086 var options = { interval: 100 };
5087 files.forEach(function(file) {
5088 debug('file %s', file);
5089 fs.watchFile(file, options, function(curr, prev) {
5090 if (prev.mtime < curr.mtime) fn(file);
5099 function ignored(path) {
5100 return !~ignore.indexOf(path);
5104 * Lookup files in the given `dir`.
5110 exports.files = function(dir, ret) {
5115 .forEach(function(path) {
5116 path = join(dir, path);
5117 if (fs.statSync(path).isDirectory()) {
5118 exports.files(path, ret);
5119 } else if (path.match(/\.(js|coffee)$/)) {
5128 * Compute a slug from the given `str`.
5130 * @param {String} str
5135 exports.slug = function(str) {
5138 .replace(/ +/g, '-')
5139 .replace(/[^-\w]/g, '');
5143 * Strip the function definition from `str`,
5144 * and re-indent for pre whitespace.
5147 exports.clean = function(str) {
5148 str = str.replace(/^function *\(.*\) *{/, '').replace(/\s+\}$/, '');
5150 var spaces = str.match(/^\n?( *)/)[1].length,
5151 re = new RegExp('^ {' + spaces + '}', 'gm');
5153 str = str.replace(re, '');
5155 return exports.trim(str);
5159 * Escape regular expression characters in `str`.
5161 * @param {String} str
5166 exports.escapeRegexp = function(str) {
5167 return str.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
5171 * Trim the given `str`.
5173 * @param {String} str
5178 exports.trim = function(str) {
5179 return str.replace(/^\s+|\s+$/g, '');
5183 * Parse the given `qs`.
5185 * @param {String} qs
5190 exports.parseQuery = function(qs) {
5191 return exports.reduce(
5192 qs.replace('?', '').split('&'),
5193 function(obj, pair) {
5194 var i = pair.indexOf('='),
5195 key = pair.slice(0, i),
5196 val = pair.slice(++i);
5198 obj[key] = decodeURIComponent(val);
5206 * Highlight the given string of `js`.
5208 * @param {String} js
5213 function highlight(js) {
5215 .replace(/</g, '<')
5216 .replace(/>/g, '>')
5217 .replace(/\/\/(.*)/gm, '<span class="comment
">//$1</span>')
5218 .replace(/('.*?')/gm, '<span class="string
">$1</span>')
5219 .replace(/(\d+\.\d+)/gm, '<span class="number
">$1</span>')
5220 .replace(/(\d+)/gm, '<span class="number
">$1</span>')
5223 '<span class="keyword
">new</span> <span class="init
">$1</span>'
5226 /\b(function|new|throw|return|var|if|else)\b/gm,
5227 '<span class="keyword
">$1</span>'
5232 * Highlight the contents of tag `name`.
5234 * @param {String} name
5238 exports.highlightTags = function(name) {
5239 var code = document.getElementsByTagName(name);
5240 for (var i = 0, len = code.length; i < len; ++i) {
5241 code[i].innerHTML = highlight(code[i].innerHTML);
5244 }); // module: utils.js
5248 * These are meant only to allow
5249 * mocha.js to run untouched, not
5250 * to allow running node code in
5255 process.exit = function(status) {};
5256 process.stdout = {};
5260 * Remove uncaughtException listener.
5263 process.removeListener = function(e) {
5264 if ('uncaughtException' == e) {
5265 window.onerror = null;
5270 * Implements uncaughtException listener.
5273 process.on = function(e, fn) {
5274 if ('uncaughtException' == e) {
5275 window.onerror = function(err, url, line) {
5276 fn(new Error(err + ' (' + url + ':' + line + ')'));
5287 var Mocha = (window.Mocha = require('mocha')),
5288 mocha = (window.mocha = new Mocha({ reporter: 'html' }));
5290 var immediateQueue = [],
5293 function timeslice() {
5294 var immediateStart = new Date().getTime();
5295 while (immediateQueue.length && new Date().getTime() - immediateStart < 100) {
5296 immediateQueue.shift()();
5298 if (immediateQueue.length) {
5299 immediateTimeout = setTimeout(timeslice, 0);
5301 immediateTimeout = null;
5306 * High-performance override of Runner.immediately.
5309 Mocha.Runner.immediately = function(callback) {
5310 immediateQueue.push(callback);
5311 if (!immediateTimeout) {
5312 immediateTimeout = setTimeout(timeslice, 0);
5317 * Override ui to ensure that the ui functions are initialized.
5318 * Normally this would happen in Mocha.prototype.loadFiles.
5321 mocha.ui = function(ui) {
5322 Mocha.prototype.ui.call(this, ui);
5323 this.suite.emit('pre-require', window, null, this);
5328 * Setup mocha with the given setting options.
5331 mocha.setup = function(opts) {
5332 if ('string' == typeof opts) opts = { ui: opts };
5333 for (var opt in opts) this[opt](opts[opt]);
5338 * Run mocha, returning the Runner.
5341 mocha.run = function(fn) {
5342 var options = mocha.options;
5343 mocha.globals('location');
5345 var query = Mocha.utils.parseQuery(window.location.search || '');
5346 if (query.grep) mocha.grep(query.grep);
5347 if (query.invert) mocha.invert();
5349 return Mocha.prototype.run.call(mocha, function() {
5350 Mocha.utils.highlightTags('code');