Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

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