Skip to content

Commit 191cc19

Browse files
a8mboneskull
authored andcommitted
feature(mocha/grep): improve grep - issue #808
Add the ability to pass grep as a regexp-like string. (query in the browser or flag in the cli). This improvement gives you pass a regexp that including a flag, and solved #808 as well.
1 parent 0e7f38f commit 191cc19

File tree

6 files changed

+92
-40
lines changed

6 files changed

+92
-40
lines changed

bin/_mocha

+2-2
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,11 @@ mocha.suite.bail(program.bail);
253253

254254
// --grep
255255

256-
if (program.grep) mocha.grep(new RegExp(program.grep));
256+
if (program.grep) mocha.grep(program.grep);
257257

258258
// --fgrep
259259

260-
if (program.fgrep) mocha.grep(program.fgrep);
260+
if (program.fgrep) mocha.fgrep(program.fgrep);
261261

262262
// --invert
263263

browser-entry.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ mocha.run = function(fn){
132132
mocha.globals('location');
133133

134134
var query = Mocha.utils.parseQuery(global.location.search || '');
135-
if (query.grep) mocha.grep(new RegExp(query.grep));
136-
if (query.fgrep) mocha.grep(query.fgrep);
135+
if (query.grep) mocha.grep(query.grep);
136+
if (query.fgrep) mocha.fgrep(query.fgrep);
137137
if (query.invert) mocha.invert();
138138

139139
return Mocha.prototype.run.call(mocha, function(err){

lib/mocha.js

+19-3
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function Mocha(options) {
8080
this.grep(new RegExp(options.grep));
8181
}
8282
if (options.fgrep) {
83-
this.grep(options.fgrep);
83+
this.fgrep(options.fgrep);
8484
}
8585
this.suite = new exports.Suite('', new exports.Context());
8686
this.ui(options.ui);
@@ -246,6 +246,17 @@ Mocha.prototype._growl = function(runner, reporter) {
246246
});
247247
};
248248

249+
/**
250+
* Escape string and add it to grep as a regexp.
251+
*
252+
* @api public
253+
* @param str
254+
* @returns {Mocha}
255+
*/
256+
Mocha.prototype.fgrep = function(str) {
257+
return this.grep(new RegExp(escapeRe(str)));
258+
};
259+
249260
/**
250261
* Add regexp to grep, if `re` is a string it is escaped.
251262
*
@@ -256,10 +267,15 @@ Mocha.prototype._growl = function(runner, reporter) {
256267
* @return {Mocha}
257268
*/
258269
Mocha.prototype.grep = function(re) {
259-
this.options.grep = typeof re === 'string' ? new RegExp(escapeRe(re)) : re;
270+
if (utils.isString(re)) {
271+
// extract args if it's regex-like, i.e: [string, pattern, flag]
272+
var arg = re.match(/^\/(.*)\/(g|i|)$|.*/);
273+
this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);
274+
} else {
275+
this.options.grep = re;
276+
}
260277
return this;
261278
};
262-
263279
/**
264280
* Invert `.grep()` matches.
265281
*

test/grep.js

+39-22
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,61 @@ describe('Mocha', function(){
55
it('should add a RegExp to the mocha.options object', function(){
66
var mocha = new Mocha({ grep: /foo.*/ });
77
mocha.options.grep.toString().should.equal('/foo.*/');
8-
})
8+
});
99

1010
it('should convert string to a RegExp', function(){
1111
var mocha = new Mocha({ grep: 'foo.*' });
1212
mocha.options.grep.toString().should.equal('/foo.*/');
13-
})
14-
})
13+
});
14+
});
1515

1616
describe('"fgrep" option', function(){
1717
it('should escape and convert string to a RegExp', function(){
1818
var mocha = new Mocha({ fgrep: 'foo.*' });
1919
mocha.options.grep.toString().should.equal('/foo\\.\\*/');
20-
})
21-
})
20+
});
21+
});
2222

23-
describe('.grep()', function(){
24-
it('should add a RegExp to the mocha.options object', function(){
25-
var mocha = new Mocha;
26-
mocha.grep(/foo/);
27-
mocha.options.grep.toString().should.equal('/foo/');
28-
})
23+
describe('.grep()', function() {
24+
// Test helper
25+
function testGrep(mocha) {
26+
return function testGrep(grep, expected) {
27+
mocha.grep(grep);
28+
mocha.options.grep.toString().should.equal(expected);
29+
}
30+
}
2931

30-
it('should convert grep string to a RegExp', function(){
31-
var mocha = new Mocha;
32-
mocha.grep('foo');
33-
mocha.options.grep.toString().should.equal('/foo/');
34-
})
32+
it('should add a RegExp to the mocha.options object', function() {
33+
var test = testGrep(new Mocha);
34+
test(/foo/, '/foo/');
35+
});
36+
37+
it('should convert grep string to a RegExp', function() {
38+
var test = testGrep(new Mocha);
39+
test('foo', '/foo/');
40+
test('^foo.*bar$', '/^foo.*bar$/');
41+
test('^@.*(?=\\(\\)$)', '/^@.*(?=\\(\\)$)/');
42+
});
43+
44+
it('should covert grep regex-like string to a RegExp', function() {
45+
var test = testGrep(new Mocha);
46+
test('/foo/', '/foo/');
47+
// Keep the flags
48+
test('/baz/i', '/baz/i');
49+
test('/bar/g', '/bar/g');
50+
test('/^foo(.*)bar/g', '/^foo(.*)bar/g');
51+
});
3552

3653
it('should return it\'s parent Mocha object for chainability', function(){
3754
var mocha = new Mocha;
3855
mocha.grep().should.equal(mocha);
39-
})
40-
})
56+
});
57+
});
4158

4259
describe('"invert" option', function(){
4360
it('should add a Boolean to the mocha.options object', function(){
4461
var mocha = new Mocha({ invert: true });
45-
mocha.options.invert.should.be.ok();
46-
})
47-
})
48-
})
62+
mocha.options.invert.should.be.ok;
63+
});
64+
});
65+
});

test/integration/fixtures/options/grep.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
describe('grep', function() {
2+
describe('Match', function() {
3+
it('should run', function(){});
4+
it('should also run', function() {});
5+
});
6+
27
describe('match', function() {
38
it('should run', function(){});
49
it('should also run', function() {});
510
});
611

7-
describe('fail', function(){
12+
describe('fail', function() {
813
it('should not be ran', function() {
914
throw new Error('Spec should not run');
1015
});

test/integration/options.js

+24-10
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,29 @@ describe('options', function() {
125125
});
126126
});
127127

128-
it('runs specs matching a RegExp', function(done) {
129-
args = ['--grep', '.*'];
130-
run('options/grep.js', args, function(err, res) {
131-
assert(!err);
132-
assert.equal(res.stats.pending, 0);
133-
assert.equal(res.stats.passes, 2);
134-
assert.equal(res.stats.failures, 1);
135-
assert.equal(res.code, 1);
136-
done();
128+
describe('runs specs matching a RegExp', function() {
129+
it('with RegExp like strings(pattern follow by flag)', function(done) {
130+
args = ['--grep', '/match/i'];
131+
run('options/grep.js', args, function(err, res) {
132+
assert(!err);
133+
assert.equal(res.stats.pending, 0);
134+
assert.equal(res.stats.passes, 4);
135+
assert.equal(res.stats.failures, 0);
136+
assert.equal(res.code, 0);
137+
done();
138+
});
139+
});
140+
141+
it('string as pattern', function(done) {
142+
args = ['--grep', '.*'];
143+
run('options/grep.js', args, function(err, res) {
144+
assert(!err);
145+
assert.equal(res.stats.pending, 0);
146+
assert.equal(res.stats.passes, 4);
147+
assert.equal(res.stats.failures, 1);
148+
assert.equal(res.code, 1);
149+
done();
150+
});
137151
});
138152
});
139153

@@ -143,7 +157,7 @@ describe('options', function() {
143157
run('options/grep.js', args, function(err, res) {
144158
assert(!err);
145159
assert.equal(res.stats.pending, 0);
146-
assert.equal(res.stats.passes, 2);
160+
assert.equal(res.stats.passes, 4);
147161
assert.equal(res.stats.failures, 0);
148162
assert.equal(res.code, 0);
149163
done();

0 commit comments

Comments
 (0)