"use strict";

var events = require("../../").Runner.constants;
var helpers = require("./helpers.cjs");
var reporters = require("../../").reporters;

var Doc = reporters.Doc;
var createMockRunner = helpers.createMockRunner;
var createRunReporterFunction = helpers.createRunReporterFunction;

var EVENT_SUITE_BEGIN = events.EVENT_SUITE_BEGIN;
var EVENT_SUITE_END = events.EVENT_SUITE_END;
var EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;
var EVENT_TEST_PASS = events.EVENT_TEST_PASS;

describe("Doc reporter", function () {
  var runner;
  var options = {};
  var runReporter = createRunReporterFunction(Doc);

  afterEach(function () {
    runner = null;
  });

  describe("event handlers", function () {
    describe("on 'suite' event", function () {
      describe("when suite root does not exist", function () {
        var expectedTitle = "expectedTitle";
        var unescapedTitle = "<div>" + expectedTitle + "</div>";
        var suite = {
          root: false,
          title: expectedTitle,
        };

        it("should log html with indents and expected title", async function () {
          runner = createMockRunner(
            "suite",
            EVENT_SUITE_BEGIN,
            null,
            null,
            suite,
          );
          var { stdout } = await runReporter({}, runner, options);
          var expectedArray = [
            '    <section class="suite">\n',
            "      <h1>" + expectedTitle + "</h1>\n",
            "      <dl>\n",
          ];
          expect(stdout, "to equal", expectedArray);
        });

        it("should escape title where necessary", async function () {
          var suite = {
            root: false,
            title: unescapedTitle,
          };
          expectedTitle =
            "&#x3C;div&#x3E;" + expectedTitle + "&#x3C;/div&#x3E;";

          runner = createMockRunner(
            "suite",
            EVENT_SUITE_BEGIN,
            null,
            null,
            suite,
          );
          var { stdout } = await runReporter({}, runner, options);
          var expectedArray = [
            '    <section class="suite">\n',
            "      <h1>" + expectedTitle + "</h1>\n",
            "      <dl>\n",
          ];
          expect(stdout, "to equal", expectedArray);
        });
      });

      describe("when suite root exists", function () {
        var suite = {
          root: true,
        };

        it("should not log any html", async function () {
          runner = createMockRunner(
            "suite",
            EVENT_SUITE_BEGIN,
            null,
            null,
            suite,
          );
          var { stdout } = await runReporter({}, runner, options);
          expect(stdout, "to be empty");
        });
      });
    });

    describe("on 'suite end' event", function () {
      describe("when suite root does not exist", function () {
        var suite = {
          root: false,
        };

        it("should log expected html with indents", async function () {
          runner = createMockRunner(
            "suite end",
            EVENT_SUITE_END,
            null,
            null,
            suite,
          );
          var { stdout } = await runReporter({}, runner, options);
          var expectedArray = ["  </dl>\n", "</section>\n"];
          expect(stdout, "to equal", expectedArray);
        });
      });

      describe("when suite root exists", function () {
        var suite = {
          root: true,
        };

        it("should not log any html", async function () {
          runner = createMockRunner(
            "suite end",
            EVENT_SUITE_END,
            null,
            null,
            suite,
          );
          var { stdout } = await runReporter({}, runner, options);
          expect(stdout, "to be empty");
        });
      });
    });

    describe("on 'pass' event", function () {
      var expectedTitle = "some tite";
      var expectedFile = "testFile.spec.js";
      var expectedBody = "some body";
      var test = {
        title: expectedTitle,
        file: expectedFile,
        body: expectedBody,
        slow: function () {
          return "";
        },
      };

      it("should log html with indents, expected title, and body", async function () {
        runner = createMockRunner("pass", EVENT_TEST_PASS, null, null, test);
        var { stdout } = await runReporter({}, runner, options);
        var expectedArray = [
          "    <dt>" + expectedTitle + "</dt>\n",
          "    <dt>" + expectedFile + "</dt>\n",
          "    <dd><pre><code>" + expectedBody + "</code></pre></dd>\n",
        ];
        expect(stdout, "to equal", expectedArray);
      });

      it("should escape title and body where necessary", async function () {
        var unescapedTitle = "<div>" + expectedTitle + "</div>";
        var unescapedFile = "<div>" + expectedFile + "</div>";
        var unescapedBody = "<div>" + expectedBody + "</div>";
        test.title = unescapedTitle;
        test.file = unescapedFile;
        test.body = unescapedBody;

        var expectedEscapedTitle =
          "&#x3C;div&#x3E;" + expectedTitle + "&#x3C;/div&#x3E;";
        var expectedEscapedFile =
          "&#x3C;div&#x3E;" + expectedFile + "&#x3C;/div&#x3E;";
        var expectedEscapedBody =
          "&#x3C;div&#x3E;" + expectedBody + "&#x3C;/div&#x3E;";
        runner = createMockRunner("pass", EVENT_TEST_PASS, null, null, test);
        var { stdout } = await runReporter({}, runner, options);
        var expectedArray = [
          "    <dt>" + expectedEscapedTitle + "</dt>\n",
          "    <dt>" + expectedEscapedFile + "</dt>\n",
          "    <dd><pre><code>" + expectedEscapedBody + "</code></pre></dd>\n",
        ];
        expect(stdout, "to equal", expectedArray);
      });
    });

    describe("on 'fail' event", function () {
      var expectedTitle = "some tite";
      var expectedFile = "testFile.spec.js";
      var expectedBody = "some body";
      var expectedError = "some error";
      var test = {
        title: expectedTitle,
        file: expectedFile,
        body: expectedBody,
        slow: function () {
          return "";
        },
      };

      it("should log html with indents, expected title, body, and error", async function () {
        runner = createMockRunner(
          "fail two args",
          EVENT_TEST_FAIL,
          null,
          null,
          test,
          expectedError,
        );
        var { stdout } = await runReporter({}, runner, options);
        var expectedArray = [
          '    <dt class="error">' + expectedTitle + "</dt>\n",
          '    <dt class="error">' + expectedFile + "</dt>\n",
          '    <dd class="error"><pre><code>' +
            expectedBody +
            "</code></pre></dd>\n",
          '    <dd class="error">' + expectedError + "</dd>\n",
        ];
        expect(stdout, "to equal", expectedArray);
      });

      it("should escape title, body, and error where necessary", async function () {
        var unescapedTitle = "<div>" + expectedTitle + "</div>";
        var unescapedFile = "<div>" + expectedFile + "</div>";
        var unescapedBody = "<div>" + expectedBody + "</div>";
        var unescapedError = "<div>" + expectedError + "</div>";
        test.title = unescapedTitle;
        test.file = unescapedFile;
        test.body = unescapedBody;

        var expectedEscapedTitle =
          "&#x3C;div&#x3E;" + expectedTitle + "&#x3C;/div&#x3E;";
        var expectedEscapedFile =
          "&#x3C;div&#x3E;" + expectedFile + "&#x3C;/div&#x3E;";
        var expectedEscapedBody =
          "&#x3C;div&#x3E;" + expectedBody + "&#x3C;/div&#x3E;";
        var expectedEscapedError =
          "&#x3C;div&#x3E;" + expectedError + "&#x3C;/div&#x3E;";
        runner = createMockRunner(
          "fail two args",
          EVENT_TEST_FAIL,
          null,
          null,
          test,
          unescapedError,
        );
        var { stdout } = await runReporter({}, runner, options);
        var expectedArray = [
          '    <dt class="error">' + expectedEscapedTitle + "</dt>\n",
          '    <dt class="error">' + expectedEscapedFile + "</dt>\n",
          '    <dd class="error"><pre><code>' +
            expectedEscapedBody +
            "</code></pre></dd>\n",
          '    <dd class="error">' + expectedEscapedError + "</dd>\n",
        ];
        expect(stdout, "to equal", expectedArray);
      });
    });
  });
});
