node.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. /*
  2. * Helpers for testing Redux.
  3. */
  4. const FINISHED = "@@test/SPYSHOULDBEFINISHED";
  5. /**
  6. * Creates the middleware that checks if specified actions are dispatched.
  7. * Use it like `const spy = spyInTheMiddle(fn1, fn2, ...), store = applyMiddleware(..., spy)(reducer);`.
  8. * The fn1, ... get action in the parameter and should return truthy value if it is the expected one,
  9. * in which case the expectation will be removed; and shoudl return falsy value if it can be ignored.
  10. * For the moment, only first expectation in the list is checked until it returns true, then it is removed and the next one will be used,
  11. * In case the action is invalid (like, it has right type but wrong payload), the expectation fn can (and should) throw,
  12. * for example using the test assertion (in chai/expect, assertions are truthy, so your expectation fn can look like below)
  13. *
  14. * ({type, payload: {foo}}) => type == "FOOIFY" && expect(foo).to.equal("bar")
  15. *
  16. * All actions are passed downstream, unless you threw.
  17. *
  18. * @param expectations
  19. */
  20. export const spyInTheMiddle = (...expectations) => store => next => action => {
  21. if (action.type == FINISHED && expectations.length > 0) throw new Error(`Expectations left unfulfilled: ${expectations.length}`);
  22. if (expectations[0] && expectations[0](action)) {
  23. expectations.shift();
  24. }
  25. return next(action);
  26. };
  27. /**
  28. * Call `store.dispatch(SPY_VERIFY)` at the end of the test.
  29. * It will pass if all expectations were fulfilled and fail if there are still some hanging there.
  30. * @type {{type: string}}
  31. */
  32. export const SPY_VERIFY = {type: FINISHED};
  33. /**
  34. * Reducer that always returns unchanged state.
  35. * @param state
  36. * @param action
  37. */
  38. export const dumbReducer = (state, action) => state;