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: ` - - ` - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - { - ignorePatterns: ['custom(\\-\\w+)+'] - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - { - ignorePatterns: ['custom(\\-\\w+)+'] - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - { - ignorePatterns: ['custom(\\-\\w+)+'] - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - { - ignorePatterns: ['Custom(\\w+)+'] - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - { - ignorePatterns: ['Custom(\\w+)+'] - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - { - ignorePatterns: ['Custom(\\w+)+'] - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - { - ignorePatterns: ['Custom(\\w+)+', 'Warm(\\w+)+', 'InfoBtn(\\w+)+'] - } - ] - }, - { - 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: ` - - ` - }, - { - 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: ` - - - ` - }, - { - 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: [ - { - 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: ` - - `, - 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: ` - - - `, - 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: ` - - - `, - 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: ` - - `, - 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() +}