Skip to content

Commit

Permalink
Add no-empty-file rule (#1506)
Browse files Browse the repository at this point in the history
Co-authored-by: fisker Cheung <lionkay@gmail.com>
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
3 people committed Nov 2, 2021
1 parent 46f8638 commit a2ba25e
Show file tree
Hide file tree
Showing 7 changed files with 603 additions and 0 deletions.
1 change: 1 addition & 0 deletions configs/recommended.js
Expand Up @@ -24,6 +24,7 @@ module.exports = {
'unicorn/no-array-reduce': 'error',
'unicorn/no-console-spaces': 'error',
'unicorn/no-document-cookie': 'error',
'unicorn/no-empty-file': 'error',
'unicorn/no-for-loop': 'error',
'unicorn/no-hex-escape': 'error',
'unicorn/no-instanceof-array': 'error',
Expand Down
65 changes: 65 additions & 0 deletions docs/rules/no-empty-file.md
@@ -0,0 +1,65 @@
# Disallow empty files

Meaningless files clutter a codebase.

Disallow any files only containing the following:

- Whitespace
- Comments
- Directives
- Empty statements
- Empty block statements
- Hashbang

## Fail

```js

```

```js
// Comment
```

```js
/* Comment */
```

```js
'use strict';
```

```js
;
```

```js
{
}
```

```js
#!/usr/bin/env node
```

## Pass

```js
const x = 0;
```

```js
'use strict';
const x = 0;
```

```js
;;
const x = 0;
```

```js
{
const x = 0;
}
```
2 changes: 2 additions & 0 deletions readme.md
Expand Up @@ -57,6 +57,7 @@ Configure it in `package.json`.
"unicorn/no-array-reduce": "error",
"unicorn/no-console-spaces": "error",
"unicorn/no-document-cookie": "error",
"unicorn/no-empty-file": "error",
"unicorn/no-for-loop": "error",
"unicorn/no-hex-escape": "error",
"unicorn/no-instanceof-array": "error",
Expand Down Expand Up @@ -180,6 +181,7 @@ Each rule has emojis denoting:
| [no-array-reduce](docs/rules/no-array-reduce.md) | Disallow `Array#reduce()` and `Array#reduceRight()`. || | |
| [no-console-spaces](docs/rules/no-console-spaces.md) | Do not use leading/trailing space between `console.log` parameters. || 🔧 | |
| [no-document-cookie](docs/rules/no-document-cookie.md) | Do not use `document.cookie` directly. || | |
| [no-empty-file](docs/rules/no-empty-file.md) | Disallow empty files. || | |
| [no-for-loop](docs/rules/no-for-loop.md) | Do not use a `for` loop that can be replaced with a `for-of` loop. || 🔧 | |
| [no-hex-escape](docs/rules/no-hex-escape.md) | Enforce the use of Unicode escapes instead of hexadecimal escapes. || 🔧 | |
| [no-instanceof-array](docs/rules/no-instanceof-array.md) | Require `Array.isArray()` instead of `instanceof Array`. || 🔧 | |
Expand Down
47 changes: 47 additions & 0 deletions rules/no-empty-file.js
@@ -0,0 +1,47 @@
'use strict';

const MESSAGE_ID = 'no-empty-file';
const messages = {
[MESSAGE_ID]: 'Empty files are not allowed.',
};

const isEmpty = node =>
(
(node.type === 'Program' || node.type === 'BlockStatement')
&& node.body.every(currentNode => isEmpty(currentNode))
)
|| node.type === 'EmptyStatement'
|| (node.type === 'ExpressionStatement' && 'directive' in node);

const create = context => {
const filename = context.getPhysicalFilename().toLowerCase();

if (!/\.(?:js|mjs|cjs|ts|mts|cts)$/.test(filename)) {
return {};
}

return {
Program(node) {
if (!isEmpty(node)) {
return;
}

return {
node,
messageId: MESSAGE_ID,
};
},
};
};

module.exports = {
create,
meta: {
type: 'suggestion',
docs: {
description: 'Disallow empty files.',
},
schema: [],
messages,
},
};
74 changes: 74 additions & 0 deletions test/no-empty-file.mjs
@@ -0,0 +1,74 @@
import outdent from 'outdent';
import {getTester} from './utils/test.mjs';

const {test} = getTester(import.meta);

test.snapshot({
valid: [
...[
'const x = 0;',
';; const x = 0;',
'{{{;;const x = 0;}}}',
outdent`
'use strict';
const x = 0;
`,
';;\'use strict\';',
'{\'use strict\';}',
'("use strict")',
'`use strict`',
'({})',
outdent`
#!/usr/bin/env node
console.log('done');
`,
'false',
'("")',
'NaN',
'undefined',
'null',
'[]',
'(() => {})()',
].map(code => ({code, filename: 'example.js'})),
'',
...[
'md',
'vue',
'svelte',
'tsx',
].map(extension => ({code: '', filename: `example.${extension}`})),
],
invalid: [
...[
'',
'\uFEFF',
' ',
'\t',
'\n',
'\r',
'\r\n',
outdent`
`,
'// comment',
'/* comment */',
'#!/usr/bin/env node',
'\'use asm\';',
'\'use strict\';',
'"use strict"',
'""',
';',
';;',
'{}',
'{;;}',
'{{}}',
].map(code => ({code, filename: 'example.js'})),
...[
'mjs',
'cjs',
'ts',
'mts',
'cts',
].map(extension => ({code: '{}', filename: `example.${extension}`})),
],
});

0 comments on commit a2ba25e

Please sign in to comment.