@chubbyts/chubbyts-function-mock
Version:
A function mock helper.
90 lines (89 loc) • 2.97 kB
JavaScript
/* eslint-disable @typescript-eslint/no-invalid-void-type */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { deepStrictEqual } from 'assert';
const formatContext = (context) => JSON.stringify(context);
export const internalResolveCallerLineFromStack = (stack) => {
if (!stack) {
return undefined;
}
const stackLines = stack.split('\n');
for (const stackLine of stackLines) {
if (-1 === stackLine.search(/at /)) {
continue;
}
if (-1 === stackLine.search(/function-mock\.(cjs|js|mjs|ts)/)) {
return parseInt(stackLine.split(':')[1]);
}
}
return undefined;
};
export const createFunctionMock = (mocks) => {
const line = internalResolveCallerLineFromStack(new Error().stack);
// eslint-disable-next-line functional/no-let
let mockIndex = 0;
return (...actualParameters) => {
// eslint-disable-next-line functional/immutable-data
const mock = mocks.shift();
if (!mock) {
throw new Error(`Missing mock: ${formatContext({
line,
mockIndex,
})}`);
}
if (typeof mock === 'function') {
mockIndex++;
return mock(...actualParameters);
}
if ('callback' in mock) {
mockIndex++;
return mock.callback(...actualParameters);
}
if (actualParameters.length !== mock.parameters.length) {
throw new Error(`Parameters count mismatch: ${formatContext({
line,
mockIndex,
actual: actualParameters.length,
expect: mock.parameters.length,
})}`);
}
mock.parameters.forEach((expect, parameterIndex) => {
const actual = actualParameters[parameterIndex];
if (mock.strict) {
if (actual !== expect) {
throw new Error(`Parameter mismatch: ${formatContext({
line,
mockIndex,
parameterIndex,
actual,
expect,
strict: true,
})}`);
}
}
else {
try {
deepStrictEqual(actual, expect);
}
catch {
throw new Error(`Parameter mismatch: ${formatContext({
line,
mockIndex,
parameterIndex,
actual,
expect,
})}`);
}
}
});
mockIndex++;
if ('error' in mock) {
throw mock.error;
}
if ('return' in mock) {
return mock.return;
}
};
};
export const useFunctionMock = (mocks) => {
return [createFunctionMock(mocks), mocks];
};