Skip to content

Commit

Permalink
Fixed false positives for binded and unbinded attrs in 'vue/attribute…
Browse files Browse the repository at this point in the history
…s-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
  • Loading branch information
ota-meshi committed Feb 17, 2020
1 parent 667bb2e commit f558b79
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 7 deletions.
16 changes: 12 additions & 4 deletions docs/rules/attributes-order.md
Expand Up @@ -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`

<eslint-code-block fix :rules="{'vue/attributes-order': ['error', {alphabetical: true}]}">

```vue
Expand All @@ -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"
Expand All @@ -147,8 +150,13 @@ This rule aims to enforce ordering of component attributes. The default order is
</div>
<div
:a-prop="A"
:z-prop="Z">
:z-prop="Z"
:a-prop="A">
</div>
<div
:class="foo"
class="bar">
</div>
</template>
Expand Down
23 changes: 20 additions & 3 deletions lib/rules/attributes-order.js
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
}
Expand Down
150 changes: 150 additions & 0 deletions tests/lib/rules/attributes-order.js
Expand Up @@ -312,6 +312,72 @@ tester.run('attributes-order', rule, {
</div>
</template>`,
options: [{ alphabetical: true }]
},
{
filename: 'test.vue',
code:
`<template>
<div
class="foo"
:class="bar">
</div>
</template>`,
options: [{ alphabetical: true }]
},
{
filename: 'duplicate.vue',
code:
`<template>
<div
class="foo"
class="bar">
</div>
</template>`,
options: [{ alphabetical: true }]
},
{
filename: 'duplicate.vue',
code:
`<template>
<div
:class="foo"
:class="bar">
</div>
</template>`,
options: [{ alphabetical: true }]
},
{
filename: 'test.vue',
code:
`<template>
<div
v-if="foo"
v-show="bar">
</div>
</template>`,
options: [{ alphabetical: true }]
},
{
filename: 'test.vue',
code:
`<template>
<div
v-bar="bar"
v-foo="foo">
</div>
</template>`,
options: [{ alphabetical: true }]
},
{
filename: 'test.vue',
code:
`<template>
<div
v-foo.a="a"
v-foo.b="b">
</div>
</template>`,
options: [{ alphabetical: true }]
}
],

Expand Down Expand Up @@ -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:
`<template>
<div
:class="foo"
class="bar">
</div>
</template>`,
options: [{ alphabetical: true }],
output:
`<template>
<div
class="bar"
:class="foo">
</div>
</template>`,
errors: [{
message: 'Attribute "class" should go before ":class".'
}]
},
{
filename: 'test.vue',
code:
`<template>
<div
v-show="foo"
v-if="bar">
</div>
</template>`,
options: [{ alphabetical: true }],
output:
`<template>
<div
v-if="bar"
v-show="foo">
</div>
</template>`,
errors: [{
message: 'Attribute "v-if" should go before "v-show".'
}]
},
{
filename: 'test.vue',
code:
`<template>
<div
v-foo="foo"
v-bar="bar">
</div>
</template>`,
options: [{ alphabetical: true }],
output:
`<template>
<div
v-bar="bar"
v-foo="foo">
</div>
</template>`,
errors: [{
message: 'Attribute "v-bar" should go before "v-foo".'
}]
},
{
filename: 'test.vue',
code:
`<template>
<div
v-foo.b="b"
v-foo.a="a">
</div>
</template>`,
options: [{ alphabetical: true }],
output:
`<template>
<div
v-foo.a="a"
v-foo.b="b">
</div>
</template>`,
errors: [{
message: 'Attribute "v-foo.a" should go before "v-foo.b".'
}]
}
]
})

0 comments on commit f558b79

Please sign in to comment.