Skip to content

Commit

Permalink
text-encoding-identifier-case: Auto-fix encoding in `fs.{readFile,r…
Browse files Browse the repository at this point in the history
…eadFileSync}()` (#1755)
  • Loading branch information
fisker committed Mar 25, 2022
1 parent 93f49f2 commit 5e1c932
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 14 deletions.
4 changes: 3 additions & 1 deletion docs/rules/text-encoding-identifier-case.md
Expand Up @@ -4,12 +4,14 @@
<!-- RULE_NOTICE -->
*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).*
<!-- /RULE_NOTICE -->

- 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
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Expand Up @@ -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. || 🔧 | |
<!-- /RULES_TABLE -->

Expand Down
42 changes: 33 additions & 9 deletions rules/text-encoding-identifier-case.js
Expand Up @@ -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) {
Expand All @@ -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;
},
});

Expand All @@ -63,6 +86,7 @@ module.exports = {
docs: {
description: 'Enforce consistent case for text encoding identifiers.',
},
fixable: 'code',
hasSuggestions: true,
messages,
},
Expand Down
198 changes: 195 additions & 3 deletions test/snapshots/text-encoding-identifier-case.mjs.md
Expand Up @@ -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\`.␊
`
Binary file modified test/snapshots/text-encoding-identifier-case.mjs.snap
Binary file not shown.
13 changes: 13 additions & 0 deletions test/text-encoding-identifier-case.mjs
Expand Up @@ -19,6 +19,19 @@ test.snapshot({
'\'utf-8\'',
'"Utf8"',
'"ASCII"',
'fs.readFile?.(file, "UTF-8")',
'fs?.readFile(file, "UTF-8")',
'readFile(file, "UTF-8")',
'fs.readFile(...file, "UTF-8")',
'new fs.readFile(file, "UTF-8")',
'fs.readFile(file, {encoding: "UTF-8"})',
'fs.readFile("UTF-8")',
'fs.readFile(file, "UTF-8", () => {})',
'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",)',
],
});

0 comments on commit 5e1c932

Please sign in to comment.