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');
});
});