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
text/typescript
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>>;
}