UNPKG

@sprucelabs/test-utils

Version:

Helpful utilities to make asserting more complicated conditions quick and easy! ⚡️

151 lines (150 loc) 6.36 kB
import SpruceTestResolver, { TestLifecycleListeners, } from './SpruceTestResolver.js'; if (typeof it === 'undefined') { //@ts-ignore global.it = () => { }; } let areLifecycleHooksInPlace = false; //recursive function to get static method by name looping up through constructor chain function resolveMethod(Target, name) { if (Target[name]) { return Target[name]; } if (Target.constructor && Target.constructor !== Target) { return resolveMethod(Target.constructor, name); } return null; } /** Hooks up before, after, etc. */ function hookupTestClassToJestLifecycle(Target) { if (areLifecycleHooksInPlace) { return; } areLifecycleHooksInPlace = true; const hooks = ['beforeAll', 'beforeEach', 'afterAll', 'afterEach']; hooks.forEach((hook) => { // @ts-ignore if (global[hook]) { // @ts-ignore global[hook](async () => { SpruceTestResolver.resolveTestClass(Target); if (hook === 'beforeEach') { await TestLifecycleListeners.emitWillRunBeforeEach(); await runBeforeEach(Target); await TestLifecycleListeners.emitDidRunBeforeEach(); } else if (hook === 'afterEach') { await TestLifecycleListeners.emitWillRunAfterEach(); await runAfterEach(Target); await TestLifecycleListeners.emitDidRunAfterEach(); SpruceTestResolver.reset(); } else if (hook === 'beforeAll') { await TestLifecycleListeners.emitWillRunBeforeAll(); await runBeforeAll(Target); await TestLifecycleListeners.emitDidRunBeforeAll(); SpruceTestResolver.reset(); } else if (hook === 'afterAll') { await TestLifecycleListeners.emitWillRunAfterAll(); await runAfterAll(Target); await TestLifecycleListeners.emitDidRunAfterAll(); } }); } }); } async function runBeforeAll(Target) { await callStaticHook(Target, 'beforeAll'); } async function runAfterAll(Target) { await callStaticHook(Target, 'afterAll'); } async function callStaticHook(Target, hook) { var _a; const cb = resolveMethod(Target, hook); await ((_a = cb === null || cb === void 0 ? void 0 : cb.apply) === null || _a === void 0 ? void 0 : _a.call(cb, SpruceTestResolver.ActiveTestClass ? Target.constructor : Target)); } async function runAfterEach(Target) { var _a, _b, _c, _d, _e; if (SpruceTestResolver.ActiveTestClass) { const Resolved = SpruceTestResolver.resolveTestClass(Target); await ((_a = Resolved.afterEach) === null || _a === void 0 ? void 0 : _a.apply(Resolved)); } else if (Target.afterEach) { await ((_c = (_b = Target.afterEach) === null || _b === void 0 ? void 0 : _b.apply) === null || _c === void 0 ? void 0 : _c.call(_b, Target)); } else { await ((_e = (_d = Target === null || Target === void 0 ? void 0 : Target.constructor.afterEach) === null || _d === void 0 ? void 0 : _d.apply) === null || _e === void 0 ? void 0 : _e.call(_d, Target.constructor)); } } async function runBeforeEach(Target) { var _a, _b, _c, _d, _e; if (SpruceTestResolver.ActiveTestClass) { const Resolved = SpruceTestResolver.resolveTestClass(Target); await ((_a = Resolved.beforeEach) === null || _a === void 0 ? void 0 : _a.apply(Resolved)); } else if (Target.beforeEach) { await ((_c = (_b = Target.beforeEach) === null || _b === void 0 ? void 0 : _b.apply) === null || _c === void 0 ? void 0 : _c.call(_b, Target)); } else { await ((_e = (_d = Target === null || Target === void 0 ? void 0 : Target.constructor.beforeEach) === null || _d === void 0 ? void 0 : _d.apply) === null || _e === void 0 ? void 0 : _e.call(_d, Target.constructor)); } } /** Test decorator */ export default function test(description, ...args) { return function (Target, propertyKey, descriptor) { hookupTestClassToJestLifecycle(Target); // Make sure each test gets the spruce it(description !== null && description !== void 0 ? description : propertyKey, async () => { const Resolved = SpruceTestResolver.resolveTestClass(Target); if (!Resolved[propertyKey]) { throw new Error(`The test '${propertyKey}()' should NOT be static when tests run with suite()`); } const bound = descriptor.value.bind(Resolved); //@ts-ignore global.activeTest = { file: Target.name, test: propertyKey, }; return bound(...args); }); }; } export function suite() { return function (Target) { SpruceTestResolver.ActiveTestClass = Target; }; } /** Only decorator */ test.only = (description, ...args) => { return function (target, propertyKey, descriptor) { // Lets attach before/after hookupTestClassToJestLifecycle(target); // Make sure each test gets the spruce it.only(description !== null && description !== void 0 ? description : propertyKey, async () => { const bound = descriptor.value.bind(SpruceTestResolver.resolveTestClass(target)); return bound(...args); }); }; }; /** Todo decorator */ test.todo = (description, ..._args) => { return function (target, propertyKey) { // Lets attach before/after hookupTestClassToJestLifecycle(target); // Make sure each test gets the spruce it.todo(description !== null && description !== void 0 ? description : propertyKey); }; }; /** Skip decorator */ test.skip = (description, ...args) => { return function (target, propertyKey, descriptor) { // Lets attach before/after hookupTestClassToJestLifecycle(target); // Make sure each test gets the spruce it.skip(description !== null && description !== void 0 ? description : propertyKey, async () => { const bound = descriptor.value.bind(SpruceTestResolver.resolveTestClass(target)); return bound(...args); }); }; };