testdouble
Version:
A minimal test double library for TDD with JavaScript
86 lines (83 loc) • 3 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = require("./wrap/lodash");
const callback_1 = require("./callback");
const is_callback_1 = require("./matchers/is-callback");
const calls_1 = require("./store/calls");
const log_1 = require("./log");
const stubbings_1 = require("./store/stubbings");
const config_1 = require("./config");
const clone_deep_if_possible_1 = require("./clone-deep-if-possible");
const symbols_1 = require("./symbols");
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');
}
});
}
exports.default = when;
function addStubbing(stubbedValues, config, plan) {
const last = calls_1.default.pop();
ensureRehearsalOccurred(last);
ensureCloneableIfCloneArgs(last, config);
lodash_1.default.assign(config, { plan });
stubbings_1.default.add(last.testDouble, concatImpliedCallback(last.args, config), stubbedValues, config);
return last.testDouble;
}
function ensureRehearsalOccurred(last) {
if (!last) {
return log_1.default.error('td.when', `\
No test double invocation call detected for \`when()\`.
Usage:
when(myTestDouble('foo')).thenReturn('bar')\
`);
}
}
function ensureCloneableIfCloneArgs(last, config) {
if (config.cloneArgs && (0, clone_deep_if_possible_1.default)(last.args) === symbols_1.default.uncloneable) {
return log_1.default.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 (!lodash_1.default.some(args, is_callback_1.default)) {
return args.concat(callback_1.default);
}
else {
return args;
}
}
function warnIfPromiseless() {
if ((0, config_1.default)().promiseConstructor == null) {
log_1.default.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')
})\
`);
}
}
;