1081 lines
44 KiB
JavaScript
1081 lines
44 KiB
JavaScript
"use strict";
|
|
|
|
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
var _require = require("lodash"),
|
|
assign = _require.assign;
|
|
var expressionParser = require("../../expressions.js");
|
|
var expressionParserIE11 = require("../../expressions-ie11.js");
|
|
var Docxtemplater = require("../../docxtemplater.js");
|
|
var _require2 = require("../../utils.js"),
|
|
last = _require2.last;
|
|
var _require3 = require("../utils.js"),
|
|
createDocV4 = _require3.createDocV4,
|
|
createXmlTemplaterDocx = _require3.createXmlTemplaterDocx,
|
|
expect = _require3.expect,
|
|
expectToThrowSnapshot = _require3.expectToThrowSnapshot,
|
|
getContent = _require3.getContent,
|
|
getZip = _require3.getZip,
|
|
paragraph = _require3.paragraph,
|
|
cell = _require3.cell,
|
|
captureLogs = _require3.captureLogs;
|
|
var inspectModule = require("../../inspect-module.js");
|
|
describe("Loading", function () {
|
|
describe("ajax done correctly", function () {
|
|
it("should have the right number of files (the docx unzipped)", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
expect(Object.keys(doc.zip.files).length).to.be.equal(16);
|
|
});
|
|
});
|
|
describe("basic loading", function () {
|
|
it("should load file tag-example.docx", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
expect(_typeof(doc)).to.be.equal("object");
|
|
});
|
|
});
|
|
describe("output and input", function () {
|
|
it("should be the same", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
var output = doc.toBase64();
|
|
expect(output.length).to.be.equal(22808);
|
|
expect(output.substr(0, 50)).to.be.equal("UEsDBAoAAAAIAAAAIQAMTxYSigEAAJYHAAATAAAAW0NvbnRlbn");
|
|
});
|
|
});
|
|
});
|
|
describe("Zip output", function () {
|
|
if (typeof window === "undefined") {
|
|
it("should work with toBuffer and also verify that the fileorder contains [Content_Types].xml and _rels/.rels in first characters", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
doc.render({});
|
|
var buf = doc.toBuffer();
|
|
expect(buf).to.be["instanceof"](Buffer);
|
|
|
|
// Work on a copy to preserve the original buffer
|
|
var sanitizedBuf = Buffer.from(buf);
|
|
|
|
// Replace ZIP local file headers with PK@@ to stabilize snapshot
|
|
var HEADER_SIG = Buffer.from("504b0304", "hex"); // "PK\x03\x04"
|
|
var offset = 0;
|
|
while (offset < sanitizedBuf.length) {
|
|
var idx = sanitizedBuf.indexOf(HEADER_SIG, offset);
|
|
if (idx === -1) {
|
|
break;
|
|
}
|
|
|
|
// Zero out mod time + date
|
|
sanitizedBuf.writeUInt16LE(0, idx + 8);
|
|
sanitizedBuf.writeUInt16LE(0, idx + 10);
|
|
|
|
/*
|
|
* Overwrite the 30-byte header with 'PK@@' followed by 26 dashes
|
|
* This ensures exact replacement without affecting filename
|
|
*/
|
|
sanitizedBuf.write("PK@@--------------------------", idx, 30, "ascii");
|
|
offset = idx + 30;
|
|
}
|
|
|
|
// Now convert to safe printable string for snapshot testing
|
|
var allChars = sanitizedBuf.toString().replace(/[^@a-zA-Z_1-9[\]./-]/g, "-");
|
|
|
|
// Get first ~1KB for snapshot
|
|
var firstChars = allChars.slice(0, 1100);
|
|
expect(firstChars).to.matchSnapshot();
|
|
|
|
// Check that expected files appear in expected order
|
|
var expectedFiles = ["[Content_Types].xml", "_rels/.rels", "word/_rels/document.xml.rels", "word/document.xml", "word/footnotes.xml", "word/endnotes.xml", "word/header1.xml", "word/footer1.xml", "word/theme/theme1.xml", "word/settings.xml", "word/webSettings.xml", "word/stylesWithEffects.xml", "word/fontTable.xml", "docProps/core.xml", "word/styles.xml", "docProps/app.xml"];
|
|
expect(expectedFiles.map(function (file) {
|
|
return allChars.indexOf(file);
|
|
})).to.deep.equal([30, 445, 708, 1094, 1741, 2233, 2764, 6425, 7028, 8678, 9677, 9956, 11905, 14516, 12426, 14861]);
|
|
});
|
|
}
|
|
it("should work with toBlob", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
doc.render({});
|
|
var buf = doc.toBlob();
|
|
expect(buf).to.be["instanceof"](Blob);
|
|
});
|
|
it("should work with toBase64", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
doc.render({});
|
|
var buf = doc.toBase64();
|
|
expect(buf).to.be.a("string");
|
|
});
|
|
it("should work with toUint8Array", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
doc.render({});
|
|
var buf = doc.toUint8Array();
|
|
expect(buf).to.be["instanceof"](Uint8Array);
|
|
});
|
|
it("should work with toArrayBuffer", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
doc.render({});
|
|
var buf = doc.toArrayBuffer();
|
|
expect(buf).to.be["instanceof"](ArrayBuffer);
|
|
});
|
|
});
|
|
describe("Retrieving text content", function () {
|
|
it("should work for the footer", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
expect(doc.getFullText("word/footer1.xml")).to.be.equal("{last_name}{first_name}{phone}");
|
|
});
|
|
it("should work for the document", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
expect(doc.getFullText()).to.be.equal("{last_name} {first_name}");
|
|
});
|
|
});
|
|
describe("Retrieving list of templated files", function () {
|
|
it("should return 6 templatedFiles for a simple document", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
var templatedFiles = doc.getTemplatedFiles();
|
|
expect(templatedFiles).to.be.eql(["word/settings.xml", "docProps/core.xml", "docProps/app.xml", "word/header1.xml", "word/document.xml", "word/footer1.xml", "word/footnotes.xml"]);
|
|
});
|
|
});
|
|
describe("Api versioning", function () {
|
|
it("should work with valid numbers", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
expect(doc.verifyApiVersion("3.6.0")).to.be.equal(true);
|
|
expect(doc.verifyApiVersion("3.5.0")).to.be.equal(true);
|
|
expect(doc.verifyApiVersion("3.4.2")).to.be.equal(true);
|
|
expect(doc.verifyApiVersion("3.4.22")).to.be.equal(true);
|
|
});
|
|
it("should fail with invalid versions", function () {
|
|
var doc = createDocV4("tag-example.docx");
|
|
expectToThrowSnapshot(function () {
|
|
return doc.verifyApiVersion("5.0");
|
|
});
|
|
expectToThrowSnapshot(function () {
|
|
return doc.verifyApiVersion("5.6.0");
|
|
});
|
|
expectToThrowSnapshot(function () {
|
|
return doc.verifyApiVersion("3.48.0");
|
|
});
|
|
expectToThrowSnapshot(function () {
|
|
return doc.verifyApiVersion("3.47.100");
|
|
});
|
|
});
|
|
});
|
|
describe("Docxtemplater loops", function () {
|
|
it("should replace all the tags", function () {
|
|
var doc = createDocV4("tag-loop-example.docx");
|
|
doc.render({
|
|
nom: "Hipp",
|
|
prenom: "Edgar",
|
|
telephone: "0652455478",
|
|
description: "New Website",
|
|
offre: [{
|
|
titre: "titre1",
|
|
prix: "1260"
|
|
}, {
|
|
titre: "titre2",
|
|
prix: "2000"
|
|
}, {
|
|
titre: "titre3",
|
|
prix: "1400",
|
|
nom: "Offre"
|
|
}]
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Votre proposition commercialeHippPrix: 1260Titre titre1HippPrix: 2000Titre titre2OffrePrix: 1400Titre titre3HippEdgar");
|
|
});
|
|
it("should work with loops inside loops", function () {
|
|
var tags = {
|
|
products: [{
|
|
title: "Microsoft",
|
|
name: "DOS",
|
|
reference: "Win7",
|
|
avantages: [{
|
|
title: "Everyone uses it",
|
|
proof: [{
|
|
reason: "it is quite cheap"
|
|
}, {
|
|
reason: "it is quit simple"
|
|
}, {
|
|
reason: "it works on a lot of different Hardware"
|
|
}]
|
|
}]
|
|
}, {
|
|
title: "Linux",
|
|
name: "Ubuntu",
|
|
reference: "Ubuntu10",
|
|
avantages: [{
|
|
title: "It's very powerful",
|
|
proof: [{
|
|
reason: "the terminal is your friend"
|
|
}, {
|
|
reason: "Hello world"
|
|
}, {
|
|
reason: "it's free"
|
|
}]
|
|
}]
|
|
}, {
|
|
title: "Apple",
|
|
name: "Mac",
|
|
reference: "OSX",
|
|
avantages: [{
|
|
title: "It's very easy",
|
|
proof: [{
|
|
reason: "you can do a lot just with the mouse"
|
|
}, {
|
|
reason: "It's nicely designed"
|
|
}]
|
|
}]
|
|
}]
|
|
};
|
|
var doc = createDocV4("tag-product-loop.docx");
|
|
doc.render(tags);
|
|
var text = doc.getFullText();
|
|
var expectedText = "MicrosoftProduct name : DOSProduct reference : Win7Everyone 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 HardwareLinuxProduct name : UbuntuProduct reference : Ubuntu10It's very powerfulProof that it works nicely : It works because the terminal is your friend It works because Hello world It works because it's freeAppleProduct name : MacProduct reference : OSXIt's very easyProof that it works nicely : It works because you can do a lot just with the mouse It works because It's nicely designed";
|
|
expect(text.length).to.be.equal(expectedText.length);
|
|
expect(text).to.be.equal(expectedText);
|
|
});
|
|
it("should work with object value", function () {
|
|
var content = "<w:t>{#todo}{todo}{/todo}</w:t>";
|
|
var expectedContent = '<w:t xml:space="preserve">abc</w:t>';
|
|
var scope = {
|
|
todo: {
|
|
todo: "abc"
|
|
}
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
expect(getContent(xmlTemplater)).to.be.deep.equal(expectedContent);
|
|
});
|
|
it("should work with string value", function () {
|
|
var content = "<w:t>{#todo}{todo}{/todo}</w:t>";
|
|
var expectedContent = '<w:t xml:space="preserve">abc</w:t>';
|
|
var scope = {
|
|
todo: "abc"
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(xmlTemplater);
|
|
expect(c).to.be.deep.equal(expectedContent);
|
|
});
|
|
it("should not have sideeffects with inverted with array length 3", function () {
|
|
var content = "<w:t>{^todos}No {/todos}Todos</w:t>\n<w:t>{#todos}{.}{/todos}</w:t>";
|
|
var expectedContent = "<w:t xml:space=\"preserve\">Todos</w:t>\n<w:t xml:space=\"preserve\">ABC</w:t>";
|
|
var scope = {
|
|
todos: ["A", "B", "C"]
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(xmlTemplater);
|
|
expect(c).to.be.deep.equal(expectedContent);
|
|
});
|
|
it("should not have sideeffects with inverted with empty array", function () {
|
|
var content = "<w:t>{^todos}No {/todos}Todos</w:t>\n\t\t<w:t>{#todos}{.}{/todos}</w:t>";
|
|
var expectedContent = "<w:t xml:space=\"preserve\">No Todos</w:t>\n\t\t<w:t/>";
|
|
var scope = {
|
|
todos: []
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(xmlTemplater);
|
|
expect(c).to.be.deep.equal(expectedContent);
|
|
});
|
|
it("should provide inverted loops", function () {
|
|
var content = "<w:t>{^products}No products found{/products}</w:t>";
|
|
var samplesEmpty = [{
|
|
products: []
|
|
}, {
|
|
products: false
|
|
}, {}];
|
|
for (var _i2 = 0; _i2 < samplesEmpty.length; _i2++) {
|
|
var tags = samplesEmpty[_i2];
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: tags
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("No products found");
|
|
}
|
|
var samples = [{
|
|
products: [{
|
|
name: "Bread"
|
|
}]
|
|
}, {
|
|
products: true
|
|
}, {
|
|
products: "Bread"
|
|
}, {
|
|
products: {
|
|
name: "Bread"
|
|
}
|
|
}];
|
|
for (var _i4 = 0; _i4 < samples.length; _i4++) {
|
|
var _tags = samples[_i4];
|
|
var _doc = createXmlTemplaterDocx(content, {
|
|
tags: _tags
|
|
});
|
|
expect(_doc.getFullText()).to.be.equal("");
|
|
}
|
|
});
|
|
it("should be possible to close loops with {/}", function () {
|
|
var content = "<w:t>{#products}Product {name}{/}</w:t>";
|
|
var tags = {
|
|
products: [{
|
|
name: "Bread"
|
|
}]
|
|
};
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: tags
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Product Bread");
|
|
});
|
|
it("should be possible to close double loops with {/}", function () {
|
|
var content = "<w:t>{#companies}{#products}Product {name}{/}{/}</w:t>";
|
|
var tags = {
|
|
companies: [{
|
|
products: [{
|
|
name: "Bread"
|
|
}]
|
|
}]
|
|
};
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: tags
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Product Bread");
|
|
});
|
|
it("should work with complex loops", function () {
|
|
var content = "<w:t>{title} {#users} {name} friends are : {#friends} {.</w:t>TAG..TAG<w:t>},{/friends} {/users</w:t>TAG2<w:t>}</w:t>";
|
|
var scope = {
|
|
title: "###Title###",
|
|
users: [{
|
|
name: "John Doe",
|
|
friends: ["Jane", "Henry"]
|
|
}, {}],
|
|
name: "Default",
|
|
friends: ["None"]
|
|
};
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("###Title### John Doe friends are : Jane, Henry, Default friends are : None, ");
|
|
});
|
|
});
|
|
describe("Changing the parser", function () {
|
|
it("should work with uppercassing", function () {
|
|
var content = "<w:t>Hello {name}</w:t>";
|
|
var scope = {
|
|
name: "Edgar"
|
|
};
|
|
function parser(tag) {
|
|
return _defineProperty({}, "get", function get(scope) {
|
|
return scope[tag].toUpperCase();
|
|
});
|
|
}
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
parser: parser
|
|
});
|
|
expect(xmlTemplater.getFullText()).to.be.equal("Hello EDGAR");
|
|
});
|
|
it("should work when setting from the Docxtemplater interface", function () {
|
|
var doc = createDocV4("tag-example.docx", {
|
|
parser: function parser(tag) {
|
|
return _defineProperty({}, "get", function get(scope) {
|
|
return scope[tag].toUpperCase();
|
|
});
|
|
}
|
|
});
|
|
doc.render({
|
|
first_name: "Hipp",
|
|
last_name: "Edgar",
|
|
phone: "0652455478",
|
|
description: "New Website"
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("EDGAR HIPP");
|
|
expect(doc.getFullText("word/header1.xml")).to.be.equal("EDGAR HIPP0652455478NEW WEBSITE");
|
|
expect(doc.getFullText("word/footer1.xml")).to.be.equal("EDGARHIPP0652455478");
|
|
});
|
|
it("should work with expression parser", function () {
|
|
var tags = {
|
|
person: {
|
|
first_name: "Hipp",
|
|
last_name: "Edgar",
|
|
birth_year: 1955,
|
|
age: 59
|
|
}
|
|
};
|
|
var doc = createDocV4("angular-example.docx", {
|
|
parser: expressionParser
|
|
});
|
|
doc.render(tags);
|
|
expect(doc.getFullText()).to.be.equal("Hipp Edgar 2014");
|
|
});
|
|
it("should work with loops", function () {
|
|
var content = "<w:t>Hello {#person.adult}you{/person.adult}</w:t>";
|
|
var scope = {
|
|
person: {
|
|
name: "Edgar",
|
|
adult: true
|
|
}
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
parser: expressionParser
|
|
});
|
|
expect(xmlTemplater.getFullText()).to.be.equal("Hello you");
|
|
});
|
|
it("should work with loops with expressionParser for ie 11", function () {
|
|
var content = "<w:t>Hello {#person.adult}you{/person.adult}</w:t>";
|
|
var scope = {
|
|
person: {
|
|
name: "Edgar",
|
|
adult: true
|
|
}
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
parser: expressionParserIE11
|
|
});
|
|
expect(xmlTemplater.getFullText()).to.be.equal("Hello you");
|
|
});
|
|
it("should be able to access meta to get the index", function () {
|
|
var content = "<w:t>Hello {#users}{$index} {#$isFirst}@{/}{#$isLast}!{/}{name} {/users}</w:t>";
|
|
var scope = {
|
|
users: [{
|
|
name: "Jane"
|
|
}, {
|
|
name: "Mary"
|
|
}]
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
parser: function parser(tag) {
|
|
return {
|
|
get: function get(scope, context) {
|
|
if (tag === "$index") {
|
|
return last(context.scopePathItem);
|
|
}
|
|
if (tag === "$isLast") {
|
|
var totalLength = context.scopePathLength[context.scopePathLength.length - 1];
|
|
var index = context.scopePathItem[context.scopePathItem.length - 1];
|
|
return index === totalLength - 1;
|
|
}
|
|
if (tag === "$isFirst") {
|
|
var _index = context.scopePathItem[context.scopePathItem.length - 1];
|
|
return _index === 0;
|
|
}
|
|
return scope[tag];
|
|
}
|
|
};
|
|
}
|
|
});
|
|
expect(xmlTemplater.getFullText()).to.be.equal("Hello 0 @Jane 1 !Mary ");
|
|
});
|
|
it("should be able to disable parent scope inheritance", function () {
|
|
var content = "<w:t>Hello {#users}{companyName}-{name} {/}</w:t>";
|
|
var scope = {
|
|
users: [{
|
|
name: "Jane"
|
|
}, {}],
|
|
companyName: "My company, should not be shown",
|
|
name: "Foo"
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
nullGetter: function nullGetter(part) {
|
|
if (!part.module) {
|
|
return "NULL";
|
|
}
|
|
if (part.module === "rawxml") {
|
|
return "";
|
|
}
|
|
return "";
|
|
},
|
|
parser: function parser(tag) {
|
|
return {
|
|
get: function get(scope, context) {
|
|
if (context.num < context.scopePath.length) {
|
|
return null;
|
|
}
|
|
if (context.num > context.scopePath.length) {
|
|
throw new Error("Invalid context num");
|
|
}
|
|
return scope[tag];
|
|
}
|
|
};
|
|
}
|
|
});
|
|
expect(xmlTemplater.getFullText()).to.be.equal("Hello NULL-Jane NULL-NULL ");
|
|
});
|
|
it("should be able to retrieve parent scope with .. syntax and ... syntax", function () {
|
|
var content = "<w:t>{#loop}{#contractors}{...company} {..company} {company} {/}{/loop}</w:t>";
|
|
var tags = {
|
|
company: "Root company",
|
|
loop: [{
|
|
company: "ACME Company",
|
|
contractors: [{
|
|
company: "The other Company"
|
|
}, {
|
|
company: "Foobar Company"
|
|
}]
|
|
}]
|
|
};
|
|
var options = {
|
|
parser: function parser(tag) {
|
|
var matchesParent = /^(\.{2,})(.*)/g;
|
|
var parentCount = 0;
|
|
if (matchesParent.test(tag)) {
|
|
parentCount = tag.replace(matchesParent, "$1").length - 1;
|
|
tag = tag.replace(matchesParent, "$2");
|
|
}
|
|
return {
|
|
get: function get(scope, context) {
|
|
if (context.scopePath.length - context.num < parentCount) {
|
|
return null;
|
|
}
|
|
return scope[tag];
|
|
}
|
|
};
|
|
},
|
|
tags: tags
|
|
};
|
|
var doc = createXmlTemplaterDocx(content, options);
|
|
expect(doc.getFullText()).to.be.equal("Root company ACME Company The other Company Root company ACME Company Foobar Company ");
|
|
});
|
|
it("should be able to have scopePathItem with different lengths when having conditions", function () {
|
|
var content = "<w:t>{#cond}{name}{/}</w:t>";
|
|
var scope = {
|
|
cond: true,
|
|
name: "John"
|
|
};
|
|
var innerContext = null;
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
parser: function parser(tag) {
|
|
return {
|
|
get: function get(scope, context) {
|
|
if (tag === "name") {
|
|
innerContext = context;
|
|
}
|
|
return scope[tag];
|
|
}
|
|
};
|
|
}
|
|
});
|
|
expect(xmlTemplater.getFullText()).to.be.equal("John");
|
|
expect(innerContext.scopePath).to.be.deep.equal(["cond"]);
|
|
expect(innerContext.scopePathItem).to.be.deep.equal([0]);
|
|
expect(innerContext.scopeList.length).to.be.equal(2);
|
|
expect(innerContext.scopeList[0]).to.be.deep.equal(innerContext.scopeList[1]);
|
|
});
|
|
it("should call the parser just once", function () {
|
|
var calls = 0;
|
|
var content = "<w:t>{name}</w:t>";
|
|
var scope = {
|
|
name: "John"
|
|
};
|
|
createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
parser: function parser(tag) {
|
|
return {
|
|
get: function get(scope) {
|
|
calls++;
|
|
return scope[tag];
|
|
}
|
|
};
|
|
}
|
|
});
|
|
expect(calls).to.equal(1);
|
|
});
|
|
it("should be able to access meta and context to get the type of tag", function () {
|
|
var content = "<w:p><w:t>Hello {#users}{name}{/users}</w:t></w:p>\n\t\t<w:p><w:t>{@rrr}</w:t></w:p>\n\t\t";
|
|
var scope = {
|
|
users: [{
|
|
name: "Jane"
|
|
}],
|
|
rrr: ""
|
|
};
|
|
var contexts = [];
|
|
var pX = [];
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope,
|
|
parser: function parser(tag, x) {
|
|
pX.push(x);
|
|
return {
|
|
get: function get(scope, context) {
|
|
contexts.push(context);
|
|
if (tag === "$index") {
|
|
return last(context.scopePathItem);
|
|
}
|
|
return scope[tag];
|
|
}
|
|
};
|
|
}
|
|
});
|
|
expect(xmlTemplater.getFullText()).to.be.equal("Hello Jane");
|
|
var values = contexts.map(function (_ref3) {
|
|
var _ref3$meta$part = _ref3.meta.part,
|
|
type = _ref3$meta$part.type,
|
|
value = _ref3$meta$part.value,
|
|
module = _ref3$meta$part.module;
|
|
return {
|
|
type: type,
|
|
value: value,
|
|
module: module
|
|
};
|
|
});
|
|
expect(values).to.be.deep.equal([{
|
|
type: "placeholder",
|
|
value: "users",
|
|
module: "loop"
|
|
}, {
|
|
type: "placeholder",
|
|
value: "name",
|
|
module: undefined
|
|
}, {
|
|
type: "placeholder",
|
|
value: "rrr",
|
|
module: "rawxml"
|
|
}]);
|
|
expect(pX.map(function (_ref4) {
|
|
var _ref4$tag = _ref4.tag,
|
|
type = _ref4$tag.type,
|
|
value = _ref4$tag.value,
|
|
module = _ref4$tag.module;
|
|
return {
|
|
type: type,
|
|
value: value,
|
|
module: module
|
|
};
|
|
})).to.be.deep.equal([{
|
|
type: "placeholder",
|
|
value: "name",
|
|
module: undefined
|
|
}, {
|
|
type: "placeholder",
|
|
value: "users",
|
|
module: "loop"
|
|
}, {
|
|
type: "placeholder",
|
|
value: "rrr",
|
|
module: "rawxml"
|
|
}]);
|
|
});
|
|
});
|
|
describe("Change the delimiters", function () {
|
|
it("should work with lt and gt delimiter < and >", function () {
|
|
var doc = createDocV4("delimiter-gt.docx", {
|
|
delimiters: {
|
|
start: "<",
|
|
end: ">"
|
|
}
|
|
});
|
|
doc.render({
|
|
user: "John"
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Hello John");
|
|
});
|
|
it("should work with delimiter % both sides", function () {
|
|
var doc = createDocV4("delimiter-pct.docx", {
|
|
delimiters: {
|
|
start: "%",
|
|
end: "%"
|
|
}
|
|
});
|
|
doc.render({
|
|
user: "John",
|
|
company: "PCorp"
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Hello John from PCorp");
|
|
});
|
|
});
|
|
describe("Special characters", function () {
|
|
it("should parse placeholder containing special characters", function () {
|
|
var content = "<w:t>Hello {>name}</w:t>";
|
|
var scope = {
|
|
">name": "Edgar"
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(xmlTemplater);
|
|
expect(c).to.be.deep.equal('<w:t xml:space="preserve">Hello Edgar</w:t>');
|
|
});
|
|
it("should not decode xml entities recursively", function () {
|
|
var content = "<w:t>Hello {&lt;}</w:t>";
|
|
var scope = {
|
|
"<": "good",
|
|
"<": "bad!!"
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(xmlTemplater);
|
|
expect(c).to.be.deep.equal('<w:t xml:space="preserve">Hello good</w:t>');
|
|
});
|
|
it("should render placeholder containing special characters", function () {
|
|
var content = "<w:t>Hello {name}</w:t>";
|
|
var scope = {
|
|
name: "<Edgar>"
|
|
};
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(xmlTemplater);
|
|
expect(c).to.be.deep.equal('<w:t xml:space="preserve">Hello <Edgar></w:t>');
|
|
});
|
|
it("should read full text correctly", function () {
|
|
var doc = createDocV4("cyrillic.docx");
|
|
var fullText = doc.getFullText();
|
|
var charcodes = [];
|
|
for (var i = 0, len = fullText.length; i < len; i++) {
|
|
charcodes[i] = fullText.charCodeAt(i);
|
|
}
|
|
expect(charcodes.slice(0, 8)).to.be.deep.equal([1024, 1050, 1048, 1046, 1044, 1045, 1039, 1040]);
|
|
});
|
|
it("should still read full text after applying tags", function () {
|
|
var doc = createDocV4("cyrillic.docx");
|
|
doc.render({
|
|
name: "Edgar"
|
|
});
|
|
var fullText = doc.getFullText();
|
|
var charcodes = [];
|
|
for (var i = 0, len = fullText.length; i < len; i++) {
|
|
charcodes[i] = fullText.charCodeAt(i);
|
|
}
|
|
expect(charcodes.slice(0, 8)).to.be.deep.equal([1024, 1050, 1048, 1046, 1044, 1045, 1039, 1040]);
|
|
expect(fullText.indexOf("Edgar")).to.be.equal(9);
|
|
});
|
|
it("should insert russian characters", function () {
|
|
var russian = "Пупкина";
|
|
var doc = createDocV4("tag-example.docx");
|
|
doc.render({
|
|
last_name: russian
|
|
});
|
|
expect(doc.getFullText().substr(0, 7)).to.be.equal(russian);
|
|
});
|
|
});
|
|
describe("Complex table example", function () {
|
|
it("should not do anything special when loop outside of table", function () {
|
|
var content = "<w:p><w:t>{#tables}</w:t></w:p>\n<w:tbl><w:tr><w:tc>\n<w:p><w:t>{user}</w:t></w:p>\n</w:tc></w:tr></w:tbl>\n<w:p><w:t>{/tables}</w:t></w:p>";
|
|
var scope = {
|
|
tables: [{
|
|
user: "John"
|
|
}, {
|
|
user: "Jane"
|
|
}]
|
|
};
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(doc);
|
|
expect(c).to.be.equal("<w:p><w:t/></w:p>\n<w:tbl><w:tr><w:tc>\n<w:p><w:t xml:space=\"preserve\">John</w:t></w:p>\n</w:tc></w:tr></w:tbl>\n<w:p><w:t/></w:p>\n<w:tbl><w:tr><w:tc>\n<w:p><w:t xml:space=\"preserve\">Jane</w:t></w:p>\n</w:tc></w:tr></w:tbl>\n<w:p><w:t/></w:p>");
|
|
});
|
|
it("should work when looping inside tables", function () {
|
|
var tags = {
|
|
table1: [1],
|
|
key: "value"
|
|
};
|
|
var template = "<w:tr>\n\t\t".concat(cell("{#table1}Hi"), "\n\t\t").concat(cell("{/table1}"), "\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t").concat(cell("{#table1}Ho"), "\n\t\t").concat(cell("{/table1}"), "\n\t\t</w:tr>\n\t\t").concat(paragraph("{key}"), "\n\t\t");
|
|
var doc = createXmlTemplaterDocx(template, {
|
|
tags: tags
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("HiHovalue");
|
|
var expected = "<w:tr>\n\t\t".concat(cell("Hi"), "\n\t\t").concat(cell(""), "\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t").concat(cell("Ho"), "\n\t\t").concat(cell(""), "\n\t\t</w:tr>\n\t\t").concat(paragraph("value"), "\n\t\t");
|
|
expect(getContent(doc)).to.be.equal(expected);
|
|
});
|
|
});
|
|
describe("Raw Xml Insertion", function () {
|
|
it("should work with simple example", function () {
|
|
var inner = paragraph("{@complexXml}");
|
|
var content = "<w:document>".concat(inner, "</w:document>");
|
|
var scope = {
|
|
complexXml: '<w:p w:rsidR="00612058" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr><w:r><w:rPr><w:color w:val="FF0000"/></w:rPr><w:t>My custom XML</w:t></w:r></w:p><w:tbl><w:tblPr><w:tblStyle w:val="Grilledutableau"/><w:tblW w:w="0" w:type="auto"/><w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/></w:tblPr><w:tblGrid><w:gridCol w:w="2952"/><w:gridCol w:w="2952"/><w:gridCol w:w="2952"/></w:tblGrid><w:tr w:rsidR="00EA4B08" w:rsidTr="00EA4B08"><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="DDD9C3" w:themeFill="background2" w:themeFillShade="E6"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRPr="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:b/><w:color w:val="000000" w:themeColor="text1"/></w:rPr></w:pPr><w:r><w:rPr><w:b/><w:color w:val="000000" w:themeColor="text1"/></w:rPr><w:t>Test</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="DDD9C3" w:themeFill="background2" w:themeFillShade="E6"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRPr="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:b/><w:color w:val="FF0000"/></w:rPr></w:pPr><w:r><w:rPr><w:b/><w:color w:val="FF0000"/></w:rPr><w:t>Xml</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="DDD9C3" w:themeFill="background2" w:themeFillShade="E6"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr><w:r><w:rPr><w:color w:val="FF0000"/></w:rPr><w:t>Generated</w:t></w:r></w:p></w:tc></w:tr><w:tr w:rsidR="00EA4B08" w:rsidTr="00EA4B08"><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="C6D9F1" w:themeFill="text2" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRPr="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="000000" w:themeColor="text1"/><w:u w:val="single"/></w:rPr></w:pPr><w:r w:rsidRPr="00EA4B08"><w:rPr><w:color w:val="000000" w:themeColor="text1"/><w:u w:val="single"/></w:rPr><w:t>Underline</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="C6D9F1" w:themeFill="text2" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr><w:r w:rsidRPr="00EA4B08"><w:rPr><w:color w:val="FF0000"/><w:highlight w:val="yellow"/></w:rPr><w:t>Highlighting</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="C6D9F1" w:themeFill="text2" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRPr="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:rFonts w:ascii="Bauhaus 93" w:hAnsi="Bauhaus 93"/><w:color w:val="FF0000"/></w:rPr></w:pPr><w:r w:rsidRPr="00EA4B08"><w:rPr><w:rFonts w:ascii="Bauhaus 93" w:hAnsi="Bauhaus 93"/><w:color w:val="FF0000"/></w:rPr><w:t>Font</w:t></w:r></w:p></w:tc></w:tr><w:tr w:rsidR="00EA4B08" w:rsidTr="00EA4B08"><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="F2DBDB" w:themeFill="accent2" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00EA4B08"><w:pPr><w:jc w:val="center"/><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr><w:r><w:rPr><w:color w:val="FF0000"/></w:rPr><w:t>Centering</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="F2DBDB" w:themeFill="accent2" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRPr="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:i/><w:color w:val="FF0000"/></w:rPr></w:pPr><w:r w:rsidRPr="00EA4B08"><w:rPr><w:i/><w:color w:val="FF0000"/></w:rPr><w:t>Italic</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="F2DBDB" w:themeFill="accent2" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr></w:p></w:tc></w:tr><w:tr w:rsidR="00EA4B08" w:rsidTr="00EA4B08"><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="E5DFEC" w:themeFill="accent4" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="E5DFEC" w:themeFill="accent4" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="E5DFEC" w:themeFill="accent4" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr></w:p></w:tc></w:tr><w:tr w:rsidR="00EA4B08" w:rsidTr="00EA4B08"><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="FDE9D9" w:themeFill="accent6" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="FDE9D9" w:themeFill="accent6" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="2952" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="FDE9D9" w:themeFill="accent6" w:themeFillTint="33"/></w:tcPr><w:p w:rsidR="00EA4B08" w:rsidRDefault="00EA4B08" w:rsidP="00612058"><w:pPr><w:rPr><w:color w:val="FF0000"/></w:rPr></w:pPr></w:p></w:tc></w:tr></w:tbl>'
|
|
};
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(doc);
|
|
expect(c.length).to.be.equal(content.length + scope.complexXml.length - inner.length + "<w:p/>".length);
|
|
expect(c).to.contain(scope.complexXml);
|
|
});
|
|
it("should work even when tags are after the xml", function () {
|
|
var content = "<w:tbl>\n\t\t<w:tr>\n\t\t".concat(cell("{@complexXml}"), "\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t").concat(cell("{name}"), "\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t").concat(cell("{first_name}"), "\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t").concat(cell("{#products} {year}"), "\n\t\t").concat(cell("{name}"), "\n\t\t").concat(cell("{company}{/products}"), "\n\t\t</w:tr>\n\t\t</w:tbl>\n\t\t");
|
|
var scope = {
|
|
complexXml: paragraph("Hello"),
|
|
name: "John",
|
|
first_name: "Doe",
|
|
products: [{
|
|
year: 1550,
|
|
name: "Moto",
|
|
company: "Fein"
|
|
}, {
|
|
year: 1987,
|
|
name: "Water",
|
|
company: "Test"
|
|
}, {
|
|
year: 2010,
|
|
name: "Bread",
|
|
company: "Yu"
|
|
}]
|
|
};
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(doc);
|
|
expect(c).to.contain(scope.complexXml);
|
|
expect(doc.getFullText()).to.be.equal("HelloJohnDoe 1550MotoFein 1987WaterTest 2010BreadYu");
|
|
});
|
|
it("should work with false value", function () {
|
|
var content = paragraph("{@rawXML}") + paragraph("Hi");
|
|
var doc = createXmlTemplaterDocx(content, {
|
|
tags: {
|
|
rawXML: false
|
|
}
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Hi");
|
|
});
|
|
it("should work with closing tag in the form of <w:t>}{/body}</w:t>", function () {
|
|
var scope = {
|
|
body: [{
|
|
paragraph: "hello"
|
|
}]
|
|
};
|
|
var content = "<w:t>{#body}</w:t>\n\t\t<w:t>{paragraph</w:t>\n\t\t\t<w:t>}{/body}</w:t>";
|
|
var xmlTemplater = createXmlTemplaterDocx(content, {
|
|
tags: scope
|
|
});
|
|
var c = getContent(xmlTemplater);
|
|
expect(c).not.to.contain("</w:t></w:t>");
|
|
});
|
|
it("should work with simple example and given options", function () {
|
|
var doc = createDocV4("one-raw-xml-tag.docx", {
|
|
fileTypeConfig: assign({}, Docxtemplater.FileTypeConfig.docx(), {
|
|
tagRawXml: "w:r"
|
|
})
|
|
});
|
|
doc.render({
|
|
xmlTag: '<w:r><w:rPr><w:color w:val="FF0000"/></w:rPr><w:t>My custom</w:t></w:r><w:r><w:rPr><w:color w:val="00FF00"/></w:rPr><w:t>XML</w:t></w:r>'
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("asdfMy customXMLqwery");
|
|
});
|
|
});
|
|
describe("Multi line", function () {
|
|
it("should work when tag spans multiple lines (paragraphs)", function () {
|
|
return this.render({
|
|
name: "tag-spanning-multiline.docx",
|
|
data: {
|
|
first_name: "Hipp",
|
|
last_name: "Edgar",
|
|
phone: "0652455478",
|
|
description: "New Website"
|
|
},
|
|
expectedName: "expected-tag-spanning-multiline.docx"
|
|
});
|
|
});
|
|
});
|
|
describe("Constructor v4", function () {
|
|
it("should work when modules are attached", function () {
|
|
var isModuleCalled = false;
|
|
var module = {
|
|
name: "TestModule",
|
|
optionsTransformer: function optionsTransformer(options) {
|
|
isModuleCalled = true;
|
|
return options;
|
|
}
|
|
};
|
|
createDocV4("tag-example.docx", {
|
|
modules: [module]
|
|
});
|
|
expect(isModuleCalled).to.equal(true);
|
|
});
|
|
it("should throw an error when modules passed is not an array", function () {
|
|
expect(function () {
|
|
return new Docxtemplater(getZip("tag-example.docx"), {
|
|
modules: {}
|
|
});
|
|
}).to["throw"]("The modules argument of docxtemplater's constructor must be an array");
|
|
});
|
|
it("should warn if trying to reuse same zip for two docxtemplater templates", function () {
|
|
var zip = getZip("tag-example.docx");
|
|
var doc = new Docxtemplater(zip);
|
|
var capture = captureLogs();
|
|
doc.render();
|
|
/* eslint-disable-next-line no-unused-vars */
|
|
var otherDoc = new Docxtemplater(zip);
|
|
capture.stop();
|
|
var logs = capture.logs();
|
|
expect(logs).to.deep.equal(["Warning : This zip file appears to be the outcome of a previous docxtemplater generation. This typically indicates that docxtemplater was integrated by reusing the same zip file. It is recommended to create a new Pizzip instance for each docxtemplater generation."]);
|
|
});
|
|
it("should be possible to customize warnFn", function () {
|
|
var zip = getZip("tag-example.docx");
|
|
var doc = new Docxtemplater(zip);
|
|
doc.render();
|
|
var myErrors = [];
|
|
/* eslint-disable-next-line no-unused-vars */
|
|
var otherDoc = new Docxtemplater(zip, {
|
|
warnFn: function warnFn(errors) {
|
|
myErrors = errors;
|
|
}
|
|
});
|
|
expect(myErrors.length).to.deep.equal(1);
|
|
expect(myErrors[0]).to.be["instanceof"](Error);
|
|
});
|
|
it("should throw an error when an invalid zip is passed", function () {
|
|
expect(function () {
|
|
return new Docxtemplater("content");
|
|
}).to["throw"]("The first argument of docxtemplater's constructor must be a valid zip file (jszip v2 or pizzip v3)");
|
|
expect(function () {
|
|
return new Docxtemplater({
|
|
files: []
|
|
});
|
|
}).to["throw"]("The first argument of docxtemplater's constructor must be a valid zip file (jszip v2 or pizzip v3)");
|
|
var zip = getZip("tag-example.docx");
|
|
zip.files = null;
|
|
expect(function () {
|
|
return new Docxtemplater(zip);
|
|
}).to["throw"]("The first argument of docxtemplater's constructor must be a valid zip file (jszip v2 or pizzip v3)");
|
|
if (typeof Buffer !== "undefined") {
|
|
expect(function () {
|
|
return new Docxtemplater(Buffer.from("content"));
|
|
}).to["throw"]("You passed a Buffer to the Docxtemplater constructor. The first argument of docxtemplater's constructor must be a valid zip file (jszip v2 or pizzip v3)");
|
|
}
|
|
});
|
|
it("should work when the delimiters are passed", function () {
|
|
var options = {
|
|
delimiters: {
|
|
start: "<",
|
|
end: ">"
|
|
}
|
|
};
|
|
var doc = createDocV4("delimiter-gt.docx", options);
|
|
doc.render({
|
|
user: "John"
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Hello John");
|
|
});
|
|
it("should work when both modules and delimiters are passed and modules should have access to options object", function () {
|
|
var isModuleCalled = false,
|
|
optionsPassedToModule;
|
|
var options = {
|
|
delimiters: {
|
|
start: "%",
|
|
end: "%"
|
|
},
|
|
modules: [{
|
|
name: "MyModule",
|
|
optionsTransformer: function optionsTransformer(options) {
|
|
optionsPassedToModule = options;
|
|
isModuleCalled = true;
|
|
return options;
|
|
}
|
|
}]
|
|
};
|
|
var doc = createDocV4("delimiter-pct.docx", options);
|
|
expect(isModuleCalled).to.be.equal(true);
|
|
expect(optionsPassedToModule.delimiters.start).to.be.equal("%");
|
|
expect(optionsPassedToModule.delimiters.end).to.be.equal("%");
|
|
// Verify that default options are passed to the modules
|
|
expect(optionsPassedToModule.linebreaks).to.be.equal(false);
|
|
doc.render({
|
|
user: "John",
|
|
company: "Acme"
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Hello John from Acme");
|
|
});
|
|
it("should throw error when using a non-instanciated class as a module", function () {
|
|
var MyTestModule = /*#__PURE__*/function () {
|
|
function MyTestModule() {
|
|
_classCallCheck(this, MyTestModule);
|
|
}
|
|
return _createClass(MyTestModule, [{
|
|
key: "render",
|
|
value: function render(part) {
|
|
return {
|
|
value: part.value
|
|
};
|
|
}
|
|
}]);
|
|
}();
|
|
var options = {
|
|
delimiters: {
|
|
start: "%",
|
|
end: "%"
|
|
},
|
|
modules: [MyTestModule]
|
|
};
|
|
expect(function () {
|
|
return createDocV4("delimiter-pct.docx", options);
|
|
}).to["throw"]("Cannot attach a class/function as a module. Most probably you forgot to instantiate the module by using `new` on the module.");
|
|
});
|
|
it("should throw if using v4 constructor and setOptions", function () {
|
|
var doc = createDocV4("tag-multiline.docx");
|
|
expect(function () {
|
|
return doc.setOptions({
|
|
linebreaks: true
|
|
});
|
|
}).to["throw"]("setOptions() should not be called manually when using the v4 constructor");
|
|
});
|
|
it("should throw if using v4 constructor and attachModule", function () {
|
|
var doc = createDocV4("tag-multiline.docx");
|
|
expect(function () {
|
|
return doc.attachModule({
|
|
render: function render() {}
|
|
});
|
|
}).to["throw"]("attachModule() should not be called manually when using the v4 constructor");
|
|
});
|
|
it("should throw if using v4 constructor and loadZip", function () {
|
|
var doc = createDocV4("tag-multiline.docx");
|
|
expect(function () {
|
|
return doc.loadZip();
|
|
}).to["throw"]("loadZip() should not be called manually when using the v4 constructor");
|
|
});
|
|
it("should render correctly", function () {
|
|
var doc = new Docxtemplater(getZip("tag-example.docx"));
|
|
doc.render({
|
|
first_name: "John",
|
|
last_name: "Doe"
|
|
});
|
|
expect(doc.getFullText()).to.be.equal("Doe John");
|
|
});
|
|
it("should work when modules are attached with valid filetypes", function () {
|
|
var isModuleCalled = false;
|
|
var module = {
|
|
name: "FooModule",
|
|
optionsTransformer: function optionsTransformer(options) {
|
|
isModuleCalled = true;
|
|
return options;
|
|
},
|
|
supportedFileTypes: ["pptx", "docx"]
|
|
};
|
|
createDocV4("tag-example.docx", {
|
|
modules: [module]
|
|
});
|
|
expect(isModuleCalled).to.equal(true);
|
|
});
|
|
it("should throw an error when supportedFieldType property in passed module is not an Array", function () {
|
|
var zip = getZip("tag-example.docx");
|
|
var module = {
|
|
optionsTransformer: function optionsTransformer(options) {
|
|
return options;
|
|
},
|
|
supportedFileTypes: "pptx"
|
|
};
|
|
expect(function () {
|
|
return new Docxtemplater(zip, {
|
|
modules: [module]
|
|
});
|
|
}).to["throw"]("The supportedFileTypes field of the module must be an array");
|
|
});
|
|
it("should fail with readable error when using new Docxtemplater(null)", function () {
|
|
expect(function () {
|
|
return new Docxtemplater(null, {});
|
|
}).to["throw"]("The first argument of docxtemplater's constructor must be a valid zip file (jszip v2 or pizzip v3)");
|
|
});
|
|
it("should fail with readable error when using new Docxtemplater(null, {modules: [inspectModule()]})", function () {
|
|
expect(function () {
|
|
return new Docxtemplater(null, {
|
|
modules: [inspectModule()]
|
|
});
|
|
}).to["throw"]("The first argument of docxtemplater's constructor must be a valid zip file (jszip v2 or pizzip v3)");
|
|
});
|
|
}); |