-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
33 lines (28 loc) · 1.3 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const chars = "abcdefghijklmnopqrstuvwxyz";
function random(count: number) {
return Array(count).fill(null).map(() => chars[Math.round(Math.random() * chars.length)]).join("");
}
type OverrideIfFunction<T> = T extends (...args: any[]) => any ? jest.Mock<ReturnType<T>, Parameters<T>> : T
type FunctionExcluded<T> = { [key in keyof T]?: T[key] extends (...args: any[]) => any ? never : T[key] };
type MockedObject<T> = {
[key in keyof T]: OverrideIfFunction<T[key]>;
}
export function mock<T extends {}>(overrideProps?: FunctionExcluded<T>): T & MockedObject<T> {
return inner<T>(overrideProps);
}
function inner<T extends { [key: string]: (...args: any) => any }>(overrideProps?: { [key in keyof T]?: T[key] }) {
const inner: { [key in string | number]: jest.Mock } = {};
const id = random(5);
return new Proxy({ __id__: id } as unknown as (T & MockedObject<T>), {
get(_, key) {
if (key === "__id__") return `#${id}`;
if (key === "then") return;
if (typeof key === "symbol") return;
if (key === "toString") return () => `mock#${id}`;
if (key === "toJSON") return () => ({ id: `#${id}` });
if (key === "_isAllArgsFunctionMatcher") return false;
if (overrideProps?.[key] != null) return overrideProps?.[key];
return inner[key] = inner[key] ?? jest.fn();
}
});
}