UNPKG

testdouble

Version:

A minimal test double library for TDD with JavaScript

103 lines (101 loc) 4.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("../wrap/lodash"); const args_match_1 = require("../args-match"); const is_callback_1 = require("../matchers/is-callback"); const notify_after_satisfaction_1 = require("../matchers/notify-after-satisfaction"); const config_1 = require("../config"); const log_1 = require("../log"); const index_1 = require("./index"); exports.default = { add(testDouble, args, stubbedValues, config) { return index_1.default.for(testDouble).stubbings.push({ callCount: 0, stubbedValues, args: config.cloneArgs ? lodash_1.default.cloneDeep(args) : args, config }); }, invoke(testDouble, actualArgs, actualContext) { const stubbing = stubbingFor(testDouble, actualArgs); if (stubbing) { (0, notify_after_satisfaction_1.default)(stubbing.args, actualArgs); return executePlan(stubbing, actualArgs, actualContext); } }, for(testDouble) { return index_1.default.for(testDouble).stubbings; } }; const stubbingFor = (testDouble, actualArgs) => lodash_1.default.findLast(index_1.default.for(testDouble).stubbings, stubbing => isSatisfied(stubbing, actualArgs)); const executePlan = (stubbing, actualArgs, actualContext) => { const value = stubbedValueFor(stubbing); stubbing.callCount += 1; invokeCallbackFor(stubbing, actualArgs); switch (stubbing.config.plan) { case 'thenReturn': return value; case 'thenDo': return value.apply(actualContext, actualArgs); case 'thenThrow': throw value; case 'thenResolve': return createPromise(stubbing, value, true); case 'thenReject': return createPromise(stubbing, value, false); } }; const invokeCallbackFor = (stubbing, actualArgs) => { if (lodash_1.default.some(stubbing.args, is_callback_1.default)) { lodash_1.default.each(stubbing.args, (expectedArg, i) => { if ((0, is_callback_1.default)(expectedArg)) { callCallback(stubbing, actualArgs[i], callbackArgs(stubbing, expectedArg)); } }); } }; const callbackArgs = (stubbing, expectedArg) => { if (expectedArg.args != null) { return expectedArg.args; } else if (stubbing.config.plan === 'thenCallback') { return stubbing.stubbedValues; } else { return []; } }; const callCallback = (stubbing, callback, args) => { if (stubbing.config.delay) { lodash_1.default.delay(callback, stubbing.config.delay, ...args); } else if (stubbing.config.defer) { lodash_1.default.defer(callback, ...args); } else { callback(...args); // eslint-disable-line } }; const createPromise = (stubbing, value, willResolve) => { const Promise = (0, config_1.default)().promiseConstructor; ensurePromise(Promise); return new Promise((resolve, reject) => { callCallback(stubbing, () => willResolve ? resolve(value) : reject(value), [value]); }); }; const stubbedValueFor = (stubbing) => stubbing.callCount < stubbing.stubbedValues.length ? stubbing.stubbedValues[stubbing.callCount] : lodash_1.default.last(stubbing.stubbedValues); const isSatisfied = (stubbing, actualArgs) => (0, args_match_1.default)(stubbing.args, actualArgs, stubbing.config) && hasTimesRemaining(stubbing); const hasTimesRemaining = (stubbing) => stubbing.config.times == null ? true : stubbing.callCount < stubbing.config.times; const ensurePromise = (Promise) => { if (Promise == null) { return log_1.default.error('td.when', `\ no promise constructor is set (perhaps this runtime lacks a native Promise function?), which means this stubbing can't return a promise to your subject under test, resulting in this error. To resolve the issue, set a promise constructor with \`td.config\`, like this: td.config({ promiseConstructor: require('bluebird') })\ `); } };