qs 0.4.0 → 0.5.1

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