Repository: vuejs/eslint-plugin-vue
Pull request #405 (2018-02-23 15:06:31)

[Update] Make `vue/attributes-order` fixable
This PR makes `vue/attributes-order` fixable. #401
In case of `Attribute "A" should go before  "B"` error message, autofix will move A before B


Patch:
diff --git a/README.md b/README.md
index 9797e5f9..2467f256 100644
--- a/README.md
+++ b/README.md
@@ -91,7 +91,7 @@ If you want to disallow `eslint-disable` functionality, please disable [vue/comm
 
 ## :gear: Configs
 
-This plugin provides two predefined configs:
+This plugin provides four predefined configs:
 - `plugin:vue/base` - Settings and rules to enable correct ESLint parsing
 - `plugin:vue/essential` - Above, plus rules to prevent errors or unintended behavior
 - `plugin:vue/strongly-recommended` - Above, plus rules to considerably improve code readability and/or dev experience
@@ -209,7 +209,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
 |:---|:--------|:------------|
 | :wrench: | [vue/html-closing-bracket-newline](./docs/rules/html-closing-bracket-newline.md) | require or disallow a line break before tag's closing brackets |
 | :wrench: | [vue/html-closing-bracket-spacing](./docs/rules/html-closing-bracket-spacing.md) | require or disallow a space before tag's closing brackets |
-|  | [vue/prop-name-casing](./docs/rules/prop-name-casing.md) | enforce specific casing for the Prop name in Vue components |
+| :wrench: | [vue/prop-name-casing](./docs/rules/prop-name-casing.md) | enforce specific casing for the Prop name in Vue components |
 | :wrench: | [vue/script-indent](./docs/rules/script-indent.md) | enforce consistent indentation in `<script>` |
 
 <!--RULES_TABLE_END-->
diff --git a/docs/rules/attributes-order.md b/docs/rules/attributes-order.md
index 137fee21..0462bdf3 100644
--- a/docs/rules/attributes-order.md
+++ b/docs/rules/attributes-order.md
@@ -4,7 +4,7 @@
 
 ## :book: Rule Details
 
-This rule aims to enfore ordering of component attributes. The default order is specified in the [Vue styleguide](https://vuejs.org/v2/style-guide/#Element-attribute-order-recommended) and is:
+This rule aims to enforce ordering of component attributes. The default order is specified in the [Vue styleguide](https://vuejs.org/v2/style-guide/#Element-attribute-order-recommended) and is:
 - DEFINITION
 ex: 'is'
 - LIST_RENDERING
@@ -86,7 +86,7 @@ Specify custom order of attribute groups
 :+1: Examples of **correct** code with custom order`:
 
 ```html
-<!-- 'vue/attribute-order': [2, { order: ['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'BINDING', 'OTHER_ATTR', 'EVENTS', 'CONTENT', 'DEFINITION'] }] -->
+<!-- 'vue/attributes-order': [2, { order: ['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'BINDING', 'OTHER_ATTR', 'EVENTS', 'CONTENT', 'DEFINITION'] }] -->
 <div
   propOne="prop"
   propTwo="prop"
@@ -95,7 +95,7 @@ Specify custom order of attribute groups
 ```
 
 ```html
-<!-- 'vue/attribute-order': [2, { order: ['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'BINDING', 'DEFINITION', 'OTHER_ATTR', 'EVENTS', 'CONTENT'] }] -->
+<!-- 'vue/attributes-order': [2, { order: ['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'BINDING', 'DEFINITION', 'OTHER_ATTR', 'EVENTS', 'CONTENT'] }] -->
 <div
   ref="header"
   is="header"
@@ -107,10 +107,10 @@ Specify custom order of attribute groups
 :-1: Examples of **incorrect** code with custom order`:
 
 ```html
-<!-- 'vue/attribute-order': [2, { order: ['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'BINDING', 'DEFINITION', 'OTHER_ATTR', 'EVENTS', 'CONTENT'] }] -->
+<!-- 'vue/attributes-order': [2, { order: ['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'BINDING', 'DEFINITION', 'OTHER_ATTR', 'EVENTS', 'CONTENT'] }] -->
 <div
   ref="header"
   propOne="prop"
   is="header">
 </div>
-```
\ No newline at end of file
+```
diff --git a/docs/rules/prop-name-casing.md b/docs/rules/prop-name-casing.md
index 8c109687..a01b5c75 100644
--- a/docs/rules/prop-name-casing.md
+++ b/docs/rules/prop-name-casing.md
@@ -1,5 +1,7 @@
 # enforce specific casing for the Prop name in Vue components (vue/prop-name-casing)
 
+- :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
+
 This rule would enforce proper casing of props in vue components(camelCase).
 
 ## :book: Rule Details
diff --git a/docs/rules/valid-template-root.md b/docs/rules/valid-template-root.md
index e113d524..2f4b24ff 100644
--- a/docs/rules/valid-template-root.md
+++ b/docs/rules/valid-template-root.md
@@ -16,8 +16,6 @@ This rule reports the template root in the following cases:
 
 :-1: Examples of **incorrect** code for this rule:
 
-:-1: Examples of **incorrect** code for this rule:
-
 ```js
 template: ''
 ```
diff --git a/lib/rules/attribute-hyphenation.js b/lib/rules/attribute-hyphenation.js
index 7f11c3f8..8a394d42 100644
--- a/lib/rules/attribute-hyphenation.js
+++ b/lib/rules/attribute-hyphenation.js
@@ -16,7 +16,7 @@ module.exports = {
     docs: {
       description: 'enforce attribute naming style in template',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/attribute-hyphenation.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/attribute-hyphenation.md'
     },
     fixable: 'code',
     schema: [
diff --git a/lib/rules/attributes-order.js b/lib/rules/attributes-order.js
index e5cd19dd..0ae63b95 100644
--- a/lib/rules/attributes-order.js
+++ b/lib/rules/attributes-order.js
@@ -29,7 +29,7 @@ function getAttributeType (name, isDirective) {
       return 'DEFINITION'
     } else if (name === 'id') {
       return 'GLOBAL'
-    } else if (name === 'ref' || name === 'key' || name === 'slot') {
+    } else if (name === 'ref' || name === 'key' || name === 'slot' || name === 'slot-scope') {
       return 'UNIQUE'
     } else {
       return 'OTHER_ATTR'
@@ -59,6 +59,31 @@ function create (context) {
       message: `Attribute "${currentNode}" should go before "${prevNode}".`,
       data: {
         currentNode
+      },
+
+      fix (fixer) {
+        const attributes = node.parent.attributes
+        const shiftAttrs = attributes.slice(attributes.indexOf(previousNode), attributes.indexOf(node) + 1)
+
+        // If we can upgrade requirements to `eslint@>4.1.0`, this code can be replaced by:
+        // return shiftAttrs.map((attr, i) => {
+        //   const text = attr === previousNode ? sourceCode.getText(node) : sourceCode.getText(shiftAttrs[i - 1])
+        //   return fixer.replaceText(attr, text)
+        // })
+        const replaceDataList = shiftAttrs.map((attr, i) => {
+          const text = attr === previousNode ? sourceCode.getText(node) : sourceCode.getText(shiftAttrs[i - 1])
+          return {
+            range: attr.range,
+            text
+          }
+        })
+        const replaceRange = [previousNode.range[0], node.range[1]]
+        let text = sourceCode.text.slice(replaceRange[0], replaceRange[1])
+        replaceDataList.reverse().forEach((data) => {
+          const textRange = data.range.map(r => r - replaceRange[0])
+          text = text.slice(0, textRange[0]) + data.text + text.slice(textRange[1], text.length)
+        })
+        return fixer.replaceTextRange(replaceRange, text)
       }
     })
   }
@@ -85,7 +110,7 @@ module.exports = {
       description: 'enforce order of attributes',
       category: 'recommended'
     },
-    fixable: null,
+    fixable: 'code',
     schema: {
       type: 'array',
       properties: {
diff --git a/lib/rules/comment-directive.js b/lib/rules/comment-directive.js
index 108ba5c6..0ccf9ca8 100644
--- a/lib/rules/comment-directive.js
+++ b/lib/rules/comment-directive.js
@@ -109,7 +109,7 @@ module.exports = {
     docs: {
       description: 'support comment-directives in `<template>`',
       category: 'base',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/comment-directive.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/comment-directive.md'
     },
     schema: []
   },
diff --git a/lib/rules/html-closing-bracket-newline.js b/lib/rules/html-closing-bracket-newline.js
index 36bdaf65..9328baeb 100644
--- a/lib/rules/html-closing-bracket-newline.js
+++ b/lib/rules/html-closing-bracket-newline.js
@@ -32,7 +32,7 @@ module.exports = {
     docs: {
       description: "require or disallow a line break before tag's closing brackets",
       category: undefined,
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/html-closing-bracket-newline.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/html-closing-bracket-newline.md'
     },
     fixable: 'whitespace',
     schema: [{
diff --git a/lib/rules/html-closing-bracket-spacing.js b/lib/rules/html-closing-bracket-spacing.js
index fe1b1684..458f19dc 100644
--- a/lib/rules/html-closing-bracket-spacing.js
+++ b/lib/rules/html-closing-bracket-spacing.js
@@ -53,7 +53,7 @@ module.exports = {
     docs: {
       description: 'require or disallow a space before tag\'s closing brackets',
       category: undefined,
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/html-closing-bracket-spacing.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/html-closing-bracket-spacing.md'
     },
     schema: [{
       type: 'object',
diff --git a/lib/rules/html-end-tags.js b/lib/rules/html-end-tags.js
index a04d40d5..10ef24ce 100644
--- a/lib/rules/html-end-tags.js
+++ b/lib/rules/html-end-tags.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce end tag style',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/html-end-tags.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/html-end-tags.md'
     },
     fixable: 'code',
     schema: []
diff --git a/lib/rules/html-indent.js b/lib/rules/html-indent.js
index a73b088c..9455048b 100644
--- a/lib/rules/html-indent.js
+++ b/lib/rules/html-indent.js
@@ -29,7 +29,7 @@ module.exports = {
     docs: {
       description: 'enforce consistent indentation in `<template>`',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/html-indent.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/html-indent.md'
     },
     fixable: 'whitespace',
     schema: [
diff --git a/lib/rules/html-quotes.js b/lib/rules/html-quotes.js
index f62d2e34..cc062a8f 100644
--- a/lib/rules/html-quotes.js
+++ b/lib/rules/html-quotes.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce quotes style of HTML attributes',
       category: 'recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/html-quotes.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/html-quotes.md'
     },
     fixable: 'code',
     schema: [
diff --git a/lib/rules/html-self-closing.js b/lib/rules/html-self-closing.js
index 55d0aa26..e913cbfb 100644
--- a/lib/rules/html-self-closing.js
+++ b/lib/rules/html-self-closing.js
@@ -88,7 +88,7 @@ module.exports = {
     docs: {
       description: 'enforce self-closing style',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/html-self-closing.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/html-self-closing.md'
     },
     fixable: 'code',
     schema: {
diff --git a/lib/rules/jsx-uses-vars.js b/lib/rules/jsx-uses-vars.js
index dc8a4513..0472eaae 100644
--- a/lib/rules/jsx-uses-vars.js
+++ b/lib/rules/jsx-uses-vars.js
@@ -39,7 +39,7 @@ module.exports = {
     docs: {
       description: 'prevent variables used in JSX to be marked as unused', // eslint-disable-line consistent-docs-description
       category: 'base',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/jsx-uses-vars.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/jsx-uses-vars.md'
     },
     schema: []
   },
diff --git a/lib/rules/max-attributes-per-line.js b/lib/rules/max-attributes-per-line.js
index 54e9b187..e7d57ce2 100644
--- a/lib/rules/max-attributes-per-line.js
+++ b/lib/rules/max-attributes-per-line.js
@@ -14,7 +14,7 @@ module.exports = {
     docs: {
       description: 'enforce the maximum number of attributes per line',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/max-attributes-per-line.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/max-attributes-per-line.md'
     },
     fixable: 'whitespace', // or "code" or "whitespace"
     schema: [
diff --git a/lib/rules/mustache-interpolation-spacing.js b/lib/rules/mustache-interpolation-spacing.js
index 19e4f06f..62df0e41 100644
--- a/lib/rules/mustache-interpolation-spacing.js
+++ b/lib/rules/mustache-interpolation-spacing.js
@@ -19,7 +19,7 @@ module.exports = {
     docs: {
       description: 'enforce unified spacing in mustache interpolations',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/mustache-interpolation-spacing.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/mustache-interpolation-spacing.md'
     },
     fixable: 'whitespace',
     schema: [
diff --git a/lib/rules/name-property-casing.js b/lib/rules/name-property-casing.js
index cfe45f85..420a8606 100644
--- a/lib/rules/name-property-casing.js
+++ b/lib/rules/name-property-casing.js
@@ -17,7 +17,7 @@ module.exports = {
     docs: {
       description: 'enforce specific casing for the name property in Vue components',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/name-property-casing.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/name-property-casing.md'
     },
     fixable: 'code', // or "code" or "whitespace"
     schema: [
diff --git a/lib/rules/no-async-in-computed-properties.js b/lib/rules/no-async-in-computed-properties.js
index 5c1976dc..a42d7e92 100644
--- a/lib/rules/no-async-in-computed-properties.js
+++ b/lib/rules/no-async-in-computed-properties.js
@@ -64,7 +64,7 @@ module.exports = {
     docs: {
       description: 'disallow asynchronous actions in computed properties',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-async-in-computed-properties.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-async-in-computed-properties.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/no-confusing-v-for-v-if.js b/lib/rules/no-confusing-v-for-v-if.js
index c7a41275..7a676d70 100644
--- a/lib/rules/no-confusing-v-for-v-if.js
+++ b/lib/rules/no-confusing-v-for-v-if.js
@@ -39,7 +39,7 @@ module.exports = {
     docs: {
       description: 'disallow confusing `v-for` and `v-if` on the same element',
       category: 'recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-confusing-v-for-v-if.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-confusing-v-for-v-if.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/no-dupe-keys.js b/lib/rules/no-dupe-keys.js
index 5f513feb..0905845a 100644
--- a/lib/rules/no-dupe-keys.js
+++ b/lib/rules/no-dupe-keys.js
@@ -17,7 +17,7 @@ module.exports = {
     docs: {
       description: 'disallow duplication of field names',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-dupe-keys.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-dupe-keys.md'
     },
     fixable: null, // or "code" or "whitespace"
     schema: [
diff --git a/lib/rules/no-duplicate-attributes.js b/lib/rules/no-duplicate-attributes.js
index 6b1a09db..03bf8a28 100644
--- a/lib/rules/no-duplicate-attributes.js
+++ b/lib/rules/no-duplicate-attributes.js
@@ -39,7 +39,7 @@ module.exports = {
     docs: {
       description: 'disallow duplication of attributes',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-duplicate-attributes.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-duplicate-attributes.md'
     },
     fixable: null,
 
diff --git a/lib/rules/no-multi-spaces.js b/lib/rules/no-multi-spaces.js
index 9721b368..a5436aed 100644
--- a/lib/rules/no-multi-spaces.js
+++ b/lib/rules/no-multi-spaces.js
@@ -13,7 +13,7 @@ module.exports = {
     docs: {
       description: 'disallow multiple spaces',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-multi-spaces.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-multi-spaces.md'
     },
     fixable: 'whitespace', // or "code" or "whitespace"
     schema: []
diff --git a/lib/rules/no-parsing-error.js b/lib/rules/no-parsing-error.js
index b4d091fa..e01032fd 100644
--- a/lib/rules/no-parsing-error.js
+++ b/lib/rules/no-parsing-error.js
@@ -58,7 +58,7 @@ module.exports = {
     docs: {
       description: 'disallow parsing errors in `<template>`',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-parsing-error.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-parsing-error.md'
     },
     fixable: null,
     schema: [
diff --git a/lib/rules/no-reserved-keys.js b/lib/rules/no-reserved-keys.js
index e69027b1..c64c3c20 100644
--- a/lib/rules/no-reserved-keys.js
+++ b/lib/rules/no-reserved-keys.js
@@ -18,7 +18,7 @@ module.exports = {
     docs: {
       description: 'disallow overwriting reserved keys',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-reserved-keys.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-reserved-keys.md'
     },
     fixable: null,
     schema: [
diff --git a/lib/rules/no-shared-component-data.js b/lib/rules/no-shared-component-data.js
index 66ddb0b5..8bcbd9ce 100644
--- a/lib/rules/no-shared-component-data.js
+++ b/lib/rules/no-shared-component-data.js
@@ -40,7 +40,7 @@ module.exports = {
     docs: {
       description: "enforce component's data property to be a function",
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-shared-component-data.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-shared-component-data.md'
     },
     fixable: 'code',
     schema: []
diff --git a/lib/rules/no-side-effects-in-computed-properties.js b/lib/rules/no-side-effects-in-computed-properties.js
index 8aa32741..7376ab93 100644
--- a/lib/rules/no-side-effects-in-computed-properties.js
+++ b/lib/rules/no-side-effects-in-computed-properties.js
@@ -15,7 +15,7 @@ module.exports = {
     docs: {
       description: 'disallow side effects in computed properties',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-side-effects-in-computed-properties.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-side-effects-in-computed-properties.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/no-template-key.js b/lib/rules/no-template-key.js
index 56d6ca22..7e16b5e6 100644
--- a/lib/rules/no-template-key.js
+++ b/lib/rules/no-template-key.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'disallow `key` attribute on `<template>`',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-template-key.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-template-key.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/no-textarea-mustache.js b/lib/rules/no-textarea-mustache.js
index 21725d42..31437462 100644
--- a/lib/rules/no-textarea-mustache.js
+++ b/lib/rules/no-textarea-mustache.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'disallow mustaches in `<textarea>`',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-textarea-mustache.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-textarea-mustache.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/no-unused-vars.js b/lib/rules/no-unused-vars.js
index 63b6f033..81ea583b 100644
--- a/lib/rules/no-unused-vars.js
+++ b/lib/rules/no-unused-vars.js
@@ -15,7 +15,7 @@ module.exports = {
     docs: {
       description: 'disallow unused variable definitions of v-for directives or scope attributes',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/no-unused-vars.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/no-unused-vars.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/order-in-components.js b/lib/rules/order-in-components.js
index 0dcdbeba..fe6125c3 100644
--- a/lib/rules/order-in-components.js
+++ b/lib/rules/order-in-components.js
@@ -135,7 +135,7 @@ module.exports = {
     docs: {
       description: 'enforce order of properties in components',
       category: 'recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/order-in-components.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/order-in-components.md'
     },
     fixable: 'code', // null or "code" or "whitespace"
     schema: [
diff --git a/lib/rules/prop-name-casing.js b/lib/rules/prop-name-casing.js
index f744aee5..04c2a16e 100644
--- a/lib/rules/prop-name-casing.js
+++ b/lib/rules/prop-name-casing.js
@@ -8,6 +8,20 @@ const utils = require('../utils')
 const casing = require('../utils/casing')
 const allowedCaseOptions = ['camelCase', 'snake_case']
 
+function canFixPropertyName (node, originalName) {
+  // Can not fix of computed property names & shorthand
+  if (node.computed || node.shorthand) {
+    return false
+  }
+  const key = node.key
+  // Can not fix of unknown types
+  if (key.type !== 'Literal' && key.type !== 'Identifier') {
+    return false
+  }
+  // Can fix of ASCII printable characters
+  return originalName.match(/[ -~]+/)
+}
+
 // ------------------------------------------------------------------------------
 // Rule Definition
 // ------------------------------------------------------------------------------
@@ -46,7 +60,12 @@ function create (context) {
           data: {
             name: propName,
             caseType: caseType
-          }
+          },
+          fix: canFixPropertyName(item, propName) ? fixer => {
+            return item.key.type === 'Literal'
+              ? fixer.replaceText(item.key, item.key.raw.replace(item.key.value, convertedName))
+              : fixer.replaceText(item.key, convertedName)
+          } : undefined
         })
       }
     }
@@ -63,7 +82,7 @@ module.exports = {
       description: 'enforce specific casing for the Prop name in Vue components',
       category: undefined // 'strongly-recommended'
     },
-    fixable: null, // or "code" or "whitespace"
+    fixable: 'code',  // null or "code" or "whitespace"
     schema: [
       {
         enum: allowedCaseOptions
diff --git a/lib/rules/require-component-is.js b/lib/rules/require-component-is.js
index 42c8693c..d102bec6 100644
--- a/lib/rules/require-component-is.js
+++ b/lib/rules/require-component-is.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'require `v-bind:is` of `<component>` elements',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/require-component-is.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/require-component-is.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/require-default-prop.js b/lib/rules/require-default-prop.js
index 2f293674..4569e72f 100644
--- a/lib/rules/require-default-prop.js
+++ b/lib/rules/require-default-prop.js
@@ -15,7 +15,7 @@ module.exports = {
     docs: {
       description: 'require default value for props',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/require-default-prop.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/require-default-prop.md'
     },
     fixable: null, // or "code" or "whitespace"
     schema: []
diff --git a/lib/rules/require-prop-types.js b/lib/rules/require-prop-types.js
index caad7ee7..2850245c 100644
--- a/lib/rules/require-prop-types.js
+++ b/lib/rules/require-prop-types.js
@@ -15,7 +15,7 @@ module.exports = {
     docs: {
       description: 'require type definitions in props',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/require-prop-types.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/require-prop-types.md'
     },
     fixable: null, // or "code" or "whitespace"
     schema: [
diff --git a/lib/rules/require-render-return.js b/lib/rules/require-render-return.js
index 1943e4cc..0ddf8565 100644
--- a/lib/rules/require-render-return.js
+++ b/lib/rules/require-render-return.js
@@ -15,7 +15,7 @@ module.exports = {
     docs: {
       description: 'enforce render function to always return value',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/require-render-return.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/require-render-return.md'
     },
     fixable: null, // or "code" or "whitespace"
     schema: []
diff --git a/lib/rules/require-v-for-key.js b/lib/rules/require-v-for-key.js
index 67d3f3d4..8f73a12c 100644
--- a/lib/rules/require-v-for-key.js
+++ b/lib/rules/require-v-for-key.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'require `v-bind:key` with `v-for` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/require-v-for-key.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/require-v-for-key.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/require-valid-default-prop.js b/lib/rules/require-valid-default-prop.js
index d2ca4859..74a3b637 100644
--- a/lib/rules/require-valid-default-prop.js
+++ b/lib/rules/require-valid-default-prop.js
@@ -24,7 +24,7 @@ module.exports = {
     docs: {
       description: 'enforce props default values to be valid',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/require-valid-default-prop.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/require-valid-default-prop.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/return-in-computed-property.js b/lib/rules/return-in-computed-property.js
index 233f157f..9913e711 100644
--- a/lib/rules/return-in-computed-property.js
+++ b/lib/rules/return-in-computed-property.js
@@ -15,7 +15,7 @@ module.exports = {
     docs: {
       description: 'enforce that a return statement is present in computed property',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/return-in-computed-property.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/return-in-computed-property.md'
     },
     fixable: null, // or "code" or "whitespace"
     schema: [
diff --git a/lib/rules/script-indent.js b/lib/rules/script-indent.js
index 0adf3cf3..35bf130e 100644
--- a/lib/rules/script-indent.js
+++ b/lib/rules/script-indent.js
@@ -19,7 +19,7 @@ module.exports = {
     docs: {
       description: 'enforce consistent indentation in `<script>`',
       category: undefined,
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/script-indent.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/script-indent.md'
     },
     fixable: 'whitespace',
     schema: [
diff --git a/lib/rules/this-in-template.js b/lib/rules/this-in-template.js
index 3891b94b..0fefc5f1 100644
--- a/lib/rules/this-in-template.js
+++ b/lib/rules/this-in-template.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce usage of `this` in template',
       category: 'recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/this-in-template.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/this-in-template.md'
     },
     fixable: null,
     schema: [
diff --git a/lib/rules/v-bind-style.js b/lib/rules/v-bind-style.js
index 2bc003f7..d6d0dc35 100644
--- a/lib/rules/v-bind-style.js
+++ b/lib/rules/v-bind-style.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce `v-bind` directive style',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/v-bind-style.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/v-bind-style.md'
     },
     fixable: 'code',
     schema: [
diff --git a/lib/rules/v-on-style.js b/lib/rules/v-on-style.js
index 2b3ccce8..838de429 100644
--- a/lib/rules/v-on-style.js
+++ b/lib/rules/v-on-style.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce `v-on` directive style',
       category: 'strongly-recommended',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/v-on-style.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/v-on-style.md'
     },
     fixable: 'code',
     schema: [
diff --git a/lib/rules/valid-template-root.js b/lib/rules/valid-template-root.js
index f62b7e71..58dd6900 100644
--- a/lib/rules/valid-template-root.js
+++ b/lib/rules/valid-template-root.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid template root',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-template-root.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-template-root.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-bind.js b/lib/rules/valid-v-bind.js
index 7f1ad619..2fe8f192 100644
--- a/lib/rules/valid-v-bind.js
+++ b/lib/rules/valid-v-bind.js
@@ -26,7 +26,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-bind` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-bind.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-bind.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-cloak.js b/lib/rules/valid-v-cloak.js
index 808873f3..1c7f8365 100644
--- a/lib/rules/valid-v-cloak.js
+++ b/lib/rules/valid-v-cloak.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-cloak` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-cloak.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-cloak.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-else-if.js b/lib/rules/valid-v-else-if.js
index a3ddc4fd..883f14d5 100644
--- a/lib/rules/valid-v-else-if.js
+++ b/lib/rules/valid-v-else-if.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-else-if` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-else-if.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-else-if.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-else.js b/lib/rules/valid-v-else.js
index 2611a229..40fc1cae 100644
--- a/lib/rules/valid-v-else.js
+++ b/lib/rules/valid-v-else.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-else` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-else.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-else.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-for.js b/lib/rules/valid-v-for.js
index 4c57a25f..1b11273e 100644
--- a/lib/rules/valid-v-for.js
+++ b/lib/rules/valid-v-for.js
@@ -106,7 +106,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-for` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-for.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-for.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-html.js b/lib/rules/valid-v-html.js
index b4f66038..80a5fd3b 100644
--- a/lib/rules/valid-v-html.js
+++ b/lib/rules/valid-v-html.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-html` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-html.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-html.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-if.js b/lib/rules/valid-v-if.js
index 43e2e8bb..66f8700d 100644
--- a/lib/rules/valid-v-if.js
+++ b/lib/rules/valid-v-if.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-if` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-if.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-if.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-model.js b/lib/rules/valid-v-model.js
index 94eef2fa..b909a576 100644
--- a/lib/rules/valid-v-model.js
+++ b/lib/rules/valid-v-model.js
@@ -82,7 +82,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-model` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-model.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-model.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-on.js b/lib/rules/valid-v-on.js
index 7ab1d07d..9b00e04d 100644
--- a/lib/rules/valid-v-on.js
+++ b/lib/rules/valid-v-on.js
@@ -115,7 +115,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-on` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-on.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-on.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-once.js b/lib/rules/valid-v-once.js
index bd652bca..95659280 100644
--- a/lib/rules/valid-v-once.js
+++ b/lib/rules/valid-v-once.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-once` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-once.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-once.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-pre.js b/lib/rules/valid-v-pre.js
index ce87288f..4c2af978 100644
--- a/lib/rules/valid-v-pre.js
+++ b/lib/rules/valid-v-pre.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-pre` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-pre.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-pre.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-show.js b/lib/rules/valid-v-show.js
index eb6c49a4..330d3e31 100644
--- a/lib/rules/valid-v-show.js
+++ b/lib/rules/valid-v-show.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-show` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-show.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-show.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/valid-v-text.js b/lib/rules/valid-v-text.js
index e9a3460f..45db03a5 100644
--- a/lib/rules/valid-v-text.js
+++ b/lib/rules/valid-v-text.js
@@ -20,7 +20,7 @@ module.exports = {
     docs: {
       description: 'enforce valid `v-text` directives',
       category: 'essential',
-      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.3.0/docs/rules/valid-v-text.md'
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.4.0/docs/rules/valid-v-text.md'
     },
     fixable: null,
     schema: []
diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js
index dfc89d57..f93379da 100644
--- a/lib/utils/indent-common.js
+++ b/lib/utils/indent-common.js
@@ -1024,6 +1024,9 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
     ExportAllDeclaration (node) {
       const tokens = tokenStore.getTokens(node)
       const firstToken = tokens.shift()
+      if (isSemicolon(last(tokens))) {
+        tokens.pop()
+      }
       setOffset(tokens, 1, firstToken)
     },
 
@@ -1445,25 +1448,20 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
 
     // Process semicolons.
     ':statement' (node) {
-      const info = offsets.get(tokenStore.getFirstToken(node))
+      const firstToken = tokenStore.getFirstToken(node)
       const lastToken = tokenStore.getLastToken(node)
-      if (info == null) {
-        return
-      }
-      if (isSemicolon(lastToken)) {
-        offsets.set(lastToken, info)
+      if (isSemicolon(lastToken) && firstToken !== lastToken) {
+        setOffset(lastToken, 0, firstToken)
       }
 
       // Set to the semicolon of the previous token for semicolon-free style.
       // E.g.,
       //   foo
       //   ;[1,2,3].forEach(f)
-      const prevToken = tokenStore.getTokenBefore(node)
-      if (isSemicolon(prevToken)) {
-        const prevPrevToken = tokenStore.getTokenBefore(prevToken)
-        if (prevPrevToken == null || prevToken.loc.end.line !== prevPrevToken.loc.start.line) {
-          offsets.set(prevToken, info)
-        }
+      const info = offsets.get(firstToken)
+      const prevToken = tokenStore.getTokenBefore(firstToken)
+      if (info != null && isSemicolon(prevToken) && prevToken.loc.end.line === firstToken.loc.start.line) {
+        offsets.set(prevToken, info)
       }
     },
 
diff --git a/package.json b/package.json
index 3c187a53..68567918 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-plugin-vue",
-  "version": "4.3.0",
+  "version": "4.4.0",
   "description": "Official ESLint plugin for Vue.js",
   "main": "lib/index.js",
   "scripts": {
@@ -48,7 +48,7 @@
   },
   "devDependencies": {
     "@types/node": "^4.2.16",
-    "babel-eslint": "^8.1.2",
+    "babel-eslint": "^8.2.2",
     "chai": "^4.1.0",
     "eslint": "^4.14.0",
     "eslint-plugin-eslint-plugin": "^0.8.0",


Test patch:
diff --git a/tests/fixtures/script-indent/export-named-declaration-04.vue b/tests/fixtures/script-indent/export-named-declaration-04.vue
index 410623c4..5cd53b33 100644
--- a/tests/fixtures/script-indent/export-named-declaration-04.vue
+++ b/tests/fixtures/script-indent/export-named-declaration-04.vue
@@ -2,7 +2,7 @@
 <script>
 export
   const a = 0
-;
+  ;
 export
   const
     b
diff --git a/tests/fixtures/script-indent/issue407.vue b/tests/fixtures/script-indent/issue407.vue
new file mode 100644
index 00000000..40ecda9d
--- /dev/null
+++ b/tests/fixtures/script-indent/issue407.vue
@@ -0,0 +1,12 @@
+<!--{"options":[4,{"baseIndent":1,"switchCase":2}]}-->
+<script>
+    function test() {
+        const variable = 0;
+
+        if (variable === 0) {
+            console.info('wrong indentation reported');
+        }
+    }
+
+    test();
+</script>
diff --git a/tests/lib/rules/attributes-order.js b/tests/lib/rules/attributes-order.js
index 39c20716..9366ac13 100644
--- a/tests/lib/rules/attributes-order.js
+++ b/tests/lib/rules/attributes-order.js
@@ -208,6 +208,40 @@ tester.run('attributes-order', rule, {
             'EVENTS',
             'CONTENT']
         }]
+    },
+    {
+      filename: 'test.vue',
+      code:
+        `<template>
+          <div
+            v-if="!visible"
+            v-for="item in items"
+            v-once
+            is="header"
+            v-on:click="functionCall"
+            ref="header"
+            :prop="headerData"
+            v-text="textContent"
+            id="uniqueID"
+            myProp="prop"
+            >
+          </div>
+        </template>`,
+      options: [
+        { order:
+          [
+            'CONDITIONALS',
+            'LIST_RENDERING',
+            'RENDER_MODIFIERS',
+            'DEFINITION',
+            'EVENTS',
+            'UNIQUE',
+            'BINDING',
+            'CONTENT',
+            'GLOBAL',
+            'OTHER_ATTR'
+          ]
+        }]
     }
   ],
 
@@ -215,6 +249,7 @@ tester.run('attributes-order', rule, {
     {
       filename: 'test.vue',
       code: '<template><div v-cloak is="header"></div></template>',
+      output: '<template><div is="header" v-cloak></div></template>',
       errors: [{
         message: 'Attribute "is" should go before "v-cloak".',
         type: 'VIdentifier'
@@ -223,6 +258,7 @@ tester.run('attributes-order', rule, {
     {
       filename: 'test.vue',
       code: '<template><div id="uniqueID" v-cloak></div></template>',
+      output: '<template><div v-cloak id="uniqueID"></div></template>',
       errors: [{
         message: 'Attribute "v-cloak" should go before "id".',
         type: 'VDirectiveKey'
@@ -239,6 +275,15 @@ tester.run('attributes-order', rule, {
             :bindingProp="foo">
           </div>
         </template>`,
+      output:
+        `<template>
+          <div
+            v-model="toggle"
+            model="baz"
+            :bindingProp="foo"
+            propOne="bar">
+          </div>
+        </template>`,
       errors: [{
         message: 'Attribute "v-model" should go before "model".',
         type: 'VDirectiveKey'
@@ -260,6 +305,16 @@ tester.run('attributes-order', rule, {
             propOne="bar">
           </div>
         </template>`,
+      output:
+        `<template>
+          <div
+            :bindingProp="foo"
+            model="baz"
+            v-model="toggle"
+            v-on="functionCall"
+            propOne="bar">
+          </div>
+        </template>`,
       errors: [{
         message: 'Attribute "v-model" should go before "v-on".',
         type: 'VDirectiveKey'
@@ -272,6 +327,7 @@ tester.run('attributes-order', rule, {
     {
       filename: 'test.vue',
       code: '<template><div data-id="foo" aria-test="bar" is="custom" myProp="prop"></div></template>',
+      output: '<template><div data-id="foo" is="custom" aria-test="bar" myProp="prop"></div></template>',
       errors: [{
         message: 'Attribute "is" should go before "aria-test".',
         type: 'VIdentifier'
@@ -293,10 +349,167 @@ tester.run('attributes-order', rule, {
             'EVENTS',
             'CONTENT']
         }],
+      output: '<template><div ref="header" is="header" propone="prop" ></div></template>',
       errors: [{
         message: 'Attribute "is" should go before "propone".',
         type: 'VIdentifier'
       }]
+    },
+    {
+      filename: 'test.vue',
+      code:
+        `<template>
+          <div v-cloak
+            is="header">
+          </div>
+        </template>`,
+      output:
+        `<template>
+          <div is="header"
+            v-cloak>
+          </div>
+        </template>`,
+      errors: [{
+        message: 'Attribute "is" should go before "v-cloak".',
+        type: 'VIdentifier'
+      }]
+    },
+    {
+      filename: 'test.vue',
+      code:
+        `<template>
+          <div
+            v-if="!visible"
+            v-for="item in items"
+            v-once
+            is="header"
+            v-on:click="functionCall"
+            ref="header"
+            :prop="headerData"
+            v-text="textContent"
+            id="uniqueID"
+            myProp="prop"
+            >
+          </div>
+        </template>`,
+      output:
+        `<template>
+          <div
+            v-for="item in items"
+            v-if="!visible"
+            is="header"
+            v-once
+            ref="header"
+            v-on:click="functionCall"
+            :prop="headerData"
+            id="uniqueID"
+            v-text="textContent"
+            myProp="prop"
+            >
+          </div>
+        </template>`,
+      errors: [
+        {
+          message: 'Attribute "v-for" should go before "v-if".',
+          type: 'VDirectiveKey'
+        },
+        {
+          message: 'Attribute "is" should go before "v-once".',
+          type: 'VIdentifier'
+        },
+        {
+          message: 'Attribute "ref" should go before "v-on:click".',
+          type: 'VIdentifier'
+        },
+        {
+          message: 'Attribute ":prop" should go before "v-on:click".',
+          type: 'VDirectiveKey'
+        },
+        {
+          message: 'Attribute "id" should go before "v-text".',
+          type: 'VIdentifier'
+        },
+        {
+          message: 'Attribute "myProp" should go before "v-text".',
+          type: 'VIdentifier'
+        }
+      ]
+    },
+    {
+      filename: 'test.vue',
+      code:
+        `<template>
+          <div
+            v-if="!visible"
+            v-for="item in items"
+            v-once
+            is="header"
+            v-on:click="functionCall"
+            ref="header"
+            :prop="headerData"
+            v-text="textContent"
+            id="uniqueID"
+            myProp="prop"
+            >
+          </div>
+        </template>`,
+      options: [
+        { order:
+          [
+            'EVENTS',
+            'BINDING',
+            'UNIQUE',
+            'DEFINITION',
+            'CONDITIONALS',
+            'LIST_RENDERING',
+            'RENDER_MODIFIERS',
+            'GLOBAL',
+            'OTHER_ATTR',
+            'CONTENT'
+          ]
+        }],
+      output:
+        `<template>
+          <div
+            v-if="!visible"
+            v-for="item in items"
+            is="header"
+            v-once
+            v-on:click="functionCall"
+            ref="header"
+            :prop="headerData"
+            id="uniqueID"
+            v-text="textContent"
+            myProp="prop"
+            >
+          </div>
+        </template>`,
+      errors: [
+        {
+          message: 'Attribute "is" should go before "v-once".',
+          nodeType: 'VIdentifier'
+        },
+        {
+          message: 'Attribute "v-on:click" should go before "v-once".',
+          nodeType: 'VDirectiveKey'
+        },
+        {
+          message: 'Attribute "ref" should go before "v-once".',
+          nodeType: 'VIdentifier'
+        },
+        {
+          message: 'Attribute ":prop" should go before "v-once".',
+          nodeType: 'VDirectiveKey'
+        },
+        {
+          message: 'Attribute "id" should go before "v-text".',
+          nodeType: 'VIdentifier'
+        },
+        {
+          message: 'Attribute "myProp" should go before "v-text".',
+          nodeType: 'VIdentifier'
+        }
+      ]
     }
   ]
 })
diff --git a/tests/lib/rules/prop-name-casing.js b/tests/lib/rules/prop-name-casing.js
index 3df60c8b..0c706635 100644
--- a/tests/lib/rules/prop-name-casing.js
+++ b/tests/lib/rules/prop-name-casing.js
@@ -121,6 +121,13 @@ ruleTester.run('prop-name-casing', rule, {
           }
         }
       `,
+      output: `
+        export default {
+          props: {
+            greetingText: String
+          }
+        }
+      `,
       parserOptions,
       errors: [{
         message: 'Prop "greeting_text" is not in camelCase.',
@@ -138,6 +145,13 @@ ruleTester.run('prop-name-casing', rule, {
         }
       `,
       options: ['camelCase'],
+      output: `
+        export default {
+          props: {
+            greetingText: String
+          }
+        }
+      `,
       parserOptions,
       errors: [{
         message: 'Prop "greeting_text" is not in camelCase.',
@@ -155,6 +169,13 @@ ruleTester.run('prop-name-casing', rule, {
         }
       `,
       options: ['snake_case'],
+      output: `
+        export default {
+          props: {
+            greeting_text: String
+          }
+        }
+      `,
       parserOptions,
       errors: [{
         message: 'Prop "greetingText" is not in snake_case.',
@@ -172,6 +193,13 @@ ruleTester.run('prop-name-casing', rule, {
         }
       `,
       options: ['camelCase'],
+      output: `
+        export default {
+          props: {
+            'greetingText': String
+          }
+        }
+      `,
       parserOptions,
       errors: [{
         message: 'Prop "greeting-text" is not in camelCase.',
@@ -189,12 +217,156 @@ ruleTester.run('prop-name-casing', rule, {
         }
       `,
       options: ['snake_case'],
+      output: `
+        export default {
+          props: {
+            'greeting_text': String
+          }
+        }
+      `,
       parserOptions,
       errors: [{
         message: 'Prop "greeting-text" is not in snake_case.',
         type: 'Property',
         line: 4
       }]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+        export default {
+          props: {
+            'greeting_text': String
+          }
+        }
+      `,
+      output: `
+        export default {
+          props: {
+            'greetingText': String
+          }
+        }
+      `,
+      parserOptions,
+      errors: [{
+        message: 'Prop "greeting_text" is not in camelCase.',
+        type: 'Property',
+        line: 4
+      }]
+    },
+    {
+      // computed property name
+      filename: 'test.vue',
+      code: `
+        export default {
+          props: {
+            ['greeting-text']: String
+          }
+        }
+      `,
+      output: null,
+      parserOptions,
+      errors: [{
+        message: 'Prop "greeting-text" is not in camelCase.',
+        type: 'Property',
+        line: 4
+      }]
+    },
+    {
+      // shorthand
+      filename: 'test.vue',
+      code: `
+        export default {
+          props: {
+            greeting_text
+          }
+        }
+      `,
+      output: null,
+      parserOptions,
+      errors: [{
+        message: 'Prop "greeting_text" is not in camelCase.',
+        type: 'Property',
+        line: 4
+      }]
+    },
+    {
+      // valiable computed property name
+      filename: 'test.vue',
+      code: `
+        export default {
+          props: {
+            [greeting_text]: String
+          }
+        }
+      `,
+      output: null,
+      parserOptions,
+      errors: [{
+        // bug ?
+        message: 'Prop "greeting_text" is not in camelCase.',
+        type: 'Property',
+        line: 4
+      }]
+    },
+    {
+      // emoji
+      filename: 'test.vue',
+      code: `
+        export default {
+          props: {
+            '\u{1F37B}': String
+          }
+        }
+      `,
+      output: null,
+      parserOptions,
+      errors: [{
+        message: 'Prop "\u{1F37B}" is not in camelCase.',
+        type: 'Property',
+        line: 4
+      }]
+    },
+    {
+      // Japanese characters
+      filename: 'test.vue',
+      code: `
+        export default {
+          props: {
+            '漢字': String
+          }
+        }
+      `,
+      output: null,
+      parserOptions,
+      errors: [{
+        message: 'Prop "漢字" is not in camelCase.',
+        type: 'Property',
+        line: 4
+      }]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+        export default {
+          props: {
+            'abc-123-def': String
+          }
+        }
+      `,
+      output: `
+        export default {
+          props: {
+            'abc123Def': String
+          }
+        }
+      `,
+      parserOptions,
+      errors: [{
+        message: 'Prop "abc-123-def" is not in camelCase.',
+        type: 'Property',
+        line: 4
+      }]
     }
   ]
 })