UNPKG

@chubbyts/chubbyts-function-mock

Version:
90 lines (89 loc) 2.97 kB
/* 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]; };