Skip to content

Commit

Permalink
Added fromPromiseFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
winstonewert committed Jan 7, 2016
1 parent b2477cb commit c6e20cd
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 9 deletions.
27 changes: 19 additions & 8 deletions src/index.js
Expand Up @@ -28,24 +28,27 @@ export function fromEmitter(emitter) {
var events = reaction.events

function emit(eventType, ...args) {
if(!cancelled) {
if(!cancelled) {
var actionCreator = events[eventType]
if (actionCreator) {
dispatch(actionCreator(...args))
}
}
}
}
var stripped = _.omit(reaction, 'events')

var cancel = emitter(reaction, emit)
var cancel = emitter(stripped, emit)

return {
reaction: _.omit(reaction, 'events'),
replaceEvents: (events_) => {events = events_},
cancel: () => {
cancel()
reaction: stripped,
replaceEvents: (events_) => {events = events_},
cancel: () => {
if (cancel) {
cancel()
}
cancelled = true
}
}
}
}

var newReactions = []
Expand All @@ -71,3 +74,11 @@ export function fromEmitter(emitter) {
return newReactions
}
}

export function fromPromiseFactory(promiseFactory) {
return fromEmitter((reaction, emit) => {
promiseFactory(reaction)
.then((result) => emit('resolved', result))
.catch((error) => emit('rejected', error))
})
}
2 changes: 1 addition & 1 deletion test/fromEmitter.spec.js
Expand Up @@ -29,7 +29,7 @@ describe('fromEmitter', () => {
strictEqual(result.length, 1)
deepEqual(result[0].reaction, { foobar: 42 })
strictEqual(emitter.callCount, 1)
strictEqual(emitter.args[0][0], reaction)
deepEqual(emitter.args[0][0], { foobar: 42 })
strictEqual(dispatch.callCount, 0)
strictEqual(cancel.callCount, 0)
})
Expand Down
145 changes: 145 additions & 0 deletions test/fromPromiseFactory.spec.js
@@ -0,0 +1,145 @@
import sinon from 'sinon'
import { fromPromiseFactory } from '../src'
import { strictEqual, deepEqual } from 'assert'

describe('fromPromiseFactory', () => {

var promises, reactor, dispatch

function promiseFactory(reaction) {
return new Promise(function (resolve, reject) {
promises.push({ reaction, resolve, reject })
})
}

beforeEach(() => {
promises = []
reactor = fromPromiseFactory(promiseFactory)
dispatch = sinon.spy()
})

it('does nothing if there are no reactions', () => {
var result = reactor(undefined, [], dispatch)

strictEqual(promises.length, 0)
strictEqual(result.length, 0)
strictEqual(dispatch.callCount, 0)
})

it('creates a promise for new reactions', () => {

const reaction = { 'foobar': 42, events: {} }
var result = reactor(undefined, [ reaction ], dispatch)

strictEqual(promises.length, 1)
strictEqual(result.length, 1)
deepEqual(promises[0].reaction, { foobar: 42 })
deepEqual(result[0].reaction, { foobar: 42 })
strictEqual(dispatch.callCount, 0)
})
it('a different reaction replaces the original', () => {

const reaction = { 'foobar': 42 }
const reaction2 = { 'goat': 7 }
var result = reactor(undefined, [ reaction ], dispatch)
result = reactor(result, [ reaction2 ], dispatch)

strictEqual(result.length, 1)
deepEqual(result[0].reaction, reaction2)
strictEqual(promises.length, 2)
deepEqual(promises[0].reaction, reaction)
deepEqual(promises[1].reaction, reaction2)
strictEqual(dispatch.callCount, 0)
})
it('a second iteration with the same reactions produces the same results', () => {

const reaction = { 'foobar': 42 }
var initial = reactor(undefined, [ reaction ], dispatch)
var result = reactor(initial, [ reaction ], dispatch)

strictEqual(result.length, 1)
deepEqual(result[0].reaction, reaction)
strictEqual(promises.length, 1)
strictEqual(dispatch.callCount, 0)
})
it('a second iteration with the reaction removed, causes it to be cancelled', () => {

const reaction = { 'foobar': 42 }
var initial = reactor(undefined, [ reaction ], dispatch)
var result = reactor(initial, [], dispatch)

strictEqual(result.length, 0)
strictEqual(promises.length, 1)
strictEqual(dispatch.callCount, 0)
})
it('creates reactions if added', () => {

const reaction = { 'foobar': 42 }
var initial = reactor(undefined, [], dispatch)
var result = reactor(initial, [ reaction ], dispatch)

strictEqual(result.length, 1)
deepEqual(result[0].reaction, reaction)
strictEqual(promises.length, 1)
strictEqual(dispatch.callCount, 0)
})

it('creates multiple reactions', () => {

const reaction = { 'foobar': 42 }
const reaction2 = { 'goat': 7 }
var result = reactor(undefined, [ reaction, reaction2 ], dispatch)

strictEqual(result.length, 2)
deepEqual(result[0].reaction, reaction)
deepEqual(result[1].reaction, reaction2)
strictEqual(promises.length, 2)
strictEqual(dispatch.callCount, 0)
})

it('cancels multiple reactions', () => {

const reaction = { 'foobar': 42 }
const reaction2 = { 'goat': 7 }
var result = reactor(undefined, [ reaction, reaction2 ], dispatch)
result = reactor(result, [], dispatch)

strictEqual(result.length, 0)
strictEqual(promises.length, 2)
strictEqual(dispatch.callCount, 0)
})
it('dispatches events', () => {
return new Promise(function (resolve) {
const reaction = { 'foobar': 42, events: { resolved: () => 8 } }
reactor(undefined, [ reaction ], resolve)
promises[0].resolve()
}).then( (action) => strictEqual(action, 8))
})

it('dispatches rejection events events', () => {
return new Promise(function (resolve) {
const reaction = { 'foobar': 42, events: { rejected: () => 8 } }
reactor(undefined, [ reaction ], resolve)
promises[0].reject()
}).then( (action) => strictEqual(action, 8))
})

it('dispatches events with argments', () => {
return new Promise(function (resolve) {
const reaction = { 'foobar': 42, events: { resolved: (x) => x } }
reactor(undefined, [ reaction ], resolve)
promises[0].resolve(99)
}).then((action) => strictEqual(action, 99))
})

it('replaces actions that only differ by event', () => {
return new Promise(function (resolve) {
const reaction = { 'foobar': 42, events: { resolved: (x) => x } }
const reaction2 = { 'foobar': 42, events: { resolved: (x) => x+1 } }
var result = reactor(undefined, [ reaction ], resolve)
result = reactor(result, [ reaction2 ], resolve)
promises[0].resolve(99)
}).then((action) => strictEqual(action, 100))
})

})

0 comments on commit c6e20cd

Please sign in to comment.