Skip to content

Commit

Permalink
Merge pull request #296 from goatslacker/278
Browse files Browse the repository at this point in the history
Adding a batching function for the dispatcher
  • Loading branch information
goatslacker committed Jun 3, 2015
2 parents 4cf98e3 + cd48286 commit 907c94c
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/alt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Alt {
this.serialize = config.serialize || JSON.stringify
this.deserialize = config.deserialize || JSON.parse
this.dispatcher = config.dispatcher || new Dispatcher()
this.batchingFunction = config.batchingFunction || (callback => callback())
this.actions = { global: {} }
this.stores = {}
this.storeTransforms = config.storeTransforms || []
Expand All @@ -23,7 +24,7 @@ class Alt {
}

dispatch(action, data, details) {
this.dispatcher.dispatch({ action, data, details })
this.batchingFunction(() => this.dispatcher.dispatch({ action, data, details }))
}

createUnsavedStore(StoreModel, ...args) {
Expand Down
112 changes: 112 additions & 0 deletions test/batching-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { jsdom } from 'jsdom'
import Alt from '../'
import React from 'react/addons'
import { assert } from 'chai'
import sinon from 'sinon'

const { TestUtils } = React.addons

const Actions = {
buttonClick() {
setTimeout(() => {
this.actions.switchComponent()
}, 10)
},

switchComponent() {
this.dispatch()
},

uhoh() {
this.dispatch()
}
}

function Store(actions) {
this.active = false

this.bindAction(actions.switchComponent, () => {
this.active = true
})
}

class ComponentA extends React.Component {
constructor(props) {
super(props)

this.state = props.alt.stores.store.getState()
}

componentWillMount() {
this.props.alt.stores.store.listen(state => this.setState(state))
}

render() {
if (this.state.active) {
return <ComponentB alt={this.props.alt} callback={this.props.callback} />
} else {
return <div />
}
}
}

class ComponentB extends React.Component {
componentWillMount() {
let error = null
try {
this.props.alt.actions.actions.uhoh()
} catch (err) {
error = err
} finally {
this.props.callback(error)
}
}

render() {
return <div />
}
}

export default {
'Batching dispatcher': {
beforeEach() {
global.document = jsdom('<!doctype html><html><body></body></html>')
global.window = global.document.parentWindow
global.navigator = global.window.navigator
},

afterEach() {
delete global.document
delete global.window
delete global.navigator
},

'does not batch'(done) {
const alt = new Alt()
alt.addActions('actions', Actions)
alt.addStore('store', Store, alt.actions.actions)

function test(err) {
assert.match(err, /dispatch in the middle of a dispatch/)
done()
}

TestUtils.renderIntoDocument(<ComponentA alt={alt} callback={test} />)
alt.actions.actions.buttonClick()
},

'allows batching'(done) {
const alt = new Alt({ batchingFunction: React.addons.batchedUpdates })
alt.addActions('actions', Actions)
alt.addStore('store', Store, alt.actions.actions)

function test(err) {
assert.isNull(err)
done()
}

TestUtils.renderIntoDocument(<ComponentA alt={alt} callback={test} />)
alt.actions.actions.buttonClick()
},
}
}

0 comments on commit 907c94c

Please sign in to comment.