pve-eslint/eslint/tests/lib/cli-engine/file-enumerator.js
Dominik Csapak 56c4a2cb43 upgrade to v7.0.0
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2020-05-22 13:50:35 +02:00

488 lines
22 KiB
JavaScript

/**
* @fileoverview Tests for FileEnumerator class.
* @author Toru Nagashima <https://github.com/mysticatea>
*/
"use strict";
const fs = require("fs");
const path = require("path");
const os = require("os");
const { assert } = require("chai");
const sh = require("shelljs");
const { CascadingConfigArrayFactory } =
require("../../../lib/cli-engine/cascading-config-array-factory");
const { defineFileEnumeratorWithInMemoryFileSystem } = require("../../_utils");
describe("FileEnumerator", () => {
describe("'iterateFiles(patterns)' method should iterate files and configs.", () => {
describe("with three directories ('lib', 'lib/nested', 'test') that contains 'one.js' and 'two.js'", () => {
const root = path.join(os.tmpdir(), "eslint/file-enumerator");
const files = {
/* eslint-disable quote-props */
"lib": {
"nested": {
"one.js": "",
"two.js": "",
"parser.js": "",
".eslintrc.yml": "parser: './parser'"
},
"one.js": "",
"two.js": ""
},
"test": {
"one.js": "",
"two.js": "",
".eslintrc.yml": "env: { mocha: true }"
},
".eslintignore": "/lib/nested/parser.js",
".eslintrc.json": JSON.stringify({
rules: {
"no-undef": "error",
"no-unused-vars": "error"
}
})
/* eslint-enable quote-props */
};
const { FileEnumerator } = defineFileEnumeratorWithInMemoryFileSystem({ cwd: () => root, files });
/** @type {FileEnumerator} */
let enumerator;
beforeEach(() => {
enumerator = new FileEnumerator();
});
it("should ignore empty strings.", () => {
Array.from(enumerator.iterateFiles(["lib/*.js", ""])); // don't throw "file not found" error.
});
describe("if 'lib/*.js' was given,", () => {
/** @type {Array<{config:(typeof import('../../../lib/cli-engine'))["ConfigArray"], filePath:string, ignored:boolean}>} */
let list;
beforeEach(() => {
list = [...enumerator.iterateFiles("lib/*.js")];
});
it("should list two files.", () => {
assert.strictEqual(list.length, 2);
});
it("should list 'lib/one.js' and 'lib/two.js'.", () => {
assert.deepStrictEqual(
list.map(entry => entry.filePath),
[
path.join(root, "lib/one.js"),
path.join(root, "lib/two.js")
]
);
});
it("should use the config '.eslintrc.json' for both files.", () => {
assert.strictEqual(list[0].config, list[1].config);
assert.strictEqual(list[0].config.length, 3);
assert.strictEqual(list[0].config[0].name, "DefaultIgnorePattern");
assert.strictEqual(list[0].config[1].filePath, path.join(root, ".eslintrc.json"));
assert.strictEqual(list[0].config[2].filePath, path.join(root, ".eslintignore"));
});
});
describe("if 'lib/**/*.js' was given,", () => {
/** @type {Array<{config:(typeof import('../../../lib/cli-engine'))["ConfigArray"], filePath:string, ignored:boolean}>} */
let list;
beforeEach(() => {
list = [...enumerator.iterateFiles("lib/**/*.js")];
});
it("should list four files.", () => {
assert.strictEqual(list.length, 4);
});
it("should list 'lib/nested/one.js', 'lib/nested/two.js', 'lib/one.js', 'lib/two.js'.", () => {
assert.deepStrictEqual(
list.map(entry => entry.filePath),
[
path.join(root, "lib/nested/one.js"),
path.join(root, "lib/nested/two.js"),
path.join(root, "lib/one.js"),
path.join(root, "lib/two.js")
]
);
});
it("should use the merged config of '.eslintrc.json' and 'lib/nested/.eslintrc.yml' for 'lib/nested/one.js' and 'lib/nested/two.js'.", () => {
assert.strictEqual(list[0].config, list[1].config);
assert.strictEqual(list[0].config.length, 4);
assert.strictEqual(list[0].config[0].name, "DefaultIgnorePattern");
assert.strictEqual(list[0].config[1].filePath, path.join(root, ".eslintrc.json"));
assert.strictEqual(list[0].config[2].filePath, path.join(root, "lib/nested/.eslintrc.yml"));
assert.strictEqual(list[0].config[3].filePath, path.join(root, ".eslintignore"));
});
it("should use the config '.eslintrc.json' for 'lib/one.js' and 'lib/two.js'.", () => {
assert.strictEqual(list[2].config, list[3].config);
assert.strictEqual(list[2].config.length, 3);
assert.strictEqual(list[2].config[0].name, "DefaultIgnorePattern");
assert.strictEqual(list[2].config[1].filePath, path.join(root, ".eslintrc.json"));
assert.strictEqual(list[2].config[2].filePath, path.join(root, ".eslintignore"));
});
});
describe("if 'lib/*.js' and 'test/*.js' were given,", () => {
/** @type {Array<{config:(typeof import('../../../lib/cli-engine'))["ConfigArray"], filePath:string, ignored:boolean}>} */
let list;
beforeEach(() => {
list = [...enumerator.iterateFiles(["lib/*.js", "test/*.js"])];
});
it("should list four files.", () => {
assert.strictEqual(list.length, 4);
});
it("should list 'lib/one.js', 'lib/two.js', 'test/one.js', 'test/two.js'.", () => {
assert.deepStrictEqual(
list.map(entry => entry.filePath),
[
path.join(root, "lib/one.js"),
path.join(root, "lib/two.js"),
path.join(root, "test/one.js"),
path.join(root, "test/two.js")
]
);
});
it("should use the config '.eslintrc.json' for 'lib/one.js' and 'lib/two.js'.", () => {
assert.strictEqual(list[0].config, list[1].config);
assert.strictEqual(list[0].config.length, 3);
assert.strictEqual(list[0].config[0].name, "DefaultIgnorePattern");
assert.strictEqual(list[0].config[1].filePath, path.join(root, ".eslintrc.json"));
assert.strictEqual(list[0].config[2].filePath, path.join(root, ".eslintignore"));
});
it("should use the merged config of '.eslintrc.json' and 'test/.eslintrc.yml' for 'test/one.js' and 'test/two.js'.", () => {
assert.strictEqual(list[2].config, list[3].config);
assert.strictEqual(list[2].config.length, 4);
assert.strictEqual(list[2].config[0].name, "DefaultIgnorePattern");
assert.strictEqual(list[2].config[1].filePath, path.join(root, ".eslintrc.json"));
assert.strictEqual(list[2].config[2].filePath, path.join(root, "test/.eslintrc.yml"));
assert.strictEqual(list[2].config[3].filePath, path.join(root, ".eslintignore"));
});
});
});
// This group moved from 'tests/lib/util/glob-utils.js' when refactoring to keep the cumulated test cases.
describe("with 'tests/fixtures/glob-utils' files", () => {
const { FileEnumerator } = require("../../../lib/cli-engine/file-enumerator");
let fixtureDir;
/**
* Returns the path inside of the fixture directory.
* @param {...string} args file path segments.
* @returns {string} The path inside the fixture directory.
* @private
*/
function getFixturePath(...args) {
return path.join(fs.realpathSync(fixtureDir), ...args);
}
/**
* List files as a compatible shape with glob-utils.
* @param {string|string[]} patterns The patterns to list files.
* @param {Object} options The option for FileEnumerator.
* @returns {{filename:string,ignored:boolean}[]} The listed files.
*/
function listFiles(patterns, options) {
return Array.from(
new FileEnumerator({
...options,
configArrayFactory: new CascadingConfigArrayFactory({
...options,
// Disable "No Configuration Found" error.
useEslintrc: false
})
}).iterateFiles(patterns),
({ filePath, ignored }) => ({ filename: filePath, ignored })
);
}
before(() => {
fixtureDir = `${os.tmpdir()}/eslint/tests/fixtures/`;
sh.mkdir("-p", fixtureDir);
sh.cp("-r", "./tests/fixtures/*", fixtureDir);
});
after(() => {
sh.rm("-r", fixtureDir);
});
describe("listFilesToProcess()", () => {
it("should return an array with a resolved (absolute) filename", () => {
const patterns = [getFixturePath("glob-util", "one-js-file", "**/*.js")];
const result = listFiles(patterns, {
cwd: getFixturePath()
});
const file1 = getFixturePath("glob-util", "one-js-file", "baz.js");
assert.isArray(result);
assert.deepStrictEqual(result, [{ filename: file1, ignored: false }]);
});
it("should return all files matching a glob pattern", () => {
const patterns = [getFixturePath("glob-util", "two-js-files", "**/*.js")];
const result = listFiles(patterns, {
cwd: getFixturePath()
});
const file1 = getFixturePath("glob-util", "two-js-files", "bar.js");
const file2 = getFixturePath("glob-util", "two-js-files", "foo.js");
assert.strictEqual(result.length, 2);
assert.deepStrictEqual(result, [
{ filename: file1, ignored: false },
{ filename: file2, ignored: false }
]);
});
it("should return all files matching multiple glob patterns", () => {
const patterns = [
getFixturePath("glob-util", "two-js-files", "**/*.js"),
getFixturePath("glob-util", "one-js-file", "**/*.js")
];
const result = listFiles(patterns, {
cwd: getFixturePath()
});
const file1 = getFixturePath("glob-util", "two-js-files", "bar.js");
const file2 = getFixturePath("glob-util", "two-js-files", "foo.js");
const file3 = getFixturePath("glob-util", "one-js-file", "baz.js");
assert.strictEqual(result.length, 3);
assert.deepStrictEqual(result, [
{ filename: file1, ignored: false },
{ filename: file2, ignored: false },
{ filename: file3, ignored: false }
]);
});
it("should ignore hidden files for standard glob patterns", () => {
const patterns = [getFixturePath("glob-util", "hidden", "**/*.js")];
assert.throws(() => {
listFiles(patterns, {
cwd: getFixturePath()
});
}, `All files matched by '${patterns[0]}' are ignored.`);
});
it("should return hidden files if included in glob pattern", () => {
const patterns = [getFixturePath("glob-util", "hidden", "**/.*.js")];
const result = listFiles(patterns, {
cwd: getFixturePath()
});
const file1 = getFixturePath("glob-util", "hidden", ".foo.js");
assert.strictEqual(result.length, 1);
assert.deepStrictEqual(result, [
{ filename: file1, ignored: false }
]);
});
it("should ignore default ignored files if not passed explicitly", () => {
const directory = getFixturePath("glob-util", "hidden");
const patterns = [directory];
assert.throws(() => {
listFiles(patterns, {
cwd: getFixturePath()
});
}, `All files matched by '${directory}' are ignored.`);
});
it("should ignore and warn for default ignored files when passed explicitly", () => {
const filename = getFixturePath("glob-util", "hidden", ".foo.js");
const patterns = [filename];
const result = listFiles(patterns, {
cwd: getFixturePath()
});
assert.strictEqual(result.length, 1);
assert.deepStrictEqual(result[0], { filename, ignored: true });
});
it("should ignore default ignored files if not passed explicitly even if ignore is false", () => {
const directory = getFixturePath("glob-util", "hidden");
const patterns = [directory];
assert.throws(() => {
listFiles(patterns, {
cwd: getFixturePath(),
ignore: false
});
}, `All files matched by '${directory}' are ignored.`);
});
it("should not ignore default ignored files when passed explicitly if ignore is false", () => {
const filename = getFixturePath("glob-util", "hidden", ".foo.js");
const patterns = [filename];
const result = listFiles(patterns, {
cwd: getFixturePath(),
ignore: false
});
assert.strictEqual(result.length, 1);
assert.deepStrictEqual(result[0], { filename, ignored: false });
});
it("should throw an error for a file which does not exist", () => {
const filename = getFixturePath("glob-util", "hidden", "bar.js");
const patterns = [filename];
assert.throws(() => {
listFiles(patterns, {
cwd: getFixturePath(),
allowMissingGlobs: true
});
}, `No files matching '${filename}' were found.`);
});
it("should throw if a folder that does not have any applicable files is linted", () => {
const filename = getFixturePath("glob-util", "empty");
const patterns = [filename];
assert.throws(() => {
listFiles(patterns, {
cwd: getFixturePath()
});
}, `No files matching '${filename}' were found.`);
});
it("should throw if only ignored files match a glob", () => {
const pattern = getFixturePath("glob-util", "ignored");
const options = { ignore: true, ignorePath: getFixturePath("glob-util", "ignored", ".eslintignore") };
assert.throws(() => {
listFiles([pattern], options);
}, `All files matched by '${pattern}' are ignored.`);
});
it("should throw an error if no files match a glob", () => {
// Relying here on the .eslintignore from the repo root
const patterns = ["tests/fixtures/glob-util/ignored/**/*.js"];
assert.throws(() => {
listFiles(patterns);
}, `All files matched by '${patterns[0]}' are ignored.`);
});
it("should return an ignored file, if ignore option is turned off", () => {
const options = { ignore: false };
const patterns = [getFixturePath("glob-util", "ignored", "**/*.js")];
const result = listFiles(patterns, options);
assert.strictEqual(result.length, 1);
});
it("should ignore a file from a glob if it matches a pattern in an ignore file", () => {
const options = { ignore: true, ignorePath: getFixturePath("glob-util", "ignored", ".eslintignore") };
const patterns = [getFixturePath("glob-util", "ignored", "**/*.js")];
assert.throws(() => {
listFiles(patterns, options);
}, `All files matched by '${patterns[0]}' are ignored.`);
});
it("should ignore a file from a glob if matching a specified ignore pattern", () => {
const options = { ignore: true, cliConfig: { ignorePatterns: ["foo.js"] }, cwd: getFixturePath() };
const patterns = [getFixturePath("glob-util", "ignored", "**/*.js")];
assert.throws(() => {
listFiles(patterns, options);
}, `All files matched by '${patterns[0]}' are ignored.`);
});
it("should return a file only once if listed in more than 1 pattern", () => {
const patterns = [
getFixturePath("glob-util", "one-js-file", "**/*.js"),
getFixturePath("glob-util", "one-js-file", "baz.js")
];
const result = listFiles(patterns, {
cwd: path.join(fixtureDir, "..")
});
const file1 = getFixturePath("glob-util", "one-js-file", "baz.js");
assert.isArray(result);
assert.deepStrictEqual(result, [
{ filename: file1, ignored: false }
]);
});
it("should set 'ignored: true' for files that are explicitly specified but ignored", () => {
const options = { ignore: true, cliConfig: { ignorePatterns: ["foo.js"] }, cwd: getFixturePath() };
const filename = getFixturePath("glob-util", "ignored", "foo.js");
const patterns = [filename];
const result = listFiles(patterns, options);
assert.strictEqual(result.length, 1);
assert.deepStrictEqual(result, [
{ filename, ignored: true }
]);
});
it("should not return files from default ignored folders", () => {
const options = { cwd: getFixturePath("glob-util") };
const glob = getFixturePath("glob-util", "**/*.js");
const patterns = [glob];
const result = listFiles(patterns, options);
const resultFilenames = result.map(resultObj => resultObj.filename);
assert.notInclude(resultFilenames, getFixturePath("glob-util", "node_modules", "dependency.js"));
});
it("should return unignored files from default ignored folders", () => {
const options = { cliConfig: { ignorePatterns: ["!/node_modules/dependency.js"] }, cwd: getFixturePath("glob-util") };
const glob = getFixturePath("glob-util", "**/*.js");
const patterns = [glob];
const result = listFiles(patterns, options);
const unignoredFilename = getFixturePath("glob-util", "node_modules", "dependency.js");
assert.includeDeepMembers(result, [{ filename: unignoredFilename, ignored: false }]);
});
it("should return unignored files from folders unignored in .eslintignore", () => {
const options = { cwd: getFixturePath("glob-util", "unignored"), ignore: true };
const glob = getFixturePath("glob-util", "unignored", "**/*.js");
const patterns = [glob];
const result = listFiles(patterns, options);
const filename = getFixturePath("glob-util", "unignored", "dir", "foo.js");
assert.strictEqual(result.length, 1);
assert.deepStrictEqual(result, [{ filename, ignored: false }]);
});
it("should return unignored files from folders unignored in .eslintignore for explicitly specified folder", () => {
const options = { cwd: getFixturePath("glob-util", "unignored"), ignore: true };
const dir = getFixturePath("glob-util", "unignored", "dir");
const patterns = [dir];
const result = listFiles(patterns, options);
const filename = getFixturePath("glob-util", "unignored", "dir", "foo.js");
assert.strictEqual(result.length, 1);
assert.deepStrictEqual(result, [{ filename, ignored: false }]);
});
});
});
});
});