Skip to content

Commit

Permalink
Fix: change multiline-always to proportional-always
Browse files Browse the repository at this point in the history
- If the node is multiline then require newline
- If the node is singleline then require space

Signed-off-by: Sebastian Malton <sebastian@malton.name>
  • Loading branch information
Nokel81 committed Apr 5, 2022
1 parent c297a96 commit 25d74d5
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 64 deletions.
108 changes: 62 additions & 46 deletions lib/rules/jsx-tag-spacing.js
Expand Up @@ -101,9 +101,9 @@ function validateBeforeSelfClosing(context, node, option) {
const leftToken = getTokenBeforeClosingBracket(node);
const closingSlash = sourceCode.getTokenAfter(leftToken);

if (node.loc.start.line !== node.loc.end.line && option === 'multiline-always') {
if (node.loc.start.line !== node.loc.end.line && option === 'proportional-always') {
if (leftToken.loc.end.line === closingSlash.loc.start.line) {
report(context, messages.beforeSelfCloseNeedNewline, 'beforeSelfCloseNeedNewline', {
return report(context, messages.beforeSelfCloseNeedNewline, 'beforeSelfCloseNeedNewline', {
node,
loc: leftToken.loc.end,
fix(fixer) {
Expand All @@ -117,15 +117,17 @@ function validateBeforeSelfClosing(context, node, option) {
return;
}

if (option === 'always' && !sourceCode.isSpaceBetweenTokens(leftToken, closingSlash)) {
const adjacent = !sourceCode.isSpaceBetweenTokens(leftToken, closingSlash);

if ((option === 'always' || option === 'proportional-always') && adjacent) {
report(context, messages.beforeSelfCloseNeedSpace, 'beforeSelfCloseNeedSpace', {
node,
loc: closingSlash.loc.start,
fix(fixer) {
return fixer.insertTextBefore(closingSlash, ' ');
},
});
} else if (option === 'never' && sourceCode.isSpaceBetweenTokens(leftToken, closingSlash)) {
} else if (option === 'never' && !adjacent) {
report(context, messages.beforeSelfCloseNoSpace, 'beforeSelfCloseNoSpace', {
node,
loc: closingSlash.loc.start,
Expand Down Expand Up @@ -178,54 +180,68 @@ function validateAfterOpening(context, node, option) {

function validateBeforeClosing(context, node, option) {
// Don't enforce this rule for self closing tags
if (!node.selfClosing) {
const sourceCode = context.getSourceCode();
const lastTokens = sourceCode.getLastTokens(node, 2);
const closingToken = lastTokens[1];
const leftToken = lastTokens[0];

if (node.loc.start.line !== node.loc.end.line && option === 'multiline-always') {
if (leftToken.loc.end.line === closingToken.loc.start.line) {
report(context, messages.beforeCloseNeedNewline, 'beforeCloseNeedNewline', {
node,
loc: leftToken.loc.end,
fix(fixer) {
return fixer.insertTextBefore(closingToken, '\n');
},
});
}
}

if (leftToken.loc.start.line !== closingToken.loc.start.line) {
return;
}
if (node.selfClosing) {
return;
}

const adjacent = !sourceCode.isSpaceBetweenTokens(leftToken, closingToken);
const sourceCode = context.getSourceCode();
const leftToken = option === 'proportional-always'
? getTokenBeforeClosingBracket(node)
: sourceCode.getLastTokens(node, 2)[0];
const closingToken = sourceCode.getTokenAfter(leftToken);

if (option === 'never' && !adjacent) {
report(context, messages.beforeCloseNoSpace, 'beforeCloseNoSpace', {
if (node.loc.start.line !== node.loc.end.line && option === 'proportional-always') {
if (leftToken.loc.end.line === closingToken.loc.start.line) {
return report(context, messages.beforeCloseNeedNewline, 'beforeCloseNeedNewline', {
node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start,
},
fix(fixer) {
return fixer.removeRange([leftToken.range[1], closingToken.range[0]]);
},
});
} else if (option === 'always' && adjacent) {
report(context, messages.beforeCloseNeedSpace, 'beforeCloseNeedSpace', {
node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start,
},
loc: leftToken.loc.end,
fix(fixer) {
return fixer.insertTextBefore(closingToken, ' ');
return fixer.insertTextBefore(closingToken, '\n');
},
});
}
}

if (leftToken.loc.start.line !== closingToken.loc.start.line) {
return;
}

const adjacent = !sourceCode.isSpaceBetweenTokens(leftToken, closingToken);

if (option === 'never' && !adjacent) {
report(context, messages.beforeCloseNoSpace, 'beforeCloseNoSpace', {
node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start,
},
fix(fixer) {
return fixer.removeRange([leftToken.range[1], closingToken.range[0]]);
},
});
} else if (option === 'always' && adjacent) {
report(context, messages.beforeCloseNeedSpace, 'beforeCloseNeedSpace', {
node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start,
},
fix(fixer) {
return fixer.insertTextBefore(closingToken, ' ');
},
});
} else if (option === 'proportional-always' && node.type === 'JSXOpeningElement' && adjacent !== (node.loc.start.line === node.loc.end.line)) {
report(context, messages.beforeCloseNeedSpace, 'beforeCloseNeedSpace', {
node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start,
},
fix(fixer) {
return fixer.insertTextBefore(closingToken, ' ');
},
});
}
}

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -259,13 +275,13 @@ module.exports = {
enum: ['always', 'never', 'allow'],
},
beforeSelfClosing: {
enum: ['always', 'multiline-always', 'never', 'allow'],
enum: ['always', 'proportional-always', 'never', 'allow'],
},
afterOpening: {
enum: ['always', 'allow-multiline', 'never', 'allow'],
},
beforeClosing: {
enum: ['always', 'multiline-always', 'never', 'allow'],
enum: ['always', 'proportional-always', 'never', 'allow'],
},
},
default: optionDefaults,
Expand Down
2 changes: 1 addition & 1 deletion lib/util/getTokenBeforeClosingBracket.js
Expand Up @@ -7,7 +7,7 @@
*/
function getTokenBeforeClosingBracket(node) {
const attributes = node.attributes;
if (attributes.length === 0) {
if (!attributes || attributes.length === 0) {
return node.name;
}
return attributes[attributes.length - 1];
Expand Down
38 changes: 21 additions & 17 deletions tests/lib/rules/jsx-tag-spacing.js
Expand Up @@ -114,21 +114,13 @@ ruleTester.run('jsx-tag-spacing', rule, {
code: '<App/>',
options: beforeSelfClosingOptions('never'),
},
{
code: '<App/>',
options: beforeSelfClosingOptions('multiline-always'),
},
{
code: '<App />',
options: beforeSelfClosingOptions('multiline-always'),
},
{
code: '<App foo/>',
options: beforeSelfClosingOptions('multiline-always'),
options: beforeSelfClosingOptions('proportional-always'),
},
{
code: '<App foo />',
options: beforeSelfClosingOptions('multiline-always'),
options: beforeSelfClosingOptions('proportional-always'),
},
{
code: `
Expand All @@ -139,23 +131,23 @@ ruleTester.run('jsx-tag-spacing', rule, {
hello
</App>
`,
options: beforeClosingOptions('multiline-always'),
options: beforeClosingOptions('proportional-always'),
},
{
code: `
<App foo={bar}>
hello
</App>
`,
options: beforeClosingOptions('multiline-always'),
options: beforeClosingOptions('proportional-always'),
},
{
code: `
<App
foo={bar}
/>
`,
options: beforeSelfClosingOptions('multiline-always'),
options: beforeSelfClosingOptions('proportional-always'),
},
{
code: '<App foo/>',
Expand Down Expand Up @@ -345,6 +337,18 @@ ruleTester.run('jsx-tag-spacing', rule, {
options: beforeSelfClosingOptions('never'),
errors: [{ messageId: 'beforeSelfCloseNoSpace' }],
},
{
code: '<App/>',
output: '<App />',
options: beforeSelfClosingOptions('proportional-always'),
errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],
},
{
code: '<App foo/>',
output: '<App foo />',
options: beforeSelfClosingOptions('proportional-always'),
errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],
},
{
code: `
<App
Expand All @@ -353,7 +357,7 @@ ruleTester.run('jsx-tag-spacing', rule, {
<App
foo={bar}
/>`,
options: beforeSelfClosingOptions('multiline-always'),
options: beforeSelfClosingOptions('proportional-always'),
errors: [{ messageId: 'beforeSelfCloseNeedNewline' }],
},
{
Expand All @@ -364,7 +368,7 @@ ruleTester.run('jsx-tag-spacing', rule, {
<App
foo={bar}${' '}
/>`,
options: beforeSelfClosingOptions('multiline-always'),
options: beforeSelfClosingOptions('proportional-always'),
errors: [{ messageId: 'beforeSelfCloseNeedNewline' }],
},
{
Expand All @@ -383,7 +387,7 @@ ruleTester.run('jsx-tag-spacing', rule, {
hello
</App>
`,
options: beforeClosingOptions('multiline-always'),
options: beforeClosingOptions('proportional-always'),
errors: [{ messageId: 'beforeCloseNeedNewline' }],
},
{
Expand All @@ -400,7 +404,7 @@ ruleTester.run('jsx-tag-spacing', rule, {
hello
</App>
`,
options: beforeClosingOptions('multiline-always'),
options: beforeClosingOptions('proportional-always'),
errors: [{ messageId: 'beforeCloseNeedNewline' }],
},
{
Expand Down

0 comments on commit 25d74d5

Please sign in to comment.