diff --git a/lib/util/check-existence.js b/lib/util/check-existence.js index a7899a75..fdfd897d 100644 --- a/lib/util/check-existence.js +++ b/lib/util/check-existence.js @@ -4,11 +4,7 @@ */ "use strict" -const path = require("path") -const exists = require("./exists") const getAllowModules = require("./get-allow-modules") -const isTypescript = require("./is-typescript") -const { convertJsExtensionToTs } = require("../util/map-typescript-extension") /** * Reports a missing file from ImportTarget @@ -17,13 +13,16 @@ const { convertJsExtensionToTs } = require("../util/map-typescript-extension") * @returns {void} */ function markMissing(context, target) { + // This should never happen... this is just a fallback for typescript + target.resolveError ??= `"${target.name}" is not found` + context.report({ node: target.node, loc: /** @type {import('eslint').AST.SourceLocation} */ ( target.node.loc ), messageId: "notFound", - data: /** @type {Record} */ (target), + data: { resolveError: target.resolveError }, }) } @@ -38,52 +37,20 @@ function markMissing(context, target) { * @returns {void} */ exports.checkExistence = function checkExistence(context, targets) { + /** @type {Set} */ const allowed = new Set(getAllowModules(context)) - target: for (const target of targets) { - if ( - target.moduleName != null && - !allowed.has(target.moduleName) && - target.filePath == null - ) { - markMissing(context, target) - continue - } - - if ( - target.moduleName != null || - target.filePath == null || - exists(target.filePath) - ) { + for (const target of targets) { + if (allowed.has(target.moduleName)) { continue } - if (isTypescript(context) === false) { + if (target.resolveError != null) { markMissing(context, target) - continue } - - const parsed = path.parse(target.filePath) - const pathWithoutExt = path.resolve(parsed.dir, parsed.name) - - const reversedExtensions = convertJsExtensionToTs( - context, - target.filePath, - parsed.ext - ) - - for (const reversedExtension of reversedExtensions) { - const reversedPath = pathWithoutExt + reversedExtension - - if (exists(reversedPath)) { - continue target - } - } - - markMissing(context, target) } } exports.messages = { - notFound: '"{{name}}" is not found.', + notFound: "{{resolveError}}", } diff --git a/lib/util/import-target.js b/lib/util/import-target.js index 54741451..a407c58f 100644 --- a/lib/util/import-target.js +++ b/lib/util/import-target.js @@ -131,6 +131,12 @@ module.exports = class ImportTarget { */ this.moduleName = this.getModuleName() + /** + * This is the full resolution failure reasons + * @type {string | null} + */ + this.resolveError = null + /** * The full path of this import target. * If the target is a module and it does not exist then this is `null`. @@ -239,6 +245,19 @@ module.exports = class ImportTarget { return [this.options.basedir] } + /** + * @param {string} baseDir + * @param {unknown} error + * @returns {void} + */ + handleResolutionError(baseDir, error) { + if (error instanceof Error === false) { + throw error + } + + this.resolveError = error.message + } + /** * Resolve the given id to file paths. * @returns {string | null} The resolved path. @@ -274,7 +293,8 @@ module.exports = class ImportTarget { extensionAlias = getTypescriptExtensionMap(this.context).backward } - const requireResolve = resolver.create.sync({ + /** @type {import('enhanced-resolve').ResolveOptionsOptionalFS} */ + this.resolverConfig = { conditionNames, extensions, mainFields, @@ -282,16 +302,19 @@ module.exports = class ImportTarget { extensionAlias, alias, - }) + } + + const requireResolve = resolver.create.sync(this.resolverConfig) const cwd = this.context.settings?.cwd ?? process.cwd() for (const directory of this.getPaths()) { + const baseDir = resolve(cwd, directory) + try { - const baseDir = resolve(cwd, directory) const resolved = requireResolve(baseDir, this.name) if (typeof resolved === "string") return resolved - } catch { - continue + } catch (error) { + this.handleResolutionError(baseDir, error) } } diff --git a/package.json b/package.json index 949a31ea..e89c1cb2 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,6 @@ "*.md": "markdownlint --fix" }, "imports": { - "#eslint-rule-tester": "./tests/eslint-rule-tester.js" + "#test-helpers": "./tests/test-helpers.js" } } diff --git a/tests/fixtures/no-missing/node_modules/misconfigured-default/build/index.js b/tests/fixtures/no-missing/node_modules/misconfigured-default/build/index.js new file mode 100644 index 00000000..336ce12b --- /dev/null +++ b/tests/fixtures/no-missing/node_modules/misconfigured-default/build/index.js @@ -0,0 +1 @@ +export {} diff --git a/tests/fixtures/no-missing/node_modules/misconfigured-default/package.json b/tests/fixtures/no-missing/node_modules/misconfigured-default/package.json new file mode 100644 index 00000000..34cec732 --- /dev/null +++ b/tests/fixtures/no-missing/node_modules/misconfigured-default/package.json @@ -0,0 +1,9 @@ +{ + "name": "misconfigured-default", + "exports": { + ".": { + "default": "./build/index.js", + "types": "./src/index.ts" + } + } +} diff --git a/tests/fixtures/no-missing/node_modules/misconfigured-default/src/index.ts b/tests/fixtures/no-missing/node_modules/misconfigured-default/src/index.ts new file mode 100644 index 00000000..336ce12b --- /dev/null +++ b/tests/fixtures/no-missing/node_modules/misconfigured-default/src/index.ts @@ -0,0 +1 @@ +export {} diff --git a/tests/helpers.js b/tests/helpers.js deleted file mode 100644 index fe685cdc..00000000 --- a/tests/helpers.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * @fileoverview Helpers for tests. - * @author 唯然 - */ -"use strict" - -const eslintVersion = require("eslint/package.json").version - -// greater than or equal to ESLint v8 -exports.gtEslintV8 = +eslintVersion.split(".")[0] >= 8 diff --git a/tests/lib/configs/eslintrc.js b/tests/lib/configs/eslintrc.js index b79b15b7..9f826a6e 100644 --- a/tests/lib/configs/eslintrc.js +++ b/tests/lib/configs/eslintrc.js @@ -3,8 +3,6 @@ const assert = require("assert") const path = require("path") const { LegacyESLint } = require("eslint/use-at-your-own-risk") -// const {ESLint} = require("eslint") -const { gtEslintV8 } = require("../../helpers") const originalCwd = process.cwd() // this is needed as `recommended` config was cached @@ -15,7 +13,7 @@ function clearRequireCache() { } describe("node/recommended config", () => { - ;(gtEslintV8 ? describe : describe.skip)("in CJS directory", () => { + describe("in CJS directory", () => { const root = path.resolve(__dirname, "../../fixtures/configs/cjs/") /** @type {Linter} */ @@ -84,7 +82,7 @@ describe("node/recommended config", () => { endLine: 1, line: 1, messageId: "notFound", - message: '"foo" is not found.', + message: `Can't resolve 'foo' in '${root}'`, nodeType: "Literal", ruleId: "n/no-missing-import", severity: 2, @@ -124,34 +122,31 @@ describe("node/recommended config", () => { endLine: 1, line: 1, messageId: "notFound", - message: '"foo" is not found.', + message: `Can't resolve 'foo' in '${root}'`, nodeType: "Literal", ruleId: "n/no-missing-import", severity: 2, }, ]) }) - ;(gtEslintV8 ? it : it.skip)( - "*.cjs files should be a script.", - async () => { - const report = await linter.lintText("import 'foo'", { - filePath: path.join(root, "test.cjs"), - }) - - assert.deepStrictEqual(report[0].messages, [ - { - column: 1, - fatal: true, - line: 1, - message: - "Parsing error: 'import' and 'export' may appear only with 'sourceType: module'", - ruleId: null, - nodeType: null, - severity: 2, - }, - ]) - } - ) + it("*.cjs files should be a script.", async () => { + const report = await linter.lintText("import 'foo'", { + filePath: path.join(root, "test.cjs"), + }) + + assert.deepStrictEqual(report[0].messages, [ + { + column: 1, + fatal: true, + line: 1, + message: + "Parsing error: 'import' and 'export' may appear only with 'sourceType: module'", + ruleId: null, + nodeType: null, + severity: 2, + }, + ]) + }) it("*.mjs files should be a module.", async () => { const report = await linter.lintText("import 'foo'", { @@ -165,7 +160,7 @@ describe("node/recommended config", () => { endLine: 1, line: 1, messageId: "notFound", - message: '"foo" is not found.', + message: `Can't resolve 'foo' in '${root}'`, nodeType: "Literal", ruleId: "n/no-missing-import", severity: 2, diff --git a/tests/lib/rules/callback-return.js b/tests/lib/rules/callback-return.js index dcc3b81f..bff1e5ba 100644 --- a/tests/lib/rules/callback-return.js +++ b/tests/lib/rules/callback-return.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/callback-return") const ruleTester = new RuleTester() diff --git a/tests/lib/rules/exports-style.js b/tests/lib/rules/exports-style.js index 7ff2a7cf..34165382 100644 --- a/tests/lib/rules/exports-style.js +++ b/tests/lib/rules/exports-style.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/exports-style") new RuleTester({ languageOptions: { ecmaVersion: 11 } }).run( diff --git a/tests/lib/rules/file-extension-in-import.js b/tests/lib/rules/file-extension-in-import.js index 9c03c343..e14b48f5 100644 --- a/tests/lib/rules/file-extension-in-import.js +++ b/tests/lib/rules/file-extension-in-import.js @@ -6,7 +6,7 @@ const path = require("path") const { Linter } = require("eslint") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("../../test-helpers").RuleTester const rule = require("../../../lib/rules/file-extension-in-import") const DynamicImportSupported = (() => { diff --git a/tests/lib/rules/global-require.js b/tests/lib/rules/global-require.js index ce0cf7e5..0c28caf9 100644 --- a/tests/lib/rules/global-require.js +++ b/tests/lib/rules/global-require.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/global-require") const ERROR = { messageId: "unexpected", type: "CallExpression" } diff --git a/tests/lib/rules/handle-callback-err.js b/tests/lib/rules/handle-callback-err.js index efb313f0..c52c7cc0 100644 --- a/tests/lib/rules/handle-callback-err.js +++ b/tests/lib/rules/handle-callback-err.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/handle-callback-err") const ruleTester = new RuleTester() diff --git a/tests/lib/rules/hashbang.js b/tests/lib/rules/hashbang.js index f2640679..8de43036 100644 --- a/tests/lib/rules/hashbang.js +++ b/tests/lib/rules/hashbang.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/shebang") /** diff --git a/tests/lib/rules/no-callback-literal.js b/tests/lib/rules/no-callback-literal.js index 2db15d59..b55da190 100644 --- a/tests/lib/rules/no-callback-literal.js +++ b/tests/lib/rules/no-callback-literal.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-callback-literal") const tsParser = require("@typescript-eslint/parser") diff --git a/tests/lib/rules/no-deprecated-api.js b/tests/lib/rules/no-deprecated-api.js index cead2680..7039e03e 100644 --- a/tests/lib/rules/no-deprecated-api.js +++ b/tests/lib/rules/no-deprecated-api.js @@ -4,7 +4,7 @@ */ "use strict" -const { RuleTester } = require("#eslint-rule-tester") +const { RuleTester } = require("#test-helpers") const rule = require("../../../lib/rules/no-deprecated-api") const ruleTester = new RuleTester() diff --git a/tests/lib/rules/no-exports-assign.js b/tests/lib/rules/no-exports-assign.js index 5f8b2699..29222395 100644 --- a/tests/lib/rules/no-exports-assign.js +++ b/tests/lib/rules/no-exports-assign.js @@ -4,7 +4,7 @@ */ "use strict" -const { RuleTester } = require("#eslint-rule-tester") +const { RuleTester } = require("#test-helpers") const rule = require("../../../lib/rules/no-exports-assign.js") new RuleTester({ diff --git a/tests/lib/rules/no-extraneous-import.js b/tests/lib/rules/no-extraneous-import.js index 4829d58f..1b180e90 100644 --- a/tests/lib/rules/no-extraneous-import.js +++ b/tests/lib/rules/no-extraneous-import.js @@ -6,7 +6,7 @@ const path = require("path") const { Linter } = require("eslint") -const { RuleTester } = require("#eslint-rule-tester") +const { RuleTester } = require("#test-helpers") const rule = require("../../../lib/rules/no-extraneous-import") const DynamicImportSupported = (() => { diff --git a/tests/lib/rules/no-extraneous-require.js b/tests/lib/rules/no-extraneous-require.js index ad8adc0d..5706492b 100644 --- a/tests/lib/rules/no-extraneous-require.js +++ b/tests/lib/rules/no-extraneous-require.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-extraneous-require") /** diff --git a/tests/lib/rules/no-hide-core-modules.js b/tests/lib/rules/no-hide-core-modules.js index bf93ea5b..fc2e216b 100644 --- a/tests/lib/rules/no-hide-core-modules.js +++ b/tests/lib/rules/no-hide-core-modules.js @@ -14,7 +14,7 @@ //------------------------------------------------------------------------------ const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-hide-core-modules") //------------------------------------------------------------------------------ diff --git a/tests/lib/rules/no-missing-import.js b/tests/lib/rules/no-missing-import.js index 66190d3b..afd0a5c1 100644 --- a/tests/lib/rules/no-missing-import.js +++ b/tests/lib/rules/no-missing-import.js @@ -6,7 +6,7 @@ const path = require("path") const { Linter } = require("eslint") -const { RuleTester } = require("#eslint-rule-tester") +const { RuleTester, isCaseSensitiveFileSystem } = require("../../test-helpers") const rule = require("../../../lib/rules/no-missing-import") const DynamicImportSupported = (() => { @@ -39,6 +39,18 @@ function fixture(name) { return path.resolve(__dirname, "../../fixtures/no-missing", name) } +function cantResolve(name, dir = "") { + return [ + { + messageId: "notFound", + data: { + resolveError: `Can't resolve '${name}' in '${fixture(dir)}'`, + }, + }, + ] +} + +/** @type {import('eslint').RuleTester} */ const ruleTester = new RuleTester({ languageOptions: { sourceType: "module", @@ -66,10 +78,11 @@ ruleTester.run("no-missing-import", rule, { filename: fixture("test.js"), code: "import a from './a.js';", }, - { - filename: fixture("test.ts"), - code: "import a from './a.js';", - }, + // I dont think this should resolve, as it wont after a standard `tsc` + // { + // filename: fixture("test.ts"), + // code: "import a from './a.js';", + // }, { filename: fixture("test.ts"), code: "import a from './d.js';", @@ -320,89 +333,115 @@ ruleTester.run("no-missing-import", rule, { { filename: fixture("test.js"), code: "import abc from 'no-exist-package-0';", - errors: ['"no-exist-package-0" is not found.'], + errors: cantResolve("no-exist-package-0"), }, { filename: fixture("test.js"), code: "import abcdef from 'esm-module/sub.mjs';", - errors: ['"esm-module/sub.mjs" is not found.'], + errors: [ + { + messageId: "notFound", + data: { + resolveError: [ + "Package path ./sub.mjs is not exported from package", + fixture("node_modules/esm-module"), + `(see exports field in ${fixture("node_modules/esm-module/package.json")})`, + ].join(" "), + }, + }, + ], }, { filename: fixture("test.js"), code: "import test from '@mysticatea/test';", - errors: ['"@mysticatea/test" is not found.'], + errors: cantResolve("@mysticatea/test"), }, { filename: fixture("test.js"), code: "import c from './c';", - errors: ['"./c" is not found.'], + errors: cantResolve("./c"), }, { filename: fixture("test.ts"), code: "import d from './d';", - errors: ['"./d" is not found.'], + errors: cantResolve("./d"), }, { filename: fixture("test.js"), code: "import d from './d';", - errors: ['"./d" is not found.'], + errors: cantResolve("./d"), }, { filename: fixture("test.js"), code: "import a from './a.json';", - errors: ['"./a.json" is not found.'], + errors: cantResolve("./a.json"), }, // Should work fine if the filename is relative. { - filename: "tests/fixtures/no-missing/test.js", + filename: fixture("test.js"), code: "import eslint from 'no-exist-package-0';", - errors: ['"no-exist-package-0" is not found.'], + errors: cantResolve("no-exist-package-0"), }, { filename: "tests/fixtures/no-missing/test.js", code: "import c from './c';", - errors: ['"./c" is not found.'], + errors: cantResolve("./c"), }, // Relative paths to a directory should work. { filename: fixture("test.js"), code: "import a from './bar';", - errors: ['"./bar" is not found.'], + errors: cantResolve("./bar"), }, { filename: fixture("test.js"), code: "import a from './bar/';", - errors: ['"./bar/" is not found.'], + errors: cantResolve("./bar/"), }, // Relative paths to an existing directory should not work. { filename: fixture("test.js"), code: "import a from '.';", - errors: ['"." is not found.'], + errors: cantResolve("."), }, { filename: fixture("test.js"), code: "import a from './';", - errors: ['"./" is not found.'], + errors: cantResolve("./"), }, { filename: fixture("test.js"), code: "import a from './foo';", - errors: ['"./foo" is not found.'], + errors: cantResolve("./foo"), }, { filename: fixture("test.js"), code: "import a from './foo/';", - errors: ['"./foo/" is not found.'], + errors: cantResolve("./foo/"), }, // Case sensitive { filename: fixture("test.js"), code: "import a from './A.js';", - errors: ['"./A.js" is not found.'], + errors: cantResolve("./A.js"), + skip: !isCaseSensitiveFileSystem, + }, + + { + filename: fixture("test.js"), + code: "import 'misconfigured-default';", + errors: [ + { + messageId: "notFound", + data: { + name: "misconfigured-default", + resolveError: "Default condition should be last one", + }, + }, + ], }, // import() @@ -412,7 +451,7 @@ ruleTester.run("no-missing-import", rule, { filename: fixture("test.js"), code: "function f() { import('no-exist-package-0') }", languageOptions: { ecmaVersion: 2020 }, - errors: ['"no-exist-package-0" is not found.'], + errors: cantResolve("no-exist-package-0"), }, ] : []), diff --git a/tests/lib/rules/no-missing-require.js b/tests/lib/rules/no-missing-require.js index 97c8506b..c21541d6 100644 --- a/tests/lib/rules/no-missing-require.js +++ b/tests/lib/rules/no-missing-require.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const { RuleTester, isCaseSensitiveFileSystem } = require("../../test-helpers") const rule = require("../../../lib/rules/no-missing-require") const tsReactExtensionMap = [ @@ -25,6 +25,17 @@ function fixture(name) { return path.resolve(__dirname, "../../fixtures/no-missing", name) } +function cantResolve(name, dir = "") { + return [ + { + messageId: "notFound", + data: { + resolveError: `Can't resolve '${name}' in '${fixture(dir)}'`, + }, + }, + ] +} + const ruleTester = new RuleTester() ruleTester.run("no-missing-require", rule, { valid: [ @@ -333,65 +344,66 @@ ruleTester.run("no-missing-require", rule, { { filename: fixture("test.js"), code: "require('no-exist-package-0');", - errors: ['"no-exist-package-0" is not found.'], + errors: cantResolve("no-exist-package-0"), }, { filename: fixture("test.js"), code: "require('@mysticatea/test');", - errors: ['"@mysticatea/test" is not found.'], + errors: cantResolve("@mysticatea/test"), }, { filename: fixture("test.js"), code: "require('./c');", - errors: ['"./c" is not found.'], + errors: cantResolve("./c"), }, { filename: fixture("test.js"), code: "require('./d');", - errors: ['"./d" is not found.'], + errors: cantResolve("./d"), }, { filename: fixture("test.js"), code: "require('./a.json');", - errors: ['"./a.json" is not found.'], + errors: cantResolve("./a.json"), }, // Should work fine if the filename is relative. { filename: "tests/fixtures/no-missing/test.js", code: "require('no-exist-package-0');", - errors: ['"no-exist-package-0" is not found.'], + errors: cantResolve("no-exist-package-0"), }, { filename: "tests/fixtures/no-missing/test.js", code: "require('./c');", - errors: ['"./c" is not found.'], + errors: cantResolve("./c"), }, // Relative paths to a directory should work. { filename: fixture("test.js"), code: "require('./bar');", - errors: ['"./bar" is not found.'], + errors: cantResolve("./bar"), }, { filename: fixture("test.js"), code: "require('./bar/');", - errors: ['"./bar/" is not found.'], + errors: cantResolve("./bar/"), }, // Case sensitive { filename: fixture("test.js"), code: "require('./A');", - errors: ['"./A" is not found.'], + errors: cantResolve("./A"), + skip: !isCaseSensitiveFileSystem, }, // require.resolve { filename: fixture("test.js"), code: "require.resolve('no-exist-package-0');", - errors: ['"no-exist-package-0" is not found.'], + errors: cantResolve("no-exist-package-0"), }, ], }) diff --git a/tests/lib/rules/no-mixed-requires.js b/tests/lib/rules/no-mixed-requires.js index 4213b098..c8ddbcc9 100644 --- a/tests/lib/rules/no-mixed-requires.js +++ b/tests/lib/rules/no-mixed-requires.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-mixed-requires") const ruleTester = new RuleTester() diff --git a/tests/lib/rules/no-new-require.js b/tests/lib/rules/no-new-require.js index 4d88358e..0a4521fc 100644 --- a/tests/lib/rules/no-new-require.js +++ b/tests/lib/rules/no-new-require.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-new-require") new RuleTester().run("no-new-require", rule, { diff --git a/tests/lib/rules/no-path-concat.js b/tests/lib/rules/no-path-concat.js index 9edf2398..21970410 100644 --- a/tests/lib/rules/no-path-concat.js +++ b/tests/lib/rules/no-path-concat.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-path-concat") new RuleTester().run("no-path-concat", rule, { diff --git a/tests/lib/rules/no-process-env.js b/tests/lib/rules/no-process-env.js index 2111ab39..29ce6a39 100644 --- a/tests/lib/rules/no-process-env.js +++ b/tests/lib/rules/no-process-env.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-process-env") new RuleTester().run("no-process-env", rule, { diff --git a/tests/lib/rules/no-process-exit.js b/tests/lib/rules/no-process-exit.js index a5226a0d..f0db454d 100644 --- a/tests/lib/rules/no-process-exit.js +++ b/tests/lib/rules/no-process-exit.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-process-exit") const ruleTester = new RuleTester() diff --git a/tests/lib/rules/no-restricted-import.js b/tests/lib/rules/no-restricted-import.js index 67b17ef6..a8d5fb2e 100644 --- a/tests/lib/rules/no-restricted-import.js +++ b/tests/lib/rules/no-restricted-import.js @@ -6,7 +6,7 @@ const path = require("path") const { Linter } = require("eslint") -const { RuleTester } = require("#eslint-rule-tester") +const { RuleTester } = require("#test-helpers") const rule = require("../../../lib/rules/no-restricted-import") const DynamicImportSupported = (() => { diff --git a/tests/lib/rules/no-restricted-require.js b/tests/lib/rules/no-restricted-require.js index 340b8f9e..1c63c825 100644 --- a/tests/lib/rules/no-restricted-require.js +++ b/tests/lib/rules/no-restricted-require.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-restricted-require") new RuleTester().run("no-restricted-require", rule, { diff --git a/tests/lib/rules/no-sync.js b/tests/lib/rules/no-sync.js index f4fcf0b8..0de41ef5 100644 --- a/tests/lib/rules/no-sync.js +++ b/tests/lib/rules/no-sync.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-sync") new RuleTester().run("no-sync", rule, { diff --git a/tests/lib/rules/no-unpublished-bin.js b/tests/lib/rules/no-unpublished-bin.js index 02293b52..61943331 100644 --- a/tests/lib/rules/no-unpublished-bin.js +++ b/tests/lib/rules/no-unpublished-bin.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-unpublished-bin") /** diff --git a/tests/lib/rules/no-unpublished-import.js b/tests/lib/rules/no-unpublished-import.js index 9582c69d..7197c969 100644 --- a/tests/lib/rules/no-unpublished-import.js +++ b/tests/lib/rules/no-unpublished-import.js @@ -6,7 +6,7 @@ const path = require("path") const { Linter } = require("eslint") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-unpublished-import") const globals = require("globals") diff --git a/tests/lib/rules/no-unpublished-require.js b/tests/lib/rules/no-unpublished-require.js index 864cb042..b33d8c9d 100644 --- a/tests/lib/rules/no-unpublished-require.js +++ b/tests/lib/rules/no-unpublished-require.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../lib/rules/no-unpublished-require") /** diff --git a/tests/lib/rules/no-unsupported-features/es-builtins.js b/tests/lib/rules/no-unsupported-features/es-builtins.js index a78c9cce..3130aac7 100644 --- a/tests/lib/rules/no-unsupported-features/es-builtins.js +++ b/tests/lib/rules/no-unsupported-features/es-builtins.js @@ -3,7 +3,7 @@ * See LICENSE file in root directory for full license. */ "use strict" -const { RuleTester } = require("#eslint-rule-tester") +const { RuleTester } = require("#test-helpers") const rule = require("../../../../lib/rules/no-unsupported-features/es-builtins") const globals = require("globals") diff --git a/tests/lib/rules/no-unsupported-features/es-syntax.js b/tests/lib/rules/no-unsupported-features/es-syntax.js index 0790b8f1..093af9b9 100644 --- a/tests/lib/rules/no-unsupported-features/es-syntax.js +++ b/tests/lib/rules/no-unsupported-features/es-syntax.js @@ -5,7 +5,7 @@ "use strict" const path = require("path") -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/no-unsupported-features/es-syntax") /** diff --git a/tests/lib/rules/no-unsupported-features/node-builtins.js b/tests/lib/rules/no-unsupported-features/node-builtins.js index ad0de17d..458729e8 100644 --- a/tests/lib/rules/no-unsupported-features/node-builtins.js +++ b/tests/lib/rules/no-unsupported-features/node-builtins.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("../../../test-helpers").RuleTester const rule = require("../../../../lib/rules/no-unsupported-features/node-builtins") /** diff --git a/tests/lib/rules/prefer-global/buffer.js b/tests/lib/rules/prefer-global/buffer.js index 936f0fe2..140ab2f1 100644 --- a/tests/lib/rules/prefer-global/buffer.js +++ b/tests/lib/rules/prefer-global/buffer.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-global/buffer") new RuleTester().run("prefer-global/buffer", rule, { diff --git a/tests/lib/rules/prefer-global/console.js b/tests/lib/rules/prefer-global/console.js index e611f647..deb892b0 100644 --- a/tests/lib/rules/prefer-global/console.js +++ b/tests/lib/rules/prefer-global/console.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-global/console") new RuleTester().run("prefer-global/console", rule, { diff --git a/tests/lib/rules/prefer-global/process.js b/tests/lib/rules/prefer-global/process.js index 8df0c8a7..c751341c 100644 --- a/tests/lib/rules/prefer-global/process.js +++ b/tests/lib/rules/prefer-global/process.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-global/process") new RuleTester().run("prefer-global/process", rule, { diff --git a/tests/lib/rules/prefer-global/text-decoder.js b/tests/lib/rules/prefer-global/text-decoder.js index 5c561857..031f15f3 100644 --- a/tests/lib/rules/prefer-global/text-decoder.js +++ b/tests/lib/rules/prefer-global/text-decoder.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-global/text-decoder") new RuleTester().run("prefer-global/text-decoder", rule, { diff --git a/tests/lib/rules/prefer-global/text-encoder.js b/tests/lib/rules/prefer-global/text-encoder.js index c1b03210..a065111d 100644 --- a/tests/lib/rules/prefer-global/text-encoder.js +++ b/tests/lib/rules/prefer-global/text-encoder.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-global/text-encoder") new RuleTester().run("prefer-global/text-encoder", rule, { diff --git a/tests/lib/rules/prefer-global/url-search-params.js b/tests/lib/rules/prefer-global/url-search-params.js index 031e3115..d581c036 100644 --- a/tests/lib/rules/prefer-global/url-search-params.js +++ b/tests/lib/rules/prefer-global/url-search-params.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-global/url-search-params") new RuleTester().run("prefer-global/url-search-params", rule, { diff --git a/tests/lib/rules/prefer-global/url.js b/tests/lib/rules/prefer-global/url.js index a06218f1..70c8fd63 100644 --- a/tests/lib/rules/prefer-global/url.js +++ b/tests/lib/rules/prefer-global/url.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-global/url") new RuleTester().run("prefer-global/url", rule, { diff --git a/tests/lib/rules/prefer-node-protocol.js b/tests/lib/rules/prefer-node-protocol.js index 5db6103c..e2796177 100644 --- a/tests/lib/rules/prefer-node-protocol.js +++ b/tests/lib/rules/prefer-node-protocol.js @@ -4,7 +4,7 @@ */ "use strict" -const { RuleTester } = require("#eslint-rule-tester") +const { RuleTester } = require("#test-helpers") const rule = require("../../../lib/rules/prefer-node-protocol.js") new RuleTester({ diff --git a/tests/lib/rules/prefer-promises/dns.js b/tests/lib/rules/prefer-promises/dns.js index 63958469..44e0ecda 100644 --- a/tests/lib/rules/prefer-promises/dns.js +++ b/tests/lib/rules/prefer-promises/dns.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-promises/dns") new RuleTester({ diff --git a/tests/lib/rules/prefer-promises/fs.js b/tests/lib/rules/prefer-promises/fs.js index 2a717e06..0efe5820 100644 --- a/tests/lib/rules/prefer-promises/fs.js +++ b/tests/lib/rules/prefer-promises/fs.js @@ -4,7 +4,7 @@ */ "use strict" -const RuleTester = require("#eslint-rule-tester").RuleTester +const RuleTester = require("#test-helpers").RuleTester const rule = require("../../../../lib/rules/prefer-promises/fs") new RuleTester({ diff --git a/tests/eslint-rule-tester.js b/tests/test-helpers.js similarity index 72% rename from tests/eslint-rule-tester.js rename to tests/test-helpers.js index 28a4e95f..bff30126 100644 --- a/tests/eslint-rule-tester.js +++ b/tests/test-helpers.js @@ -8,12 +8,17 @@ const { RuleTester } = require("eslint") const { FlatRuleTester } = require("eslint/use-at-your-own-risk") const globals = require("globals") const semverSatisfies = require("semver/functions/satisfies") +const os = require("os") // greater than or equal to ESLint v9 exports.gteEslintV9 = semverSatisfies(eslintVersion, ">=9", { includePrerelease: true, }) +const platform = os.platform() +exports.isCaseSensitiveFileSystem = + platform === "linux" || platform === "freebsd" || platform === "openbsd" + exports.FlatRuleTester = exports.gteEslintV9 ? RuleTester : FlatRuleTester // to support the `env:{ es6: true, node: true}` rule-tester (env has been away in flat config.) @@ -40,5 +45,21 @@ exports.RuleTester = function (config = defaultConfig) { ) const ruleTester = new exports.FlatRuleTester(config) + const $run = ruleTester.run.bind(ruleTester) + ruleTester.run = function (name, rule, tests) { + tests.valid = tests.valid.filter(shouldRun) + tests.invalid = tests.invalid.filter(shouldRun) + + $run(name, rule, tests) + } return ruleTester } + +// support skip in tests +function shouldRun(item) { + if (typeof item === "string") return true + + const skip = item.skip + delete item.skip + return skip === void 0 || skip === false +}