From 3f88f28d7877b37a7e9a9d0c46fa0750866cf44a Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 26 Apr 2018 10:04:08 -0400 Subject: [PATCH 0001/1248] Update require-v-for-key.md --- docs/rules/require-v-for-key.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rules/require-v-for-key.md b/docs/rules/require-v-for-key.md index 5c54a3d20..d139c5d2a 100644 --- a/docs/rules/require-v-for-key.md +++ b/docs/rules/require-v-for-key.md @@ -10,7 +10,7 @@ On other elements, it's better that `v-bind:key` is written as well. This rule reports the elements which have `v-for` and do not have `v-bind:key`. This rule does not report custom components. -It will be reported by [no-invalid-v-for] rule. +It will be reported by [valid-v-for] rule. :-1: Examples of **incorrect** code for this rule: @@ -33,6 +33,6 @@ Nothing. ## :couple: Related rules -- [no-invalid-v-for] +- [valid-v-for] -[no-invalid-v-for]: ./no-invalid-v-for.md +[valid-v-for]: ./valid-v-for.md From a95dfbba3b1301c22f5598d6e289ec3dc5afad39 Mon Sep 17 00:00:00 2001 From: ota Date: Thu, 12 Jul 2018 01:10:12 +0900 Subject: [PATCH 0002/1248] =?UTF-8?q?=E2=AD=90=EF=B8=8FNew:=20Add=20`vue/n?= =?UTF-8?q?o-use-v-if-with-v-for`=20rule=20(#406)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Vue.extend support, add missing info about Vue.mixin check in readme * Docs: fixes wording in docs (#372) * Fix: fix script-indent to prevent removing + ``` + +:+1: Examples of **correct** code for this rule: + +```html + + +``` + +## :wrench: Options + +Nothing. diff --git a/lib/rules/no-template-shadow.js b/lib/rules/no-template-shadow.js new file mode 100644 index 000000000..6a476d67d --- /dev/null +++ b/lib/rules/no-template-shadow.js @@ -0,0 +1,76 @@ +/** + * @fileoverview Disallow variable declarations from shadowing variables declared in the outer scope. + * @author Armano + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ + +const utils = require('../utils') + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ + +const GROUP_NAMES = ['props', 'computed', 'data', 'methods'] + +module.exports = { + meta: { + docs: { + description: 'disallow variable declarations from shadowing variables declared in the outer scope', + category: 'strongly-recommended', + url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.1/docs/rules/no-template-shadow.md' + }, + fixable: null, + schema: [] + }, + + create (context) { + const jsVars = new Set() + let scope = { + parent: null, + nodes: [] + } + + // ---------------------------------------------------------------------- + // Public + // ---------------------------------------------------------------------- + + return utils.defineTemplateBodyVisitor(context, { + VElement (node) { + scope = { + parent: scope, + nodes: scope.nodes.slice() // make copy + } + if (node.variables) { + for (const variable of node.variables) { + const varNode = variable.id + const name = varNode.name + if (scope.nodes.some(node => node.name === name) || jsVars.has(name)) { + context.report({ + node: varNode, + loc: varNode.loc, + message: "Variable '{{name}}' is already declared in the upper scope.", + data: { + name + } + }) + } else { + scope.nodes.push(varNode) + } + } + } + }, + 'VElement:exit' (node) { + scope = scope.parent + } + }, utils.executeOnVue(context, (obj) => { + const properties = Array.from(utils.iterateProperties(obj, new Set(GROUP_NAMES))) + for (const node of properties) { + jsVars.add(node.name) + } + })) + } +} diff --git a/lib/utils/index.js b/lib/utils/index.js index f45950fcd..e0279636c 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -26,7 +26,7 @@ module.exports = { * * @param {RuleContext} context The rule context to use parser services. * @param {Object} templateBodyVisitor The visitor to traverse the template body. - * @param {Object} scriptVisitor The visitor to traverse the script. + * @param {Object} [scriptVisitor] The visitor to traverse the script. * @returns {Object} The merged visitor. */ defineTemplateBodyVisitor (context, templateBodyVisitor, scriptVisitor) { diff --git a/tests/lib/rules/no-template-shadow.js b/tests/lib/rules/no-template-shadow.js new file mode 100644 index 000000000..c52f4ddb4 --- /dev/null +++ b/tests/lib/rules/no-template-shadow.js @@ -0,0 +1,213 @@ +/** + * @fileoverview Disallow variable declarations from shadowing variables declared in the outer scope. + * @author Armano + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ + +const rule = require('../../../lib/rules/no-template-shadow') +const RuleTester = require('eslint').RuleTester + +// ------------------------------------------------------------------------------ +// Tests +// ------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parser: 'vue-eslint-parser', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module' + } +}) + +ruleTester.run('no-template-shadow', rule, { + + valid: [ + '', + '', + '', + '', + '', + '', + { + filename: 'test.vue', + code: ` + ` + }, + { + filename: 'test.vue', + code: ` + ` + } + ], + + invalid: [ + { + filename: 'test.vue', + code: '', + errors: [{ + message: "Variable 'i' is already declared in the upper scope.", + type: 'Identifier' + }] + }, + { + filename: 'test.vue', + code: ` + `, + errors: [{ + message: "Variable 'i' is already declared in the upper scope.", + type: 'Identifier', + line: 2 + }] + }, + { + filename: 'test.vue', + code: ` + `, + errors: [{ + message: "Variable 'i' is already declared in the upper scope.", + type: 'Identifier', + line: 2 + }, { + message: "Variable 'i' is already declared in the upper scope.", + type: 'Identifier', + line: 3 + }] + }, + { + filename: 'test.vue', + code: ` + `, + errors: [{ + message: "Variable 'i' is already declared in the upper scope.", + type: 'Identifier', + line: 2 + }, { + message: "Variable 'i' is already declared in the upper scope.", + type: 'Identifier', + line: 3 + }] + }, + { + filename: 'test.vue', + code: ` + `, + errors: [{ + message: "Variable 'i' is already declared in the upper scope.", + type: 'Identifier', + line: 2 + }, { + message: "Variable 'f' is already declared in the upper scope.", + type: 'Identifier', + line: 3 + }] + }, + { + filename: 'test.vue', + code: ` + `, + errors: [{ + message: "Variable 'e' is already declared in the upper scope.", + type: 'Identifier', + line: 6 + }, { + message: "Variable 'f' is already declared in the upper scope.", + type: 'Identifier', + line: 7 + }] + } + ] +}) From 8d204094a03a3f41735d63af6014c1a2305df674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Mon, 30 Jul 2018 16:32:05 +0200 Subject: [PATCH 0041/1248] Update no-use-v-if-v-for category to essential --- lib/rules/no-use-v-if-with-v-for.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/no-use-v-if-with-v-for.js b/lib/rules/no-use-v-if-with-v-for.js index 760a16811..eedd9b2e0 100644 --- a/lib/rules/no-use-v-if-with-v-for.js +++ b/lib/rules/no-use-v-if-with-v-for.js @@ -51,7 +51,7 @@ module.exports = { meta: { docs: { description: 'disallow use v-if on the same element as v-for', - category: 'recommended', + category: 'essential', url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.1/docs/rules/no-use-v-if-with-v-for.md' }, fixable: null, From 74f7dc634cfb9e38672e9295555de0fa6e488c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Mon, 30 Jul 2018 16:32:39 +0200 Subject: [PATCH 0042/1248] Update README & configs --- README.md | 5 +++-- docs/rules/component-name-in-template-casing.md | 3 +-- docs/rules/no-template-shadow.md | 4 +++- docs/rules/no-use-v-if-with-v-for.md | 2 +- lib/configs/essential.js | 1 + lib/configs/recommended.js | 1 - lib/configs/strongly-recommended.js | 2 +- lib/index.js | 1 + 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1e5ed04da..7870ed231 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi | | [vue/no-template-key](./docs/rules/no-template-key.md) | disallow `key` attribute on ``, + { + code: ` + `, + options: [{ + ignores: ['ignore-tag'] + }] + }, + // Ignore if no closing brackets + ` + + `, + output: ` + + `, + errors: [ + { + message: 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + line: 5, + column: 12, + nodeType: 'HTMLTagClose', + endLine: 5, + endColumn: 12 + }, + { + message: 'Expected 1 line break before closing tag (`
`), but no line breaks found.', + line: 5, + column: 19, + nodeType: 'HTMLEndTagOpen', + endLine: 5, + endColumn: 19 + } + ] + }, + // spaces + { + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + line: 5, + column: 12, + endLine: 5, + endColumn: 15 + }, + { + message: 'Expected 1 line break before closing tag (`
`), but no line breaks found.', + line: 5, + column: 22, + endLine: 5, + endColumn: 22 + } + ] + }, + // elements + { + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + line: 3, + column: 16, + endLine: 3, + endColumn: 16 + }, + { + message: 'Expected 1 line break before closing tag (`
`), but no line breaks found.', + line: 4, + column: 22, + endLine: 4, + endColumn: 22 + } + ] + }, + // contents + { + code: ` + `, + output: ` + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + { + code: ` + `, + output: ` + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.' + ] + }, + { + code: ` + `, + output: ` + `, + errors: [ + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + // comments + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + // one error + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.' + ] + }, + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + // multi + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (``), but no line breaks found.' + ] + }, + // multi line breaks + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but 2 line breaks found.', + 'Expected 1 line break before closing tag (`
`), but 2 line breaks found.' + ] + }, + // mustache + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + // mix + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + // start tag + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + { + code: ` + + `, + output: ` + + `, + errors: [ + 'Expected 1 line break after opening tag (`
`), but no line breaks found.', + 'Expected 1 line break before closing tag (`
`), but no line breaks found.' + ] + }, + { + code: ` + + `, + output: ` + + `, + errors: ['Expected 1 line break after opening tag (`
`), but no line breaks found.'] + } + ] +}) From a7d0b3c8aa6e93f79d4aecc11325e476936cf116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Tue, 14 Aug 2018 01:39:53 +0200 Subject: [PATCH 0050/1248] Update script-indent.md --- docs/rules/script-indent.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/rules/script-indent.md b/docs/rules/script-indent.md index 1e073899e..bb882d900 100644 --- a/docs/rules/script-indent.md +++ b/docs/rules/script-indent.md @@ -79,6 +79,24 @@ const d = { ``` +## Important note + +This rule only checks `.vue` files and does not interfere with other `.js` files. Unfortunately the default `indent` rule when turned on will try to lint both, so in order to make them complementary you can use `overrides` setting and disable `indent` rule on `.vue` files: + +``` +"rules": { + "vue/script-indent": ["error", 4, { "baseIndent": 1 }] +}, +"overrides": [ + { + "files": ["*.vue"], + "rules": { + "indent": "off" + } + } +] +``` + ## Related rules - [indent](https://eslint.org/docs/rules/indent) From cae7d51d8a3e81e9d507aae3e9114027061cba33 Mon Sep 17 00:00:00 2001 From: ota Date: Tue, 14 Aug 2018 08:41:51 +0900 Subject: [PATCH 0051/1248] [New] Add `vue/singleline-html-element-content-newline` rule (#552) * [New] Add `vue/singleline-html-element-content-newline` rule * Update `strict` -> `ignoreWhenNoAttributes`, `ignoreNames` -> `ignores` and report messages --- README.md | 1 + ...singleline-html-element-content-newline.md | 101 ++++ lib/index.js | 1 + ...singleline-html-element-content-newline.js | 152 ++++++ ...singleline-html-element-content-newline.js | 439 ++++++++++++++++++ 5 files changed, 694 insertions(+) create mode 100644 docs/rules/singleline-html-element-content-newline.md create mode 100644 lib/rules/singleline-html-element-content-newline.js create mode 100644 tests/lib/rules/singleline-html-element-content-newline.js diff --git a/README.md b/README.md index 6a4191b4c..4ad4a2048 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi | :wrench: | [vue/multiline-html-element-content-newline](./docs/rules/multiline-html-element-content-newline.md) | require a line break before and after the contents of a multiline element | | :wrench: | [vue/no-spaces-around-equal-signs-in-attribute](./docs/rules/no-spaces-around-equal-signs-in-attribute.md) | disallow spaces around equal signs in attribute | | :wrench: | [vue/script-indent](./docs/rules/script-indent.md) | enforce consistent indentation in ` +``` + +:+1: Examples of **correct** code: + +```json +{ + "vue/no-unused-components": ["error", { + "ignoreWhenBindingPresent": false + }] +} +``` + +```html + + + +``` diff --git a/lib/rules/no-unused-components.js b/lib/rules/no-unused-components.js index 90673dfff..aff3743b2 100644 --- a/lib/rules/no-unused-components.js +++ b/lib/rules/no-unused-components.js @@ -23,42 +23,51 @@ module.exports = { url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.3/docs/rules/no-unused-components.md' }, fixable: null, - schema: [] + schema: [{ + type: 'object', + properties: { + ignoreWhenBindingPresent: { + type: 'boolean' + } + }, + additionalProperties: false + }] }, create (context) { + const options = context.options[0] || {} + const ignoreWhenBindingPresent = options.ignoreWhenBindingPresent !== undefined ? options.ignoreWhenBindingPresent : true const usedComponents = [] let registeredComponents = [] + let ignoreReporting = false let templateLocation return utils.defineTemplateBodyVisitor(context, { VElement (node) { - if (!utils.isCustomComponent(node)) return - let usedComponentName - - if (utils.hasAttribute(node, 'is')) { - usedComponentName = utils.findAttribute(node, 'is').value.value - } else if (utils.hasDirective(node, 'bind', 'is')) { - const directiveNode = utils.findDirective(node, 'bind', 'is') - if ( - directiveNode.value.type === 'VExpressionContainer' && - directiveNode.value.expression.type === 'Literal' - ) { - usedComponentName = directiveNode.value.expression.value - } - } else { - usedComponentName = node.rawName + if (utils.isHtmlElementNode(node) && !utils.isHtmlWellKnownElementName(node.rawName)) { + usedComponents.push(node.rawName) } + }, + "VAttribute[directive=true][key.name='bind'][key.argument='is']" (node) { + if (node.value.type !== 'VExpressionContainer') return - if (usedComponentName) { - usedComponents.push(usedComponentName) + if (node.value.expression.type === 'Literal') { + usedComponents.push(node.value.expression.value) + } else if (ignoreWhenBindingPresent) { + ignoreReporting = true } }, + "VAttribute[directive=false][key.name='is']" (node) { + usedComponents.push(node.value.value) + }, "VElement[name='template']" (rootNode) { templateLocation = templateLocation || rootNode.loc.start }, "VElement[name='template']:exit" (rootNode) { - if (rootNode.loc.start !== templateLocation) return + if ( + rootNode.loc.start !== templateLocation || + ignoreReporting + ) return registeredComponents .filter(({ name }) => { diff --git a/lib/utils/index.js b/lib/utils/index.js index b39eeba04..8c39c63d8 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -233,7 +233,7 @@ module.exports = { assert(node && node.type === 'VElement') return ( - (this.isHtmlElementNode(node) && !this.isHtmlWellKnownElementName(node.name)) || + (this.isHtmlElementNode(node) && !this.isHtmlWellKnownElementName(node.rawName)) || this.hasAttribute(node, 'is') || this.hasDirective(node, 'bind', 'is') ) @@ -280,7 +280,7 @@ module.exports = { isHtmlWellKnownElementName (name) { assert(typeof name === 'string') - return HTML_ELEMENT_NAMES.has(name.toLowerCase()) + return HTML_ELEMENT_NAMES.has(name) }, /** @@ -291,7 +291,7 @@ module.exports = { isHtmlVoidElementName (name) { assert(typeof name === 'string') - return VOID_ELEMENT_NAMES.has(name.toLowerCase()) + return VOID_ELEMENT_NAMES.has(name) }, /** diff --git a/tests/lib/rules/no-unused-components.js b/tests/lib/rules/no-unused-components.js index f412b3ecb..939413a59 100644 --- a/tests/lib/rules/no-unused-components.js +++ b/tests/lib/rules/no-unused-components.js @@ -282,6 +282,57 @@ tester.run('no-unused-components', rule, { } ` }, + { + filename: 'test.vue', + code: ` + ` + }, + + { + filename: 'test.vue', + code: ` + + `, + options: [{ ignoreWhenBindingPresent: true }] + }, // Ignore when `render` is used instead of temoplate { @@ -364,6 +415,40 @@ tester.run('no-unused-components', rule, { message: 'The "the-button" component has been registered but not used.', line: 11 }] + }, + // Setting: ignoreWhenBindingPresent + { + filename: 'test.vue', + code: ` + + `, + options: [{ ignoreWhenBindingPresent: false }], + errors: [{ + message: 'The "Foo" component has been registered but not used.', + line: 13 + }, { + message: 'The "Bar" component has been registered but not used.', + line: 14 + }] } ] }) From 117ffc619f15cbb4ed627d58b922e03f4d02acc0 Mon Sep 17 00:00:00 2001 From: Ruslan Gunawardana Date: Thu, 13 Sep 2018 23:40:05 +0300 Subject: [PATCH 0054/1248] Fixed typo in v-html rule description (#561) According to OWASP shorthand XSS stands for Cross-Site Scripting: https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) --- docs/rules/no-v-html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-v-html.md b/docs/rules/no-v-html.md index a5494a2fc..d5e82d17f 100644 --- a/docs/rules/no-v-html.md +++ b/docs/rules/no-v-html.md @@ -2,7 +2,7 @@ - :gear: This rule is included in `"plugin:vue/recommended"`. -This rule reports use of `v-html` directive in order to reduce the risk of injecting potentially unsafe / unescaped html into the browser leading to Cross Side Scripting (XSS) attacks. +This rule reports use of `v-html` directive in order to reduce the risk of injecting potentially unsafe / unescaped html into the browser leading to Cross-Site Scripting (XSS) attacks. ## :book: Rule Details From f0c8b379ce8e98f5f3cd0ee582ad6abbf6604f7f Mon Sep 17 00:00:00 2001 From: ota Date: Wed, 19 Sep 2018 04:56:30 +0900 Subject: [PATCH 0055/1248] Fix: Made not to conflict when `html-self-closing` and `component-name-in-template-casing` are autofix (#555) * fixed #554 * Deleted useless test case. --- lib/rules/html-self-closing.js | 6 ++- tests/lib/autofix.js | 98 ++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 tests/lib/autofix.js diff --git a/lib/rules/html-self-closing.js b/lib/rules/html-self-closing.js index 65aac0a57..de3107436 100644 --- a/lib/rules/html-self-closing.js +++ b/lib/rules/html-self-closing.js @@ -165,7 +165,11 @@ module.exports = { if (elementType === ELEMENT_TYPE.VOID) { return fixer.replaceText(close, '>') } - return fixer.replaceText(close, `>`) + // If only `close` is targeted for replacement, it conflicts with `component-name-in-template-casing`, + // so replace the entire element. + // return fixer.replaceText(close, `>`) + const elementPart = sourceCode.text.slice(node.range[0], close.range[0]) + return fixer.replaceText(node, elementPart + `>`) } }) } diff --git a/tests/lib/autofix.js b/tests/lib/autofix.js new file mode 100644 index 000000000..7d1b9604d --- /dev/null +++ b/tests/lib/autofix.js @@ -0,0 +1,98 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +'use strict' + +const Linter = require('eslint').Linter +const chai = require('chai') + +const rules = require('../..').rules + +const assert = chai.assert + +const baseConfig = { + parser: 'vue-eslint-parser', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + jsx: true + } + } +} + +describe('Complex autofix test cases', () => { + const linter = new Linter() + for (const key of Object.keys(rules)) { + const ruleId = `vue/${key}` + linter.defineRule(ruleId, rules[key]) + } + + // https://github.com/vuejs/eslint-plugin-vue/issues/554 + describe('Autofix of `html-self-closing` and `component-name-in-template-casing` should not conflict.', () => { + const kebabConfig = Object.assign({}, baseConfig, { 'rules': { + 'vue/html-self-closing': ['error', { + 'html': { + 'component': 'never' + } + }], + 'vue/component-name-in-template-casing': ['error', 'kebab-case'] + }}) + const pascalConfig = Object.assign({}, baseConfig, { 'rules': { + 'vue/html-self-closing': ['error', { + 'html': { + 'component': 'never' + } + }], + 'vue/component-name-in-template-casing': ['error'] + }}) + it('Even if set kebab-case, the output should be as expected.', () => { + const code = ` + ` + const output = ` + ` + + assert.equal( + linter.verifyAndFix(code, kebabConfig, 'test.vue').output, + output + ) + }) + it('Even if set PascalCase, the output should be as expected.', () => { + const code = ` + ` + const output = ` + ` + + assert.equal( + linter.verifyAndFix(code, pascalConfig, 'test.vue').output, + output + ) + }) + it('Even if element have an attributes, the output should be as expected.', () => { + const code = ` + ` + const output = ` + ` + + assert.equal( + linter.verifyAndFix(code, pascalConfig, 'test.vue').output, + output + ) + }) + }) +}) From 562fde184a7a37f551fc98711a0bb4233c749606 Mon Sep 17 00:00:00 2001 From: Adi Sahar Date: Tue, 18 Sep 2018 23:04:50 +0300 Subject: [PATCH 0056/1248] Update Readme with Vetur information (#559) * Update "Why doesn't it work on .vue file?" I had an issue where the plugin works, but red markings of errors remained. So I found out the instructions for this section are missing a note regarding Vetur. You need the following setting to complete the setup: ``` "vetur.validation.template": false ``` Note: While it solved my issue, there is something to consider with how it's applied. Eslint is mostly used in a per-project manner. This means, if you apply the rule above to `settings.json`, it is global a rule and Vue projects that do not use this plugin will not show template errors. So to solve this, you need to apply the setting locally. In the context of VS Code, it's easy. You just save a "workspace" to your project root and that creates a file, where you can apply the settings, thus locally. See [here](https://github.com/Microsoft/vscode/issues/37519) for details. * Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ad4a2048..2cebaac59 100644 --- a/README.md +++ b/README.md @@ -284,8 +284,9 @@ The `vue-eslint-parser` uses the parser which is set by `parserOptions.parser` t ``` 2. Make sure your tool is set to lint `.vue` files. - - CLI targets only `.js` files by default. You have to specify additional extensions by `--ext` option or glob patterns. E.g. `eslint "src/**/*.{js,vue}"` or `eslint src --ext .vue`. + - CLI targets only `.js` files by default. You have to specify additional extensions by `--ext` option or glob patterns. E.g. `eslint "src/**/*.{js,vue}"` or `eslint src --ext .vue`. If you use `@vue/cli-plugin-eslint` and the `vue-cli-service lint` command - you don't have to worry about it. - VSCode targets only JavaScript or HTML files by default. You have to add `"vue"` to the `"eslint.validate"` array in vscode settings. e.g. `"eslint.validate": [ "javascript", "javascriptreact", "vue" ]` + - If you use `Vetur` plugin in VSCode - set `"vetur.validation.template": false` to avoid default Vetur template validation. Check out [vetur documentation](https://github.com/vuejs/vetur/blob/master/docs/linting-error.md) for more info. ## :anchor: Semantic Versioning Policy From b1e1bb95ebfdc98a8187551c27c6d2b9f73b1625 Mon Sep 17 00:00:00 2001 From: ota Date: Wed, 19 Sep 2018 05:10:57 +0900 Subject: [PATCH 0057/1248] Fix: if no trailing comma, not to leave trailing comma after fixed of `order-in-components` (#569) * Fix: if no trailing comma, not to leave trailing comma after fixed of `order-in-components` * use array fixer --- lib/rules/order-in-components.js | 24 +++++----- tests/lib/autofix.js | 62 ++++++++++++++++++++++++++ tests/lib/rules/order-in-components.js | 32 +++++++++++-- 3 files changed, 103 insertions(+), 15 deletions(-) diff --git a/lib/rules/order-in-components.js b/lib/rules/order-in-components.js index ffd103ebb..c95294958 100644 --- a/lib/rules/order-in-components.js +++ b/lib/rules/order-in-components.js @@ -193,22 +193,22 @@ module.exports = { if (hasSideEffectsPossibility) { return undefined } - const comma = sourceCode.getTokenAfter(propertyNode) - const hasAfterComma = isComma(comma) + const afterComma = sourceCode.getTokenAfter(propertyNode) + const hasAfterComma = isComma(afterComma) - const codeStart = sourceCode.getTokenBefore(propertyNode).range[1] // to include comments - const codeEnd = hasAfterComma ? comma.range[1] : propertyNode.range[1] + const beforeComma = sourceCode.getTokenBefore(propertyNode) + const codeStart = beforeComma.range[1] // to include comments + const codeEnd = hasAfterComma ? afterComma.range[1] : propertyNode.range[1] const propertyCode = sourceCode.text.slice(codeStart, codeEnd) + (hasAfterComma ? '' : ',') const insertTarget = sourceCode.getTokenBefore(firstUnorderedPropertyNode) - // If we can upgrade requirements to `eslint@>4.1.0`, this code can be replaced by: - // return [ - // fixer.removeRange([codeStart, codeEnd]), - // fixer.insertTextAfter(insertTarget, propertyCode) - // ] - const insertStart = insertTarget.range[1] - const newCode = propertyCode + sourceCode.text.slice(insertStart, codeStart) - return fixer.replaceTextRange([insertStart, codeEnd], newCode) + + const removeStart = hasAfterComma ? codeStart : beforeComma.range[0] + + return [ + fixer.removeRange([removeStart, codeEnd]), + fixer.insertTextAfter(insertTarget, propertyCode) + ] } }) } diff --git a/tests/lib/autofix.js b/tests/lib/autofix.js index 7d1b9604d..5a38dd0e4 100644 --- a/tests/lib/autofix.js +++ b/tests/lib/autofix.js @@ -29,6 +29,64 @@ describe('Complex autofix test cases', () => { linter.defineRule(ruleId, rules[key]) } + // https://github.com/vuejs/eslint-plugin-vue/issues/566 + describe('Autofix of `vue/order-in-components` and `comma-dangle` should not conflict.', () => { + const config = Object.assign({}, baseConfig, { 'rules': { + 'vue/order-in-components': ['error'], + 'comma-dangle': ['error', 'always'] + }}) + + it('Even if set comma-dangle:always, the output should be as expected.', () => { + const code = ` + ` + const output = ` + ` + assert.equal( + linter.verifyAndFix(code, config, 'test.vue').output, + output + ) + }) + + it('Even if include comments, the output should be as expected.', () => { + const code = ` + ` + const output = ` + ` + assert.equal( + linter.verifyAndFix(code, config, 'test.vue').output, + output + ) + }) + }) + // https://github.com/vuejs/eslint-plugin-vue/issues/554 describe('Autofix of `html-self-closing` and `component-name-in-template-casing` should not conflict.', () => { const kebabConfig = Object.assign({}, baseConfig, { 'rules': { @@ -39,6 +97,7 @@ describe('Complex autofix test cases', () => { }], 'vue/component-name-in-template-casing': ['error', 'kebab-case'] }}) + const pascalConfig = Object.assign({}, baseConfig, { 'rules': { 'vue/html-self-closing': ['error', { 'html': { @@ -47,6 +106,7 @@ describe('Complex autofix test cases', () => { }], 'vue/component-name-in-template-casing': ['error'] }}) + it('Even if set kebab-case, the output should be as expected.', () => { const code = ` - `, - errors: [ - { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 2 }, - { message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 3 }, - { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 4 } - ] - }, - { - filename: 'test.vue', - code: unIndent` - - `, - output: unIndent` - - `, - errors: [ - { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 2 }, - { message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 3 }, - { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 4 } - ] - }, - { - filename: 'test.vue', - code: unIndent` - `, - output: unIndent` - - `, errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 2 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 3 }, - { message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 4 }, - { message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 5 }, - { message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 6 }, - { message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 7 }, + { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 4 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 8 } ] } From 8fd7ab841a42b25f1ce0b025063fb16bd41a9337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Sun, 18 Nov 2018 12:43:26 +0100 Subject: [PATCH 0091/1248] chore: Update uncategorized rules' categories (#651) --- lib/rules/component-name-in-template-casing.js | 2 +- lib/rules/multiline-html-element-content-newline.js | 2 +- lib/rules/no-spaces-around-equal-signs-in-attribute.js | 2 +- lib/rules/singleline-html-element-content-newline.js | 2 +- lib/rules/use-v-on-exact.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/rules/component-name-in-template-casing.js b/lib/rules/component-name-in-template-casing.js index 6de8e6681..eb85e8a99 100644 --- a/lib/rules/component-name-in-template-casing.js +++ b/lib/rules/component-name-in-template-casing.js @@ -22,7 +22,7 @@ module.exports = { meta: { docs: { description: 'enforce specific casing for the component naming style in template', - category: undefined, // strongly-recommended + category: 'strongly-recommended', url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.4/docs/rules/component-name-in-template-casing.md' }, fixable: 'code', diff --git a/lib/rules/multiline-html-element-content-newline.js b/lib/rules/multiline-html-element-content-newline.js index 415c8ddf4..c32db8e6c 100644 --- a/lib/rules/multiline-html-element-content-newline.js +++ b/lib/rules/multiline-html-element-content-newline.js @@ -51,7 +51,7 @@ module.exports = { meta: { docs: { description: 'require a line break before and after the contents of a multiline element', - category: undefined, + category: 'strongly-recommended', url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.4/docs/rules/multiline-html-element-content-newline.md' }, fixable: 'whitespace', diff --git a/lib/rules/no-spaces-around-equal-signs-in-attribute.js b/lib/rules/no-spaces-around-equal-signs-in-attribute.js index 3a2dbb891..eefe09e87 100644 --- a/lib/rules/no-spaces-around-equal-signs-in-attribute.js +++ b/lib/rules/no-spaces-around-equal-signs-in-attribute.js @@ -18,7 +18,7 @@ module.exports = { meta: { docs: { description: 'disallow spaces around equal signs in attribute', - category: undefined, + category: 'strongly-recommended', url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.4/docs/rules/no-spaces-around-equal-signs-in-attribute.md' }, fixable: 'whitespace', diff --git a/lib/rules/singleline-html-element-content-newline.js b/lib/rules/singleline-html-element-content-newline.js index 309f789d4..f444a9908 100644 --- a/lib/rules/singleline-html-element-content-newline.js +++ b/lib/rules/singleline-html-element-content-newline.js @@ -46,7 +46,7 @@ module.exports = { meta: { docs: { description: 'require a line break before and after the contents of a singleline element', - category: undefined, + category: 'strongly-recommended', url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.4/docs/rules/singleline-html-element-content-newline.md' }, fixable: 'whitespace', diff --git a/lib/rules/use-v-on-exact.js b/lib/rules/use-v-on-exact.js index 959dec01e..8291b9af0 100644 --- a/lib/rules/use-v-on-exact.js +++ b/lib/rules/use-v-on-exact.js @@ -18,7 +18,7 @@ module.exports = { meta: { docs: { description: 'enforce usage of `exact` modifier on `v-on`', - category: undefined, // essential + category: 'essential', url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.4/docs/rules/use-v-on-exact.md' }, fixable: null, From adb4a0db2c8e730c74c4134927b3646ac39274c5 Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 18 Nov 2018 13:03:34 +0100 Subject: [PATCH 0092/1248] Fix reporting issues from `executeOnFunctionsWithoutReturn` (#655) --- lib/utils/index.js | 6 +- tests/lib/rules/require-render-return.js | 78 ++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/lib/utils/index.js b/lib/utils/index.js index 9491117f6..cf58a0fce 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -685,8 +685,12 @@ module.exports = { node: null } + function isReachable (segment) { + return segment.reachable + } + function isValidReturn () { - if (!funcInfo.hasReturn) { + if (funcInfo.codePath.currentSegments.some(isReachable)) { return false } return !treatUndefinedAsUnspecified || funcInfo.hasReturnValue diff --git a/tests/lib/rules/require-render-return.js b/tests/lib/rules/require-render-return.js index 38132b287..e7fde4e60 100644 --- a/tests/lib/rules/require-render-return.js +++ b/tests/lib/rules/require-render-return.js @@ -70,6 +70,36 @@ ruleTester.run('require-render-return', rule, { }`, parserOptions }, + { + filename: 'test.vue', + code: `export default { + render() { + const foo = function () {} + return foo + } + }`, + parserOptions + }, + { + filename: 'test.vue', + code: `export default { + render() { + if (a) { + if (b) { + + } + if (c) { + return true + } else { + return foo + } + } else { + return foo + } + } + }`, + parserOptions + }, { filename: 'test.vue', code: `export default { @@ -119,6 +149,22 @@ ruleTester.run('require-render-return', rule, { line: 2 }] }, + { + filename: 'test.vue', + code: `export default { + render: function () { + if (foo) { + return h('div', 'hello') + } + } + }`, + parserOptions, + errors: [{ + message: 'Expected to return a value in render function.', + type: 'Identifier', + line: 2 + }] + }, { code: `Vue.component('test', { render: function () { @@ -133,6 +179,38 @@ ruleTester.run('require-render-return', rule, { type: 'Identifier', line: 2 }] + }, + { + code: `Vue.component('test2', { + render: function () { + if (a) { + return h('div', 'hello') + } + } + })`, + parserOptions, + errors: [{ + message: 'Expected to return a value in render function.', + type: 'Identifier', + line: 2 + }] + }, + { + code: `Vue.component('test2', { + render: function () { + if (a) { + + } else { + return h('div', 'hello') + } + } + })`, + parserOptions, + errors: [{ + message: 'Expected to return a value in render function.', + type: 'Identifier', + line: 2 + }] } ] }) From 5da94e1910653b3e34135d4ecf7e0d0df215331a Mon Sep 17 00:00:00 2001 From: ota Date: Sun, 18 Nov 2018 21:20:30 +0900 Subject: [PATCH 0093/1248] Update valid-v-bind.md (#660) --- docs/rules/valid-v-bind.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/rules/valid-v-bind.md b/docs/rules/valid-v-bind.md index dfc9091dd..bf3ecacf4 100644 --- a/docs/rules/valid-v-bind.md +++ b/docs/rules/valid-v-bind.md @@ -15,6 +15,8 @@ This rule does not report `v-bind` directives which do not have their argument ( This rule does not check syntax errors in directives because it's checked by [no-parsing-error] rule. +:-1: Examples of **incorrect** code for this rule: + ```html
From 07a7d9f6bc7dafe6db0bf8644f35109f3c4efd3c Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 18 Nov 2018 13:23:54 +0100 Subject: [PATCH 0094/1248] Fix: multiline-html-element-content-newline case sensitivity (#663) * Fix: multiline-html-element-content-newline case sensitivity fix issue #662 * fix typo in tests --- .../multiline-html-element-content-newline.js | 13 +++++-- .../multiline-html-element-content-newline.js | 34 ++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/rules/multiline-html-element-content-newline.js b/lib/rules/multiline-html-element-content-newline.js index c32db8e6c..659b76d3b 100644 --- a/lib/rules/multiline-html-element-content-newline.js +++ b/lib/rules/multiline-html-element-content-newline.js @@ -9,6 +9,7 @@ // ------------------------------------------------------------------------------ const utils = require('../utils') +const casing = require('../utils/casing') // ------------------------------------------------------------------------------ // Helpers @@ -20,7 +21,7 @@ function isMultilineElement (element) { function parseOptions (options) { return Object.assign({ - 'ignores': ['pre', 'textarea'] + ignores: ['pre', 'textarea'] }, options) } @@ -80,12 +81,18 @@ module.exports = { let inIgnoreElement + function isIgnoredElement (node) { + return ignores.includes(node.name) || + ignores.includes(casing.pascalCase(node.rawName)) || + ignores.includes(casing.kebabCase(node.rawName)) + } + return utils.defineTemplateBodyVisitor(context, { 'VElement' (node) { if (inIgnoreElement) { return } - if (ignores.indexOf(node.name) >= 0) { + if (isIgnoredElement(node)) { // ignore element name inIgnoreElement = node return @@ -114,7 +121,7 @@ module.exports = { }, messageId: 'unexpectedAfterClosingBracket', data: { - name: node.name, + name: node.rawName, actual: getPhrase(beforeLineBreaks) }, fix (fixer) { diff --git a/tests/lib/rules/multiline-html-element-content-newline.js b/tests/lib/rules/multiline-html-element-content-newline.js index c60fa513f..e653218e9 100644 --- a/tests/lib/rules/multiline-html-element-content-newline.js +++ b/tests/lib/rules/multiline-html-element-content-newline.js @@ -91,13 +91,45 @@ tester.run('multiline-html-element-content-newline', rule, { >content
content
- >content + content content `, options: [{ ignores: ['ignore-tag'] }] }, + { + code: ` + `, + options: [{ + ignores: ['IgnoreTag'] + }] + }, + { + code: ` + `, + options: [{ + ignores: ['IgnoreTag'] + }] + }, // Ignore if no closing brackets ` `, - errors: [{ - message: "'.sync' modifiers require the attribute value which is valid as LHS.", - line: 3, - column: 24, - endColumn: 47 - }] + errors: [ + { + message: + "'.sync' modifiers require the attribute value which is valid as LHS.", + line: 3, + column: 24, + endColumn: 47 + } + ] }, { filename: 'test.vue', @@ -156,12 +174,15 @@ tester.run('valid-v-bind-sync', rule, { `, - errors: [{ - message: "'.sync' modifiers aren't supported on non Vue-components.", - line: 3, - column: 18, - endColumn: 33 - }] + errors: [ + { + message: + "'.sync' modifiers aren't supported on non Vue-components.", + line: 3, + column: 18, + endColumn: 33 + } + ] }, { filename: 'test.vue', @@ -170,12 +191,15 @@ tester.run('valid-v-bind-sync', rule, { `, - errors: [{ - message: "'.sync' modifiers require the attribute value which is valid as LHS.", - line: 3, - column: 24, - endColumn: 41 - }] + errors: [ + { + message: + "'.sync' modifiers require the attribute value which is valid as LHS.", + line: 3, + column: 24, + endColumn: 41 + } + ] }, { filename: 'test.vue', @@ -184,12 +208,15 @@ tester.run('valid-v-bind-sync', rule, { `, - errors: [{ - message: "'.sync' modifiers require the attribute value which is valid as LHS.", - line: 3, - column: 24, - endColumn: 46 - }] + errors: [ + { + message: + "'.sync' modifiers require the attribute value which is valid as LHS.", + line: 3, + column: 24, + endColumn: 46 + } + ] }, { filename: 'test.vue', @@ -198,12 +225,15 @@ tester.run('valid-v-bind-sync', rule, { `, - errors: [{ - message: "'.sync' modifiers aren't supported on non Vue-components.", - line: 3, - column: 18, - endColumn: 39 - }] + errors: [ + { + message: + "'.sync' modifiers aren't supported on non Vue-components.", + line: 3, + column: 18, + endColumn: 39 + } + ] }, { filename: 'test.vue', @@ -214,12 +244,15 @@ tester.run('valid-v-bind-sync', rule, {
`, - errors: [{ - message: "'.sync' modifiers cannot update the iteration variable 'x' itself.", - line: 4, - column: 26, - endColumn: 39 - }] + errors: [ + { + message: + "'.sync' modifiers cannot update the iteration variable 'x' itself.", + line: 4, + column: 26, + endColumn: 39 + } + ] }, { filename: 'test.vue', @@ -230,12 +263,15 @@ tester.run('valid-v-bind-sync', rule, {
`, - errors: [{ - message: "'.sync' modifiers cannot update the iteration variable 'e' itself.", - line: 4, - column: 26, - endColumn: 45 - }] + errors: [ + { + message: + "'.sync' modifiers cannot update the iteration variable 'e' itself.", + line: 4, + column: 26, + endColumn: 45 + } + ] }, { filename: 'test.vue', @@ -250,10 +286,13 @@ tester.run('valid-v-bind-sync', rule, {
`, - errors: [{ - message: "'.sync' modifiers cannot update the iteration variable 'e1' itself.", - line: 6 - }] + errors: [ + { + message: + "'.sync' modifiers cannot update the iteration variable 'e1' itself.", + line: 6 + } + ] }, { filename: 'test.vue', @@ -264,10 +303,13 @@ tester.run('valid-v-bind-sync', rule, { `, - errors: [{ - message: "'.sync' modifiers cannot update the iteration variable 'index' itself.", - line: 4 - }] + errors: [ + { + message: + "'.sync' modifiers cannot update the iteration variable 'index' itself.", + line: 4 + } + ] }, { filename: 'test.vue', @@ -276,17 +318,23 @@ tester.run('valid-v-bind-sync', rule, {
`, - errors: ["'.sync' modifiers aren't supported on
non Vue-components."] + errors: [ + "'.sync' modifiers aren't supported on
non Vue-components." + ] }, { filename: 'test.vue', code: '', - errors: ["'.sync' modifiers require the attribute value which is valid as LHS."] + errors: [ + "'.sync' modifiers require the attribute value which is valid as LHS." + ] }, { filename: 'test.vue', code: '', - errors: ["'.sync' modifiers require the attribute value which is valid as LHS."] + errors: [ + "'.sync' modifiers require the attribute value which is valid as LHS." + ] } ] }) diff --git a/tests/lib/rules/valid-v-else-if.js b/tests/lib/rules/valid-v-else-if.js index b0c18093f..778d07339 100644 --- a/tests/lib/rules/valid-v-else-if.js +++ b/tests/lib/rules/valid-v-else-if.js @@ -29,11 +29,13 @@ tester.run('valid-v-else-if', rule, { }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', @@ -43,57 +45,82 @@ tester.run('valid-v-else-if', rule, { invalid: [ { filename: 'test.vue', - code: '', - errors: ["'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + code: + '', + errors: [ + "'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', code: '', - errors: ["'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + errors: [ + "'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', code: '', - errors: ["'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + errors: [ + "'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + code: + '', + errors: [ + "'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + code: + '', + errors: [ + "'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + code: + '', + errors: [ + "'v-else-if' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else-if' and 'v-if' directives can't exist on the same element."] + code: + '', + errors: [ + "'v-else-if' and 'v-if' directives can't exist on the same element." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else-if' and 'v-else' directives can't exist on the same element."] + code: + '', + errors: [ + "'v-else-if' and 'v-else' directives can't exist on the same element." + ] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["'v-else-if' directives require no argument."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["'v-else-if' directives require no modifier."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["'v-else-if' directives require that attribute value."] } ] diff --git a/tests/lib/rules/valid-v-else.js b/tests/lib/rules/valid-v-else.js index 7825e4dfb..1e235f9b5 100644 --- a/tests/lib/rules/valid-v-else.js +++ b/tests/lib/rules/valid-v-else.js @@ -29,11 +29,13 @@ tester.run('valid-v-else', rule, { }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', @@ -44,56 +46,79 @@ tester.run('valid-v-else', rule, { { filename: 'test.vue', code: '', - errors: ["'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + errors: [ + "'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', code: '', - errors: ["'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + errors: [ + "'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', code: '', - errors: ["'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + errors: [ + "'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', code: '', - errors: ["'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + errors: [ + "'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + code: + '', + errors: [ + "'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive."] + code: + '', + errors: [ + "'v-else' directives require being preceded by the element which has a 'v-if' or 'v-else-if' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else' and 'v-if' directives can't exist on the same element. You may want 'v-else-if' directives."] + code: + '', + errors: [ + "'v-else' and 'v-if' directives can't exist on the same element. You may want 'v-else-if' directives." + ] }, { filename: 'test.vue', - code: '', - errors: ["'v-else' and 'v-else-if' directives can't exist on the same element."] + code: + '', + errors: [ + "'v-else' and 'v-else-if' directives can't exist on the same element." + ] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["'v-else' directives require no argument."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["'v-else' directives require no modifier."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["'v-else' directives require no attribute value."] } ] diff --git a/tests/lib/rules/valid-v-for.js b/tests/lib/rules/valid-v-for.js index d83b634a3..74a1ea614 100644 --- a/tests/lib/rules/valid-v-for.js +++ b/tests/lib/rules/valid-v-for.js @@ -37,55 +37,68 @@ tester.run('valid-v-for', rule, { }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', - code: '' + code: + '' }, { filename: 'test.vue', @@ -134,92 +147,123 @@ tester.run('valid-v-for', rule, { }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Invalid alias ''."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Invalid alias ''."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Invalid alias ''."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Invalid alias '{b,c}'."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Invalid alias '{c,d}'."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Custom elements in iteration require 'v-bind:key' directives."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Custom elements in iteration require 'v-bind:key' directives."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Custom elements in iteration require 'v-bind:key' directives."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Custom elements in iteration require 'v-bind:key' directives."] }, { filename: 'test.vue', - code: '', - errors: ["Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."] + code: + '', + errors: [ + "Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."] + code: + '', + errors: [ + "Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."] + code: + '', + errors: [ + "Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."] + code: + '', + errors: [ + "Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive." + ] }, { filename: 'test.vue', - code: '', - errors: ["Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."] + code: + '', + errors: [ + "Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive." + ] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["Custom elements in iteration require 'v-bind:key' directives."] }, { filename: 'test.vue', - code: '', + code: + '', errors: ["'v-for' directives require that attribute value."] }, { filename: 'test.vue', - code: '', - errors: ["Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."] + code: + '', + errors: [ + "Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive." + ] }, { filename: 'test.vue', - errors: ["Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."], + errors: [ + "Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive." + ], code: ` ` + }, + // empty value + { + filename: 'empty-value.vue', + code: '', + errors: ["'v-for' directives require that attribute value."] } ] }) diff --git a/tests/lib/rules/valid-v-html.js b/tests/lib/rules/valid-v-html.js index 9a30bcf48..afb312f74 100644 --- a/tests/lib/rules/valid-v-html.js +++ b/tests/lib/rules/valid-v-html.js @@ -30,6 +30,16 @@ tester.run('valid-v-html', rule, { { filename: 'test.vue', code: '' + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '' + }, + // comment value (parsing error) + { + filename: 'comment-value.vue', + code: '' } ], invalid: [ @@ -47,6 +57,12 @@ tester.run('valid-v-html', rule, { filename: 'test.vue', code: '', errors: ["'v-html' directives require that attribute value."] + }, + // empty value + { + filename: 'empty-value.vue', + code: '', + errors: ["'v-html' directives require that attribute value."] } ] }) diff --git a/tests/lib/rules/valid-v-if.js b/tests/lib/rules/valid-v-if.js index effe04836..d3afe5780 100644 --- a/tests/lib/rules/valid-v-if.js +++ b/tests/lib/rules/valid-v-if.js @@ -30,6 +30,16 @@ tester.run('valid-v-if', rule, { { filename: 'test.vue', code: '' + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '' + }, + // comment value (parsing error) + { + filename: 'comment-value.vue', + code: '' } ], invalid: [ @@ -62,6 +72,12 @@ tester.run('valid-v-if', rule, { filename: 'test.vue', code: '', errors: ["'v-if' directives require that attribute value."] + }, + // empty value + { + filename: 'empty-value.vue', + code: '', + errors: ["'v-if' directives require that attribute value."] } ] }) diff --git a/tests/lib/rules/valid-v-model.js b/tests/lib/rules/valid-v-model.js index c9c28585a..9e78ef47a 100644 --- a/tests/lib/rules/valid-v-model.js +++ b/tests/lib/rules/valid-v-model.js @@ -150,6 +150,16 @@ tester.run('valid-v-model', rule, { filename: 'test.vue', code: '' + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '' + }, + // comment value (parsing error) + { + filename: 'comment-value.vue', + code: '' } ], invalid: [ @@ -216,6 +226,12 @@ tester.run('valid-v-model', rule, { errors: [ "'v-model' directives cannot update the iteration variable 'e' itself." ] + }, + // empty value + { + filename: 'empty-value.vue', + code: '', + errors: ["'v-model' directives require that attribute value."] } ] }) diff --git a/tests/lib/rules/valid-v-on.js b/tests/lib/rules/valid-v-on.js index 911039ea5..6f162e1df 100644 --- a/tests/lib/rules/valid-v-on.js +++ b/tests/lib/rules/valid-v-on.js @@ -96,6 +96,33 @@ tester.run('valid-v-on', rule, { filename: 'test.vue', code: '', options: [{ modifiers: ['bar', 'aaa'] }] + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '' + }, + // comment value (valid) + { + filename: 'comment-value.vue', + code: '' + }, + { + filename: 'comment-value.vue', + code: '' + }, + { + filename: 'comment-value.vue', + code: '' + }, + { + filename: 'comment-value.vue', + code: '' + }, + // empty value + { + filename: 'empty-value.vue', + code: '' } ], invalid: [ @@ -139,6 +166,14 @@ tester.run('valid-v-on', rule, { filename: 'test.vue', code: '', errors: ['Avoid using JavaScript keyword as "v-on" value: "delete".'] + }, + // empty value + { + filename: 'empty-value.vue', + code: '', + errors: [ + "'v-on' directives require a value or verb modifier (like 'stop' or 'prevent')." + ] } ] }) diff --git a/tests/lib/rules/valid-v-once.js b/tests/lib/rules/valid-v-once.js index 0c6a71a20..c9f3750c3 100644 --- a/tests/lib/rules/valid-v-once.js +++ b/tests/lib/rules/valid-v-once.js @@ -47,6 +47,24 @@ tester.run('valid-v-once', rule, { filename: 'test.vue', code: '', errors: ["'v-once' directives require no attribute value."] + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '', + errors: ["'v-once' directives require no attribute value."] + }, + // comment value + { + filename: 'comment-value.vue', + code: '', + errors: ["'v-once' directives require no attribute value."] + }, + // empty value + { + filename: 'comment-value.vue', + code: '', + errors: ["'v-once' directives require no attribute value."] } ] }) diff --git a/tests/lib/rules/valid-v-pre.js b/tests/lib/rules/valid-v-pre.js index ae9d38e6f..3d9c9d883 100644 --- a/tests/lib/rules/valid-v-pre.js +++ b/tests/lib/rules/valid-v-pre.js @@ -47,6 +47,24 @@ tester.run('valid-v-pre', rule, { filename: 'test.vue', code: '', errors: ["'v-pre' directives require no attribute value."] + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '', + errors: ["'v-pre' directives require no attribute value."] + }, + // comment value + { + filename: 'comment-value.vue', + code: '', + errors: ["'v-pre' directives require no attribute value."] + }, + // empty value + { + filename: 'empty-value.vue', + code: '', + errors: ["'v-pre' directives require no attribute value."] } ] }) diff --git a/tests/lib/rules/valid-v-show.js b/tests/lib/rules/valid-v-show.js index 0471ccd9f..4220e8749 100644 --- a/tests/lib/rules/valid-v-show.js +++ b/tests/lib/rules/valid-v-show.js @@ -30,6 +30,16 @@ tester.run('valid-v-show', rule, { { filename: 'test.vue', code: '' + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '' + }, + // comment value (parsing error) + { + filename: 'comment-value.vue', + code: '' } ], invalid: [ @@ -48,8 +58,9 @@ tester.run('valid-v-show', rule, { code: '', errors: ["'v-show' directives require that attribute value."] }, + // empty value { - filename: 'test.vue', + filename: 'empty-value.vue', code: '', errors: ["'v-show' directives require that attribute value."] } diff --git a/tests/lib/rules/valid-v-slot.js b/tests/lib/rules/valid-v-slot.js index ab8307fed..0043756f1 100644 --- a/tests/lib/rules/valid-v-slot.js +++ b/tests/lib/rules/valid-v-slot.js @@ -83,7 +83,13 @@ tester.run('valid-v-slot', rule, { - ` + `, + // parsing error + { + filename: 'parsing-error.vue', + code: + '' + } ], invalid: [ // Verify location. @@ -294,6 +300,26 @@ tester.run('valid-v-slot', rule, { `, errors: [{ messageId: 'requireAttributeValue' }] + }, + // comment value + { + filename: 'comment-value1.vue', + code: + '', + errors: [{ messageId: 'requireAttributeValue' }] + }, + { + filename: 'comment-value2.vue', + code: + '', + errors: [{ messageId: 'requireAttributeValue' }] + }, + // empty value + { + filename: 'empty-value.vue', + code: + '', + errors: [{ messageId: 'requireAttributeValue' }] } ] }) diff --git a/tests/lib/rules/valid-v-text.js b/tests/lib/rules/valid-v-text.js index 3956462ce..611b1a31a 100644 --- a/tests/lib/rules/valid-v-text.js +++ b/tests/lib/rules/valid-v-text.js @@ -34,6 +34,16 @@ tester.run('valid-v-text', rule, { { filename: 'test.vue', code: '' + }, + // parsing error + { + filename: 'parsing-error.vue', + code: '' + }, + // comment value (parsing error) + { + filename: 'parsing-error.vue', + code: '' } ], invalid: [ @@ -51,6 +61,12 @@ tester.run('valid-v-text', rule, { filename: 'test.vue', code: '', errors: ["'v-text' directives require that attribute value."] + }, + // empty value + { + filename: 'empty-value.vue', + code: '', + errors: ["'v-text' directives require that attribute value."] } ] }) From e5c835eb957340b153ea2047e3ba274b88ba01bb Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Fri, 5 Jun 2020 14:29:35 +0900 Subject: [PATCH 0346/1248] Add `vue/no-bare-strings-in-template` rule (#1185) --- docs/rules/README.md | 1 + docs/rules/no-bare-strings-in-template.md | 88 ++++++ lib/index.js | 1 + lib/rules/no-bare-strings-in-template.js | 279 +++++++++++++++++ lib/utils/regexp.js | 14 +- package.json | 2 + .../lib/rules/no-bare-strings-in-template.js | 290 ++++++++++++++++++ 7 files changed, 673 insertions(+), 2 deletions(-) create mode 100644 docs/rules/no-bare-strings-in-template.md create mode 100644 lib/rules/no-bare-strings-in-template.js create mode 100644 tests/lib/rules/no-bare-strings-in-template.js diff --git a/docs/rules/README.md b/docs/rules/README.md index f3e2bfdf6..55b3c4e0d 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -282,6 +282,7 @@ For example: | [vue/html-comment-content-spacing](./html-comment-content-spacing.md) | enforce unified spacing in HTML comments | :wrench: | | [vue/html-comment-indent](./html-comment-indent.md) | enforce consistent indentation in HTML comments | :wrench: | | [vue/match-component-file-name](./match-component-file-name.md) | require component name property to match its file name | | +| [vue/no-bare-strings-in-template](./no-bare-strings-in-template.md) | disallow the use of bare strings in ` `, - options: [{ ignoreWhenEmpty: false, ignoreWhenNoAttributes: false }], output: ` `, + options: [{ ignoreWhenEmpty: false, ignoreWhenNoAttributes: false }], errors: [ 'Expected 1 line break after opening tag (`
`), but no line breaks found.' ] @@ -473,13 +473,13 @@ singleline element
`, - options: [{ ignoreWhenEmpty: false, ignoreWhenNoAttributes: false }], output: ` `, + options: [{ ignoreWhenEmpty: false, ignoreWhenNoAttributes: false }], errors: [ 'Expected 1 line break after opening tag (`
`), but no line breaks found.' ] diff --git a/tests/lib/rules/space-in-parens.js b/tests/lib/rules/space-in-parens.js index 8791652ed..ef6fe628e 100644 --- a/tests/lib/rules/space-in-parens.js +++ b/tests/lib/rules/space-in-parens.js @@ -94,13 +94,13 @@ tester.run('space-in-parens', rule, { @click="foo(arg)" /> `, - options: ['always'], output: ` `, + options: ['always'], errors: [ errorMessage({ messageId: 'missingOpeningSpace', @@ -143,13 +143,13 @@ tester.run('space-in-parens', rule, { :value="(1 + 2) + 3" > `, - options: ['always'], output: ` `, + options: ['always'], errors: [ errorMessage({ messageId: 'missingOpeningSpace', @@ -192,13 +192,13 @@ tester.run('space-in-parens', rule, { :[(1+2)]="(1 + 2) + 3" > `, - options: ['always'], output: ` `, + options: ['always'], errors: [ errorMessage({ messageId: 'missingOpeningSpace', diff --git a/tests/lib/rules/space-unary-ops.js b/tests/lib/rules/space-unary-ops.js index 6b3e7c25f..63539a5a7 100644 --- a/tests/lib/rules/space-unary-ops.js +++ b/tests/lib/rules/space-unary-ops.js @@ -50,8 +50,8 @@ tester.run('space-unary-ops', rule, { }, { code: '', - options: [{ nonwords: true }], output: '', + options: [{ nonwords: true }], errors: ["Unary operator '!' must be followed by whitespace."] }, diff --git a/tests/lib/rules/template-curly-spacing.js b/tests/lib/rules/template-curly-spacing.js index 6c4376969..0fe530511 100644 --- a/tests/lib/rules/template-curly-spacing.js +++ b/tests/lib/rules/template-curly-spacing.js @@ -41,14 +41,13 @@ tester.run('template-curly-spacing', rule, { }, // CSS vars injection - { - code: ` + ` ` - } + + ` ], invalid: [ { @@ -79,12 +78,12 @@ tester.run('template-curly-spacing', rule, {
`, - options: ['always'], output: ` `, + options: ['always'], errors: [ { message: "Expected space(s) after '${'.", diff --git a/tests/lib/rules/this-in-template.js b/tests/lib/rules/this-in-template.js index 904aa00c4..5686bf137 100644 --- a/tests/lib/rules/this-in-template.js +++ b/tests/lib/rules/this-in-template.js @@ -248,14 +248,14 @@ ruleTester.run('this-in-template', rule, { { code: ``, output: ``, - errors: ["Unexpected usage of 'this'."], - options: ['never'] + options: ['never'], + errors: ["Unexpected usage of 'this'."] }, { code: ``, output: ``, - errors: ["Unexpected usage of 'this'."], - options: ['never'] + options: ['never'], + errors: ["Unexpected usage of 'this'."] } ] }) diff --git a/tests/lib/rules/use-v-on-exact.js b/tests/lib/rules/use-v-on-exact.js index 73ac2408b..929fd746a 100644 --- a/tests/lib/rules/use-v-on-exact.js +++ b/tests/lib/rules/use-v-on-exact.js @@ -15,92 +15,48 @@ const ruleTester = new RuleTester({ ruleTester.run('use-v-on-exact', rule, { valid: [ - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: `` - }, - { - code: ` + ` ], invalid: [ diff --git a/tests/lib/rules/v-bind-style.js b/tests/lib/rules/v-bind-style.js index 2fd1ce7c2..0cb67f62f 100644 --- a/tests/lib/rules/v-bind-style.js +++ b/tests/lib/rules/v-bind-style.js @@ -67,44 +67,44 @@ tester.run('v-bind-style', rule, { }, { filename: 'test.vue', - options: ['shorthand'], code: '', output: '', + options: ['shorthand'], errors: ["Unexpected 'v-bind' before ':'."] }, { filename: 'test.vue', - options: ['longform'], code: '', output: '', + options: ['longform'], errors: ["Expected 'v-bind' before ':'."] }, { filename: 'test.vue', - options: ['longform'], code: '', output: '', + options: ['longform'], errors: ["Expected 'v-bind:' instead of '.'."] }, { filename: 'test.vue', - options: ['longform'], code: '', output: '', + options: ['longform'], errors: ["Expected 'v-bind:' instead of '.'."] }, { filename: 'test.vue', - options: ['longform'], code: '', output: '', + options: ['longform'], errors: ["Expected 'v-bind:' instead of '.'."] }, { filename: 'test.vue', - options: ['longform'], code: '', output: '', + options: ['longform'], errors: ["Expected 'v-bind:' instead of '.'."] } ] diff --git a/tests/lib/rules/v-for-delimiter-style.js b/tests/lib/rules/v-for-delimiter-style.js index b1500af50..23665a32c 100644 --- a/tests/lib/rules/v-for-delimiter-style.js +++ b/tests/lib/rules/v-for-delimiter-style.js @@ -94,9 +94,9 @@ tester.run('v-for-delimiter-style', rule, { }, { filename: 'test.vue', - options: ['in'], code: '', output: '', + options: ['in'], errors: [ { message: "Expected 'in' instead of 'of' in 'v-for'.", @@ -106,9 +106,9 @@ tester.run('v-for-delimiter-style', rule, { }, { filename: 'test.vue', - options: ['of'], code: '', output: '', + options: ['of'], errors: [ { message: "Expected 'of' instead of 'in' in 'v-for'.", diff --git a/tests/lib/rules/v-on-event-hyphenation.js b/tests/lib/rules/v-on-event-hyphenation.js index 087e5d00a..beaa5e3fa 100644 --- a/tests/lib/rules/v-on-event-hyphenation.js +++ b/tests/lib/rules/v-on-event-hyphenation.js @@ -73,12 +73,12 @@ tester.run('v-on-event-hyphenation', rule, { `, - options: ['always', { autofix: true }], output: ` `, + options: ['always', { autofix: true }], errors: [ { message: "v-on event '@customEvent' must be hyphenated.", @@ -95,12 +95,12 @@ tester.run('v-on-event-hyphenation', rule, { `, - options: ['never', { autofix: true }], output: ` `, + options: ['never', { autofix: true }], errors: ["v-on event 'v-on:custom-event' can't be hyphenated."] }, { @@ -110,13 +110,13 @@ tester.run('v-on-event-hyphenation', rule, { `, - options: ['always', { autofix: true }], output: ` `, + options: ['always', { autofix: true }], errors: ["v-on event '@update:modelValue' must be hyphenated."] }, { @@ -126,13 +126,13 @@ tester.run('v-on-event-hyphenation', rule, { `, - options: ['never', { autofix: true }], output: ` `, + options: ['never', { autofix: true }], errors: ["v-on event '@update:model-value' can't be hyphenated."] }, { @@ -144,7 +144,6 @@ tester.run('v-on-event-hyphenation', rule, { `, - options: ['always', { autofix: true }], output: ` `, + options: ['always', { autofix: true }], errors: [ "v-on event '@upDate:modelValue' must be hyphenated.", "v-on event '@up-date:modelValue' must be hyphenated.", @@ -168,7 +168,6 @@ tester.run('v-on-event-hyphenation', rule, { `, - options: ['never', { autofix: true }], output: ` `, + options: ['never', { autofix: true }], errors: [ "v-on event '@up-date:modelValue' can't be hyphenated.", "v-on event '@upDate:model-value' can't be hyphenated.", diff --git a/tests/lib/rules/v-on-function-call.js b/tests/lib/rules/v-on-function-call.js index d8486a448..d06bbe231 100644 --- a/tests/lib/rules/v-on-function-call.js +++ b/tests/lib/rules/v-on-function-call.js @@ -161,37 +161,37 @@ tester.run('v-on-function-call', rule, { filename: 'test.vue', code: '', output: null, + options: ['always'], errors: [ "Method calls inside of 'v-on' directives must have parentheses." - ], - options: ['always'] + ] }, { filename: 'test.vue', code: '', output: ``, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', code: '', output: ``, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', code: '', output: null, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -204,13 +204,13 @@ tester.run('v-on-function-call', rule, { ">
`, output: null, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses.", "Method calls without arguments inside of 'v-on' directives must not have parentheses.", "Method calls without arguments inside of 'v-on' directives must not have parentheses.", "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -222,10 +222,10 @@ tester.run('v-on-function-call', rule, { `, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -237,10 +237,10 @@ tester.run('v-on-function-call', rule, { `, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -254,11 +254,11 @@ tester.run('v-on-function-call', rule, {
`, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses.", "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -270,10 +270,10 @@ tester.run('v-on-function-call', rule, { `, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -285,19 +285,19 @@ tester.run('v-on-function-call', rule, { `, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', code: '', output: '', + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -319,10 +319,10 @@ tester.run('v-on-function-call', rule, { } } `, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] }, { filename: 'test.vue', @@ -344,10 +344,10 @@ tester.run('v-on-function-call', rule, { } } `, + options: ['never'], errors: [ "Method calls without arguments inside of 'v-on' directives must not have parentheses." - ], - options: ['never'] + ] } ] }) diff --git a/tests/lib/rules/v-on-handler-style.js b/tests/lib/rules/v-on-handler-style.js index e3afd05d5..314bbf8c8 100644 --- a/tests/lib/rules/v-on-handler-style.js +++ b/tests/lib/rules/v-on-handler-style.js @@ -78,12 +78,12 @@ tester.run('v-on-handler-style', rule, {