From adfb5daa5d3859b8c07097de6ff0bf342b9ad062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Sun, 11 Nov 2018 02:33:54 +0100 Subject: [PATCH 1/5] Fix #616 - Improve error message in max-attributes-per-line, remove white spaces --- lib/rules/max-attributes-per-line.js | 32 +++++++++++++++++----- tests/lib/rules/max-attributes-per-line.js | 30 ++++++++++++++------ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/lib/rules/max-attributes-per-line.js b/lib/rules/max-attributes-per-line.js index 517a4ef89..70c2a4ccc 100644 --- a/lib/rules/max-attributes-per-line.js +++ b/lib/rules/max-attributes-per-line.js @@ -70,6 +70,7 @@ module.exports = { const multilineMaximum = configuration.multiline const singlelinemMaximum = configuration.singleline const canHaveFirstLine = configuration.allowFirstLine + const template = context.parserServices.getTemplateBodyTokenStore && context.parserServices.getTemplateBodyTokenStore() return utils.defineTemplateBodyVisitor(context, { 'VStartTag' (node) { @@ -78,17 +79,17 @@ module.exports = { if (!numberOfAttributes) return if (utils.isSingleLine(node) && numberOfAttributes > singlelinemMaximum) { - showErrors(node.attributes.slice(singlelinemMaximum), node) + showErrors(node.attributes.slice(singlelinemMaximum)) } if (!utils.isSingleLine(node)) { if (!canHaveFirstLine && node.attributes[0].loc.start.line === node.loc.start.line) { - showErrors([node.attributes[0]], node) + showErrors([node.attributes[0]]) } groupAttrsByLine(node.attributes) .filter(attrs => attrs.length > multilineMaximum) - .forEach(attrs => showErrors(attrs.splice(multilineMaximum), node)) + .forEach(attrs => showErrors(attrs.splice(multilineMaximum))) } } }) @@ -128,16 +129,33 @@ module.exports = { return defaults } - function showErrors (attributes, node) { + function showErrors (attributes) { attributes.forEach((prop, i) => { + const isBinding = prop.key.name === 'bind' + + const fix = (fixer) => { + if (i !== 0) return null + + // Find the closest token before the current prop + // that is not a white space + const prevToken = template.getTokenBefore(prop, { + filter: (token) => token.type !== 'HTMLWhitespace' + }) + + const range = [prevToken.range[1], prop.range[0]] + + return fixer.replaceTextRange(range, '\n') + } + context.report({ node: prop, loc: prop.loc, - message: 'Attribute "{{propName}}" should be on a new line.', + message: '{{propType}} "{{propName}}" should be on a new line.', data: { - propName: prop.key.name + propType: isBinding ? 'Binding' : 'Attribute', + propName: isBinding ? prop.key.raw.argument : prop.key.name }, - fix: i === 0 ? (fixer) => fixer.insertTextBefore(prop, '\n') : undefined + fix }) }) } diff --git a/tests/lib/rules/max-attributes-per-line.js b/tests/lib/rules/max-attributes-per-line.js index 0e8ab915f..0f0f3c114 100644 --- a/tests/lib/rules/max-attributes-per-line.js +++ b/tests/lib/rules/max-attributes-per-line.js @@ -91,17 +91,29 @@ ruleTester.run('max-attributes-per-line', rule, { invalid: [ { code: ``, - output: ``, errors: ['Attribute "age" should be on a new line.'] }, + { + code: ``, + output: ``, + errors: ['Binding "age" should be on a new line.'] + }, + { + code: ``, + output: ``, + errors: ['Binding "age" should be on a new line.'] + }, { code: ``, - output: ``, { code: ``, options: [{ singleline: 1, multiline: { max: 1, allowFirstLine: false }}], - output: ``, errors: [{ message: 'Attribute "age" should be on a new line.', @@ -145,7 +157,7 @@ age="30" job="Vet">`, `, options: [{ singleline: 3, multiline: { max: 1, allowFirstLine: false }}], - output: ``, options: [{ singleline: 3, multiline: { max: 1, allowFirstLine: false }}], output: ``, options: [{ singleline: 3, multiline: 1 }], output: ``, :age="user.age">`, errors: ['Binding "age" should be on a new line.'] }, + { + code: ``, + output: ``, + errors: ['Event "buy" should be on a new line.'] + }, + { + code: ``, + output: ``, + errors: ['Event "click" should be on a new line.'] + }, + { + code: ``, + output: ``, + errors: ['Directive "v-if" should be on a new line.'] + }, { code: ``, output: ``, code: ``, output: ``, - errors: ['Directive "v-if" should be on a new line.'] + errors: ['Directive "if" should be on a new line.'] }, { code: ``, From af215d4d91376f619a68102a2e503e01c8d9fd28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Mon, 12 Nov 2018 21:21:07 +0100 Subject: [PATCH 5/5] 616 Handle v-bind case --- lib/rules/max-attributes-per-line.js | 2 +- lib/utils/index.js | 15 +++------------ tests/lib/rules/max-attributes-per-line.js | 6 ++++++ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/lib/rules/max-attributes-per-line.js b/lib/rules/max-attributes-per-line.js index 573816c77..421e55394 100644 --- a/lib/rules/max-attributes-per-line.js +++ b/lib/rules/max-attributes-per-line.js @@ -139,7 +139,7 @@ module.exports = { } else if (utils.isEventAttribute(prop)) { propType = 'Event' propName = prop.key.raw.argument - } else if (utils.isDirectiveAttribute(prop)) { + } else if (prop.directive) { propType = 'Directive' } diff --git a/lib/utils/index.js b/lib/utils/index.js index fc29ec315..bc9cc0407 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -300,7 +300,9 @@ module.exports = { * @returns {boolean} */ isBindingAttribute (attribute) { - return attribute.directive && attribute.key.name === 'bind' + return attribute.directive && + attribute.key.name === 'bind' && + attribute.key.argument }, /** @@ -312,17 +314,6 @@ module.exports = { return attribute.directive && attribute.key.name === 'on' }, - /** - * Check whether the given attribute node is a directive - * @param {ASTNode} name The attribute to check. - * @returns {boolean} - */ - isDirectiveAttribute (attribute) { - return attribute.directive && - attribute.key.name !== 'on' && - attribute.key.name !== 'bind' - }, - /** * Parse member expression node to get array with all of its parts * @param {ASTNode} MemberExpression diff --git a/tests/lib/rules/max-attributes-per-line.js b/tests/lib/rules/max-attributes-per-line.js index c34fee373..ce4d45ffe 100644 --- a/tests/lib/rules/max-attributes-per-line.js +++ b/tests/lib/rules/max-attributes-per-line.js @@ -101,6 +101,12 @@ age="30">`, :age="user.age">`, errors: ['Binding "age" should be on a new line.'] }, + { + code: ``, + output: ``, + errors: ['Directive "bind" should be on a new line.'] + }, { code: ``, output: `