-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
495 additions
and
183 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/* eslint-env mocha */ | ||
const { expect } = require('chai'); | ||
const istanbulVM = require('./istanbulVM'); | ||
const RouteChangeType = require('../testable/lib/RouteChangeType').default; | ||
|
||
describe('RouteChange', () => { | ||
const validTestRegExp = /^\/test\/([^\/#?]+)\/page\/([^\/#?]+)\/dialog\/([^\/#?]+)$/; | ||
const vm = istanbulVM(); | ||
let result = null; | ||
|
||
describe('::transfromPathToRegExp', () => { | ||
|
||
it('should return an object', () => { | ||
vm.runModule('../testable/lib/RouteChange'); | ||
result = vm.runModule('./tests/RouteChange_transformPathToRegExp'); | ||
|
||
expect(result.global.result).to.have.property('regExp'); | ||
expect(result.global.result).to.have.property('paramsCollector'); | ||
}); | ||
|
||
it('should return the right regEx', () => { | ||
expect(result.global.result.regExp.source) | ||
.to.be.equal(validTestRegExp.source); | ||
}); | ||
|
||
it('should collect all params', () => { | ||
expect(Object.keys(result.global.result.paramsCollector)).to.have.lengthOf(3, 3); | ||
}); | ||
}); | ||
|
||
describe('::populateStateParamValues', () => { | ||
it('should populate the route params', () => { | ||
result = vm.runModule('./tests/RouteChange_populateStateParamValues_1'); | ||
|
||
expect(result.global.result).to.have.property('param1', '108978234'); | ||
expect(result.global.result).to.have.property('param2', 'id-24397876'); | ||
expect(result.global.result).to.have.property('param3', 'BigWhiteThing'); | ||
}); | ||
|
||
it('should work fine if there are no params to collect', () => { | ||
result = vm.runModule('./tests/RouteChange_populateStateParamValues_2'); | ||
|
||
expect(result.global.result).to.be.empty; | ||
}); | ||
}); | ||
|
||
describe('::routeItemWasEntered', () => { | ||
it('should not enter if the path doesn\'t match!', () => { | ||
result = vm.runModule('./tests/RouteChange_routeItemWasEntered_1'); | ||
|
||
expect(result.global.result).to.not.be.ok; | ||
}); | ||
|
||
it('should enter if the path matches', () => { | ||
result = vm.runModule('./tests/RouteChange_routeItemWasEntered_2'); | ||
|
||
expect(result.global.result).to.be.ok; | ||
}); | ||
|
||
it('should not enter if the path matches, is persistent and active', () => { | ||
result = vm.runModule('./tests/RouteChange_routeItemWasEntered_3'); | ||
|
||
expect(result.global.result).to.not.be.ok; | ||
}); | ||
}); | ||
|
||
describe('::routeItemWasLost', () => { | ||
it('should be lost if the path matches', () => { | ||
result = vm.runModule('./tests/RouteChange_routeItemWasLost_1'); | ||
|
||
expect(result.global.result).to.be.ok; | ||
}); | ||
}); | ||
|
||
const executedActions = [false, false, false]; | ||
|
||
const state = { actions : [{ | ||
path: '/home/rooms/place/1', | ||
persistent: false, | ||
active: false, | ||
enter() { executedActions[0] = 'enter_0'; }, | ||
leave() { executedActions[0] = 'leave_0'; } | ||
}, { | ||
path: '/home/rooms/place/1/info', | ||
persistent: true, | ||
active: false, | ||
enter() { executedActions[1] = 'enter_1'; }, | ||
leave() { executedActions[1] = 'leave_1'; }, | ||
}, { | ||
path: '/work/about', | ||
persistent: true, | ||
active: true, | ||
enter() { executedActions[2] = 'enter_2'; }, | ||
leave() { executedActions[2] = 'leave_2'; }, | ||
}], overrides : {}, }; | ||
|
||
describe('constructor', () => { | ||
const type = RouteChangeType.ADD; | ||
const path = '/home/rooms/place/1'; | ||
|
||
vm._context.global.params = { type: type, path : path, state: state }; | ||
|
||
it('should construct a new RouteChange object', () => { | ||
result = vm.runModule('./tests/RouteChange_constructor'); | ||
|
||
expect(result.global.routeChange).to.have.property('type', type); | ||
expect(result.global.routeChange).to.have.property('path', path); | ||
expect(result.global.routeChange).to.have.property('state', state); | ||
}); | ||
}); | ||
|
||
describe('trigger', () => { | ||
it('should enter the action that matches the current path', () => { | ||
executedActions[0] = executedActions[1] = executedActions[2] = false; | ||
|
||
vm.runModule('./tests/RouteChange_trigger_1'); | ||
|
||
expect(executedActions).to.be.eql(['enter_0', false, false]); | ||
}); | ||
|
||
it('should enter the persistent state, but not if it already active', () => { | ||
const path = '/home/rooms/place/1/info'; | ||
|
||
vm._context.global.routeChange.path = path; | ||
executedActions[0] = executedActions[1] = executedActions[2] = false; | ||
|
||
vm.runModule('./tests/RouteChange_trigger_1'); | ||
|
||
expect(executedActions).to.be.eql([false, 'enter_1', false]); | ||
}); | ||
|
||
it('should not enter a persistent and already active state', () => { | ||
const path = '/home/rooms/place/1/info'; | ||
executedActions[0] = executedActions[1] = executedActions[2] = false; | ||
|
||
vm._context.global.routeChange.path = path; | ||
vm.runModule('./tests/RouteChange_trigger_1'); | ||
|
||
expect(executedActions).to.be.eql([false, false, false]); | ||
}); | ||
|
||
it('should error if an invalid change type was set', () => { | ||
const path = '/home/rooms/place/1'; | ||
executedActions[0] = executedActions[1] = executedActions[2] = false; | ||
|
||
vm._context.routeChange.type = 123; | ||
vm._context.routeChange.path = path; | ||
result = vm.runModule('./tests/RouteChange_trigger_1'); | ||
|
||
expect(executedActions).to.be.eql([false, false, false]); | ||
expect(result.console.stats.error).to.be.equal(1); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
/* eslint-env mocha */ | ||
|
||
const { expect } = require('chai'); | ||
const istanbulVM = require('./istanbulVM'); | ||
|
||
describe('Router', () => { | ||
const triggerTracker = [false, false, false]; | ||
|
||
const vm = istanbulVM({ | ||
testActions: [{ | ||
path: '/home/pages/p1', | ||
onEnter() { triggerTracker[0] = 'enter_0'; }, | ||
onLeave() { triggerTracker[0] = 'leave_0'; }, | ||
isPersistent: false, | ||
}, { | ||
path: '/home/pages/p1/info', | ||
onEnter() { triggerTracker[1] = 'enter_1'; }, | ||
onLeave() { triggerTracker[1] = 'leave_1'; }, | ||
isPersistent: true, | ||
}, { | ||
path: ['/', '/home'], | ||
onEnter() { triggerTracker[2] = 'enter_2'; }, | ||
onLeave() { triggerTracker[2] = 'leave_2'; }, | ||
isPersistent: false, | ||
}], | ||
|
||
Event: function() {}, | ||
|
||
window: { | ||
location: { hash: '/start' }, | ||
localStorage: { | ||
store: {}, | ||
setItem(key, value) { | ||
this.store[key] = value; | ||
}, | ||
|
||
getItem(key) { | ||
return this.store[key]; | ||
} | ||
}, | ||
|
||
eventDispatched: false, | ||
|
||
dispatchEvent() { this.eventDispatched = true; }, | ||
|
||
addEventListener(name, fn) { | ||
this[name] = fn; | ||
} | ||
} | ||
}); | ||
|
||
describe('init', () => { | ||
it('should init all submitted states', () => { | ||
vm.runModule('../testable/lib/Router'); | ||
const result = vm.runModule('./tests/Router/init'); | ||
|
||
expect(result.Router.state.actions).to.have.lengthOf(4); | ||
expect(result.window.hashchange).to.be.a('function'); | ||
}); | ||
}); | ||
|
||
describe('addRoutable', () => { | ||
it('should add a new Routable object', () => { | ||
const result = vm.runModule('./tests/Router/addRoutable'); | ||
|
||
expect(result.Router.state.actions[result.Router.state.actions.length - 1].path) | ||
.to.be.equal('/home/routable/page/1'); | ||
}); | ||
}); | ||
|
||
describe('down', () => { | ||
it('should append a new segment to the path', () => { | ||
expect(vm._context.window.location.hash).to.be.equal('/start'); | ||
|
||
const result = vm.runModule('./tests/Router/down'); | ||
|
||
expect(result.window.location.hash).to.be.equal('/start/second'); | ||
}); | ||
}); | ||
|
||
describe('remove', () => { | ||
it('should remove the action at the given id', () => { | ||
expect(vm._context.Router.state.actions).to.have.lengthOf(5); | ||
|
||
const result = vm.runModule('./tests/Router/remove'); | ||
|
||
expect(result.Router.state.actions).to.have.lengthOf(4); | ||
}); | ||
}); | ||
|
||
describe('routeChanged', () => { | ||
it('should enter the first and third state', () => { | ||
vm.runModule('./tests/Router/routeChanged_1'); | ||
|
||
expect(triggerTracker).to.be.eql(['enter_0', false, 'enter_2']); | ||
}); | ||
|
||
it('should leave the first state when navigating up', () => { | ||
triggerTracker[0] = triggerTracker[1] = triggerTracker[2] = false; | ||
|
||
vm.runModule('./tests/Router/routeChanged_2'); | ||
|
||
expect(triggerTracker).to.be.eql(['leave_0', false, false]); | ||
}); | ||
|
||
it('should not leave persistent states', () => { | ||
vm.runModule('./tests/Router/routeChanged_3'); | ||
|
||
triggerTracker[0] = triggerTracker[1] = triggerTracker[2] = false; | ||
|
||
vm.runModule('./tests/Router/routeChanged_2'); | ||
|
||
expect(triggerTracker).to.be.eql(['leave_0', false, false]); | ||
}); | ||
|
||
it('should redirect when trying to navigate into an overwritten state', () => { | ||
triggerTracker[0] = triggerTracker[1] = triggerTracker[2] = false; | ||
|
||
expect(vm._context.window.location.hash).to.be.equal('#!/home'); | ||
|
||
vm.runModule('./tests/Router/routeChanged_1'); | ||
const result = vm.runModule('./tests/Router/routeChanged_4'); | ||
|
||
expect(triggerTracker).to.be.eql(['enter_0', false, false]); | ||
expect(result.window.location.hash).to.be.equal('#!/home/pages/p1/info'); | ||
}); | ||
|
||
it('should leave a persistent state if we actively navigate out of it', () => { | ||
triggerTracker[0] = triggerTracker[1] = triggerTracker[2] = false; | ||
|
||
vm.runModule('./tests/Router/routeChanged_1'); | ||
|
||
expect(triggerTracker).to.be.eql([false, 'leave_1', false]); | ||
}); | ||
}); | ||
|
||
describe('up', () => { | ||
it('should dop the lowest element in the path', () => { | ||
vm._context.window.location.hash = '#!/home/pages/p2'; | ||
|
||
const result = vm.runModule('./tests/Router/up'); | ||
|
||
expect(result.window.location.hash).to.be.equal('#!/home/pages'); | ||
}); | ||
}); | ||
|
||
describe('validateRoutePath', () => { | ||
it('should throw if the hash path is invalid', () => { | ||
const result = vm.runModule('./tests/Router/validateRoutePath'); | ||
|
||
expect(result.console.stats.error).to.be.equal(1); | ||
}); | ||
}); | ||
|
||
describe('switchTo', () => { | ||
it('should switch to the given path', () => { | ||
const result = vm.runModule('./tests/Router/switchTo'); | ||
|
||
expect(result.window.location.hash).to.be.equal('#!/test/path'); | ||
}); | ||
}); | ||
|
||
describe('restore', () => { | ||
it('should restore the last path if no path is currently set', () => { | ||
vm._context.window.location.hash = ''; | ||
vm._context.window.localStorage.store['af.router.backup'] = '/backed/path/in/storage'; | ||
|
||
const result = vm.runModule('./tests/Router/restore'); | ||
|
||
expect(result.window.location.hash).to.be.equal('#!/backed/path/in/storage'); | ||
}); | ||
|
||
it('should not restore from backup if there is already a path set', () => { | ||
vm._context.window.location.hash = '#!/test/path/a1'; | ||
|
||
const result = vm.runModule('./tests/Router/restore'); | ||
|
||
expect(result.window.eventDispatched).to.be.true; | ||
}); | ||
|
||
it('should just simply trigger if there is no backup', () => { | ||
vm._context.window.location.hash = ''; | ||
vm._context.window.localStorage.store = {}; | ||
vm._context.window.eventDispatched = false; | ||
|
||
let result = vm.runModule('./tests/Router/restore'); | ||
|
||
expect(result.window.location.hash).to.be.empty; | ||
expect(result.window.eventDispatched).to.be.true; | ||
|
||
result = vm.runModule('./tests/Router/getCurrentPath'); | ||
|
||
expect(result.currentPath).to.be.eql(['#!', '']); | ||
}); | ||
}); | ||
|
||
describe('triggerGoogleAnalytics', () => { | ||
it('should trigger google analytics if available', () => { | ||
vm._context.window.location = { | ||
protocol: 'https:', | ||
host: 'example.org', | ||
pathname: '/test/', | ||
search: '?test=1', | ||
hash: '#test' | ||
}; | ||
|
||
vm._context.window.ga = function() { vm._context.window.ga.triggered = true; }; | ||
|
||
const result = vm.runModule('./tests/Router/triggerGoogleAnalytics'); | ||
|
||
expect(result.window.ga.triggered).to.be.true; | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.