Skip to content

Commit

Permalink
Fixes gh lucasefe#13: Destructuring assignment should not confuse the…
Browse files Browse the repository at this point in the history
… rule
  • Loading branch information
Daniel Perrett committed Mar 3, 2021
1 parent d7c2364 commit 10b8e24
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 18 deletions.
34 changes: 16 additions & 18 deletions lib/rules/align-assignments.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,23 @@ module.exports = {
message: 'This group of assignments is not aligned',
fix: fixer => {
const fixings = group.map(function(node) {
const tokens = sourceCode.getTokens(node);
const firstToken = tokens[0];
const assignmentToken = tokens.find(token => [ '=', '+=', '-=', '*=', '/=', '%=', '&=', '^=', '|=', '<<=', '>>=', '**=', '>>>=' ].includes(token.value));
const line = sourceCode.getText(node);
const lineIsAligned = line.charAt(maxPos) === '=';
const tokens = sourceCode.getTokens(node);
const firstToken = tokens[0];
const assignmentToken = tokens.find(token => [ '=', '+=', '-=', '*=', '/=', '%=', '&=', '^=', '|=', '<<=', '>>=', '**=', '>>>=' ].includes(token.value));
const line = sourceCode.getText(node);
const lineIsAligned = line.charAt(maxPos) === '=';

if (lineIsAligned || !assignmentToken || isMultiline(firstToken, assignmentToken))
return fixer.replaceText(node, line);
else {
// source line may include spaces, we need to accomodate for that.
const assignmentPos = findAssignment(node);
const spacePrefix = firstToken.loc.start.column;
const startDelimiter = assignmentToken.loc.start.column - spacePrefix;
const endDelimiter = assignmentToken.loc.end.column - spacePrefix;
const start = line.slice(0, startDelimiter).replace(/\s+$/m, '');
const ending = line.slice(endDelimiter).replace(/^\s+/m, '');
const spacesRequired = maxPos - start.length - assignmentToken.value.length + 1;
const spacesRequired = maxPos - assignmentPos + 1;
const spaces = ' '.repeat(spacesRequired);
const fixedText = `${start}${spaces}${assignmentToken.value} ${ending}`;
return fixer.replaceText(node, fixedText);
Expand All @@ -122,27 +124,23 @@ module.exports = {
}

function findAssignment(node) {
const prefix = getPrefix(node);
const source = sourceCode.getText(node);
const match = source.substr(prefix).match(spaceMatcher);
const position = match ? match.index + prefix + match[2].length : null;
return position;
}

function getPrefix(node) {
const nodeBefore = isAssignmentExpression(node) ?
node.left :
node.declarations.find(dcl => dcl.type === 'VariableDeclarator').id;
const source = sourceCode.getText(node);
const spacePrefix = sourceCode.getTokens(node)[0].loc.start.column;
const match = source.substr(nodeBefore.loc.end.column - spacePrefix - 1).match(spaceMatcher);
const position = match ? nodeBefore.loc.end.column - spacePrefix + match.index + match[2].length - 1 : null;

const prefix = nodeBefore.loc.end.column - nodeBefore.loc.start.column;
return prefix;
return position;
}

function areAligned(maxPos, nodes) {
return nodes
.filter(assignmentOnFirstLine)
.map(node => sourceCode.getText(node))
.every(source => source.charAt(maxPos) === '=');
.every(
node => sourceCode.getText(node).charAt(maxPos) === '='
);
}

function getMaxPos(nodes) {
Expand Down
52 changes: 52 additions & 0 deletions tests/lib/rules/align-assignments_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ ruleTester.run('align-assignments', rule, {
'for (let i = outArray.length - 1; i >= 0; i--)',
' out += outArray[i].toString(toBase);'
])
},
{
code: code([
'const { foo = ({}) } = {}',
'const bar = {}'
])
},
{
code: code([
'const { foo = {} } = {}',
'const bar = {}'
])
}
],
invalid: [
Expand Down Expand Up @@ -314,7 +326,47 @@ ruleTester.run('align-assignments', rule, {
errors: [
{ message: 'This group of assignments is not aligned' }
]
},
{
code: code([
'const { foo = ({}) } = {}',
'const bar = {}'
]),
output: code([
'const { foo = ({}) } = {}',
'const bar = {}'
]),
errors: [
{ message: 'This group of assignments is not aligned' }
]
},
{
code: code([
'const { foo = {} } = {}',
'const bar = {}'
]),
output: code([
'const { foo = {} } = {}',
'const bar = {}'
]),
errors: [
{ message: 'This group of assignments is not aligned' }
]
},
{
code: code([
'const { foo = {} } = {}',
'const bar = {}'
]),
output: code([
'const { foo = {} } = {}',
'const bar = {}'
]),
errors: [
{ message: 'This group of assignments is not aligned' }
]
}

]
});

Expand Down

0 comments on commit 10b8e24

Please sign in to comment.