You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.9 KiB
103 lines
2.9 KiB
2 years ago
|
import * as tinyspy from 'tinyspy';
|
||
|
|
||
|
const spies = /* @__PURE__ */ new Set();
|
||
|
function isMockFunction(fn2) {
|
||
|
return typeof fn2 === "function" && "_isMockFunction" in fn2 && fn2._isMockFunction;
|
||
|
}
|
||
|
function spyOn(obj, method, accessType) {
|
||
|
const dictionary = {
|
||
|
get: "getter",
|
||
|
set: "setter"
|
||
|
};
|
||
|
const objMethod = accessType ? { [dictionary[accessType]]: method } : method;
|
||
|
const stub = tinyspy.spyOn(obj, objMethod);
|
||
|
return enhanceSpy(stub);
|
||
|
}
|
||
|
let callOrder = 0;
|
||
|
function enhanceSpy(spy) {
|
||
|
const stub = spy;
|
||
|
let implementation;
|
||
|
let instances = [];
|
||
|
let invocations = [];
|
||
|
const mockContext = {
|
||
|
get calls() {
|
||
|
return stub.calls;
|
||
|
},
|
||
|
get instances() {
|
||
|
return instances;
|
||
|
},
|
||
|
get invocationCallOrder() {
|
||
|
return invocations;
|
||
|
},
|
||
|
get results() {
|
||
|
return stub.results.map(([callType, value]) => {
|
||
|
const type = callType === "error" ? "throw" : "return";
|
||
|
return { type, value };
|
||
|
});
|
||
|
},
|
||
|
get lastCall() {
|
||
|
return stub.calls[stub.calls.length - 1];
|
||
|
}
|
||
|
};
|
||
|
let onceImplementations = [];
|
||
|
let name = stub.name;
|
||
|
stub.getMockName = () => name || "vi.fn()";
|
||
|
stub.mockName = (n) => {
|
||
|
name = n;
|
||
|
return stub;
|
||
|
};
|
||
|
stub.mockClear = () => {
|
||
|
stub.reset();
|
||
|
instances = [];
|
||
|
invocations = [];
|
||
|
return stub;
|
||
|
};
|
||
|
stub.mockReset = () => {
|
||
|
stub.mockClear();
|
||
|
implementation = () => void 0;
|
||
|
onceImplementations = [];
|
||
|
return stub;
|
||
|
};
|
||
|
stub.mockRestore = () => {
|
||
|
stub.mockReset();
|
||
|
implementation = void 0;
|
||
|
return stub;
|
||
|
};
|
||
|
stub.getMockImplementation = () => implementation;
|
||
|
stub.mockImplementation = (fn2) => {
|
||
|
implementation = fn2;
|
||
|
return stub;
|
||
|
};
|
||
|
stub.mockImplementationOnce = (fn2) => {
|
||
|
onceImplementations.push(fn2);
|
||
|
return stub;
|
||
|
};
|
||
|
stub.mockReturnThis = () => stub.mockImplementation(function() {
|
||
|
return this;
|
||
|
});
|
||
|
stub.mockReturnValue = (val) => stub.mockImplementation(() => val);
|
||
|
stub.mockReturnValueOnce = (val) => stub.mockImplementationOnce(() => val);
|
||
|
stub.mockResolvedValue = (val) => stub.mockImplementation(() => Promise.resolve(val));
|
||
|
stub.mockResolvedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.resolve(val));
|
||
|
stub.mockRejectedValue = (val) => stub.mockImplementation(() => Promise.reject(val));
|
||
|
stub.mockRejectedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.reject(val));
|
||
|
Object.defineProperty(stub, "mock", {
|
||
|
get: () => mockContext
|
||
|
});
|
||
|
stub.willCall(function(...args) {
|
||
|
instances.push(this);
|
||
|
invocations.push(++callOrder);
|
||
|
const impl = onceImplementations.shift() || implementation || stub.getOriginal() || (() => {
|
||
|
});
|
||
|
return impl.apply(this, args);
|
||
|
});
|
||
|
spies.add(stub);
|
||
|
return stub;
|
||
|
}
|
||
|
function fn(implementation) {
|
||
|
return enhanceSpy(tinyspy.spyOn({ fn: implementation || (() => {
|
||
|
}) }, "fn"));
|
||
|
}
|
||
|
|
||
|
export { spies as a, fn as f, isMockFunction as i, spyOn as s };
|