diff --git a/packages/react-native-fantom/runtime/expect.js b/packages/react-native-fantom/runtime/expect.js index 3be588d68d1..ccb0200bbb8 100644 --- a/packages/react-native-fantom/runtime/expect.js +++ b/packages/react-native-fantom/runtime/expect.js @@ -15,6 +15,9 @@ import deepEqual from 'deep-equal'; import {diff} from 'jest-diff'; import {format, plugins} from 'pretty-format'; +const stringify = (data: mixed): string => + format(data, {min: true, plugins: [plugins.ReactElement]}); + class ErrorWithCustomBlame extends Error { // Initially 5 to ignore all the frames from Babel helpers to instantiate this // custom error class. @@ -255,6 +258,22 @@ class Expect { } } + toBeCalledWith(...args: mixed[]): void { + return this.toHaveBeenCalledWith(...args); + } + + toHaveBeenCalledWith(...args: mixed[]): void { + const mock = this.#requireMock(); + const pass = mock.calls.some(callArgs => + deepEqual(callArgs, args, {strict: true}), + ); + if (!this.#isExpectedResult(pass)) { + throw new ErrorWithCustomBlame( + `Expected ${String(this.#received)}${this.#maybeNotLabel()} to have been called with ${stringify(args)}, but it was called with ${stringify(mock.calls)}`, + ).blameToPreviousFrame(); + } + } + toBeGreaterThan(expected: number): void { if (typeof this.#received !== 'number') { throw new ErrorWithCustomBlame( diff --git a/packages/react-native-fantom/src/__tests__/expect-itest.js b/packages/react-native-fantom/src/__tests__/expect-itest.js index a0eb8611690..de7eaa84ce3 100644 --- a/packages/react-native-fantom/src/__tests__/expect-itest.js +++ b/packages/react-native-fantom/src/__tests__/expect-itest.js @@ -317,6 +317,47 @@ describe('expect', () => { }), ); + ['toBeCalledWith', 'toHaveBeenCalledWith'].map(toHaveBeenCalledWithAlias => + test(toHaveBeenCalledWithAlias, () => { + const fn = jest.fn(); + + expect(fn).not[toHaveBeenCalledWithAlias](); + + expect(() => { + expect(fn)[toHaveBeenCalledWithAlias](); + }).toThrow(); + + fn('happy'); + fn({a: 1}, 2); + fn(['fantom'], {isAwesome: true}); + + expect(fn)[toHaveBeenCalledWithAlias]('happy'); + expect(fn)[toHaveBeenCalledWithAlias]({a: 1}, 2); + expect(fn)[toHaveBeenCalledWithAlias](['fantom'], {isAwesome: true}); + expect(fn).not[toHaveBeenCalledWithAlias](); + expect(fn).not[toHaveBeenCalledWithAlias]({a: 1}); + expect(fn).not[toHaveBeenCalledWithAlias]({a: 1}, 2, null); + expect(fn).not[toHaveBeenCalledWithAlias]({a: 1, b: 2}, 2); + + expect(() => { + expect(fn).not[toHaveBeenCalledWithAlias]({a: 1}, 2); + }).toThrow(); + + expect(() => { + expect(fn)[toHaveBeenCalledWithAlias](1); + }).toThrow(); + + // Passing functions that aren't mocks should always fail + expect(() => { + expect(() => {})[toHaveBeenCalledWithAlias](); + }).toThrow(); + + expect(() => { + expect(() => {}).not[toHaveBeenCalledWithAlias](); + }).toThrow(); + }), + ); + describe('jest.fn()', () => { it('tracks execution of functions without implementations', () => { const fn = jest.fn();