From edb02c1138b7b13461e8881e2d4071bf77eedf06 Mon Sep 17 00:00:00 2001 From: Ben Durrant Date: Sun, 17 Sep 2023 23:11:28 +0100 Subject: [PATCH] Add JSDoc and update readme --- README.md | 97 +++++++++++++++++++++++++++++++ src/asymmetricMatchers/exactly.ts | 26 +++++++++ src/matchers/context.ts | 61 +++++++++++++++++++ 3 files changed, 184 insertions(+) diff --git a/README.md b/README.md index 084cd50..a778703 100644 --- a/README.md +++ b/README.md @@ -129,3 +129,100 @@ declare global { } } ``` + +## Matchers + +### Asymmetric Matchers + + + + + + + + + + +
NameDescriptionExample
+ +`exactly` + + + +Uses `Object.is` to ensure referential equality in situations where deep equality would typically be used. + + + +```ts +expect(mock).toBeCalledWith(expect.exactly(reference)); +``` + +
+ +### Symmetric Matchers + + + + + + + + + + + + + + + + + + + + +
NameDescriptionExample
+ +`toBeCalledWithContext`/`toHaveBeenCalledWithContext` + + + +Assert a function has been called with a specific context (`this`). + + + +```ts +expect(mock).toBeCalledWithContext(expectedContext); +expect(mock).toHaveBeenCalledWithContext(expectedContext); +``` + +
+ +`lastCalledWithContext`/`toHaveBeenLastCalledWithContext` + + + +Assert the last call of a function was with a specific context (`this`). + + + +```ts +expect(mock).lastCalledWithContext(expectedContext); +expect(mock).toHaveBeenLastCalledWithContext(expectedContext); +``` + +
+ +`nthCalledWithContext`/`toHaveBeenNthCalledWithContext` + + + +Assert the Nth call of a function was with a specific context (`this`). + + + +```ts +expect(mock).lastCalledWithContext(expectedContext); +expect(mock).toHaveBeenLastCalledWithContext(expectedContext); +``` + +
diff --git a/src/asymmetricMatchers/exactly.ts b/src/asymmetricMatchers/exactly.ts index ee8f86c..6f36411 100644 --- a/src/asymmetricMatchers/exactly.ts +++ b/src/asymmetricMatchers/exactly.ts @@ -2,6 +2,19 @@ import type { MatcherFunction } from "expect"; import type { MatcherHintOptions } from "jest-matcher-utils"; import type { AsymmetricMatcher } from "../utils/types"; +/** + * Matches against the provided value using `Object.is`. + * You can use it inside "deep equal" matchers like `toBeCalledWith` to ensure that only the correct reference will be allowed. + * @example + * const fn = jest.fn(); + * const ref = {}; + * + * fn(ref); + * + * expect(fn).toBeCalledWith({}) + * expect(fn).not.toBeCalledWith(expect.exactly({})) + * expect(fn).toBeCalledWith(expect.exactly(ref)) + */ export const exactly: MatcherFunction<[expected: unknown]> = function ( received, expected, @@ -38,6 +51,19 @@ export const exactly: MatcherFunction<[expected: unknown]> = function ( declare module "./index" { export interface AsymmetricMixNMatchers { + /** + * Matches against the provided value using `Object.is`. + * You can use it inside "deep equal" matchers like `toBeCalledWith` to ensure that only the correct reference will be allowed. + * @example + * const fn = jest.fn(); + * const ref = {}; + * + * fn(ref); + * + * expect(fn).toBeCalledWith({}) + * expect(fn).not.toBeCalledWith(expect.exactly({})) + * expect(fn).toBeCalledWith(expect.exactly(ref)) + */ exactly(expected: E): AsymmetricMatcher; } } diff --git a/src/matchers/context.ts b/src/matchers/context.ts index 113a34d..c0b13f6 100644 --- a/src/matchers/context.ts +++ b/src/matchers/context.ts @@ -408,25 +408,55 @@ const createNthCalledWithContextMatcher = ( }; }; +/** + * Ensure a mock function is called with a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ export const toBeCalledWithContext = createToBeCalledWithContextMatcher( "toBeCalledWithContext", ); +/** + * Ensure a mock function is called with a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ export const toHaveBeenCalledWithContext = createToBeCalledWithContextMatcher( "toHaveBeenCalledWithContext", ); +/** + * Ensure the last call to a mock function was provided a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ export const lastCalledWithContext = createLastCalledWithContextMatcher( "lastCalledWithContext", ); +/** + * Ensure the last call to a mock function was provided a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ export const toHaveBeenLastCalledWithContext = createLastCalledWithContextMatcher("toHaveBeenLastCalledWithContext"); +/** + * Ensure that a mock function was called with a specific context on an Nth call. + * + * Optionally you can provide a type for the expected context via a generic. + */ export const nthCalledWithContext = createNthCalledWithContextMatcher( "nthCalledWithContext", ); +/** + * Ensure that a mock function was called with a specific context on an Nth call. + * + * Optionally you can provide a type for the expected context via a generic. + */ export const toHaveBeenNthCalledWithContext = createNthCalledWithContextMatcher( "toHaveBeenNthCalledWithContext", ); @@ -434,13 +464,44 @@ export const toHaveBeenNthCalledWithContext = createNthCalledWithContextMatcher( declare module "./index" { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface MixNMatchers { + /** + * Ensure a mock function is called with a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ toBeCalledWithContext(expected: E): R; + /** + * Ensure a mock function is called with a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ toHaveBeenCalledWithContext(expected: E): R; + /** + * Ensure the last call to a mock function was provided a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ lastCalledWithContext(expected: E): R; + /** + * Ensure the last call to a mock function was provided a specific context (`this`) + * + * Optionally you can provide a type for the expected context via a generic. + */ toHaveBeenLastCalledWithContext(expected: E): R; + /** + * Ensure that a mock function was called with a specific context on an Nth call. + * + * Optionally you can provide a type for the expected context via a generic. + */ nthCalledWithContext(n: number, expected: E): R; + + /** + * Ensure that a mock function was called with a specific context on an Nth call. + * + * Optionally you can provide a type for the expected context via a generic. + */ toHaveBeenNthCalledWithContext(n: number, expected: E): R; } }