/**
 * Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
 * Modifications copyright (c) Microsoft Corporation.
 *
 * This source code is licensed under the MIT license found here
 * https://github.com/jestjs/jest/blob/v30.2.0/LICENSE
 */
// Adapted from jest/packages/expect/src/__tests__/matchers.test.js,
// asymmetricMatchers.test.ts and toThrowMatchers.test.ts.
import { test, expect } from './pageTest';
test.describe('.toBe()', () => {
    test('does not throw', () => {
        expect('a').not.toBe('b');
        expect('a').toBe('a');
        expect(1).not.toBe(2);
        expect(1).toBe(1);
        expect(null).not.toBe(undefined);
        expect(null).toBe(null);
        expect(undefined).toBe(undefined);
        expect(NaN).toBe(NaN);
        expect(BigInt(1)).not.toBe(BigInt(2));
        expect(BigInt(1)).not.toBe(1);
        expect(BigInt(1)).toBe(BigInt(1));
    });
    for (const [i, [a, b]] of [
        [1, 2],
        [true, false],
        [{}, {}],
        [{ a: 1 }, { a: 1 }],
        [{ a: 1 }, { a: 5 }],
        [{ a: undefined, b: 2 }, { b: 2 }],
        [new Date('2020-02-20'), new Date('2020-02-20')],
        [/received/, /expected/],
        [['abc'], ['cde']],
        [[], []],
        [null, undefined],
        [-0, +0],
    ].entries()) {
        test(`fails for: ${JSON.stringify(a)} and ${JSON.stringify(b)} #${i}`, () => {
            expect(() => expect(a).toBe(b)).toThrow();
        });
    }
    for (const v of [false, 1, 'a', undefined, null, {}, []]) {
        test(`fails for '${JSON.stringify(v)}' with '.not'`, () => {
            expect(() => expect(v).not.toBe(v)).toThrow();
        });
    }
    test('does not crash on circular references', () => {
        const obj = {};
        obj.circular = obj;
        expect(() => expect(obj).toBe({})).toThrow();
    });
    test('matcherResult property contains matcher name, expected and actual values', () => {
        const actual = { a: 1 };
        const expected = { a: 2 };
        try {
            expect(actual).toBe(expected);
        }
        catch (error) {
            expect(error.matcherResult).toEqual(expect.objectContaining({
                actual,
                expected,
                name: 'toBe',
            }));
        }
    });
});
test.describe('.toStrictEqual()', () => {
    class TestClassA {
        a;
        b;
        constructor(a, b) {
            this.a = a;
            this.b = b;
        }
    }
    class TestClassB {
        a;
        b;
        constructor(a, b) {
            this.a = a;
            this.b = b;
        }
    }
    test('does not ignore keys with undefined values', () => {
        expect({ a: undefined, b: 2 }).not.toStrictEqual({ b: 2 });
    });
    test('does not ignore keys with undefined values inside an array', () => {
        expect([{ a: undefined }]).not.toStrictEqual([{}]);
    });
    test('passes when comparing same type', () => {
        expect({ test: new TestClassA(1, 2) }).toStrictEqual({ test: new TestClassA(1, 2) });
    });
    test('does not pass for different types', () => {
        expect({ test: new TestClassA(1, 2) }).not.toStrictEqual({ test: new TestClassB(1, 2) });
    });
    test('passes for matching buffers', () => {
        expect(Uint8Array.from([1]).buffer).toStrictEqual(Uint8Array.from([1]).buffer);
        expect(Uint8Array.from([]).buffer).toStrictEqual(Uint8Array.from([]).buffer);
        expect(Uint8Array.from([9, 3]).buffer).toStrictEqual(Uint8Array.from([9, 3]).buffer);
    });
    test('does not pass when ArrayBuffers are not equal', () => {
        expect(Uint8Array.from([1, 2]).buffer).not.toStrictEqual(Uint8Array.from([0, 0]).buffer);
    });
});
test.describe('.toEqual()', () => {
    for (const [a, b] of [
        [true, false],
        [1, 2],
        [0, Number.MIN_VALUE],
        [{ a: 1 }, { a: 2 }],
        ['banana', 'apple'],
        [null, undefined],
        [[1], [2]],
        [new Set([1, 2]), new Set()],
        [new Set([1, 2]), new Set([1, 2, 3])],
        [new Map([['a', 0]]), new Map([['b', 0]])],
        [new Uint8Array([97, 98, 99]), new Uint8Array([97, 98, 100])],
        [{ a: 1, b: 2 }, expect.objectContaining({ a: 2 })],
        [[1, 3], expect.arrayContaining([1, 2])],
        ['abd', expect.stringContaining('bc')],
        ['abd', expect.stringMatching(/bc/i)],
        [undefined, expect.anything()],
        [undefined, expect.any(Function)],
    ].entries()) {
        test(`{pass: false} expect().toEqual() #${a}`, () => {
            expect(() => expect(b[0]).toEqual(b[1])).toThrow();
            expect(b[0]).not.toEqual(b[1]);
        });
    }
    for (const [a, b] of [
        [true, true],
        [1, 1],
        [NaN, NaN],
        ['abc', 'abc'],
        [[1], [1]],
        [{}, {}],
        [{ a: 99 }, { a: 99 }],
        [new Set(), new Set()],
        [new Set([1, 2]), new Set([1, 2])],
        [new Set([1, 2]), new Set([2, 1])],
        [new Map(), new Map()],
        [new Uint8Array([97, 98, 99]), new Uint8Array([97, 98, 99])],
        [{ a: 1, b: 2 }, expect.objectContaining({ a: 1 })],
        [[1, 2, 3], expect.arrayContaining([2, 3])],
        ['abcd', expect.stringContaining('bc')],
        ['abcd', expect.stringMatching('bc')],
        [true, expect.anything()],
        [() => { }, expect.any(Function)],
    ].entries()) {
        test(`{pass: true} expect().toEqual() #${a}`, () => {
            expect(b[0]).toEqual(b[1]);
            expect(() => expect(b[0]).not.toEqual(b[1])).toThrow();
        });
    }
    test('assertion error matcherResult property contains matcher name, expected and actual values', () => {
        const actual = { a: 1 };
        const expected = { a: 2 };
        try {
            expect(actual).toEqual(expected);
        }
        catch (error) {
            expect(error.matcherResult).toEqual(expect.objectContaining({
                actual,
                expected,
                name: 'toEqual',
            }));
        }
    });
    test('symbol based keys in arrays are processed correctly', () => {
        const mySymbol = Symbol('test');
        const actual1 = [];
        actual1[mySymbol] = 3;
        const actual2 = [];
        actual2[mySymbol] = 4;
        const expected = [];
        expected[mySymbol] = 3;
        expect(actual1).toEqual(expected);
        expect(actual2).not.toEqual(expected);
    });
    test('non-enumerable members should be skipped during equal', () => {
        const actual = { x: 3 };
        Object.defineProperty(actual, 'test', { enumerable: false, value: 5 });
        expect(actual).toEqual({ x: 3 });
    });
    test('objectContaining sample can be used multiple times', () => {
        const expected = expect.objectContaining({ b: 7 });
        expect({ a: 1, b: 2 }).not.toEqual(expected);
        expect({ a: 3, b: 7 }).toEqual(expected);
    });
    test.describe('cyclic object equality', () => {
        test('properties with the same circularity are equal', () => {
            const a = {};
            a.x = a;
            const b = {};
            b.x = b;
            expect(a).toEqual(b);
            expect(b).toEqual(a);
        });
        test('properties with different circularity are not equal', () => {
            const a = {};
            a.x = { y: a };
            const b = {};
            const bx = {};
            b.x = bx;
            bx.y = bx;
            expect(a).not.toEqual(b);
            expect(b).not.toEqual(a);
        });
    });
});
test.describe('.toBeInstanceOf()', () => {
    class A {
    }
    class B {
    }
    class C extends B {
    }
    class E extends C {
    }
    for (const [i, [a, b]] of [
        [new Map(), Map],
        [[], Array],
        [new A(), A],
        [new C(), B],
        [new E(), B],
    ].entries()) {
        test(`passing instanceof #${i}`, () => {
            expect(() => expect(a).not.toBeInstanceOf(b)).toThrow();
            expect(a).toBeInstanceOf(b);
        });
    }
    for (const [i, [a, b]] of [
        ['a', String],
        [1, Number],
        [true, Boolean],
        [new A(), B],
    ].entries()) {
        test(`failing instanceof #${i}`, () => {
            expect(() => expect(a).toBeInstanceOf(b)).toThrow();
            expect(a).not.toBeInstanceOf(b);
        });
    }
    test('throws if constructor is not a function', () => {
        expect(() => expect({}).toBeInstanceOf(4)).toThrow();
    });
});
test.describe('.toBeTruthy(), .toBeFalsy()', () => {
    for (const v of [{}, [], true, 1, 'a', 0.5, new Map(), () => { }, Infinity]) {
        test(`'${String(v)}' is truthy`, () => {
            expect(v).toBeTruthy();
            expect(v).not.toBeFalsy();
            expect(() => expect(v).not.toBeTruthy()).toThrow();
            expect(() => expect(v).toBeFalsy()).toThrow();
        });
    }
    for (const v of [false, null, NaN, 0, '', undefined]) {
        test(`'${String(v)}' is falsy`, () => {
            expect(v).toBeFalsy();
            expect(v).not.toBeTruthy();
            expect(() => expect(v).toBeTruthy()).toThrow();
            expect(() => expect(v).not.toBeFalsy()).toThrow();
        });
    }
});
test.describe('.toBeNaN()', () => {
    test('{pass: true}', () => {
        for (const v of [NaN, Math.sqrt(-1), Infinity - Infinity, 0 / 0]) {
            expect(v).toBeNaN();
            expect(() => expect(v).not.toBeNaN()).toThrow();
        }
    });
    test('throws', () => {
        for (const v of [1, '', null, undefined, {}, [], 0.2, 0, Infinity, -Infinity]) {
            expect(() => expect(v).toBeNaN()).toThrow();
            expect(v).not.toBeNaN();
        }
    });
});
test.describe('.toBeNull()', () => {
    for (const v of [{}, [], true, 1, 'a', 0.5, new Map(), () => { }, Infinity]) {
        test(`fails for '${String(v)}'`, () => {
            expect(v).not.toBeNull();
            expect(() => expect(v).toBeNull()).toThrow();
        });
    }
    test('fails for null with .not', () => {
        expect(() => expect(null).not.toBeNull()).toThrow();
    });
    test('pass for null', () => {
        expect(null).toBeNull();
    });
});
test.describe('.toBeDefined(), .toBeUndefined()', () => {
    for (const v of [{}, [], true, 1, 'a', 0.5, new Map(), () => { }, Infinity]) {
        test(`'${String(v)}' is defined`, () => {
            expect(v).toBeDefined();
            expect(v).not.toBeUndefined();
            expect(() => expect(v).not.toBeDefined()).toThrow();
            expect(() => expect(v).toBeUndefined()).toThrow();
        });
    }
    test('undefined is undefined', () => {
        expect(undefined).toBeUndefined();
        expect(undefined).not.toBeDefined();
        expect(() => expect(undefined).toBeDefined()).toThrow();
        expect(() => expect(undefined).not.toBeUndefined()).toThrow();
    });
});
test.describe('.toBeGreaterThan(), .toBeLessThan(), .toBeGreaterThanOrEqual(), .toBeLessThanOrEqual()', () => {
    for (const [small, big] of [
        [1, 2],
        [-Infinity, Infinity],
        [Number.MIN_VALUE, Number.MAX_VALUE],
        [0.1, 0.2],
    ]) {
        test(`comparing ${small} and ${big}`, () => {
            expect(small).toBeLessThan(big);
            expect(big).not.toBeLessThan(small);
            expect(big).toBeGreaterThan(small);
            expect(small).not.toBeGreaterThan(big);
            expect(small).toBeLessThanOrEqual(big);
            expect(big).not.toBeLessThanOrEqual(small);
            expect(big).toBeGreaterThanOrEqual(small);
            expect(small).not.toBeGreaterThanOrEqual(big);
            expect(() => expect(small).toBeGreaterThan(big)).toThrow();
            expect(() => expect(small).not.toBeLessThan(big)).toThrow();
            expect(() => expect(big).not.toBeGreaterThan(small)).toThrow();
            expect(() => expect(big).toBeLessThan(small)).toThrow();
            expect(() => expect(small).toBeGreaterThanOrEqual(big)).toThrow();
            expect(() => expect(small).not.toBeLessThanOrEqual(big)).toThrow();
            expect(() => expect(big).not.toBeGreaterThanOrEqual(small)).toThrow();
            expect(() => expect(big).toBeLessThanOrEqual(small)).toThrow();
        });
    }
    test('can compare BigInt to Numbers', () => {
        const a = BigInt(2);
        expect(a).toBeGreaterThan(1);
        expect(a).toBeGreaterThanOrEqual(2);
        expect(2).toBeLessThanOrEqual(a);
        expect(a).toBeLessThan(3);
        expect(a).toBeLessThanOrEqual(2);
    });
    for (const [n1, n2] of [
        [1, 1],
        [Number.MIN_VALUE, Number.MIN_VALUE],
        [Infinity, Infinity],
        [-Infinity, -Infinity],
    ]) {
        test(`equal numbers: [${n1}, ${n2}]`, () => {
            expect(n1).toBeGreaterThanOrEqual(n2);
            expect(n1).toBeLessThanOrEqual(n2);
            expect(() => expect(n1).not.toBeGreaterThanOrEqual(n2)).toThrow();
            expect(() => expect(n1).not.toBeLessThanOrEqual(n2)).toThrow();
        });
    }
});
test.describe('.toContain(), .toContainEqual()', () => {
    const typedArray = new Int8Array(2);
    typedArray[0] = 0;
    typedArray[1] = 1;
    test('iterable', () => {
        const iterable = {
            *[Symbol.iterator]() {
                yield 1;
                yield 2;
                yield 3;
            },
        };
        expect(iterable).toContain(2);
        expect(iterable).toContainEqual(2);
        expect(() => expect(iterable).not.toContain(1)).toThrow();
        expect(() => expect(iterable).not.toContainEqual(1)).toThrow();
    });
    for (const [i, [list, v]] of [
        [[1, 2, 3, 4], 1],
        [['a', 'b', 'c', 'd'], 'a'],
        [[undefined, null], null],
        [[undefined, null], undefined],
        ['abcdef', 'abc'],
        ['11112111', '2'],
        [new Set(['abc', 'def']), 'abc'],
        [typedArray, 1],
    ].entries()) {
        test(`contains #${i}`, () => {
            expect(list).toContain(v);
            expect(() => expect(list).not.toContain(v)).toThrow();
        });
    }
    for (const [i, [list, v]] of [
        [[1, 2, 3], 4],
        [[null, undefined], 1],
        [[{}, []], []],
        [[{}, []], {}],
    ].entries()) {
        test(`does not contain #${i}`, () => {
            expect(list).not.toContain(v);
            expect(() => expect(list).toContain(v)).toThrow();
        });
    }
    test('error cases', () => {
        expect(() => expect(null).toContain(1)).toThrow();
    });
    for (const [i, [list, v]] of [
        [[1, 2, 3, 4], 1],
        [['a', 'b', 'c', 'd'], 'a'],
        [[undefined, null], null],
        [[{ a: 'b' }, { a: 'c' }], { a: 'b' }],
        [new Set([1, 2, 3, 4]), 1],
    ].entries()) {
        test(`contains a value equal #${i}`, () => {
            expect(list).toContainEqual(v);
            expect(() => expect(list).not.toContainEqual(v)).toThrow();
        });
    }
    test('error cases for toContainEqual', () => {
        expect(() => expect(null).toContainEqual(1)).toThrow();
    });
});
test.describe('.toBeCloseTo', () => {
    for (const [n1, n2] of [
        [0, 0],
        [0, 0.001],
        [1.23, 1.229],
        [1.23, 1.226],
        [1.23, 1.234],
        [Infinity, Infinity],
        [-Infinity, -Infinity],
    ]) {
        test(`{pass: true} expect(${n1}).toBeCloseTo(${n2})`, () => {
            expect(n1).toBeCloseTo(n2);
            expect(() => expect(n1).not.toBeCloseTo(n2)).toThrow();
        });
    }
    for (const [n1, n2] of [
        [0, 0.01],
        [1, 1.23],
        [Infinity, -Infinity],
        [Infinity, 1.23],
        [-Infinity, -1.23],
    ]) {
        test(`{pass: false} expect(${n1}).toBeCloseTo(${n2})`, () => {
            expect(n1).not.toBeCloseTo(n2);
            expect(() => expect(n1).toBeCloseTo(n2)).toThrow();
        });
    }
    for (const [n1, n2, p] of [
        [0, 0.1, 0],
        [0, 0.0001, 3],
        [0, 0.000_004, 5],
        [2.000_000_2, 2, 5],
    ]) {
        test(`{pass: true} expect(${n1}).toBeCloseTo(${n2}, ${p})`, () => {
            expect(n1).toBeCloseTo(n2, p);
            expect(() => expect(n1).not.toBeCloseTo(n2, p)).toThrow();
        });
    }
});
test.describe('.toMatch()', () => {
    for (const [n1, n2] of [
        ['foo', 'foo'],
        ['Foo bar', /^foo/i],
    ]) {
        test(`{pass: true} expect(${n1}).toMatch(${n2})`, () => {
            expect(n1).toMatch(n2);
            expect(() => expect(n1).not.toMatch(n2)).toThrow();
        });
    }
    for (const [n1, n2] of [
        ['bar', 'foo'],
        ['bar', /foo/],
    ]) {
        test(`throws: [${n1}, ${n2}]`, () => {
            expect(() => expect(n1).toMatch(n2)).toThrow();
        });
    }
    for (const [i, [n1, n2]] of [
        [1, 'foo'],
        [{}, 'foo'],
        [[], 'foo'],
        [true, 'foo'],
        [/foo/i, 'foo'],
        [() => { }, 'foo'],
        [undefined, 'foo'],
    ].entries()) {
        test(`throws if non String actual value passed #${i}`, () => {
            expect(() => expect(n1).toMatch(n2)).toThrow();
        });
    }
    for (const [i, [n1, n2]] of [
        ['foo', 1],
        ['foo', {}],
        ['foo', []],
        ['foo', true],
        ['foo', () => { }],
        ['foo', undefined],
    ].entries()) {
        test(`throws if non String/RegExp expected value passed #${i}`, () => {
            expect(() => expect(n1).toMatch(n2)).toThrow();
        });
    }
    test('escapes strings properly', () => {
        expect('this?: throws').toMatch('this?: throws');
    });
    test('does not maintain RegExp state between calls', () => {
        const regex = /f\d+/gi;
        expect('f123').toMatch(regex);
        expect('F456').toMatch(regex);
        expect(regex.lastIndex).toBe(0);
    });
});
test.describe('.toHaveLength', () => {
    for (const [i, [received, length]] of [
        [[1, 2], 2],
        [[], 0],
        [['a', 'b'], 2],
        ['abc', 3],
        ['', 0],
        [() => { }, 0],
    ].entries()) {
        test(`{pass: true} toHaveLength(${length}) #${i}`, () => {
            expect(received).toHaveLength(length);
            expect(() => expect(received).not.toHaveLength(length)).toThrow();
        });
    }
    for (const [i, [received, length]] of [
        [[1, 2], 3],
        [[], 1],
        [['a', 'b'], 99],
        ['abc', 66],
        ['', 1],
    ].entries()) {
        test(`{pass: false} toHaveLength(${length}) #${i}`, () => {
            expect(received).not.toHaveLength(length);
            expect(() => expect(received).toHaveLength(length)).toThrow();
        });
    }
    test('error cases', () => {
        expect(() => expect({ a: 9 }).toHaveLength(1)).toThrow();
        expect(() => expect(0).toHaveLength(1)).toThrow();
        expect(() => expect(undefined).not.toHaveLength(1)).toThrow();
    });
});
test.describe('.toHaveProperty()', () => {
    for (const [i, [obj, keyPath, value]] of [
        [{ a: { b: { c: { d: 1 } } } }, 'a.b.c.d', 1],
        [{ a: { b: { c: { d: 1 } } } }, ['a', 'b', 'c', 'd'], 1],
        [{ 'a.b.c.d': 1 }, ['a.b.c.d'], 1],
        [{ a: { b: [1, 2, 3] } }, ['a', 'b', 1], 2],
        [{ a: { b: [1, 2, 3] } }, ['a', 'b', 1], expect.any(Number)],
        [{ a: 0 }, 'a', 0],
        [{ a: { b: undefined } }, 'a.b', undefined],
        [{ a: { b: { c: 5 } } }, 'a.b', { c: 5 }],
        [{ a: { b: [{ c: [{ d: 1 }] }] } }, 'a.b[0].c[0].d', 1],
        [{ '': 1 }, '', 1],
    ].entries()) {
        test(`{pass: true} toHaveProperty with value #${i}`, () => {
            expect(obj).toHaveProperty(keyPath, value);
            expect(() => expect(obj).not.toHaveProperty(keyPath, value)).toThrow();
        });
    }
    for (const [i, [obj, keyPath, value]] of [
        [{ a: { b: { c: { d: 1 } } } }, 'a.b.ttt.d', 1],
        [{ a: { b: { c: { d: 1 } } } }, 'a.b.c.d', 2],
        [{ 'a.b.c.d': 1 }, 'a.b.c.d', 2],
        [{ a: { b: { c: {} } } }, 'a.b.c.d', 1],
        [{ a: 1 }, 'a.b.c.d', 5],
        [{}, 'a', 'test'],
        [{ a: { b: 3 } }, 'a.b', undefined],
    ].entries()) {
        test(`{pass: false} toHaveProperty with value #${i}`, () => {
            expect(() => expect(obj).toHaveProperty(keyPath, value)).toThrow();
            expect(obj).not.toHaveProperty(keyPath, value);
        });
    }
    for (const [i, [obj, keyPath]] of [
        [{ a: { b: { c: { d: 1 } } } }, 'a.b.c.d'],
        [{ a: { b: { c: { d: 1 } } } }, ['a', 'b', 'c', 'd']],
        [{ 'a.b.c.d': 1 }, ['a.b.c.d']],
        [{ a: 0 }, 'a'],
        [{ a: { b: undefined } }, 'a.b'],
    ].entries()) {
        test(`{pass: true} toHaveProperty without value #${i}`, () => {
            expect(obj).toHaveProperty(keyPath);
            expect(() => expect(obj).not.toHaveProperty(keyPath)).toThrow();
        });
    }
    for (const [i, [obj, keyPath]] of [
        [{ a: { b: { c: {} } } }, 'a.b.c.d'],
        [{ a: 1 }, 'a.b.c.d'],
        [{}, 'a'],
    ].entries()) {
        test(`{pass: false} toHaveProperty without value #${i}`, () => {
            expect(() => expect(obj).toHaveProperty(keyPath)).toThrow();
            expect(obj).not.toHaveProperty(keyPath);
        });
    }
    for (const [i, [obj, keyPath]] of [
        [null, 'a.b'],
        [undefined, 'a'],
        [{ a: { b: {} } }, undefined],
        [{ a: { b: {} } }, null],
        [{ a: { b: {} } }, 1],
    ].entries()) {
        test(`{error} toHaveProperty #${i}`, () => {
            expect(() => expect(obj).toHaveProperty(keyPath)).toThrow();
        });
    }
});
test.describe('.toMatchObject()', () => {
    for (const [i, [a, b]] of [
        [{ a: 'b', c: 'd' }, { a: 'b' }],
        [{ a: 'b', c: 'd' }, { a: 'b', c: 'd' }],
        [{ a: 'b', t: { x: { r: 'r' }, z: 'z' } }, { a: 'b', t: { z: 'z' } }],
        [{ a: [3, 4, 5], b: 'b' }, { a: [3, 4, 5] }],
        [{ a: 1, c: 2 }, { a: expect.any(Number) }],
        [new Set([1, 2]), new Set([1, 2])],
        [new Date('2015-11-30'), new Date('2015-11-30')],
        [{ a: null, b: 'b' }, { a: null }],
        [{ a: undefined, b: 'b' }, { a: undefined }],
        [[1, 2], [1, 2]],
        [new Error('foo'), new Error('foo')],
        [new Error('bar'), { message: 'bar' }],
    ].entries()) {
        test(`{pass: true} toMatchObject #${i}`, () => {
            expect(a).toMatchObject(b);
            expect(() => expect(a).not.toMatchObject(b)).toThrow();
        });
    }
    for (const [i, [a, b]] of [
        [{ a: 'b', c: 'd' }, { e: 'b' }],
        [{ a: 'b', c: 'd' }, { a: 'b!', c: 'd' }],
        [{ a: 'a', c: 'd' }, { a: expect.any(Number) }],
        [{ a: [3, 4, 5], b: 'b' }, { a: [3, 4, 5, 6] }],
        [[1, 2], [1, 3]],
        [new Set([1, 2]), new Set([2])],
        [new Error('foo'), new Error('bar')],
    ].entries()) {
        test(`{pass: false} toMatchObject #${i}`, () => {
            expect(a).not.toMatchObject(b);
            expect(() => expect(a).toMatchObject(b)).toThrow();
        });
    }
    for (const [i, [a, b]] of [
        [null, {}],
        [4, {}],
        ['44', {}],
        [true, {}],
        [undefined, {}],
        [{}, null],
        [{}, 4],
    ].entries()) {
        test(`throws toMatchObject #${i}`, () => {
            expect(() => expect(a).toMatchObject(b)).toThrow();
        });
    }
    test('does not match properties up in the prototype chain', () => {
        const a = {};
        a.ref = a;
        const b = Object.create(a);
        b.other = 'child';
        const matcher = { other: 'child' };
        matcher.ref = matcher;
        expect(b).not.toMatchObject(matcher);
        expect(() => expect(b).toMatchObject(matcher)).toThrow();
    });
});
test.describe('.toThrow()', () => {
    class CustomError extends Error {
    }
    test('to throw or not to throw', () => {
        expect(() => {
            throw new CustomError('apple');
        }).toThrow();
        expect(() => { }).not.toThrow();
    });
    test('substring passes', () => {
        expect(() => {
            throw new CustomError('apple');
        }).toThrow('apple');
        expect(() => {
            throw new CustomError('banana');
        }).not.toThrow('apple');
        expect(() => { }).not.toThrow('apple');
    });
    test('substring fails when did not throw', () => {
        expect(() => expect(() => { }).toThrow('apple')).toThrow();
    });
    test('substring fails when message did not match', () => {
        expect(() => expect(() => {
            throw new CustomError('apple');
        }).toThrow('banana')).toThrow();
    });
    test('regexp passes', () => {
        expect(() => {
            throw new CustomError('apple');
        }).toThrow(/apple/);
        expect(() => {
            throw new CustomError('banana');
        }).not.toThrow(/apple/);
        expect(() => { }).not.toThrow(/apple/);
    });
    test('regexp fails when did not throw', () => {
        expect(() => expect(() => { }).toThrow(/apple/)).toThrow();
    });
    test('error class passes', () => {
        class Err extends CustomError {
        }
        class Err2 extends CustomError {
        }
        expect(() => {
            throw new Err('apple');
        }).toThrow(Err);
        expect(() => {
            throw new Err('apple');
        }).toThrow(CustomError);
        expect(() => {
            throw new Err('apple');
        }).not.toThrow(Err2);
    });
    test('object with message passes', () => {
        expect(() => {
            throw new CustomError('apple');
        }).toThrow({ message: 'apple' });
        expect(() => {
            throw new CustomError('banana');
        }).not.toThrow({ message: 'apple' });
    });
    test('properly escapes strings when matching against errors', () => {
        expect(() => {
            throw new TypeError('"this"? throws.');
        }).toThrow('"this"? throws.');
    });
    test('error message and cause properties', () => {
        const errorCause = new Error('cause');
        const error = new Error('message', { cause: errorCause });
        expect(() => {
            throw error;
        }).toThrow({ message: 'message', cause: errorCause });
    });
});
test.describe('asymmetric matchers', () => {
    test('Any matches primitives', () => {
        expect('jest').toEqual(expect.any(String));
        expect(1).toEqual(expect.any(Number));
        expect(() => { }).toEqual(expect.any(Function));
        expect(true).toEqual(expect.any(Boolean));
        expect({}).toEqual(expect.any(Object));
        expect([]).toEqual(expect.any(Array));
    });
    test('Any throws when called with empty constructor', () => {
        expect(() => expect.any()).toThrow('any() expects to be passed a constructor function. Please pass one or use anything() to match any object.');
    });
    test('Anything matches any type', () => {
        expect('jest').toEqual(expect.anything());
        expect(1).toEqual(expect.anything());
        expect(() => { }).toEqual(expect.anything());
        expect(true).toEqual(expect.anything());
        expect({}).toEqual(expect.anything());
        expect([]).toEqual(expect.anything());
    });
    test('Anything does not match null and undefined', () => {
        expect(null).not.toEqual(expect.anything());
        expect(undefined).not.toEqual(expect.anything());
    });
    test('ArrayContaining matches', () => {
        expect(['foo']).toEqual(expect.arrayContaining(['foo']));
        expect(['foo', 'bar']).toEqual(expect.arrayContaining(['foo']));
    });
    test('ArrayContaining does not match', () => {
        expect(['bar']).not.toEqual(expect.arrayContaining(['foo']));
    });
    test('ObjectContaining matches', () => {
        expect({ foo: 'foo', jest: 'jest' }).toEqual(expect.objectContaining({ foo: 'foo' }));
        expect({ foo: undefined }).toEqual(expect.objectContaining({ foo: undefined }));
    });
    test('ObjectContaining does not match', () => {
        expect({ bar: 'bar' }).not.toEqual(expect.objectContaining({ foo: 'foo' }));
        expect({ foo: 'foox' }).not.toEqual(expect.objectContaining({ foo: 'foo' }));
        expect({}).not.toEqual(expect.objectContaining({ foo: undefined }));
    });
    test('ObjectContaining throws for non-objects', () => {
        expect(() => expect({}).toEqual(expect.objectContaining(1337))).toThrow("You must provide an object to ObjectContaining, not 'number'.");
    });
    test('StringContaining matches string against string', () => {
        expect('queen*').toEqual(expect.stringContaining('en*'));
        expect('queue').not.toEqual(expect.stringContaining('en*'));
    });
    test('StringMatching matches string against regexp', () => {
        expect('queen').toEqual(expect.stringMatching(/en/));
        expect('queue').not.toEqual(expect.stringMatching(/en/));
    });
    test('StringMatching matches string against string', () => {
        expect('queen').toEqual(expect.stringMatching('en'));
        expect('queue').not.toEqual(expect.stringMatching('en'));
    });
    test('closeTo matches', () => {
        expect(0).toEqual(expect.closeTo(0));
        expect(0.001).toEqual(expect.closeTo(0));
        expect(1.229).toEqual(expect.closeTo(1.23));
        expect(Infinity).toEqual(expect.closeTo(Infinity));
    });
    test('closeTo does not match', () => {
        expect(0.01).not.toEqual(expect.closeTo(0));
        expect(1.23).not.toEqual(expect.closeTo(1));
        expect(Infinity).not.toEqual(expect.closeTo(-Infinity));
    });
    test('closeTo with precision', () => {
        expect(0.1).toEqual(expect.closeTo(0, 0));
        expect(0.0001).toEqual(expect.closeTo(0, 3));
        expect(0.000_004).toEqual(expect.closeTo(0, 5));
    });
    test('closeTo throws if expected is not number', () => {
        expect(() => expect.closeTo('a')).toThrow('Expected is not a Number');
    });
    test('arrayOf matches', () => {
        expect([1]).toEqual(expect.arrayOf(1));
        expect([1, 1, 1]).toEqual(expect.arrayOf(1));
        expect([{ a: 1 }, { a: 1 }]).toEqual(expect.arrayOf({ a: 1 }));
        expect(['a', 'b', 'c']).toEqual(expect.arrayOf(expect.any(String)));
    });
    test('arrayOf does not match', () => {
        expect([2]).not.toEqual(expect.arrayOf(1));
        expect([1, 2]).not.toEqual(expect.arrayOf(1));
        expect('not an array').not.toEqual(expect.arrayOf(1));
        expect({}).not.toEqual(expect.arrayOf(1));
        expect([1, 2]).not.toEqual(expect.arrayOf(expect.any(String)));
    });
});
//# sourceMappingURL=expect-builtins.spec.js.map