From ae790c6a91815221b9dd235c4bc48ee5d23786c3 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Tue, 9 Jul 2024 15:13:02 +0200 Subject: [PATCH 1/3] Fix `vue/require-typed-object-prop` tests `.vue` files need script tags --- tests/lib/rules/require-typed-object-prop.js | 265 +++++++------------ 1 file changed, 96 insertions(+), 169 deletions(-) diff --git a/tests/lib/rules/require-typed-object-prop.js b/tests/lib/rules/require-typed-object-prop.js index 9f5f000a9..8f430273c 100644 --- a/tests/lib/rules/require-typed-object-prop.js +++ b/tests/lib/rules/require-typed-object-prop.js @@ -9,7 +9,12 @@ const rule = require('../../../lib/rules/require-typed-object-prop') const ruleTester = new RuleTester({ languageOptions: { - parser: require('@typescript-eslint/parser') + parser: require('vue-eslint-parser'), + ecmaVersion: 6, + sourceType: 'module', + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + } } }) @@ -19,20 +24,22 @@ ruleTester.run('require-typed-object-prop', rule, { { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', @@ -40,31 +47,28 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module' - } + ` }, // array props { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', @@ -72,31 +76,28 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module' - } + ` }, // primitive props { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', @@ -104,31 +105,28 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module' - } + ` }, // union { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', @@ -136,31 +134,28 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module' - } + ` }, // function { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', @@ -168,40 +163,38 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module' - } + ` }, // typed object { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', @@ -209,42 +202,28 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } - } + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', code: ` + + ` }, { filename: 'test.vue', @@ -252,15 +231,7 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } - } + ` }, // any { @@ -269,15 +240,7 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } - } + ` }, { filename: 'test.vue', @@ -289,15 +252,7 @@ ruleTester.run('require-typed-object-prop', rule, { } }; - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } - } + ` }, { filename: 'test.vue', @@ -309,13 +264,7 @@ ruleTester.run('require-typed-object-prop', rule, { } }); - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { parser: require.resolve('@typescript-eslint/parser') } - } + ` }, // unknown { @@ -324,13 +273,7 @@ ruleTester.run('require-typed-object-prop', rule, { - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { parser: require.resolve('@typescript-eslint/parser') } - } + ` }, { filename: 'test.vue', @@ -342,13 +285,7 @@ ruleTester.run('require-typed-object-prop', rule, { } }; - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { parser: require.resolve('@typescript-eslint/parser') } - } + ` }, { filename: 'test.vue', @@ -360,13 +297,7 @@ ruleTester.run('require-typed-object-prop', rule, { } }); - `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { parser: require.resolve('@typescript-eslint/parser') } - } + ` } ], invalid: [ @@ -377,14 +308,6 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: Object }); `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } - }, errors: [ { messageId: 'expectedTypeAnnotation', @@ -422,14 +345,6 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: Array }); `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } - }, errors: [ { messageId: 'expectedTypeAnnotation', @@ -463,35 +378,40 @@ ruleTester.run('require-typed-object-prop', rule, { { filename: 'test.vue', code: ` + `, - languageOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'expectedTypeAnnotation', - line: 3, + line: 4, column: 23, - endLine: 3, + endLine: 4, endColumn: 29, suggestions: [ { messageId: 'addTypeAnnotation', data: { type: 'any' }, output: ` + ` }, { messageId: 'addTypeAnnotation', data: { type: 'unknown' }, output: ` + ` } ] @@ -501,35 +421,40 @@ ruleTester.run('require-typed-object-prop', rule, { { filename: 'test.vue', code: ` + `, - languageOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'expectedTypeAnnotation', - line: 3, + line: 4, column: 23, - endLine: 3, + endLine: 4, endColumn: 29, suggestions: [ { messageId: 'addTypeAnnotation', data: { type: 'any' }, output: ` + ` }, { messageId: 'addTypeAnnotation', data: { type: 'unknown' }, output: ` + ` } ] @@ -539,35 +464,40 @@ ruleTester.run('require-typed-object-prop', rule, { { filename: 'test.vue', code: ` + `, - languageOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'expectedTypeAnnotation', - line: 3, + line: 4, column: 31, - endLine: 3, + endLine: 4, endColumn: 37, suggestions: [ { messageId: 'addTypeAnnotation', data: { type: 'any' }, output: ` + ` }, { messageId: 'addTypeAnnotation', data: { type: 'unknown' }, output: ` + ` } ] @@ -577,35 +507,40 @@ ruleTester.run('require-typed-object-prop', rule, { { filename: 'test.vue', code: ` + `, - languageOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: [ { messageId: 'expectedTypeAnnotation', - line: 3, + line: 4, column: 31, - endLine: 3, + endLine: 4, endColumn: 37, suggestions: [ { messageId: 'addTypeAnnotation', data: { type: 'any' }, output: ` + ` }, { messageId: 'addTypeAnnotation', data: { type: 'unknown' }, output: ` + ` } ] @@ -619,14 +554,6 @@ ruleTester.run('require-typed-object-prop', rule, { defineProps({ foo: { type: Object } }); `, - languageOptions: { - parser: require('vue-eslint-parser'), - ecmaVersion: 6, - sourceType: 'module', - parserOptions: { - parser: require.resolve('@typescript-eslint/parser') - } - }, errors: [ { messageId: 'expectedTypeAnnotation', From 7f1a598232f714dda667f67a63987a8e6fd3e2ff Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Tue, 9 Jul 2024 15:15:04 +0200 Subject: [PATCH 2/3] Add test to make sure the rule works in `.ts` files --- tests/lib/rules/require-typed-object-prop.js | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/lib/rules/require-typed-object-prop.js b/tests/lib/rules/require-typed-object-prop.js index 8f430273c..4a7e53742 100644 --- a/tests/lib/rules/require-typed-object-prop.js +++ b/tests/lib/rules/require-typed-object-prop.js @@ -583,6 +583,44 @@ ruleTester.run('require-typed-object-prop', rule, { ] } ] + }, + { + // `.ts` file + filename: 'test.ts', + code: ` + export default Vue.extend({ + props: { foo: Object } + }); + `, + errors: [ + { + messageId: 'expectedTypeAnnotation', + line: 3, + column: 23, + endLine: 3, + endColumn: 29, + suggestions: [ + { + messageId: 'addTypeAnnotation', + data: { type: 'any' }, + output: ` + export default Vue.extend({ + props: { foo: Object as PropType } + }); + ` + }, + { + messageId: 'addTypeAnnotation', + data: { type: 'unknown' }, + output: ` + export default Vue.extend({ + props: { foo: Object as PropType } + }); + ` + } + ] + } + ] } ] }) From ff97a0b2327776c73c9e4c652ef2f220a3ec6c8a Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Tue, 9 Jul 2024 15:18:02 +0200 Subject: [PATCH 3/3] Exclude JavaScript components in `vue/require-typed-object-prop` --- lib/rules/require-typed-object-prop.js | 24 +++++++++++++++++ tests/lib/rules/require-typed-object-prop.js | 27 ++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/lib/rules/require-typed-object-prop.js b/lib/rules/require-typed-object-prop.js index ee88a0f35..eb7a278ae 100644 --- a/lib/rules/require-typed-object-prop.js +++ b/lib/rules/require-typed-object-prop.js @@ -129,6 +129,30 @@ module.exports = { }, /** @param {RuleContext} context */ create(context) { + const filename = context.getFilename() + if (!utils.isVueFile(filename) && !utils.isTypeScriptFile(filename)) { + return {} + } + + if (utils.isVueFile(filename)) { + const sourceCode = context.getSourceCode() + const documentFragment = + sourceCode.parserServices.getDocumentFragment && + sourceCode.parserServices.getDocumentFragment() + if (!documentFragment) { + return {} + } + const scripts = documentFragment.children.filter( + /** @returns {element is VElement} */ + (element) => utils.isVElement(element) && element.name === 'script' + ) + if ( + scripts.every((script) => !utils.hasAttribute(script, 'lang', 'ts')) + ) { + return {} + } + } + return utils.compositingVisitors( utils.defineScriptSetupVisitor(context, { onDefinePropsEnter(_node, props) { diff --git a/tests/lib/rules/require-typed-object-prop.js b/tests/lib/rules/require-typed-object-prop.js index 4a7e53742..8a16fb567 100644 --- a/tests/lib/rules/require-typed-object-prop.js +++ b/tests/lib/rules/require-typed-object-prop.js @@ -298,6 +298,33 @@ ruleTester.run('require-typed-object-prop', rule, { }); ` + }, + // JavaScript components + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.js', + code: ` + export default Vue.extend({ + props: { foo: Object } + }); + ` } ], invalid: [ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy