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