diff --git a/README.md b/README.md index 5298919..f27e8da 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,12 @@ io.use(router); * Easy to use interface for manipulating socket.io events. * Express-like routing capabilties for socket.io events. * Gives you more control over how events are handled. +* Attach `Router` instances to other `Router` instances. # Examples +The method `on` is an alias to `use`. + ```javascript var assert = require('assert'); var router = require('socket.io-events')(); @@ -111,6 +114,206 @@ router.on(function (socket, args, next) { io.use(router); ``` +You can even attach a `Router' intance to another `Router` intance. + +```javascript +var Router = require('socket.io-events')(); + +var a = Router(); +a.use(function (sock, args, next) { next() }); + +var b = Router(); +b.use(function (sock, args, next) { next() }); + +a.use(b) + +var io = require('socket.io')(3000); +io.use(a); +``` + +# API + +## Router + +Get the `Router` class. + +```javascript +var Router = require('socket.io-events'); +``` + +The `use` and `on` methods are equivalent. They also can be chained. + +```javascript +var router = Router() + .use(function (sock, args, next) { }) + .use(function (sock, args, next) { }) + .use(function (sock, args, next) { }); +``` + +### Router#() + +Make a `Router` instance + +```javascript +var router = Router(); +``` + +### Router#use(fn:Function, ...) + +Attach a `function` to the router. + +```javascript +router.use(function (sock, args, next) { + //do something! + next(); +}); +``` + +You can pass in multiple `function`s. + +```javascript +var a = function (sock, args, next) { next() }; +var b = function (sock, args, next) { next() }; +var c = function (sock, args, next) { next() }; + +router.use(a,b,c); +``` + +You can pass in a function that accepts an `Error` object. + +```javascript +router.use(function (err, sock, args, next) { + console.error(err); + + //calling next(err) will invoke the next error handler. + //to resume operation just call next() + next(err); +}); +``` + +### Router#use(event:String, fn:Function, ...) + +Bind the `function` to the `event`. + +```javascript +router.use('chat', function (sock, args, next) { + assert.equal(args[0], 'chat'); + args[1] = args[1].length > 128 ? args[1].slice(0, 125) + '...' : args[1]; + next(); +}); +``` + +You can also pass in multiple `function`s for handling the `event`. + +```javascript +var chop = function (sock, args, next) { next() }; +var clean = function (sock, args, next) { next() }; +var pretty = function (sock, args, next) { next() }; + +router.use('chat', chop, clean, pretty); +``` + +### Router#use(router:Router, ...) + +You can attach another `Router` instance to your `Router` instance. + +```javascript +var another = Router(); +another.use(function (sock, args, next) { next(); }); + +router.use(another); +``` + +Attach multiple routers in a single call. + +```javascript +var foo = Router(); +foo.use(function (sock, args, next) { next(); }); + +var bar = Router(); +bar.use(function (sock, args, next) { next(); }); + +var baz = Router(); +baz.use(function (sock, args, next) { next(); }); + +router.use(foo, bar, baz); +``` + +### Router#use(name:String, router:Router, ...) + +Just like attaching a `function` to the router given the `event`. You can attach `Router` +instance as well to the `event`. + +```javascript +var foo = Router(); +foo.use(function (sock, args, next) { next(); }); + +router.use('some event', foo); +``` + +Attach multiple routers in a single call to the `event` too. + +```javascript +var foo = Router(); +foo.use(function (sock, args, next) { next(); }); + +var bar = Router(); +bar.use(function (sock, args, next) { next(); }); + +var baz = Router(); +baz.use(function (sock, args, next) { next(); }); + +router.use('some event', foo, bar, baz); +``` + +### Router#use(fns:Array, ...) + +Attach an `Array` of `Fuction`'s or `Router` instances, or an `Array` or `Array`s . + +```javascript +var middleware = [ + function (sock, args, next) { next(); }, + [ + function (sock, args, next) { next(); }, + Router().use(function (sock, args, next) { next(); }), + function (sock, args, next) { next(); }, + ], + Router().use(function (sock, args, next) { next(); }) +]; + +var errHandler = function (err, sock, args, next) { next(err); } + +router.use(middleware, errHandler); +``` + +### Router#use(name:String, fns:Array, ...) + +Attach everything to an event. + +```javascript +var middleware = [ + function (sock, args, next) { next(); }, + [ + function (sock, args, next) { next(); }, + Router().use(function (sock, args, next) { next(); }), + function (sock, args, next) { next(); }, + ], + Router().use(function (sock, args, next) { next(); }) +]; + +var errHandler = function (err, sock, args, next) { next(err); } + +router.use('only this event', middleware, errHandler); +``` + +### Router#on(...) + +This is an alias to to the `use` method. It does the same thing. + +```javascript +router.on(function (sock, args, next) { next() }); +``` + # Installation and Environment Setup Install node.js (See download and install instructions here: http://nodejs.org/). diff --git a/examples/multiple.js b/examples/multiple.js new file mode 100644 index 0000000..3dc13ba --- /dev/null +++ b/examples/multiple.js @@ -0,0 +1,55 @@ +var ok = require('assert').equal; +var Router = require('./..'); + +var a = Router(); +a.on('say', function (sock, args, next) { + args.push('World'); + next(); +}); + +var b = Router(); +b.use('say', function (sock, args, next) { + args.push('Good'); + next(); +}); + +var c = Router(); +c.use('say', function (sock, args, next) { + args.push('Bye'); + next(); +}); + +var d = Router(); +d.use(function (sock, args, next) { + args.push('!!!'); + next(); +}); + +a.use(b) +b.use(c); +c.use(d); + +var io = require('socket.io')(3000); +io.use(a); +io.on('connection', function (sock) { + sock.on('say', function (hello, world, good, bye, exclamation) { + sock.emit('say', hello, world, good, bye, exclamation); + }); +}); + +setTimeout(function () { + var sock = require('socket.io-client').connect('ws://localhost:3000'); + sock.on('connect', function () { + sock.emit('say', 'Hello'); + }); + sock.on('say', function (hello, world, good, bye, exclamation) { + ok(hello, 'Hello'); + ok(world, 'World'); + ok(good, 'Good'); + ok(bye, 'Bye'); + ok(exclamation, '!!!'); + console.log('we good'); + process.exit(0); + }); + +}, 1000); diff --git a/examples/run.sh b/examples/run.sh index 03685c7..371bd93 100755 --- a/examples/run.sh +++ b/examples/run.sh @@ -5,3 +5,5 @@ echo 'testing bau' node bau echo 'testing recover' node recover +echo 'testing routers attached to routers' +node multiple diff --git a/lib/router.js b/lib/router.js index e3a7adc..34fe3ed 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1,5 +1,7 @@ var debug = require('debug')('router'); +var util = require('util'); var emit = require('events').EventEmitter.prototype.emit; +var slice = Array.prototype.slice; module.exports = Router; @@ -14,6 +16,7 @@ function Router () { if (!(this instanceof Router)) return new Router(); function router (socket, cb) { + debug('router socket.id %s typeof cb %s', socket ? socket.id : null, typeof cb); router.middleware(socket, cb); } @@ -40,7 +43,7 @@ function Router () { */ router.middleware = function (socket, cb) { - debug('middleware'); + debug('middleware socket.id %s typeof cb %s', socket.id, typeof cb); if ('function' != typeof socket.onevent || socket.onevent !== router.onEvent) { socket.onevent = router.onEvent; } @@ -63,7 +66,7 @@ function Router () { args.push(this.ack(packet.id)); } - router.onRoute(this, args); + router.onRoute(null, this, args); }; @@ -71,52 +74,107 @@ function Router () { * Pushes the socket and arguments through the middleware * * @api private + * @param {Error} err *optional * @param {Socket} socket * @param {Array} args + * @param {Function} cb */ - router.onRoute = function (socket, args) { + router.onRoute = function (err, socket, args, cb) { - var done = function (emit, args) { - debug('done callled'); - emit.apply(socket, args); - }; + debug('onRoute err? %s socket.id %s args?', util.isError(err), (socket ? socket.id : null), args); - var path = this.getPath(args.length ? args[0] : '*'); - socket = this.decorate(socket, done); + socket = router.decorate(socket, function (emit, args) { debug('done callled'); emit.apply(socket, args); }); - var i = 0, len = path.length; + var i = 0, path = router.getPath(args.length ? args[0] : '*'), len = path.length; + + debug('got path the length is %s', len); + + debug('about to call "step" for the first time passing %s for err', err); (function step (err) { - debug('current step %s of %s', i, len); + debug('current step %s of %s', i+1, len); function next (err) { + debug('next called err? %s', util.isError(err)); if (++i >= len) { debug('last step'); - if (err) return emit.apply(socket, ['error', args]); - return emit.apply(socket, args); + if (err) { + debug('has err'); + if ('function' === typeof cb) { + debug('cb is function'); + cb(err, socket, args); + } + else { + debug('default which is to call emit on the socket'); + emit.apply(socket, ['error', args]); + } + } + else { + debug('no err'); + if ('function' === typeof cb) { + debug('cb is function'); + cb(null, socket, args); + } + else { + debug('default which is to call emit on the socket'); + emit.apply(socket, args); + } + } + } + else { + debug('calling step'); + step(err); } - step(err); } var fn = path[i]; + debug('typeof fn? %s', typeof fn); + try { if (err) { + debug('we have an error'); if (fn.length >= 4) { - fn(err, socket, args, next); + debug('the fn.length is >= 4'); + if (fn instanceof Router) { + debug('we have a router instance'); + fn.onRoute(err, socket, args, next); + } + else { + debug('we have a regular function'); + fn(err, socket, args, next); + } } else { + debug('fn is not an erorr handler call next %s', typeof next); next(err); } } else { + debug('we do not have an error'); + debug('fn %s', fn); if (fn.length >= 4) { - next(); + debug('the fn.length is >= 4'); + if (fn instanceof Router) { + debug('we have a router instance'); + fn.onRoute(null, socket, args, next); + } + else { + debug('we have a regular function call next %s', typeof next); + next(); + } } else { - fn(socket, args, next); + if (fn instanceof Router) { + debug('we have a router instance'); + fn.onRoute(null, socket, args, next); + } + else { + debug('fn is normal invoke it socket.id %s args %s typeof next %s', (socket ? socket.id : null), args, typeof next); + fn(socket, args, next); + } } } } @@ -127,13 +185,15 @@ function Router () { next(e); } - })(); + })(err); }; + + debug('router instanceof Router? %s', router instanceof Router); return router; -} +}; /** @@ -146,16 +206,19 @@ function Router () { */ Router.prototype.decorate = function (socket, done) { - debug('decorate'); + debug('decorate socket.id %s typeof done %s', socket.id, typeof done); var emit = socket.emit; + + debug('is the "emit" on socket.id %s wrapped? %s', socket.id, (emit.wrapped ? true : false)); // prevent double wrapping if (emit.wrapped) return socket; socket.emit = function () { - done(emit, Array.prototype.slice.call(arguments)); + done(emit, slice.call(arguments)); }; + debug('"emit" on socket.id %s is now wrapped', socket.id); socket.emit.wrapped = true; return socket; @@ -179,17 +242,8 @@ Router.prototype.getPath = function (name) { var fns = []; points .sort(function (a, b) { - var res = a[0] - b[0]; - debug('sort index a %s, b %s = %s', a, b, res); - return res; - }) - /* - .sort(function (a, b) { - var res = (a[1].length >= 4 ? 1 : 0) - (b[1].length >= 4 ? 1 : 0); - debug('sort index a %s, b %s = %s', a, b, res); - return res; + return a[0] - b[0]; }) - */ .forEach(function (point) { fns.push(point[1]); }); @@ -197,45 +251,45 @@ Router.prototype.getPath = function (name) { }; /** - * Used to bind functions + * Use this method to attach handlers, and other routers * * @api public - * @param {mixed} Either a string, function, or array of functions + * @param {mixed} Either a string and one of either a [function, or array of functions, or a Router] * @return Router */ -Router.prototype.on = function () { +Router.prototype.use = function () { if (!arguments.length) throw new Error('expecting at least one parameter'); - + var args = slice.call(arguments); + debug('use called %s', args); + var name = typeof args[0] === 'string' ? args.shift() : '*'; + debug('the name %s', name); + if (!args.length) throw new Error('we have the name, but need a handler'); + var fns = this.fns(name); var self = this; - var args = Array.prototype.slice.call(arguments); - var first = args.shift(); - var type = typeof first; - var name = '*'; - var fn; - - if (type === 'string') { - name = first; - if (!args.length) throw new Error('need a function'); - } - else if (type === 'function') { - fn = first; - this.fns(name).push([this.index(), first]); - } - else if (type === 'object' && first instanceof Array) { - this.on.apply(this, first); + var i, arg, type; + for (i=0; i - - Given -> @foo = jasmine.createSpy 'foo' - Given -> @bar = jasmine.createSpy 'bar' - Given -> @baz = jasmine.createSpy 'baz' - Given -> @no = jasmine.createSpy 'no' - Given -> - @router = require('./..')() - @router.on (socket, args, next) => - @foo() - next() - @router.on 'some event', (socket, args, next) => - @bar() - next() - @router.on '*', (socket, args, next) => - @baz() - socket.emit.apply(socket, args) - @router.on 'some event', (socket, args, next) => - @no() - next() - - Given -> - @io = require('socket.io')(3000) - @io.use @router.middleware - - Given -> @message = 'Hello, World' - - When (done) -> - @socket = require('socket.io-client').connect('ws://localhost:3000') - @socket.on 'connect', => - @socket.emit 'some event', @message - @socket.on 'some event', (message) => - @res = message - done() - - Then -> expect(@res).toEqual @message - And -> expect(@baz).toHaveBeenCalled() - And -> expect(@bar).toHaveBeenCalled() - And -> expect(@foo).toHaveBeenCalled() - And -> expect(@no).not.toHaveBeenCalled() - -describe 'when a router receives some event and it is not handle business as usual', -> - - Given -> - @router = require('./..')() - @router.on (socket, args, next) -> next() - - Given -> - @io = require('socket.io')(3001) - @io.use @router.middleware - @io.on 'connect', (socket) -> - socket.on 'echo', (data) -> - socket.emit 'echo', data - - Given -> @message = 'Hello, World' - - When (done) -> - @socket = require('socket.io-client').connect('ws://localhost:3001') - @socket.on 'connect', => - @socket.emit 'echo', @message - @socket.on 'echo', (message) => - @res = message - done() - Then -> expect(@res).toEqual @message +debug = require('debug')('router') + +describe 'routing events', -> + + describe 'when a router receives some event it should route it to a handler', -> + + Given -> @foo = jasmine.createSpy 'foo' + Given -> @bar = jasmine.createSpy 'bar' + Given -> @baz = jasmine.createSpy 'baz' + Given -> @no = jasmine.createSpy 'no' + Given -> + @router = require('./..')() + @router.on (socket, args, next) => + @foo() + next() + @router.on 'some event', (socket, args, next) => + @bar() + next() + @router.on '*', (socket, args, next) => + @baz() + socket.emit.apply(socket, args) + @router.on 'some event', (socket, args, next) => + @no() + next() + + Given -> + @io = require('socket.io')(3000) + @io.use @router.middleware + + Given -> @message = 'Hello, World' + + When (done) -> + @socket = require('socket.io-client').connect('ws://localhost:3000') + @socket.on 'connect', => + @socket.emit 'some event', @message + @socket.on 'some event', (message) => + @res = message + done() + + Then -> expect(@res).toEqual @message + And -> expect(@baz).toHaveBeenCalled() + And -> expect(@bar).toHaveBeenCalled() + And -> expect(@foo).toHaveBeenCalled() + And -> expect(@no).not.toHaveBeenCalled() + + describe 'when a router receives some event and it is not handle business as usual', -> + + Given -> + @router = require('./..')() + @router.on (socket, args, next) -> next() + + Given -> + @io = require('socket.io')(3001) + @io.use @router.middleware + @io.on 'connect', (socket) -> + socket.on 'echo', (data) -> + socket.emit 'echo', data + + Given -> @message = 'Hello, World' + + When (done) -> + @socket = require('socket.io-client').connect('ws://localhost:3001') + @socket.on 'connect', => + @socket.emit 'echo', @message + @socket.on 'echo', (message) => + @res = message + done() + Then -> expect(@res).toEqual @message + + describe 'two routers connected to each other', -> + + Given -> @hit = 0 + + Given -> + @a = require('./..')() + @a.on (socket, args, next) => + debug('handler "a" socket.id %s args %s typeof next', socket.id, args, typeof next) + @hit++ + next() + + Given -> + @b = require('./..')() + @b.on (socket, args, next) => + debug('handler "b" socket.id %s args %s typeof next', socket.id, args, typeof next) + @hit++ + next() + + Given -> @a.use @b + + Given -> + @io = require('socket.io')(3002) + @io.use @a + @io.on 'connect', (socket) -> + socket.on 'echo', (data) -> + socket.emit 'echo', data + + Given -> @message = 'Hello, World' + + When (done) -> + @socket = require('socket.io-client').connect('ws://localhost:3002') + @socket.on 'connect', => + @socket.emit 'echo', @message + @socket.on 'echo', (message) => + @res = message + done() + Then -> expect(@res).toEqual @message + And -> expect(@hit).toBe 2 diff --git a/spec/lib/router-spec.coffee b/spec/lib/router-spec.coffee index ec10fbc..cd36eda 100644 --- a/spec/lib/router-spec.coffee +++ b/spec/lib/router-spec.coffee @@ -35,9 +35,9 @@ describe 'Router', -> Given -> @packet = id:1, data: ['message', 'hello'] When -> @router.onEvent.call @socket, @packet Then -> expect(@socket.ack).toHaveBeenCalledWith @packet.id - And -> expect(@router.onRoute).toHaveBeenCalledWith @socket, ['message', 'hello', @fn] + And -> expect(@router.onRoute).toHaveBeenCalledWith null, @socket, ['message', 'hello', @fn] - describe '#onRoute', -> + describe '#onRoute (err:Error=null, sock:Object, args:Array)', -> Given -> @order = [] Given -> @a = jasmine.createSpy 'a' @@ -49,16 +49,16 @@ describe 'Router', -> Given -> @error = new Error 'something wrong' Given -> @foo = (socket, args, next) => @a(); @order.push('a'); next() Given -> @bar = (socket, args, next) => @b(); @order.push('b'); next() - Given -> @baz = (socket, args, next) => @c(); @order.push('c'); next @error + Given -> @baz = (socket, args, next) => @c(); @order.push('c'); next @error Given -> @err = (err, socket, args, next) => @d err; @order.push('d'); next err Given -> @err1 = (err, socket, args, next) => @e err; @order.push('e'); next() Given -> @cra = (socket, args, next) => @f(); @order.push('f'); next() Given -> @path = [@foo, @bar, @err, @baz, @err1, @cra] - Given -> @router.on @path + Given -> @router.use @path Given -> spyOn(@router,['getPath']).andCallThrough() Given -> spyOn(@router,['decorate']).andCallThrough() Given -> @args = ['message', 'hello', @fn] - When -> @router.onRoute @socket, @args + When -> @router.onRoute null, @socket, @args, null Then -> expect(@router.getPath).toHaveBeenCalledWith @args[0] And -> expect(@router.decorate).toHaveBeenCalledWith @socket, jasmine.any(Function) And -> expect(@a).toHaveBeenCalled() @@ -69,6 +69,74 @@ describe 'Router', -> And -> expect(@f).toHaveBeenCalled() And -> expect(@order).toEqual ['a', 'b', 'c', 'e', 'f'] + describe '#onRoute (err:Error=null, sock:Object, args:Array, cb:Function)', -> + + Given -> @order = [] + Given -> @cb = jasmine.createSpy 'cb' + Given -> @a = jasmine.createSpy 'a' + Given -> @b = jasmine.createSpy 'b' + Given -> @c = jasmine.createSpy 'c' + Given -> @d = jasmine.createSpy 'd' + Given -> @e = jasmine.createSpy 'e' + Given -> @f = jasmine.createSpy 'f' + Given -> @error = new Error 'something wrong' + Given -> @foo = (socket, args, next) => @a(); @order.push('a'); next() + Given -> @bar = (socket, args, next) => @b(); @order.push('b'); next() + Given -> @baz = (socket, args, next) => @c(); @order.push('c'); next @error + Given -> @err = (err, socket, args, next) => @d err; @order.push('d'); next err + Given -> @err1 = (err, socket, args, next) => @e err; @order.push('e'); next() + Given -> @cra = (socket, args, next) => @f(); @order.push('f'); next() + Given -> @path = [@foo, @bar, @err, @baz, @err1, @cra] + Given -> @router.use @path + Given -> spyOn(@router,['getPath']).andCallThrough() + Given -> spyOn(@router,['decorate']).andCallThrough() + Given -> @args = ['message', 'hello', @fn] + When -> @router.onRoute null, @socket, @args, @cb + Then -> expect(@router.getPath).toHaveBeenCalledWith @args[0] + And -> expect(@router.decorate).toHaveBeenCalledWith @socket, jasmine.any(Function) + And -> expect(@a).toHaveBeenCalled() + And -> expect(@b).toHaveBeenCalled() + And -> expect(@c).toHaveBeenCalled() + And -> expect(@d).not.toHaveBeenCalled() + And -> expect(@e).toHaveBeenCalledWith @error + And -> expect(@f).toHaveBeenCalled() + And -> expect(@cb).toHaveBeenCalled() + And -> expect(@order).toEqual ['a', 'b', 'c', 'e', 'f'] + + describe '#onRoute (err:Error, sock:Object, args:Array)', -> + + Given -> @order = [] + Given -> @cb = jasmine.createSpy 'cb' + Given -> @a = jasmine.createSpy 'a' + Given -> @b = jasmine.createSpy 'b' + Given -> @c = jasmine.createSpy 'c' + Given -> @d = jasmine.createSpy 'd' + Given -> @e = jasmine.createSpy 'e' + Given -> @f = jasmine.createSpy 'f' + Given -> @error = new Error 'something wrong' + Given -> @foo = (socket, args, next) => @a(); @order.push('a'); next() + Given -> @bar = (socket, args, next) => @b(); @order.push('b'); next() + Given -> @baz = (socket, args, next) => @c(); @order.push('c'); next @error + Given -> @err = (err, socket, args, next) => @d err; @order.push('d'); next err + Given -> @err1 = (err, socket, args, next) => @e err; @order.push('e'); next() + Given -> @cra = (socket, args, next) => @f(); @order.push('f'); next() + Given -> @path = [@foo, @bar, @err, @baz, @err1, @cra] + Given -> @router.use @path + Given -> spyOn(@router,['getPath']).andCallThrough() + Given -> spyOn(@router,['decorate']).andCallThrough() + Given -> @args = ['message', 'hello', @fn] + When -> @router.onRoute @error, @socket, @args, @cb + Then -> expect(@router.getPath).toHaveBeenCalledWith @args[0] + And -> expect(@router.decorate).toHaveBeenCalledWith @socket, jasmine.any(Function) + And -> expect(@a).not.toHaveBeenCalled() + And -> expect(@b).not.toHaveBeenCalled() + And -> expect(@c).not.toHaveBeenCalled() + And -> expect(@d).toHaveBeenCalled() + And -> expect(@e).toHaveBeenCalledWith @error + And -> expect(@f).toHaveBeenCalled() + And -> expect(@cb).toHaveBeenCalled() + And -> expect(@order).toEqual ['d', 'e', 'f'] + describe '#decorate', -> Given -> @old = emit: @socket.emit @@ -79,36 +147,57 @@ describe 'Router', -> @socket.emit 'hello' Then -> expect(@old.emit.apply).toHaveBeenCalledWith @socket, ['hello'] - describe '#on (fn:Function)', -> + describe '#use', -> + + Given -> @test = => @router.use() + Then -> expect(@test).toThrow new Error 'expecting at least one parameter' + + describe '#use (name:Sring)', -> + + Given -> @test = => @router.use 'some event' + Then -> expect(@test).toThrow new Error 'we have the name, but need a handler' + + describe '#use (fn:Function)', -> Given -> @fn = (socket, args, next) -> - When -> @router.on @fn + When -> @router.use @fn + Then -> expect(@router.fns().length).toBe 1 + + describe '#use (router:Router)', -> + + Given -> @a = @Router() + When -> @router.use @a Then -> expect(@router.fns().length).toBe 1 + And -> expect(@router.fns()[0][1]).toEqual @a - describe '#on (name:String,fn:Function)', -> + describe '#use (name:String,fn:Function)', -> Given -> @name = 'name' Given -> @fn = (socket, args, next) -> - When -> @router.on @name, @fn + When -> @router.use @name, @fn Then -> expect(@router.fns(@name).length).toBe 1 - describe '#on (name:Array)', -> + describe '#use (name:Array)', -> Given -> @a = -> Given -> @b = -> Given -> @c = -> Given -> @name = [@a, @b, @c] - When -> @router.on @name + When -> @router.use @name Then -> expect(@router.fns()).toEqual [[0,@a], [1,@b], [2,@c]] + describe '#on', -> + + Then -> expect(@router.on).toEqual @router.use + describe '#getPath (name:String)', -> Given -> @a = -> Given -> @b = -> Given -> @c = -> - Given -> @router.on @a - Given -> @router.on 'event', @b - Given -> @router.on '*', @c + Given -> @router.use @a + Given -> @router.use 'event', @b + Given -> @router.use '*', @c When -> @path = @router.getPath ['event'] Then -> expect(@path).toEqual [@a, @b, @c]