Skip to content

Commit 943ceb7

Browse files
committed
Better support for non-ending strict mode matches with a trailing slash
1 parent 362337d commit 943ceb7

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed

index.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@ module.exports = pathtoRegexp;
2222

2323
function pathtoRegexp(path, keys, options) {
2424
options = options || {};
25-
var sensitive = options.sensitive;
2625
var strict = options.strict;
2726
var end = options.end !== false;
27+
var flags = options.sensitive ? '' : 'i';
2828
keys = keys || [];
2929

3030
if (path instanceof RegExp) return path;
3131
if (path instanceof Array) path = '(' + path.join('|') + ')';
3232

33-
path = path
34-
.concat(strict ? '' : '/?')
33+
path = ('^' + path + (strict ? '' : '/?'))
3534
.replace(/\/\(/g, '/(?:')
3635
.replace(/([\/\.])/g, '\\$1')
3736
.replace(/(\\\/)?(\\\.)?:(\w+)(\(.*?\))?(\*)?(\?)?/g, function (match, slash, format, key, capture, star, optional) {
@@ -52,5 +51,8 @@ function pathtoRegexp(path, keys, options) {
5251
})
5352
.replace(/\*/g, '(.*)');
5453

55-
return new RegExp('^' + path + (end ? '$' : '(?=\/|$)'), sensitive ? '' : 'i');
54+
// If the path is non-ending, match until the end or a slash.
55+
path += (end ? '$' : (path[path.length - 1] === '/' ? '' : '(?=\\/|$)'));
56+
57+
return new RegExp(path, flags);
5658
};

test.js

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,30 @@ describe('path-to-regexp', function () {
4646
assert.ok(!m);
4747
});
4848

49+
it('should do strict matches with trailing slashes', function () {
50+
var params = [];
51+
var re = pathToRegExp('/:test/', params, { strict: true });
52+
var m;
53+
54+
assert.equal(params.length, 1);
55+
assert.equal(params[0].name, 'test');
56+
assert.equal(params[0].optional, false);
57+
58+
m = re.exec('/route');
59+
60+
assert.ok(!m);
61+
62+
m = re.exec('/route/');
63+
64+
assert.equal(m.length, 2);
65+
assert.equal(m[0], '/route/');
66+
assert.equal(m[1], 'route');
67+
68+
m = re.exec('/route//');
69+
70+
assert.ok(!m);
71+
});
72+
4973
it('should allow optional express format params', function () {
5074
var params = [];
5175
var re = pathToRegExp('/:test?', params);
@@ -388,19 +412,47 @@ describe('path-to-regexp', function () {
388412
assert.equal(m[1], 'test');
389413
});
390414

415+
it('should match trailing slashing in non-ending strict mode', function () {
416+
var params = [];
417+
var re = pathToRegExp('/route/', params, { end: false, strict: true });
418+
419+
assert.equal(params.length, 0);
420+
421+
m = re.exec('/route/');
422+
423+
assert.equal(m.length, 1);
424+
assert.equal(m[0], '/route/');
425+
426+
m = re.exec('/route/test');
427+
428+
assert.equal(m.length, 1);
429+
assert.equal(m[0], '/route/');
430+
431+
m = re.exec('/route');
432+
433+
assert.ok(!m);
434+
435+
m = re.exec('/route//');
436+
437+
assert.equal(m.length, 1);
438+
assert.equal(m[0], '/route/');
439+
});
440+
391441
it('should not match trailing slashes in non-ending strict mode', function () {
392442
var params = [];
393-
var re = pathToRegExp('/:test', params, { end: false, strict: true });
443+
var re = pathToRegExp('/route', params, { end: false, strict: true });
394444

395-
assert.equal(params.length, 1);
396-
assert.equal(params[0].name, 'test');
397-
assert.equal(params[0].optional, false);
445+
assert.equal(params.length, 0);
398446

399-
m = re.exec('/test/');
447+
m = re.exec('/route');
400448

401-
assert.equal(m.length, 2);
402-
assert.equal(m[0], '/test');
403-
assert.equal(m[1], 'test');
449+
assert.equal(m.length, 1);
450+
assert.equal(m[0], '/route');
451+
452+
m = re.exec('/route/');
453+
454+
assert.ok(m.length, 1);
455+
assert.equal(m[0], '/route');
404456
});
405457

406458
it('should match text after an express param', function () {

0 commit comments

Comments
 (0)