Skip to content

Commit

Permalink
feat(createRoute): add .createRoute method
Browse files Browse the repository at this point in the history
allows to just get some route object without adding it to the routes (this.routes) actully

Resolves #2
  • Loading branch information
tunnckoCore committed Oct 14, 2016
1 parent eb58885 commit 0135211
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 26 deletions.
58 changes: 38 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ KoaBetterRouter.prototype.loadMethods = function loadMethods () {
}

/**
* > Powerful method to do the routing if you don't want
* > Powerful method to add `route` if you don't want
* to populate you router instance with dozens of methods.
* The `method` can be just HTTP verb or `method`
* plus `pathname` something like `'GET /users'`.
* plus `route` something like `'GET /users'`.
* Both modern and generators middlewares can be given too,
* and can be combined too.
* and can be combined too. **Adds routes to `this.routes` array**.
*
* **Example**
*
Expand Down Expand Up @@ -156,47 +156,65 @@ KoaBetterRouter.prototype.loadMethods = function loadMethods () {
* ```
*
* @param {String} `<method>` http verb or `'GET /users'`
* @param {String|Function} `[pathname]` for what `ctx.path` handler to be called
* @param {String|Function} `[route]` for what `ctx.path` handler to be called
* @param {Function} `...fns` can be array or single function, any number of
* arguments after `pathname` can be given too
* arguments after `route` can be given too
* @return {KoaBetterRouter} `this` instance for chaining
* @api public
*/

KoaBetterRouter.prototype.addRoute = function addRoute (method, pathname, fns) {
KoaBetterRouter.prototype.addRoute = function addRoute (method, route, fns) {
let routeObject = this.createRoute.apply(this, arguments)
this.routes.push(routeObject)
return this
}

/**
* > Just creates route object without adding it to `this.routes` array.
*
* @param {String} `<method>` http verb or `'GET /users'`
* @param {String|Function} `[route]` for what `ctx.path` handler to be called
* @param {Function} `...fns` can be array or single function, any number of
* arguments after `route` can be given too
* @return {KoaBetterRouter} `this` instance for chaining
* @return {Object} plain `route` object with useful properties
* @api public
*/

KoaBetterRouter.prototype.createRoute = function createRoute (method, route, fns) {
let args = [].slice.call(arguments, 3)
let middlewares = utils.arrayify(fns).concat(args)

if (typeof method !== 'string') {
throw new TypeError('.addRoute: expect `method` to be a string')
throw new TypeError('.createRoute: expect `method` to be a string')
}

let parts = method.split(' ')
method = parts[0] || 'get'
method = method.toUpperCase()

if (typeof pathname === 'function') {
middlewares = [pathname].concat(middlewares)
pathname = parts[1]
if (typeof route === 'function') {
middlewares = [route].concat(middlewares)
route = parts[1]
}
if (Array.isArray(pathname)) {
middlewares = pathname.concat(middlewares)
pathname = parts[1]
if (Array.isArray(route)) {
middlewares = route.concat(middlewares)
route = parts[1]
}
if (typeof pathname !== 'string') {
throw new TypeError('.addRoute: expect `pathname` be string, array or function')
if (typeof route !== 'string') {
throw new TypeError('.createRoute: expect `route` be string, array or function')
}

let prefixed = utils.createPrefix(this.options.prefix, pathname)
this.routes.push({
let prefixed = utils.createPrefix(this.options.prefix, route)
return {
prefix: this.options.prefix,
path: prefixed,
pathname: pathname,
pathname: route,
route: route,
match: this.route(prefixed),
method: method,
middlewares: middlewares
})
return this
}
}

/**
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test": "npm run coverage",
"posttest": "npm run lint:coverage",
"coverage": "nyc node test.js",
"lint:coverage": "nyc check-coverage --lines 100 --branches 93 --statements 100 --functions 100",
"lint:coverage": "nyc check-coverage --lines 100 --branches 96 --statements 100 --functions 100",
"report-coverage": "nyc report --reporter=text-lcov | coveralls",
"prerelease": "npm test",
"release": "standard-version --sign --no-verify",
Expand All @@ -32,6 +32,7 @@
"commitizen": "^2.8.6",
"coveralls": "^2.11.12",
"cz-conventional-changelog": "^1.2.0",
"is-es6-generator-function": "^1.0.0",

This comment has been minimized.

Copy link
@tunnckoCore

tunnckoCore Oct 14, 2016

Owner

wtf?!

"koa": "^2.0.0-alpha.7",
"mukla": "^0.4.1",
"nyc": "^8.1.0",
Expand Down
32 changes: 27 additions & 5 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ test('should expose constructor', function (done) {

test('should have `.addRoute`, `.middleware` and `legacyMiddlewares` methods', function (done) {
test.strictEqual(typeof router.addRoute, 'function')
test.strictEqual(typeof router.createRoute, 'function')
test.strictEqual(typeof router.middleware, 'function')
test.strictEqual(typeof router.loadMethods, 'function')
test.strictEqual(typeof router.legacyMiddleware, 'function')
Expand Down Expand Up @@ -64,7 +65,7 @@ test('should have empty `.routes` array on initialization', function (done) {
done()
})

test('should `.addRoute` throw TypeError if `method` a string', function (done) {
test('should `.addRoute/.createRoute` throw TypeError if `method` a string', function (done) {
function fixture () {
router.addRoute(123)
}
Expand All @@ -73,22 +74,22 @@ test('should `.addRoute` throw TypeError if `method` a string', function (done)
done()
})

test('should `.addRoute` throw TypeError pathname not a string, array or function', function (done) {
test('should `.addRoute/.createRoute` throw TypeError route not a string, array or function', function (done) {
function fixture () {
router.addRoute('GET', 123)
}
test.throws(fixture, TypeError)
test.throws(fixture, /expect `pathname` be string, array or function/)
test.throws(fixture, /expect `route` be string, array or function/)
done()
})

test('should `.addRoute` be able to accept single function as `pathname`', function (done) {
test('should `.addRoute` be able to accept single function as `route`', function (done) {
let apiRouter = Router()
apiRouter.addRoute('GET /users', function (ctx, next) {})
done()
})

test('should `.addRoute` accept `pathname` to be array of middlewares', function (done) {
test('should `.addRoute` accept `route` to be array of middlewares', function (done) {
let apiRouter = Router()
apiRouter.addRoute('GET /companies', [
function (ctx, next) {
Expand All @@ -108,6 +109,27 @@ test('should `.addRoute` accept `pathname` to be array of middlewares', function
.end(done)
})

test('should `.createRoute` just return route object', function (done) {
let router = new Router({ prefix: '/api' })
let route = router.createRoute('GET', '/users', [
function foo (ctx, next) {},
function bar (ctx, next) {},
function baz (ctx, next) {}
])

test.strictEqual(router.routes.length, 0)

// route object
test.strictEqual(route.prefix, '/api')
test.strictEqual(route.path, '/api/users')
test.strictEqual(route.pathname, '/users')
test.strictEqual(route.route, '/users')
test.strictEqual(route.method, 'GET')
test.strictEqual(typeof route.match, 'function')
test.strictEqual(route.middlewares.length, 3)
done()
})

test('should `.middleware` return generator function when opts.legacy: true', function (done) {
let router = Router()
let ret = router.middleware({ legacy: true })
Expand Down

0 comments on commit 0135211

Please sign in to comment.