Skip to content

Commit 638d53e

Browse files
fb55jmbpwtw
authored andcommitted
refactor: Make location info parser tests work (inikulin#440)
1 parent b2540d1 commit 638d53e

File tree

4 files changed

+49
-44
lines changed

4 files changed

+49
-44
lines changed

packages/parse5-htmlparser2-tree-adapter/lib/index.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,7 @@ export function getTemplateContent(templateElement: Element): Document {
104104
return templateElement.children[0] as Document;
105105
}
106106

107-
export function setDocumentType(
108-
document: Document,
109-
name: string | null,
110-
publicId: string | null,
111-
systemId: string | null
112-
): void {
107+
export function setDocumentType(document: Document, name: string, publicId: string, systemId: string): void {
113108
const data = doctype.serializeContent(name, publicId, systemId);
114109
let doctypeNode = document.children.find(
115110
(node): node is ProcessingInstruction => isDirective(node) && node.name === '!doctype'

packages/parse5/lib/common/doctype.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export function getDocumentMode(token: DoctypeToken): DOCUMENT_MODE {
140140
return DOCUMENT_MODE.NO_QUIRKS;
141141
}
142142

143-
export function serializeContent(name: string | null, publicId: string | null, systemId: string | null): string {
143+
export function serializeContent(name: string, publicId: string, systemId: string): string {
144144
let str = '!DOCTYPE ';
145145

146146
if (name) {
@@ -153,7 +153,7 @@ export function serializeContent(name: string | null, publicId: string | null, s
153153
str += ' SYSTEM';
154154
}
155155

156-
if (systemId !== null) {
156+
if (systemId) {
157157
str += ` ${enquoteDoctypeId(systemId)}`;
158158
}
159159

packages/parse5/lib/serializer/index.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,11 @@ export function serialize<T extends TreeAdapterTypeMap = DefaultTreeAdapter.Defa
106106
* @param options Serialization options.
107107
*/
108108
export function serializeOuter<T extends TreeAdapterTypeMap = DefaultTreeAdapter.DefaultTreeAdapterMap>(
109-
node: T['element'],
109+
node: T['node'],
110110
options?: SerializerOptions<T>
111111
): string {
112112
const opts = { ...defaultOpts, ...options };
113-
return serializeElement(node, opts);
113+
return serializeNode(node, opts);
114114
}
115115

116116
function serializeChildNodes<T extends TreeAdapterTypeMap>(
@@ -129,21 +129,30 @@ function serializeChildNodes<T extends TreeAdapterTypeMap>(
129129

130130
if (childNodes) {
131131
for (const currentNode of childNodes) {
132-
if (options.treeAdapter.isElementNode(currentNode)) {
133-
html += serializeElement(currentNode, options);
134-
} else if (options.treeAdapter.isTextNode(currentNode)) {
135-
html += serializeTextNode(currentNode, options);
136-
} else if (options.treeAdapter.isCommentNode(currentNode)) {
137-
html += serializeCommentNode(currentNode, options);
138-
} else if (options.treeAdapter.isDocumentTypeNode(currentNode)) {
139-
html += serializeDocumentTypeNode(currentNode, options);
140-
}
132+
html += serializeNode(currentNode, options);
141133
}
142134
}
143135

144136
return html;
145137
}
146138

139+
function serializeNode<T extends TreeAdapterTypeMap>(node: T['node'], options: InternalOptions<T>): string {
140+
if (options.treeAdapter.isElementNode(node)) {
141+
return serializeElement(node, options);
142+
}
143+
if (options.treeAdapter.isTextNode(node)) {
144+
return serializeTextNode(node, options);
145+
}
146+
if (options.treeAdapter.isCommentNode(node)) {
147+
return serializeCommentNode(node, options);
148+
}
149+
if (options.treeAdapter.isDocumentTypeNode(node)) {
150+
return serializeDocumentTypeNode(node, options);
151+
}
152+
// Return an empty string for unknown nodes
153+
return '';
154+
}
155+
147156
function serializeElement<T extends TreeAdapterTypeMap>(node: T['element'], options: InternalOptions<T>): string {
148157
const tn = options.treeAdapter.getTagName(node);
149158

test/utils/generate-location-info-parser-tests.ts

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { TreeAdapter, TreeAdapterTypeMap } from 'parse5/dist/tree-adapters/inter
44
import * as assert from 'node:assert';
55
import * as fs from 'node:fs';
66
import * as path from 'node:path';
7-
import { escapeString } from 'parse5/dist/serializer/index.js';
87
import * as parse5 from 'parse5/dist/index.js';
98
import {
109
removeNewLines,
@@ -13,22 +12,19 @@ import {
1312
normalizeNewLine,
1413
generateTestsForEachTreeAdapter,
1514
} from './common.js';
15+
import * as doctype from 'parse5/dist/common/doctype.js';
1616

1717
function walkTree<T extends TreeAdapterTypeMap>(
18-
document: T['document'],
18+
parent: T['parentNode'],
1919
treeAdapter: TreeAdapter<T>,
2020
handler: (node: T['node']) => void
2121
): void {
22-
const stack = [...treeAdapter.getChildNodes(document)];
23-
let node;
24-
while ((node = stack.shift())) {
25-
const children = treeAdapter.getChildNodes(node);
22+
for (const node of treeAdapter.getChildNodes(parent)) {
23+
if (treeAdapter.isElementNode(node)) {
24+
walkTree(node, treeAdapter, handler);
25+
}
2626

2727
handler(node);
28-
29-
if (children?.length) {
30-
stack.unshift(...children);
31-
}
3228
}
3329
}
3430

@@ -75,7 +71,10 @@ function assertAttrsLocation(location: ElementLocation, serializedNode: string,
7571
assert.ok(location.attrs, 'Expected attrs to be defined');
7672

7773
for (const attr of Object.values(location.attrs)) {
78-
const expected = serializedNode.slice(attr.startOffset, attr.endOffset);
74+
const expected = serializedNode.slice(
75+
attr.startOffset - location.startOffset,
76+
attr.endOffset - location.startOffset
77+
);
7978

8079
assertLocation(attr, expected, html, lines);
8180
}
@@ -113,42 +112,44 @@ export function generateLocationInfoParserTests(
113112
//Then for each node in the tree we run the serializer and compare results with the substring
114113
//obtained via the location info from the expected serialization results.
115114
it(`Location info (Parser) - ${test.name}`, async () => {
116-
const serializerOpts = { treeAdapter };
117-
const html = escapeString(test.data);
115+
const html = test.data;
118116
const lines = html.split(/\r?\n/g);
119117

120118
const parserOpts = {
121119
treeAdapter,
122120
sourceCodeLocationInfo: true,
123121
};
124122

125-
const parsingResult = await parse(html, parserOpts);
123+
const parsingResult = parse(html, parserOpts);
126124
const document = parsingResult.node;
127125

128126
walkTree(document, treeAdapter, (node) => {
129127
const location = treeAdapter.getNodeSourceCodeLocation(node);
130128

131-
if (location) {
132-
const fragment = treeAdapter.createDocumentFragment();
129+
assert.ok(location);
133130

134-
treeAdapter.appendChild(fragment, node);
131+
const serializedNode = treeAdapter.isDocumentTypeNode(node)
132+
? `<${doctype.serializeContent(
133+
treeAdapter.getDocumentTypeNodeName(node),
134+
treeAdapter.getDocumentTypeNodePublicId(node),
135+
treeAdapter.getDocumentTypeNodeSystemId(node)
136+
)}>`
137+
: parse5.serializeOuter(node, { treeAdapter });
135138

136-
const serializedNode = parse5.serialize(fragment, serializerOpts);
139+
assertLocation(location, serializedNode, html, lines);
137140

138-
assertNodeLocation(location, serializedNode, html, lines);
139-
140-
// TODO: None of the cases below are ever matched.
141-
142-
if (location.startTag) {
143-
assertStartTagLocation(location, serializedNode, html, lines);
144-
}
141+
if (treeAdapter.isElementNode(node)) {
142+
assertStartTagLocation(location, serializedNode, html, lines);
145143

146144
if (location.endTag) {
147145
assertEndTagLocation(location, serializedNode, html, lines);
148146
}
149147

150148
if (location.attrs) {
151149
assertAttrsLocation(location, serializedNode, html, lines);
150+
} else {
151+
// If we don't have `location.attrs`, we expect that the node has no attributes.
152+
assert.strictEqual(treeAdapter.getAttrList(node).length, 0);
152153
}
153154
}
154155
});

0 commit comments

Comments
 (0)