Skip to content

Commit

Permalink
improve
Browse files Browse the repository at this point in the history
  • Loading branch information
fundon committed Aug 1, 2016
1 parent 1b56015 commit 1d2955a
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 25 deletions.
41 changes: 18 additions & 23 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@ const COLON = 58 // ':'
*/
class Node {

constructor (prefix = '/', children, handlers, pnames) {
constructor (prefix = '/', children, maps) {
this.label = prefix.charCodeAt(0)
this.prefix = prefix
this.children = children || []
this.handlers = handlers || Object.create(null)
this.pnames = pnames
this.maps = maps || Object.create(null)
}

/**
Expand All @@ -60,12 +59,12 @@ class Node {
return
}

addHandler (method, handler) {
this.handlers[method] = handler
addMap (method, map) {
this.maps[method] = map
}

findHandler (method) {
return this.handlers[method]
findMap (method) {
return this.maps[method]
}

}
Expand Down Expand Up @@ -162,29 +161,25 @@ class Router {
cn.label = search.charCodeAt(0)
cn.prefix = search
if (handler !== undefined) {
cn.pnames = pnames
cn.addHandler(method, handler)
cn.addMap(method, { pnames, handler })
}
} else if (l < pl) {
// Split node
n = new Node(cn.prefix.substring(l), cn.children, cn.handlers, cn.pnames)
n = new Node(cn.prefix.substring(l), cn.children, cn.maps)
cn.children = [n] // Add to parent

// Reset parent node
cn.label = cn.prefix.charCodeAt(0)
cn.prefix = cn.prefix.substring(0, l)
cn.handler = undefined
cn.pnames = undefined
cn.handlers = Object.create(null)
cn.maps = Object.create(null)

if (l === sl) {
// At parent node
cn.pnames = pnames
cn.addHandler(method, handler)
cn.addMap(method, { pnames, handler })
} else {
// Create child node
n = new Node(search.substring(l), [], Object.create(null), pnames)
n.addHandler(method, handler)
n = new Node(search.substring(l), [])
n.addMap(method, { pnames, handler })
cn.children.push(n)
}
} else if (l < sl) {
Expand All @@ -196,14 +191,13 @@ class Router {
continue
}
// Create child node
n = new Node(search, [], Object.create(null), pnames)
n.addHandler(method, handler)
n = new Node(search, [])
n.addMap(method, { pnames, handler })
cn.children.push(n)
} else {
// Node already exists
if (handler !== undefined) {
cn.pnames = pnames
cn.addHandler(method, handler)
cn.addMap(method, { pnames, handler })
}
}
return
Expand Down Expand Up @@ -232,8 +226,9 @@ class Router {
// Search order static > param > match-any
if (search.length === 0 || search === cn.prefix) {
// Found
if ((result[0] = cn.findHandler(method)) !== undefined) {
let pnames = cn.pnames
let map = cn.findMap(method)
if ((result[0] = map && map.handler) !== undefined) {
let pnames = map.pnames
if (pnames !== undefined) {
for (let i = 0, l = pnames.length; i < l; ++i) {
params[i].name = pnames[i]
Expand Down
5 changes: 3 additions & 2 deletions test/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ function prefix(tail, p, on, off) {
return format('%s%s', p, tail ? on : off)
}

Node.prototype.printTree = function printTree(pfx, tail) {
Node.prototype.printTree = function printTree(pfx, tail, method = 'GET') {
let map = this.maps[method]
let p = prefix(tail, pfx, '└── ', '├── ')
console.log(
'%s%s h=%s children=%s',
p,
this.prefix,
this.handler ? 'function' : undefined,
map && map.handler ? map.handler.name : '',
this.children.length
)

Expand Down
44 changes: 44 additions & 0 deletions test/rest.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import _ from 'lodash'
import assert from 'power-assert'
import Router from '..'
import './node'

function createFunc(name) {
var a = `(function ${name||''}(){})`
return eval(a)
}

// https://github.com/labstack/echo/issues/479
const api = [
['GET', '/:piyo', '/piyo', 'piyo'],
['POST', '/:hoge', '/hoge', 'hoge'],
]

describe('Rest API', () => {
let r

beforeEach(() => {
r = new Router()
_.shuffle(api).forEach((i) => {
let [method, path] = i
r.add(method, path, createFunc(_.camelCase('rest-api' + path + '-' + method)))
})
})

it('Parse API routes', () => {
r.tree.printTree('', true, 'GET')
r.tree.printTree('', true, 'POST')
})

_.shuffle(api).forEach((i) => {
let [method, path, realpath, paramName] = i
it(path, () => {
let [handler, params] = r.find(method, realpath)
console.log(method, path, realpath, handler.name, params)
assert.notEqual(null, handler)
assert.equal(_.camelCase('rest-api' + path + '-' + method), handler.name)
assert.equal((path.match(/\:/g) || []).length, params.length)
assert.equal(params[0].name, paramName)
})
})
})

0 comments on commit 1d2955a

Please sign in to comment.