140 lines
3.6 KiB
JavaScript
140 lines
3.6 KiB
JavaScript
import { expect } from 'chai';
|
|
import { it } from 'mocha';
|
|
import * as parse5 from 'parse5';
|
|
import { traverseHtml } from '../../../src/program/utils/traverse-html.js';
|
|
|
|
function getId(p5Path) {
|
|
return p5Path.node.attrs.find(a => a.name === 'id').value;
|
|
}
|
|
|
|
describe('traverseHtml', () => {
|
|
it('finds different tag names', async () => {
|
|
const htmlCode = `
|
|
<div id="a-lvl1">
|
|
<span id="a-lvl2">
|
|
<my-tag id="a-lvl3">
|
|
<not-found></notfound>
|
|
</my-tag>
|
|
</span>
|
|
</div>
|
|
<div id="b"></div>
|
|
`;
|
|
|
|
const ast = parse5.parseFragment(htmlCode);
|
|
const foundDivs = [];
|
|
const foundSpans = [];
|
|
const foundMyTags = [];
|
|
|
|
traverseHtml(ast, {
|
|
div(p5Path) {
|
|
foundDivs.push(getId(p5Path));
|
|
},
|
|
span(p5Path) {
|
|
foundSpans.push(getId(p5Path));
|
|
},
|
|
// eslint-disable-next-line object-shorthand
|
|
'my-tag'(p5Path) {
|
|
foundMyTags.push(getId(p5Path));
|
|
},
|
|
});
|
|
|
|
expect(foundDivs).to.deep.equal(['a-lvl1', 'b']);
|
|
expect(foundSpans).to.deep.equal(['a-lvl2']);
|
|
expect(foundMyTags).to.deep.equal(['a-lvl3']);
|
|
});
|
|
|
|
it('traverses different levels in DOM order', async () => {
|
|
const htmlCode = `
|
|
<div id="a-lvl1">
|
|
<span id="a-lvl2">
|
|
<my-tag id="a-lvl3">
|
|
<not-found></notfound>
|
|
</my-tag>
|
|
</span>
|
|
</div>
|
|
<div id="b"></div>
|
|
`;
|
|
|
|
const ast = parse5.parseFragment(htmlCode);
|
|
const callOrder = [];
|
|
const processObj = {
|
|
span(p5Path) {
|
|
callOrder.push(`span#${getId(p5Path)}`);
|
|
},
|
|
div(p5Path) {
|
|
callOrder.push(`div#${getId(p5Path)}`);
|
|
},
|
|
// eslint-disable-next-line object-shorthand
|
|
'my-tag'(p5Path) {
|
|
callOrder.push(`my-tag#${getId(p5Path)}`);
|
|
},
|
|
};
|
|
traverseHtml(ast, processObj);
|
|
|
|
// call order based on dom tree
|
|
expect(callOrder).to.deep.equal(['div#a-lvl1', 'span#a-lvl2', 'my-tag#a-lvl3', 'div#b']);
|
|
});
|
|
|
|
it('allows to stop traversal (for performance)', async () => {
|
|
const htmlCode = `
|
|
<div id="a-lvl1">
|
|
<span id="a-lvl2">
|
|
<my-tag id="a-lvl3">
|
|
<not-found></notfound>
|
|
</my-tag>
|
|
</span>
|
|
</div>
|
|
<div id="b"></div>
|
|
`;
|
|
|
|
const ast = parse5.parseFragment(htmlCode);
|
|
const callOrder = [];
|
|
const processObj = {
|
|
div(p5Path) {
|
|
callOrder.push(`div#${getId(p5Path)}`);
|
|
p5Path.stop();
|
|
},
|
|
span(p5Path) {
|
|
callOrder.push(`span#${getId(p5Path)}`);
|
|
},
|
|
// eslint-disable-next-line object-shorthand
|
|
'my-tag'(p5Path) {
|
|
callOrder.push(`my-tag#${getId(p5Path)}`);
|
|
},
|
|
};
|
|
traverseHtml(ast, processObj);
|
|
|
|
expect(callOrder).to.deep.equal(['div#a-lvl1']);
|
|
});
|
|
|
|
it('allows to traverse within a path', async () => {
|
|
const htmlCode = `
|
|
<div id="a-lvl1">
|
|
<span id="a-lvl2">
|
|
<my-tag id="a-lvl3">
|
|
<not-found id="a-lvl4"></notfound>
|
|
</my-tag>
|
|
</span>
|
|
</div>
|
|
<div id="b"></div>
|
|
`;
|
|
|
|
const ast = parse5.parseFragment(htmlCode);
|
|
const callOrder = [];
|
|
const processObj = {
|
|
// eslint-disable-next-line object-shorthand
|
|
'my-tag'(p5Path) {
|
|
callOrder.push(`my-tag#${getId(p5Path)}`);
|
|
p5Path.traverseHtml({
|
|
// eslint-disable-next-line object-shorthand, no-shadow
|
|
'not-found'(p5Path) {
|
|
callOrder.push(`not-found#${getId(p5Path)}`);
|
|
},
|
|
});
|
|
},
|
|
};
|
|
traverseHtml(ast, processObj);
|
|
|
|
expect(callOrder).to.deep.equal(['my-tag#a-lvl3', 'not-found#a-lvl4']);
|
|
});
|
|
});
|