Skip to content

Commit

Permalink
feat(serverHistory): create a server History class
Browse files Browse the repository at this point in the history
Allow for server side routing using a history object designed
to work without the browser.
Switch all the tests to use the serverHistory class instead of the previous mock.
  • Loading branch information
TylorS committed Feb 4, 2016
1 parent 3c792dd commit 121288c
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 33 deletions.
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export {makeRouterDriver} from './makeRouterDriver'
export {supportsHistory} from './util'
export {supportsHistory, createLocation} from './util'
export {createServerHistory} from './serverHistory'
2 changes: 1 addition & 1 deletion src/pathFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {createAPI} from './api'
import {splitPath} from './util'

function isStrictlyInScope(namespace, path) {
const pathParts = path.split('/').filter(x => x.length > 0)
const pathParts = splitPath(path)
return namespace.every((v, i) => {
return pathParts[i] === v
})
Expand Down
27 changes: 27 additions & 0 deletions src/serverHistory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {createLocation} from './util'

function ServerHistory() {}

ServerHistory.prototype.listen = function listen(listener) {
this.listener = listener
}

ServerHistory.prototype.push = function push(location) {
const listener = this.listener
if (!listener) {
throw new Error('There is no active listener')
}
listener(createLocation(location))
}

ServerHistory.prototype.createHref = function createHref(path) {
return path
}

ServerHistory.prototype.createLocation = createLocation

function createServerHistory() {
return new ServerHistory()
}

export {createServerHistory}
26 changes: 25 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ function supportsHistory() {

if (typeof window !== `undefined`) {
return window.history && `pushState` in window.history
} else {
return false
}
}

Expand All @@ -35,4 +37,26 @@ function makeCreateHref(namespace, createHref) {
}
}

export {supportsHistory, splitPath, filterPath, makeCreateHref}
const locationDefaults = {
pathname: '/',
action: 'POP',
hash: '',
search: '',
state: null,
key: null,
}

function createLocation(location = locationDefaults) {
if (typeof location === 'string') {
return Object.assign(locationDefaults, {pathname: location})
}
return Object.assign(locationDefaults, location)
}

export {
supportsHistory,
splitPath,
filterPath,
makeCreateHref,
createLocation,
}
14 changes: 0 additions & 14 deletions test/helper/mockHistory.js

This file was deleted.

42 changes: 26 additions & 16 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint max-nested-callbacks: 0 */
import {describe, it} from 'mocha'
import assert from 'assert'
import {createMockHistory} from './helper/mockHistory'
import {makeRouterDriver} from '../src'
import {makeRouterDriver, createServerHistory} from '../src'

describe('Cyclic Router', () => {
describe('makeRouterDriver', () => {
Expand All @@ -14,15 +13,15 @@ describe('Cyclic Router', () => {

it('should accept any object with a listen() method', () => {
assert.doesNotThrow(() => {
makeRouterDriver(createMockHistory())
makeRouterDriver(createServerHistory())
})
})

describe('routerDriver', () => {
it('should return an object with `path` `define` `observable` ' +
'`createHref` and `dispose`',
() => {
const router = makeRouterDriver(createMockHistory())()
const router = makeRouterDriver(createServerHistory())()
assert.notStrictEqual(router.path, null)
assert.strictEqual(typeof router.path, 'function')
assert.notStrictEqual(router.define, null)
Expand All @@ -42,7 +41,7 @@ describe('Cyclic Router', () => {
it('should return an object with `path` `define` `observable` ' +
'`createHref` and `dispose`',
() => {
const router = makeRouterDriver(createMockHistory())().path('/')
const router = makeRouterDriver(createServerHistory())().path('/')
assert.notStrictEqual(router.path, null)
assert.strictEqual(typeof router.path, 'function')
assert.notStrictEqual(router.define, null)
Expand All @@ -61,7 +60,7 @@ describe('Cyclic Router', () => {
'/somewhere/else',
'/path/that/is/correct',
]
const history = createMockHistory(routes)
const history = createServerHistory(routes)
const router = makeRouterDriver(history)().path('/path')

router.observable.subscribe((location) => {
Expand All @@ -77,7 +76,7 @@ describe('Cyclic Router', () => {
'/some/really/really/deeply/nested/incorrect/route',
]

const history = createMockHistory(routes)
const history = createServerHistory(routes)
const router = makeRouterDriver(history)()
.path('/some').path('/really').path('/really').path('/deeply')
.path('/nested').path('/route').path('/that')
Expand All @@ -95,7 +94,7 @@ describe('Cyclic Router', () => {
'/some/really/really/deeply/nested/incorrect/route',
]

const history = createMockHistory(routes)
const history = createServerHistory(routes)
const router = makeRouterDriver(history)()
.path('/some').path('/really').path('/really').path('/deeply')
.path('/nested').path('/route').path('/that')
Expand All @@ -116,7 +115,7 @@ describe('Cyclic Router', () => {
'/some/really/really/deeply/nested/incorrect/route',
]

const history = createMockHistory(routes)
const history = createServerHistory(routes)
const router = makeRouterDriver(history)()
.path('/some').path('/really').path('/really').path('/deeply')
.path('/nested').path('/route').path('/that')
Expand All @@ -131,7 +130,7 @@ describe('Cyclic Router', () => {
it('should return an object with `path$` `value$` `fullPath$` ' +
'`createHref` and `dispose`',
() => {
const router = makeRouterDriver(createMockHistory())().define({})
const router = makeRouterDriver(createServerHistory())().define({})
assert.notStrictEqual(router.path$, null)
assert.strictEqual(typeof router.path$, 'object')
assert.strictEqual(typeof router.path$.subscribe, 'function')
Expand All @@ -157,7 +156,7 @@ describe('Cyclic Router', () => {
const routes = [
'/some/route',
]
const history = createMockHistory(routes)
const history = createServerHistory()
const {path$, value$, fullPath$} =
makeRouterDriver(history)().define(defintion)

Expand All @@ -173,6 +172,8 @@ describe('Cyclic Router', () => {
assert.strictEqual(fullPath, '/some/route')
setTimeout(done, 10)
})

routes.forEach(r => history.push(r))
})

it('should respect prior filtering by path()', done => {
Expand All @@ -187,7 +188,7 @@ describe('Cyclic Router', () => {
'/some/nested/correct/route',
'/wrong/route',
]
const history = createMockHistory(routes)
const history = createServerHistory()
const {path$, value$, fullPath$} = makeRouterDriver(history)()
.path('/some').path('/nested').define(defintion)

Expand All @@ -203,6 +204,8 @@ describe('Cyclic Router', () => {
assert.strictEqual(fullPath, '/some/nested/correct/route')
setTimeout(done, 10)
})

routes.forEach(r => history.push(r))
})

it('should match a default route if one is not found', done => {
Expand All @@ -218,7 +221,7 @@ describe('Cyclic Router', () => {
'/some/nested/incorrect/route',
'/wrong/route',
]
const history = createMockHistory(routes)
const history = createServerHistory()
const {path$, value$, fullPath$} = makeRouterDriver(history)()
.path('/some').path('/nested').define(defintion)

Expand All @@ -234,6 +237,8 @@ describe('Cyclic Router', () => {
assert.strictEqual(fullPath, '/some/nested/incorrect/route')
setTimeout(done, 10)
})

routes.forEach(r => history.push(r))
})

it('should create a proper href using createHref()', done => {
Expand All @@ -250,7 +255,7 @@ describe('Cyclic Router', () => {
'/wrong/route',
]

const history = createMockHistory(routes)
const history = createServerHistory()
const {fullPath$, createHref} = makeRouterDriver(history)()
.path('/some').path('/nested').define(defintion)

Expand All @@ -259,6 +264,8 @@ describe('Cyclic Router', () => {
assert.strictEqual(createHref('/correct/route'), pathname)
setTimeout(done, 5)
})

routes.forEach(r => history.push(r))
})

it('should match partials', done => {
Expand All @@ -275,7 +282,7 @@ describe('Cyclic Router', () => {
'/wrong/route',
]

const history = createMockHistory(routes)
const history = createServerHistory()
const {path$, fullPath$} = makeRouterDriver(history)()
.path('/some').path('/nested').define(defintion)

Expand All @@ -287,6 +294,8 @@ describe('Cyclic Router', () => {
assert.strictEqual(pathname, '/some/nested/correct/route/partial')
setTimeout(done, 5)
})

routes.forEach(r => history.push(r))
})

it('should not work after being disposed', done => {
Expand All @@ -303,12 +312,13 @@ describe('Cyclic Router', () => {
'/wrong/route',
]

const history = createMockHistory(routes)
const history = createServerHistory()
const {fullPath$, dispose} = makeRouterDriver(history)()
.path('/some').path('/nested').define(defintion)

dispose()
fullPath$.subscribe(done.fail)
routes.forEach(r => history.push(r))
setTimeout(done, 10)
})
})
Expand Down

0 comments on commit 121288c

Please sign in to comment.