From 5e1c932e73c219ddabad2cd1463573fbaf3a2f33 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 25 Mar 2022 12:40:02 +0800 Subject: [PATCH] `text-encoding-identifier-case`: Auto-fix encoding in `fs.{readFile,readFileSync}()` (#1755) --- docs/rules/text-encoding-identifier-case.md | 4 +- readme.md | 2 +- rules/text-encoding-identifier-case.js | 42 +++- .../text-encoding-identifier-case.mjs.md | 198 +++++++++++++++++- .../text-encoding-identifier-case.mjs.snap | Bin 437 -> 1046 bytes test/text-encoding-identifier-case.mjs | 13 ++ 6 files changed, 245 insertions(+), 14 deletions(-) diff --git a/docs/rules/text-encoding-identifier-case.md b/docs/rules/text-encoding-identifier-case.md index aa59c2f1df..fc1d00ea64 100644 --- a/docs/rules/text-encoding-identifier-case.md +++ b/docs/rules/text-encoding-identifier-case.md @@ -4,12 +4,14 @@ ✅ *This rule is part of the [recommended](https://github.com/sindresorhus/eslint-plugin-unicorn#recommended-config) config.* -💡 *This rule provides [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).* +🔧💡 *This rule is [auto-fixable](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) and provides [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).* - Enforce `'utf8'` for [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoding. - Enforce `'ascii'` for [ASCII](https://en.wikipedia.org/wiki/ASCII) encoding. +This rule only auto-fix encoding in `fs.readFile()` and `fs.readFileSync()`. + ## Fail ```js diff --git a/readme.md b/readme.md index 939012d484..84c6be653f 100644 --- a/readme.md +++ b/readme.md @@ -150,7 +150,7 @@ Each rule has emojis denoting: | [require-post-message-target-origin](docs/rules/require-post-message-target-origin.md) | Enforce using the `targetOrigin` argument with `window.postMessage()`. | | | 💡 | | [string-content](docs/rules/string-content.md) | Enforce better string content. | | 🔧 | 💡 | | [template-indent](docs/rules/template-indent.md) | Fix whitespace-insensitive template indentation. | ✅ | 🔧 | | -| [text-encoding-identifier-case](docs/rules/text-encoding-identifier-case.md) | Enforce consistent case for text encoding identifiers. | ✅ | | 💡 | +| [text-encoding-identifier-case](docs/rules/text-encoding-identifier-case.md) | Enforce consistent case for text encoding identifiers. | ✅ | 🔧 | 💡 | | [throw-new-error](docs/rules/throw-new-error.md) | Require `new` when throwing an error. | ✅ | 🔧 | | diff --git a/rules/text-encoding-identifier-case.js b/rules/text-encoding-identifier-case.js index b5dc9d67e0..23a76531f2 100644 --- a/rules/text-encoding-identifier-case.js +++ b/rules/text-encoding-identifier-case.js @@ -19,6 +19,19 @@ const getReplacement = encoding => { } }; +// `fs.{readFile,readFileSync}()` +const isFsReadFileEncoding = node => + node.parent.type === 'CallExpression' + && !node.parent.optional + && node.parent.arguments[1] === node + && node.parent.arguments[0] + && node.parent.arguments[0].type !== 'SpreadElement' + && node.parent.callee.type === 'MemberExpression' + && !node.parent.callee.optional + && !node.parent.callee.computed + && node.parent.callee.property.type === 'Identifier' + && (node.parent.callee.property.name === 'readFile' || node.parent.callee.property.name === 'readFileSync'); + /** @param {import('eslint').Rule.RuleContext} context */ const create = () => ({ Literal(node) { @@ -39,19 +52,29 @@ const create = () => ({ replacement, }; - return { + /** @param {import('eslint').Rule.RuleFixer} fixer */ + const fix = fixer => replaceStringLiteral(fixer, node, replacement); + + const problem = { node, messageId: MESSAGE_ID_ERROR, data: messageData, - suggest: [ - { - messageId: MESSAGE_ID_SUGGESTION, - data: messageData, - /** @param {import('eslint').Rule.RuleFixer} fixer */ - fix: fixer => replaceStringLiteral(fixer, node, replacement), - }, - ], }; + + if (isFsReadFileEncoding(node)) { + problem.fix = fix; + return problem; + } + + problem.suggest = [ + { + messageId: MESSAGE_ID_SUGGESTION, + data: messageData, + fix: fixer => replaceStringLiteral(fixer, node, replacement), + }, + ]; + + return problem; }, }); @@ -63,6 +86,7 @@ module.exports = { docs: { description: 'Enforce consistent case for text encoding identifiers.', }, + fixable: 'code', hasSuggestions: true, messages, }, diff --git a/test/snapshots/text-encoding-identifier-case.mjs.md b/test/snapshots/text-encoding-identifier-case.mjs.md index 15980fd03d..de592321d8 100644 --- a/test/snapshots/text-encoding-identifier-case.mjs.md +++ b/test/snapshots/text-encoding-identifier-case.mjs.md @@ -75,15 +75,207 @@ Generated by [AVA](https://avajs.dev). ` ## Invalid #6 - 1 | await fs.readFile(file, "UTF-8",) + 1 | fs.readFile?.(file, "UTF-8") > Error 1/1 `␊ - > 1 | await fs.readFile(file, "UTF-8",)␊ - | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + > 1 | fs.readFile?.(file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | fs.readFile?.(file, "utf8")␊ + ` + +## Invalid #7 + 1 | fs?.readFile(file, "UTF-8") + +> Error 1/1 + + `␊ + > 1 | fs?.readFile(file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | fs?.readFile(file, "utf8")␊ + ` + +## Invalid #8 + 1 | readFile(file, "UTF-8") + +> Error 1/1 + + `␊ + > 1 | readFile(file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | readFile(file, "utf8")␊ + ` + +## Invalid #9 + 1 | fs.readFile(...file, "UTF-8") + +> Error 1/1 + + `␊ + > 1 | fs.readFile(...file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | fs.readFile(...file, "utf8")␊ + ` + +## Invalid #10 + 1 | new fs.readFile(file, "UTF-8") + +> Error 1/1 + + `␊ + > 1 | new fs.readFile(file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | new fs.readFile(file, "utf8")␊ + ` + +## Invalid #11 + 1 | fs.readFile(file, {encoding: "UTF-8"}) + +> Error 1/1 + + `␊ + > 1 | fs.readFile(file, {encoding: "UTF-8"})␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | fs.readFile(file, {encoding: "utf8"})␊ + ` + +## Invalid #12 + 1 | fs.readFile("UTF-8") + +> Error 1/1 + + `␊ + > 1 | fs.readFile("UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | fs.readFile("utf8")␊ + ` + +## Invalid #13 + 1 | fs.readFile(file, "UTF-8", () => {}) + +> Output + + `␊ + 1 | fs.readFile(file, "utf8", () => {})␊ + ` + +> Error 1/1 + + `␊ + > 1 | fs.readFile(file, "UTF-8", () => {})␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ` + +## Invalid #14 + 1 | fs.readFileSync(file, "UTF-8") + +> Output + + `␊ + 1 | fs.readFileSync(file, "utf8")␊ + ` + +> Error 1/1 + + `␊ + > 1 | fs.readFileSync(file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ` + +## Invalid #15 + 1 | fs[readFile](file, "UTF-8") + +> Error 1/1 + + `␊ + > 1 | fs[readFile](file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | fs[readFile](file, "utf8")␊ + ` + +## Invalid #16 + 1 | fs["readFile"](file, "UTF-8") + +> Error 1/1 + + `␊ + > 1 | fs["readFile"](file, "UTF-8")␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`UTF-8\` with \`utf8\`.␊ + 1 | fs["readFile"](file, "utf8")␊ + ` + +## Invalid #17 + 1 | await fs.readFile(file, "UTF-8",) + +> Output + + `␊ 1 | await fs.readFile(file, "utf8",)␊ ` + +> Error 1/1 + + `␊ + > 1 | await fs.readFile(file, "UTF-8",)␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ` + +## Invalid #18 + 1 | fs.promises.readFile(file, "UTF-8",) + +> Output + + `␊ + 1 | fs.promises.readFile(file, "utf8",)␊ + ` + +> Error 1/1 + + `␊ + > 1 | fs.promises.readFile(file, "UTF-8",)␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ` + +## Invalid #19 + 1 | whatever.readFile(file, "UTF-8",) + +> Output + + `␊ + 1 | whatever.readFile(file, "utf8",)␊ + ` + +> Error 1/1 + + `␊ + > 1 | whatever.readFile(file, "UTF-8",)␊ + | ^^^^^^^ Prefer \`utf8\` over \`UTF-8\`.␊ + ` diff --git a/test/snapshots/text-encoding-identifier-case.mjs.snap b/test/snapshots/text-encoding-identifier-case.mjs.snap index 4dbb4876666d882105e32c8ee6106c403502aab2..a3d0ae8d8e4e90449e71d5225885e9b18532d499 100644 GIT binary patch literal 1046 zcmV+x1nK)hRzVlneJPk{C$# z{~WCsExTOqeRS@kBbO^bF@i8_BSmpR+_`=pz^Evpy7t+j9^hMRtAO%e|DPw zlUfqcYBsOV@AH)>j9^hqHU@^t7DCa-{{=IfE;7`pwD)|&2o@D!2g)pP2njso@nU(^ zyYfQ;yyc8wQ4J0ThFQ1vXbZ>pD(?BqQSRTmWC9~t)RvQhVMFoevXckfQzCcB@jPU( z^JWB#3UV;kmpXONOO7hu6FAz|6o7P6v#v z41!Dt8My2e3>9h=ltN3=ER?tufS^Vp4h$3mic-^3ixd({fl>(y`DGwBNLhj&7nd%T z0atKodU|ScNoIbYf}y^ll|oQzK~7?FD%3`W^30M9s7v&Kt^_-|6zpUa|FAJa{gYO# zSCpEV;+C0{s-dT+mj8NI7~EA0)=^9q>4__f6N{5GGhrSDtE8_-Ayz^?3ULfPlEGZGSmuPqa$agV zN(oElf^Sg7H4Z;wi*BTPHChR#K`EAmU>P!@g58Jsi#dq@i74gypJn(aq6N`>>{@au{%^jLsP-lPN5pzpBXq)1;X9&=xSWeo@iK55?|~Op}d6YJ8VV%YX&SS3r{!q5Ff%%-ICee`b QKaNHa0MPw&AW0Jd0E)NbF8}}l literal 437 zcmV;m0ZRTsRzVKK85o!u*uk!0WMvR! zI>^9fr(md1qo5R8l4haAr2qsq3UOed5KxqwmRh8cPzsbvP{=O>u|dib^tiZmsSLP+ zOViU+i%T-|^ArsA4XqS{QVVhtlT)EKDwJoIWI$b_2XrOa$)#W?qxk12+&@4`T{I72 z_YqhjeZ2&+l2|{TfcwcY*xAz)m!A@glQT16o&u|+ucshZLOlg>4BS^>F3zY54RIqb zs=x~Aoch345*t;5j8H!%mM3PGD5MqZ6{RMoxMk*~YNP=P9hhHrG@-u51%^y0;Pfas fbb$WE9_Q-dETBHrvM0#dKvx3*bhZN@ {})', + 'fs.readFileSync(file, "UTF-8")', + 'fs[readFile](file, "UTF-8")', + 'fs["readFile"](file, "UTF-8")', 'await fs.readFile(file, "UTF-8",)', + 'fs.promises.readFile(file, "UTF-8",)', + 'whatever.readFile(file, "UTF-8",)', ], });