UNPKG

testdouble

Version:

A minimal test double library for TDD with JavaScript

88 lines (79 loc) 2.53 kB
import _ from './wrap/lodash' import callback from './callback' import isCallback from './matchers/is-callback' import calls from './store/calls' import log from './log' import stubbings from './store/stubbings' import tdConfig from './config' import cloneDeepIfPossible from './clone-deep-if-possible' import symbols from './symbols' export default function when (__userDoesRehearsalInvocationHere__, config = {}) { return ({ thenReturn (...stubbedValues) { return addStubbing(stubbedValues, config, 'thenReturn') }, thenCallback (...stubbedValues) { return addStubbing(stubbedValues, config, 'thenCallback') }, thenDo (...stubbedValues) { return addStubbing(stubbedValues, config, 'thenDo') }, thenThrow (...stubbedValues) { return addStubbing(stubbedValues, config, 'thenThrow') }, thenResolve (...stubbedValues) { warnIfPromiseless() return addStubbing(stubbedValues, config, 'thenResolve') }, thenReject (...stubbedValues) { warnIfPromiseless() return addStubbing(stubbedValues, config, 'thenReject') } }) } function addStubbing (stubbedValues, config, plan) { const last = calls.pop() ensureRehearsalOccurred(last) ensureCloneableIfCloneArgs(last, config) _.assign(config, { plan }) stubbings.add(last.testDouble, concatImpliedCallback(last.args, config), stubbedValues, config) return last.testDouble } function ensureRehearsalOccurred (last) { if (!last) { return log.error('td.when', `\ No test double invocation call detected for \`when()\`. Usage: when(myTestDouble('foo')).thenReturn('bar')\ ` ) } } function ensureCloneableIfCloneArgs (last, config) { if (config.cloneArgs && cloneDeepIfPossible(last.args) === symbols.uncloneable) { return log.error('td.when', `\ Failed to deep-clone arguments. Ensure lodash _.cloneDeep works on them `) } } function concatImpliedCallback (args, config) { if (config.plan !== 'thenCallback') { return args } else if (!_.some(args, isCallback)) { return args.concat(callback) } else { return args } } function warnIfPromiseless () { if (tdConfig().promiseConstructor == null) { log.warn('td.when', `\ no promise constructor is set, so this \`thenResolve\` or \`thenReject\` stubbing will fail if it's satisfied by an invocation on the test double. You can tell testdouble.js which promise constructor to use with \`td.config\`, like so: td.config({ promiseConstructor: require('bluebird') })\ `) } }