Skip to content

Commit

Permalink
Add lintFiles() tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kaicataldo committed Mar 6, 2020
1 parent 00b2bb0 commit d7276fd
Show file tree
Hide file tree
Showing 15 changed files with 3,321 additions and 376 deletions.
12 changes: 6 additions & 6 deletions lib/eslint/eslint.js
Expand Up @@ -136,10 +136,10 @@ function processOptions({
ignore = true,
ignorePath = null,
ignorePattern = [],
parser = "espree",
parser = null, // Question: if this is set to a default value it ends up overriding the value set in the config. That seems like unexpected behavior to me.
parserOptions = {}, // TODO: Is this correct?
plugins = [],
reportUnusedDisableDirectives = false,
reportUnusedDisableDirectives = null,
resolvePluginsRelativeTo = cwd,
rulePaths = [],
rules = {}, // TODO: Is this correct?
Expand Down Expand Up @@ -214,8 +214,8 @@ function processOptions({
throw new Error("ignorePattern must be a string or an array of strings.");
}

if (typeof parser !== "string") {
throw new Error("parser must be a string.");
if (typeof parser !== "string" && parser !== null) {
throw new Error("parser must be a string or null.");
}

if (typeof parserOptions !== "object" && parserOptions !== null) {
Expand All @@ -226,8 +226,8 @@ function processOptions({
throw new Error("plugins must be an array.");
}

if (typeof reportUnusedDisableDirectives !== "boolean") {
throw new Error("reportUnusedDisableDirectives must be a boolean.");
if (typeof reportUnusedDisableDirectives !== "boolean" && reportUnusedDisableDirectives !== null) {
throw new Error("reportUnusedDisableDirectives must be a boolean or null.");
}

if (typeof resolvePluginsRelativeTo !== "string") {
Expand Down
114 changes: 103 additions & 11 deletions tests/lib/cli-engine/_utils.js → tests/_utils/in-memory-fs.js
Expand Up @@ -2,12 +2,13 @@
* @fileoverview Define classes what use the in-memory file system.
*
* This provides utilities to test `ConfigArrayFactory`,
* `CascadingConfigArrayFactory`, `FileEnumerator`, and `CLIEngine`.
* `CascadingConfigArrayFactory`, `FileEnumerator`, `CLIEngine`, and `ESLint`.
*
* - `defineConfigArrayFactoryWithInMemoryFileSystem({ cwd, files })`
* - `defineCascadingConfigArrayFactoryWithInMemoryFileSystem({ cwd, files })`
* - `defineFileEnumeratorWithInMemoryFileSystem({ cwd, files })`
* - `defineCLIEngineWithInMemoryFileSystem({ cwd, files })`
* - `defineESLintWithInMemoryFileSystem({ cwd, files })`
*
* Those functions define correspond classes with the in-memory file system.
* Those search config files, parsers, and plugins in the `files` option via the
Expand Down Expand Up @@ -55,30 +56,33 @@

const path = require("path");
const vm = require("vm");
const { Volume, createFsFromVolume } = require("memfs");
const Proxyquire = require("proxyquire/lib/proxyquire");
const { defineInMemoryFs } = require("../_utils");

const CascadingConfigArrayFactoryPath =
require.resolve("../../../lib/cli-engine/cascading-config-array-factory");
require.resolve("../../lib/cli-engine/cascading-config-array-factory");
const CLIEnginePath =
require.resolve("../../../lib/cli-engine/cli-engine");
require.resolve("../../lib/cli-engine/cli-engine");
const ConfigArrayFactoryPath =
require.resolve("../../../lib/cli-engine/config-array-factory");
require.resolve("../../lib/cli-engine/config-array-factory");
const FileEnumeratorPath =
require.resolve("../../../lib/cli-engine/file-enumerator");
require.resolve("../../lib/cli-engine/file-enumerator");
const LoadRulesPath =
require.resolve("../../../lib/cli-engine/load-rules");
require.resolve("../../lib/cli-engine/load-rules");
const ESLintPath =
require.resolve("../../lib/eslint/eslint");
const ESLintAllPath =
require.resolve("../../../conf/eslint-all");
require.resolve("../../conf/eslint-all");
const ESLintRecommendedPath =
require.resolve("../../../conf/eslint-recommended");
require.resolve("../../conf/eslint-recommended");

// Ensure the needed files has been loaded and cached.
require(CascadingConfigArrayFactoryPath);
require(CLIEnginePath);
require(ConfigArrayFactoryPath);
require(FileEnumeratorPath);
require(LoadRulesPath);
require(ESLintPath);
require("js-yaml");
require("espree");

Expand Down Expand Up @@ -236,12 +240,57 @@ function fsImportFresh(fs, stubs, absolutePath) {
);
}

/**
* Define in-memory file system.
* @param {Object} options The options.
* @param {() => string} [options.cwd] The current working directory.
* @param {Object} [options.files] The initial files definition in the in-memory file system.
* @returns {import("fs")} The stubbed `ConfigArrayFactory` class.
*/
function defineInMemoryFs({
cwd = process.cwd,
files = {}
} = {}) {

/**
* The in-memory file system for this mock.
* @type {import("fs")}
*/
const fs = createFsFromVolume(new Volume());

fs.mkdirSync(cwd(), { recursive: true });

/*
* Write all files to the in-memory file system and compile all JavaScript
* files then set to `stubs`.
*/
(function initFiles(directoryPath, definition) {
for (const [filename, content] of Object.entries(definition)) {
const filePath = path.resolve(directoryPath, filename);
const parentPath = path.dirname(filePath);

if (typeof content === "object") {
initFiles(filePath, content);
} else if (typeof content === "string") {
if (!fs.existsSync(parentPath)) {
fs.mkdirSync(parentPath, { recursive: true });
}
fs.writeFileSync(filePath, content);
} else {
throw new Error(`Invalid content: ${typeof content}`);
}
}
}(cwd(), files));

return fs;
}

/**
* Define stubbed `ConfigArrayFactory` class what uses the in-memory file system.
* @param {Object} options The options.
* @param {() => string} [options.cwd] The current working directory.
* @param {Object} [options.files] The initial files definition in the in-memory file system.
* @returns {{ fs: import("fs"), RelativeModuleResolver: import("../../../lib/shared/relative-module-resolver"), ConfigArrayFactory: import("../../../lib/cli-engine/config-array-factory")["ConfigArrayFactory"] }} The stubbed `ConfigArrayFactory` class.
* @returns {{ fs: import("fs"), RelativeModuleResolver: import("../../lib/shared/relative-module-resolver"), ConfigArrayFactory: import("../../lib/cli-engine/config-array-factory")["ConfigArrayFactory"] }} The stubbed `ConfigArrayFactory` class.
*/
function defineConfigArrayFactoryWithInMemoryFileSystem({
cwd = process.cwd,
Expand Down Expand Up @@ -438,9 +487,52 @@ function defineCLIEngineWithInMemoryFileSystem({
};
}

/**
* Define stubbed `ESLint` class that uses the in-memory file system.
* @param {Object} options The options.
* @param {() => string} [options.cwd] The current working directory.
* @param {Object} [options.files] The initial files definition in the in-memory file system.
* @returns {{ fs: import("fs"), RelativeModuleResolver: import("../../lib/shared/relative-module-resolver"), ConfigArrayFactory: import("../../lib/cli-engine/config-array-factory")["ConfigArrayFactory"], CascadingConfigArrayFactory: import("../../lib/cli-engine/cascading-config-array-factory")["CascadingConfigArrayFactory"], FileEnumerator: import("../../lib/cli-engine/file-enumerator")["FileEnumerator"], ESLint: import("../../lib/eslint/eslint")["ESLint"], getCLIEngineInternalSlots: import("../../lib//eslint/eslint")["getESLintInternalSlots"] }} The stubbed `ESLint` class.
*/
function defineESLintWithInMemoryFileSystem({
cwd = process.cwd,
files = {}
} = {}) {
const {
fs,
RelativeModuleResolver,
ConfigArrayFactory,
CascadingConfigArrayFactory,
FileEnumerator,
CLIEngine
} = defineCLIEngineWithInMemoryFileSystem({ cwd, files });
const { ESLint, getESLintInternalSlots } = proxyquire(ESLintPath, {
"../cli-engine": { CLIEngine }
});

// Override the default cwd.
return {
fs,
RelativeModuleResolver,
ConfigArrayFactory,
CascadingConfigArrayFactory,
FileEnumerator,
ESLint: cwd === process.cwd
? ESLint
: class extends ESLint {
constructor(options) {
super({ cwd: cwd(), ...options });
}
},
getESLintInternalSlots
};
}

module.exports = {
defineInMemoryFs,
defineConfigArrayFactoryWithInMemoryFileSystem,
defineCascadingConfigArrayFactoryWithInMemoryFileSystem,
defineFileEnumeratorWithInMemoryFileSystem,
defineCLIEngineWithInMemoryFileSystem
defineCLIEngineWithInMemoryFileSystem,
defineESLintWithInMemoryFileSystem
};
39 changes: 39 additions & 0 deletions tests/_utils/index.js
@@ -0,0 +1,39 @@
"use strict";

const {
defineInMemoryFs,
defineConfigArrayFactoryWithInMemoryFileSystem,
defineCascadingConfigArrayFactoryWithInMemoryFileSystem,
defineFileEnumeratorWithInMemoryFileSystem,
defineCLIEngineWithInMemoryFileSystem,
defineESLintWithInMemoryFileSystem
} = require("./in-memory-fs");


/**
* Prevents leading spaces in a multiline template literal from appearing in the resulting string
* @param {string[]} strings The strings in the template literal
* @param {any[]} values The interpolation values in the template literal.
* @returns {string} The template literal, with spaces removed from all lines
*/
function unIndent(strings, ...values) {
const text = strings
.map((s, i) => (i === 0 ? s : values[i - 1] + s))
.join("");
const lines = text.replace(/^\n/u, "").replace(/\n\s*$/u, "").split("\n");
const lineIndents = lines.filter(line => line.trim()).map(line => line.match(/ */u)[0].length);
const minLineIndent = Math.min(...lineIndents);

return lines.map(line => line.slice(minLineIndent)).join("\n");
}


module.exports = {
unIndent,
defineInMemoryFs,
defineConfigArrayFactoryWithInMemoryFileSystem,
defineCascadingConfigArrayFactoryWithInMemoryFileSystem,
defineFileEnumeratorWithInMemoryFileSystem,
defineCLIEngineWithInMemoryFileSystem,
defineESLintWithInMemoryFileSystem
};
76 changes: 0 additions & 76 deletions tests/lib/_utils.js

This file was deleted.

2 changes: 1 addition & 1 deletion tests/lib/cli-engine/cascading-config-array-factory.js
Expand Up @@ -12,7 +12,7 @@ const sh = require("shelljs");
const sinon = require("sinon");
const { ConfigArrayFactory } = require("../../../lib/cli-engine/config-array-factory");
const { ExtractedConfig } = require("../../../lib/cli-engine/config-array/extracted-config");
const { defineCascadingConfigArrayFactoryWithInMemoryFileSystem } = require("./_utils");
const { defineCascadingConfigArrayFactoryWithInMemoryFileSystem } = require("../../_utils");

/** @typedef {InstanceType<ReturnType<defineCascadingConfigArrayFactoryWithInMemoryFileSystem>["CascadingConfigArrayFactory"]>} CascadingConfigArrayFactory */
/** @typedef {ReturnType<CascadingConfigArrayFactory["getConfigArrayForFile"]>} ConfigArray */
Expand Down
3 changes: 1 addition & 2 deletions tests/lib/cli-engine/cli-engine.js
Expand Up @@ -18,8 +18,7 @@ const assert = require("chai").assert,
os = require("os"),
hash = require("../../../lib/cli-engine/hash"),
{ CascadingConfigArrayFactory } = require("../../../lib/cli-engine/cascading-config-array-factory"),
{ unIndent } = require("../_utils"),
{ defineCLIEngineWithInMemoryFileSystem } = require("./_utils");
{ unIndent, defineCLIEngineWithInMemoryFileSystem } = require("../../_utils");

const proxyquire = require("proxyquire").noCallThru().noPreserveCache();
const fCache = require("file-entry-cache");
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/cli-engine/config-array-factory.js
Expand Up @@ -10,7 +10,7 @@ const { assert } = require("chai");
const { spy } = require("sinon");
const { ConfigArray } = require("../../../lib/cli-engine/config-array");
const { OverrideTester } = require("../../../lib/cli-engine/config-array");
const { defineConfigArrayFactoryWithInMemoryFileSystem } = require("./_utils");
const { defineConfigArrayFactoryWithInMemoryFileSystem } = require("../../_utils");

const tempDir = path.join(os.tmpdir(), "eslint/config-array-factory");

Expand Down
2 changes: 1 addition & 1 deletion tests/lib/cli-engine/file-enumerator.js
Expand Up @@ -11,7 +11,7 @@ const { assert } = require("chai");
const sh = require("shelljs");
const { CascadingConfigArrayFactory } =
require("../../../lib/cli-engine/cascading-config-array-factory");
const { defineFileEnumeratorWithInMemoryFileSystem } = require("./_utils");
const { defineFileEnumeratorWithInMemoryFileSystem } = require("../../_utils");

describe("FileEnumerator", () => {
describe("'iterateFiles(patterns)' method should iterate files and configs.", () => {
Expand Down
6 changes: 0 additions & 6 deletions tests/lib/eslint/_utils.js

This file was deleted.

0 comments on commit d7276fd

Please sign in to comment.