UNPKG

93.2 kBJavaScriptView Raw
1;(function(){
2
3
4// CommonJS require()
5
6function require(p){
7 var path = require.resolve(p)
8 , mod = require.modules[path];
9 if (!mod) throw new Error('failed to require "' + p + '"');
10 if (!mod.exports) {
11 mod.exports = {};
12 mod.call(mod.exports, mod, mod.exports, require.relative(path));
13 }
14 return mod.exports;
15 }
16
17require.modules = {};
18
19require.resolve = function (path){
20 var orig = path
21 , reg = path + '.js'
22 , index = path + '/index.js';
23 return require.modules[reg] && reg
24 || require.modules[index] && index
25 || orig;
26 };
27
28require.register = function (path, fn){
29 require.modules[path] = fn;
30 };
31
32require.relative = function (parent) {
33 return function(p){
34 if ('.' != p.charAt(0)) return require(p);
35
36 var path = parent.split('/')
37 , segs = p.split('/');
38 path.pop();
39
40 for (var i = 0; i < segs.length; i++) {
41 var seg = segs[i];
42 if ('..' == seg) path.pop();
43 else if ('.' != seg) path.push(seg);
44 }
45
46 return require(path.join('/'));
47 };
48 };
49
50
51require.register("browser/debug.js", function(module, exports, require){
52
53module.exports = function(type){
54 return function(){
55
56 }
57};
58}); // module: browser/debug.js
59
60require.register("browser/diff.js", function(module, exports, require){
61
62}); // module: browser/diff.js
63
64require.register("browser/events.js", function(module, exports, require){
65
66/**
67 * Module exports.
68 */
69
70exports.EventEmitter = EventEmitter;
71
72/**
73 * Check if `obj` is an array.
74 */
75
76function isArray(obj) {
77 return '[object Array]' == {}.toString.call(obj);
78}
79
80/**
81 * Event emitter constructor.
82 *
83 * @api public
84 */
85
86function EventEmitter(){};
87
88/**
89 * Adds a listener.
90 *
91 * @api public
92 */
93
94EventEmitter.prototype.on = function (name, fn) {
95 if (!this.$events) {
96 this.$events = {};
97 }
98
99 if (!this.$events[name]) {
100 this.$events[name] = fn;
101 } else if (isArray(this.$events[name])) {
102 this.$events[name].push(fn);
103 } else {
104 this.$events[name] = [this.$events[name], fn];
105 }
106
107 return this;
108};
109
110EventEmitter.prototype.addListener = EventEmitter.prototype.on;
111
112/**
113 * Adds a volatile listener.
114 *
115 * @api public
116 */
117
118EventEmitter.prototype.once = function (name, fn) {
119 var self = this;
120
121 function on () {
122 self.removeListener(name, on);
123 fn.apply(this, arguments);
124 };
125
126 on.listener = fn;
127 this.on(name, on);
128
129 return this;
130};
131
132/**
133 * Removes a listener.
134 *
135 * @api public
136 */
137
138EventEmitter.prototype.removeListener = function (name, fn) {
139 if (this.$events && this.$events[name]) {
140 var list = this.$events[name];
141
142 if (isArray(list)) {
143 var pos = -1;
144
145 for (var i = 0, l = list.length; i < l; i++) {
146 if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
147 pos = i;
148 break;
149 }
150 }
151
152 if (pos < 0) {
153 return this;
154 }
155
156 list.splice(pos, 1);
157
158 if (!list.length) {
159 delete this.$events[name];
160 }
161 } else if (list === fn || (list.listener && list.listener === fn)) {
162 delete this.$events[name];
163 }
164 }
165
166 return this;
167};
168
169/**
170 * Removes all listeners for an event.
171 *
172 * @api public
173 */
174
175EventEmitter.prototype.removeAllListeners = function (name) {
176 if (name === undefined) {
177 this.$events = {};
178 return this;
179 }
180
181 if (this.$events && this.$events[name]) {
182 this.$events[name] = null;
183 }
184
185 return this;
186};
187
188/**
189 * Gets all listeners for a certain event.
190 *
191 * @api public
192 */
193
194EventEmitter.prototype.listeners = function (name) {
195 if (!this.$events) {
196 this.$events = {};
197 }
198
199 if (!this.$events[name]) {
200 this.$events[name] = [];
201 }
202
203 if (!isArray(this.$events[name])) {
204 this.$events[name] = [this.$events[name]];
205 }
206
207 return this.$events[name];
208};
209
210/**
211 * Emits an event.
212 *
213 * @api public
214 */
215
216EventEmitter.prototype.emit = function (name) {
217 if (!this.$events) {
218 return false;
219 }
220
221 var handler = this.$events[name];
222
223 if (!handler) {
224 return false;
225 }
226
227 var args = [].slice.call(arguments, 1);
228
229 if ('function' == typeof handler) {
230 handler.apply(this, args);
231 } else if (isArray(handler)) {
232 var listeners = handler.slice();
233
234 for (var i = 0, l = listeners.length; i < l; i++) {
235 listeners[i].apply(this, args);
236 }
237 } else {
238 return false;
239 }
240
241 return true;
242};
243}); // module: browser/events.js
244
245require.register("browser/fs.js", function(module, exports, require){
246
247}); // module: browser/fs.js
248
249require.register("browser/path.js", function(module, exports, require){
250
251}); // module: browser/path.js
252
253require.register("browser/progress.js", function(module, exports, require){
254
255/**
256 * Expose `Progress`.
257 */
258
259module.exports = Progress;
260
261/**
262 * Initialize a new `Progress` indicator.
263 */
264
265function Progress() {
266 this.percent = 0;
267 this.size(0);
268 this.fontSize(11);
269 this.font('helvetica, arial, sans-serif');
270}
271
272/**
273 * Set progress size to `n`.
274 *
275 * @param {Number} n
276 * @return {Progress} for chaining
277 * @api public
278 */
279
280Progress.prototype.size = function(n){
281 this._size = n;
282 return this;
283};
284
285/**
286 * Set text to `str`.
287 *
288 * @param {String} str
289 * @return {Progress} for chaining
290 * @api public
291 */
292
293Progress.prototype.text = function(str){
294 this._text = str;
295 return this;
296};
297
298/**
299 * Set font size to `n`.
300 *
301 * @param {Number} n
302 * @return {Progress} for chaining
303 * @api public
304 */
305
306Progress.prototype.fontSize = function(n){
307 this._fontSize = n;
308 return this;
309};
310
311/**
312 * Set font `family`.
313 *
314 * @param {String} family
315 * @return {Progress} for chaining
316 */
317
318Progress.prototype.font = function(family){
319 this._font = family;
320 return this;
321};
322
323/**
324 * Update percentage to `n`.
325 *
326 * @param {Number} n
327 * @return {Progress} for chaining
328 */
329
330Progress.prototype.update = function(n){
331 this.percent = n;
332 return this;
333};
334
335/**
336 * Draw on `ctx`.
337 *
338 * @param {CanvasRenderingContext2d} ctx
339 * @return {Progress} for chaining
340 */
341
342Progress.prototype.draw = function(ctx){
343 var percent = Math.min(this.percent, 100)
344 , size = this._size
345 , half = size / 2
346 , x = half
347 , y = half
348 , rad = half - 1
349 , fontSize = this._fontSize;
350
351 ctx.font = fontSize + 'px ' + this._font;
352
353 var angle = Math.PI * 2 * (percent / 100);
354 ctx.clearRect(0, 0, size, size);
355
356 // outer circle
357 ctx.strokeStyle = '#9f9f9f';
358 ctx.beginPath();
359 ctx.arc(x, y, rad, 0, angle, false);
360 ctx.stroke();
361
362 // inner circle
363 ctx.strokeStyle = '#eee';
364 ctx.beginPath();
365 ctx.arc(x, y, rad - 1, 0, angle, true);
366 ctx.stroke();
367
368 // text
369 var text = this._text || (percent | 0) + '%'
370 , w = ctx.measureText(text).width;
371
372 ctx.fillText(
373 text
374 , x - w / 2 + 1
375 , y + fontSize / 2 - 1);
376
377 return this;
378};
379
380}); // module: browser/progress.js
381
382require.register("browser/tty.js", function(module, exports, require){
383
384exports.isatty = function(){
385 return true;
386};
387
388exports.getWindowSize = function(){
389 return [window.innerHeight, window.innerWidth];
390};
391}); // module: browser/tty.js
392
393require.register("context.js", function(module, exports, require){
394
395/**
396 * Expose `Context`.
397 */
398
399module.exports = Context;
400
401/**
402 * Initialize a new `Context`.
403 *
404 * @api private
405 */
406
407function Context(){}
408
409/**
410 * Set or get the context `Runnable` to `runnable`.
411 *
412 * @param {Runnable} runnable
413 * @return {Context}
414 * @api private
415 */
416
417Context.prototype.runnable = function(runnable){
418 if (0 == arguments.length) return this._runnable;
419 this.test = this._runnable = runnable;
420 return this;
421};
422
423/**
424 * Set test timeout `ms`.
425 *
426 * @param {Number} ms
427 * @return {Context} self
428 * @api private
429 */
430
431Context.prototype.timeout = function(ms){
432 this.runnable().timeout(ms);
433 return this;
434};
435
436/**
437 * Inspect the context void of `._runnable`.
438 *
439 * @return {String}
440 * @api private
441 */
442
443Context.prototype.inspect = function(){
444 return JSON.stringify(this, function(key, val){
445 if ('_runnable' == key) return;
446 if ('test' == key) return;
447 return val;
448 }, 2);
449};
450
451}); // module: context.js
452
453require.register("hook.js", function(module, exports, require){
454
455/**
456 * Module dependencies.
457 */
458
459var Runnable = require('./runnable');
460
461/**
462 * Expose `Hook`.
463 */
464
465module.exports = Hook;
466
467/**
468 * Initialize a new `Hook` with the given `title` and callback `fn`.
469 *
470 * @param {String} title
471 * @param {Function} fn
472 * @api private
473 */
474
475function Hook(title, fn) {
476 Runnable.call(this, title, fn);
477 this.type = 'hook';
478}
479
480/**
481 * Inherit from `Runnable.prototype`.
482 */
483
484Hook.prototype = new Runnable;
485Hook.prototype.constructor = Hook;
486
487
488/**
489 * Get or set the test `err`.
490 *
491 * @param {Error} err
492 * @return {Error}
493 * @api public
494 */
495
496Hook.prototype.error = function(err){
497 if (0 == arguments.length) {
498 var err = this._error;
499 this._error = null;
500 return err;
501 }
502
503 this._error = err;
504};
505
506
507}); // module: hook.js
508
509require.register("interfaces/bdd.js", function(module, exports, require){
510
511/**
512 * Module dependencies.
513 */
514
515var Suite = require('../suite')
516 , Test = require('../test');
517
518/**
519 * BDD-style interface:
520 *
521 * describe('Array', function(){
522 * describe('#indexOf()', function(){
523 * it('should return -1 when not present', function(){
524 *
525 * });
526 *
527 * it('should return the index when present', function(){
528 *
529 * });
530 * });
531 * });
532 *
533 */
534
535module.exports = function(suite){
536 var suites = [suite];
537
538 suite.on('pre-require', function(context, file, mocha){
539
540 /**
541 * Execute before running tests.
542 */
543
544 context.before = function(fn){
545 suites[0].beforeAll(fn);
546 };
547
548 /**
549 * Execute after running tests.
550 */
551
552 context.after = function(fn){
553 suites[0].afterAll(fn);
554 };
555
556 /**
557 * Execute before each test case.
558 */
559
560 context.beforeEach = function(fn){
561 suites[0].beforeEach(fn);
562 };
563
564 /**
565 * Execute after each test case.
566 */
567
568 context.afterEach = function(fn){
569 suites[0].afterEach(fn);
570 };
571
572 /**
573 * Describe a "suite" with the given `title`
574 * and callback `fn` containing nested suites
575 * and/or tests.
576 */
577
578 context.describe = context.context = function(title, fn){
579 var suite = Suite.create(suites[0], title);
580 suites.unshift(suite);
581 fn();
582 suites.shift();
583 return suite;
584 };
585
586 /**
587 * Pending describe.
588 */
589
590 context.xdescribe =
591 context.xcontext =
592 context.describe.skip = function(title, fn){
593 var suite = Suite.create(suites[0], title);
594 suite.pending = true;
595 suites.unshift(suite);
596 fn();
597 suites.shift();
598 };
599
600 /**
601 * Exclusive suite.
602 */
603
604 context.describe.only = function(title, fn){
605 var suite = context.describe(title, fn);
606 mocha.grep(suite.fullTitle());
607 };
608
609 /**
610 * Describe a specification or test-case
611 * with the given `title` and callback `fn`
612 * acting as a thunk.
613 */
614
615 context.it = context.specify = function(title, fn){
616 var suite = suites[0];
617 if (suite.pending) var fn = null;
618 var test = new Test(title, fn);
619 suite.addTest(test);
620 return test;
621 };
622
623 /**
624 * Exclusive test-case.
625 */
626
627 context.it.only = function(title, fn){
628 var test = context.it(title, fn);
629 mocha.grep(test.fullTitle());
630 };
631
632 /**
633 * Pending test case.
634 */
635
636 context.xit =
637 context.xspecify =
638 context.it.skip = function(title){
639 context.it(title);
640 };
641 });
642};
643
644}); // module: interfaces/bdd.js
645
646require.register("interfaces/exports.js", function(module, exports, require){
647
648/**
649 * Module dependencies.
650 */
651
652var Suite = require('../suite')
653 , Test = require('../test');
654
655/**
656 * TDD-style interface:
657 *
658 * exports.Array = {
659 * '#indexOf()': {
660 * 'should return -1 when the value is not present': function(){
661 *
662 * },
663 *
664 * 'should return the correct index when the value is present': function(){
665 *
666 * }
667 * }
668 * };
669 *
670 */
671
672module.exports = function(suite){
673 var suites = [suite];
674
675 suite.on('require', visit);
676
677 function visit(obj) {
678 var suite;
679 for (var key in obj) {
680 if ('function' == typeof obj[key]) {
681 var fn = obj[key];
682 switch (key) {
683 case 'before':
684 suites[0].beforeAll(fn);
685 break;
686 case 'after':
687 suites[0].afterAll(fn);
688 break;
689 case 'beforeEach':
690 suites[0].beforeEach(fn);
691 break;
692 case 'afterEach':
693 suites[0].afterEach(fn);
694 break;
695 default:
696 suites[0].addTest(new Test(key, fn));
697 }
698 } else {
699 var suite = Suite.create(suites[0], key);
700 suites.unshift(suite);
701 visit(obj[key]);
702 suites.shift();
703 }
704 }
705 }
706};
707}); // module: interfaces/exports.js
708
709require.register("interfaces/index.js", function(module, exports, require){
710
711exports.bdd = require('./bdd');
712exports.tdd = require('./tdd');
713exports.qunit = require('./qunit');
714exports.exports = require('./exports');
715
716}); // module: interfaces/index.js
717
718require.register("interfaces/qunit.js", function(module, exports, require){
719
720/**
721 * Module dependencies.
722 */
723
724var Suite = require('../suite')
725 , Test = require('../test');
726
727/**
728 * QUnit-style interface:
729 *
730 * suite('Array');
731 *
732 * test('#length', function(){
733 * var arr = [1,2,3];
734 * ok(arr.length == 3);
735 * });
736 *
737 * test('#indexOf()', function(){
738 * var arr = [1,2,3];
739 * ok(arr.indexOf(1) == 0);
740 * ok(arr.indexOf(2) == 1);
741 * ok(arr.indexOf(3) == 2);
742 * });
743 *
744 * suite('String');
745 *
746 * test('#length', function(){
747 * ok('foo'.length == 3);
748 * });
749 *
750 */
751
752module.exports = function(suite){
753 var suites = [suite];
754
755 suite.on('pre-require', function(context){
756
757 /**
758 * Execute before running tests.
759 */
760
761 context.before = function(fn){
762 suites[0].beforeAll(fn);
763 };
764
765 /**
766 * Execute after running tests.
767 */
768
769 context.after = function(fn){
770 suites[0].afterAll(fn);
771 };
772
773 /**
774 * Execute before each test case.
775 */
776
777 context.beforeEach = function(fn){
778 suites[0].beforeEach(fn);
779 };
780
781 /**
782 * Execute after each test case.
783 */
784
785 context.afterEach = function(fn){
786 suites[0].afterEach(fn);
787 };
788
789 /**
790 * Describe a "suite" with the given `title`.
791 */
792
793 context.suite = function(title){
794 if (suites.length > 1) suites.shift();
795 var suite = Suite.create(suites[0], title);
796 suites.unshift(suite);
797 };
798
799 /**
800 * Describe a specification or test-case
801 * with the given `title` and callback `fn`
802 * acting as a thunk.
803 */
804
805 context.test = function(title, fn){
806 suites[0].addTest(new Test(title, fn));
807 };
808 });
809};
810
811}); // module: interfaces/qunit.js
812
813require.register("interfaces/tdd.js", function(module, exports, require){
814
815/**
816 * Module dependencies.
817 */
818
819var Suite = require('../suite')
820 , Test = require('../test');
821
822/**
823 * TDD-style interface:
824 *
825 * suite('Array', function(){
826 * suite('#indexOf()', function(){
827 * suiteSetup(function(){
828 *
829 * });
830 *
831 * test('should return -1 when not present', function(){
832 *
833 * });
834 *
835 * test('should return the index when present', function(){
836 *
837 * });
838 *
839 * suiteTeardown(function(){
840 *
841 * });
842 * });
843 * });
844 *
845 */
846
847module.exports = function(suite){
848 var suites = [suite];
849
850 suite.on('pre-require', function(context, file, mocha){
851
852 /**
853 * Execute before each test case.
854 */
855
856 context.setup = function(fn){
857 suites[0].beforeEach(fn);
858 };
859
860 /**
861 * Execute after each test case.
862 */
863
864 context.teardown = function(fn){
865 suites[0].afterEach(fn);
866 };
867
868 /**
869 * Execute before the suite.
870 */
871
872 context.suiteSetup = function(fn){
873 suites[0].beforeAll(fn);
874 };
875
876 /**
877 * Execute after the suite.
878 */
879
880 context.suiteTeardown = function(fn){
881 suites[0].afterAll(fn);
882 };
883
884 /**
885 * Describe a "suite" with the given `title`
886 * and callback `fn` containing nested suites
887 * and/or tests.
888 */
889
890 context.suite = function(title, fn){
891 var suite = Suite.create(suites[0], title);
892 suites.unshift(suite);
893 fn();
894 suites.shift();
895 return suite;
896 };
897
898 /**
899 * Exclusive test-case.
900 */
901
902 context.suite.only = function(title, fn){
903 var suite = context.suite(title, fn);
904 mocha.grep(suite.fullTitle());
905 };
906
907 /**
908 * Describe a specification or test-case
909 * with the given `title` and callback `fn`
910 * acting as a thunk.
911 */
912
913 context.test = function(title, fn){
914 var test = new Test(title, fn);
915 suites[0].addTest(test);
916 return test;
917 };
918
919 /**
920 * Exclusive test-case.
921 */
922
923 context.test.only = function(title, fn){
924 var test = context.test(title, fn);
925 mocha.grep(test.fullTitle());
926 };
927 });
928};
929
930}); // module: interfaces/tdd.js
931
932require.register("mocha.js", function(module, exports, require){
933/*!
934 * mocha
935 * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
936 * MIT Licensed
937 */
938
939/**
940 * Module dependencies.
941 */
942
943var path = require('browser/path')
944 , utils = require('./utils');
945
946/**
947 * Expose `Mocha`.
948 */
949
950exports = module.exports = Mocha;
951
952/**
953 * Expose internals.
954 */
955
956exports.utils = utils;
957exports.interfaces = require('./interfaces');
958exports.reporters = require('./reporters');
959exports.Runnable = require('./runnable');
960exports.Context = require('./context');
961exports.Runner = require('./runner');
962exports.Suite = require('./suite');
963exports.Hook = require('./hook');
964exports.Test = require('./test');
965
966/**
967 * Return image `name` path.
968 *
969 * @param {String} name
970 * @return {String}
971 * @api private
972 */
973
974function image(name) {
975 return __dirname + '/../images/' + name + '.png';
976}
977
978/**
979 * Setup mocha with `options`.
980 *
981 * Options:
982 *
983 * - `ui` name "bdd", "tdd", "exports" etc
984 * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
985 * - `globals` array of accepted globals
986 * - `timeout` timeout in milliseconds
987 * - `ignoreLeaks` ignore global leaks
988 * - `grep` string or regexp to filter tests with
989 *
990 * @param {Object} options
991 * @api public
992 */
993
994function Mocha(options) {
995 options = options || {};
996 this.files = [];
997 this.options = options;
998 this.grep(options.grep);
999 this.suite = new exports.Suite('', new exports.Context);
1000 this.ui(options.ui);
1001 this.reporter(options.reporter);
1002 if (options.timeout) this.timeout(options.timeout);
1003}
1004
1005/**
1006 * Add test `file`.
1007 *
1008 * @param {String} file
1009 * @api public
1010 */
1011
1012Mocha.prototype.addFile = function(file){
1013 this.files.push(file);
1014 return this;
1015};
1016
1017/**
1018 * Set reporter to `reporter`, defaults to "dot".
1019 *
1020 * @param {String|Function} reporter name of a reporter or a reporter constructor
1021 * @api public
1022 */
1023
1024Mocha.prototype.reporter = function(reporter){
1025 if ('function' == typeof reporter) {
1026 this._reporter = reporter;
1027 } else {
1028 reporter = reporter || 'dot';
1029 try {
1030 this._reporter = require('./reporters/' + reporter);
1031 } catch (err) {
1032 this._reporter = require(reporter);
1033 }
1034 if (!this._reporter) throw new Error('invalid reporter "' + reporter + '"');
1035 }
1036 return this;
1037};
1038
1039/**
1040 * Set test UI `name`, defaults to "bdd".
1041 *
1042 * @param {String} bdd
1043 * @api public
1044 */
1045
1046Mocha.prototype.ui = function(name){
1047 name = name || 'bdd';
1048 this._ui = exports.interfaces[name];
1049 if (!this._ui) throw new Error('invalid interface "' + name + '"');
1050 this._ui = this._ui(this.suite);
1051 return this;
1052};
1053
1054/**
1055 * Load registered files.
1056 *
1057 * @api private
1058 */
1059
1060Mocha.prototype.loadFiles = function(fn){
1061 var self = this;
1062 var suite = this.suite;
1063 var pending = this.files.length;
1064 this.files.forEach(function(file){
1065 file = path.resolve(file);
1066 suite.emit('pre-require', global, file, self);
1067 suite.emit('require', require(file), file, self);
1068 suite.emit('post-require', global, file, self);
1069 --pending || (fn && fn());
1070 });
1071};
1072
1073/**
1074 * Enable growl support.
1075 *
1076 * @api private
1077 */
1078
1079Mocha.prototype._growl = function(runner, reporter) {
1080 var notify = require('growl');
1081
1082 runner.on('end', function(){
1083 var stats = reporter.stats;
1084 if (stats.failures) {
1085 var msg = stats.failures + ' of ' + runner.total + ' tests failed';
1086 notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
1087 } else {
1088 notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
1089 name: 'mocha'
1090 , title: 'Passed'
1091 , image: image('ok')
1092 });
1093 }
1094 });
1095};
1096
1097/**
1098 * Add regexp to grep, if `re` is a string it is escaped.
1099 *
1100 * @param {RegExp|String} re
1101 * @return {Mocha}
1102 * @api public
1103 */
1104
1105Mocha.prototype.grep = function(re){
1106 this.options.grep = 'string' == typeof re
1107 ? new RegExp(utils.escapeRegexp(re))
1108 : re;
1109 return this;
1110};
1111
1112/**
1113 * Invert `.grep()` matches.
1114 *
1115 * @return {Mocha}
1116 * @api public
1117 */
1118
1119Mocha.prototype.invert = function(){
1120 this.options.invert = true;
1121 return this;
1122};
1123
1124/**
1125 * Ignore global leaks.
1126 *
1127 * @return {Mocha}
1128 * @api public
1129 */
1130
1131Mocha.prototype.ignoreLeaks = function(){
1132 this.options.ignoreLeaks = true;
1133 return this;
1134};
1135
1136/**
1137 * Enable growl support.
1138 *
1139 * @return {Mocha}
1140 * @api public
1141 */
1142
1143Mocha.prototype.growl = function(){
1144 this.options.growl = true;
1145 return this;
1146};
1147
1148/**
1149 * Ignore `globals` array or string.
1150 *
1151 * @param {Array|String} globals
1152 * @return {Mocha}
1153 * @api public
1154 */
1155
1156Mocha.prototype.globals = function(globals){
1157 this.options.globals = (this.options.globals || []).concat(globals);
1158 return this;
1159};
1160
1161/**
1162 * Set the timeout in milliseconds.
1163 *
1164 * @param {Number} timeout
1165 * @return {Mocha}
1166 * @api public
1167 */
1168
1169Mocha.prototype.timeout = function(timeout){
1170 this.suite.timeout(timeout);
1171 return this;
1172};
1173
1174/**
1175 * Run tests and invoke `fn()` when complete.
1176 *
1177 * @param {Function} fn
1178 * @return {Runner}
1179 * @api public
1180 */
1181
1182Mocha.prototype.run = function(fn){
1183 this.loadFiles();
1184 var suite = this.suite;
1185 var options = this.options;
1186 var runner = new exports.Runner(suite);
1187 var reporter = new this._reporter(runner);
1188 runner.ignoreLeaks = options.ignoreLeaks;
1189 if (options.grep) runner.grep(options.grep, options.invert);
1190 if (options.globals) runner.globals(options.globals);
1191 if (options.growl) this._growl(runner, reporter);
1192 return runner.run(fn);
1193};
1194
1195}); // module: mocha.js
1196
1197require.register("reporters/base.js", function(module, exports, require){
1198
1199/**
1200 * Module dependencies.
1201 */
1202
1203var tty = require('browser/tty')
1204 , diff = require('browser/diff');
1205
1206/**
1207 * Save timer references to avoid Sinon interfering (see GH-237).
1208 */
1209
1210var Date = global.Date
1211 , setTimeout = global.setTimeout
1212 , setInterval = global.setInterval
1213 , clearTimeout = global.clearTimeout
1214 , clearInterval = global.clearInterval;
1215
1216/**
1217 * Check if both stdio streams are associated with a tty.
1218 */
1219
1220var isatty = tty.isatty(1) && tty.isatty(2);
1221
1222/**
1223 * Expose `Base`.
1224 */
1225
1226exports = module.exports = Base;
1227
1228/**
1229 * Enable coloring by default.
1230 */
1231
1232exports.useColors = isatty;
1233
1234/**
1235 * Default color map.
1236 */
1237
1238exports.colors = {
1239 'pass': 90
1240 , 'fail': 31
1241 , 'bright pass': 92
1242 , 'bright fail': 91
1243 , 'bright yellow': 93
1244 , 'pending': 36
1245 , 'suite': 0
1246 , 'error title': 0
1247 , 'error message': 31
1248 , 'error stack': 90
1249 , 'checkmark': 32
1250 , 'fast': 90
1251 , 'medium': 33
1252 , 'slow': 31
1253 , 'green': 32
1254 , 'light': 90
1255 , 'diff gutter': 90
1256 , 'diff added': 42
1257 , 'diff removed': 41
1258};
1259
1260/**
1261 * Color `str` with the given `type`,
1262 * allowing colors to be disabled,
1263 * as well as user-defined color
1264 * schemes.
1265 *
1266 * @param {String} type
1267 * @param {String} str
1268 * @return {String}
1269 * @api private
1270 */
1271
1272var color = exports.color = function(type, str) {
1273 if (!exports.useColors) return str;
1274 return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
1275};
1276
1277/**
1278 * Expose term window size, with some
1279 * defaults for when stderr is not a tty.
1280 */
1281
1282exports.window = {
1283 width: isatty
1284 ? process.stdout.getWindowSize
1285 ? process.stdout.getWindowSize(1)[0]
1286 : tty.getWindowSize()[1]
1287 : 75
1288};
1289
1290/**
1291 * Expose some basic cursor interactions
1292 * that are common among reporters.
1293 */
1294
1295exports.cursor = {
1296 hide: function(){
1297 process.stdout.write('\u001b[?25l');
1298 },
1299
1300 show: function(){
1301 process.stdout.write('\u001b[?25h');
1302 },
1303
1304 deleteLine: function(){
1305 process.stdout.write('\u001b[2K');
1306 },
1307
1308 beginningOfLine: function(){
1309 process.stdout.write('\u001b[0G');
1310 },
1311
1312 CR: function(){
1313 exports.cursor.deleteLine();
1314 exports.cursor.beginningOfLine();
1315 }
1316};
1317
1318/**
1319 * A test is considered slow if it
1320 * exceeds the following value in milliseconds.
1321 */
1322
1323exports.slow = 75;
1324
1325/**
1326 * Outut the given `failures` as a list.
1327 *
1328 * @param {Array} failures
1329 * @api public
1330 */
1331
1332exports.list = function(failures){
1333 console.error();
1334 failures.forEach(function(test, i){
1335 // format
1336 var fmt = color('error title', ' %s) %s:\n')
1337 + color('error message', ' %s')
1338 + color('error stack', '\n%s\n');
1339
1340 // msg
1341 var err = test.err
1342 , message = err.message || ''
1343 , stack = err.stack || message
1344 , index = stack.indexOf(message) + message.length
1345 , msg = stack.slice(0, index)
1346 , actual = err.actual
1347 , expected = err.expected;
1348
1349 // actual / expected diff
1350 if ('string' == typeof actual && 'string' == typeof expected) {
1351 var len = Math.max(actual.length, expected.length);
1352
1353 if (len < 20) msg = errorDiff(err, 'Chars');
1354 else msg = errorDiff(err, 'Words');
1355
1356 // linenos
1357 var lines = msg.split('\n');
1358 if (lines.length > 4) {
1359 var width = String(lines.length).length;
1360 msg = lines.map(function(str, i){
1361 return pad(++i, width) + ' |' + ' ' + str;
1362 }).join('\n');
1363 }
1364
1365 // legend
1366 msg = '\n'
1367 + color('diff removed', 'actual')
1368 + ' '
1369 + color('diff added', 'expected')
1370 + '\n\n'
1371 + msg
1372 + '\n';
1373
1374 // indent
1375 msg = msg.replace(/^/gm, ' ');
1376
1377 fmt = color('error title', ' %s) %s:\n%s')
1378 + color('error stack', '\n%s\n');
1379 }
1380
1381 // indent stack trace without msg
1382 stack = stack.slice(index ? index + 1 : index)
1383 .replace(/^/gm, ' ');
1384
1385 console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
1386 });
1387};
1388
1389/**
1390 * Initialize a new `Base` reporter.
1391 *
1392 * All other reporters generally
1393 * inherit from this reporter, providing
1394 * stats such as test duration, number
1395 * of tests passed / failed etc.
1396 *
1397 * @param {Runner} runner
1398 * @api public
1399 */
1400
1401function Base(runner) {
1402 var self = this
1403 , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
1404 , failures = this.failures = [];
1405
1406 if (!runner) return;
1407 this.runner = runner;
1408
1409 runner.on('start', function(){
1410 stats.start = new Date;
1411 });
1412
1413 runner.on('suite', function(suite){
1414 stats.suites = stats.suites || 0;
1415 suite.root || stats.suites++;
1416 });
1417
1418 runner.on('test end', function(test){
1419 stats.tests = stats.tests || 0;
1420 stats.tests++;
1421 });
1422
1423 runner.on('pass', function(test){
1424 stats.passes = stats.passes || 0;
1425
1426 var medium = exports.slow / 2;
1427 test.speed = test.duration > exports.slow
1428 ? 'slow'
1429 : test.duration > medium
1430 ? 'medium'
1431 : 'fast';
1432
1433 stats.passes++;
1434 });
1435
1436 runner.on('fail', function(test, err){
1437 stats.failures = stats.failures || 0;
1438 stats.failures++;
1439 test.err = err;
1440 failures.push(test);
1441 });
1442
1443 runner.on('end', function(){
1444 stats.end = new Date;
1445 stats.duration = new Date - stats.start;
1446 });
1447
1448 runner.on('pending', function(){
1449 stats.pending++;
1450 });
1451}
1452
1453/**
1454 * Output common epilogue used by many of
1455 * the bundled reporters.
1456 *
1457 * @api public
1458 */
1459
1460Base.prototype.epilogue = function(){
1461 var stats = this.stats
1462 , fmt
1463 , tests;
1464
1465 console.log();
1466
1467 function pluralize(n) {
1468 return 1 == n ? 'test' : 'tests';
1469 }
1470
1471 // failure
1472 if (stats.failures) {
1473 fmt = color('bright fail', ' ✖')
1474 + color('fail', ' %d of %d %s failed')
1475 + color('light', ':')
1476
1477 console.error(fmt,
1478 stats.failures,
1479 this.runner.total,
1480 pluralize(this.runner.total));
1481
1482 Base.list(this.failures);
1483 console.error();
1484 return;
1485 }
1486
1487 // pass
1488 fmt = color('bright pass', ' ✔')
1489 + color('green', ' %d %s complete')
1490 + color('light', ' (%dms)');
1491
1492 console.log(fmt,
1493 stats.tests || 0,
1494 pluralize(stats.tests),
1495 stats.duration);
1496
1497 // pending
1498 if (stats.pending) {
1499 fmt = color('pending', ' •')
1500 + color('pending', ' %d %s pending');
1501
1502 console.log(fmt, stats.pending, pluralize(stats.pending));
1503 }
1504
1505 console.log();
1506};
1507
1508/**
1509 * Pad the given `str` to `len`.
1510 *
1511 * @param {String} str
1512 * @param {String} len
1513 * @return {String}
1514 * @api private
1515 */
1516
1517function pad(str, len) {
1518 str = String(str);
1519 return Array(len - str.length + 1).join(' ') + str;
1520}
1521
1522/**
1523 * Return a character diff for `err`.
1524 *
1525 * @param {Error} err
1526 * @return {String}
1527 * @api private
1528 */
1529
1530function errorDiff(err, type) {
1531 return diff['diff' + type](err.actual, err.expected).map(function(str){
1532 if (/^(\n+)$/.test(str.value)) str.value = Array(++RegExp.$1.length).join('<newline>');
1533 if (str.added) return colorLines('diff added', str.value);
1534 if (str.removed) return colorLines('diff removed', str.value);
1535 return str.value;
1536 }).join('');
1537}
1538
1539/**
1540 * Color lines for `str`, using the color `name`.
1541 *
1542 * @param {String} name
1543 * @param {String} str
1544 * @return {String}
1545 * @api private
1546 */
1547
1548function colorLines(name, str) {
1549 return str.split('\n').map(function(str){
1550 return color(name, str);
1551 }).join('\n');
1552}
1553
1554}); // module: reporters/base.js
1555
1556require.register("reporters/doc.js", function(module, exports, require){
1557
1558/**
1559 * Module dependencies.
1560 */
1561
1562var Base = require('./base')
1563 , utils = require('../utils');
1564
1565/**
1566 * Expose `Doc`.
1567 */
1568
1569exports = module.exports = Doc;
1570
1571/**
1572 * Initialize a new `Doc` reporter.
1573 *
1574 * @param {Runner} runner
1575 * @api public
1576 */
1577
1578function Doc(runner) {
1579 Base.call(this, runner);
1580
1581 var self = this
1582 , stats = this.stats
1583 , total = runner.total
1584 , indents = 2;
1585
1586 function indent() {
1587 return Array(indents).join(' ');
1588 }
1589
1590 runner.on('suite', function(suite){
1591 if (suite.root) return;
1592 ++indents;
1593 console.log('%s<section class="suite">', indent());
1594 ++indents;
1595 console.log('%s<h1>%s</h1>', indent(), suite.title);
1596 console.log('%s<dl>', indent());
1597 });
1598
1599 runner.on('suite end', function(suite){
1600 if (suite.root) return;
1601 console.log('%s</dl>', indent());
1602 --indents;
1603 console.log('%s</section>', indent());
1604 --indents;
1605 });
1606
1607 runner.on('pass', function(test){
1608 console.log('%s <dt>%s</dt>', indent(), test.title);
1609 var code = utils.escape(utils.clean(test.fn.toString()));
1610 console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
1611 });
1612}
1613
1614}); // module: reporters/doc.js
1615
1616require.register("reporters/dot.js", function(module, exports, require){
1617
1618/**
1619 * Module dependencies.
1620 */
1621
1622var Base = require('./base')
1623 , color = Base.color;
1624
1625/**
1626 * Expose `Dot`.
1627 */
1628
1629exports = module.exports = Dot;
1630
1631/**
1632 * Initialize a new `Dot` matrix test reporter.
1633 *
1634 * @param {Runner} runner
1635 * @api public
1636 */
1637
1638function Dot(runner) {
1639 Base.call(this, runner);
1640
1641 var self = this
1642 , stats = this.stats
1643 , width = Base.window.width * .75 | 0
1644 , c = '․'
1645 , n = 0;
1646
1647 runner.on('start', function(){
1648 process.stdout.write('\n ');
1649 });
1650
1651 runner.on('pending', function(test){
1652 process.stdout.write(color('pending', c));
1653 });
1654
1655 runner.on('pass', function(test){
1656 if (++n % width == 0) process.stdout.write('\n ');
1657 if ('slow' == test.speed) {
1658 process.stdout.write(color('bright yellow', c));
1659 } else {
1660 process.stdout.write(color(test.speed, c));
1661 }
1662 });
1663
1664 runner.on('fail', function(test, err){
1665 if (++n % width == 0) process.stdout.write('\n ');
1666 process.stdout.write(color('fail', c));
1667 });
1668
1669 runner.on('end', function(){
1670 console.log();
1671 self.epilogue();
1672 });
1673}
1674
1675/**
1676 * Inherit from `Base.prototype`.
1677 */
1678
1679Dot.prototype = new Base;
1680Dot.prototype.constructor = Dot;
1681
1682}); // module: reporters/dot.js
1683
1684require.register("reporters/html-cov.js", function(module, exports, require){
1685
1686/**
1687 * Module dependencies.
1688 */
1689
1690var JSONCov = require('./json-cov')
1691 , fs = require('browser/fs');
1692
1693/**
1694 * Expose `HTMLCov`.
1695 */
1696
1697exports = module.exports = HTMLCov;
1698
1699/**
1700 * Initialize a new `JsCoverage` reporter.
1701 *
1702 * @param {Runner} runner
1703 * @api public
1704 */
1705
1706function HTMLCov(runner) {
1707 var jade = require('jade')
1708 , file = __dirname + '/templates/coverage.jade'
1709 , str = fs.readFileSync(file, 'utf8')
1710 , fn = jade.compile(str, { filename: file })
1711 , self = this;
1712
1713 JSONCov.call(this, runner, false);
1714
1715 runner.on('end', function(){
1716 process.stdout.write(fn({
1717 cov: self.cov
1718 , coverageClass: coverageClass
1719 }));
1720 });
1721}
1722
1723/**
1724 * Return coverage class for `n`.
1725 *
1726 * @return {String}
1727 * @api private
1728 */
1729
1730function coverageClass(n) {
1731 if (n >= 75) return 'high';
1732 if (n >= 50) return 'medium';
1733 if (n >= 25) return 'low';
1734 return 'terrible';
1735}
1736}); // module: reporters/html-cov.js
1737
1738require.register("reporters/html.js", function(module, exports, require){
1739
1740/**
1741 * Module dependencies.
1742 */
1743
1744var Base = require('./base')
1745 , utils = require('../utils')
1746 , Progress = require('../browser/progress')
1747 , escape = utils.escape;
1748
1749/**
1750 * Save timer references to avoid Sinon interfering (see GH-237).
1751 */
1752
1753var Date = global.Date
1754 , setTimeout = global.setTimeout
1755 , setInterval = global.setInterval
1756 , clearTimeout = global.clearTimeout
1757 , clearInterval = global.clearInterval;
1758
1759/**
1760 * Expose `Doc`.
1761 */
1762
1763exports = module.exports = HTML;
1764
1765/**
1766 * Stats template.
1767 */
1768
1769var statsTemplate = '<ul id="stats">'
1770 + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
1771 + '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
1772 + '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
1773 + '<li class="duration">duration: <em>0</em>s</li>'
1774 + '</ul>';
1775
1776/**
1777 * Initialize a new `Doc` reporter.
1778 *
1779 * @param {Runner} runner
1780 * @api public
1781 */
1782
1783function HTML(runner, root) {
1784 Base.call(this, runner);
1785
1786 var self = this
1787 , stats = this.stats
1788 , total = runner.total
1789 , stat = fragment(statsTemplate)
1790 , items = stat.getElementsByTagName('li')
1791 , passes = items[1].getElementsByTagName('em')[0]
1792 , passesLink = items[1].getElementsByTagName('a')[0]
1793 , failures = items[2].getElementsByTagName('em')[0]
1794 , failuresLink = items[2].getElementsByTagName('a')[0]
1795 , duration = items[3].getElementsByTagName('em')[0]
1796 , canvas = stat.getElementsByTagName('canvas')[0]
1797 , report = fragment('<ul id="report"></ul>')
1798 , stack = [report]
1799 , progress
1800 , ctx
1801
1802 root = root || document.getElementById('mocha');
1803
1804 if (canvas.getContext) {
1805 var ratio = window.devicePixelRatio || 1;
1806 canvas.style.width = canvas.width;
1807 canvas.style.height = canvas.height;
1808 canvas.width *= ratio;
1809 canvas.height *= ratio;
1810 ctx = canvas.getContext('2d');
1811 ctx.scale(ratio, ratio);
1812 progress = new Progress;
1813 }
1814
1815 if (!root) return error('#mocha div missing, add it to your document');
1816
1817 // pass toggle
1818 on(passesLink, 'click', function () {
1819 var className = /pass/.test(report.className) ? '' : ' pass';
1820 report.className = report.className.replace(/fail|pass/g, '') + className;
1821 });
1822
1823 // failure toggle
1824 on(failuresLink, 'click', function () {
1825 var className = /fail/.test(report.className) ? '' : ' fail';
1826 report.className = report.className.replace(/fail|pass/g, '') + className;
1827 });
1828
1829 root.appendChild(stat);
1830 root.appendChild(report);
1831
1832 if (progress) progress.size(40);
1833
1834 runner.on('suite', function(suite){
1835 if (suite.root) return;
1836
1837 // suite
1838 var url = '?grep=' + encodeURIComponent(suite.fullTitle());
1839 var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
1840
1841 // container
1842 stack[0].appendChild(el);
1843 stack.unshift(document.createElement('ul'));
1844 el.appendChild(stack[0]);
1845 });
1846
1847 runner.on('suite end', function(suite){
1848 if (suite.root) return;
1849 stack.shift();
1850 });
1851
1852 runner.on('fail', function(test, err){
1853 if ('hook' == test.type || err.uncaught) runner.emit('test end', test);
1854 });
1855
1856 runner.on('test end', function(test){
1857 window.scrollTo(0, document.body.scrollHeight);
1858
1859 // TODO: add to stats
1860 var percent = stats.tests / total * 100 | 0;
1861 if (progress) progress.update(percent).draw(ctx);
1862
1863 // update stats
1864 var ms = new Date - stats.start;
1865 text(passes, stats.passes);
1866 text(failures, stats.failures);
1867 text(duration, (ms / 1000).toFixed(2));
1868
1869 // test
1870 if ('passed' == test.state) {
1871 var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span></h2></li>', test.speed, test.title, test.duration);
1872 } else if (test.pending) {
1873 var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
1874 } else {
1875 var el = fragment('<li class="test fail"><h2>%e</h2></li>', test.title);
1876 var str = test.err.stack || test.err.toString();
1877
1878 // FF / Opera do not add the message
1879 if (!~str.indexOf(test.err.message)) {
1880 str = test.err.message + '\n' + str;
1881 }
1882
1883 // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
1884 // check for the result of the stringifying.
1885 if ('[object Error]' == str) str = test.err.message;
1886
1887 // Safari doesn't give you a stack. Let's at least provide a source line.
1888 if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
1889 str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
1890 }
1891
1892 el.appendChild(fragment('<pre class="error">%e</pre>', str));
1893 }
1894
1895 // toggle code
1896 // TODO: defer
1897 if (!test.pending) {
1898 var h2 = el.getElementsByTagName('h2')[0];
1899
1900 on(h2, 'click', function(){
1901 pre.style.display = 'none' == pre.style.display
1902 ? 'inline-block'
1903 : 'none';
1904 });
1905
1906 var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
1907 el.appendChild(pre);
1908 pre.style.display = 'none';
1909 }
1910
1911 stack[0].appendChild(el);
1912 });
1913}
1914
1915/**
1916 * Display error `msg`.
1917 */
1918
1919function error(msg) {
1920 document.body.appendChild(fragment('<div id="error">%s</div>', msg));
1921}
1922
1923/**
1924 * Return a DOM fragment from `html`.
1925 */
1926
1927function fragment(html) {
1928 var args = arguments
1929 , div = document.createElement('div')
1930 , i = 1;
1931
1932 div.innerHTML = html.replace(/%([se])/g, function(_, type){
1933 switch (type) {
1934 case 's': return String(args[i++]);
1935 case 'e': return escape(args[i++]);
1936 }
1937 });
1938
1939 return div.firstChild;
1940}
1941
1942/**
1943 * Set `el` text to `str`.
1944 */
1945
1946function text(el, str) {
1947 if (el.textContent) {
1948 el.textContent = str;
1949 } else {
1950 el.innerText = str;
1951 }
1952}
1953
1954/**
1955 * Listen on `event` with callback `fn`.
1956 */
1957
1958function on(el, event, fn) {
1959 if (el.addEventListener) {
1960 el.addEventListener(event, fn, false);
1961 } else {
1962 el.attachEvent('on' + event, fn);
1963 }
1964}
1965
1966}); // module: reporters/html.js
1967
1968require.register("reporters/index.js", function(module, exports, require){
1969
1970exports.Base = require('./base');
1971exports.Dot = require('./dot');
1972exports.Doc = require('./doc');
1973exports.TAP = require('./tap');
1974exports.JSON = require('./json');
1975exports.HTML = require('./html');
1976exports.List = require('./list');
1977exports.Min = require('./min');
1978exports.Spec = require('./spec');
1979exports.Nyan = require('./nyan');
1980exports.XUnit = require('./xunit');
1981exports.Markdown = require('./markdown');
1982exports.Progress = require('./progress');
1983exports.Landing = require('./landing');
1984exports.JSONCov = require('./json-cov');
1985exports.HTMLCov = require('./html-cov');
1986exports.JSONStream = require('./json-stream');
1987exports.Teamcity = require('./teamcity');
1988
1989}); // module: reporters/index.js
1990
1991require.register("reporters/json-cov.js", function(module, exports, require){
1992
1993/**
1994 * Module dependencies.
1995 */
1996
1997var Base = require('./base');
1998
1999/**
2000 * Expose `JSONCov`.
2001 */
2002
2003exports = module.exports = JSONCov;
2004
2005/**
2006 * Initialize a new `JsCoverage` reporter.
2007 *
2008 * @param {Runner} runner
2009 * @param {Boolean} output
2010 * @api public
2011 */
2012
2013function JSONCov(runner, output) {
2014 var self = this
2015 , output = 1 == arguments.length ? true : output;
2016
2017 Base.call(this, runner);
2018
2019 var tests = []
2020 , failures = []
2021 , passes = [];
2022
2023 runner.on('test end', function(test){
2024 tests.push(test);
2025 });
2026
2027 runner.on('pass', function(test){
2028 passes.push(test);
2029 });
2030
2031 runner.on('fail', function(test){
2032 failures.push(test);
2033 });
2034
2035 runner.on('end', function(){
2036 var cov = global._$jscoverage || {};
2037 var result = self.cov = map(cov);
2038 result.stats = self.stats;
2039 result.tests = tests.map(clean);
2040 result.failures = failures.map(clean);
2041 result.passes = passes.map(clean);
2042 if (!output) return;
2043 process.stdout.write(JSON.stringify(result, null, 2 ));
2044 });
2045}
2046
2047/**
2048 * Map jscoverage data to a JSON structure
2049 * suitable for reporting.
2050 *
2051 * @param {Object} cov
2052 * @return {Object}
2053 * @api private
2054 */
2055
2056function map(cov) {
2057 var ret = {
2058 instrumentation: 'node-jscoverage'
2059 , sloc: 0
2060 , hits: 0
2061 , misses: 0
2062 , coverage: 0
2063 , files: []
2064 };
2065
2066 for (var filename in cov) {
2067 var data = coverage(filename, cov[filename]);
2068 ret.files.push(data);
2069 ret.hits += data.hits;
2070 ret.misses += data.misses;
2071 ret.sloc += data.sloc;
2072 }
2073
2074 if (ret.sloc > 0) {
2075 ret.coverage = (ret.hits / ret.sloc) * 100;
2076 }
2077
2078 return ret;
2079};
2080
2081/**
2082 * Map jscoverage data for a single source file
2083 * to a JSON structure suitable for reporting.
2084 *
2085 * @param {String} filename name of the source file
2086 * @param {Object} data jscoverage coverage data
2087 * @return {Object}
2088 * @api private
2089 */
2090
2091function coverage(filename, data) {
2092 var ret = {
2093 filename: filename,
2094 coverage: 0,
2095 hits: 0,
2096 misses: 0,
2097 sloc: 0,
2098 source: {}
2099 };
2100
2101 data.source.forEach(function(line, num){
2102 num++;
2103
2104 if (data[num] === 0) {
2105 ret.misses++;
2106 ret.sloc++;
2107 } else if (data[num] !== undefined) {
2108 ret.hits++;
2109 ret.sloc++;
2110 }
2111
2112 ret.source[num] = {
2113 source: line
2114 , coverage: data[num] === undefined
2115 ? ''
2116 : data[num]
2117 };
2118 });
2119
2120 ret.coverage = ret.hits / ret.sloc * 100;
2121
2122 return ret;
2123}
2124
2125/**
2126 * Return a plain-object representation of `test`
2127 * free of cyclic properties etc.
2128 *
2129 * @param {Object} test
2130 * @return {Object}
2131 * @api private
2132 */
2133
2134function clean(test) {
2135 return {
2136 title: test.title
2137 , fullTitle: test.fullTitle()
2138 , duration: test.duration
2139 }
2140}
2141
2142}); // module: reporters/json-cov.js
2143
2144require.register("reporters/json-stream.js", function(module, exports, require){
2145
2146/**
2147 * Module dependencies.
2148 */
2149
2150var Base = require('./base')
2151 , color = Base.color;
2152
2153/**
2154 * Expose `List`.
2155 */
2156
2157exports = module.exports = List;
2158
2159/**
2160 * Initialize a new `List` test reporter.
2161 *
2162 * @param {Runner} runner
2163 * @api public
2164 */
2165
2166function List(runner) {
2167 Base.call(this, runner);
2168
2169 var self = this
2170 , stats = this.stats
2171 , total = runner.total;
2172
2173 runner.on('start', function(){
2174 console.log(JSON.stringify(['start', { total: total }]));
2175 });
2176
2177 runner.on('pass', function(test){
2178 console.log(JSON.stringify(['pass', clean(test)]));
2179 });
2180
2181 runner.on('fail', function(test, err){
2182 console.log(JSON.stringify(['fail', clean(test)]));
2183 });
2184
2185 runner.on('end', function(){
2186 process.stdout.write(JSON.stringify(['end', self.stats]));
2187 });
2188}
2189
2190/**
2191 * Return a plain-object representation of `test`
2192 * free of cyclic properties etc.
2193 *
2194 * @param {Object} test
2195 * @return {Object}
2196 * @api private
2197 */
2198
2199function clean(test) {
2200 return {
2201 title: test.title
2202 , fullTitle: test.fullTitle()
2203 , duration: test.duration
2204 }
2205}
2206}); // module: reporters/json-stream.js
2207
2208require.register("reporters/json.js", function(module, exports, require){
2209
2210/**
2211 * Module dependencies.
2212 */
2213
2214var Base = require('./base')
2215 , cursor = Base.cursor
2216 , color = Base.color;
2217
2218/**
2219 * Expose `JSON`.
2220 */
2221
2222exports = module.exports = JSONReporter;
2223
2224/**
2225 * Initialize a new `JSON` reporter.
2226 *
2227 * @param {Runner} runner
2228 * @api public
2229 */
2230
2231function JSONReporter(runner) {
2232 var self = this;
2233 Base.call(this, runner);
2234
2235 var tests = []
2236 , failures = []
2237 , passes = [];
2238
2239 runner.on('test end', function(test){
2240 tests.push(test);
2241 });
2242
2243 runner.on('pass', function(test){
2244 passes.push(test);
2245 });
2246
2247 runner.on('fail', function(test){
2248 failures.push(test);
2249 });
2250
2251 runner.on('end', function(){
2252 var obj = {
2253 stats: self.stats
2254 , tests: tests.map(clean)
2255 , failures: failures.map(clean)
2256 , passes: passes.map(clean)
2257 };
2258
2259 process.stdout.write(JSON.stringify(obj, null, 2));
2260 });
2261}
2262
2263/**
2264 * Return a plain-object representation of `test`
2265 * free of cyclic properties etc.
2266 *
2267 * @param {Object} test
2268 * @return {Object}
2269 * @api private
2270 */
2271
2272function clean(test) {
2273 return {
2274 title: test.title
2275 , fullTitle: test.fullTitle()
2276 , duration: test.duration
2277 }
2278}
2279}); // module: reporters/json.js
2280
2281require.register("reporters/landing.js", function(module, exports, require){
2282
2283/**
2284 * Module dependencies.
2285 */
2286
2287var Base = require('./base')
2288 , cursor = Base.cursor
2289 , color = Base.color;
2290
2291/**
2292 * Expose `Landing`.
2293 */
2294
2295exports = module.exports = Landing;
2296
2297/**
2298 * Airplane color.
2299 */
2300
2301Base.colors.plane = 0;
2302
2303/**
2304 * Airplane crash color.
2305 */
2306
2307Base.colors['plane crash'] = 31;
2308
2309/**
2310 * Runway color.
2311 */
2312
2313Base.colors.runway = 90;
2314
2315/**
2316 * Initialize a new `Landing` reporter.
2317 *
2318 * @param {Runner} runner
2319 * @api public
2320 */
2321
2322function Landing(runner) {
2323 Base.call(this, runner);
2324
2325 var self = this
2326 , stats = this.stats
2327 , width = Base.window.width * .75 | 0
2328 , total = runner.total
2329 , stream = process.stdout
2330 , plane = color('plane', '✈')
2331 , crashed = -1
2332 , n = 0;
2333
2334 function runway() {
2335 var buf = Array(width).join('-');
2336 return ' ' + color('runway', buf);
2337 }
2338
2339 runner.on('start', function(){
2340 stream.write('\n ');
2341 cursor.hide();
2342 });
2343
2344 runner.on('test end', function(test){
2345 // check if the plane crashed
2346 var col = -1 == crashed
2347 ? width * ++n / total | 0
2348 : crashed;
2349
2350 // show the crash
2351 if ('failed' == test.state) {
2352 plane = color('plane crash', '✈');
2353 crashed = col;
2354 }
2355
2356 // render landing strip
2357 stream.write('\u001b[4F\n\n');
2358 stream.write(runway());
2359 stream.write('\n ');
2360 stream.write(color('runway', Array(col).join('⋅')));
2361 stream.write(plane)
2362 stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
2363 stream.write(runway());
2364 stream.write('\u001b[0m');
2365 });
2366
2367 runner.on('end', function(){
2368 cursor.show();
2369 console.log();
2370 self.epilogue();
2371 });
2372}
2373
2374/**
2375 * Inherit from `Base.prototype`.
2376 */
2377
2378Landing.prototype = new Base;
2379Landing.prototype.constructor = Landing;
2380
2381}); // module: reporters/landing.js
2382
2383require.register("reporters/list.js", function(module, exports, require){
2384
2385/**
2386 * Module dependencies.
2387 */
2388
2389var Base = require('./base')
2390 , cursor = Base.cursor
2391 , color = Base.color;
2392
2393/**
2394 * Expose `List`.
2395 */
2396
2397exports = module.exports = List;
2398
2399/**
2400 * Initialize a new `List` test reporter.
2401 *
2402 * @param {Runner} runner
2403 * @api public
2404 */
2405
2406function List(runner) {
2407 Base.call(this, runner);
2408
2409 var self = this
2410 , stats = this.stats
2411 , n = 0;
2412
2413 runner.on('start', function(){
2414 console.log();
2415 });
2416
2417 runner.on('test', function(test){
2418 process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
2419 });
2420
2421 runner.on('pending', function(test){
2422 var fmt = color('checkmark', ' -')
2423 + color('pending', ' %s');
2424 console.log(fmt, test.fullTitle());
2425 });
2426
2427 runner.on('pass', function(test){
2428 var fmt = color('checkmark', ' ✓')
2429 + color('pass', ' %s: ')
2430 + color(test.speed, '%dms');
2431 cursor.CR();
2432 console.log(fmt, test.fullTitle(), test.duration);
2433 });
2434
2435 runner.on('fail', function(test, err){
2436 cursor.CR();
2437 console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
2438 });
2439
2440 runner.on('end', self.epilogue.bind(self));
2441}
2442
2443/**
2444 * Inherit from `Base.prototype`.
2445 */
2446
2447List.prototype = new Base;
2448List.prototype.constructor = List;
2449
2450
2451}); // module: reporters/list.js
2452
2453require.register("reporters/markdown.js", function(module, exports, require){
2454/**
2455 * Module dependencies.
2456 */
2457
2458var Base = require('./base')
2459 , utils = require('../utils');
2460
2461/**
2462 * Expose `Markdown`.
2463 */
2464
2465exports = module.exports = Markdown;
2466
2467/**
2468 * Initialize a new `Markdown` reporter.
2469 *
2470 * @param {Runner} runner
2471 * @api public
2472 */
2473
2474function Markdown(runner) {
2475 Base.call(this, runner);
2476
2477 var self = this
2478 , stats = this.stats
2479 , total = runner.total
2480 , level = 0
2481 , buf = '';
2482
2483 function title(str) {
2484 return Array(level).join('#') + ' ' + str;
2485 }
2486
2487 function indent() {
2488 return Array(level).join(' ');
2489 }
2490
2491 function mapTOC(suite, obj) {
2492 var ret = obj;
2493 obj = obj[suite.title] = obj[suite.title] || { suite: suite };
2494 suite.suites.forEach(function(suite){
2495 mapTOC(suite, obj);
2496 });
2497 return ret;
2498 }
2499
2500 function stringifyTOC(obj, level) {
2501 ++level;
2502 var buf = '';
2503 var link;
2504 for (var key in obj) {
2505 if ('suite' == key) continue;
2506 if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
2507 if (key) buf += Array(level).join(' ') + link;
2508 buf += stringifyTOC(obj[key], level);
2509 }
2510 --level;
2511 return buf;
2512 }
2513
2514 function generateTOC(suite) {
2515 var obj = mapTOC(suite, {});
2516 return stringifyTOC(obj, 0);
2517 }
2518
2519 generateTOC(runner.suite);
2520
2521 runner.on('suite', function(suite){
2522 ++level;
2523 var slug = utils.slug(suite.fullTitle());
2524 buf += '<a name="' + slug + '" />' + '\n';
2525 buf += title(suite.title) + '\n';
2526 });
2527
2528 runner.on('suite end', function(suite){
2529 --level;
2530 });
2531
2532 runner.on('pass', function(test){
2533 var code = utils.clean(test.fn.toString());
2534 buf += test.title + '.\n';
2535 buf += '\n```js\n';
2536 buf += code + '\n';
2537 buf += '```\n\n';
2538 });
2539
2540 runner.on('end', function(){
2541 process.stdout.write('# TOC\n');
2542 process.stdout.write(generateTOC(runner.suite));
2543 process.stdout.write(buf);
2544 });
2545}
2546}); // module: reporters/markdown.js
2547
2548require.register("reporters/min.js", function(module, exports, require){
2549
2550/**
2551 * Module dependencies.
2552 */
2553
2554var Base = require('./base');
2555
2556/**
2557 * Expose `Min`.
2558 */
2559
2560exports = module.exports = Min;
2561
2562/**
2563 * Initialize a new `Min` minimal test reporter (best used with --watch).
2564 *
2565 * @param {Runner} runner
2566 * @api public
2567 */
2568
2569function Min(runner) {
2570 Base.call(this, runner);
2571
2572 runner.on('start', function(){
2573 // clear screen
2574 process.stdout.write('\u001b[2J');
2575 // set cursor position
2576 process.stdout.write('\u001b[1;3H');
2577 });
2578
2579 runner.on('end', this.epilogue.bind(this));
2580}
2581
2582/**
2583 * Inherit from `Base.prototype`.
2584 */
2585
2586Min.prototype = new Base;
2587Min.prototype.constructor = Min;
2588
2589}); // module: reporters/min.js
2590
2591require.register("reporters/nyan.js", function(module, exports, require){
2592
2593/**
2594 * Module dependencies.
2595 */
2596
2597var Base = require('./base')
2598 , color = Base.color;
2599
2600/**
2601 * Expose `Dot`.
2602 */
2603
2604exports = module.exports = NyanCat;
2605
2606/**
2607 * Initialize a new `Dot` matrix test reporter.
2608 *
2609 * @param {Runner} runner
2610 * @api public
2611 */
2612
2613function NyanCat(runner) {
2614 Base.call(this, runner);
2615
2616 var self = this
2617 , stats = this.stats
2618 , width = Base.window.width * .75 | 0
2619 , rainbowColors = this.rainbowColors = self.generateColors()
2620 , colorIndex = this.colorIndex = 0
2621 , numerOfLines = this.numberOfLines = 4
2622 , trajectories = this.trajectories = [[], [], [], []]
2623 , nyanCatWidth = this.nyanCatWidth = 11
2624 , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
2625 , scoreboardWidth = this.scoreboardWidth = 5
2626 , tick = this.tick = 0
2627 , n = 0;
2628
2629 runner.on('start', function(){
2630 Base.cursor.hide();
2631 self.draw('start');
2632 });
2633
2634 runner.on('pending', function(test){
2635 self.draw('pending');
2636 });
2637
2638 runner.on('pass', function(test){
2639 self.draw('pass');
2640 });
2641
2642 runner.on('fail', function(test, err){
2643 self.draw('fail');
2644 });
2645
2646 runner.on('end', function(){
2647 Base.cursor.show();
2648 for (var i = 0; i < self.numberOfLines; i++) write('\n');
2649 self.epilogue();
2650 });
2651}
2652
2653/**
2654 * Draw the nyan cat with runner `status`.
2655 *
2656 * @param {String} status
2657 * @api private
2658 */
2659
2660NyanCat.prototype.draw = function(status){
2661 this.appendRainbow();
2662 this.drawScoreboard();
2663 this.drawRainbow();
2664 this.drawNyanCat(status);
2665 this.tick = !this.tick;
2666};
2667
2668/**
2669 * Draw the "scoreboard" showing the number
2670 * of passes, failures and pending tests.
2671 *
2672 * @api private
2673 */
2674
2675NyanCat.prototype.drawScoreboard = function(){
2676 var stats = this.stats;
2677 var colors = Base.colors;
2678
2679 function draw(color, n) {
2680 write(' ');
2681 write('\u001b[' + color + 'm' + n + '\u001b[0m');
2682 write('\n');
2683 }
2684
2685 draw(colors.green, stats.passes);
2686 draw(colors.fail, stats.failures);
2687 draw(colors.pending, stats.pending);
2688 write('\n');
2689
2690 this.cursorUp(this.numberOfLines);
2691};
2692
2693/**
2694 * Append the rainbow.
2695 *
2696 * @api private
2697 */
2698
2699NyanCat.prototype.appendRainbow = function(){
2700 var segment = this.tick ? '_' : '-';
2701 var rainbowified = this.rainbowify(segment);
2702
2703 for (var index = 0; index < this.numberOfLines; index++) {
2704 var trajectory = this.trajectories[index];
2705 if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
2706 trajectory.push(rainbowified);
2707 }
2708};
2709
2710/**
2711 * Draw the rainbow.
2712 *
2713 * @api private
2714 */
2715
2716NyanCat.prototype.drawRainbow = function(){
2717 var self = this;
2718
2719 this.trajectories.forEach(function(line, index) {
2720 write('\u001b[' + self.scoreboardWidth + 'C');
2721 write(line.join(''));
2722 write('\n');
2723 });
2724
2725 this.cursorUp(this.numberOfLines);
2726};
2727
2728/**
2729 * Draw the nyan cat with `status`.
2730 *
2731 * @param {String} status
2732 * @api private
2733 */
2734
2735NyanCat.prototype.drawNyanCat = function(status) {
2736 var self = this;
2737 var startWidth = this.scoreboardWidth + this.trajectories[0].length;
2738
2739 [0, 1, 2, 3].forEach(function(index) {
2740 write('\u001b[' + startWidth + 'C');
2741
2742 switch (index) {
2743 case 0:
2744 write('_,------,');
2745 write('\n');
2746 break;
2747 case 1:
2748 var padding = self.tick ? ' ' : ' ';
2749 write('_|' + padding + '/\\_/\\ ');
2750 write('\n');
2751 break;
2752 case 2:
2753 var padding = self.tick ? '_' : '__';
2754 var tail = self.tick ? '~' : '^';
2755 var face;
2756 switch (status) {
2757 case 'pass':
2758 face = '( ^ .^)';
2759 break;
2760 case 'fail':
2761 face = '( o .o)';
2762 break;
2763 default:
2764 face = '( - .-)';
2765 }
2766 write(tail + '|' + padding + face + ' ');
2767 write('\n');
2768 break;
2769 case 3:
2770 var padding = self.tick ? ' ' : ' ';
2771 write(padding + '"" "" ');
2772 write('\n');
2773 break;
2774 }
2775 });
2776
2777 this.cursorUp(this.numberOfLines);
2778};
2779
2780/**
2781 * Move cursor up `n`.
2782 *
2783 * @param {Number} n
2784 * @api private
2785 */
2786
2787NyanCat.prototype.cursorUp = function(n) {
2788 write('\u001b[' + n + 'A');
2789};
2790
2791/**
2792 * Move cursor down `n`.
2793 *
2794 * @param {Number} n
2795 * @api private
2796 */
2797
2798NyanCat.prototype.cursorDown = function(n) {
2799 write('\u001b[' + n + 'B');
2800};
2801
2802/**
2803 * Generate rainbow colors.
2804 *
2805 * @return {Array}
2806 * @api private
2807 */
2808
2809NyanCat.prototype.generateColors = function(){
2810 var colors = [];
2811
2812 for (var i = 0; i < (6 * 7); i++) {
2813 var pi3 = Math.floor(Math.PI / 3);
2814 var n = (i * (1.0 / 6));
2815 var r = Math.floor(3 * Math.sin(n) + 3);
2816 var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
2817 var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
2818 colors.push(36 * r + 6 * g + b + 16);
2819 }
2820
2821 return colors;
2822};
2823
2824/**
2825 * Apply rainbow to the given `str`.
2826 *
2827 * @param {String} str
2828 * @return {String}
2829 * @api private
2830 */
2831
2832NyanCat.prototype.rainbowify = function(str){
2833 var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
2834 this.colorIndex += 1;
2835 return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
2836};
2837
2838/**
2839 * Stdout helper.
2840 */
2841
2842function write(string) {
2843 process.stdout.write(string);
2844}
2845
2846/**
2847 * Inherit from `Base.prototype`.
2848 */
2849
2850NyanCat.prototype = new Base;
2851NyanCat.prototype.constructor = NyanCat;
2852
2853
2854}); // module: reporters/nyan.js
2855
2856require.register("reporters/progress.js", function(module, exports, require){
2857
2858/**
2859 * Module dependencies.
2860 */
2861
2862var Base = require('./base')
2863 , cursor = Base.cursor
2864 , color = Base.color;
2865
2866/**
2867 * Expose `Progress`.
2868 */
2869
2870exports = module.exports = Progress;
2871
2872/**
2873 * General progress bar color.
2874 */
2875
2876Base.colors.progress = 90;
2877
2878/**
2879 * Initialize a new `Progress` bar test reporter.
2880 *
2881 * @param {Runner} runner
2882 * @param {Object} options
2883 * @api public
2884 */
2885
2886function Progress(runner, options) {
2887 Base.call(this, runner);
2888
2889 var self = this
2890 , options = options || {}
2891 , stats = this.stats
2892 , width = Base.window.width * .50 | 0
2893 , total = runner.total
2894 , complete = 0
2895 , max = Math.max;
2896
2897 // default chars
2898 options.open = options.open || '[';
2899 options.complete = options.complete || '▬';
2900 options.incomplete = options.incomplete || '⋅';
2901 options.close = options.close || ']';
2902 options.verbose = false;
2903
2904 // tests started
2905 runner.on('start', function(){
2906 console.log();
2907 cursor.hide();
2908 });
2909
2910 // tests complete
2911 runner.on('test end', function(){
2912 complete++;
2913 var incomplete = total - complete
2914 , percent = complete / total
2915 , n = width * percent | 0
2916 , i = width - n;
2917
2918 cursor.CR();
2919 process.stdout.write('\u001b[J');
2920 process.stdout.write(color('progress', ' ' + options.open));
2921 process.stdout.write(Array(n).join(options.complete));
2922 process.stdout.write(Array(i).join(options.incomplete));
2923 process.stdout.write(color('progress', options.close));
2924 if (options.verbose) {
2925 process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
2926 }
2927 });
2928
2929 // tests are complete, output some stats
2930 // and the failures if any
2931 runner.on('end', function(){
2932 cursor.show();
2933 console.log();
2934 self.epilogue();
2935 });
2936}
2937
2938/**
2939 * Inherit from `Base.prototype`.
2940 */
2941
2942Progress.prototype = new Base;
2943Progress.prototype.constructor = Progress;
2944
2945
2946}); // module: reporters/progress.js
2947
2948require.register("reporters/spec.js", function(module, exports, require){
2949
2950/**
2951 * Module dependencies.
2952 */
2953
2954var Base = require('./base')
2955 , cursor = Base.cursor
2956 , color = Base.color;
2957
2958/**
2959 * Expose `Spec`.
2960 */
2961
2962exports = module.exports = Spec;
2963
2964/**
2965 * Initialize a new `Spec` test reporter.
2966 *
2967 * @param {Runner} runner
2968 * @api public
2969 */
2970
2971function Spec(runner) {
2972 Base.call(this, runner);
2973
2974 var self = this
2975 , stats = this.stats
2976 , indents = 0
2977 , n = 0;
2978
2979 function indent() {
2980 return Array(indents).join(' ')
2981 }
2982
2983 runner.on('start', function(){
2984 console.log();
2985 });
2986
2987 runner.on('suite', function(suite){
2988 ++indents;
2989 console.log(color('suite', '%s%s'), indent(), suite.title);
2990 });
2991
2992 runner.on('suite end', function(suite){
2993 --indents;
2994 if (1 == indents) console.log();
2995 });
2996
2997 runner.on('test', function(test){
2998 process.stdout.write(indent() + color('pass', ' ◦ ' + test.title + ': '));
2999 });
3000
3001 runner.on('pending', function(test){
3002 var fmt = indent() + color('pending', ' - %s');
3003 console.log(fmt, test.title);
3004 });
3005
3006 runner.on('pass', function(test){
3007 if ('fast' == test.speed) {
3008 var fmt = indent()
3009 + color('checkmark', ' ✓')
3010 + color('pass', ' %s ');
3011 cursor.CR();
3012 console.log(fmt, test.title);
3013 } else {
3014 var fmt = indent()
3015 + color('checkmark', ' ✓')
3016 + color('pass', ' %s ')
3017 + color(test.speed, '(%dms)');
3018 cursor.CR();
3019 console.log(fmt, test.title, test.duration);
3020 }
3021 });
3022
3023 runner.on('fail', function(test, err){
3024 cursor.CR();
3025 console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
3026 });
3027
3028 runner.on('end', self.epilogue.bind(self));
3029}
3030
3031/**
3032 * Inherit from `Base.prototype`.
3033 */
3034
3035Spec.prototype = new Base;
3036Spec.prototype.constructor = Spec;
3037
3038
3039}); // module: reporters/spec.js
3040
3041require.register("reporters/tap.js", function(module, exports, require){
3042
3043/**
3044 * Module dependencies.
3045 */
3046
3047var Base = require('./base')
3048 , cursor = Base.cursor
3049 , color = Base.color;
3050
3051/**
3052 * Expose `TAP`.
3053 */
3054
3055exports = module.exports = TAP;
3056
3057/**
3058 * Initialize a new `TAP` reporter.
3059 *
3060 * @param {Runner} runner
3061 * @api public
3062 */
3063
3064function TAP(runner) {
3065 Base.call(this, runner);
3066
3067 var self = this
3068 , stats = this.stats
3069 , total = runner.total
3070 , n = 1;
3071
3072 runner.on('start', function(){
3073 console.log('%d..%d', 1, total);
3074 });
3075
3076 runner.on('test end', function(){
3077 ++n;
3078 });
3079
3080 runner.on('pending', function(test){
3081 console.log('ok %d %s # SKIP -', n, title(test));
3082 });
3083
3084 runner.on('pass', function(test){
3085 console.log('ok %d %s', n, title(test));
3086 });
3087
3088 runner.on('fail', function(test, err){
3089 console.log('not ok %d %s', n, title(test));
3090 console.log(err.stack.replace(/^/gm, ' '));
3091 });
3092}
3093
3094/**
3095 * Return a TAP-safe title of `test`
3096 *
3097 * @param {Object} test
3098 * @return {String}
3099 * @api private
3100 */
3101
3102function title(test) {
3103 return test.fullTitle().replace(/#/g, '');
3104}
3105
3106}); // module: reporters/tap.js
3107
3108require.register("reporters/teamcity.js", function(module, exports, require){
3109
3110/**
3111 * Module dependencies.
3112 */
3113
3114var Base = require('./base');
3115
3116/**
3117 * Expose `Teamcity`.
3118 */
3119
3120exports = module.exports = Teamcity;
3121
3122/**
3123 * Initialize a new `Teamcity` reporter.
3124 *
3125 * @param {Runner} runner
3126 * @api public
3127 */
3128
3129function Teamcity(runner) {
3130 Base.call(this, runner);
3131 var stats = this.stats;
3132
3133 runner.on('start', function() {
3134 console.log("##teamcity[testSuiteStarted name='mocha.suite']");
3135 });
3136
3137 runner.on('test', function(test) {
3138 console.log("##teamcity[testStarted name='" + escape(test.fullTitle()) + "']");
3139 });
3140
3141 runner.on('fail', function(test, err) {
3142 console.log("##teamcity[testFailed name='" + escape(test.fullTitle()) + "' message='" + escape(err.message) + "']");
3143 });
3144
3145 runner.on('pending', function(test) {
3146 console.log("##teamcity[testIgnored name='" + escape(test.fullTitle()) + "' message='pending']");
3147 });
3148
3149 runner.on('test end', function(test) {
3150 console.log("##teamcity[testFinished name='" + escape(test.fullTitle()) + "' duration='" + test.duration + "']");
3151 });
3152
3153 runner.on('end', function() {
3154 console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='" + stats.duration + "']");
3155 });
3156}
3157
3158/**
3159 * Escape the given `str`.
3160 */
3161
3162function escape(str) {
3163 return str
3164 .replace(/\|/g, "||")
3165 .replace(/\n/g, "|n")
3166 .replace(/\r/g, "|r")
3167 .replace(/\[/g, "|[")
3168 .replace(/\]/g, "|]")
3169 .replace(/\u0085/g, "|x")
3170 .replace(/\u2028/g, "|l")
3171 .replace(/\u2029/g, "|p")
3172 .replace(/'/g, "|'");
3173}
3174
3175}); // module: reporters/teamcity.js
3176
3177require.register("reporters/xunit.js", function(module, exports, require){
3178
3179/**
3180 * Module dependencies.
3181 */
3182
3183var Base = require('./base')
3184 , utils = require('../utils')
3185 , escape = utils.escape;
3186
3187/**
3188 * Save timer references to avoid Sinon interfering (see GH-237).
3189 */
3190
3191var Date = global.Date
3192 , setTimeout = global.setTimeout
3193 , setInterval = global.setInterval
3194 , clearTimeout = global.clearTimeout
3195 , clearInterval = global.clearInterval;
3196
3197/**
3198 * Expose `XUnit`.
3199 */
3200
3201exports = module.exports = XUnit;
3202
3203/**
3204 * Initialize a new `XUnit` reporter.
3205 *
3206 * @param {Runner} runner
3207 * @api public
3208 */
3209
3210function XUnit(runner) {
3211 Base.call(this, runner);
3212 var stats = this.stats
3213 , tests = []
3214 , self = this;
3215
3216 runner.on('pass', function(test){
3217 tests.push(test);
3218 });
3219
3220 runner.on('fail', function(test){
3221 tests.push(test);
3222 });
3223
3224 runner.on('end', function(){
3225 console.log(tag('testsuite', {
3226 name: 'Mocha Tests'
3227 , tests: stats.tests
3228 , failures: stats.failures
3229 , errors: stats.failures
3230 , skip: stats.tests - stats.failures - stats.passes
3231 , timestamp: (new Date).toUTCString()
3232 , time: stats.duration / 1000
3233 }, false));
3234
3235 tests.forEach(test);
3236 console.log('</testsuite>');
3237 });
3238}
3239
3240/**
3241 * Inherit from `Base.prototype`.
3242 */
3243
3244XUnit.prototype = new Base;
3245XUnit.prototype.constructor = XUnit;
3246
3247
3248/**
3249 * Output tag for the given `test.`
3250 */
3251
3252function test(test) {
3253 var attrs = {
3254 classname: test.parent.fullTitle()
3255 , name: test.title
3256 , time: test.duration / 1000
3257 };
3258
3259 if ('failed' == test.state) {
3260 var err = test.err;
3261 attrs.message = escape(err.message);
3262 console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
3263 } else if (test.pending) {
3264 console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
3265 } else {
3266 console.log(tag('testcase', attrs, true) );
3267 }
3268}
3269
3270/**
3271 * HTML tag helper.
3272 */
3273
3274function tag(name, attrs, close, content) {
3275 var end = close ? '/>' : '>'
3276 , pairs = []
3277 , tag;
3278
3279 for (var key in attrs) {
3280 pairs.push(key + '="' + escape(attrs[key]) + '"');
3281 }
3282
3283 tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
3284 if (content) tag += content + '</' + name + end;
3285 return tag;
3286}
3287
3288/**
3289 * Return cdata escaped CDATA `str`.
3290 */
3291
3292function cdata(str) {
3293 return '<![CDATA[' + escape(str) + ']]>';
3294}
3295
3296}); // module: reporters/xunit.js
3297
3298require.register("runnable.js", function(module, exports, require){
3299
3300/**
3301 * Module dependencies.
3302 */
3303
3304var EventEmitter = require('browser/events').EventEmitter
3305 , debug = require('browser/debug')('mocha:runnable');
3306
3307/**
3308 * Save timer references to avoid Sinon interfering (see GH-237).
3309 */
3310
3311var Date = global.Date
3312 , setTimeout = global.setTimeout
3313 , setInterval = global.setInterval
3314 , clearTimeout = global.clearTimeout
3315 , clearInterval = global.clearInterval;
3316
3317/**
3318 * Expose `Runnable`.
3319 */
3320
3321module.exports = Runnable;
3322
3323/**
3324 * Initialize a new `Runnable` with the given `title` and callback `fn`.
3325 *
3326 * @param {String} title
3327 * @param {Function} fn
3328 * @api private
3329 */
3330
3331function Runnable(title, fn) {
3332 this.title = title;
3333 this.fn = fn;
3334 this.async = fn && fn.length;
3335 this.sync = ! this.async;
3336 this._timeout = 2000;
3337 this.timedOut = false;
3338}
3339
3340/**
3341 * Inherit from `EventEmitter.prototype`.
3342 */
3343
3344Runnable.prototype = new EventEmitter;
3345Runnable.prototype.constructor = Runnable;
3346
3347
3348/**
3349 * Set & get timeout `ms`.
3350 *
3351 * @param {Number} ms
3352 * @return {Runnable|Number} ms or self
3353 * @api private
3354 */
3355
3356Runnable.prototype.timeout = function(ms){
3357 if (0 == arguments.length) return this._timeout;
3358 debug('timeout %d', ms);
3359 this._timeout = ms;
3360 if (this.timer) this.resetTimeout();
3361 return this;
3362};
3363
3364/**
3365 * Return the full title generated by recursively
3366 * concatenating the parent's full title.
3367 *
3368 * @return {String}
3369 * @api public
3370 */
3371
3372Runnable.prototype.fullTitle = function(){
3373 return this.parent.fullTitle() + ' ' + this.title;
3374};
3375
3376/**
3377 * Clear the timeout.
3378 *
3379 * @api private
3380 */
3381
3382Runnable.prototype.clearTimeout = function(){
3383 clearTimeout(this.timer);
3384};
3385
3386/**
3387 * Inspect the runnable void of private properties.
3388 *
3389 * @return {String}
3390 * @api private
3391 */
3392
3393Runnable.prototype.inspect = function(){
3394 return JSON.stringify(this, function(key, val){
3395 if ('_' == key[0]) return;
3396 if ('parent' == key) return '#<Suite>';
3397 if ('ctx' == key) return '#<Context>';
3398 return val;
3399 }, 2);
3400};
3401
3402/**
3403 * Reset the timeout.
3404 *
3405 * @api private
3406 */
3407
3408Runnable.prototype.resetTimeout = function(){
3409 var self = this
3410 , ms = this.timeout();
3411
3412 this.clearTimeout();
3413 if (ms) {
3414 this.timer = setTimeout(function(){
3415 self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
3416 self.timedOut = true;
3417 }, ms);
3418 }
3419};
3420
3421/**
3422 * Run the test and invoke `fn(err)`.
3423 *
3424 * @param {Function} fn
3425 * @api private
3426 */
3427
3428Runnable.prototype.run = function(fn){
3429 var self = this
3430 , ms = this.timeout()
3431 , start = new Date
3432 , ctx = this.ctx
3433 , finished
3434 , emitted;
3435
3436 if (ctx) ctx.runnable(this);
3437
3438 // timeout
3439 if (this.async) {
3440 if (ms) {
3441 this.timer = setTimeout(function(){
3442 done(new Error('timeout of ' + ms + 'ms exceeded'));
3443 self.timedOut = true;
3444 }, ms);
3445 }
3446 }
3447
3448 // called multiple times
3449 function multiple(err) {
3450 if (emitted) return;
3451 emitted = true;
3452 self.emit('error', err || new Error('done() called multiple times'));
3453 }
3454
3455 // finished
3456 function done(err) {
3457 if (self.timedOut) return;
3458 if (finished) return multiple(err);
3459 self.clearTimeout();
3460 self.duration = new Date - start;
3461 finished = true;
3462 fn(err);
3463 }
3464
3465 // for .resetTimeout()
3466 this.callback = done;
3467
3468 // async
3469 if (this.async) {
3470 try {
3471 this.fn.call(ctx, function(err){
3472 if (err instanceof Error) return done(err);
3473 if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
3474 done();
3475 });
3476 } catch (err) {
3477 done(err);
3478 }
3479 return;
3480 }
3481
3482 // sync
3483 try {
3484 if (!this.pending) this.fn.call(ctx);
3485 this.duration = new Date - start;
3486 fn();
3487 } catch (err) {
3488 fn(err);
3489 }
3490};
3491
3492}); // module: runnable.js
3493
3494require.register("runner.js", function(module, exports, require){
3495
3496/**
3497 * Module dependencies.
3498 */
3499
3500var EventEmitter = require('browser/events').EventEmitter
3501 , debug = require('browser/debug')('mocha:runner')
3502 , Test = require('./test')
3503 , utils = require('./utils')
3504 , filter = utils.filter
3505 , keys = utils.keys
3506 , noop = function(){};
3507
3508/**
3509 * Expose `Runner`.
3510 */
3511
3512module.exports = Runner;
3513
3514/**
3515 * Initialize a `Runner` for the given `suite`.
3516 *
3517 * Events:
3518 *
3519 * - `start` execution started
3520 * - `end` execution complete
3521 * - `suite` (suite) test suite execution started
3522 * - `suite end` (suite) all tests (and sub-suites) have finished
3523 * - `test` (test) test execution started
3524 * - `test end` (test) test completed
3525 * - `hook` (hook) hook execution started
3526 * - `hook end` (hook) hook complete
3527 * - `pass` (test) test passed
3528 * - `fail` (test, err) test failed
3529 *
3530 * @api public
3531 */
3532
3533function Runner(suite) {
3534 var self = this;
3535 this._globals = [];
3536 this.suite = suite;
3537 this.total = suite.total();
3538 this.failures = 0;
3539 this.on('test end', function(test){ self.checkGlobals(test); });
3540 this.on('hook end', function(hook){ self.checkGlobals(hook); });
3541 this.grep(/.*/);
3542 this.globals(utils.keys(global).concat(['errno']));
3543}
3544
3545/**
3546 * Inherit from `EventEmitter.prototype`.
3547 */
3548
3549Runner.prototype = new EventEmitter;
3550Runner.prototype.constructor = Runner;
3551
3552
3553/**
3554 * Run tests with full titles matching `re`. Updates runner.total
3555 * with number of tests matched.
3556 *
3557 * @param {RegExp} re
3558 * @param {Boolean} invert
3559 * @return {Runner} for chaining
3560 * @api public
3561 */
3562
3563Runner.prototype.grep = function(re, invert){
3564 debug('grep %s', re);
3565 this._grep = re;
3566 this._invert = invert;
3567 this.total = this.grepTotal(this.suite);
3568 return this;
3569};
3570
3571/**
3572 * Returns the number of tests matching the grep search for the
3573 * given suite.
3574 *
3575 * @param {Suite} suite
3576 * @return {Number}
3577 * @api public
3578 */
3579
3580Runner.prototype.grepTotal = function(suite) {
3581 var self = this;
3582 var total = 0;
3583
3584 suite.eachTest(function(test){
3585 var match = self._grep.test(test.fullTitle());
3586 if (self._invert) match = !match;
3587 if (match) total++;
3588 });
3589
3590 return total;
3591};
3592
3593/**
3594 * Allow the given `arr` of globals.
3595 *
3596 * @param {Array} arr
3597 * @return {Runner} for chaining
3598 * @api public
3599 */
3600
3601Runner.prototype.globals = function(arr){
3602 if (0 == arguments.length) return this._globals;
3603 debug('globals %j', arr);
3604 utils.forEach(arr, function(arr){
3605 this._globals.push(arr);
3606 }, this);
3607 return this;
3608};
3609
3610/**
3611 * Check for global variable leaks.
3612 *
3613 * @api private
3614 */
3615
3616Runner.prototype.checkGlobals = function(test){
3617 if (this.ignoreLeaks) return;
3618 var leaks = filterLeaks(this._globals);
3619
3620 this._globals = this._globals.concat(leaks);
3621
3622 if (leaks.length > 1) {
3623 this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
3624 } else if (leaks.length) {
3625 this.fail(test, new Error('global leak detected: ' + leaks[0]));
3626 }
3627};
3628
3629/**
3630 * Fail the given `test`.
3631 *
3632 * @param {Test} test
3633 * @param {Error} err
3634 * @api private
3635 */
3636
3637Runner.prototype.fail = function(test, err){
3638 ++this.failures;
3639 test.state = 'failed';
3640 if ('string' == typeof err) {
3641 err = new Error('the string "' + err + '" was thrown, throw an Error :)');
3642 }
3643 this.emit('fail', test, err);
3644};
3645
3646/**
3647 * Fail the given `hook` with `err`.
3648 *
3649 * Hook failures (currently) hard-end due
3650 * to that fact that a failing hook will
3651 * surely cause subsequent tests to fail,
3652 * causing jumbled reporting.
3653 *
3654 * @param {Hook} hook
3655 * @param {Error} err
3656 * @api private
3657 */
3658
3659Runner.prototype.failHook = function(hook, err){
3660 this.fail(hook, err);
3661 this.emit('end');
3662};
3663
3664/**
3665 * Run hook `name` callbacks and then invoke `fn()`.
3666 *
3667 * @param {String} name
3668 * @param {Function} function
3669 * @api private
3670 */
3671
3672Runner.prototype.hook = function(name, fn){
3673 var suite = this.suite
3674 , hooks = suite['_' + name]
3675 , ms = suite._timeout
3676 , self = this
3677 , timer;
3678
3679 function next(i) {
3680 var hook = hooks[i];
3681 if (!hook) return fn();
3682 self.currentRunnable = hook;
3683
3684 self.emit('hook', hook);
3685
3686 hook.on('error', function(err){
3687 self.failHook(hook, err);
3688 });
3689
3690 hook.run(function(err){
3691 hook.removeAllListeners('error');
3692 var testError = hook.error();
3693 if (testError) self.fail(self.test, testError);
3694 if (err) return self.failHook(hook, err);
3695 self.emit('hook end', hook);
3696 next(++i);
3697 });
3698 }
3699
3700 process.nextTick(function(){
3701 next(0);
3702 });
3703};
3704
3705/**
3706 * Run hook `name` for the given array of `suites`
3707 * in order, and callback `fn(err)`.
3708 *
3709 * @param {String} name
3710 * @param {Array} suites
3711 * @param {Function} fn
3712 * @api private
3713 */
3714
3715Runner.prototype.hooks = function(name, suites, fn){
3716 var self = this
3717 , orig = this.suite;
3718
3719 function next(suite) {
3720 self.suite = suite;
3721
3722 if (!suite) {
3723 self.suite = orig;
3724 return fn();
3725 }
3726
3727 self.hook(name, function(err){
3728 if (err) {
3729 self.suite = orig;
3730 return fn(err);
3731 }
3732
3733 next(suites.pop());
3734 });
3735 }
3736
3737 next(suites.pop());
3738};
3739
3740/**
3741 * Run hooks from the top level down.
3742 *
3743 * @param {String} name
3744 * @param {Function} fn
3745 * @api private
3746 */
3747
3748Runner.prototype.hookUp = function(name, fn){
3749 var suites = [this.suite].concat(this.parents()).reverse();
3750 this.hooks(name, suites, fn);
3751};
3752
3753/**
3754 * Run hooks from the bottom up.
3755 *
3756 * @param {String} name
3757 * @param {Function} fn
3758 * @api private
3759 */
3760
3761Runner.prototype.hookDown = function(name, fn){
3762 var suites = [this.suite].concat(this.parents());
3763 this.hooks(name, suites, fn);
3764};
3765
3766/**
3767 * Return an array of parent Suites from
3768 * closest to furthest.
3769 *
3770 * @return {Array}
3771 * @api private
3772 */
3773
3774Runner.prototype.parents = function(){
3775 var suite = this.suite
3776 , suites = [];
3777 while (suite = suite.parent) suites.push(suite);
3778 return suites;
3779};
3780
3781/**
3782 * Run the current test and callback `fn(err)`.
3783 *
3784 * @param {Function} fn
3785 * @api private
3786 */
3787
3788Runner.prototype.runTest = function(fn){
3789 var test = this.test
3790 , self = this;
3791
3792 try {
3793 test.on('error', function(err){
3794 self.fail(test, err);
3795 });
3796 test.run(fn);
3797 } catch (err) {
3798 fn(err);
3799 }
3800};
3801
3802/**
3803 * Run tests in the given `suite` and invoke
3804 * the callback `fn()` when complete.
3805 *
3806 * @param {Suite} suite
3807 * @param {Function} fn
3808 * @api private
3809 */
3810
3811Runner.prototype.runTests = function(suite, fn){
3812 var self = this
3813 , tests = suite.tests
3814 , test;
3815
3816 function next(err) {
3817 // if we bail after first err
3818 if (self.failures && suite._bail) return fn();
3819
3820 // next test
3821 test = tests.shift();
3822
3823 // all done
3824 if (!test) return fn();
3825
3826 // grep
3827 var match = self._grep.test(test.fullTitle());
3828 if (self._invert) match = !match;
3829 if (!match) return next();
3830
3831 // pending
3832 if (test.pending) {
3833 self.emit('pending', test);
3834 self.emit('test end', test);
3835 return next();
3836 }
3837
3838 // execute test and hook(s)
3839 self.emit('test', self.test = test);
3840 self.hookDown('beforeEach', function(){
3841 self.currentRunnable = self.test;
3842 self.runTest(function(err){
3843 test = self.test;
3844
3845 if (err) {
3846 self.fail(test, err);
3847 self.emit('test end', test);
3848 return self.hookUp('afterEach', next);
3849 }
3850
3851 test.state = 'passed';
3852 self.emit('pass', test);
3853 self.emit('test end', test);
3854 self.hookUp('afterEach', next);
3855 });
3856 });
3857 }
3858
3859 this.next = next;
3860 next();
3861};
3862
3863/**
3864 * Run the given `suite` and invoke the
3865 * callback `fn()` when complete.
3866 *
3867 * @param {Suite} suite
3868 * @param {Function} fn
3869 * @api private
3870 */
3871
3872Runner.prototype.runSuite = function(suite, fn){
3873 var total = this.grepTotal(suite)
3874 , self = this
3875 , i = 0;
3876
3877 debug('run suite %s', suite.fullTitle());
3878
3879 if (!total) return fn();
3880
3881 this.emit('suite', this.suite = suite);
3882
3883 function next() {
3884 var curr = suite.suites[i++];
3885 if (!curr) return done();
3886 self.runSuite(curr, next);
3887 }
3888
3889 function done() {
3890 self.suite = suite;
3891 self.hook('afterAll', function(){
3892 self.emit('suite end', suite);
3893 fn();
3894 });
3895 }
3896
3897 this.hook('beforeAll', function(){
3898 self.runTests(suite, next);
3899 });
3900};
3901
3902/**
3903 * Handle uncaught exceptions.
3904 *
3905 * @param {Error} err
3906 * @api private
3907 */
3908
3909Runner.prototype.uncaught = function(err){
3910 debug('uncaught exception %s', err.message);
3911 var runnable = this.currentRunnable;
3912 if (!runnable || 'failed' == runnable.state) return;
3913 runnable.clearTimeout();
3914 err.uncaught = true;
3915 this.fail(runnable, err);
3916
3917 // recover from test
3918 if ('test' == runnable.type) {
3919 this.emit('test end', runnable);
3920 this.hookUp('afterEach', this.next);
3921 return;
3922 }
3923
3924 // bail on hooks
3925 this.emit('end');
3926};
3927
3928/**
3929 * Run the root suite and invoke `fn(failures)`
3930 * on completion.
3931 *
3932 * @param {Function} fn
3933 * @return {Runner} for chaining
3934 * @api public
3935 */
3936
3937Runner.prototype.run = function(fn){
3938 var self = this
3939 , fn = fn || function(){};
3940
3941 debug('start');
3942
3943 // uncaught callback
3944 function uncaught(err) {
3945 self.uncaught(err);
3946 }
3947
3948 // callback
3949 this.on('end', function(){
3950 debug('end');
3951 process.removeListener('uncaughtException', uncaught);
3952 fn(self.failures);
3953 });
3954
3955 // run suites
3956 this.emit('start');
3957 this.runSuite(this.suite, function(){
3958 debug('finished running');
3959 self.emit('end');
3960 });
3961
3962 // uncaught exception
3963 process.on('uncaughtException', uncaught);
3964
3965 return this;
3966};
3967
3968/**
3969 * Filter leaks with the given globals flagged as `ok`.
3970 *
3971 * @param {Array} ok
3972 * @return {Array}
3973 * @api private
3974 */
3975
3976function filterLeaks(ok) {
3977 return filter(keys(global), function(key){
3978 var matched = filter(ok, function(ok){
3979 if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
3980 return key == ok;
3981 });
3982 return matched.length == 0 && (!global.navigator || 'onerror' !== key);
3983 });
3984}
3985}); // module: runner.js
3986
3987require.register("suite.js", function(module, exports, require){
3988
3989/**
3990 * Module dependencies.
3991 */
3992
3993var EventEmitter = require('browser/events').EventEmitter
3994 , debug = require('browser/debug')('mocha:suite')
3995 , utils = require('./utils')
3996 , Hook = require('./hook');
3997
3998/**
3999 * Expose `Suite`.
4000 */
4001
4002exports = module.exports = Suite;
4003
4004/**
4005 * Create a new `Suite` with the given `title`
4006 * and parent `Suite`. When a suite with the
4007 * same title is already present, that suite
4008 * is returned to provide nicer reporter
4009 * and more flexible meta-testing.
4010 *
4011 * @param {Suite} parent
4012 * @param {String} title
4013 * @return {Suite}
4014 * @api public
4015 */
4016
4017exports.create = function(parent, title){
4018 var suite = new Suite(title, parent.ctx);
4019 suite.parent = parent;
4020 if (parent.pending) suite.pending = true;
4021 title = suite.fullTitle();
4022 parent.addSuite(suite);
4023 return suite;
4024};
4025
4026/**
4027 * Initialize a new `Suite` with the given
4028 * `title` and `ctx`.
4029 *
4030 * @param {String} title
4031 * @param {Context} ctx
4032 * @api private
4033 */
4034
4035function Suite(title, ctx) {
4036 this.title = title;
4037 this.ctx = ctx;
4038 this.suites = [];
4039 this.tests = [];
4040 this.pending = false;
4041 this._beforeEach = [];
4042 this._beforeAll = [];
4043 this._afterEach = [];
4044 this._afterAll = [];
4045 this.root = !title;
4046 this._timeout = 2000;
4047 this._bail = false;
4048}
4049
4050/**
4051 * Inherit from `EventEmitter.prototype`.
4052 */
4053
4054Suite.prototype = new EventEmitter;
4055Suite.prototype.constructor = Suite;
4056
4057
4058/**
4059 * Return a clone of this `Suite`.
4060 *
4061 * @return {Suite}
4062 * @api private
4063 */
4064
4065Suite.prototype.clone = function(){
4066 var suite = new Suite(this.title);
4067 debug('clone');
4068 suite.ctx = this.ctx;
4069 suite.timeout(this.timeout());
4070 suite.bail(this.bail());
4071 return suite;
4072};
4073
4074/**
4075 * Set timeout `ms` or short-hand such as "2s".
4076 *
4077 * @param {Number|String} ms
4078 * @return {Suite|Number} for chaining
4079 * @api private
4080 */
4081
4082Suite.prototype.timeout = function(ms){
4083 if (0 == arguments.length) return this._timeout;
4084 if (String(ms).match(/s$/)) ms = parseFloat(ms) * 1000;
4085 debug('timeout %d', ms);
4086 this._timeout = parseInt(ms, 10);
4087 return this;
4088};
4089
4090/**
4091 * Sets whether to bail after first error.
4092 *
4093 * @parma {Boolean} bail
4094 * @return {Suite|Number} for chaining
4095 * @api private
4096 */
4097
4098Suite.prototype.bail = function(bail){
4099 if (0 == arguments.length) return this._bail;
4100 debug('bail %s', bail);
4101 this._bail = bail;
4102 return this;
4103};
4104
4105/**
4106 * Run `fn(test[, done])` before running tests.
4107 *
4108 * @param {Function} fn
4109 * @return {Suite} for chaining
4110 * @api private
4111 */
4112
4113Suite.prototype.beforeAll = function(fn){
4114 if (this.pending) return this;
4115 var hook = new Hook('"before all" hook', fn);
4116 hook.parent = this;
4117 hook.timeout(this.timeout());
4118 hook.ctx = this.ctx;
4119 this._beforeAll.push(hook);
4120 this.emit('beforeAll', hook);
4121 return this;
4122};
4123
4124/**
4125 * Run `fn(test[, done])` after running tests.
4126 *
4127 * @param {Function} fn
4128 * @return {Suite} for chaining
4129 * @api private
4130 */
4131
4132Suite.prototype.afterAll = function(fn){
4133 if (this.pending) return this;
4134 var hook = new Hook('"after all" hook', fn);
4135 hook.parent = this;
4136 hook.timeout(this.timeout());
4137 hook.ctx = this.ctx;
4138 this._afterAll.push(hook);
4139 this.emit('afterAll', hook);
4140 return this;
4141};
4142
4143/**
4144 * Run `fn(test[, done])` before each test case.
4145 *
4146 * @param {Function} fn
4147 * @return {Suite} for chaining
4148 * @api private
4149 */
4150
4151Suite.prototype.beforeEach = function(fn){
4152 if (this.pending) return this;
4153 var hook = new Hook('"before each" hook', fn);
4154 hook.parent = this;
4155 hook.timeout(this.timeout());
4156 hook.ctx = this.ctx;
4157 this._beforeEach.push(hook);
4158 this.emit('beforeEach', hook);
4159 return this;
4160};
4161
4162/**
4163 * Run `fn(test[, done])` after each test case.
4164 *
4165 * @param {Function} fn
4166 * @return {Suite} for chaining
4167 * @api private
4168 */
4169
4170Suite.prototype.afterEach = function(fn){
4171 if (this.pending) return this;
4172 var hook = new Hook('"after each" hook', fn);
4173 hook.parent = this;
4174 hook.timeout(this.timeout());
4175 hook.ctx = this.ctx;
4176 this._afterEach.push(hook);
4177 this.emit('afterEach', hook);
4178 return this;
4179};
4180
4181/**
4182 * Add a test `suite`.
4183 *
4184 * @param {Suite} suite
4185 * @return {Suite} for chaining
4186 * @api private
4187 */
4188
4189Suite.prototype.addSuite = function(suite){
4190 suite.parent = this;
4191 suite.timeout(this.timeout());
4192 suite.bail(this.bail());
4193 this.suites.push(suite);
4194 this.emit('suite', suite);
4195 return this;
4196};
4197
4198/**
4199 * Add a `test` to this suite.
4200 *
4201 * @param {Test} test
4202 * @return {Suite} for chaining
4203 * @api private
4204 */
4205
4206Suite.prototype.addTest = function(test){
4207 test.parent = this;
4208 test.timeout(this.timeout());
4209 test.ctx = this.ctx;
4210 this.tests.push(test);
4211 this.emit('test', test);
4212 return this;
4213};
4214
4215/**
4216 * Return the full title generated by recursively
4217 * concatenating the parent's full title.
4218 *
4219 * @return {String}
4220 * @api public
4221 */
4222
4223Suite.prototype.fullTitle = function(){
4224 if (this.parent) {
4225 var full = this.parent.fullTitle();
4226 if (full) return full + ' ' + this.title;
4227 }
4228 return this.title;
4229};
4230
4231/**
4232 * Return the total number of tests.
4233 *
4234 * @return {Number}
4235 * @api public
4236 */
4237
4238Suite.prototype.total = function(){
4239 return utils.reduce(this.suites, function(sum, suite){
4240 return sum + suite.total();
4241 }, 0) + this.tests.length;
4242};
4243
4244/**
4245 * Iterates through each suite recursively to find
4246 * all tests. Applies a function in the format
4247 * `fn(test)`.
4248 *
4249 * @param {Function} fn
4250 * @return {Suite}
4251 * @api private
4252 */
4253
4254Suite.prototype.eachTest = function(fn){
4255 utils.forEach(this.tests, fn);
4256 utils.forEach(this.suites, function(suite){
4257 suite.eachTest(fn);
4258 });
4259 return this;
4260};
4261
4262}); // module: suite.js
4263
4264require.register("test.js", function(module, exports, require){
4265
4266/**
4267 * Module dependencies.
4268 */
4269
4270var Runnable = require('./runnable');
4271
4272/**
4273 * Expose `Test`.
4274 */
4275
4276module.exports = Test;
4277
4278/**
4279 * Initialize a new `Test` with the given `title` and callback `fn`.
4280 *
4281 * @param {String} title
4282 * @param {Function} fn
4283 * @api private
4284 */
4285
4286function Test(title, fn) {
4287 Runnable.call(this, title, fn);
4288 this.pending = !fn;
4289 this.type = 'test';
4290}
4291
4292/**
4293 * Inherit from `Runnable.prototype`.
4294 */
4295
4296Test.prototype = new Runnable;
4297Test.prototype.constructor = Test;
4298
4299
4300}); // module: test.js
4301
4302require.register("utils.js", function(module, exports, require){
4303
4304/**
4305 * Module dependencies.
4306 */
4307
4308var fs = require('browser/fs')
4309 , path = require('browser/path')
4310 , join = path.join
4311 , debug = require('browser/debug')('mocha:watch');
4312
4313/**
4314 * Ignored directories.
4315 */
4316
4317var ignore = ['node_modules', '.git'];
4318
4319/**
4320 * Escape special characters in the given string of html.
4321 *
4322 * @param {String} html
4323 * @return {String}
4324 * @api private
4325 */
4326
4327exports.escape = function(html) {
4328 return String(html)
4329 .replace(/&/g, '&amp;')
4330 .replace(/"/g, '&quot;')
4331 .replace(/</g, '&lt;')
4332 .replace(/>/g, '&gt;');
4333};
4334
4335/**
4336 * Array#forEach (<=IE8)
4337 *
4338 * @param {Array} array
4339 * @param {Function} fn
4340 * @param {Object} scope
4341 * @api private
4342 */
4343
4344exports.forEach = function(arr, fn, scope) {
4345 for (var i = 0, l = arr.length; i < l; i++)
4346 fn.call(scope, arr[i], i);
4347};
4348
4349/**
4350 * Array#indexOf (<=IE8)
4351 *
4352 * @parma {Array} arr
4353 * @param {Object} obj to find index of
4354 * @param {Number} start
4355 * @api private
4356 */
4357
4358exports.indexOf = function (arr, obj, start) {
4359 for (var i = start || 0, l = arr.length; i < l; i++) {
4360 if (arr[i] === obj)
4361 return i;
4362 }
4363 return -1;
4364};
4365
4366/**
4367 * Array#reduce (<=IE8)
4368 *
4369 * @param {Array} array
4370 * @param {Function} fn
4371 * @param {Object} initial value
4372 * @param {Object} scope
4373 * @api private
4374 */
4375
4376exports.reduce = function(arr, fn, val, scope) {
4377 var rval = val;
4378
4379 for (var i = 0, l = arr.length; i < l; i++) {
4380 rval = fn.call(scope, rval, arr[i], i, arr);
4381 }
4382
4383 return rval;
4384};
4385
4386/**
4387 * Array#filter (<=IE8)
4388 *
4389 * @param {Array} array
4390 * @param {Function} fn
4391 * @param {Object} scope
4392 * @api private
4393 */
4394
4395exports.filter = function(arr, fn, scope) {
4396 var ret = [];
4397
4398 for (var i = 0, l = arr.length; i < l; i++) {
4399 var val = arr[i];
4400 if (fn.call(scope, val, i, arr))
4401 ret.push(val);
4402 }
4403
4404 return ret;
4405};
4406
4407/**
4408 * Object.keys (<=IE8)
4409 *
4410 * @param {Object} obj
4411 * @return {Array} keys
4412 * @api private
4413 */
4414
4415exports.keys = Object.keys || function(obj) {
4416 var keys = []
4417 , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
4418
4419 for (var key in obj) {
4420 if (has.call(obj, key)) {
4421 keys.push(key);
4422 }
4423 }
4424
4425 return keys;
4426};
4427
4428/**
4429 * Watch the given `files` for changes
4430 * and invoke `fn(file)` on modification.
4431 *
4432 * @param {Array} files
4433 * @param {Function} fn
4434 * @api private
4435 */
4436
4437exports.watch = function(files, fn){
4438 var options = { interval: 100 };
4439 files.forEach(function(file){
4440 debug('file %s', file);
4441 fs.watchFile(file, options, function(curr, prev){
4442 if (prev.mtime < curr.mtime) fn(file);
4443 });
4444 });
4445};
4446
4447/**
4448 * Ignored files.
4449 */
4450
4451function ignored(path){
4452 return !~ignore.indexOf(path);
4453}
4454
4455/**
4456 * Lookup files in the given `dir`.
4457 *
4458 * @return {Array}
4459 * @api private
4460 */
4461
4462exports.files = function(dir, ret){
4463 ret = ret || [];
4464
4465 fs.readdirSync(dir)
4466 .filter(ignored)
4467 .forEach(function(path){
4468 path = join(dir, path);
4469 if (fs.statSync(path).isDirectory()) {
4470 exports.files(path, ret);
4471 } else if (path.match(/\.(js|coffee)$/)) {
4472 ret.push(path);
4473 }
4474 });
4475
4476 return ret;
4477};
4478
4479/**
4480 * Compute a slug from the given `str`.
4481 *
4482 * @param {String} str
4483 * @return {String}
4484 * @api private
4485 */
4486
4487exports.slug = function(str){
4488 return str
4489 .toLowerCase()
4490 .replace(/ +/g, '-')
4491 .replace(/[^-\w]/g, '');
4492};
4493
4494/**
4495 * Strip the function definition from `str`,
4496 * and re-indent for pre whitespace.
4497 */
4498
4499exports.clean = function(str) {
4500 str = str
4501 .replace(/^function *\(.*\) *{/, '')
4502 .replace(/\s+\}$/, '');
4503
4504 var spaces = str.match(/^\n?( *)/)[1].length
4505 , re = new RegExp('^ {' + spaces + '}', 'gm');
4506
4507 str = str.replace(re, '');
4508
4509 return exports.trim(str);
4510};
4511
4512/**
4513 * Escape regular expression characters in `str`.
4514 *
4515 * @param {String} str
4516 * @return {String}
4517 * @api private
4518 */
4519
4520exports.escapeRegexp = function(str){
4521 return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
4522};
4523
4524/**
4525 * Trim the given `str`.
4526 *
4527 * @param {String} str
4528 * @return {String}
4529 * @api private
4530 */
4531
4532exports.trim = function(str){
4533 return str.replace(/^\s+|\s+$/g, '');
4534};
4535
4536/**
4537 * Parse the given `qs`.
4538 *
4539 * @param {String} qs
4540 * @return {Object}
4541 * @api private
4542 */
4543
4544exports.parseQuery = function(qs){
4545 return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
4546 var i = pair.indexOf('=')
4547 , key = pair.slice(0, i)
4548 , val = pair.slice(++i);
4549
4550 obj[key] = decodeURIComponent(val);
4551 return obj;
4552 }, {});
4553};
4554
4555/**
4556 * Highlight the given string of `js`.
4557 *
4558 * @param {String} js
4559 * @return {String}
4560 * @api private
4561 */
4562
4563function highlight(js) {
4564 return js
4565 .replace(/</g, '&lt;')
4566 .replace(/>/g, '&gt;')
4567 .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
4568 .replace(/('.*?')/gm, '<span class="string">$1</span>')
4569 .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
4570 .replace(/(\d+)/gm, '<span class="number">$1</span>')
4571 .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
4572 .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
4573}
4574
4575/**
4576 * Highlight the contents of tag `name`.
4577 *
4578 * @param {String} name
4579 * @api private
4580 */
4581
4582exports.highlightTags = function(name) {
4583 var code = document.getElementsByTagName(name);
4584 for (var i = 0, len = code.length; i < len; ++i) {
4585 code[i].innerHTML = highlight(code[i].innerHTML);
4586 }
4587};
4588}); // module: utils.js
4589/**
4590 * Node shims.
4591 *
4592 * These are meant only to allow
4593 * mocha.js to run untouched, not
4594 * to allow running node code in
4595 * the browser.
4596 */
4597
4598process = {};
4599process.exit = function(status){};
4600process.stdout = {};
4601global = window;
4602
4603/**
4604 * next tick implementation.
4605 */
4606
4607process.nextTick = (function(){
4608 // postMessage behaves badly on IE8
4609 if (window.ActiveXObject || !window.postMessage) {
4610 return function(fn){ fn() };
4611 }
4612
4613 // based on setZeroTimeout by David Baron
4614 // - http://dbaron.org/log/20100309-faster-timeouts
4615 var timeouts = []
4616 , name = 'mocha-zero-timeout'
4617
4618 window.addEventListener('message', function(e){
4619 if (e.source == window && e.data == name) {
4620 if (e.stopPropagation) e.stopPropagation();
4621 if (timeouts.length) timeouts.shift()();
4622 }
4623 }, true);
4624
4625 return function(fn){
4626 timeouts.push(fn);
4627 window.postMessage(name, '*');
4628 }
4629})();
4630
4631/**
4632 * Remove uncaughtException listener.
4633 */
4634
4635process.removeListener = function(e){
4636 if ('uncaughtException' == e) {
4637 window.onerror = null;
4638 }
4639};
4640
4641/**
4642 * Implements uncaughtException listener.
4643 */
4644
4645process.on = function(e, fn){
4646 if ('uncaughtException' == e) {
4647 window.onerror = fn;
4648 }
4649};
4650
4651// boot
4652;(function(){
4653
4654 /**
4655 * Expose mocha.
4656 */
4657
4658 var Mocha = window.Mocha = require('mocha'),
4659 mocha = window.mocha = new Mocha({ reporter: 'html' });
4660
4661 /**
4662 * Override ui to ensure that the ui functions are initialized.
4663 * Normally this would happen in Mocha.prototype.loadFiles.
4664 */
4665
4666 mocha.ui = function(ui){
4667 Mocha.prototype.ui.call(this, ui);
4668 this.suite.emit('pre-require', window, null, this);
4669 return this;
4670 };
4671
4672 /**
4673 * Setup mocha with the given setting options.
4674 */
4675
4676 mocha.setup = function(opts){
4677 if ('string' == typeof opts) opts = { ui: opts };
4678 for (var opt in opts) this[opt](opts[opt]);
4679 return this;
4680 };
4681
4682 /**
4683 * Run mocha, returning the Runner.
4684 */
4685
4686 mocha.run = function(fn){
4687 var options = mocha.options;
4688 mocha.globals('location');
4689
4690 var query = Mocha.utils.parseQuery(window.location.search || '');
4691 if (query.grep) mocha.grep(query.grep);
4692
4693 return Mocha.prototype.run.call(mocha, function(){
4694 Mocha.utils.highlightTags('code');
4695 if (fn) fn();
4696 });
4697 };
4698})();
4699})();
\No newline at end of file