Add some comments and handle edge cases

This commit is contained in:
Arunoda Susiripala 2016-04-06 20:40:55 +05:30
parent bfed1ebc95
commit 80adb2fa8d
12 changed files with 12 additions and 1539 deletions

View File

@ -1,12 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setWindow = setWindow;
function setWindow(search) {
global.window = {
location: { search: search },
addEventListener: function addEventListener() {}
};
}

View File

@ -1,156 +0,0 @@
'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
var _chai = require('chai');
var _client_api = require('../client_api');
var _client_api2 = _interopRequireDefault(_client_api);
var _sinon = require('sinon');
var _sinon2 = _interopRequireDefault(_sinon);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _global = global;
var describe = _global.describe;
var it = _global.it;
function getClientApi() {
var syncedStore = { aa: 30 };
var storyStore = { aa: 10 };
var api = new _client_api2.default({ syncedStore: syncedStore, storyStore: storyStore });
return api;
}
describe('client.ClientApi', function () {
describe('constructor', function () {
it('should set _syncedStore & _storyStore properly', function () {
var syncedStore = { aa: 30 };
var storyStore = { aa: 10 };
var api = new _client_api2.default({ syncedStore: syncedStore, storyStore: storyStore });
(0, _chai.expect)(api._syncedStore).to.be.equal(syncedStore);
(0, _chai.expect)(api._storyStore).to.be.equal(storyStore);
});
});
describe('storiesOf', function () {
it('should return an api where we can add stories', function () {
var api = getClientApi();
var chainApi = api.storiesOf('kind');
(0, _chai.expect)((0, _typeof3.default)(chainApi.add)).to.be.equal('function');
});
it('should remove story of the given kind, when hot module is disposing', function () {
var doDispose = null;
var hotModule = {
hot: {
dispose: function dispose(fn) {
doDispose = fn;
}
}
};
var api = getClientApi();
api._storyStore.removeStoryKind = _sinon2.default.stub();
api.storiesOf('kind', hotModule);
doDispose();
(0, _chai.expect)(api._storyStore.removeStoryKind.args[0][0]).to.be.equal('kind');
});
});
describe('storiesOf.add', function () {
it('should add a given story', function () {
var api = getClientApi();
var handle = function handle() {};
api._storyStore.addStory = _sinon2.default.stub();
api.storiesOf('kind').add('name', handle);
var args = api._storyStore.addStory.args[0];
(0, _chai.expect)(args[0]).to.be.equal('kind');
(0, _chai.expect)(args[1]).to.be.equal('name');
(0, _chai.expect)(args[2]).to.be.equal(handle);
});
it('should support method chaining', function () {
var api = getClientApi();
var handle = function handle() {};
api._storyStore.addStory = _sinon2.default.stub();
api.storiesOf('kind').add('name', handle).add('name2', handle);
});
});
describe('action', function () {
it('should send action info to the syncedStore', function () {
var api = getClientApi();
api._syncedStore.getData = function () {
return { actions: [] };
};
api._syncedStore.setData = _sinon2.default.stub();
var cb = api.action('hello');
cb(10, 20);
var args = api._syncedStore.setData.args[0];
(0, _chai.expect)(args[0].actions).to.be.deep.equal([{
name: 'hello',
args: [10, 20]
}]);
});
it('should only keep the latest 5 actions in the syncedStore', function () {
var api = getClientApi();
api._syncedStore.getData = function () {
return {
actions: [50, 40, 30, 20, 10]
};
};
api._syncedStore.setData = _sinon2.default.stub();
var cb = api.action('hello');
cb(10, 20);
var args = api._syncedStore.setData.args[0];
(0, _chai.expect)(args[0].actions).to.be.deep.equal([{
name: 'hello',
args: [10, 20]
}, 50, 40, 30, 20]);
});
it('should replace any Synthetic Event with it\'s name', function () {
var api = getClientApi();
api._syncedStore.getData = function () {
return { actions: [] };
};
api._syncedStore.setData = _sinon2.default.stub();
var SyntheticAction = function SyntheticAction() {
(0, _classCallCheck3.default)(this, SyntheticAction);
};
var cb = api.action('hello');
cb(new SyntheticAction());
var args = api._syncedStore.setData.args[0];
(0, _chai.expect)(args[0].actions).to.be.deep.equal([{
name: 'hello',
args: ['[SyntheticAction]']
}]);
});
});
});

View File

@ -1,226 +0,0 @@
'use strict';
var _chai = require('chai');
var _sinon = require('sinon');
var _sinon2 = _interopRequireDefault(_sinon);
var _config_api = require('../config_api');
var _config_api2 = _interopRequireDefault(_config_api);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _global = global;
var describe = _global.describe;
var it = _global.it;
function buildMock(fields) {
var obj = {};
fields.forEach(function (field) {
obj[field] = _sinon2.default.stub();
});
return obj;
}
function getConfigApi() {
var storyStore = buildMock(['addStory', 'removeStoryKind', 'clean', 'hasStoryKind', 'dumpStoryBook', 'getStoryKinds', 'hasStory', 'getStories']);
storyStore.hasStoryKind = function () {
return true;
};
storyStore.hasStory = function () {
return true;
};
var syncedStore = buildMock(['setData']);
syncedStore.getData = function () {
return {};
};
var c = new _config_api2.default({
syncedStore: syncedStore,
storyStore: storyStore
});
return c;
}
describe('client.ConfigApi', function () {
describe('_renderError', function () {
it('should send error stack and message to syncedStore', function () {
var api = getConfigApi();
api._syncedStore.getData = function () {
return {};
};
var message = 'the-message';
var stack = 'the-stack';
var error = new Error(message);
error.stack = stack;
api._renderError(error);
var capturedError = api._syncedStore.setData.args[0][0].error;
(0, _chai.expect)(capturedError).to.deep.equal({ message: message, stack: stack });
});
});
describe('_renderMain', function () {
it('should run loaders if provided', function (done) {
var api = getConfigApi();
var loaders = done;
api._renderMain(loaders);
});
it('should set error in syncedStore to null', function () {
var api = getConfigApi();
api._syncedStore.getData = function () {
return { error: 'something-else' };
};
api._renderMain();
var data = api._syncedStore.setData.args[0][0];
(0, _chai.expect)(data.error).to.be.equal(null);
});
it('should get a dump of storyStore and send it to syncedStore', function () {
var api = getConfigApi();
var dump = { aa: 10 };
api._storyStore.dumpStoryBook = function () {
return dump;
};
api._renderMain();
var data = api._syncedStore.setData.args[0][0];
(0, _chai.expect)(data.storyStore).to.deep.equal(dump);
});
it('should set __updatedAt field with a updated value to syncedStore', function () {
it('should get a dump of storyStore and send it to syncedStore', function () {
var api = getConfigApi();
api._renderMain();
var data = api._syncedStore.setData.args[0][0];
(0, _chai.expect)(data.__updatedAt <= Date.now()).to.deep.equal(true);
});
});
it('should select a new kind if the current one is not available', function () {
var api = getConfigApi();
api._storyStore.hasStoryKind = function () {
return false;
};
api._storyStore.getStoryKinds = function () {
return ['abc'];
};
api._renderMain();
var data = api._syncedStore.setData.args[0][0];
(0, _chai.expect)(data.selectedKind).to.deep.equal('abc');
});
describe('if there is kind', function () {
it('should select a new story if the current one is not available', function () {
var api = getConfigApi();
api._storyStore.hasStoryKind = function () {
return true;
};
api._storyStore.hasStory = function () {
return false;
};
api._storyStore.getStories = function () {
return ['kkr'];
};
api._renderMain();
var data = api._syncedStore.setData.args[0][0];
(0, _chai.expect)(data.selectedStory).to.deep.equal('kkr');
});
});
});
describe('configure', function () {
describe('initially', function () {
it('should call _renderMain with loaders', function () {
var api = getConfigApi();
api._renderMain = _sinon2.default.stub();
var loaders = function loaders() {};
var m = {};
api.configure(loaders, m);
(0, _chai.expect)(api._renderMain.args[0][0]).to.be.equal(loaders);
});
describe('if caused an error', function () {
it('should call _renderError with the error', function () {
var api = getConfigApi();
var error = new Error('horra');
api._renderMain = function () {
throw error;
};
api._renderError = _sinon2.default.stub();
var loaders = function loaders() {};
var m = {};
api.configure(loaders, m);
(0, _chai.expect)(api._renderError.args[0][0]).to.be.equal(error);
});
});
});
describe('with hot reload', function () {
it('should call _renderMain with loaders', function (done) {
var api = getConfigApi();
api._renderMain = _sinon2.default.stub();
var doAccept = null;
var m = {
hot: {
accept: function accept(fn) {
doAccept = fn;
}
}
};
api.configure(null, m);
doAccept();
setTimeout(function () {
(0, _chai.expect)(api._renderMain.callCount).to.be.equal(2);
done();
}, 10);
});
describe('if caused an error', function () {
it('should call _renderError with the error', function (done) {
var error = new Error('error');
var api = getConfigApi();
api._renderMain = function () {
throw error;
};
api._renderError = _sinon2.default.stub();
var doAccept = null;
var m = {
hot: {
accept: function accept(fn) {
doAccept = fn;
}
}
};
api.configure(null, m);
doAccept();
setTimeout(function () {
(0, _chai.expect)(api._renderError.callCount).to.be.equal(2);
done();
}, 10);
});
});
});
});
});

View File

@ -1,228 +0,0 @@
'use strict';
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
var _sinon = require('sinon');
var _sinon2 = _interopRequireDefault(_sinon);
var _chai = require('chai');
var _synced_store = require('../synced_store');
var _synced_store2 = _interopRequireDefault(_synced_store);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _global = global;
var describe = _global.describe;
var it = _global.it;
function getSyncedData(dataId) {
var window = {
location: {},
addEventListener: function addEventListener() {}
};
if (dataId) {
window.location.search = '?dataId=' + dataId;
}
var syncedData = new _synced_store2.default(window);
syncedData._bus = {};
return syncedData;
}
describe('data', function () {
describe('normal mode', function () {
it('should set the `iframeMode` as false', function () {
var syncedData = getSyncedData();
var data = syncedData.getData();
(0, _chai.expect)(data.iframeMode).to.be.equal(false);
});
it('should set a random Id to dataId', function () {
var syncedData = getSyncedData();
var data = syncedData.getData();
(0, _chai.expect)((0, _typeof3.default)(data.dataId)).to.be.equal('string');
});
});
describe('iframe mode', function () {
it('should get the dataId from the URL', function () {
var currentDataId = _uuid2.default.v4();
var syncedData = getSyncedData(currentDataId);
var data = syncedData.getData();
(0, _chai.expect)(data.dataId).to.be.equal(currentDataId);
});
it('should set the iframeMode as true', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var data = syncedData.getData();
(0, _chai.expect)(data.iframeMode).to.be.equal(true);
});
});
describe('watchData', function () {
it('should add the handler to handlers', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var fn = function fn() {};
syncedData.watchData(fn);
var fnStored = syncedData._handlers.pop();
(0, _chai.expect)(fnStored).to.be.equal(fn);
});
it('should remove the handler when the return function called', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var stop = syncedData.watchData(function () {});
var countStart = syncedData._handlers.length;
stop();
var countEnd = syncedData._handlers.length;
(0, _chai.expect)(countStart - countEnd).to.be.equal(1);
});
});
describe('setData', function () {
it('should emit data to the pageBus', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var kkr = _uuid2.default.v4();
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
syncedData.setData({ kkr: kkr });
var data = syncedData.getData();
var sentString = syncedData._bus.emit.args[0][1];
var sentJSON = JSON.parse(sentString);
(0, _chai.expect)(sentJSON).to.deep.equal(data);
syncedData._bus.emit = originalEmit;
});
it('should update existing data', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var kkr = _uuid2.default.v4();
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
var previousKKR = syncedData.getData().kkr;
syncedData.setData({ kkr: kkr });
var data = syncedData.getData();
(0, _chai.expect)(data.kkr).not.to.be.equal(previousKKR);
syncedData._bus.emit = originalEmit;
});
it('should run all handlers with the data', function (done) {
var syncedData = getSyncedData(_uuid2.default.v4());
var kkr = _uuid2.default.v4();
var stop = syncedData.watchData(function (data) {
stop();
(0, _chai.expect)(data.kkr).to.be.equal(kkr);
done();
});
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
syncedData.setData({ kkr: kkr });
syncedData._bus.emit = originalEmit;
});
it('should add a property with __lastUpdated with Date.now()', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var now = _uuid2.default.v4();
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
var originalNow = Date.now;
Date.now = function () {
return now;
};
syncedData.setData({ aa: 10 });
var data = syncedData.getData();
(0, _chai.expect)(data.__lastUpdated).to.be.equal(now);
Date.now = originalNow;
syncedData._bus.emit = originalEmit;
});
});
describe('receiveData', function () {
it('should set received data as the new data', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var previousData = syncedData.getData();
var newData = { kkr: _uuid2.default.v4() };
syncedData._onData((0, _stringify2.default)(newData));
var updatedData = syncedData.getData();
delete updatedData.iframeMode;
(0, _chai.expect)(updatedData).to.deep.equal(newData);
(0, _chai.expect)(previousData).not.to.deep.equal(newData);
});
it('should run all handlers with data', function (done) {
var syncedData = getSyncedData(_uuid2.default.v4());
var newData = { kkr: _uuid2.default.v4() };
var stop = syncedData.watchData(function (data) {
stop();
var updatedData = (0, _extends3.default)({}, data);
delete updatedData.iframeMode;
(0, _chai.expect)(updatedData).to.deep.equal(newData);
done();
});
syncedData._onData((0, _stringify2.default)(newData));
});
it('should set the local iframeMode to data', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var newData = {
kkr: _uuid2.default.v4(),
iframeMode: _uuid2.default.v4()
};
var oldIframeMode = syncedData.getData().iframeMode;
syncedData._onData((0, _stringify2.default)(newData));
var newIframeMode = syncedData.getData().iframeMode;
(0, _chai.expect)(newIframeMode).to.be.deep.equal(oldIframeMode);
});
});
describe('getDataKey', function () {
it('should get the data key prefixed with the current dataId', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var dataId = syncedData.getData().dataId;
var dataKey = syncedData.getDataKey();
(0, _chai.expect)(dataKey).to.be.equal('data-' + dataId);
});
});
});

View File

@ -1,56 +0,0 @@
'use strict';
var _chai = require('chai');
var _global = global;
var describe = _global.describe;
var it = _global.it;
describe('client.index', function () {
describe('storiesOf', function () {
it('should add the story to storybox');
it('should return .add method');
it('should return .add method even called .add');
it('should remove story kind on hot module dispose');
});
describe('action', function () {
it('should push the action to existing actions');
it('should only keep recent 5 actions');
it('should replace Synthetic events with their name');
});
describe('renderError', function () {
it('should set error stack and message into data.setData');
});
describe('renderMain', function () {
it('should run loaders');
it('should call data.setData with the storybook dump');
it('should call data.setData with the __updatedAt');
it('should reset data.error');
describe('current selectedKind is not available', function () {
it('should select selectedKind from the first storykind');
});
describe('there is a selectedKind in storybook', function () {
describe('current selectedStory is not available', function () {
it('should select selectedStory from the first story');
});
});
});
describe('configure', function () {
describe('immediately', function () {
it('should run renderMain');
it('should run renderError if there was an error running renderMain');
});
describe('on hot reload', function () {
it('should run renderMain');
it('should run renderError if there was an error running renderMain');
});
});
});

View File

@ -1,179 +0,0 @@
'use strict';
var _chai = require('chai');
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
var _story_store = require('../story_store');
var _story_store2 = _interopRequireDefault(_story_store);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _global = global;
var describe = _global.describe;
var it = _global.it;
var beforeEach = _global.beforeEach;
var storyStore = new _story_store2.default();
describe('client.StoryStore', function () {
beforeEach(function () {
return storyStore.clean();
});
describe('addStory', function () {
it('should add the first story properly', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name', story);
(0, _chai.expect)(storyStore.getStory(kind, 'name')).to.be.equal(story);
});
it('should add another story of the previous kind', function () {
var kind = _uuid2.default.v4();
function story1() {}
function story2() {}
storyStore.addStory(kind, 'name1', story1);
storyStore.addStory(kind, 'name2', story2);
(0, _chai.expect)(storyStore.getStory(kind, 'name1')).to.be.equal(story1);
(0, _chai.expect)(storyStore.getStory(kind, 'name2')).to.be.equal(story2);
});
it('should replace the same story if came again', function () {
var kind = _uuid2.default.v4();
function story1() {}
function story2() {}
storyStore.addStory(kind, 'name', story1);
storyStore.addStory(kind, 'name', story2);
(0, _chai.expect)(storyStore.getStory(kind, 'name')).to.be.equal(story2);
});
});
describe('getStoryKinds', function () {
it('should return all story kind names with FIFO order', function () {
var kind1 = _uuid2.default.v4();
var kind2 = _uuid2.default.v4();
var kind3 = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind1, 'name', story);
storyStore.addStory(kind2, 'name', story);
storyStore.addStory(kind3, 'name', story);
(0, _chai.expect)(storyStore.getStoryKinds()).to.deep.equal([kind1, kind2, kind3]);
});
});
describe('getStories', function () {
it('should return an empty array, if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storyStore.getStories(kind)).to.deep.equal([]);
});
it('should return all story names with FIFO order', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name1', story);
storyStore.addStory(kind, 'name2', story);
storyStore.addStory(kind, 'name3', story);
(0, _chai.expect)(storyStore.getStories(kind)).to.deep.equal(['name1', 'name2', 'name3']);
});
});
describe('getStory', function () {
it('should return null if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storyStore.getStory(kind, 'name')).to.be.equal(null);
});
it('should return null if there is no story', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name', story);
(0, _chai.expect)(storyStore.getStory(kind, 'other-name')).to.be.equal(null);
});
it('shodld return the story if exists', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name', story);
(0, _chai.expect)(storyStore.getStory(kind, 'name')).to.be.equal(story);
});
});
describe('removeStoryKind', function () {
it('should remove the given kind', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name', story);
(0, _chai.expect)(storyStore.getStory(kind, 'name')).to.be.equal(story);
storyStore.removeStoryKind(kind);
(0, _chai.expect)(storyStore.getStory(kind, 'name')).to.be.equal(null);
});
});
describe('hasStoryKind', function () {
it('should return true if there is a kind', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name', story);
(0, _chai.expect)(storyStore.hasStoryKind(kind)).to.be.equal(true);
});
it('should return false if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storyStore.hasStoryKind(kind)).to.be.equal(false);
});
});
describe('hasStory', function () {
it('should return true if there is a story', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name', story);
(0, _chai.expect)(storyStore.hasStory(kind, 'name')).to.be.equal(true);
});
it('should return false if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storyStore.hasStoryKind(kind, 'name')).to.be.equal(false);
});
it('should return false if there is no story', function () {
var kind = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind, 'name', story);
(0, _chai.expect)(storyStore.hasStory(kind, 'name2')).to.be.equal(false);
});
});
describe('dumpStoryBook', function () {
it('should dump all story kinds and stories properly', function () {
var kind1 = _uuid2.default.v4();
var kind2 = _uuid2.default.v4();
function story() {}
storyStore.addStory(kind1, 'name1', story);
storyStore.addStory(kind1, 'name2', story);
storyStore.addStory(kind2, 'name10', story);
storyStore.addStory(kind2, 'name20', story);
(0, _chai.expect)(storyStore.dumpStoryBook()).to.be.deep.equal([{ kind: kind1, stories: ['name1', 'name2'] }, { kind: kind2, stories: ['name10', 'name20'] }]);
});
});
});

View File

@ -1,179 +0,0 @@
'use strict';
var _chai = require('chai');
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
var _storybook = require('../storybook');
var _storybook2 = _interopRequireDefault(_storybook);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _global = global;
var describe = _global.describe;
var it = _global.it;
var beforeEach = _global.beforeEach;
var storybook = new _storybook2.default();
describe('client.storybook', function () {
beforeEach(function () {
return storybook.clean();
});
describe('storybook.addStory', function () {
it('should add the first story properly', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name', story);
(0, _chai.expect)(storybook.getStory(kind, 'name')).to.be.equal(story);
});
it('should add another story of the previous kind', function () {
var kind = _uuid2.default.v4();
function story1() {}
function story2() {}
storybook.addStory(kind, 'name1', story1);
storybook.addStory(kind, 'name2', story2);
(0, _chai.expect)(storybook.getStory(kind, 'name1')).to.be.equal(story1);
(0, _chai.expect)(storybook.getStory(kind, 'name2')).to.be.equal(story2);
});
it('should replace the same story if came again', function () {
var kind = _uuid2.default.v4();
function story1() {}
function story2() {}
storybook.addStory(kind, 'name', story1);
storybook.addStory(kind, 'name', story2);
(0, _chai.expect)(storybook.getStory(kind, 'name')).to.be.equal(story2);
});
});
describe('storybook.getStoryKinds', function () {
it('should return all story kind names with FIFO order', function () {
var kind1 = _uuid2.default.v4();
var kind2 = _uuid2.default.v4();
var kind3 = _uuid2.default.v4();
function story() {}
storybook.addStory(kind1, 'name', story);
storybook.addStory(kind2, 'name', story);
storybook.addStory(kind3, 'name', story);
(0, _chai.expect)(storybook.getStoryKinds()).to.deep.equal([kind1, kind2, kind3]);
});
});
describe('storybook.getStories', function () {
it('should return an empty array, if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storybook.getStories(kind)).to.deep.equal([]);
});
it('should return all story names with FIFO order', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name1', story);
storybook.addStory(kind, 'name2', story);
storybook.addStory(kind, 'name3', story);
(0, _chai.expect)(storybook.getStories(kind)).to.deep.equal(['name1', 'name2', 'name3']);
});
});
describe('storybook.getStory', function () {
it('should return null if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storybook.getStory(kind, 'name')).to.be.equal(null);
});
it('should return null if there is no story', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name', story);
(0, _chai.expect)(storybook.getStory(kind, 'other-name')).to.be.equal(null);
});
it('shodld return the story if exists', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name', story);
(0, _chai.expect)(storybook.getStory(kind, 'name')).to.be.equal(story);
});
});
describe('storybook.removeStoryKind', function () {
it('should remove the given kind', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name', story);
(0, _chai.expect)(storybook.getStory(kind, 'name')).to.be.equal(story);
storybook.removeStoryKind(kind);
(0, _chai.expect)(storybook.getStory(kind, 'name')).to.be.equal(null);
});
});
describe('storybook.hasStoryKind', function () {
it('should return true if there is a kind', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name', story);
(0, _chai.expect)(storybook.hasStoryKind(kind)).to.be.equal(true);
});
it('should return false if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storybook.hasStoryKind(kind)).to.be.equal(false);
});
});
describe('storybook.hasStory', function () {
it('should return true if there is a story', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name', story);
(0, _chai.expect)(storybook.hasStory(kind, 'name')).to.be.equal(true);
});
it('should return false if there is no kind', function () {
var kind = _uuid2.default.v4();
(0, _chai.expect)(storybook.hasStoryKind(kind, 'name')).to.be.equal(false);
});
it('should return false if there is no story', function () {
var kind = _uuid2.default.v4();
function story() {}
storybook.addStory(kind, 'name', story);
(0, _chai.expect)(storybook.hasStory(kind, 'name2')).to.be.equal(false);
});
});
describe('storybook.dumpStoryBook', function () {
it('should dump all story kinds and stories properly', function () {
var kind1 = _uuid2.default.v4();
var kind2 = _uuid2.default.v4();
function story() {}
storybook.addStory(kind1, 'name1', story);
storybook.addStory(kind1, 'name2', story);
storybook.addStory(kind2, 'name10', story);
storybook.addStory(kind2, 'name20', story);
(0, _chai.expect)(storybook.dumpStoryBook()).to.be.deep.equal([{ kind: kind1, stories: ['name1', 'name2'] }, { kind: kind2, stories: ['name10', 'name20'] }]);
});
});
});

View File

@ -1,228 +0,0 @@
'use strict';
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
var _sinon = require('sinon');
var _sinon2 = _interopRequireDefault(_sinon);
var _chai = require('chai');
var _synced_store = require('../synced_store');
var _synced_store2 = _interopRequireDefault(_synced_store);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _global = global;
var describe = _global.describe;
var it = _global.it;
function getSyncedData(dataId) {
var window = {
location: {},
addEventListener: function addEventListener() {}
};
if (dataId) {
window.location.search = '?dataId=' + dataId;
}
var syncedData = new _synced_store2.default(window);
syncedData._bus = {};
return syncedData;
}
describe('client.SyncedStore', function () {
describe('normal mode', function () {
it('should set the `iframeMode` as false', function () {
var syncedData = getSyncedData();
var data = syncedData.getData();
(0, _chai.expect)(data.iframeMode).to.be.equal(false);
});
it('should set a random Id to dataId', function () {
var syncedData = getSyncedData();
var data = syncedData.getData();
(0, _chai.expect)((0, _typeof3.default)(data.dataId)).to.be.equal('string');
});
});
describe('iframe mode', function () {
it('should get the dataId from the URL', function () {
var currentDataId = _uuid2.default.v4();
var syncedData = getSyncedData(currentDataId);
var data = syncedData.getData();
(0, _chai.expect)(data.dataId).to.be.equal(currentDataId);
});
it('should set the iframeMode as true', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var data = syncedData.getData();
(0, _chai.expect)(data.iframeMode).to.be.equal(true);
});
});
describe('watchData', function () {
it('should add the handler to handlers', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var fn = function fn() {};
syncedData.watchData(fn);
var fnStored = syncedData._handlers.pop();
(0, _chai.expect)(fnStored).to.be.equal(fn);
});
it('should remove the handler when the return function called', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var stop = syncedData.watchData(function () {});
var countStart = syncedData._handlers.length;
stop();
var countEnd = syncedData._handlers.length;
(0, _chai.expect)(countStart - countEnd).to.be.equal(1);
});
});
describe('setData', function () {
it('should emit data to the pageBus', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var kkr = _uuid2.default.v4();
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
syncedData.setData({ kkr: kkr });
var data = syncedData.getData();
var sentString = syncedData._bus.emit.args[0][1];
var sentJSON = JSON.parse(sentString);
(0, _chai.expect)(sentJSON).to.deep.equal(data);
syncedData._bus.emit = originalEmit;
});
it('should update existing data', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var kkr = _uuid2.default.v4();
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
var previousKKR = syncedData.getData().kkr;
syncedData.setData({ kkr: kkr });
var data = syncedData.getData();
(0, _chai.expect)(data.kkr).not.to.be.equal(previousKKR);
syncedData._bus.emit = originalEmit;
});
it('should run all handlers with the data', function (done) {
var syncedData = getSyncedData(_uuid2.default.v4());
var kkr = _uuid2.default.v4();
var stop = syncedData.watchData(function (data) {
stop();
(0, _chai.expect)(data.kkr).to.be.equal(kkr);
done();
});
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
syncedData.setData({ kkr: kkr });
syncedData._bus.emit = originalEmit;
});
it('should add a property with __lastUpdated with Date.now()', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var now = _uuid2.default.v4();
var originalEmit = syncedData._bus.emit;
syncedData._bus.emit = _sinon2.default.stub();
var originalNow = Date.now;
Date.now = function () {
return now;
};
syncedData.setData({ aa: 10 });
var data = syncedData.getData();
(0, _chai.expect)(data.__lastUpdated).to.be.equal(now);
Date.now = originalNow;
syncedData._bus.emit = originalEmit;
});
});
describe('receiveData', function () {
it('should set received data as the new data', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var previousData = syncedData.getData();
var newData = { kkr: _uuid2.default.v4() };
syncedData._onData((0, _stringify2.default)(newData));
var updatedData = syncedData.getData();
delete updatedData.iframeMode;
(0, _chai.expect)(updatedData).to.deep.equal(newData);
(0, _chai.expect)(previousData).not.to.deep.equal(newData);
});
it('should run all handlers with data', function (done) {
var syncedData = getSyncedData(_uuid2.default.v4());
var newData = { kkr: _uuid2.default.v4() };
var stop = syncedData.watchData(function (data) {
stop();
var updatedData = (0, _extends3.default)({}, data);
delete updatedData.iframeMode;
(0, _chai.expect)(updatedData).to.deep.equal(newData);
done();
});
syncedData._onData((0, _stringify2.default)(newData));
});
it('should set the local iframeMode to data', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var newData = {
kkr: _uuid2.default.v4(),
iframeMode: _uuid2.default.v4()
};
var oldIframeMode = syncedData.getData().iframeMode;
syncedData._onData((0, _stringify2.default)(newData));
var newIframeMode = syncedData.getData().iframeMode;
(0, _chai.expect)(newIframeMode).to.be.deep.equal(oldIframeMode);
});
});
describe('getDataKey', function () {
it('should get the data key prefixed with the current dataId', function () {
var syncedData = getSyncedData(_uuid2.default.v4());
var dataId = syncedData.getData().dataId;
var dataKey = syncedData.getDataKey();
(0, _chai.expect)(dataKey).to.be.equal('data-' + dataId);
});
});
});

137
dist/client/data.js vendored
View File

@ -1,137 +0,0 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _pageBus = require('page-bus');
var _pageBus2 = _interopRequireDefault(_pageBus);
var _jsonStringifySafe = require('json-stringify-safe');
var _jsonStringifySafe2 = _interopRequireDefault(_jsonStringifySafe);
var _queryString = require('query-string');
var _queryString2 = _interopRequireDefault(_queryString);
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Data = function () {
function Data(window) {
(0, _classCallCheck3.default)(this, Data);
this._window = window;
this._parsedQs = _queryString2.default.parse(window.location.search);
// We need to check whether we are inside a iframe or not.
// This is used by here and as well as in the UI
this._iframeMode = Boolean(this._parsedQs.dataId);
// We need to create a unique Id for each page. We need to communicate
// using this id as a namespace. Otherwise, each every iframe will get the
// data.
// We create a new UUID if this is main page. Then, this is used by UI to
// create queryString param when creating the iframe.
// If we are in the iframe, we'll get it from the queryString.
this._dataId = this._iframeMode ? this._parsedQs.dataId : _uuid2.default.v4();
this._data = {
iframeMode: this._iframeMode,
dataId: this._dataId
};
this._handlers = [];
}
(0, _createClass3.default)(Data, [{
key: '_onData',
value: function _onData(dataString) {
var _this = this;
var d = JSON.parse(dataString);
this._data = (0, _extends3.default)({}, d, {
iframeMode: this._iframeMode
});
this._handlers.forEach(function (handler) {
handler(_this.getData());
});
}
}, {
key: 'init',
value: function init() {
var _this2 = this;
this._bus = (0, _pageBus2.default)();
// listen to the bus and apply
this._bus.on(this.getDataKey(), this._onData.bind(this));
// do initial render
this._handlers.forEach(function (handler) {
return handler(_this2.getData());
});
}
}, {
key: 'getDataKey',
value: function getDataKey() {
return 'data-' + this._data.dataId;
}
}, {
key: 'getData',
value: function getData() {
return (0, _extends3.default)({}, this._data);
}
}, {
key: 'setData',
value: function setData(fields) {
var _this3 = this;
(0, _keys2.default)(fields).forEach(function (key) {
_this3._data[key] = fields[key];
});
this._data.__lastUpdated = Date.now();
// In page-bus, we must send non-identical data.
// Otherwise, it'll cache and won't trigger.
// That's why we are setting the __lastUpdated value here.
this._bus.emit(this.getDataKey(), (0, _jsonStringifySafe2.default)(this.getData()));
this._handlers.forEach(function (handler) {
return handler(_this3.getData());
});
}
}, {
key: 'watchData',
value: function watchData(fn) {
var _this4 = this;
this._handlers.push(fn);
return function () {
var index = _this4._handlers.indexOf(fn);
_this4._handlers.splice(index, 1);
};
}
}]);
return Data;
}();
exports.default = Data;

View File

@ -1,131 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require("babel-runtime/helpers/createClass");
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var cnt = 0;
var Storybook = function () {
function Storybook() {
(0, _classCallCheck3.default)(this, Storybook);
this._data = {};
}
(0, _createClass3.default)(Storybook, [{
key: "addStory",
value: function addStory(kind, name, fn) {
if (!this._data[kind]) {
this._data[kind] = {
kind: kind,
index: cnt++,
stories: {}
};
}
this._data[kind].stories[name] = {
name: name,
index: cnt++,
fn: fn
};
}
}, {
key: "getStoryKinds",
value: function getStoryKinds() {
var _this = this;
return (0, _keys2.default)(this._data).map(function (key) {
return _this._data[key];
}).sort(function (info1, info2) {
return info1.index - info2.index;
}).map(function (info) {
return info.kind;
});
}
}, {
key: "getStories",
value: function getStories(kind) {
var _this2 = this;
if (!this._data[kind]) {
return [];
}
return (0, _keys2.default)(this._data[kind].stories).map(function (name) {
return _this2._data[kind].stories[name];
}).sort(function (info1, info2) {
return info1.index - info2.index;
}).map(function (info) {
return info.name;
});
}
}, {
key: "getStory",
value: function getStory(kind, name) {
var storiesKind = this._data[kind];
if (!storiesKind) {
return null;
}
var storyInfo = storiesKind.stories[name];
if (!storyInfo) {
return null;
}
return storyInfo.fn;
}
}, {
key: "removeStoryKind",
value: function removeStoryKind(kind) {
delete this._data[kind];
}
}, {
key: "hasStoryKind",
value: function hasStoryKind(kind) {
return Boolean(this._data[kind]);
}
}, {
key: "hasStory",
value: function hasStory(kind, name) {
return Boolean(this.getStory(kind, name));
}
}, {
key: "dumpStoryBook",
value: function dumpStoryBook() {
var _this3 = this;
var data = this.getStoryKinds().map(function (kind) {
return { kind: kind, stories: _this3.getStories(kind) };
});
return data;
}
}, {
key: "clean",
value: function clean() {
var _this4 = this;
this.getStoryKinds().forEach(function (kind) {
return delete _this4._data[kind];
});
}
}]);
return Storybook;
}();
exports.default = Storybook;

View File

@ -112,12 +112,13 @@ if (_fs2.default.existsSync(customConfigPath)) {
var customConfig = require(customConfigPath);
logger.info('=> Loading custom webpack config.');
finalConfig = (0, _extends3.default)({}, customConfig, _webpack4.default, {
plugins: [].concat((0, _toConsumableArray3.default)(_webpack4.default.plugins), (0, _toConsumableArray3.default)(customConfig.plugins)),
// We need to use our and custom plugins.
plugins: [].concat((0, _toConsumableArray3.default)(_webpack4.default.plugins), (0, _toConsumableArray3.default)(customConfig.plugins || [])),
module: (0, _extends3.default)({}, _webpack4.default.module, {
loaders: [].concat((0, _toConsumableArray3.default)(_webpack4.default.module.loaders), (0, _toConsumableArray3.default)(customConfig.module.loaders))
// We need to use our and custom loaders.
loaders: [].concat((0, _toConsumableArray3.default)(_webpack4.default.module.loaders), (0, _toConsumableArray3.default)(customConfig.module.loaders || []))
})
});
finalConfig.resolve.modulesDirectories.push('node_modules');
}
var compiler = (0, _webpack2.default)(finalConfig);

View File

@ -75,18 +75,22 @@ if (fs.existsSync(customConfigPath)) {
logger.info('=> Loading custom webpack config.');
finalConfig = {
...customConfig,
// We'll always load our configurations after the custom config.
// So, we'll always load the stuff we need.
...config,
// We need to use our and custom plugins.
plugins: [
...config.plugins,
...customConfig.plugins
...customConfig.plugins || [],
],
module: {
...config.module,
// We need to use our and custom loaders.
loaders: [
...config.module.loaders,
...customConfig.module.loaders
]
}
...customConfig.module.loaders || [],
],
},
};
}