Skip to content

Commit e9fa04b

Browse files
authoredJul 20, 2021
Fix additional entry inejcted to params (#124)
* fix additional entry inejcted to params .. * add unit test for this case ..
1 parent 344ba0b commit e9fa04b

File tree

2 files changed

+458
-430
lines changed

2 files changed

+458
-430
lines changed
 

‎lib/layer.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ function Layer(path, methods, middleware, opts) {
2424
this.paramNames = [];
2525
this.stack = Array.isArray(middleware) ? middleware : [middleware];
2626

27-
for(let i = 0; i < methods.length; i++) {
27+
for (let i = 0; i < methods.length; i++) {
2828
const l = this.methods.push(methods[i].toUpperCase());
29-
if (this.methods[l-1] === 'GET') this.methods.unshift('HEAD');
29+
if (this.methods[l - 1] === 'GET') this.methods.unshift('HEAD');
3030
}
3131

3232
// ensure middleware is a function
@@ -68,10 +68,10 @@ Layer.prototype.match = function (path) {
6868
Layer.prototype.params = function (path, captures, existingParams) {
6969
const params = existingParams || {};
7070

71-
for (let len = captures.length, i=0; i<len; i++) {
71+
for (let len = captures.length, i = 0; i < len; i++) {
7272
if (this.paramNames[i]) {
7373
const c = captures[i];
74-
params[this.paramNames[i].name] = c ? safeDecodeURIComponent(c) : c;
74+
if (c && c.length !== 0) params[this.paramNames[i].name] = c ? safeDecodeURIComponent(c) : c;
7575
}
7676
}
7777

@@ -125,7 +125,7 @@ Layer.prototype.url = function (params, options) {
125125
let replace = {};
126126

127127
if (args instanceof Array) {
128-
for (let len = tokens.length, i=0, j=0; i<len; i++) {
128+
for (let len = tokens.length, i = 0, j = 0; i < len; i++) {
129129
if (tokens[i].name) replace[tokens[i].name] = args[j++];
130130
}
131131
} else if (tokens.some(token => token.name)) {

‎test/lib/router.js

+453-425
Original file line numberDiff line numberDiff line change
@@ -80,43 +80,43 @@ describe('Router', function () {
8080
});
8181

8282
it('router can be accecced with ctx', function (done) {
83-
const app = new Koa();
84-
const router = new Router();
85-
router.get('home', '/', function (ctx) {
86-
ctx.body = {
87-
url: ctx.router.url('home')
88-
};
83+
const app = new Koa();
84+
const router = new Router();
85+
router.get('home', '/', function (ctx) {
86+
ctx.body = {
87+
url: ctx.router.url('home')
88+
};
89+
});
90+
app.use(router.routes());
91+
request(http.createServer(app.callback()))
92+
.get('/')
93+
.expect(200)
94+
.end(function (err, res) {
95+
if (err) return done(err);
96+
expect(res.body.url).to.eql("/");
97+
done();
8998
});
90-
app.use(router.routes());
91-
request(http.createServer(app.callback()))
92-
.get('/')
93-
.expect(200)
94-
.end(function (err, res) {
95-
if (err) return done(err);
96-
expect(res.body.url).to.eql("/");
97-
done();
98-
});
9999
});
100100

101-
it('registers multiple middleware for one route', function(done) {
101+
it('registers multiple middleware for one route', function (done) {
102102
const app = new Koa();
103103
const router = new Router();
104104

105-
router.get('/double', function(ctx, next) {
106-
return new Promise(function(resolve, reject) {
107-
setTimeout(function() {
108-
ctx.body = {message: 'Hello'};
105+
router.get('/double', function (ctx, next) {
106+
return new Promise(function (resolve, reject) {
107+
setTimeout(function () {
108+
ctx.body = { message: 'Hello' };
109109
resolve(next());
110110
}, 1);
111111
});
112-
}, function(ctx, next) {
113-
return new Promise(function(resolve, reject) {
114-
setTimeout(function() {
112+
}, function (ctx, next) {
113+
return new Promise(function (resolve, reject) {
114+
setTimeout(function () {
115115
ctx.body.message += ' World';
116116
resolve(next());
117117
}, 1);
118118
});
119-
}, function(ctx, next) {
119+
}, function (ctx, next) {
120120
ctx.body.message += '!';
121121
});
122122

@@ -174,7 +174,7 @@ describe('Router', function () {
174174
const router = Router();
175175
router.get('/async', function (ctx, next) {
176176
return new Promise(function (resolve, reject) {
177-
setTimeout(function() {
177+
setTimeout(function () {
178178
ctx.body = {
179179
msg: 'promises!'
180180
};
@@ -436,23 +436,23 @@ describe('Router', function () {
436436
});
437437
const server = http.createServer(app.callback());
438438
request(server)
439-
.get('/programming/how-to-node')
440-
.expect(204)
441-
.end(function (err, res) {
442-
if (err) return done(err);
443-
request(server)
444-
.post('/programming')
439+
.get('/programming/how-to-node')
445440
.expect(204)
446441
.end(function (err, res) {
447442
if (err) return done(err);
448443
request(server)
449-
.put('/programming/not-a-title')
444+
.post('/programming')
450445
.expect(204)
451446
.end(function (err, res) {
452-
done(err);
447+
if (err) return done(err);
448+
request(server)
449+
.put('/programming/not-a-title')
450+
.expect(204)
451+
.end(function (err, res) {
452+
done(err);
453+
});
453454
});
454455
});
455-
});
456456
});
457457

458458
it('matches corresponding requests with optional route parameter', function (done) {
@@ -474,23 +474,23 @@ describe('Router', function () {
474474
});
475475
const server = http.createServer(app.callback());
476476
request(server)
477-
.get('/resources')
478-
.expect(204)
479-
.end(function (err, res) {
480-
if (err) return done(err);
481-
request(server)
482-
.get('/resources/' + id)
477+
.get('/resources')
483478
.expect(204)
484479
.end(function (err, res) {
485480
if (err) return done(err);
486481
request(server)
487-
.get('/resources/' + id + ext)
482+
.get('/resources/' + id)
488483
.expect(204)
489484
.end(function (err, res) {
490-
done(err);
485+
if (err) return done(err);
486+
request(server)
487+
.get('/resources/' + id + ext)
488+
.expect(204)
489+
.end(function (err, res) {
490+
done(err);
491+
});
491492
});
492493
});
493-
});
494494
});
495495

496496
it('executes route middleware using `app.context`', function (done) {
@@ -514,11 +514,11 @@ describe('Router', function () {
514514
done();
515515
});
516516
request(http.createServer(app.callback()))
517-
.get('/match/this')
518-
.expect(204)
519-
.end(function (err) {
520-
if (err) return done(err);
521-
});
517+
.get('/match/this')
518+
.expect(204)
519+
.end(function (err) {
520+
if (err) return done(err);
521+
});
522522
});
523523

524524
it('does not match after ctx.throw()', function (done) {
@@ -534,14 +534,14 @@ describe('Router', function () {
534534
counter++;
535535
});
536536
const server = http.createServer(app.callback());
537-
request(server)
537+
request(server)
538538
.get('/')
539539
.expect(403)
540540
.end(function (err, res) {
541541
if (err) return done(err);
542542
counter.should.equal(1);
543543
done();
544-
});
544+
});
545545
});
546546

547547
it('supports promises for route middleware', function (done) {
@@ -566,9 +566,9 @@ describe('Router', function () {
566566
});
567567
});
568568
request(http.createServer(app.callback()))
569-
.get('/')
570-
.expect(204)
571-
.end(done);
569+
.get('/')
570+
.expect(204)
571+
.end(done);
572572
});
573573

574574
describe('Router#allowedMethods()', function () {
@@ -577,35 +577,35 @@ describe('Router', function () {
577577
const router = new Router();
578578
app.use(router.routes());
579579
app.use(router.allowedMethods());
580-
router.get('/users', function (ctx, next) {});
581-
router.put('/users', function (ctx, next) {});
580+
router.get('/users', function (ctx, next) { });
581+
router.put('/users', function (ctx, next) { });
582582
request(http.createServer(app.callback()))
583-
.options('/users')
584-
.expect(200)
585-
.end(function (err, res) {
586-
if (err) return done(err);
587-
res.header.should.have.property('content-length', '0');
588-
res.header.should.have.property('allow', 'HEAD, GET, PUT');
589-
done();
590-
});
583+
.options('/users')
584+
.expect(200)
585+
.end(function (err, res) {
586+
if (err) return done(err);
587+
res.header.should.have.property('content-length', '0');
588+
res.header.should.have.property('allow', 'HEAD, GET, PUT');
589+
done();
590+
});
591591
});
592592

593593
it('responds with 405 Method Not Allowed', function (done) {
594594
const app = new Koa();
595595
const router = new Router();
596-
router.get('/users', function () {});
597-
router.put('/users', function () {});
598-
router.post('/events', function () {});
596+
router.get('/users', function () { });
597+
router.put('/users', function () { });
598+
router.post('/events', function () { });
599599
app.use(router.routes());
600600
app.use(router.allowedMethods());
601601
request(http.createServer(app.callback()))
602-
.post('/users')
603-
.expect(405)
604-
.end(function (err, res) {
605-
if (err) return done(err);
606-
res.header.should.have.property('allow', 'HEAD, GET, PUT');
607-
done();
608-
});
602+
.post('/users')
603+
.expect(405)
604+
.end(function (err, res) {
605+
if (err) return done(err);
606+
res.header.should.have.property('allow', 'HEAD, GET, PUT');
607+
done();
608+
});
609609
});
610610

611611
it('responds with 405 Method Not Allowed using the "throw" option', function (done) {
@@ -624,18 +624,18 @@ describe('Router', function () {
624624
});
625625
});
626626
app.use(router.allowedMethods({ throw: true }));
627-
router.get('/users', function () {});
628-
router.put('/users', function () {});
629-
router.post('/events', function () {});
627+
router.get('/users', function () { });
628+
router.put('/users', function () { });
629+
router.post('/events', function () { });
630630
request(http.createServer(app.callback()))
631-
.post('/users')
632-
.expect(405)
633-
.end(function (err, res) {
634-
if (err) return done(err);
635-
// the 'Allow' header is not set when throwing
636-
res.header.should.not.have.property('allow');
637-
done();
638-
});
631+
.post('/users')
632+
.expect(405)
633+
.end(function (err, res) {
634+
if (err) return done(err);
635+
// the 'Allow' header is not set when throwing
636+
res.header.should.not.have.property('allow');
637+
done();
638+
});
639639
});
640640

641641
it('responds with user-provided throwable using the "throw" and "methodNotAllowed" options', function (done) {
@@ -667,38 +667,39 @@ describe('Router', function () {
667667
return notAllowedErr;
668668
}
669669
}));
670-
router.get('/users', function () {});
671-
router.put('/users', function () {});
672-
router.post('/events', function () {});
670+
router.get('/users', function () { });
671+
router.put('/users', function () { });
672+
router.post('/events', function () { });
673673
request(http.createServer(app.callback()))
674-
.post('/users')
675-
.expect(405)
676-
.end(function (err, res) {
677-
if (err) return done(err);
678-
// the 'Allow' header is not set when throwing
679-
res.header.should.not.have.property('allow');
680-
res.body.should.eql({ error: 'Custom Not Allowed Error',
681-
statusCode: 405,
682-
otherStuff: true
674+
.post('/users')
675+
.expect(405)
676+
.end(function (err, res) {
677+
if (err) return done(err);
678+
// the 'Allow' header is not set when throwing
679+
res.header.should.not.have.property('allow');
680+
res.body.should.eql({
681+
error: 'Custom Not Allowed Error',
682+
statusCode: 405,
683+
otherStuff: true
684+
});
685+
done();
683686
});
684-
done();
685-
});
686687
});
687688

688689
it('responds with 501 Not Implemented', function (done) {
689690
const app = new Koa();
690691
const router = new Router();
691692
app.use(router.routes());
692693
app.use(router.allowedMethods());
693-
router.get('/users', function () {});
694-
router.put('/users', function () {});
694+
router.get('/users', function () { });
695+
router.put('/users', function () { });
695696
request(http.createServer(app.callback()))
696-
.search('/users')
697-
.expect(501)
698-
.end(function (err, res) {
699-
if (err) return done(err);
700-
done();
701-
});
697+
.search('/users')
698+
.expect(501)
699+
.end(function (err, res) {
700+
if (err) return done(err);
701+
done();
702+
});
702703
});
703704

704705
it('responds with 501 Not Implemented using the "throw" option', function (done) {
@@ -717,17 +718,17 @@ describe('Router', function () {
717718
});
718719
});
719720
app.use(router.allowedMethods({ throw: true }));
720-
router.get('/users', function () {});
721-
router.put('/users', function () {});
721+
router.get('/users', function () { });
722+
router.put('/users', function () { });
722723
request(http.createServer(app.callback()))
723-
.search('/users')
724-
.expect(501)
725-
.end(function (err, res) {
726-
if (err) return done(err);
727-
// the 'Allow' header is not set when throwing
728-
res.header.should.not.have.property('allow');
729-
done();
730-
});
724+
.search('/users')
725+
.expect(501)
726+
.end(function (err, res) {
727+
if (err) return done(err);
728+
// the 'Allow' header is not set when throwing
729+
res.header.should.not.have.property('allow');
730+
done();
731+
});
731732
});
732733

733734
it('responds with user-provided throwable using the "throw" and "notImplemented" options', function (done) {
@@ -760,21 +761,22 @@ describe('Router', function () {
760761
return notImplementedErr;
761762
}
762763
}));
763-
router.get('/users', function () {});
764-
router.put('/users', function () {});
764+
router.get('/users', function () { });
765+
router.put('/users', function () { });
765766
request(http.createServer(app.callback()))
766-
.search('/users')
767-
.expect(501)
768-
.end(function (err, res) {
769-
if (err) return done(err);
770-
// the 'Allow' header is not set when throwing
771-
res.header.should.not.have.property('allow');
772-
res.body.should.eql({ error: 'Custom Not Implemented Error',
773-
statusCode: 501,
774-
otherStuff: true
767+
.search('/users')
768+
.expect(501)
769+
.end(function (err, res) {
770+
if (err) return done(err);
771+
// the 'Allow' header is not set when throwing
772+
res.header.should.not.have.property('allow');
773+
res.body.should.eql({
774+
error: 'Custom Not Implemented Error',
775+
statusCode: 501,
776+
otherStuff: true
777+
});
778+
done();
775779
});
776-
done();
777-
});
778780
});
779781

780782
it('does not send 405 if route matched but status is 404', function (done) {
@@ -786,12 +788,12 @@ describe('Router', function () {
786788
ctx.status = 404;
787789
});
788790
request(http.createServer(app.callback()))
789-
.get('/users')
790-
.expect(404)
791-
.end(function (err, res) {
792-
if (err) return done(err);
793-
done();
794-
});
791+
.get('/users')
792+
.expect(404)
793+
.end(function (err, res) {
794+
if (err) return done(err);
795+
done();
796+
});
795797
});
796798

797799
it('sets the allowed methods to a single Allow header #273', function (done) {
@@ -801,7 +803,7 @@ describe('Router', function () {
801803
app.use(router.routes());
802804
app.use(router.allowedMethods());
803805

804-
router.get('/', function (ctx, next) {});
806+
router.get('/', function (ctx, next) { });
805807

806808
request(http.createServer(app.callback()))
807809
.options('/')
@@ -845,34 +847,34 @@ describe('Router', function () {
845847
});
846848

847849
request(http.createServer(app.callback()))
848-
.get('/users')
849-
.set('Host', 'helloworld.example.com')
850-
.expect(200)
851-
.expect('GET /users', done);
850+
.get('/users')
851+
.set('Host', 'helloworld.example.com')
852+
.expect(200)
853+
.expect('GET /users', done);
852854
});
853855

854856
it("parameter added to request in ctx", function (done) {
855-
const app = new Koa();
856-
const router = new Router();
857-
router.get("/echo/:saying", function (ctx) {
858-
try {
859-
expect(ctx.params.saying).eql("helloWorld");
860-
expect(ctx.request.params.saying).eql("helloWorld");
861-
ctx.body = { echo: ctx.params.saying };
862-
} catch(err) {
863-
ctx.status = 500;
864-
ctx.body = err.message;
865-
}
857+
const app = new Koa();
858+
const router = new Router();
859+
router.get("/echo/:saying", function (ctx) {
860+
try {
861+
expect(ctx.params.saying).eql("helloWorld");
862+
expect(ctx.request.params.saying).eql("helloWorld");
863+
ctx.body = { echo: ctx.params.saying };
864+
} catch (err) {
865+
ctx.status = 500;
866+
ctx.body = err.message;
867+
}
868+
});
869+
app.use(router.routes());
870+
request(http.createServer(app.callback()))
871+
.get("/echo/helloWorld")
872+
.expect(200)
873+
.end(function (err, res) {
874+
if (err) return done(err);
875+
expect(res.body).to.eql({ echo: "helloWorld" });
876+
done();
866877
});
867-
app.use(router.routes());
868-
request(http.createServer(app.callback()))
869-
.get("/echo/helloWorld")
870-
.expect(200)
871-
.end(function (err, res) {
872-
if (err) return done(err);
873-
expect(res.body).to.eql({ echo: "helloWorld" });
874-
done();
875-
});
876878
});
877879

878880
it("parameter added to request in ctx with sub router", function (done) {
@@ -891,7 +893,7 @@ describe('Router', function () {
891893
expect(ctx.params.saying).eql("helloWorld");
892894
expect(ctx.request.params.saying).eql("helloWorld");
893895
ctx.body = { echo: ctx.params.saying };
894-
} catch(err) {
896+
} catch (err) {
895897
ctx.status = 500;
896898
ctx.body = err.message;
897899
}
@@ -901,12 +903,12 @@ describe('Router', function () {
901903
app.use(router.routes());
902904
request(http.createServer(app.callback()))
903905
.get('/echo/helloWorld')
904-
.expect(200)
905-
.end(function (err, res) {
906-
if (err) return done(err);
907-
expect(res.body).to.eql({ echo: "helloWorld" });
908-
done();
909-
});
906+
.expect(200)
907+
.end(function (err, res) {
908+
if (err) return done(err);
909+
expect(res.body).to.eql({ echo: "helloWorld" });
910+
done();
911+
});
910912
});
911913

912914
describe('Router#[verb]()', function () {
@@ -917,36 +919,36 @@ describe('Router', function () {
917919
methods.forEach(function (method) {
918920
router.should.have.property(method);
919921
router[method].should.be.type('function');
920-
router[method]('/', function () {});
922+
router[method]('/', function () { });
921923
});
922924
router.stack.should.have.length(methods.length);
923925
});
924926

925927
it('registers route with a regexp path', function () {
926928
const router = new Router();
927929
methods.forEach(function (method) {
928-
router[method](/^\/\w$/i, function () {}).should.equal(router);
930+
router[method](/^\/\w$/i, function () { }).should.equal(router);
929931
});
930932
});
931933

932934
it('registers route with a given name', function () {
933935
const router = new Router();
934936
methods.forEach(function (method) {
935-
router[method](method, '/', function () {}).should.equal(router);
937+
router[method](method, '/', function () { }).should.equal(router);
936938
});
937939
});
938940

939941
it('registers route with with a given name and regexp path', function () {
940942
const router = new Router();
941943
methods.forEach(function (method) {
942-
router[method](method, /^\/$/i, function () {}).should.equal(router);
944+
router[method](method, /^\/$/i, function () { }).should.equal(router);
943945
});
944946
});
945947

946948
it('enables route chaining', function () {
947949
const router = new Router();
948950
methods.forEach(function (method) {
949-
router[method]('/', function () {}).should.equal(router);
951+
router[method]('/', function () { }).should.equal(router);
950952
});
951953
});
952954

@@ -960,7 +962,7 @@ describe('Router', function () {
960962
expect(router.stack[1]).to.have.property('path', '/two');
961963
});
962964

963-
it('resolves non-parameterized routes without attached parameters', function(done) {
965+
it('resolves non-parameterized routes without attached parameters', function (done) {
964966
const app = new Koa();
965967
const router = new Router();
966968

@@ -1128,11 +1130,11 @@ describe('Router', function () {
11281130
const app = new Koa();
11291131
const router = new Router();
11301132

1131-
router.use(function(ctx, next) {
1133+
router.use(function (ctx, next) {
11321134
return next();
11331135
});
11341136

1135-
router.get('/foo/:id', function(ctx) {
1137+
router.get('/foo/:id', function (ctx) {
11361138
ctx.body = ctx.params;
11371139
});
11381140

@@ -1210,7 +1212,7 @@ describe('Router', function () {
12101212
.expect(200);
12111213
})).then((resList) => {
12121214
resList.forEach(res => {
1213-
assert.deepEqual(res.body, {foo: 'foo', bar: 'bar', baz: 'baz' });
1215+
assert.deepEqual(res.body, { foo: 'foo', bar: 'bar', baz: 'baz' });
12141216
});
12151217

12161218
done();
@@ -1252,7 +1254,7 @@ describe('Router', function () {
12521254
.expect(200);
12531255
})).then((resList) => {
12541256
resList.forEach(res => {
1255-
assert.deepEqual(res.body, {foo: 'foo', bar: 'bar', baz: 'baz' });
1257+
assert.deepEqual(res.body, { foo: 'foo', bar: 'bar', baz: 'baz' });
12561258
});
12571259

12581260
done();
@@ -1266,7 +1268,7 @@ describe('Router', function () {
12661268
const router = new Router();
12671269
router.should.have.property('register');
12681270
router.register.should.be.type('function');
1269-
const route = router.register('/', ['GET', 'POST'], function () {});
1271+
const route = router.register('/', ['GET', 'POST'], function () { });
12701272
app.use(router.routes());
12711273
router.stack.should.be.an.instanceOf(Array);
12721274
router.stack.should.have.property('length', 1);
@@ -1293,8 +1295,8 @@ describe('Router', function () {
12931295
const app = new Koa();
12941296
const router = new Router();
12951297
app.use(router.routes());
1296-
router.get('home', '/', function () {});
1297-
router.get('sign-up-form', '/sign-up-form', function () {});
1298+
router.get('home', '/', function () { });
1299+
router.get('sign-up-form', '/sign-up-form', function () { });
12981300
router.redirect('home', 'sign-up-form');
12991301
request(http.createServer(app.callback()))
13001302
.post('/')
@@ -1377,30 +1379,30 @@ describe('Router', function () {
13771379
});
13781380

13791381
it('generates URL for given route name within embedded routers', function (done) {
1380-
const app = new Koa();
1381-
const router = new Router({
1382-
prefix: "/books"
1383-
});
1382+
const app = new Koa();
1383+
const router = new Router({
1384+
prefix: "/books"
1385+
});
13841386

1385-
const embeddedRouter = new Router({
1386-
prefix: "/chapters"
1387-
});
1388-
embeddedRouter.get('chapters', '/:chapterName/:pageNumber', function (ctx) {
1389-
ctx.status = 204;
1390-
});
1391-
router.use(embeddedRouter.routes());
1392-
app.use(router.routes());
1393-
let url = router.url(
1394-
'chapters',
1395-
{ chapterName: 'Learning ECMA6', pageNumber: 123 },
1396-
{ encode: encodeURIComponent }
1397-
);
1398-
url.should.equal('/books/chapters/Learning%20ECMA6/123');
1399-
url = router.url('chapters', 'Learning ECMA6', 123, {
1400-
encode: encodeURIComponent,
1401-
});
1402-
url.should.equal('/books/chapters/Learning%20ECMA6/123');
1403-
done();
1387+
const embeddedRouter = new Router({
1388+
prefix: "/chapters"
1389+
});
1390+
embeddedRouter.get('chapters', '/:chapterName/:pageNumber', function (ctx) {
1391+
ctx.status = 204;
1392+
});
1393+
router.use(embeddedRouter.routes());
1394+
app.use(router.routes());
1395+
let url = router.url(
1396+
'chapters',
1397+
{ chapterName: 'Learning ECMA6', pageNumber: 123 },
1398+
{ encode: encodeURIComponent }
1399+
);
1400+
url.should.equal('/books/chapters/Learning%20ECMA6/123');
1401+
url = router.url('chapters', 'Learning ECMA6', 123, {
1402+
encode: encodeURIComponent,
1403+
});
1404+
url.should.equal('/books/chapters/Learning%20ECMA6/123');
1405+
done();
14041406
});
14051407

14061408
it('generates URL for given route name within two embedded routers', function (done) {
@@ -1429,71 +1431,71 @@ describe('Router', function () {
14291431
done();
14301432
});
14311433

1432-
it('generates URL for given route name with params and query params', function(done) {
1433-
const app = new Koa();
1434-
const router = new Router();
1435-
router.get('books', '/books/:category/:id', function (ctx) {
1436-
ctx.status = 204;
1437-
});
1438-
let url = router.url('books', 'programming', 4, {
1439-
query: { page: 3, limit: 10 }
1440-
});
1441-
url.should.equal('/books/programming/4?page=3&limit=10');
1442-
url = router.url('books',
1443-
{ category: 'programming', id: 4 },
1444-
{ query: { page: 3, limit: 10 }}
1445-
);
1446-
url.should.equal('/books/programming/4?page=3&limit=10');
1447-
url = router.url('books',
1448-
{ category: 'programming', id: 4 },
1449-
{ query: 'page=3&limit=10' }
1450-
);
1451-
url.should.equal('/books/programming/4?page=3&limit=10');
1452-
done();
1434+
it('generates URL for given route name with params and query params', function (done) {
1435+
const app = new Koa();
1436+
const router = new Router();
1437+
router.get('books', '/books/:category/:id', function (ctx) {
1438+
ctx.status = 204;
1439+
});
1440+
let url = router.url('books', 'programming', 4, {
1441+
query: { page: 3, limit: 10 }
1442+
});
1443+
url.should.equal('/books/programming/4?page=3&limit=10');
1444+
url = router.url('books',
1445+
{ category: 'programming', id: 4 },
1446+
{ query: { page: 3, limit: 10 } }
1447+
);
1448+
url.should.equal('/books/programming/4?page=3&limit=10');
1449+
url = router.url('books',
1450+
{ category: 'programming', id: 4 },
1451+
{ query: 'page=3&limit=10' }
1452+
);
1453+
url.should.equal('/books/programming/4?page=3&limit=10');
1454+
done();
14531455
})
14541456

1455-
it('generates URL for given route name without params and query params', function(done) {
1456-
var router = new Router();
1457-
router.get('books', '/books', function (ctx) {
1458-
ctx.status = 204;
1459-
});
1460-
var url = router.url('books');
1461-
url.should.equal('/books');
1462-
var url = router.url('books');
1463-
url.should.equal('/books', {});
1464-
var url = router.url('books');
1465-
url.should.equal('/books', {}, {});
1466-
var url = router.url('books',
1467-
{},
1468-
{ query: { page: 3, limit: 10 } }
1469-
);
1470-
url.should.equal('/books?page=3&limit=10');
1471-
var url = router.url('books',
1472-
{},
1473-
{ query: 'page=3&limit=10' }
1474-
);
1475-
url.should.equal('/books?page=3&limit=10');
1476-
done();
1457+
it('generates URL for given route name without params and query params', function (done) {
1458+
var router = new Router();
1459+
router.get('books', '/books', function (ctx) {
1460+
ctx.status = 204;
1461+
});
1462+
var url = router.url('books');
1463+
url.should.equal('/books');
1464+
var url = router.url('books');
1465+
url.should.equal('/books', {});
1466+
var url = router.url('books');
1467+
url.should.equal('/books', {}, {});
1468+
var url = router.url('books',
1469+
{},
1470+
{ query: { page: 3, limit: 10 } }
1471+
);
1472+
url.should.equal('/books?page=3&limit=10');
1473+
var url = router.url('books',
1474+
{},
1475+
{ query: 'page=3&limit=10' }
1476+
);
1477+
url.should.equal('/books?page=3&limit=10');
1478+
done();
14771479
})
14781480

14791481

1480-
it('generates URL for given route name without params and query params', function(done) {
1481-
var router = new Router();
1482-
router.get('category', '/category', function (ctx) {
1483-
ctx.status = 204;
1484-
});
1485-
const url = router.url('category', {
1486-
query: { page: 3, limit: 10 }
1487-
});
1488-
url.should.equal('/category?page=3&limit=10');
1489-
done();
1482+
it('generates URL for given route name without params and query params', function (done) {
1483+
var router = new Router();
1484+
router.get('category', '/category', function (ctx) {
1485+
ctx.status = 204;
1486+
});
1487+
const url = router.url('category', {
1488+
query: { page: 3, limit: 10 }
1489+
});
1490+
url.should.equal('/category?page=3&limit=10');
1491+
done();
14901492
})
14911493

1492-
it("should test Error flow if no route is found for name", function() {
1494+
it("should test Error flow if no route is found for name", function () {
14931495
const app = new Koa();
14941496
const router = new Router();
14951497
app.use(router.routes());
1496-
router.get("books", "/:category/:title", function(ctx) {
1498+
router.get("books", "/:category/:title", function (ctx) {
14971499
ctx.status = 204;
14981500
});
14991501

@@ -1556,24 +1558,24 @@ describe('Router', function () {
15561558
app
15571559
.use(router.routes())
15581560
.callback()))
1559-
.get('/first/users/3')
1560-
.expect(200)
1561-
.end(function (err, res) {
1562-
if (err) return done(err);
1563-
res.should.have.property('body');
1564-
res.body.should.have.property('name', 'alex');
1565-
res.body.should.have.property('ordered', 'parameters');
1566-
done();
1567-
});
1561+
.get('/first/users/3')
1562+
.expect(200)
1563+
.end(function (err, res) {
1564+
if (err) return done(err);
1565+
res.should.have.property('body');
1566+
res.body.should.have.property('name', 'alex');
1567+
res.body.should.have.property('ordered', 'parameters');
1568+
done();
1569+
});
15681570
});
15691571

1570-
it('runs parameter middleware in order of URL appearance even when added in random order', function(done) {
1572+
it('runs parameter middleware in order of URL appearance even when added in random order', function (done) {
15711573
const app = new Koa();
15721574
const router = new Router();
15731575
router
15741576
// intentional random order
15751577
.param('a', function (id, ctx, next) {
1576-
ctx.state.loaded = [ id ];
1578+
ctx.state.loaded = [id];
15771579
return next();
15781580
})
15791581
.param('d', function (id, ctx, next) {
@@ -1596,14 +1598,14 @@ describe('Router', function () {
15961598
app
15971599
.use(router.routes())
15981600
.callback()))
1599-
.get('/1/2/3/4')
1600-
.expect(200)
1601-
.end(function(err, res) {
1602-
if (err) return done(err);
1603-
res.should.have.property('body');
1604-
res.body.should.eql([ '1', '2', '3', '4' ]);
1605-
done();
1606-
});
1601+
.get('/1/2/3/4')
1602+
.expect(200)
1603+
.end(function (err, res) {
1604+
if (err) return done(err);
1605+
res.should.have.property('body');
1606+
res.body.should.eql(['1', '2', '3', '4']);
1607+
done();
1608+
});
16071609
});
16081610

16091611
it('runs parent parameter middleware for subrouter', function (done) {
@@ -1625,15 +1627,15 @@ describe('Router', function () {
16251627
.use('/:id/children', subrouter.routes());
16261628

16271629
request(http.createServer(app.use(router.routes()).callback()))
1628-
.get('/did-not-run/children/2')
1629-
.expect(200)
1630-
.end(function (err, res) {
1631-
if (err) return done(err);
1632-
res.should.have.property('body');
1633-
res.body.should.have.property('id', 'ran');
1634-
res.body.should.have.property('cid', '2');
1635-
done();
1636-
});
1630+
.get('/did-not-run/children/2')
1631+
.expect(200)
1632+
.end(function (err, res) {
1633+
if (err) return done(err);
1634+
res.should.have.property('body');
1635+
res.body.should.have.property('id', 'ran');
1636+
res.body.should.have.property('cid', '2');
1637+
done();
1638+
});
16371639
});
16381640
});
16391641

@@ -1650,13 +1652,13 @@ describe('Router', function () {
16501652
app
16511653
.use(router.routes())
16521654
.callback()))
1653-
.get('/info')
1654-
.expect(200)
1655-
.end(function (err, res) {
1656-
if (err) return done(err);
1657-
res.text.should.equal('hello');
1658-
done();
1659-
});
1655+
.get('/info')
1656+
.expect(200)
1657+
.end(function (err, res) {
1658+
if (err) return done(err);
1659+
res.text.should.equal('hello');
1660+
done();
1661+
});
16601662
});
16611663

16621664
it('should allow setting a prefix', function (done) {
@@ -1691,12 +1693,12 @@ describe('Router', function () {
16911693
app
16921694
.use(router.routes())
16931695
.callback()))
1694-
.get('/info/')
1695-
.expect(404)
1696-
.end(function (err, res) {
1697-
if (err) return done(err);
1698-
done();
1699-
});
1696+
.get('/info/')
1697+
.expect(404)
1698+
.end(function (err, res) {
1699+
if (err) return done(err);
1700+
done();
1701+
});
17001702
});
17011703
});
17021704

@@ -1713,13 +1715,13 @@ describe('Router', function () {
17131715
app
17141716
.use(router.routes())
17151717
.callback()))
1716-
.get('/info')
1717-
.expect(200)
1718-
.end(function (err, res) {
1719-
if (err) return done(err);
1720-
res.text.should.equal('hello');
1721-
done();
1722-
});
1718+
.get('/info')
1719+
.expect(200)
1720+
.end(function (err, res) {
1721+
if (err) return done(err);
1722+
res.text.should.equal('hello');
1723+
done();
1724+
});
17231725
});
17241726

17251727
it('responds with 404 when has a trailing slash', function (done) {
@@ -1734,12 +1736,12 @@ describe('Router', function () {
17341736
app
17351737
.use(router.routes())
17361738
.callback()))
1737-
.get('/info/')
1738-
.expect(404)
1739-
.end(function (err, res) {
1740-
if (err) return done(err);
1741-
done();
1742-
});
1739+
.get('/info/')
1740+
.expect(404)
1741+
.end(function (err, res) {
1742+
if (err) return done(err);
1743+
done();
1744+
});
17431745
});
17441746
});
17451747

@@ -1771,18 +1773,18 @@ describe('Router', function () {
17711773
app
17721774
.use(routerMiddleware)
17731775
.callback()))
1774-
.get('/users/1')
1775-
.expect(200)
1776-
.end(function (err, res) {
1777-
if (err) return done(err);
1778-
expect(res.body).to.be.an('object');
1779-
expect(res.body).to.have.property('hello', 'world');
1780-
expect(middlewareCount).to.equal(2);
1781-
done();
1782-
});
1776+
.get('/users/1')
1777+
.expect(200)
1778+
.end(function (err, res) {
1779+
if (err) return done(err);
1780+
expect(res.body).to.be.an('object');
1781+
expect(res.body).to.have.property('hello', 'world');
1782+
expect(middlewareCount).to.equal(2);
1783+
done();
1784+
});
17831785
});
17841786

1785-
it('places a `_matchedRoute` value on context', function(done) {
1787+
it('places a `_matchedRoute` value on context', function (done) {
17861788
const app = new Koa();
17871789
const router = new Router();
17881790
const middleware = function (ctx, next) {
@@ -1803,15 +1805,15 @@ describe('Router', function () {
18031805
app
18041806
.use(routerMiddleware)
18051807
.callback()))
1806-
.get('/users/1')
1807-
.expect(200)
1808-
.end(function(err, res) {
1809-
if (err) return done(err);
1810-
done();
1811-
});
1808+
.get('/users/1')
1809+
.expect(200)
1810+
.end(function (err, res) {
1811+
if (err) return done(err);
1812+
done();
1813+
});
18121814
});
18131815

1814-
it('places a `_matchedRouteName` value on the context for a named route', function(done) {
1816+
it('places a `_matchedRouteName` value on the context for a named route', function (done) {
18151817
const app = new Koa();
18161818
const router = new Router();
18171819

@@ -1821,15 +1823,15 @@ describe('Router', function () {
18211823
});
18221824

18231825
request(http.createServer(app.use(router.routes()).callback()))
1824-
.get('/users/1')
1825-
.expect(200)
1826-
.end(function(err, res) {
1827-
if (err) return done(err);
1828-
done();
1829-
});
1826+
.get('/users/1')
1827+
.expect(200)
1828+
.end(function (err, res) {
1829+
if (err) return done(err);
1830+
done();
1831+
});
18301832
});
18311833

1832-
it('does not place a `_matchedRouteName` value on the context for unnamed routes', function(done) {
1834+
it('does not place a `_matchedRouteName` value on the context for unnamed routes', function (done) {
18331835
const app = new Koa();
18341836
const router = new Router();
18351837

@@ -1839,15 +1841,15 @@ describe('Router', function () {
18391841
});
18401842

18411843
request(http.createServer(app.use(router.routes()).callback()))
1842-
.get('/users/1')
1843-
.expect(200)
1844-
.end(function(err, res) {
1845-
if (err) return done(err);
1846-
done();
1847-
});
1844+
.get('/users/1')
1845+
.expect(200)
1846+
.end(function (err, res) {
1847+
if (err) return done(err);
1848+
done();
1849+
});
18481850
});
18491851

1850-
it('places a `routerPath` value on the context for current route', function(done) {
1852+
it('places a `routerPath` value on the context for current route', function (done) {
18511853
const app = new Koa();
18521854
const router = new Router();
18531855

@@ -1859,13 +1861,13 @@ describe('Router', function () {
18591861
request(http.createServer(app.use(router.routes()).callback()))
18601862
.get('/users/1')
18611863
.expect(200)
1862-
.end(function(err, res) {
1864+
.end(function (err, res) {
18631865
if (err) return done(err);
18641866
done();
18651867
});
18661868
});
18671869

1868-
it('places a `_matchedRoute` value on the context for current route', function(done) {
1870+
it('places a `_matchedRoute` value on the context for current route', function (done) {
18691871
const app = new Koa();
18701872
const router = new Router();
18711873

@@ -1881,7 +1883,7 @@ describe('Router', function () {
18811883
request(http.createServer(app.use(router.routes()).callback()))
18821884
.get('/users/list')
18831885
.expect(200)
1884-
.end(function(err, res) {
1886+
.end(function (err, res) {
18851887
if (err) return done(err);
18861888
done();
18871889
});
@@ -1900,13 +1902,13 @@ describe('Router', function () {
19001902
app
19011903
.use(router.routes())
19021904
.callback()))
1903-
.head('/users/1')
1904-
.expect(200)
1905-
.end(function (err, res) {
1906-
if (err) return done(err);
1907-
expect(res.body).to.be.empty();
1908-
done();
1909-
});
1905+
.head('/users/1')
1906+
.expect(200)
1907+
.end(function (err, res) {
1908+
if (err) return done(err);
1909+
expect(res.body).to.be.empty();
1910+
done();
1911+
});
19101912
});
19111913

19121914
it('should work with middleware', function (done) {
@@ -1920,13 +1922,13 @@ describe('Router', function () {
19201922
app
19211923
.use(router.routes())
19221924
.callback()))
1923-
.head('/users/1')
1924-
.expect(200)
1925-
.end(function (err, res) {
1926-
if (err) return done(err);
1927-
expect(res.body).to.be.empty();
1928-
done();
1929-
});
1925+
.head('/users/1')
1926+
.expect(200)
1927+
.end(function (err, res) {
1928+
if (err) return done(err);
1929+
expect(res.body).to.be.empty();
1930+
done();
1931+
});
19301932
});
19311933
});
19321934

@@ -1952,7 +1954,7 @@ describe('Router', function () {
19521954
});
19531955

19541956

1955-
it('populates ctx.params correctly for router prefix (including use)', function(done) {
1957+
it('populates ctx.params correctly for router prefix (including use)', function (done) {
19561958
var app = new Koa();
19571959
var router = new Router({ prefix: '/:category' });
19581960
app.use(router.routes());
@@ -1963,7 +1965,7 @@ describe('Router', function () {
19631965
ctx.params.should.have.property('category', 'cats');
19641966
return next();
19651967
})
1966-
.get('/suffixHere', function(ctx) {
1968+
.get('/suffixHere', function (ctx) {
19671969
ctx.should.have.property('params');
19681970
ctx.params.should.be.type('object');
19691971
ctx.params.should.have.property('category', 'cats');
@@ -1972,13 +1974,13 @@ describe('Router', function () {
19721974
request(http.createServer(app.callback()))
19731975
.get('/cats/suffixHere')
19741976
.expect(204)
1975-
.end(function(err, res) {
1977+
.end(function (err, res) {
19761978
if (err) return done(err);
19771979
done();
19781980
});
19791981
});
19801982

1981-
it('populates ctx.params correctly for more complex router prefix (including use)', function(done) {
1983+
it('populates ctx.params correctly for more complex router prefix (including use)', function (done) {
19821984
var app = new Koa();
19831985
var router = new Router({ prefix: '/:category/:color' });
19841986
app.use(router.routes());
@@ -1990,7 +1992,7 @@ describe('Router', function () {
19901992
ctx.params.should.have.property('color', 'gray');
19911993
return next();
19921994
})
1993-
.get('/:active/suffixHere', function(ctx) {
1995+
.get('/:active/suffixHere', function (ctx) {
19941996
ctx.should.have.property('params');
19951997
ctx.params.should.be.type('object');
19961998
ctx.params.should.have.property('category', 'cats');
@@ -2001,13 +2003,39 @@ describe('Router', function () {
20012003
request(http.createServer(app.callback()))
20022004
.get('/cats/gray/true/suffixHere')
20032005
.expect(204)
2004-
.end(function(err, res) {
2006+
.end(function (err, res) {
2007+
if (err) return done(err);
2008+
done();
2009+
});
2010+
});
2011+
2012+
it('populates ctx.params correctly for dynamic and static prefix (including async use)', function (done) {
2013+
var app = new Koa();
2014+
var router = new Router({ prefix: '/:ping/pong' });
2015+
app.use(router.routes());
2016+
router
2017+
.use(async (ctx, next) => {
2018+
ctx.should.have.property('params');
2019+
ctx.params.should.be.type('object');
2020+
ctx.params.should.have.property('ping', 'pingKey');
2021+
await next();
2022+
})
2023+
.get('/', function (ctx) {
2024+
ctx.should.have.property('params');
2025+
ctx.params.should.be.type('object');
2026+
ctx.params.should.have.property('ping', 'pingKey');
2027+
ctx.body = ctx.params
2028+
});
2029+
request(http.createServer(app.callback()))
2030+
.get('/pingKey/pong')
2031+
.expect(200, /{"ping":"pingKey"}/)
2032+
.end(function (err, res) {
20052033
if (err) return done(err);
20062034
done();
20072035
});
20082036
});
20092037

2010-
it('populates ctx.params correctly for static prefix', function(done) {
2038+
it('populates ctx.params correctly for static prefix', function (done) {
20112039
var app = new Koa();
20122040
var router = new Router({ prefix: '/all' });
20132041
app.use(router.routes());
@@ -2018,7 +2046,7 @@ describe('Router', function () {
20182046
ctx.params.should.be.empty();
20192047
return next();
20202048
})
2021-
.get('/:active/suffixHere', function(ctx) {
2049+
.get('/:active/suffixHere', function (ctx) {
20222050
ctx.should.have.property('params');
20232051
ctx.params.should.be.type('object');
20242052
ctx.params.should.have.property('active', 'true');
@@ -2027,7 +2055,7 @@ describe('Router', function () {
20272055
request(http.createServer(app.callback()))
20282056
.get('/all/true/suffixHere')
20292057
.expect(204)
2030-
.end(function(err, res) {
2058+
.end(function (err, res) {
20312059
if (err) return done(err);
20322060
done();
20332061
});
@@ -2038,11 +2066,11 @@ describe('Router', function () {
20382066
const app = new Koa();
20392067
const router = new Router();
20402068

2041-
router.use(function(ctx, next) {
2069+
router.use(function (ctx, next) {
20422070
return next();
20432071
});
20442072

2045-
router.get('/foo/:id', function(ctx) {
2073+
router.get('/foo/:id', function (ctx) {
20462074
ctx.body = ctx.params;
20472075
});
20482076

@@ -2099,46 +2127,46 @@ describe('Router', function () {
20992127

21002128
it('should support root level router middleware', function (done) {
21012129
request(server)
2102-
.get(prefix)
2103-
.expect(200)
2104-
.end(function (err, res) {
2105-
if (err) return done(err);
2106-
expect(middlewareCount).to.equal(2);
2107-
expect(res.body).to.be.an('object');
2108-
expect(res.body).to.have.property('name', 'worked');
2109-
done();
2110-
});
2130+
.get(prefix)
2131+
.expect(200)
2132+
.end(function (err, res) {
2133+
if (err) return done(err);
2134+
expect(middlewareCount).to.equal(2);
2135+
expect(res.body).to.be.an('object');
2136+
expect(res.body).to.have.property('name', 'worked');
2137+
done();
2138+
});
21112139
});
21122140

21132141
it('should support requests with a trailing path slash', function (done) {
21142142
request(server)
2115-
.get('/admin/')
2116-
.expect(200)
2117-
.end(function (err, res) {
2118-
if (err) return done(err);
2119-
expect(middlewareCount).to.equal(2);
2120-
expect(res.body).to.be.an('object');
2121-
expect(res.body).to.have.property('name', 'worked');
2122-
done();
2123-
});
2143+
.get('/admin/')
2144+
.expect(200)
2145+
.end(function (err, res) {
2146+
if (err) return done(err);
2147+
expect(middlewareCount).to.equal(2);
2148+
expect(res.body).to.be.an('object');
2149+
expect(res.body).to.have.property('name', 'worked');
2150+
done();
2151+
});
21242152
});
21252153

21262154
it('should support requests without a trailing path slash', function (done) {
21272155
request(server)
2128-
.get('/admin')
2129-
.expect(200)
2130-
.end(function (err, res) {
2131-
if (err) return done(err);
2132-
expect(middlewareCount).to.equal(2);
2133-
expect(res.body).to.be.an('object');
2134-
expect(res.body).to.have.property('name', 'worked');
2135-
done();
2136-
});
2156+
.get('/admin')
2157+
.expect(200)
2158+
.end(function (err, res) {
2159+
if (err) return done(err);
2160+
expect(middlewareCount).to.equal(2);
2161+
expect(res.body).to.be.an('object');
2162+
expect(res.body).to.have.property('name', 'worked');
2163+
done();
2164+
});
21372165
});
21382166
}
21392167
}
21402168

2141-
it(`prefix and '/' route behavior`, function(done) {
2169+
it(`prefix and '/' route behavior`, function (done) {
21422170
const app = new Koa();
21432171
const router = new Router({
21442172
strict: false,
@@ -2150,11 +2178,11 @@ describe('Router', function () {
21502178
prefix: '/bar'
21512179
})
21522180

2153-
router.get('/', function(ctx) {
2181+
router.get('/', function (ctx) {
21542182
ctx.body = '';
21552183
});
21562184

2157-
strictRouter.get('/', function(ctx) {
2185+
strictRouter.get('/', function (ctx) {
21582186
ctx.body = '';
21592187
});
21602188

@@ -2196,8 +2224,8 @@ describe('Router', function () {
21962224

21972225
describe('Static Router#url()', function () {
21982226
it('generates route URL', function () {
2199-
const url = Router.url('/:category/:title', { category: 'programming', title: 'how-to-node' });
2200-
url.should.equal('/programming/how-to-node');
2227+
const url = Router.url('/:category/:title', { category: 'programming', title: 'how-to-node' });
2228+
url.should.equal('/programming/how-to-node');
22012229
});
22022230

22032231
it('escapes using encodeURIComponent()', function () {
@@ -2209,30 +2237,30 @@ describe('Router', function () {
22092237
url.should.equal('/programming/how%20to%20node');
22102238
});
22112239

2212-
it('generates route URL with params and query params', function(done) {
2213-
let url = Router.url('/books/:category/:id', 'programming', 4, {
2214-
query: { page: 3, limit: 10 }
2215-
});
2216-
url.should.equal('/books/programming/4?page=3&limit=10');
2217-
url = Router.url('/books/:category/:id',
2218-
{ category: 'programming', id: 4 },
2219-
{ query: { page: 3, limit: 10 }}
2220-
);
2221-
url.should.equal('/books/programming/4?page=3&limit=10');
2222-
url = Router.url('/books/:category/:id',
2223-
{ category: 'programming', id: 4 },
2224-
{ query: 'page=3&limit=10' }
2225-
);
2226-
url.should.equal('/books/programming/4?page=3&limit=10');
2227-
done();
2240+
it('generates route URL with params and query params', function (done) {
2241+
let url = Router.url('/books/:category/:id', 'programming', 4, {
2242+
query: { page: 3, limit: 10 }
2243+
});
2244+
url.should.equal('/books/programming/4?page=3&limit=10');
2245+
url = Router.url('/books/:category/:id',
2246+
{ category: 'programming', id: 4 },
2247+
{ query: { page: 3, limit: 10 } }
2248+
);
2249+
url.should.equal('/books/programming/4?page=3&limit=10');
2250+
url = Router.url('/books/:category/:id',
2251+
{ category: 'programming', id: 4 },
2252+
{ query: 'page=3&limit=10' }
2253+
);
2254+
url.should.equal('/books/programming/4?page=3&limit=10');
2255+
done();
22282256
});
22292257

2230-
it('generates router URL without params and with with query params', function(done) {
2231-
const url = Router.url('/category', {
2232-
query: { page: 3, limit: 10 }
2233-
});
2234-
url.should.equal('/category?page=3&limit=10');
2235-
done();
2258+
it('generates router URL without params and with with query params', function (done) {
2259+
const url = Router.url('/category', {
2260+
query: { page: 3, limit: 10 }
2261+
});
2262+
url.should.equal('/category?page=3&limit=10');
2263+
done();
22362264
});
22372265
});
22382266
});

0 commit comments

Comments
 (0)
Please sign in to comment.