From 0ee35d3bd296a87465fb39e69adaf892557cc7cb Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Mon, 6 Sep 2021 08:21:49 +0900 Subject: [PATCH 001/638] Update indent rule to support Class static block and typescript-eslint v5(rc) (#1619) * Update indent rule to support typescript-eslint v5 * Update ts-static-block-01.vue * static block to es * fix job * ignore cache * use cache * ignore cache * use cache * remove cache --- .circleci/config.yml | 53 ++++++-- lib/utils/indent-common.js | 11 ++ lib/utils/indent-ts.js | 116 +++++++++++++++--- package.json | 2 +- .../ts-abstract-class-property-02.vue | 10 +- .../script-indent/ts-static-block-01.vue | 8 ++ .../script-indent/ts-type-annotation-03.vue | 13 +- typings/eslint-plugin-vue/global.d.ts | 1 + .../eslint-plugin-vue/util-types/ast/ast.ts | 2 + .../util-types/ast/es-ast.ts | 14 ++- 10 files changed, 187 insertions(+), 43 deletions(-) create mode 100644 tests/fixtures/script-indent/ts-static-block-01.vue diff --git a/.circleci/config.yml b/.circleci/config.yml index b80032ae8..7d8f4bcde 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,6 +6,7 @@ workflows: - node-v10 - eslint-v7 - eslint-v8 + - ts-eslint-v4 - node-v12 - node-v14 - lint @@ -20,19 +21,19 @@ jobs: name: Versions command: npm version - checkout - - restore_cache: - keys: - - v2-npm-lock-{{ .Branch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package.json" }} + # - restore_cache: + # keys: + # - v2-npm-lock-{{ .Branch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package.json" }} - run: name: Install dependencies command: npm install - - save_cache: - key: v2-npm-lock-{{ .Branch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package.json" }} - paths: - - node_modules - run: name: Test command: npm test + # - save_cache: + # key: v2-npm-lock-{{ .Branch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package.json" }} + # paths: + # - node_modules node-v8: docker: @@ -53,9 +54,23 @@ jobs: name: Test command: npm test node-v10: - <<: *node-base docker: - image: node:10 + steps: + - run: + name: Versions + command: npm version + - checkout + - run: + name: Install @typescript-eslint/parser@4 + command: | + npm install @typescript-eslint/parser@^4 + - run: + name: Install dependencies + command: npm install + - run: + name: Test + command: npm test eslint-v7: docker: - image: node:10 @@ -67,7 +82,7 @@ jobs: - run: name: Install eslint@7 command: | - npm install --save-exact eslint@7 + npm install eslint@7 - run: name: Install dependencies command: npm install @@ -85,7 +100,25 @@ jobs: - run: name: Install eslint@8 command: | - npm install --save-exact eslint@^8.0.0-0 + npm install eslint@^8.0.0-0 + - run: + name: Install dependencies + command: npm install + - run: + name: Test + command: npm test + ts-eslint-v4: + docker: + - image: node:14 + steps: + - run: + name: Versions + command: npm version + - checkout + - run: + name: Install @typescript-eslint/parser@4 + command: | + npm install @typescript-eslint/parser@^4 - run: name: Install dependencies command: npm install diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index a4d0dbcfd..39ef58670 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -16,6 +16,7 @@ const { isNotClosingParenToken, isOpeningBraceToken, isClosingBraceToken, + isNotOpeningBraceToken, isOpeningBracketToken, isClosingBracketToken, isSemicolonToken @@ -1150,6 +1151,16 @@ module.exports.defineVisitor = function create( 1 ) }, + StaticBlock(node) { + const firstToken = tokenStore.getFirstToken(node) + let next = tokenStore.getTokenAfter(firstToken) + while (next && isNotOpeningBraceToken(next)) { + setOffset(next, 0, firstToken) + next = tokenStore.getTokenAfter(next) + } + setOffset(next, 0, firstToken) + processNodeList(node.body, next, tokenStore.getLastToken(node), 1) + }, /** @param {BreakStatement | ContinueStatement | ReturnStatement | ThrowStatement} node */ 'BreakStatement, ContinueStatement, ReturnStatement, ThrowStatement'(node) { if ( diff --git a/lib/utils/indent-ts.js b/lib/utils/indent-ts.js index 9afcdb34f..ed2080750 100644 --- a/lib/utils/indent-ts.js +++ b/lib/utils/indent-ts.js @@ -27,7 +27,7 @@ const { * @typedef {import('@typescript-eslint/types').TSESTree.TSConstructSignatureDeclaration} TSConstructSignatureDeclaration * @typedef {import('@typescript-eslint/types').TSESTree.TSImportEqualsDeclaration} TSImportEqualsDeclaration * @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractMethodDefinition} TSAbstractMethodDefinition - * @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractClassProperty} TSAbstractClassProperty + * @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractPropertyDefinition} TSAbstractPropertyDefinition * @typedef {import('@typescript-eslint/types').TSESTree.TSEnumMember} TSEnumMember * @typedef {import('@typescript-eslint/types').TSESTree.TSPropertySignature} TSPropertySignature * @typedef {import('@typescript-eslint/types').TSESTree.TSIndexSignature} TSIndexSignature @@ -50,12 +50,13 @@ const { * @typedef {import('@typescript-eslint/types').TSESTree.TSOptionalType} TSOptionalType * @typedef {import('@typescript-eslint/types').TSESTree.TSNonNullExpression} TSNonNullExpression * @typedef {import('@typescript-eslint/types').TSESTree.JSXChild} JSXChild + * @typedef {import('@typescript-eslint/types').TSESTree.TypeNode} TypeNode * */ /** - * Perhaps this node will be deprecated in the future. - * It was present in @typescript-eslint/parser@4.1.0. - * @typedef {import('@typescript-eslint/types').TSESTree.ClassProperty} ClassProperty + * Deprecated in @typescript-eslint/parser v5 + * @typedef {import('@typescript-eslint/types').TSESTree.PropertyDefinition} ClassProperty + * @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractPropertyDefinition} TSAbstractClassProperty */ module.exports = { @@ -203,6 +204,7 @@ function defineVisitor({ * | TSConstructSignatureDeclaration * | TSImportEqualsDeclaration * | TSAbstractMethodDefinition + * | TSAbstractPropertyDefinition * | TSAbstractClassProperty * | TSEnumMember * | ClassProperty @@ -211,10 +213,80 @@ function defineVisitor({ * | TSMethodSignature} node */ ['TSTypeAliasDeclaration, TSCallSignatureDeclaration, TSConstructSignatureDeclaration, TSImportEqualsDeclaration,' + - 'TSAbstractMethodDefinition, TSAbstractClassProperty, TSEnumMember, ClassProperty,' + - 'TSPropertySignature, TSIndexSignature, TSMethodSignature'](node) { + 'TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSEnumMember,' + + 'TSPropertySignature, TSIndexSignature, TSMethodSignature,' + + // Deprecated in @typescript-eslint/parser v5 + 'ClassProperty, TSAbstractClassProperty'](node) { processSemicolons(node) }, + /** + * @param {TSESTreeNode} node + */ + // eslint-disable-next-line complexity -- ignore + '*[type=/^TS/]'(node) { + if ( + node.type !== 'TSAnyKeyword' && + node.type !== 'TSArrayType' && + node.type !== 'TSBigIntKeyword' && + node.type !== 'TSBooleanKeyword' && + node.type !== 'TSConditionalType' && + node.type !== 'TSConstructorType' && + node.type !== 'TSFunctionType' && + node.type !== 'TSImportType' && + node.type !== 'TSIndexedAccessType' && + node.type !== 'TSInferType' && + node.type !== 'TSIntersectionType' && + node.type !== 'TSIntrinsicKeyword' && + node.type !== 'TSLiteralType' && + node.type !== 'TSMappedType' && + node.type !== 'TSNamedTupleMember' && + node.type !== 'TSNeverKeyword' && + node.type !== 'TSNullKeyword' && + node.type !== 'TSNumberKeyword' && + node.type !== 'TSObjectKeyword' && + node.type !== 'TSOptionalType' && + node.type !== 'TSRestType' && + node.type !== 'TSStringKeyword' && + node.type !== 'TSSymbolKeyword' && + node.type !== 'TSTemplateLiteralType' && + node.type !== 'TSThisType' && + node.type !== 'TSTupleType' && + node.type !== 'TSTypeLiteral' && + node.type !== 'TSTypeOperator' && + node.type !== 'TSTypePredicate' && + node.type !== 'TSTypeQuery' && + node.type !== 'TSTypeReference' && + node.type !== 'TSUndefinedKeyword' && + node.type !== 'TSUnionType' && + node.type !== 'TSUnknownKeyword' && + node.type !== 'TSVoidKeyword' + ) { + return + } + /** @type {TypeNode} */ + const typeNode = node + if (/** @type {any} */ (typeNode.parent).type === 'TSParenthesizedType') { + return + } + // Process parentheses. + let leftToken = tokenStore.getTokenBefore(node) + let rightToken = tokenStore.getTokenAfter(node) + let firstToken = tokenStore.getFirstToken(node) + + while ( + leftToken && + rightToken && + isOpeningParenToken(leftToken) && + isClosingParenToken(rightToken) + ) { + setOffset(firstToken, 1, leftToken) + setOffset(rightToken, 0, leftToken) + + firstToken = leftToken + leftToken = tokenStore.getTokenBefore(leftToken) + rightToken = tokenStore.getTokenAfter(rightToken) + } + }, /** * Process type annotation * @@ -535,15 +607,6 @@ function defineVisitor({ setOffset(typeTokens.firstToken, offset, firstToken) } }, - TSParenthesizedType(node) { - // (T) - processNodeList( - [node.typeAnnotation], - tokenStore.getFirstToken(node), - tokenStore.getLastToken(node), - 1 - ) - }, TSMappedType(node) { // {[key in foo]: bar} const leftBraceToken = tokenStore.getFirstToken(node) @@ -1026,12 +1089,12 @@ function defineVisitor({ * // ^^^^^^^ * ``` * - * @param {TSAbstractMethodDefinition | TSAbstractClassProperty | TSEnumMember | ClassProperty} node + * @param {TSAbstractMethodDefinition | TSAbstractPropertyDefinition | TSEnumMember | TSAbstractClassProperty | ClassProperty} node * */ - 'TSAbstractMethodDefinition, TSAbstractClassProperty, TSEnumMember, ClassProperty'( - node - ) { + ['TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSEnumMember,' + + // Deprecated in @typescript-eslint/parser v5 + 'ClassProperty, TSAbstractClassProperty'](node) { const { keyNode, valueNode } = node.type === 'TSEnumMember' ? { keyNode: node.id, valueNode: node.initializer } @@ -1275,6 +1338,21 @@ function defineVisitor({ setOffset(atToken, 0, tokenStore.getFirstToken(decorators[0])) } }, + + // ---------------------------------------------------------------------- + // DEPRECATED NODES + // ---------------------------------------------------------------------- + /** @param {any} node */ + TSParenthesizedType(node) { + // Deprecated in @typescript-eslint/parser v5 + // (T) + processNodeList( + [node.typeAnnotation], + tokenStore.getFirstToken(node), + tokenStore.getLastToken(node), + 1 + ) + }, // ---------------------------------------------------------------------- // SINGLE TOKEN NODES // ---------------------------------------------------------------------- diff --git a/package.json b/package.json index 661acff1e..7076d867e 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@types/natural-compare": "^1.4.0", "@types/node": "^13.13.5", "@types/semver": "^7.2.0", - "@typescript-eslint/parser": "^4.28.0", + "@typescript-eslint/parser": "^5.0.0-0", "@vuepress/plugin-pwa": "^1.4.1", "env-cmd": "^10.1.0", "eslint": "^7.0.0", diff --git a/tests/fixtures/script-indent/ts-abstract-class-property-02.vue b/tests/fixtures/script-indent/ts-abstract-class-property-02.vue index 9e3214a0f..6b10b8033 100644 --- a/tests/fixtures/script-indent/ts-abstract-class-property-02.vue +++ b/tests/fixtures/script-indent/ts-abstract-class-property-02.vue @@ -6,12 +6,14 @@ abstract class A { 1 ; abstract public b - = - 's' + // parser v5 does not parse value. + // = + // 's' ; protected abstract c - = - i + // parser v5 does not parse value. + // = + // i ; } diff --git a/tests/fixtures/script-indent/ts-static-block-01.vue b/tests/fixtures/script-indent/ts-static-block-01.vue new file mode 100644 index 000000000..522271628 --- /dev/null +++ b/tests/fixtures/script-indent/ts-static-block-01.vue @@ -0,0 +1,8 @@ + + diff --git a/tests/fixtures/script-indent/ts-type-annotation-03.vue b/tests/fixtures/script-indent/ts-type-annotation-03.vue index ed1bab907..6569f4e53 100644 --- a/tests/fixtures/script-indent/ts-type-annotation-03.vue +++ b/tests/fixtures/script-indent/ts-type-annotation-03.vue @@ -18,11 +18,12 @@ class Foo { ? : number; - abstract absopt2 - ? - : - number - = - 42; +// parser v5 does not parse value. +// abstract absopt2 +// ? +// : +// number +// = +// 42; } diff --git a/typings/eslint-plugin-vue/global.d.ts b/typings/eslint-plugin-vue/global.d.ts index 96ceee311..c2ae50632 100644 --- a/typings/eslint-plugin-vue/global.d.ts +++ b/typings/eslint-plugin-vue/global.d.ts @@ -137,6 +137,7 @@ declare global { type ClassBody = VAST.ClassBody type MethodDefinition = VAST.MethodDefinition type PropertyDefinition = VAST.PropertyDefinition + type StaticBlock = VAST.StaticBlock type ModuleDeclaration = VAST.ModuleDeclaration type ImportDeclaration = VAST.ImportDeclaration type ExportNamedDeclaration = VAST.ExportNamedDeclaration diff --git a/typings/eslint-plugin-vue/util-types/ast/ast.ts b/typings/eslint-plugin-vue/util-types/ast/ast.ts index 68d6b8843..005fabe57 100644 --- a/typings/eslint-plugin-vue/util-types/ast/ast.ts +++ b/typings/eslint-plugin-vue/util-types/ast/ast.ts @@ -333,6 +333,8 @@ export type ESNodeListenerMap = { 'MethodDefinition:exit': ES.MethodDefinition PropertyDefinition: ES.PropertyDefinition 'PropertyDefinition:exit': ES.PropertyDefinition + StaticBlock: ES.StaticBlock + 'StaticBlock:exit': ES.StaticBlock ImportDeclaration: ES.ImportDeclaration 'ImportDeclaration:exit': ES.ImportDeclaration ExportNamedDeclaration: ES.ExportNamedDeclaration diff --git a/typings/eslint-plugin-vue/util-types/ast/es-ast.ts b/typings/eslint-plugin-vue/util-types/ast/es-ast.ts index ba320a979..eff4f983b 100644 --- a/typings/eslint-plugin-vue/util-types/ast/es-ast.ts +++ b/typings/eslint-plugin-vue/util-types/ast/es-ast.ts @@ -27,6 +27,7 @@ export type ESNode = | ClassBody | MethodDefinition | PropertyDefinition + | StaticBlock | ModuleDeclaration | ModuleSpecifier @@ -63,10 +64,12 @@ export type Statement = export interface EmptyStatement extends HasParentNode { type: 'EmptyStatement' } -export interface BlockStatement extends HasParentNode { - type: 'BlockStatement' +interface BaseBlock extends HasParentNode { body: Statement[] } +export interface BlockStatement extends BaseBlock { + type: 'BlockStatement' +} export interface ExpressionStatement extends HasParentNode { type: 'ExpressionStatement' expression: Expression @@ -187,7 +190,7 @@ export interface ClassDeclaration extends HasParentNode { } export interface ClassBody extends HasParentNode { type: 'ClassBody' - body: (MethodDefinition | PropertyDefinition)[] + body: (MethodDefinition | PropertyDefinition | StaticBlock)[] } interface BaseMethodDefinition extends HasParentNode { type: 'MethodDefinition' @@ -242,6 +245,11 @@ export type PropertyDefinition = | PropertyDefinitionComputedName | PropertyDefinitionPrivate +export interface StaticBlock extends BaseBlock { + type: 'StaticBlock' + parent: ClassBody +} + export type ModuleDeclaration = | ImportDeclaration | ExportNamedDeclaration From 5fe244513a4488ff6c2e489d93df0a5e999eed29 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Mon, 6 Sep 2021 08:30:52 +0900 Subject: [PATCH 002/638] Change type determination logic of type-only defineProps to follow vue v3.2.9. (#1620) --- lib/utils/ts-ast-utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/utils/ts-ast-utils.js b/lib/utils/ts-ast-utils.js index f23a752e3..b801b6374 100644 --- a/lib/utils/ts-ast-utils.js +++ b/lib/utils/ts-ast-utils.js @@ -255,6 +255,7 @@ function inferRuntimeType(context, node, checked = new Set()) { case 'Map': case 'WeakSet': case 'WeakMap': + case 'Date': return [node.typeName.name] case 'Record': case 'Partial': From eaf6584892da37f8b319461af1fd3a34ace1541d Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Mon, 13 Sep 2021 13:35:58 +0900 Subject: [PATCH 003/638] Add tests with espree v9 (#1622) --- docs/user-guide/README.md | 11 ++++++----- package.json | 3 ++- tests/fixtures/script-indent/static-block-01.vue | 8 ++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 tests/fixtures/script-indent/static-block-01.vue diff --git a/docs/user-guide/README.md b/docs/user-guide/README.md index 39e44d9ab..1a62fbf71 100644 --- a/docs/user-guide/README.md +++ b/docs/user-guide/README.md @@ -265,9 +265,10 @@ See also: "[How to use a custom parser?](#how-to-use-a-custom-parser)" section. ] ``` -2. Make sure your tool is set to lint `.vue` files. - - CLI targets only `.js` files by default. You have to specify additional extensions with the `--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. - - If you are having issues with configuring editor, please read [editor integrations](#editor-integrations) +1. Make sure your tool is set to lint `.vue` files. + + - CLI targets only `.js` files by default. You have to specify additional extensions with the `--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. + - If you are having issues with configuring editor, please read [editor integrations](#editor-integrations) ### Conflict with [Prettier] @@ -384,8 +385,8 @@ See also [ESLint - Specifying Globals > Using configuration files](https://eslin ##### Using ESLint <= v7.x The parser `espree` that comes with `ESLint` v7.x doesn't understand the syntax of ES2022, so it can't parse the Top Level `await` either. -However, `espree` v8+ can understand the syntax of ES2022 and parse the Top Level `await`. -You install `espree` v8+ and specify `"espree"` and ES2022 in your configuration, the parser will be able to parse it. +However, `espree` >= v8 can understand the syntax of ES2022 and parse the Top Level `await`. +You install `espree` >= v8 and specify `"espree"` and ES2022 in your configuration, the parser will be able to parse it. ```js module.exports = { diff --git a/package.json b/package.json index 7076d867e..59855a324 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@types/semver": "^7.2.0", "@typescript-eslint/parser": "^5.0.0-0", "@vuepress/plugin-pwa": "^1.4.1", + "acorn": "^8.5.0", "env-cmd": "^10.1.0", "eslint": "^7.0.0", "eslint-config-prettier": "^6.11.0", @@ -74,7 +75,7 @@ "eslint-plugin-prettier": "^3.1.3", "eslint-plugin-vue": "file:.", "eslint4b": "^7.0.0", - "espree": "^8.0.0", + "espree": "^9.0.0", "lodash": "^4.17.15", "mocha": "^7.1.2", "nyc": "^15.0.1", diff --git a/tests/fixtures/script-indent/static-block-01.vue b/tests/fixtures/script-indent/static-block-01.vue new file mode 100644 index 000000000..87bfc6b34 --- /dev/null +++ b/tests/fixtures/script-indent/static-block-01.vue @@ -0,0 +1,8 @@ + + From 8efec75531a54cdc49eb4f15b2f6f25e3e691471 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Fri, 17 Sep 2021 19:34:01 +0900 Subject: [PATCH 004/638] Add `vue/component-api-style` rule (#1626) * Add `vue/component-api-style` rule * Update package.json --- docs/rules/README.md | 1 + docs/rules/component-api-style.md | 144 +++++++ lib/index.js | 1 + lib/rules/component-api-style.js | 257 +++++++++++ lib/utils/index.js | 78 ++++ tests/lib/rules/component-api-style.js | 566 +++++++++++++++++++++++++ 6 files changed, 1047 insertions(+) create mode 100644 docs/rules/component-api-style.md create mode 100644 lib/rules/component-api-style.js create mode 100644 tests/lib/rules/component-api-style.js diff --git a/docs/rules/README.md b/docs/rules/README.md index 5f86b7fc7..85f6e661b 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -288,6 +288,7 @@ For example: |:--------|:------------|:---| | [vue/block-lang](./block-lang.md) | disallow use other than available `lang` | | | [vue/block-tag-newline](./block-tag-newline.md) | enforce line breaks after opening and before closing block-level tags | :wrench: | +| [vue/component-api-style](./component-api-style.md) | enforce component API style | | | [vue/component-name-in-template-casing](./component-name-in-template-casing.md) | enforce specific casing for the component naming style in template | :wrench: | | [vue/custom-event-name-casing](./custom-event-name-casing.md) | enforce specific casing for custom event name | | | [vue/html-button-has-type](./html-button-has-type.md) | disallow usage of button without an explicit type attribute | | diff --git a/docs/rules/component-api-style.md b/docs/rules/component-api-style.md new file mode 100644 index 000000000..8472d4c1b --- /dev/null +++ b/docs/rules/component-api-style.md @@ -0,0 +1,144 @@ +--- +pageClass: rule-details +sidebarDepth: 0 +title: vue/component-api-style +description: enforce component API style +--- +# vue/component-api-style + +> enforce component API style + +- :exclamation: ***This rule has not been released yet.*** + +## :book: Rule Details + +This rule aims to make the API style you use to define Vue components consistent in your project. + +For example, if you want to allow only ` +``` + + + + + +```vue + +``` + + + + + +```vue + +``` + + + +## :wrench: Options + +```json +{ + "vue/component-api-style": ["error", + ["script-setup", "composition"] // "script-setup", "composition", or "options" + ] +} +``` + +- Array options ... Defines the API styles you want to allow. Default is `["script-setup", "composition"]`. You can use the following values. + - `"script-setup"` ... If set, allows ` +``` + + + + + +```vue + + +``` + + + + + +```vue + +``` + + + +## :mag: Implementation + +- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/component-api-style.js) +- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/component-api-style.js) diff --git a/lib/index.js b/lib/index.js index af29765ca..0015fb579 100644 --- a/lib/index.js +++ b/lib/index.js @@ -21,6 +21,7 @@ module.exports = { 'comma-spacing': require('./rules/comma-spacing'), 'comma-style': require('./rules/comma-style'), 'comment-directive': require('./rules/comment-directive'), + 'component-api-style': require('./rules/component-api-style'), 'component-definition-name-casing': require('./rules/component-definition-name-casing'), 'component-name-in-template-casing': require('./rules/component-name-in-template-casing'), 'component-tags-order': require('./rules/component-tags-order'), diff --git a/lib/rules/component-api-style.js b/lib/rules/component-api-style.js new file mode 100644 index 000000000..4cec3b1ab --- /dev/null +++ b/lib/rules/component-api-style.js @@ -0,0 +1,257 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +'use strict' + +const utils = require('../utils') + +/** + * @typedef { 'script-setup' | 'composition' | 'options' } PreferOption + * + * @typedef {PreferOption[]} UserPreferOption + * + * @typedef {object} NormalizeOptions + * @property {object} allowsSFC + * @property {boolean} [allowsSFC.scriptSetup] + * @property {boolean} [allowsSFC.composition] + * @property {boolean} [allowsSFC.options] + * @property {object} allowsOther + * @property {boolean} [allowsOther.composition] + * @property {boolean} [allowsOther.options] + */ + +/** @type {PreferOption[]} */ +const STYLE_OPTIONS = ['script-setup', 'composition', 'options'] + +/** + * Normalize options. + * @param {any[]} options The options user configured. + * @returns {NormalizeOptions} The normalized options. + */ +function parseOptions(options) { + /** @type {NormalizeOptions} */ + const opts = { allowsSFC: {}, allowsOther: {} } + + /** @type {UserPreferOption} */ + const preferOptions = options[0] || ['script-setup', 'composition'] + for (const prefer of preferOptions) { + if (prefer === 'script-setup') { + opts.allowsSFC.scriptSetup = true + } else if (prefer === 'composition') { + opts.allowsSFC.composition = true + opts.allowsOther.composition = true + } else if (prefer === 'options') { + opts.allowsSFC.options = true + opts.allowsOther.options = true + } + } + + if (!opts.allowsOther.composition && !opts.allowsOther.options) { + opts.allowsOther.composition = true + opts.allowsOther.options = true + } + + return opts +} + +const OPTIONS_API_OPTIONS = new Set([ + 'mixins', + 'extends', + // state + 'data', + 'computed', + 'methods', + 'watch', + 'provide', + 'inject', + // lifecycle + 'beforeCreate', + 'created', + 'beforeMount', + 'mounted', + 'beforeUpdate', + 'updated', + 'activated', + 'deactivated', + 'beforeDestroy', + 'beforeUnmount', + 'destroyed', + 'unmounted', + 'render', + 'renderTracked', + 'renderTriggered', + 'errorCaptured', + // public API + 'expose' +]) +const COMPOSITION_API_OPTIONS = new Set(['setup']) + +const LIFECYCLE_HOOK_OPTIONS = new Set([ + 'beforeCreate', + 'created', + 'beforeMount', + 'mounted', + 'beforeUpdate', + 'updated', + 'activated', + 'deactivated', + 'beforeDestroy', + 'beforeUnmount', + 'destroyed', + 'unmounted', + 'renderTracked', + 'renderTriggered', + 'errorCaptured' +]) + +/** + * @typedef { 'script-setup' | 'composition' | 'options' } ApiStyle + */ + +/** + * @param {object} allowsOpt + * @param {boolean} [allowsOpt.scriptSetup] + * @param {boolean} [allowsOpt.composition] + * @param {boolean} [allowsOpt.options] + */ +function buildAllowedPhrase(allowsOpt) { + const phrases = [] + if (allowsOpt.scriptSetup) { + phrases.push('` + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + options: [['options']], + code: ` + + ` + }, + { + filename: 'test.js', + code: ` + import { ref, defineComponent } from 'vue' + defineComponent({ + setup() { + const msg = ref('Hello World!') + // ... + return { + msg, + // ... + } + } + }) + ` + }, + { + filename: 'test.js', + options: [['options']], + code: ` + import { defineComponent } from 'vue' + defineComponent({ + data () { + return { + msg: 'Hello World!', + // ... + } + }, + // ... + }) + ` + }, + { + filename: 'test.vue', + options: [['script-setup']], + code: ` + + ` + }, + { + filename: 'test.js', + options: [['script-setup']], + code: ` + import { ref, defineComponent } from 'vue' + defineComponent({ + setup() { + const msg = ref('Hello World!') + // ... + return { + msg, + // ... + } + } + }) + ` + }, + { + filename: 'test.js', + options: [['script-setup']], + code: ` + import { defineComponent } from 'vue' + defineComponent({ + data () { + return { + msg: 'Hello World!', + // ... + } + }, + // ... + }) + ` + }, + { + filename: 'test.vue', + options: [['composition']], + code: ` + + ` + } + ], + invalid: [ + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + message: + 'Options API is not allowed in your project. `data` option is the API of Options API. Use ` + `, + options: [['options']], + errors: [ + { + message: + '` + `, + options: [['options']], + errors: [ + { + message: + 'Composition API is not allowed in your project. `setup` function is the API of Composition API. Use Options API instead.', + line: 5, + column: 9 + } + ] + }, + { + filename: 'test.js', + code: ` + import { defineComponent } from 'vue' + defineComponent({ + data () { + return { + msg: 'Hello World!', + // ... + } + }, + // ... + }) + `, + errors: [ + { + message: + 'Options API is not allowed in your project. `data` option is the API of Options API. Use Composition API instead.', + line: 4, + column: 9 + } + ] + }, + { + filename: 'test.js', + code: ` + import { ref, defineComponent } from 'vue' + defineComponent({ + setup() { + const msg = ref('Hello World!') + // ... + return { + msg, + // ... + } + } + }) + `, + options: [['options']], + errors: [ + { + message: + 'Composition API is not allowed in your project. `setup` function is the API of Composition API. Use Options API instead.', + line: 4, + column: 9 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + options: [['script-setup']], + errors: [ + { + message: + 'Composition API is not allowed in your project. Use ` + `, + errors: [ + { + message: + 'Options API is not allowed in your project. Use ` + `, + options: [['composition']], + errors: [ + { + message: + '` + `, + errors: [ + { + message: + 'Options API is not allowed in your project. `data` option is the API of Options API. Use Composition API instead.', + line: 4, + column: 9 + } + ] + }, + { + filename: 'test.vue', + options: [['composition']], + code: ` + + `, + errors: [ + { + message: + 'Options API is not allowed in your project. `mixins` option is the API of Options API. Use Composition API instead.', + line: 4, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `extends` option is the API of Options API. Use Composition API instead.', + line: 5, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `data` option is the API of Options API. Use Composition API instead.', + line: 7, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `computed` option is the API of Options API. Use Composition API instead.', + line: 8, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `methods` option is the API of Options API. Use Composition API instead.', + line: 9, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `watch` option is the API of Options API. Use Composition API instead.', + line: 10, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `provide` option is the API of Options API. Use Composition API instead.', + line: 11, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `inject` option is the API of Options API. Use Composition API instead.', + line: 12, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `beforeCreate` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 14, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `created` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 15, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `beforeMount` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 16, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `mounted` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 17, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `beforeUpdate` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 18, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `updated` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 19, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `activated` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 20, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `deactivated` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 21, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `beforeDestroy` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 22, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `beforeUnmount` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 23, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `destroyed` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 24, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `unmounted` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 25, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `render` function is the API of Options API. Use Composition API instead.', + line: 26, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `renderTracked` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 27, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `renderTriggered` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 28, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `errorCaptured` lifecycle hook is the API of Options API. Use Composition API instead.', + line: 29, + column: 9 + }, + { + message: + 'Options API is not allowed in your project. `expose` option is the API of Options API. Use Composition API instead.', + line: 31, + column: 9 + } + ] + } + ] +}) From 03ba30e95a625c46be0c6c58660ac9f061877a87 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Fri, 17 Sep 2021 19:36:02 +0900 Subject: [PATCH 005/638] 7.18.0 --- docs/rules/component-api-style.md | 7 +++++-- package.json | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/rules/component-api-style.md b/docs/rules/component-api-style.md index 8472d4c1b..d20dc9fe3 100644 --- a/docs/rules/component-api-style.md +++ b/docs/rules/component-api-style.md @@ -3,13 +3,12 @@ pageClass: rule-details sidebarDepth: 0 title: vue/component-api-style description: enforce component API style +since: v7.18.0 --- # vue/component-api-style > enforce component API style -- :exclamation: ***This rule has not been released yet.*** - ## :book: Rule Details This rule aims to make the API style you use to define Vue components consistent in your project. @@ -138,6 +137,10 @@ export default { +## :rocket: Version + +This rule was introduced in eslint-plugin-vue v7.18.0 + ## :mag: Implementation - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/component-api-style.js) diff --git a/package.json b/package.json index 59855a324..8e8220581 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-vue", - "version": "7.17.0", + "version": "7.18.0", "description": "Official ESLint plugin for Vue.js", "main": "lib/index.js", "scripts": { From c2c709dfb9ef3f4d482d2cdd84b33d74585f9395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tao=20Bojl=C3=A9n?= <66130243+taobojlen@users.noreply.github.com> Date: Thu, 30 Sep 2021 00:36:10 +0100 Subject: [PATCH 006/638] Add vue/no-restricted-class rule (#1639) * Add vue/no-restricted-class rule * don't match '@class' * accept options in an array * handle array syntax * refactor with @ota-meshi's suggestions * handle objects converted to strings * run update script --- docs/rules/README.md | 1 + docs/rules/no-restricted-class.md | 79 +++++++++++++ lib/index.js | 1 + lib/rules/no-restricted-class.js | 154 +++++++++++++++++++++++++ tests/lib/rules/no-restricted-class.js | 118 +++++++++++++++++++ 5 files changed, 353 insertions(+) create mode 100644 docs/rules/no-restricted-class.md create mode 100644 lib/rules/no-restricted-class.js create mode 100644 tests/lib/rules/no-restricted-class.js diff --git a/docs/rules/README.md b/docs/rules/README.md index 85f6e661b..2f89e3a53 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -310,6 +310,7 @@ For example: | [vue/no-reserved-component-names](./no-reserved-component-names.md) | disallow the use of reserved names in component definitions | | | [vue/no-restricted-block](./no-restricted-block.md) | disallow specific block | | | [vue/no-restricted-call-after-await](./no-restricted-call-after-await.md) | disallow asynchronously called restricted methods | | +| [vue/no-restricted-class](./no-restricted-class.md) | disallow specific classes in Vue components | | | [vue/no-restricted-component-options](./no-restricted-component-options.md) | disallow specific component option | | | [vue/no-restricted-custom-event](./no-restricted-custom-event.md) | disallow specific custom event | | | [vue/no-restricted-props](./no-restricted-props.md) | disallow specific props | | diff --git a/docs/rules/no-restricted-class.md b/docs/rules/no-restricted-class.md new file mode 100644 index 000000000..c7aebce6b --- /dev/null +++ b/docs/rules/no-restricted-class.md @@ -0,0 +1,79 @@ +--- +pageClass: rule-details +sidebarDepth: 0 +title: vue/no-restricted-class +description: disallow specific classes in Vue components +--- +# vue/no-restricted-class + +> disallow specific classes in Vue components + +- :exclamation: ***This rule has not been released yet.*** + +## :book: Rule Details + +This rule lets you specify a list of classes that you don't want to allow in your templates. + +## :wrench: Options + +The simplest way to specify a list of forbidden classes is to pass it directly +in the rule configuration. + +```json +{ + "vue/no-restricted-props": ["error", "forbidden", "forbidden-two", "forbidden-three"] +} +``` + + + +```vue + + + +``` + + + +::: warning Note +This rule will only detect classes that are used as strings in your templates. Passing classes via +variables, like below, will not be detected by this rule. + +```vue + + + +``` +::: + +## :mag: Implementation + +- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-restricted-class.js) +- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-restricted-class.js) diff --git a/lib/index.js b/lib/index.js index 0015fb579..ef111732d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -101,6 +101,7 @@ module.exports = { 'no-reserved-keys': require('./rules/no-reserved-keys'), 'no-restricted-block': require('./rules/no-restricted-block'), 'no-restricted-call-after-await': require('./rules/no-restricted-call-after-await'), + 'no-restricted-class': require('./rules/no-restricted-class'), 'no-restricted-component-options': require('./rules/no-restricted-component-options'), 'no-restricted-custom-event': require('./rules/no-restricted-custom-event'), 'no-restricted-props': require('./rules/no-restricted-props'), diff --git a/lib/rules/no-restricted-class.js b/lib/rules/no-restricted-class.js new file mode 100644 index 000000000..b1dcccb07 --- /dev/null +++ b/lib/rules/no-restricted-class.js @@ -0,0 +1,154 @@ +/** + * @fileoverview Forbid certain classes from being used + * @author Tao Bojlen + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ +const utils = require('../utils') + +// ------------------------------------------------------------------------------ +// Helpers +// ------------------------------------------------------------------------------ +/** + * Report a forbidden class + * @param {string} className + * @param {*} node + * @param {RuleContext} context + * @param {Set} forbiddenClasses + */ +const reportForbiddenClass = (className, node, context, forbiddenClasses) => { + if (forbiddenClasses.has(className)) { + const loc = node.value ? node.value.loc : node.loc + context.report({ + node, + loc, + messageId: 'forbiddenClass', + data: { + class: className + } + }) + } +} + +/** + * @param {Expression} node + * @param {boolean} [textOnly] + * @returns {IterableIterator<{ className:string, reportNode: ESNode }>} + */ +function* extractClassNames(node, textOnly) { + if (node.type === 'Literal') { + yield* `${node.value}` + .split(/\s+/) + .map((className) => ({ className, reportNode: node })) + return + } + if (node.type === 'TemplateLiteral') { + for (const templateElement of node.quasis) { + yield* templateElement.value.cooked + .split(/\s+/) + .map((className) => ({ className, reportNode: templateElement })) + } + for (const expr of node.expressions) { + yield* extractClassNames(expr, true) + } + return + } + if (node.type === 'BinaryExpression') { + if (node.operator !== '+') { + return + } + yield* extractClassNames(node.left, true) + yield* extractClassNames(node.right, true) + return + } + if (textOnly) { + return + } + if (node.type === 'ObjectExpression') { + for (const prop of node.properties) { + if (prop.type !== 'Property') { + continue + } + const classNames = utils.getStaticPropertyName(prop) + if (!classNames) { + continue + } + yield* classNames + .split(/\s+/) + .map((className) => ({ className, reportNode: prop.key })) + } + return + } + if (node.type === 'ArrayExpression') { + for (const element of node.elements) { + if (element == null) { + continue + } + if (element.type === 'SpreadElement') { + continue + } + yield* extractClassNames(element) + } + return + } +} + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'disallow specific classes in Vue components', + url: 'https://eslint.vuejs.org/rules/no-restricted-class.html', + categories: undefined + }, + fixable: null, + messages: { + forbiddenClass: "'{{class}}' class is not allowed." + }, + schema: { + type: 'array', + items: { + type: 'string' + } + } + }, + + /** @param {RuleContext} context */ + create(context) { + const forbiddenClasses = new Set(context.options || []) + + return utils.defineTemplateBodyVisitor(context, { + /** + * @param {VAttribute & { value: VLiteral } } node + */ + 'VAttribute[directive=false][key.name="class"]'(node) { + node.value.value + .split(/\s+/) + .forEach((className) => + reportForbiddenClass(className, node, context, forbiddenClasses) + ) + }, + + /** @param {VExpressionContainer} node */ + "VAttribute[directive=true][key.name.name='bind'][key.argument.name='class'] > VExpressionContainer.value"( + node + ) { + if (!node.expression) { + return + } + + for (const { className, reportNode } of extractClassNames( + /** @type {Expression} */ (node.expression) + )) { + reportForbiddenClass(className, reportNode, context, forbiddenClasses) + } + } + }) + } +} diff --git a/tests/lib/rules/no-restricted-class.js b/tests/lib/rules/no-restricted-class.js new file mode 100644 index 000000000..baf39778f --- /dev/null +++ b/tests/lib/rules/no-restricted-class.js @@ -0,0 +1,118 @@ +/** + * @author Tao Bojlen + */ + +'use strict' + +const rule = require('../../../lib/rules/no-restricted-class') +const RuleTester = require('eslint').RuleTester + +const ruleTester = new RuleTester({ + parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 2020, sourceType: 'module' } +}) + +ruleTester.run('no-restricted-class', rule, { + valid: [ + { code: `` }, + { + code: ``, + options: ['forbidden'] + }, + { + code: ``, + options: ['forbidden'] + }, + { + code: ``, + options: ['forbidden'] + }, + { + code: ``, + options: ['forbidden'] + } + ], + + invalid: [ + { + code: ``, + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'VAttribute' + } + ], + options: ['forbidden'] + }, + { + code: ``, + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'Literal' + } + ], + options: ['forbidden'] + }, + { + code: ``, + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'Literal' + } + ], + options: ['forbidden'] + }, + { + code: ``, + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'Identifier' + } + ], + options: ['forbidden'] + }, + { + code: '', + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'TemplateElement' + } + ], + options: ['forbidden'] + }, + { + code: ``, + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'Literal' + } + ], + options: ['forbidden'] + }, + { + code: ``, + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'Literal' + } + ], + options: ['forbidden'] + }, + { + code: ``, + errors: [ + { + message: "'forbidden' class is not allowed.", + type: 'Literal' + } + ], + options: ['forbidden'] + } + ] +}) From a56c7ece26236bb672c53da0185314859f2d346f Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Sun, 3 Oct 2021 07:04:01 +0900 Subject: [PATCH 007/638] Chore: add generate new rule command (#1645) --- docs/developer-guide/README.md | 5 +- package.json | 1 + tools/new-rule.js | 160 +++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 tools/new-rule.js diff --git a/docs/developer-guide/README.md b/docs/developer-guide/README.md index f08ecc3a8..c5bfcc99e 100644 --- a/docs/developer-guide/README.md +++ b/docs/developer-guide/README.md @@ -13,8 +13,7 @@ Please include as much detail as possible to help us properly address your issue In order to add a new rule or a rule change, you should: - Create issue on GitHub with description of proposed rule -- Generate a new rule using the [official yeoman generator](https://github.com/eslint/generator-eslint) -- Run `npm start` +- Generate a new rule using the `npm run new -- [rule-name]` command - Write test scenarios & implement logic - Describe the rule in the generated `docs` file - Make sure all tests are passing @@ -38,10 +37,12 @@ After opening [astexplorer.net], select `Vue` as the syntax and `vue-eslint-pars Since single file components in Vue are not plain JavaScript, we can't use the default parser, and we had to introduce additional one: `vue-eslint-parser`, that generates enhanced AST with nodes that represent specific parts of the template syntax, as well as what's inside the ` + + ` } ], @@ -2507,6 +2571,145 @@ tester.run('no-unused-properties', rule, { "'f' of computed property found, but never used.", "'h' of method found, but never used." ] + }, + + // toRef, toRefs + { + filename: 'test.vue', + code: ` + + `, + errors: ["'bar' of property found, but never used."] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: ["'bar' of property found, but never used."] + }, + { + filename: 'test.vue', + code: ` + + `, + options: deepDataOptions, + errors: ["'foo.baz' of data found, but never used."] + }, + { + filename: 'test.vue', + code: ` + + `, + options: deepDataOptions, + errors: [ + "'foo.bar.b' of data found, but never used.", + "'foo.baz.a' of data found, but never used." + ] + }, + { + filename: 'test.vue', + code: ` + + `, + options: deepDataOptions, + errors: [ + "'foo.bar.b' of data found, but never used.", + "'foo.baz' of data found, but never used." + ] } ] }) From 5788883670fc6273512796d5be8b3f2730b43ac0 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Tue, 5 Oct 2021 11:15:59 +0900 Subject: [PATCH 010/638] Fix unable to autofix event name with `update:`. (#1648) --- lib/rules/v-on-event-hyphenation.js | 31 ++++----- tests/lib/rules/v-on-event-hyphenation.js | 80 +++++++++++++++++++++++ 2 files changed, 96 insertions(+), 15 deletions(-) diff --git a/lib/rules/v-on-event-hyphenation.js b/lib/rules/v-on-event-hyphenation.js index 60823e013..7ef07f1d8 100644 --- a/lib/rules/v-on-event-hyphenation.js +++ b/lib/rules/v-on-event-hyphenation.js @@ -51,15 +51,16 @@ module.exports = { const ignoredAttributes = (optionsPayload && optionsPayload.ignore) || [] const autofix = Boolean(optionsPayload && optionsPayload.autofix) - const caseConverter = casing.getExactConverter( + const caseConverter = casing.getConverter( useHyphenated ? 'kebab-case' : 'camelCase' ) /** * @param {VDirective} node + * @param {VIdentifier} argument * @param {string} name */ - function reportIssue(node, name) { + function reportIssue(node, argument, name) { const text = sourceCode.getText(node.key) context.report({ @@ -71,13 +72,14 @@ module.exports = { data: { text }, - fix: autofix - ? (fixer) => - fixer.replaceText( - node.key, - text.replace(name, caseConverter(name)) - ) - : null + fix: + autofix && + // It cannot be converted in snake_case. + !name.includes('_') + ? (fixer) => { + return fixer.replaceText(argument, caseConverter(name)) + } + : null }) } @@ -99,14 +101,13 @@ module.exports = { return utils.defineTemplateBodyVisitor(context, { "VAttribute[directive=true][key.name.name='on']"(node) { if (!utils.isCustomComponent(node.parent.parent)) return - - const name = - node.key.argument && - node.key.argument.type === 'VIdentifier' && - node.key.argument.rawName + if (!node.key.argument || node.key.argument.type !== 'VIdentifier') { + return + } + const name = node.key.argument.rawName if (!name || isIgnoredAttribute(name)) return - reportIssue(node, name) + reportIssue(node, node.key.argument, name) } }) } diff --git a/tests/lib/rules/v-on-event-hyphenation.js b/tests/lib/rules/v-on-event-hyphenation.js index c77449971..087e5d00a 100644 --- a/tests/lib/rules/v-on-event-hyphenation.js +++ b/tests/lib/rules/v-on-event-hyphenation.js @@ -102,6 +102,86 @@ tester.run('v-on-event-hyphenation', rule, { `, errors: ["v-on event 'v-on:custom-event' can't be hyphenated."] + }, + { + code: ` + + `, + options: ['always', { autofix: true }], + output: ` + + `, + errors: ["v-on event '@update:modelValue' must be hyphenated."] + }, + { + code: ` + + `, + options: ['never', { autofix: true }], + output: ` + + `, + errors: ["v-on event '@update:model-value' can't be hyphenated."] + }, + { + code: ` + + `, + options: ['always', { autofix: true }], + output: ` + + `, + errors: [ + "v-on event '@upDate:modelValue' must be hyphenated.", + "v-on event '@up-date:modelValue' must be hyphenated.", + "v-on event '@upDate:model-value' must be hyphenated." + ] + }, + { + code: ` + + `, + options: ['never', { autofix: true }], + output: ` + + `, + errors: [ + "v-on event '@up-date:modelValue' can't be hyphenated.", + "v-on event '@upDate:model-value' can't be hyphenated.", + "v-on event '@up-date:model-value' can't be hyphenated." + ] } ] }) From 1ece73e4470f1de1e3691529e4ceadbeecd6fd01 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Tue, 5 Oct 2021 11:24:38 +0900 Subject: [PATCH 011/638] 7.19.0 --- docs/rules/no-restricted-class.md | 7 +++++-- docs/rules/no-useless-template-attributes.md | 7 +++++-- package.json | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/rules/no-restricted-class.md b/docs/rules/no-restricted-class.md index c7aebce6b..267bfebaa 100644 --- a/docs/rules/no-restricted-class.md +++ b/docs/rules/no-restricted-class.md @@ -3,13 +3,12 @@ pageClass: rule-details sidebarDepth: 0 title: vue/no-restricted-class description: disallow specific classes in Vue components +since: v7.19.0 --- # vue/no-restricted-class > disallow specific classes in Vue components -- :exclamation: ***This rule has not been released yet.*** - ## :book: Rule Details This rule lets you specify a list of classes that you don't want to allow in your templates. @@ -73,6 +72,10 @@ export default { ``` ::: +## :rocket: Version + +This rule was introduced in eslint-plugin-vue v7.19.0 + ## :mag: Implementation - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-restricted-class.js) diff --git a/docs/rules/no-useless-template-attributes.md b/docs/rules/no-useless-template-attributes.md index ec24eb70f..c6b71027d 100644 --- a/docs/rules/no-useless-template-attributes.md +++ b/docs/rules/no-useless-template-attributes.md @@ -3,13 +3,12 @@ pageClass: rule-details sidebarDepth: 0 title: vue/no-useless-template-attributes description: disallow useless attribute on ` `, - options: ['always', { exceptions: ['*', '++'] }], output: null, + options: ['always', { exceptions: ['*', '++'] }], errors: [ 'Expected space after exception block.', { @@ -347,8 +341,8 @@ tester.run('html-comment-content-spacing', rule, { `, - options: ['always', { exceptions: ['*', '++'] }], output: null, + options: ['always', { exceptions: ['*', '++'] }], errors: [ 'Expected space after exception block.', { diff --git a/tests/lib/rules/html-comment-indent.js b/tests/lib/rules/html-comment-indent.js index 4ec5c6ee2..12880167e 100644 --- a/tests/lib/rules/html-comment-indent.js +++ b/tests/lib/rules/html-comment-indent.js @@ -16,23 +16,21 @@ const tester = new RuleTester({ }) tester.run('html-comment-indent', rule, { valid: [ - { - code: ` - + `, { code: ` + `, // IE conditional comments - { - code: ` - - ` - }, - { - code: ` - - ` - } + ` + + `, + ` + + ` ], invalid: [ @@ -232,7 +224,6 @@ tester.run('html-comment-indent', rule, { --> `, - options: ['tab'], output: ` `, + options: ['tab'], errors: [ { message: 'Expected relative indentation of 1 tab but found 0 tabs.', @@ -318,7 +310,6 @@ tester.run('html-comment-indent', rule, { --> `, - options: [4], output: ` `, + options: [4], errors: [ { message: @@ -407,7 +399,6 @@ tester.run('html-comment-indent', rule, { --> `, - options: [0], output: ` `, + options: [0], errors: [ { message: diff --git a/tests/lib/rules/html-end-tags.js b/tests/lib/rules/html-end-tags.js index b60c9848a..0d795875d 100644 --- a/tests/lib/rules/html-end-tags.js +++ b/tests/lib/rules/html-end-tags.js @@ -62,6 +62,7 @@ tester.run('html-end-tags', rule, { // https://github.com/vuejs/eslint-plugin-vue/issues/1403 { + filename: 'test.vue', code: ` - `, - filename: 'test.vue' + ` } ], invalid: [ diff --git a/tests/lib/rules/html-self-closing.js b/tests/lib/rules/html-self-closing.js index 5589c3da1..11ae3c6cf 100644 --- a/tests/lib/rules/html-self-closing.js +++ b/tests/lib/rules/html-self-closing.js @@ -69,6 +69,7 @@ tester.run('html-self-closing', rule, { // https://github.com/vuejs/eslint-plugin-vue/issues/1403 { + filename: 'test.vue', code: ` - `, - filename: 'test.vue' + ` } // other cases are in `invalid` tests. diff --git a/tests/lib/rules/jsx-uses-vars.js b/tests/lib/rules/jsx-uses-vars.js index 895093da7..3a2c7e82b 100644 --- a/tests/lib/rules/jsx-uses-vars.js +++ b/tests/lib/rules/jsx-uses-vars.js @@ -27,8 +27,7 @@ linter.defineRule('jsx-uses-vars', rule) describe('jsx-uses-vars', () => { ruleTester.run('no-unused-vars', ruleNoUnusedVars, { valid: [ - { - code: ` + ` /* eslint jsx-uses-vars: 1 */ import SomeComponent from './SomeComponent.jsx'; export default { @@ -38,10 +37,8 @@ describe('jsx-uses-vars', () => { ) }, }; + `, ` - }, - { - code: ` /* eslint jsx-uses-vars: 1 */ import SomeComponent from './SomeComponent.vue'; import OtherComponent from './OtherComponent.vue'; @@ -63,10 +60,8 @@ describe('jsx-uses-vars', () => { ) } } + `, ` - }, - { - code: ` /* eslint jsx-uses-vars: 1 */ export default { render () { @@ -76,7 +71,6 @@ describe('jsx-uses-vars', () => { } } ` - } ], invalid: [ diff --git a/tests/lib/rules/key-spacing.js b/tests/lib/rules/key-spacing.js index 519230e23..3d8d48a22 100644 --- a/tests/lib/rules/key-spacing.js +++ b/tests/lib/rules/key-spacing.js @@ -31,8 +31,8 @@ tester.run('key-spacing', rule, { }, { code: '', - options: [{ beforeColon: true }], output: '', + options: [{ beforeColon: true }], errors: [ "Missing space after key 'a'.", "Missing space before value for key 'a'." diff --git a/tests/lib/rules/keyword-spacing.js b/tests/lib/rules/keyword-spacing.js index dad5574e5..dadd553b7 100644 --- a/tests/lib/rules/keyword-spacing.js +++ b/tests/lib/rules/keyword-spacing.js @@ -101,7 +101,6 @@ tester.run('keyword-spacing', rule, { } " /> `, - options: [{ before: false, after: false }], output: ``, + options: [{ before: false, after: false }], errors: [ { message: 'Unexpected space(s) after "if".', diff --git a/tests/lib/rules/max-attributes-per-line.js b/tests/lib/rules/max-attributes-per-line.js index 252bd22c1..fdee711e7 100644 --- a/tests/lib/rules/max-attributes-per-line.js +++ b/tests/lib/rules/max-attributes-per-line.js @@ -14,23 +14,17 @@ const ruleTester = new RuleTester({ ruleTester.run('max-attributes-per-line', rule, { valid: [ - { - code: `` - }, - { - code: ``, + `` - }, - { - code: ``, + `` - }, + `, { code: ``, }, { code: ``, - options: [{ singleline: { max: 2 } }], output: ``, + options: [{ singleline: { max: 2 } }], errors: [ { message: "'job' should be on a new line.", @@ -110,13 +102,13 @@ job="Vet">`, job="Vet"> `, - options: [{ singleline: 3, multiline: 1 }], output: ``, + options: [{ singleline: 3, multiline: 1 }], errors: [ { message: "'age' should be on a new line.", @@ -131,13 +123,13 @@ age="30" job="Vet"> `, - options: [{ multiline: { max: 1 } }], output: ``, + options: [{ multiline: { max: 1 } }], errors: [ { message: "'age' should be on a new line.", diff --git a/tests/lib/rules/max-len.js b/tests/lib/rules/max-len.js index 3ff9f2dff..a1141ec22 100644 --- a/tests/lib/rules/max-len.js +++ b/tests/lib/rules/max-len.js @@ -1075,33 +1075,33 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b { filename: 'test.vue', code: ``, - errors: ['This line has a length of 41. Maximum allowed is 40.'], - options: [40] + options: [40], + errors: ['This line has a length of 41. Maximum allowed is 40.'] }, { filename: 'test.vue', code: ``, - errors: ['This line has a length of 41. Maximum allowed is 40.'], - options: [{ code: 40 }] + options: [{ code: 40 }], + errors: ['This line has a length of 41. Maximum allowed is 40.'] }, // tabWidth { filename: 'test.vue', code: ``, - errors: ['This line has a length of 45. Maximum allowed is 40.'], - options: [40, 4] + options: [40, 4], + errors: ['This line has a length of 45. Maximum allowed is 40.'] }, { filename: 'test.vue', code: ``, - errors: ['This line has a length of 45. Maximum allowed is 40.'], - options: [{ code: 40, tabWidth: 4 }] + options: [{ code: 40, tabWidth: 4 }], + errors: ['This line has a length of 45. Maximum allowed is 40.'] }, { filename: 'test.vue', code: ``, - errors: ['This line has a length of 44. Maximum allowed is 40.'], - options: [{ code: 40, tabWidth: 3 }] + options: [{ code: 40, tabWidth: 3 }], + errors: ['This line has a length of 44. Maximum allowed is 40.'] }, // comments { @@ -1122,6 +1122,7 @@ var a; // 41 cols comment * */ `, + options: [{ comments: 40 }], errors: [ { message: @@ -1148,8 +1149,7 @@ var a; // 41 cols comment * 'This line has a comment length of 41. Maximum allowed is 40.', line: 13 } - ], - options: [{ comments: 40 }] + ] }, // .js { @@ -1159,6 +1159,7 @@ var a = '81 columns ' var b = \`81 columns \`; /* 81 columns */ `, + options: [], errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', @@ -1172,8 +1173,7 @@ var b = \`81 columns message: 'This line has a length of 81. Maximum allowed is 80.', line: 4 } - ], - options: [] + ] }, { filename: 'test.js', @@ -1182,6 +1182,7 @@ var a = '81 columns ignoreStrings ' var b = \`81 columns \`; /* 81 columns */ `, + options: [{ ignoreStrings: true }], errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', @@ -1191,8 +1192,7 @@ var b = \`81 columns message: 'This line has a length of 81. Maximum allowed is 80.', line: 4 } - ], - options: [{ ignoreStrings: true }] + ] }, { filename: 'test.js', @@ -1201,6 +1201,7 @@ var a = '81 columns ' var b = \`81 columns \`; /* 81 columns */ `, + options: [{ ignoreComments: true }], errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', @@ -1210,8 +1211,7 @@ var b = \`81 columns message: 'This line has a length of 81. Maximum allowed is 80.', line: 3 } - ], - options: [{ ignoreComments: true }] + ] }, // only script comment { @@ -1222,6 +1222,7 @@ var b = \`81 columns 41 cols * */ `, + options: [{ comments: 40 }], errors: [ { message: @@ -1238,8 +1239,7 @@ var b = \`81 columns 'This line has a comment length of 41. Maximum allowed is 40.', line: 4 } - ], - options: [{ comments: 40 }] + ] } ] }) diff --git a/tests/lib/rules/multi-word-component-names.js b/tests/lib/rules/multi-word-component-names.js index 96302eec8..3d68364bc 100644 --- a/tests/lib/rules/multi-word-component-names.js +++ b/tests/lib/rules/multi-word-component-names.js @@ -165,14 +165,14 @@ tester.run('multi-word-component-names', rule, { }, { filename: 'test.vue', - options: [{ ignores: ['Todo'] }], code: ` - ` + `, + options: [{ ignores: ['Todo'] }] }, { filename: 'test.js', @@ -314,7 +314,6 @@ tester.run('multi-word-component-names', rule, { }, { filename: 'test.vue', - options: [{ ignores: ['Todo'] }], code: ` `, + options: [{ ignores: ['Todo'] }], errors: [ { message: 'Component name "Item" should always be multi-word.', diff --git a/tests/lib/rules/multiline-html-element-content-newline.js b/tests/lib/rules/multiline-html-element-content-newline.js index d06982955..2d68c7685 100644 --- a/tests/lib/rules/multiline-html-element-content-newline.js +++ b/tests/lib/rules/multiline-html-element-content-newline.js @@ -566,7 +566,6 @@ content
`, - options: [{ allowEmptyLines: true, ignoreWhenEmpty: false }], output: ` `, + options: [{ allowEmptyLines: true, ignoreWhenEmpty: false }], errors: [ 'Expected 1 line break after opening tag (`
`), but no line breaks found.' ] @@ -594,7 +594,6 @@ content content
`, - options: [{ allowEmptyLines: true }], output: ` `, + options: [{ allowEmptyLines: true }], 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.' diff --git a/tests/lib/rules/multiline-ternary.js b/tests/lib/rules/multiline-ternary.js index 2922f0e65..d79e82eff 100644 --- a/tests/lib/rules/multiline-ternary.js +++ b/tests/lib/rules/multiline-ternary.js @@ -92,6 +92,7 @@ tester.run('multiline-ternary', rule, { ` : null, + options: ['always-multiline'], errors: [ { message: @@ -99,8 +100,7 @@ tester.run('multiline-ternary', rule, { line: 5, column: 15 } - ], - options: ['always-multiline'] + ] }, { filename: 'test.vue', @@ -123,6 +123,7 @@ tester.run('multiline-ternary', rule, { ` : null, + options: ['never'], errors: [ { message: @@ -130,8 +131,7 @@ tester.run('multiline-ternary', rule, { line: 4, column: 21 } - ], - options: ['never'] + ] }, { filename: 'test.vue', diff --git a/tests/lib/rules/new-line-between-multi-line-property.js b/tests/lib/rules/new-line-between-multi-line-property.js index a302cca7e..31983d7b0 100644 --- a/tests/lib/rules/new-line-between-multi-line-property.js +++ b/tests/lib/rules/new-line-between-multi-line-property.js @@ -280,7 +280,6 @@ ruleTester.run('new-line-between-multi-line-property', rule, { // test set insertLine and minLineOfMultilineProperty to 5 { filename: 'test.vue', - options: [{ minLineOfMultilineProperty: 5 }], code: ` `, + options: [{ minLineOfMultilineProperty: 5 }], errors: [ { message: @@ -331,7 +331,6 @@ ruleTester.run('new-line-between-multi-line-property', rule, { // test js comments { filename: 'test.vue', - options: [{ minLineOfMultilineProperty: 5 }], code: ` `, + options: [{ minLineOfMultilineProperty: 5 }], errors: [ { message: @@ -384,7 +384,6 @@ ruleTester.run('new-line-between-multi-line-property', rule, { // test js doc { filename: 'test.vue', - options: [], code: ` `, + options: [], errors: [ { message: diff --git a/tests/lib/rules/next-tick-style.js b/tests/lib/rules/next-tick-style.js index 24ef50a8e..28e2d338c 100644 --- a/tests/lib/rules/next-tick-style.js +++ b/tests/lib/rules/next-tick-style.js @@ -40,7 +40,6 @@ tester.run('next-tick-style', rule, { }, { filename: 'test.vue', - options: ['promise'], code: `` + }`, + options: ['promise'] }, { filename: 'test.vue', - options: ['callback'], code: `` + }`, + options: ['callback'] }, // https://github.com/vuejs/eslint-plugin-vue/pull/1400#discussion_r550937977 { filename: 'test.vue', - options: ['promise'], code: `` + }`, + options: ['promise'] }, { filename: 'test.vue', - options: ['callback'], code: `` + }`, + options: ['callback'] } ], invalid: [ @@ -173,7 +173,6 @@ tester.run('next-tick-style', rule, { }, { filename: 'test.vue', - options: ['promise'], code: ``, + options: ['promise'], errors: [ { message: @@ -239,7 +239,6 @@ tester.run('next-tick-style', rule, { }, { filename: 'test.vue', - options: ['callback'], code: ``, output: null, + options: ['callback'], errors: [ { message: diff --git a/tests/lib/rules/no-async-in-computed-properties.js b/tests/lib/rules/no-async-in-computed-properties.js index 31950ec5d..2e150b021 100644 --- a/tests/lib/rules/no-async-in-computed-properties.js +++ b/tests/lib/rules/no-async-in-computed-properties.js @@ -303,11 +303,6 @@ ruleTester.run('no-async-in-computed-properties', rule, { { // https://github.com/vuejs/eslint-plugin-vue/issues/1690 filename: 'test.vue', - parser, - parserOptions: { - sourceType: 'module', - ecmaVersion: 2020 - }, code: ` `, - output: ` - `, + output: null, errors: [ '`slot` attributes are deprecated.', '`slot` attributes are deprecated.' diff --git a/tests/lib/rules/no-deprecated-v-bind-sync.js b/tests/lib/rules/no-deprecated-v-bind-sync.js index 626993731..c02342a86 100644 --- a/tests/lib/rules/no-deprecated-v-bind-sync.js +++ b/tests/lib/rules/no-deprecated-v-bind-sync.js @@ -68,7 +68,7 @@ ruleTester.run('no-deprecated-v-bind-sync', rule, { { filename: 'test.vue', code: "", - output: "", + output: null, errors: [ "'.sync' modifier on 'v-bind' directive is deprecated. Use 'v-model:propName' instead." ] @@ -76,7 +76,7 @@ ruleTester.run('no-deprecated-v-bind-sync', rule, { { filename: 'test.vue', code: '', - output: '', + output: null, errors: [ "'.sync' modifier on 'v-bind' directive is deprecated. Use 'v-model:propName' instead." ] @@ -84,8 +84,7 @@ ruleTester.run('no-deprecated-v-bind-sync', rule, { { filename: 'test.vue', code: '', - output: - '', + output: null, errors: [ "'.sync' modifier on 'v-bind' directive is deprecated. Use 'v-model:propName' instead." ] diff --git a/tests/lib/rules/no-duplicate-attributes.js b/tests/lib/rules/no-duplicate-attributes.js index 25f6fe5dc..b47611184 100644 --- a/tests/lib/rules/no-duplicate-attributes.js +++ b/tests/lib/rules/no-duplicate-attributes.js @@ -73,26 +73,26 @@ tester.run('no-duplicate-attributes', rule, { { filename: 'test.vue', code: '', - errors: ["Duplicate attribute 'style'."], - options: [{ allowCoexistStyle: false }] + options: [{ allowCoexistStyle: false }], + errors: ["Duplicate attribute 'style'."] }, { filename: 'test.vue', code: '', - errors: ["Duplicate attribute 'class'."], - options: [{ allowCoexistClass: false }] + options: [{ allowCoexistClass: false }], + errors: ["Duplicate attribute 'class'."] }, { filename: 'test.vue', code: '', - errors: ["Duplicate attribute 'style'."], - options: [{ allowCoexistStyle: false }] + options: [{ allowCoexistStyle: false }], + errors: ["Duplicate attribute 'style'."] }, { filename: 'test.vue', code: '', - errors: ["Duplicate attribute 'class'."], - options: [{ allowCoexistClass: false }] + options: [{ allowCoexistClass: false }], + errors: ["Duplicate attribute 'class'."] } ] }) diff --git a/tests/lib/rules/no-multiple-template-root.js b/tests/lib/rules/no-multiple-template-root.js index 167dc6385..e57afd188 100644 --- a/tests/lib/rules/no-multiple-template-root.js +++ b/tests/lib/rules/no-multiple-template-root.js @@ -49,6 +49,7 @@ ruleTester.run('no-multiple-template-root', rule, { // https://github.com/vuejs/eslint-plugin-vue/issues/1439 { + filename: 'test.vue', code: ` - `, - filename: 'test.vue' + ` } ], invalid: [ diff --git a/tests/lib/rules/no-parsing-error.js b/tests/lib/rules/no-parsing-error.js index 7eb295c4b..54500f18c 100644 --- a/tests/lib/rules/no-parsing-error.js +++ b/tests/lib/rules/no-parsing-error.js @@ -206,6 +206,7 @@ tester.run('no-parsing-error', rule, { // https://github.com/vuejs/eslint-plugin-vue/issues/1403 { + filename: 'test.vue', code: ` - `, - filename: 'test.vue' + ` } ], invalid: [ diff --git a/tests/lib/rules/no-potential-component-option-typo.js b/tests/lib/rules/no-potential-component-option-typo.js index 2b85fc999..68ea21901 100644 --- a/tests/lib/rules/no-potential-component-option-typo.js +++ b/tests/lib/rules/no-potential-component-option-typo.js @@ -174,6 +174,7 @@ tester.run('no-potential-component-option-typo', rule, { method: {} } `, + options: [{ custom: ['data', 'methods'] }], errors: [ { message: "'dat' may be a typo, which is similar to option [data].", @@ -209,8 +210,7 @@ tester.run('no-potential-component-option-typo', rule, { } ] } - ], - options: [{ custom: ['data', 'methods'] }] + ] }, // test if user define custom rule is duplicate with presets // test custom option that is not available in the presets @@ -224,6 +224,9 @@ tester.run('no-potential-component-option-typo', rule, { custo: {} } `, + options: [ + { custom: ['data', 'methods', 'custom', 'foo'], presets: ['all'] } + ], errors: [ { message: "'dat' may be a typo, which is similar to option [data].", @@ -279,9 +282,6 @@ tester.run('no-potential-component-option-typo', rule, { } ] } - ], - options: [ - { custom: ['data', 'methods', 'custom', 'foo'], presets: ['all'] } ] }, // test if report correctly, only have preset option @@ -294,6 +294,7 @@ tester.run('no-potential-component-option-typo', rule, { method: {} } `, + options: [{ presets: ['vue'] }], errors: [ { message: "'dat' may be a typo, which is similar to option [data].", @@ -329,8 +330,7 @@ tester.run('no-potential-component-option-typo', rule, { } ] } - ], - options: [{ presets: ['vue'] }] + ] }, // multi preset report typo { @@ -343,6 +343,7 @@ tester.run('no-potential-component-option-typo', rule, { method: {} } `, + options: [{ presets: ['vue', 'vue-router'] }], errors: [ { message: "'dat' may be a typo, which is similar to option [data].", @@ -399,8 +400,7 @@ tester.run('no-potential-component-option-typo', rule, { } ] } - ], - options: [{ presets: ['vue', 'vue-router'] }] + ] }, // test multi suggestion { @@ -411,6 +411,7 @@ tester.run('no-potential-component-option-typo', rule, { method: {} } `, + options: [{ custom: ['data', 'methods'], threshold: 10, presets: [] }], errors: [ { message: `'method' may be a typo, which is similar to option [methods,data].`, @@ -437,8 +438,7 @@ tester.run('no-potential-component-option-typo', rule, { } ] } - ], - options: [{ custom: ['data', 'methods'], threshold: 10, presets: [] }] + ] } ] }) diff --git a/tests/lib/rules/no-ref-as-operand.js b/tests/lib/rules/no-ref-as-operand.js index 1cdbb1041..a932ff1c2 100644 --- a/tests/lib/rules/no-ref-as-operand.js +++ b/tests/lib/rules/no-ref-as-operand.js @@ -131,26 +131,21 @@ tester.run('no-ref-as-operand', rule, { const count = ref(0) const foo = count `, - { - code: ` + ` - ` - }, - { - code: ` + `, + ` - ` - }, - { - code: ` + `, + ` - ` - }, - { - code: ` + `, + ` - ` - } + ` ], invalid: [ { diff --git a/tests/lib/rules/no-required-prop-with-default.js b/tests/lib/rules/no-required-prop-with-default.js index 236de8cd4..ec1e749cc 100644 --- a/tests/lib/rules/no-required-prop-with-default.js +++ b/tests/lib/rules/no-required-prop-with-default.js @@ -196,7 +196,6 @@ tester.run('no-required-prop-with-default', rule, { ); `, - options: [{ autofix: true }], output: ` `, + options: [{ autofix: true }], parserOptions: { parser: require.resolve('@typescript-eslint/parser') }, @@ -237,7 +237,6 @@ tester.run('no-required-prop-with-default', rule, { ); `, - options: [{ autofix: true }], output: ` `, + options: [{ autofix: true }], parserOptions: { parser: require.resolve('@typescript-eslint/parser') }, @@ -647,7 +647,6 @@ tester.run('no-required-prop-with-default', rule, { ); `, - options: [{ autofix: true }], output: ` `, + options: [{ autofix: true }], parserOptions: { parser: require.resolve('@typescript-eslint/parser') }, @@ -868,19 +868,7 @@ tester.run('no-required-prop-with-default', rule, { }) `, - output: ` - - `, + output: null, errors: [ { message: 'Prop "name" should be optional.', diff --git a/tests/lib/rules/no-restricted-call-after-await.js b/tests/lib/rules/no-restricted-call-after-await.js index 69eaf3a42..5409f7f29 100644 --- a/tests/lib/rules/no-restricted-call-after-await.js +++ b/tests/lib/rules/no-restricted-call-after-await.js @@ -147,8 +147,8 @@ tester.run('no-restricted-call-after-await', rule, { useI18n() `, - parserOptions: { ecmaVersion: 2022 }, - options: [{ module: 'vue-i18n', path: 'useI18n' }] + options: [{ module: 'vue-i18n', path: 'useI18n' }], + parserOptions: { ecmaVersion: 2022 } } ], invalid: [ diff --git a/tests/lib/rules/no-restricted-class.js b/tests/lib/rules/no-restricted-class.js index 02815b2c6..2d53598c8 100644 --- a/tests/lib/rules/no-restricted-class.js +++ b/tests/lib/rules/no-restricted-class.js @@ -14,7 +14,7 @@ const ruleTester = new RuleTester({ ruleTester.run('no-restricted-class', rule, { valid: [ - { code: `` }, + ``, { code: ``, options: ['forbidden'] @@ -40,93 +40,93 @@ ruleTester.run('no-restricted-class', rule, { invalid: [ { code: ``, + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'VAttribute' } - ], - options: ['forbidden'] + ] }, { code: ``, + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'Literal' } - ], - options: ['forbidden'] + ] }, { code: ``, + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'Literal' } - ], - options: ['forbidden'] + ] }, { code: ``, + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'Identifier' } - ], - options: ['forbidden'] + ] }, { code: '', + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'TemplateElement' } - ], - options: ['forbidden'] + ] }, { code: ``, + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'Literal' } - ], - options: ['forbidden'] + ] }, { code: ``, + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'Literal' } - ], - options: ['forbidden'] + ] }, { code: ``, + options: ['forbidden'], errors: [ { message: "'forbidden' class is not allowed.", type: 'Literal' } - ], - options: ['forbidden'] + ] }, { code: ``, + options: ['/^for(bidden|gotten)/'], errors: [ { message: "'forbidden' class is not allowed.", type: 'VAttribute' } - ], - options: ['/^for(bidden|gotten)/'] + ] } ] }) diff --git a/tests/lib/rules/no-restricted-html-elements.js b/tests/lib/rules/no-restricted-html-elements.js index 775d94580..3dee64643 100644 --- a/tests/lib/rules/no-restricted-html-elements.js +++ b/tests/lib/rules/no-restricted-html-elements.js @@ -38,38 +38,38 @@ tester.run('no-restricted-html-elements', rule, { { filename: 'test.vue', code: '', + options: ['button'], errors: [ { message: 'Unexpected use of forbidden HTML element button.', line: 1, column: 16 } - ], - options: ['button'] + ] }, { filename: 'test.vue', code: '', + options: ['div'], errors: [ { message: 'Unexpected use of forbidden HTML element div.', line: 1, column: 11 } - ], - options: ['div'] + ] }, { filename: 'test.vue', code: '', + options: [{ element: 'marquee', message: 'Custom error' }], errors: [ { message: 'Custom error', line: 1, column: 11 } - ], - options: [{ element: 'marquee', message: 'Custom error' }] + ] } ] }) diff --git a/tests/lib/rules/no-restricted-props.js b/tests/lib/rules/no-restricted-props.js index 0f1947ed1..934a255b0 100644 --- a/tests/lib/rules/no-restricted-props.js +++ b/tests/lib/rules/no-restricted-props.js @@ -386,10 +386,10 @@ tester.run('no-restricted-props', rule, { }>() `, + options: [{ name: 'foo', suggest: 'Foo' }], parserOptions: { parser: require.resolve('@typescript-eslint/parser') }, - options: [{ name: 'foo', suggest: 'Foo' }], errors: [ { message: 'Using `foo` props is not allowed.', diff --git a/tests/lib/rules/no-setup-props-destructure.js b/tests/lib/rules/no-setup-props-destructure.js index d990f8857..5e84a565e 100644 --- a/tests/lib/rules/no-setup-props-destructure.js +++ b/tests/lib/rules/no-setup-props-destructure.js @@ -160,12 +160,11 @@ tester.run('no-setup-props-destructure', rule, { ` }, - { - code: ` + ` Vue.component('test', { el: a = b - })` - }, + }) + `, { filename: 'test.vue', code: ` diff --git a/tests/lib/rules/no-side-effects-in-computed-properties.js b/tests/lib/rules/no-side-effects-in-computed-properties.js index cec6747f3..a72004060 100644 --- a/tests/lib/rules/no-side-effects-in-computed-properties.js +++ b/tests/lib/rules/no-side-effects-in-computed-properties.js @@ -19,8 +19,8 @@ const ruleTester = new RuleTester({ ruleTester.run('no-side-effects-in-computed-properties', rule, { valid: [ - { - code: `Vue.component('test', { + ` + Vue.component('test', { ...foo, computed: { ...test0({}), @@ -97,10 +97,10 @@ ruleTester.run('no-side-effects-in-computed-properties', rule, { this.someArray.forEach(arr => console.log(arr)) } } - })` - }, - { - code: `Vue.component('test', { + }) + `, + ` + Vue.component('test', { computed: { ...mapGetters(['example']), test1() { @@ -115,18 +115,18 @@ ruleTester.run('no-side-effects-in-computed-properties', rule, { return something.b } } - })` - }, - { - code: `Vue.component('test', { + }) + `, + ` + Vue.component('test', { name: 'something', data() { return {} } - })` - }, - { - code: `Vue.component('test', { + }) + `, + ` + Vue.component('test', { computed: { test () { let a; @@ -134,10 +134,10 @@ ruleTester.run('no-side-effects-in-computed-properties', rule, { return a }, } - })` - }, - { - code: `Vue.component('test', { + }) + `, + ` + Vue.component('test', { computed: { test () { return { @@ -153,32 +153,32 @@ ruleTester.run('no-side-effects-in-computed-properties', rule, { } }, } - })` - }, - { - code: `Vue.component('test', { + }) + `, + ` + Vue.component('test', { computed: { test () { return this.something['a']().reverse() }, } - })` - }, - { - code: `const test = { el: '#app' } + }) + `, + ` + const test = { el: '#app' } Vue.component('test', { el: test.el - })` - }, - { - code: `Vue.component('test', { + }) + `, + ` + Vue.component('test', { computed: { test () { return [...this.items].reverse() }, } - })` - }, + }) + `, { filename: 'test.vue', code: ` @@ -392,13 +392,13 @@ ruleTester.run('no-side-effects-in-computed-properties', rule, { } }); `, + parser: require.resolve('@typescript-eslint/parser'), errors: [ { line: 5, message: 'Unexpected side effect in "test1" computed property.' } - ], - parser: require.resolve('@typescript-eslint/parser') + ] }, { diff --git a/tests/lib/rules/no-template-target-blank.js b/tests/lib/rules/no-template-target-blank.js index 5445ae6d7..b9896d7ed 100644 --- a/tests/lib/rules/no-template-target-blank.js +++ b/tests/lib/rules/no-template-target-blank.js @@ -15,31 +15,21 @@ const ruleTester = new RuleTester({ ruleTester.run('no-template-target-blank', rule, { valid: [ - { code: '' }, - { code: '' }, - { code: '' }, - { - code: '' - }, - { code: '' }, - { - code: '' - }, - { - code: '' - }, + '', + '', + '', + '', + '', + '', + '', { code: '', options: [{ allowReferrer: true }] }, - { code: '' }, - { - code: '' - }, - { code: '' }, - { - code: '' - }, + '', + '', + '', + '', { code: '', options: [{ enforceDynamicLinks: 'never' }] diff --git a/tests/lib/rules/no-this-in-before-route-enter.js b/tests/lib/rules/no-this-in-before-route-enter.js index 1171959ae..f3861672e 100644 --- a/tests/lib/rules/no-this-in-before-route-enter.js +++ b/tests/lib/rules/no-this-in-before-route-enter.js @@ -83,8 +83,8 @@ export default { ], invalid: [ { - code: template(`this.xxx();`), filename: 'ValidComponent.vue', + code: template(`this.xxx();`), errors: [ { message: @@ -97,8 +97,8 @@ export default { ] }, { - code: functionTemplate('this.method();'), filename: 'ValidComponent.vue', + code: functionTemplate('this.method();'), errors: [ { message: @@ -111,8 +111,8 @@ export default { ] }, { - code: template('this.attr = this.method();'), filename: 'ValidComponent.vue', + code: template('this.attr = this.method();'), errors: [ { message: @@ -133,8 +133,8 @@ export default { ] }, { - code: functionTemplate('this.attr = this.method();'), filename: 'ValidComponent.vue', + code: functionTemplate('this.attr = this.method();'), errors: [ { message: @@ -155,10 +155,10 @@ export default { ] }, { + filename: 'ValidComponent.vue', code: template(` if (this.method()) {} `), - filename: 'ValidComponent.vue', errors: [ { message: @@ -171,10 +171,10 @@ export default { ] }, { + filename: 'ValidComponent.vue', code: functionTemplate(` if (true) { this.method(); } `), - filename: 'ValidComponent.vue', errors: [ { message: diff --git a/tests/lib/rules/no-undef-components.js b/tests/lib/rules/no-undef-components.js index f90cb56df..0941f003d 100644 --- a/tests/lib/rules/no-undef-components.js +++ b/tests/lib/rules/no-undef-components.js @@ -656,12 +656,12 @@ tester.run('no-undef-components', rule, { `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } } ], invalid: [ @@ -803,12 +803,12 @@ tester.run('no-undef-components', rule, { `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') }, - parser: require.resolve('vue-eslint-parser'), errors: [ { message: diff --git a/tests/lib/rules/no-undef-properties.js b/tests/lib/rules/no-undef-properties.js index 9a97fe1a9..7ba344197 100644 --- a/tests/lib/rules/no-undef-properties.js +++ b/tests/lib/rules/no-undef-properties.js @@ -1169,13 +1169,13 @@ tester.run('no-undef-properties', rule, {
{{ foo }}
{{ unknown }}
`, - ...getTypeScriptFixtureTestOptions(), errors: [ { message: "'unknown' is not defined.", line: 11 } - ] + ], + ...getTypeScriptFixtureTestOptions() } ] }) diff --git a/tests/lib/rules/no-unsupported-features.js b/tests/lib/rules/no-unsupported-features.js index d12109311..77ee72055 100644 --- a/tests/lib/rules/no-unsupported-features.js +++ b/tests/lib/rules/no-unsupported-features.js @@ -45,7 +45,6 @@ tester.run('no-unsupported-features', rule, { `, - options: [{ version: '^2.5.0' }], output: ` `, + options: [{ version: '^2.5.0' }], errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', diff --git a/tests/lib/rules/no-unsupported-features/define-options.js b/tests/lib/rules/no-unsupported-features/define-options.js index 10b2069b2..a53bd776c 100644 --- a/tests/lib/rules/no-unsupported-features/define-options.js +++ b/tests/lib/rules/no-unsupported-features/define-options.js @@ -47,7 +47,6 @@ tester.run('no-unsupported-features/define-options', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: @@ -68,7 +68,6 @@ export default { name: 'Foo' } `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: diff --git a/tests/lib/rules/no-unsupported-features/slot-scope-attribute.js b/tests/lib/rules/no-unsupported-features/slot-scope-attribute.js index 5307aa616..8f8b0b136 100644 --- a/tests/lib/rules/no-unsupported-features/slot-scope-attribute.js +++ b/tests/lib/rules/no-unsupported-features/slot-scope-attribute.js @@ -66,8 +66,8 @@ tester.run('no-unsupported-features/slot-scope-attribute', rule, { `, - options: buildOptions(), output: null, + options: buildOptions(), errors: [ { message: @@ -83,8 +83,8 @@ tester.run('no-unsupported-features/slot-scope-attribute', rule, { `, - options: buildOptions(), output: null, + options: buildOptions(), errors: [ { message: @@ -100,8 +100,8 @@ tester.run('no-unsupported-features/slot-scope-attribute', rule, { `, - options: buildOptions({ version: '^3.0.0' }), output: null, + options: buildOptions({ version: '^3.0.0' }), errors: [ { message: diff --git a/tests/lib/rules/no-unsupported-features/v-bind-prop-modifier-shorthand.js b/tests/lib/rules/no-unsupported-features/v-bind-prop-modifier-shorthand.js index 1cefc8ff1..58ffda146 100644 --- a/tests/lib/rules/no-unsupported-features/v-bind-prop-modifier-shorthand.js +++ b/tests/lib/rules/no-unsupported-features/v-bind-prop-modifier-shorthand.js @@ -63,11 +63,11 @@ tester.run('no-unsupported-features/v-bind-prop-modifier-shorthand', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`.prop` shorthand are not supported until Vue.js "3.2.0".', @@ -80,11 +80,11 @@ tester.run('no-unsupported-features/v-bind-prop-modifier-shorthand', rule, { `, - options: buildOptions({ version: '2.5.99' }), output: ` `, + options: buildOptions({ version: '2.5.99' }), errors: [ { message: '`.prop` shorthand are not supported until Vue.js "3.2.0".', @@ -97,11 +97,11 @@ tester.run('no-unsupported-features/v-bind-prop-modifier-shorthand', rule, { `, - options: buildOptions({ version: '3.1.0' }), output: ` `, + options: buildOptions({ version: '3.1.0' }), errors: [ { message: '`.prop` shorthand are not supported until Vue.js "3.2.0".', diff --git a/tests/lib/rules/no-unsupported-features/v-slot.js b/tests/lib/rules/no-unsupported-features/v-slot.js index 66b3b0b9e..a382a7eda 100644 --- a/tests/lib/rules/no-unsupported-features/v-slot.js +++ b/tests/lib/rules/no-unsupported-features/v-slot.js @@ -81,13 +81,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -102,13 +102,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -123,13 +123,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -144,13 +144,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -165,13 +165,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -186,13 +186,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -207,13 +207,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -228,13 +228,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -249,13 +249,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -271,13 +271,13 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: ` `, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -292,8 +292,8 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: null, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -310,8 +310,8 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: null, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', @@ -328,8 +328,8 @@ tester.run('no-unsupported-features/v-slot', rule, { `, - options: buildOptions(), output: null, + options: buildOptions(), errors: [ { message: '`v-slot` are not supported until Vue.js "2.6.0".', diff --git a/tests/lib/rules/no-unused-properties.js b/tests/lib/rules/no-unused-properties.js index 2db132c48..0139559b1 100644 --- a/tests/lib/rules/no-unused-properties.js +++ b/tests/lib/rules/no-unused-properties.js @@ -1651,9 +1651,6 @@ tester.run('no-unused-properties', rule, { { // https://github.com/vuejs/eslint-plugin-vue/issues/1643 filename: 'test.vue', - parserOptions: { - parser: '@typescript-eslint/parser' - }, code: ` `, - options: [ - 'never', - { - objectsInObjects: true - } - ], output: ` `, + options: [ + 'never', + { + objectsInObjects: true + } + ], errors: [ "There should be no space after '{'.", "There should be no space after '{'.", @@ -145,13 +145,13 @@ tester.run('object-curly-spacing', rule, { Hello World `, - options: ['never'], output: ` `, + options: ['never'], errors: [ "There should be no space after '{'.", "There should be no space after '{'.", diff --git a/tests/lib/rules/order-in-components.js b/tests/lib/rules/order-in-components.js index b12c41a33..669383e52 100644 --- a/tests/lib/rules/order-in-components.js +++ b/tests/lib/rules/order-in-components.js @@ -197,7 +197,6 @@ ruleTester.run('order-in-components', rule, { }, } `, - parserOptions, output: ` export default { name: 'app', @@ -211,6 +210,7 @@ ruleTester.run('order-in-components', rule, { }, } `, + parserOptions, errors: [ { message: @@ -239,11 +239,6 @@ ruleTester.run('order-in-components', rule, { }, } `, - parserOptions: { - ecmaVersion: 6, - sourceType: 'module', - ecmaFeatures: { jsx: true } - }, output: ` export default { name: 'app', @@ -262,6 +257,11 @@ ruleTester.run('order-in-components', rule, { }, } `, + parserOptions: { + ecmaVersion: 6, + sourceType: 'module', + ecmaFeatures: { jsx: true } + }, errors: [ { message: @@ -294,7 +294,6 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, - parserOptions: { ecmaVersion: 6 }, output: ` Vue.component('smart-list', { name: 'app', @@ -307,6 +306,7 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, + parserOptions: { ecmaVersion: 6 }, errors: [ { message: @@ -329,7 +329,6 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, - parserOptions: { ecmaVersion: 6 }, output: ` app.component('smart-list', { name: 'app', @@ -342,6 +341,7 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, + parserOptions: { ecmaVersion: 6 }, errors: [ { message: @@ -365,7 +365,6 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, - parserOptions: { ecmaVersion: 6 }, output: ` const { component } = Vue; component('smart-list', { @@ -379,6 +378,7 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, + parserOptions: { ecmaVersion: 6 }, errors: [ { message: @@ -402,7 +402,6 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, - parserOptions: { ecmaVersion: 6 }, output: ` new Vue({ el: '#app', @@ -416,6 +415,7 @@ ruleTester.run('order-in-components', rule, { template: '
' }) `, + parserOptions: { ecmaVersion: 6 }, errors: [ { message: @@ -449,7 +449,6 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: ` export default { name: 'burger', @@ -468,6 +467,7 @@ ruleTester.run('order-in-components', rule, { }, }; `, + parserOptions, errors: [ { message: @@ -486,7 +486,6 @@ ruleTester.run('order-in-components', rule, { test: 'ok' }; `, - parserOptions, output: ` export default { data() { @@ -496,6 +495,7 @@ ruleTester.run('order-in-components', rule, { }; `, options: [{ order: ['data', 'test', 'name'] }], + parserOptions, errors: [ { message: @@ -515,7 +515,6 @@ ruleTester.run('order-in-components', rule, { name: 'burger' }; `, - parserOptions, output: ` export default { /** name of vue component */ @@ -525,6 +524,7 @@ ruleTester.run('order-in-components', rule, { } }; `, + parserOptions, errors: [ { message: @@ -544,7 +544,6 @@ ruleTester.run('order-in-components', rule, { name: 'burger' }; `, - parserOptions, output: ` export default { /** name of vue component */ @@ -554,6 +553,7 @@ ruleTester.run('order-in-components', rule, { }/*test*/ }; `, + parserOptions, errors: [ { message: @@ -565,8 +565,8 @@ ruleTester.run('order-in-components', rule, { { filename: 'example.vue', code: `export default {data(){},name:'burger'};`, - parserOptions, output: `export default {name:'burger',data(){}};`, + parserOptions, errors: [ { message: @@ -586,8 +586,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -607,8 +607,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -628,8 +628,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -649,8 +649,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -670,8 +670,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -691,8 +691,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -712,8 +712,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -733,8 +733,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -754,8 +754,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -775,8 +775,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -796,8 +796,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -817,8 +817,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -838,8 +838,8 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: null, + parserOptions, errors: [ { message: @@ -859,7 +859,6 @@ ruleTester.run('order-in-components', rule, { test: fn(), }; `, - parserOptions, output: ` export default { name: 'burger', @@ -868,6 +867,7 @@ ruleTester.run('order-in-components', rule, { test: fn(), }; `, + parserOptions, errors: [ { message: @@ -896,7 +896,6 @@ ruleTester.run('order-in-components', rule, { name: 'burger', }; `, - parserOptions, output: ` export default { name: 'burger', @@ -914,6 +913,7 @@ ruleTester.run('order-in-components', rule, { testOptionalChaining: a?.b?.c, }; `, + parserOptions, errors: [ { message: @@ -934,11 +934,6 @@ ruleTester.run('order-in-components', rule, { }; `, - parser: require.resolve('vue-eslint-parser'), - parserOptions: { - ...parserOptions, - parser: { ts: require.resolve('@typescript-eslint/parser') } - }, output: ` `, + parser: require.resolve('vue-eslint-parser'), + parserOptions: { + ...parserOptions, + parser: { ts: require.resolve('@typescript-eslint/parser') } + }, errors: [ { message: @@ -967,8 +967,6 @@ ruleTester.run('order-in-components', rule, { }) `, - parser: require.resolve('vue-eslint-parser'), - parserOptions, output: ` `, + parser: require.resolve('vue-eslint-parser'), + parserOptions, errors: [ { message: diff --git a/tests/lib/rules/padding-line-between-blocks.js b/tests/lib/rules/padding-line-between-blocks.js index 622839bdc..f53461bae 100644 --- a/tests/lib/rules/padding-line-between-blocks.js +++ b/tests/lib/rules/padding-line-between-blocks.js @@ -125,12 +125,12 @@ tester.run('padding-line-between-blocks', rule, { `, - options: ['never'], output: ` `, + options: ['never'], errors: [ { message: 'Unexpected blank line before this block.', @@ -214,7 +214,6 @@ tester.run('padding-line-between-blocks', rule, { `, - options: ['never'], output: ` @@ -225,6 +224,7 @@ tester.run('padding-line-between-blocks', rule, { `, + options: ['never'], errors: [ { message: 'Unexpected blank line before this block.', @@ -290,7 +290,6 @@ tester.run('padding-line-between-blocks', rule, { `, - options: ['never'], output: ` @@ -304,6 +303,7 @@ tester.run('padding-line-between-blocks', rule, { TEXT `, + options: ['never'], errors: [ { message: 'Unexpected blank line before this block.', diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index 67aa6b228..70c7a57bb 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -498,18 +498,18 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'always', prev: '*', next: '*' }, + { blankLine: 'never', prev: 'br', next: '*' } + ] + ], errors: [ { message: 'Expected blank line before this tag.', line: 7, column: 13 } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: '*' } - ] ] }, { @@ -541,18 +541,18 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'always', prev: '*', next: '*' }, + { blankLine: 'never', prev: '*', next: 'br' } + ] + ], errors: [ { message: 'Expected blank line before this tag.', line: 8, column: 13 } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: '*', next: 'br' } - ] ] }, { @@ -586,6 +586,7 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'never', prev: '*', next: '*' }]], errors: [ { message: 'Unexpected blank line before this tag.', @@ -597,8 +598,7 @@ tester.run('padding-line-between-tags', rule, { line: 11, column: 13 } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -624,6 +624,7 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'never', prev: '*', next: '*' }]], errors: [ { message: 'Unexpected blank line before this tag.', @@ -635,8 +636,7 @@ tester.run('padding-line-between-tags', rule, { line: 9, column: 11 } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -669,18 +669,18 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'never', prev: '*', next: '*' }, + { blankLine: 'always', prev: 'br', next: 'div' } + ] + ], errors: [ { message: 'Expected blank line before this tag.', line: 8, column: 13 } - ], - options: [ - [ - { blankLine: 'never', prev: '*', next: '*' }, - { blankLine: 'always', prev: 'br', next: 'div' } - ] ] }, { @@ -712,6 +712,13 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'always', prev: '*', next: '*' }, + { blankLine: 'never', prev: 'br', next: 'div' }, + { blankLine: 'never', prev: 'br', next: 'img' } + ] + ], errors: [ { message: 'Expected blank line before this tag.', @@ -728,13 +735,6 @@ tester.run('padding-line-between-tags', rule, { line: 9, column: 11 } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: 'div' }, - { blankLine: 'never', prev: 'br', next: 'img' } - ] ] }, { @@ -764,18 +764,18 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'always', prev: 'br', next: 'div' }, + { blankLine: 'always', prev: 'div', next: 'br' } + ] + ], errors: [ { message: 'Expected blank line before this tag.', line: 8, column: 11 } - ], - options: [ - [ - { blankLine: 'always', prev: 'br', next: 'div' }, - { blankLine: 'always', prev: 'div', next: 'br' } - ] ] }, { @@ -805,18 +805,18 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'always', prev: 'br', next: 'div' }, + { blankLine: 'always', prev: 'br', next: 'br' } + ] + ], errors: [ { message: 'Expected blank line before this tag.', line: 9, column: 11 } - ], - options: [ - [ - { blankLine: 'always', prev: 'br', next: 'div' }, - { blankLine: 'always', prev: 'br', next: 'br' } - ] ] }, { @@ -848,6 +848,12 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'always', prev: '*', next: '*' }, + { blankLine: 'never', prev: 'br', next: 'br' } + ] + ], errors: [ { message: 'Expected blank line before this tag.', @@ -864,12 +870,6 @@ tester.run('padding-line-between-tags', rule, { line: 10, column: 11 } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: 'br' } - ] ] }, { @@ -901,14 +901,14 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'never', prev: 'br', next: 'br' }]], errors: [ { message: 'Unexpected blank line before this tag.', line: 11, column: 11 } - ], - options: [[{ blankLine: 'never', prev: 'br', next: 'br' }]] + ] }, { filename: 'test.vue', @@ -935,14 +935,14 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'always', prev: '*', next: 'br' }]], errors: [ { message: 'Expected blank line before this tag.', line: 7, column: 11 } - ], - options: [[{ blankLine: 'always', prev: '*', next: 'br' }]] + ] }, { filename: 'test.vue', @@ -1015,14 +1015,14 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'never', prev: '*', next: '*' }]], errors: [ { message: 'Unexpected blank line before this tag.', line: 6, column: 12 } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -1045,14 +1045,14 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'never', prev: '*', next: '*' }]], errors: [ { message: 'Unexpected blank line before this tag.', line: 7, column: 12 } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -1076,14 +1076,14 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'never', prev: '*', next: '*' }]], errors: [ { message: 'Unexpected blank line before this tag.', line: 8, column: 12 } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -1109,14 +1109,14 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'never', prev: '*', next: '*' }]], errors: [ { message: 'Unexpected blank line before this tag.', line: 10, column: 12 } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -1147,14 +1147,14 @@ tester.run('padding-line-between-tags', rule, {
`, + options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]], errors: [ { message: 'Expected blank line before this tag.', line: 7, column: 11 } - ], - options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -1191,6 +1191,7 @@ tester.run('padding-line-between-tags', rule, {
`, + options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]], errors: [ { message: 'Expected blank line before this tag.', @@ -1207,8 +1208,7 @@ tester.run('padding-line-between-tags', rule, { line: 9, column: 11 } - ], - options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]] + ] }, { filename: 'test.vue', @@ -1243,6 +1243,12 @@ tester.run('padding-line-between-tags', rule, { `, + options: [ + [ + { blankLine: 'consistent', prev: '*', next: '*' }, + { blankLine: 'never', prev: 'br', next: 'br' } + ] + ], errors: [ { message: 'Unexpected blank line before this tag.', @@ -1259,12 +1265,6 @@ tester.run('padding-line-between-tags', rule, { line: 13, column: 11 } - ], - options: [ - [ - { blankLine: 'consistent', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: 'br' } - ] ] }, { @@ -1288,14 +1288,14 @@ tester.run('padding-line-between-tags', rule, { `, + options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]], errors: [ { message: 'Unexpected blank line before this tag.', line: 7, column: 11 } - ], - options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]] + ] } ] }) diff --git a/tests/lib/rules/prefer-true-attribute-shorthand.js b/tests/lib/rules/prefer-true-attribute-shorthand.js index e7d52ef7f..0bad5c173 100644 --- a/tests/lib/rules/prefer-true-attribute-shorthand.js +++ b/tests/lib/rules/prefer-true-attribute-shorthand.js @@ -157,6 +157,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { `, + output: null, errors: [ { messageId: 'expectShort', @@ -172,8 +173,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { } ] } - ], - output: null + ] }, { filename: 'test.vue', @@ -181,6 +181,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { `, + output: null, errors: [ { messageId: 'expectShort', @@ -196,8 +197,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { } ] } - ], - output: null + ] }, { filename: 'test.vue', @@ -205,6 +205,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { `, + output: null, options: ['always'], errors: [ { @@ -221,8 +222,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { } ] } - ], - output: null + ] }, { filename: 'test.vue', @@ -230,6 +230,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { `, + output: null, options: ['always'], errors: [ { @@ -246,8 +247,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { } ] } - ], - output: null + ] }, { filename: 'test.vue', @@ -255,6 +255,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { `, + output: null, options: ['never'], errors: [ { @@ -276,8 +277,7 @@ tester.run('prefer-true-attribute-shorthand', rule, { } ] } - ], - output: null + ] } ] }) diff --git a/tests/lib/rules/require-emit-validator.js b/tests/lib/rules/require-emit-validator.js index 2b60e8910..d539b55ea 100644 --- a/tests/lib/rules/require-emit-validator.js +++ b/tests/lib/rules/require-emit-validator.js @@ -118,8 +118,8 @@ ruleTester.run('require-emit-validator', rule, { } }) `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', @@ -132,8 +132,8 @@ ruleTester.run('require-emit-validator', rule, { }, }) `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', @@ -333,8 +333,8 @@ ruleTester.run('require-emit-validator', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'missing', diff --git a/tests/lib/rules/require-explicit-emits.js b/tests/lib/rules/require-explicit-emits.js index 43a3c2599..af90569dd 100644 --- a/tests/lib/rules/require-explicit-emits.js +++ b/tests/lib/rules/require-explicit-emits.js @@ -1975,14 +1975,14 @@ emits: {'foo': null} emit('baz') emit('qux') `, - ...getTypeScriptFixtureTestOptions(), errors: [ { message: 'The "qux" event has been triggered but not declared on `defineEmits`.', line: 8 } - ] + ], + ...getTypeScriptFixtureTestOptions() } ] }) diff --git a/tests/lib/rules/require-expose.js b/tests/lib/rules/require-expose.js index 64d073c24..76932cd95 100644 --- a/tests/lib/rules/require-expose.js +++ b/tests/lib/rules/require-expose.js @@ -95,15 +95,13 @@ tester.run('require-expose', rule, { ` }, - { - code: ` + ` Vue.mixin({ methods: { foo () {} } }) - ` - }, + `, { filename: 'test.vue', code: ` diff --git a/tests/lib/rules/require-macro-variable-name.js b/tests/lib/rules/require-macro-variable-name.js index c54c224a5..ed99a64e5 100644 --- a/tests/lib/rules/require-macro-variable-name.js +++ b/tests/lib/rules/require-macro-variable-name.js @@ -237,6 +237,7 @@ tester.run('require-macro-variable-name', rule, { const attrs = useAttrs({}) `, + options: [customOptions], errors: [ { message: `The variable name of "defineSlots" must be "${customOptions.defineSlots}".`, @@ -289,8 +290,7 @@ tester.run('require-macro-variable-name', rule, { } ] } - ], - options: [customOptions] + ] }, { filename: 'test.vue', @@ -300,6 +300,7 @@ tester.run('require-macro-variable-name', rule, { const attrsCustom = useAttrs({}) `, + options: [{ defineSlots: 'slotsCustom' }], errors: [ { message: `The variable name of "useAttrs" must be "attrs".`, @@ -317,8 +318,7 @@ tester.run('require-macro-variable-name', rule, { } ] } - ], - options: [{ defineSlots: 'slotsCustom' }] + ] } ] }) diff --git a/tests/lib/rules/require-prop-comment.js b/tests/lib/rules/require-prop-comment.js index 900f25ec3..3863abc3d 100644 --- a/tests/lib/rules/require-prop-comment.js +++ b/tests/lib/rules/require-prop-comment.js @@ -20,8 +20,7 @@ const tester = new RuleTester({ tester.run('require-prop-comment', rule, { valid: [ - { - code: ` + ` - ` - }, + `, { code: ` - ` - }, + `, { code: ` `, + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + }, errors: [ { line: 4, column: 9, message: 'The "a" property should have a JSDoc comment.' } - ], - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } + ] } ] }) diff --git a/tests/lib/rules/require-prop-type-constructor.js b/tests/lib/rules/require-prop-type-constructor.js index 9cd4eae6e..a4d6766df 100644 --- a/tests/lib/rules/require-prop-type-constructor.js +++ b/tests/lib/rules/require-prop-type-constructor.js @@ -224,13 +224,13 @@ ruleTester.run('require-prop-type-constructor', rule, { } } `, + parser: require.resolve('@typescript-eslint/parser'), errors: [ { message: 'The "a" property should be a constructor.', line: 5 } - ], - parser: require.resolve('@typescript-eslint/parser') + ] }, { filename: 'ExtraCommas.vue', @@ -248,13 +248,13 @@ ruleTester.run('require-prop-type-constructor', rule, { } } `, + parser: require.resolve('@typescript-eslint/parser'), errors: [ { message: 'The "name" property should be a constructor.', line: 4 } - ], - parser: require.resolve('@typescript-eslint/parser') + ] }, { filename: 'LiteralsComponent.vue', diff --git a/tests/lib/rules/require-prop-types.js b/tests/lib/rules/require-prop-types.js index 9b7077fc1..fdb91dd30 100644 --- a/tests/lib/rules/require-prop-types.js +++ b/tests/lib/rules/require-prop-types.js @@ -137,8 +137,8 @@ ruleTester.run('require-prop-types', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', @@ -151,8 +151,8 @@ ruleTester.run('require-prop-types', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', @@ -163,8 +163,8 @@ ruleTester.run('require-prop-types', rule, { }) `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, - parser: require.resolve('vue-eslint-parser') + parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', @@ -173,12 +173,12 @@ ruleTester.run('require-prop-types', rule, { defineProps<{foo:string}>() `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } }, { code: ` @@ -308,8 +308,8 @@ ruleTester.run('require-prop-types', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { message: 'Prop "foo" should define at least its type.', @@ -326,8 +326,8 @@ ruleTester.run('require-prop-types', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { message: 'Prop "foo" should define at least its type.', @@ -344,8 +344,8 @@ ruleTester.run('require-prop-types', rule, { }) `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { message: 'Prop "foo" should define at least its type.', @@ -360,8 +360,8 @@ ruleTester.run('require-prop-types', rule, { defineProps(['foo']) `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { message: 'Prop "foo" should define at least its type.', diff --git a/tests/lib/rules/require-typed-object-prop.js b/tests/lib/rules/require-typed-object-prop.js index 5d93965a5..f574e82d8 100644 --- a/tests/lib/rules/require-typed-object-prop.js +++ b/tests/lib/rules/require-typed-object-prop.js @@ -14,235 +14,235 @@ ruleTester.run('require-typed-object-prop', rule, { // empty { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default { props: {} } - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default Vue.extend({ props: {} }); - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` `, - parser: require.resolve('vue-eslint-parser') + parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, // array props { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default { props: ['foo'] } - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default Vue.extend({ props: ['foo'] }); - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` `, - parser: require.resolve('vue-eslint-parser') + parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, // primitive props { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default { props: { foo: String } } - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default Vue.extend({ props: { foo: String } }); - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` `, - parser: require.resolve('vue-eslint-parser') + parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, // union { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default { props: { foo: [Number, String, Boolean] } } - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default Vue.extend({ props: { foo: [Number, String, Boolean] } }); - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` `, - parser: require.resolve('vue-eslint-parser') + parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, // function { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default { props: { foo: someFunction() } } - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default Vue.extend({ props: { foo: someFunction() } }); - ` + `, + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` `, - parser: require.resolve('vue-eslint-parser') + parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, // typed object { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default { props: { foo: Object as PropType } } `, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default { props: { foo: Array as PropType } } `, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, code: ` export default Vue.extend({ props: { foo: Object as PropType } }); `, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', - parserOptions: { - ecmaVersion: 6, - sourceType: 'module', - parser: require.resolve('@typescript-eslint/parser') - }, code: ` `, - parser: require.resolve('vue-eslint-parser') - }, - - { - filename: 'test.vue', + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, + } + }, + + { + filename: 'test.vue', code: ` export default { props: { foo: Object as () => User } } `, - parser: require.resolve('@typescript-eslint/parser') - }, - { - filename: 'test.vue', + parser: require.resolve('@typescript-eslint/parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, + } + }, + { + filename: 'test.vue', code: ` export default Vue.extend({ props: { foo: Object as () => User } }); `, - parser: require.resolve('@typescript-eslint/parser') - }, - { - filename: 'test.vue', + parser: require.resolve('@typescript-eslint/parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, + } + }, + { + filename: 'test.vue', code: ` `, - parser: require.resolve('vue-eslint-parser') + parser: require.resolve('vue-eslint-parser'), + parserOptions: { + ecmaVersion: 6, + sourceType: 'module', + parser: require.resolve('@typescript-eslint/parser') + } }, // any { @@ -252,12 +252,12 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: { type: Object as any } }); `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } }, { filename: 'test.vue', @@ -270,12 +270,12 @@ ruleTester.run('require-typed-object-prop', rule, { }; `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } }, { filename: 'test.vue', @@ -288,12 +288,12 @@ ruleTester.run('require-typed-object-prop', rule, { }); `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } }, // unknown { @@ -303,12 +303,12 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: { type: Object as unknown } }); `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } }, { filename: 'test.vue', @@ -321,12 +321,12 @@ ruleTester.run('require-typed-object-prop', rule, { }; `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } }, { filename: 'test.vue', @@ -339,12 +339,12 @@ ruleTester.run('require-typed-object-prop', rule, { }); `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } } ], invalid: [ @@ -355,8 +355,8 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: Object }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'expectedTypeAnnotation', @@ -394,8 +394,8 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: Array }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'expectedTypeAnnotation', @@ -585,8 +585,8 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: { type: Object } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'expectedTypeAnnotation', diff --git a/tests/lib/rules/require-typed-ref.js b/tests/lib/rules/require-typed-ref.js index 571b5c5de..3da293b9a 100644 --- a/tests/lib/rules/require-typed-ref.js +++ b/tests/lib/rules/require-typed-ref.js @@ -75,13 +75,13 @@ tester.run('require-typed-ref', rule, { }, { filename: 'test.vue', - parser: require.resolve('vue-eslint-parser'), code: ` - ` + `, + parser: require.resolve('vue-eslint-parser') }, { filename: 'test.js', @@ -197,13 +197,13 @@ tester.run('require-typed-ref', rule, { }, { filename: 'test.vue', - parser: require.resolve('vue-eslint-parser'), code: ` `, + parser: require.resolve('vue-eslint-parser'), errors: [ { messageId: 'noType', diff --git a/tests/lib/rules/require-valid-default-prop.js b/tests/lib/rules/require-valid-default-prop.js index cec05ba05..1e6f7cd7a 100644 --- a/tests/lib/rules/require-valid-default-prop.js +++ b/tests/lib/rules/require-valid-default-prop.js @@ -122,8 +122,8 @@ ruleTester.run('require-valid-default-prop', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, - parser: require.resolve('@typescript-eslint/parser') + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' } }, { filename: 'test.vue', @@ -214,8 +214,8 @@ ruleTester.run('require-valid-default-prop', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: errorMessage('function') }, { @@ -229,8 +229,8 @@ ruleTester.run('require-valid-default-prop', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: errorMessage('function') }, { @@ -244,8 +244,8 @@ ruleTester.run('require-valid-default-prop', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: errorMessage('function') }, { @@ -264,12 +264,12 @@ ruleTester.run('require-valid-default-prop', rule, { num: 1 }); `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') - }, - parser: require.resolve('vue-eslint-parser') + } }, { code: ` @@ -614,8 +614,8 @@ ruleTester.run('require-valid-default-prop', rule, { } as PropOptions } });`, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: errorMessage('function or number') }, @@ -874,8 +874,8 @@ ruleTester.run('require-valid-default-prop', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: errorMessage('function') }, { @@ -889,8 +889,8 @@ ruleTester.run('require-valid-default-prop', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: errorMessage('function') }, { @@ -904,8 +904,8 @@ ruleTester.run('require-valid-default-prop', rule, { } }); `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: errorMessage('function') }, { @@ -920,8 +920,8 @@ ruleTester.run('require-valid-default-prop', rule, { }) `, - parserOptions: { ecmaVersion: 6, sourceType: 'module' }, parser: require.resolve('vue-eslint-parser'), + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { message: "Type of the default value for 'foo' prop must be a string.", @@ -938,12 +938,12 @@ ruleTester.run('require-valid-default-prop', rule, { }) `, + parser: require.resolve('vue-eslint-parser'), parserOptions: { ecmaVersion: 6, sourceType: 'module', parser: require.resolve('@typescript-eslint/parser') }, - parser: require.resolve('vue-eslint-parser'), errors: [ { message: "Type of the default value for 'foo' prop must be a string.", @@ -967,7 +967,6 @@ ruleTester.run('require-valid-default-prop', rule, { i: ['foo', 'bar'], }) `, - ...getTypeScriptFixtureTestOptions(), errors: [ { message: "Type of the default value for 'a' prop must be a string.", @@ -1006,7 +1005,8 @@ ruleTester.run('require-valid-default-prop', rule, { message: "Type of the default value for 'i' prop must be a function.", line: 13 } - ] + ], + ...getTypeScriptFixtureTestOptions() } ] }) diff --git a/tests/lib/rules/return-in-computed-property.js b/tests/lib/rules/return-in-computed-property.js index 9fbe2c84e..71afcc3eb 100644 --- a/tests/lib/rules/return-in-computed-property.js +++ b/tests/lib/rules/return-in-computed-property.js @@ -94,8 +94,8 @@ ruleTester.run('return-in-computed-property', rule, { } } `, - parserOptions, - options: [{ treatUndefinedAsUnspecified: false }] + options: [{ treatUndefinedAsUnspecified: false }], + parserOptions }, { filename: 'test.vue', @@ -144,8 +144,8 @@ ruleTester.run('return-in-computed-property', rule, { } } `, - parserOptions, - options: [{ treatUndefinedAsUnspecified: false }] + options: [{ treatUndefinedAsUnspecified: false }], + parserOptions } ], @@ -264,8 +264,8 @@ ruleTester.run('return-in-computed-property', rule, { } } `, - parserOptions, options: [{ treatUndefinedAsUnspecified: false }], + parserOptions, errors: [ { message: 'Expected to return a value in "foo" computed property.', @@ -284,8 +284,8 @@ ruleTester.run('return-in-computed-property', rule, { } } `, - parserOptions, options: [{ treatUndefinedAsUnspecified: true }], + parserOptions, errors: [ { message: 'Expected to return a value in "foo" computed property.', @@ -378,8 +378,8 @@ ruleTester.run('return-in-computed-property', rule, { } } `, - parserOptions, options: [{ treatUndefinedAsUnspecified: false }], + parserOptions, errors: [ { message: 'Expected to return a value in computed function.', diff --git a/tests/lib/rules/singleline-html-element-content-newline.js b/tests/lib/rules/singleline-html-element-content-newline.js index a740ff0ed..5bf2c9392 100644 --- a/tests/lib/rules/singleline-html-element-content-newline.js +++ b/tests/lib/rules/singleline-html-element-content-newline.js @@ -372,7 +372,6 @@ content
singleline content
`, - options: [{ ignoreWhenNoAttributes: false }], output: ` `, + options: [{ ignoreWhenNoAttributes: false }], 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.' @@ -391,7 +391,6 @@ singleline content singlelinechildren `, - options: [{ ignoreWhenNoAttributes: false }], output: ` `, + options: [{ ignoreWhenNoAttributes: false }], errors: [ 'Expected 1 line break after opening tag (``), but no line breaks found.', 'Expected 1 line break after opening tag (``), but no line breaks found.', @@ -418,7 +418,6 @@ children
`, - options: [{ ignoreWhenNoAttributes: false }], output: ` `, + options: [{ ignoreWhenNoAttributes: false }], 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.' @@ -437,7 +437,6 @@ children
singleline element
`, - options: [{ ignoreWhenNoAttributes: false }], output: ` `, + options: [{ ignoreWhenNoAttributes: false }], 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.' @@ -456,13 +456,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.' ] @@ -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, {