diff --git a/apps/oxlint/conformance/src/groups/eslint.ts b/apps/oxlint/conformance/src/groups/eslint.ts index 96edc52d40599..178e5921f1ee2 100644 --- a/apps/oxlint/conformance/src/groups/eslint.ts +++ b/apps/oxlint/conformance/src/groups/eslint.ts @@ -48,7 +48,7 @@ const group: TestGroup = { return false; }, - ruleTesters: ["../../../lib/rule-tester/rule-tester.js"], + ruleTesters: [{ specifier: "../../../lib/rule-tester/rule-tester.js", propName: null }], parsers: [{ specifier: "@typescript-eslint/parser", lang: "ts" }], }; diff --git a/apps/oxlint/conformance/src/groups/react_hooks.ts b/apps/oxlint/conformance/src/groups/react_hooks.ts index 9541509ab63da..7a708a9908165 100644 --- a/apps/oxlint/conformance/src/groups/react_hooks.ts +++ b/apps/oxlint/conformance/src/groups/react_hooks.ts @@ -60,7 +60,11 @@ const group: TestGroup = { return false; }, - ruleTesters: ["eslint-v7", "eslint-v8", "eslint-v9"], + ruleTesters: [ + { specifier: "eslint-v7", propName: "RuleTester" }, + { specifier: "eslint-v8", propName: "RuleTester" }, + { specifier: "eslint-v9", propName: "RuleTester" }, + ], parsers: [ { specifier: "babel-eslint", lang: "jsx" }, diff --git a/apps/oxlint/conformance/src/index.ts b/apps/oxlint/conformance/src/index.ts index 4c6cf35bec47e..5f7b7274874eb 100644 --- a/apps/oxlint/conformance/src/index.ts +++ b/apps/oxlint/conformance/src/index.ts @@ -94,12 +94,19 @@ export interface TestGroup { /** * `RuleTester` instances to replace with the Oxc conformance `RuleTester`. * - * Array elements are module specifiers which are resolved relative to a file in the tests directory, - * using `require.resolve`. + * - `specifier` is a module specifier which is resolved relative to the tests directory, using `require.resolve`. + * - `propName` is name of the property to set on the module to the `RuleTester` class. + * If `null`, the module is set as `module.exports`. * - * e.g. `["../../lib/rule-tester.js", "eslint"]` + * e.g.: + * ```js + * [ + * { specifier: "eslint", propName: "RuleTester" }, + * { specifier: "../../lib/rule-tester.js", propName: null }, + * ] + * ``` */ - ruleTesters: string[]; + ruleTesters: { specifier: string; propName: string | null }[]; /** * Known parsers to accept. @@ -154,12 +161,6 @@ const require = createRequire(import.meta.url); const normalizePath = pathSep === "\\" ? (path: string) => path.replaceAll("\\", "/") : (path: string) => path; -// `RuleTester` will be `module.exports`, so allow loading that module with either: -// 1. `import RuleTester from "path/to/rule_tester.js";` -// 2. `import { RuleTester } from "path/to/rule_tester.js";` -// @ts-expect-error - not a property of `RuleTester` -RuleTester.RuleTester = RuleTester; - // Run const mocks = initMocks(); runGroups(TEST_GROUPS, mocks); @@ -228,8 +229,14 @@ function runGroup(group: TestGroup, mocks: Mocks) { const requireFromTestsDir = createRequire(pathJoin(testFilesDirPath, "dummy.js")); const resolveFromTestsDir = requireFromTestsDir.resolve.bind(requireFromTestsDir); - for (const specifier of group.ruleTesters) { - mocks.set(resolveFromTestsDir(specifier), RuleTester); + for (const tester of group.ruleTesters) { + const { specifier, propName } = tester; + if (propName === null) { + mocks.set(resolveFromTestsDir(specifier), RuleTester); + } else { + const mod = requireFromTestsDir(specifier); + mod[propName] = RuleTester; + } } // Run `prepare` function