@chubbyjs/chubbyjs-mock
Version:
A very strict mocking library for class based objects.
106 lines (105 loc) • 4.26 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.mockByCallsUsed = void 0;
const AbstractArgument_1 = require("./Argument/AbstractArgument");
const mockByCallsUsed = (mock) => mock.__mockByCalls.calls.length === mock.__mockByCalls.index;
exports.mockByCallsUsed = mockByCallsUsed;
class MockByCalls {
create(classDefinition, calls = []) {
const mock = {
...Object.fromEntries(this.getMethods(new classDefinition()).map((method) => {
return [
method,
(...args) => {
return mock.__mockByCalls.mock(method, args);
},
];
})),
...{
__mockByCalls: {
calls,
index: 0,
mock: (actualMethod, actualArgs) => {
const call = mock.__mockByCalls.calls[mock.__mockByCalls.index];
if (!call) {
throw new Error(`Missing call: ${JSON.stringify({
class: classDefinition.name,
callIndex: mock.__mockByCalls.index,
actualMethod,
})}`);
}
this.matchMethod(call.getMethod(), actualMethod, classDefinition.name, mock.__mockByCalls.index);
if (call.hasWith()) {
const expectedArgs = call.getWith();
this.matchArguments(expectedArgs, actualArgs, classDefinition.name, mock.__mockByCalls.index, actualMethod);
}
mock.__mockByCalls.index++;
const error = call.getError();
if (error) {
throw error;
}
if (call.hasReturnSelf()) {
return mock;
}
if (call.hasReturn()) {
return call.getReturn();
}
const returnCallback = call.getReturnCallback();
if (returnCallback) {
return returnCallback(...actualArgs);
}
},
},
},
};
// @ts-ignore
return mock;
}
getMethods(actualObject) {
const props = [];
let object = actualObject;
do {
props.push(...Object.getOwnPropertyNames(object));
} while ((object = Object.getPrototypeOf(object)));
return props.filter((prop) => typeof actualObject[prop] == 'function');
}
matchMethod(expectedMethod, actualMethod, className, callIndex) {
if (actualMethod !== expectedMethod) {
throw new Error(`Method mismatch: ${JSON.stringify({
class: className,
callIndex,
actualMethod,
expectedMethod,
})}`);
}
}
matchArguments(expectedArgs, actualArgs, className, callIndex, actualMethod) {
if (actualArgs.length !== expectedArgs.length) {
throw new Error(`Arguments count mismatch: ${JSON.stringify({
class: className,
callIndex,
actualMethod,
actualArgsLength: actualArgs.length,
expectedArgsLength: expectedArgs.length,
})}`);
}
expectedArgs.forEach((expectedArg, argIndex) => {
const actualArg = actualArgs[argIndex];
if (expectedArg instanceof AbstractArgument_1.default) {
expectedArg.assert(actualArg);
return;
}
if (actualArg !== expectedArg) {
throw new Error(`Argument mismatch: ${JSON.stringify({
class: className,
callIndex,
actualMethod,
argIndex,
actualArg,
expectedArg,
})}`);
}
});
}
}
exports.default = MockByCalls;
;