sm-utility 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -18,3 +18,4 @@ __exportStar(require("./general"), exports);
18
18
  __exportStar(require("./infrastructure"), exports);
19
19
  __exportStar(require("./logger"), exports);
20
20
  __exportStar(require("./request"), exports);
21
+ __exportStar(require("./stubs"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sm-utility",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "reusable utility codes for sm projects",
5
5
  "main": "index.js",
6
6
  "types": "./index.d.ts",
@@ -0,0 +1,46 @@
1
+ declare type GenericClass<T> = (new (...args: any[]) => T);
2
+ declare type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
3
+ declare type TypesByMethodNames<T> = {
4
+ [K in keyof T]?: T[K] extends (...args: any[]) => infer R ? R : never;
5
+ };
6
+ declare type ResolvedTypesByMethodNames<T> = {
7
+ [K in keyof T]?: T[K] extends (...args: any[]) => infer R ? UnwrapPromise<R> : never;
8
+ };
9
+ /**
10
+ * Creates a mock instance of a given class with customized method implementations,
11
+ * where method return values are automatically unwrapped if they are promises.
12
+ * @example
13
+ * const userRepository = mockResolvedClass(UserRepository, {
14
+ * findUserByToken: { token: 'adhf753', name: 'John' },
15
+ * });
16
+ * @param Class - The class to mock.
17
+ * @param givenMethods - An object containing customized key-value pairs where the key
18
+ * is the method name and the value is the resolved method value.
19
+ * @returns A mocked instance of the provided class with overridden methods.
20
+ */
21
+ export declare function mockResolvedClass<T>(Class: GenericClass<T>, givenMethods?: ResolvedTypesByMethodNames<T>): T;
22
+ /**
23
+ * Creates a mock instance of a given class with customized method implementations.
24
+ * @example
25
+ * const userRepository = mockClass(UserRepository, {
26
+ * findUserByToken: Promise.resolve({ token: 'adhf753', name: 'John' }),
27
+ * });
28
+ * @param Class - The class to mock.
29
+ * @param methods - An object containing customized key-value pairs where the key
30
+ * is the method name and the value is the returned method value.
31
+ * @returns A mocked instance of the provided class with overridden methods.
32
+ */
33
+ export declare function mockClass<T>(Class: GenericClass<T>, givenMethods?: TypesByMethodNames<T>): T;
34
+ /**
35
+ * Creates a raw mock instance of a given class with no method implementations.
36
+ * This function is intended for use with testing frameworks like jest (spyOn) when
37
+ * you want to set up **manual** method spies. Alternatively, consider using
38
+ * {@link mockClass} or {@link mockResolvedClass} for more comprehensive method mocking.
39
+ * @example
40
+ * const rawUserRepository = rawInstance(UserRepository);
41
+ * jest.spyOn(rawUserRepository, 'findUserByToken').mockRejectedValue(new Error('Token expired'));
42
+ * @param Class - The class to mock.
43
+ * @returns A raw mocked instance of the provided class with no implemented methods.
44
+ */
45
+ export declare function rawInstance<T>(Class: GenericClass<T>): T;
46
+ export {};
package/stubs/index.js ADDED
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rawInstance = exports.mockClass = exports.mockResolvedClass = void 0;
4
+ class MockedClassInstance {
5
+ }
6
+ ;
7
+ /**
8
+ * Creates a mock instance of a given class with customized method implementations,
9
+ * where method return values are automatically unwrapped if they are promises.
10
+ * @example
11
+ * const userRepository = mockResolvedClass(UserRepository, {
12
+ * findUserByToken: { token: 'adhf753', name: 'John' },
13
+ * });
14
+ * @param Class - The class to mock.
15
+ * @param givenMethods - An object containing customized key-value pairs where the key
16
+ * is the method name and the value is the resolved method value.
17
+ * @returns A mocked instance of the provided class with overridden methods.
18
+ */
19
+ function mockResolvedClass(Class, givenMethods) {
20
+ const MockedClass = rawInstance(Class);
21
+ if (!givenMethods)
22
+ return MockedClass;
23
+ for (const classMethod in givenMethods) {
24
+ const methodName = classMethod;
25
+ const mockImplementation = () => givenMethods[methodName];
26
+ MockedClass[methodName] = mockImplementation;
27
+ }
28
+ return MockedClass;
29
+ }
30
+ exports.mockResolvedClass = mockResolvedClass;
31
+ /**
32
+ * Creates a mock instance of a given class with customized method implementations.
33
+ * @example
34
+ * const userRepository = mockClass(UserRepository, {
35
+ * findUserByToken: Promise.resolve({ token: 'adhf753', name: 'John' }),
36
+ * });
37
+ * @param Class - The class to mock.
38
+ * @param methods - An object containing customized key-value pairs where the key
39
+ * is the method name and the value is the returned method value.
40
+ * @returns A mocked instance of the provided class with overridden methods.
41
+ */
42
+ function mockClass(Class, givenMethods) {
43
+ const MockedClass = rawInstance(Class);
44
+ if (!givenMethods)
45
+ return MockedClass;
46
+ for (const classMethod in givenMethods) {
47
+ const methodName = classMethod;
48
+ const mockImplementation = () => givenMethods[methodName];
49
+ MockedClass[methodName] = mockImplementation;
50
+ }
51
+ return MockedClass;
52
+ }
53
+ exports.mockClass = mockClass;
54
+ /**
55
+ * Creates a raw mock instance of a given class with no method implementations.
56
+ * This function is intended for use with testing frameworks like jest (spyOn) when
57
+ * you want to set up **manual** method spies. Alternatively, consider using
58
+ * {@link mockClass} or {@link mockResolvedClass} for more comprehensive method mocking.
59
+ * @example
60
+ * const rawUserRepository = rawInstance(UserRepository);
61
+ * jest.spyOn(rawUserRepository, 'findUserByToken').mockRejectedValue(new Error('Token expired'));
62
+ * @param Class - The class to mock.
63
+ * @returns A raw mocked instance of the provided class with no implemented methods.
64
+ */
65
+ function rawInstance(Class) {
66
+ const MockedClass = new MockedClassInstance();
67
+ const classMethods = Object.getOwnPropertyNames(Class.prototype).filter(methodName => methodName !== 'constructor' &&
68
+ typeof Class.prototype[methodName] === 'function');
69
+ for (const classMethod of classMethods) {
70
+ const methodName = classMethod;
71
+ const mockImplementation = () => {
72
+ throw new Error(`Method ${classMethod} not implemented`);
73
+ };
74
+ MockedClass[methodName] = mockImplementation;
75
+ }
76
+ return MockedClass;
77
+ }
78
+ exports.rawInstance = rawInstance;