episode-7
v1.1.2
Published
Sequence async side-effects with ES6 generators and easily test them.
Downloads
33
Readme
Episode 7 📺
A facade for side-effects: write test-friendly, async/await-style, JS code.
Care about unit testing around side-effects? You may fall in love with Episode 7.
Episode 7 is a simpler way
- spy on, intercept, & fake async function calls
- avoid brittle HTTP mocks
- confidently handle async errors
A tiny library 🐿
- no production npm dependencies
- <100-lines-of-code (without comments)
Functional in nature 🌲
Inspired by the test-friendly generator architecture of redux-saga
and the pure side-effects of Elm.
Requires
ES6/Generator support.
- Known to work in Node.js 6.2
- Should work in any ES6-compliant JavaScript environment
Install
npm install episode-7 --save
Changes
See: CHANGELOG
Usage
const Episode7 = require('episode-7');
const fetch = require('node-fetch');
// Compose an Episode 7 Generator for an async call sequence.
//
function* findFirstMovie(searchTerm) {
// Wrap side-effects with Episode 7's `call`
//
let results = yield Episode7.call(
fetchJson,
`http://www.omdbapi.com/?s=${encodeURIComponent(searchTerm)}`
);
// Do something programmatic with the result.
//
let firstResultId = results.Search[0].imdbID;
// Use that transformed value to make the next call.
//
let movie = yield Episode7.call(
fetchJson,
`http://www.omdbapi.com/?i=${encodeURIComponent(firstResultId)}`
);
return movie;
}
// Side-effect function,
// a barebones helper to fetch & decode JSON.
//
function fetchJson(url) {
return fetch(url).then( response => response.json() );
}
// Run the generator with Episode 7, returning a promise.
//
Episode7.run(findFirstMovie, 'Episode 7')
.then( movie => console.log(movie.Title) )
.catch( error => console.error(error) )
Smooth running tips 🚝
Handle errors
catch
after Episode7.run
to handle errors from the async flow (log|exit|retry).
Avoid catching within side-effect functions. Allow their errors to bubble up.
Name generator functions
Declare generator functions as named function expressions; this makes stacktraces & error messages more meaningful.
Background
I created this module to make it easy to code & test sequences of web service API requests interleaved with programmatic logic. I'm pulling the essence of redux-saga
into the smallest, plainest surface area conceivable.