diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..872909c93 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +node_modules +lib/recommended-rules.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..906fd952a --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,23 @@ +module.exports = { + root: true, + parserOptions: { + ecmaVersion: 6 + }, + env: { + node: true, + mocha: true + }, + extends: [ + 'plugin:eslint-plugin/recommended', + 'plugin:vue-libs/recommended' + ], + plugins: [ + 'eslint-plugin' + ], + rules: { + 'complexity': 'off', + 'eslint-plugin/report-message-format': ['error', '^[A-Z].*\\.$'], + 'eslint-plugin/prefer-placeholders': 'error', + 'eslint-plugin/consistent-output': 'error' + } +} diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index ef741a1a1..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "root": true, - "extends": [ - "mysticatea", - "mysticatea/node", - "plugin:eslint-plugin/recommended" - ], - "plugins": [ - "eslint-plugin" - ], - "rules": { - "complexity": "off", - "eslint-plugin/report-message-format": ["error", "^[A-Z].*\\.$"], - "eslint-plugin/prefer-placeholders": "error", - "eslint-plugin/consistent-output": "error" - } -} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 97175d6db..000000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -sudo: false -language: node_js -node_js: - - "4" - - "6" - - "7" -before_install: - - if [[ `npm --version` == 2* ]]; then npm install -g npm@3; fi -after_success: - - npm run codecov diff --git a/README.md b/README.md index f06a04430..aa7a9bfee 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,130 @@ # eslint-plugin-vue +[![NPM version](https://img.shields.io/npm/v/eslint-plugin-vue.svg?style=flat)](https://npmjs.org/package/eslint-plugin-vue) +[![NPM downloads](https://img.shields.io/npm/dm/eslint-plugin-vue.svg?style=flat)](https://npmjs.org/package/eslint-plugin-vue) +[![CircleCI](https://circleci.com/gh/vuejs/eslint-plugin-vue.svg?style=svg)](https://circleci.com/gh/vuejs/eslint-plugin-vue) + > Official ESLint plugin for Vue.js -## 💿 Installation +## :exclamation: Requirements + +- [ESLint](http://eslint.org/) `>=3.18.0`. +- Node.js `>=4.0.0` -Use [npm](https://www.npmjs.com/). +## :cd: Installation ``` -> npm install --save-dev eslint eslint-plugin-vue +npm install --save-dev eslint eslint-plugin-vue ``` -- Requires Node.js `^4.0.0 || >=6.0.0` -- Requires ESLint `>=3.18.0` - -## 📖 Usage +## :rocket: Usage -Write `.eslintrc.*` file to configure rules. See also: http://eslint.org/docs/user-guide/configuring +Create `.eslintrc.*` file to configure rules. See also: [http://eslint.org/docs/user-guide/configuring](http://eslint.org/docs/user-guide/configuring). -**.eslintrc.json** (An example) +Example **.eslintrc.js**: -```json -{ - "plugins": ["vue"], - "extends": ["eslint:recommended", "plugin:vue/recommended"], - "rules": { - "vue/html-quotes": ["error", "double"], - "vue/v-bind-style": ["error", "shorthand"], - "vue/v-on-style": ["error", "shorthand"] - } +```javascript +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:vue/recommended' // or 'plugin:vue/base' + ], + rules: { + // override/add rules' settings here + 'vue/no-invalid-v-if': 'error' + } } ``` -## 💡 Rules +## ⚙ Configs -- ⭐️ the mark of a recommended rule. -- ✒️ the mark of a fixable rule. +This plugin provides two predefined configs: +- `plugin:vue/base` - contains necessary settings for this plugin to work properly +- `plugin:vue/recommended` - extends base config with recommended rules (the ones with check mark :white_check_mark: in the table below) - -### Possible Errors +## :bulb: Rules -| | Rule ID | Description | -|:---|:--------|:------------| -| ⭐️ | [no-invalid-template-root](./docs/rules/no-invalid-template-root.md) | disallow invalid template root. | -| ⭐️ | [no-invalid-v-bind](./docs/rules/no-invalid-v-bind.md) | disallow invalid v-bind directives. | -| ⭐️ | [no-invalid-v-cloak](./docs/rules/no-invalid-v-cloak.md) | disallow invalid v-cloak directives. | -| ⭐️ | [no-invalid-v-else-if](./docs/rules/no-invalid-v-else-if.md) | disallow invalid v-else-if directives. | -| ⭐️ | [no-invalid-v-else](./docs/rules/no-invalid-v-else.md) | disallow invalid v-else directives. | -| ⭐️ | [no-invalid-v-for](./docs/rules/no-invalid-v-for.md) | disallow invalid v-for directives. | -| ⭐️ | [no-invalid-v-html](./docs/rules/no-invalid-v-html.md) | disallow invalid v-html directives. | -| ⭐️ | [no-invalid-v-if](./docs/rules/no-invalid-v-if.md) | disallow invalid v-if directives. | -| ⭐️ | [no-invalid-v-model](./docs/rules/no-invalid-v-model.md) | disallow invalid v-model directives. | -| ⭐️ | [no-invalid-v-on](./docs/rules/no-invalid-v-on.md) | disallow invalid v-on directives. | -| ⭐️ | [no-invalid-v-once](./docs/rules/no-invalid-v-once.md) | disallow invalid v-once directives. | -| ⭐️ | [no-invalid-v-pre](./docs/rules/no-invalid-v-pre.md) | disallow invalid v-pre directives. | -| ⭐️ | [no-invalid-v-show](./docs/rules/no-invalid-v-show.md) | disallow invalid v-show directives. | -| ⭐️ | [no-invalid-v-text](./docs/rules/no-invalid-v-text.md) | disallow invalid v-text directives. | -| ⭐️ | [no-parsing-error](./docs/rules/no-parsing-error.md) | disallow parsing errors in `", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives aren't supported on
elements."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives require no argument."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives don't support the modifier 'aaa'."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives require that attribute value."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives require the attribute value which is valid as LHS."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives don't support dynamic input types."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives don't support dynamic input types."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives don't support 'file' input type."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-model' directives cannot update the iteration variable 'x' itself."], - }, - ], +tester.run('no-invalid-v-model', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives aren't supported on
elements."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives require no argument."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives don't support the modifier 'aaa'."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives require that attribute value."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives require the attribute value which is valid as LHS."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives don't support dynamic input types."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives don't support dynamic input types."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives don't support 'file' input type."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-model' directives cannot update the iteration variable 'x' itself."] + } + ] }) diff --git a/tests/lib/rules/no-invalid-v-on.js b/tests/lib/rules/no-invalid-v-on.js index e0d12b2a2..24cc67eec 100644 --- a/tests/lib/rules/no-invalid-v-on.js +++ b/tests/lib/rules/no-invalid-v-on.js @@ -3,62 +3,62 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/no-invalid-v-on") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-invalid-v-on') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("no-invalid-v-on", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["'v-on' directives require event names."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-on' directives don't support the modifier 'aaa'."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-on' directives require that attribute value."], - }, - ], +tester.run('no-invalid-v-on', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["'v-on' directives require event names."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-on' directives don't support the modifier 'aaa'."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-on' directives require that attribute value."] + } + ] }) diff --git a/tests/lib/rules/no-invalid-v-once.js b/tests/lib/rules/no-invalid-v-once.js index 709ac8036..26c7a998b 100644 --- a/tests/lib/rules/no-invalid-v-once.js +++ b/tests/lib/rules/no-invalid-v-once.js @@ -3,50 +3,50 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/no-invalid-v-once") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-invalid-v-once') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("no-invalid-v-once", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["'v-once' directives require no argument."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-once' directives require no modifier."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-once' directives require no attribute value."], - }, - ], +tester.run('no-invalid-v-once', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["'v-once' directives require no argument."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-once' directives require no modifier."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-once' directives require no attribute value."] + } + ] }) diff --git a/tests/lib/rules/no-invalid-v-pre.js b/tests/lib/rules/no-invalid-v-pre.js index 064e5ac79..b31b474b3 100644 --- a/tests/lib/rules/no-invalid-v-pre.js +++ b/tests/lib/rules/no-invalid-v-pre.js @@ -3,50 +3,50 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/no-invalid-v-pre") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-invalid-v-pre') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("no-invalid-v-pre", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["'v-pre' directives require no argument."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-pre' directives require no modifier."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-pre' directives require no attribute value."], - }, - ], +tester.run('no-invalid-v-pre', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["'v-pre' directives require no argument."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-pre' directives require no modifier."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-pre' directives require no attribute value."] + } + ] }) diff --git a/tests/lib/rules/no-invalid-v-show.js b/tests/lib/rules/no-invalid-v-show.js index 458d57771..4d2e97507 100644 --- a/tests/lib/rules/no-invalid-v-show.js +++ b/tests/lib/rules/no-invalid-v-show.js @@ -3,50 +3,50 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/no-invalid-v-show") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-invalid-v-show') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("no-invalid-v-show", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["'v-show' directives require no argument."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-show' directives require no modifier."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-show' directives require that attribute value."], - }, - ], +tester.run('no-invalid-v-show', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["'v-show' directives require no argument."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-show' directives require no modifier."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-show' directives require that attribute value."] + } + ] }) diff --git a/tests/lib/rules/no-invalid-v-text.js b/tests/lib/rules/no-invalid-v-text.js index bbbdacc99..759363d1d 100644 --- a/tests/lib/rules/no-invalid-v-text.js +++ b/tests/lib/rules/no-invalid-v-text.js @@ -3,50 +3,50 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/no-invalid-v-text") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-invalid-v-text') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("no-invalid-v-text", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["'v-text' directives require no argument."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-text' directives require no modifier."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-text' directives require that attribute value."], - }, - ], +tester.run('no-invalid-v-text', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["'v-text' directives require no argument."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-text' directives require no modifier."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-text' directives require that attribute value."] + } + ] }) diff --git a/tests/lib/rules/no-parsing-error.js b/tests/lib/rules/no-parsing-error.js index a05c78fb7..9a20abba1 100644 --- a/tests/lib/rules/no-parsing-error.js +++ b/tests/lib/rules/no-parsing-error.js @@ -3,84 +3,84 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/no-parsing-error") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-parsing-error') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("no-parsing-error", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Unexpected token b."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Unexpected token b."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Unexpected token b."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Unexpected token ;."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Expected an expression but got no code."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Expected an expression but got no code."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Expected an expression but got no code."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Unexpected token )."], - }, - { - filename: "test.vue", - code: "", - errors: ["Parsing error: Assigning to rvalue."], - }, - ], +tester.run('no-parsing-error', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Unexpected token b.'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Unexpected token b.'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Unexpected token b.'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Unexpected token ;.'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Expected an expression but got no code.'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Expected an expression but got no code.'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Expected an expression but got no code.'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Unexpected token ).'] + }, + { + filename: 'test.vue', + code: '', + errors: ['Parsing error: Assigning to rvalue.'] + } + ] }) diff --git a/tests/lib/rules/no-textarea-mustache.js b/tests/lib/rules/no-textarea-mustache.js index eb628546f..8b6bff0dc 100644 --- a/tests/lib/rules/no-textarea-mustache.js +++ b/tests/lib/rules/no-textarea-mustache.js @@ -3,48 +3,48 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/no-textarea-mustache") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-textarea-mustache') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("no-textarea-mustache", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["Unexpected mustache. Use 'v-model' instead."], - }, - { - filename: "test.vue", - code: "", - errors: [ - "Unexpected mustache. Use 'v-model' instead.", - "Unexpected mustache. Use 'v-model' instead.", - ], - }, - ], +tester.run('no-textarea-mustache', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["Unexpected mustache. Use 'v-model' instead."] + }, + { + filename: 'test.vue', + code: '', + errors: [ + "Unexpected mustache. Use 'v-model' instead.", + "Unexpected mustache. Use 'v-model' instead." + ] + } + ] }) diff --git a/tests/lib/rules/require-component-is.js b/tests/lib/rules/require-component-is.js index 87771c4ac..f59b72b88 100644 --- a/tests/lib/rules/require-component-is.js +++ b/tests/lib/rules/require-component-is.js @@ -3,49 +3,49 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/require-component-is") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/require-component-is') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("require-component-is", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["Expected '' elements to have 'v-bind:is' attribute."], - }, - { - filename: "test.vue", - code: "", - errors: ["Expected '' elements to have 'v-bind:is' attribute."], - }, - ], +tester.run('require-component-is', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["Expected '' elements to have 'v-bind:is' attribute."] + }, + { + filename: 'test.vue', + code: '', + errors: ["Expected '' elements to have 'v-bind:is' attribute."] + } + ] }) diff --git a/tests/lib/rules/require-v-for-key.js b/tests/lib/rules/require-v-for-key.js index d5e48420f..156e4befa 100644 --- a/tests/lib/rules/require-v-for-key.js +++ b/tests/lib/rules/require-v-for-key.js @@ -3,53 +3,53 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/require-v-for-key") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/require-v-for-key') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("require-v-for-key", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - errors: ["'v-for' directives require 'v-bind:key' directives."], - }, - { - filename: "test.vue", - code: "", - errors: ["'v-for' directives require 'v-bind:key' directives."], - }, - ], +tester.run('require-v-for-key', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + errors: ["'v-for' directives require 'v-bind:key' directives."] + }, + { + filename: 'test.vue', + code: '', + errors: ["'v-for' directives require 'v-bind:key' directives."] + } + ] }) diff --git a/tests/lib/rules/v-bind-style.js b/tests/lib/rules/v-bind-style.js index 8269257cb..eeab4b9ab 100644 --- a/tests/lib/rules/v-bind-style.js +++ b/tests/lib/rules/v-bind-style.js @@ -3,69 +3,69 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/v-bind-style") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/v-bind-style') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("v-bind-style", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - options: ["shorthand"], - }, - { - filename: "test.vue", - code: "", - options: ["longform"], - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - output: "", - errors: ["Unexpected 'v-bind' before ':'."], - }, - { - filename: "test.vue", - options: ["shorthand"], - code: "", - output: "", - errors: ["Unexpected 'v-bind' before ':'."], - }, - { - filename: "test.vue", - options: ["longform"], - code: "", - output: "", - errors: ["Expected 'v-bind' before ':'."], - }, - ], +tester.run('v-bind-style', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '', + options: ['shorthand'] + }, + { + filename: 'test.vue', + code: '', + options: ['longform'] + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + output: '', + errors: ["Unexpected 'v-bind' before ':'."] + }, + { + filename: 'test.vue', + options: ['shorthand'], + code: '', + output: '', + errors: ["Unexpected 'v-bind' before ':'."] + }, + { + filename: 'test.vue', + options: ['longform'], + code: '', + output: '', + errors: ["Expected 'v-bind' before ':'."] + } + ] }) diff --git a/tests/lib/rules/v-on-style.js b/tests/lib/rules/v-on-style.js index c2473f49b..ba0ea711a 100644 --- a/tests/lib/rules/v-on-style.js +++ b/tests/lib/rules/v-on-style.js @@ -3,69 +3,69 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const RuleTester = require("eslint").RuleTester -const rule = require("../../../lib/rules/v-on-style") +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/v-on-style') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Tests -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const tester = new RuleTester({ - parser: "vue-eslint-parser", - parserOptions: {ecmaVersion: 2015}, + parser: 'vue-eslint-parser', + parserOptions: { ecmaVersion: 2015 } }) -tester.run("v-on-style", rule, { - valid: [ - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - }, - { - filename: "test.vue", - code: "", - options: ["shorthand"], - }, - { - filename: "test.vue", - code: "", - options: ["longform"], - }, - ], - invalid: [ - { - filename: "test.vue", - code: "", - output: "", - errors: ["Expected '@' instead of 'v-on:'."], - }, - { - filename: "test.vue", - options: ["shorthand"], - code: "", - output: "", - errors: ["Expected '@' instead of 'v-on:'."], - }, - { - filename: "test.vue", - options: ["longform"], - code: "", - output: "", - errors: ["Expected 'v-on:' instead of '@'."], - }, - ], +tester.run('v-on-style', rule, { + valid: [ + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: '', + options: ['shorthand'] + }, + { + filename: 'test.vue', + code: '', + options: ['longform'] + } + ], + invalid: [ + { + filename: 'test.vue', + code: '', + output: '', + errors: ["Expected '@' instead of 'v-on:'."] + }, + { + filename: 'test.vue', + options: ['shorthand'], + code: '', + output: '', + errors: ["Expected '@' instead of 'v-on:'."] + }, + { + filename: 'test.vue', + options: ['longform'], + code: '', + output: '', + errors: ["Expected 'v-on:' instead of '@'."] + } + ] }) diff --git a/tools/update-rules.js b/tools/update-rules.js index 28886e003..2cf537c78 100644 --- a/tools/update-rules.js +++ b/tools/update-rules.js @@ -3,94 +3,89 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const fs = require("fs") -const path = require("path") +const fs = require('fs') +const path = require('path') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Main -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const ROOT = path.resolve(__dirname, "../lib/rules") -const README = path.resolve(__dirname, "../README.md") -const RULES_JS = path.resolve(__dirname, "../lib/rules.js") -const RECOMMENDED_JSON = path.resolve(__dirname, "../lib/recommended.json") -const STAR = "⭐️" -const PEN = "✒️" -const CATEGORIES = ["Possible Errors", "Best Practices", "Stylistic Issues"] -const TABLE_PLACE_HOLDER = /[\s\S]*/ +const root = path.resolve(__dirname, '../lib/rules') +const readmeFile = path.resolve(__dirname, '../README.md') +const recommendedRulesFile = path.resolve(__dirname, '../lib/recommended-rules.js') +const tablePlaceholder = /[\s\S]*/ +const readmeContent = fs.readFileSync(readmeFile, 'utf8') -const ruleNames = fs.readdirSync(ROOT) - .filter(file => path.extname(file) === ".js") - .map(file => path.basename(file, ".js")) +const STAR = ':white_check_mark:' +const PEN = ':wrench:' -const rules = new Map( - ruleNames.map(name => [ - name, - require(path.join(ROOT, name)), - ]) -) +const rules = fs.readdirSync(root) + .filter(file => path.extname(file) === '.js') + .map(file => path.basename(file, '.js')) + .map(fileName => [ + fileName, + require(path.join(root, fileName)) + ]) + +const categories = rules + .map(entry => entry[1].meta.docs.category) + .reduce((arr, category) => { + if (!arr.includes(category)) { + arr.push(category) + } + return arr + }, []) -const RULE_TABLE = CATEGORIES.map(category => `### ${category} +const rulesTableContent = categories.map(category => ` +### ${category} | | Rule ID | Description | |:---|:--------|:------------| ${ - Array.from(rules.entries()) - .filter(entry => entry[1].meta.docs.category === category) - .map(entry => { - const name = entry[0] - const meta = entry[1].meta - const mark = `${meta.docs.recommended ? STAR : ""}${meta.fixable ? PEN : ""}` - const link = `[${name}](./docs/rules/${name}.md)` - const description = meta.docs.description || "(no description)" - return `| ${mark} | ${link} | ${description} |` - }) - .join("\n") + rules + .filter(entry => entry[1].meta.docs.category === category) + .map(entry => { + const name = entry[0] + const meta = entry[1].meta + const mark = `${meta.docs.recommended ? STAR : ''}${meta.fixable ? PEN : ''}` + const link = `[${name}](./docs/rules/${name}.md)` + const description = meta.docs.description || '(no description)' + return `| ${mark} | ${link} | ${description} |` + }) + .join('\n') } -`).join("\n") +`).join('\n') -const RULES_JS_CONTENT = `/** - * @author Toru Nagashima - * @copyright 2017 Toru Nagashima. All rights reserved. - * See LICENSE file in root directory for full license. - */ -"use strict" +const recommendedRules = rules.reduce((obj, entry) => { + const name = `vue/${entry[0]}` + const recommended = entry[1].meta.docs.recommended + const status = recommended ? 'error' : 'off' + obj[name] = status + return obj +}, {}) -module.exports = { -${ruleNames.map(name => ` "${name}": require("./rules/${name}"),`).join("\n")} -} -` - -const recommendedConf = { - parser: "vue-eslint-parser", - env: {es6: true}, - rules: Array.from(rules.entries()) - .reduce((obj, entry) => { - const name = entry[0] - const recommended = entry[1].meta.docs.recommended - obj[`vue/${name}`] = recommended ? "error" : "off" - return obj - }, {}), -} +const recommendedRulesContent = `/* + * IMPORTANT! + * This file has been automatically generated, + * in order to update it's content execute "npm run update" + */ +module.exports = ${JSON.stringify(recommendedRules, null, 2)}` fs.writeFileSync( - README, - fs.readFileSync(README, "utf8").replace( - TABLE_PLACE_HOLDER, - `\n${RULE_TABLE}\n` - ) -) -fs.writeFileSync( - RULES_JS, - RULES_JS_CONTENT + readmeFile, + readmeContent.replace( + tablePlaceholder, + `\n${rulesTableContent}\n` + ) ) + fs.writeFileSync( - RECOMMENDED_JSON, - JSON.stringify(recommendedConf, null, 4) + recommendedRulesFile, + recommendedRulesContent )