konacha 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -535,12 +535,7 @@ var Suite = require('../suite')
535
535
  module.exports = function(suite){
536
536
  var suites = [suite];
537
537
 
538
- suite.on('pre-require', function(context){
539
-
540
- // noop variants
541
-
542
- context.xdescribe = function(){};
543
- context.xit = function(){};
538
+ suite.on('pre-require', function(context, file, mocha){
544
539
 
545
540
  /**
546
541
  * Execute before running tests.
@@ -585,6 +580,30 @@ module.exports = function(suite){
585
580
  suites.unshift(suite);
586
581
  fn();
587
582
  suites.shift();
583
+ return suite;
584
+ };
585
+
586
+ /**
587
+ * Pending describe.
588
+ */
589
+
590
+ context.xdescribe =
591
+ context.xcontext =
592
+ context.describe.skip = function(title, fn){
593
+ var suite = Suite.create(suites[0], title);
594
+ suite.pending = true;
595
+ suites.unshift(suite);
596
+ fn();
597
+ suites.shift();
598
+ };
599
+
600
+ /**
601
+ * Exclusive suite.
602
+ */
603
+
604
+ context.describe.only = function(title, fn){
605
+ var suite = context.describe(title, fn);
606
+ mocha.grep(suite.fullTitle());
588
607
  };
589
608
 
590
609
  /**
@@ -594,7 +613,30 @@ module.exports = function(suite){
594
613
  */
595
614
 
596
615
  context.it = context.specify = function(title, fn){
597
- suites[0].addTest(new Test(title, fn));
616
+ var suite = suites[0];
617
+ if (suite.pending) var fn = null;
618
+ var test = new Test(title, fn);
619
+ suite.addTest(test);
620
+ return test;
621
+ };
622
+
623
+ /**
624
+ * Exclusive test-case.
625
+ */
626
+
627
+ context.it.only = function(title, fn){
628
+ var test = context.it(title, fn);
629
+ mocha.grep(test.fullTitle());
630
+ };
631
+
632
+ /**
633
+ * Pending test case.
634
+ */
635
+
636
+ context.xit =
637
+ context.xspecify =
638
+ context.it.skip = function(title){
639
+ context.it(title);
598
640
  };
599
641
  });
600
642
  };
@@ -805,7 +847,7 @@ var Suite = require('../suite')
805
847
  module.exports = function(suite){
806
848
  var suites = [suite];
807
849
 
808
- suite.on('pre-require', function(context){
850
+ suite.on('pre-require', function(context, file, mocha){
809
851
 
810
852
  /**
811
853
  * Execute before each test case.
@@ -850,6 +892,16 @@ module.exports = function(suite){
850
892
  suites.unshift(suite);
851
893
  fn();
852
894
  suites.shift();
895
+ return suite;
896
+ };
897
+
898
+ /**
899
+ * Exclusive test-case.
900
+ */
901
+
902
+ context.suite.only = function(title, fn){
903
+ var suite = context.suite(title, fn);
904
+ mocha.grep(suite.fullTitle());
853
905
  };
854
906
 
855
907
  /**
@@ -859,7 +911,18 @@ module.exports = function(suite){
859
911
  */
860
912
 
861
913
  context.test = function(title, fn){
862
- suites[0].addTest(new Test(title, fn));
914
+ var test = new Test(title, fn);
915
+ suites[0].addTest(test);
916
+ return test;
917
+ };
918
+
919
+ /**
920
+ * Exclusive test-case.
921
+ */
922
+
923
+ context.test.only = function(title, fn){
924
+ var test = context.test(title, fn);
925
+ mocha.grep(test.fullTitle());
863
926
  };
864
927
  });
865
928
  };
@@ -985,13 +1048,16 @@ Mocha.prototype.ui = function(name){
985
1048
  * @api private
986
1049
  */
987
1050
 
988
- Mocha.prototype.loadFiles = function(){
1051
+ Mocha.prototype.loadFiles = function(fn){
1052
+ var self = this;
989
1053
  var suite = this.suite;
1054
+ var pending = this.files.length;
990
1055
  this.files.forEach(function(file){
991
1056
  file = path.resolve(file);
992
- suite.emit('pre-require', global, file);
993
- suite.emit('require', require(file), file);
994
- suite.emit('post-require', global, file);
1057
+ suite.emit('pre-require', global, file, self);
1058
+ suite.emit('require', require(file), file, self);
1059
+ suite.emit('post-require', global, file, self);
1060
+ --pending || (fn && fn());
995
1061
  });
996
1062
  };
997
1063
 
@@ -1001,7 +1067,7 @@ Mocha.prototype.loadFiles = function(){
1001
1067
  * @api private
1002
1068
  */
1003
1069
 
1004
- Mocha.prototype.growl = function(runner, reporter) {
1070
+ Mocha.prototype._growl = function(runner, reporter) {
1005
1071
  var notify = require('growl');
1006
1072
 
1007
1073
  runner.on('end', function(){
@@ -1034,6 +1100,55 @@ Mocha.prototype.grep = function(re){
1034
1100
  return this;
1035
1101
  };
1036
1102
 
1103
+ /**
1104
+ * Invert `.grep()` matches.
1105
+ *
1106
+ * @return {Mocha}
1107
+ * @api public
1108
+ */
1109
+
1110
+ Mocha.prototype.invert = function(){
1111
+ this.options.invert = true;
1112
+ return this;
1113
+ };
1114
+
1115
+ /**
1116
+ * Ignore global leaks.
1117
+ *
1118
+ * @return {Mocha}
1119
+ * @api public
1120
+ */
1121
+
1122
+ Mocha.prototype.ignoreLeaks = function(){
1123
+ this.options.ignoreLeaks = true;
1124
+ return this;
1125
+ };
1126
+
1127
+ /**
1128
+ * Enable growl support.
1129
+ *
1130
+ * @return {Mocha}
1131
+ * @api public
1132
+ */
1133
+
1134
+ Mocha.prototype.growl = function(){
1135
+ this.options.growl = true;
1136
+ return this;
1137
+ };
1138
+
1139
+ /**
1140
+ * Ignore `globals`.
1141
+ *
1142
+ * @param {Array} globals
1143
+ * @return {Mocha}
1144
+ * @api public
1145
+ */
1146
+
1147
+ Mocha.prototype.globals = function(globals){
1148
+ this.options.globals = globals;
1149
+ return this;
1150
+ };
1151
+
1037
1152
  /**
1038
1153
  * Run tests and invoke `fn()` when complete.
1039
1154
  *
@@ -1049,9 +1164,9 @@ Mocha.prototype.run = function(fn){
1049
1164
  var runner = new exports.Runner(suite);
1050
1165
  var reporter = new this._reporter(runner);
1051
1166
  runner.ignoreLeaks = options.ignoreLeaks;
1052
- if (options.grep) runner.grep(options.grep);
1167
+ if (options.grep) runner.grep(options.grep, options.invert);
1053
1168
  if (options.globals) runner.globals(options.globals);
1054
- if (options.growl) this.growl(runner, reporter);
1169
+ if (options.growl) this._growl(runner, reporter);
1055
1170
  return runner.run(fn);
1056
1171
  };
1057
1172
 
@@ -1134,7 +1249,7 @@ exports.colors = {
1134
1249
 
1135
1250
  var color = exports.color = function(type, str) {
1136
1251
  if (!exports.useColors) return str;
1137
- return '\033[' + exports.colors[type] + 'm' + str + '\033[0m';
1252
+ return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
1138
1253
  };
1139
1254
 
1140
1255
  /**
@@ -1157,19 +1272,19 @@ exports.window = {
1157
1272
 
1158
1273
  exports.cursor = {
1159
1274
  hide: function(){
1160
- process.stdout.write('\033[?25l');
1275
+ process.stdout.write('\u001b[?25l');
1161
1276
  },
1162
1277
 
1163
1278
  show: function(){
1164
- process.stdout.write('\033[?25h');
1279
+ process.stdout.write('\u001b[?25h');
1165
1280
  },
1166
1281
 
1167
1282
  deleteLine: function(){
1168
- process.stdout.write('\033[2K');
1283
+ process.stdout.write('\u001b[2K');
1169
1284
  },
1170
1285
 
1171
1286
  beginningOfLine: function(){
1172
- process.stdout.write('\033[0G');
1287
+ process.stdout.write('\u001b[0G');
1173
1288
  },
1174
1289
 
1175
1290
  CR: function(){
@@ -1504,6 +1619,7 @@ function Dot(runner) {
1504
1619
  var self = this
1505
1620
  , stats = this.stats
1506
1621
  , width = Base.window.width * .75 | 0
1622
+ , c = '․'
1507
1623
  , n = 0;
1508
1624
 
1509
1625
  runner.on('start', function(){
@@ -1511,21 +1627,21 @@ function Dot(runner) {
1511
1627
  });
1512
1628
 
1513
1629
  runner.on('pending', function(test){
1514
- process.stdout.write(color('pending', '.'));
1630
+ process.stdout.write(color('pending', c));
1515
1631
  });
1516
1632
 
1517
1633
  runner.on('pass', function(test){
1518
1634
  if (++n % width == 0) process.stdout.write('\n ');
1519
1635
  if ('slow' == test.speed) {
1520
- process.stdout.write(color('bright yellow', '.'));
1636
+ process.stdout.write(color('bright yellow', c));
1521
1637
  } else {
1522
- process.stdout.write(color(test.speed, '.'));
1638
+ process.stdout.write(color(test.speed, c));
1523
1639
  }
1524
1640
  });
1525
1641
 
1526
1642
  runner.on('fail', function(test, err){
1527
1643
  if (++n % width == 0) process.stdout.write('\n ');
1528
- process.stdout.write(color('fail', '.'));
1644
+ process.stdout.write(color('fail', c));
1529
1645
  });
1530
1646
 
1531
1647
  runner.on('end', function(){
@@ -1630,8 +1746,8 @@ exports = module.exports = HTML;
1630
1746
 
1631
1747
  var statsTemplate = '<ul id="stats">'
1632
1748
  + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
1633
- + '<li class="passes">passes: <em>0</em></li>'
1634
- + '<li class="failures">failures: <em>0</em></li>'
1749
+ + '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
1750
+ + '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
1635
1751
  + '<li class="duration">duration: <em>0</em>s</li>'
1636
1752
  + '</ul>';
1637
1753
 
@@ -1642,17 +1758,18 @@ var statsTemplate = '<ul id="stats">'
1642
1758
  * @api public
1643
1759
  */
1644
1760
 
1645
- function HTML(runner) {
1761
+ function HTML(runner, root) {
1646
1762
  Base.call(this, runner);
1647
1763
 
1648
1764
  var self = this
1649
1765
  , stats = this.stats
1650
1766
  , total = runner.total
1651
- , root = document.getElementById('mocha')
1652
1767
  , stat = fragment(statsTemplate)
1653
1768
  , items = stat.getElementsByTagName('li')
1654
1769
  , passes = items[1].getElementsByTagName('em')[0]
1770
+ , passesLink = items[1].getElementsByTagName('a')[0]
1655
1771
  , failures = items[2].getElementsByTagName('em')[0]
1772
+ , failuresLink = items[2].getElementsByTagName('a')[0]
1656
1773
  , duration = items[3].getElementsByTagName('em')[0]
1657
1774
  , canvas = stat.getElementsByTagName('canvas')[0]
1658
1775
  , report = fragment('<ul id="report"></ul>')
@@ -1660,13 +1777,33 @@ function HTML(runner) {
1660
1777
  , progress
1661
1778
  , ctx
1662
1779
 
1780
+ root = root || document.getElementById('mocha');
1781
+
1663
1782
  if (canvas.getContext) {
1783
+ var ratio = window.devicePixelRatio || 1;
1784
+ canvas.style.width = canvas.width;
1785
+ canvas.style.height = canvas.height;
1786
+ canvas.width *= ratio;
1787
+ canvas.height *= ratio;
1664
1788
  ctx = canvas.getContext('2d');
1789
+ ctx.scale(ratio, ratio);
1665
1790
  progress = new Progress;
1666
1791
  }
1667
1792
 
1668
1793
  if (!root) return error('#mocha div missing, add it to your document');
1669
1794
 
1795
+ // pass toggle
1796
+ on(passesLink, 'click', function () {
1797
+ var className = /pass/.test(report.className) ? '' : ' pass';
1798
+ report.className = report.className.replace(/fail|pass/g, '') + className;
1799
+ });
1800
+
1801
+ // failure toggle
1802
+ on(failuresLink, 'click', function () {
1803
+ var className = /fail/.test(report.className) ? '' : ' fail';
1804
+ report.className = report.className.replace(/fail|pass/g, '') + className;
1805
+ });
1806
+
1670
1807
  root.appendChild(stat);
1671
1808
  root.appendChild(report);
1672
1809
 
@@ -1676,7 +1813,8 @@ function HTML(runner) {
1676
1813
  if (suite.root) return;
1677
1814
 
1678
1815
  // suite
1679
- var url = location.protocol + '//' + location.host + location.pathname + '?grep=^' + utils.escapeRegexp(suite.fullTitle());
1816
+ var grep = '^' + encodeURIComponent(utils.escapeRegexp(suite.fullTitle()));
1817
+ var url = '?grep=' + grep;
1680
1818
  var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
1681
1819
 
1682
1820
  // container
@@ -1734,17 +1872,16 @@ function HTML(runner) {
1734
1872
  }
1735
1873
 
1736
1874
  // toggle code
1737
- var h2 = el.getElementsByTagName('h2')[0];
1738
-
1739
- on(h2, 'click', function(){
1740
- pre.style.display = 'none' == pre.style.display
1741
- ? 'block'
1742
- : 'none';
1743
- });
1744
-
1745
- // code
1746
1875
  // TODO: defer
1747
1876
  if (!test.pending) {
1877
+ var h2 = el.getElementsByTagName('h2')[0];
1878
+
1879
+ on(h2, 'click', function(){
1880
+ pre.style.display = 'none' == pre.style.display
1881
+ ? 'inline-block'
1882
+ : 'none';
1883
+ });
1884
+
1748
1885
  var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
1749
1886
  el.appendChild(pre);
1750
1887
  pre.style.display = 'none';
@@ -1804,6 +1941,7 @@ function on(el, event, fn) {
1804
1941
  el.attachEvent('on' + event, fn);
1805
1942
  }
1806
1943
  }
1944
+
1807
1945
  }); // module: reporters/html.js
1808
1946
 
1809
1947
  require.register("reporters/index.js", function(module, exports, require){
@@ -2194,14 +2332,14 @@ function Landing(runner) {
2194
2332
  }
2195
2333
 
2196
2334
  // render landing strip
2197
- stream.write('\033[4F\n\n');
2335
+ stream.write('\u001b[4F\n\n');
2198
2336
  stream.write(runway());
2199
2337
  stream.write('\n ');
2200
2338
  stream.write(color('runway', Array(col).join('⋅')));
2201
2339
  stream.write(plane)
2202
2340
  stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
2203
2341
  stream.write(runway());
2204
- stream.write('\033[0m');
2342
+ stream.write('\u001b[0m');
2205
2343
  });
2206
2344
 
2207
2345
  runner.on('end', function(){
@@ -2411,9 +2549,9 @@ function Min(runner) {
2411
2549
 
2412
2550
  runner.on('start', function(){
2413
2551
  // clear screen
2414
- process.stdout.write('\033[2J');
2552
+ process.stdout.write('\u001b[2J');
2415
2553
  // set cursor position
2416
- process.stdout.write('\033[1;3H');
2554
+ process.stdout.write('\u001b[1;3H');
2417
2555
  });
2418
2556
 
2419
2557
  runner.on('end', this.epilogue.bind(this));
@@ -2518,7 +2656,7 @@ NyanCat.prototype.drawScoreboard = function(){
2518
2656
 
2519
2657
  function draw(color, n) {
2520
2658
  write(' ');
2521
- write('\033[' + color + 'm' + n + '\033[0m');
2659
+ write('\u001b[' + color + 'm' + n + '\u001b[0m');
2522
2660
  write('\n');
2523
2661
  }
2524
2662
 
@@ -2557,7 +2695,7 @@ NyanCat.prototype.drawRainbow = function(){
2557
2695
  var self = this;
2558
2696
 
2559
2697
  this.trajectories.forEach(function(line, index) {
2560
- write('\033[' + self.scoreboardWidth + 'C');
2698
+ write('\u001b[' + self.scoreboardWidth + 'C');
2561
2699
  write(line.join(''));
2562
2700
  write('\n');
2563
2701
  });
@@ -2577,7 +2715,7 @@ NyanCat.prototype.drawNyanCat = function(status) {
2577
2715
  var startWidth = this.scoreboardWidth + this.trajectories[0].length;
2578
2716
 
2579
2717
  [0, 1, 2, 3].forEach(function(index) {
2580
- write('\033[' + startWidth + 'C');
2718
+ write('\u001b[' + startWidth + 'C');
2581
2719
 
2582
2720
  switch (index) {
2583
2721
  case 0:
@@ -2625,7 +2763,7 @@ NyanCat.prototype.drawNyanCat = function(status) {
2625
2763
  */
2626
2764
 
2627
2765
  NyanCat.prototype.cursorUp = function(n) {
2628
- write('\033[' + n + 'A');
2766
+ write('\u001b[' + n + 'A');
2629
2767
  };
2630
2768
 
2631
2769
  /**
@@ -2636,7 +2774,7 @@ NyanCat.prototype.cursorUp = function(n) {
2636
2774
  */
2637
2775
 
2638
2776
  NyanCat.prototype.cursorDown = function(n) {
2639
- write('\033[' + n + 'B');
2777
+ write('\u001b[' + n + 'B');
2640
2778
  };
2641
2779
 
2642
2780
  /**
@@ -2672,7 +2810,7 @@ NyanCat.prototype.generateColors = function(){
2672
2810
  NyanCat.prototype.rainbowify = function(str){
2673
2811
  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
2674
2812
  this.colorIndex += 1;
2675
- return '\033[38;5;' + color + 'm' + str + '\033[0m';
2813
+ return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
2676
2814
  };
2677
2815
 
2678
2816
  /**
@@ -2756,7 +2894,7 @@ function Progress(runner, options) {
2756
2894
  , i = width - n;
2757
2895
 
2758
2896
  cursor.CR();
2759
- process.stdout.write('\033[J');
2897
+ process.stdout.write('\u001b[J');
2760
2898
  process.stdout.write(color('progress', ' ' + options.open));
2761
2899
  process.stdout.write(Array(n).join(options.complete));
2762
2900
  process.stdout.write(Array(i).join(options.incomplete));
@@ -3053,7 +3191,11 @@ function XUnit(runner) {
3053
3191
  , tests = []
3054
3192
  , self = this;
3055
3193
 
3056
- runner.on('test end', function(test){
3194
+ runner.on('pass', function(test){
3195
+ tests.push(test);
3196
+ });
3197
+
3198
+ runner.on('fail', function(test){
3057
3199
  tests.push(test);
3058
3200
  });
3059
3201
 
@@ -3138,7 +3280,7 @@ require.register("runnable.js", function(module, exports, require){
3138
3280
  */
3139
3281
 
3140
3282
  var EventEmitter = require('browser/events').EventEmitter
3141
- , debug = require('browser/debug')('runnable');
3283
+ , debug = require('browser/debug')('mocha:runnable');
3142
3284
 
3143
3285
  /**
3144
3286
  * Save timer references to avoid Sinon interfering (see GH-237).
@@ -3334,7 +3476,7 @@ require.register("runner.js", function(module, exports, require){
3334
3476
  */
3335
3477
 
3336
3478
  var EventEmitter = require('browser/events').EventEmitter
3337
- , debug = require('browser/debug')('runner')
3479
+ , debug = require('browser/debug')('mocha:runner')
3338
3480
  , Test = require('./test')
3339
3481
  , utils = require('./utils')
3340
3482
  , filter = utils.filter
@@ -3743,9 +3885,9 @@ Runner.prototype.runSuite = function(suite, fn){
3743
3885
  */
3744
3886
 
3745
3887
  Runner.prototype.uncaught = function(err){
3746
- debug('uncaught exception');
3888
+ debug('uncaught exception %s', err.message);
3747
3889
  var runnable = this.currentRunnable;
3748
- if ('failed' == runnable.state) return;
3890
+ if (!runnable || 'failed' == runnable.state) return;
3749
3891
  runnable.clearTimeout();
3750
3892
  err.uncaught = true;
3751
3893
  this.fail(runnable, err);
@@ -3827,7 +3969,7 @@ require.register("suite.js", function(module, exports, require){
3827
3969
  */
3828
3970
 
3829
3971
  var EventEmitter = require('browser/events').EventEmitter
3830
- , debug = require('browser/debug')('suite')
3972
+ , debug = require('browser/debug')('mocha:suite')
3831
3973
  , utils = require('./utils')
3832
3974
  , Hook = require('./hook');
3833
3975
 
@@ -3853,6 +3995,7 @@ exports = module.exports = Suite;
3853
3995
  exports.create = function(parent, title){
3854
3996
  var suite = new Suite(title, parent.ctx);
3855
3997
  suite.parent = parent;
3998
+ if (parent.pending) suite.pending = true;
3856
3999
  title = suite.fullTitle();
3857
4000
  parent.addSuite(suite);
3858
4001
  return suite;
@@ -3872,6 +4015,7 @@ function Suite(title, ctx) {
3872
4015
  this.ctx = ctx;
3873
4016
  this.suites = [];
3874
4017
  this.tests = [];
4018
+ this.pending = false;
3875
4019
  this._beforeEach = [];
3876
4020
  this._beforeAll = [];
3877
4021
  this._afterEach = [];
@@ -3945,6 +4089,7 @@ Suite.prototype.bail = function(bail){
3945
4089
  */
3946
4090
 
3947
4091
  Suite.prototype.beforeAll = function(fn){
4092
+ if (this.pending) return this;
3948
4093
  var hook = new Hook('"before all" hook', fn);
3949
4094
  hook.parent = this;
3950
4095
  hook.timeout(this.timeout());
@@ -3963,6 +4108,7 @@ Suite.prototype.beforeAll = function(fn){
3963
4108
  */
3964
4109
 
3965
4110
  Suite.prototype.afterAll = function(fn){
4111
+ if (this.pending) return this;
3966
4112
  var hook = new Hook('"after all" hook', fn);
3967
4113
  hook.parent = this;
3968
4114
  hook.timeout(this.timeout());
@@ -3981,6 +4127,7 @@ Suite.prototype.afterAll = function(fn){
3981
4127
  */
3982
4128
 
3983
4129
  Suite.prototype.beforeEach = function(fn){
4130
+ if (this.pending) return this;
3984
4131
  var hook = new Hook('"before each" hook', fn);
3985
4132
  hook.parent = this;
3986
4133
  hook.timeout(this.timeout());
@@ -3999,6 +4146,7 @@ Suite.prototype.beforeEach = function(fn){
3999
4146
  */
4000
4147
 
4001
4148
  Suite.prototype.afterEach = function(fn){
4149
+ if (this.pending) return this;
4002
4150
  var hook = new Hook('"after each" hook', fn);
4003
4151
  hook.parent = this;
4004
4152
  hook.timeout(this.timeout());
@@ -4138,7 +4286,7 @@ require.register("utils.js", function(module, exports, require){
4138
4286
  var fs = require('browser/fs')
4139
4287
  , path = require('browser/path')
4140
4288
  , join = path.join
4141
- , debug = require('browser/debug')('watch');
4289
+ , debug = require('browser/debug')('mocha:watch');
4142
4290
 
4143
4291
  /**
4144
4292
  * Ignored directories.
@@ -4336,7 +4484,7 @@ exports.clean = function(str) {
4336
4484
 
4337
4485
  str = str.replace(re, '');
4338
4486
 
4339
- return str.trim();
4487
+ return exports.trim(str);
4340
4488
  };
4341
4489
 
4342
4490
  /**
@@ -4350,6 +4498,18 @@ exports.clean = function(str) {
4350
4498
  exports.escapeRegexp = function(str){
4351
4499
  return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
4352
4500
  };
4501
+
4502
+ /**
4503
+ * Trim the given `str`.
4504
+ *
4505
+ * @param {String} str
4506
+ * @return {String}
4507
+ * @api private
4508
+ */
4509
+
4510
+ exports.trim = function(str){
4511
+ return str.replace(/^\s+|\s+$/g, '');
4512
+ };
4353
4513
  }); // module: utils.js
4354
4514
  /**
4355
4515
  * Node shims.
@@ -4424,6 +4584,8 @@ window.mocha = require('mocha');
4424
4584
  var utils = mocha.utils
4425
4585
  , options = {}
4426
4586
 
4587
+ // TODO: use new Mocha here... not mocha.grep etc
4588
+
4427
4589
  mocha.suite = new mocha.Suite('', new mocha.Context());
4428
4590
 
4429
4591
  /**
@@ -4468,6 +4630,14 @@ window.mocha = require('mocha');
4468
4630
  }, {});
4469
4631
  }
4470
4632
 
4633
+ /**
4634
+ * Grep.
4635
+ */
4636
+
4637
+ mocha.grep = function(str){
4638
+ options.grep = new RegExp(utils.escapeRegexp(str));
4639
+ };
4640
+
4471
4641
  /**
4472
4642
  * Setup mocha with the given setting options.
4473
4643
  */
@@ -4480,7 +4650,7 @@ window.mocha = require('mocha');
4480
4650
  if (!ui) throw new Error('invalid mocha interface "' + ui + '"');
4481
4651
  if (options.timeout) mocha.suite.timeout(options.timeout);
4482
4652
  ui(mocha.suite);
4483
- mocha.suite.emit('pre-require', window);
4653
+ mocha.suite.emit('pre-require', window, null, mocha);
4484
4654
  };
4485
4655
 
4486
4656
  /**
@@ -4494,6 +4664,7 @@ window.mocha = require('mocha');
4494
4664
  var reporter = new Reporter(runner);
4495
4665
  var query = parse(window.location.search || "");
4496
4666
  if (query.grep) runner.grep(new RegExp(query.grep));
4667
+ if (options.grep) runner.grep(options.grep);
4497
4668
  if (options.ignoreLeaks) runner.ignoreLeaks = true;
4498
4669
  if (options.globals) runner.globals(options.globals);
4499
4670
  runner.globals(['location']);