Repository: vuejs/eslint-plugin-vue
Pull request #809 (2019-02-08 03:23:13)

Fix spelling mistake
Change v-if-else into v-else-if


Patch:
diff --git a/README.md b/README.md
index 3552e99c..f5932178 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
 
 ## :book: Documentation
 
-See https://eslint.vuejs.org
+See [the official website](https://eslint.vuejs.org).
 
 ## :anchor: Versioning Policy
 
@@ -17,37 +17,37 @@ This plugin is following [Semantic Versioning](https://semver.org/) and [ESLint'
 
 ## :newspaper: Changelog
 
-We're using [GitHub Releases](https://github.com/vuejs/eslint-plugin-vue/releases).
+This project uses [GitHub Releases](https://github.com/vuejs/eslint-plugin-vue/releases).
 
-## :beers: Contribution guide
+## :beers: Contribution Guide
 
-Contributing is welcome!
+Contribution is welcome!
 
-See https://eslint.vuejs.org/developer-guide/
+See [The ESLint Vue Plugin Developer Guide](https://eslint.vuejs.org/developer-guide/).
 
-### Working with rules
+### Working with Rules
 
-Before you start writing new rule, please read the [official ESLint guide](https://eslint.org/docs/developer-guide/working-with-rules).
+Before you start writing a new rule, please read [the official ESLint guide](https://eslint.org/docs/developer-guide/working-with-rules).
 
-Next in order to get an idea how does the AST of the code that you want to check looks like, you can use one of the following applications:
-- [astexplorer.net](https://astexplorer.net/) - best tool to inspect ASTs, but it doesn't support Vue templates yet
-- [ast.js.org](https://ast.js.org/) - not fully featured, but supports Vue templates syntax
+Next, in order to get an idea how does the AST of the code that you want to check looks like, use one of the following applications:
+- [astexplorer.net](https://astexplorer.net/) - the best tool to inspect ASTs, but it doesn't support Vue template yet
+- [ast.js.org](https://ast.js.org/) - not fully featured, but supports Vue template syntax
 
-Since single file components in Vue are not plain JavaScript, we can't use the default parser, and we had to introduce additional one: `vue-eslint-parser`, that generates enhanced AST with nodes that represent specific parts of the template syntax, as well as what's inside the `<script>` tag.
+Since single file components in Vue are not plain JavaScript, the default parser couldn't be used, so a new one was introduced. `vue-eslint-parser` generates enhanced AST with nodes that represent specific parts of the template syntax, as well as what's inside the `<script>` tag.
 
 To know more about certain nodes in produced ASTs, go here:
 - [ESTree docs](https://github.com/estree/estree)
 - [vue-eslint-parser AST docs](https://github.com/mysticatea/vue-eslint-parser/blob/master/docs/ast.md)
 
-The `vue-eslint-parser` provides few useful parser services, to help traverse the produced AST and access tokens of the template:
+The `vue-eslint-parser` provides a few useful parser services that help traverse the produced AST and access tokens of the template:
 - `context.parserServices.defineTemplateBodyVisitor(visitor, scriptVisitor)`
 - `context.parserServices.getTemplateBodyTokenStore()`
 
-Check out an [example rule](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/mustache-interpolation-spacing.js) to get a better understanding of how these work.
+Check out [an example rule](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/mustache-interpolation-spacing.js) to get a better understanding of how these work.
 
-Please be aware that regarding what kind of code examples you'll write in tests, you'll have to accordingly setup the parser in `RuleTester` (you can do it on per test case basis though). [See an example here](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/attribute-hyphenation.js#L19)
+Please be aware that regarding what kind of code examples you'll write in tests, you'll have to accordingly set up the parser in `RuleTester` (you can do it on a per test case basis). See an example [here](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/attribute-hyphenation.js#L19).
 
-If you'll stuck, remember there are plenty of rules you can learn from already, and if you can't find the right solution - don't hesitate to reach out in issues. We're happy to help!
+If you'll stuck, remember there are plenty of rules you can learn from already. If you can't find the right solution, don't hesitate to reach out in [issues](https://github.com/vuejs/eslint-plugin-vue/issues) – we're happy to help!
 
 ## :lock: License
 
diff --git a/docs/rules/valid-v-else.md b/docs/rules/valid-v-else.md
index c632ca1e..3dcd4bb1 100644
--- a/docs/rules/valid-v-else.md
+++ b/docs/rules/valid-v-else.md
@@ -18,8 +18,8 @@ This rule reports `v-else` directives in the following cases:
 - The directive has that argument. E.g. `<div v-if="foo"></div><div v-else:aaa></div>`
 - The directive has that modifier. E.g. `<div v-if="foo"></div><div v-else.bbb></div>`
 - The directive has that attribute value. E.g. `<div v-if="foo"></div><div v-else="bar"></div>`
-- The directive is on the elements that the previous element don't have `v-if`/`v-if-else` directives. E.g. `<div v-else></div>`
-- The directive is on the elements which have `v-if`/`v-if-else` directives. E.g. `<div v-if="foo" v-else></div>`
+- The directive is on the elements that the previous element don't have `v-if`/`v-else-if` directives. E.g. `<div v-else></div>`
+- The directive is on the elements which have `v-if`/`v-else-if` directives. E.g. `<div v-if="foo" v-else></div>`
 
 <eslint-code-block :rules="{'vue/valid-v-else': ['error']}">
 
diff --git a/lib/utils/index.js b/lib/utils/index.js
index e2af0257..4c90e310 100644
--- a/lib/utils/index.js
+++ b/lib/utils/index.js
@@ -265,10 +265,11 @@ module.exports = {
 
     return componentsNode.value.properties
       .filter(p => p.type === 'Property')
-      .map(node => ({
-        node,
-        name: this.getStaticPropertyName(node.key)
-      }))
+      .map(node => {
+        const name = this.getStaticPropertyName(node)
+        return name ? { node, name } : null
+      })
+      .filter(comp => comp != null)
   },
 
   /**


Test patch:
diff --git a/tests/lib/rules/no-unused-components.js b/tests/lib/rules/no-unused-components.js
index b8dfcaaf..a0362597 100644
--- a/tests/lib/rules/no-unused-components.js
+++ b/tests/lib/rules/no-unused-components.js
@@ -427,6 +427,50 @@ tester.run('no-unused-components', rule, {
       <template>
         <component :is></component>
       </template>`
+    },
+
+    // computed properties
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div />
+      </template>
+      <script>
+        export default {
+          components: {
+            [foo.bar]: baz
+          }
+        }
+      </script>`
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div />
+      </template>
+      <script>
+        export default {
+          components: {
+            [foo]: Bar
+          }
+        }
+      </script>`
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <foo />
+      </template>
+      <script>
+        export default {
+          components: {
+            ['foo']: Foo
+          }
+        }
+      </script>`
     }
   ],
   invalid: [
@@ -566,6 +610,40 @@ tester.run('no-unused-components', rule, {
         message: 'The "Foo" component has been registered but not used.',
         line: 8
       }]
+    },
+
+    // computed properties
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div />
+      </template>
+      <script>
+        export default {
+          components: {
+            ['foo']: Foo,
+            [\`bar\`]: Bar,
+            ['baz']: Baz,
+            [qux]: Qux,
+            ...components,
+            quux,
+          }
+        }
+      </script>`,
+      errors: [{
+        message: 'The "foo" component has been registered but not used.',
+        line: 8
+      }, {
+        message: 'The "bar" component has been registered but not used.',
+        line: 9
+      }, {
+        message: 'The "baz" component has been registered but not used.',
+        line: 10
+      }, {
+        message: 'The "quux" component has been registered but not used.',
+        line: 13
+      }]
     }
   ]
 })
diff --git a/tests/lib/utils/index.js b/tests/lib/utils/index.js
index 0b8c07e2..f698a98e 100644
--- a/tests/lib/utils/index.js
+++ b/tests/lib/utils/index.js
@@ -246,6 +246,25 @@ describe('getRegisteredComponents', () => {
       ['PrimaryButton', 'secondaryButton', 'the-modal', 'the_dropdown', 'the_input', 'SomeComponent'],
     )
   })
+
+  it('should return an array of only components whose names can be identified', () => {
+    node = parse(`const test = {
+      name: 'test',
+      components: {
+        ...test,
+        Foo,
+        [bar]: Bar,
+        [baz.baz]: Baz,
+        [\`\${qux}\`]: Qux,
+        [\`Quux\`]: Quux
+      }
+    }`)
+
+    assert.deepEqual(
+      utils.getRegisteredComponents(node).map(c => c.name),
+      ['Foo', 'Quux'],
+    )
+  })
 })
 
 describe('getComponentProps', () => {