Skip to content

Commit

Permalink
feat: add new rule enforce-line-break (#484)
Browse files Browse the repository at this point in the history
* feat: add new rule enforce-line-break

* feat: edit new rule enforce line break - don't add line if comments above type declaration is on the 1st line, update tests

* fix: clean up code

* fix: change message - enforceLineBreak

Co-authored-by: Angelica Bocanegra <angelica.bocanegra@tabcorp.com.au>
  • Loading branch information
angelica-bocanegra and Angelica Bocanegra committed Jun 29, 2021
1 parent d2f6d9b commit 417068c
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 0 deletions.
1 change: 1 addition & 0 deletions .README/README.md
Expand Up @@ -160,6 +160,7 @@ When `true`, only checks files with a [`@flow` annotation](http://flowtype.org/d
{"gitdown": "include", "file": "./rules/boolean-style.md"}
{"gitdown": "include", "file": "./rules/define-flow-type.md"}
{"gitdown": "include", "file": "./rules/delimiter-dangle.md"}
{"gitdown": "include", "file": "./rules/enforce-line-break.md"}
{"gitdown": "include", "file": "./rules/generic-spacing.md"}
{"gitdown": "include", "file": "./rules/newline-after-flow-annotation.md"}
{"gitdown": "include", "file": "./rules/no-dupe-keys.md"}
Expand Down
5 changes: 5 additions & 0 deletions .README/rules/enforce-line-break.md
@@ -0,0 +1,5 @@
### `enforce-line-break`

This rule enforces line breaks between type definitions.

<!-- assertions enforceLineBreak -->
78 changes: 78 additions & 0 deletions README.md
Expand Up @@ -22,6 +22,7 @@
* [`boolean-style`](#eslint-plugin-flowtype-rules-boolean-style)
* [`define-flow-type`](#eslint-plugin-flowtype-rules-define-flow-type)
* [`delimiter-dangle`](#eslint-plugin-flowtype-rules-delimiter-dangle)
* [`enforce-line-break`](#eslint-plugin-flowtype-rules-enforce-line-break)
* [`generic-spacing`](#eslint-plugin-flowtype-rules-generic-spacing)
* [`newline-after-flow-annotation`](#eslint-plugin-flowtype-rules-newline-after-flow-annotation)
* [`no-dupe-keys`](#eslint-plugin-flowtype-rules-no-dupe-keys)
Expand Down Expand Up @@ -1662,6 +1663,83 @@ type X = []
<a name="eslint-plugin-flowtype-rules-enforce-line-break"></a>
### <code>enforce-line-break</code>
This rule enforces line breaks between type definitions.
The following patterns are considered problems:
```js
type baz = 6;
const hi = 2;
// Message: New line required below type declaration

const foo = 6;
type hi = 2;

// Message: New line required above type declaration

const som = "jes";
// a comment
type fed = "hed";

// Message: New line required above type declaration

type som = "jes";
// a comment
const fed = "hed";

// Message: New line required below type declaration

type hello = 34;
const som = "jes";
type fed = "hed";

// Message: New line required below type declaration
// Message: New line required above type declaration
```
The following patterns are not considered problems:
```js
type gjs = 6;

type gjs = 6;

type hi = 2;


type X = 4;

const red = "serpent";
console.log("hello");

// number or string
type Y = string | number;

// resting + sleep
type snooze = "dreaming" | "";

type Props = {
accountBalance: string | number,
accountNumber: string | number,
};

const x = 4;
const y = 489;

// Some Comment
type Props = {
accountBalance: string | number,
accountNumber: string | number,
};

type RoadT = "grass" | "gravel" | "cement";
```
<a name="eslint-plugin-flowtype-rules-generic-spacing"></a>
### <code>generic-spacing</code>
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Expand Up @@ -6,6 +6,7 @@ import arrayStyleSimpleType from './rules/arrayStyleSimpleType';
import booleanStyle from './rules/booleanStyle';
import defineFlowType from './rules/defineFlowType';
import delimiterDangle from './rules/delimiterDangle';
import enforceLineBreak from './rules/enforceLineBreak';
import genericSpacing from './rules/genericSpacing';
import newlineAfterFlowAnnotation from './rules/newlineAfterFlowAnnotation';
import noDupeKeys from './rules/noDupeKeys';
Expand Down Expand Up @@ -53,6 +54,7 @@ const rules = {
'boolean-style': booleanStyle,
'define-flow-type': defineFlowType,
'delimiter-dangle': delimiterDangle,
'enforce-line-break': enforceLineBreak,
'generic-spacing': genericSpacing,
'newline-after-flow-annotation': newlineAfterFlowAnnotation,
'no-dupe-keys': noDupeKeys,
Expand Down
63 changes: 63 additions & 0 deletions src/rules/enforceLineBreak.js
@@ -0,0 +1,63 @@
const schema = [];

const breakLineMessage = (direction) => {
return `New line required ${direction} type declaration`;
};

const create = (context) => {
return {
TypeAlias (node) {
const sourceCode = context.getSourceCode();
if (sourceCode.lines.length === 1) {
return;
}

if (node.loc.start.line !== 1) {
if (node.leadingComments && node.leadingComments[0].loc.start.line !== 1) {
const lineAboveComment = sourceCode.lines[node.leadingComments[0].loc.start.line - 2];
if (lineAboveComment !== '') {
context.report({
fix (fixer) {
return fixer.insertTextBeforeRange(node.leadingComments[0].range, '\n');
},
message: breakLineMessage('above'),
node,
});
}
} else if (!node.leadingComments) {
const isLineAbove = sourceCode.lines[node.loc.start.line - 2];
if (isLineAbove !== '') {
context.report({
fix (fixer) {
return fixer.insertTextBefore(node, '\n');
},
message: breakLineMessage('above'),
node,
});
}
}
}

if (sourceCode.lines.length !== node.loc.end.line) {
const isLineBelow = sourceCode.lines[node.loc.end.line];
if (isLineBelow !== '') {
context.report({
fix (fixer) {
return fixer.insertTextAfter(node, '\n');
},
message: breakLineMessage('below'),
node,
});
}
}
},
};
};

export default {
create,
meta: {
fixable: 'code',
},
schema,
};
81 changes: 81 additions & 0 deletions tests/rules/assertions/enforceLineBreak.js
@@ -0,0 +1,81 @@
export default {
invalid: [
{
code: 'type baz = 6;\nconst hi = 2;',
errors: [{
message: 'New line required below type declaration',
}],
output: 'type baz = 6;\n\nconst hi = 2;',
},
{
code: 'const foo = 6;\ntype hi = 2;\n',
errors: [
{message: 'New line required above type declaration'},
],
output: 'const foo = 6;\n\ntype hi = 2;\n',
},
{
code: 'const som = "jes";\n// a comment\ntype fed = "hed";\n',
errors: [
{message: 'New line required above type declaration'},
],
output: 'const som = "jes";\n\n// a comment\ntype fed = "hed";\n',
},
{
code: 'type som = "jes";\n// a comment\nconst fed = "hed";\n',
errors: [
{message: 'New line required below type declaration'},
],
output: 'type som = "jes";\n\n// a comment\nconst fed = "hed";\n',
},
{
code: 'type hello = 34;\nconst som = "jes";\ntype fed = "hed";\n',
errors: [
{message: 'New line required below type declaration'},
{message: 'New line required above type declaration'},
],
output: 'type hello = 34;\n\nconst som = "jes";\n\ntype fed = "hed";\n',
},
],
valid: [
{
code: 'type gjs = 6;',
},
{
code: 'type gjs = 6;\n\ntype hi = 2;\n',
},
{
code:
`type X = 4;
const red = "serpent";
console.log("hello");
// number or string
type Y = string | number;
// resting + sleep
type snooze = "dreaming" | "";`,
},
{
code:
`type Props = {
accountBalance: string | number,
accountNumber: string | number,
};`,
},
{
code:
`const x = 4;
const y = 489;
// Some Comment
type Props = {
accountBalance: string | number,
accountNumber: string | number,
};
type RoadT = "grass" | "gravel" | "cement";`,
},
],
};
1 change: 1 addition & 0 deletions tests/rules/index.js
Expand Up @@ -17,6 +17,7 @@ const reportingRules = [
'boolean-style',
'define-flow-type',
'delimiter-dangle',
'enforce-line-break',
'generic-spacing',
'newline-after-flow-annotation',
'no-dupe-keys',
Expand Down

0 comments on commit 417068c

Please sign in to comment.