From 46daa2555a43549aabdcfee1651e84034994699e Mon Sep 17 00:00:00 2001 From: Josh Perez Date: Sat, 28 Mar 2015 18:58:21 -0700 Subject: [PATCH] Add before and after hooks --- dist/alt-browser-with-addons.js | 6 +++ dist/alt-browser.js | 6 +++ dist/alt-with-runtime.js | 6 +++ dist/alt.js | 6 +++ docs/createStore.md | 12 +++++ src/alt.js | 14 ++++++ test/before-and-after-test.js | 85 +++++++++++++++++++++++++++++++++ 7 files changed, 135 insertions(+) create mode 100644 test/before-and-after-test.js diff --git a/dist/alt-browser-with-addons.js b/dist/alt-browser-with-addons.js index 26553850..a925eb8b 100644 --- a/dist/alt-browser-with-addons.js +++ b/dist/alt-browser-with-addons.js @@ -1072,12 +1072,18 @@ var AltStore = (function () { // Register dispatcher this.dispatchToken = dispatcher.register(function (payload) { + if (typeof model.beforeEach === "function") { + model.beforeEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } if (model[LISTENERS][payload.action]) { var result = model[LISTENERS][payload.action](payload.data); if (result !== false) { _this8.emitChange(); } } + if (typeof model.afterEach === "function") { + model.afterEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } }); if (this[LIFECYCLE].init) { diff --git a/dist/alt-browser.js b/dist/alt-browser.js index 2b5a0060..123abef2 100644 --- a/dist/alt-browser.js +++ b/dist/alt-browser.js @@ -816,12 +816,18 @@ var AltStore = (function () { // Register dispatcher this.dispatchToken = dispatcher.register(function (payload) { + if (typeof model.beforeEach === "function") { + model.beforeEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } if (model[LISTENERS][payload.action]) { var result = model[LISTENERS][payload.action](payload.data); if (result !== false) { _this8.emitChange(); } } + if (typeof model.afterEach === "function") { + model.afterEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } }); if (this[LIFECYCLE].init) { diff --git a/dist/alt-with-runtime.js b/dist/alt-with-runtime.js index f5476076..f0342ea0 100644 --- a/dist/alt-with-runtime.js +++ b/dist/alt-with-runtime.js @@ -73,12 +73,18 @@ var AltStore = (function () { // Register dispatcher this.dispatchToken = dispatcher.register(function (payload) { + if (typeof model.beforeEach === "function") { + model.beforeEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } if (model[LISTENERS][payload.action]) { var result = model[LISTENERS][payload.action](payload.data); if (result !== false) { _this8.emitChange(); } } + if (typeof model.afterEach === "function") { + model.afterEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } }); if (this[LIFECYCLE].init) { diff --git a/dist/alt.js b/dist/alt.js index 2dd7d4e4..9ec27993 100644 --- a/dist/alt.js +++ b/dist/alt.js @@ -85,12 +85,18 @@ var AltStore = (function () { // Register dispatcher this.dispatchToken = dispatcher.register(function (payload) { + if (typeof model.beforeEach === "function") { + model.beforeEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } if (model[LISTENERS][payload.action]) { var result = model[LISTENERS][payload.action](payload.data); if (result !== false) { _this8.emitChange(); } } + if (typeof model.afterEach === "function") { + model.afterEach(payload.action.toString(), payload.data, _this8[STATE_CONTAINER]); + } }); if (this[LIFECYCLE].init) { diff --git a/docs/createStore.md b/docs/createStore.md index 6da1e146..2bf02620 100644 --- a/docs/createStore.md +++ b/docs/createStore.md @@ -241,3 +241,15 @@ class MyStore { ## StoreModel#_storeName This is a reference to the store's internal name. This is either the identifier you provided to `createStore` or StoreModel's class name. + +## StoreModel#beforeEach + +> (action: string, data: mixed, state: object): undefined + +This method gets called, if defined, before the payload hits the action. You can use this method to `waitFor` other stores, save previous state, or perform any bookeeping. The state passed in to `beforeEach` is the current state pre-action. + +## StoreModel#afterEach + +> (action: string, data: mixed, state: object): undefined + +This method gets called, if defined, after the payload hits the action and the store emits a change. You can use this method for bookeeping and as a companion to `beforeEach`. The state passed in to `afterEach` is the current state post-action. diff --git a/src/alt.js b/src/alt.js index 8684e1a7..c74c9602 100644 --- a/src/alt.js +++ b/src/alt.js @@ -68,12 +68,26 @@ class AltStore { // Register dispatcher this.dispatchToken = dispatcher.register((payload) => { + if (typeof model.beforeEach === 'function') { + model.beforeEach( + payload.action.toString(), + payload.data, + this[STATE_CONTAINER] + ) + } if (model[LISTENERS][payload.action]) { const result = model[LISTENERS][payload.action](payload.data) if (result !== false) { this.emitChange() } } + if (typeof model.afterEach === 'function') { + model.afterEach( + payload.action.toString(), + payload.data, + this[STATE_CONTAINER] + ) + } }) if (this[LIFECYCLE].init) { diff --git a/test/before-and-after-test.js b/test/before-and-after-test.js new file mode 100644 index 00000000..f4e77026 --- /dev/null +++ b/test/before-and-after-test.js @@ -0,0 +1,85 @@ +import Alt from '../dist/alt-with-runtime' +import { assert } from 'chai' +import sinon from 'sinon' + +const alt = new Alt() +const action = alt.generateActions('fire') + +const beforeEach = sinon.spy() +const afterEach = sinon.spy() + +const store = alt.createStore({ + displayName: 'Store', + + state: { a: 1 }, + + bindListeners: { + change: action.fire + }, + + change(x) { + this.setState({ a: x }) + }, + + beforeEach, + afterEach +}) + +export default { + 'Before and After hooks': { + beforeEach() { + alt.recycle() + }, + + 'before and after hook fire once'() { + action.fire(2) + + assert.ok(beforeEach.calledOnce) + assert.ok(afterEach.calledOnce) + }, + + 'before is called before after'() { + action.fire(2) + + assert.ok(beforeEach.calledBefore(afterEach)) + assert.ok(afterEach.calledAfter(beforeEach)) + }, + + 'args passed in'() { + action.fire(2) + + assert.ok(beforeEach.args[0].length === 3, '3 args are passed') + assert.ok(afterEach.args[0].length === 3, '3 args are passed') + + assert.ok(beforeEach.args[0][1] === 2, 'before has payload') + assert.ok(afterEach.args[0][1] === 2, 'after has payload') + }, + + 'before and after get state'() { + let beforeValue = null + let afterValue = null + + const store = alt.createStore({ + displayName: 'SpecialStore', + state: { a: 1 }, + bindListeners: { + change: action.fire + }, + change(x) { + this.setState({ a: x }) + }, + beforeEach(a, b, state) { + beforeValue = state.a + }, + afterEach(a, b, state) { + afterValue = state.a + } + }) + + action.fire(2) + + assert.ok(beforeValue === 1, 'before has current state') + assert.ok(afterValue === 2, 'after has next state') + } + } +}