Skip to content

Commit

Permalink
full test coverage + several fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
TitanNano committed Feb 26, 2017
1 parent 8422c6a commit 38f02c6
Show file tree
Hide file tree
Showing 21 changed files with 495 additions and 183 deletions.
154 changes: 154 additions & 0 deletions .travis/RouteChange.js
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);
});
});
});
214 changes: 214 additions & 0 deletions .travis/Router.js
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;
});
});
});
Loading

0 comments on commit 38f02c6

Please sign in to comment.