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');
function* findFirstMovie(searchTerm) {
let results = yield Episode7.call(
fetchJson,
`http://www.omdbapi.com/?s=${encodeURIComponent(searchTerm)}`
);
let firstResultId = results.Search[0].imdbID;
let movie = yield Episode7.call(
fetchJson,
`http://www.omdbapi.com/?i=${encodeURIComponent(firstResultId)}`
);
return movie;
}
function fetchJson(url) {
return fetch(url).then( response => response.json() );
}
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.