From 7290ff2dc7d34d1192509d6fc1c5efd92f0ba5c1 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 4 Jan 2022 19:31:17 +0800 Subject: [PATCH] Add internal ESLint rule `no-legacy-format-test-fixtures` (#12044) --- .eslintrc.js | 6 ++ .../index.js | 1 + .../no-legacy-format-test-fixtures.js | 64 +++++++++++++++++++ .../test.js | 24 +++++++ 4 files changed, 95 insertions(+) create mode 100644 scripts/tools/eslint-plugin-prettier-internal-rules/no-legacy-format-test-fixtures.js diff --git a/.eslintrc.js b/.eslintrc.js index 6a127026d..efa17c5d3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -184,6 +184,12 @@ module.exports = { "jest/prefer-to-be": "error", }, }, + { + files: ["tests/format/**/*.js"], + rules: { + "prettier-internal-rules/no-legacy-format-test-fixtures": "error", + }, + }, { files: ["tests/integration/**/*.js"], rules: { diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/index.js b/scripts/tools/eslint-plugin-prettier-internal-rules/index.js index b58a79e97..0eafd86c4 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/index.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/index.js @@ -12,6 +12,7 @@ module.exports = { "no-doc-builder-concat": require("./no-doc-builder-concat.js"), "no-empty-flat-contents-for-if-break": require("./no-empty-flat-contents-for-if-break.js"), "no-identifier-n": require("./no-identifier-n.js"), + "no-legacy-format-test-fixtures": require("./no-legacy-format-test-fixtures.js"), "no-node-comments": require("./no-node-comments.js"), "no-unnecessary-ast-path-call": require("./no-unnecessary-ast-path-call.js"), "prefer-ast-path-each": require("./prefer-ast-path-each.js"), diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/no-legacy-format-test-fixtures.js b/scripts/tools/eslint-plugin-prettier-internal-rules/no-legacy-format-test-fixtures.js new file mode 100644 index 000000000..74a87f307 --- /dev/null +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/no-legacy-format-test-fixtures.js @@ -0,0 +1,64 @@ +"use strict"; + +const dirnameArgumentSelector = [ + "CallExpression", + '[callee.type="Identifier"]', + '[callee.name="run_spec"]', + " > ", + "Identifier.arguments:first-child", + '[name="__dirname"]', +].join(""); + +const dirnamePropertySelector = [ + "CallExpression", + '[callee.type="Identifier"]', + '[callee.name="run_spec"]', + " > ", + "ObjectExpression.arguments:first-child", + " > ", + "Property.properties", + '[key.type="Identifier"]', + '[key.name="dirname"]', + '[value.type="Identifier"]', + '[value.name="__dirname"]', +].join(""); + +const MESSAGE_ID_ARGUMENT = "dirname-argument"; +const MESSAGE_ID_PROPERTY = "dirname-property"; + +module.exports = { + meta: { + type: "suggestion", + docs: { + url: "https://github.com/prettier/prettier/blob/main/scripts/tools/eslint-plugin-prettier-internal-rules/no-legacy-format-test-fixtures.js", + }, + messages: { + [MESSAGE_ID_ARGUMENT]: "Use `import.meta` instead of `__dirname`.", + [MESSAGE_ID_PROPERTY]: + "Use `importMeta: import.meta` instead of `dirname: __dirname`.", + }, + fixable: "code", + hasSuggestions: true, + }, + create(context) { + return { + [dirnameArgumentSelector](node) { + context.report({ + node, + messageId: MESSAGE_ID_ARGUMENT, + fix: (fixer) => fixer.replaceText(node, "import.meta"), + }); + }, + [dirnamePropertySelector](node) { + context.report({ + node, + messageId: MESSAGE_ID_PROPERTY, + fix: (fixer) => [ + fixer.replaceText(node.key, "importMeta"), + fixer.replaceText(node.value, "import.meta"), + ], + }); + }, + }; + }, +}; diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js index f89175aac..b7d5857b5 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js @@ -331,6 +331,30 @@ test("no-identifier-n", { ], }); +test("no-legacy-format-test-fixtures", { + valid: [ + "run_spec(import.meta, ['babel'])", + "run_spec({importMeta: import.meta}, ['babel'])", + ].map((code) => ({ code, parserOptions: { sourceType: "module" } })), + invalid: [ + { + code: "run_spec(__dirname, ['babel'])", + errors: [{ message: "Use `import.meta` instead of `__dirname`." }], + output: "run_spec(import.meta, ['babel'])", + }, + { + code: "run_spec({snippets: ['x'], dirname: __dirname}, ['babel'])", + errors: [ + { + message: + "Use `importMeta: import.meta` instead of `dirname: __dirname`.", + }, + ], + output: "run_spec({snippets: ['x'], importMeta: import.meta}, ['babel'])", + }, + ].map((test) => ({ ...test, parserOptions: { sourceType: "module" } })), +}); + test("no-node-comments", { valid: [ "const comments = node.notComments",