This repository has been archived by the owner on Mar 24, 2022. It is now read-only.
forked from inikulin/parse5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.test.ts
132 lines (111 loc) · 5.48 KB
/
index.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import * as assert from 'node:assert';
import * as parse5 from 'parse5';
import { jest } from '@jest/globals';
import { Parser, ParserOptions } from './index.js';
import type { TreeAdapterTypeMap } from './../tree-adapters/interface.js';
import { generateParsingTests } from 'parse5-test-utils/utils/generate-parsing-tests.js';
import { treeAdapters } from 'parse5-test-utils/utils/common.js';
import { NAMESPACES as NS } from '../common/html.js';
import { isElementNode } from '../tree-adapters/default.js';
const origParseFragment = Parser.prototype.parseFragment;
generateParsingTests('parser', 'Parser', {}, (test, opts) => ({
node: test.fragmentContext
? parse5.parseFragment(test.fragmentContext, test.input, opts)
: parse5.parse(test.input, opts),
}));
describe('parser', () => {
it('Regression - HTML5 Legacy Doctype Misparsed with htmlparser2 tree adapter (GH-45)', () => {
const html = '<!DOCTYPE html SYSTEM "about:legacy-compat"><html><head></head><body>Hi there!</body></html>';
const document = parse5.parse(html, { treeAdapter: treeAdapters.htmlparser2 });
assert.ok(treeAdapters.htmlparser2.isDocumentTypeNode(document.childNodes[0]));
assert.strictEqual(document.childNodes[0].data, '!DOCTYPE html SYSTEM "about:legacy-compat"');
});
describe('Regression - Incorrect arguments fallback for the parser.parseFragment (GH-82, GH-83)', () => {
beforeEach(() => {
Parser.prototype.parseFragment = function <T extends TreeAdapterTypeMap>(
this: Parser<T>,
html: string,
fragmentContext?: T['element']
): { html: string; fragmentContext: T['element'] | null | undefined; options: ParserOptions<T> } {
return {
html,
fragmentContext,
options: this.options,
};
};
});
afterEach(() => {
Parser.prototype.parseFragment = origParseFragment;
});
it('parses correctly', () => {
const fragmentContext = treeAdapters.default.createElement('div', NS.HTML, []);
const html = '<script></script>';
const opts = { sourceCodeLocationInfo: true };
let args: any = parse5.parseFragment(fragmentContext, html, opts);
expect(args).toHaveProperty('fragmentContext', fragmentContext);
expect(args).toHaveProperty('html', html);
assert.ok(args.options.sourceCodeLocationInfo);
args = parse5.parseFragment(html, opts);
assert.ok(!args.fragmentContext);
expect(args).toHaveProperty('html', html);
assert.ok(args.options.sourceCodeLocationInfo);
args = parse5.parseFragment(html);
assert.ok(!args.fragmentContext);
expect(args).toHaveProperty('html', html);
assert.ok(!args.options.sourceCodeLocationInfo);
});
});
describe("Regression - Don't inherit from Object when creating collections (GH-119)", () => {
beforeEach(() => {
/*eslint-disable no-extend-native*/
// @ts-expect-error Adding unknown prototype method
Object.prototype.heyYo = 123;
/*eslint-enable no-extend-native*/
});
afterEach(() => {
// @ts-expect-error Deleting unknown prototype property
delete Object.prototype.heyYo;
});
it('parses correctly', () => {
const fragment = parse5.parseFragment('<div id="123">', {
treeAdapter: treeAdapters.htmlparser2,
});
assert.ok(treeAdapters.htmlparser2.isElementNode(fragment.childNodes[0]));
assert.strictEqual(treeAdapters.htmlparser2.getAttrList(fragment.childNodes[0]).length, 1);
});
});
it('Regression - DOCTYPE empty fields (GH-236)', () => {
const document = parse5.parse('<!DOCTYPE>');
const doctype = document.childNodes[0];
expect(doctype).toHaveProperty('name', '');
expect(doctype).toHaveProperty('publicId', '');
expect(doctype).toHaveProperty('systemId', '');
});
describe('Tree adapters', () => {
it('should support onItemPush and onItemPop', () => {
const onItemPush = jest.fn();
const onItemPop = jest.fn();
const document = parse5.parse('<p><p>', {
treeAdapter: {
...treeAdapters.default,
onItemPush,
onItemPop,
},
});
const htmlElement = document.childNodes[0];
assert.ok(isElementNode(htmlElement));
const bodyElement = htmlElement.childNodes[1];
assert.ok(isElementNode(bodyElement));
// Expect 5 opened elements; in order: html, head, body, and 2x p
expect(onItemPush).toHaveBeenCalledTimes(5);
expect(onItemPush).toHaveBeenNthCalledWith(1, htmlElement);
expect(onItemPush).toHaveBeenNthCalledWith(3, bodyElement);
// The last opened element is the second p
expect(onItemPush).toHaveBeenLastCalledWith(bodyElement.childNodes[1]);
// The second p isn't closed, plus we never pop body and html. Alas, only 2 pop events (head and p).
expect(onItemPop).toHaveBeenCalledTimes(2);
// The last pop event should be the first p.
expect(onItemPop).toHaveBeenLastCalledWith(bodyElement.childNodes[0], bodyElement);
});
});
});