From ba196342a208dfbae5e04ec4d24db0b2205ffc9d Mon Sep 17 00:00:00 2001 From: Joshua Goldberg Date: Tue, 12 Jun 2018 01:43:42 -0700 Subject: [PATCH] Cleaned up & partially expanded Jest's jest-tests.ts The old file was a mix of pure types tests and copied real-world behavior examples. It was quite confusing. This organizes the contents into what is mostly a superset of the existing tests. --- types/jest/jest-tests.ts | 1623 +++++++++++++++++++++----------------- 1 file changed, 898 insertions(+), 725 deletions(-) diff --git a/types/jest/jest-tests.ts b/types/jest/jest-tests.ts index e154561c86..bfaaec6259 100644 --- a/types/jest/jest-tests.ts +++ b/types/jest/jest-tests.ts @@ -1,762 +1,935 @@ -// TODO: Avoid requiring things that don't exist. -declare var require: { - (s: string): any; - requireActual(s: string): any; - requireMock(s: string): any; +/* Lifecycle events */ + +beforeAll(() => {}); +beforeAll((done: jest.DoneCallback) => {}); +beforeAll((done: jest.DoneCallback) => done.fail(), 9001); + +beforeEach(() => {}); +beforeEach((done: jest.DoneCallback) => {}); +beforeEach((done: jest.DoneCallback) => done.fail(), 9001); + +afterAll(() => {}); +afterAll((done: jest.DoneCallback) => {}); +afterAll((done: jest.DoneCallback) => done.fail(), 9001); + +afterEach(() => {}); +afterEach((done: jest.DoneCallback) => {}); +afterEach((done: jest.DoneCallback) => done.fail(), 9001); + +/* describe */ + +describe(0, () => {}); +describe("name", () => {}); +describe(() => {}, () => {}); +describe({ name: "name" }, () => {}); + +describe.only(0, () => {}); +describe.only("name", () => {}); +describe.only(() => {}, () => {}); +describe.only({ name: "name" }, () => {}); + +describe.skip(0, () => {}); +describe.skip("name", () => {}); +describe.skip(() => {}, () => {}); +describe.skip({ name: "name" }, () => {}); + +fdescribe(0, () => {}); +fdescribe("name", () => {}); +fdescribe(() => {}, () => {}); +fdescribe({ name: "name" }, () => {}); + +fdescribe.only(0, () => {}); +fdescribe.only("name", () => {}); +fdescribe.only(() => {}, () => {}); +fdescribe.only({ name: "name" }, () => {}); + +fdescribe.skip(0, () => {}); +fdescribe.skip("name", () => {}); +fdescribe.skip(() => {}, () => {}); +fdescribe.skip({ name: "name" }, () => {}); + +xdescribe(0, () => {}); +xdescribe("name", () => {}); +xdescribe(() => {}, () => {}); +xdescribe({ name: "name" }, () => {}); + +xdescribe.only(0, () => {}); +xdescribe.only("name", () => {}); +xdescribe.only(() => {}, () => {}); +xdescribe.only({ name: "name" }, () => {}); + +xdescribe.skip(0, () => {}); +xdescribe.skip("name", () => {}); +xdescribe.skip(() => {}, () => {}); +xdescribe.skip({ name: "name" }, () => {}); + +/* it */ + +it("name", () => {}); +it("name", async () => {}); +it("name", () => {}, 9001); +it("name", async () => {}, 9001); +it("name", (callback: jest.DoneCallback) => {}, 9001); + +it.only("name", () => {}); +it.only("name", async () => {}); +it.only("name", () => {}, 9001); +it.only("name", async () => {}, 9001); +it.only("name", (callback: jest.DoneCallback) => {}, 9001); + +it.skip("name", () => {}); +it.skip("name", async () => {}); +it.skip("name", () => {}, 9001); +it.skip("name", async () => {}, 9001); +it.skip("name", (callback: jest.DoneCallback) => {}, 9001); + +it.concurrent("name", () => {}); +it.concurrent("name", async () => {}); +it.concurrent("name", () => {}, 9001); +it.concurrent("name", async () => {}, 9001); +it.concurrent("name", (callback: jest.DoneCallback) => {}, 9001); + +fit("name", () => {}); +fit("name", async () => {}); +fit("name", () => {}, 9001); +fit("name", async () => {}, 9001); +fit("name", (callback: jest.DoneCallback) => {}, 9001); + +fit.only("name", () => {}); +fit.only("name", async () => {}); +fit.only("name", () => {}, 9001); +fit.only("name", async () => {}, 9001); +fit.only("name", (callback: jest.DoneCallback) => {}, 9001); + +fit.skip("name", () => {}); +fit.skip("name", async () => {}); +fit.skip("name", () => {}, 9001); +fit.skip("name", async () => {}, 9001); +fit.skip("name", (callback: jest.DoneCallback) => {}, 9001); + +fit.concurrent("name", () => {}); +fit.concurrent("name", async () => {}); +fit.concurrent("name", () => {}, 9001); +fit.concurrent("name", async () => {}, 9001); +fit.concurrent("name", (callback: jest.DoneCallback) => {}, 9001); + +xit("name", () => {}); +xit("name", async () => {}); +xit("name", () => {}, 9001); +xit("name", async () => {}, 9001); +xit("name", (callback: jest.DoneCallback) => {}, 9001); + +xit.only("name", () => {}); +xit.only("name", async () => {}); +xit.only("name", () => {}, 9001); +xit.only("name", async () => {}, 9001); +xit.only("name", (callback: jest.DoneCallback) => {}, 9001); + +xit.skip("name", () => {}); +xit.skip("name", async () => {}); +xit.skip("name", () => {}, 9001); +xit.skip("name", async () => {}, 9001); +xit.skip("name", (callback: jest.DoneCallback) => {}, 9001); + +xit.concurrent("name", () => {}); +xit.concurrent("name", async () => {}); +xit.concurrent("name", () => {}, 9001); +xit.concurrent("name", async () => {}, 9001); +xit.concurrent("name", (callback: jest.DoneCallback) => {}, 9001); + +test("name", () => {}); +test("name", async () => {}); +test("name", () => {}, 9001); +test("name", async () => {}, 9001); +test("name", (callback: jest.DoneCallback) => {}, 9001); + +test.only("name", () => {}); +test.only("name", async () => {}); +test.only("name", () => {}, 9001); +test.only("name", async () => {}, 9001); +test.only("name", (callback: jest.DoneCallback) => {}, 9001); + +test.skip("name", () => {}); +test.skip("name", async () => {}); +test.skip("name", () => {}, 9001); +test.skip("name", async () => {}, 9001); +test.skip("name", (callback: jest.DoneCallback) => {}, 9001); + +test.concurrent("name", () => {}); +test.concurrent("name", async () => {}); +test.concurrent("name", () => {}, 9001); +test.concurrent("name", async () => {}, 9001); +test.concurrent("name", (callback: jest.DoneCallback) => {}, 9001); + +xtest("name", () => {}); +xtest("name", async () => {}); +xtest("name", () => {}, 9001); +xtest("name", async () => {}, 9001); +xtest("name", (callback: jest.DoneCallback) => {}, 9001); + +xtest.only("name", () => {}); +xtest.only("name", async () => {}); +xtest.only("name", () => {}, 9001); +xtest.only("name", async () => {}, 9001); +xtest.only("name", (callback: jest.DoneCallback) => {}, 9001); + +xtest.skip("name", () => {}); +xtest.skip("name", async () => {}); +xtest.skip("name", () => {}, 9001); +xtest.skip("name", async () => {}, 9001); +xtest.skip("name", (callback: jest.DoneCallback) => {}, 9001); + +xtest.concurrent("name", () => {}); +xtest.concurrent("name", async () => {}); +xtest.concurrent("name", () => {}, 9001); +xtest.concurrent("name", async () => {}, 9001); +xtest.concurrent("name", (callback: jest.DoneCallback) => {}, 9001); + +/* Done callbacks */ + +describe("", () => { + it("", (callback: jest.DoneCallback): void => { + callback(); + callback(""); + callback("", 3); + callback.fail(); + callback.fail("error"); + callback.fail({ message: "message" }); + }); +}); + +/* NodeRequire interface (require extensions) */ + +declare const nodeRequire: NodeRequire; + +// $ExpectType any +nodeRequire.requireActual("moduleName"); + +// $ExpectType any +nodeRequire.requireMock("moduleName"); + +/* Top-level jest namespace functions */ + +const customMatcherFactories: jasmine.CustomMatcherFactories = {}; + +jest + .addMatchers(customMatcherFactories) + .addMatchers({}) + .addMatchers(customMatcherFactories) + .autoMockOff() + .autoMockOn() + .clearAllMocks() + .clearAllTimers() + .resetAllMocks() + .restoreAllMocks() + .clearAllTimers() + .deepUnmock("moduleName") + .disableAutomock() + .doMock("moduleName") + .doMock("moduleName", jest.fn()) + .doMock("moduleName", jest.fn(), {}) + .doMock("moduleName", jest.fn(), { virtual: true }) + .dontMock("moduleName") + .enableAutomock() + .mock("moduleName") + .mock("moduleName", jest.fn()) + .mock("moduleName", jest.fn(), {}) + .mock("moduleName", jest.fn(), { virtual: true }) + .resetModuleRegistry() + .resetModules() + .runAllImmediates() + .runAllTicks() + .runAllTimers() + .runOnlyPendingTimers() + .runTimersToTime(9001) + .advanceTimersByTime(9001) + .setMock("moduleName", {}) + .setMock<{}>("moduleName", {}) + .setMock<{ a: "b" }>("moduleName", { a: "b" }) + .setTimeout(9001) + .unmock("moduleName") + .useFakeTimers() + .useRealTimers(); + +/* Mocks and spies */ + +const mock1: jest.Mock = jest.fn(); +const mock2: jest.Mock = jest.fn(() => undefined); +const mock3: jest.Mock = jest.fn(() => "abc"); +const mock4: jest.Mock<"abc"> = jest.fn((): "abc" => "abc"); +const mock5: jest.Mock = jest.fn((...args: string[]) => args.join("")); +const mock6: jest.Mock = jest.fn((arg: {}) => arg); + +const genMockModule1: {} = jest.genMockFromModule("moduleName"); +const genMockModule2: { a: "b" } = jest.genMockFromModule<{ a: "b" }>("moduleName"); + +const isStringMock: boolean = jest.isMockFunction("foo"); +const isMockMock: boolean = jest.isMockFunction(mock1); + +const maybeMock = () => {}; +if (jest.isMockFunction(maybeMock)) { + maybeMock.getMockName(); +} + +const mockName: string = jest.fn().getMockName(); +const mockContextVoid: jest.MockContext = jest.fn().mock; +const mockContextString: jest.MockContext = jest.fn(() => "").mock; + +jest.fn().mockClear(); + +jest.fn().mockReset(); + +const spiedTarget = { + returnsVoid(): void { }, + returnsString(): string { + return ""; + } }; -// TODO: use real jquery types? -declare const $: any; -// Tests based on the Jest website -jest.unmock('../sum'); +const spy1 = jest.spyOn(spiedTarget, "returnsVoid"); +const spy2 = jest.spyOn(spiedTarget, "returnsVoid", "get"); +const spy3 = jest.spyOn(spiedTarget, "returnsString", "set"); -class TestClass { } +const spy1Name: string = spy1.getMockName(); -describe(TestClass, () => { }); +const spy2Calls: any[][] = spy2.mock.calls; -describe('sum', () => { - it('adds 1 + 2 to equal 3', () => { - const sum: (a: number, b: number) => number = require('../sum'); - expect(sum(1, 2)).toBe(3); - }); +spy2.mockClear(); +spy2.mockReset(); + +const spy3Mock: jest.Mock<() => string> = spy3 + .mockImplementation(() => "") + .mockImplementation((arg: {}) => arg) + .mockImplementation((...args: string[]) => args.join("")) + .mockName("name") + .mockReturnThis() + .mockReturnValue("value") + .mockReturnValueOnce("value") + .mockResolvedValue("value") + .mockResolvedValueOnce("value") + .mockRejectedValue("value") + .mockRejectedValueOnce("value"); + +/* Snapshot serialization */ + +const snapshotSerializerPlugin: jest.SnapshotSerializerPlugin = { + print: () => "", + test: () => true, +}; + +expect.addSnapshotSerializer(snapshotSerializerPlugin); + +expect.addSnapshotSerializer({ + print: (value: {}) => "", + test: (value: {}) => value === value, }); -describe('restoreAllMocks', () => { - afterEach(() => { - jest.restoreAllMocks(); - }); +expect.addSnapshotSerializer({ + print: ( + value: {}, + serialize: ((val: {}) => string), + indent: ((str: string) => string), + opts: {}, + ) => "", + test: (value: {}) => value === value, }); -describe('fetchCurrentUser', () => { - it('calls the callback when $.ajax requests are finished', () => { - const fetchCurrentUser = require('../fetchCurrentUser'); +expect.addSnapshotSerializer({ + print(value, serialize, indent, opts, colors) { + let result = ""; - // Create a mock function for our callback - const callback = jest.fn(); - fetchCurrentUser(callback); + if (opts.callToJSON !== undefined && opts.callToJSON) { + result += " "; + } - // Now we emulate the process by which `$.ajax` would execute its own - // callback - $.ajax.mock.calls[0 /*first call*/][0 /*first argument*/].success({ - firstName: 'Bobby', - lastName: '");DROP TABLE Users;--' - }); + result += opts.edgeSpacing; + result += opts.spacing; - // And finally we assert that this emulated call by `$.ajax` incurred a - // call back into the mock function we provided as a callback - expect(callback.mock.calls[0/*first call*/][0/*first arg*/]).toEqual({ - loggedIn: true, - fullName: 'Bobby ");DROP TABLE Users;--' - }); - }); + if (opts.escapeRegex !== undefined && opts.escapeRegex) { + result += " "; + } + + if (opts.indent !== undefined) { + for (let i = 0; i < opts.indent; i += 1) { + result += "\t"; + } + } + + if (opts.maxDepth !== undefined) { + result = result.substring(0, opts.maxDepth); + } + + if (opts.min !== undefined && opts.min) { + result += " "; + } + + if (opts.plugins !== undefined) { + for (const plugin of opts.plugins) { + expect.addSnapshotSerializer(plugin); + } + } + + if (opts.printFunctionName !== undefined && opts.printFunctionName) { + result += " "; + } + + if (opts.theme) { + if (opts.theme.comment !== undefined) { + result += opts.theme.comment; + } + + if (opts.theme.content !== undefined) { + result += opts.theme.content; + } + + if (opts.theme.prop !== undefined) { + result += opts.theme.prop; + } + + if (opts.theme.tag !== undefined) { + result += opts.theme.tag; + } + + if (opts.theme.value !== undefined) { + result += opts.theme.value; + } + } + + for (const color of [ + colors.comment, + colors.content, + colors.prop, + colors.tag, + colors.value, + ]) { + result += color.open; + result += color.close; + } + + return result; + }, + test: (value: {}) => value === value, }); -// unmock is the recommended approach for unmocking... -jest.unmock('../displayUser.js'); +/* expect extensions */ -describe('displayUser', () => { - it('displays a user after a click', () => { - // Set up our document body - document.body.innerHTML = - '
' + - ' ' + - '
'; +const expectExtendMap: jest.ExpectExtendMap = {}; - const displayUser = require.requireActual('../displayUser'); - const $ = require('jquery'); - const fetchCurrentUser = require('../fetchCurrentUser'); - - // Tell the fetchCurrentUser mock function to automatically invoke - // its callback with some data - fetchCurrentUser.mockImplementation((cb: (...args: any[]) => any) => { - cb({ - loggedIn: true, - fullName: 'Johnny Cash' - }); - }); - - // Use jquery to emulate a click on our button - $('#button').click(); - - // Assert that the fetchCurrentUser function was called, and that the - // #username span's innter text was updated as we'd it expect. - expect(fetchCurrentUser).toBeCalled(); - expect($('#username').text()).toEqual('Johnny Cash - Logged In'); - }); -}); - -jest.unmock('../CheckboxWithLabel.js'); -describe('CheckboxWithLabel', () => { - it('changes the text after click', () => { - const React = require('react/addons'); - const CheckboxWithLabel = require('../CheckboxWithLabel.js'); - const TestUtils = React.addons.TestUtils; - - // Render a checkbox with label in the document - const checkbox = TestUtils.renderIntoDocument( - CheckboxWithLabel({ - labelOn: "On", - labelOff: "Off" - }) - ); - - // Verify that it's Off by default - const label = TestUtils.findRenderedDOMComponentWithTag( - checkbox, 'label'); - expect(label.getDOMNode().textContent).toEqual('Off'); - - // Simulate a click and verify that it is now On - const input = TestUtils.findRenderedDOMComponentWithTag( - checkbox, 'input'); - TestUtils.Simulate.change(input); - expect(label.getDOMNode().textContent).toEqual('On'); - }); -}); - -jest.runAllTicks(); -xdescribe('Hooks and Suits', () => { - let tested: boolean; - - beforeEach(() => { - tested = false; - }); - - afterEach(() => { - tested = true; - }); - - test('tested', () => { - expect(tested).toBeTruthy(); - expect(tested).not.toBeFalsy(); - }); - - fit('tested', () => { - expect(tested).toBeDefined(); - expect(tested).not.toBeUndefined(); - }); - - xit('expect null to be null', () => { - expect(null).toBeNull(); - }); - - xit('expect NaN to be NaN', () => { - expect(NaN).toBeNaN(); - }); -}); - -describe('compartion', () => { - const sum: (a: number, b: number) => number = require.requireMock('../sum'); - - it('compares is 7 + 2 greater than 3', () => { - expect(sum(7, 2)).toBeGreaterThan(3); - }); - - it('compares is 2 + 7 greater than or equal to 3', () => { - expect(sum(2, 7)).toBeGreaterThanOrEqual(3); - }); - - it('compares is 3 less than 3 + 4', () => { - expect(3).toBeLessThan(sum(3, 4)); - }); - - it('compares is 3 less than or equal to 4 + 3', () => { - expect(3).toBeLessThanOrEqual(sum(4, 3)); - }); - - it('works sanely with simple decimals', () => { - expect(0.2 + 0.1).toBeCloseTo(0.3, 5); - }); - - it('works sanely with simple decimals and the default delta', () => { - expect(0.2 + 0.1).toBeCloseTo(0.3); - }); -}); - -describe('toThrow API', () => { - function throwTypeError(): void { - throw new TypeError('toThrow Definition was out of date'); - } - - it('throws', () => { - expect(throwTypeError()).toThrow(); - expect(throwTypeError()).toThrowError(); - }); - - it('throws TypeError', () => { - expect(throwTypeError()).toThrow(TypeError); - expect(throwTypeError()).toThrowError(TypeError); - }); - - it('throws \'Definition was out of date\'', () => { - expect(throwTypeError()).toThrow(/Definition was out of date/); - expect(throwTypeError()).toThrowError(/Definition was out of date/); - }); - - it('throws \'toThorow Definition was out of date\'', () => { - expect(throwTypeError()).toThrow('toThrow Definition was out of date'); - expect(throwTypeError()).toThrowError('toThrow Definition was out of date'); - }); -}); - -describe('Assymetric matchers', () => { - it('works', () => { - expect({ - timestamp: 1480807810388, - text: 'Some text content, but we care only about *this part*', - color: '#bada55', - greeting: 'hello, world!', - }).toEqual({ - timestamp: expect.any(Number), - text: expect.stringMatching('*this part*'), - color: expect.stringMatching(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i), - greeting: expect.stringContaining('hello'), - }); - - expect("foo").toStrictEqual("foo"); - expect({ a: "foo" }).toStrictEqual({ a: "foo" }); - - const callback = jest.fn(); - expect(callback).toEqual(expect.any(Function)); - callback(5, "test"); - expect(callback).toBeCalledWith(expect.any(Number), expect.any(String)); - const obj = { - items: [1] +expect.extend(expectExtendMap); +expect.extend({}); +expect.extend({ + foo(this: jest.MatcherUtils, received: {}, ...actual: Array<{}>) { + return { + message: () => JSON.stringify(received), + pass: false, }; - expect(obj).toEqual(expect.objectContaining({ - items: expect.arrayContaining([ - expect.any(Number) - ]) + } +}); + +/* Basic matchers */ + +describe("", () => { + it("", () => { + expect(jest.fn()).lastCalledWith(); + expect(jest.fn()).lastCalledWith("jest"); + expect(jest.fn()).lastCalledWith({}, {}); + + expect(jest.fn()).lastReturnedWith("jest"); + expect(jest.fn()).lastReturnedWith({}); + + expect(jest.fn()).nthReturnedWith(0, "jest"); + expect(jest.fn()).nthReturnedWith(1, {}); + + expect({}).toBe({}); + expect([]).toBe([]); + expect(10).toBe(10); + + expect(jest.fn()).toBeCalled(); + + expect(jest.fn()).toBeCalledWith(); + expect(jest.fn()).toBeCalledWith("jest"); + expect(jest.fn()).toBeCalledWith({}, {}); + + expect(0).toBeCloseTo(1); + expect(0).toBeCloseTo(1, 2); + + expect(undefined).toBeDefined(); + expect({}).toBeDefined(); + + expect(true).toBeFalsy(); + expect(false).toBeFalsy(); + expect(0).toBeFalsy(); + + expect(0).toBeGreaterThan(1); + + expect(0).toBeGreaterThanOrEqual(1); + + expect(3).toBeInstanceOf(Number); + + expect(0).toBeLessThan(1); + + expect(0).toBeLessThanOrEqual(1); + + expect(null).toBeNull(); + expect(undefined).toBeNull(); + + expect(true).toBeTruthy(); + expect(false).toBeFalsy(); + expect(1).toBeTruthy(); + + expect(undefined).toBeUndefined(); + expect({}).toBeUndefined(); + + expect(NaN).toBeNaN(); + expect(Infinity).toBeNaN(); + + expect([]).toContain({}); + expect(["abc"]).toContain("abc"); + expect(["abc"]).toContain("def"); + + expect([]).toContainEqual({}); + expect(["abc"]).toContainEqual("def"); + + expect([]).toEqual([]); + expect({}).toEqual({}); + + expect(jest.fn()).toHaveBeenCalled(); + + expect(jest.fn()).toHaveBeenCalledTimes(0); + expect(jest.fn()).toHaveBeenCalledTimes(1); + + expect(jest.fn()).toHaveBeenCalledWith(); + expect(jest.fn()).toHaveBeenCalledWith("jest"); + expect(jest.fn()).toHaveBeenCalledWith({}, {}); + + expect(jest.fn()).toHaveBeenCalledWith(0); + expect(jest.fn()).toHaveBeenCalledWith(1, "jest"); + expect(jest.fn()).toHaveBeenCalledWith(2, {}, {}); + + expect(jest.fn()).toHaveBeenLastCalledWith(); + expect(jest.fn()).toHaveBeenLastCalledWith("jest"); + expect(jest.fn()).toHaveBeenLastCalledWith({}, {}); + + expect(jest.fn()).toHaveLastReturnedWith("jest"); + expect(jest.fn()).toHaveLastReturnedWith({}); + + expect([]).toHaveLength(0); + expect("").toHaveLength(1); + + expect(jest.fn()).toHaveNthReturnedWith(0, "jest"); + expect(jest.fn()).toHaveNthReturnedWith(1, {}); + + expect({}).toHaveProperty("property"); + expect({}).toHaveProperty("property", {}); + expect({}).toHaveProperty(["property"]); + expect({}).toHaveProperty(["property"], {}); + expect({}).toHaveProperty(["property", "deep"]); + expect({}).toHaveProperty(["property", "deep"], {}); + + expect(jest.fn()).toHaveReturned(); + + expect(jest.fn()).toHaveReturnedTimes(0); + expect(jest.fn()).toHaveReturnedTimes(1); + + expect(jest.fn()).toHaveReturnedWith("jest"); + expect(jest.fn()).toHaveReturnedWith({}); + + expect("").toMatch(""); + expect("").toMatch(/foo/); + + expect({}).toMatchObject({}); + expect({ abc: "def" }).toMatchObject({ abc: "def" }); + expect({}).toMatchObject([{}, {}]); + expect({ abc: "def" }).toMatchObject([{ abc: "def" }, { invalid: "property" }]); + + expect({}).toMatchSnapshot(); + expect({}).toMatchSnapshot("snapshotName"); + + expect(jest.fn()).toReturn(); + + expect(jest.fn()).toReturnTimes(0); + expect(jest.fn()).toReturnTimes(1); + + expect(jest.fn()).toReturnWith("jest"); + expect(jest.fn()).toReturnWith({}); + + expect(true).toStrictEqual(false); + expect({}).toStrictEqual({}); + + expect(() => {}).toThrow(); + expect(() => { throw new Error(); }).toThrow(""); + expect(jest.fn()).toThrow(Error); + expect(jest.fn(() => { throw new Error(); })).toThrow(/foo/); + + expect(() => {}).toThrowErrorMatchingSnapshot(); + expect(() => { throw new Error(); }).toThrowErrorMatchingSnapshot(); + expect(jest.fn()).toThrowErrorMatchingSnapshot(); + expect(jest.fn(() => { throw new Error(); })).toThrowErrorMatchingSnapshot(); + + /* not */ + + expect({}).not.toEqual({}); + expect([]).not.toStrictEqual([]); + + /* Promise matchers */ + + expect(Promise.reject("jest")).rejects.toEqual("jest"); + expect(Promise.reject({})).rejects.toEqual({}); + expect(Promise.resolve("jest")).rejects.toEqual("jest"); + expect(Promise.resolve({})).rejects.toEqual({}); + + expect(Promise.reject("jest")).resolves.toEqual("jest"); + expect(Promise.reject({})).resolves.toEqual({}); + expect(Promise.resolve("jest")).resolves.toEqual("jest"); + expect(Promise.resolve({})).resolves.toEqual({}); + + /* type matchers */ + + expect({}).toBe(expect.anything()); + + expect({}).toBe(expect.any(class Foo { })); + expect(new Error()).toBe(expect.any(Error)); + expect(7).toBe(expect.any(Number)); + + expect({}).toBe(expect.arrayContaining(["a", "b"])); + expect(["abc"]).toBe(expect.arrayContaining(["a", "b"])); + + expect.objectContaining({}); + expect.stringMatching("foo"); + expect.stringMatching(/foo/); + expect.stringContaining("foo"); + + expect({ abc: "def" }).toBe(expect.objectContaining({ + abc: expect.arrayContaining([expect.any(Date), {}]), + def: expect.objectContaining({ + foo: "bar", + }), + ghi: expect.stringMatching("foo"), })); - expect.assertions(4); + /* Miscellaneous */ - interface Test { - a: number; - b: string; + expect.hasAssertions(); + expect.assertions(0); + expect.assertions(9001); + }); +}); + +/* Test framework and config */ + +const workTestFramework = async (testFramework: jest.TestFramework): Promise => { + return testFramework( + { + bail: true, + collectCoverage: false, + collectCoverageFrom: ["glob"], + collectCoverageOnlyFrom: { + abc: true, + def: false, + }, + coverageDirectory: "", + coverageReporters: [""], + coverageThreshold: { + global: { + abc: 90, + def: 100, + }, + }, + expand: true, + forceExit: false, + logHeapUsage: true, + mapCoverage: false, + noStackTrace: true, + notify: false, + projects: ["projects"], + replname: "", + reporters: [ + ["abc", {}], + ["def", {}], + ], + rootDir: "path", + silent: true, + testNamePattern: "", + testPathPattern: "", + testResultsProcessor: "", + updateSnapshot: "all" as "all" | "new" | "none", + useStderr: true, + verbose: false, + watch: true, + watchman: false, + }, + { + automock: true, + browser: false, + cache: true, + cacheDirectory: "", + clearMocks: true, + coveragePathIgnorePatterns: [""], + cwd: "", + detectLeaks: true, + displayName: "", + forceCoverageMatch: ["abc", "def"], + globals: { + "ts-jest": {}, + }, + haste: { + defaultPlatform: "", + hasteImplModulePath: "", + platforms: ["win95", "win2000", "clippy"], + providesModuleNodeModules: ["abc", "def"], + }, + moduleDirectories: ["", ""], + moduleFileExtensions: [".ts", ".json"], + moduleLoader: "laoder", + moduleNameMapper: [ + ["abc", "def"], + ["ghi", "jkl"], + ], + modulePathIgnorePatterns: ["abc", "def"], + modulePaths: ["abc", "def"], + name: "", + resetMocks: true, + resetModules: false, + resolver: "", + rootDir: "", + roots: ["", ""], + runner: "", + setupFiles: ["abc", "def"], + setupTestFrameworkScriptFile: "", + skipNodeResolution: true, + snapshotSerializers: ["abc", "def"], + testEnvironment: "", + testEnvironmentOptions: {}, + testLocationInResults: true, + testMatch: [".test.ts"], + testPathIgnorePatterns: ["*.spec.*"], + testRegex: "abc", + testRunner: "m", + testURL: "localhost:3000", + timers: "real", + transform: [ + ["abc", "def"], + ], + transformIgnorePatterns: ["", ""], + unmockedModulePathPatterns: ["abc"], + watchPathIgnorePatterns: ["def"], + }, + { + global: {}, + fakeTimers: { + clearAllTimers() { }, + runAllImmediates() { }, + runAllTicks() { }, + runAllTimers() { }, + runTimersToTime(time: number) { }, + advanceTimersByTime(time: number) { }, + runOnlyPendingTimers() { }, + runWithRealTimers(callback: () => void) { + callback(); + }, + useFakeTimers() { }, + useRealTimers() { }, + }, + testFilePath: "", + moduleMocker: {}, + dispose() {}, + runScript(script: "") { + return {}; + }, + }, + {}, + "testPath" + ); +}; + +/* Jasmine status changers */ + +describe("", () => { + it("", () => { + pending(); + pending("reason"); + + fail(); + fail("error"); + fail(new Error("reason")); + fail({}); + }); +}); + +/* Jasmine clocks and timing */ + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 9001; + +const clock = jasmine.clock(); + +clock.install(); + +clock.mockDate(); +clock.mockDate(undefined); +clock.mockDate(new Date()); + +clock.tick(0); +clock.tick(9001); + +/* Jasmine matchers */ + +expect({}).toBe(jasmine.anything()); + +expect({}).toBe(jasmine.any(class Foo { })); +expect(new Error()).toBe(jasmine.any(Error)); +expect(7).toBe(jasmine.any(Number)); + +expect({}).toBe(jasmine.arrayContaining(["a", "b"])); +expect(["abc"]).toBe(jasmine.arrayContaining(["a", "b"])); + +jasmine.arrayContaining([]); +new (jasmine.arrayContaining([]))([]); +const arrayContained: boolean = jasmine + .arrayContaining([]) + .asymmetricMatch([]); +const arrayContainedName: string = jasmine + .arrayContaining([]) + .jasmineToString(); + +jasmine.objectContaining({}); +new (jasmine.objectContaining({}))({}); +const objectContained: boolean = jasmine + .objectContaining({}) + .jasmineMatches({}, ["abc"], ["def"]); +const objectContainedName: string = jasmine + .objectContaining({}) + .jasmineToString(); + +jasmine.stringMatching("foo"); +jasmine.stringMatching(/foo/); +new (jasmine.stringMatching("foo"))({}); +const stringContained: boolean = jasmine + .stringMatching(/foo/) + .jasmineMatches({}); +const stringContainedName: string = jasmine + .stringMatching("foo") + .jasmineToString(); + +expect({ abc: "def" }).toBe(jasmine.objectContaining({ + abc: jasmine.arrayContaining([jasmine.any(Date), {}]), + def: jasmine.objectContaining({ + foo: "bar", + }), + ghi: jasmine.stringMatching("foo"), +})); + +/* Jasmine spies */ + +describe("", () => { + it("", () => { + let spy = jasmine.createSpy(); + jasmine.createSpy("name"); + jasmine.createSpy("name", () => {}); + jasmine.createSpy("name", (arg: {}) => arg); + jasmine.createSpy("name", (...args: string[]) => args.join("")); + + spy = jasmine.createSpy() + .and.callFake(() => {}) + .and.callFake((arg: {}) => arg) + .and.callFake((...args: string[]) => args.join("")) + .and.callThrough() + .and.returnValue("jasmine") + .and.returnValue({}) + .and.returnValues() + .and.returnValues("jasmine") + .and.returnValues({}, {}) + .and.stub() + .and.throwError("message"); + + const identity: string = spy.identity; + + let args: any[]; + args = spy.mostRecentCall.args; + args = spy.argsForCall[0]; + args = spy.calls.allArgs(); + args = spy.calls.argsFor(0); + + const spyCalled: boolean = spy.calls.any(); + + const wasCalled: boolean = spy.wasCalled; + + for (const call of [ + ...spy.calls.all(), + spy.calls.first(), + spy.calls.mostRecent(), + ]) { + const callType: jasmine.CallInfo = call; + const callArgs: any[] = call.args; + const { object, returnValue } = call; } - // It's useful to create expected objects before the test call for refactoring purposes - // Assymetric matchers must return any in this case to constrain the required type - const test: Test = { - a: expect.any(Number), - b: expect.anything() + spy.calls.reset(); + + const spyReturn = spy(); + + /* Jasmine spy objects */ + + let spyObject = { + abc() { + return ""; + }, + def: 7, }; - expect(callback).toHaveBeenCalledWith(test); + + spyObject = jasmine.createSpyObj("baseName", ["abc"]); + spyObject = jasmine.createSpyObj("baseName", ["abc"]); + + const newSpyObject: typeof spyObject = jasmine.createSpyObj("baseName", ["abc"]); }); }); -describe('setTimeout', () => { - it('works as expected', done => { - jest.setTimeout(1000); +/* Jasmine pp */ - setTimeout(() => { - expect(true).toBeTruthy(); - done(); - }, 900); - }); -}); +const pp: string = jasmine.pp({}); -describe("spy call matchers", () => { - const spy = jest.fn(); +/* Jasmine equality testers */ - expect(spy).lastReturnedWith("foo"); - expect(spy).nthReturnedWith(3, "foo"); - expect(spy).toHaveBeenCalled(); - expect(spy).toHaveBeenCalledTimes(7); - expect(spy).toHaveBeenCalledWith("foo"); - expect(spy).toHaveBeenLastCalledWith("foo"); - expect(spy).toHaveBeenNthCalledWith(3, "foo"); - expect(spy).toHaveReturned(); - expect(spy).toHaveReturnedTimes(7); - expect(spy).toHaveReturnedWith("foo"); - expect(spy).toHaveLastReturnedWith("foo"); - expect(spy).toHaveNthReturnedWith(3, "foo"); - expect(spy).toReturn(); - expect(spy).toReturnTimes(3); - expect(spy).toReturnWith("foo"); -}); +const equalityTesterObject = (first: {}, second: {}) => false; +const equalityTesterString: jasmine.CustomEqualityTester = (first: string, second: string) => first === second; -describe('Extending extend', () => { - it('works', () => { - expect.extend({ - toBeNumber(received: any, actual: any) { - const pass = received === actual; - const message = - () => `expected ${received} ${pass ? 'not ' : ''} to be ${actual}`; - return { message, pass }; - }, - toBeVariadicMatcher(received: any, floor: number, ceiling: number) { - const pass = received >= floor && received <= ceiling; - const message = - () => `expected ${received} ${pass ? 'not ' : ''} to be within range ${floor}-${ceiling}`; - return { message, pass }; - }, - toBeTest(received: any, actual: any) { - this.utils.ensureNoExpected(received); - this.utils.ensureActualIsNumber(received); - this.utils.ensureExpectedIsNumber(actual); - this.utils.ensureNumbers(received, actual); +jasmine.addCustomEqualityTester(equalityTesterObject); +jasmine.addCustomEqualityTester(equalityTesterObject); - return { - message: () => ` - ${this.utils.getType(received).toLowerCase()} \n\n - ${this.utils.matcherHint(".not.toBe")} ${this.utils.printExpected(actual)} ${this.utils.printReceived(received)}\n\n - `, - pass: true - }; - } - }); - }); -}); - -describe('missing tests', () => { - it('creates closures', () => { - class Closure { - private arg: T; - - constructor(private readonly fn: (arg: T) => void) { - this.fn = fn; - } - - bind(arg: T): void { - this.arg = arg; - } - - call(): void { - this.fn(this.arg); - } - } - - type StringClosure = (arg: string) => void; - const spy: jest.Mock = jest.fn(); - const closure: Closure = new Closure(spy); - closure.bind('jest'); - closure.call(); - expect(spy).lastCalledWith('jest'); - expect(spy).toBeCalledWith('jest'); - expect(jest.isMockFunction(spy)).toBeTruthy(); - }); - - it('tests all missing Mocks functionality', () => { - type FruitsGetter = () => string[]; - const mock: jest.Mock = jest.fn(); - mock.mockImplementationOnce(() => ['Orange', 'Apple', 'Plum']); - jest.setMock('./../tesks/getFruits', mock); - const getFruits: FruitsGetter = require('./../tesks/getFruits'); - expect(getFruits()).toContain('Orange'); - mock.mockReturnValueOnce(['Apple', 'Plum']); - expect(mock()).not.toContain('Orange'); - const myBeverage: any = {delicious: true, sour: false}; - expect(myBeverage).toContainEqual({delicious: true, sour: false}); - mock.mockReturnValue([]); // Deprecated: Use jest.fn(() => value) instead. - mock.mockClear(); - const thisMock: jest.Mock = jest.fn().mockReturnThis(); - expect(thisMock()).toBe(this); - }); - - it('async test with mockResolvedValue and mockResolvedValueOnce', async () => { - const asyncMock = jest - .fn() - .mockResolvedValue('default') - .mockResolvedValueOnce('first call') - .mockResolvedValueOnce('second call'); - - await asyncMock(); // first call - await asyncMock(); // second call - await asyncMock(); // default - await asyncMock(); // default - }); - - it('async test with mockRejectedValue', async () => { - const asyncMock = jest.fn().mockRejectedValue(new Error('Async error')); - - await asyncMock(); // throws "Async error" - }); - - it('async test with mockResolvedValueOnce and mockRejectedValueOnce', async () => { - const asyncMock = jest - .fn() - .mockResolvedValueOnce('first call') - .mockRejectedValueOnce(new Error('Async error')); - - await asyncMock(); // first call - await asyncMock(); // throws "Async error" - }); - - it('tests mock name functionality', () => { - const mock: jest.Mock = jest.fn(); - mock.mockName('Carrot'); - expect(mock.getMockName()).toBe('Carrot'); - }); - - it('tests mock name functionality', () => { - const mock = spyOn(console, 'warn'); - expect(mock).toHaveBeenCalled(); - }); - - it('creates snapshoter', () => { - jest.disableAutomock().mock('./render', () => jest.fn((): string => "{Link to: \"facebook\"}"), { virtual: true }); - const render: () => string = require('./render'); - expect(render()).toMatch(/Link/); - jest.enableAutomock(); - }); - - it('runs only pending timers', () => { - jest.useRealTimers(); - setTimeout(() => expect(1).not.toEqual(0), 3000); - jest.runOnlyPendingTimers().runTimersToTime(300); - }); - - it('runs all timers', () => { - jest.clearAllTimers(); - jest.useFakeTimers(); - setTimeout(() => expect(0).not.toEqual(1), 3000); - jest.runAllTimers(); - }); - - it('cleares cache', () => { - const sum1 = require('../sum'); - jest.resetModules(); - const sum2 = require('../sum'); - expect(sum1).not.toBe(sum2); - }); -}); - -describe('toMatchSnapshot', () => { - it('compares snapshots', () => { - expect({ type: 'a', props: { href: 'https://www.facebook.com/' }, children: [ 'Facebook' ] }).toMatchSnapshot(); - }); - - it('can give name to snapshot', () => { - expect({ type: 'a', props: { href: 'https://www.facebook.com/' }, children: [ 'Facebook' ] }).toMatchSnapshot('given name'); - }); -}); - -describe('toThrowErrorMatchingSnapshot', () => { - it('compares snapshots', () => { - expect(() => { throw new Error('descriptiton'); }).toThrowErrorMatchingSnapshot(); - }); -}); - -const testSerializerPluginString = "set by testSerializerPlugin"; -let testSerializerPluginCallCount = 0; -expect.addSnapshotSerializer({ - print(val, serialize, indent, opts, colors) { - val.willOverwrite = testSerializerPluginString; - testSerializerPluginCallCount += 1; - return 'plugin called: ' + serialize(val.willOverwrite); - }, - test(val) { - return val && val.willOverwrite && val.willOverwrite !== testSerializerPluginString; - }, -}); -describe('addSnapshotSerializer', () => { - it('the plugin does its work', () => { - testSerializerPluginCallCount = 0; - expect({ willOverwrite: { x: 1, y: 2, } }).toMatchSnapshot(); - expect({ willOverwrite: "this will get overwritten by testSerializerPlugin" }).toMatchSnapshot(); - expect({ willOverwrite: "so will this" }).toMatchSnapshot(); - expect({ foo: "this will not" }).toMatchSnapshot(); - expect(testSerializerPluginCallCount).toBe(3); - }); -}); - -function testInstances() { - const mockFn = jest.fn<(...args: any[]) => any>(); - const a = new mockFn(); - const b = new mockFn(); - - mockFn.mock.instances[0] === a; // true - mockFn.mock.instances[1] === b; // true -} - -function testMockImplementation() { - const mockFn = jest.fn<(...args: any[]) => any>().mockImplementation((scalar: number): number => { - return 42 + scalar; - }); - - const a = mockFn(0); - const b = mockFn(1); - - a === 42; // true - b === 43; // true - - mockFn.mock.calls[0][0] === 0; // true - mockFn.mock.calls[1][0] === 1; // true -} - -// Test from jest Docs: -describe('genMockFromModule', () => { - // Interfaces: - interface MockFiles { - [index: string]: string; - } - - interface MockedFS { - readdirSync(dir: string): string[]; - __setMockFiles(newMockFiles: MockFiles): void ; - } - - // ------------------------------------------------------------------------------------ - // FileSummarizer.ts - - const fs = require('fs'); - - function summarizeFilesInDirectorySync(directory: string): string[] { - return fs.readdirSync(directory).map((fileName: string) => ({ - fileName, - directory, - })); - } - - // export default summarizeFilesInDirectorySync; // For sake of compilation - - // ------------------------------------------------------------------------------------ - // __mocks__/fs.js - - const path = require('path'); - - const mockedFS: MockedFS = jest.genMockFromModule('fs'); - - let mockFiles: any = Object.create(null); - function __setMockFiles(newMockFiles: MockFiles): void { - mockFiles = Object.create(null); - for (const file in newMockFiles) { - const dir: string = path.dirname(file); - - if (!mockFiles[dir]) { - mockFiles[dir] = []; - } - mockFiles[dir].push(path.basename(file)); - } - } - - function readdirSync(directoryPath: string): string[] { - return mockFiles[directoryPath] || []; - } - - mockedFS.readdirSync = readdirSync; - mockedFS.__setMockFiles = __setMockFiles; - - // export = mockedFS; // For sake of compilation - // ------------------------------------------------------------------------------------ - // __tests__/FileSummarizer-test.js - - jest.mock('fs'); - - describe('listFilesInDirectorySync', () => { - const MOCK_FILE_INFO: MockFiles = { - '/path/to/file1.js': 'console.log("file1 contents");', - '/path/to/file2.txt': 'file2 contents', - }; - - beforeEach(() => { - // Set up some mocked out file info before each test - (require('fs') as MockedFS).__setMockFiles(MOCK_FILE_INFO); - }); - - it('includes all files in the directory in the summary', () => { - const FileSummarizer: (dir: string) => string[] = require('../FileSummarizer'); - const fileSummary = FileSummarizer('/path/to'); - - expect(fileSummary.length).toBe(2); - }); - }); -}); - -/** - * Pass strictNullChecks - */ -describe('strictNullChecks', () => { - it('does not complain when using done callback', (done) => { - done(); - }); -}); - -describe('beforeEach with timeout', () => { - beforeEach(() => { - // this shouldn't take more than a second - }, 1000); -}); - -class TestApi { - constructor() { } - testProp: boolean; - private readonly anotherProp: string; - testMethod(a: number): string { return ""; } -} - -declare function mockedFunc(a: number): string; - -declare function mockedFuncWithApi(api: TestApi): void; - -describe('Mocked type', () => { - it('Works', () => { - const mock: jest.Mocked = new TestApi() as any; - mock.testProp; - mock.testMethod.mockImplementation(() => 'test'); - mock.testMethod(5).toUpperCase(); - - mockedFuncWithApi(mock); - }); -}); - -describe('Mocks', () => { - it('jest.fn() without args is a function type', () => { - const test = jest.fn(); - test(); - new test(); - test.mock.instances[0]; - test.mockImplementation(() => { }); - }); - - it('jest.fn() with returned object infers type', () => { - const testMock = jest.fn(() => ({ a: 5, test: jest.fn() })); - - testMock(5, 5, 'a'); - testMock.mockImplementation(() => { }); - testMock.caller; - - const ins = new testMock(); - ins.a; - ins.test(); - ins.test.mockImplementation(() => 5); - ins.test.mock.calls; - - const anotherMock = jest.fn(() => { - const api: Partial = { - testMethod: jest.fn() - }; - return api; - }); - const anotherIns: jest.Mocked = new anotherMock() as any; - anotherIns.testMethod.mockImplementation(() => 1); - }); - - it('jest.fn() accepts constructor arguments', () => { - interface TestLog { - log(...msg: any[]): void; - } - - class LogMock extends jest.fn((verbose?: boolean) => { - const mockLog = () => { - if (verbose) { - return jest.fn((...args) => { - const subj = args.shift() || ""; - console.log(subj, ...args); - }); - } - return jest.fn(); - }; +/* Jasmine matchers */ +const customMatcherFactoriesNone = {}; +const customMatcherFactoriesIndex: { [i: string]: jasmine.CustomMatcherFactory } = {}; +const customMatcherFactoriesManual = { + abc: () => ({ + compare: (actual: "", expected: "", ...args: Array<{}>) => ({ + pass: true, + message: "", + }), + }), + def: (util: jasmine.MatchersUtil, customEqualityTestesr: jasmine.CustomEqualityTester): jasmine.CustomMatcher => ({ + compare(actual: T, expected: T): jasmine.CustomMatcherResult { return { - log: mockLog() + pass: actual === expected, + message: () => "foo", }; - }) { - } + }, + }), +}; - const nonVerboseLog = new LogMock(); - nonVerboseLog.log("this is completely catched by jest"); - expect(nonVerboseLog.log).toBeCalledWith("this is completely catched by jest"); - const verboseLog = new LogMock(true); - verboseLog.log("this should also be printed to the console"); - expect(verboseLog.log).toBeCalledWith("this should also be printed to the console"); - }); -}); +const matchersUtil1 = { + buildFailureMessage: () => "", + contains: (haystack: string, needle: string) => haystack.indexOf(needle) !== -1, + equals: (a: {}, b: {}) => false, +}; -// https://facebook.github.io/jest/docs/en/expect.html#resolves -describe('resolves', () => { - it('unwraps the expected Promise', () => { - const expectation = expect(Promise.resolve('test')).resolves.toEqual('test'); - expect(expectation instanceof Promise).toBeTruthy(); - return expectation; - }); +let matchersUtil2: jasmine.MatchersUtil = { + buildFailureMessage(matcherName: string, isNot: boolean, actual: any, ...expected: any[]): string { + return `${matcherName}${isNot ? "1" : "0"}${actual}${expected.join("")}`; + }, + contains(haystack: T[], needle: T, customTesters?: jasmine.CustomEqualityTester[]) { + return true; + }, + equals: (a: {}, b: {}, customTesters?: jasmine.CustomEqualityTester[]) => false, +}; - it('unwraps a .toHaveBeenCalledX', done => { - expect.assertions(2); - - const fn = jest.fn(); - return expect(Promise.resolve(fn)).resolves.toHaveBeenCalledTimes(0).then(val => { - expect(val).toEqual(true); - done(); - }); - }); - - it('unwraps a not.toHaveBeenCalledX', done => { - expect.assertions(2); - - const fn = jest.fn(); - return expect(Promise.resolve(fn)).resolves.not.toHaveBeenCalledTimes(1).then(val => { - expect(val).toEqual(true); - done(); - }); - }); -}); - -// https://facebook.github.io/jest/docs/en/expect.html#rejects -describe('rejects', () => { - it('unwraps the expected Promise', () => { - const expectation = expect(Promise.reject(new Error('error'))).rejects.toMatch('error'); - expect(expectation instanceof Promise).toBeTruthy(); - return expectation; - }); -}); - -// https://facebook.github.io/jest/docs/en/expect.html#tohavepropertykeypath-value -describe('toHaveProperty', () => { - it('it accepts a keyPath as string', () => { - expect({ a: { b: {}}}).toHaveProperty('a'); - }); - it('it accepts a keyPath as string with dot notation', () => { - expect({ a: { b: {}}}).toHaveProperty('a.b'); - }); - it('it accepts a keyPath as an array', () => { - expect({ a: { b: {}}}).toHaveProperty(['a', 'b']); - }); - it('it accepts a keyPath as an array containing non-string values', () => { - expect({ a: ['b']}).toHaveProperty(['a', 0]); - }); -}); - -class MyTransformer implements jest.Transformer { - process(text: string, path: string) { - return ` - // some comments - ${text} - `; - } -} - -class MyReporter implements jest.Reporter { - onRunStart() { - console.log('hello world'); - } -} - -declare const testResult: jest.TestResult; -const myTestRunner: jest.TestFramework = () => Promise.resolve(testResult); - -const testResultsProcessor: jest.TestResultsProcessor = result => ({...result, numFailedTests: 1}); - -// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18826 -test('moduleName 1', () => { - jest.doMock('../moduleName', () => { - return jest.fn(() => 1); - }); - const moduleName = require('../moduleName'); - expect(moduleName()).toEqual(1); -}); -test('moduleName 2', () => { - jest.doMock('../moduleName', () => { - return jest.fn(() => 2); - }); - const moduleName = require('../moduleName'); - expect(moduleName()).toEqual(2); -}); - -describe('toHaveBeenNthCalledWith', () => { - const fn = jest.fn(); - - expect(fn).toHaveBeenNthCalledWith(3, "foo"); -}); +matchersUtil2 = matchersUtil1;