Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: bower_components/polymer-test-tools/mocha/mocha.js

Issue 786953007: npm_modules: Fork bower_components into Polymer 0.4.0 and 0.5.0 versions (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 ;(function(){
2
3 // CommonJS require()
4
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 }
15
16 require.modules = {};
17
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 };
26
27 require.register = function (path, fn){
28 require.modules[path] = fn;
29 };
30
31 require.relative = function (parent) {
32 return function(p){
33 if ('.' != p.charAt(0)) return require(p);
34
35 var path = parent.split('/')
36 , segs = p.split('/');
37 path.pop();
38
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 }
44
45 return require(path.join('/'));
46 };
47 };
48
49
50 require.register("browser/debug.js", function(module, exports, require){
51
52 module.exports = function(type){
53 return function(){
54 }
55 };
56
57 }); // module: browser/debug.js
58
59 require.register("browser/diff.js", function(module, exports, require){
60 /* See LICENSE file for terms of use */
61
62 /*
63 * Text diff implementation.
64 *
65 * This library supports the following APIS:
66 * JsDiff.diffChars: Character by character diff
67 * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
68 * JsDiff.diffLines: Line based diff
69 *
70 * JsDiff.diffCss: Diff targeted at CSS content
71 *
72 * These methods are based on the implementation proposed in
73 * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
74 * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
75 */
76 var JsDiff = (function() {
77 /*jshint maxparams: 5*/
78 function clonePath(path) {
79 return { newPos: path.newPos, components: path.components.slice(0) };
80 }
81 function removeEmpty(array) {
82 var ret = [];
83 for (var i = 0; i < array.length; i++) {
84 if (array[i]) {
85 ret.push(array[i]);
86 }
87 }
88 return ret;
89 }
90 function escapeHTML(s) {
91 var n = s;
92 n = n.replace(/&/g, '&amp;');
93 n = n.replace(/</g, '&lt;');
94 n = n.replace(/>/g, '&gt;');
95 n = n.replace(/"/g, '&quot;');
96
97 return n;
98 }
99
100 var Diff = function(ignoreWhitespace) {
101 this.ignoreWhitespace = ignoreWhitespace;
102 };
103 Diff.prototype = {
104 diff: function(oldString, newString) {
105 // Handle the identity case (this is due to unrolling editLength == 0
106 if (newString === oldString) {
107 return [{ value: newString }];
108 }
109 if (!newString) {
110 return [{ value: oldString, removed: true }];
111 }
112 if (!oldString) {
113 return [{ value: newString, added: true }];
114 }
115
116 newString = this.tokenize(newString);
117 oldString = this.tokenize(oldString);
118
119 var newLen = newString.length, oldLen = oldString.length;
120 var maxEditLength = newLen + oldLen;
121 var bestPath = [{ newPos: -1, components: [] }];
122
123 // Seed editLength = 0
124 var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
125 if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
126 return bestPath[0].components;
127 }
128
129 for (var editLength = 1; editLength <= maxEditLength; editLength++) {
130 for (var diagonalPath = -1*editLength; diagonalPath <= editLength; dia gonalPath+=2) {
131 var basePath;
132 var addPath = bestPath[diagonalPath-1],
133 removePath = bestPath[diagonalPath+1];
134 oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
135 if (addPath) {
136 // No one else is going to attempt to use this value, clear it
137 bestPath[diagonalPath-1] = undefined;
138 }
139
140 var canAdd = addPath && addPath.newPos+1 < newLen;
141 var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
142 if (!canAdd && !canRemove) {
143 bestPath[diagonalPath] = undefined;
144 continue;
145 }
146
147 // Select the diagonal that we want to branch from. We select the pr ior
148 // path whose position in the new string is the farthest from the or igin
149 // and does not pass the bounds of the diff graph
150 if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
151 basePath = clonePath(removePath);
152 this.pushComponent(basePath.components, oldString[oldPos], undefin ed, true);
153 } else {
154 basePath = clonePath(addPath);
155 basePath.newPos++;
156 this.pushComponent(basePath.components, newString[basePath.newPos] , true, undefined);
157 }
158
159 var oldPos = this.extractCommon(basePath, newString, oldString, diag onalPath);
160
161 if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
162 return basePath.components;
163 } else {
164 bestPath[diagonalPath] = basePath;
165 }
166 }
167 }
168 },
169
170 pushComponent: function(components, value, added, removed) {
171 var last = components[components.length-1];
172 if (last && last.added === added && last.removed === removed) {
173 // We need to clone here as the component clone operation is just
174 // as shallow array clone
175 components[components.length-1] =
176 {value: this.join(last.value, value), added: added, removed: removed };
177 } else {
178 components.push({value: value, added: added, removed: removed });
179 }
180 },
181 extractCommon: function(basePath, newString, oldString, diagonalPath) {
182 var newLen = newString.length,
183 oldLen = oldString.length,
184 newPos = basePath.newPos,
185 oldPos = newPos - diagonalPath;
186 while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[n ewPos+1], oldString[oldPos+1])) {
187 newPos++;
188 oldPos++;
189
190 this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
191 }
192 basePath.newPos = newPos;
193 return oldPos;
194 },
195
196 equals: function(left, right) {
197 var reWhitespace = /\S/;
198 if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.t est(right)) {
199 return true;
200 } else {
201 return left === right;
202 }
203 },
204 join: function(left, right) {
205 return left + right;
206 },
207 tokenize: function(value) {
208 return value;
209 }
210 };
211
212 var CharDiff = new Diff();
213
214 var WordDiff = new Diff(true);
215 var WordWithSpaceDiff = new Diff();
216 WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
217 return removeEmpty(value.split(/(\s+|\b)/));
218 };
219
220 var CssDiff = new Diff(true);
221 CssDiff.tokenize = function(value) {
222 return removeEmpty(value.split(/([{}:;,]|\s+)/));
223 };
224
225 var LineDiff = new Diff();
226 LineDiff.tokenize = function(value) {
227 return value.split(/^/m);
228 };
229
230 return {
231 Diff: Diff,
232
233 diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
234 diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
235 diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff (oldStr, newStr); },
236 diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
237
238 diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
239
240 createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
241 var ret = [];
242
243 ret.push('Index: ' + fileName);
244 ret.push('================================================================ ===');
245 ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
246 ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
247
248 var diff = LineDiff.diff(oldStr, newStr);
249 if (!diff[diff.length-1].value) {
250 diff.pop(); // Remove trailing newline add
251 }
252 diff.push({value: '', lines: []}); // Append an empty value to make clea nup easier
253
254 function contextLines(lines) {
255 return lines.map(function(entry) { return ' ' + entry; });
256 }
257 function eofNL(curRange, i, current) {
258 var last = diff[diff.length-2],
259 isLast = i === diff.length-2,
260 isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
261
262 // Figure out if this is the last line for the given file and missing NL
263 if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
264 curRange.push('\\ No newline at end of file');
265 }
266 }
267
268 var oldRangeStart = 0, newRangeStart = 0, curRange = [],
269 oldLine = 1, newLine = 1;
270 for (var i = 0; i < diff.length; i++) {
271 var current = diff[i],
272 lines = current.lines || current.value.replace(/\n$/, '').split('\n' );
273 current.lines = lines;
274
275 if (current.added || current.removed) {
276 if (!oldRangeStart) {
277 var prev = diff[i-1];
278 oldRangeStart = oldLine;
279 newRangeStart = newLine;
280
281 if (prev) {
282 curRange = contextLines(prev.lines.slice(-4));
283 oldRangeStart -= curRange.length;
284 newRangeStart -= curRange.length;
285 }
286 }
287 curRange.push.apply(curRange, lines.map(function(entry) { return (curr ent.added?'+':'-') + entry; }));
288 eofNL(curRange, i, current);
289
290 if (current.added) {
291 newLine += lines.length;
292 } else {
293 oldLine += lines.length;
294 }
295 } else {
296 if (oldRangeStart) {
297 // Close out any changes that have been output (or join overlapping)
298 if (lines.length <= 8 && i < diff.length-2) {
299 // Overlapping
300 curRange.push.apply(curRange, contextLines(lines));
301 } else {
302 // end the range and output
303 var contextSize = Math.min(lines.length, 4);
304 ret.push(
305 '@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextS ize)
306 + ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextS ize)
307 + ' @@');
308 ret.push.apply(ret, curRange);
309 ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
310 if (lines.length <= 4) {
311 eofNL(ret, i, current);
312 }
313
314 oldRangeStart = 0; newRangeStart = 0; curRange = [];
315 }
316 }
317 oldLine += lines.length;
318 newLine += lines.length;
319 }
320 }
321
322 return ret.join('\n') + '\n';
323 },
324
325 applyPatch: function(oldStr, uniDiff) {
326 var diffstr = uniDiff.split('\n');
327 var diff = [];
328 var remEOFNL = false,
329 addEOFNL = false;
330
331 for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {
332 if(diffstr[i][0] === '@') {
333 var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
334 diff.unshift({
335 start:meh[3],
336 oldlength:meh[2],
337 oldlines:[],
338 newlength:meh[4],
339 newlines:[]
340 });
341 } else if(diffstr[i][0] === '+') {
342 diff[0].newlines.push(diffstr[i].substr(1));
343 } else if(diffstr[i][0] === '-') {
344 diff[0].oldlines.push(diffstr[i].substr(1));
345 } else if(diffstr[i][0] === ' ') {
346 diff[0].newlines.push(diffstr[i].substr(1));
347 diff[0].oldlines.push(diffstr[i].substr(1));
348 } else if(diffstr[i][0] === '\\') {
349 if (diffstr[i-1][0] === '+') {
350 remEOFNL = true;
351 } else if(diffstr[i-1][0] === '-') {
352 addEOFNL = true;
353 }
354 }
355 }
356
357 var str = oldStr.split('\n');
358 for (var i = diff.length - 1; i >= 0; i--) {
359 var d = diff[i];
360 for (var j = 0; j < d.oldlength; j++) {
361 if(str[d.start-1+j] !== d.oldlines[j]) {
362 return false;
363 }
364 }
365 Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newli nes));
366 }
367
368 if (remEOFNL) {
369 while (!str[str.length-1]) {
370 str.pop();
371 }
372 } else if (addEOFNL) {
373 str.push('');
374 }
375 return str.join('\n');
376 },
377
378 convertChangesToXML: function(changes){
379 var ret = [];
380 for ( var i = 0; i < changes.length; i++) {
381 var change = changes[i];
382 if (change.added) {
383 ret.push('<ins>');
384 } else if (change.removed) {
385 ret.push('<del>');
386 }
387
388 ret.push(escapeHTML(change.value));
389
390 if (change.added) {
391 ret.push('</ins>');
392 } else if (change.removed) {
393 ret.push('</del>');
394 }
395 }
396 return ret.join('');
397 },
398
399 // See: http://code.google.com/p/google-diff-match-patch/wiki/API
400 convertChangesToDMP: function(changes){
401 var ret = [], change;
402 for ( var i = 0; i < changes.length; i++) {
403 change = changes[i];
404 ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
405 }
406 return ret;
407 }
408 };
409 })();
410
411 if (typeof module !== 'undefined') {
412 module.exports = JsDiff;
413 }
414
415 }); // module: browser/diff.js
416
417 require.register("browser/events.js", function(module, exports, require){
418
419 /**
420 * Module exports.
421 */
422
423 exports.EventEmitter = EventEmitter;
424
425 /**
426 * Check if `obj` is an array.
427 */
428
429 function isArray(obj) {
430 return '[object Array]' == {}.toString.call(obj);
431 }
432
433 /**
434 * Event emitter constructor.
435 *
436 * @api public
437 */
438
439 function EventEmitter(){};
440
441 /**
442 * Adds a listener.
443 *
444 * @api public
445 */
446
447 EventEmitter.prototype.on = function (name, fn) {
448 if (!this.$events) {
449 this.$events = {};
450 }
451
452 if (!this.$events[name]) {
453 this.$events[name] = fn;
454 } else if (isArray(this.$events[name])) {
455 this.$events[name].push(fn);
456 } else {
457 this.$events[name] = [this.$events[name], fn];
458 }
459
460 return this;
461 };
462
463 EventEmitter.prototype.addListener = EventEmitter.prototype.on;
464
465 /**
466 * Adds a volatile listener.
467 *
468 * @api public
469 */
470
471 EventEmitter.prototype.once = function (name, fn) {
472 var self = this;
473
474 function on () {
475 self.removeListener(name, on);
476 fn.apply(this, arguments);
477 };
478
479 on.listener = fn;
480 this.on(name, on);
481
482 return this;
483 };
484
485 /**
486 * Removes a listener.
487 *
488 * @api public
489 */
490
491 EventEmitter.prototype.removeListener = function (name, fn) {
492 if (this.$events && this.$events[name]) {
493 var list = this.$events[name];
494
495 if (isArray(list)) {
496 var pos = -1;
497
498 for (var i = 0, l = list.length; i < l; i++) {
499 if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
500 pos = i;
501 break;
502 }
503 }
504
505 if (pos < 0) {
506 return this;
507 }
508
509 list.splice(pos, 1);
510
511 if (!list.length) {
512 delete this.$events[name];
513 }
514 } else if (list === fn || (list.listener && list.listener === fn)) {
515 delete this.$events[name];
516 }
517 }
518
519 return this;
520 };
521
522 /**
523 * Removes all listeners for an event.
524 *
525 * @api public
526 */
527
528 EventEmitter.prototype.removeAllListeners = function (name) {
529 if (name === undefined) {
530 this.$events = {};
531 return this;
532 }
533
534 if (this.$events && this.$events[name]) {
535 this.$events[name] = null;
536 }
537
538 return this;
539 };
540
541 /**
542 * Gets all listeners for a certain event.
543 *
544 * @api public
545 */
546
547 EventEmitter.prototype.listeners = function (name) {
548 if (!this.$events) {
549 this.$events = {};
550 }
551
552 if (!this.$events[name]) {
553 this.$events[name] = [];
554 }
555
556 if (!isArray(this.$events[name])) {
557 this.$events[name] = [this.$events[name]];
558 }
559
560 return this.$events[name];
561 };
562
563 /**
564 * Emits an event.
565 *
566 * @api public
567 */
568
569 EventEmitter.prototype.emit = function (name) {
570 if (!this.$events) {
571 return false;
572 }
573
574 var handler = this.$events[name];
575
576 if (!handler) {
577 return false;
578 }
579
580 var args = [].slice.call(arguments, 1);
581
582 if ('function' == typeof handler) {
583 handler.apply(this, args);
584 } else if (isArray(handler)) {
585 var listeners = handler.slice();
586
587 for (var i = 0, l = listeners.length; i < l; i++) {
588 listeners[i].apply(this, args);
589 }
590 } else {
591 return false;
592 }
593
594 return true;
595 };
596 }); // module: browser/events.js
597
598 require.register("browser/fs.js", function(module, exports, require){
599
600 }); // module: browser/fs.js
601
602 require.register("browser/path.js", function(module, exports, require){
603
604 }); // module: browser/path.js
605
606 require.register("browser/progress.js", function(module, exports, require){
607 /**
608 * Expose `Progress`.
609 */
610
611 module.exports = Progress;
612
613 /**
614 * Initialize a new `Progress` indicator.
615 */
616
617 function Progress() {
618 this.percent = 0;
619 this.size(0);
620 this.fontSize(11);
621 this.font('helvetica, arial, sans-serif');
622 }
623
624 /**
625 * Set progress size to `n`.
626 *
627 * @param {Number} n
628 * @return {Progress} for chaining
629 * @api public
630 */
631
632 Progress.prototype.size = function(n){
633 this._size = n;
634 return this;
635 };
636
637 /**
638 * Set text to `str`.
639 *
640 * @param {String} str
641 * @return {Progress} for chaining
642 * @api public
643 */
644
645 Progress.prototype.text = function(str){
646 this._text = str;
647 return this;
648 };
649
650 /**
651 * Set font size to `n`.
652 *
653 * @param {Number} n
654 * @return {Progress} for chaining
655 * @api public
656 */
657
658 Progress.prototype.fontSize = function(n){
659 this._fontSize = n;
660 return this;
661 };
662
663 /**
664 * Set font `family`.
665 *
666 * @param {String} family
667 * @return {Progress} for chaining
668 */
669
670 Progress.prototype.font = function(family){
671 this._font = family;
672 return this;
673 };
674
675 /**
676 * Update percentage to `n`.
677 *
678 * @param {Number} n
679 * @return {Progress} for chaining
680 */
681
682 Progress.prototype.update = function(n){
683 this.percent = n;
684 return this;
685 };
686
687 /**
688 * Draw on `ctx`.
689 *
690 * @param {CanvasRenderingContext2d} ctx
691 * @return {Progress} for chaining
692 */
693
694 Progress.prototype.draw = function(ctx){
695 try {
696 var percent = Math.min(this.percent, 100)
697 , size = this._size
698 , half = size / 2
699 , x = half
700 , y = half
701 , rad = half - 1
702 , fontSize = this._fontSize;
703
704 ctx.font = fontSize + 'px ' + this._font;
705
706 var angle = Math.PI * 2 * (percent / 100);
707 ctx.clearRect(0, 0, size, size);
708
709 // outer circle
710 ctx.strokeStyle = '#9f9f9f';
711 ctx.beginPath();
712 ctx.arc(x, y, rad, 0, angle, false);
713 ctx.stroke();
714
715 // inner circle
716 ctx.strokeStyle = '#eee';
717 ctx.beginPath();
718 ctx.arc(x, y, rad - 1, 0, angle, true);
719 ctx.stroke();
720
721 // text
722 var text = this._text || (percent | 0) + '%'
723 , w = ctx.measureText(text).width;
724
725 ctx.fillText(
726 text
727 , x - w / 2 + 1
728 , y + fontSize / 2 - 1);
729 } catch (ex) {} //don't fail if we can't render progress
730 return this;
731 };
732
733 }); // module: browser/progress.js
734
735 require.register("browser/tty.js", function(module, exports, require){
736
737 exports.isatty = function(){
738 return true;
739 };
740
741 exports.getWindowSize = function(){
742 if ('innerHeight' in global) {
743 return [global.innerHeight, global.innerWidth];
744 } else {
745 // In a Web Worker, the DOM Window is not available.
746 return [640, 480];
747 }
748 };
749
750 }); // module: browser/tty.js
751
752 require.register("context.js", function(module, exports, require){
753
754 /**
755 * Expose `Context`.
756 */
757
758 module.exports = Context;
759
760 /**
761 * Initialize a new `Context`.
762 *
763 * @api private
764 */
765
766 function Context(){}
767
768 /**
769 * Set or get the context `Runnable` to `runnable`.
770 *
771 * @param {Runnable} runnable
772 * @return {Context}
773 * @api private
774 */
775
776 Context.prototype.runnable = function(runnable){
777 if (0 == arguments.length) return this._runnable;
778 this.test = this._runnable = runnable;
779 return this;
780 };
781
782 /**
783 * Set test timeout `ms`.
784 *
785 * @param {Number} ms
786 * @return {Context} self
787 * @api private
788 */
789
790 Context.prototype.timeout = function(ms){
791 this.runnable().timeout(ms);
792 return this;
793 };
794
795 /**
796 * Set test slowness threshold `ms`.
797 *
798 * @param {Number} ms
799 * @return {Context} self
800 * @api private
801 */
802
803 Context.prototype.slow = function(ms){
804 this.runnable().slow(ms);
805 return this;
806 };
807
808 /**
809 * Inspect the context void of `._runnable`.
810 *
811 * @return {String}
812 * @api private
813 */
814
815 Context.prototype.inspect = function(){
816 return JSON.stringify(this, function(key, val){
817 if ('_runnable' == key) return;
818 if ('test' == key) return;
819 return val;
820 }, 2);
821 };
822
823 }); // module: context.js
824
825 require.register("hook.js", function(module, exports, require){
826
827 /**
828 * Module dependencies.
829 */
830
831 var Runnable = require('./runnable');
832
833 /**
834 * Expose `Hook`.
835 */
836
837 module.exports = Hook;
838
839 /**
840 * Initialize a new `Hook` with the given `title` and callback `fn`.
841 *
842 * @param {String} title
843 * @param {Function} fn
844 * @api private
845 */
846
847 function Hook(title, fn) {
848 Runnable.call(this, title, fn);
849 this.type = 'hook';
850 }
851
852 /**
853 * Inherit from `Runnable.prototype`.
854 */
855
856 function F(){};
857 F.prototype = Runnable.prototype;
858 Hook.prototype = new F;
859 Hook.prototype.constructor = Hook;
860
861
862 /**
863 * Get or set the test `err`.
864 *
865 * @param {Error} err
866 * @return {Error}
867 * @api public
868 */
869
870 Hook.prototype.error = function(err){
871 if (0 == arguments.length) {
872 var err = this._error;
873 this._error = null;
874 return err;
875 }
876
877 this._error = err;
878 };
879
880 }); // module: hook.js
881
882 require.register("interfaces/bdd.js", function(module, exports, require){
883
884 /**
885 * Module dependencies.
886 */
887
888 var Suite = require('../suite')
889 , Test = require('../test')
890 , utils = require('../utils');
891
892 /**
893 * BDD-style interface:
894 *
895 * describe('Array', function(){
896 * describe('#indexOf()', function(){
897 * it('should return -1 when not present', function(){
898 *
899 * });
900 *
901 * it('should return the index when present', function(){
902 *
903 * });
904 * });
905 * });
906 *
907 */
908
909 module.exports = function(suite){
910 var suites = [suite];
911
912 suite.on('pre-require', function(context, file, mocha){
913
914 /**
915 * Execute before running tests.
916 */
917
918 context.before = function(name, fn){
919 suites[0].beforeAll(name, fn);
920 };
921
922 /**
923 * Execute after running tests.
924 */
925
926 context.after = function(name, fn){
927 suites[0].afterAll(name, fn);
928 };
929
930 /**
931 * Execute before each test case.
932 */
933
934 context.beforeEach = function(name, fn){
935 suites[0].beforeEach(name, fn);
936 };
937
938 /**
939 * Execute after each test case.
940 */
941
942 context.afterEach = function(name, fn){
943 suites[0].afterEach(name, fn);
944 };
945
946 /**
947 * Describe a "suite" with the given `title`
948 * and callback `fn` containing nested suites
949 * and/or tests.
950 */
951
952 context.describe = context.context = function(title, fn){
953 var suite = Suite.create(suites[0], title);
954 suites.unshift(suite);
955 fn.call(suite);
956 suites.shift();
957 return suite;
958 };
959
960 /**
961 * Pending describe.
962 */
963
964 context.xdescribe =
965 context.xcontext =
966 context.describe.skip = function(title, fn){
967 var suite = Suite.create(suites[0], title);
968 suite.pending = true;
969 suites.unshift(suite);
970 fn.call(suite);
971 suites.shift();
972 };
973
974 /**
975 * Exclusive suite.
976 */
977
978 context.describe.only = function(title, fn){
979 var suite = context.describe(title, fn);
980 mocha.grep(suite.fullTitle());
981 return suite;
982 };
983
984 /**
985 * Describe a specification or test-case
986 * with the given `title` and callback `fn`
987 * acting as a thunk.
988 */
989
990 context.it = context.specify = function(title, fn){
991 var suite = suites[0];
992 if (suite.pending) var fn = null;
993 var test = new Test(title, fn);
994 suite.addTest(test);
995 return test;
996 };
997
998 /**
999 * Exclusive test-case.
1000 */
1001
1002 context.it.only = function(title, fn){
1003 var test = context.it(title, fn);
1004 var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
1005 mocha.grep(new RegExp(reString));
1006 return test;
1007 };
1008
1009 /**
1010 * Pending test case.
1011 */
1012
1013 context.xit =
1014 context.xspecify =
1015 context.it.skip = function(title){
1016 context.it(title);
1017 };
1018 });
1019 };
1020
1021 }); // module: interfaces/bdd.js
1022
1023 require.register("interfaces/exports.js", function(module, exports, require){
1024
1025 /**
1026 * Module dependencies.
1027 */
1028
1029 var Suite = require('../suite')
1030 , Test = require('../test');
1031
1032 /**
1033 * TDD-style interface:
1034 *
1035 * exports.Array = {
1036 * '#indexOf()': {
1037 * 'should return -1 when the value is not present': function(){
1038 *
1039 * },
1040 *
1041 * 'should return the correct index when the value is present': function (){
1042 *
1043 * }
1044 * }
1045 * };
1046 *
1047 */
1048
1049 module.exports = function(suite){
1050 var suites = [suite];
1051
1052 suite.on('require', visit);
1053
1054 function visit(obj) {
1055 var suite;
1056 for (var key in obj) {
1057 if ('function' == typeof obj[key]) {
1058 var fn = obj[key];
1059 switch (key) {
1060 case 'before':
1061 suites[0].beforeAll(fn);
1062 break;
1063 case 'after':
1064 suites[0].afterAll(fn);
1065 break;
1066 case 'beforeEach':
1067 suites[0].beforeEach(fn);
1068 break;
1069 case 'afterEach':
1070 suites[0].afterEach(fn);
1071 break;
1072 default:
1073 suites[0].addTest(new Test(key, fn));
1074 }
1075 } else {
1076 var suite = Suite.create(suites[0], key);
1077 suites.unshift(suite);
1078 visit(obj[key]);
1079 suites.shift();
1080 }
1081 }
1082 }
1083 };
1084
1085 }); // module: interfaces/exports.js
1086
1087 require.register("interfaces/index.js", function(module, exports, require){
1088
1089 exports.bdd = require('./bdd');
1090 exports.tdd = require('./tdd');
1091 exports.qunit = require('./qunit');
1092 exports.exports = require('./exports');
1093
1094 }); // module: interfaces/index.js
1095
1096 require.register("interfaces/qunit.js", function(module, exports, require){
1097
1098 /**
1099 * Module dependencies.
1100 */
1101
1102 var Suite = require('../suite')
1103 , Test = require('../test')
1104 , utils = require('../utils');
1105
1106 /**
1107 * QUnit-style interface:
1108 *
1109 * suite('Array');
1110 *
1111 * test('#length', function(){
1112 * var arr = [1,2,3];
1113 * ok(arr.length == 3);
1114 * });
1115 *
1116 * test('#indexOf()', function(){
1117 * var arr = [1,2,3];
1118 * ok(arr.indexOf(1) == 0);
1119 * ok(arr.indexOf(2) == 1);
1120 * ok(arr.indexOf(3) == 2);
1121 * });
1122 *
1123 * suite('String');
1124 *
1125 * test('#length', function(){
1126 * ok('foo'.length == 3);
1127 * });
1128 *
1129 */
1130
1131 module.exports = function(suite){
1132 var suites = [suite];
1133
1134 suite.on('pre-require', function(context, file, mocha){
1135
1136 /**
1137 * Execute before running tests.
1138 */
1139
1140 context.before = function(name, fn){
1141 suites[0].beforeAll(name, fn);
1142 };
1143
1144 /**
1145 * Execute after running tests.
1146 */
1147
1148 context.after = function(name, fn){
1149 suites[0].afterAll(name, fn);
1150 };
1151
1152 /**
1153 * Execute before each test case.
1154 */
1155
1156 context.beforeEach = function(name, fn){
1157 suites[0].beforeEach(name, fn);
1158 };
1159
1160 /**
1161 * Execute after each test case.
1162 */
1163
1164 context.afterEach = function(name, fn){
1165 suites[0].afterEach(name, fn);
1166 };
1167
1168 /**
1169 * Describe a "suite" with the given `title`.
1170 */
1171
1172 context.suite = function(title){
1173 if (suites.length > 1) suites.shift();
1174 var suite = Suite.create(suites[0], title);
1175 suites.unshift(suite);
1176 return suite;
1177 };
1178
1179 /**
1180 * Exclusive test-case.
1181 */
1182
1183 context.suite.only = function(title, fn){
1184 var suite = context.suite(title, fn);
1185 mocha.grep(suite.fullTitle());
1186 };
1187
1188 /**
1189 * Describe a specification or test-case
1190 * with the given `title` and callback `fn`
1191 * acting as a thunk.
1192 */
1193
1194 context.test = function(title, fn){
1195 var test = new Test(title, fn);
1196 suites[0].addTest(test);
1197 return test;
1198 };
1199
1200 /**
1201 * Exclusive test-case.
1202 */
1203
1204 context.test.only = function(title, fn){
1205 var test = context.test(title, fn);
1206 var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
1207 mocha.grep(new RegExp(reString));
1208 };
1209
1210 /**
1211 * Pending test case.
1212 */
1213
1214 context.test.skip = function(title){
1215 context.test(title);
1216 };
1217 });
1218 };
1219
1220 }); // module: interfaces/qunit.js
1221
1222 require.register("interfaces/tdd.js", function(module, exports, require){
1223
1224 /**
1225 * Module dependencies.
1226 */
1227
1228 var Suite = require('../suite')
1229 , Test = require('../test')
1230 , utils = require('../utils');;
1231
1232 /**
1233 * TDD-style interface:
1234 *
1235 * suite('Array', function(){
1236 * suite('#indexOf()', function(){
1237 * suiteSetup(function(){
1238 *
1239 * });
1240 *
1241 * test('should return -1 when not present', function(){
1242 *
1243 * });
1244 *
1245 * test('should return the index when present', function(){
1246 *
1247 * });
1248 *
1249 * suiteTeardown(function(){
1250 *
1251 * });
1252 * });
1253 * });
1254 *
1255 */
1256
1257 module.exports = function(suite){
1258 var suites = [suite];
1259
1260 suite.on('pre-require', function(context, file, mocha){
1261
1262 /**
1263 * Execute before each test case.
1264 */
1265
1266 context.setup = function(name, fn){
1267 suites[0].beforeEach(name, fn);
1268 };
1269
1270 /**
1271 * Execute after each test case.
1272 */
1273
1274 context.teardown = function(name, fn){
1275 suites[0].afterEach(name, fn);
1276 };
1277
1278 /**
1279 * Execute before the suite.
1280 */
1281
1282 context.suiteSetup = function(name, fn){
1283 suites[0].beforeAll(name, fn);
1284 };
1285
1286 /**
1287 * Execute after the suite.
1288 */
1289
1290 context.suiteTeardown = function(name, fn){
1291 suites[0].afterAll(name, fn);
1292 };
1293
1294 /**
1295 * Describe a "suite" with the given `title`
1296 * and callback `fn` containing nested suites
1297 * and/or tests.
1298 */
1299
1300 context.suite = function(title, fn){
1301 var suite = Suite.create(suites[0], title);
1302 suites.unshift(suite);
1303 fn.call(suite);
1304 suites.shift();
1305 return suite;
1306 };
1307
1308 /**
1309 * Pending suite.
1310 */
1311 context.suite.skip = function(title, fn) {
1312 var suite = Suite.create(suites[0], title);
1313 suite.pending = true;
1314 suites.unshift(suite);
1315 fn.call(suite);
1316 suites.shift();
1317 };
1318
1319 /**
1320 * Exclusive test-case.
1321 */
1322
1323 context.suite.only = function(title, fn){
1324 var suite = context.suite(title, fn);
1325 mocha.grep(suite.fullTitle());
1326 };
1327
1328 /**
1329 * Describe a specification or test-case
1330 * with the given `title` and callback `fn`
1331 * acting as a thunk.
1332 */
1333
1334 context.test = function(title, fn){
1335 var suite = suites[0];
1336 if (suite.pending) var fn = null;
1337 var test = new Test(title, fn);
1338 suite.addTest(test);
1339 return test;
1340 };
1341
1342 /**
1343 * Exclusive test-case.
1344 */
1345
1346 context.test.only = function(title, fn){
1347 var test = context.test(title, fn);
1348 var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
1349 mocha.grep(new RegExp(reString));
1350 };
1351
1352 /**
1353 * Pending test case.
1354 */
1355
1356 context.test.skip = function(title){
1357 context.test(title);
1358 };
1359 });
1360 };
1361
1362 }); // module: interfaces/tdd.js
1363
1364 require.register("mocha.js", function(module, exports, require){
1365 /*!
1366 * mocha
1367 * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
1368 * MIT Licensed
1369 */
1370
1371 /**
1372 * Module dependencies.
1373 */
1374
1375 var path = require('browser/path')
1376 , utils = require('./utils');
1377
1378 /**
1379 * Expose `Mocha`.
1380 */
1381
1382 exports = module.exports = Mocha;
1383
1384 /**
1385 * Expose internals.
1386 */
1387
1388 exports.utils = utils;
1389 exports.interfaces = require('./interfaces');
1390 exports.reporters = require('./reporters');
1391 exports.Runnable = require('./runnable');
1392 exports.Context = require('./context');
1393 exports.Runner = require('./runner');
1394 exports.Suite = require('./suite');
1395 exports.Hook = require('./hook');
1396 exports.Test = require('./test');
1397
1398 /**
1399 * Return image `name` path.
1400 *
1401 * @param {String} name
1402 * @return {String}
1403 * @api private
1404 */
1405
1406 function image(name) {
1407 return __dirname + '/../images/' + name + '.png';
1408 }
1409
1410 /**
1411 * Setup mocha with `options`.
1412 *
1413 * Options:
1414 *
1415 * - `ui` name "bdd", "tdd", "exports" etc
1416 * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
1417 * - `globals` array of accepted globals
1418 * - `timeout` timeout in milliseconds
1419 * - `bail` bail on the first test failure
1420 * - `slow` milliseconds to wait before considering a test slow
1421 * - `ignoreLeaks` ignore global leaks
1422 * - `grep` string or regexp to filter tests with
1423 *
1424 * @param {Object} options
1425 * @api public
1426 */
1427
1428 function Mocha(options) {
1429 options = options || {};
1430 this.files = [];
1431 this.options = options;
1432 this.grep(options.grep);
1433 this.suite = new exports.Suite('', new exports.Context);
1434 this.ui(options.ui);
1435 this.bail(options.bail);
1436 this.reporter(options.reporter);
1437 if (null != options.timeout) this.timeout(options.timeout);
1438 this.useColors(options.useColors)
1439 if (options.slow) this.slow(options.slow);
1440
1441 this.suite.on('pre-require', function (context) {
1442 exports.afterEach = context.afterEach || context.teardown;
1443 exports.after = context.after || context.suiteTeardown;
1444 exports.beforeEach = context.beforeEach || context.setup;
1445 exports.before = context.before || context.suiteSetup;
1446 exports.describe = context.describe || context.suite;
1447 exports.it = context.it || context.test;
1448 exports.setup = context.setup || context.beforeEach;
1449 exports.suiteSetup = context.suiteSetup || context.before;
1450 exports.suiteTeardown = context.suiteTeardown || context.after;
1451 exports.suite = context.suite || context.describe;
1452 exports.teardown = context.teardown || context.afterEach;
1453 exports.test = context.test || context.it;
1454 });
1455 }
1456
1457 /**
1458 * Enable or disable bailing on the first failure.
1459 *
1460 * @param {Boolean} [bail]
1461 * @api public
1462 */
1463
1464 Mocha.prototype.bail = function(bail){
1465 if (0 == arguments.length) bail = true;
1466 this.suite.bail(bail);
1467 return this;
1468 };
1469
1470 /**
1471 * Add test `file`.
1472 *
1473 * @param {String} file
1474 * @api public
1475 */
1476
1477 Mocha.prototype.addFile = function(file){
1478 this.files.push(file);
1479 return this;
1480 };
1481
1482 /**
1483 * Set reporter to `reporter`, defaults to "dot".
1484 *
1485 * @param {String|Function} reporter name or constructor
1486 * @api public
1487 */
1488
1489 Mocha.prototype.reporter = function(reporter){
1490 if ('function' == typeof reporter) {
1491 this._reporter = reporter;
1492 } else {
1493 reporter = reporter || 'dot';
1494 var _reporter;
1495 try { _reporter = require('./reporters/' + reporter); } catch (err) {};
1496 if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
1497 if (!_reporter && reporter === 'teamcity')
1498 console.warn('The Teamcity reporter was moved to a package named ' +
1499 'mocha-teamcity-reporter ' +
1500 '(https://npmjs.org/package/mocha-teamcity-reporter).');
1501 if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
1502 this._reporter = _reporter;
1503 }
1504 return this;
1505 };
1506
1507 /**
1508 * Set test UI `name`, defaults to "bdd".
1509 *
1510 * @param {String} bdd
1511 * @api public
1512 */
1513
1514 Mocha.prototype.ui = function(name){
1515 name = name || 'bdd';
1516 this._ui = exports.interfaces[name];
1517 if (!this._ui) try { this._ui = require(name); } catch (err) {};
1518 if (!this._ui) throw new Error('invalid interface "' + name + '"');
1519 this._ui = this._ui(this.suite);
1520 return this;
1521 };
1522
1523 /**
1524 * Load registered files.
1525 *
1526 * @api private
1527 */
1528
1529 Mocha.prototype.loadFiles = function(fn){
1530 var self = this;
1531 var suite = this.suite;
1532 var pending = this.files.length;
1533 this.files.forEach(function(file){
1534 file = path.resolve(file);
1535 suite.emit('pre-require', global, file, self);
1536 suite.emit('require', require(file), file, self);
1537 suite.emit('post-require', global, file, self);
1538 --pending || (fn && fn());
1539 });
1540 };
1541
1542 /**
1543 * Enable growl support.
1544 *
1545 * @api private
1546 */
1547
1548 Mocha.prototype._growl = function(runner, reporter) {
1549 var notify = require('growl');
1550
1551 runner.on('end', function(){
1552 var stats = reporter.stats;
1553 if (stats.failures) {
1554 var msg = stats.failures + ' of ' + runner.total + ' tests failed';
1555 notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
1556 } else {
1557 notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
1558 name: 'mocha'
1559 , title: 'Passed'
1560 , image: image('ok')
1561 });
1562 }
1563 });
1564 };
1565
1566 /**
1567 * Add regexp to grep, if `re` is a string it is escaped.
1568 *
1569 * @param {RegExp|String} re
1570 * @return {Mocha}
1571 * @api public
1572 */
1573
1574 Mocha.prototype.grep = function(re){
1575 this.options.grep = 'string' == typeof re
1576 ? new RegExp(utils.escapeRegexp(re))
1577 : re;
1578 return this;
1579 };
1580
1581 /**
1582 * Invert `.grep()` matches.
1583 *
1584 * @return {Mocha}
1585 * @api public
1586 */
1587
1588 Mocha.prototype.invert = function(){
1589 this.options.invert = true;
1590 return this;
1591 };
1592
1593 /**
1594 * Ignore global leaks.
1595 *
1596 * @param {Boolean} ignore
1597 * @return {Mocha}
1598 * @api public
1599 */
1600
1601 Mocha.prototype.ignoreLeaks = function(ignore){
1602 this.options.ignoreLeaks = !!ignore;
1603 return this;
1604 };
1605
1606 /**
1607 * Enable global leak checking.
1608 *
1609 * @return {Mocha}
1610 * @api public
1611 */
1612
1613 Mocha.prototype.checkLeaks = function(){
1614 this.options.ignoreLeaks = false;
1615 return this;
1616 };
1617
1618 /**
1619 * Enable growl support.
1620 *
1621 * @return {Mocha}
1622 * @api public
1623 */
1624
1625 Mocha.prototype.growl = function(){
1626 this.options.growl = true;
1627 return this;
1628 };
1629
1630 /**
1631 * Ignore `globals` array or string.
1632 *
1633 * @param {Array|String} globals
1634 * @return {Mocha}
1635 * @api public
1636 */
1637
1638 Mocha.prototype.globals = function(globals){
1639 this.options.globals = (this.options.globals || []).concat(globals);
1640 return this;
1641 };
1642
1643 /**
1644 * Emit color output.
1645 *
1646 * @param {Boolean} colors
1647 * @return {Mocha}
1648 * @api public
1649 */
1650
1651 Mocha.prototype.useColors = function(colors){
1652 this.options.useColors = arguments.length && colors != undefined
1653 ? colors
1654 : true;
1655 return this;
1656 };
1657
1658 /**
1659 * Use inline diffs rather than +/-.
1660 *
1661 * @param {Boolean} inlineDiffs
1662 * @return {Mocha}
1663 * @api public
1664 */
1665
1666 Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
1667 this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
1668 ? inlineDiffs
1669 : false;
1670 return this;
1671 };
1672
1673 /**
1674 * Set the timeout in milliseconds.
1675 *
1676 * @param {Number} timeout
1677 * @return {Mocha}
1678 * @api public
1679 */
1680
1681 Mocha.prototype.timeout = function(timeout){
1682 this.suite.timeout(timeout);
1683 return this;
1684 };
1685
1686 /**
1687 * Set slowness threshold in milliseconds.
1688 *
1689 * @param {Number} slow
1690 * @return {Mocha}
1691 * @api public
1692 */
1693
1694 Mocha.prototype.slow = function(slow){
1695 this.suite.slow(slow);
1696 return this;
1697 };
1698
1699 /**
1700 * Makes all tests async (accepting a callback)
1701 *
1702 * @return {Mocha}
1703 * @api public
1704 */
1705
1706 Mocha.prototype.asyncOnly = function(){
1707 this.options.asyncOnly = true;
1708 return this;
1709 };
1710
1711 /**
1712 * Run tests and invoke `fn()` when complete.
1713 *
1714 * @param {Function} fn
1715 * @return {Runner}
1716 * @api public
1717 */
1718
1719 Mocha.prototype.run = function(fn){
1720 if (this.files.length) this.loadFiles();
1721 var suite = this.suite;
1722 var options = this.options;
1723 options.files = this.files;
1724 var runner = new exports.Runner(suite);
1725 var reporter = new this._reporter(runner, options);
1726 runner.ignoreLeaks = false !== options.ignoreLeaks;
1727 runner.asyncOnly = options.asyncOnly;
1728 if (options.grep) runner.grep(options.grep, options.invert);
1729 if (options.globals) runner.globals(options.globals);
1730 if (options.growl) this._growl(runner, reporter);
1731 exports.reporters.Base.useColors = options.useColors;
1732 exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
1733 return runner.run(fn);
1734 };
1735
1736 }); // module: mocha.js
1737
1738 require.register("ms.js", function(module, exports, require){
1739 /**
1740 * Helpers.
1741 */
1742
1743 var s = 1000;
1744 var m = s * 60;
1745 var h = m * 60;
1746 var d = h * 24;
1747 var y = d * 365.25;
1748
1749 /**
1750 * Parse or format the given `val`.
1751 *
1752 * Options:
1753 *
1754 * - `long` verbose formatting [false]
1755 *
1756 * @param {String|Number} val
1757 * @param {Object} options
1758 * @return {String|Number}
1759 * @api public
1760 */
1761
1762 module.exports = function(val, options){
1763 options = options || {};
1764 if ('string' == typeof val) return parse(val);
1765 return options.long ? longFormat(val) : shortFormat(val);
1766 };
1767
1768 /**
1769 * Parse the given `str` and return milliseconds.
1770 *
1771 * @param {String} str
1772 * @return {Number}
1773 * @api private
1774 */
1775
1776 function parse(str) {
1777 var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|yea rs?|y)?$/i.exec(str);
1778 if (!match) return;
1779 var n = parseFloat(match[1]);
1780 var type = (match[2] || 'ms').toLowerCase();
1781 switch (type) {
1782 case 'years':
1783 case 'year':
1784 case 'y':
1785 return n * y;
1786 case 'days':
1787 case 'day':
1788 case 'd':
1789 return n * d;
1790 case 'hours':
1791 case 'hour':
1792 case 'h':
1793 return n * h;
1794 case 'minutes':
1795 case 'minute':
1796 case 'm':
1797 return n * m;
1798 case 'seconds':
1799 case 'second':
1800 case 's':
1801 return n * s;
1802 case 'ms':
1803 return n;
1804 }
1805 }
1806
1807 /**
1808 * Short format for `ms`.
1809 *
1810 * @param {Number} ms
1811 * @return {String}
1812 * @api private
1813 */
1814
1815 function shortFormat(ms) {
1816 if (ms >= d) return Math.round(ms / d) + 'd';
1817 if (ms >= h) return Math.round(ms / h) + 'h';
1818 if (ms >= m) return Math.round(ms / m) + 'm';
1819 if (ms >= s) return Math.round(ms / s) + 's';
1820 return ms + 'ms';
1821 }
1822
1823 /**
1824 * Long format for `ms`.
1825 *
1826 * @param {Number} ms
1827 * @return {String}
1828 * @api private
1829 */
1830
1831 function longFormat(ms) {
1832 return plural(ms, d, 'day')
1833 || plural(ms, h, 'hour')
1834 || plural(ms, m, 'minute')
1835 || plural(ms, s, 'second')
1836 || ms + ' ms';
1837 }
1838
1839 /**
1840 * Pluralization helper.
1841 */
1842
1843 function plural(ms, n, name) {
1844 if (ms < n) return;
1845 if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
1846 return Math.ceil(ms / n) + ' ' + name + 's';
1847 }
1848
1849 }); // module: ms.js
1850
1851 require.register("reporters/base.js", function(module, exports, require){
1852
1853 /**
1854 * Module dependencies.
1855 */
1856
1857 var tty = require('browser/tty')
1858 , diff = require('browser/diff')
1859 , ms = require('../ms')
1860 , utils = require('../utils');
1861
1862 /**
1863 * Save timer references to avoid Sinon interfering (see GH-237).
1864 */
1865
1866 var Date = global.Date
1867 , setTimeout = global.setTimeout
1868 , setInterval = global.setInterval
1869 , clearTimeout = global.clearTimeout
1870 , clearInterval = global.clearInterval;
1871
1872 /**
1873 * Check if both stdio streams are associated with a tty.
1874 */
1875
1876 var isatty = tty.isatty(1) && tty.isatty(2);
1877
1878 /**
1879 * Expose `Base`.
1880 */
1881
1882 exports = module.exports = Base;
1883
1884 /**
1885 * Enable coloring by default.
1886 */
1887
1888 exports.useColors = isatty || (process.env.MOCHA_COLORS !== undefined);
1889
1890 /**
1891 * Inline diffs instead of +/-
1892 */
1893
1894 exports.inlineDiffs = false;
1895
1896 /**
1897 * Default color map.
1898 */
1899
1900 exports.colors = {
1901 'pass': 90
1902 , 'fail': 31
1903 , 'bright pass': 92
1904 , 'bright fail': 91
1905 , 'bright yellow': 93
1906 , 'pending': 36
1907 , 'suite': 0
1908 , 'error title': 0
1909 , 'error message': 31
1910 , 'error stack': 90
1911 , 'checkmark': 32
1912 , 'fast': 90
1913 , 'medium': 33
1914 , 'slow': 31
1915 , 'green': 32
1916 , 'light': 90
1917 , 'diff gutter': 90
1918 , 'diff added': 42
1919 , 'diff removed': 41
1920 };
1921
1922 /**
1923 * Default symbol map.
1924 */
1925
1926 exports.symbols = {
1927 ok: '✓',
1928 err: '✖',
1929 dot: '․'
1930 };
1931
1932 // With node.js on Windows: use symbols available in terminal default fonts
1933 if ('win32' == process.platform) {
1934 exports.symbols.ok = '\u221A';
1935 exports.symbols.err = '\u00D7';
1936 exports.symbols.dot = '.';
1937 }
1938
1939 /**
1940 * Color `str` with the given `type`,
1941 * allowing colors to be disabled,
1942 * as well as user-defined color
1943 * schemes.
1944 *
1945 * @param {String} type
1946 * @param {String} str
1947 * @return {String}
1948 * @api private
1949 */
1950
1951 var color = exports.color = function(type, str) {
1952 if (!exports.useColors) return str;
1953 return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
1954 };
1955
1956 /**
1957 * Expose term window size, with some
1958 * defaults for when stderr is not a tty.
1959 */
1960
1961 exports.window = {
1962 width: isatty
1963 ? process.stdout.getWindowSize
1964 ? process.stdout.getWindowSize(1)[0]
1965 : tty.getWindowSize()[1]
1966 : 75
1967 };
1968
1969 /**
1970 * Expose some basic cursor interactions
1971 * that are common among reporters.
1972 */
1973
1974 exports.cursor = {
1975 hide: function(){
1976 isatty && process.stdout.write('\u001b[?25l');
1977 },
1978
1979 show: function(){
1980 isatty && process.stdout.write('\u001b[?25h');
1981 },
1982
1983 deleteLine: function(){
1984 isatty && process.stdout.write('\u001b[2K');
1985 },
1986
1987 beginningOfLine: function(){
1988 isatty && process.stdout.write('\u001b[0G');
1989 },
1990
1991 CR: function(){
1992 if (isatty) {
1993 exports.cursor.deleteLine();
1994 exports.cursor.beginningOfLine();
1995 } else {
1996 process.stdout.write('\r');
1997 }
1998 }
1999 };
2000
2001 /**
2002 * Outut the given `failures` as a list.
2003 *
2004 * @param {Array} failures
2005 * @api public
2006 */
2007
2008 exports.list = function(failures){
2009 console.error();
2010 failures.forEach(function(test, i){
2011 // format
2012 var fmt = color('error title', ' %s) %s:\n')
2013 + color('error message', ' %s')
2014 + color('error stack', '\n%s\n');
2015
2016 // msg
2017 var err = test.err
2018 , message = err.message || ''
2019 , stack = err.stack || message
2020 , index = stack.indexOf(message) + message.length
2021 , msg = stack.slice(0, index)
2022 , actual = err.actual
2023 , expected = err.expected
2024 , escape = true;
2025
2026 // uncaught
2027 if (err.uncaught) {
2028 msg = 'Uncaught ' + msg;
2029 }
2030
2031 // explicitly show diff
2032 if (err.showDiff && sameType(actual, expected)) {
2033 escape = false;
2034 err.actual = actual = stringify(canonicalize(actual));
2035 err.expected = expected = stringify(canonicalize(expected));
2036 }
2037
2038 // actual / expected diff
2039 if ('string' == typeof actual && 'string' == typeof expected) {
2040 fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n ');
2041 var match = message.match(/^([^:]+): expected/);
2042 msg = '\n ' + color('error message', match ? match[1] : msg);
2043
2044 if (exports.inlineDiffs) {
2045 msg += inlineDiff(err, escape);
2046 } else {
2047 msg += unifiedDiff(err, escape);
2048 }
2049 }
2050
2051 // indent stack trace without msg
2052 stack = stack.slice(index ? index + 1 : index)
2053 .replace(/^/gm, ' ');
2054
2055 console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
2056 });
2057 };
2058
2059 /**
2060 * Initialize a new `Base` reporter.
2061 *
2062 * All other reporters generally
2063 * inherit from this reporter, providing
2064 * stats such as test duration, number
2065 * of tests passed / failed etc.
2066 *
2067 * @param {Runner} runner
2068 * @api public
2069 */
2070
2071 function Base(runner) {
2072 var self = this
2073 , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failure s: 0 }
2074 , failures = this.failures = [];
2075
2076 if (!runner) return;
2077 this.runner = runner;
2078
2079 runner.stats = stats;
2080
2081 runner.on('start', function(){
2082 stats.start = new Date;
2083 });
2084
2085 runner.on('suite', function(suite){
2086 stats.suites = stats.suites || 0;
2087 suite.root || stats.suites++;
2088 });
2089
2090 runner.on('test end', function(test){
2091 stats.tests = stats.tests || 0;
2092 stats.tests++;
2093 });
2094
2095 runner.on('pass', function(test){
2096 stats.passes = stats.passes || 0;
2097
2098 var medium = test.slow() / 2;
2099 test.speed = test.duration > test.slow()
2100 ? 'slow'
2101 : test.duration > medium
2102 ? 'medium'
2103 : 'fast';
2104
2105 stats.passes++;
2106 });
2107
2108 runner.on('fail', function(test, err){
2109 stats.failures = stats.failures || 0;
2110 stats.failures++;
2111 test.err = err;
2112 failures.push(test);
2113 });
2114
2115 runner.on('end', function(){
2116 stats.end = new Date;
2117 stats.duration = new Date - stats.start;
2118 });
2119
2120 runner.on('pending', function(){
2121 stats.pending++;
2122 });
2123 }
2124
2125 /**
2126 * Output common epilogue used by many of
2127 * the bundled reporters.
2128 *
2129 * @api public
2130 */
2131
2132 Base.prototype.epilogue = function(){
2133 var stats = this.stats;
2134 var tests;
2135 var fmt;
2136
2137 console.log();
2138
2139 // passes
2140 fmt = color('bright pass', ' ')
2141 + color('green', ' %d passing')
2142 + color('light', ' (%s)');
2143
2144 console.log(fmt,
2145 stats.passes || 0,
2146 ms(stats.duration));
2147
2148 // pending
2149 if (stats.pending) {
2150 fmt = color('pending', ' ')
2151 + color('pending', ' %d pending');
2152
2153 console.log(fmt, stats.pending);
2154 }
2155
2156 // failures
2157 if (stats.failures) {
2158 fmt = color('fail', ' %d failing');
2159
2160 console.error(fmt,
2161 stats.failures);
2162
2163 Base.list(this.failures);
2164 console.error();
2165 }
2166
2167 console.log();
2168 };
2169
2170 /**
2171 * Pad the given `str` to `len`.
2172 *
2173 * @param {String} str
2174 * @param {String} len
2175 * @return {String}
2176 * @api private
2177 */
2178
2179 function pad(str, len) {
2180 str = String(str);
2181 return Array(len - str.length + 1).join(' ') + str;
2182 }
2183
2184
2185 /**
2186 * Returns an inline diff between 2 strings with coloured ANSI output
2187 *
2188 * @param {Error} Error with actual/expected
2189 * @return {String} Diff
2190 * @api private
2191 */
2192
2193 function inlineDiff(err, escape) {
2194 var msg = errorDiff(err, 'WordsWithSpace', escape);
2195
2196 // linenos
2197 var lines = msg.split('\n');
2198 if (lines.length > 4) {
2199 var width = String(lines.length).length;
2200 msg = lines.map(function(str, i){
2201 return pad(++i, width) + ' |' + ' ' + str;
2202 }).join('\n');
2203 }
2204
2205 // legend
2206 msg = '\n'
2207 + color('diff removed', 'actual')
2208 + ' '
2209 + color('diff added', 'expected')
2210 + '\n\n'
2211 + msg
2212 + '\n';
2213
2214 // indent
2215 msg = msg.replace(/^/gm, ' ');
2216 return msg;
2217 }
2218
2219 /**
2220 * Returns a unified diff between 2 strings
2221 *
2222 * @param {Error} Error with actual/expected
2223 * @return {String} Diff
2224 * @api private
2225 */
2226
2227 function unifiedDiff(err, escape) {
2228 var indent = ' ';
2229 function cleanUp(line) {
2230 if (escape) {
2231 line = escapeInvisibles(line);
2232 }
2233 if (line[0] === '+') return indent + colorLines('diff added', line);
2234 if (line[0] === '-') return indent + colorLines('diff removed', line);
2235 if (line.match(/\@\@/)) return null;
2236 if (line.match(/\\ No newline/)) return null;
2237 else return indent + line;
2238 }
2239 function notBlank(line) {
2240 return line != null;
2241 }
2242 msg = diff.createPatch('string', err.actual, err.expected);
2243 var lines = msg.split('\n').splice(4);
2244 return '\n '
2245 + colorLines('diff added', '+ expected') + ' '
2246 + colorLines('diff removed', '- actual')
2247 + '\n\n'
2248 + lines.map(cleanUp).filter(notBlank).join('\n');
2249 }
2250
2251 /**
2252 * Return a character diff for `err`.
2253 *
2254 * @param {Error} err
2255 * @return {String}
2256 * @api private
2257 */
2258
2259 function errorDiff(err, type, escape) {
2260 var actual = escape ? escapeInvisibles(err.actual) : err.actual;
2261 var expected = escape ? escapeInvisibles(err.expected) : err.expected;
2262 return diff['diff' + type](actual, expected).map(function(str){
2263 if (str.added) return colorLines('diff added', str.value);
2264 if (str.removed) return colorLines('diff removed', str.value);
2265 return str.value;
2266 }).join('');
2267 }
2268
2269 /**
2270 * Returns a string with all invisible characters in plain text
2271 *
2272 * @param {String} line
2273 * @return {String}
2274 * @api private
2275 */
2276 function escapeInvisibles(line) {
2277 return line.replace(/\t/g, '<tab>')
2278 .replace(/\r/g, '<CR>')
2279 .replace(/\n/g, '<LF>\n');
2280 }
2281
2282 /**
2283 * Color lines for `str`, using the color `name`.
2284 *
2285 * @param {String} name
2286 * @param {String} str
2287 * @return {String}
2288 * @api private
2289 */
2290
2291 function colorLines(name, str) {
2292 return str.split('\n').map(function(str){
2293 return color(name, str);
2294 }).join('\n');
2295 }
2296
2297 /**
2298 * Stringify `obj`.
2299 *
2300 * @param {Object} obj
2301 * @return {String}
2302 * @api private
2303 */
2304
2305 function stringify(obj) {
2306 if (obj instanceof RegExp) return obj.toString();
2307 return JSON.stringify(obj, null, 2);
2308 }
2309
2310 /**
2311 * Return a new object that has the keys in sorted order.
2312 * @param {Object} obj
2313 * @return {Object}
2314 * @api private
2315 */
2316
2317 function canonicalize(obj, stack) {
2318 stack = stack || [];
2319
2320 if (utils.indexOf(stack, obj) !== -1) return obj;
2321
2322 var canonicalizedObj;
2323
2324 if ('[object Array]' == {}.toString.call(obj)) {
2325 stack.push(obj);
2326 canonicalizedObj = utils.map(obj, function(item) {
2327 return canonicalize(item, stack);
2328 });
2329 stack.pop();
2330 } else if (typeof obj === 'object' && obj !== null) {
2331 stack.push(obj);
2332 canonicalizedObj = {};
2333 utils.forEach(utils.keys(obj).sort(), function(key) {
2334 canonicalizedObj[key] = canonicalize(obj[key], stack);
2335 });
2336 stack.pop();
2337 } else {
2338 canonicalizedObj = obj;
2339 }
2340
2341 return canonicalizedObj;
2342 }
2343
2344 /**
2345 * Check that a / b have the same type.
2346 *
2347 * @param {Object} a
2348 * @param {Object} b
2349 * @return {Boolean}
2350 * @api private
2351 */
2352
2353 function sameType(a, b) {
2354 a = Object.prototype.toString.call(a);
2355 b = Object.prototype.toString.call(b);
2356 return a == b;
2357 }
2358
2359
2360 }); // module: reporters/base.js
2361
2362 require.register("reporters/doc.js", function(module, exports, require){
2363
2364 /**
2365 * Module dependencies.
2366 */
2367
2368 var Base = require('./base')
2369 , utils = require('../utils');
2370
2371 /**
2372 * Expose `Doc`.
2373 */
2374
2375 exports = module.exports = Doc;
2376
2377 /**
2378 * Initialize a new `Doc` reporter.
2379 *
2380 * @param {Runner} runner
2381 * @api public
2382 */
2383
2384 function Doc(runner) {
2385 Base.call(this, runner);
2386
2387 var self = this
2388 , stats = this.stats
2389 , total = runner.total
2390 , indents = 2;
2391
2392 function indent() {
2393 return Array(indents).join(' ');
2394 }
2395
2396 runner.on('suite', function(suite){
2397 if (suite.root) return;
2398 ++indents;
2399 console.log('%s<section class="suite">', indent());
2400 ++indents;
2401 console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
2402 console.log('%s<dl>', indent());
2403 });
2404
2405 runner.on('suite end', function(suite){
2406 if (suite.root) return;
2407 console.log('%s</dl>', indent());
2408 --indents;
2409 console.log('%s</section>', indent());
2410 --indents;
2411 });
2412
2413 runner.on('pass', function(test){
2414 console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
2415 var code = utils.escape(utils.clean(test.fn.toString()));
2416 console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
2417 });
2418 }
2419
2420 }); // module: reporters/doc.js
2421
2422 require.register("reporters/dot.js", function(module, exports, require){
2423
2424 /**
2425 * Module dependencies.
2426 */
2427
2428 var Base = require('./base')
2429 , color = Base.color;
2430
2431 /**
2432 * Expose `Dot`.
2433 */
2434
2435 exports = module.exports = Dot;
2436
2437 /**
2438 * Initialize a new `Dot` matrix test reporter.
2439 *
2440 * @param {Runner} runner
2441 * @api public
2442 */
2443
2444 function Dot(runner) {
2445 Base.call(this, runner);
2446
2447 var self = this
2448 , stats = this.stats
2449 , width = Base.window.width * .75 | 0
2450 , n = 0;
2451
2452 runner.on('start', function(){
2453 process.stdout.write('\n ');
2454 });
2455
2456 runner.on('pending', function(test){
2457 process.stdout.write(color('pending', Base.symbols.dot));
2458 });
2459
2460 runner.on('pass', function(test){
2461 if (++n % width == 0) process.stdout.write('\n ');
2462 if ('slow' == test.speed) {
2463 process.stdout.write(color('bright yellow', Base.symbols.dot));
2464 } else {
2465 process.stdout.write(color(test.speed, Base.symbols.dot));
2466 }
2467 });
2468
2469 runner.on('fail', function(test, err){
2470 if (++n % width == 0) process.stdout.write('\n ');
2471 process.stdout.write(color('fail', Base.symbols.dot));
2472 });
2473
2474 runner.on('end', function(){
2475 console.log();
2476 self.epilogue();
2477 });
2478 }
2479
2480 /**
2481 * Inherit from `Base.prototype`.
2482 */
2483
2484 function F(){};
2485 F.prototype = Base.prototype;
2486 Dot.prototype = new F;
2487 Dot.prototype.constructor = Dot;
2488
2489 }); // module: reporters/dot.js
2490
2491 require.register("reporters/html-cov.js", function(module, exports, require){
2492
2493 /**
2494 * Module dependencies.
2495 */
2496
2497 var JSONCov = require('./json-cov')
2498 , fs = require('browser/fs');
2499
2500 /**
2501 * Expose `HTMLCov`.
2502 */
2503
2504 exports = module.exports = HTMLCov;
2505
2506 /**
2507 * Initialize a new `JsCoverage` reporter.
2508 *
2509 * @param {Runner} runner
2510 * @api public
2511 */
2512
2513 function HTMLCov(runner) {
2514 var jade = require('jade')
2515 , file = __dirname + '/templates/coverage.jade'
2516 , str = fs.readFileSync(file, 'utf8')
2517 , fn = jade.compile(str, { filename: file })
2518 , self = this;
2519
2520 JSONCov.call(this, runner, false);
2521
2522 runner.on('end', function(){
2523 process.stdout.write(fn({
2524 cov: self.cov
2525 , coverageClass: coverageClass
2526 }));
2527 });
2528 }
2529
2530 /**
2531 * Return coverage class for `n`.
2532 *
2533 * @return {String}
2534 * @api private
2535 */
2536
2537 function coverageClass(n) {
2538 if (n >= 75) return 'high';
2539 if (n >= 50) return 'medium';
2540 if (n >= 25) return 'low';
2541 return 'terrible';
2542 }
2543 }); // module: reporters/html-cov.js
2544
2545 require.register("reporters/html.js", function(module, exports, require){
2546
2547 /**
2548 * Module dependencies.
2549 */
2550
2551 var Base = require('./base')
2552 , utils = require('../utils')
2553 , Progress = require('../browser/progress')
2554 , escape = utils.escape;
2555
2556 /**
2557 * Save timer references to avoid Sinon interfering (see GH-237).
2558 */
2559
2560 var Date = global.Date
2561 , setTimeout = global.setTimeout
2562 , setInterval = global.setInterval
2563 , clearTimeout = global.clearTimeout
2564 , clearInterval = global.clearInterval;
2565
2566 /**
2567 * Expose `HTML`.
2568 */
2569
2570 exports = module.exports = HTML;
2571
2572 /**
2573 * Stats template.
2574 */
2575
2576 var statsTemplate = '<ul id="mocha-stats">'
2577 + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
2578 + '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
2579 + '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
2580 + '<li class="duration">duration: <em>0</em>s</li>'
2581 + '</ul>';
2582
2583 /**
2584 * Initialize a new `HTML` reporter.
2585 *
2586 * @param {Runner} runner
2587 * @api public
2588 */
2589
2590 function HTML(runner) {
2591 Base.call(this, runner);
2592
2593 var self = this
2594 , stats = this.stats
2595 , total = runner.total
2596 , stat = fragment(statsTemplate)
2597 , items = stat.getElementsByTagName('li')
2598 , passes = items[1].getElementsByTagName('em')[0]
2599 , passesLink = items[1].getElementsByTagName('a')[0]
2600 , failures = items[2].getElementsByTagName('em')[0]
2601 , failuresLink = items[2].getElementsByTagName('a')[0]
2602 , duration = items[3].getElementsByTagName('em')[0]
2603 , canvas = stat.getElementsByTagName('canvas')[0]
2604 , report = fragment('<ul id="mocha-report"></ul>')
2605 , stack = [report]
2606 , progress
2607 , ctx
2608 , root = document.getElementById('mocha');
2609
2610 if (canvas.getContext) {
2611 var ratio = window.devicePixelRatio || 1;
2612 canvas.style.width = canvas.width;
2613 canvas.style.height = canvas.height;
2614 canvas.width *= ratio;
2615 canvas.height *= ratio;
2616 ctx = canvas.getContext('2d');
2617 ctx.scale(ratio, ratio);
2618 progress = new Progress;
2619 }
2620
2621 if (!root) return error('#mocha div missing, add it to your document');
2622
2623 // pass toggle
2624 on(passesLink, 'click', function(){
2625 unhide();
2626 var name = /pass/.test(report.className) ? '' : ' pass';
2627 report.className = report.className.replace(/fail|pass/g, '') + name;
2628 if (report.className.trim()) hideSuitesWithout('test pass');
2629 });
2630
2631 // failure toggle
2632 on(failuresLink, 'click', function(){
2633 unhide();
2634 var name = /fail/.test(report.className) ? '' : ' fail';
2635 report.className = report.className.replace(/fail|pass/g, '') + name;
2636 if (report.className.trim()) hideSuitesWithout('test fail');
2637 });
2638
2639 root.appendChild(stat);
2640 root.appendChild(report);
2641
2642 if (progress) progress.size(40);
2643
2644 runner.on('suite', function(suite){
2645 if (suite.root) return;
2646
2647 // suite
2648 var url = self.suiteURL(suite);
2649 var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url , escape(suite.title));
2650
2651 // container
2652 stack[0].appendChild(el);
2653 stack.unshift(document.createElement('ul'));
2654 el.appendChild(stack[0]);
2655 });
2656
2657 runner.on('suite end', function(suite){
2658 if (suite.root) return;
2659 stack.shift();
2660 });
2661
2662 runner.on('fail', function(test, err){
2663 if ('hook' == test.type) runner.emit('test end', test);
2664 });
2665
2666 runner.on('test end', function(test){
2667 // TODO: add to stats
2668 var percent = stats.tests / this.total * 100 | 0;
2669 if (progress) progress.update(percent).draw(ctx);
2670
2671 // update stats
2672 var ms = new Date - stats.start;
2673 text(passes, stats.passes);
2674 text(failures, stats.failures);
2675 text(duration, (ms / 1000).toFixed(2));
2676
2677 // test
2678 if ('passed' == test.state) {
2679 var url = self.testURL(test);
2680 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);
2681 } else if (test.pending) {
2682 var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.t itle);
2683 } else {
2684 var el = fragment('<li class="test fail"><h2>%e <a href="?grep=%e" class=" replay">‣</a></h2></li>', test.title, encodeURIComponent(test.fullTitle()));
2685 var str = test.err.stack || test.err.toString();
2686
2687 // FF / Opera do not add the message
2688 if (!~str.indexOf(test.err.message)) {
2689 str = test.err.message + '\n' + str;
2690 }
2691
2692 // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
2693 // check for the result of the stringifying.
2694 if ('[object Error]' == str) str = test.err.message;
2695
2696 // Safari doesn't give you a stack. Let's at least provide a source line.
2697 if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
2698 str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
2699 }
2700
2701 el.appendChild(fragment('<pre class="error">%e</pre>', str));
2702 }
2703
2704 // toggle code
2705 // TODO: defer
2706 if (!test.pending) {
2707 var h2 = el.getElementsByTagName('h2')[0];
2708
2709 on(h2, 'click', function(){
2710 pre.style.display = 'none' == pre.style.display
2711 ? 'block'
2712 : 'none';
2713 });
2714
2715 var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toStr ing()));
2716 el.appendChild(pre);
2717 pre.style.display = 'none';
2718 }
2719
2720 // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
2721 if (stack[0]) stack[0].appendChild(el);
2722 });
2723 }
2724
2725 /**
2726 * Provide suite URL
2727 *
2728 * @param {Object} [suite]
2729 */
2730
2731 HTML.prototype.suiteURL = function(suite){
2732 return '?grep=' + encodeURIComponent(suite.fullTitle());
2733 };
2734
2735 /**
2736 * Provide test URL
2737 *
2738 * @param {Object} [test]
2739 */
2740
2741 HTML.prototype.testURL = function(test){
2742 return '?grep=' + encodeURIComponent(test.fullTitle());
2743 };
2744
2745 /**
2746 * Display error `msg`.
2747 */
2748
2749 function error(msg) {
2750 document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
2751 }
2752
2753 /**
2754 * Return a DOM fragment from `html`.
2755 */
2756
2757 function fragment(html) {
2758 var args = arguments
2759 , div = document.createElement('div')
2760 , i = 1;
2761
2762 div.innerHTML = html.replace(/%([se])/g, function(_, type){
2763 switch (type) {
2764 case 's': return String(args[i++]);
2765 case 'e': return escape(args[i++]);
2766 }
2767 });
2768
2769 return div.firstChild;
2770 }
2771
2772 /**
2773 * Check for suites that do not have elements
2774 * with `classname`, and hide them.
2775 */
2776
2777 function hideSuitesWithout(classname) {
2778 var suites = document.getElementsByClassName('suite');
2779 for (var i = 0; i < suites.length; i++) {
2780 var els = suites[i].getElementsByClassName(classname);
2781 if (0 == els.length) suites[i].className += ' hidden';
2782 }
2783 }
2784
2785 /**
2786 * Unhide .hidden suites.
2787 */
2788
2789 function unhide() {
2790 var els = document.getElementsByClassName('suite hidden');
2791 for (var i = 0; i < els.length; ++i) {
2792 els[i].className = els[i].className.replace('suite hidden', 'suite');
2793 }
2794 }
2795
2796 /**
2797 * Set `el` text to `str`.
2798 */
2799
2800 function text(el, str) {
2801 if (el.textContent) {
2802 el.textContent = str;
2803 } else {
2804 el.innerText = str;
2805 }
2806 }
2807
2808 /**
2809 * Listen on `event` with callback `fn`.
2810 */
2811
2812 function on(el, event, fn) {
2813 if (el.addEventListener) {
2814 el.addEventListener(event, fn, false);
2815 } else {
2816 el.attachEvent('on' + event, fn);
2817 }
2818 }
2819
2820 }); // module: reporters/html.js
2821
2822 require.register("reporters/index.js", function(module, exports, require){
2823
2824 exports.Base = require('./base');
2825 exports.Dot = require('./dot');
2826 exports.Doc = require('./doc');
2827 exports.TAP = require('./tap');
2828 exports.JSON = require('./json');
2829 exports.HTML = require('./html');
2830 exports.List = require('./list');
2831 exports.Min = require('./min');
2832 exports.Spec = require('./spec');
2833 exports.Nyan = require('./nyan');
2834 exports.XUnit = require('./xunit');
2835 exports.Markdown = require('./markdown');
2836 exports.Progress = require('./progress');
2837 exports.Landing = require('./landing');
2838 exports.JSONCov = require('./json-cov');
2839 exports.HTMLCov = require('./html-cov');
2840 exports.JSONStream = require('./json-stream');
2841
2842 }); // module: reporters/index.js
2843
2844 require.register("reporters/json-cov.js", function(module, exports, require){
2845
2846 /**
2847 * Module dependencies.
2848 */
2849
2850 var Base = require('./base');
2851
2852 /**
2853 * Expose `JSONCov`.
2854 */
2855
2856 exports = module.exports = JSONCov;
2857
2858 /**
2859 * Initialize a new `JsCoverage` reporter.
2860 *
2861 * @param {Runner} runner
2862 * @param {Boolean} output
2863 * @api public
2864 */
2865
2866 function JSONCov(runner, output) {
2867 var self = this
2868 , output = 1 == arguments.length ? true : output;
2869
2870 Base.call(this, runner);
2871
2872 var tests = []
2873 , failures = []
2874 , passes = [];
2875
2876 runner.on('test end', function(test){
2877 tests.push(test);
2878 });
2879
2880 runner.on('pass', function(test){
2881 passes.push(test);
2882 });
2883
2884 runner.on('fail', function(test){
2885 failures.push(test);
2886 });
2887
2888 runner.on('end', function(){
2889 var cov = global._$jscoverage || {};
2890 var result = self.cov = map(cov);
2891 result.stats = self.stats;
2892 result.tests = tests.map(clean);
2893 result.failures = failures.map(clean);
2894 result.passes = passes.map(clean);
2895 if (!output) return;
2896 process.stdout.write(JSON.stringify(result, null, 2 ));
2897 });
2898 }
2899
2900 /**
2901 * Map jscoverage data to a JSON structure
2902 * suitable for reporting.
2903 *
2904 * @param {Object} cov
2905 * @return {Object}
2906 * @api private
2907 */
2908
2909 function map(cov) {
2910 var ret = {
2911 instrumentation: 'node-jscoverage'
2912 , sloc: 0
2913 , hits: 0
2914 , misses: 0
2915 , coverage: 0
2916 , files: []
2917 };
2918
2919 for (var filename in cov) {
2920 var data = coverage(filename, cov[filename]);
2921 ret.files.push(data);
2922 ret.hits += data.hits;
2923 ret.misses += data.misses;
2924 ret.sloc += data.sloc;
2925 }
2926
2927 ret.files.sort(function(a, b) {
2928 return a.filename.localeCompare(b.filename);
2929 });
2930
2931 if (ret.sloc > 0) {
2932 ret.coverage = (ret.hits / ret.sloc) * 100;
2933 }
2934
2935 return ret;
2936 };
2937
2938 /**
2939 * Map jscoverage data for a single source file
2940 * to a JSON structure suitable for reporting.
2941 *
2942 * @param {String} filename name of the source file
2943 * @param {Object} data jscoverage coverage data
2944 * @return {Object}
2945 * @api private
2946 */
2947
2948 function coverage(filename, data) {
2949 var ret = {
2950 filename: filename,
2951 coverage: 0,
2952 hits: 0,
2953 misses: 0,
2954 sloc: 0,
2955 source: {}
2956 };
2957
2958 data.source.forEach(function(line, num){
2959 num++;
2960
2961 if (data[num] === 0) {
2962 ret.misses++;
2963 ret.sloc++;
2964 } else if (data[num] !== undefined) {
2965 ret.hits++;
2966 ret.sloc++;
2967 }
2968
2969 ret.source[num] = {
2970 source: line
2971 , coverage: data[num] === undefined
2972 ? ''
2973 : data[num]
2974 };
2975 });
2976
2977 ret.coverage = ret.hits / ret.sloc * 100;
2978
2979 return ret;
2980 }
2981
2982 /**
2983 * Return a plain-object representation of `test`
2984 * free of cyclic properties etc.
2985 *
2986 * @param {Object} test
2987 * @return {Object}
2988 * @api private
2989 */
2990
2991 function clean(test) {
2992 return {
2993 title: test.title
2994 , fullTitle: test.fullTitle()
2995 , duration: test.duration
2996 }
2997 }
2998
2999 }); // module: reporters/json-cov.js
3000
3001 require.register("reporters/json-stream.js", function(module, exports, require){
3002
3003 /**
3004 * Module dependencies.
3005 */
3006
3007 var Base = require('./base')
3008 , color = Base.color;
3009
3010 /**
3011 * Expose `List`.
3012 */
3013
3014 exports = module.exports = List;
3015
3016 /**
3017 * Initialize a new `List` test reporter.
3018 *
3019 * @param {Runner} runner
3020 * @api public
3021 */
3022
3023 function List(runner) {
3024 Base.call(this, runner);
3025
3026 var self = this
3027 , stats = this.stats
3028 , total = runner.total;
3029
3030 runner.on('start', function(){
3031 console.log(JSON.stringify(['start', { total: total }]));
3032 });
3033
3034 runner.on('pass', function(test){
3035 console.log(JSON.stringify(['pass', clean(test)]));
3036 });
3037
3038 runner.on('fail', function(test, err){
3039 console.log(JSON.stringify(['fail', clean(test)]));
3040 });
3041
3042 runner.on('end', function(){
3043 process.stdout.write(JSON.stringify(['end', self.stats]));
3044 });
3045 }
3046
3047 /**
3048 * Return a plain-object representation of `test`
3049 * free of cyclic properties etc.
3050 *
3051 * @param {Object} test
3052 * @return {Object}
3053 * @api private
3054 */
3055
3056 function clean(test) {
3057 return {
3058 title: test.title
3059 , fullTitle: test.fullTitle()
3060 , duration: test.duration
3061 }
3062 }
3063 }); // module: reporters/json-stream.js
3064
3065 require.register("reporters/json.js", function(module, exports, require){
3066
3067 /**
3068 * Module dependencies.
3069 */
3070
3071 var Base = require('./base')
3072 , cursor = Base.cursor
3073 , color = Base.color;
3074
3075 /**
3076 * Expose `JSON`.
3077 */
3078
3079 exports = module.exports = JSONReporter;
3080
3081 /**
3082 * Initialize a new `JSON` reporter.
3083 *
3084 * @param {Runner} runner
3085 * @api public
3086 */
3087
3088 function JSONReporter(runner) {
3089 var self = this;
3090 Base.call(this, runner);
3091
3092 var tests = []
3093 , failures = []
3094 , passes = [];
3095
3096 runner.on('test end', function(test){
3097 tests.push(test);
3098 });
3099
3100 runner.on('pass', function(test){
3101 passes.push(test);
3102 });
3103
3104 runner.on('fail', function(test){
3105 failures.push(test);
3106 });
3107
3108 runner.on('end', function(){
3109 var obj = {
3110 stats: self.stats
3111 , tests: tests.map(clean)
3112 , failures: failures.map(clean)
3113 , passes: passes.map(clean)
3114 };
3115
3116 process.stdout.write(JSON.stringify(obj, null, 2));
3117 });
3118 }
3119
3120 /**
3121 * Return a plain-object representation of `test`
3122 * free of cyclic properties etc.
3123 *
3124 * @param {Object} test
3125 * @return {Object}
3126 * @api private
3127 */
3128
3129 function clean(test) {
3130 return {
3131 title: test.title
3132 , fullTitle: test.fullTitle()
3133 , duration: test.duration
3134 }
3135 }
3136 }); // module: reporters/json.js
3137
3138 require.register("reporters/landing.js", function(module, exports, require){
3139
3140 /**
3141 * Module dependencies.
3142 */
3143
3144 var Base = require('./base')
3145 , cursor = Base.cursor
3146 , color = Base.color;
3147
3148 /**
3149 * Expose `Landing`.
3150 */
3151
3152 exports = module.exports = Landing;
3153
3154 /**
3155 * Airplane color.
3156 */
3157
3158 Base.colors.plane = 0;
3159
3160 /**
3161 * Airplane crash color.
3162 */
3163
3164 Base.colors['plane crash'] = 31;
3165
3166 /**
3167 * Runway color.
3168 */
3169
3170 Base.colors.runway = 90;
3171
3172 /**
3173 * Initialize a new `Landing` reporter.
3174 *
3175 * @param {Runner} runner
3176 * @api public
3177 */
3178
3179 function Landing(runner) {
3180 Base.call(this, runner);
3181
3182 var self = this
3183 , stats = this.stats
3184 , width = Base.window.width * .75 | 0
3185 , total = runner.total
3186 , stream = process.stdout
3187 , plane = color('plane', '✈')
3188 , crashed = -1
3189 , n = 0;
3190
3191 function runway() {
3192 var buf = Array(width).join('-');
3193 return ' ' + color('runway', buf);
3194 }
3195
3196 runner.on('start', function(){
3197 stream.write('\n ');
3198 cursor.hide();
3199 });
3200
3201 runner.on('test end', function(test){
3202 // check if the plane crashed
3203 var col = -1 == crashed
3204 ? width * ++n / total | 0
3205 : crashed;
3206
3207 // show the crash
3208 if ('failed' == test.state) {
3209 plane = color('plane crash', '✈');
3210 crashed = col;
3211 }
3212
3213 // render landing strip
3214 stream.write('\u001b[4F\n\n');
3215 stream.write(runway());
3216 stream.write('\n ');
3217 stream.write(color('runway', Array(col).join('â‹…')));
3218 stream.write(plane)
3219 stream.write(color('runway', Array(width - col).join('â‹…') + '\n'));
3220 stream.write(runway());
3221 stream.write('\u001b[0m');
3222 });
3223
3224 runner.on('end', function(){
3225 cursor.show();
3226 console.log();
3227 self.epilogue();
3228 });
3229 }
3230
3231 /**
3232 * Inherit from `Base.prototype`.
3233 */
3234
3235 function F(){};
3236 F.prototype = Base.prototype;
3237 Landing.prototype = new F;
3238 Landing.prototype.constructor = Landing;
3239
3240 }); // module: reporters/landing.js
3241
3242 require.register("reporters/list.js", function(module, exports, require){
3243
3244 /**
3245 * Module dependencies.
3246 */
3247
3248 var Base = require('./base')
3249 , cursor = Base.cursor
3250 , color = Base.color;
3251
3252 /**
3253 * Expose `List`.
3254 */
3255
3256 exports = module.exports = List;
3257
3258 /**
3259 * Initialize a new `List` test reporter.
3260 *
3261 * @param {Runner} runner
3262 * @api public
3263 */
3264
3265 function List(runner) {
3266 Base.call(this, runner);
3267
3268 var self = this
3269 , stats = this.stats
3270 , n = 0;
3271
3272 runner.on('start', function(){
3273 console.log();
3274 });
3275
3276 runner.on('test', function(test){
3277 process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
3278 });
3279
3280 runner.on('pending', function(test){
3281 var fmt = color('checkmark', ' -')
3282 + color('pending', ' %s');
3283 console.log(fmt, test.fullTitle());
3284 });
3285
3286 runner.on('pass', function(test){
3287 var fmt = color('checkmark', ' '+Base.symbols.dot)
3288 + color('pass', ' %s: ')
3289 + color(test.speed, '%dms');
3290 cursor.CR();
3291 console.log(fmt, test.fullTitle(), test.duration);
3292 });
3293
3294 runner.on('fail', function(test, err){
3295 cursor.CR();
3296 console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
3297 });
3298
3299 runner.on('end', self.epilogue.bind(self));
3300 }
3301
3302 /**
3303 * Inherit from `Base.prototype`.
3304 */
3305
3306 function F(){};
3307 F.prototype = Base.prototype;
3308 List.prototype = new F;
3309 List.prototype.constructor = List;
3310
3311
3312 }); // module: reporters/list.js
3313
3314 require.register("reporters/markdown.js", function(module, exports, require){
3315 /**
3316 * Module dependencies.
3317 */
3318
3319 var Base = require('./base')
3320 , utils = require('../utils');
3321
3322 /**
3323 * Expose `Markdown`.
3324 */
3325
3326 exports = module.exports = Markdown;
3327
3328 /**
3329 * Initialize a new `Markdown` reporter.
3330 *
3331 * @param {Runner} runner
3332 * @api public
3333 */
3334
3335 function Markdown(runner) {
3336 Base.call(this, runner);
3337
3338 var self = this
3339 , stats = this.stats
3340 , level = 0
3341 , buf = '';
3342
3343 function title(str) {
3344 return Array(level).join('#') + ' ' + str;
3345 }
3346
3347 function indent() {
3348 return Array(level).join(' ');
3349 }
3350
3351 function mapTOC(suite, obj) {
3352 var ret = obj;
3353 obj = obj[suite.title] = obj[suite.title] || { suite: suite };
3354 suite.suites.forEach(function(suite){
3355 mapTOC(suite, obj);
3356 });
3357 return ret;
3358 }
3359
3360 function stringifyTOC(obj, level) {
3361 ++level;
3362 var buf = '';
3363 var link;
3364 for (var key in obj) {
3365 if ('suite' == key) continue;
3366 if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle ()) + ')\n';
3367 if (key) buf += Array(level).join(' ') + link;
3368 buf += stringifyTOC(obj[key], level);
3369 }
3370 --level;
3371 return buf;
3372 }
3373
3374 function generateTOC(suite) {
3375 var obj = mapTOC(suite, {});
3376 return stringifyTOC(obj, 0);
3377 }
3378
3379 generateTOC(runner.suite);
3380
3381 runner.on('suite', function(suite){
3382 ++level;
3383 var slug = utils.slug(suite.fullTitle());
3384 buf += '<a name="' + slug + '"></a>' + '\n';
3385 buf += title(suite.title) + '\n';
3386 });
3387
3388 runner.on('suite end', function(suite){
3389 --level;
3390 });
3391
3392 runner.on('pass', function(test){
3393 var code = utils.clean(test.fn.toString());
3394 buf += test.title + '.\n';
3395 buf += '\n```js\n';
3396 buf += code + '\n';
3397 buf += '```\n\n';
3398 });
3399
3400 runner.on('end', function(){
3401 process.stdout.write('# TOC\n');
3402 process.stdout.write(generateTOC(runner.suite));
3403 process.stdout.write(buf);
3404 });
3405 }
3406 }); // module: reporters/markdown.js
3407
3408 require.register("reporters/min.js", function(module, exports, require){
3409
3410 /**
3411 * Module dependencies.
3412 */
3413
3414 var Base = require('./base');
3415
3416 /**
3417 * Expose `Min`.
3418 */
3419
3420 exports = module.exports = Min;
3421
3422 /**
3423 * Initialize a new `Min` minimal test reporter (best used with --watch).
3424 *
3425 * @param {Runner} runner
3426 * @api public
3427 */
3428
3429 function Min(runner) {
3430 Base.call(this, runner);
3431
3432 runner.on('start', function(){
3433 // clear screen
3434 process.stdout.write('\u001b[2J');
3435 // set cursor position
3436 process.stdout.write('\u001b[1;3H');
3437 });
3438
3439 runner.on('end', this.epilogue.bind(this));
3440 }
3441
3442 /**
3443 * Inherit from `Base.prototype`.
3444 */
3445
3446 function F(){};
3447 F.prototype = Base.prototype;
3448 Min.prototype = new F;
3449 Min.prototype.constructor = Min;
3450
3451
3452 }); // module: reporters/min.js
3453
3454 require.register("reporters/nyan.js", function(module, exports, require){
3455 /**
3456 * Module dependencies.
3457 */
3458
3459 var Base = require('./base')
3460 , color = Base.color;
3461
3462 /**
3463 * Expose `Dot`.
3464 */
3465
3466 exports = module.exports = NyanCat;
3467
3468 /**
3469 * Initialize a new `Dot` matrix test reporter.
3470 *
3471 * @param {Runner} runner
3472 * @api public
3473 */
3474
3475 function NyanCat(runner) {
3476 Base.call(this, runner);
3477 var self = this
3478 , stats = this.stats
3479 , width = Base.window.width * .75 | 0
3480 , rainbowColors = this.rainbowColors = self.generateColors()
3481 , colorIndex = this.colorIndex = 0
3482 , numerOfLines = this.numberOfLines = 4
3483 , trajectories = this.trajectories = [[], [], [], []]
3484 , nyanCatWidth = this.nyanCatWidth = 11
3485 , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
3486 , scoreboardWidth = this.scoreboardWidth = 5
3487 , tick = this.tick = 0
3488 , n = 0;
3489
3490 runner.on('start', function(){
3491 Base.cursor.hide();
3492 self.draw();
3493 });
3494
3495 runner.on('pending', function(test){
3496 self.draw();
3497 });
3498
3499 runner.on('pass', function(test){
3500 self.draw();
3501 });
3502
3503 runner.on('fail', function(test, err){
3504 self.draw();
3505 });
3506
3507 runner.on('end', function(){
3508 Base.cursor.show();
3509 for (var i = 0; i < self.numberOfLines; i++) write('\n');
3510 self.epilogue();
3511 });
3512 }
3513
3514 /**
3515 * Draw the nyan cat
3516 *
3517 * @api private
3518 */
3519
3520 NyanCat.prototype.draw = function(){
3521 this.appendRainbow();
3522 this.drawScoreboard();
3523 this.drawRainbow();
3524 this.drawNyanCat();
3525 this.tick = !this.tick;
3526 };
3527
3528 /**
3529 * Draw the "scoreboard" showing the number
3530 * of passes, failures and pending tests.
3531 *
3532 * @api private
3533 */
3534
3535 NyanCat.prototype.drawScoreboard = function(){
3536 var stats = this.stats;
3537 var colors = Base.colors;
3538
3539 function draw(color, n) {
3540 write(' ');
3541 write('\u001b[' + color + 'm' + n + '\u001b[0m');
3542 write('\n');
3543 }
3544
3545 draw(colors.green, stats.passes);
3546 draw(colors.fail, stats.failures);
3547 draw(colors.pending, stats.pending);
3548 write('\n');
3549
3550 this.cursorUp(this.numberOfLines);
3551 };
3552
3553 /**
3554 * Append the rainbow.
3555 *
3556 * @api private
3557 */
3558
3559 NyanCat.prototype.appendRainbow = function(){
3560 var segment = this.tick ? '_' : '-';
3561 var rainbowified = this.rainbowify(segment);
3562
3563 for (var index = 0; index < this.numberOfLines; index++) {
3564 var trajectory = this.trajectories[index];
3565 if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
3566 trajectory.push(rainbowified);
3567 }
3568 };
3569
3570 /**
3571 * Draw the rainbow.
3572 *
3573 * @api private
3574 */
3575
3576 NyanCat.prototype.drawRainbow = function(){
3577 var self = this;
3578
3579 this.trajectories.forEach(function(line, index) {
3580 write('\u001b[' + self.scoreboardWidth + 'C');
3581 write(line.join(''));
3582 write('\n');
3583 });
3584
3585 this.cursorUp(this.numberOfLines);
3586 };
3587
3588 /**
3589 * Draw the nyan cat
3590 *
3591 * @api private
3592 */
3593
3594 NyanCat.prototype.drawNyanCat = function() {
3595 var self = this;
3596 var startWidth = this.scoreboardWidth + this.trajectories[0].length;
3597 var color = '\u001b[' + startWidth + 'C';
3598 var padding = '';
3599
3600 write(color);
3601 write('_,------,');
3602 write('\n');
3603
3604 write(color);
3605 padding = self.tick ? ' ' : ' ';
3606 write('_|' + padding + '/\\_/\\ ');
3607 write('\n');
3608
3609 write(color);
3610 padding = self.tick ? '_' : '__';
3611 var tail = self.tick ? '~' : '^';
3612 var face;
3613 write(tail + '|' + padding + this.face() + ' ');
3614 write('\n');
3615
3616 write(color);
3617 padding = self.tick ? ' ' : ' ';
3618 write(padding + '"" "" ');
3619 write('\n');
3620
3621 this.cursorUp(this.numberOfLines);
3622 };
3623
3624 /**
3625 * Draw nyan cat face.
3626 *
3627 * @return {String}
3628 * @api private
3629 */
3630
3631 NyanCat.prototype.face = function() {
3632 var stats = this.stats;
3633 if (stats.failures) {
3634 return '( x .x)';
3635 } else if (stats.pending) {
3636 return '( o .o)';
3637 } else if(stats.passes) {
3638 return '( ^ .^)';
3639 } else {
3640 return '( - .-)';
3641 }
3642 }
3643
3644 /**
3645 * Move cursor up `n`.
3646 *
3647 * @param {Number} n
3648 * @api private
3649 */
3650
3651 NyanCat.prototype.cursorUp = function(n) {
3652 write('\u001b[' + n + 'A');
3653 };
3654
3655 /**
3656 * Move cursor down `n`.
3657 *
3658 * @param {Number} n
3659 * @api private
3660 */
3661
3662 NyanCat.prototype.cursorDown = function(n) {
3663 write('\u001b[' + n + 'B');
3664 };
3665
3666 /**
3667 * Generate rainbow colors.
3668 *
3669 * @return {Array}
3670 * @api private
3671 */
3672
3673 NyanCat.prototype.generateColors = function(){
3674 var colors = [];
3675
3676 for (var i = 0; i < (6 * 7); i++) {
3677 var pi3 = Math.floor(Math.PI / 3);
3678 var n = (i * (1.0 / 6));
3679 var r = Math.floor(3 * Math.sin(n) + 3);
3680 var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
3681 var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
3682 colors.push(36 * r + 6 * g + b + 16);
3683 }
3684
3685 return colors;
3686 };
3687
3688 /**
3689 * Apply rainbow to the given `str`.
3690 *
3691 * @param {String} str
3692 * @return {String}
3693 * @api private
3694 */
3695
3696 NyanCat.prototype.rainbowify = function(str){
3697 var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
3698 this.colorIndex += 1;
3699 return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
3700 };
3701
3702 /**
3703 * Stdout helper.
3704 */
3705
3706 function write(string) {
3707 process.stdout.write(string);
3708 }
3709
3710 /**
3711 * Inherit from `Base.prototype`.
3712 */
3713
3714 function F(){};
3715 F.prototype = Base.prototype;
3716 NyanCat.prototype = new F;
3717 NyanCat.prototype.constructor = NyanCat;
3718
3719
3720 }); // module: reporters/nyan.js
3721
3722 require.register("reporters/progress.js", function(module, exports, require){
3723
3724 /**
3725 * Module dependencies.
3726 */
3727
3728 var Base = require('./base')
3729 , cursor = Base.cursor
3730 , color = Base.color;
3731
3732 /**
3733 * Expose `Progress`.
3734 */
3735
3736 exports = module.exports = Progress;
3737
3738 /**
3739 * General progress bar color.
3740 */
3741
3742 Base.colors.progress = 90;
3743
3744 /**
3745 * Initialize a new `Progress` bar test reporter.
3746 *
3747 * @param {Runner} runner
3748 * @param {Object} options
3749 * @api public
3750 */
3751
3752 function Progress(runner, options) {
3753 Base.call(this, runner);
3754
3755 var self = this
3756 , options = options || {}
3757 , stats = this.stats
3758 , width = Base.window.width * .50 | 0
3759 , total = runner.total
3760 , complete = 0
3761 , max = Math.max;
3762
3763 // default chars
3764 options.open = options.open || '[';
3765 options.complete = options.complete || 'â–¬';
3766 options.incomplete = options.incomplete || Base.symbols.dot;
3767 options.close = options.close || ']';
3768 options.verbose = false;
3769
3770 // tests started
3771 runner.on('start', function(){
3772 console.log();
3773 cursor.hide();
3774 });
3775
3776 // tests complete
3777 runner.on('test end', function(){
3778 complete++;
3779 var incomplete = total - complete
3780 , percent = complete / total
3781 , n = width * percent | 0
3782 , i = width - n;
3783
3784 cursor.CR();
3785 process.stdout.write('\u001b[J');
3786 process.stdout.write(color('progress', ' ' + options.open));
3787 process.stdout.write(Array(n).join(options.complete));
3788 process.stdout.write(Array(i).join(options.incomplete));
3789 process.stdout.write(color('progress', options.close));
3790 if (options.verbose) {
3791 process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
3792 }
3793 });
3794
3795 // tests are complete, output some stats
3796 // and the failures if any
3797 runner.on('end', function(){
3798 cursor.show();
3799 console.log();
3800 self.epilogue();
3801 });
3802 }
3803
3804 /**
3805 * Inherit from `Base.prototype`.
3806 */
3807
3808 function F(){};
3809 F.prototype = Base.prototype;
3810 Progress.prototype = new F;
3811 Progress.prototype.constructor = Progress;
3812
3813
3814 }); // module: reporters/progress.js
3815
3816 require.register("reporters/spec.js", function(module, exports, require){
3817
3818 /**
3819 * Module dependencies.
3820 */
3821
3822 var Base = require('./base')
3823 , cursor = Base.cursor
3824 , color = Base.color;
3825
3826 /**
3827 * Expose `Spec`.
3828 */
3829
3830 exports = module.exports = Spec;
3831
3832 /**
3833 * Initialize a new `Spec` test reporter.
3834 *
3835 * @param {Runner} runner
3836 * @api public
3837 */
3838
3839 function Spec(runner) {
3840 Base.call(this, runner);
3841
3842 var self = this
3843 , stats = this.stats
3844 , indents = 0
3845 , n = 0;
3846
3847 function indent() {
3848 return Array(indents).join(' ')
3849 }
3850
3851 runner.on('start', function(){
3852 console.log();
3853 });
3854
3855 runner.on('suite', function(suite){
3856 ++indents;
3857 console.log(color('suite', '%s%s'), indent(), suite.title);
3858 });
3859
3860 runner.on('suite end', function(suite){
3861 --indents;
3862 if (1 == indents) console.log();
3863 });
3864
3865 runner.on('pending', function(test){
3866 var fmt = indent() + color('pending', ' - %s');
3867 console.log(fmt, test.title);
3868 });
3869
3870 runner.on('pass', function(test){
3871 if ('fast' == test.speed) {
3872 var fmt = indent()
3873 + color('checkmark', ' ' + Base.symbols.ok)
3874 + color('pass', ' %s ');
3875 cursor.CR();
3876 console.log(fmt, test.title);
3877 } else {
3878 var fmt = indent()
3879 + color('checkmark', ' ' + Base.symbols.ok)
3880 + color('pass', ' %s ')
3881 + color(test.speed, '(%dms)');
3882 cursor.CR();
3883 console.log(fmt, test.title, test.duration);
3884 }
3885 });
3886
3887 runner.on('fail', function(test, err){
3888 cursor.CR();
3889 console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
3890 });
3891
3892 runner.on('end', self.epilogue.bind(self));
3893 }
3894
3895 /**
3896 * Inherit from `Base.prototype`.
3897 */
3898
3899 function F(){};
3900 F.prototype = Base.prototype;
3901 Spec.prototype = new F;
3902 Spec.prototype.constructor = Spec;
3903
3904
3905 }); // module: reporters/spec.js
3906
3907 require.register("reporters/tap.js", function(module, exports, require){
3908
3909 /**
3910 * Module dependencies.
3911 */
3912
3913 var Base = require('./base')
3914 , cursor = Base.cursor
3915 , color = Base.color;
3916
3917 /**
3918 * Expose `TAP`.
3919 */
3920
3921 exports = module.exports = TAP;
3922
3923 /**
3924 * Initialize a new `TAP` reporter.
3925 *
3926 * @param {Runner} runner
3927 * @api public
3928 */
3929
3930 function TAP(runner) {
3931 Base.call(this, runner);
3932
3933 var self = this
3934 , stats = this.stats
3935 , n = 1
3936 , passes = 0
3937 , failures = 0;
3938
3939 runner.on('start', function(){
3940 var total = runner.grepTotal(runner.suite);
3941 console.log('%d..%d', 1, total);
3942 });
3943
3944 runner.on('test end', function(){
3945 ++n;
3946 });
3947
3948 runner.on('pending', function(test){
3949 console.log('ok %d %s # SKIP -', n, title(test));
3950 });
3951
3952 runner.on('pass', function(test){
3953 passes++;
3954 console.log('ok %d %s', n, title(test));
3955 });
3956
3957 runner.on('fail', function(test, err){
3958 failures++;
3959 console.log('not ok %d %s', n, title(test));
3960 if (err.stack) console.log(err.stack.replace(/^/gm, ' '));
3961 });
3962
3963 runner.on('end', function(){
3964 console.log('# tests ' + (passes + failures));
3965 console.log('# pass ' + passes);
3966 console.log('# fail ' + failures);
3967 });
3968 }
3969
3970 /**
3971 * Return a TAP-safe title of `test`
3972 *
3973 * @param {Object} test
3974 * @return {String}
3975 * @api private
3976 */
3977
3978 function title(test) {
3979 return test.fullTitle().replace(/#/g, '');
3980 }
3981
3982 }); // module: reporters/tap.js
3983
3984 require.register("reporters/xunit.js", function(module, exports, require){
3985
3986 /**
3987 * Module dependencies.
3988 */
3989
3990 var Base = require('./base')
3991 , utils = require('../utils')
3992 , escape = utils.escape;
3993
3994 /**
3995 * Save timer references to avoid Sinon interfering (see GH-237).
3996 */
3997
3998 var Date = global.Date
3999 , setTimeout = global.setTimeout
4000 , setInterval = global.setInterval
4001 , clearTimeout = global.clearTimeout
4002 , clearInterval = global.clearInterval;
4003
4004 /**
4005 * Expose `XUnit`.
4006 */
4007
4008 exports = module.exports = XUnit;
4009
4010 /**
4011 * Initialize a new `XUnit` reporter.
4012 *
4013 * @param {Runner} runner
4014 * @api public
4015 */
4016
4017 function XUnit(runner) {
4018 Base.call(this, runner);
4019 var stats = this.stats
4020 , tests = []
4021 , self = this;
4022
4023 runner.on('pending', function(test){
4024 tests.push(test);
4025 });
4026
4027 runner.on('pass', function(test){
4028 tests.push(test);
4029 });
4030
4031 runner.on('fail', function(test){
4032 tests.push(test);
4033 });
4034
4035 runner.on('end', function(){
4036 console.log(tag('testsuite', {
4037 name: 'Mocha Tests'
4038 , tests: stats.tests
4039 , failures: stats.failures
4040 , errors: stats.failures
4041 , skipped: stats.tests - stats.failures - stats.passes
4042 , timestamp: (new Date).toUTCString()
4043 , time: (stats.duration / 1000) || 0
4044 }, false));
4045
4046 tests.forEach(test);
4047 console.log('</testsuite>');
4048 });
4049 }
4050
4051 /**
4052 * Inherit from `Base.prototype`.
4053 */
4054
4055 function F(){};
4056 F.prototype = Base.prototype;
4057 XUnit.prototype = new F;
4058 XUnit.prototype.constructor = XUnit;
4059
4060
4061 /**
4062 * Output tag for the given `test.`
4063 */
4064
4065 function test(test) {
4066 var attrs = {
4067 classname: test.parent.fullTitle()
4068 , name: test.title
4069 , time: (test.duration / 1000) || 0
4070 };
4071
4072 if ('failed' == test.state) {
4073 var err = test.err;
4074 attrs.message = escape(err.message);
4075 console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata (err.stack))));
4076 } else if (test.pending) {
4077 console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
4078 } else {
4079 console.log(tag('testcase', attrs, true) );
4080 }
4081 }
4082
4083 /**
4084 * HTML tag helper.
4085 */
4086
4087 function tag(name, attrs, close, content) {
4088 var end = close ? '/>' : '>'
4089 , pairs = []
4090 , tag;
4091
4092 for (var key in attrs) {
4093 pairs.push(key + '="' + escape(attrs[key]) + '"');
4094 }
4095
4096 tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
4097 if (content) tag += content + '</' + name + end;
4098 return tag;
4099 }
4100
4101 /**
4102 * Return cdata escaped CDATA `str`.
4103 */
4104
4105 function cdata(str) {
4106 return '<![CDATA[' + escape(str) + ']]>';
4107 }
4108
4109 }); // module: reporters/xunit.js
4110
4111 require.register("runnable.js", function(module, exports, require){
4112
4113 /**
4114 * Module dependencies.
4115 */
4116
4117 var EventEmitter = require('browser/events').EventEmitter
4118 , debug = require('browser/debug')('mocha:runnable')
4119 , milliseconds = require('./ms');
4120
4121 /**
4122 * Save timer references to avoid Sinon interfering (see GH-237).
4123 */
4124
4125 var Date = global.Date
4126 , setTimeout = global.setTimeout
4127 , setInterval = global.setInterval
4128 , clearTimeout = global.clearTimeout
4129 , clearInterval = global.clearInterval;
4130
4131 /**
4132 * Object#toString().
4133 */
4134
4135 var toString = Object.prototype.toString;
4136
4137 /**
4138 * Expose `Runnable`.
4139 */
4140
4141 module.exports = Runnable;
4142
4143 /**
4144 * Initialize a new `Runnable` with the given `title` and callback `fn`.
4145 *
4146 * @param {String} title
4147 * @param {Function} fn
4148 * @api private
4149 */
4150
4151 function Runnable(title, fn) {
4152 this.title = title;
4153 this.fn = fn;
4154 this.async = fn && fn.length;
4155 this.sync = ! this.async;
4156 this._timeout = 2000;
4157 this._slow = 75;
4158 this.timedOut = false;
4159 }
4160
4161 /**
4162 * Inherit from `EventEmitter.prototype`.
4163 */
4164
4165 function F(){};
4166 F.prototype = EventEmitter.prototype;
4167 Runnable.prototype = new F;
4168 Runnable.prototype.constructor = Runnable;
4169
4170
4171 /**
4172 * Set & get timeout `ms`.
4173 *
4174 * @param {Number|String} ms
4175 * @return {Runnable|Number} ms or self
4176 * @api private
4177 */
4178
4179 Runnable.prototype.timeout = function(ms){
4180 if (0 == arguments.length) return this._timeout;
4181 if ('string' == typeof ms) ms = milliseconds(ms);
4182 debug('timeout %d', ms);
4183 this._timeout = ms;
4184 if (this.timer) this.resetTimeout();
4185 return this;
4186 };
4187
4188 /**
4189 * Set & get slow `ms`.
4190 *
4191 * @param {Number|String} ms
4192 * @return {Runnable|Number} ms or self
4193 * @api private
4194 */
4195
4196 Runnable.prototype.slow = function(ms){
4197 if (0 === arguments.length) return this._slow;
4198 if ('string' == typeof ms) ms = milliseconds(ms);
4199 debug('timeout %d', ms);
4200 this._slow = ms;
4201 return this;
4202 };
4203
4204 /**
4205 * Return the full title generated by recursively
4206 * concatenating the parent's full title.
4207 *
4208 * @return {String}
4209 * @api public
4210 */
4211
4212 Runnable.prototype.fullTitle = function(){
4213 return this.parent.fullTitle() + ' ' + this.title;
4214 };
4215
4216 /**
4217 * Clear the timeout.
4218 *
4219 * @api private
4220 */
4221
4222 Runnable.prototype.clearTimeout = function(){
4223 clearTimeout(this.timer);
4224 };
4225
4226 /**
4227 * Inspect the runnable void of private properties.
4228 *
4229 * @return {String}
4230 * @api private
4231 */
4232
4233 Runnable.prototype.inspect = function(){
4234 return JSON.stringify(this, function(key, val){
4235 if ('_' == key[0]) return;
4236 if ('parent' == key) return '#<Suite>';
4237 if ('ctx' == key) return '#<Context>';
4238 return val;
4239 }, 2);
4240 };
4241
4242 /**
4243 * Reset the timeout.
4244 *
4245 * @api private
4246 */
4247
4248 Runnable.prototype.resetTimeout = function(){
4249 var self = this;
4250 var ms = this.timeout() || 1e9;
4251
4252 this.clearTimeout();
4253 this.timer = setTimeout(function(){
4254 self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
4255 self.timedOut = true;
4256 }, ms);
4257 };
4258
4259 /**
4260 * Whitelist these globals for this test run
4261 *
4262 * @api private
4263 */
4264 Runnable.prototype.globals = function(arr){
4265 var self = this;
4266 this._allowedGlobals = arr;
4267 };
4268
4269 /**
4270 * Run the test and invoke `fn(err)`.
4271 *
4272 * @param {Function} fn
4273 * @api private
4274 */
4275
4276 Runnable.prototype.run = function(fn){
4277 var self = this
4278 , ms = this.timeout()
4279 , start = new Date
4280 , ctx = this.ctx
4281 , finished
4282 , emitted;
4283
4284 if (ctx) ctx.runnable(this);
4285
4286 // called multiple times
4287 function multiple(err) {
4288 if (emitted) return;
4289 emitted = true;
4290 self.emit('error', err || new Error('done() called multiple times'));
4291 }
4292
4293 // finished
4294 function done(err) {
4295 if (self.timedOut) return;
4296 if (finished) return multiple(err);
4297 self.clearTimeout();
4298 self.duration = new Date - start;
4299 finished = true;
4300 fn(err);
4301 }
4302
4303 // for .resetTimeout()
4304 this.callback = done;
4305
4306 // explicit async with `done` argument
4307 if (this.async) {
4308 this.resetTimeout();
4309
4310 try {
4311 this.fn.call(ctx, function(err){
4312 if (err instanceof Error || toString.call(err) === "[object Error]") ret urn done(err);
4313 if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
4314 done();
4315 });
4316 } catch (err) {
4317 done(err);
4318 }
4319 return;
4320 }
4321
4322 if (this.asyncOnly) {
4323 return done(new Error('--async-only option in use without declaring `done()` '));
4324 }
4325
4326 // sync or promise-returning
4327 try {
4328 if (this.pending) {
4329 done();
4330 } else {
4331 callFn(this.fn);
4332 }
4333 } catch (err) {
4334 done(err);
4335 }
4336
4337 function callFn(fn) {
4338 var result = fn.call(ctx);
4339 if (result && typeof result.then === 'function') {
4340 self.resetTimeout();
4341 result.then(function(){ done() }, done);
4342 } else {
4343 done();
4344 }
4345 }
4346 };
4347
4348 }); // module: runnable.js
4349
4350 require.register("runner.js", function(module, exports, require){
4351 /**
4352 * Module dependencies.
4353 */
4354
4355 var EventEmitter = require('browser/events').EventEmitter
4356 , debug = require('browser/debug')('mocha:runner')
4357 , Test = require('./test')
4358 , utils = require('./utils')
4359 , filter = utils.filter
4360 , keys = utils.keys;
4361
4362 /**
4363 * Non-enumerable globals.
4364 */
4365
4366 var globals = [
4367 'setTimeout',
4368 'clearTimeout',
4369 'setInterval',
4370 'clearInterval',
4371 'XMLHttpRequest',
4372 'Date'
4373 ];
4374
4375 /**
4376 * Expose `Runner`.
4377 */
4378
4379 module.exports = Runner;
4380
4381 /**
4382 * Initialize a `Runner` for the given `suite`.
4383 *
4384 * Events:
4385 *
4386 * - `start` execution started
4387 * - `end` execution complete
4388 * - `suite` (suite) test suite execution started
4389 * - `suite end` (suite) all tests (and sub-suites) have finished
4390 * - `test` (test) test execution started
4391 * - `test end` (test) test completed
4392 * - `hook` (hook) hook execution started
4393 * - `hook end` (hook) hook complete
4394 * - `pass` (test) test passed
4395 * - `fail` (test, err) test failed
4396 * - `pending` (test) test pending
4397 *
4398 * @api public
4399 */
4400
4401 function Runner(suite) {
4402 var self = this;
4403 this._globals = [];
4404 this._abort = false;
4405 this.suite = suite;
4406 this.total = suite.total();
4407 this.failures = 0;
4408 this.on('test end', function(test){ self.checkGlobals(test); });
4409 this.on('hook end', function(hook){ self.checkGlobals(hook); });
4410 this.grep(/.*/);
4411 this.globals(this.globalProps().concat(extraGlobals()));
4412 }
4413
4414 /**
4415 * Wrapper for setImmediate, process.nextTick, or browser polyfill.
4416 *
4417 * @param {Function} fn
4418 * @api private
4419 */
4420
4421 Runner.immediately = global.setImmediate || process.nextTick;
4422
4423 /**
4424 * Inherit from `EventEmitter.prototype`.
4425 */
4426
4427 function F(){};
4428 F.prototype = EventEmitter.prototype;
4429 Runner.prototype = new F;
4430 Runner.prototype.constructor = Runner;
4431
4432
4433 /**
4434 * Run tests with full titles matching `re`. Updates runner.total
4435 * with number of tests matched.
4436 *
4437 * @param {RegExp} re
4438 * @param {Boolean} invert
4439 * @return {Runner} for chaining
4440 * @api public
4441 */
4442
4443 Runner.prototype.grep = function(re, invert){
4444 debug('grep %s', re);
4445 this._grep = re;
4446 this._invert = invert;
4447 this.total = this.grepTotal(this.suite);
4448 return this;
4449 };
4450
4451 /**
4452 * Returns the number of tests matching the grep search for the
4453 * given suite.
4454 *
4455 * @param {Suite} suite
4456 * @return {Number}
4457 * @api public
4458 */
4459
4460 Runner.prototype.grepTotal = function(suite) {
4461 var self = this;
4462 var total = 0;
4463
4464 suite.eachTest(function(test){
4465 var match = self._grep.test(test.fullTitle());
4466 if (self._invert) match = !match;
4467 if (match) total++;
4468 });
4469
4470 return total;
4471 };
4472
4473 /**
4474 * Return a list of global properties.
4475 *
4476 * @return {Array}
4477 * @api private
4478 */
4479
4480 Runner.prototype.globalProps = function() {
4481 var props = utils.keys(global);
4482
4483 // non-enumerables
4484 for (var i = 0; i < globals.length; ++i) {
4485 if (~utils.indexOf(props, globals[i])) continue;
4486 props.push(globals[i]);
4487 }
4488
4489 return props;
4490 };
4491
4492 /**
4493 * Allow the given `arr` of globals.
4494 *
4495 * @param {Array} arr
4496 * @return {Runner} for chaining
4497 * @api public
4498 */
4499
4500 Runner.prototype.globals = function(arr){
4501 if (0 == arguments.length) return this._globals;
4502 debug('globals %j', arr);
4503 this._globals = this._globals.concat(arr);
4504 return this;
4505 };
4506
4507 /**
4508 * Check for global variable leaks.
4509 *
4510 * @api private
4511 */
4512
4513 Runner.prototype.checkGlobals = function(test){
4514 if (this.ignoreLeaks) return;
4515 var ok = this._globals;
4516
4517 var globals = this.globalProps();
4518 var isNode = process.kill;
4519 var leaks;
4520
4521 if (test) {
4522 ok = ok.concat(test._allowedGlobals || []);
4523 }
4524
4525 if(this.prevGlobalsLength == globals.length) return;
4526 this.prevGlobalsLength = globals.length;
4527
4528 leaks = filterLeaks(ok, globals);
4529 this._globals = this._globals.concat(leaks);
4530
4531 if (leaks.length > 1) {
4532 this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + '') );
4533 } else if (leaks.length) {
4534 this.fail(test, new Error('global leak detected: ' + leaks[0]));
4535 }
4536 };
4537
4538 /**
4539 * Fail the given `test`.
4540 *
4541 * @param {Test} test
4542 * @param {Error} err
4543 * @api private
4544 */
4545
4546 Runner.prototype.fail = function(test, err){
4547 ++this.failures;
4548 test.state = 'failed';
4549
4550 if ('string' == typeof err) {
4551 err = new Error('the string "' + err + '" was thrown, throw an Error :)');
4552 }
4553
4554 this.emit('fail', test, err);
4555 };
4556
4557 /**
4558 * Fail the given `hook` with `err`.
4559 *
4560 * Hook failures work in the following pattern:
4561 * - If bail, then exit
4562 * - Failed `before` hook skips all tests in a suite and subsuites,
4563 * but jumps to corresponding `after` hook
4564 * - Failed `before each` hook skips remaining tests in a
4565 * suite and jumps to corresponding `after each` hook,
4566 * which is run only once
4567 * - Failed `after` hook does not alter
4568 * execution order
4569 * - Failed `after each` hook skips remaining tests in a
4570 * suite and subsuites, but executes other `after each`
4571 * hooks
4572 *
4573 * @param {Hook} hook
4574 * @param {Error} err
4575 * @api private
4576 */
4577
4578 Runner.prototype.failHook = function(hook, err){
4579 this.fail(hook, err);
4580 if (this.suite.bail()) {
4581 this.emit('end');
4582 }
4583 };
4584
4585 /**
4586 * Run hook `name` callbacks and then invoke `fn()`.
4587 *
4588 * @param {String} name
4589 * @param {Function} function
4590 * @api private
4591 */
4592
4593 Runner.prototype.hook = function(name, fn){
4594 var suite = this.suite
4595 , hooks = suite['_' + name]
4596 , self = this
4597 , timer;
4598
4599 function next(i) {
4600 var hook = hooks[i];
4601 if (!hook) return fn();
4602 if (self.failures && suite.bail()) return fn();
4603 self.currentRunnable = hook;
4604
4605 hook.ctx.currentTest = self.test;
4606
4607 self.emit('hook', hook);
4608
4609 hook.on('error', function(err){
4610 self.failHook(hook, err);
4611 });
4612
4613 hook.run(function(err){
4614 hook.removeAllListeners('error');
4615 var testError = hook.error();
4616 if (testError) self.fail(self.test, testError);
4617 if (err) {
4618 self.failHook(hook, err);
4619
4620 // stop executing hooks, notify callee of hook err
4621 return fn(err);
4622 }
4623 self.emit('hook end', hook);
4624 delete hook.ctx.currentTest;
4625 next(++i);
4626 });
4627 }
4628
4629 Runner.immediately(function(){
4630 next(0);
4631 });
4632 };
4633
4634 /**
4635 * Run hook `name` for the given array of `suites`
4636 * in order, and callback `fn(err, errSuite)`.
4637 *
4638 * @param {String} name
4639 * @param {Array} suites
4640 * @param {Function} fn
4641 * @api private
4642 */
4643
4644 Runner.prototype.hooks = function(name, suites, fn){
4645 var self = this
4646 , orig = this.suite;
4647
4648 function next(suite) {
4649 self.suite = suite;
4650
4651 if (!suite) {
4652 self.suite = orig;
4653 return fn();
4654 }
4655
4656 self.hook(name, function(err){
4657 if (err) {
4658 var errSuite = self.suite;
4659 self.suite = orig;
4660 return fn(err, errSuite);
4661 }
4662
4663 next(suites.pop());
4664 });
4665 }
4666
4667 next(suites.pop());
4668 };
4669
4670 /**
4671 * Run hooks from the top level down.
4672 *
4673 * @param {String} name
4674 * @param {Function} fn
4675 * @api private
4676 */
4677
4678 Runner.prototype.hookUp = function(name, fn){
4679 var suites = [this.suite].concat(this.parents()).reverse();
4680 this.hooks(name, suites, fn);
4681 };
4682
4683 /**
4684 * Run hooks from the bottom up.
4685 *
4686 * @param {String} name
4687 * @param {Function} fn
4688 * @api private
4689 */
4690
4691 Runner.prototype.hookDown = function(name, fn){
4692 var suites = [this.suite].concat(this.parents());
4693 this.hooks(name, suites, fn);
4694 };
4695
4696 /**
4697 * Return an array of parent Suites from
4698 * closest to furthest.
4699 *
4700 * @return {Array}
4701 * @api private
4702 */
4703
4704 Runner.prototype.parents = function(){
4705 var suite = this.suite
4706 , suites = [];
4707 while (suite = suite.parent) suites.push(suite);
4708 return suites;
4709 };
4710
4711 /**
4712 * Run the current test and callback `fn(err)`.
4713 *
4714 * @param {Function} fn
4715 * @api private
4716 */
4717
4718 Runner.prototype.runTest = function(fn){
4719 var test = this.test
4720 , self = this;
4721
4722 if (this.asyncOnly) test.asyncOnly = true;
4723
4724 try {
4725 test.on('error', function(err){
4726 self.fail(test, err);
4727 });
4728 test.run(fn);
4729 } catch (err) {
4730 fn(err);
4731 }
4732 };
4733
4734 /**
4735 * Run tests in the given `suite` and invoke
4736 * the callback `fn()` when complete.
4737 *
4738 * @param {Suite} suite
4739 * @param {Function} fn
4740 * @api private
4741 */
4742
4743 Runner.prototype.runTests = function(suite, fn){
4744 var self = this
4745 , tests = suite.tests.slice()
4746 , test;
4747
4748
4749 function hookErr(err, errSuite, after) {
4750 // before/after Each hook for errSuite failed:
4751 var orig = self.suite;
4752
4753 // for failed 'after each' hook start from errSuite parent,
4754 // otherwise start from errSuite itself
4755 self.suite = after ? errSuite.parent : errSuite;
4756
4757 if (self.suite) {
4758 // call hookUp afterEach
4759 self.hookUp('afterEach', function(err2, errSuite2) {
4760 self.suite = orig;
4761 // some hooks may fail even now
4762 if (err2) return hookErr(err2, errSuite2, true);
4763 // report error suite
4764 fn(errSuite);
4765 });
4766 } else {
4767 // there is no need calling other 'after each' hooks
4768 self.suite = orig;
4769 fn(errSuite);
4770 }
4771 }
4772
4773 function next(err, errSuite) {
4774 // if we bail after first err
4775 if (self.failures && suite._bail) return fn();
4776
4777 if (self._abort) return fn();
4778
4779 if (err) return hookErr(err, errSuite, true);
4780
4781 // next test
4782 test = tests.shift();
4783
4784 // all done
4785 if (!test) return fn();
4786
4787 // grep
4788 var match = self._grep.test(test.fullTitle());
4789 if (self._invert) match = !match;
4790 if (!match) return next();
4791
4792 // pending
4793 if (test.pending) {
4794 self.emit('pending', test);
4795 self.emit('test end', test);
4796 return next();
4797 }
4798
4799 // execute test and hook(s)
4800 self.emit('test', self.test = test);
4801 self.hookDown('beforeEach', function(err, errSuite){
4802
4803 if (err) return hookErr(err, errSuite, false);
4804
4805 self.currentRunnable = self.test;
4806 self.runTest(function(err){
4807 test = self.test;
4808
4809 if (err) {
4810 self.fail(test, err);
4811 self.emit('test end', test);
4812 return self.hookUp('afterEach', next);
4813 }
4814
4815 test.state = 'passed';
4816 self.emit('pass', test);
4817 self.emit('test end', test);
4818 self.hookUp('afterEach', next);
4819 });
4820 });
4821 }
4822
4823 this.next = next;
4824 next();
4825 };
4826
4827 /**
4828 * Run the given `suite` and invoke the
4829 * callback `fn()` when complete.
4830 *
4831 * @param {Suite} suite
4832 * @param {Function} fn
4833 * @api private
4834 */
4835
4836 Runner.prototype.runSuite = function(suite, fn){
4837 var total = this.grepTotal(suite)
4838 , self = this
4839 , i = 0;
4840
4841 debug('run suite %s', suite.fullTitle());
4842
4843 if (!total) return fn();
4844
4845 this.emit('suite', this.suite = suite);
4846
4847 function next(errSuite) {
4848 if (errSuite) {
4849 // current suite failed on a hook from errSuite
4850 if (errSuite == suite) {
4851 // if errSuite is current suite
4852 // continue to the next sibling suite
4853 return done();
4854 } else {
4855 // errSuite is among the parents of current suite
4856 // stop execution of errSuite and all sub-suites
4857 return done(errSuite);
4858 }
4859 }
4860
4861 if (self._abort) return done();
4862
4863 var curr = suite.suites[i++];
4864 if (!curr) return done();
4865 self.runSuite(curr, next);
4866 }
4867
4868 function done(errSuite) {
4869 self.suite = suite;
4870 self.hook('afterAll', function(){
4871 self.emit('suite end', suite);
4872 fn(errSuite);
4873 });
4874 }
4875
4876 this.hook('beforeAll', function(err){
4877 if (err) return done();
4878 self.runTests(suite, next);
4879 });
4880 };
4881
4882 /**
4883 * Handle uncaught exceptions.
4884 *
4885 * @param {Error} err
4886 * @api private
4887 */
4888
4889 Runner.prototype.uncaught = function(err){
4890 debug('uncaught exception %s', err.message);
4891 var runnable = this.currentRunnable;
4892 if (!runnable || 'failed' == runnable.state) return;
4893 runnable.clearTimeout();
4894 err.uncaught = true;
4895 this.fail(runnable, err);
4896
4897 // recover from test
4898 if ('test' == runnable.type) {
4899 this.emit('test end', runnable);
4900 this.hookUp('afterEach', this.next);
4901 return;
4902 }
4903
4904 // bail on hooks
4905 this.emit('end');
4906 };
4907
4908 /**
4909 * Run the root suite and invoke `fn(failures)`
4910 * on completion.
4911 *
4912 * @param {Function} fn
4913 * @return {Runner} for chaining
4914 * @api public
4915 */
4916
4917 Runner.prototype.run = function(fn){
4918 var self = this
4919 , fn = fn || function(){};
4920
4921 function uncaught(err){
4922 self.uncaught(err);
4923 }
4924
4925 debug('start');
4926
4927 // callback
4928 this.on('end', function(){
4929 debug('end');
4930 process.removeListener('uncaughtException', uncaught);
4931 fn(self.failures);
4932 });
4933
4934 // run suites
4935 this.emit('start');
4936 this.runSuite(this.suite, function(){
4937 debug('finished running');
4938 self.emit('end');
4939 });
4940
4941 // uncaught exception
4942 process.on('uncaughtException', uncaught);
4943
4944 return this;
4945 };
4946
4947 /**
4948 * Cleanly abort execution
4949 *
4950 * @return {Runner} for chaining
4951 * @api public
4952 */
4953 Runner.prototype.abort = function(){
4954 debug('aborting');
4955 this._abort = true;
4956 }
4957
4958 /**
4959 * Filter leaks with the given globals flagged as `ok`.
4960 *
4961 * @param {Array} ok
4962 * @param {Array} globals
4963 * @return {Array}
4964 * @api private
4965 */
4966
4967 function filterLeaks(ok, globals) {
4968 return filter(globals, function(key){
4969 // Firefox and Chrome exposes iframes as index inside the window object
4970 if (/^d+/.test(key)) return false;
4971
4972 // in firefox
4973 // if runner runs in an iframe, this iframe's window.getInterface method not init at first
4974 // it is assigned in some seconds
4975 if (global.navigator && /^getInterface/.test(key)) return false;
4976
4977 // an iframe could be approached by window[iframeIndex]
4978 // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
4979 if (global.navigator && /^\d+/.test(key)) return false;
4980
4981 // Opera and IE expose global variables for HTML element IDs (issue #243)
4982 if (/^mocha-/.test(key)) return false;
4983
4984 var matched = filter(ok, function(ok){
4985 if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
4986 return key == ok;
4987 });
4988 return matched.length == 0 && (!global.navigator || 'onerror' !== key);
4989 });
4990 }
4991
4992 /**
4993 * Array of globals dependent on the environment.
4994 *
4995 * @return {Array}
4996 * @api private
4997 */
4998
4999 function extraGlobals() {
5000 if (typeof(process) === 'object' &&
5001 typeof(process.version) === 'string') {
5002
5003 var nodeVersion = process.version.split('.').reduce(function(a, v) {
5004 return a << 8 | v;
5005 });
5006
5007 // 'errno' was renamed to process._errno in v0.9.11.
5008
5009 if (nodeVersion < 0x00090B) {
5010 return ['errno'];
5011 }
5012 }
5013
5014 return [];
5015 }
5016
5017 }); // module: runner.js
5018
5019 require.register("suite.js", function(module, exports, require){
5020
5021 /**
5022 * Module dependencies.
5023 */
5024
5025 var EventEmitter = require('browser/events').EventEmitter
5026 , debug = require('browser/debug')('mocha:suite')
5027 , milliseconds = require('./ms')
5028 , utils = require('./utils')
5029 , Hook = require('./hook');
5030
5031 /**
5032 * Expose `Suite`.
5033 */
5034
5035 exports = module.exports = Suite;
5036
5037 /**
5038 * Create a new `Suite` with the given `title`
5039 * and parent `Suite`. When a suite with the
5040 * same title is already present, that suite
5041 * is returned to provide nicer reporter
5042 * and more flexible meta-testing.
5043 *
5044 * @param {Suite} parent
5045 * @param {String} title
5046 * @return {Suite}
5047 * @api public
5048 */
5049
5050 exports.create = function(parent, title){
5051 var suite = new Suite(title, parent.ctx);
5052 suite.parent = parent;
5053 if (parent.pending) suite.pending = true;
5054 title = suite.fullTitle();
5055 parent.addSuite(suite);
5056 return suite;
5057 };
5058
5059 /**
5060 * Initialize a new `Suite` with the given
5061 * `title` and `ctx`.
5062 *
5063 * @param {String} title
5064 * @param {Context} ctx
5065 * @api private
5066 */
5067
5068 function Suite(title, parentContext) {
5069 this.title = title;
5070 var context = function () {};
5071 context.prototype = parentContext;
5072 this.ctx = new context();
5073 this.suites = [];
5074 this.tests = [];
5075 this.pending = false;
5076 this._beforeEach = [];
5077 this._beforeAll = [];
5078 this._afterEach = [];
5079 this._afterAll = [];
5080 this.root = !title;
5081 this._timeout = 2000;
5082 this._slow = 75;
5083 this._bail = false;
5084 }
5085
5086 /**
5087 * Inherit from `EventEmitter.prototype`.
5088 */
5089
5090 function F(){};
5091 F.prototype = EventEmitter.prototype;
5092 Suite.prototype = new F;
5093 Suite.prototype.constructor = Suite;
5094
5095
5096 /**
5097 * Return a clone of this `Suite`.
5098 *
5099 * @return {Suite}
5100 * @api private
5101 */
5102
5103 Suite.prototype.clone = function(){
5104 var suite = new Suite(this.title);
5105 debug('clone');
5106 suite.ctx = this.ctx;
5107 suite.timeout(this.timeout());
5108 suite.slow(this.slow());
5109 suite.bail(this.bail());
5110 return suite;
5111 };
5112
5113 /**
5114 * Set timeout `ms` or short-hand such as "2s".
5115 *
5116 * @param {Number|String} ms
5117 * @return {Suite|Number} for chaining
5118 * @api private
5119 */
5120
5121 Suite.prototype.timeout = function(ms){
5122 if (0 == arguments.length) return this._timeout;
5123 if ('string' == typeof ms) ms = milliseconds(ms);
5124 debug('timeout %d', ms);
5125 this._timeout = parseInt(ms, 10);
5126 return this;
5127 };
5128
5129 /**
5130 * Set slow `ms` or short-hand such as "2s".
5131 *
5132 * @param {Number|String} ms
5133 * @return {Suite|Number} for chaining
5134 * @api private
5135 */
5136
5137 Suite.prototype.slow = function(ms){
5138 if (0 === arguments.length) return this._slow;
5139 if ('string' == typeof ms) ms = milliseconds(ms);
5140 debug('slow %d', ms);
5141 this._slow = ms;
5142 return this;
5143 };
5144
5145 /**
5146 * Sets whether to bail after first error.
5147 *
5148 * @parma {Boolean} bail
5149 * @return {Suite|Number} for chaining
5150 * @api private
5151 */
5152
5153 Suite.prototype.bail = function(bail){
5154 if (0 == arguments.length) return this._bail;
5155 debug('bail %s', bail);
5156 this._bail = bail;
5157 return this;
5158 };
5159
5160 /**
5161 * Run `fn(test[, done])` before running tests.
5162 *
5163 * @param {Function} fn
5164 * @return {Suite} for chaining
5165 * @api private
5166 */
5167
5168 Suite.prototype.beforeAll = function(title, fn){
5169 if (this.pending) return this;
5170 if ('function' === typeof title) {
5171 fn = title;
5172 title = fn.name;
5173 }
5174 title = '"before all" hook' + (title ? ': ' + title : '');
5175
5176 var hook = new Hook(title, fn);
5177 hook.parent = this;
5178 hook.timeout(this.timeout());
5179 hook.slow(this.slow());
5180 hook.ctx = this.ctx;
5181 this._beforeAll.push(hook);
5182 this.emit('beforeAll', hook);
5183 return this;
5184 };
5185
5186 /**
5187 * Run `fn(test[, done])` after running tests.
5188 *
5189 * @param {Function} fn
5190 * @return {Suite} for chaining
5191 * @api private
5192 */
5193
5194 Suite.prototype.afterAll = function(title, fn){
5195 if (this.pending) return this;
5196 if ('function' === typeof title) {
5197 fn = title;
5198 title = fn.name;
5199 }
5200 title = '"after all" hook' + (title ? ': ' + title : '');
5201
5202 var hook = new Hook(title, fn);
5203 hook.parent = this;
5204 hook.timeout(this.timeout());
5205 hook.slow(this.slow());
5206 hook.ctx = this.ctx;
5207 this._afterAll.push(hook);
5208 this.emit('afterAll', hook);
5209 return this;
5210 };
5211
5212 /**
5213 * Run `fn(test[, done])` before each test case.
5214 *
5215 * @param {Function} fn
5216 * @return {Suite} for chaining
5217 * @api private
5218 */
5219
5220 Suite.prototype.beforeEach = function(title, fn){
5221 if (this.pending) return this;
5222 if ('function' === typeof title) {
5223 fn = title;
5224 title = fn.name;
5225 }
5226 title = '"before each" hook' + (title ? ': ' + title : '');
5227
5228 var hook = new Hook(title, fn);
5229 hook.parent = this;
5230 hook.timeout(this.timeout());
5231 hook.slow(this.slow());
5232 hook.ctx = this.ctx;
5233 this._beforeEach.push(hook);
5234 this.emit('beforeEach', hook);
5235 return this;
5236 };
5237
5238 /**
5239 * Run `fn(test[, done])` after each test case.
5240 *
5241 * @param {Function} fn
5242 * @return {Suite} for chaining
5243 * @api private
5244 */
5245
5246 Suite.prototype.afterEach = function(title, fn){
5247 if (this.pending) return this;
5248 if ('function' === typeof title) {
5249 fn = title;
5250 title = fn.name;
5251 }
5252 title = '"after each" hook' + (title ? ': ' + title : '');
5253
5254 var hook = new Hook(title, fn);
5255 hook.parent = this;
5256 hook.timeout(this.timeout());
5257 hook.slow(this.slow());
5258 hook.ctx = this.ctx;
5259 this._afterEach.push(hook);
5260 this.emit('afterEach', hook);
5261 return this;
5262 };
5263
5264 /**
5265 * Add a test `suite`.
5266 *
5267 * @param {Suite} suite
5268 * @return {Suite} for chaining
5269 * @api private
5270 */
5271
5272 Suite.prototype.addSuite = function(suite){
5273 suite.parent = this;
5274 suite.timeout(this.timeout());
5275 suite.slow(this.slow());
5276 suite.bail(this.bail());
5277 this.suites.push(suite);
5278 this.emit('suite', suite);
5279 return this;
5280 };
5281
5282 /**
5283 * Add a `test` to this suite.
5284 *
5285 * @param {Test} test
5286 * @return {Suite} for chaining
5287 * @api private
5288 */
5289
5290 Suite.prototype.addTest = function(test){
5291 test.parent = this;
5292 test.timeout(this.timeout());
5293 test.slow(this.slow());
5294 test.ctx = this.ctx;
5295 this.tests.push(test);
5296 this.emit('test', test);
5297 return this;
5298 };
5299
5300 /**
5301 * Return the full title generated by recursively
5302 * concatenating the parent's full title.
5303 *
5304 * @return {String}
5305 * @api public
5306 */
5307
5308 Suite.prototype.fullTitle = function(){
5309 if (this.parent) {
5310 var full = this.parent.fullTitle();
5311 if (full) return full + ' ' + this.title;
5312 }
5313 return this.title;
5314 };
5315
5316 /**
5317 * Return the total number of tests.
5318 *
5319 * @return {Number}
5320 * @api public
5321 */
5322
5323 Suite.prototype.total = function(){
5324 return utils.reduce(this.suites, function(sum, suite){
5325 return sum + suite.total();
5326 }, 0) + this.tests.length;
5327 };
5328
5329 /**
5330 * Iterates through each suite recursively to find
5331 * all tests. Applies a function in the format
5332 * `fn(test)`.
5333 *
5334 * @param {Function} fn
5335 * @return {Suite}
5336 * @api private
5337 */
5338
5339 Suite.prototype.eachTest = function(fn){
5340 utils.forEach(this.tests, fn);
5341 utils.forEach(this.suites, function(suite){
5342 suite.eachTest(fn);
5343 });
5344 return this;
5345 };
5346
5347 }); // module: suite.js
5348
5349 require.register("test.js", function(module, exports, require){
5350
5351 /**
5352 * Module dependencies.
5353 */
5354
5355 var Runnable = require('./runnable');
5356
5357 /**
5358 * Expose `Test`.
5359 */
5360
5361 module.exports = Test;
5362
5363 /**
5364 * Initialize a new `Test` with the given `title` and callback `fn`.
5365 *
5366 * @param {String} title
5367 * @param {Function} fn
5368 * @api private
5369 */
5370
5371 function Test(title, fn) {
5372 Runnable.call(this, title, fn);
5373 this.pending = !fn;
5374 this.type = 'test';
5375 }
5376
5377 /**
5378 * Inherit from `Runnable.prototype`.
5379 */
5380
5381 function F(){};
5382 F.prototype = Runnable.prototype;
5383 Test.prototype = new F;
5384 Test.prototype.constructor = Test;
5385
5386
5387 }); // module: test.js
5388
5389 require.register("utils.js", function(module, exports, require){
5390 /**
5391 * Module dependencies.
5392 */
5393
5394 var fs = require('browser/fs')
5395 , path = require('browser/path')
5396 , join = path.join
5397 , debug = require('browser/debug')('mocha:watch');
5398
5399 /**
5400 * Ignored directories.
5401 */
5402
5403 var ignore = ['node_modules', '.git'];
5404
5405 /**
5406 * Escape special characters in the given string of html.
5407 *
5408 * @param {String} html
5409 * @return {String}
5410 * @api private
5411 */
5412
5413 exports.escape = function(html){
5414 return String(html)
5415 .replace(/&/g, '&amp;')
5416 .replace(/"/g, '&quot;')
5417 .replace(/</g, '&lt;')
5418 .replace(/>/g, '&gt;');
5419 };
5420
5421 /**
5422 * Array#forEach (<=IE8)
5423 *
5424 * @param {Array} array
5425 * @param {Function} fn
5426 * @param {Object} scope
5427 * @api private
5428 */
5429
5430 exports.forEach = function(arr, fn, scope){
5431 for (var i = 0, l = arr.length; i < l; i++)
5432 fn.call(scope, arr[i], i);
5433 };
5434
5435 /**
5436 * Array#map (<=IE8)
5437 *
5438 * @param {Array} array
5439 * @param {Function} fn
5440 * @param {Object} scope
5441 * @api private
5442 */
5443
5444 exports.map = function(arr, fn, scope){
5445 var result = [];
5446 for (var i = 0, l = arr.length; i < l; i++)
5447 result.push(fn.call(scope, arr[i], i));
5448 return result;
5449 };
5450
5451 /**
5452 * Array#indexOf (<=IE8)
5453 *
5454 * @parma {Array} arr
5455 * @param {Object} obj to find index of
5456 * @param {Number} start
5457 * @api private
5458 */
5459
5460 exports.indexOf = function(arr, obj, start){
5461 for (var i = start || 0, l = arr.length; i < l; i++) {
5462 if (arr[i] === obj)
5463 return i;
5464 }
5465 return -1;
5466 };
5467
5468 /**
5469 * Array#reduce (<=IE8)
5470 *
5471 * @param {Array} array
5472 * @param {Function} fn
5473 * @param {Object} initial value
5474 * @api private
5475 */
5476
5477 exports.reduce = function(arr, fn, val){
5478 var rval = val;
5479
5480 for (var i = 0, l = arr.length; i < l; i++) {
5481 rval = fn(rval, arr[i], i, arr);
5482 }
5483
5484 return rval;
5485 };
5486
5487 /**
5488 * Array#filter (<=IE8)
5489 *
5490 * @param {Array} array
5491 * @param {Function} fn
5492 * @api private
5493 */
5494
5495 exports.filter = function(arr, fn){
5496 var ret = [];
5497
5498 for (var i = 0, l = arr.length; i < l; i++) {
5499 var val = arr[i];
5500 if (fn(val, i, arr)) ret.push(val);
5501 }
5502
5503 return ret;
5504 };
5505
5506 /**
5507 * Object.keys (<=IE8)
5508 *
5509 * @param {Object} obj
5510 * @return {Array} keys
5511 * @api private
5512 */
5513
5514 exports.keys = Object.keys || function(obj) {
5515 var keys = []
5516 , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
5517
5518 for (var key in obj) {
5519 if (has.call(obj, key)) {
5520 keys.push(key);
5521 }
5522 }
5523
5524 return keys;
5525 };
5526
5527 /**
5528 * Watch the given `files` for changes
5529 * and invoke `fn(file)` on modification.
5530 *
5531 * @param {Array} files
5532 * @param {Function} fn
5533 * @api private
5534 */
5535
5536 exports.watch = function(files, fn){
5537 var options = { interval: 100 };
5538 files.forEach(function(file){
5539 debug('file %s', file);
5540 fs.watchFile(file, options, function(curr, prev){
5541 if (prev.mtime < curr.mtime) fn(file);
5542 });
5543 });
5544 };
5545
5546 /**
5547 * Ignored files.
5548 */
5549
5550 function ignored(path){
5551 return !~ignore.indexOf(path);
5552 }
5553
5554 /**
5555 * Lookup files in the given `dir`.
5556 *
5557 * @return {Array}
5558 * @api private
5559 */
5560
5561 exports.files = function(dir, ret){
5562 ret = ret || [];
5563
5564 fs.readdirSync(dir)
5565 .filter(ignored)
5566 .forEach(function(path){
5567 path = join(dir, path);
5568 if (fs.statSync(path).isDirectory()) {
5569 exports.files(path, ret);
5570 } else if (path.match(/\.(js|coffee|litcoffee|coffee.md)$/)) {
5571 ret.push(path);
5572 }
5573 });
5574
5575 return ret;
5576 };
5577
5578 /**
5579 * Compute a slug from the given `str`.
5580 *
5581 * @param {String} str
5582 * @return {String}
5583 * @api private
5584 */
5585
5586 exports.slug = function(str){
5587 return str
5588 .toLowerCase()
5589 .replace(/ +/g, '-')
5590 .replace(/[^-\w]/g, '');
5591 };
5592
5593 /**
5594 * Strip the function definition from `str`,
5595 * and re-indent for pre whitespace.
5596 */
5597
5598 exports.clean = function(str) {
5599 str = str
5600 .replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
5601 .replace(/^function *\(.*\) *{/, '')
5602 .replace(/\s+\}$/, '');
5603
5604 var spaces = str.match(/^\n?( *)/)[1].length
5605 , tabs = str.match(/^\n?(\t*)/)[1].length
5606 , re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces ) + '}', 'gm');
5607
5608 str = str.replace(re, '');
5609
5610 return exports.trim(str);
5611 };
5612
5613 /**
5614 * Escape regular expression characters in `str`.
5615 *
5616 * @param {String} str
5617 * @return {String}
5618 * @api private
5619 */
5620
5621 exports.escapeRegexp = function(str){
5622 return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
5623 };
5624
5625 /**
5626 * Trim the given `str`.
5627 *
5628 * @param {String} str
5629 * @return {String}
5630 * @api private
5631 */
5632
5633 exports.trim = function(str){
5634 return str.replace(/^\s+|\s+$/g, '');
5635 };
5636
5637 /**
5638 * Parse the given `qs`.
5639 *
5640 * @param {String} qs
5641 * @return {Object}
5642 * @api private
5643 */
5644
5645 exports.parseQuery = function(qs){
5646 return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
5647 var i = pair.indexOf('=')
5648 , key = pair.slice(0, i)
5649 , val = pair.slice(++i);
5650
5651 obj[key] = decodeURIComponent(val);
5652 return obj;
5653 }, {});
5654 };
5655
5656 /**
5657 * Highlight the given string of `js`.
5658 *
5659 * @param {String} js
5660 * @return {String}
5661 * @api private
5662 */
5663
5664 function highlight(js) {
5665 return js
5666 .replace(/</g, '&lt;')
5667 .replace(/>/g, '&gt;')
5668 .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
5669 .replace(/('.*?')/gm, '<span class="string">$1</span>')
5670 .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
5671 .replace(/(\d+)/gm, '<span class="number">$1</span>')
5672 .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="in it">$1</span>')
5673 .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyw ord">$1</span>')
5674 }
5675
5676 /**
5677 * Highlight the contents of tag `name`.
5678 *
5679 * @param {String} name
5680 * @api private
5681 */
5682
5683 exports.highlightTags = function(name) {
5684 var code = document.getElementsByTagName(name);
5685 for (var i = 0, len = code.length; i < len; ++i) {
5686 code[i].innerHTML = highlight(code[i].innerHTML);
5687 }
5688 };
5689
5690 }); // module: utils.js
5691 // The global object is "self" in Web Workers.
5692 global = (function() { return this; })();
5693
5694 /**
5695 * Save timer references to avoid Sinon interfering (see GH-237).
5696 */
5697
5698 var Date = global.Date;
5699 var setTimeout = global.setTimeout;
5700 var setInterval = global.setInterval;
5701 var clearTimeout = global.clearTimeout;
5702 var clearInterval = global.clearInterval;
5703
5704 /**
5705 * Node shims.
5706 *
5707 * These are meant only to allow
5708 * mocha.js to run untouched, not
5709 * to allow running node code in
5710 * the browser.
5711 */
5712
5713 var process = {};
5714 process.exit = function(status){};
5715 process.stdout = {};
5716
5717 var uncaughtExceptionHandlers = [];
5718
5719 /**
5720 * Remove uncaughtException listener.
5721 */
5722
5723 process.removeListener = function(e, fn){
5724 if ('uncaughtException' == e) {
5725 global.onerror = function() {};
5726 var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);
5727 if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }
5728 }
5729 };
5730
5731 /**
5732 * Implements uncaughtException listener.
5733 */
5734
5735 process.on = function(e, fn){
5736 if ('uncaughtException' == e) {
5737 global.onerror = function(err, url, line){
5738 fn(new Error(err + ' (' + url + ':' + line + ')'));
5739 return true;
5740 };
5741 uncaughtExceptionHandlers.push(fn);
5742 }
5743 };
5744
5745 /**
5746 * Expose mocha.
5747 */
5748
5749 var Mocha = global.Mocha = require('mocha'),
5750 mocha = global.mocha = new Mocha({ reporter: 'html' });
5751
5752 // The BDD UI is registered by default, but no UI will be functional in the
5753 // browser without an explicit call to the overridden `mocha.ui` (see below).
5754 // Ensure that this default UI does not expose its methods to the global scope.
5755 mocha.suite.removeAllListeners('pre-require');
5756
5757 var immediateQueue = []
5758 , immediateTimeout;
5759
5760 function timeslice() {
5761 var immediateStart = new Date().getTime();
5762 while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
5763 immediateQueue.shift()();
5764 }
5765 if (immediateQueue.length) {
5766 immediateTimeout = setTimeout(timeslice, 0);
5767 } else {
5768 immediateTimeout = null;
5769 }
5770 }
5771
5772 /**
5773 * High-performance override of Runner.immediately.
5774 */
5775
5776 Mocha.Runner.immediately = function(callback) {
5777 immediateQueue.push(callback);
5778 if (!immediateTimeout) {
5779 immediateTimeout = setTimeout(timeslice, 0);
5780 }
5781 };
5782
5783 /**
5784 * Function to allow assertion libraries to throw errors directly into mocha.
5785 * This is useful when running tests in a browser because window.onerror will
5786 * only receive the 'message' attribute of the Error.
5787 */
5788 mocha.throwError = function(err) {
5789 Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {
5790 fn(err);
5791 });
5792 throw err;
5793 };
5794
5795 /**
5796 * Override ui to ensure that the ui functions are initialized.
5797 * Normally this would happen in Mocha.prototype.loadFiles.
5798 */
5799
5800 mocha.ui = function(ui){
5801 Mocha.prototype.ui.call(this, ui);
5802 this.suite.emit('pre-require', global, null, this);
5803 return this;
5804 };
5805
5806 /**
5807 * Setup mocha with the given setting options.
5808 */
5809
5810 mocha.setup = function(opts){
5811 if ('string' == typeof opts) opts = { ui: opts };
5812 for (var opt in opts) this[opt](opts[opt]);
5813 return this;
5814 };
5815
5816 /**
5817 * Run mocha, returning the Runner.
5818 */
5819
5820 mocha.run = function(fn){
5821 var options = mocha.options;
5822 mocha.globals('location');
5823
5824 var query = Mocha.utils.parseQuery(global.location.search || '');
5825 if (query.grep) mocha.grep(query.grep);
5826 if (query.invert) mocha.invert();
5827
5828 return Mocha.prototype.run.call(mocha, function(){
5829 // The DOM Document is not available in Web Workers.
5830 if (global.document) {
5831 Mocha.utils.highlightTags('code');
5832 }
5833 if (fn) fn();
5834 });
5835 };
5836
5837 /**
5838 * Expose the process shim.
5839 */
5840
5841 Mocha.process = process;
5842 })();
OLDNEW
« no previous file with comments | « bower_components/polymer-test-tools/mocha/mocha.css ('k') | bower_components/polymer-test-tools/tools.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698