Skip to content

Commit

Permalink
[feat] Routes as Map
Browse files Browse the repository at this point in the history
Keeps Sorted Order in Place.
  • Loading branch information
scott-wyatt committed Jul 19, 2018
1 parent 324ea45 commit bace812
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 22 deletions.
4 changes: 2 additions & 2 deletions lib/RouterSpool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as pkg from '../package.json'
* @see https://github.com/fabrix-app/spool-hapi
*/
export class RouterSpool extends SystemSpool {
private _routes = {}
private _routes: Map<string, {[key: string]: any}> // = new Map

constructor (app) {
super(app, {
Expand Down Expand Up @@ -63,7 +63,7 @@ export class RouterSpool extends SystemSpool {
/**
* Get's the routes from spool-router
*/
get routes(): {[key: string]: any} {
get routes(): Map<string, {[key: string]: any}> {
return this._routes
}

Expand Down
3 changes: 2 additions & 1 deletion lib/config/router.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const router = {
prefix: null,
sortOrder: 'asc'
sortOrder: 'asc',
debug: false
}
3 changes: 2 additions & 1 deletion lib/schemas/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ import * as joi from 'joi'

export const routerSchema = joi.object().keys({
sortOrder: joi.string().allow('asc', 'desc').required(),
prefix: joi.string().allow('', null).required()
prefix: joi.string().allow('', null).required(),
debug: joi.any()
})
20 changes: 14 additions & 6 deletions lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ export const Utils = {
*/
buildRoute (app: FabrixApp, path: string, rawRoute: IRoute) {
const orgRoute = Object.assign({ }, rawRoute)
orgRoute._orgPath = path
orgRoute.config = orgRoute.config || (orgRoute.config = { })
orgRoute.config.pre = orgRoute.config.pre || (orgRoute.config.pre = [ ])

if (app.config.get('router.debug')) {
orgRoute._orgPath = path
}

path = Utils.getPathFromRoute(app, path, orgRoute)

if (app.config.get('router.debug')) {
orgRoute._newPath = path
}

Utils.getHandlerFromString(app, orgRoute)

orgRoute.config.pre = orgRoute.config.pre
Expand Down Expand Up @@ -183,10 +191,10 @@ export const Utils = {
* Sort a route collection by object key
*/
sortRoutes(routes, order) {
const toReturn = {}
const toReturn = new Map
const sorted = Object.keys(routes).sort(Utils.createSpecificityComparator({ order: order }))
sorted.forEach((r, i) => {
toReturn[r] = routes[r]
toReturn.set(r, routes[r])
})
return toReturn
},
Expand Down Expand Up @@ -215,19 +223,19 @@ export const Utils = {
|| routeA === catchAllRoute
) {
return asc ? 1 : -1
// Also push index route down to end, but not past the default
}
// Also push index route down to end, but not past the default
else if (
routeB === defaultRoute
|| routeB === catchAllRoute
) {
return asc ? -1 : 1
// Also push index route down to end, but not past the default
}
// Also push index route down to end, but not past the default
else if (/^\/$/.test(routeA) && (routeB !== defaultRoute && routeB !== catchAllRoute)) {
return asc ? 1 : -1
// Otherwise, sort based on either depth or free variable priority
}
// Otherwise, sort based on either depth or free variable priority
else {
const slicedA = routeA.split('/') // .normalize('/' + routeA + '/').split('/').join('/')
const slicedB = routeB.split('/') // .normalize('/' + routeB + '/').split('/').join('/')
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ module.exports = {
customPrefixer: {
prefix: '/prefix'
},
router: {
debug: true
},
routes: {
'/test/foo': {
'GET': 'TestController.foo'
Expand Down
10 changes: 5 additions & 5 deletions test/integration/spool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ describe('Router Spool', () => {
// assert(_.isFunction(routes[2].handler))
// assert(_.isPlainObject(routes[3].handler))

assert(global.app.routes['/test/foo1'])
assert(global.app.routes['/test/foo2'])
assert(global.app.routes['/prefix/test/custom/prefix'])
assert(global.app.routes.get('/test/foo1'))
assert(global.app.routes.get('/test/foo2'))
assert(global.app.routes.get('/prefix/test/custom/prefix'))

assert.equal(Object.keys(global.app.routes).length, 9)
assert.equal(global.app.routes.size, 9)
})
})

describe('route #config', () => {

it('tags could be an array', () => {
const routes = global.app.routes
const route = routes['/test/foo/tags']
const route = routes.get('/test/foo/tags')
assert(_.isObject(route.GET.config))
assert(_.isArray(route.GET.config.tags))
assert(_.includes(route.GET.config.tags, 'test', 'other'))
Expand Down
134 changes: 127 additions & 7 deletions test/unit/lib/routeSortOrder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ const sort = require('../../../dist/utils').Utils.sortRoutes
describe('Utils Route Sort Order', () => {
it('should exist', () => {
assert(routeOrder)
assert(sort)
})
it('should sort the routes for free variables', () => {
it('should sort the routes for free variables (express style)', () => {
let routes = {
'/a': {},
'/a/:id': {},
Expand All @@ -24,9 +25,11 @@ describe('Utils Route Sort Order', () => {
'/b/*': {}
}

routes = sort(routes, {order: 'asc'})

assert.deepEqual(routes, {
routes = sort(routes, 'asc')
assert(routes)
console.log(routes)
const ordered = new Map()
const order = {
'/a': {},
'/a/:id': {},
'/a/*': {},
Expand All @@ -38,11 +41,15 @@ describe('Utils Route Sort Order', () => {
'/b/:id/:world': {},
'/b/:id/*': {},
'/': {},
'*': {}
'*': {},
}
Object.keys(order).forEach(k => {
ordered.set(k, order[k])
})
assert.deepEqual(routes, ordered)
})

it('should sort the routes for free variables', () => {
it('should sort the routes for free variables (hapi style)', () => {
let routes = {
'/a': {},
'/a/{id}': {},
Expand All @@ -59,8 +66,49 @@ describe('Utils Route Sort Order', () => {
}

routes = sort(routes, 'asc')
assert(routes)

const ordered = new Map()
const order = {
'/a': {},
'/a/{id}': {},
'/a/*': {},
'/a/{id}/{world}': {},
'/a/{id}/*': {},
'/b': {},
'/b/{id}': {},
'/b/*': {},
'/b/{id}/{world}': {},
'/b/{id}/*': {},
'/': {},
'*': {},
}
Object.keys(order).forEach(k => {
ordered.set(k, order[k])
})
assert.deepEqual(routes, ordered)
})

it('should sort the routes for free variables desc', () => {
let routes = {
'/a': {},
'/a/{id}': {},
'/a/*': {},
'/b': {},
'/a/{id}/{world}': {},
'/a/{id}/*': {},
'*': {},
'/b/{id}/{world}': {},
'/': {},
'/b/{id}/*': {},
'/b/{id}': {},
'/b/*': {},
}

assert.deepEqual(routes, {
routes = sort(routes, 'desc')
assert(routes)
const ordered = new Map()
const order = {
'/a': {},
'/a/{id}': {},
'/a/*': {},
Expand All @@ -73,6 +121,78 @@ describe('Utils Route Sort Order', () => {
'/b/{id}/*': {},
'/': {},
'*': {},
}
Object.keys(order).forEach(k => {
ordered.set(k, order[k])
})
assert.deepEqual(routes, ordered)
})

it('should sort the routes for free variables asc', () => {
let routes = {
'/a': {},
'/a/{id}': {},
'/a/*': {},
'/b': {},
'/a/{id}/{world}': {},
'/a/{id}/*': {},
'*': {},
'/b/{id}/{world}': {},
'/': {},
'/b/{id}/*': {},
'/b/{id}': {},
'/b/*': {},
}

const order = Object.keys(routes).sort(routeOrder({order: 'asc'}))
assert.deepEqual(order, [
'/a',
'/a/{id}',
'/a/*',
'/a/{id}/{world}',
'/a/{id}/*',
'/b',
'/b/{id}',
'/b/*',
'/b/{id}/{world}',
'/b/{id}/*',
'/',
'*',
])
})

// TODO
it.skip('should sort the routes for free variables desc', () => {
let routes = {
'/a': {},
'/a/{id}': {},
'/a/*': {},
'/b': {},
'/a/{id}/{world}': {},
'/a/{id}/*': {},
'*': {},
'/b/{id}/{world}': {},
'/': {},
'/b/{id}/*': {},
'/b/{id}': {},
'/b/*': {},
}

const order = Object.keys(routes).sort(routeOrder({order: 'desc'}))
console.log('BROKE', order)
assert.deepEqual(order, [
'*',
'/',
'/b/{id}/*',
'/b/{id}/{world}',
'/b/*',
'/b/{id}',
'/b',
'/a/{id}/*',
'/a/{id}/{world}',
'/a/*',
'/a/{id}',
'/a'
])
})
})

0 comments on commit bace812

Please sign in to comment.