From f558b79bfe1f09dfca4ee5d90c7d9e5f0155304d Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Mon, 17 Feb 2020 22:38:51 +0900 Subject: [PATCH] Fixed false positives for binded and unbinded attrs in 'vue/attributes-order' with `alphabetical` option. (#1055) * Fixed false positives for binded and unbinded attrs in 'vue/attributes-order' with `alphabetical` option. * Fixed #1056 * test timeout to 300000ms * revert timeout --- docs/rules/attributes-order.md | 16 ++- lib/rules/attributes-order.js | 23 ++++- tests/lib/rules/attributes-order.js | 150 ++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 7 deletions(-) diff --git a/docs/rules/attributes-order.md b/docs/rules/attributes-order.md index 879ec1d57..59941462a 100644 --- a/docs/rules/attributes-order.md +++ b/docs/rules/attributes-order.md @@ -106,12 +106,13 @@ This rule aims to enforce ordering of component attributes. The default order is "EVENTS", "CONTENT" ], - "alphabetical": true + "alphabetical": false }] } ``` -### Alphabetical order +### `"alphabetical": true` + ```vue @@ -122,6 +123,8 @@ This rule aims to enforce ordering of component attributes. The default order is :another-custom-prop="value" :blue-color="false" boolean-prop + class="foo" + :class="bar" z-prop="Z" v-on:[c]="functionCall" @change="functionCall" @@ -147,8 +150,13 @@ This rule aims to enforce ordering of component attributes. The default order is
+ :z-prop="Z" + :a-prop="A"> +
+ +
diff --git a/lib/rules/attributes-order.js b/lib/rules/attributes-order.js index ac8afe283..32b1cb102 100644 --- a/lib/rules/attributes-order.js +++ b/lib/rules/attributes-order.js @@ -24,10 +24,20 @@ const ATTRS = { function getAttributeName (attribute, sourceCode) { const isBind = attribute.directive && attribute.key.name.name === 'bind' - debugger return isBind ? (attribute.key.argument ? sourceCode.getText(attribute.key.argument) : '') - : (attribute.directive ? sourceCode.getText(attribute.key.argument) : attribute.key.name) + : (attribute.directive ? getDirectiveKeyName(attribute.key, sourceCode) : attribute.key.name) +} + +function getDirectiveKeyName (directiveKey, sourceCode) { + let text = 'v-' + directiveKey.name.name + if (directiveKey.argument) { + text += ':' + sourceCode.getText(directiveKey.argument) + } + for (const modifier of directiveKey.modifiers) { + text += '.' + modifier.name + } + return text } function getAttributeType (attribute, sourceCode) { @@ -75,7 +85,14 @@ function getPosition (attribute, attributePosition, sourceCode) { function isAlphabetical (prevNode, currNode, sourceCode) { const isSameType = getAttributeType(prevNode, sourceCode) === getAttributeType(currNode, sourceCode) if (isSameType) { - return getAttributeName(prevNode, sourceCode) < getAttributeName(currNode, sourceCode) + const prevName = getAttributeName(prevNode, sourceCode) + const currName = getAttributeName(currNode, sourceCode) + if (prevName === currName) { + const prevIsBind = Boolean(prevNode.directive && prevNode.key.name.name === 'bind') + const currIsBind = Boolean(currNode.directive && currNode.key.name.name === 'bind') + return prevIsBind <= currIsBind + } + return prevName < currName } return true } diff --git a/tests/lib/rules/attributes-order.js b/tests/lib/rules/attributes-order.js index 481148f9d..5583c9a1c 100644 --- a/tests/lib/rules/attributes-order.js +++ b/tests/lib/rules/attributes-order.js @@ -312,6 +312,72 @@ tester.run('attributes-order', rule, { `, options: [{ alphabetical: true }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }] + }, + { + filename: 'duplicate.vue', + code: + ``, + options: [{ alphabetical: true }] + }, + { + filename: 'duplicate.vue', + code: + ``, + options: [{ alphabetical: true }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }] } ], @@ -778,6 +844,90 @@ tester.run('attributes-order', rule, { message: 'Attribute "v-on:click" should go before "v-text".', type: 'VDirectiveKey' }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }], + output: + ``, + errors: [{ + message: 'Attribute "class" should go before ":class".' + }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }], + output: + ``, + errors: [{ + message: 'Attribute "v-if" should go before "v-show".' + }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }], + output: + ``, + errors: [{ + message: 'Attribute "v-bar" should go before "v-foo".' + }] + }, + { + filename: 'test.vue', + code: + ``, + options: [{ alphabetical: true }], + output: + ``, + errors: [{ + message: 'Attribute "v-foo.a" should go before "v-foo.b".' + }] } ] })