Server IP : 162.213.251.212 / Your IP : 3.149.245.181 [ Web Server : LiteSpeed System : Linux business55.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64 User : allssztx ( 535) PHP Version : 8.1.31 Disable Function : NONE Domains : 1 Domains MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /proc/self/root/home/allssztx/needapair.com/node_modules/docxtemplater/js/tests/e2e/ |
Upload File : |
"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; 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.getZip().generate({ type: "base64" }); expect(output.length).to.be.equal(90732); expect(output.substr(0, 50)).to.be.equal("UEsDBAoAAAAAAAAAIQAMTxYSlgcAAJYHAAATAAAAW0NvbnRlbn"); }); }); }); describe("Retrieving text content", function () { it("should work for the footer", function () { var doc = createDocV4("tag-example.docx"); var fullText = doc.getFullText("word/footer1.xml"); expect(fullText.length).not.to.be.equal(0); expect(fullText).to.be.equal("{last_name}{first_name}{phone}"); }); it("should work for the document", function () { var doc = createDocV4("tag-example.docx"); var fullText = doc.getFullText(); expect(fullText).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(doc.verifyApiVersion.bind(null, "5.0")); expectToThrowSnapshot(doc.verifyApiVersion.bind(null, "5.6.0")); expectToThrowSnapshot(doc.verifyApiVersion.bind(null, "3.44.0")); expectToThrowSnapshot(doc.verifyApiVersion.bind(null, "3.41.100")); }); }); describe("Inspect module", function () { it("should get main tags", function () { var iModule = inspectModule(); var doc = createDocV4("tag-loop-example.docx", { modules: [iModule] }); expect(iModule.getStructuredTags()).to.matchSnapshot(); expect(iModule.getTags()).to.be.deep.equal({ offre: { nom: {}, prix: {}, titre: {} }, nom: {}, prenom: {} }); var data = { offre: [{}], prenom: "John" }; doc.render(data); var fi = iModule.fullInspected["word/document.xml"]; var _fi$nullValues = fi.nullValues, summary = _fi$nullValues.summary, detail = _fi$nullValues.detail; var postparsed = fi.postparsed, parsed = fi.parsed, xmllexed = fi.xmllexed; expect(postparsed.length).to.equal(249); expect(parsed.length).to.equal(385); expect(xmllexed.length).to.equal(383); expect(iModule.inspect.tags).to.be.deep.equal(data); expect(detail).to.be.an("array"); expect(detail[0].part.value).to.equal("nom"); expect(detail[0].scopeManager.scopeList[0].prenom).to.equal("John"); expect(summary).to.be.deep.equal([["offre", "nom"], ["offre", "prix"], ["offre", "titre"], ["nom"]]); }); it("should get all tags (pptx file)", function () { var iModule = inspectModule(); createDocV4("multi-page.pptx", { modules: [iModule] }); expect(iModule.getStructuredTags()).to.matchSnapshot(); expect(iModule.getFileType()).to.be.deep.equal("pptx"); expect(iModule.getAllTags()).to.be.deep.equal({ tag: {}, users: { name: {} } }); expect(iModule.getTemplatedFiles().sort()).to.be.deep.equal(["ppt/slides/slide1.xml", "ppt/slides/slide2.xml", "ppt/slideLayouts/slideLayout1.xml", "ppt/slideLayouts/slideLayout10.xml", "ppt/slideLayouts/slideLayout11.xml", "ppt/slideLayouts/slideLayout12.xml", "ppt/slideLayouts/slideLayout2.xml", "ppt/slideLayouts/slideLayout3.xml", "ppt/slideLayouts/slideLayout4.xml", "ppt/slideLayouts/slideLayout5.xml", "ppt/slideLayouts/slideLayout6.xml", "ppt/slideLayouts/slideLayout7.xml", "ppt/slideLayouts/slideLayout8.xml", "ppt/slideLayouts/slideLayout9.xml", "ppt/slideMasters/slideMaster1.xml", "ppt/presentation.xml", "docProps/app.xml", "docProps/core.xml"].sort()); }); it("should get all tags and merge them", function () { var iModule = inspectModule(); createDocV4("multi-page-to-merge.pptx", { modules: [iModule] }); expect(iModule.getAllTags()).to.be.deep.equal({ tag: {}, users: { name: {}, age: {}, company: {} } }); }); it("should get all tags with additional data", function () { var iModule = inspectModule(); createDocV4("tag-product-loop.docx", { modules: [iModule] }); expect(iModule.getAllStructuredTags()).to.be.deep.equal([{ type: "placeholder", value: "products", raw: "#products", lIndex: 17, sectPrCount: 0, module: "loop", inverted: false, offset: 0, lastParagrapSectPr: "", endLindex: 216, subparsed: [{ type: "placeholder", value: "title", offset: 11, endLindex: 33, lIndex: 33 }, { type: "placeholder", value: "name", offset: 33, endLindex: 57, lIndex: 57 }, { type: "placeholder", value: "reference", offset: 59, endLindex: 74, lIndex: 74 }, { type: "placeholder", value: "avantages", module: "loop", raw: "#avantages", inverted: false, offset: 70, sectPrCount: 0, lastParagrapSectPr: "", endLindex: 192, lIndex: 92, subparsed: [{ type: "placeholder", value: "title", offset: 82, endLindex: 108, lIndex: 108 }, { type: "placeholder", value: "proof", module: "loop", raw: "#proof", sectPrCount: 0, lastParagrapSectPr: "", inverted: false, offset: 117, endLindex: 174, lIndex: 136, subparsed: [{ type: "placeholder", value: "reason", offset: 143, endLindex: 158, lIndex: 158 }] }] }] }]); }); }); 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); var fullText = doc.getFullText(); expect(fullText).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" }); var fullText = doc.getFullText(); expect(fullText).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" }); var fullText = doc.getFullText(); expect(fullText).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(); expect(fullText.charCodeAt(0)).to.be.equal(1024); expect(fullText.charCodeAt(1)).to.be.equal(1050); expect(fullText.charCodeAt(2)).to.be.equal(1048); expect(fullText.charCodeAt(3)).to.be.equal(1046); expect(fullText.charCodeAt(4)).to.be.equal(1044); expect(fullText.charCodeAt(5)).to.be.equal(1045); expect(fullText.charCodeAt(6)).to.be.equal(1039); expect(fullText.charCodeAt(7)).to.be.equal(1040); }); it("should still read full text after applying tags", function () { var doc = createDocV4("cyrillic.docx"); doc.render({ name: "Edgar" }); var fullText = doc.getFullText(); expect(fullText.charCodeAt(0)).to.be.equal(1024); expect(fullText.charCodeAt(1)).to.be.equal(1050); expect(fullText.charCodeAt(2)).to.be.equal(1048); expect(fullText.charCodeAt(3)).to.be.equal(1046); expect(fullText.charCodeAt(4)).to.be.equal(1044); expect(fullText.charCodeAt(5)).to.be.equal(1045); expect(fullText.charCodeAt(6)).to.be.equal(1039); expect(fullText.charCodeAt(7)).to.be.equal(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 }); var outputText = doc.getFullText(); expect(outputText.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<w:tc><w:p><w:t>{#table1}Hi</w:t></w:p></w:tc>\n\t\t<w:tc><w:p><w:t>{/table1}</w:t></w:p> </w:tc>\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t<w:tc><w:p><w:t>{#table1}Ho</w:t></w:p></w:tc>\n\t\t<w:tc><w:p><w:t>{/table1}</w:t></w:p></w:tc>\n\t\t</w:tr>\n\t\t<w:p><w:t>{key}</w:t></w:p>\n\t\t"; var doc = createXmlTemplaterDocx(template, { tags: tags }); var fullText = doc.getFullText(); expect(fullText).to.be.equal("HiHovalue"); var expected = "<w:tr>\n\t\t<w:tc><w:p><w:t xml:space=\"preserve\">Hi</w:t></w:p></w:tc>\n\t\t<w:tc><w:p><w:t/></w:p> </w:tc>\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t<w:tc><w:p><w:t xml:space=\"preserve\">Ho</w:t></w:p></w:tc>\n\t\t<w:tc><w:p><w:t/></w:p></w:tc>\n\t\t</w:tr>\n\t\t<w:p><w:t xml:space=\"preserve\">value</w:t></w:p>\n\t\t"; var c = getContent(doc); expect(c).to.be.equal(expected); }); }); describe("Raw Xml Insertion", function () { it("should work with simple example", function () { var inner = "<w:p><w:r><w:t>{@complexXml}</w:t></w:r></w:p>"; 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<w:tc>\n\t\t<w:p>\n\t\t<w:r>\n\t\t<w:t>{@complexXml}</w:t>\n\t\t</w:r>\n\t\t</w:p>\n\t\t</w:tc>\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t<w:tc>\n\t\t<w:p>\n\t\t<w:r>\n\t\t<w:t>{name}</w:t>\n\t\t</w:r>\n\t\t</w:p>\n\t\t</w:tc>\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t<w:tc>\n\t\t<w:p>\n\t\t<w:r>\n\t\t<w:t>{first_name}</w:t>\n\t\t</w:r>\n\t\t</w:p>\n\t\t</w:tc>\n\t\t</w:tr>\n\t\t<w:tr>\n\t\t<w:tc>\n\t\t<w:p>\n\t\t<w:r>\n\t\t<w:t>{#products} {year}</w:t>\n\t\t</w:r>\n\t\t</w:p>\n\t\t</w:tc>\n\t\t<w:tc>\n\t\t<w:p>\n\t\t<w:r>\n\t\t<w:t>{name}</w:t>\n\t\t</w:r>\n\t\t</w:p>\n\t\t</w:tc>\n\t\t<w:tc>\n\t\t<w:p>\n\t\t<w:r>\n\t\t<w:t>{company}{/products}</w:t>\n\t\t</w:r>\n\t\t</w:p>\n\t\t</w:tc>\n\t\t</w:tr>\n\t\t</w:tbl>\n\t\t"; var scope = { complexXml: "<w:p><w:r><w:t>Hello</w:t></w:r></w:p>", 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 = "\n\t\t\t<w:p><w:r><w:t>{@rawXML}</w:t></w:r></w:p>\n\t\t\t<w:p><w:r><w:t>Hi</w:t></w:r></w:p>\n\t\t"; 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 throw an error when an invalid zip is passed", function () { 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)"); 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)"); if (typeof Buffer !== "undefined") { expect(function () { return new Docxtemplater(Buffer.from("content")); }).to["throw"]("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" }); var fullText = doc.getFullText(); expect(fullText).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" }); var fullText = doc.getFullText(); expect(fullText).to.be.equal("Hello John from Acme"); }); var MyTestModule = /*#__PURE__*/function () { function MyTestModule() { _classCallCheck(this, MyTestModule); } return _createClass(MyTestModule, [{ key: "render", value: function render(part) { return { value: part.value }; } }]); }(); it("should throw error when using a non-instanciated class as a module", function () { 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)"); }); });