URLFetcherNullWriter for resource requests.
[chromium-blink-merge.git] / third_party / mocha / mocha.js
blob5ff1385758bf6b6d2fb4ec324a31cce612183091
1 ;(function(){
3 // CommonJS require()
5 function require(p){
6     var path = require.resolve(p)
7       , mod = require.modules[path];
8     if (!mod) throw new Error('failed to require "' + p + '"');
9     if (!mod.exports) {
10       mod.exports = {};
11       mod.call(mod.exports, mod, mod.exports, require.relative(path));
12     }
13     return mod.exports;
14   }
16 require.modules = {};
18 require.resolve = function (path){
19     var orig = path
20       , reg = path + '.js'
21       , index = path + '/index.js';
22     return require.modules[reg] && reg
23       || require.modules[index] && index
24       || orig;
25   };
27 require.register = function (path, fn){
28     require.modules[path] = fn;
29   };
31 require.relative = function (parent) {
32     return function(p){
33       if ('.' != p.charAt(0)) return require(p);
35       var path = parent.split('/')
36         , segs = p.split('/');
37       path.pop();
39       for (var i = 0; i < segs.length; i++) {
40         var seg = segs[i];
41         if ('..' == seg) path.pop();
42         else if ('.' != seg) path.push(seg);
43       }
45       return require(path.join('/'));
46     };
47   };
50 require.register("browser/debug.js", function(module, exports, require){
51 module.exports = function(type){
52   return function(){
53   }
56 }); // module: browser/debug.js
58 require.register("browser/diff.js", function(module, exports, require){
59 /* See LICENSE file for terms of use */
62  * Text diff implementation.
63  *
64  * This library supports the following APIS:
65  * JsDiff.diffChars: Character by character diff
66  * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
67  * JsDiff.diffLines: Line based diff
68  *
69  * JsDiff.diffCss: Diff targeted at CSS content
70  *
71  * These methods are based on the implementation proposed in
72  * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
73  * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
74  */
75 var JsDiff = (function() {
76   /*jshint maxparams: 5*/
77   function clonePath(path) {
78     return { newPos: path.newPos, components: path.components.slice(0) };
79   }
80   function removeEmpty(array) {
81     var ret = [];
82     for (var i = 0; i < array.length; i++) {
83       if (array[i]) {
84         ret.push(array[i]);
85       }
86     }
87     return ret;
88   }
89   function escapeHTML(s) {
90     var n = s;
91     n = n.replace(/&/g, '&amp;');
92     n = n.replace(/</g, '&lt;');
93     n = n.replace(/>/g, '&gt;');
94     n = n.replace(/"/g, '&quot;');
96     return n;
97   }
99   var Diff = function(ignoreWhitespace) {
100     this.ignoreWhitespace = ignoreWhitespace;
101   };
102   Diff.prototype = {
103       diff: function(oldString, newString) {
104         // Handle the identity case (this is due to unrolling editLength == 0
105         if (newString === oldString) {
106           return [{ value: newString }];
107         }
108         if (!newString) {
109           return [{ value: oldString, removed: true }];
110         }
111         if (!oldString) {
112           return [{ value: newString, added: true }];
113         }
115         newString = this.tokenize(newString);
116         oldString = this.tokenize(oldString);
118         var newLen = newString.length, oldLen = oldString.length;
119         var maxEditLength = newLen + oldLen;
120         var bestPath = [{ newPos: -1, components: [] }];
122         // Seed editLength = 0
123         var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
124         if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
125           return bestPath[0].components;
126         }
128         for (var editLength = 1; editLength <= maxEditLength; editLength++) {
129           for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
130             var basePath;
131             var addPath = bestPath[diagonalPath-1],
132                 removePath = bestPath[diagonalPath+1];
133             oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
134             if (addPath) {
135               // No one else is going to attempt to use this value, clear it
136               bestPath[diagonalPath-1] = undefined;
137             }
139             var canAdd = addPath && addPath.newPos+1 < newLen;
140             var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
141             if (!canAdd && !canRemove) {
142               bestPath[diagonalPath] = undefined;
143               continue;
144             }
146             // Select the diagonal that we want to branch from. We select the prior
147             // path whose position in the new string is the farthest from the origin
148             // and does not pass the bounds of the diff graph
149             if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
150               basePath = clonePath(removePath);
151               this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
152             } else {
153               basePath = clonePath(addPath);
154               basePath.newPos++;
155               this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
156             }
158             var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
160             if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
161               return basePath.components;
162             } else {
163               bestPath[diagonalPath] = basePath;
164             }
165           }
166         }
167       },
169       pushComponent: function(components, value, added, removed) {
170         var last = components[components.length-1];
171         if (last && last.added === added && last.removed === removed) {
172           // We need to clone here as the component clone operation is just
173           // as shallow array clone
174           components[components.length-1] =
175             {value: this.join(last.value, value), added: added, removed: removed };
176         } else {
177           components.push({value: value, added: added, removed: removed });
178         }
179       },
180       extractCommon: function(basePath, newString, oldString, diagonalPath) {
181         var newLen = newString.length,
182             oldLen = oldString.length,
183             newPos = basePath.newPos,
184             oldPos = newPos - diagonalPath;
185         while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
186           newPos++;
187           oldPos++;
189           this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
190         }
191         basePath.newPos = newPos;
192         return oldPos;
193       },
195       equals: function(left, right) {
196         var reWhitespace = /\S/;
197         if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
198           return true;
199         } else {
200           return left === right;
201         }
202       },
203       join: function(left, right) {
204         return left + right;
205       },
206       tokenize: function(value) {
207         return value;
208       }
209   };
211   var CharDiff = new Diff();
213   var WordDiff = new Diff(true);
214   var WordWithSpaceDiff = new Diff();
215   WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
216     return removeEmpty(value.split(/(\s+|\b)/));
217   };
219   var CssDiff = new Diff(true);
220   CssDiff.tokenize = function(value) {
221     return removeEmpty(value.split(/([{}:;,]|\s+)/));
222   };
224   var LineDiff = new Diff();
225   LineDiff.tokenize = function(value) {
226     var retLines = [],
227         lines = value.split(/^/m);
229     for(var i = 0; i < lines.length; i++) {
230       var line = lines[i],
231           lastLine = lines[i - 1];
233       // Merge lines that may contain windows new lines
234       if (line == '\n' && lastLine && lastLine[lastLine.length - 1] === '\r') {
235         retLines[retLines.length - 1] += '\n';
236       } else if (line) {
237         retLines.push(line);
238       }
239     }
241     return retLines;
242   };
244   return {
245     Diff: Diff,
247     diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
248     diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
249     diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff(oldStr, newStr); },
250     diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
252     diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
254     createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
255       var ret = [];
257       ret.push('Index: ' + fileName);
258       ret.push('===================================================================');
259       ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
260       ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
262       var diff = LineDiff.diff(oldStr, newStr);
263       if (!diff[diff.length-1].value) {
264         diff.pop();   // Remove trailing newline add
265       }
266       diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier
268       function contextLines(lines) {
269         return lines.map(function(entry) { return ' ' + entry; });
270       }
271       function eofNL(curRange, i, current) {
272         var last = diff[diff.length-2],
273             isLast = i === diff.length-2,
274             isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
276         // Figure out if this is the last line for the given file and missing NL
277         if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
278           curRange.push('\\ No newline at end of file');
279         }
280       }
282       var oldRangeStart = 0, newRangeStart = 0, curRange = [],
283           oldLine = 1, newLine = 1;
284       for (var i = 0; i < diff.length; i++) {
285         var current = diff[i],
286             lines = current.lines || current.value.replace(/\n$/, '').split('\n');
287         current.lines = lines;
289         if (current.added || current.removed) {
290           if (!oldRangeStart) {
291             var prev = diff[i-1];
292             oldRangeStart = oldLine;
293             newRangeStart = newLine;
295             if (prev) {
296               curRange = contextLines(prev.lines.slice(-4));
297               oldRangeStart -= curRange.length;
298               newRangeStart -= curRange.length;
299             }
300           }
301           curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?'+':'-') + entry; }));
302           eofNL(curRange, i, current);
304           if (current.added) {
305             newLine += lines.length;
306           } else {
307             oldLine += lines.length;
308           }
309         } else {
310           if (oldRangeStart) {
311             // Close out any changes that have been output (or join overlapping)
312             if (lines.length <= 8 && i < diff.length-2) {
313               // Overlapping
314               curRange.push.apply(curRange, contextLines(lines));
315             } else {
316               // end the range and output
317               var contextSize = Math.min(lines.length, 4);
318               ret.push(
319                   '@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)
320                   + ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)
321                   + ' @@');
322               ret.push.apply(ret, curRange);
323               ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
324               if (lines.length <= 4) {
325                 eofNL(ret, i, current);
326               }
328               oldRangeStart = 0;  newRangeStart = 0; curRange = [];
329             }
330           }
331           oldLine += lines.length;
332           newLine += lines.length;
333         }
334       }
336       return ret.join('\n') + '\n';
337     },
339     applyPatch: function(oldStr, uniDiff) {
340       var diffstr = uniDiff.split('\n');
341       var diff = [];
342       var remEOFNL = false,
343           addEOFNL = false;
345       for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {
346         if(diffstr[i][0] === '@') {
347           var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
348           diff.unshift({
349             start:meh[3],
350             oldlength:meh[2],
351             oldlines:[],
352             newlength:meh[4],
353             newlines:[]
354           });
355         } else if(diffstr[i][0] === '+') {
356           diff[0].newlines.push(diffstr[i].substr(1));
357         } else if(diffstr[i][0] === '-') {
358           diff[0].oldlines.push(diffstr[i].substr(1));
359         } else if(diffstr[i][0] === ' ') {
360           diff[0].newlines.push(diffstr[i].substr(1));
361           diff[0].oldlines.push(diffstr[i].substr(1));
362         } else if(diffstr[i][0] === '\\') {
363           if (diffstr[i-1][0] === '+') {
364             remEOFNL = true;
365           } else if(diffstr[i-1][0] === '-') {
366             addEOFNL = true;
367           }
368         }
369       }
371       var str = oldStr.split('\n');
372       for (var i = diff.length - 1; i >= 0; i--) {
373         var d = diff[i];
374         for (var j = 0; j < d.oldlength; j++) {
375           if(str[d.start-1+j] !== d.oldlines[j]) {
376             return false;
377           }
378         }
379         Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
380       }
382       if (remEOFNL) {
383         while (!str[str.length-1]) {
384           str.pop();
385         }
386       } else if (addEOFNL) {
387         str.push('');
388       }
389       return str.join('\n');
390     },
392     convertChangesToXML: function(changes){
393       var ret = [];
394       for ( var i = 0; i < changes.length; i++) {
395         var change = changes[i];
396         if (change.added) {
397           ret.push('<ins>');
398         } else if (change.removed) {
399           ret.push('<del>');
400         }
402         ret.push(escapeHTML(change.value));
404         if (change.added) {
405           ret.push('</ins>');
406         } else if (change.removed) {
407           ret.push('</del>');
408         }
409       }
410       return ret.join('');
411     },
413     // See: http://code.google.com/p/google-diff-match-patch/wiki/API
414     convertChangesToDMP: function(changes){
415       var ret = [], change;
416       for ( var i = 0; i < changes.length; i++) {
417         change = changes[i];
418         ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
419       }
420       return ret;
421     }
422   };
423 })();
425 if (typeof module !== 'undefined') {
426     module.exports = JsDiff;
429 }); // module: browser/diff.js
431 require.register("browser/escape-string-regexp.js", function(module, exports, require){
432 'use strict';
434 var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
436 module.exports = function (str) {
437   if (typeof str !== 'string') {
438     throw new TypeError('Expected a string');
439   }
441   return str.replace(matchOperatorsRe,  '\\$&');
444 }); // module: browser/escape-string-regexp.js
446 require.register("browser/events.js", function(module, exports, require){
448  * Module exports.
449  */
451 exports.EventEmitter = EventEmitter;
454  * Check if `obj` is an array.
455  */
457 function isArray(obj) {
458   return '[object Array]' == {}.toString.call(obj);
462  * Event emitter constructor.
464  * @api public
465  */
467 function EventEmitter(){};
470  * Adds a listener.
472  * @api public
473  */
475 EventEmitter.prototype.on = function (name, fn) {
476   if (!this.$events) {
477     this.$events = {};
478   }
480   if (!this.$events[name]) {
481     this.$events[name] = fn;
482   } else if (isArray(this.$events[name])) {
483     this.$events[name].push(fn);
484   } else {
485     this.$events[name] = [this.$events[name], fn];
486   }
488   return this;
491 EventEmitter.prototype.addListener = EventEmitter.prototype.on;
494  * Adds a volatile listener.
496  * @api public
497  */
499 EventEmitter.prototype.once = function (name, fn) {
500   var self = this;
502   function on () {
503     self.removeListener(name, on);
504     fn.apply(this, arguments);
505   };
507   on.listener = fn;
508   this.on(name, on);
510   return this;
514  * Removes a listener.
516  * @api public
517  */
519 EventEmitter.prototype.removeListener = function (name, fn) {
520   if (this.$events && this.$events[name]) {
521     var list = this.$events[name];
523     if (isArray(list)) {
524       var pos = -1;
526       for (var i = 0, l = list.length; i < l; i++) {
527         if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
528           pos = i;
529           break;
530         }
531       }
533       if (pos < 0) {
534         return this;
535       }
537       list.splice(pos, 1);
539       if (!list.length) {
540         delete this.$events[name];
541       }
542     } else if (list === fn || (list.listener && list.listener === fn)) {
543       delete this.$events[name];
544     }
545   }
547   return this;
551  * Removes all listeners for an event.
553  * @api public
554  */
556 EventEmitter.prototype.removeAllListeners = function (name) {
557   if (name === undefined) {
558     this.$events = {};
559     return this;
560   }
562   if (this.$events && this.$events[name]) {
563     this.$events[name] = null;
564   }
566   return this;
570  * Gets all listeners for a certain event.
572  * @api public
573  */
575 EventEmitter.prototype.listeners = function (name) {
576   if (!this.$events) {
577     this.$events = {};
578   }
580   if (!this.$events[name]) {
581     this.$events[name] = [];
582   }
584   if (!isArray(this.$events[name])) {
585     this.$events[name] = [this.$events[name]];
586   }
588   return this.$events[name];
592  * Emits an event.
594  * @api public
595  */
597 EventEmitter.prototype.emit = function (name) {
598   if (!this.$events) {
599     return false;
600   }
602   var handler = this.$events[name];
604   if (!handler) {
605     return false;
606   }
608   var args = [].slice.call(arguments, 1);
610   if ('function' == typeof handler) {
611     handler.apply(this, args);
612   } else if (isArray(handler)) {
613     var listeners = handler.slice();
615     for (var i = 0, l = listeners.length; i < l; i++) {
616       listeners[i].apply(this, args);
617     }
618   } else {
619     return false;
620   }
622   return true;
625 }); // module: browser/events.js
627 require.register("browser/fs.js", function(module, exports, require){
629 }); // module: browser/fs.js
631 require.register("browser/glob.js", function(module, exports, require){
633 }); // module: browser/glob.js
635 require.register("browser/path.js", function(module, exports, require){
637 }); // module: browser/path.js
639 require.register("browser/progress.js", function(module, exports, require){
641  * Expose `Progress`.
642  */
644 module.exports = Progress;
647  * Initialize a new `Progress` indicator.
648  */
650 function Progress() {
651   this.percent = 0;
652   this.size(0);
653   this.fontSize(11);
654   this.font('helvetica, arial, sans-serif');
658  * Set progress size to `n`.
660  * @param {Number} n
661  * @return {Progress} for chaining
662  * @api public
663  */
665 Progress.prototype.size = function(n){
666   this._size = n;
667   return this;
671  * Set text to `str`.
673  * @param {String} str
674  * @return {Progress} for chaining
675  * @api public
676  */
678 Progress.prototype.text = function(str){
679   this._text = str;
680   return this;
684  * Set font size to `n`.
686  * @param {Number} n
687  * @return {Progress} for chaining
688  * @api public
689  */
691 Progress.prototype.fontSize = function(n){
692   this._fontSize = n;
693   return this;
697  * Set font `family`.
699  * @param {String} family
700  * @return {Progress} for chaining
701  */
703 Progress.prototype.font = function(family){
704   this._font = family;
705   return this;
709  * Update percentage to `n`.
711  * @param {Number} n
712  * @return {Progress} for chaining
713  */
715 Progress.prototype.update = function(n){
716   this.percent = n;
717   return this;
721  * Draw on `ctx`.
723  * @param {CanvasRenderingContext2d} ctx
724  * @return {Progress} for chaining
725  */
727 Progress.prototype.draw = function(ctx){
728   try {
729     var percent = Math.min(this.percent, 100)
730       , size = this._size
731       , half = size / 2
732       , x = half
733       , y = half
734       , rad = half - 1
735       , fontSize = this._fontSize;
737     ctx.font = fontSize + 'px ' + this._font;
739     var angle = Math.PI * 2 * (percent / 100);
740     ctx.clearRect(0, 0, size, size);
742     // outer circle
743     ctx.strokeStyle = '#9f9f9f';
744     ctx.beginPath();
745     ctx.arc(x, y, rad, 0, angle, false);
746     ctx.stroke();
748     // inner circle
749     ctx.strokeStyle = '#eee';
750     ctx.beginPath();
751     ctx.arc(x, y, rad - 1, 0, angle, true);
752     ctx.stroke();
754     // text
755     var text = this._text || (percent | 0) + '%'
756       , w = ctx.measureText(text).width;
758     ctx.fillText(
759         text
760       , x - w / 2 + 1
761       , y + fontSize / 2 - 1);
762   } catch (ex) {} //don't fail if we can't render progress
763   return this;
766 }); // module: browser/progress.js
768 require.register("browser/tty.js", function(module, exports, require){
769 exports.isatty = function(){
770   return true;
773 exports.getWindowSize = function(){
774   if ('innerHeight' in global) {
775     return [global.innerHeight, global.innerWidth];
776   } else {
777     // In a Web Worker, the DOM Window is not available.
778     return [640, 480];
779   }
782 }); // module: browser/tty.js
784 require.register("context.js", function(module, exports, require){
786  * Expose `Context`.
787  */
789 module.exports = Context;
792  * Initialize a new `Context`.
794  * @api private
795  */
797 function Context(){}
800  * Set or get the context `Runnable` to `runnable`.
802  * @param {Runnable} runnable
803  * @return {Context}
804  * @api private
805  */
807 Context.prototype.runnable = function(runnable){
808   if (0 == arguments.length) return this._runnable;
809   this.test = this._runnable = runnable;
810   return this;
814  * Set test timeout `ms`.
816  * @param {Number} ms
817  * @return {Context} self
818  * @api private
819  */
821 Context.prototype.timeout = function(ms){
822   if (arguments.length === 0) return this.runnable().timeout();
823   this.runnable().timeout(ms);
824   return this;
828  * Set test timeout `enabled`.
830  * @param {Boolean} enabled
831  * @return {Context} self
832  * @api private
833  */
835 Context.prototype.enableTimeouts = function (enabled) {
836   this.runnable().enableTimeouts(enabled);
837   return this;
842  * Set test slowness threshold `ms`.
844  * @param {Number} ms
845  * @return {Context} self
846  * @api private
847  */
849 Context.prototype.slow = function(ms){
850   this.runnable().slow(ms);
851   return this;
855  * Mark a test as skipped.
857  * @return {Context} self
858  * @api private
859  */
861 Context.prototype.skip = function(){
862     this.runnable().skip();
863     return this;
867  * Inspect the context void of `._runnable`.
869  * @return {String}
870  * @api private
871  */
873 Context.prototype.inspect = function(){
874   return JSON.stringify(this, function(key, val){
875     if ('_runnable' == key) return;
876     if ('test' == key) return;
877     return val;
878   }, 2);
881 }); // module: context.js
883 require.register("hook.js", function(module, exports, require){
885  * Module dependencies.
886  */
888 var Runnable = require('./runnable');
891  * Expose `Hook`.
892  */
894 module.exports = Hook;
897  * Initialize a new `Hook` with the given `title` and callback `fn`.
899  * @param {String} title
900  * @param {Function} fn
901  * @api private
902  */
904 function Hook(title, fn) {
905   Runnable.call(this, title, fn);
906   this.type = 'hook';
910  * Inherit from `Runnable.prototype`.
911  */
913 function F(){};
914 F.prototype = Runnable.prototype;
915 Hook.prototype = new F;
916 Hook.prototype.constructor = Hook;
920  * Get or set the test `err`.
922  * @param {Error} err
923  * @return {Error}
924  * @api public
925  */
927 Hook.prototype.error = function(err){
928   if (0 == arguments.length) {
929     var err = this._error;
930     this._error = null;
931     return err;
932   }
934   this._error = err;
937 }); // module: hook.js
939 require.register("interfaces/bdd.js", function(module, exports, require){
941  * Module dependencies.
942  */
944 var Suite = require('../suite')
945   , Test = require('../test')
946   , utils = require('../utils')
947   , escapeRe = require('browser/escape-string-regexp');
950  * BDD-style interface:
952  *      describe('Array', function(){
953  *        describe('#indexOf()', function(){
954  *          it('should return -1 when not present', function(){
956  *          });
958  *          it('should return the index when present', function(){
960  *          });
961  *        });
962  *      });
964  */
966 module.exports = function(suite){
967   var suites = [suite];
969   suite.on('pre-require', function(context, file, mocha){
971     var common = require('./common')(suites, context);
973     context.before = common.before;
974     context.after = common.after;
975     context.beforeEach = common.beforeEach;
976     context.afterEach = common.afterEach;
977     context.run = mocha.options.delay && common.runWithSuite(suite);
978     /**
979      * Describe a "suite" with the given `title`
980      * and callback `fn` containing nested suites
981      * and/or tests.
982      */
984     context.describe = context.context = function(title, fn){
985       var suite = Suite.create(suites[0], title);
986       suite.file = file;
987       suites.unshift(suite);
988       fn.call(suite);
989       suites.shift();
990       return suite;
991     };
993     /**
994      * Pending describe.
995      */
997     context.xdescribe =
998     context.xcontext =
999     context.describe.skip = function(title, fn){
1000       var suite = Suite.create(suites[0], title);
1001       suite.pending = true;
1002       suites.unshift(suite);
1003       fn.call(suite);
1004       suites.shift();
1005     };
1007     /**
1008      * Exclusive suite.
1009      */
1011     context.describe.only = function(title, fn){
1012       var suite = context.describe(title, fn);
1013       mocha.grep(suite.fullTitle());
1014       return suite;
1015     };
1017     /**
1018      * Describe a specification or test-case
1019      * with the given `title` and callback `fn`
1020      * acting as a thunk.
1021      */
1023     context.it = context.specify = function(title, fn){
1024       var suite = suites[0];
1025       if (suite.pending) fn = null;
1026       var test = new Test(title, fn);
1027       test.file = file;
1028       suite.addTest(test);
1029       return test;
1030     };
1032     /**
1033      * Exclusive test-case.
1034      */
1036     context.it.only = function(title, fn){
1037       var test = context.it(title, fn);
1038       var reString = '^' + escapeRe(test.fullTitle()) + '$';
1039       mocha.grep(new RegExp(reString));
1040       return test;
1041     };
1043     /**
1044      * Pending test case.
1045      */
1047     context.xit =
1048     context.xspecify =
1049     context.it.skip = function(title){
1050       context.it(title);
1051     };
1053   });
1056 }); // module: interfaces/bdd.js
1058 require.register("interfaces/common.js", function(module, exports, require){
1060  * Functions common to more than one interface
1061  * @module lib/interfaces/common
1062  */
1064 'use strict';
1066 module.exports = function (suites, context) {
1068   return {
1069     /**
1070      * This is only present if flag --delay is passed into Mocha.  It triggers
1071      * root suite execution.  Returns a function which runs the root suite.
1072      */
1073     runWithSuite: function runWithSuite(suite) {
1074       return function run() {
1075         suite.run();
1076       };
1077     },
1079     /**
1080      * Execute before running tests.
1081      */
1082     before: function (name, fn) {
1083       suites[0].beforeAll(name, fn);
1084     },
1086     /**
1087      * Execute after running tests.
1088      */
1089     after: function (name, fn) {
1090       suites[0].afterAll(name, fn);
1091     },
1093     /**
1094      * Execute before each test case.
1095      */
1096     beforeEach: function (name, fn) {
1097       suites[0].beforeEach(name, fn);
1098     },
1100     /**
1101      * Execute after each test case.
1102      */
1103     afterEach: function (name, fn) {
1104       suites[0].afterEach(name, fn);
1105     },
1107     test: {
1108       /**
1109        * Pending test case.
1110        */
1111       skip: function (title) {
1112         context.test(title);
1113       }
1114     }
1115   }
1118 }); // module: interfaces/common.js
1120 require.register("interfaces/exports.js", function(module, exports, require){
1122  * Module dependencies.
1123  */
1125 var Suite = require('../suite')
1126   , Test = require('../test');
1129  * TDD-style interface:
1131  *     exports.Array = {
1132  *       '#indexOf()': {
1133  *         'should return -1 when the value is not present': function(){
1135  *         },
1137  *         'should return the correct index when the value is present': function(){
1139  *         }
1140  *       }
1141  *     };
1143  */
1145 module.exports = function(suite){
1146   var suites = [suite];
1148   suite.on('require', visit);
1150   function visit(obj, file) {
1151     var suite;
1152     for (var key in obj) {
1153       if ('function' == typeof obj[key]) {
1154         var fn = obj[key];
1155         switch (key) {
1156           case 'before':
1157             suites[0].beforeAll(fn);
1158             break;
1159           case 'after':
1160             suites[0].afterAll(fn);
1161             break;
1162           case 'beforeEach':
1163             suites[0].beforeEach(fn);
1164             break;
1165           case 'afterEach':
1166             suites[0].afterEach(fn);
1167             break;
1168           default:
1169             var test = new Test(key, fn);
1170             test.file = file;
1171             suites[0].addTest(test);
1172         }
1173       } else {
1174         suite = Suite.create(suites[0], key);
1175         suites.unshift(suite);
1176         visit(obj[key]);
1177         suites.shift();
1178       }
1179     }
1180   }
1183 }); // module: interfaces/exports.js
1185 require.register("interfaces/index.js", function(module, exports, require){
1186 exports.bdd = require('./bdd');
1187 exports.tdd = require('./tdd');
1188 exports.qunit = require('./qunit');
1189 exports.exports = require('./exports');
1191 }); // module: interfaces/index.js
1193 require.register("interfaces/qunit.js", function(module, exports, require){
1195  * Module dependencies.
1196  */
1198 var Suite = require('../suite')
1199   , Test = require('../test')
1200   , escapeRe = require('browser/escape-string-regexp')
1201   , utils = require('../utils');
1204  * QUnit-style interface:
1206  *     suite('Array');
1208  *     test('#length', function(){
1209  *       var arr = [1,2,3];
1210  *       ok(arr.length == 3);
1211  *     });
1213  *     test('#indexOf()', function(){
1214  *       var arr = [1,2,3];
1215  *       ok(arr.indexOf(1) == 0);
1216  *       ok(arr.indexOf(2) == 1);
1217  *       ok(arr.indexOf(3) == 2);
1218  *     });
1220  *     suite('String');
1222  *     test('#length', function(){
1223  *       ok('foo'.length == 3);
1224  *     });
1226  */
1228 module.exports = function(suite){
1229   var suites = [suite];
1231   suite.on('pre-require', function(context, file, mocha){
1233     var common = require('./common')(suites, context);
1235     context.before = common.before;
1236     context.after = common.after;
1237     context.beforeEach = common.beforeEach;
1238     context.afterEach = common.afterEach;
1239     context.run = mocha.options.delay && common.runWithSuite(suite);
1240     /**
1241      * Describe a "suite" with the given `title`.
1242      */
1244     context.suite = function(title){
1245       if (suites.length > 1) suites.shift();
1246       var suite = Suite.create(suites[0], title);
1247       suite.file = file;
1248       suites.unshift(suite);
1249       return suite;
1250     };
1252     /**
1253      * Exclusive test-case.
1254      */
1256     context.suite.only = function(title, fn){
1257       var suite = context.suite(title, fn);
1258       mocha.grep(suite.fullTitle());
1259     };
1261     /**
1262      * Describe a specification or test-case
1263      * with the given `title` and callback `fn`
1264      * acting as a thunk.
1265      */
1267     context.test = function(title, fn){
1268       var test = new Test(title, fn);
1269       test.file = file;
1270       suites[0].addTest(test);
1271       return test;
1272     };
1274     /**
1275      * Exclusive test-case.
1276      */
1278     context.test.only = function(title, fn){
1279       var test = context.test(title, fn);
1280       var reString = '^' + escapeRe(test.fullTitle()) + '$';
1281       mocha.grep(new RegExp(reString));
1282     };
1284     context.test.skip = common.test.skip;
1286   });
1289 }); // module: interfaces/qunit.js
1291 require.register("interfaces/tdd.js", function(module, exports, require){
1293  * Module dependencies.
1294  */
1296 var Suite = require('../suite')
1297   , Test = require('../test')
1298   , escapeRe = require('browser/escape-string-regexp')
1299   , utils = require('../utils');
1302  * TDD-style interface:
1304  *      suite('Array', function(){
1305  *        suite('#indexOf()', function(){
1306  *          suiteSetup(function(){
1308  *          });
1310  *          test('should return -1 when not present', function(){
1312  *          });
1314  *          test('should return the index when present', function(){
1316  *          });
1318  *          suiteTeardown(function(){
1320  *          });
1321  *        });
1322  *      });
1324  */
1326 module.exports = function(suite){
1327   var suites = [suite];
1329   suite.on('pre-require', function(context, file, mocha){
1331     var common = require('./common')(suites, context);
1333     context.setup = common.beforeEach;
1334     context.teardown = common.afterEach;
1335     context.suiteSetup = common.before;
1336     context.suiteTeardown = common.after;
1337     context.run = mocha.options.delay && common.runWithSuite(suite);
1338     /**
1339      * Describe a "suite" with the given `title`
1340      * and callback `fn` containing nested suites
1341      * and/or tests.
1342      */
1344     context.suite = function(title, fn){
1345       var suite = Suite.create(suites[0], title);
1346       suite.file = file;
1347       suites.unshift(suite);
1348       fn.call(suite);
1349       suites.shift();
1350       return suite;
1351     };
1353     /**
1354      * Pending suite.
1355      */
1356     context.suite.skip = function(title, fn) {
1357       var suite = Suite.create(suites[0], title);
1358       suite.pending = true;
1359       suites.unshift(suite);
1360       fn.call(suite);
1361       suites.shift();
1362     };
1364     /**
1365      * Exclusive test-case.
1366      */
1368     context.suite.only = function(title, fn){
1369       var suite = context.suite(title, fn);
1370       mocha.grep(suite.fullTitle());
1371     };
1373     /**
1374      * Describe a specification or test-case
1375      * with the given `title` and callback `fn`
1376      * acting as a thunk.
1377      */
1379     context.test = function(title, fn){
1380       var suite = suites[0];
1381       if (suite.pending) fn = null;
1382       var test = new Test(title, fn);
1383       test.file = file;
1384       suite.addTest(test);
1385       return test;
1386     };
1388     /**
1389      * Exclusive test-case.
1390      */
1392     context.test.only = function(title, fn){
1393       var test = context.test(title, fn);
1394       var reString = '^' + escapeRe(test.fullTitle()) + '$';
1395       mocha.grep(new RegExp(reString));
1396     };
1398     context.test.skip = common.test.skip;
1399   });
1402 }); // module: interfaces/tdd.js
1404 require.register("mocha.js", function(module, exports, require){
1406  * mocha
1407  * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
1408  * MIT Licensed
1409  */
1412  * Module dependencies.
1413  */
1415 var path = require('browser/path')
1416   , escapeRe = require('browser/escape-string-regexp')
1417   , utils = require('./utils');
1420  * Expose `Mocha`.
1421  */
1423 exports = module.exports = Mocha;
1426  * To require local UIs and reporters when running in node.
1427  */
1429 if (typeof process !== 'undefined' && typeof process.cwd === 'function') {
1430   var join = path.join
1431     , cwd = process.cwd();
1432   module.paths.push(cwd, join(cwd, 'node_modules'));
1436  * Expose internals.
1437  */
1439 exports.utils = utils;
1440 exports.interfaces = require('./interfaces');
1441 exports.reporters = require('./reporters');
1442 exports.Runnable = require('./runnable');
1443 exports.Context = require('./context');
1444 exports.Runner = require('./runner');
1445 exports.Suite = require('./suite');
1446 exports.Hook = require('./hook');
1447 exports.Test = require('./test');
1450  * Return image `name` path.
1452  * @param {String} name
1453  * @return {String}
1454  * @api private
1455  */
1457 function image(name) {
1458   return __dirname + '/../images/' + name + '.png';
1462  * Setup mocha with `options`.
1464  * Options:
1466  *   - `ui` name "bdd", "tdd", "exports" etc
1467  *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`
1468  *   - `globals` array of accepted globals
1469  *   - `timeout` timeout in milliseconds
1470  *   - `bail` bail on the first test failure
1471  *   - `slow` milliseconds to wait before considering a test slow
1472  *   - `ignoreLeaks` ignore global leaks
1473  *   - `fullTrace` display the full stack-trace on failing
1474  *   - `grep` string or regexp to filter tests with
1476  * @param {Object} options
1477  * @api public
1478  */
1480 function Mocha(options) {
1481   options = options || {};
1482   this.files = [];
1483   this.options = options;
1484   if (options.grep) this.grep(new RegExp(options.grep));
1485   if (options.fgrep) this.grep(options.fgrep);
1486   this.suite = new exports.Suite('', new exports.Context);
1487   this.ui(options.ui);
1488   this.bail(options.bail);
1489   this.reporter(options.reporter, options.reporterOptions);
1490   if (null != options.timeout) this.timeout(options.timeout);
1491   this.useColors(options.useColors);
1492   if (options.enableTimeouts !== null) this.enableTimeouts(options.enableTimeouts);
1493   if (options.slow) this.slow(options.slow);
1495   this.suite.on('pre-require', function (context) {
1496     exports.afterEach = context.afterEach || context.teardown;
1497     exports.after = context.after || context.suiteTeardown;
1498     exports.beforeEach = context.beforeEach || context.setup;
1499     exports.before = context.before || context.suiteSetup;
1500     exports.describe = context.describe || context.suite;
1501     exports.it = context.it || context.test;
1502     exports.setup = context.setup || context.beforeEach;
1503     exports.suiteSetup = context.suiteSetup || context.before;
1504     exports.suiteTeardown = context.suiteTeardown || context.after;
1505     exports.suite = context.suite || context.describe;
1506     exports.teardown = context.teardown || context.afterEach;
1507     exports.test = context.test || context.it;
1508     exports.run = context.run;
1509   });
1513  * Enable or disable bailing on the first failure.
1515  * @param {Boolean} [bail]
1516  * @api public
1517  */
1519 Mocha.prototype.bail = function(bail){
1520   if (0 == arguments.length) bail = true;
1521   this.suite.bail(bail);
1522   return this;
1526  * Add test `file`.
1528  * @param {String} file
1529  * @api public
1530  */
1532 Mocha.prototype.addFile = function(file){
1533   this.files.push(file);
1534   return this;
1538  * Set reporter to `reporter`, defaults to "spec".
1540  * @param {String|Function} reporter name or constructor
1541  * @param {Object} reporterOptions optional options
1542  * @api public
1543  */
1544 Mocha.prototype.reporter = function(reporter, reporterOptions){
1545   if ('function' == typeof reporter) {
1546     this._reporter = reporter;
1547   } else {
1548     reporter = reporter || 'spec';
1549     var _reporter;
1550     try { _reporter = require('./reporters/' + reporter); } catch (err) {}
1551     if (!_reporter) try { _reporter = require(reporter); } catch (err) {
1552       err.message.indexOf('Cannot find module') !== -1
1553         ? console.warn('"' + reporter + '" reporter not found')
1554         : console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack);
1555     }
1556     if (!_reporter && reporter === 'teamcity')
1557       console.warn('The Teamcity reporter was moved to a package named ' +
1558         'mocha-teamcity-reporter ' +
1559         '(https://npmjs.org/package/mocha-teamcity-reporter).');
1560     if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
1561     this._reporter = _reporter;
1562   }
1563   this.options.reporterOptions = reporterOptions;
1564   return this;
1568  * Set test UI `name`, defaults to "bdd".
1570  * @param {String} bdd
1571  * @api public
1572  */
1574 Mocha.prototype.ui = function(name){
1575   name = name || 'bdd';
1576   this._ui = exports.interfaces[name];
1577   if (!this._ui) try { this._ui = require(name); } catch (err) {}
1578   if (!this._ui) throw new Error('invalid interface "' + name + '"');
1579   this._ui = this._ui(this.suite);
1580   return this;
1584  * Load registered files.
1586  * @api private
1587  */
1589 Mocha.prototype.loadFiles = function(fn){
1590   var self = this;
1591   var suite = this.suite;
1592   var pending = this.files.length;
1593   this.files.forEach(function(file){
1594     file = path.resolve(file);
1595     suite.emit('pre-require', global, file, self);
1596     suite.emit('require', require(file), file, self);
1597     suite.emit('post-require', global, file, self);
1598     --pending || (fn && fn());
1599   });
1603  * Enable growl support.
1605  * @api private
1606  */
1608 Mocha.prototype._growl = function(runner, reporter) {
1609   var notify = require('growl');
1611   runner.on('end', function(){
1612     var stats = reporter.stats;
1613     if (stats.failures) {
1614       var msg = stats.failures + ' of ' + runner.total + ' tests failed';
1615       notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
1616     } else {
1617       notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
1618           name: 'mocha'
1619         , title: 'Passed'
1620         , image: image('ok')
1621       });
1622     }
1623   });
1627  * Add regexp to grep, if `re` is a string it is escaped.
1629  * @param {RegExp|String} re
1630  * @return {Mocha}
1631  * @api public
1632  */
1634 Mocha.prototype.grep = function(re){
1635   this.options.grep = 'string' == typeof re
1636     ? new RegExp(escapeRe(re))
1637     : re;
1638   return this;
1642  * Invert `.grep()` matches.
1644  * @return {Mocha}
1645  * @api public
1646  */
1648 Mocha.prototype.invert = function(){
1649   this.options.invert = true;
1650   return this;
1654  * Ignore global leaks.
1656  * @param {Boolean} ignore
1657  * @return {Mocha}
1658  * @api public
1659  */
1661 Mocha.prototype.ignoreLeaks = function(ignore){
1662   this.options.ignoreLeaks = !!ignore;
1663   return this;
1667  * Enable global leak checking.
1669  * @return {Mocha}
1670  * @api public
1671  */
1673 Mocha.prototype.checkLeaks = function(){
1674   this.options.ignoreLeaks = false;
1675   return this;
1679  * Display long stack-trace on failing
1681  * @return {Mocha}
1682  * @api public
1683  */
1685 Mocha.prototype.fullTrace = function() {
1686   this.options.fullStackTrace = true;
1687   return this;
1691  * Enable growl support.
1693  * @return {Mocha}
1694  * @api public
1695  */
1697 Mocha.prototype.growl = function(){
1698   this.options.growl = true;
1699   return this;
1703  * Ignore `globals` array or string.
1705  * @param {Array|String} globals
1706  * @return {Mocha}
1707  * @api public
1708  */
1710 Mocha.prototype.globals = function(globals){
1711   this.options.globals = (this.options.globals || []).concat(globals);
1712   return this;
1716  * Emit color output.
1718  * @param {Boolean} colors
1719  * @return {Mocha}
1720  * @api public
1721  */
1723 Mocha.prototype.useColors = function(colors){
1724   if (colors !== undefined) {
1725     this.options.useColors = colors;
1726   }
1727   return this;
1731  * Use inline diffs rather than +/-.
1733  * @param {Boolean} inlineDiffs
1734  * @return {Mocha}
1735  * @api public
1736  */
1738 Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
1739   this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
1740   ? inlineDiffs
1741   : false;
1742   return this;
1746  * Set the timeout in milliseconds.
1748  * @param {Number} timeout
1749  * @return {Mocha}
1750  * @api public
1751  */
1753 Mocha.prototype.timeout = function(timeout){
1754   this.suite.timeout(timeout);
1755   return this;
1759  * Set slowness threshold in milliseconds.
1761  * @param {Number} slow
1762  * @return {Mocha}
1763  * @api public
1764  */
1766 Mocha.prototype.slow = function(slow){
1767   this.suite.slow(slow);
1768   return this;
1772  * Enable timeouts.
1774  * @param {Boolean} enabled
1775  * @return {Mocha}
1776  * @api public
1777  */
1779 Mocha.prototype.enableTimeouts = function(enabled) {
1780   this.suite.enableTimeouts(arguments.length && enabled !== undefined
1781     ? enabled
1782     : true);
1783   return this
1787  * Makes all tests async (accepting a callback)
1789  * @return {Mocha}
1790  * @api public
1791  */
1793 Mocha.prototype.asyncOnly = function(){
1794   this.options.asyncOnly = true;
1795   return this;
1799  * Disable syntax highlighting (in browser).
1800  * @returns {Mocha}
1801  * @api public
1802  */
1803 Mocha.prototype.noHighlighting = function() {
1804   this.options.noHighlighting = true;
1805   return this;
1809  * Delay root suite execution.
1810  * @returns {Mocha}
1811  * @api public
1812  */
1813 Mocha.prototype.delay = function delay() {
1814   this.options.delay = true;
1815   return this;
1819  * Run tests and invoke `fn()` when complete.
1821  * @param {Function} fn
1822  * @return {Runner}
1823  * @api public
1824  */
1825 Mocha.prototype.run = function(fn){
1826   if (this.files.length) this.loadFiles();
1827   var suite = this.suite;
1828   var options = this.options;
1829   options.files = this.files;
1830   var runner = new exports.Runner(suite, options.delay);
1831   var reporter = new this._reporter(runner, options);
1832   runner.ignoreLeaks = false !== options.ignoreLeaks;
1833   runner.fullStackTrace = options.fullStackTrace;
1834   runner.asyncOnly = options.asyncOnly;
1835   if (options.grep) runner.grep(options.grep, options.invert);
1836   if (options.globals) runner.globals(options.globals);
1837   if (options.growl) this._growl(runner, reporter);
1838   if (options.useColors !== undefined) {
1839     exports.reporters.Base.useColors = options.useColors;
1840   }
1841   exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
1843   function done(failures) {
1844       if (reporter.done) {
1845           reporter.done(failures, fn);
1846       } else fn && fn(failures);
1847   }
1849   return runner.run(done);
1852 }); // module: mocha.js
1854 require.register("ms.js", function(module, exports, require){
1856  * Helpers.
1857  */
1859 var s = 1000;
1860 var m = s * 60;
1861 var h = m * 60;
1862 var d = h * 24;
1863 var y = d * 365.25;
1866  * Parse or format the given `val`.
1868  * Options:
1870  *  - `long` verbose formatting [false]
1872  * @param {String|Number} val
1873  * @param {Object} options
1874  * @return {String|Number}
1875  * @api public
1876  */
1878 module.exports = function(val, options){
1879   options = options || {};
1880   if ('string' == typeof val) return parse(val);
1881   return options['long'] ? longFormat(val) : shortFormat(val);
1885  * Parse the given `str` and return milliseconds.
1887  * @param {String} str
1888  * @return {Number}
1889  * @api private
1890  */
1892 function parse(str) {
1893   var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
1894   if (!match) return;
1895   var n = parseFloat(match[1]);
1896   var type = (match[2] || 'ms').toLowerCase();
1897   switch (type) {
1898     case 'years':
1899     case 'year':
1900     case 'y':
1901       return n * y;
1902     case 'days':
1903     case 'day':
1904     case 'd':
1905       return n * d;
1906     case 'hours':
1907     case 'hour':
1908     case 'h':
1909       return n * h;
1910     case 'minutes':
1911     case 'minute':
1912     case 'm':
1913       return n * m;
1914     case 'seconds':
1915     case 'second':
1916     case 's':
1917       return n * s;
1918     case 'ms':
1919       return n;
1920   }
1924  * Short format for `ms`.
1926  * @param {Number} ms
1927  * @return {String}
1928  * @api private
1929  */
1931 function shortFormat(ms) {
1932   if (ms >= d) return Math.round(ms / d) + 'd';
1933   if (ms >= h) return Math.round(ms / h) + 'h';
1934   if (ms >= m) return Math.round(ms / m) + 'm';
1935   if (ms >= s) return Math.round(ms / s) + 's';
1936   return ms + 'ms';
1940  * Long format for `ms`.
1942  * @param {Number} ms
1943  * @return {String}
1944  * @api private
1945  */
1947 function longFormat(ms) {
1948   return plural(ms, d, 'day')
1949     || plural(ms, h, 'hour')
1950     || plural(ms, m, 'minute')
1951     || plural(ms, s, 'second')
1952     || ms + ' ms';
1956  * Pluralization helper.
1957  */
1959 function plural(ms, n, name) {
1960   if (ms < n) return;
1961   if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
1962   return Math.ceil(ms / n) + ' ' + name + 's';
1965 }); // module: ms.js
1967 require.register("pending.js", function(module, exports, require){
1970  * Expose `Pending`.
1971  */
1973 module.exports = Pending;
1976  * Initialize a new `Pending` error with the given message.
1978  * @param {String} message
1979  */
1981 function Pending(message) {
1982     this.message = message;
1985 }); // module: pending.js
1987 require.register("reporters/base.js", function(module, exports, require){
1989  * Module dependencies.
1990  */
1992 var tty = require('browser/tty')
1993   , diff = require('browser/diff')
1994   , ms = require('../ms')
1995   , utils = require('../utils')
1996   , supportsColor = process.env ? require('supports-color') : null;
1999  * Save timer references to avoid Sinon interfering (see GH-237).
2000  */
2002 var Date = global.Date
2003   , setTimeout = global.setTimeout
2004   , setInterval = global.setInterval
2005   , clearTimeout = global.clearTimeout
2006   , clearInterval = global.clearInterval;
2009  * Check if both stdio streams are associated with a tty.
2010  */
2012 var isatty = tty.isatty(1) && tty.isatty(2);
2015  * Expose `Base`.
2016  */
2018 exports = module.exports = Base;
2021  * Enable coloring by default, except in the browser interface.
2022  */
2024 exports.useColors = process.env
2025   ? (supportsColor || (process.env.MOCHA_COLORS !== undefined))
2026   : false;
2029  * Inline diffs instead of +/-
2030  */
2032 exports.inlineDiffs = false;
2035  * Default color map.
2036  */
2038 exports.colors = {
2039     'pass': 90
2040   , 'fail': 31
2041   , 'bright pass': 92
2042   , 'bright fail': 91
2043   , 'bright yellow': 93
2044   , 'pending': 36
2045   , 'suite': 0
2046   , 'error title': 0
2047   , 'error message': 31
2048   , 'error stack': 90
2049   , 'checkmark': 32
2050   , 'fast': 90
2051   , 'medium': 33
2052   , 'slow': 31
2053   , 'green': 32
2054   , 'light': 90
2055   , 'diff gutter': 90
2056   , 'diff added': 42
2057   , 'diff removed': 41
2061  * Default symbol map.
2062  */
2064 exports.symbols = {
2065   ok: '✓',
2066   err: '✖',
2067   dot: '․'
2070 // With node.js on Windows: use symbols available in terminal default fonts
2071 if ('win32' == process.platform) {
2072   exports.symbols.ok = '\u221A';
2073   exports.symbols.err = '\u00D7';
2074   exports.symbols.dot = '.';
2078  * Color `str` with the given `type`,
2079  * allowing colors to be disabled,
2080  * as well as user-defined color
2081  * schemes.
2083  * @param {String} type
2084  * @param {String} str
2085  * @return {String}
2086  * @api private
2087  */
2089 var color = exports.color = function(type, str) {
2090   if (!exports.useColors) return String(str);
2091   return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
2095  * Expose term window size, with some
2096  * defaults for when stderr is not a tty.
2097  */
2099 exports.window = {
2100   width: isatty
2101     ? process.stdout.getWindowSize
2102       ? process.stdout.getWindowSize(1)[0]
2103       : tty.getWindowSize()[1]
2104     : 75
2108  * Expose some basic cursor interactions
2109  * that are common among reporters.
2110  */
2112 exports.cursor = {
2113   hide: function(){
2114     isatty && process.stdout.write('\u001b[?25l');
2115   },
2117   show: function(){
2118     isatty && process.stdout.write('\u001b[?25h');
2119   },
2121   deleteLine: function(){
2122     isatty && process.stdout.write('\u001b[2K');
2123   },
2125   beginningOfLine: function(){
2126     isatty && process.stdout.write('\u001b[0G');
2127   },
2129   CR: function(){
2130     if (isatty) {
2131       exports.cursor.deleteLine();
2132       exports.cursor.beginningOfLine();
2133     } else {
2134       process.stdout.write('\r');
2135     }
2136   }
2140  * Outut the given `failures` as a list.
2142  * @param {Array} failures
2143  * @api public
2144  */
2146 exports.list = function(failures){
2147   console.log();
2148   failures.forEach(function(test, i){
2149     // format
2150     var fmt = color('error title', '  %s) %s:\n')
2151       + color('error message', '     %s')
2152       + color('error stack', '\n%s\n');
2154     // msg
2155     var err = test.err
2156       , message = err.message || ''
2157       , stack = err.stack || message
2158       , index = stack.indexOf(message)
2159       , actual = err.actual
2160       , expected = err.expected
2161       , escape = true;
2162     if (index === -1) {
2163       msg = message;
2164     } else {
2165       index += message.length;
2166       msg = stack.slice(0, index);
2167       // remove msg from stack
2168       stack = stack.slice(index + 1);
2169     }
2171     // uncaught
2172     if (err.uncaught) {
2173       msg = 'Uncaught ' + msg;
2174     }
2175     // explicitly show diff
2176     if (err.showDiff !== false && sameType(actual, expected)
2177         && expected !== undefined) {
2179       if ('string' !== typeof actual) {
2180         escape = false;
2181         err.actual = actual = utils.stringify(actual);
2182         err.expected = expected = utils.stringify(expected);
2183       }
2185       fmt = color('error title', '  %s) %s:\n%s') + color('error stack', '\n%s\n');
2186       var match = message.match(/^([^:]+): expected/);
2187       msg = '\n      ' + color('error message', match ? match[1] : msg);
2189       if (exports.inlineDiffs) {
2190         msg += inlineDiff(err, escape);
2191       } else {
2192         msg += unifiedDiff(err, escape);
2193       }
2194     }
2196     // indent stack trace
2197     stack = stack.replace(/^/gm, '  ');
2199     console.log(fmt, (i + 1), test.fullTitle(), msg, stack);
2200   });
2204  * Initialize a new `Base` reporter.
2206  * All other reporters generally
2207  * inherit from this reporter, providing
2208  * stats such as test duration, number
2209  * of tests passed / failed etc.
2211  * @param {Runner} runner
2212  * @api public
2213  */
2215 function Base(runner) {
2216   var self = this
2217     , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
2218     , failures = this.failures = [];
2220   if (!runner) return;
2221   this.runner = runner;
2223   runner.stats = stats;
2225   runner.on('start', function(){
2226     stats.start = new Date;
2227   });
2229   runner.on('suite', function(suite){
2230     stats.suites = stats.suites || 0;
2231     suite.root || stats.suites++;
2232   });
2234   runner.on('test end', function(test){
2235     stats.tests = stats.tests || 0;
2236     stats.tests++;
2237   });
2239   runner.on('pass', function(test){
2240     stats.passes = stats.passes || 0;
2242     var medium = test.slow() / 2;
2243     test.speed = test.duration > test.slow()
2244       ? 'slow'
2245       : test.duration > medium
2246         ? 'medium'
2247         : 'fast';
2249     stats.passes++;
2250   });
2252   runner.on('fail', function(test, err){
2253     stats.failures = stats.failures || 0;
2254     stats.failures++;
2255     test.err = err;
2256     failures.push(test);
2257   });
2259   runner.on('end', function(){
2260     stats.end = new Date;
2261     stats.duration = new Date - stats.start;
2262   });
2264   runner.on('pending', function(){
2265     stats.pending++;
2266   });
2270  * Output common epilogue used by many of
2271  * the bundled reporters.
2273  * @api public
2274  */
2276 Base.prototype.epilogue = function(){
2277   var stats = this.stats;
2278   var tests;
2279   var fmt;
2281   console.log();
2283   // passes
2284   fmt = color('bright pass', ' ')
2285     + color('green', ' %d passing')
2286     + color('light', ' (%s)');
2288   console.log(fmt,
2289     stats.passes || 0,
2290     ms(stats.duration));
2292   // pending
2293   if (stats.pending) {
2294     fmt = color('pending', ' ')
2295       + color('pending', ' %d pending');
2297     console.log(fmt, stats.pending);
2298   }
2300   // failures
2301   if (stats.failures) {
2302     fmt = color('fail', '  %d failing');
2304     console.log(fmt, stats.failures);
2306     Base.list(this.failures);
2307     console.log();
2308   }
2310   console.log();
2314  * Pad the given `str` to `len`.
2316  * @param {String} str
2317  * @param {String} len
2318  * @return {String}
2319  * @api private
2320  */
2322 function pad(str, len) {
2323   str = String(str);
2324   return Array(len - str.length + 1).join(' ') + str;
2329  * Returns an inline diff between 2 strings with coloured ANSI output
2331  * @param {Error} Error with actual/expected
2332  * @return {String} Diff
2333  * @api private
2334  */
2336 function inlineDiff(err, escape) {
2337   var msg = errorDiff(err, 'WordsWithSpace', escape);
2339   // linenos
2340   var lines = msg.split('\n');
2341   if (lines.length > 4) {
2342     var width = String(lines.length).length;
2343     msg = lines.map(function(str, i){
2344       return pad(++i, width) + ' |' + ' ' + str;
2345     }).join('\n');
2346   }
2348   // legend
2349   msg = '\n'
2350     + color('diff removed', 'actual')
2351     + ' '
2352     + color('diff added', 'expected')
2353     + '\n\n'
2354     + msg
2355     + '\n';
2357   // indent
2358   msg = msg.replace(/^/gm, '      ');
2359   return msg;
2363  * Returns a unified diff between 2 strings
2365  * @param {Error} Error with actual/expected
2366  * @return {String} Diff
2367  * @api private
2368  */
2370 function unifiedDiff(err, escape) {
2371   var indent = '      ';
2372   function cleanUp(line) {
2373     if (escape) {
2374       line = escapeInvisibles(line);
2375     }
2376     if (line[0] === '+') return indent + colorLines('diff added', line);
2377     if (line[0] === '-') return indent + colorLines('diff removed', line);
2378     if (line.match(/\@\@/)) return null;
2379     if (line.match(/\\ No newline/)) return null;
2380     else return indent + line;
2381   }
2382   function notBlank(line) {
2383     return line != null;
2384   }
2385   var msg = diff.createPatch('string', err.actual, err.expected);
2386   var lines = msg.split('\n').splice(4);
2387   return '\n      '
2388          + colorLines('diff added',   '+ expected') + ' '
2389          + colorLines('diff removed', '- actual')
2390          + '\n\n'
2391          + lines.map(cleanUp).filter(notBlank).join('\n');
2395  * Return a character diff for `err`.
2397  * @param {Error} err
2398  * @return {String}
2399  * @api private
2400  */
2402 function errorDiff(err, type, escape) {
2403   var actual   = escape ? escapeInvisibles(err.actual)   : err.actual;
2404   var expected = escape ? escapeInvisibles(err.expected) : err.expected;
2405   return diff['diff' + type](actual, expected).map(function(str){
2406     if (str.added) return colorLines('diff added', str.value);
2407     if (str.removed) return colorLines('diff removed', str.value);
2408     return str.value;
2409   }).join('');
2413  * Returns a string with all invisible characters in plain text
2415  * @param {String} line
2416  * @return {String}
2417  * @api private
2418  */
2419 function escapeInvisibles(line) {
2420     return line.replace(/\t/g, '<tab>')
2421                .replace(/\r/g, '<CR>')
2422                .replace(/\n/g, '<LF>\n');
2426  * Color lines for `str`, using the color `name`.
2428  * @param {String} name
2429  * @param {String} str
2430  * @return {String}
2431  * @api private
2432  */
2434 function colorLines(name, str) {
2435   return str.split('\n').map(function(str){
2436     return color(name, str);
2437   }).join('\n');
2441  * Check that a / b have the same type.
2443  * @param {Object} a
2444  * @param {Object} b
2445  * @return {Boolean}
2446  * @api private
2447  */
2449 function sameType(a, b) {
2450   a = Object.prototype.toString.call(a);
2451   b = Object.prototype.toString.call(b);
2452   return a == b;
2455 }); // module: reporters/base.js
2457 require.register("reporters/doc.js", function(module, exports, require){
2459  * Module dependencies.
2460  */
2462 var Base = require('./base')
2463   , utils = require('../utils');
2466  * Expose `Doc`.
2467  */
2469 exports = module.exports = Doc;
2472  * Initialize a new `Doc` reporter.
2474  * @param {Runner} runner
2475  * @api public
2476  */
2478 function Doc(runner) {
2479   Base.call(this, runner);
2481   var self = this
2482     , stats = this.stats
2483     , total = runner.total
2484     , indents = 2;
2486   function indent() {
2487     return Array(indents).join('  ');
2488   }
2490   runner.on('suite', function(suite){
2491     if (suite.root) return;
2492     ++indents;
2493     console.log('%s<section class="suite">', indent());
2494     ++indents;
2495     console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
2496     console.log('%s<dl>', indent());
2497   });
2499   runner.on('suite end', function(suite){
2500     if (suite.root) return;
2501     console.log('%s</dl>', indent());
2502     --indents;
2503     console.log('%s</section>', indent());
2504     --indents;
2505   });
2507   runner.on('pass', function(test){
2508     console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));
2509     var code = utils.escape(utils.clean(test.fn.toString()));
2510     console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);
2511   });
2513   runner.on('fail', function(test, err){
2514     console.log('%s  <dt class="error">%s</dt>', indent(), utils.escape(test.title));
2515     var code = utils.escape(utils.clean(test.fn.toString()));
2516     console.log('%s  <dd class="error"><pre><code>%s</code></pre></dd>', indent(), code);
2517     console.log('%s  <dd class="error">%s</dd>', indent(), utils.escape(err));
2518   });
2521 }); // module: reporters/doc.js
2523 require.register("reporters/dot.js", function(module, exports, require){
2525  * Module dependencies.
2526  */
2528 var Base = require('./base')
2529   , color = Base.color;
2532  * Expose `Dot`.
2533  */
2535 exports = module.exports = Dot;
2538  * Initialize a new `Dot` matrix test reporter.
2540  * @param {Runner} runner
2541  * @api public
2542  */
2544 function Dot(runner) {
2545   Base.call(this, runner);
2547   var self = this
2548     , stats = this.stats
2549     , width = Base.window.width * .75 | 0
2550     , n = -1;
2552   runner.on('start', function(){
2553     process.stdout.write('\n');
2554   });
2556   runner.on('pending', function(test){
2557     if (++n % width == 0) process.stdout.write('\n  ');
2558     process.stdout.write(color('pending', Base.symbols.dot));
2559   });
2561   runner.on('pass', function(test){
2562     if (++n % width == 0) process.stdout.write('\n  ');
2563     if ('slow' == test.speed) {
2564       process.stdout.write(color('bright yellow', Base.symbols.dot));
2565     } else {
2566       process.stdout.write(color(test.speed, Base.symbols.dot));
2567     }
2568   });
2570   runner.on('fail', function(test, err){
2571     if (++n % width == 0) process.stdout.write('\n  ');
2572     process.stdout.write(color('fail', Base.symbols.dot));
2573   });
2575   runner.on('end', function(){
2576     console.log();
2577     self.epilogue();
2578   });
2582  * Inherit from `Base.prototype`.
2583  */
2585 function F(){};
2586 F.prototype = Base.prototype;
2587 Dot.prototype = new F;
2588 Dot.prototype.constructor = Dot;
2591 }); // module: reporters/dot.js
2593 require.register("reporters/html-cov.js", function(module, exports, require){
2595  * Module dependencies.
2596  */
2598 var JSONCov = require('./json-cov')
2599   , fs = require('browser/fs');
2602  * Expose `HTMLCov`.
2603  */
2605 exports = module.exports = HTMLCov;
2608  * Initialize a new `JsCoverage` reporter.
2610  * @param {Runner} runner
2611  * @api public
2612  */
2614 function HTMLCov(runner) {
2615   var jade = require('jade')
2616     , file = __dirname + '/templates/coverage.jade'
2617     , str = fs.readFileSync(file, 'utf8')
2618     , fn = jade.compile(str, { filename: file })
2619     , self = this;
2621   JSONCov.call(this, runner, false);
2623   runner.on('end', function(){
2624     process.stdout.write(fn({
2625         cov: self.cov
2626       , coverageClass: coverageClass
2627     }));
2628   });
2632  * Return coverage class for `n`.
2634  * @return {String}
2635  * @api private
2636  */
2638 function coverageClass(n) {
2639   if (n >= 75) return 'high';
2640   if (n >= 50) return 'medium';
2641   if (n >= 25) return 'low';
2642   return 'terrible';
2645 }); // module: reporters/html-cov.js
2647 require.register("reporters/html.js", function(module, exports, require){
2649  * Module dependencies.
2650  */
2652 var Base = require('./base')
2653   , utils = require('../utils')
2654   , Progress = require('../browser/progress')
2655   , escape = utils.escape;
2658  * Save timer references to avoid Sinon interfering (see GH-237).
2659  */
2661 var Date = global.Date
2662   , setTimeout = global.setTimeout
2663   , setInterval = global.setInterval
2664   , clearTimeout = global.clearTimeout
2665   , clearInterval = global.clearInterval;
2668  * Expose `HTML`.
2669  */
2671 exports = module.exports = HTML;
2674  * Stats template.
2675  */
2677 var statsTemplate = '<ul id="mocha-stats">'
2678   + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
2679   + '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
2680   + '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
2681   + '<li class="duration">duration: <em>0</em>s</li>'
2682   + '</ul>';
2685  * Initialize a new `HTML` reporter.
2687  * @param {Runner} runner
2688  * @api public
2689  */
2691 function HTML(runner) {
2692   Base.call(this, runner);
2694   var self = this
2695     , stats = this.stats
2696     , total = runner.total
2697     , stat = fragment(statsTemplate)
2698     , items = stat.getElementsByTagName('li')
2699     , passes = items[1].getElementsByTagName('em')[0]
2700     , passesLink = items[1].getElementsByTagName('a')[0]
2701     , failures = items[2].getElementsByTagName('em')[0]
2702     , failuresLink = items[2].getElementsByTagName('a')[0]
2703     , duration = items[3].getElementsByTagName('em')[0]
2704     , canvas = stat.getElementsByTagName('canvas')[0]
2705     , report = fragment('<ul id="mocha-report"></ul>')
2706     , stack = [report]
2707     , progress
2708     , ctx
2709     , root = document.getElementById('mocha');
2711   if (canvas.getContext) {
2712     var ratio = window.devicePixelRatio || 1;
2713     canvas.style.width = canvas.width;
2714     canvas.style.height = canvas.height;
2715     canvas.width *= ratio;
2716     canvas.height *= ratio;
2717     ctx = canvas.getContext('2d');
2718     ctx.scale(ratio, ratio);
2719     progress = new Progress;
2720   }
2722   if (!root) return error('#mocha div missing, add it to your document');
2724   // pass toggle
2725   on(passesLink, 'click', function(){
2726     unhide();
2727     var name = /pass/.test(report.className) ? '' : ' pass';
2728     report.className = report.className.replace(/fail|pass/g, '') + name;
2729     if (report.className.trim()) hideSuitesWithout('test pass');
2730   });
2732   // failure toggle
2733   on(failuresLink, 'click', function(){
2734     unhide();
2735     var name = /fail/.test(report.className) ? '' : ' fail';
2736     report.className = report.className.replace(/fail|pass/g, '') + name;
2737     if (report.className.trim()) hideSuitesWithout('test fail');
2738   });
2740   root.appendChild(stat);
2741   root.appendChild(report);
2743   if (progress) progress.size(40);
2745   runner.on('suite', function(suite){
2746     if (suite.root) return;
2748     // suite
2749     var url = self.suiteURL(suite);
2750     var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
2752     // container
2753     stack[0].appendChild(el);
2754     stack.unshift(document.createElement('ul'));
2755     el.appendChild(stack[0]);
2756   });
2758   runner.on('suite end', function(suite){
2759     if (suite.root) return;
2760     stack.shift();
2761   });
2763   runner.on('fail', function(test, err){
2764     if ('hook' == test.type) runner.emit('test end', test);
2765   });
2767   runner.on('test end', function(test){
2768     // TODO: add to stats
2769     var percent = stats.tests / this.total * 100 | 0;
2770     if (progress) progress.update(percent).draw(ctx);
2772     // update stats
2773     var ms = new Date - stats.start;
2774     text(passes, stats.passes);
2775     text(failures, stats.failures);
2776     text(duration, (ms / 1000).toFixed(2));
2778     // test
2779     if ('passed' == test.state) {
2780       var url = self.testURL(test);
2781       var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, url);
2782     } else if (test.pending) {
2783       var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
2784     } else {
2785       var el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">‣</a></h2></li>', test.title, self.testURL(test));
2786       var str = test.err.stack || test.err.toString();
2788       // FF / Opera do not add the message
2789       if (!~str.indexOf(test.err.message)) {
2790         str = test.err.message + '\n' + str;
2791       }
2793       // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
2794       // check for the result of the stringifying.
2795       if ('[object Error]' == str) str = test.err.message;
2797       // Safari doesn't give you a stack. Let's at least provide a source line.
2798       if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
2799         str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
2800       }
2802       el.appendChild(fragment('<pre class="error">%e</pre>', str));
2803     }
2805     // toggle code
2806     // TODO: defer
2807     if (!test.pending) {
2808       var h2 = el.getElementsByTagName('h2')[0];
2810       on(h2, 'click', function(){
2811         pre.style.display = 'none' == pre.style.display
2812           ? 'block'
2813           : 'none';
2814       });
2816       var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
2817       el.appendChild(pre);
2818       pre.style.display = 'none';
2819     }
2821     // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
2822     if (stack[0]) stack[0].appendChild(el);
2823   });
2827  * Makes a URL, preserving querystring ("search") parameters.
2828  * @param {string} s
2829  * @returns {string} your new URL
2830  */
2831 var makeUrl = function makeUrl(s) {
2832   var search = window.location.search;
2834   // Remove previous grep query parameter if present
2835   if (search) {
2836     search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?');
2837   }
2839   return window.location.pathname + (search ? search + '&' : '?' ) + 'grep=' + encodeURIComponent(s);
2843  * Provide suite URL
2845  * @param {Object} [suite]
2846  */
2847 HTML.prototype.suiteURL = function(suite){
2848   return makeUrl(suite.fullTitle());
2852  * Provide test URL
2854  * @param {Object} [test]
2855  */
2857 HTML.prototype.testURL = function(test){
2858   return makeUrl(test.fullTitle());
2862  * Display error `msg`.
2863  */
2865 function error(msg) {
2866   document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
2870  * Return a DOM fragment from `html`.
2871  */
2873 function fragment(html) {
2874   var args = arguments
2875     , div = document.createElement('div')
2876     , i = 1;
2878   div.innerHTML = html.replace(/%([se])/g, function(_, type){
2879     switch (type) {
2880       case 's': return String(args[i++]);
2881       case 'e': return escape(args[i++]);
2882     }
2883   });
2885   return div.firstChild;
2889  * Check for suites that do not have elements
2890  * with `classname`, and hide them.
2891  */
2893 function hideSuitesWithout(classname) {
2894   var suites = document.getElementsByClassName('suite');
2895   for (var i = 0; i < suites.length; i++) {
2896     var els = suites[i].getElementsByClassName(classname);
2897     if (0 == els.length) suites[i].className += ' hidden';
2898   }
2902  * Unhide .hidden suites.
2903  */
2905 function unhide() {
2906   var els = document.getElementsByClassName('suite hidden');
2907   for (var i = 0; i < els.length; ++i) {
2908     els[i].className = els[i].className.replace('suite hidden', 'suite');
2909   }
2913  * Set `el` text to `str`.
2914  */
2916 function text(el, str) {
2917   if (el.textContent) {
2918     el.textContent = str;
2919   } else {
2920     el.innerText = str;
2921   }
2925  * Listen on `event` with callback `fn`.
2926  */
2928 function on(el, event, fn) {
2929   if (el.addEventListener) {
2930     el.addEventListener(event, fn, false);
2931   } else {
2932     el.attachEvent('on' + event, fn);
2933   }
2936 }); // module: reporters/html.js
2938 require.register("reporters/index.js", function(module, exports, require){
2939 exports.Base = require('./base');
2940 exports.Dot = require('./dot');
2941 exports.Doc = require('./doc');
2942 exports.TAP = require('./tap');
2943 exports.JSON = require('./json');
2944 exports.HTML = require('./html');
2945 exports.List = require('./list');
2946 exports.Min = require('./min');
2947 exports.Spec = require('./spec');
2948 exports.Nyan = require('./nyan');
2949 exports.XUnit = require('./xunit');
2950 exports.Markdown = require('./markdown');
2951 exports.Progress = require('./progress');
2952 exports.Landing = require('./landing');
2953 exports.JSONCov = require('./json-cov');
2954 exports.HTMLCov = require('./html-cov');
2955 exports.JSONStream = require('./json-stream');
2957 }); // module: reporters/index.js
2959 require.register("reporters/json-cov.js", function(module, exports, require){
2961  * Module dependencies.
2962  */
2964 var Base = require('./base');
2967  * Expose `JSONCov`.
2968  */
2970 exports = module.exports = JSONCov;
2973  * Initialize a new `JsCoverage` reporter.
2975  * @param {Runner} runner
2976  * @param {Boolean} output
2977  * @api public
2978  */
2980 function JSONCov(runner, output) {
2981   var self = this
2982     , output = 1 == arguments.length ? true : output;
2984   Base.call(this, runner);
2986   var tests = []
2987     , failures = []
2988     , passes = [];
2990   runner.on('test end', function(test){
2991     tests.push(test);
2992   });
2994   runner.on('pass', function(test){
2995     passes.push(test);
2996   });
2998   runner.on('fail', function(test){
2999     failures.push(test);
3000   });
3002   runner.on('end', function(){
3003     var cov = global._$jscoverage || {};
3004     var result = self.cov = map(cov);
3005     result.stats = self.stats;
3006     result.tests = tests.map(clean);
3007     result.failures = failures.map(clean);
3008     result.passes = passes.map(clean);
3009     if (!output) return;
3010     process.stdout.write(JSON.stringify(result, null, 2 ));
3011   });
3015  * Map jscoverage data to a JSON structure
3016  * suitable for reporting.
3018  * @param {Object} cov
3019  * @return {Object}
3020  * @api private
3021  */
3023 function map(cov) {
3024   var ret = {
3025       instrumentation: 'node-jscoverage'
3026     , sloc: 0
3027     , hits: 0
3028     , misses: 0
3029     , coverage: 0
3030     , files: []
3031   };
3033   for (var filename in cov) {
3034     var data = coverage(filename, cov[filename]);
3035     ret.files.push(data);
3036     ret.hits += data.hits;
3037     ret.misses += data.misses;
3038     ret.sloc += data.sloc;
3039   }
3041   ret.files.sort(function(a, b) {
3042     return a.filename.localeCompare(b.filename);
3043   });
3045   if (ret.sloc > 0) {
3046     ret.coverage = (ret.hits / ret.sloc) * 100;
3047   }
3049   return ret;
3053  * Map jscoverage data for a single source file
3054  * to a JSON structure suitable for reporting.
3056  * @param {String} filename name of the source file
3057  * @param {Object} data jscoverage coverage data
3058  * @return {Object}
3059  * @api private
3060  */
3062 function coverage(filename, data) {
3063   var ret = {
3064     filename: filename,
3065     coverage: 0,
3066     hits: 0,
3067     misses: 0,
3068     sloc: 0,
3069     source: {}
3070   };
3072   data.source.forEach(function(line, num){
3073     num++;
3075     if (data[num] === 0) {
3076       ret.misses++;
3077       ret.sloc++;
3078     } else if (data[num] !== undefined) {
3079       ret.hits++;
3080       ret.sloc++;
3081     }
3083     ret.source[num] = {
3084         source: line
3085       , coverage: data[num] === undefined
3086         ? ''
3087         : data[num]
3088     };
3089   });
3091   ret.coverage = ret.hits / ret.sloc * 100;
3093   return ret;
3097  * Return a plain-object representation of `test`
3098  * free of cyclic properties etc.
3100  * @param {Object} test
3101  * @return {Object}
3102  * @api private
3103  */
3105 function clean(test) {
3106   return {
3107       title: test.title
3108     , fullTitle: test.fullTitle()
3109     , duration: test.duration
3110   }
3113 }); // module: reporters/json-cov.js
3115 require.register("reporters/json-stream.js", function(module, exports, require){
3117  * Module dependencies.
3118  */
3120 var Base = require('./base')
3121   , color = Base.color;
3124  * Expose `List`.
3125  */
3127 exports = module.exports = List;
3130  * Initialize a new `List` test reporter.
3132  * @param {Runner} runner
3133  * @api public
3134  */
3136 function List(runner) {
3137   Base.call(this, runner);
3139   var self = this
3140     , stats = this.stats
3141     , total = runner.total;
3143   runner.on('start', function(){
3144     console.log(JSON.stringify(['start', { total: total }]));
3145   });
3147   runner.on('pass', function(test){
3148     console.log(JSON.stringify(['pass', clean(test)]));
3149   });
3151   runner.on('fail', function(test, err){
3152     test = clean(test);
3153     test.err = err.message;
3154     console.log(JSON.stringify(['fail', test]));
3155   });
3157   runner.on('end', function(){
3158     process.stdout.write(JSON.stringify(['end', self.stats]));
3159   });
3163  * Return a plain-object representation of `test`
3164  * free of cyclic properties etc.
3166  * @param {Object} test
3167  * @return {Object}
3168  * @api private
3169  */
3171 function clean(test) {
3172   return {
3173       title: test.title
3174     , fullTitle: test.fullTitle()
3175     , duration: test.duration
3176   }
3179 }); // module: reporters/json-stream.js
3181 require.register("reporters/json.js", function(module, exports, require){
3183  * Module dependencies.
3184  */
3186 var Base = require('./base')
3187   , cursor = Base.cursor
3188   , color = Base.color;
3191  * Expose `JSON`.
3192  */
3194 exports = module.exports = JSONReporter;
3197  * Initialize a new `JSON` reporter.
3199  * @param {Runner} runner
3200  * @api public
3201  */
3203 function JSONReporter(runner) {
3204   var self = this;
3205   Base.call(this, runner);
3207   var tests = []
3208     , pending = []
3209     , failures = []
3210     , passes = [];
3212   runner.on('test end', function(test){
3213     tests.push(test);
3214   });
3216   runner.on('pass', function(test){
3217     passes.push(test);
3218   });
3220   runner.on('fail', function(test){
3221     failures.push(test);
3222   });
3224   runner.on('pending', function(test){
3225     pending.push(test);
3226   });
3228   runner.on('end', function(){
3229     var obj = {
3230       stats: self.stats,
3231       tests: tests.map(clean),
3232       pending: pending.map(clean),
3233       failures: failures.map(clean),
3234       passes: passes.map(clean)
3235     };
3237     runner.testResults = obj;
3239     process.stdout.write(JSON.stringify(obj, null, 2));
3240   });
3244  * Return a plain-object representation of `test`
3245  * free of cyclic properties etc.
3247  * @param {Object} test
3248  * @return {Object}
3249  * @api private
3250  */
3252 function clean(test) {
3253   return {
3254     title: test.title,
3255     fullTitle: test.fullTitle(),
3256     duration: test.duration,
3257     err: errorJSON(test.err || {})
3258   }
3262  * Transform `error` into a JSON object.
3263  * @param {Error} err
3264  * @return {Object}
3265  */
3267 function errorJSON(err) {
3268   var res = {};
3269   Object.getOwnPropertyNames(err).forEach(function(key) {
3270     res[key] = err[key];
3271   }, err);
3272   return res;
3275 }); // module: reporters/json.js
3277 require.register("reporters/landing.js", function(module, exports, require){
3279  * Module dependencies.
3280  */
3282 var Base = require('./base')
3283   , cursor = Base.cursor
3284   , color = Base.color;
3287  * Expose `Landing`.
3288  */
3290 exports = module.exports = Landing;
3293  * Airplane color.
3294  */
3296 Base.colors.plane = 0;
3299  * Airplane crash color.
3300  */
3302 Base.colors['plane crash'] = 31;
3305  * Runway color.
3306  */
3308 Base.colors.runway = 90;
3311  * Initialize a new `Landing` reporter.
3313  * @param {Runner} runner
3314  * @api public
3315  */
3317 function Landing(runner) {
3318   Base.call(this, runner);
3320   var self = this
3321     , stats = this.stats
3322     , width = Base.window.width * .75 | 0
3323     , total = runner.total
3324     , stream = process.stdout
3325     , plane = color('plane', '✈')
3326     , crashed = -1
3327     , n = 0;
3329   function runway() {
3330     var buf = Array(width).join('-');
3331     return '  ' + color('runway', buf);
3332   }
3334   runner.on('start', function(){
3335     stream.write('\n\n\n  ');
3336     cursor.hide();
3337   });
3339   runner.on('test end', function(test){
3340     // check if the plane crashed
3341     var col = -1 == crashed
3342       ? width * ++n / total | 0
3343       : crashed;
3345     // show the crash
3346     if ('failed' == test.state) {
3347       plane = color('plane crash', '✈');
3348       crashed = col;
3349     }
3351     // render landing strip
3352     stream.write('\u001b['+(width+1)+'D\u001b[2A');
3353     stream.write(runway());
3354     stream.write('\n  ');
3355     stream.write(color('runway', Array(col).join('â‹…')));
3356     stream.write(plane)
3357     stream.write(color('runway', Array(width - col).join('â‹…') + '\n'));
3358     stream.write(runway());
3359     stream.write('\u001b[0m');
3360   });
3362   runner.on('end', function(){
3363     cursor.show();
3364     console.log();
3365     self.epilogue();
3366   });
3370  * Inherit from `Base.prototype`.
3371  */
3373 function F(){};
3374 F.prototype = Base.prototype;
3375 Landing.prototype = new F;
3376 Landing.prototype.constructor = Landing;
3379 }); // module: reporters/landing.js
3381 require.register("reporters/list.js", function(module, exports, require){
3383  * Module dependencies.
3384  */
3386 var Base = require('./base')
3387   , cursor = Base.cursor
3388   , color = Base.color;
3391  * Expose `List`.
3392  */
3394 exports = module.exports = List;
3397  * Initialize a new `List` test reporter.
3399  * @param {Runner} runner
3400  * @api public
3401  */
3403 function List(runner) {
3404   Base.call(this, runner);
3406   var self = this
3407     , stats = this.stats
3408     , n = 0;
3410   runner.on('start', function(){
3411     console.log();
3412   });
3414   runner.on('test', function(test){
3415     process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));
3416   });
3418   runner.on('pending', function(test){
3419     var fmt = color('checkmark', '  -')
3420       + color('pending', ' %s');
3421     console.log(fmt, test.fullTitle());
3422   });
3424   runner.on('pass', function(test){
3425     var fmt = color('checkmark', '  '+Base.symbols.dot)
3426       + color('pass', ' %s: ')
3427       + color(test.speed, '%dms');
3428     cursor.CR();
3429     console.log(fmt, test.fullTitle(), test.duration);
3430   });
3432   runner.on('fail', function(test, err){
3433     cursor.CR();
3434     console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());
3435   });
3437   runner.on('end', self.epilogue.bind(self));
3441  * Inherit from `Base.prototype`.
3442  */
3444 function F(){};
3445 F.prototype = Base.prototype;
3446 List.prototype = new F;
3447 List.prototype.constructor = List;
3450 }); // module: reporters/list.js
3452 require.register("reporters/markdown.js", function(module, exports, require){
3454  * Module dependencies.
3455  */
3457 var Base = require('./base')
3458   , utils = require('../utils');
3461  * Constants
3462  */
3464 var SUITE_PREFIX = '$';
3467  * Expose `Markdown`.
3468  */
3470 exports = module.exports = Markdown;
3473  * Initialize a new `Markdown` reporter.
3475  * @param {Runner} runner
3476  * @api public
3477  */
3479 function Markdown(runner) {
3480   Base.call(this, runner);
3482   var self = this
3483     , stats = this.stats
3484     , level = 0
3485     , buf = '';
3487   function title(str) {
3488     return Array(level).join('#') + ' ' + str;
3489   }
3491   function indent() {
3492     return Array(level).join('  ');
3493   }
3495   function mapTOC(suite, obj) {
3496     var ret = obj,
3497         key = SUITE_PREFIX + suite.title;
3498     obj = obj[key] = obj[key] || { suite: suite };
3499     suite.suites.forEach(function(suite){
3500       mapTOC(suite, obj);
3501     });
3502     return ret;
3503   }
3505   function stringifyTOC(obj, level) {
3506     ++level;
3507     var buf = '';
3508     var link;
3509     for (var key in obj) {
3510       if ('suite' == key) continue;
3511       if (key !== SUITE_PREFIX) {
3512         link = ' - [' + key.substring(1) + ']';
3513         link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
3514         buf += Array(level).join('  ') + link;
3515       }
3516       buf += stringifyTOC(obj[key], level);
3517     }
3518     return buf;
3519   }
3521   function generateTOC(suite) {
3522     var obj = mapTOC(suite, {});
3523     return stringifyTOC(obj, 0);
3524   }
3526   generateTOC(runner.suite);
3528   runner.on('suite', function(suite){
3529     ++level;
3530     var slug = utils.slug(suite.fullTitle());
3531     buf += '<a name="' + slug + '"></a>' + '\n';
3532     buf += title(suite.title) + '\n';
3533   });
3535   runner.on('suite end', function(suite){
3536     --level;
3537   });
3539   runner.on('pass', function(test){
3540     var code = utils.clean(test.fn.toString());
3541     buf += test.title + '.\n';
3542     buf += '\n```js\n';
3543     buf += code + '\n';
3544     buf += '```\n\n';
3545   });
3547   runner.on('end', function(){
3548     process.stdout.write('# TOC\n');
3549     process.stdout.write(generateTOC(runner.suite));
3550     process.stdout.write(buf);
3551   });
3554 }); // module: reporters/markdown.js
3556 require.register("reporters/min.js", function(module, exports, require){
3558  * Module dependencies.
3559  */
3561 var Base = require('./base');
3564  * Expose `Min`.
3565  */
3567 exports = module.exports = Min;
3570  * Initialize a new `Min` minimal test reporter (best used with --watch).
3572  * @param {Runner} runner
3573  * @api public
3574  */
3576 function Min(runner) {
3577   Base.call(this, runner);
3579   runner.on('start', function(){
3580     // clear screen
3581     process.stdout.write('\u001b[2J');
3582     // set cursor position
3583     process.stdout.write('\u001b[1;3H');
3584   });
3586   runner.on('end', this.epilogue.bind(this));
3590  * Inherit from `Base.prototype`.
3591  */
3593 function F(){};
3594 F.prototype = Base.prototype;
3595 Min.prototype = new F;
3596 Min.prototype.constructor = Min;
3599 }); // module: reporters/min.js
3601 require.register("reporters/nyan.js", function(module, exports, require){
3603  * Module dependencies.
3604  */
3606 var Base = require('./base');
3609  * Expose `Dot`.
3610  */
3612 exports = module.exports = NyanCat;
3615  * Initialize a new `Dot` matrix test reporter.
3617  * @param {Runner} runner
3618  * @api public
3619  */
3621 function NyanCat(runner) {
3622   Base.call(this, runner);
3623   var self = this
3624     , stats = this.stats
3625     , width = Base.window.width * .75 | 0
3626     , rainbowColors = this.rainbowColors = self.generateColors()
3627     , colorIndex = this.colorIndex = 0
3628     , numerOfLines = this.numberOfLines = 4
3629     , trajectories = this.trajectories = [[], [], [], []]
3630     , nyanCatWidth = this.nyanCatWidth = 11
3631     , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
3632     , scoreboardWidth = this.scoreboardWidth = 5
3633     , tick = this.tick = 0
3634     , n = 0;
3636   runner.on('start', function(){
3637     Base.cursor.hide();
3638     self.draw();
3639   });
3641   runner.on('pending', function(test){
3642     self.draw();
3643   });
3645   runner.on('pass', function(test){
3646     self.draw();
3647   });
3649   runner.on('fail', function(test, err){
3650     self.draw();
3651   });
3653   runner.on('end', function(){
3654     Base.cursor.show();
3655     for (var i = 0; i < self.numberOfLines; i++) write('\n');
3656     self.epilogue();
3657   });
3661  * Draw the nyan cat
3663  * @api private
3664  */
3666 NyanCat.prototype.draw = function(){
3667   this.appendRainbow();
3668   this.drawScoreboard();
3669   this.drawRainbow();
3670   this.drawNyanCat();
3671   this.tick = !this.tick;
3675  * Draw the "scoreboard" showing the number
3676  * of passes, failures and pending tests.
3678  * @api private
3679  */
3681 NyanCat.prototype.drawScoreboard = function(){
3682   var stats = this.stats;
3684   function draw(type, n) {
3685     write(' ');
3686     write(Base.color(type, n));
3687     write('\n');
3688   }
3690   draw('green', stats.passes);
3691   draw('fail', stats.failures);
3692   draw('pending', stats.pending);
3693   write('\n');
3695   this.cursorUp(this.numberOfLines);
3699  * Append the rainbow.
3701  * @api private
3702  */
3704 NyanCat.prototype.appendRainbow = function(){
3705   var segment = this.tick ? '_' : '-';
3706   var rainbowified = this.rainbowify(segment);
3708   for (var index = 0; index < this.numberOfLines; index++) {
3709     var trajectory = this.trajectories[index];
3710     if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
3711     trajectory.push(rainbowified);
3712   }
3716  * Draw the rainbow.
3718  * @api private
3719  */
3721 NyanCat.prototype.drawRainbow = function(){
3722   var self = this;
3724   this.trajectories.forEach(function(line, index) {
3725     write('\u001b[' + self.scoreboardWidth + 'C');
3726     write(line.join(''));
3727     write('\n');
3728   });
3730   this.cursorUp(this.numberOfLines);
3734  * Draw the nyan cat
3736  * @api private
3737  */
3739 NyanCat.prototype.drawNyanCat = function() {
3740   var self = this;
3741   var startWidth = this.scoreboardWidth + this.trajectories[0].length;
3742   var dist = '\u001b[' + startWidth + 'C';
3743   var padding = '';
3745   write(dist);
3746   write('_,------,');
3747   write('\n');
3749   write(dist);
3750   padding = self.tick ? '  ' : '   ';
3751   write('_|' + padding + '/\\_/\\ ');
3752   write('\n');
3754   write(dist);
3755   padding = self.tick ? '_' : '__';
3756   var tail = self.tick ? '~' : '^';
3757   var face;
3758   write(tail + '|' + padding + this.face() + ' ');
3759   write('\n');
3761   write(dist);
3762   padding = self.tick ? ' ' : '  ';
3763   write(padding + '""  "" ');
3764   write('\n');
3766   this.cursorUp(this.numberOfLines);
3770  * Draw nyan cat face.
3772  * @return {String}
3773  * @api private
3774  */
3776 NyanCat.prototype.face = function() {
3777   var stats = this.stats;
3778   if (stats.failures) {
3779     return '( x .x)';
3780   } else if (stats.pending) {
3781     return '( o .o)';
3782   } else if(stats.passes) {
3783     return '( ^ .^)';
3784   } else {
3785     return '( - .-)';
3786   }
3790  * Move cursor up `n`.
3792  * @param {Number} n
3793  * @api private
3794  */
3796 NyanCat.prototype.cursorUp = function(n) {
3797   write('\u001b[' + n + 'A');
3801  * Move cursor down `n`.
3803  * @param {Number} n
3804  * @api private
3805  */
3807 NyanCat.prototype.cursorDown = function(n) {
3808   write('\u001b[' + n + 'B');
3812  * Generate rainbow colors.
3814  * @return {Array}
3815  * @api private
3816  */
3818 NyanCat.prototype.generateColors = function(){
3819   var colors = [];
3821   for (var i = 0; i < (6 * 7); i++) {
3822     var pi3 = Math.floor(Math.PI / 3);
3823     var n = (i * (1.0 / 6));
3824     var r = Math.floor(3 * Math.sin(n) + 3);
3825     var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
3826     var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
3827     colors.push(36 * r + 6 * g + b + 16);
3828   }
3830   return colors;
3834  * Apply rainbow to the given `str`.
3836  * @param {String} str
3837  * @return {String}
3838  * @api private
3839  */
3841 NyanCat.prototype.rainbowify = function(str){
3842   if (!Base.useColors)
3843     return str;
3844   var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
3845   this.colorIndex += 1;
3846   return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
3850  * Stdout helper.
3851  */
3853 function write(string) {
3854   process.stdout.write(string);
3858  * Inherit from `Base.prototype`.
3859  */
3861 function F(){};
3862 F.prototype = Base.prototype;
3863 NyanCat.prototype = new F;
3864 NyanCat.prototype.constructor = NyanCat;
3867 }); // module: reporters/nyan.js
3869 require.register("reporters/progress.js", function(module, exports, require){
3871  * Module dependencies.
3872  */
3874 var Base = require('./base')
3875   , cursor = Base.cursor
3876   , color = Base.color;
3879  * Expose `Progress`.
3880  */
3882 exports = module.exports = Progress;
3885  * General progress bar color.
3886  */
3888 Base.colors.progress = 90;
3891  * Initialize a new `Progress` bar test reporter.
3893  * @param {Runner} runner
3894  * @param {Object} options
3895  * @api public
3896  */
3898 function Progress(runner, options) {
3899   Base.call(this, runner);
3901   var self = this
3902     , options = options || {}
3903     , stats = this.stats
3904     , width = Base.window.width * .50 | 0
3905     , total = runner.total
3906     , complete = 0
3907     , max = Math.max
3908     , lastN = -1;
3910   // default chars
3911   options.open = options.open || '[';
3912   options.complete = options.complete || 'â–¬';
3913   options.incomplete = options.incomplete || Base.symbols.dot;
3914   options.close = options.close || ']';
3915   options.verbose = false;
3917   // tests started
3918   runner.on('start', function(){
3919     console.log();
3920     cursor.hide();
3921   });
3923   // tests complete
3924   runner.on('test end', function(){
3925     complete++;
3926     var incomplete = total - complete
3927       , percent = complete / total
3928       , n = width * percent | 0
3929       , i = width - n;
3931     if (lastN === n && !options.verbose) {
3932       // Don't re-render the line if it hasn't changed
3933       return;
3934     }
3935     lastN = n;
3937     cursor.CR();
3938     process.stdout.write('\u001b[J');
3939     process.stdout.write(color('progress', '  ' + options.open));
3940     process.stdout.write(Array(n).join(options.complete));
3941     process.stdout.write(Array(i).join(options.incomplete));
3942     process.stdout.write(color('progress', options.close));
3943     if (options.verbose) {
3944       process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
3945     }
3946   });
3948   // tests are complete, output some stats
3949   // and the failures if any
3950   runner.on('end', function(){
3951     cursor.show();
3952     console.log();
3953     self.epilogue();
3954   });
3958  * Inherit from `Base.prototype`.
3959  */
3961 function F(){};
3962 F.prototype = Base.prototype;
3963 Progress.prototype = new F;
3964 Progress.prototype.constructor = Progress;
3967 }); // module: reporters/progress.js
3969 require.register("reporters/spec.js", function(module, exports, require){
3971  * Module dependencies.
3972  */
3974 var Base = require('./base')
3975   , cursor = Base.cursor
3976   , color = Base.color;
3979  * Expose `Spec`.
3980  */
3982 exports = module.exports = Spec;
3985  * Initialize a new `Spec` test reporter.
3987  * @param {Runner} runner
3988  * @api public
3989  */
3991 function Spec(runner) {
3992   Base.call(this, runner);
3994   var self = this
3995     , stats = this.stats
3996     , indents = 0
3997     , n = 0;
3999   function indent() {
4000     return Array(indents).join('  ')
4001   }
4003   runner.on('start', function(){
4004     console.log();
4005   });
4007   runner.on('suite', function(suite){
4008     ++indents;
4009     console.log(color('suite', '%s%s'), indent(), suite.title);
4010   });
4012   runner.on('suite end', function(suite){
4013     --indents;
4014     if (1 == indents) console.log();
4015   });
4017   runner.on('pending', function(test){
4018     var fmt = indent() + color('pending', '  - %s');
4019     console.log(fmt, test.title);
4020   });
4022   runner.on('pass', function(test){
4023     if ('fast' == test.speed) {
4024       var fmt = indent()
4025         + color('checkmark', '  ' + Base.symbols.ok)
4026         + color('pass', ' %s');
4027       cursor.CR();
4028       console.log(fmt, test.title);
4029     } else {
4030       var fmt = indent()
4031         + color('checkmark', '  ' + Base.symbols.ok)
4032         + color('pass', ' %s')
4033         + color(test.speed, ' (%dms)');
4034       cursor.CR();
4035       console.log(fmt, test.title, test.duration);
4036     }
4037   });
4039   runner.on('fail', function(test, err){
4040     cursor.CR();
4041     console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);
4042   });
4044   runner.on('end', self.epilogue.bind(self));
4048  * Inherit from `Base.prototype`.
4049  */
4051 function F(){};
4052 F.prototype = Base.prototype;
4053 Spec.prototype = new F;
4054 Spec.prototype.constructor = Spec;
4057 }); // module: reporters/spec.js
4059 require.register("reporters/tap.js", function(module, exports, require){
4061  * Module dependencies.
4062  */
4064 var Base = require('./base')
4065   , cursor = Base.cursor
4066   , color = Base.color;
4069  * Expose `TAP`.
4070  */
4072 exports = module.exports = TAP;
4075  * Initialize a new `TAP` reporter.
4077  * @param {Runner} runner
4078  * @api public
4079  */
4081 function TAP(runner) {
4082   Base.call(this, runner);
4084   var self = this
4085     , stats = this.stats
4086     , n = 1
4087     , passes = 0
4088     , failures = 0;
4090   runner.on('start', function(){
4091     var total = runner.grepTotal(runner.suite);
4092     console.log('%d..%d', 1, total);
4093   });
4095   runner.on('test end', function(){
4096     ++n;
4097   });
4099   runner.on('pending', function(test){
4100     console.log('ok %d %s # SKIP -', n, title(test));
4101   });
4103   runner.on('pass', function(test){
4104     passes++;
4105     console.log('ok %d %s', n, title(test));
4106   });
4108   runner.on('fail', function(test, err){
4109     failures++;
4110     console.log('not ok %d %s', n, title(test));
4111     if (err.stack) console.log(err.stack.replace(/^/gm, '  '));
4112   });
4114   runner.on('end', function(){
4115     console.log('# tests ' + (passes + failures));
4116     console.log('# pass ' + passes);
4117     console.log('# fail ' + failures);
4118   });
4122  * Return a TAP-safe title of `test`
4124  * @param {Object} test
4125  * @return {String}
4126  * @api private
4127  */
4129 function title(test) {
4130   return test.fullTitle().replace(/#/g, '');
4133 }); // module: reporters/tap.js
4135 require.register("reporters/xunit.js", function(module, exports, require){
4137  * Module dependencies.
4138  */
4140 var Base = require('./base')
4141   , utils = require('../utils')
4142   , fs = require('browser/fs')
4143   , escape = utils.escape;
4146  * Save timer references to avoid Sinon interfering (see GH-237).
4147  */
4149 var Date = global.Date
4150   , setTimeout = global.setTimeout
4151   , setInterval = global.setInterval
4152   , clearTimeout = global.clearTimeout
4153   , clearInterval = global.clearInterval;
4156  * Expose `XUnit`.
4157  */
4159 exports = module.exports = XUnit;
4162  * Initialize a new `XUnit` reporter.
4164  * @param {Runner} runner
4165  * @api public
4166  */
4168 function XUnit(runner, options) {
4169   Base.call(this, runner);
4170   var stats = this.stats
4171     , tests = []
4172     , self = this;
4174   if (options.reporterOptions && options.reporterOptions.output) {
4175       if (! fs.createWriteStream) {
4176           throw new Error('file output not supported in browser');
4177       }
4178       self.fileStream = fs.createWriteStream(options.reporterOptions.output);
4179   }
4181   runner.on('pending', function(test){
4182     tests.push(test);
4183   });
4185   runner.on('pass', function(test){
4186     tests.push(test);
4187   });
4189   runner.on('fail', function(test){
4190     tests.push(test);
4191   });
4193   runner.on('end', function(){
4194     self.write(tag('testsuite', {
4195         name: 'Mocha Tests'
4196       , tests: stats.tests
4197       , failures: stats.failures
4198       , errors: stats.failures
4199       , skipped: stats.tests - stats.failures - stats.passes
4200       , timestamp: (new Date).toUTCString()
4201       , time: (stats.duration / 1000) || 0
4202     }, false));
4204     tests.forEach(function(t) { self.test(t); });
4205     self.write('</testsuite>');
4206   });
4210  * Override done to close the stream (if it's a file).
4211  */
4212 XUnit.prototype.done = function(failures, fn) {
4213     if (this.fileStream) {
4214         this.fileStream.end(function() {
4215             fn(failures);
4216         });
4217     } else {
4218         fn(failures);
4219     }
4223  * Inherit from `Base.prototype`.
4224  */
4226 function F(){};
4227 F.prototype = Base.prototype;
4228 XUnit.prototype = new F;
4229 XUnit.prototype.constructor = XUnit;
4233  * Write out the given line
4234  */
4235 XUnit.prototype.write = function(line) {
4236     if (this.fileStream) {
4237         this.fileStream.write(line + '\n');
4238     } else {
4239         console.log(line);
4240     }
4244  * Output tag for the given `test.`
4245  */
4247 XUnit.prototype.test = function(test, ostream) {
4248   var attrs = {
4249       classname: test.parent.fullTitle()
4250     , name: test.title
4251     , time: (test.duration / 1000) || 0
4252   };
4254   if ('failed' == test.state) {
4255     var err = test.err;
4256     this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + "\n" + err.stack))));
4257   } else if (test.pending) {
4258     this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
4259   } else {
4260     this.write(tag('testcase', attrs, true) );
4261   }
4265  * HTML tag helper.
4266  */
4268 function tag(name, attrs, close, content) {
4269   var end = close ? '/>' : '>'
4270     , pairs = []
4271     , tag;
4273   for (var key in attrs) {
4274     pairs.push(key + '="' + escape(attrs[key]) + '"');
4275   }
4277   tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
4278   if (content) tag += content + '</' + name + end;
4279   return tag;
4283  * Return cdata escaped CDATA `str`.
4284  */
4286 function cdata(str) {
4287   return '<![CDATA[' + escape(str) + ']]>';
4290 }); // module: reporters/xunit.js
4292 require.register("runnable.js", function(module, exports, require){
4294  * Module dependencies.
4295  */
4297 var EventEmitter = require('browser/events').EventEmitter
4298   , debug = require('browser/debug')('mocha:runnable')
4299   , Pending = require('./pending')
4300   , milliseconds = require('./ms')
4301   , utils = require('./utils');
4304  * Save timer references to avoid Sinon interfering (see GH-237).
4305  */
4307 var Date = global.Date
4308   , setTimeout = global.setTimeout
4309   , setInterval = global.setInterval
4310   , clearTimeout = global.clearTimeout
4311   , clearInterval = global.clearInterval;
4314  * Object#toString().
4315  */
4317 var toString = Object.prototype.toString;
4320  * Expose `Runnable`.
4321  */
4323 module.exports = Runnable;
4326  * Initialize a new `Runnable` with the given `title` and callback `fn`.
4328  * @param {String} title
4329  * @param {Function} fn
4330  * @api private
4331  */
4333 function Runnable(title, fn) {
4334   this.title = title;
4335   this.fn = fn;
4336   this.async = fn && fn.length;
4337   this.sync = ! this.async;
4338   this._timeout = 2000;
4339   this._slow = 75;
4340   this._enableTimeouts = true;
4341   this.timedOut = false;
4342   this._trace = new Error('done() called multiple times')
4346  * Inherit from `EventEmitter.prototype`.
4347  */
4349 function F(){};
4350 F.prototype = EventEmitter.prototype;
4351 Runnable.prototype = new F;
4352 Runnable.prototype.constructor = Runnable;
4356  * Set & get timeout `ms`.
4358  * @param {Number|String} ms
4359  * @return {Runnable|Number} ms or self
4360  * @api private
4361  */
4363 Runnable.prototype.timeout = function(ms){
4364   if (0 == arguments.length) return this._timeout;
4365   if (ms === 0) this._enableTimeouts = false;
4366   if ('string' == typeof ms) ms = milliseconds(ms);
4367   debug('timeout %d', ms);
4368   this._timeout = ms;
4369   if (this.timer) this.resetTimeout();
4370   return this;
4374  * Set & get slow `ms`.
4376  * @param {Number|String} ms
4377  * @return {Runnable|Number} ms or self
4378  * @api private
4379  */
4381 Runnable.prototype.slow = function(ms){
4382   if (0 === arguments.length) return this._slow;
4383   if ('string' == typeof ms) ms = milliseconds(ms);
4384   debug('timeout %d', ms);
4385   this._slow = ms;
4386   return this;
4390  * Set and & get timeout `enabled`.
4392  * @param {Boolean} enabled
4393  * @return {Runnable|Boolean} enabled or self
4394  * @api private
4395  */
4397 Runnable.prototype.enableTimeouts = function(enabled){
4398   if (arguments.length === 0) return this._enableTimeouts;
4399   debug('enableTimeouts %s', enabled);
4400   this._enableTimeouts = enabled;
4401   return this;
4405  * Halt and mark as pending.
4407  * @api private
4408  */
4410 Runnable.prototype.skip = function(){
4411     throw new Pending();
4415  * Return the full title generated by recursively
4416  * concatenating the parent's full title.
4418  * @return {String}
4419  * @api public
4420  */
4422 Runnable.prototype.fullTitle = function(){
4423   return this.parent.fullTitle() + ' ' + this.title;
4427  * Clear the timeout.
4429  * @api private
4430  */
4432 Runnable.prototype.clearTimeout = function(){
4433   clearTimeout(this.timer);
4437  * Inspect the runnable void of private properties.
4439  * @return {String}
4440  * @api private
4441  */
4443 Runnable.prototype.inspect = function(){
4444   return JSON.stringify(this, function(key, val){
4445     if ('_' == key[0]) return;
4446     if ('parent' == key) return '#<Suite>';
4447     if ('ctx' == key) return '#<Context>';
4448     return val;
4449   }, 2);
4453  * Reset the timeout.
4455  * @api private
4456  */
4458 Runnable.prototype.resetTimeout = function(){
4459   var self = this;
4460   var ms = this.timeout() || 1e9;
4462   if (!this._enableTimeouts) return;
4463   this.clearTimeout();
4464   this.timer = setTimeout(function(){
4465     if (!self._enableTimeouts) return;
4466     self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));
4467     self.timedOut = true;
4468   }, ms);
4472  * Whitelist these globals for this test run
4474  * @api private
4475  */
4476 Runnable.prototype.globals = function(arr){
4477   var self = this;
4478   this._allowedGlobals = arr;
4482  * Run the test and invoke `fn(err)`.
4484  * @param {Function} fn
4485  * @api private
4486  */
4488 Runnable.prototype.run = function(fn){
4489   var self = this
4490     , start = new Date
4491     , ctx = this.ctx
4492     , finished
4493     , emitted;
4495   // Some times the ctx exists but it is not runnable
4496   if (ctx && ctx.runnable) ctx.runnable(this);
4498   // called multiple times
4499   function multiple(err) {
4500     if (emitted) return;
4501     emitted = true;
4502     self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));
4503   }
4505   // finished
4506   function done(err) {
4507     var ms = self.timeout();
4508     if (self.timedOut) return;
4509     if (finished) return multiple(err || self._trace);
4511     // Discard the resolution if this test has already failed asynchronously
4512     if (self.state) return;
4514     self.clearTimeout();
4515     self.duration = new Date - start;
4516     finished = true;
4517     if (!err && self.duration > ms && self._enableTimeouts) err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');
4518     fn(err);
4519   }
4521   // for .resetTimeout()
4522   this.callback = done;
4524   // explicit async with `done` argument
4525   if (this.async) {
4526     this.resetTimeout();
4528     try {
4529       this.fn.call(ctx, function(err){
4530         if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
4531         if (null != err) {
4532           if (Object.prototype.toString.call(err) === '[object Object]') {
4533             return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
4534           } else {
4535             return done(new Error('done() invoked with non-Error: ' + err));
4536           }
4537         }
4538         done();
4539       });
4540     } catch (err) {
4541       done(utils.getError(err));
4542     }
4543     return;
4544   }
4546   if (this.asyncOnly) {
4547     return done(new Error('--async-only option in use without declaring `done()`'));
4548   }
4550   // sync or promise-returning
4551   try {
4552     if (this.pending) {
4553       done();
4554     } else {
4555       callFn(this.fn);
4556     }
4557   } catch (err) {
4558     done(utils.getError(err));
4559   }
4561   function callFn(fn) {
4562     var result = fn.call(ctx);
4563     if (result && typeof result.then === 'function') {
4564       self.resetTimeout();
4565       result
4566         .then(function() {
4567           done()
4568         },
4569         function(reason) {
4570           done(reason || new Error('Promise rejected with no or falsy reason'))
4571         });
4572     } else {
4573       done();
4574     }
4575   }
4578 }); // module: runnable.js
4580 require.register("runner.js", function(module, exports, require){
4582  * Module dependencies.
4583  */
4585 var EventEmitter = require('browser/events').EventEmitter
4586   , debug = require('browser/debug')('mocha:runner')
4587   , Pending = require('./pending')
4588   , Test = require('./test')
4589   , utils = require('./utils')
4590   , filter = utils.filter
4591   , keys = utils.keys
4592   , type = utils.type
4593   , stringify = utils.stringify
4594   , stackFilter = utils.stackTraceFilter();
4597  * Non-enumerable globals.
4598  */
4600 var globals = [
4601   'setTimeout',
4602   'clearTimeout',
4603   'setInterval',
4604   'clearInterval',
4605   'XMLHttpRequest',
4606   'Date',
4607   'setImmediate',
4608   'clearImmediate'
4612  * Expose `Runner`.
4613  */
4615 module.exports = Runner;
4618  * Initialize a `Runner` for the given `suite`.
4620  * Events:
4622  *   - `start`  execution started
4623  *   - `end`  execution complete
4624  *   - `suite`  (suite) test suite execution started
4625  *   - `suite end`  (suite) all tests (and sub-suites) have finished
4626  *   - `test`  (test) test execution started
4627  *   - `test end`  (test) test completed
4628  *   - `hook`  (hook) hook execution started
4629  *   - `hook end`  (hook) hook complete
4630  *   - `pass`  (test) test passed
4631  *   - `fail`  (test, err) test failed
4632  *   - `pending`  (test) test pending
4634  * @param {Suite} suite Root suite
4635  * @param {boolean} [delay] Whether or not to delay execution of root suite
4636  *   until ready.
4637  * @api public
4638  */
4640 function Runner(suite, delay) {
4641   var self = this;
4642   this._globals = [];
4643   this._abort = false;
4644   this._delay = delay;
4645   this.suite = suite;
4646   this.total = suite.total();
4647   this.failures = 0;
4648   this.on('test end', function(test){ self.checkGlobals(test); });
4649   this.on('hook end', function(hook){ self.checkGlobals(hook); });
4650   this.grep(/.*/);
4651   this.globals(this.globalProps().concat(extraGlobals()));
4655  * Wrapper for setImmediate, process.nextTick, or browser polyfill.
4657  * @param {Function} fn
4658  * @api private
4659  */
4661 Runner.immediately = global.setImmediate || process.nextTick;
4664  * Inherit from `EventEmitter.prototype`.
4665  */
4667 function F(){};
4668 F.prototype = EventEmitter.prototype;
4669 Runner.prototype = new F;
4670 Runner.prototype.constructor = Runner;
4674  * Run tests with full titles matching `re`. Updates runner.total
4675  * with number of tests matched.
4677  * @param {RegExp} re
4678  * @param {Boolean} invert
4679  * @return {Runner} for chaining
4680  * @api public
4681  */
4683 Runner.prototype.grep = function(re, invert){
4684   debug('grep %s', re);
4685   this._grep = re;
4686   this._invert = invert;
4687   this.total = this.grepTotal(this.suite);
4688   return this;
4692  * Returns the number of tests matching the grep search for the
4693  * given suite.
4695  * @param {Suite} suite
4696  * @return {Number}
4697  * @api public
4698  */
4700 Runner.prototype.grepTotal = function(suite) {
4701   var self = this;
4702   var total = 0;
4704   suite.eachTest(function(test){
4705     var match = self._grep.test(test.fullTitle());
4706     if (self._invert) match = !match;
4707     if (match) total++;
4708   });
4710   return total;
4714  * Return a list of global properties.
4716  * @return {Array}
4717  * @api private
4718  */
4720 Runner.prototype.globalProps = function() {
4721   var props = utils.keys(global);
4723   // non-enumerables
4724   for (var i = 0; i < globals.length; ++i) {
4725     if (~utils.indexOf(props, globals[i])) continue;
4726     props.push(globals[i]);
4727   }
4729   return props;
4733  * Allow the given `arr` of globals.
4735  * @param {Array} arr
4736  * @return {Runner} for chaining
4737  * @api public
4738  */
4740 Runner.prototype.globals = function(arr){
4741   if (0 == arguments.length) return this._globals;
4742   debug('globals %j', arr);
4743   this._globals = this._globals.concat(arr);
4744   return this;
4748  * Check for global variable leaks.
4750  * @api private
4751  */
4753 Runner.prototype.checkGlobals = function(test){
4754   if (this.ignoreLeaks) return;
4755   var ok = this._globals;
4757   var globals = this.globalProps();
4758   var leaks;
4760   if (test) {
4761     ok = ok.concat(test._allowedGlobals || []);
4762   }
4764   if(this.prevGlobalsLength == globals.length) return;
4765   this.prevGlobalsLength = globals.length;
4767   leaks = filterLeaks(ok, globals);
4768   this._globals = this._globals.concat(leaks);
4770   if (leaks.length > 1) {
4771     this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
4772   } else if (leaks.length) {
4773     this.fail(test, new Error('global leak detected: ' + leaks[0]));
4774   }
4778  * Fail the given `test`.
4780  * @param {Test} test
4781  * @param {Error} err
4782  * @api private
4783  */
4785 Runner.prototype.fail = function(test, err) {
4786   ++this.failures;
4787   test.state = 'failed';
4789   if (!(err instanceof Error)) {
4790     err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');
4791   }
4793   err.stack = (this.fullStackTrace || !err.stack)
4794     ? err.stack
4795     : stackFilter(err.stack);
4797   this.emit('fail', test, err);
4801  * Fail the given `hook` with `err`.
4803  * Hook failures work in the following pattern:
4804  * - If bail, then exit
4805  * - Failed `before` hook skips all tests in a suite and subsuites,
4806  *   but jumps to corresponding `after` hook
4807  * - Failed `before each` hook skips remaining tests in a
4808  *   suite and jumps to corresponding `after each` hook,
4809  *   which is run only once
4810  * - Failed `after` hook does not alter
4811  *   execution order
4812  * - Failed `after each` hook skips remaining tests in a
4813  *   suite and subsuites, but executes other `after each`
4814  *   hooks
4816  * @param {Hook} hook
4817  * @param {Error} err
4818  * @api private
4819  */
4821 Runner.prototype.failHook = function(hook, err){
4822   this.fail(hook, err);
4823   if (this.suite.bail()) {
4824     this.emit('end');
4825   }
4829  * Run hook `name` callbacks and then invoke `fn()`.
4831  * @param {String} name
4832  * @param {Function} function
4833  * @api private
4834  */
4836 Runner.prototype.hook = function(name, fn){
4837   var suite = this.suite
4838     , hooks = suite['_' + name]
4839     , self = this
4840     , timer;
4842   function next(i) {
4843     var hook = hooks[i];
4844     if (!hook) return fn();
4845     self.currentRunnable = hook;
4847     hook.ctx.currentTest = self.test;
4849     self.emit('hook', hook);
4851     hook.on('error', function(err){
4852       self.failHook(hook, err);
4853     });
4855     hook.run(function(err){
4856       hook.removeAllListeners('error');
4857       var testError = hook.error();
4858       if (testError) self.fail(self.test, testError);
4859       if (err) {
4860         if (err instanceof Pending) {
4861           suite.pending = true;
4862         } else {
4863           self.failHook(hook, err);
4865           // stop executing hooks, notify callee of hook err
4866           return fn(err);
4867         }
4868       }
4869       self.emit('hook end', hook);
4870       delete hook.ctx.currentTest;
4871       next(++i);
4872     });
4873   }
4875   Runner.immediately(function(){
4876     next(0);
4877   });
4881  * Run hook `name` for the given array of `suites`
4882  * in order, and callback `fn(err, errSuite)`.
4884  * @param {String} name
4885  * @param {Array} suites
4886  * @param {Function} fn
4887  * @api private
4888  */
4890 Runner.prototype.hooks = function(name, suites, fn){
4891   var self = this
4892     , orig = this.suite;
4894   function next(suite) {
4895     self.suite = suite;
4897     if (!suite) {
4898       self.suite = orig;
4899       return fn();
4900     }
4902     self.hook(name, function(err){
4903       if (err) {
4904         var errSuite = self.suite;
4905         self.suite = orig;
4906         return fn(err, errSuite);
4907       }
4909       next(suites.pop());
4910     });
4911   }
4913   next(suites.pop());
4917  * Run hooks from the top level down.
4919  * @param {String} name
4920  * @param {Function} fn
4921  * @api private
4922  */
4924 Runner.prototype.hookUp = function(name, fn){
4925   var suites = [this.suite].concat(this.parents()).reverse();
4926   this.hooks(name, suites, fn);
4930  * Run hooks from the bottom up.
4932  * @param {String} name
4933  * @param {Function} fn
4934  * @api private
4935  */
4937 Runner.prototype.hookDown = function(name, fn){
4938   var suites = [this.suite].concat(this.parents());
4939   this.hooks(name, suites, fn);
4943  * Return an array of parent Suites from
4944  * closest to furthest.
4946  * @return {Array}
4947  * @api private
4948  */
4950 Runner.prototype.parents = function(){
4951   var suite = this.suite
4952     , suites = [];
4953   while (suite = suite.parent) suites.push(suite);
4954   return suites;
4958  * Run the current test and callback `fn(err)`.
4960  * @param {Function} fn
4961  * @api private
4962  */
4964 Runner.prototype.runTest = function(fn){
4965   var test = this.test
4966     , self = this;
4968   if (this.asyncOnly) test.asyncOnly = true;
4970   try {
4971     test.on('error', function(err){
4972       self.fail(test, err);
4973     });
4974     test.run(fn);
4975   } catch (err) {
4976     fn(err);
4977   }
4981  * Run tests in the given `suite` and invoke
4982  * the callback `fn()` when complete.
4984  * @param {Suite} suite
4985  * @param {Function} fn
4986  * @api private
4987  */
4989 Runner.prototype.runTests = function(suite, fn){
4990   var self = this
4991     , tests = suite.tests.slice()
4992     , test;
4995   function hookErr(err, errSuite, after) {
4996     // before/after Each hook for errSuite failed:
4997     var orig = self.suite;
4999     // for failed 'after each' hook start from errSuite parent,
5000     // otherwise start from errSuite itself
5001     self.suite = after ? errSuite.parent : errSuite;
5003     if (self.suite) {
5004       // call hookUp afterEach
5005       self.hookUp('afterEach', function(err2, errSuite2) {
5006         self.suite = orig;
5007         // some hooks may fail even now
5008         if (err2) return hookErr(err2, errSuite2, true);
5009         // report error suite
5010         fn(errSuite);
5011       });
5012     } else {
5013       // there is no need calling other 'after each' hooks
5014       self.suite = orig;
5015       fn(errSuite);
5016     }
5017   }
5019   function next(err, errSuite) {
5020     // if we bail after first err
5021     if (self.failures && suite._bail) return fn();
5023     if (self._abort) return fn();
5025     if (err) return hookErr(err, errSuite, true);
5027     // next test
5028     test = tests.shift();
5030     // all done
5031     if (!test) return fn();
5033     // grep
5034     var match = self._grep.test(test.fullTitle());
5035     if (self._invert) match = !match;
5036     if (!match) return next();
5038     // pending
5039     if (test.pending) {
5040       self.emit('pending', test);
5041       self.emit('test end', test);
5042       return next();
5043     }
5045     // execute test and hook(s)
5046     self.emit('test', self.test = test);
5047     self.hookDown('beforeEach', function(err, errSuite){
5049       if (suite.pending) {
5050         self.emit('pending', test);
5051         self.emit('test end', test);
5052         return next();
5053       }
5054       if (err) return hookErr(err, errSuite, false);
5056       self.currentRunnable = self.test;
5057       self.runTest(function(err){
5058         test = self.test;
5060         if (err) {
5061           if (err instanceof Pending) {
5062             self.emit('pending', test);
5063           } else {
5064             self.fail(test, err);
5065           }
5066           self.emit('test end', test);
5068           if (err instanceof Pending) {
5069             return next();
5070           }
5072           return self.hookUp('afterEach', next);
5073         }
5075         test.state = 'passed';
5076         self.emit('pass', test);
5077         self.emit('test end', test);
5078         self.hookUp('afterEach', next);
5079       });
5080     });
5081   }
5083   this.next = next;
5084   next();
5088  * Run the given `suite` and invoke the
5089  * callback `fn()` when complete.
5091  * @param {Suite} suite
5092  * @param {Function} fn
5093  * @api private
5094  */
5096 Runner.prototype.runSuite = function(suite, fn){
5097   var total = this.grepTotal(suite)
5098     , self = this
5099     , i = 0;
5101   debug('run suite %s', suite.fullTitle());
5103   if (!total) return fn();
5105   this.emit('suite', this.suite = suite);
5107   function next(errSuite) {
5108     if (errSuite) {
5109       // current suite failed on a hook from errSuite
5110       if (errSuite == suite) {
5111         // if errSuite is current suite
5112         // continue to the next sibling suite
5113         return done();
5114       } else {
5115         // errSuite is among the parents of current suite
5116         // stop execution of errSuite and all sub-suites
5117         return done(errSuite);
5118       }
5119     }
5121     if (self._abort) return done();
5123     var curr = suite.suites[i++];
5124     if (!curr) return done();
5125     self.runSuite(curr, next);
5126   }
5128   function done(errSuite) {
5129     self.suite = suite;
5130     self.hook('afterAll', function(){
5131       self.emit('suite end', suite);
5132       fn(errSuite);
5133     });
5134   }
5136   this.hook('beforeAll', function(err){
5137     if (err) return done();
5138     self.runTests(suite, next);
5139   });
5143  * Handle uncaught exceptions.
5145  * @param {Error} err
5146  * @api private
5147  */
5149 Runner.prototype.uncaught = function(err){
5150   if (err) {
5151     debug('uncaught exception %s', err !== function () {
5152       return this;
5153     }.call(err) ? err : ( err.message || err ));
5154   } else {
5155     debug('uncaught undefined exception');
5156     err = utils.undefinedError();
5157   }
5158   err.uncaught = true;
5160   var runnable = this.currentRunnable;
5161   if (!runnable) return;
5163   runnable.clearTimeout();
5165   // Ignore errors if complete
5166   if (runnable.state) return;
5167   this.fail(runnable, err);
5169   // recover from test
5170   if ('test' == runnable.type) {
5171     this.emit('test end', runnable);
5172     this.hookUp('afterEach', this.next);
5173     return;
5174   }
5176   // bail on hooks
5177   this.emit('end');
5181  * Run the root suite and invoke `fn(failures)`
5182  * on completion.
5184  * @param {Function} fn
5185  * @return {Runner} for chaining
5186  * @api public
5187  */
5189 Runner.prototype.run = function(fn){
5190   var self = this,
5191     rootSuite = this.suite;
5193   fn = fn || function(){};
5195   function uncaught(err){
5196     self.uncaught(err);
5197   }
5199   function start() {
5200     self.emit('start');
5201     self.runSuite(rootSuite, function(){
5202       debug('finished running');
5203       self.emit('end');
5204     });
5205   }
5207   debug('start');
5209   // callback
5210   this.on('end', function(){
5211     debug('end');
5212     process.removeListener('uncaughtException', uncaught);
5213     fn(self.failures);
5214   });
5216   // uncaught exception
5217   process.on('uncaughtException', uncaught);
5219   if (this._delay) {
5220     // for reporters, I guess.
5221     // might be nice to debounce some dots while we wait.
5222     this.emit('waiting', rootSuite);
5223     rootSuite.once('run', start);
5224   }
5225   else {
5226     start();
5227   }
5229   return this;
5233  * Cleanly abort execution
5235  * @return {Runner} for chaining
5236  * @api public
5237  */
5238 Runner.prototype.abort = function(){
5239   debug('aborting');
5240   this._abort = true;
5244  * Filter leaks with the given globals flagged as `ok`.
5246  * @param {Array} ok
5247  * @param {Array} globals
5248  * @return {Array}
5249  * @api private
5250  */
5252 function filterLeaks(ok, globals) {
5253   return filter(globals, function(key){
5254     // Firefox and Chrome exposes iframes as index inside the window object
5255     if (/^d+/.test(key)) return false;
5257     // in firefox
5258     // if runner runs in an iframe, this iframe's window.getInterface method not init at first
5259     // it is assigned in some seconds
5260     if (global.navigator && /^getInterface/.test(key)) return false;
5262     // an iframe could be approached by window[iframeIndex]
5263     // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
5264     if (global.navigator && /^\d+/.test(key)) return false;
5266     // Opera and IE expose global variables for HTML element IDs (issue #243)
5267     if (/^mocha-/.test(key)) return false;
5269     var matched = filter(ok, function(ok){
5270       if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
5271       return key == ok;
5272     });
5273     return matched.length == 0 && (!global.navigator || 'onerror' !== key);
5274   });
5278  * Array of globals dependent on the environment.
5280  * @return {Array}
5281  * @api private
5282  */
5284 function extraGlobals() {
5285  if (typeof(process) === 'object' &&
5286      typeof(process.version) === 'string') {
5288    var nodeVersion = process.version.split('.').reduce(function(a, v) {
5289      return a << 8 | v;
5290    });
5292    // 'errno' was renamed to process._errno in v0.9.11.
5294    if (nodeVersion < 0x00090B) {
5295      return ['errno'];
5296    }
5299  return [];
5302 }); // module: runner.js
5304 require.register("suite.js", function(module, exports, require){
5306  * Module dependencies.
5307  */
5309 var EventEmitter = require('browser/events').EventEmitter
5310   , debug = require('browser/debug')('mocha:suite')
5311   , milliseconds = require('./ms')
5312   , utils = require('./utils')
5313   , Hook = require('./hook');
5316  * Expose `Suite`.
5317  */
5319 exports = module.exports = Suite;
5322  * Create a new `Suite` with the given `title`
5323  * and parent `Suite`. When a suite with the
5324  * same title is already present, that suite
5325  * is returned to provide nicer reporter
5326  * and more flexible meta-testing.
5328  * @param {Suite} parent
5329  * @param {String} title
5330  * @return {Suite}
5331  * @api public
5332  */
5334 exports.create = function(parent, title){
5335   var suite = new Suite(title, parent.ctx);
5336   suite.parent = parent;
5337   if (parent.pending) suite.pending = true;
5338   title = suite.fullTitle();
5339   parent.addSuite(suite);
5340   return suite;
5344  * Initialize a new `Suite` with the given
5345  * `title` and `ctx`.
5347  * @param {String} title
5348  * @param {Context} ctx
5349  * @api private
5350  */
5352 function Suite(title, parentContext) {
5353   this.title = title;
5354   var context = function() {};
5355   context.prototype = parentContext;
5356   this.ctx = new context();
5357   this.suites = [];
5358   this.tests = [];
5359   this.pending = false;
5360   this._beforeEach = [];
5361   this._beforeAll = [];
5362   this._afterEach = [];
5363   this._afterAll = [];
5364   this.root = !title;
5365   this._timeout = 2000;
5366   this._enableTimeouts = true;
5367   this._slow = 75;
5368   this._bail = false;
5369   this.delayed = false;
5373  * Inherit from `EventEmitter.prototype`.
5374  */
5376 function F(){};
5377 F.prototype = EventEmitter.prototype;
5378 Suite.prototype = new F;
5379 Suite.prototype.constructor = Suite;
5383  * Return a clone of this `Suite`.
5385  * @return {Suite}
5386  * @api private
5387  */
5389 Suite.prototype.clone = function(){
5390   var suite = new Suite(this.title);
5391   debug('clone');
5392   suite.ctx = this.ctx;
5393   suite.timeout(this.timeout());
5394   suite.enableTimeouts(this.enableTimeouts());
5395   suite.slow(this.slow());
5396   suite.bail(this.bail());
5397   return suite;
5401  * Set timeout `ms` or short-hand such as "2s".
5403  * @param {Number|String} ms
5404  * @return {Suite|Number} for chaining
5405  * @api private
5406  */
5408 Suite.prototype.timeout = function(ms){
5409   if (0 == arguments.length) return this._timeout;
5410   if (ms.toString() === '0') this._enableTimeouts = false;
5411   if ('string' == typeof ms) ms = milliseconds(ms);
5412   debug('timeout %d', ms);
5413   this._timeout = parseInt(ms, 10);
5414   return this;
5418   * Set timeout `enabled`.
5419   *
5420   * @param {Boolean} enabled
5421   * @return {Suite|Boolean} self or enabled
5422   * @api private
5423   */
5425 Suite.prototype.enableTimeouts = function(enabled){
5426   if (arguments.length === 0) return this._enableTimeouts;
5427   debug('enableTimeouts %s', enabled);
5428   this._enableTimeouts = enabled;
5429   return this;
5433  * Set slow `ms` or short-hand such as "2s".
5435  * @param {Number|String} ms
5436  * @return {Suite|Number} for chaining
5437  * @api private
5438  */
5440 Suite.prototype.slow = function(ms){
5441   if (0 === arguments.length) return this._slow;
5442   if ('string' == typeof ms) ms = milliseconds(ms);
5443   debug('slow %d', ms);
5444   this._slow = ms;
5445   return this;
5449  * Sets whether to bail after first error.
5451  * @param {Boolean} bail
5452  * @return {Suite|Number} for chaining
5453  * @api private
5454  */
5456 Suite.prototype.bail = function(bail){
5457   if (0 == arguments.length) return this._bail;
5458   debug('bail %s', bail);
5459   this._bail = bail;
5460   return this;
5464  * Run `fn(test[, done])` before running tests.
5466  * @param {Function} fn
5467  * @return {Suite} for chaining
5468  * @api private
5469  */
5471 Suite.prototype.beforeAll = function(title, fn){
5472   if (this.pending) return this;
5473   if ('function' === typeof title) {
5474     fn = title;
5475     title = fn.name;
5476   }
5477   title = '"before all" hook' + (title ? ': ' + title : '');
5479   var hook = new Hook(title, fn);
5480   hook.parent = this;
5481   hook.timeout(this.timeout());
5482   hook.enableTimeouts(this.enableTimeouts());
5483   hook.slow(this.slow());
5484   hook.ctx = this.ctx;
5485   this._beforeAll.push(hook);
5486   this.emit('beforeAll', hook);
5487   return this;
5491  * Run `fn(test[, done])` after running tests.
5493  * @param {Function} fn
5494  * @return {Suite} for chaining
5495  * @api private
5496  */
5498 Suite.prototype.afterAll = function(title, fn){
5499   if (this.pending) return this;
5500   if ('function' === typeof title) {
5501     fn = title;
5502     title = fn.name;
5503   }
5504   title = '"after all" hook' + (title ? ': ' + title : '');
5506   var hook = new Hook(title, fn);
5507   hook.parent = this;
5508   hook.timeout(this.timeout());
5509   hook.enableTimeouts(this.enableTimeouts());
5510   hook.slow(this.slow());
5511   hook.ctx = this.ctx;
5512   this._afterAll.push(hook);
5513   this.emit('afterAll', hook);
5514   return this;
5518  * Run `fn(test[, done])` before each test case.
5520  * @param {Function} fn
5521  * @return {Suite} for chaining
5522  * @api private
5523  */
5525 Suite.prototype.beforeEach = function(title, fn){
5526   if (this.pending) return this;
5527   if ('function' === typeof title) {
5528     fn = title;
5529     title = fn.name;
5530   }
5531   title = '"before each" hook' + (title ? ': ' + title : '');
5533   var hook = new Hook(title, fn);
5534   hook.parent = this;
5535   hook.timeout(this.timeout());
5536   hook.enableTimeouts(this.enableTimeouts());
5537   hook.slow(this.slow());
5538   hook.ctx = this.ctx;
5539   this._beforeEach.push(hook);
5540   this.emit('beforeEach', hook);
5541   return this;
5545  * Run `fn(test[, done])` after each test case.
5547  * @param {Function} fn
5548  * @return {Suite} for chaining
5549  * @api private
5550  */
5552 Suite.prototype.afterEach = function(title, fn){
5553   if (this.pending) return this;
5554   if ('function' === typeof title) {
5555     fn = title;
5556     title = fn.name;
5557   }
5558   title = '"after each" hook' + (title ? ': ' + title : '');
5560   var hook = new Hook(title, fn);
5561   hook.parent = this;
5562   hook.timeout(this.timeout());
5563   hook.enableTimeouts(this.enableTimeouts());
5564   hook.slow(this.slow());
5565   hook.ctx = this.ctx;
5566   this._afterEach.push(hook);
5567   this.emit('afterEach', hook);
5568   return this;
5572  * Add a test `suite`.
5574  * @param {Suite} suite
5575  * @return {Suite} for chaining
5576  * @api private
5577  */
5579 Suite.prototype.addSuite = function(suite){
5580   suite.parent = this;
5581   suite.timeout(this.timeout());
5582   suite.enableTimeouts(this.enableTimeouts());
5583   suite.slow(this.slow());
5584   suite.bail(this.bail());
5585   this.suites.push(suite);
5586   this.emit('suite', suite);
5587   return this;
5591  * Add a `test` to this suite.
5593  * @param {Test} test
5594  * @return {Suite} for chaining
5595  * @api private
5596  */
5598 Suite.prototype.addTest = function(test){
5599   test.parent = this;
5600   test.timeout(this.timeout());
5601   test.enableTimeouts(this.enableTimeouts());
5602   test.slow(this.slow());
5603   test.ctx = this.ctx;
5604   this.tests.push(test);
5605   this.emit('test', test);
5606   return this;
5610  * Return the full title generated by recursively
5611  * concatenating the parent's full title.
5613  * @return {String}
5614  * @api public
5615  */
5617 Suite.prototype.fullTitle = function(){
5618   if (this.parent) {
5619     var full = this.parent.fullTitle();
5620     if (full) return full + ' ' + this.title;
5621   }
5622   return this.title;
5626  * Return the total number of tests.
5628  * @return {Number}
5629  * @api public
5630  */
5632 Suite.prototype.total = function(){
5633   return utils.reduce(this.suites, function(sum, suite){
5634     return sum + suite.total();
5635   }, 0) + this.tests.length;
5639  * Iterates through each suite recursively to find
5640  * all tests. Applies a function in the format
5641  * `fn(test)`.
5643  * @param {Function} fn
5644  * @return {Suite}
5645  * @api private
5646  */
5648 Suite.prototype.eachTest = function(fn){
5649   utils.forEach(this.tests, fn);
5650   utils.forEach(this.suites, function(suite){
5651     suite.eachTest(fn);
5652   });
5653   return this;
5657  * This will run the root suite if we happen to be running in delayed mode.
5658  */
5659 Suite.prototype.run = function run() {
5660   if (this.root) {
5661     this.emit('run');
5662   }
5665 }); // module: suite.js
5667 require.register("test.js", function(module, exports, require){
5669  * Module dependencies.
5670  */
5672 var Runnable = require('./runnable');
5675  * Expose `Test`.
5676  */
5678 module.exports = Test;
5681  * Initialize a new `Test` with the given `title` and callback `fn`.
5683  * @param {String} title
5684  * @param {Function} fn
5685  * @api private
5686  */
5688 function Test(title, fn) {
5689   Runnable.call(this, title, fn);
5690   this.pending = !fn;
5691   this.type = 'test';
5695  * Inherit from `Runnable.prototype`.
5696  */
5698 function F(){};
5699 F.prototype = Runnable.prototype;
5700 Test.prototype = new F;
5701 Test.prototype.constructor = Test;
5704 }); // module: test.js
5706 require.register("utils.js", function(module, exports, require){
5708  * Module dependencies.
5709  */
5711 var fs = require('browser/fs')
5712   , path = require('browser/path')
5713   , basename = path.basename
5714   , exists = fs.existsSync || path.existsSync
5715   , glob = require('browser/glob')
5716   , join = path.join
5717   , debug = require('browser/debug')('mocha:watch');
5720  * Ignored directories.
5721  */
5723 var ignore = ['node_modules', '.git'];
5726  * Escape special characters in the given string of html.
5728  * @param  {String} html
5729  * @return {String}
5730  * @api private
5731  */
5733 exports.escape = function(html){
5734   return String(html)
5735     .replace(/&/g, '&amp;')
5736     .replace(/"/g, '&quot;')
5737     .replace(/</g, '&lt;')
5738     .replace(/>/g, '&gt;');
5742  * Array#forEach (<=IE8)
5744  * @param {Array} array
5745  * @param {Function} fn
5746  * @param {Object} scope
5747  * @api private
5748  */
5750 exports.forEach = function(arr, fn, scope){
5751   for (var i = 0, l = arr.length; i < l; i++)
5752     fn.call(scope, arr[i], i);
5756  * Array#map (<=IE8)
5758  * @param {Array} array
5759  * @param {Function} fn
5760  * @param {Object} scope
5761  * @api private
5762  */
5764 exports.map = function(arr, fn, scope){
5765   var result = [];
5766   for (var i = 0, l = arr.length; i < l; i++)
5767     result.push(fn.call(scope, arr[i], i, arr));
5768   return result;
5772  * Array#indexOf (<=IE8)
5774  * @parma {Array} arr
5775  * @param {Object} obj to find index of
5776  * @param {Number} start
5777  * @api private
5778  */
5780 exports.indexOf = function(arr, obj, start){
5781   for (var i = start || 0, l = arr.length; i < l; i++) {
5782     if (arr[i] === obj)
5783       return i;
5784   }
5785   return -1;
5789  * Array#reduce (<=IE8)
5791  * @param {Array} array
5792  * @param {Function} fn
5793  * @param {Object} initial value
5794  * @api private
5795  */
5797 exports.reduce = function(arr, fn, val){
5798   var rval = val;
5800   for (var i = 0, l = arr.length; i < l; i++) {
5801     rval = fn(rval, arr[i], i, arr);
5802   }
5804   return rval;
5808  * Array#filter (<=IE8)
5810  * @param {Array} array
5811  * @param {Function} fn
5812  * @api private
5813  */
5815 exports.filter = function(arr, fn){
5816   var ret = [];
5818   for (var i = 0, l = arr.length; i < l; i++) {
5819     var val = arr[i];
5820     if (fn(val, i, arr)) ret.push(val);
5821   }
5823   return ret;
5827  * Object.keys (<=IE8)
5829  * @param {Object} obj
5830  * @return {Array} keys
5831  * @api private
5832  */
5834 exports.keys = Object.keys || function(obj) {
5835   var keys = []
5836     , has = Object.prototype.hasOwnProperty; // for `window` on <=IE8
5838   for (var key in obj) {
5839     if (has.call(obj, key)) {
5840       keys.push(key);
5841     }
5842   }
5844   return keys;
5848  * Watch the given `files` for changes
5849  * and invoke `fn(file)` on modification.
5851  * @param {Array} files
5852  * @param {Function} fn
5853  * @api private
5854  */
5856 exports.watch = function(files, fn){
5857   var options = { interval: 100 };
5858   files.forEach(function(file){
5859     debug('file %s', file);
5860     fs.watchFile(file, options, function(curr, prev){
5861       if (prev.mtime < curr.mtime) fn(file);
5862     });
5863   });
5867  * Array.isArray (<=IE8)
5869  * @param {Object} obj
5870  * @return {Boolean}
5871  * @api private
5872  */
5873 var isArray = Array.isArray || function (obj) {
5874   return '[object Array]' == {}.toString.call(obj);
5878  * @description
5879  * Buffer.prototype.toJSON polyfill
5880  * @type {Function}
5881  */
5882 if(typeof Buffer !== 'undefined' && Buffer.prototype) {
5883   Buffer.prototype.toJSON = Buffer.prototype.toJSON || function () {
5884     return Array.prototype.slice.call(this, 0);
5885   };
5889  * Ignored files.
5890  */
5892 function ignored(path){
5893   return !~ignore.indexOf(path);
5897  * Lookup files in the given `dir`.
5899  * @return {Array}
5900  * @api private
5901  */
5903 exports.files = function(dir, ext, ret){
5904   ret = ret || [];
5905   ext = ext || ['js'];
5907   var re = new RegExp('\\.(' + ext.join('|') + ')$');
5909   fs.readdirSync(dir)
5910     .filter(ignored)
5911     .forEach(function(path){
5912       path = join(dir, path);
5913       if (fs.statSync(path).isDirectory()) {
5914         exports.files(path, ext, ret);
5915       } else if (path.match(re)) {
5916         ret.push(path);
5917       }
5918     });
5920   return ret;
5924  * Compute a slug from the given `str`.
5926  * @param {String} str
5927  * @return {String}
5928  * @api private
5929  */
5931 exports.slug = function(str){
5932   return str
5933     .toLowerCase()
5934     .replace(/ +/g, '-')
5935     .replace(/[^-\w]/g, '');
5939  * Strip the function definition from `str`,
5940  * and re-indent for pre whitespace.
5941  */
5943 exports.clean = function(str) {
5944   str = str
5945     .replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
5946     .replace(/^function *\(.*\)\s*{|\(.*\) *=> *{?/, '')
5947     .replace(/\s+\}$/, '');
5949   var spaces = str.match(/^\n?( *)/)[1].length
5950     , tabs = str.match(/^\n?(\t*)/)[1].length
5951     , re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');
5953   str = str.replace(re, '');
5955   return exports.trim(str);
5959  * Trim the given `str`.
5961  * @param {String} str
5962  * @return {String}
5963  * @api private
5964  */
5966 exports.trim = function(str){
5967   return str.replace(/^\s+|\s+$/g, '');
5971  * Parse the given `qs`.
5973  * @param {String} qs
5974  * @return {Object}
5975  * @api private
5976  */
5978 exports.parseQuery = function(qs){
5979   return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
5980     var i = pair.indexOf('=')
5981       , key = pair.slice(0, i)
5982       , val = pair.slice(++i);
5984     obj[key] = decodeURIComponent(val);
5985     return obj;
5986   }, {});
5990  * Highlight the given string of `js`.
5992  * @param {String} js
5993  * @return {String}
5994  * @api private
5995  */
5997 function highlight(js) {
5998   return js
5999     .replace(/</g, '&lt;')
6000     .replace(/>/g, '&gt;')
6001     .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
6002     .replace(/('.*?')/gm, '<span class="string">$1</span>')
6003     .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
6004     .replace(/(\d+)/gm, '<span class="number">$1</span>')
6005     .replace(/\bnew[ \t]+(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
6006     .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
6010  * Highlight the contents of tag `name`.
6012  * @param {String} name
6013  * @api private
6014  */
6016 exports.highlightTags = function(name) {
6017   var code = document.getElementById('mocha').getElementsByTagName(name);
6018   for (var i = 0, len = code.length; i < len; ++i) {
6019     code[i].innerHTML = highlight(code[i].innerHTML);
6020   }
6024  * If a value could have properties, and has none, this function is called, which returns
6025  * a string representation of the empty value.
6027  * Functions w/ no properties return `'[Function]'`
6028  * Arrays w/ length === 0 return `'[]'`
6029  * Objects w/ no properties return `'{}'`
6030  * All else: return result of `value.toString()`
6032  * @param {*} value Value to inspect
6033  * @param {string} [type] The type of the value, if known.
6034  * @returns {string}
6035  */
6036 var emptyRepresentation = function emptyRepresentation(value, type) {
6037   type = type || exports.type(value);
6039   switch(type) {
6040     case 'function':
6041       return '[Function]';
6042     case 'object':
6043       return '{}';
6044     case 'array':
6045       return '[]';
6046     default:
6047       return value.toString();
6048   }
6052  * Takes some variable and asks `{}.toString()` what it thinks it is.
6053  * @param {*} value Anything
6054  * @example
6055  * type({}) // 'object'
6056  * type([]) // 'array'
6057  * type(1) // 'number'
6058  * type(false) // 'boolean'
6059  * type(Infinity) // 'number'
6060  * type(null) // 'null'
6061  * type(new Date()) // 'date'
6062  * type(/foo/) // 'regexp'
6063  * type('type') // 'string'
6064  * type(global) // 'global'
6065  * @api private
6066  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
6067  * @returns {string}
6068  */
6069 exports.type = function type(value) {
6070   if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
6071     return 'buffer';
6072   }
6073   return Object.prototype.toString.call(value)
6074     .replace(/^\[.+\s(.+?)\]$/, '$1')
6075     .toLowerCase();
6079  * @summary Stringify `value`.
6080  * @description Different behavior depending on type of value.
6081  * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.
6082  * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.
6083  * - If `value` is an *empty* object, function, or array, return result of function
6084  *   {@link emptyRepresentation}.
6085  * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of
6086  *   JSON.stringify().
6088  * @see exports.type
6089  * @param {*} value
6090  * @return {string}
6091  * @api private
6092  */
6094 exports.stringify = function(value) {
6095   var type = exports.type(value);
6097   if (!~exports.indexOf(['object', 'array', 'function'], type)) {
6098     if(type != 'buffer') {
6099       return jsonStringify(value);
6100     }
6101     var json = value.toJSON();
6102     // Based on the toJSON result
6103     return jsonStringify(json.data && json.type ? json.data : json, 2)
6104       .replace(/,(\n|$)/g, '$1');
6105   }
6107   for (var prop in value) {
6108     if (Object.prototype.hasOwnProperty.call(value, prop)) {
6109       return jsonStringify(exports.canonicalize(value), 2).replace(/,(\n|$)/g, '$1');
6110     }
6111   }
6113   return emptyRepresentation(value, type);
6117  * @description
6118  * like JSON.stringify but more sense.
6119  * @param {Object}  object
6120  * @param {Number=} spaces
6121  * @param {number=} depth
6122  * @returns {*}
6123  * @private
6124  */
6125 function jsonStringify(object, spaces, depth) {
6126   if(typeof spaces == 'undefined') return _stringify(object);  // primitive types
6128   depth = depth || 1;
6129   var space = spaces * depth
6130     , str = isArray(object) ? '[' : '{'
6131     , end = isArray(object) ? ']' : '}'
6132     , length = object.length || exports.keys(object).length
6133     , repeat = function(s, n) { return new Array(n).join(s); }; // `.repeat()` polyfill
6135   function _stringify(val) {
6136     switch (exports.type(val)) {
6137       case 'null':
6138       case 'undefined':
6139         val = '[' + val + ']';
6140         break;
6141       case 'array':
6142       case 'object':
6143         val = jsonStringify(val, spaces, depth + 1);
6144         break;
6145       case 'boolean':
6146       case 'regexp':
6147       case 'number':
6148         val = val === 0 && (1/val) === -Infinity // `-0`
6149           ? '-0'
6150           : val.toString();
6151         break;
6152       case 'date':
6153         val = '[Date: ' + val.toISOString() + ']';
6154         break;
6155       case 'buffer':
6156         var json = val.toJSON();
6157         // Based on the toJSON result
6158         json = json.data && json.type ? json.data : json;
6159         val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
6160         break;
6161       default:
6162         val = (val == '[Function]' || val == '[Circular]')
6163           ? val
6164           : '"' + val + '"'; //string
6165     }
6166     return val;
6167   }
6169   for(var i in object) {
6170     if(!object.hasOwnProperty(i)) continue;        // not my business
6171     --length;
6172     str += '\n ' + repeat(' ', space)
6173       + (isArray(object) ? '' : '"' + i + '": ') // key
6174       +  _stringify(object[i])                   // value
6175       + (length ? ',' : '');                     // comma
6176   }
6178   return str + (str.length != 1                    // [], {}
6179     ? '\n' + repeat(' ', --space) + end
6180     : end);
6184  * Return if obj is a Buffer
6185  * @param {Object} arg
6186  * @return {Boolean}
6187  * @api private
6188  */
6189 exports.isBuffer = function (arg) {
6190   return typeof Buffer !== 'undefined' && Buffer.isBuffer(arg);
6194  * @summary Return a new Thing that has the keys in sorted order.  Recursive.
6195  * @description If the Thing...
6196  * - has already been seen, return string `'[Circular]'`
6197  * - is `undefined`, return string `'[undefined]'`
6198  * - is `null`, return value `null`
6199  * - is some other primitive, return the value
6200  * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method
6201  * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.
6202  * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`
6204  * @param {*} value Thing to inspect.  May or may not have properties.
6205  * @param {Array} [stack=[]] Stack of seen values
6206  * @return {(Object|Array|Function|string|undefined)}
6207  * @see {@link exports.stringify}
6208  * @api private
6209  */
6211 exports.canonicalize = function(value, stack) {
6212   var canonicalizedObj,
6213     type = exports.type(value),
6214     prop,
6215     withStack = function withStack(value, fn) {
6216       stack.push(value);
6217       fn();
6218       stack.pop();
6219     };
6221   stack = stack || [];
6223   if (exports.indexOf(stack, value) !== -1) {
6224     return '[Circular]';
6225   }
6227   switch(type) {
6228     case 'undefined':
6229     case 'buffer':
6230     case 'null':
6231       canonicalizedObj = value;
6232       break;
6233     case 'array':
6234       withStack(value, function () {
6235         canonicalizedObj = exports.map(value, function (item) {
6236           return exports.canonicalize(item, stack);
6237         });
6238       });
6239       break;
6240     case 'function':
6241       for (prop in value) {
6242         canonicalizedObj = {};
6243         break;
6244       }
6245       if (!canonicalizedObj) {
6246         canonicalizedObj = emptyRepresentation(value, type);
6247         break;
6248       }
6249     /* falls through */
6250     case 'object':
6251       canonicalizedObj = canonicalizedObj || {};
6252       withStack(value, function () {
6253         exports.forEach(exports.keys(value).sort(), function (key) {
6254           canonicalizedObj[key] = exports.canonicalize(value[key], stack);
6255         });
6256       });
6257       break;
6258     case 'date':
6259     case 'number':
6260     case 'regexp':
6261     case 'boolean':
6262       canonicalizedObj = value;
6263       break;
6264     default:
6265       canonicalizedObj = value.toString();
6266   }
6268   return canonicalizedObj;
6272  * Lookup file names at the given `path`.
6273  */
6274 exports.lookupFiles = function lookupFiles(path, extensions, recursive) {
6275   var files = [];
6276   var re = new RegExp('\\.(' + extensions.join('|') + ')$');
6278   if (!exists(path)) {
6279     if (exists(path + '.js')) {
6280       path += '.js';
6281     } else {
6282       files = glob.sync(path);
6283       if (!files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
6284       return files;
6285     }
6286   }
6288   try {
6289     var stat = fs.statSync(path);
6290     if (stat.isFile()) return path;
6291   }
6292   catch (ignored) {
6293     return;
6294   }
6296   fs.readdirSync(path).forEach(function(file) {
6297     file = join(path, file);
6298     try {
6299       var stat = fs.statSync(file);
6300       if (stat.isDirectory()) {
6301         if (recursive) {
6302           files = files.concat(lookupFiles(file, extensions, recursive));
6303         }
6304         return;
6305       }
6306     }
6307     catch (ignored) {
6308       return;
6309     }
6310     if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') return;
6311     files.push(file);
6312   });
6314   return files;
6318  * Generate an undefined error with a message warning the user.
6320  * @return {Error}
6321  */
6323 exports.undefinedError = function() {
6324   return new Error('Caught undefined error, did you throw without specifying what?');
6328  * Generate an undefined error if `err` is not defined.
6330  * @param {Error} err
6331  * @return {Error}
6332  */
6334 exports.getError = function(err) {
6335   return err || exports.undefinedError();
6340  * @summary
6341  * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)
6342  * @description
6343  * When invoking this function you get a filter function that get the Error.stack as an input,
6344  * and return a prettify output.
6345  * (i.e: strip Mocha, node_modules, bower and componentJS from stack trace).
6346  * @returns {Function}
6347  */
6349 exports.stackTraceFilter = function() {
6350   var slash = '/'
6351     , is = typeof document === 'undefined'
6352       ? { node: true }
6353       : { browser: true }
6354     , cwd = is.node
6355       ? process.cwd() + slash
6356       : location.href.replace(/\/[^\/]*$/, '/');
6358   function isNodeModule (line) {
6359     return (~line.indexOf('node_modules'));
6360   }
6362   function isMochaInternal (line) {
6363     return (~line.indexOf('node_modules' + slash + 'mocha'))  ||
6364       (~line.indexOf('components' + slash + 'mochajs'))       ||
6365       (~line.indexOf('components' + slash + 'mocha'));
6366   }
6368   // node_modules, bower, componentJS
6369   function isBrowserModule(line) {
6370     return (~line.indexOf('node_modules')) ||
6371       (~line.indexOf('components'));
6372   }
6374   function isNodeInternal (line) {
6375     return (~line.indexOf('(timers.js:')) ||
6376       (~line.indexOf('(events.js:'))      ||
6377       (~line.indexOf('(node.js:'))        ||
6378       (~line.indexOf('(module.js:'))      ||
6379       (~line.indexOf('GeneratorFunctionPrototype.next (native)')) ||
6380       false
6381   }
6383   return function(stack) {
6384     stack = stack.split('\n');
6386     stack = exports.reduce(stack, function(list, line) {
6387       if (is.node && (isNodeModule(line) ||
6388         isMochaInternal(line) ||
6389         isNodeInternal(line)))
6390         return list;
6392       if (is.browser && (isBrowserModule(line)))
6393         return list;
6395       // Clean up cwd(absolute)
6396       list.push(line.replace(cwd, ''));
6397       return list;
6398     }, []);
6400     return stack.join('\n');
6401   }
6403 }); // module: utils.js
6404 // The global object is "self" in Web Workers.
6405 var global = (function() { return this; })();
6408  * Save timer references to avoid Sinon interfering (see GH-237).
6409  */
6411 var Date = global.Date;
6412 var setTimeout = global.setTimeout;
6413 var setInterval = global.setInterval;
6414 var clearTimeout = global.clearTimeout;
6415 var clearInterval = global.clearInterval;
6418  * Node shims.
6420  * These are meant only to allow
6421  * mocha.js to run untouched, not
6422  * to allow running node code in
6423  * the browser.
6424  */
6426 var process = {};
6427 process.exit = function(status){};
6428 process.stdout = {};
6430 var uncaughtExceptionHandlers = [];
6432 var originalOnerrorHandler = global.onerror;
6435  * Remove uncaughtException listener.
6436  * Revert to original onerror handler if previously defined.
6437  */
6439 process.removeListener = function(e, fn){
6440   if ('uncaughtException' == e) {
6441     if (originalOnerrorHandler) {
6442       global.onerror = originalOnerrorHandler;
6443     } else {
6444       global.onerror = function() {};
6445     }
6446     var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);
6447     if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }
6448   }
6452  * Implements uncaughtException listener.
6453  */
6455 process.on = function(e, fn){
6456   if ('uncaughtException' == e) {
6457     global.onerror = function(err, url, line){
6458       fn(new Error(err + ' (' + url + ':' + line + ')'));
6459       return true;
6460     };
6461     uncaughtExceptionHandlers.push(fn);
6462   }
6466  * Expose mocha.
6467  */
6469 var Mocha = global.Mocha = require('mocha'),
6470     mocha = global.mocha = new Mocha({ reporter: 'html' });
6472 // The BDD UI is registered by default, but no UI will be functional in the
6473 // browser without an explicit call to the overridden `mocha.ui` (see below).
6474 // Ensure that this default UI does not expose its methods to the global scope.
6475 mocha.suite.removeAllListeners('pre-require');
6477 var immediateQueue = []
6478   , immediateTimeout;
6480 function timeslice() {
6481   var immediateStart = new Date().getTime();
6482   while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
6483     immediateQueue.shift()();
6484   }
6485   if (immediateQueue.length) {
6486     immediateTimeout = setTimeout(timeslice, 0);
6487   } else {
6488     immediateTimeout = null;
6489   }
6493  * High-performance override of Runner.immediately.
6494  */
6496 Mocha.Runner.immediately = function(callback) {
6497   immediateQueue.push(callback);
6498   if (!immediateTimeout) {
6499     immediateTimeout = setTimeout(timeslice, 0);
6500   }
6504  * Function to allow assertion libraries to throw errors directly into mocha.
6505  * This is useful when running tests in a browser because window.onerror will
6506  * only receive the 'message' attribute of the Error.
6507  */
6508 mocha.throwError = function(err) {
6509   Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {
6510     fn(err);
6511   });
6512   throw err;
6516  * Override ui to ensure that the ui functions are initialized.
6517  * Normally this would happen in Mocha.prototype.loadFiles.
6518  */
6520 mocha.ui = function(ui){
6521   Mocha.prototype.ui.call(this, ui);
6522   this.suite.emit('pre-require', global, null, this);
6523   return this;
6527  * Setup mocha with the given setting options.
6528  */
6530 mocha.setup = function(opts){
6531   if ('string' == typeof opts) opts = { ui: opts };
6532   for (var opt in opts) this[opt](opts[opt]);
6533   return this;
6537  * Run mocha, returning the Runner.
6538  */
6540 mocha.run = function(fn){
6541   var options = mocha.options;
6542   mocha.globals('location');
6544   var query = Mocha.utils.parseQuery(global.location.search || '');
6545   if (query.grep) mocha.grep(new RegExp(query.grep));
6546   if (query.fgrep) mocha.grep(query.fgrep);
6547   if (query.invert) mocha.invert();
6549   return Mocha.prototype.run.call(mocha, function(err){
6550     // The DOM Document is not available in Web Workers.
6551     var document = global.document;
6552     if (document && document.getElementById('mocha') && options.noHighlighting !== true) {
6553       Mocha.utils.highlightTags('code');
6554     }
6555     if (fn) fn(err);
6556   });
6560  * Expose the process shim.
6561  */
6563 Mocha.process = process;
6564 })();