@sprucelabs/test-utils
Version:
Helpful utilities to make asserting more complicated conditions quick and easy! ⚡️
185 lines (184 loc) • 7.15 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = test;
exports.suite = suite;
const SpruceTestResolver_1 = __importStar(require("./SpruceTestResolver"));
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_1.default.resolveTestClass(Target);
if (hook === 'beforeEach') {
await SpruceTestResolver_1.TestLifecycleListeners.emitWillRunBeforeEach();
await runBeforeEach(Target);
await SpruceTestResolver_1.TestLifecycleListeners.emitDidRunBeforeEach();
}
else if (hook === 'afterEach') {
await SpruceTestResolver_1.TestLifecycleListeners.emitWillRunAfterEach();
await runAfterEach(Target);
await SpruceTestResolver_1.TestLifecycleListeners.emitDidRunAfterEach();
SpruceTestResolver_1.default.reset();
}
else if (hook === 'beforeAll') {
await SpruceTestResolver_1.TestLifecycleListeners.emitWillRunBeforeAll();
await runBeforeAll(Target);
await SpruceTestResolver_1.TestLifecycleListeners.emitDidRunBeforeAll();
SpruceTestResolver_1.default.reset();
}
else if (hook === 'afterAll') {
await SpruceTestResolver_1.TestLifecycleListeners.emitWillRunAfterAll();
await runAfterAll(Target);
await SpruceTestResolver_1.TestLifecycleListeners.emitDidRunAfterAll();
}
});
}
});
}
async function runBeforeAll(Target) {
await callStaticHook(Target, 'beforeAll');
}
async function runAfterAll(Target) {
await callStaticHook(Target, 'afterAll');
}
async function callStaticHook(Target, hook) {
const cb = resolveMethod(Target, hook);
await cb?.apply?.(SpruceTestResolver_1.default.ActiveTestClass ? Target.constructor : Target);
}
async function runAfterEach(Target) {
if (SpruceTestResolver_1.default.ActiveTestClass) {
const Resolved = SpruceTestResolver_1.default.resolveTestClass(Target);
await Resolved.afterEach?.apply(Resolved);
}
else if (Target.afterEach) {
await Target.afterEach?.apply?.(Target);
}
else {
await Target?.constructor.afterEach?.apply?.(Target.constructor);
}
}
async function runBeforeEach(Target) {
if (SpruceTestResolver_1.default.ActiveTestClass) {
const Resolved = SpruceTestResolver_1.default.resolveTestClass(Target);
await Resolved.beforeEach?.apply(Resolved);
}
else if (Target.beforeEach) {
await Target.beforeEach?.apply?.(Target);
}
else {
await Target?.constructor.beforeEach?.apply?.(Target.constructor);
}
}
/** Test decorator */
function test(description, ...args) {
return function (Target, propertyKey, descriptor) {
hookupTestClassToJestLifecycle(Target);
// Make sure each test gets the spruce
it(description ?? propertyKey, async () => {
const Resolved = SpruceTestResolver_1.default.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);
});
};
}
function suite() {
return function (Target) {
SpruceTestResolver_1.default.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 ?? propertyKey, async () => {
const bound = descriptor.value.bind(SpruceTestResolver_1.default.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 ?? 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 ?? propertyKey, async () => {
const bound = descriptor.value.bind(SpruceTestResolver_1.default.resolveTestClass(target));
return bound(...args);
});
};
};