Merge branch 'master' of ssh://git.buddy.wtf/archive/routing-buddy
						commit
						aa8a2c5e80
					
				| @ -1,14 +1,14 @@ | |||||||
| var util = require('util') | var util = require('util'); | ||||||
| 
 | 
 | ||||||
| function NotFound(message, options) { | function NotFound(message, options) { | ||||||
|   Error.call(this) |   Error.call(this); | ||||||
|   options = options || {} |   options = options || {}; | ||||||
|   this.message = message || '' |   this.message = message || ''; | ||||||
|   this.location = options.location || '' |   this.location = options.location || ''; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| util.inherits(NotFound, Error) | util.inherits(NotFound, Error); | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|   NotFound: NotFound |   NotFound: NotFound | ||||||
| } | }; | ||||||
|  | |||||||
| @ -1,119 +1,117 @@ | |||||||
| 'use strict' | var NotFoundError = require('./error').NotFound; | ||||||
| var NotFoundError = require('./error').NotFound | var utils = require('./utils'); | ||||||
| var utils = require('./utils') |  | ||||||
| 
 | 
 | ||||||
| var assign = utils.assign | var assign = utils.assign; | ||||||
| var isFunction = utils.isFunction | var isFunction = utils.isFunction; | ||||||
| var isRegExp = utils.isRegExp | var isRegExp = utils.isRegExp; | ||||||
| var isString = utils.isString | var isString = utils.isString; | ||||||
| var noop = utils.noop | var noop = utils.noop; | ||||||
| 
 | 
 | ||||||
| function RouteNode () { | function RouteNode () { | ||||||
|   this._children = Object.create(null) |   this._children = Object.create(null); | ||||||
|   this._funcs = Object.create(null) |   this._funcs = Object.create(null); | ||||||
|   this._regExs = Object.create(null) |   this._regExs = Object.create(null); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| assign(RouteNode.prototype, { | assign(RouteNode.prototype, { | ||||||
|   handler: null, |   handler: null, | ||||||
| 
 | 
 | ||||||
|   add: function add(parts, handler, context) { |   add: function add(parts, handler, context) { | ||||||
|     parts = parts || [] |     parts = parts || []; | ||||||
|     handler = handler || noop |     handler = handler || noop; | ||||||
|     context = context || null |     context = context || null; | ||||||
| 
 | 
 | ||||||
|     if (parts.length === 0) { |     if (parts.length === 0) { | ||||||
|       this.handler = handler |       this.handler = handler; | ||||||
|       this.context = context |       this.context = context; | ||||||
|       return this |       return this; | ||||||
|     } |     } | ||||||
|     var part = parts.shift() |     var part = parts.shift(); | ||||||
|     var node = null |     var node = null; | ||||||
| 
 | 
 | ||||||
|     if (isString(part)) { |     if (isString(part)) { | ||||||
|       node = this._children[part] |       node = this._children[part]; | ||||||
|     } else if (isRegExp(part)) { |     } else if (isRegExp(part)) { | ||||||
|       this._regExs[part] = part |       this._regExs[part] = part; | ||||||
|     } else if (isFunction(part)) { |     } else if (isFunction(part)) { | ||||||
|       this._funcs[part] = part |       this._funcs[part] = part; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (node == null) { |     if (node == null) { | ||||||
|       node = new RouteNode() |       node = new RouteNode(); | ||||||
|       this._children[part] = node |       this._children[part] = node; | ||||||
|     } |     } | ||||||
|     return node.add(parts, handler, context) |     return node.add(parts, handler, context); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   get: function get(parts, args, done) { |   get: function get(parts, args, done) { | ||||||
|     parts = parts || [] |     parts = parts || []; | ||||||
|     args = args || [] |     args = args || []; | ||||||
|     if (parts.length === 0) { |     if (parts.length === 0) { | ||||||
|       return done(null, this.handler, this.context, args) |       return done(null, this.handler, this.context, args); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var part = parts.shift() |     var part = parts.shift(); | ||||||
| 
 | 
 | ||||||
|     // Check exact matches
 |     // Check exact matches
 | ||||||
|     if (this._children[part]) { |     if (this._children[part]) { | ||||||
|       return this._children[part].get(parts, args, done) |       return this._children[part].get(parts, args, done); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Check regex matches
 |     // Check regex matches
 | ||||||
|     var results = this._getRegexChild(part) |     var results = this._getRegexChild(part); | ||||||
|     if (results && results.node) { |     if (results && results.node) { | ||||||
|       return results.node.get(parts, args.concat(results.args), done) |       return results.node.get(parts, args.concat(results.args), done); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Check function matches
 |     // Check function matches
 | ||||||
|     results = this._getFunctionChild(part) |     results = this._getFunctionChild(part); | ||||||
|     if (results && results.node) { |     if (results && results.node) { | ||||||
|       return results.node.get(parts, args.concat(results.args), done) |       return results.node.get(parts, args.concat(results.args), done); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return done(new NotFoundError('not found', {location: parts})) |     return done(new NotFoundError('not found', {location: parts})); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   _getRegexChild: function _getRegexChild(part) { |   _getRegexChild: function _getRegexChild(part) { | ||||||
|     var self = this |     var self = this; | ||||||
| 
 | 
 | ||||||
|     return Object.keys(this._regExs).reduce(function checkRegex(memo, key) { |     return Object.keys(this._regExs).reduce(function checkRegex(memo, key) { | ||||||
|       if (memo) { |       if (memo) { | ||||||
|         return memo |         return memo; | ||||||
|       } |       } | ||||||
|       var regex = self._regExs[key] |       var regex = self._regExs[key]; | ||||||
|       var results = regex.exec(part) |       var results = regex.exec(part); | ||||||
|       if (!results) { |       if (!results) { | ||||||
|         return null |         return null; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       var lastIndex = null |       var lastIndex = null; | ||||||
|       var args = [] |       var args = []; | ||||||
|       while (results && results.index !== lastIndex) { |       while (results && results.index !== lastIndex) { | ||||||
|         args = args.concat(results[0]) |         args = args.concat(results[0]); | ||||||
|         lastIndex = results.index |         lastIndex = results.index; | ||||||
|         results = regex.exec(part) |         results = regex.exec(part); | ||||||
|       } |       } | ||||||
|       return {args: args, key: key, node: self._children[key]} |       return {args: args, key: key, node: self._children[key]}; | ||||||
|     }, null) |     }, null); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   _getFunctionChild: function _getFunctionChild(part) { |   _getFunctionChild: function _getFunctionChild(part) { | ||||||
|     var self = this |     var self = this; | ||||||
|     return Object.keys(self._funcs).reduce(function checkFunc(memo, key) { |     return Object.keys(self._funcs).reduce(function checkFunc(memo, key) { | ||||||
|       if (memo) { |       if (memo) { | ||||||
|         return memo |         return memo; | ||||||
|       } |       } | ||||||
|       var func = self._funcs[key] |       var func = self._funcs[key]; | ||||||
|       var result = func(part) |       var result = func(part); | ||||||
|       if (result) { |       if (result) { | ||||||
|         return {args: [result], key: key, node: self._children[key]} |         return {args: [result], key: key, node: self._children[key]}; | ||||||
|       } else { |       } else { | ||||||
|         return null |         return null; | ||||||
|       } |       } | ||||||
|     }, null) |     }, null); | ||||||
|   } |   } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| }) | module.exports = RouteNode; | ||||||
| 
 |  | ||||||
| module.exports = RouteNode |  | ||||||
|  | |||||||
| @ -1,39 +1,37 @@ | |||||||
| 'use strict' | var toString = ({}).toString; | ||||||
| 
 | var hasOwnProp = ({}).hasOwnProperty; | ||||||
| var toString = ({}).toString |  | ||||||
| var hasOwnProp = ({}).hasOwnProperty |  | ||||||
| 
 | 
 | ||||||
| var utils = { | var utils = { | ||||||
|   noop: function noop() {}, |   noop: function noop() {}, | ||||||
| 
 | 
 | ||||||
|   isString: function isString(str) { |   isString: function isString(str) { | ||||||
|     return typeof str === 'string' |     return typeof str === 'string'; | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   forEach: function forEach(obj, fn) { |   forEach: function forEach(obj, fn) { | ||||||
|     for (var key in obj) { |     for (var key in obj) { | ||||||
|       if (hasOwnProp.call(obj, key)) { |       if (hasOwnProp.call(obj, key)) { | ||||||
|         fn(key, obj[key]) |         fn(key, obj[key]); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   assign: function assign (dest, methods) { |   assign: function assign (dest, methods) { | ||||||
|     utils.forEach(methods, function (key, val) { |     utils.forEach(methods, function (key, val) { | ||||||
|       dest[key] = val |       dest[key] = val; | ||||||
|     }) |     }); | ||||||
|   } |   } | ||||||
| } | }; | ||||||
| 
 | 
 | ||||||
| function checkType(type) { | function checkType(type) { | ||||||
|   return function _checkType(val) { |   return function _checkType(val) { | ||||||
|     return toString.call(val) === '[object ' + type + ']' |     return toString.call(val) === '[object ' + type + ']'; | ||||||
|   } |   }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // add isRegExp, isArray, isFunction
 | // add isRegExp, isArray, isFunction
 | ||||||
| ['RegExp', 'Array', 'Function'].forEach(function addIsChecks(type) { | ['RegExp', 'Array', 'Function'].forEach(function addIsChecks(type) { | ||||||
|   utils['is' + type] = checkType(type) |   utils['is' + type] = checkType(type); | ||||||
| }) | }); | ||||||
| 
 | 
 | ||||||
| module.exports = utils | module.exports = utils; | ||||||
|  | |||||||
| @ -1,91 +1,90 @@ | |||||||
| var expect = require('expect') | var expect = require('expect'); | ||||||
| var RouteNode = require('../lib/route-node') | var RouteNode = require('../lib/route-node'); | ||||||
| 
 | 
 | ||||||
| module.exports = describe('RouteNode', function () { | module.exports = describe('RouteNode', function () { | ||||||
|   it('→ exists', function () { |   it('→ exists', function () { | ||||||
|     expect(new RouteNode()).not.toBeUndefined() |     expect(new RouteNode()).toBeInstanceOf(RouteNode); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ add nodes', function () { |   describe('→ add nodes', function () { | ||||||
|     var node = null |     var node = null; | ||||||
|     var callback = function () {} |     var callback = function () {}; | ||||||
|     var context = {} |     var context = {}; | ||||||
|     beforeEach(function () { |     beforeEach(function () { | ||||||
|       node = new RouteNode() |       node = new RouteNode(); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ add root node', function (done) { |     it('→ add root node', function (done) { | ||||||
|       node.add([], callback, context) |       node.add([], callback, context); | ||||||
|       node.get([], [], function (err, func, cbContext, args) { |       node.get([], [], function (err, func, cbContext, args) { | ||||||
|         expect(err).toBe(null) |         expect(err).toBe(null); | ||||||
|         expect(func).toBe(callback) |         expect(func).toBe(callback); | ||||||
|         expect(cbContext).toBe(context) |         expect(cbContext).toBe(context); | ||||||
|         expect(args).toEqual([]) |         expect(args).toEqual([]); | ||||||
|         done() |         done(); | ||||||
|       }) |       }); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ get nested callback', function (done) { |     it('→ get nested callback', function (done) { | ||||||
|       node.add(['nested'], callback, context) |       node.add(['nested'], callback, context); | ||||||
|       node.get(['nested'], [], function (err, func, cbContext, args) { |       node.get(['nested'], [], function (err, func, cbContext, args) { | ||||||
|         expect(err).toBe(null) |         expect(err).toBe(null); | ||||||
|         expect(func).toBe(callback) |         expect(func).toBe(callback); | ||||||
|         expect(cbContext).toBe(context) |         expect(cbContext).toBe(context); | ||||||
|         expect(args).toEqual([]) |         expect(args).toEqual([]); | ||||||
|         done() |         done(); | ||||||
|       }) |       }); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ get error callback for not found', function (done) { |     it('→ get error callback for not found', function (done) { | ||||||
|       node.get(['fake', 'route'], [], function (err, func, cbContext, args) { |       node.get(['fake', 'route'], [], function (err, func, cbContext, args) { | ||||||
|         expect(err).toBeInstanceOf(Error) |         expect(err).toBeInstanceOf(Error); | ||||||
|         expect(err.message).toMatch(/not found/) |         expect(err.message).toMatch(/not found/); | ||||||
|         expect(func).toBeUndefined() |         expect(func).not.toBeDefined(); | ||||||
|         expect(cbContext).toBeUndefined() |         expect(cbContext).not.toBeDefined(); | ||||||
|         expect(args).toBeUndefined() |         expect(args).toBeUndefined(); | ||||||
|         done() |         done(); | ||||||
|       }) |       }); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ get route with regex', function (done) { |     it('→ get route with regex', function (done) { | ||||||
|       node.add(['by', 'id', /\d+/], callback, context) |       node.add(['by', 'id', /\d+/], callback, context); | ||||||
|       node.get(['by', 'id', '123'], [], function (err, func, cbContext, args) { |       node.get(['by', 'id', '123'], [], function (err, func, cbContext, args) { | ||||||
|         expect(err).toBe(null) |         expect(err).toBe(null); | ||||||
|         expect(func).toBe(callback) |         expect(func).toBe(callback); | ||||||
|         expect(cbContext).toBe(context) |         expect(cbContext).toBe(context); | ||||||
|         expect(args).toEqual(['123']) |         expect(args).toEqual(['123']); | ||||||
|         done() |         done(); | ||||||
|       }) |       }); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ get route with function', function (done) { |     it('→ get route with function', function (done) { | ||||||
|       function toInt(part) { |       function toInt(part) { | ||||||
|         var results = /^(\d+)$/.exec(part) |         var results = /^(\d+)$/.exec(part); | ||||||
|         if (results) { |         if (results) { | ||||||
|           return parseInt(results[0], 10) |           return parseInt(results[0], 10); | ||||||
|         } else { |         } else { | ||||||
|           return null |           return null; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       node.add(['by', 'id', toInt], callback, context) |       node.add(['by', 'id', toInt], callback, context); | ||||||
|       node.get(['by', 'id', '123'], [], function (err, func, cbContext, args) { |       node.get(['by', 'id', '123'], [], function (err, func, cbContext, args) { | ||||||
|         expect(err).toBe(null, err && err.message) |         expect(err).toBe(null, err && err.message); | ||||||
|         expect(func).toBe(callback) |         expect(func).toBe(callback); | ||||||
|         expect(cbContext).toBe(context) |         expect(cbContext).toBe(context); | ||||||
|         expect(args).toEqual([123]) |         expect(args).toEqual([123]); | ||||||
|         done() |         done(); | ||||||
|       }) |       }); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ pass arguments to handler before parsing', function (done) { |     it('→ pass arguments to handler before parsing', function (done) { | ||||||
|       var obj = {} |       var obj = {}; | ||||||
|       node.add(['id', /\d+/], callback) |       node.add(['id', /\d+/], callback); | ||||||
|       node.get(['id', '123'], [obj], function (err, cb, ctx, args) { |       node.get(['id', '123'], [obj], function (err, cb, ctx, args) { | ||||||
|         expect(args).toEqual([obj, '123']) |         expect(args).toEqual([obj, '123']); | ||||||
|         done() |         done(); | ||||||
|       }) |       }); | ||||||
|     }) |     }); | ||||||
| 
 |   }); | ||||||
|   }) | }); | ||||||
| }) |  | ||||||
|  | |||||||
| @ -1,150 +1,150 @@ | |||||||
| var expect = require('expect') | var expect = require('expect'); | ||||||
| var Router = require('../lib/router') | var Router = require('../lib/router'); | ||||||
| var NotFoundError = require('../lib/error').NotFound | var NotFoundError = require('../lib/error').NotFound; | ||||||
| 
 | 
 | ||||||
| describe('Router', function () { | describe('Router', function () { | ||||||
|   it('→ exists', function () { |   it('→ exists', function () { | ||||||
|     expect(Router).not.toBeUndefined() |     expect(Router).toBeDefined(); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ add root node', function (done) { |   it('→ add root node', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add('/', function () { return 'some value' }) |     router.add('/', function () { return 'some value'; }); | ||||||
|     router.route('/', function (err, handlerResult) { |     router.route('/', function (err, handlerResult) { | ||||||
|       expect(err).toBe(null) |       expect(err).toBe(null); | ||||||
|       expect(handlerResult).toBe('some value') |       expect(handlerResult).toBe('some value'); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ add/get nested route', function (done) { |   it('→ add/get nested route', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add('/some/path/here', function () { return 'some value' }) |     router.add('/some/path/here', function () { return 'some value'; }); | ||||||
|     router.route('/some/path/here', function (err, handlerResult) { |     router.route('/some/path/here', function (err, handlerResult) { | ||||||
|       expect(err).toBe(null) |       expect(err).toBe(null); | ||||||
|       expect(handlerResult).toBe('some value') |       expect(handlerResult).toBe('some value'); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ partial route is a not found error', function (done) { |   it('→ partial route is a not found error', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add(['/user', /^(\d+)$/], function (number) { return number }) |     router.add(['/user', /^(\d+)$/], function (number) { return number; }); | ||||||
|     router.route('/user/', function (err) { |     router.route('/user/', function (err) { | ||||||
|       expect(err).toBeInstanceOf(NotFoundError) |       expect(err).toBeInstanceOf(NotFoundError); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ get error in callback for missing handler', function (done) { |   it('→ get error in callback for missing handler', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.route('/some/fake/path', function (err, handlerResult) { |     router.route('/some/fake/path', function (err, handlerResult) { | ||||||
|       expect(err).toBeInstanceOf(Error) |       expect(err).toBeInstanceOf(Error); | ||||||
|       expect(err.message).toMatch(/not found/) |       expect(err.message).toMatch(/not found/); | ||||||
|       expect(handlerResult).toBeUndefined() |       expect(handlerResult).not.toBeDefined(); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ get routes based on regex', function (done) { |   it('→ get routes based on regex', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add(['/by/id', /\d+/], function (someId) { |     router.add(['/by/id', /\d+/], function (someId) { | ||||||
|       expect(someId).toBe('123') |       expect(someId).toBe('123'); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     router.route('/by/id/123', function (err) { |     router.route('/by/id/123', function (err) { | ||||||
|       expect(err).toBe(null, err && err.message) |       expect(err).toBe(null, err && err.message); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ regex routes can return NotFoundError', function (done) { |   it('→ regex routes can return NotFoundError', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add(['/by/id', /\d+/], function () {}) |     router.add(['/by/id', /\d+/], function () {}); | ||||||
|     router.route('/by/id/not-an-id', function (err) { |     router.route('/by/id/not-an-id', function (err) { | ||||||
|       expect(err).toBeInstanceOf(NotFoundError) |       expect(err).toBeInstanceOf(NotFoundError); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ get based on regex with multiple captures global', function (done) { |   it('→ get based on regex with multiple captures global', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add(['by', 'order', /(\d+)/g], function (one, two, three) { |     router.add(['by', 'order', /(\d+)/g], function (one, two, three) { | ||||||
|       expect(one).toBe('1') |       expect(one).toBe('1'); | ||||||
|       expect(two).toBe('2') |       expect(two).toBe('2'); | ||||||
|       expect(three).toBe('3') |       expect(three).toBe('3'); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     router.route('/by/order/1-2-3', function (err) { |     router.route('/by/order/1-2-3', function (err) { | ||||||
|       expect(err).toBe(null, err && err.message) |       expect(err).toBe(null, err && err.message); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ get based regex with multiple captures not global', function (done) { |   it('→ get based regex with multiple captures not global', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add(['by', 'order', /(\d+)/], function (one, two, three) { |     router.add(['by', 'order', /(\d+)/], function (one, two, three) { | ||||||
|       expect(one).toBe('1') |       expect(one).toBe('1'); | ||||||
|       expect(two).toBeUndefined() |       expect(two).not.toBeDefined(); | ||||||
|       expect(three).toBeUndefined() |       expect(three).not.toBeDefined(); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     router.route('/by/order/1-2-3', function (err) { |     router.route('/by/order/1-2-3', function (err) { | ||||||
|       expect(err).toBe(null, err && err.message) |       expect(err).toBe(null, err && err.message); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ pass in arguments before capturing path arguments', function (done) { |   it('→ pass in arguments before capturing path arguments', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     var api = {key: 123, any: 'object is passed', method: function () {}} |     var api = {key: 123, any: 'object is passed', method: function () {}}; | ||||||
|     router.add(['/by/order', /(\d+)/], function (inputApi, urlParam) { |     router.add(['/by/order', /(\d+)/], function (inputApi, urlParam) { | ||||||
|       expect(inputApi).toBe(api) |       expect(inputApi).toBe(api); | ||||||
|       expect(urlParam).toBe('123') |       expect(urlParam).toBe('123'); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     router.route('/by/order/123', {args: [api]}) |     router.route('/by/order/123', {args: [api]}); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   function toInt(part) { |   function toInt(part) { | ||||||
|     var results = /^(\d+)$/.exec(part) |     var results = /^(\d+)$/.exec(part); | ||||||
|     if (results) { |     if (results) { | ||||||
|       return parseInt(results[0], 10) |       return parseInt(results[0], 10); | ||||||
|     } else { |     } else { | ||||||
|       return null |       return null; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   it('→ get based on function', function (done) { |   it('→ get based on function', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add(['by', 'order', toInt], function (val) { |     router.add(['by', 'order', toInt], function (val) { | ||||||
|       expect(val).toBe(123) |       expect(val).toBe(123); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     router.route('/by/order/123', function (err) { |     router.route('/by/order/123', function (err) { | ||||||
|       expect(err).toBe(null) |       expect(err).toBe(null); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ function routes can return NotFoundError', function (done) { |   it('→ function routes can return NotFoundError', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.add(['/by/order', toInt], function () {}) |     router.add(['/by/order', toInt], function () {}); | ||||||
|     router.route('/by/order/not-found', function (err) { |     router.route('/by/order/not-found', function (err) { | ||||||
|       expect(err).toBeInstanceOf(NotFoundError) |       expect(err).toBeInstanceOf(NotFoundError); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ check not found error', function (done) { |   it('→ check not found error', function (done) { | ||||||
|     var router = new Router() |     var router = new Router(); | ||||||
|     router.route('/not/real/id', function (err) { |     router.route('/not/real/id', function (err) { | ||||||
|       expect(Router.isNotFound(err)).toBe(true) |       expect(Router.isNotFound(err)).toBe(true); | ||||||
|       done() |       done(); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   it('→ check not found error on not real error', function () { |   it('→ check not found error on not real error', function () { | ||||||
|     expect(Router.isNotFound(new Error('Not the missing error'))).toBe(false) |     expect(Router.isNotFound(new Error('Not the missing error'))).toBe(false); | ||||||
|   }) |   }); | ||||||
| }) | }); | ||||||
|  | |||||||
| @ -1,114 +1,115 @@ | |||||||
| var expect = require('expect') | var expect = require('expect'); | ||||||
| var utils = require('../lib/utils') | var utils = require('../lib/utils'); | ||||||
| 
 | 
 | ||||||
| var assign = utils.assign | var assign = utils.assign; | ||||||
| var forEach = utils.forEach | var forEach = utils.forEach; | ||||||
| var isArray = utils.isArray | var isArray = utils.isArray; | ||||||
| var isFunction = utils.isFunction | var isFunction = utils.isFunction; | ||||||
| var isRegExp = utils.isRegExp | var isRegExp = utils.isRegExp; | ||||||
| var isString = utils.isString | var isString = utils.isString; | ||||||
| var noop = utils.noop | var noop = utils.noop; | ||||||
| 
 | 
 | ||||||
| function SomeClass (foo) { | function SomeClass (foo) { | ||||||
|   this.foo = foo |   this.foo = foo; | ||||||
| } | } | ||||||
| SomeClass.prototype.bar = 'asdf' | 
 | ||||||
|  | SomeClass.prototype.bar = 'asdf'; | ||||||
| 
 | 
 | ||||||
| describe('utils', function () { | describe('utils', function () { | ||||||
|   it('→ exists', function () { |   it('→ exists', function () { | ||||||
|     expect(utils).not.toBeUndefined() |     expect(utils).not.toBeUndefined(); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ noop', function () { |   describe('→ noop', function () { | ||||||
|     it('→ is a function', function () { |     it('→ is a function', function () { | ||||||
|       expect(noop).toBeInstanceOf(Function) |       expect(noop).toBeInstanceOf(Function); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ isString', function () { |   describe('→ isString', function () { | ||||||
|     it('→ true for strings', function () { |     it('→ true for strings', function () { | ||||||
|       expect(isString('is string')).toBe(true) |       expect(isString('is string')).toBe(true); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ false for not strings', function () { |     it('→ false for not strings', function () { | ||||||
|       expect(isString(/is string/)).toBe(false) |       expect(isString(/is string/)).toBe(false); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ isRegExp', function () { |   describe('→ isRegExp', function () { | ||||||
|     it('→ true for regex', function () { |     it('→ true for regex', function () { | ||||||
|       expect(isRegExp(/some regex/)).toBe(true) |       expect(isRegExp(/some regex/)).toBe(true); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ false for strings', function () { |     it('→ false for strings', function () { | ||||||
|       expect(isRegExp('some string')).toBe(false) |       expect(isRegExp('some string')).toBe(false); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ isArray', function () { |   describe('→ isArray', function () { | ||||||
|     it('→ true for array', function () { |     it('→ true for array', function () { | ||||||
|       expect(isArray([])).toBe(true) |       expect(isArray([])).toBe(true); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ false for regex', function () { |     it('→ false for regex', function () { | ||||||
|       expect(isArray(/some regex/)).toBe(false) |       expect(isArray(/some regex/)).toBe(false); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ false for strings', function () { |     it('→ false for strings', function () { | ||||||
|       expect(isArray('some string')).toBe(false) |       expect(isArray('some string')).toBe(false); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ isFunction', function () { |   describe('→ isFunction', function () { | ||||||
|     it('→ true for function', function () { |     it('→ true for function', function () { | ||||||
|       expect(isFunction(function () {})).toBe(true) |       expect(isFunction(function () {})).toBe(true); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ false for array', function () { |     it('→ false for array', function () { | ||||||
|       expect(isFunction([])).toBe(false) |       expect(isFunction([])).toBe(false); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ false for regex', function () { |     it('→ false for regex', function () { | ||||||
|       expect(isFunction(/some regex/)).toBe(false) |       expect(isFunction(/some regex/)).toBe(false); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ false for strings', function () { |     it('→ false for strings', function () { | ||||||
|       expect(isFunction('some string')).toBe(false) |       expect(isFunction('some string')).toBe(false); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ forEach', function () { |   describe('→ forEach', function () { | ||||||
|     it('→ does not call properties on prototype', function () { |     it('→ does not call properties on prototype', function () { | ||||||
|       var count = 0 |       var count = 0; | ||||||
|       forEach(new SomeClass(123), function (key, value) { |       forEach(new SomeClass(123), function (key, value) { | ||||||
|         count += 1 |         count += 1; | ||||||
|         expect(key).toBe('foo') |         expect(key).toBe('foo'); | ||||||
|         expect(value).toBe(123) |         expect(value).toBe(123); | ||||||
|       }) |       }); | ||||||
|       expect(count).toEqual(1) |       expect(count).toEqual(1); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| 
 | 
 | ||||||
|   describe('→ assign', function () { |   describe('→ assign', function () { | ||||||
|     it('→ adds properties to dest', function () { |     it('→ adds properties to dest', function () { | ||||||
|       var dest = {} |       var dest = {}; | ||||||
|       var src = {foo: 123, bar: 'asdf'} |       var src = {foo: 123, bar: 'asdf'}; | ||||||
|       assign(dest, src) |       assign(dest, src); | ||||||
|       expect(dest).toEqual({foo: 123, bar: 'asdf'}) |       expect(dest).toEqual({foo: 123, bar: 'asdf'}); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ overrides properties to dest', function () { |     it('→ overrides properties to dest', function () { | ||||||
|       var dest = {foo: 456, bar: 'qwerty', blah: /foo/} |       var dest = {foo: 456, bar: 'qwerty', blah: /foo/}; | ||||||
|       var src = {foo: 123, bar: 'asdf'} |       var src = {foo: 123, bar: 'asdf'}; | ||||||
|       assign(dest, src) |       assign(dest, src); | ||||||
|       expect(dest).toEqual({foo: 123, bar: 'asdf', blah: /foo/}) |       expect(dest).toEqual({foo: 123, bar: 'asdf', blah: /foo/}); | ||||||
|     }) |     }); | ||||||
| 
 | 
 | ||||||
|     it('→ does not overrides properties on prototype', function () { |     it('→ does not overrides properties on prototype', function () { | ||||||
|       var dest = {foo: 456, bar: 'qwerty', blah: /foo/} |       var dest = {foo: 456, bar: 'qwerty', blah: /foo/}; | ||||||
|       assign(dest, new SomeClass(123)) |       assign(dest, new SomeClass(123)); | ||||||
| 
 | 
 | ||||||
|       expect(dest).toEqual({foo: 123, bar: 'qwerty', blah: /foo/}) |       expect(dest).toEqual({foo: 123, bar: 'qwerty', blah: /foo/}); | ||||||
|     }) |     }); | ||||||
|   }) |   }); | ||||||
| }) | }); | ||||||
|  | |||||||
					Loading…
					
					
				
		Reference in New Issue
	
	 Buddy Sandidge
						Buddy Sandidge