UNPKG

test-fns

Version:

write usecase driven tests systematically for simpler, safer, and more readable code

77 lines 4.22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.then = exports.when = exports.given = exports.getNumberRange = void 0; const helpful_errors_1 = require("helpful-errors"); const getNumberRange = (input) => { // Calculate the length of the range const length = input.end - input.start + 1; // Create an array with the specified range return Array.from({ length }, (_, i) => input.start + i); }; exports.getNumberRange = getNumberRange; const castToJestTestInput = ({ input, prefix, }) => { const method = input.length === 3 ? input[2] : input[1]; // its always last if (input.length === 3) return [`${prefix}: ${input[0]}`, method]; // we allow users to specify the reason for code readability, but we dont expose this in the test report to decrease noise. folks can look in the code if they want to know "why" return [`${prefix}: ${input[0]}`, method]; // otherwise, its the normal input }; const given = (desc, fn) => describe(`given: ${desc}`, fn); exports.given = given; exports.given.only = (desc, fn) => describe.only(`given: ${desc}`, fn); exports.given.skip = (desc, fn) => describe.skip(`given: ${desc}`, fn); exports.given.skipIf = (condition) => (desc, fn) => condition ? exports.given.skip(desc, fn) : (0, exports.given)(desc, fn); exports.given.runIf = (condition) => exports.given.skipIf(!condition); const when = (desc, fn) => describe(`when: ${desc}`, fn); exports.when = when; exports.when.only = (desc, fn) => describe.only(`when: ${desc}`, fn); exports.when.skip = (desc, fn) => describe.skip(`when: ${desc}`, fn); exports.when.skipIf = (condition) => (desc, fn) => condition ? exports.when.skip(desc, fn) : (0, exports.when)(desc, fn); exports.when.runIf = (condition) => exports.when.skipIf(!condition); const then = (...input) => test(...castToJestTestInput({ input, prefix: 'then' })); exports.then = then; exports.then.only = (...input) => test.only(...castToJestTestInput({ input, prefix: 'then' })); exports.then.skip = (...input) => test.skip(...castToJestTestInput({ input, prefix: 'then' })); exports.then.todo = (...input) => test.todo(castToJestTestInput({ input: [input[0]], prefix: 'then' })[0]); // note that we only pass the first input, since jest's .todo function throws an error if you pass an implementation fn exports.then.skipIf = (condition) => (...input) => condition ? exports.then.skip(...input) : (0, exports.then)(...input); exports.then.runIf = (condition) => exports.then.skipIf(!condition); exports.then.repeatably = (configuration) => (...input) => { // validate the input length if (input.length !== 2 && input.length !== 3) throw new helpful_errors_1.UnexpectedCodePathError('unsupported input length', { input, }); // support the "SOME" criteria if (configuration.criteria === 'SOME') { // use the native "retryTimes" jest.retryTimes(configuration.attempts, { logErrorsBeforeRetry: true }); // track the number of attempts let attempt = 0; beforeEach(() => attempt++); // and run the test if (input.length === 2) (0, exports.then)(input[0], () => input[1]({ attempt })); if (input.length === 3) (0, exports.then)(input[0], input[1], () => input[2]({ attempt })); return; } // support the "EVERY" criteria if (configuration.criteria === 'EVERY') { for (const attempt of (0, exports.getNumberRange)({ start: 1, end: configuration.attempts, })) { if (input.length === 2) (0, exports.then)(input[0] + `, attempt ${attempt}`, () => input[1]({ attempt })); if (input.length === 3) (0, exports.then)(input[0] + `, attempt ${attempt}`, input[1], () => input[2]({ attempt })); } return; } // throw if neither throw new helpful_errors_1.UnexpectedCodePathError('configuration.criteria was neither EVERY nor SOME', { configuration }); }; //# sourceMappingURL=givenWhenThen.js.map