text: var assert = require("assert");
  var eslint = require("eslint");
  var fs = require("fs");
  var path = require("path");
  
  var paths = {
    fixtures: path.join(__dirname, "fixtures", "rules"),
  };
  
  var encoding = "utf8";
  var errorLevel = 2;
  
  var baseEslintOpts = {
    parser: require.resolve(".."),
    parserOptions: {
      sourceType: "script"
    }
  };
  
  /**
   * Load a fixture and run eslint.linter.verify() on it.
   * Pass the return value to done().
   * @param object opts
   * @param function done
   */
  function lint (opts, done) {
    readFixture(opts.fixture, (err, src) => {
      if (err) return done(err);
      done(null, eslint.linter.verify(src, opts.eslint));
    });
  }
  
  /**
   * Read a fixture file, passing the content to done().
   * @param string|array id
   * @param function done
   */
  function readFixture (id, done) {
    if (Array.isArray(id)) id = path.join.apply(path, id);
    if (!path.extname(id)) id += ".js";
    fs.readFile(
      path.join(paths.fixtures, id),
      encoding,
      done
    );
  }
  // readFixture
  
  describe("Rules:", () => {
    describe("`strict`", strictSuite);
  });
  // describe
  
  function strictSuite () {
    var ruleId = "strict";
  
    describe("when set to 'never'", () => {
      var eslintOpts = Object.assign({}, baseEslintOpts, {
        rules: {},
      });
      eslintOpts.rules[ruleId] = [errorLevel, "never"];
  
      ["global-with", "function-with"].forEach((fixture) => {
        it(`should error on ${fixture.match(/^[^-]+/)[0]} directive`,
          (done) => {
            lint({
              fixture: ["strict", fixture],
              eslint: eslintOpts,
            }, (err, report) => {
              if (err) return done(err);
              assert(report[0].ruleId === ruleId);
              done();
            });
          }
        );
        // it
      });
    });
    // describe
  
    describe("when set to 'global'", () => {
      var eslintOpts = Object.assign({}, baseEslintOpts, {
        rules: {}
      });
      eslintOpts.rules[ruleId] = [errorLevel, "global"];
  
      it("shouldn't error on single global directive", (done) => {
        lint({
          fixture: ["strict", "global-with"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          assert(!report.length);
          done();
        });
      });
      // it
  
      it("should error twice on global directive: no and function directive: yes", (done) => {
        lint({
          fixture: ["strict", "function-with"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          [0, 1].forEach((i) => {
            assert(report[i].ruleId === ruleId);
          });
          done();
        });
      });
      // it
  
      it("should error on function directive", (done) => {
        lint({
          fixture: ["strict", "global-with-function-with"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          assert(report[0].ruleId === ruleId);
  
          // This is to make sure the test fails prior to adapting Babel AST
          // directive representation to ESLint format. Otherwise it reports an
          // error for missing global directive that masquerades as the expected
          // result of the previous assertion.
          assert(report[0].nodeType !== "Program");
          done();
        });
      });
      // it
  
      it("should error on no directive", (done) => {
        lint({
          fixture: ["strict", "none"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          assert(report[0].ruleId === ruleId);
          done();
        });
      });
      // it
    });
    // describe
  
    describe("when set to 'function'", () => {
      var eslintOpts = Object.assign({}, baseEslintOpts, {
        rules: {}
      });
      eslintOpts.rules[ruleId] = [errorLevel, "function"];
  
      it("shouldn't error on single function directive", (done) => {
        lint({
          fixture: ["strict", "function-with"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          assert(!report.length);
          done();
        });
      });
      // it
  
      it("should error twice on function directive: no and global directive: yes", (done) => {
        lint({
          fixture: ["strict", "global-with-function-without"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          [0, 1].forEach((i) => {
            assert(report[i].ruleId === ruleId);
          });
          done();
        });
      });
      // it
  
      it("should error on only global directive", (done) => {
        lint({
          fixture: ["strict", "global-with"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          assert(report[0].ruleId === ruleId);
          done();
        });
      });
      // it
  
      it("should error on extraneous global directive", (done) => {
        lint({
          fixture: ["strict", "global-with-function-with"],
          eslint: eslintOpts,
        }, (err, report) => {
          if (err) return done(err);
          assert(report[0].ruleId === ruleId);
          assert(report[0].nodeType.indexOf("Function") === -1);
          done();
        });
      });
      // it
    });
    // describe
    describe("When \"codeFrame\"", () => {
      // Strip chalk colors, these are not relevant for the test
      const stripAnsi = (str) => str.replace(
        /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
        ""
      );
  
      it("should display codeFrame when option is absent", (done) => {
        lint({
          fixture: ["syntax-error"],
          eslint: baseEslintOpts
        }, (err, report) => {
          if (err) return done(err);
          assert(stripAnsi(report[0].message).indexOf("^\n  5 |") > -1);
          done();
        });
      });
  
      it("should display codeFrame when option is true", (done) => {
        lint({
          fixture: ["syntax-error"],
          eslint: Object.assign({}, baseEslintOpts, {
            parserOptions: {
              codeFrame: true
            }
          })
        }, (err, report) => {
          if (err) return done(err);
          assert(stripAnsi(report[0].message).indexOf("^\n  5 |") > -1);
          done();
        });
      });
  
      it("should not display codeFrame when option is false", (done) => {
        lint({
          fixture: ["syntax-error"],
          eslint: Object.assign({}, baseEslintOpts, {
            parserOptions: {
              codeFrame: false
            }
          })
        }, (err, report) => {
          if (err) return done(err);
          assert(stripAnsi(report[0].message).indexOf("^\n  5 |") === -1);
          done();
        });
      });
    });
  }
  