mirror of
https://github.com/pezkuwichain/pezkuwi-dev.git
synced 2026-10-22 19:56:18 +00:00
The browser env exposed the HTML*Element constructors but not the classes above them, so a library checking `instanceof Element` (as react-tooltip does on every hover) threw "Element is not defined". Node, Element, Document, DocumentFragment, Text, ShadowRoot and SVGElement now come from JSDOM. expect().toContain and .not.toContain were stubs. A string contains a substring; any other iterable contains the item itself, not a deep-equal copy, as in jest.
283 lines
7.6 KiB
TypeScript
283 lines
7.6 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/dev-test authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
describe('expect', () => {
|
|
it('has been decorated', () => {
|
|
expect(expect(true).not).toBeDefined();
|
|
});
|
|
|
|
it('throws on unimplemented', () => {
|
|
expect(
|
|
() => expect(true).not.toHaveReturnedWith()
|
|
).toThrow('expect(...).not.toHaveReturnedWith has not been implemented');
|
|
});
|
|
|
|
it('throws on unimplemented (with alternative)', () => {
|
|
expect(
|
|
() => expect(true).not.toBeFalsy()
|
|
).toThrow('expect(...).not.toBeFalsy has not been implemented (Use expect(...).toBeTruthy instead)');
|
|
});
|
|
|
|
describe('rejects', () => {
|
|
it('matches a rejection via .toThrow', async () => {
|
|
await expect(
|
|
Promise.reject(new Error('this is a rejection message'))
|
|
).rejects.toThrow(/rejection/);
|
|
});
|
|
});
|
|
|
|
describe('.toBeDefined', () => {
|
|
it('does not throw on null', () => {
|
|
expect(null).toBeDefined();
|
|
});
|
|
|
|
it('throws on undefined', () => {
|
|
expect(
|
|
() => expect(undefined).toBeDefined()
|
|
).toThrow();
|
|
});
|
|
|
|
it('.not does not throw on undefined', () => {
|
|
expect(undefined).not.toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('.toThrow', () => {
|
|
const thrower = () => {
|
|
throw new Error('some error');
|
|
};
|
|
|
|
it('matches error with empty throw', () => {
|
|
expect(thrower).toThrow();
|
|
});
|
|
|
|
it('matches error with exact message', () => {
|
|
expect(thrower).toThrow('some error');
|
|
});
|
|
|
|
it('matches error with regex message', () => {
|
|
expect(thrower).toThrow(/me er/);
|
|
});
|
|
|
|
it('handles .not correctly (no throw, empty message)', () => {
|
|
expect(() => undefined).not.toThrow();
|
|
});
|
|
|
|
it('handles .not correctly (no throw, regex match)', () => {
|
|
expect(() => undefined).not.toThrow(/me er/);
|
|
});
|
|
|
|
it('handles .not correctly (throw, string match)', () => {
|
|
expect(() => undefined).not.toThrow('no match');
|
|
});
|
|
|
|
it('handles .not correctly (throw, regex match)', () => {
|
|
expect(() => undefined).not.toThrow(/no match/);
|
|
});
|
|
});
|
|
|
|
describe('.toMatch', () => {
|
|
it('fails matching when non-object passed in', () => {
|
|
expect(
|
|
() => expect(undefined).toMatch(/match/)
|
|
).toThrow(/Expected string/);
|
|
});
|
|
|
|
it('fails matching when non-matching string passed in', () => {
|
|
expect(
|
|
() => expect('some').toMatch(/match/)
|
|
).toThrow(/did not match/);
|
|
});
|
|
|
|
it('matches string passed', () => {
|
|
expect(
|
|
() => expect('matching').toMatch(/match/)
|
|
).not.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('.toMatchObject', () => {
|
|
it('fails matching when non-object passed in', () => {
|
|
expect(
|
|
() => expect(undefined).toMatchObject({ foo: 'bar' })
|
|
).toThrow(/Expected object/);
|
|
});
|
|
|
|
it('matches empty object', () => {
|
|
expect({
|
|
a: 'foo',
|
|
b: 'bar'
|
|
}).toMatchObject({});
|
|
});
|
|
|
|
it('matches object with some fields', () => {
|
|
expect({
|
|
a: 'foo',
|
|
b: 'bar',
|
|
c: 123,
|
|
d: [456, 789]
|
|
}).toMatchObject({
|
|
a: 'foo',
|
|
c: 123,
|
|
d: [456, 789]
|
|
});
|
|
});
|
|
|
|
it('matches an object with some expect.stringMatching supplied', () => {
|
|
expect({
|
|
a: 'foo bar',
|
|
b: 'baz',
|
|
c: 'zaz'
|
|
}).toMatchObject({
|
|
a: expect.stringMatching(/o b/),
|
|
b: expect.stringMatching('baz'),
|
|
c: 'zaz'
|
|
});
|
|
});
|
|
|
|
it('matches an object with expect.any supplied', () => {
|
|
expect({
|
|
a: 123,
|
|
b: Boolean(true),
|
|
c: 'foo'
|
|
}).toMatchObject({
|
|
a: expect.any(Number),
|
|
b: expect.any(Boolean),
|
|
c: 'foo'
|
|
});
|
|
});
|
|
|
|
it('does not match an object with non instance value for expect.any', () => {
|
|
expect(
|
|
() => expect({
|
|
a: true,
|
|
b: 'foo'
|
|
}).toMatchObject({
|
|
a: expect.any(Number),
|
|
b: 'foo'
|
|
})
|
|
).toThrow(/not an instance of Number/);
|
|
});
|
|
|
|
it('matches an object with expect.anything supplied', () => {
|
|
expect({
|
|
a: 123,
|
|
b: 'foo'
|
|
}).toMatchObject({
|
|
a: expect.anything(),
|
|
b: 'foo'
|
|
});
|
|
});
|
|
|
|
it('does not match an object with undefined value for expect.anything', () => {
|
|
expect(
|
|
() => expect({
|
|
b: 'foo'
|
|
}).toMatchObject({
|
|
a: expect.anything(),
|
|
b: 'foo'
|
|
})
|
|
).toThrow(/non-nullish/);
|
|
});
|
|
|
|
it('does not match an object with non-array value', () => {
|
|
expect(
|
|
() => expect({
|
|
a: 'foo',
|
|
b: 'bar'
|
|
}).toMatchObject({
|
|
a: 'foo',
|
|
b: [123, 456]
|
|
})
|
|
).toThrow(/Expected array value/);
|
|
});
|
|
|
|
it('allows for deep matching', () => {
|
|
expect({
|
|
a: 123,
|
|
b: {
|
|
c: 456,
|
|
d: {
|
|
e: 'foo',
|
|
f: 'bar',
|
|
g: {
|
|
h: [789, { z: 'baz' }]
|
|
}
|
|
}
|
|
}
|
|
}).toMatchObject({
|
|
a: 123,
|
|
b: {
|
|
c: expect.any(Number),
|
|
d: {
|
|
f: 'bar',
|
|
g: {
|
|
h: [expect.any(Number), { z: 'baz' }]
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('asymmetric matchers in .toEqual', () => {
|
|
it('matches an array containing all expected entries, in any order', () => {
|
|
expect([1, 2, 3]).toEqual(expect.arrayContaining([3, 1]));
|
|
expect(['a', 'b']).toEqual(expect.arrayContaining(['b', 'a']));
|
|
});
|
|
|
|
it('fails when an expected entry is missing', () => {
|
|
expect(() => expect([1, 2]).toEqual(expect.arrayContaining([3]))).toThrow();
|
|
});
|
|
|
|
it('compares array entries deeply', () => {
|
|
expect([{ a: 1 }, { b: 2 }]).toEqual(expect.arrayContaining([{ b: 2 }]));
|
|
expect(() => expect([{ a: 1 }]).toEqual(expect.arrayContaining([{ a: 2 }]))).toThrow();
|
|
});
|
|
|
|
it('matches a string containing the expected part', () => {
|
|
expect('hello world').toEqual(expect.stringContaining('lo w'));
|
|
expect(() => expect('hello').toEqual(expect.stringContaining('xyz'))).toThrow();
|
|
});
|
|
|
|
it('applies matchers nested in objects and arrays', () => {
|
|
expect({ a: [1, 2], b: 'x' }).toEqual({ a: expect.arrayContaining([2]), b: 'x' });
|
|
expect([{ a: 'xyz' }]).toEqual([{ a: expect.stringContaining('y') }]);
|
|
expect(() => expect({ a: [1], b: 'x' }).toEqual({ a: expect.arrayContaining([2]), b: 'x' })).toThrow();
|
|
});
|
|
|
|
it('still requires equal keys around a nested matcher', () => {
|
|
expect(() => expect({ a: [1], b: 'x', c: 1 }).toEqual({ a: expect.arrayContaining([1]), b: 'x' })).toThrow();
|
|
});
|
|
|
|
it('supports .not with a matcher', () => {
|
|
expect([1, 2]).not.toEqual(expect.arrayContaining([3]));
|
|
expect(() => expect([1, 2]).not.toEqual(expect.arrayContaining([2]))).toThrow();
|
|
});
|
|
});
|
|
|
|
describe('.toContain', () => {
|
|
it('finds a substring in a string', () => {
|
|
expect('voter-alice').toContain('alice');
|
|
expect(() => expect('voter-alice').toContain('bob')).toThrow();
|
|
});
|
|
|
|
it('finds the item itself in an array or other iterable', () => {
|
|
const item = { a: 1 };
|
|
|
|
expect([1, item]).toContain(item);
|
|
expect(new Set(['a'])).toContain('a');
|
|
expect(() => expect([{ a: 1 }]).toContain({ a: 1 })).toThrow();
|
|
});
|
|
|
|
it('rejects a value that is neither a string nor an iterable', () => {
|
|
expect(() => expect(123).toContain(1)).toThrow();
|
|
});
|
|
|
|
it('supports .not', () => {
|
|
expect('voter-alice').not.toContain('bob');
|
|
expect(() => expect([1, 2]).not.toContain(2)).toThrow();
|
|
});
|
|
});
|
|
});
|