From 5f453482bc98f7c10ba19d34586174ddee76b94e Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 3 Jan 2022 22:16:25 +0800 Subject: [PATCH] Add internal ESLint rule `await-cli-tests` (#12013) Co-authored-by: Sosuke Suzuki --- .eslintrc.js | 6 ++ .../await-cli-tests.js | 72 +++++++++++++++++++ .../index.js | 1 + .../test.js | 26 +++++++ 4 files changed, 105 insertions(+) create mode 100644 scripts/tools/eslint-plugin-prettier-internal-rules/await-cli-tests.js diff --git a/.eslintrc.js b/.eslintrc.js index dd11a9d1e..e06620c5f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -179,6 +179,12 @@ module.exports = { "jest/prefer-to-be": "error", }, }, + { + files: ["tests/integration/**/*.js"], + rules: { + "prettier-internal-rules/await-cli-tests": "error", + }, + }, { files: ["tests/**/*.js"], rules: { diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/await-cli-tests.js b/scripts/tools/eslint-plugin-prettier-internal-rules/await-cli-tests.js new file mode 100644 index 000000000..b066f1a07 --- /dev/null +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/await-cli-tests.js @@ -0,0 +1,72 @@ +"use strict"; + +const selector = [ + "CallExpression", + '[callee.type="Identifier"]', + '[callee.name="runPrettier"]', +].join(""); + +const MESSAGE_ID_CALL = "await-cli-tests/call"; +const MESSAGE_ID_GETTER = "await-cli-tests/getter"; + +module.exports = { + meta: { + type: "suggestion", + docs: { + url: "https://github.com/prettier/prettier/blob/main/scripts/tools/eslint-plugin-prettier-internal-rules/await-cli-tests.js", + }, + messages: { + [MESSAGE_ID_CALL]: + "'runPrettier()' should be awaited or calling `.test()`.", + [MESSAGE_ID_GETTER]: "'runPrettier().{{property}}' should be awaited.", + }, + }, + create(context) { + return { + [selector](callExpression) { + const { parent } = callExpression; + if ( + parent.type === "AwaitExpression" && + parent.argument === callExpression + ) { + return; + } + + if ( + parent.type === "MemberExpression" && + parent.object === callExpression && + parent.property.type === "Identifier" && + parent.property.name === "test" && + parent.parent.type === "CallExpression" && + parent.parent.callee === parent + ) { + return; + } + + if ( + parent.type === "MemberExpression" && + parent.object === callExpression && + parent.property.type === "Identifier" && + ["status", "write", "stdout", "stderr"].includes(parent.property.name) + ) { + const memberExpression = callExpression.parent; + if ( + memberExpression.parent.type === "AwaitExpression" && + memberExpression.parent.argument === memberExpression + ) { + return; + } + + context.report({ + node: memberExpression.property, + messageId: MESSAGE_ID_GETTER, + data: { property: memberExpression.property.name }, + }); + return; + } + + context.report({ node: callExpression, messageId: MESSAGE_ID_CALL }); + }, + }; + }, +}; diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/index.js b/scripts/tools/eslint-plugin-prettier-internal-rules/index.js index 114c4cfa0..b58a79e97 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/index.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/index.js @@ -2,6 +2,7 @@ module.exports = { rules: { + "await-cli-tests": require("./await-cli-tests.js"), "better-parent-property-check-in-needs-parens": require("./better-parent-property-check-in-needs-parens.js"), "consistent-negative-index-access": require("./consistent-negative-index-access.js"), "directly-loc-start-end": require("./directly-loc-start-end.js"), diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js index e9afa6c1d..f89175aac 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js @@ -14,6 +14,32 @@ const test = (ruleId, tests) => { ); }; +test("await-cli-tests", { + valid: [ + "async () => await runPrettier()", + "runPrettier().test()", + "notRunPrettier()", + "async () => await runPrettier().stderr", + outdent` + async () => { + const originalStdout = await runPrettier("plugins/options", ["--help"]).stdout; + } + `, + ], + invalid: [ + { + code: "runPrettier()", + errors: [ + { message: "'runPrettier()' should be awaited or calling `.test()`." }, + ], + }, + { + code: "runPrettier().stderr", + errors: [{ message: "'runPrettier().stderr' should be awaited." }], + }, + ], +}); + test("better-parent-property-check-in-needs-parens", { valid: ["function needsParens() {return parent.test === node;}"], invalid: [