"use strict";

var _require = require("../utils.js"),
  expect = _require.expect,
  expectToThrow = _require.expectToThrow,
  captureLogs = _require.captureLogs,
  makeDocxV4 = _require.makeDocxV4,
  wrapMultiError = _require.wrapMultiError,
  expectToThrowSnapshot = _require.expectToThrowSnapshot;
var Docxtemplater = require("../../docxtemplater.js");
var _Docxtemplater$DocUti = Docxtemplater.DocUtils,
  traits = _Docxtemplater$DocUti.traits,
  isContent = _Docxtemplater$DocUti.isContent;
var Errors = Docxtemplater.Errors;
var XTTemplateError = Errors.XTTemplateError;
describe("Traits", function () {
  it("should work with expandToOne and call onError if multiple tags in same paragraph", function () {
    var moduleName = "foo_module/foo";
    var ignoredErrors = [];
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      matchers: function matchers() {
        return [["__", moduleName]];
      },
      postparse: function postparse(parsed) {
        parsed = traits.expandToOne(parsed, {
          moduleName: moduleName,
          getInner: function getInner(_ref) {
            var part = _ref.part,
              left = _ref.left,
              right = _ref.right,
              postparsed = _ref.postparsed,
              index = _ref.index;
            var paragraphParts = postparsed.slice(left + 1, right);
            var error = false;
            for (var i = 0, len = paragraphParts.length; i < len; i++) {
              var p = paragraphParts[i];
              if (i === index - left - 1) {
                continue;
              }
              if (isContent(p)) {
                error = true;
              }
            }
            if (error === true) {
              // This error wil be catched by onError and then ignored (and put into ignoredErrs)
              var err = new XTTemplateError("Foo tag should be the only text in a paragraph");
              throw err;
            }
            return part;
          },
          expandTo: "w:p",
          onError: function onError(opts) {
            var part = opts.part;
            ignoredErrors.push("".concat(opts.rootError.name, " ").concat(opts.rootError.message));
            if (part.module === moduleName) {
              return "ignore";
            }
          }
        });
        return parsed;
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            value: "MYVAL"
          };
        }
      }
    };
    var doc = makeDocxV4("<w:p><w:t>Foo {__user} {__bar}</w:t></w:p>", {
      modules: [module]
    }).render();
    expect(ignoredErrors).to.deep.equal(["TemplateError Foo tag should be the only text in a paragraph"]);
    expect(doc.getFullText()).to.be.equal("Foo MYVAL MYVAL");
  });
  it("should work with expandToOne and call onError if no surrounding paragraphs found", function () {
    var moduleName = "foo_module/foo";
    var ignoredErrors = [];
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      matchers: function matchers() {
        return [["__", moduleName]];
      },
      postparse: function postparse(parsed) {
        parsed = traits.expandToOne(parsed, {
          moduleName: moduleName,
          expandTo: "w:p",
          onError: function onError(opts) {
            var part = opts.part;
            ignoredErrors.push("".concat(opts.name || opts.rootError.name, " ").concat(opts.message || opts.rootError.message));
            if (part.module === moduleName) {
              return "ignore";
            }
          },
          error: {
            message: "FooModule tag should be the only text in a paragraph",
            id: "foo_tag_w_p_noexpand"
          }
        });
        return parsed;
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            value: "MYVAL"
          };
        }
      }
    };
    var doc = makeDocxV4("<w:t>Foo {__user} {__bar}</w:t></w:p>", {
      modules: [module]
    }).render();
    expect(ignoredErrors).to.deep.equal(["TemplateError FooModule tag should be the only text in a paragraph", "TemplateError FooModule tag should be the only text in a paragraph"]);
    expect(doc.getFullText()).to.be.equal("Foo MYVAL MYVAL");
  });
  it("should just call onError but keep it if the return value is not a string", function () {
    var moduleName = "foo_module/foo";
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      matchers: function matchers() {
        return [["__", moduleName]];
      },
      postparse: function postparse(parsed) {
        parsed = traits.expandToOne(parsed, {
          moduleName: moduleName,
          getInner: function getInner(_ref2) {
            var part = _ref2.part,
              left = _ref2.left,
              right = _ref2.right,
              postparsed = _ref2.postparsed,
              index = _ref2.index;
            var paragraphParts = postparsed.slice(left + 1, right);
            var error = false;
            for (var i = 0, len = paragraphParts.length; i < len; i++) {
              var p = paragraphParts[i];
              if (i === index - left - 1) {
                continue;
              }
              if (isContent(p)) {
                error = true;
              }
            }
            if (error === true) {
              var err = new XTTemplateError("Foo tag should be the only text in a paragraph");
              err.properties = {
                explanation: "Foo tag",
                id: "foo_id"
              };
              throw err;
            }
            return part;
          },
          expandTo: "w:p",
          onError: function onError() {
            // Do nothing with the error
            return;
          }
        });
        return parsed;
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            value: "MYVAL"
          };
        }
      }
    };
    var capture = captureLogs();
    expectToThrow(function () {
      return makeDocxV4("<w:p><w:t>Foo {__user} {__bar}</w:t></w:p>", {
        modules: [module]
      }).render();
    }, XTTemplateError, wrapMultiError({
      name: "TemplateError",
      message: "Foo tag should be the only text in a paragraph",
      properties: {
        id: "foo_id",
        file: "word/document.xml"
      }
    }));
    capture.stop();
  });
  it("should just call onError but keep it if the return value is not a string", function () {
    var moduleName = "foo_module/foo";
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      matchers: function matchers() {
        return [["__", moduleName]];
      },
      postparse: function postparse(parsed) {
        parsed = traits.expandToOne(parsed, {
          moduleName: moduleName,
          getInner: function getInner(_ref3) {
            var part = _ref3.part,
              left = _ref3.left,
              right = _ref3.right,
              postparsed = _ref3.postparsed,
              index = _ref3.index;
            var paragraphParts = postparsed.slice(left + 1, right);
            var error = false;
            for (var i = 0, len = paragraphParts.length; i < len; i++) {
              var p = paragraphParts[i];
              if (i === index - left - 1) {
                continue;
              }
              if (isContent(p)) {
                error = true;
              }
            }
            if (error === true) {
              // This error wil be catched by onError and then ignored (and put into ignoredErrs)
              var err = new XTTemplateError("Foo tag should be the only text in a paragraph");
              err.properties = {
                explanation: "Hello",
                id: "foo_id"
              };
              throw err;
            }
            return part;
          },
          expandTo: "w:p",
          onError: function onError() {
            return "";
          }
        });
        return parsed;
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            value: "MYVAL"
          };
        }
      }
    };
    var capture = captureLogs();
    expectToThrowSnapshot(function () {
      return makeDocxV4("<w:t>Foo {__user} {__bar}</w:t></w:p>", {
        modules: [module]
      }).render();
    });
    capture.stop();
  });
  it("should just work if onError throws an error", function () {
    var moduleName = "foo_module/foo";
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      matchers: function matchers() {
        return [["__", moduleName]];
      },
      postparse: function postparse(parsed) {
        parsed = traits.expandToOne(parsed, {
          moduleName: moduleName,
          getInner: function getInner(_ref4) {
            var part = _ref4.part,
              left = _ref4.left,
              right = _ref4.right,
              postparsed = _ref4.postparsed,
              index = _ref4.index;
            var paragraphParts = postparsed.slice(left + 1, right);
            var error = false;
            for (var i = 0, len = paragraphParts.length; i < len; i++) {
              var p = paragraphParts[i];
              if (i === index - left - 1) {
                continue;
              }
              if (isContent(p)) {
                error = true;
              }
            }
            if (error === true) {
              var err = new XTTemplateError("Foo tag should be the only text in a paragraph");
              err.properties = {
                explanation: "Foo tag",
                id: "foo_id"
              };
              throw err;
            }
            return part;
          },
          expandTo: "w:p",
          onError: function onError() {
            throw new Error("Other error");
          }
        });
        return parsed;
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            value: "MYVAL"
          };
        }
      }
    };
    var capture = captureLogs();
    var expectedError;
    try {
      makeDocxV4("<w:p><w:t>Foo {__user} {__bar}</w:t></w:p>", {
        modules: [module]
      }).render();
    } catch (e) {
      expectedError = e;
    }
    expect(expectedError.message).to.equal("Other error");
    capture.stop();
  });
  it("should just work if getInner throws an error", function () {
    var moduleName = "foo_module/foo";
    var module = {
      name: "FooModule",
      requiredAPIVersion: "3.0.0",
      matchers: function matchers() {
        return [["__", moduleName]];
      },
      postparse: function postparse(parsed) {
        parsed = traits.expandToOne(parsed, {
          moduleName: moduleName,
          getInner: function getInner() {
            throw new Error("Error from inner");
          },
          expandTo: "w:p"
        });
        return parsed;
      },
      render: function render(part) {
        if (part.module === moduleName) {
          return {
            value: "MYVAL"
          };
        }
      }
    };
    var capture = captureLogs();
    var expectedError;
    try {
      makeDocxV4("<w:p><w:t>Foo {__user} {__bar}</w:t></w:p>", {
        modules: [module]
      }).render();
    } catch (e) {
      expectedError = e;
    }
    expect(expectedError.message).to.equal("Error from inner");
    capture.stop();
  });
});