npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redux-effects-test-jasmine

v0.1.0

Published

Jasmine helpers to test redux-effect actions

Downloads

5

Readme

Build Status

redux-effects-test-jasmine

Helper methods to test redux-effect actions with jasmine.

Installation

npm install redux-effects-test-jasmine

Usage

With the bind utility method provide by redux-effects we can structure action trees in two different ways.

  1. The first paramater of bind is a plain action ( no composed effect itself ). We will call these trees flat
  2. The first parameter of bind is a composed effect. We will call these trees nested.

The terminology comes from the way the test code looks like.

Testing flat action trees

First we define a few actions and a simple flow. Imagine we trigger something with a startAction and handle the success and failure case. On failure we will trigger cleanAction.

import {bind} from 'redux-effects';
import {createAction} from 'redux-actions';

// a set of actions
const startAction = createAction('START');
const successAction = createAction('SUCCESS');
const failureAction = createAction('FAILURE');
const cleanAction = createAction('CLEAN');

// flat action tree. Everything is written out explicitly to get a better idea.
export const doAction = (input) => bind(
  startAction(input),
  ({value}) => successAction(value),
  (response) => bind(
    failureAction(response),
    () => cleanAction()
  )
);

We want to test both flows and check if all actions are triggered properly.

/* global describe, it, expect */
import {expectEffect} from 'redux-effects-test-jasmine';

describe('a flat action', () => {
  it('should trigger: start -> success', () => {
    const start = doAction({id: 1});
    const successAction = expectEffect(start).withAction(action => {
      // check the action type
      expect(action).toBeOfType('START');

      // check the action content
      expect(action.payload).toEqual({id: 1});
    })
    // trigger the success case
    .toSuccess({value: 'data'});

    expect(successAction).toBeOfType('SUCCESS');
    expect(successAction.payload).toEqual('data');
  });

  it('should trigger: start -> failure -> clean', () => {
    const start = doAction({id: 2});
    const failureAction = expectEffect(start).withAction(action => {
      // check the action type
      expect(action).toBeOfType('START');

      // check the action content
      expect(action.payload).toEqual({id: 2});
    })
    // trigger the failure case
    .toFailure({value: 'error', statusCode: 500});

    const cleanAction = expectEffect(failureAction).withAction(action => {
      expect(action).toBeOfType('FAILURE');
      expect(action.payload).toEqual({value: 'error', statusCode: 500});
    }).toSuccess();

    expect(cleanAction).toBeOfType('CLEAN');
  });
});

Testing nested action trees

We use the same actions as defined in the previous example, but will define a new doAction.

// nested action tree. The first parameter is a composed effect
export const doAction = (input) => bind(
  bind(
    startAction(input),
    ({value}) => successAction(value),
    (response) => bind(
      failureAction(response),
      () => cleanAction()
    )
  )
);

The naive way of testing looks like this:

/* global describe, it, expect */
import {expectEffect} from 'redux-effects-test-jasmine';

describe('a nested action', () => {
  it('should trigger: start -> success', () => {
    const start = doAction({id: 1});

    // nest expections
    expectEffect(start).withAction(startActionEffect => {
      // extract successAction
      const successAction = expectEffect(startActionEffect).withAction(startAction => {
        // check the action type
        expect(startAction).toBeOfType('START');
        // check the action content
        expect(startAction.payload).toEqual({id: 1});
      })
      // trigger the success case
      .toSuccess({value: 'data'});

      expect(successAction).toBeOfType('SUCCESS');
      expect(successAction.payload).toEqual('data');
    });
  });
});

As you can see we need to nest the expectations, which can get messy. The expectEffectWithBind solves this problem by "flattening" the action tree. The algorithm basically works like this:

bind ( bind(X, XS, XF),           bind ( X,
       YS,                 ===>          bind(XS, YS, YF),
       YF )  

With this we can rewrite our test.

describe('a nested action', () => {
  it('should trigger: start -> success', () => {
    const start = doAction({id: 1});

    // effect with bind flattens the action tree
    const successAction = expectEffectWithBind(start).withAction(action => {
      // check the action type
      expect(action).toBeOfType('START');

      // check the action content
      expect(action.payload).toEqual({id: 1});
    })
    // trigger the success case
    .toSuccess({value: 'data'});

    // due to flattening the action tree the successAction is also a composed effect
    expectEffect(successAction).withAction(action => {
      expect(action).toBeOfType('SUCCESS');
      expect(action.payload).toEqual('data');
    });
  });
});

Log action trees

You can inspect action trees during testing with the logEffect utility method.

import {logEffect} from 'redux-effects-test-jasmine';

logEffect(actionToLog);

// if action needs some input value to trigger sub sequent actions
logEffect(actionToLog, () => {data: {}});

Build

To build the library

npm run build

Release

npm version [patch|minor|major]
npm publish
git push
git push --tags