Skip to content

Commit

Permalink
Support deep partial
Browse files Browse the repository at this point in the history
  • Loading branch information
kibertoad committed Dec 7, 2023
1 parent e09190c commit 9b3f611
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
19 changes: 16 additions & 3 deletions packages/core/lib/queues/HandlerSpy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type SpyResultCacheEntry<MessagePayloadSchemas extends object> = {
}

type SpyPromiseMetadata<MessagePayloadSchemas extends object> = {
fields: Partial<MessagePayloadSchemas>
fields: DeepPartial<MessagePayloadSchemas>
processingResult?: MessageProcessingResult
promise: Promise<SpyResult<MessagePayloadSchemas>>
resolve: (
Expand All @@ -43,6 +43,19 @@ export type PublicHandlerSpy<MessagePayloadSchemas extends object> = Omit<
'addProcessedMessage'
>

// eslint-disable-next-line @typescript-eslint/ban-types
type DeepPartial<T> = T extends Function
? T
: T extends object
? {
[P in keyof T]?: T[P] extends Array<infer U>
? Array<DeepPartial<U>>
: T[P] extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: DeepPartial<T[P]>
}
: T

export class HandlerSpy<MessagePayloadSchemas extends object> {
public name = 'HandlerSpy'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -59,7 +72,7 @@ export class HandlerSpy<MessagePayloadSchemas extends object> {

private messageMatchesFilter(
spyResult: SpyResult<object>,
fields: Partial<MessagePayloadSchemas>,
fields: DeepPartial<MessagePayloadSchemas>,
processingResult?: MessageProcessingResult,
) {
return (
Expand All @@ -80,7 +93,7 @@ export class HandlerSpy<MessagePayloadSchemas extends object> {
}

waitForMessage(
fields: Partial<MessagePayloadSchemas>,
fields: DeepPartial<MessagePayloadSchemas>,
processingResult?: MessageProcessingResult,
): Promise<SpyResult<MessagePayloadSchemas>> {
const processedMessageEntry = Object.values(this.messageBuffer.items).find(
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@message-queue-toolkit/core",
"version": "5.0.1",
"version": "5.0.2",
"private": false,
"license": "MIT",
"description": "Useful utilities, interfaces and base classes for message queue handling. Supports AMQP and SQS with a common abstraction on top currently",
Expand Down
40 changes: 40 additions & 0 deletions packages/core/test/queues/HandlerSpy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ type Message = {
payload?: Record<string, unknown>
}

type DeepMessage = {
id: string
status: string
payload?: {
fieldA: number
fieldB: string[]
fieldC: string
fieldD: boolean
}
}

const TEST_MESSAGE: Message = {
id: 'abc',
status: 'done',
Expand Down Expand Up @@ -133,6 +144,35 @@ describe('HandlerSpy', () => {
expect(message.message).toEqual(TEST_MESSAGE_4)
})

it('Finds previously consumed event with a deep partial match, with incomplete fields', async () => {
const spy = new HandlerSpy<DeepMessage>()
const message: DeepMessage = {
id: 'abc',
status: 'good',
payload: {
fieldA: 1,
fieldB: ['w'],
fieldC: 're',
fieldD: true,
},
}

spy.addProcessedMessage({
processingResult: 'consumed',
message,
})

const messageResult = await spy.waitForMessage({
payload: {
fieldA: 1,
fieldB: ['w'],
fieldC: 're',
},
})

expect(messageResult.message).toEqual(message)
})

it('Finds previously consumed event with an array match in order', async () => {
const spy = new HandlerSpy<Message>()

Expand Down

0 comments on commit 9b3f611

Please sign in to comment.