"use strict";

var _require = require("../utils.js"),
  expectToThrow = _require.expectToThrow,
  expectToThrowSnapshot = _require.expectToThrowSnapshot,
  shouldBeSame = _require.shouldBeSame,
  createDocV4 = _require.createDocV4,
  captureLogs = _require.captureLogs,
  expect = _require.expect,
  getZip = _require.getZip;
var expressionParser = require("../../expressions.js");
var proofStateModule = require("../../proof-state-module.js");
var inspectModule = require("../../inspect-module.js");
var Docxtemplater = require("../../docxtemplater.js");
var _require2 = require("../../doc-utils.js"),
  pushArray = _require2.pushArray,
  traits = _require2.traits,
  uniq = _require2.uniq;
var fixDocPrCorruption = require("../../modules/fix-doc-pr-corruption.js");
function uniqTimes(arr) {
  var times = {},
    result = [];
  for (var _i2 = 0; _i2 < arr.length; _i2++) {
    var el = arr[_i2];
    if (times[el] == null) {
      times[el] = 0;
      result.push([el]);
    }
    times[el] += 1;
  }
  for (var _i4 = 0; _i4 < result.length; _i4++) {
    var item = result[_i4];
    item[1] = times[item[0]];
  }
  return result;
}
describe("Verify apiversion", function () {
  it("should work with valid api version", function () {
    var module = {
      name: "Mymod",
      requiredAPIVersion: "3.23.0",
      render: function render(part) {
        return part.value;
      }
    };
    createDocV4("tag-example.docx", {
      modules: [module]
    });
  });
  it("should fail with invalid api version", function () {
    var module = {
      name: "Mymod",
      requiredAPIVersion: "3.92.0",
      render: function render(part) {
        return part.value;
      }
    };
    expectToThrowSnapshot(function () {
      return createDocV4("loop-valid.docx", {
        modules: [module]
      });
    });
  });
  it("should fail when trying to attach null module", function () {
    expectToThrow(function () {
      return new Docxtemplater(getZip("loop-valid.docx"), {
        modules: [null]
      });
    }, Error, {
      message: "Cannot attachModule with a falsy value",
      name: "InternalError",
      properties: {}
    });
  });
});
describe("Module attachment", function () {
  it("should not allow to attach the same module twice", function () {
    var module = {
      name: "TestModule",
      requiredAPIVersion: "3.0.0",
      render: function render(part) {
        return part.value;
      }
    };
    createDocV4("loop-valid.docx", {
      modules: [module]
    });
    var errMessage = null;
    try {
      createDocV4("tag-example.docx", {
        modules: [module]
      });
    } catch (e) {
      errMessage = e.message;
    }
    expect(errMessage).to.equal('Cannot attach a module that was already attached : "TestModule". The most likely cause is that you are instantiating the module at the root level, and using it for multiple instances of Docxtemplater');
  });
  it("should allow to attach the same module twice if it has a clone method", function () {
    var module = {
      name: "TestModule",
      requiredAPIVersion: "3.0.0",
      render: function render(part) {
        return part.value;
      },
      clone: function clone() {
        return this;
      }
    };
    createDocV4("loop-valid.docx", {
      modules: [module]
    });
    createDocV4("tag-example.docx", {
      modules: [module]
    });
    createDocV4("tag-example.docx", {
      modules: [module]
    });
  });
  it("should automatically detach inspect module", function () {
    var imodule = inspectModule();
    createDocV4("loop-valid.docx", {
      modules: [imodule]
    }).render();
    createDocV4("loop-valid.docx", {
      modules: [imodule]
    }).render();
  });
});
describe("Module xml parse", function () {
  it("should not mutate options (regression for issue #526)", function () {
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      optionsTransformer: function optionsTransformer(options, docxtemplater) {
        var relsFiles = docxtemplater.zip.file(/document.xml.rels/).map(function (file) {
          return file.name;
        });
        pushArray(options.xmlFileNames, relsFiles);
        return options;
      }
    };
    var opts = {
      modules: [module]
    };
    createDocV4("tag-example.docx", opts);
    delete opts.modules;
    expect(opts).to.deep.equal({});
  });
  it("should be possible to parse xml files : xmlFileNames.push() without side effect fixed since v3.55.0", function () {
    var xmlDocuments;
    var module = {
      name: "ParseXMLModule",
      requiredAPIVersion: "3.0.0",
      optionsTransformer: function optionsTransformer(options, docxtemplater) {
        var relsFiles = docxtemplater.zip.file(/document.xml.rels/).map(function (_ref) {
          var name = _ref.name;
          return name;
        });

        /*
         * This part tests that you can mutate the options here without
         * mutating it for future documents
         * Fixed since 3.55.0
         */
        pushArray(options.xmlFileNames, relsFiles);
        return options;
      },
      set: function set(options) {
        if (options.xmlDocuments) {
          xmlDocuments = options.xmlDocuments;
        }
      }
    };
    var doc = createDocV4("tag-example.docx", {
      modules: [module]
    });
    var xmlKeys = Object.keys(xmlDocuments);
    expect(xmlKeys).to.deep.equal(["[Content_Types].xml", "word/_rels/document.xml.rels"]);
    var rels = xmlDocuments["word/_rels/document.xml.rels"].getElementsByTagName("Relationship");
    expect(rels.length).to.equal(10);
    rels[5].setAttribute("Foobar", "Baz");
    doc.render();
    shouldBeSame({
      doc: doc,
      expectedName: "expected-module-change-rels.docx"
    });
  });
});
describe("Module unique tags xml", function () {
  it("should not cause an issue if tagsXmlLexedArray contains duplicates", function () {
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      optionsTransformer: function optionsTransformer(options, docxtemplater) {
        docxtemplater.fileTypeConfig.tagsXmlLexedArray.push("w:p", "w:r", "w:p");
        return options;
      }
    };
    var doc = createDocV4("tag-example.docx", {
      modules: [module]
    });
    doc.render({
      first_name: "Hipp",
      last_name: "Edgar",
      phone: "0652455478",
      description: "New Website"
    });
    shouldBeSame({
      doc: doc,
      expectedName: "expected-tag-example.docx"
    });
  });
});
describe("Module traits", function () {
  it("should not cause an issue if using traits.expandTo containing loop", function () {
    var moduleName = "comment-module";
    function getInner(_ref2) {
      var part = _ref2.part,
        leftParts = _ref2.leftParts,
        rightParts = _ref2.rightParts,
        postparse = _ref2.postparse;
      part.subparsed = postparse([].concat(leftParts).concat(rightParts), {
        basePart: part
      });
      return part;
    }
    var module = {
      name: "Test module",
      requiredAPIVersion: "3.0.0",
      parse: function parse(placeHolderContent) {
        if (placeHolderContent[0] === "£") {
          var type = "placeholder";
          return {
            type: type,
            value: placeHolderContent.substr(1),
            module: moduleName
          };
        }
      },
      postparse: function postparse(parsed, _ref3) {
        var postparse = _ref3.postparse;
        parsed = traits.expandToOne(parsed, {
          moduleName: moduleName,
          getInner: getInner,
          expandTo: ["w:p"],
          postparse: postparse
        });
        return parsed;
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            value: ""
          };
        }
      }
    };
    var doc = createDocV4("comment-with-loop.docx", {
      modules: [module]
    });
    doc.render({});
    shouldBeSame({
      doc: doc,
      expectedName: "expected-comment-example.docx"
    });
  });
});
describe("Module errors", function () {
  it("should pass the errors to errorsTransformer", function () {
    var moduleName = "ErrorModule";
    var catched = null;
    var myErrors = [];
    var module = {
      name: "Error module",
      requiredAPIVersion: "3.0.0",
      parse: function parse(placeHolderContent) {
        var type = "placeholder";
        return {
          type: type,
          value: placeHolderContent,
          module: moduleName
        };
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            errors: [new Error("foobar ".concat(part.value))]
          };
        }
      },
      errorsTransformer: function errorsTransformer(errors) {
        pushArray(myErrors, errors);
        return errors.map(function (e) {
          e.xyz = "xxx";
          return e;
        });
      }
    };
    var doc = createDocV4("tag-example.docx", {
      modules: [module]
    });
    var capture = captureLogs();
    try {
      doc.render();
    } catch (e) {
      catched = e;
    }
    capture.stop();
    expect(catched.properties.errors[0].xyz).to.equal("xxx");
    expect(myErrors.length).to.equal(9);
    expect(myErrors[0].message).to.equal("foobar last_name");
  });
  it("should log the error that is returned from render", function () {
    var moduleName = "ErrorModule";
    var module = {
      name: "Error module",
      requiredAPIVersion: "3.0.0",
      parse: function parse(placeHolderContent) {
        var type = "placeholder";
        return {
          type: type,
          value: placeHolderContent,
          module: moduleName
        };
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            errors: [new Error("foobar ".concat(part.value))]
          };
        }
      }
    };
    var error = null;
    var doc = createDocV4("tag-example.docx", {
      modules: [module]
    });
    var capture = captureLogs();
    try {
      doc.render();
    } catch (e) {
      error = e;
    }
    capture.stop();
    expect(error).to.be.an("object");
    expect(error.message).to.equal("Multi error");
    expect(error.properties.errors.length).to.equal(9);
    expect(error.properties.errors[4].properties.file).to.equal("word/document.xml");
    expect(error.properties.errors[4].message).to.equal("foobar last_name");
    expect(error.properties.errors[5].message).to.equal("foobar first_name");
    // expect(error.properties.errors[2].message).to.equal("foobar phone");

    var logs = capture.logs();
    expect(logs.length).to.equal(1, "Incorrect logs count");
    expect(logs[0]).to.contain("foobar last_name");
    expect(logs[0]).to.contain("foobar first_name");
    expect(logs[0]).to.contain("foobar phone");
    expect(logs[0]).to.satisfy(function (log) {
      return (
        // for chrome
        log.indexOf(".render") !== -1 ||
        // for firefox
        log.indexOf("render@") !== -1 ||
        // for bun (https://bun.sh/)
        log.indexOf("render (") !== -1
      );
    });
    var parsedLog = JSON.parse(logs[0]);
    expect(parsedLog.error.length).to.equal(9);
    expect(error.properties.errors[0].properties.file).to.equal("word/header1.xml");
    expect(error.properties.errors[0].message).to.equal("foobar last_name");
    expect(error.properties.errors[1].message).to.equal("foobar first_name");
    expect(error.properties.errors[2].message).to.equal("foobar phone");
    expect(error.properties.errors[6].properties.file).to.equal("word/footer1.xml");
    expect(error.properties.errors[6].message).to.equal("foobar last_name");
  });
  it("should throw specific error if adding same module twice", function () {
    var mod1 = {
      name: "TestModule",
      set: function set() {
        return null;
      }
    };
    var mod2 = {
      name: "TestModule",
      set: function set() {
        return null;
      }
    };

    // This test will test the case where the fixDocPrCorruption is used on two different instances of the docxtemplater library
    expectToThrow(function () {
      return createDocV4("loop-image-footer.docx", {
        modules: [mod1, mod2]
      });
    }, Error, {
      message: 'Detected duplicate module "TestModule"',
      name: "InternalError",
      properties: {}
    });
  });
});
describe("Module should pass options to module.parse, module.postparse, module.render, module.postrender", function () {
  it("should pass filePath and contentType options", function () {
    var filePaths = [],
      relsType = [],
      ct = [];
    var renderFP = "",
      renderCT = "",
      postrenderFP = "",
      postrenderCT = "",
      postparseFP = "",
      postparseCT = "";
    var module = {
      name: "Test module",
      requiredAPIVersion: "3.0.0",
      parse: function parse(a, options) {
        filePaths.push(options.filePath);
        ct.push(options.contentType);
        relsType.push(options.relsType);
      },
      postparse: function postparse(a, options) {
        postparseFP = options.filePath;
        postparseCT = options.contentType;
        return a;
      },
      render: function render(a, options) {
        renderFP = options.filePath;
        renderCT = options.contentType;
      },
      postrender: function postrender(a, options) {
        postrenderFP = options.filePath;
        postrenderCT = options.contentType;
        return a;
      }
    };
    createDocV4("tag-example.docx", {
      modules: [module]
    }).render({});
    expect(renderFP).to.equal("word/footnotes.xml");
    expect(renderCT).to.equal("application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml");
    expect(postparseFP).to.equal("word/footnotes.xml");
    expect(postparseCT).to.equal("application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml");
    expect(postrenderFP).to.equal("word/footnotes.xml");
    expect(postrenderCT).to.equal("application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml");

    /*
     * The order of the filePaths here is important, this has been fixed in
     * version 3.37.8 : First headers are templated, than the document,
     * than the footers.
     */
    expect(filePaths).to.deep.equal([
    // Header appears 4 times because there are 4 tags in the header
    "word/header1.xml", "word/header1.xml", "word/header1.xml", "word/header1.xml",
    // Document appears 2 times because there are 2 tags in the header
    "word/document.xml", "word/document.xml",
    // Footer appears 3 times because there are 3 tags in the header
    "word/footer1.xml", "word/footer1.xml", "word/footer1.xml"]);
    expect(ct).to.deep.equal(["application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml"]);
    expect(relsType).to.deep.equal([undefined,
    // match to header1.xml
    undefined,
    // match to header1.xml
    undefined,
    // match to header1.xml
    undefined,
    // match to header1.xml
    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
    // match to document.xml
    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
    // match to document.xml
    undefined,
    // match to footer1.xml
    undefined,
    // match to footer1.xml
    undefined // match to footer1.xml
    ]);
  });
});
describe("Module detachment", function () {
  it("should detach the module when the module does not support the document filetype", function () {
    var isModuleCalled = false;
    var isDetachedCalled = false;
    var module = {
      optionsTransformer: function optionsTransformer(options) {
        isModuleCalled = true;
        return options;
      },
      on: function on(eventName) {
        if (eventName === "detached") {
          isDetachedCalled = true;
        }
      },
      supportedFileTypes: ["pptx"]
    };
    createDocV4("tag-example.docx", {
      modules: [module]
    });
    expect(isDetachedCalled).to.equal(true);
    expect(isModuleCalled).to.equal(false);
  });
});
describe("Module Matcher API", function () {
  it("should call onMatch function", function () {
    function module1() {
      var myVal = "";
      return {
        name: "module1",
        matchers: function matchers() {
          return [["l", "module-m1", {
            onMatch: function onMatch(part) {
              myVal = part.prefix + part.lIndex + "!!";
            }
          }]];
        },
        render: function render(part) {
          if (part.module === "module-m1") {
            return {
              value: myVal
            };
          }
        }
      };
    }
    expect(this.renderV4({
      name: "tag-example.docx",
      options: {
        modules: [module1()]
      },
      data: {
        first_name: "John"
      },
      expectedText: "l29!! John"
    }));
  });
  it("should automatically choose module with longest value", function () {
    function module1() {
      return {
        name: "module1",
        matchers: function matchers() {
          return [["l", "module-m1"]];
        },
        render: function render(part) {
          if (part.module === "module-m1") {
            return {
              value: part.value
            };
          }
        }
      };
    }
    function module2() {
      return {
        name: "module2",
        matchers: function matchers() {
          return [[/last_(.*)/, "module-m2"]];
        },
        render: function render(part) {
          if (part.module === "module-m2") {
            return {
              value: part.value
            };
          }
        }
      };
    }
    function module3() {
      return {
        name: "module3",
        matchers: function matchers() {
          return [["last", "module-m3"]];
        },
        render: function render(part) {
          if (part.module === "module-m3") {
            return {
              value: part.value
            };
          }
        }
      };
    }
    expect(createDocV4("tag-example.docx", {
      modules: [module1(), module2(), module3()]
    }).render({
      first_name: "John"
    }).getFullText()).to.equal("name John");
    expect(createDocV4("tag-example.docx", {
      modules: [module3(), module2(), module1()]
    }).render({
      first_name: "John"
    }).getFullText()).to.equal("name John");
  });
});
describe("Fix doc pr corruption module", function () {
  it("should work on multiple instances in parallel (in footer)", function () {
    var doc = createDocV4("loop-image-footer.docx", {
      modules: [fixDocPrCorruption]
    });
    // This test will test the case where the fixDocPrCorruption is used on two different instances of the docxtemplater library
    createDocV4("tag-example.docx", {
      modules: [fixDocPrCorruption]
    });
    return doc.renderAsync({
      loop: [1, 2, 3, 4]
    }).then(function () {
      shouldBeSame({
        doc: doc,
        expectedName: "expected-loop-images-footer.docx"
      });
    });
  });
});
describe("Proofstate module", function () {
  it("should work with angular parser with proofstate module", function () {
    shouldBeSame({
      doc: createDocV4("angular-example.docx", {
        parser: expressionParser,
        modules: [proofStateModule]
      }).render({
        person: {
          first_name: "Hipp",
          last_name: "Edgar",
          birth_year: 1955,
          age: 59
        }
      }),
      expectedName: "expected-proofstate-removed.docx"
    });
  });
});
describe("Module calls to on(eventName) to pass events", function () {
  it("should work with v4 synchronously", function () {
    var calls = [];
    var mod = {
      name: "TestModule",
      on: function on(eventName) {
        calls.push(eventName);
      }
    };
    createDocV4("loop-image-footer.docx", {
      modules: [mod]
    }).render({
      loop: [1, 2, 3, 4]
    });
    expect(calls).to.deep.equal(["attached", "before-preparse", "after-preparse", "after-parse", "after-postparse", "syncing-zip", "synced-zip"]);
  });
});
describe("Module call order", function () {
  it("should work with v4 synchronously", function () {
    var calls = [];
    var mod = {
      name: "TestModule",
      set: function set() {
        calls.push("set");
        return null;
      },
      matchers: function matchers() {
        calls.push("matchers");
        return [];
      },
      render: function render() {
        calls.push("render");
        return null;
      },
      optionsTransformer: function optionsTransformer(options) {
        calls.push("optionsTransformer");
        return options;
      },
      preparse: function preparse() {
        calls.push("preparse");
        return null;
      },
      parse: function parse() {
        calls.push("parse");
        return null;
      },
      postparse: function postparse() {
        calls.push("postparse");
        return null;
      },
      getTraits: function getTraits() {
        calls.push("getTraits");
      },
      getFileType: function getFileType() {
        calls.push("getFileType");
      },
      nullGetter: function nullGetter() {
        calls.push("nullGetter");
      },
      postrender: function postrender() {
        calls.push("postrender");
        return [];
      },
      errorsTransformer: function errorsTransformer() {
        calls.push("errorsTransformer");
      },
      getRenderedMap: function getRenderedMap(obj) {
        calls.push("getRenderedMap");
        return obj;
      },
      on: function on() {
        calls.push("on");
      },
      resolve: function resolve() {
        calls.push("resolve");
      }
    };
    createDocV4("loop-image-footer.docx", {
      modules: [mod]
    }).render({
      loop: [1, 2, 3, 4]
    });
    expect(uniq(calls)).to.deep.equal(["on", "set", "getFileType", "optionsTransformer", "preparse", "matchers", "getTraits", "postparse", "errorsTransformer", "getRenderedMap", "render", "postrender"]);
  });
  it("should work with v4 async", function () {
    var calls = [],
      parseValues = [],
      preparsedFilePaths = [];
    var mod = {
      name: "TestModule",
      set: function set() {
        calls.push("set");
        return null;
      },
      matchers: function matchers() {
        calls.push("matchers");
        return [];
      },
      render: function render() {
        calls.push("render");
        return null;
      },
      optionsTransformer: function optionsTransformer(options) {
        calls.push("optionsTransformer");
        return options;
      },
      preparse: function preparse(_, options) {
        preparsedFilePaths.push(options.filePath);
        calls.push("preparse");
        return null;
      },
      parse: function parse(part) {
        parseValues.push(part);
        calls.push("parse");
        return null;
      },
      postparse: function postparse() {
        calls.push("postparse");
        return null;
      },
      getTraits: function getTraits() {
        calls.push("getTraits");
      },
      getFileType: function getFileType() {
        calls.push("getFileType");
      },
      nullGetter: function nullGetter() {
        calls.push("nullGetter");
      },
      postrender: function postrender() {
        calls.push("postrender");
        return [];
      },
      errorsTransformer: function errorsTransformer() {
        calls.push("errorsTransformer");
      },
      getRenderedMap: function getRenderedMap(obj) {
        calls.push("getRenderedMap");
        return obj;
      },
      on: function on() {
        calls.push("on");
      },
      resolve: function resolve() {
        calls.push("resolve");
      }
    };
    return createDocV4("tag-example.docx", {
      modules: [mod]
    }).renderAsync({
      loop: [1, 2, 3, 4]
    }).then(function () {
      expect(parseValues).to.deep.equal(["last_name", "first_name", "phone", "description", "last_name", "first_name", "last_name", "first_name", "phone"]);
      expect(parseValues.length).to.equal(9);
      expect(preparsedFilePaths).to.deep.equal(["word/settings.xml", "docProps/core.xml", "docProps/app.xml", "word/header1.xml", "word/document.xml", "word/footer1.xml", "word/footnotes.xml"]);
      expect(preparsedFilePaths.length).to.equal(7);
      expect(uniqTimes(calls)).to.deep.equal([
      // Runs on("attached") (module is attached), after-preparse, ...
      ["on", 7],
      // Runs multiple times to set xmllexed, filePath, parsed
      ["set", 62],
      /*
       * Runs Twice, it should theoretically run once
       * #tofix-getFileType-twice . However for some modules, if
       * you run it just once, the modules break (this is in
       * particular if you use const doc = new Docxtemplater();
       * doc.attachModule() which is now deprecated
       */
      ["getFileType", 2],
      // Runs Once
      ["optionsTransformer", 1],
      // Runs for each templatedFile
      ["preparse", 7],
      // Runs for each tag
      ["matchers", 9],
      // Runs for each tag
      ["parse", 9],
      // Runs for each templatedFile
      ["getTraits", 7],
      // Runs for each templatedFile
      ["postparse", 7],
      // Runs for each templatedFile
      ["errorsTransformer", 7],
      // Runs Once
      ["getRenderedMap", 1],
      // Runs for each tag * data
      ["resolve", 9],
      // Runs for each tag * data
      ["nullGetter", 9],
      // Runs for each xml tag or placeholder tag
      ["render", 242],
      // Runs for each templatedFile
      ["postrender", 7]]);
    });
  });
  it("should work with v3", function () {
    var calls = [];
    var mod = {
      name: "TestModule",
      set: function set() {
        calls.push("set");
        return null;
      },
      matchers: function matchers() {
        calls.push("matchers");
        return [];
      },
      render: function render() {
        calls.push("render");
        return null;
      },
      optionsTransformer: function optionsTransformer(options) {
        calls.push("optionsTransformer");
        return options;
      },
      preparse: function preparse() {
        calls.push("preparse");
        return null;
      },
      parse: function parse() {
        calls.push("parse");
        return null;
      },
      postparse: function postparse() {
        calls.push("postparse");
        return null;
      },
      getTraits: function getTraits() {
        calls.push("getTraits");
      },
      getFileType: function getFileType() {
        calls.push("getFileType");
      },
      nullGetter: function nullGetter() {
        calls.push("nullGetter");
      },
      postrender: function postrender() {
        calls.push("postrender");
        return [];
      },
      errorsTransformer: function errorsTransformer() {
        calls.push("errorsTransformer");
      },
      getRenderedMap: function getRenderedMap(obj) {
        calls.push("getRenderedMap");
        return obj;
      },
      on: function on() {
        calls.push("on");
      },
      resolve: function resolve() {
        calls.push("on");
      }
    };
    this.render({
      name: "loop-image-footer.docx",
      options: {
        modules: [mod]
      },
      data: {
        loop: [1, 2, 3, 4]
      }
    });
    expect(uniq(calls)).to.deep.equal(["on", "set", "getFileType", "optionsTransformer", "preparse", "matchers", "getTraits", "postparse", "errorsTransformer", "getRenderedMap", "render", "postrender"]);
  });
});
describe("Module priority", function () {
  it("should reorder modules #test-reorder-modules", function () {
    var doc = createDocV4("loop-image-footer.docx", {
      modules: [{
        priority: 4,
        name: "M1",
        parse: function parse(parsed) {
          return parsed;
        }
      }, {
        priority: -1,
        name: "M2",
        parse: function parse(parsed) {
          return parsed;
        }
      }, {
        priority: 5,
        name: "M3",
        parse: function parse(parsed) {
          return parsed;
        }
      }, {
        priority: 5,
        name: "M4",
        parse: function parse(parsed) {
          return parsed;
        }
      }, {
        priority: 5,
        name: "M5",
        parse: function parse(parsed) {
          return parsed;
        }
      }]
    });
    var orderedNames = doc.modules.map(function (_ref4) {
      var name = _ref4.name;
      return name;
    });
    expect(orderedNames).to.deep.equal(["M3",
    // Priority 5
    "M4",
    // Priority 5
    "M5",
    // Priority 5
    "M1",
    // Priority 4

    // All default modules have default priority of 0
    "LoopModule", "SpacePreserveModule", "ExpandPairTrait", "RawXmlModule", "Render", "Common", "AssertionModule", "M2" // Priority -1
    ]);
  });
});