"use strict";

var path = require("node:path");
var utils = require("../../lib/utils");

describe("stackTraceFilter()", function () {
  describe("on node", function () {
    var filter = utils.stackTraceFilter();

    describe("on POSIX OS", function () {
      before(function () {
        if (path.sep !== "/") {
          this.skip();
        }
      });

      it("should get a stack-trace as a string and prettify it", function () {
        var stack = [
          "AssertionError: foo bar",
          "at EventEmitter.<anonymous> (/usr/local/dev/test.js:16:12)",
          "at Context.<anonymous> (/usr/local/dev/test.js:19:5)",
          "Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:244:7)",
          "Runner.runTest (/usr/local/lib/node_modules/mocha/lib/runner.js:374:10)",
          "/usr/local/lib/node_modules/mocha/lib/runner.js:452:12",
          "next (/usr/local/lib/node_modules/mocha/lib/runner.js:299:14)",
          "/usr/local/lib/node_modules/mocha/lib/runner.js:309:7",
          "next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)",
          "Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)",
          "at processImmediate [as _immediateCallback] (timers.js:321:17)",
        ];
        expect(filter(stack.join("\n")), "to be", stack.slice(0, 3).join("\n"));

        stack = [
          "AssertionError: bar baz",
          "at /usr/local/dev/some-test-file.js:25:8",
          "at tryCatcher (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/util.js:24:31)",
          "at Promise._resolveFromResolver (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:439:31)",
          "at new Promise (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:53:37)",
          "at yourFunction (/usr/local/dev/own/tmp/test1.js:24:13)",
          "at Context.<anonymous> (/usr/local/dev/some-test-file:30:4)",
          "Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:218:15)",
          "next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)",
          "Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)",
          "at processImmediate [as _immediateCallback] (timers.js:321:17)",
        ];

        expect(filter(stack.join("\n")), "to be", stack.slice(0, 7).join("\n"));
      });

      it("does not ignore other bower_components and components", function () {
        var stack = [
          "Error: failed",
          "at assert (index.html:11:26)",
          "at Context.<anonymous> (test.js:17:18)",
          "at bower_components/should/should.js:4827:7",
          "at next (file:///.../bower_components/should/should.js:4766:23)",
          "at components/should/5.0.0/should.js:4827:7",
          "at next (file:///.../components/should/5.0.0/should.js:4766:23)",
          "at file:///.../bower_components/mocha/mocha.js:4794:5",
          "at timeslice (.../components/mocha/mocha.js:6218:27)",
          "at Test.require.register.Runnable.run (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4463:15)",
          "at Runner.require.register.Runner.runTest (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4892:10)",
          "at file:///.../components/mochajs/mocha/2.1.0/mocha.js:4970:12",
          "at next (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4817:14)",
        ];
        expect(filter(stack.join("\n")), "to be", stack.slice(0, 7).join("\n"));
      });

      it("should replace absolute with relative paths", function () {
        var stack = [
          "Error: " + process.cwd() + "/bla.js has a problem",
          "at foo (" + process.cwd() + "/foo/index.js:13:226)",
          "at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)",
        ];

        var expected = [
          "Error: " + process.cwd() + "/bla.js has a problem",
          "at foo (foo/index.js:13:226)",
          "at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)",
        ];

        expect(filter(stack.join("\n")), "to be", expected.join("\n"));
      });

      it("should not replace absolute path which has cwd as infix", function () {
        var stack = [
          "Error: /www" + process.cwd() + "/bla.js has a problem",
          "at foo (/www" + process.cwd() + "/foo/index.js:13:226)",
          "at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)",
        ];

        var expected = [
          "Error: /www" + process.cwd() + "/bla.js has a problem",
          "at foo (/www" + process.cwd() + "/foo/index.js:13:226)",
          "at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)",
        ];

        expect(filter(stack.join("\n")), "to be", expected.join("\n"));
      });
    });

    describe("on Windows", function () {
      before(function () {
        if (path.sep === "/") {
          this.skip();
        }
      });

      it("should work on Windows", function () {
        var stack = [
          "Error: failed",
          "at Context.<anonymous> (C:\\Users\\ishida\\src\\test\\test\\mytest.js:5:9)",
          "at callFn (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runnable.js:326:21)",
          "at Test.Runnable.run (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runnable.js:319:7)",
          "at Runner.runTest (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:422:10)",
          "at C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:528:12",
          "at next (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:342:14)",
          "at C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:352:7",
          "at next (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:284:14)",
          "at Immediate._onImmediate (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:320:5)",
        ];
        expect(filter(stack.join("\n")), "to be", stack.slice(0, 2).join("\n"));
      });
    });
  });

  describe("on browser", function () {
    var filter;
    before(function () {
      global.document = true;
      global.location = { href: "localhost:3000/foo/bar/index.html" };
      filter = utils.stackTraceFilter();
    });
    it("does not strip out other bower_components", function () {
      var stack = [
        "Error: failed",
        "at assert (index.html:11:26)",
        "at Context.<anonymous> (test.js:17:18)",
        "at bower_components/should/should.js:4827:7",
        "at next (bower_components/should/should.js:4766:23)",
        "at components/should/5.0.0/should.js:4827:7",
        "at next (components/should/5.0.0/should.js:4766:23)",
        "at Runner.require.register.Runner.runTest (node_modules/mocha.js:4892:10)",
        "at localhost:3000/foo/bar/node_modules/mocha.js:4970:12",
        "at next (node_modules/mocha.js:4817:14)",
      ];
      expect(filter(stack.join("\n")), "to be", stack.slice(0, 7).join("\n"));
    });

    after(function () {
      delete global.document;
      delete global.location;
    });
  });
});
