Skip to content

Commit

Permalink
Merge pull request #65 from akiellor/fix-dropping-of-effects
Browse files Browse the repository at this point in the history
FIX #64: Fix dropping of effects by detecting if an effect is already scheduled.
  • Loading branch information
Luke Westby committed Jul 20, 2016
2 parents d659202 + 5d29d52 commit c088cc9
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
9 changes: 9 additions & 0 deletions modules/effects.js
Expand Up @@ -52,6 +52,15 @@ export function isEffect(object) {
return object ? object[isEffectSymbol] : false;
}

/**
* Determines id the effect object is of type none
* @param {Object} The object to inspect.
* @returns {Boolean} Whether the object is a none effect.
*/
export function isNone(object) {
return object ? object.type === effectTypes.NONE : false;
}

/**
* Creates a noop effect.
* @returns {Object} An effect of type NONE, essentially a no-op.
Expand Down
7 changes: 6 additions & 1 deletion modules/install.js
Expand Up @@ -13,6 +13,7 @@ import {
batch,
none,
isEffect,
isNone,
effectToPromise,
} from './effects';

Expand All @@ -28,7 +29,11 @@ export function install() {
const liftReducer = (reducer) => (state, action) => {
const result = reducer(state, action);
const [model, effect] = liftState(result);
currentEffect = effect;
if (isNone(currentEffect)) {
currentEffect = effect
} else {
currentEffect = batch([currentEffect, effect]);
}
return model;
};

Expand Down
34 changes: 34 additions & 0 deletions test/index.test.js
Expand Up @@ -97,6 +97,40 @@ test('a looped action gets dispatched after the action that initiated it is redu
});
});

test('Effects are proccessed in the order they are recieved', (t) => {
t.plan(1);

const reducer = function (state = {}, action) {
switch (action.type) {
case 'LOOPED_BEGIN':
return loop(
{...state, done: false},
Effects.constant({type: 'LOOPED_END'})
)
case 'LOOPED_END':
return {...state, done: true};
default:
return state
}
};

const store = finalCreateStore(reducer, {});

let needsToFire = true;
store.subscribe(function() {
if (needsToFire) {
needsToFire = false;
store.dispatch({type: 'SOME_OTHER_ACTION'});
}
});

const dispatchPromise = store.dispatch({type: 'LOOPED_BEGIN'});
dispatchPromise.then(function(r) {
const state = store.getState();
t.equal(state.done, true);
});
});

test('Effects.lift', (t) => {
const lowerAction = (name) => ({ type: 'LOWER', name });
const upperAction = (arg, action) => ({ type: 'UPPER', arg, action });
Expand Down

0 comments on commit c088cc9

Please sign in to comment.