mirror of
https://github.com/pezkuwichain/pezkuwi-dev.git
synced 2026-10-22 03:36:18 +00:00
dev-test: DOM node hierarchy in the browser env; expect().toContain
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.
This commit is contained in:
1 parent
0cd4f12cfb
commit
4e3bf04010
4 files changed
+82
-1
No files matched your search
+12
@@ -24,6 +24,18 @@ describe('browser', () => {
|
||||
expect(typeof all.HTMLElement).toBe('function');
|
||||
});
|
||||
|
||||
it('contains the DOM node hierarchy', () => {
|
||||
const div = document.createElement('div');
|
||||
|
||||
expect(div).toBeInstanceOf(Element);
|
||||
expect(div).toBeInstanceOf(Node);
|
||||
expect(document.createTextNode('text')).toBeInstanceOf(Text);
|
||||
expect(document.createDocumentFragment()).toBeInstanceOf(DocumentFragment);
|
||||
expect(document.createElementNS('http://www.w3.org/2000/svg', 'svg')).toBeInstanceOf(SVGElement);
|
||||
expect(div.attachShadow({ mode: 'open' })).toBeInstanceOf(ShadowRoot);
|
||||
expect(document).toBeInstanceOf(Document);
|
||||
});
|
||||
|
||||
it('dispatches the global CustomEvent and Event on window', () => {
|
||||
expect(() => window.dispatchEvent(new CustomEvent('custom', { detail: 1 }))).not.toThrow();
|
||||
expect(() => window.dispatchEvent(new Event('plain'))).not.toThrow();
|
||||
|
||||
Vendored
+10
-1
@@ -22,8 +22,12 @@ export function browser () {
|
||||
const { window } = new JSDOM('', { url: 'http://localhost' });
|
||||
|
||||
return {
|
||||
// Event constructors, see BROWSER_OVERRIDES
|
||||
// The DOM node hierarchy, which libraries check with instanceof, and the
|
||||
// event constructors (Node has its own of these, see BROWSER_OVERRIDES)
|
||||
CustomEvent: window.CustomEvent,
|
||||
Document: window.Document,
|
||||
DocumentFragment: window.DocumentFragment,
|
||||
Element: window.Element,
|
||||
Event: window.Event,
|
||||
// All HTML Elements that are defined on the JSDOM window object.
|
||||
// (we copied as-is from the types definition). We cannot get this
|
||||
@@ -99,6 +103,11 @@ export function browser () {
|
||||
HTMLUListElement: window.HTMLUListElement,
|
||||
HTMLUnknownElement: window.HTMLUnknownElement,
|
||||
HTMLVideoElement: window.HTMLVideoElement,
|
||||
// the rest of the node hierarchy
|
||||
Node: window.Node,
|
||||
SVGElement: window.SVGElement,
|
||||
ShadowRoot: window.ShadowRoot,
|
||||
Text: window.Text,
|
||||
// normal service resumes, the base top-level names
|
||||
crypto: window.crypto,
|
||||
document: window.document,
|
||||
|
||||
+24
@@ -255,4 +255,28 @@ describe('expect', () => {
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
Vendored
+36
@@ -144,6 +144,40 @@ function assertMatchObj (value: unknown, check: object): void {
|
||||
.forEach(([key, other]) => assertMatch((value as Record<string, unknown>)[key], other));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Whether a string contains the substring, or another iterable the item
|
||||
*/
|
||||
function contains (value: unknown, item: unknown): boolean {
|
||||
if (typeof value === 'string') {
|
||||
return typeof item === 'string' && value.includes(item);
|
||||
}
|
||||
|
||||
assert.ok(typeof (value as Iterable<unknown> | null | undefined)?.[Symbol.iterator] === 'function', `Expected a string or an iterable, found ${typeof value}`);
|
||||
|
||||
return [...(value as Iterable<unknown>)].includes(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* A helper for toContain: a string contains the substring, any other
|
||||
* iterable contains the item itself (not a deep-equal copy)
|
||||
*/
|
||||
function assertContains (value: unknown, item: unknown): void {
|
||||
assert.ok(contains(value, item), `Expected ${String(value)} to contain ${String(item)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The inverse of assertContains
|
||||
*/
|
||||
function assertNotContains (value: unknown, item: unknown): void {
|
||||
assert.ok(!contains(value, item), `Expected ${String(value)} not to contain ${String(item)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
@@ -269,6 +303,7 @@ export function expect () {
|
||||
toBeDefined: () => assert.ok(value === undefined),
|
||||
toBeNull: (value: unknown) => assert.ok(value !== null),
|
||||
toBeUndefined: () => assert.ok(value !== undefined),
|
||||
toContain: (item: unknown) => assertNotContains(value, item),
|
||||
toEqual: (other: unknown) => containsMatcher(other)
|
||||
? assert.throws(() => assertEqualMatch(value, other))
|
||||
: assert.notDeepEqual(value, other),
|
||||
@@ -287,6 +322,7 @@ export function expect () {
|
||||
toBeNull: (value: unknown) => assert.ok(value === null),
|
||||
toBeTruthy: () => assert.ok(value),
|
||||
toBeUndefined: () => assert.ok(value === undefined),
|
||||
toContain: (item: unknown) => assertContains(value, item),
|
||||
toEqual: (other: unknown) => containsMatcher(other)
|
||||
? assertEqualMatch(value, other)
|
||||
: assert.deepEqual(value, other),
|
||||
|
||||
Reference in new issue
Block a user