import { COMMENT_NODE_NAME, TEXT_NODE_NAME, XmlCommentNode, XmlNode, XmlNodeType, XmlTextNode } from "src/xml"; import { xml, XmlUtils } from "src/xml/xml"; import { parseXml } from "test/testUtils"; import { describe, expect, it } from "vitest"; describe(XmlUtils, () => { describe(xml.parser.serializeNode, () => { it('serializes a simple text node', () => { const node = xml.create.textNode('hello'); const str = xml.parser.serializeNode(node); expect(str).toEqual('hello'); }); it('serializes a text node with null value as an empty string', () => { const node = xml.create.textNode(null); const str = xml.parser.serializeNode(node); expect(str).toEqual(''); }); it('serializes a text node with undefined value as an empty string', () => { const node = xml.create.textNode(undefined); const str = xml.parser.serializeNode(node); expect(str).toEqual(''); }); it('serializes an attribute with quotes', () => { const node = xml.create.generalNode('node'); node.attributes = { att: 'Some "quoted" value.' }; const str = xml.parser.serializeNode(node); expect(str).toEqual(''); }); it('serializes a comment node', () => { const node = xml.create.commentNode('comment'); const str = xml.parser.serializeNode(node); expect(str).toEqual(''); }); it('serializes a node with indentation', () => { const node = parseXml('hello', true); const str = xml.parser.serializeNode(node, { indent: 2 }); expect(str).toEqual('\n hello\n'); }); }); describe(xml.create.fromDomNode, () => { it('creates a valid xml node from a single dom node', () => { const domNode = createDomNode(''); const xmlNode = xml.create.fromDomNode(domNode); expect(xmlNode.nodeName).toEqual('my-node'); expect(xmlNode.nodeType).toEqual(XmlNodeType.General); expect(xmlNode.parentNode).toBeFalsy(); expect(xmlNode.childNodes.length).toEqual(0); expect(xmlNode.nextSibling).toBeFalsy(); }); it('creates a valid xml tree from a dom node with a single child', () => { const domNode = createDomNode(` `, true); const xmlNode = xml.create.fromDomNode(domNode); // root const root = xmlNode; expect(root.nodeName).toEqual('root'); expect(xmlNode.nodeType).toEqual(XmlNodeType.General); expect(root.parentNode).toBeFalsy(); expect(root.childNodes.length).toEqual(1); expect(root.nextSibling).toBeFalsy(); // child const child = root.childNodes[0]; expect(child.nodeName).toEqual('child'); expect(xmlNode.nodeType).toEqual(XmlNodeType.General); expect(child.parentNode).toEqual(root); expect(child.childNodes.length).toEqual(0); expect(child.nextSibling).toBeFalsy(); }); it('creates a valid xml tree from a mixed tree', () => { const domNode = createDomNode(` hi `, true); const xmlNode = xml.create.fromDomNode(domNode); // root const root = xmlNode; expect(root.nodeName).toEqual('root'); expect(root.nodeType).toEqual(XmlNodeType.General); expect(root.parentNode).toBeFalsy(); expect(root.childNodes.length).toEqual(4); expect(root.nextSibling).toBeFalsy(); const comment = root.childNodes[0]; const child1 = root.childNodes[1]; const child2 = root.childNodes[2]; const child3 = root.childNodes[3]; const grandchild1 = root.childNodes[3].childNodes[0]; // comment expect(comment.nodeName).toEqual(COMMENT_NODE_NAME); expect(comment.nodeType).toEqual(XmlNodeType.Comment); expect(comment.parentNode).toEqual(root); expect(comment.childNodes).toBeFalsy(); expect((comment as XmlCommentNode).commentContent).toEqual('comment'); expect(comment.nextSibling).toEqual(child1); // child #1 expect(child1.nodeName).toEqual('child'); expect(child1.nodeType).toEqual(XmlNodeType.General); expect(child1.parentNode).toEqual(root); expect(child1.childNodes.length).toEqual(0); expect(child1.nextSibling).toEqual(child2); // child #2 expect(child2.nodeName).toEqual('child'); expect(child2.nodeType).toEqual(XmlNodeType.General); expect(child2.parentNode).toEqual(root); expect(child2.childNodes.length).toEqual(0); expect(child2.nextSibling).toEqual(child3); // child #3 expect(child3.nodeName).toEqual('other-child'); expect(child3.nodeType).toEqual(XmlNodeType.General); expect(child3.parentNode).toEqual(root); expect(child3.childNodes.length).toEqual(1); expect(child3.nextSibling).toBeFalsy(); // grandchild #3 expect(grandchild1.nodeName).toEqual(TEXT_NODE_NAME); expect(grandchild1.nodeType).toEqual(XmlNodeType.Text); expect(grandchild1.parentNode).toEqual(child3); expect((grandchild1 as XmlTextNode).textContent).toEqual('hi'); expect(grandchild1.childNodes).toBeFalsy(); expect(grandchild1.nextSibling).toBeFalsy(); }); }); describe(xml.modify.insertBefore, () => { it('inserts before an only child', () => { const parent = parseXml(` `, true); const child = parent.childNodes[0]; const newChild: XmlNode = { nodeName: 'new-child', nodeType: XmlNodeType.General }; xml.modify.insertBefore(newChild, child); // parent expect(parent.parentNode).toBeFalsy(); expect(parent.nextSibling).toBeFalsy(); expect(parent.childNodes.length).toEqual(2); expect(parent.childNodes[0]).toEqual(newChild); expect(parent.childNodes[1]).toEqual(child); // child expect(child.parentNode).toEqual(parent); expect(child.childNodes.length).toEqual(0); expect(child.nextSibling).toBeFalsy(); // new child expect(newChild.parentNode).toEqual(parent); expect((newChild.childNodes || []).length).toEqual(0); expect(newChild.nextSibling).toEqual(child); }); }); describe(xml.modify.insertChild, () => { it('inserts into an empty child collection', () => { const parent = parseXml(``, true); const child: XmlNode = { nodeName: 'new-child', nodeType: XmlNodeType.General }; xml.modify.insertChild(parent, child, 0); // parent expect(parent.parentNode).toBeFalsy(); expect(parent.nextSibling).toBeFalsy(); expect(parent.childNodes.length).toEqual(1); expect(parent.childNodes[0]).toEqual(child); // child expect(child.parentNode).toEqual(parent); expect((child.childNodes || []).length).toEqual(0); expect(child.nextSibling).toBeFalsy(); }); }); describe(xml.modify.appendChild, () => { it('appends a child', () => { const parent = parseXml(` `, true); const child = parent.childNodes[0]; const newChild: XmlNode = { nodeName: 'new-child', nodeType: XmlNodeType.General }; xml.modify.appendChild(parent, newChild); // parent expect(parent.parentNode).toBeFalsy(); expect(parent.nextSibling).toBeFalsy(); expect(parent.childNodes.length).toEqual(2); expect(parent.childNodes[0]).toEqual(child); expect(parent.childNodes[1]).toEqual(newChild); // child expect(child.parentNode).toEqual(parent); expect(child.childNodes.length).toEqual(0); expect(child.nextSibling).toEqual(newChild); // new child expect(newChild.parentNode).toEqual(parent); expect((newChild.childNodes || []).length).toEqual(0); expect(newChild.nextSibling).toBeFalsy(); }); }); }); function createDomNode(xmlString: string, removeWhiteSpace = false): Node { if (removeWhiteSpace) // remove all whitespace outside of tags xmlString = xmlString.replace(/>\s+<').trim(); const document = xml.parser.domParse(xmlString); return document.documentElement; }