const { createXmlTemplaterDocx, expect, getContent, createXmlTemplaterDocxNoRender, } = require("./utils"); describe("XmlTemplater", function () { it("should work with simpleContent", function () { const content = "Hello {name}"; const scope = { name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar"); }); it("should work with doublecontent in w:t", function () { const content = "Hello {name}, you're {age} years old"; const scope = { name: "Edgar", age: "foo" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal( "Hello Edgar, you're foo years old" ); }); it("should work with {.} for this", function () { const content = "Hello {.}"; const scope = "Edgar"; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar"); }); it("should work with {.} for this inside loop", function () { const content = "Hello {#names}{.},{/names}"; const scope = { names: ["Edgar", "John"] }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar,John,"); }); it("should work with non w:t content", function () { const content = "{#loop}Hello {name}{/loop}"; const scope = { loop: { name: "edgar" } }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(getContent(xmlTemplater)).to.be.equal( 'Hello edgar' ); }); it("should handle in loop without error", function () { const content = `{#ab} {.}{/ab}`; const scope = { ab: [1, 2, 3] }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("123"); }); it("should work with tag in two elements", function () { const content = "Hello {name}"; const scope = { name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar"); }); it("should work with splitted tag in three elements", function () { const content = "Hello {name}"; const scope = { name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar"); }); it("should work with simple loop with object value", function () { const content = "Hello {#person}{name}{/person}"; const scope = { person: { name: "Edgar" } }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar"); }); it("should work with simple Loop", function () { const content = "Hello {#names}{name},{/names}"; const scope = { names: [{ name: "Edgar" }, { name: "Mary" }, { name: "John" }], }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar,Mary,John,"); }); it("should work with simple Loop with boolean value truthy", function () { const content = "Hello {#showName}{name},{/showName}"; const scope = { showName: true, name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar,"); }); it("should work with simple Loop with boolean value falsy", function () { const content = "Hello {#showName}{name},{/showName}"; const scope = { showName: false, name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello "); }); it("should work with dash Loop", function () { const content = "Hello {-w:p names}{name},{/names}"; const scope = { names: [{ name: "Edgar" }, { name: "Mary" }, { name: "John" }], }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal( "Hello Edgar,Hello Mary,Hello John," ); }); it("should work with loop and innerContent", function () { const content = '{#loop}{title}Proof that it works nicely :{#proof} It works because {reason}{/proof}{/loop}'; const scope = { loop: { title: "Everyone uses it", proof: [ { reason: "it is quite cheap" }, { reason: "it is quit simple" }, { reason: "it works on a lot of different Hardware" }, ], }, }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal( "Everyone uses itProof that it works nicely : It works because it is quite cheap It works because it is quit simple It works because it works on a lot of different Hardware" ); }); it("should work with loop and innerContent (with last)", function () { const content = '{#loop}Start {title}Proof that it works nicely :{#proof} It works because {reason}{/proof} End{/loop}'; const scope = { loop: { title: "Everyone uses it", proof: [ { reason: "it is quite cheap" }, { reason: "it is quit simple" }, { reason: "it works on a lot of different Hardware" }, ], }, }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal( "Start Everyone uses itProof that it works nicely : It works because it is quite cheap It works because it is quit simple It works because it works on a lot of different Hardware End" ); }); it("should work with not w:t tag (if the for loop is like {#forloop} text {/forloop}) ", function () { const content = "{#loop}Hello {#names}{name},{/names}{/loop}"; const scope = { loop: { names: [{ name: "Edgar" }, { name: "Mary" }, { name: "John" }] }, }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(getContent(xmlTemplater)).to.be.equal( 'Hello Edgar,Mary,John,' ); }); it("should work with delimiter in value", function () { const content = "Hello {name}"; const scope = { name: "{edgar}" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal("Hello {edgar}"); }); it("should work with delimiter in value with loop)", function () { const content = "Hello {#names}{name},{/names}"; const scope = { names: [{ name: "{John}" }, { name: "M}}{ary" }, { name: "Di{{{gory" }], }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal( "Hello {John},M}}{ary,Di{{{gory," ); }); it("should work when replacing with exact same value", function () { const content = 'Hello {name}'; const scope = { name: "{name}" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); xmlTemplater.getFullText(); expect(xmlTemplater.getFullText()).to.be.equal("Hello {name}"); }); it("should work with equations", function () { const content = ` y {bar} * cos⁡ ( {foo} +{baz}) Hello { name } `; const scope = { name: "John", foo: "MyFoo", bar: "MyBar", baz: "MyBaz" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope }); expect(xmlTemplater.getFullText()).to.be.equal( "yMyBar*cos⁡( MyFoo+MyBaz)Hello John" ); }); }); describe("Change the nullGetter", function () { it("should work with null", function () { const content = "Hello {#names}{#foo}{bar}{/foo}{/names}"; function nullGetter(part, scopeManager) { expect(part.value).to.equal("bar"); expect(scopeManager.scopePath).to.deep.equal(["names", "foo"]); expect(scopeManager.scopePathItem).to.deep.equal([0, 0]); return "null"; } const xmlTemplater = createXmlTemplaterDocx(content, { tags: { names: [{ foo: [{}] }], }, nullGetter, }); expect(xmlTemplater.getFullText()).to.be.equal("Hello null"); }); it("should be possible to keep null tags as is", function () { const content = "Hello {name}, your hobby is {hobby}"; function nullGetter(part) { if (!part.module) { return "{" + part.value + "}"; } if (part.module === "rawxml") { return ""; } return ""; } const data = { hobby: "diving", }; const xmlTemplater = createXmlTemplaterDocxNoRender(content, { nullGetter, }); xmlTemplater.compile(); return xmlTemplater.resolveData(data).then(function () { xmlTemplater.render(); expect(xmlTemplater.getFullText()).to.be.equal( "Hello {name}, your hobby is diving" ); }); }); it("should work with null in resolve", function () { const content = "Hello {#names}{#foo}{bar}{/foo}{/names}"; let calls = 0; function nullGetter(part, scopeManager) { calls++; expect(scopeManager.scopePath).to.deep.equal(["names", "foo"]); expect(scopeManager.scopePathItem).to.deep.equal([0, 0]); return "null"; } const data = { names: [{ foo: [{}] }], }; const xmlTemplater = createXmlTemplaterDocxNoRender(content, { nullGetter, }); xmlTemplater.compile(); return xmlTemplater.resolveData(data).then(function () { expect(calls).to.be.equal(1); xmlTemplater.render(); expect(calls).to.be.equal(1); expect(xmlTemplater.getFullText()).to.be.equal("Hello null"); }); }); }); describe("intelligent tagging multiple tables", function () { it("should work with multiple rows", function () { const content = ` {#clauses} Clause {.} {/clauses} `.replace(/\t|\n/g, ""); const scope = { clauses: ["Foo", "Bar", "Baz"] }; const doc = createXmlTemplaterDocx(content, { tags: scope }); const c = getContent(doc); expect(c).to.be.equal( ' Clause Foo Clause Bar Clause Baz' ); }); }); describe("Custom delimiters", function () { it("should work with custom tags", function () { const delimiters = { start: "[", end: "]", }; const content = "Hello [name]"; const scope = { name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope, delimiters, }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar"); }); it("should work with custom delimiters with two chars", function () { const delimiters = { start: "[[", end: "]]", }; const content = "Hello [[name]]"; const scope = { name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope, delimiters, }); expect(xmlTemplater.getFullText()).to.be.eql("Hello Edgar"); }); it("should work with custom delimiters as strings with different length", function () { const delimiters = { start: "[[[", end: "]]", }; const content = "Hello [[[name]]"; const scope = { name: "Edgar" }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope, delimiters, }); expect(xmlTemplater.getFullText()).to.be.eql("Hello Edgar"); }); it("should work with custom tags and loops", function () { const delimiters = { start: "[[[", end: "]]", }; const content = "Hello [[[#names]][[[.]],[[[/names]]"; const scope = { names: ["Edgar", "Mary", "John"] }; const xmlTemplater = createXmlTemplaterDocx(content, { tags: scope, delimiters, }); expect(xmlTemplater.getFullText()).to.be.equal("Hello Edgar,Mary,John,"); }); it("should work with loops", function () { const content = "{#loop}{innertag} {/loop}"; const xmlt = createXmlTemplaterDocx(content, { tags: { loop: [{ innertag: 10 }, { innertag: 5 }] }, }); const c = getContent(xmlt); expect(c).to.be.equal( '10 5 ' ); }); it("should work with complex loops (1)", function () { const content = "{#looptag}{innertag}{/looptag}"; const xmlt = createXmlTemplaterDocx(content, { tags: { looptag: true, innertag: "foo" }, }); const c = getContent(xmlt); expect(c).not.to.contain(""); expect(c).to.be.equal('foo'); }); it("should work with complex loops (2)", function () { const content = "{#person}{name}{/person}"; const xmlt = createXmlTemplaterDocx(content, { tags: { person: [{ name: "Henry" }] }, }); const c = getContent(xmlt); expect(c).to.contain("Henry"); expect(c).not.to.contain("Henry"); }); }); describe("getting parents context", function () { it("should work with simple loops", function () { const content = "{#loop}{name}{/loop}"; const xmlt = createXmlTemplaterDocx(content, { tags: { loop: [1], name: "Henry" }, }); const c = getContent(xmlt); expect(c).to.be.equal('Henry'); }); it("should work with double loops", function () { const content = "{#loop_first}{#loop_second}{name_inner} {name_outer}{/loop_second}{/loop_first}"; const xmlt = createXmlTemplaterDocx(content, { tags: { loop_first: [1], loop_second: [{ name_inner: "John" }], name_outer: "Henry", }, }); const c = getContent(xmlt); expect(c).to.be.equal('John Henry'); }); });