diff --git a/docs/rules/README.md b/docs/rules/README.md
index 4492988e4..0f39db375 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -315,9 +315,16 @@ The following rules extend the rules provided by ESLint itself and apply them to
| Rule ID | Replaced by |
|:--------|:------------|
-| [vue/experimental-script-setup-vars](./experimental-script-setup-vars.md) | (no replacement) |
-| [vue/name-property-casing](./name-property-casing.md) | [vue/component-definition-name-casing](./component-definition-name-casing.md) |
-| [vue/no-confusing-v-for-v-if](./no-confusing-v-for-v-if.md) | [vue/no-use-v-if-with-v-for](./no-use-v-if-with-v-for.md) |
| [vue/no-invalid-model-keys](./no-invalid-model-keys.md) | [vue/valid-model-definition](./valid-model-definition.md) |
-| [vue/no-unregistered-components](./no-unregistered-components.md) | [vue/no-undef-components](./no-undef-components.md) |
| [vue/script-setup-uses-vars](./script-setup-uses-vars.md) | (no replacement) |
+
+## Removed
+
+- :no_entry_sign: These rules have been removed in a previous major release, after they have been deprecated for a while.
+
+| Rule ID | Replaced by | Deprecated in version | Removed in version |
+|:--------|:------------|:-----------------------|:-------------------|
+| [vue/experimental-script-setup-vars](./experimental-script-setup-vars.md) | (no replacement) | [v7.13.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v7.13.0) | [v9.0.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v9.0.0) |
+| [vue/name-property-casing](./name-property-casing.md) | [vue/component-definition-name-casing](./component-definition-name-casing.md) | [v7.0.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v7.0.0) | [v9.0.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v9.0.0) |
+| [vue/no-confusing-v-for-v-if](./no-confusing-v-for-v-if.md) | [vue/no-use-v-if-with-v-for](./no-use-v-if-with-v-for.md) | [v5.0.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v5.0.0) | [v9.0.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v9.0.0) |
+| [vue/no-unregistered-components](./no-unregistered-components.md) | [vue/no-undef-components](./no-undef-components.md) | [v8.4.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v8.4.0) | [v9.0.0](https://github.com/vuejs/eslint-plugin-vue/releases/tag/v9.0.0) |
diff --git a/docs/rules/experimental-script-setup-vars.md b/docs/rules/experimental-script-setup-vars.md
index d13710246..7a77d941d 100644
--- a/docs/rules/experimental-script-setup-vars.md
+++ b/docs/rules/experimental-script-setup-vars.md
@@ -9,11 +9,7 @@ since: v7.0.0
> prevent variables defined in ``,
- `
- `,
- `
- `,
- `
-
-
- `
- ],
- invalid: [
- {
- code: `
-
- `,
- errors: [
- {
- message: 'Parsing error.',
- line: 2
- }
- ]
- }
- ]
-})
diff --git a/tests/lib/rules/name-property-casing.js b/tests/lib/rules/name-property-casing.js
deleted file mode 100644
index a7a8d41cc..000000000
--- a/tests/lib/rules/name-property-casing.js
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * @fileoverview Define a style for the name property casing for consistency purposes
- * @author Armano
- */
-'use strict'
-
-// ------------------------------------------------------------------------------
-// Requirements
-// ------------------------------------------------------------------------------
-
-const rule = require('../../../lib/rules/name-property-casing')
-const RuleTester = require('eslint').RuleTester
-
-// ------------------------------------------------------------------------------
-// Tests
-// ------------------------------------------------------------------------------
-
-const parserOptions = {
- ecmaVersion: 2018,
- sourceType: 'module'
-}
-
-const ruleTester = new RuleTester()
-ruleTester.run('name-property-casing', rule, {
- valid: [
- {
- filename: 'test.vue',
- code: `
- export default {
- }
- `,
- parserOptions
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- ...name
- }
- `,
- parserOptions
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'FooBar'
- }
- `,
- parserOptions
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'FooBar'
- }
- `,
- options: ['PascalCase'],
- parserOptions
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'foo-bar'
- }
- `,
- options: ['kebab-case'],
- parserOptions
- }
- ],
-
- invalid: [
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'foo-bar'
- }
- `,
- output: `
- export default {
- name: 'FooBar'
- }
- `,
- parserOptions,
- errors: [
- {
- message: 'Property name "foo-bar" is not PascalCase.',
- type: 'Literal',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'foo bar'
- }
- `,
- output: null,
- parserOptions,
- errors: [
- {
- message: 'Property name "foo bar" is not PascalCase.',
- type: 'Literal',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'foo!bar'
- }
- `,
- output: null,
- parserOptions,
- errors: [
- {
- message: 'Property name "foo!bar" is not PascalCase.',
- type: 'Literal',
- line: 3
- }
- ]
- },
- {
- filename: 'test.js',
- code: `
- new Vue({
- name: 'foo!bar'
- })
- `,
- output: null,
- parserOptions: { ecmaVersion: 6 },
- errors: [
- {
- message: 'Property name "foo!bar" is not PascalCase.',
- type: 'Literal',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'foo_bar'
- }
- `,
- output: `
- export default {
- name: 'FooBar'
- }
- `,
- parserOptions,
- errors: [
- {
- message: 'Property name "foo_bar" is not PascalCase.',
- type: 'Literal',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'foo_bar'
- }
- `,
- output: `
- export default {
- name: 'FooBar'
- }
- `,
- options: ['PascalCase'],
- parserOptions,
- errors: [
- {
- message: 'Property name "foo_bar" is not PascalCase.',
- type: 'Literal',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
- export default {
- name: 'foo_bar'
- }
- `,
- output: `
- export default {
- name: 'foo-bar'
- }
- `,
- options: ['kebab-case'],
- parserOptions,
- errors: [
- {
- message: 'Property name "foo_bar" is not kebab-case.',
- type: 'Literal',
- line: 3
- }
- ]
- }
- ]
-})
diff --git a/tests/lib/rules/no-confusing-v-for-v-if.js b/tests/lib/rules/no-confusing-v-for-v-if.js
deleted file mode 100644
index 47959aeb4..000000000
--- a/tests/lib/rules/no-confusing-v-for-v-if.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @author Toru Nagashima
- * @copyright 2017 Toru Nagashima. All rights reserved.
- * See LICENSE file in root directory for full license.
- */
-'use strict'
-
-// ------------------------------------------------------------------------------
-// Requirements
-// ------------------------------------------------------------------------------
-
-const RuleTester = require('eslint').RuleTester
-const rule = require('../../../lib/rules/no-confusing-v-for-v-if')
-
-// ------------------------------------------------------------------------------
-// Tests
-// ------------------------------------------------------------------------------
-
-const tester = new RuleTester({
- parser: require.resolve('vue-eslint-parser'),
- parserOptions: { ecmaVersion: 2015 }
-})
-
-tester.run('no-confusing-v-for-v-if', 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: ["This 'v-if' should be moved to the wrapper element."]
- },
- {
- filename: 'test.vue',
- code: '',
- errors: ["This 'v-if' should be moved to the wrapper element."]
- }
- ]
-})
diff --git a/tests/lib/rules/no-unregistered-components.js b/tests/lib/rules/no-unregistered-components.js
deleted file mode 100644
index f120cde81..000000000
--- a/tests/lib/rules/no-unregistered-components.js
+++ /dev/null
@@ -1,777 +0,0 @@
-/**
- * @fileoverview Report used components that are not registered
- * @author Jesús Ángel González Novez
- */
-'use strict'
-
-// ------------------------------------------------------------------------------
-// Requirements
-// ------------------------------------------------------------------------------
-
-const RuleTester = require('eslint').RuleTester
-const rule = require('../../../lib/rules/no-unregistered-components')
-
-// ------------------------------------------------------------------------------
-// Tests
-// ------------------------------------------------------------------------------
-
-const tester = new RuleTester({
- parser: require.resolve('vue-eslint-parser'),
- parserOptions: {
- ecmaVersion: 2018,
- sourceType: 'module'
- }
-})
-
-tester.run('no-unregistered-components', rule, {
- valid: [
- {
- filename: 'test.vue',
- code: `
-
- Lorem ipsum
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
- `,
- options: [
- {
- ignorePatterns: ['custom(\\-\\w+)+']
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
- `,
- options: [
- {
- ignorePatterns: ['custom(\\-\\w+)+']
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
- `,
- options: [
- {
- ignorePatterns: ['custom(\\-\\w+)+']
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
- `,
- options: [
- {
- ignorePatterns: ['Custom(\\w+)+']
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
- `,
- options: [
- {
- ignorePatterns: ['Custom(\\w+)+']
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
- `,
- options: [
- {
- ignorePatterns: ['Custom(\\w+)+']
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Text
-
-
-
- `,
- options: [
- {
- ignorePatterns: ['Custom(\\w+)+', 'Warm(\\w+)+', 'InfoBtn(\\w+)+']
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Text
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Text
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- Text
-
-
-
-
- Text
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
-
- Text
-
-
-
-
- Text
-
-
-
-
- foo
-
-
- `
- },
- {
- 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: `
-
-
-
- Text
-
-
-
-
- `
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `
- }
- ],
- invalid: [
- {
- filename: 'test.vue',
- code: `
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
- `,
- options: [
- {
- ignorePatterns: ['custom(\\-\\w+)+']
- }
- ],
- errors: [
- {
- message:
- 'The "WarmButton" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
- `,
- options: [
- {
- ignorePatterns: ['custom(\\-\\w+)+']
- }
- ],
- errors: [
- {
- message:
- 'The "WarmButton" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
- Some text
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponent" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
- Text
-
-
-
- `,
- errors: [
- {
- message:
- 'The "CustomComponentWithNamedSlots" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `,
- errors: [
- {
- message: 'The "foo" component has been used but not registered.',
- line: 3
- }
- ]
- },
- {
- filename: 'test.vue',
- code: `
-
-
-
-
- `,
- errors: [
- {
- message: 'The "foo" component has been used but not registered.',
- line: 3
- }
- ]
- }
- ]
-})
diff --git a/tests/lib/script-setup.js b/tests/lib/script-setup.js
deleted file mode 100644
index ad7409dcb..000000000
--- a/tests/lib/script-setup.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @author Yosuke Ota
- * See LICENSE file in root directory for full license.
- */
-'use strict'
-
-const Linter = require('eslint').Linter
-const parser = require('vue-eslint-parser')
-const assert = require('assert')
-const experimentalScriptSetupVars = require('../../lib/rules/experimental-script-setup-vars')
-
-const baseConfig = {
- parser: 'vue-eslint-parser',
- parserOptions: {
- ecmaVersion: 2020,
- sourceType: 'module'
- }
-}
-
-describe('script-setup test cases', () => {
- const linter = new Linter()
- linter.defineParser('vue-eslint-parser', parser)
- linter.defineRule(
- 'vue/experimental-script-setup-vars',
- experimentalScriptSetupVars
- )
-
- describe('temporary supports.', () => {
- const config = Object.assign({}, baseConfig, {
- globals: { console: false },
- rules: {
- 'vue/experimental-script-setup-vars': 'error',
- 'no-undef': 'error'
- }
- })
-
- it('should not be marked.', () => {
- const code = `
- `
- const messages = linter.verify(code, config, 'test.vue')
- assert.deepStrictEqual(messages, [])
- })
- })
-})
diff --git a/tools/update-docs-rules-index.js b/tools/update-docs-rules-index.js
index 27ab06979..3db26c36b 100644
--- a/tools/update-docs-rules-index.js
+++ b/tools/update-docs-rules-index.js
@@ -8,6 +8,7 @@ const fs = require('fs')
const path = require('path')
const rules = require('./lib/rules')
const { getPresetIds, formatItems } = require('./lib/utils')
+const removedRules = require('../lib/removed-rules')
const VUE3_EMOJI = ':three:'
const VUE2_EMOJI = ':two:'
@@ -62,6 +63,22 @@ function toDeprecatedRuleRow(rule) {
return `| ${link} | ${replacedBy || '(no replacement)'} |`
}
+function toRemovedRuleRow({
+ ruleName,
+ replacedBy,
+ deprecatedInVersion,
+ removedInVersion
+}) {
+ const link = `[vue/${ruleName}](./${ruleName}.md)`
+ const replacement =
+ replacedBy.map((name) => `[vue/${name}](./${name}.md)`).join(', ') ||
+ '(no replacement)'
+ const deprecatedVersionLink = `[${deprecatedInVersion}](https://github.com/vuejs/eslint-plugin-vue/releases/tag/${deprecatedInVersion})`
+ const removedVersionLink = `[${removedInVersion}](https://github.com/vuejs/eslint-plugin-vue/releases/tag/${removedInVersion})`
+
+ return `| ${link} | ${replacement} | ${deprecatedVersionLink} | ${removedVersionLink} |`
+}
+
const categoryGroups = [
{
title: 'Base Rules (Enabling Correct ESLint Parsing)',
@@ -217,6 +234,17 @@ ${deprecatedRules.map(toDeprecatedRuleRow).join('\n')}
`
}
+// -----------------------------------------------------------------------------
+rulesTableContent += `
+## Removed
+
+- :no_entry_sign: These rules have been removed in a previous major release, after they have been deprecated for a while.
+
+| Rule ID | Replaced by | Deprecated in version | Removed in version |
+|:--------|:------------|:-----------------------|:-------------------|
+${removedRules.map(toRemovedRuleRow).join('\n')}
+`
+
// -----------------------------------------------------------------------------
const readmeFilePath = path.resolve(__dirname, '../docs/rules/README.md')
fs.writeFileSync(
diff --git a/tools/update-docs.js b/tools/update-docs.js
index 80211d278..75f6dab6d 100644
--- a/tools/update-docs.js
+++ b/tools/update-docs.js
@@ -21,6 +21,7 @@ For example:
const fs = require('fs')
const path = require('path')
const rules = require('./lib/rules')
+const removedRules = require('../lib/removed-rules')
const { getPresetIds, formatItems } = require('./lib/utils')
const ROOT = path.resolve(__dirname, '../docs/rules')
@@ -82,10 +83,28 @@ class DocFile {
updateHeader() {
const { ruleId, meta } = this.rule
- const title = `# ${ruleId}\n\n> ${meta.docs.description}`
+ const description = meta.docs
+ ? meta.docs.description
+ : this.content.match(/^description: (.*)$/m)[1]
+ const title = `# ${ruleId}\n\n> ${description}`
const notes = []
- if (meta.deprecated) {
+ if (meta.removedInVersion) {
+ if (meta.replacedBy.length > 0) {
+ const replacedRules = meta.replacedBy.map(
+ (name) => `[vue/${name}](${name}.md) rule`
+ )
+ notes.push(
+ `- :no_entry_sign: This rule was **removed** in eslint-plugin-vue ${
+ meta.removedInVersion
+ } and replaced by ${formatItems(replacedRules)}.`
+ )
+ } else {
+ notes.push(
+ `- :no_entry_sign: This rule was **removed** in eslint-plugin-vue ${meta.removedInVersion}.`
+ )
+ }
+ } else if (meta.deprecated) {
if (meta.replacedBy) {
const replacedRules = meta.replacedBy.map(
(name) => `[vue/${name}](${name}.md) rule`
@@ -255,3 +274,15 @@ for (const rule of rules) {
.checkHeadings()
.checkGoodBadSymbols()
}
+
+for (const { ruleName, replacedBy, removedInVersion } of removedRules) {
+ const rule = {
+ name: ruleName,
+ ruleId: `vue/${ruleName}`,
+ meta: {
+ replacedBy,
+ removedInVersion
+ }
+ }
+ DocFile.read(rule).updateHeader().write()
+}