版博士V2.0程序
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.

пре 1 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import { SpyImpl } from 'tinyspy';
  2. interface MockResultReturn<T> {
  3. type: 'return';
  4. value: T;
  5. }
  6. interface MockResultIncomplete {
  7. type: 'incomplete';
  8. value: undefined;
  9. }
  10. interface MockResultThrow {
  11. type: 'throw';
  12. value: any;
  13. }
  14. type MockResult<T> = MockResultReturn<T> | MockResultThrow | MockResultIncomplete;
  15. interface MockContext<TArgs, TReturns> {
  16. calls: TArgs[];
  17. instances: TReturns[];
  18. invocationCallOrder: number[];
  19. results: MockResult<TReturns>[];
  20. lastCall: TArgs | undefined;
  21. }
  22. type Procedure = (...args: any[]) => any;
  23. type Methods<T> = {
  24. [K in keyof T]: T[K] extends Procedure ? K : never;
  25. }[keyof T] & (string | symbol);
  26. type Properties<T> = {
  27. [K in keyof T]: T[K] extends Procedure ? never : K;
  28. }[keyof T] & (string | symbol);
  29. type Classes<T> = {
  30. [K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never;
  31. }[keyof T] & (string | symbol);
  32. interface SpyInstance<TArgs extends any[] = any[], TReturns = any> {
  33. getMockName(): string;
  34. mockName(n: string): this;
  35. mock: MockContext<TArgs, TReturns>;
  36. mockClear(): this;
  37. mockReset(): this;
  38. mockRestore(): void;
  39. getMockImplementation(): ((...args: TArgs) => TReturns) | undefined;
  40. mockImplementation(fn: ((...args: TArgs) => TReturns) | (() => Promise<TReturns>)): this;
  41. mockImplementationOnce(fn: ((...args: TArgs) => TReturns) | (() => Promise<TReturns>)): this;
  42. withImplementation<T>(fn: ((...args: TArgs) => TReturns), cb: () => T): T extends Promise<unknown> ? Promise<this> : this;
  43. mockReturnThis(): this;
  44. mockReturnValue(obj: TReturns): this;
  45. mockReturnValueOnce(obj: TReturns): this;
  46. mockResolvedValue(obj: Awaited<TReturns>): this;
  47. mockResolvedValueOnce(obj: Awaited<TReturns>): this;
  48. mockRejectedValue(obj: any): this;
  49. mockRejectedValueOnce(obj: any): this;
  50. }
  51. interface MockInstance<A extends any[] = any[], R = any> extends SpyInstance<A, R> {
  52. }
  53. interface Mock<TArgs extends any[] = any, TReturns = any> extends SpyInstance<TArgs, TReturns> {
  54. new (...args: TArgs): TReturns;
  55. (...args: TArgs): TReturns;
  56. }
  57. interface PartialMock<TArgs extends any[] = any, TReturns = any> extends SpyInstance<TArgs, Partial<TReturns>> {
  58. new (...args: TArgs): TReturns;
  59. (...args: TArgs): TReturns;
  60. }
  61. type MaybeMockedConstructor<T> = T extends new (...args: Array<any>) => infer R ? Mock<ConstructorParameters<T>, R> : T;
  62. type MockedFunction<T extends Procedure> = Mock<Parameters<T>, ReturnType<T>> & {
  63. [K in keyof T]: T[K];
  64. };
  65. type PartiallyMockedFunction<T extends Procedure> = PartialMock<Parameters<T>, ReturnType<T>> & {
  66. [K in keyof T]: T[K];
  67. };
  68. type MockedFunctionDeep<T extends Procedure> = Mock<Parameters<T>, ReturnType<T>> & MockedObjectDeep<T>;
  69. type PartiallyMockedFunctionDeep<T extends Procedure> = PartialMock<Parameters<T>, ReturnType<T>> & MockedObjectDeep<T>;
  70. type MockedObject<T> = MaybeMockedConstructor<T> & {
  71. [K in Methods<T>]: T[K] extends Procedure ? MockedFunction<T[K]> : T[K];
  72. } & {
  73. [K in Properties<T>]: T[K];
  74. };
  75. type MockedObjectDeep<T> = MaybeMockedConstructor<T> & {
  76. [K in Methods<T>]: T[K] extends Procedure ? MockedFunctionDeep<T[K]> : T[K];
  77. } & {
  78. [K in Properties<T>]: MaybeMockedDeep<T[K]>;
  79. };
  80. type MaybeMockedDeep<T> = T extends Procedure ? MockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T;
  81. type MaybePartiallyMockedDeep<T> = T extends Procedure ? PartiallyMockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T;
  82. type MaybeMocked<T> = T extends Procedure ? MockedFunction<T> : T extends object ? MockedObject<T> : T;
  83. type MaybePartiallyMocked<T> = T extends Procedure ? PartiallyMockedFunction<T> : T extends object ? MockedObject<T> : T;
  84. interface Constructable {
  85. new (...args: any[]): any;
  86. }
  87. type MockedClass<T extends Constructable> = MockInstance<T extends new (...args: infer P) => any ? P : never, InstanceType<T>> & {
  88. prototype: T extends {
  89. prototype: any;
  90. } ? Mocked<T['prototype']> : never;
  91. } & T;
  92. type Mocked<T> = {
  93. [P in keyof T]: T[P] extends (...args: infer Args) => infer Returns ? MockInstance<Args, Returns> : T[P] extends Constructable ? MockedClass<T[P]> : T[P];
  94. } & T;
  95. type EnhancedSpy<TArgs extends any[] = any[], TReturns = any> = SpyInstance<TArgs, TReturns> & SpyImpl<TArgs, TReturns>;
  96. declare const spies: Set<SpyInstance<any[], any>>;
  97. declare function isMockFunction(fn: any): fn is EnhancedSpy;
  98. declare function spyOn<T, S extends Properties<Required<T>>>(obj: T, methodName: S, accessType: 'get'): SpyInstance<[], T[S]>;
  99. declare function spyOn<T, G extends Properties<Required<T>>>(obj: T, methodName: G, accessType: 'set'): SpyInstance<[T[G]], void>;
  100. declare function spyOn<T, M extends (Classes<Required<T>> | Methods<Required<T>>)>(obj: T, methodName: M): Required<T>[M] extends ({
  101. new (...args: infer A): infer R;
  102. }) | ((...args: infer A) => infer R) ? SpyInstance<A, R> : never;
  103. declare function fn<TArgs extends any[] = any, R = any>(): Mock<TArgs, R>;
  104. declare function fn<TArgs extends any[] = any[], R = any>(implementation: (...args: TArgs) => R): Mock<TArgs, R>;
  105. export { EnhancedSpy, MaybeMocked, MaybeMockedConstructor, MaybeMockedDeep, MaybePartiallyMocked, MaybePartiallyMockedDeep, Mock, MockContext, MockInstance, Mocked, MockedClass, MockedFunction, MockedFunctionDeep, MockedObject, MockedObjectDeep, PartialMock, PartiallyMockedFunction, PartiallyMockedFunctionDeep, SpyInstance, fn, isMockFunction, spies, spyOn };