diff --git a/lib/rules/align-assignments.js b/lib/rules/align-assignments.js index 4f2ab9c..419095a 100644 --- a/lib/rules/align-assignments.js +++ b/lib/rules/align-assignments.js @@ -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); @@ -121,34 +123,30 @@ module.exports = { return firstToken.loc.start.line !== assignmentToken.loc.start.line; } - function findAssigment(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) { + function findAssignment(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) { return nodes .filter(assignmentOnFirstLine) - .map(findAssigment) + .map(findAssignment) .reduce((last, current) => Math.max(last, current), []); } diff --git a/tests/lib/rules/align-assignments_test.js b/tests/lib/rules/align-assignments_test.js index b7a03ea..fa55233 100644 --- a/tests/lib/rules/align-assignments_test.js +++ b/tests/lib/rules/align-assignments_test.js @@ -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: [ @@ -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' } + ] } + ] });