Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .match(route) to get a matching route without invoking the handler #64

Merged
merged 1 commit into from
Dec 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ Register a new route. The order in which routes are registered does not matter.
Routes can register multiple callbacks. The callback can return values when
called.

### matchedRoute = router.match(route)
Matches a route and returns an object. The returned object contains the properties `{cb, params, route}`. This method does not invoke the callback of a route. If no route matches, the default route will be returned. If no default route matches, an error will be thrown.

### val = router(route, [arg1, ...])
Match a route and execute the corresponding callback. Alias: `router.emit()`.
Returns a values from the matched route (e.g. useful for streams). Any
Expand Down
33 changes: 20 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ function Wayfarer (dft) {
var _trie = trie()

emit._trie = _trie
emit.emit = emit
emit.on = on
emit.emit = emit
emit.match = match
emit._wayfarer = true

return emit
Expand All @@ -40,26 +41,32 @@ function Wayfarer (dft) {
// match and call a route
// (str, obj?) -> null
function emit (route) {
assert.notEqual(route, undefined, "'route' must be defined")
var matched = match(route)

var args = new Array(arguments.length)
args[0] = matched.params
for (var i = 1; i < args.length; i++) {
args[i] = arguments[i]
}

var node = _trie.match(route)
if (node && node.cb) {
args[0] = node.params
var cb = node.cb
return cb.apply(cb, args)
}
return matched.cb.apply(matched.cb, args)
}

function match (route) {
assert.notEqual(route, undefined, "'route' must be defined")

var matched = _trie.match(route)
if (matched && matched.cb) return new Route(matched)

var dft = _trie.match(_default)
if (dft && dft.cb) {
args[0] = dft.params
var dftcb = dft.cb
return dftcb.apply(dftcb, args)
}
if (dft && dft.cb) return new Route(dft)

throw new Error("route '" + route + "' did not match")
}

function Route (matched) {
this.cb = matched.cb
this.route = matched.cb.route
this.params = matched.params
}
}
41 changes: 38 additions & 3 deletions test/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var wayfarer = require('../')
var noop = require('noop2')
var tape = require('tape')

tape('trie', function (t) {
tape('router', function (t) {
t.test('should match a path', function (t) {
t.plan(1)
var r = wayfarer()
Expand Down Expand Up @@ -62,6 +62,21 @@ tape('trie', function (t) {
r('/foo/baz')
})

t.test('.match() should match paths', function (t) {
t.plan(2)
var r = wayfarer()
r.on('/foo/bar', function () {
t.fail('should not call callback')
})
r.on('/foo/baz', noop)

var bar = r.match('/foo/bar')
t.equal(bar.route, '/foo/bar')

var baz = r.match('/foo/baz')
t.equal(baz.route, '/foo/baz')
})

t.test('.emit() should match partials', function (t) {
t.plan(1)
var r = wayfarer()
Expand All @@ -71,6 +86,14 @@ tape('trie', function (t) {
r('/tobi')
})

t.test('.match() should match partials', function (t) {
t.plan(1)
var r = wayfarer()
r.on('/:user', noop)
var toby = r.match('/tobi')
t.equal(toby.params.user, 'tobi')
})

t.test('.emit() should match paths before partials', function (t) {
t.plan(1)
var r = wayfarer()
Expand All @@ -84,7 +107,9 @@ tape('trie', function (t) {
t.test('.emit() should allow path overriding', function (t) {
t.plan(1)
var r = wayfarer()
r.on('/:user', noop)
r.on('/:user', function () {
t.fail('wrong callback called')
})
r.on('/:user', function () {
t.pass('called')
})
Expand Down Expand Up @@ -170,6 +195,16 @@ tape('trie', function (t) {
// r10('/foo/bin/bar/baz')
})

t.test('.match() returns a handler of a route', function (t) {
t.plan(1)
var r = wayfarer()
r.on('/:user', function () {
t.pass('called')
})
var toby = r.match('/tobi')
toby.cb()
})

t.test('nested routes should call parent default route', function (t) {
t.plan(4)
var r1 = wayfarer('/404')
Expand Down Expand Up @@ -281,7 +316,7 @@ tape('trie', function (t) {
r('/test/hel%"Flo')
})

t.test('should expose .router property', function (t) {
t.test('should expose .route property', function (t) {
t.plan(1)
var r = wayfarer()
r.on('/foo', function () {
Expand Down