UNPKG

serverless-spy

Version:

CDK-based library for writing elegant integration tests on AWS serverless architecture and an additional web console to monitor events in real time.

299 lines (279 loc) 9.83 kB
import { PrettifyForDisplay } from './PrettifyForDisplay'; import { RecursivePartial } from './RecursivePartial'; import { DynamoDBSpyEvent } from '../common/spyEvents/DynamoDBSpyEvent'; import { EventBridgeRuleSpyEvent } from '../common/spyEvents/EventBridgeRuleSpyEvent'; import { EventBridgeSpyEvent } from '../common/spyEvents/EventBridgeSpyEvent'; import { FunctionConsole } from '../common/spyEvents/FunctionConsole'; import { FunctionConsoleSpyEvent } from '../common/spyEvents/FunctionConsoleSpyEvent'; import { FunctionContext } from '../common/spyEvents/FunctionContext'; import { FunctionErrorSpyEvent } from '../common/spyEvents/FunctionErrorSpyEvent'; import { FunctionRequestSpyEvent } from '../common/spyEvents/FunctionRequestSpyEvent'; import { FunctionResponseSpyEvent } from '../common/spyEvents/FunctionResponseSpyEvent'; import { S3SpyEvent } from '../common/spyEvents/S3SpyEvent'; import { SnsSubscriptionSpyEvent } from '../common/spyEvents/SnsSubscriptionSpyEvent'; import { SnsTopicSpyEvent } from '../common/spyEvents/SnsTopicSpyEvent'; import { SqsSpyEvent } from '../common/spyEvents/SqsSpyEvent'; type MyJestMatchers = ReturnType<typeof expect>; type MyJestMatchersWitOnlyFunctions = Pick< MyJestMatchers, { [P in keyof MyJestMatchers]: MyJestMatchers[P] extends (...args: any) => any ? P : never; }[keyof MyJestMatchers] >; type JestExpectWithSpyMethods<TSpyEvent, TSpyHandler> = Omit< { // toMatchObject: (expected: RecursivePartial<TSpyEvent>) => TSpyHandler; [K in keyof MyJestMatchersWitOnlyFunctions]: ( ...args: Parameters<MyJestMatchersWitOnlyFunctions[K]> ) => TSpyHandler; }, 'toContainEqual' | 'toEqual' | 'toMatchObject' | 'toStrictEqual' > & { /** * Used when you want to check that an item is in a list. * For testing the items in the list, this matcher recursively checks the * equality of all fields, rather than checking for object identity. * * Optionally, you can provide a type for the expected value via a generic. * This is particularly useful for ensuring expected objects have the right structure. */ toContainEqual(expected: TSpyEvent): TSpyHandler; /** * Used when you want to check that two objects have the same value. * This matcher recursively checks the equality of all fields, rather than checking for object identity. * * Optionally, you can provide a type for the expected value via a generic. * This is particularly useful for ensuring expected objects have the right structure. */ toEqual(expected: TSpyEvent): TSpyHandler; /** * Used to check that a JavaScript object matches a subset of the properties of an object * * Optionally, you can provide an object to use as Generic type for the expected value. * This ensures that the matching object matches the structure of the provided object-like type. * * @example * * type House = { * bath: boolean; * bedrooms: number; * kitchen: { * amenities: string[]; * area: number; * wallColor: string; * } * }; * * expect(desiredHouse).toMatchObject<House>({...standardHouse, kitchen: {area: 20}}) // wherein standardHouse is some base object of type House */ toMatchObject( expected: PrettifyForDisplay<RecursivePartial<TSpyEvent>> ): TSpyHandler; /** * Use to test that objects have the same types as well as structure. * * Optionally, you can provide a type for the expected value via a generic. * This is particularly useful for ensuring expected objects have the right structure. */ toStrictEqual(expected: TSpyEvent): TSpyHandler; }; export interface DynamoDBSpyHandler<TData = any> extends JestExpectWithSpyMethods< DynamoDBSpyEvent<TData>, DynamoDBSpyHandler<TData> > { getData: () => PrettifyForDisplay<DynamoDBSpyEvent<TData>>; } export interface EventBridgeRuleSpyHandler<TData = any> extends JestExpectWithSpyMethods< EventBridgeRuleSpyEvent<TData>, EventBridgeRuleSpyHandler<TData> > { getData: () => PrettifyForDisplay<EventBridgeRuleSpyEvent<TData>>; } export interface EventBridgeSpyHandler<TData = any> extends JestExpectWithSpyMethods< EventBridgeSpyEvent<TData>, EventBridgeSpyHandler<TData> > { getData: () => PrettifyForDisplay<EventBridgeSpyEvent<TData>>; } export interface FunctionBaseSpyHandler<TData = any> extends JestExpectWithSpyMethods< FunctionRequestSpyEvent<TData>, FunctionRequestSpyHandler<TData> > { followedByError: ( // This implementation confuses TypeScript which does not accurately display the type. param?: { condition?: (event: { spyEventType: 'FunctionError'; request: TData; context: FunctionContext; error: any; }) => boolean; timoutMs?: number; } ) => Promise< FunctionBaseSpyHandler<TData> & FunctionErrorSpyHandler<TData> & JestExpectWithSpyMethods< FunctionErrorSpyEvent<TData>, FunctionRequestSpyHandler<TData> > >; followedByConsole: ( // This implementation confuses TypeScript which does not accurately display the type. param?: { condition?: (event: { spyEventType: 'FunctionConsole'; request: TData; context: FunctionContext; console: FunctionConsole; }) => boolean; timoutMs?: number; } ) => Promise< FunctionBaseSpyHandler<TData> & FunctionConsoleSpyHandler<TData> & JestExpectWithSpyMethods< FunctionConsoleSpyEvent<TData>, FunctionRequestSpyHandler<TData> > >; followedByResponse: <TDataResponse = any>( // This implementation confuses TypeScript which does not accurately display the type. // Leave it for reference! // param: PrettifyForDisplay< // WaitForParams< // PrettifyForDisplay<FunctionResponseSpyEvent<TData, TDataResponse>> // > // > param?: { condition?: (event: { spyEventType: 'FunctionResponse'; request: TData; context: FunctionContext; response: TDataResponse; }) => boolean; timoutMs?: number; } ) => Promise< FunctionResponseSpyHandler<TData> & JestExpectWithSpyMethods< FunctionRequestSpyEvent<TData>, FunctionRequestSpyHandler<TData> > >; } export interface FunctionRequestSpyHandler<TData = any> extends FunctionBaseSpyHandler<TData> { getData: () => PrettifyForDisplay<FunctionRequestSpyEvent<TData>>; } export interface FunctionConsoleSpyHandler<TData = any> extends JestExpectWithSpyMethods< FunctionConsoleSpyEvent<TData>, FunctionConsoleSpyHandler<TData> > { getData: () => PrettifyForDisplay<FunctionConsoleSpyEvent<TData>>; followedByError: ( // This implementation confuses TypeScript which does not accurately display the type. param?: { condition?: (event: { spyEventType: 'FunctionError'; request: TData; context: FunctionContext; error: any; }) => boolean; timoutMs?: number; } ) => Promise< FunctionBaseSpyHandler<TData> & FunctionErrorSpyHandler<TData> & JestExpectWithSpyMethods< FunctionErrorSpyEvent<TData>, FunctionRequestSpyHandler<TData> > >; followedByConsole: ( // This implementation confuses TypeScript which does not accurately display the type. param?: { condition?: (event: { spyEventType: 'FunctionConsole'; request: TData; context: FunctionContext; console: FunctionConsole; }) => boolean; timoutMs?: number; } ) => Promise< FunctionBaseSpyHandler<TData> & FunctionConsoleSpyHandler<TData> & JestExpectWithSpyMethods< FunctionConsoleSpyEvent<TData>, FunctionRequestSpyHandler<TData> > >; followedByResponse: <TDataResponse = any>( // This implementation confuses TypeScript which does not accurately display the type. // Leave it for reference! // param: PrettifyForDisplay< // WaitForParams< // PrettifyForDisplay<FunctionResponseSpyEvent<TData, TDataResponse>> // > // > param?: { condition?: (event: { spyEventType: 'FunctionResponse'; request: TData; context: FunctionContext; response: TDataResponse; }) => boolean; timoutMs?: number; } ) => Promise< FunctionResponseSpyHandler<TData> & JestExpectWithSpyMethods< FunctionRequestSpyEvent<TData>, FunctionRequestSpyHandler<TData> > >; } export interface FunctionErrorSpyHandler<TData = any> extends JestExpectWithSpyMethods< FunctionErrorSpyEvent<TData>, FunctionErrorSpyHandler<TData> > { getData: () => PrettifyForDisplay<FunctionErrorSpyEvent<TData>>; } export interface FunctionResponseSpyHandler<TData = any> extends JestExpectWithSpyMethods< FunctionResponseSpyEvent<TData>, FunctionResponseSpyHandler<TData> > { getData: () => PrettifyForDisplay<FunctionResponseSpyEvent<TData>>; } export interface S3SpyHandler extends JestExpectWithSpyMethods<S3SpyEvent, S3SpyHandler> { getData: () => S3SpyEvent; } export interface SnsSubscriptionSpyHandler<TData = any> extends JestExpectWithSpyMethods< SnsSubscriptionSpyEvent<TData>, SnsSubscriptionSpyHandler<TData> > { getData: () => PrettifyForDisplay<SnsSubscriptionSpyEvent<TData>>; } export interface SnsTopicSpyHandler<TData = any> extends JestExpectWithSpyMethods< SnsTopicSpyEvent<TData>, SnsTopicSpyHandler<TData> > { getData: () => PrettifyForDisplay<SnsTopicSpyEvent<TData>>; } export interface SqsSpyHandler<TData = any> extends JestExpectWithSpyMethods<SqsSpyEvent<TData>, SqsSpyHandler<TData>> { getData: () => PrettifyForDisplay<SqsSpyEvent<TData>>; }