From 08ef531bde76dc77c25dc0cbece2b3bfaa299153 Mon Sep 17 00:00:00 2001 From: Attacktive <66462458+Attacktive@users.noreply.github.com> Date: Wed, 9 Jul 2025 18:03:32 +0900 Subject: [PATCH 001/121] docs: rephrase rule details (#2782) --- docs/rules/padding-line-between-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/padding-line-between-blocks.md b/docs/rules/padding-line-between-blocks.md index 4f3ee0290..645efeac7 100644 --- a/docs/rules/padding-line-between-blocks.md +++ b/docs/rules/padding-line-between-blocks.md @@ -14,7 +14,7 @@ since: v6.2.0 ## :book: Rule Details -This rule requires or disallows blank lines between the given 2 blocks. Properly blank lines help developers to understand the code. +This rule requires or disallows blank lines between blocks. Properly placed blank lines help developers understand the code. From a2e49a7a1a35d54651b3cc02745cb3ca606e1bee Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 9 Jul 2025 15:28:49 +0200 Subject: [PATCH 002/121] refactor: use regexp-groups to simplify ignores (#2776) Co-authored-by: Flo Edelmann --- lib/rules/attribute-hyphenation.js | 13 +- .../component-name-in-template-casing.js | 7 +- lib/rules/custom-event-name-casing.js | 7 +- lib/rules/no-restricted-block.js | 18 +-- lib/rules/no-restricted-class.js | 38 +----- lib/rules/no-restricted-component-names.js | 2 +- lib/rules/no-restricted-component-options.js | 18 +-- lib/rules/no-restricted-custom-event.js | 18 +-- lib/rules/no-restricted-props.js | 18 +-- lib/rules/no-restricted-static-attribute.js | 26 +--- lib/rules/no-restricted-v-bind.js | 22 +--- lib/rules/no-restricted-v-on.js | 23 +--- lib/rules/no-undef-properties.js | 9 +- lib/rules/prefer-true-attribute-shorthand.js | 7 +- lib/rules/prop-name-casing.js | 7 +- lib/rules/restricted-component-names.js | 7 +- lib/rules/syntaxes/slot-attribute.js | 14 +- lib/rules/v-on-event-hyphenation.js | 15 +-- lib/utils/regexp.js | 43 +++++- tests/lib/utils/regexp.js | 122 +++++++++++++++++- 20 files changed, 219 insertions(+), 215 deletions(-) diff --git a/lib/rules/attribute-hyphenation.js b/lib/rules/attribute-hyphenation.js index 65d096cd4..45e7ca687 100644 --- a/lib/rules/attribute-hyphenation.js +++ b/lib/rules/attribute-hyphenation.js @@ -6,7 +6,7 @@ const utils = require('../utils') const casing = require('../utils/casing') -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') const svgAttributes = require('../utils/svg-attributes-weird-case.json') /** @@ -79,11 +79,7 @@ module.exports = { const option = context.options[0] const optionsPayload = context.options[1] const useHyphenated = option !== 'never' - /** @type {RegExp[]} */ - const ignoredTagsRegexps = ( - (optionsPayload && optionsPayload.ignoreTags) || - [] - ).map(toRegExp) + const isIgnoredTagName = toRegExpGroupMatcher(optionsPayload?.ignoreTags) const ignoredAttributes = ['data-', 'aria-', 'slot-scope', ...svgAttributes] if (optionsPayload && optionsPayload.ignore) { @@ -142,11 +138,6 @@ module.exports = { return useHyphenated ? value.toLowerCase() === value : !/-/.test(value) } - /** @param {string} name */ - function isIgnoredTagName(name) { - return ignoredTagsRegexps.some((re) => re.test(name)) - } - return utils.defineTemplateBodyVisitor(context, { VAttribute(node) { const element = node.parent.parent diff --git a/lib/rules/component-name-in-template-casing.js b/lib/rules/component-name-in-template-casing.js index d330f60da..c7267cd49 100644 --- a/lib/rules/component-name-in-template-casing.js +++ b/lib/rules/component-name-in-template-casing.js @@ -6,7 +6,7 @@ const utils = require('../utils') const casing = require('../utils/casing') -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') const allowedCaseOptions = ['PascalCase', 'kebab-case'] const defaultCase = 'PascalCase' @@ -81,8 +81,7 @@ module.exports = { const caseType = allowedCaseOptions.includes(caseOption) ? caseOption : defaultCase - /** @type {RegExp[]} */ - const ignores = (options.ignores || []).map(toRegExp) + const isIgnored = toRegExpGroupMatcher(options.ignores) /** @type {string[]} */ const globals = (options.globals || []).map(casing.pascalCase) const registeredComponentsOnly = options.registeredComponentsOnly !== false @@ -116,7 +115,7 @@ module.exports = { * @returns {boolean} `true` if the given node is the verification target node. */ function isVerifyTarget(node) { - if (ignores.some((re) => re.test(node.rawName))) { + if (isIgnored(node.rawName)) { // ignore return false } diff --git a/lib/rules/custom-event-name-casing.js b/lib/rules/custom-event-name-casing.js index aff4609b5..c63b4e9d9 100644 --- a/lib/rules/custom-event-name-casing.js +++ b/lib/rules/custom-event-name-casing.js @@ -7,7 +7,7 @@ const { findVariable } = require('@eslint-community/eslint-utils') const utils = require('../utils') const casing = require('../utils/casing') -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') /** * @typedef {import('../utils').VueObjectData} VueObjectData @@ -92,8 +92,7 @@ module.exports = { const caseType = context.options[0] || DEFAULT_CASE const objectOption = context.options[1] || {} const caseChecker = casing.getChecker(caseType) - /** @type {RegExp[]} */ - const ignores = (objectOption.ignores || []).map(toRegExp) + const isIgnored = toRegExpGroupMatcher(objectOption.ignores) /** * Check whether the given event name is valid. @@ -109,7 +108,7 @@ module.exports = { */ function verify(nameWithLoc) { const name = nameWithLoc.name - if (isValidEventName(name) || ignores.some((re) => re.test(name))) { + if (isValidEventName(name) || isIgnored(name)) { return } context.report({ diff --git a/lib/rules/no-restricted-block.js b/lib/rules/no-restricted-block.js index 87b4bda3e..000e2c7b8 100644 --- a/lib/rules/no-restricted-block.js +++ b/lib/rules/no-restricted-block.js @@ -12,30 +12,16 @@ const regexp = require('../utils/regexp') * @property {string} [message] */ -/** - * @param {string} str - * @returns {(str: string) => boolean} - */ -function buildMatcher(str) { - if (regexp.isRegExp(str)) { - const re = regexp.toRegExp(str) - return (s) => { - re.lastIndex = 0 - return re.test(s) - } - } - return (s) => s === str -} /** * @param {any} option * @returns {ParsedOption} */ function parseOption(option) { if (typeof option === 'string') { - const matcher = buildMatcher(option) + const matcher = regexp.toRegExp(option, { remove: 'g' }) return { test(block) { - return matcher(block.rawName) + return matcher.test(block.rawName) } } } diff --git a/lib/rules/no-restricted-class.js b/lib/rules/no-restricted-class.js index 41d30df2d..1a74fd249 100644 --- a/lib/rules/no-restricted-class.js +++ b/lib/rules/no-restricted-class.js @@ -12,20 +12,10 @@ const regexp = require('../utils/regexp') * @param {string} className * @param {*} node * @param {RuleContext} context - * @param {Set} forbiddenClasses - * @param {Array} forbiddenClassesRegexps + * @param {(name: string) => boolean} isForbiddenClass */ -const reportForbiddenClass = ( - className, - node, - context, - forbiddenClasses, - forbiddenClassesRegexps -) => { - if ( - forbiddenClasses.has(className) || - forbiddenClassesRegexps.some((re) => re.test(className)) - ) { +const reportForbiddenClass = (className, node, context, isForbiddenClass) => { + if (isForbiddenClass(className)) { const loc = node.value ? node.value.loc : node.loc context.report({ node, @@ -123,10 +113,8 @@ module.exports = { /** @param {RuleContext} context */ create(context) { - const forbiddenClasses = new Set(context.options || []) - const forbiddenClassesRegexps = (context.options || []) - .filter((cl) => regexp.isRegExp(cl)) - .map((cl) => regexp.toRegExp(cl)) + const { options = [] } = context + const isForbiddenClass = regexp.toRegExpGroupMatcher(options) return utils.defineTemplateBodyVisitor(context, { /** @@ -134,13 +122,7 @@ module.exports = { */ 'VAttribute[directive=false][key.name="class"][value!=null]'(node) { for (const className of node.value.value.split(/\s+/)) { - reportForbiddenClass( - className, - node, - context, - forbiddenClasses, - forbiddenClassesRegexps - ) + reportForbiddenClass(className, node, context, isForbiddenClass) } }, @@ -155,13 +137,7 @@ module.exports = { for (const { className, reportNode } of extractClassNames( /** @type {Expression} */ (node.expression) )) { - reportForbiddenClass( - className, - reportNode, - context, - forbiddenClasses, - forbiddenClassesRegexps - ) + reportForbiddenClass(className, reportNode, context, isForbiddenClass) } } }) diff --git a/lib/rules/no-restricted-component-names.js b/lib/rules/no-restricted-component-names.js index e5111a748..df5ad4a23 100644 --- a/lib/rules/no-restricted-component-names.js +++ b/lib/rules/no-restricted-component-names.js @@ -22,7 +22,7 @@ const { isRegExp, toRegExp } = require('../utils/regexp') */ function buildMatcher(str) { if (isRegExp(str)) { - const regex = toRegExp(str) + const regex = toRegExp(str, { remove: 'g' }) return (s) => regex.test(s) } return (s) => s === casing.pascalCase(str) || s === casing.kebabCase(str) diff --git a/lib/rules/no-restricted-component-options.js b/lib/rules/no-restricted-component-options.js index b8563a92b..227a89382 100644 --- a/lib/rules/no-restricted-component-options.js +++ b/lib/rules/no-restricted-component-options.js @@ -23,21 +23,6 @@ const regexp = require('../utils/regexp') * @typedef { (node: Property | SpreadElement) => (MatchResult | null) } Tester */ -/** - * @param {string} str - * @returns {Matcher} - */ -function buildMatcher(str) { - if (regexp.isRegExp(str)) { - const re = regexp.toRegExp(str) - return (s) => { - re.lastIndex = 0 - return re.test(s) - } - } - return (s) => s === str -} - /** * @param {string | string[] | { name: string | string[], message?: string } } option * @returns {ParsedOption} @@ -65,7 +50,8 @@ function parseOption(option) { if (name === '*') { steps.push({ wildcard: true }) } else { - steps.push({ test: buildMatcher(name) }) + const matcher = regexp.toRegExp(name, { remove: 'g' }) + steps.push({ test: (value) => matcher.test(value) }) } } const message = option.message diff --git a/lib/rules/no-restricted-custom-event.js b/lib/rules/no-restricted-custom-event.js index 5ddda037f..93c1aa764 100644 --- a/lib/rules/no-restricted-custom-event.js +++ b/lib/rules/no-restricted-custom-event.js @@ -15,30 +15,16 @@ const regexp = require('../utils/regexp') * @property {string|undefined} [suggest] */ -/** - * @param {string} str - * @returns {(str: string) => boolean} - */ -function buildMatcher(str) { - if (regexp.isRegExp(str)) { - const re = regexp.toRegExp(str) - return (s) => { - re.lastIndex = 0 - return re.test(s) - } - } - return (s) => s === str -} /** * @param {string|{event: string, message?: string, suggest?: string}} option * @returns {ParsedOption} */ function parseOption(option) { if (typeof option === 'string') { - const matcher = buildMatcher(option) + const matcher = regexp.toRegExp(option, { remove: 'g' }) return { test(name) { - return matcher(name) + return matcher.test(name) } } } diff --git a/lib/rules/no-restricted-props.js b/lib/rules/no-restricted-props.js index 2d2f74bb0..e0684393d 100644 --- a/lib/rules/no-restricted-props.js +++ b/lib/rules/no-restricted-props.js @@ -18,30 +18,16 @@ const regexp = require('../utils/regexp') * @property {string|undefined} [suggest] */ -/** - * @param {string} str - * @returns {(str: string) => boolean} - */ -function buildMatcher(str) { - if (regexp.isRegExp(str)) { - const re = regexp.toRegExp(str) - return (s) => { - re.lastIndex = 0 - return re.test(s) - } - } - return (s) => s === str -} /** * @param {string|{name:string, message?: string, suggest?:string}} option * @returns {ParsedOption} */ function parseOption(option) { if (typeof option === 'string') { - const matcher = buildMatcher(option) + const matcher = regexp.toRegExp(option, { remove: 'g' }) return { test(name) { - return matcher(name) + return matcher.test(name) } } } diff --git a/lib/rules/no-restricted-static-attribute.js b/lib/rules/no-restricted-static-attribute.js index d9241620b..d7223044a 100644 --- a/lib/rules/no-restricted-static-attribute.js +++ b/lib/rules/no-restricted-static-attribute.js @@ -15,30 +15,16 @@ const regexp = require('../utils/regexp') * @property {string} [message] */ -/** - * @param {string} str - * @returns {(str: string) => boolean} - */ -function buildMatcher(str) { - if (regexp.isRegExp(str)) { - const re = regexp.toRegExp(str) - return (s) => { - re.lastIndex = 0 - return re.test(s) - } - } - return (s) => s === str -} /** * @param {any} option * @returns {ParsedOption} */ function parseOption(option) { if (typeof option === 'string') { - const matcher = buildMatcher(option) + const matcher = regexp.toRegExp(option, { remove: 'g' }) return { test({ key }) { - return matcher(key.rawName) + return matcher.test(key.rawName) } } } @@ -53,25 +39,25 @@ function parseOption(option) { return node.value == null || node.value.value === node.key.rawName } } else { - const valueMatcher = buildMatcher(option.value) + const valueMatcher = regexp.toRegExp(option.value, { remove: 'g' }) parsed.test = (node) => { if (!keyTest(node)) { return false } - return node.value != null && valueMatcher(node.value.value) + return node.value != null && valueMatcher.test(node.value.value) } } parsed.useValue = true } if (option.element) { const argTest = parsed.test - const tagMatcher = buildMatcher(option.element) + const tagMatcher = regexp.toRegExp(option.element, { remove: 'g' }) parsed.test = (node) => { if (!argTest(node)) { return false } const element = node.parent.parent - return tagMatcher(element.rawName) + return tagMatcher.test(element.rawName) } parsed.useElement = true } diff --git a/lib/rules/no-restricted-v-bind.js b/lib/rules/no-restricted-v-bind.js index f9bf5462b..e16622174 100644 --- a/lib/rules/no-restricted-v-bind.js +++ b/lib/rules/no-restricted-v-bind.js @@ -22,33 +22,19 @@ const DEFAULT_OPTIONS = [ } ] -/** - * @param {string} str - * @returns {(str: string) => boolean} - */ -function buildMatcher(str) { - if (regexp.isRegExp(str)) { - const re = regexp.toRegExp(str) - return (s) => { - re.lastIndex = 0 - return re.test(s) - } - } - return (s) => s === str -} /** * @param {any} option * @returns {ParsedOption} */ function parseOption(option) { if (typeof option === 'string') { - const matcher = buildMatcher(option) + const matcher = regexp.toRegExp(option, { remove: 'g' }) return { test(key) { return Boolean( key.argument && key.argument.type === 'VIdentifier' && - matcher(key.argument.rawName) + matcher.test(key.argument.rawName) ) }, modifiers: [] @@ -77,13 +63,13 @@ function parseOption(option) { } if (option.element) { const argTest = parsed.test - const tagMatcher = buildMatcher(option.element) + const tagMatcher = regexp.toRegExp(option.element, { remove: 'g' }) parsed.test = (key) => { if (!argTest(key)) { return false } const element = key.parent.parent.parent - return tagMatcher(element.rawName) + return tagMatcher.test(element.rawName) } parsed.useElement = true } diff --git a/lib/rules/no-restricted-v-on.js b/lib/rules/no-restricted-v-on.js index 2379df349..893d511a6 100644 --- a/lib/rules/no-restricted-v-on.js +++ b/lib/rules/no-restricted-v-on.js @@ -15,34 +15,19 @@ const regexp = require('../utils/regexp') * @property {string} [message] */ -/** - * @param {string} str - * @returns {(str: string) => boolean} - */ -function buildMatcher(str) { - if (regexp.isRegExp(str)) { - const re = regexp.toRegExp(str) - return (s) => { - re.lastIndex = 0 - return re.test(s) - } - } - return (s) => s === str -} - /** * @param {any} option * @returns {ParsedOption} */ function parseOption(option) { if (typeof option === 'string') { - const matcher = buildMatcher(option) + const matcher = regexp.toRegExp(option, { remove: 'g' }) return { test(key) { return Boolean( key.argument && key.argument.type === 'VIdentifier' && - matcher(key.argument.rawName) + matcher.test(key.argument.rawName) ) } } @@ -70,12 +55,12 @@ function parseOption(option) { } if (option.element) { const argTest = parsed.test - const tagMatcher = buildMatcher(option.element) + const tagMatcher = regexp.toRegExp(option.element, { remove: 'g' }) parsed.test = (key) => { if (!argTest(key)) { return false } - return tagMatcher(key.parent.parent.parent.rawName) + return tagMatcher.test(key.parent.parent.parent.rawName) } parsed.useElement = true } diff --git a/lib/rules/no-undef-properties.js b/lib/rules/no-undef-properties.js index 711c2ed22..3ff49bd83 100644 --- a/lib/rules/no-undef-properties.js +++ b/lib/rules/no-undef-properties.js @@ -6,7 +6,7 @@ const utils = require('../utils') const reserved = require('../utils/vue-reserved.json') -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') const { getStyleVariablesContext } = require('../utils/style-variables') const { definePropertyReferenceExtractor @@ -106,9 +106,8 @@ module.exports = { /** @param {RuleContext} context */ create(context) { const options = context.options[0] || {} - const ignores = /** @type {string[]} */ ( - options.ignores || [String.raw`/^\$/`] - ).map(toRegExp) + const { ignores = [String.raw`/^\$/`] } = options + const isIgnored = toRegExpGroupMatcher(ignores) const propertyReferenceExtractor = definePropertyReferenceExtractor(context) const programNode = context.getSourceCode().ast /** @@ -190,7 +189,7 @@ module.exports = { report(node, name, messageId = 'undef') { if ( reserved.includes(name) || - ignores.some((ignore) => ignore.test(name)) || + isIgnored(name) || propertiesDefinedByStoreHelpers.has(name) ) { return diff --git a/lib/rules/prefer-true-attribute-shorthand.js b/lib/rules/prefer-true-attribute-shorthand.js index 817525d1d..3f5446bda 100644 --- a/lib/rules/prefer-true-attribute-shorthand.js +++ b/lib/rules/prefer-true-attribute-shorthand.js @@ -4,7 +4,7 @@ */ 'use strict' -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') const utils = require('../utils') /** @@ -99,8 +99,7 @@ module.exports = { create(context) { /** @type {'always' | 'never'} */ const option = context.options[0] || 'always' - /** @type {RegExp[]} */ - const exceptReg = (context.options[1]?.except || []).map(toRegExp) + const exceptMatcher = toRegExpGroupMatcher(context.options[1]?.except) /** * @param {VAttribute | VDirective} node @@ -155,7 +154,7 @@ module.exports = { const name = getAttributeName(node) if (name === null) return - const isExcepted = exceptReg.some((re) => re.test(name)) + const isExcepted = exceptMatcher(name) if (shouldConvertToLongForm(node, isExcepted, option)) { const key = /** @type {VIdentifier} */ (node.key) diff --git a/lib/rules/prop-name-casing.js b/lib/rules/prop-name-casing.js index fd4f0dc31..7121c66c6 100644 --- a/lib/rules/prop-name-casing.js +++ b/lib/rules/prop-name-casing.js @@ -6,7 +6,7 @@ const utils = require('../utils') const casing = require('../utils/casing') -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') const allowedCaseOptions = ['camelCase', 'snake_case'] /** @@ -16,8 +16,7 @@ const allowedCaseOptions = ['camelCase', 'snake_case'] /** @param {RuleContext} context */ function create(context) { const options = context.options[0] - /** @type {RegExp[]} */ - const ignoreProps = (context.options[1]?.ignoreProps || []).map(toRegExp) + const isIgnoredProp = toRegExpGroupMatcher(context.options[1]?.ignoreProps) const caseType = allowedCaseOptions.includes(options) ? options : 'camelCase' const checker = casing.getChecker(caseType) @@ -30,7 +29,7 @@ function create(context) { if (propName == null) { continue } - if (!checker(propName) && !ignoreProps.some((re) => re.test(propName))) { + if (!checker(propName) && !isIgnoredProp(propName)) { context.report({ node: item.node, messageId: 'invalidCase', diff --git a/lib/rules/restricted-component-names.js b/lib/rules/restricted-component-names.js index 636224db6..89d04bfad 100644 --- a/lib/rules/restricted-component-names.js +++ b/lib/rules/restricted-component-names.js @@ -5,7 +5,7 @@ 'use strict' const utils = require('../utils') -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') const htmlElements = require('../utils/html-elements.json') const deprecatedHtmlElements = require('../utils/deprecated-html-elements.json') @@ -51,12 +51,11 @@ module.exports = { /** @param {RuleContext} context */ create(context) { const options = context.options[0] || {} - /** @type {RegExp[]} */ - const allow = (options.allow || []).map(toRegExp) + const isAllowed = toRegExpGroupMatcher(options.allow) /** @param {string} name */ function isAllowedTarget(name) { - return reservedNames.has(name) || allow.some((re) => re.test(name)) + return reservedNames.has(name) || isAllowed(name) } return utils.defineTemplateBodyVisitor(context, { diff --git a/lib/rules/syntaxes/slot-attribute.js b/lib/rules/syntaxes/slot-attribute.js index b77fc6c20..8d854230c 100644 --- a/lib/rules/syntaxes/slot-attribute.js +++ b/lib/rules/syntaxes/slot-attribute.js @@ -16,8 +16,7 @@ module.exports = { /** @type {{ ignore: string[] }} */ const options = context.options[0] || {} const { ignore = [] } = options - /** @type {RegExp[]} */ - const ignorePatterns = ignore.map(regexp.toRegExp) + const isAnyIgnored = regexp.toRegExpGroupMatcher(ignore) const sourceCode = context.getSourceCode() const tokenStore = @@ -125,15 +124,12 @@ module.exports = { */ function reportSlot(slotAttr) { const componentName = slotAttr.parent.parent.rawName - const componentNamePascalCase = casing.pascalCase(componentName) - const componentNameKebabCase = casing.kebabCase(componentName) if ( - ignorePatterns.some( - (pattern) => - pattern.test(componentName) || - pattern.test(componentNamePascalCase) || - pattern.test(componentNameKebabCase) + isAnyIgnored( + componentName, + casing.pascalCase(componentName), + casing.kebabCase(componentName) ) ) { return diff --git a/lib/rules/v-on-event-hyphenation.js b/lib/rules/v-on-event-hyphenation.js index c9fac76e8..056890fa0 100644 --- a/lib/rules/v-on-event-hyphenation.js +++ b/lib/rules/v-on-event-hyphenation.js @@ -2,7 +2,7 @@ const utils = require('../utils') const casing = require('../utils/casing') -const { toRegExp } = require('../utils/regexp') +const { toRegExpGroupMatcher } = require('../utils/regexp') module.exports = { meta: { @@ -63,11 +63,7 @@ module.exports = { const useHyphenated = option !== 'never' /** @type {string[]} */ const ignoredAttributes = (optionsPayload && optionsPayload.ignore) || [] - /** @type {RegExp[]} */ - const ignoredTagsRegexps = ( - (optionsPayload && optionsPayload.ignoreTags) || - [] - ).map(toRegExp) + const isIgnoredTag = toRegExpGroupMatcher(optionsPayload?.ignoreTags) const autofix = Boolean(optionsPayload && optionsPayload.autofix) const caseConverter = casing.getConverter( @@ -111,17 +107,12 @@ module.exports = { return useHyphenated ? value.toLowerCase() === value : !/-/.test(value) } - /** @param {string} name */ - function isIgnoredTagName(name) { - return ignoredTagsRegexps.some((re) => re.test(name)) - } - return utils.defineTemplateBodyVisitor(context, { "VAttribute[directive=true][key.name.name='on']"(node) { const element = node.parent.parent if ( !utils.isCustomComponent(element) || - isIgnoredTagName(element.rawName) + isIgnoredTag(element.rawName) ) { return } diff --git a/lib/utils/regexp.js b/lib/utils/regexp.js index 3ee40ae41..006568067 100644 --- a/lib/utils/regexp.js +++ b/lib/utils/regexp.js @@ -22,14 +22,25 @@ function escape(string) { * Strings like `"/^foo/i"` are converted to `/^foo/i` of `RegExp`. * * @param {string} string The string to convert. + * @param {{add?: string, remove?: string}} [flags] The flags to add or remove. + * - `add`: Flags to add to the `RegExp` (e.g. `'i'` for case-insensitive). + * - `remove`: Flags to remove from the `RegExp` (e.g. `'g'` to remove global matching). * @returns {RegExp} Returns the `RegExp`. */ -function toRegExp(string) { +function toRegExp(string, flags = {}) { const parts = RE_REGEXP_STR.exec(string) + const { add: forceAddFlags = '', remove: forceRemoveFlags = '' } = + typeof flags === 'object' ? flags : {} // Avoid issues when this is called directly from array.map if (parts) { - return new RegExp(parts[1], parts[2]) + return new RegExp( + parts[1], + parts[2].replace( + new RegExp(`[${forceAddFlags}${forceRemoveFlags}]`, 'g'), + '' + ) + forceAddFlags + ) } - return new RegExp(`^${escape(string)}$`) + return new RegExp(`^${escape(string)}$`, forceAddFlags) } /** @@ -41,8 +52,32 @@ function isRegExp(string) { return RE_REGEXP_STR.test(string) } +/** + * Converts an array of strings to a singular function to match any of them. + * This function converts each string to a `RegExp` and returns a function that checks all of them. + * + * @param {string[]} [patterns] The strings or regular expression strings to match. + * @returns {(...toCheck: string[]) => boolean} Returns a function that checks if any string matches any of the given patterns. + */ +function toRegExpGroupMatcher(patterns = []) { + if (patterns.length === 0) { + return () => false + } + + // In the future, we could optimize this by joining expressions with identical flags. + const regexps = patterns.map((pattern) => toRegExp(pattern, { remove: 'g' })) + + if (regexps.length === 1) { + return (...toCheck) => toCheck.some((str) => regexps[0].test(str)) + } + + return (...toCheck) => + regexps.some((regexp) => toCheck.some((str) => regexp.test(str))) +} + module.exports = { escape, toRegExp, - isRegExp + isRegExp, + toRegExpGroupMatcher } diff --git a/tests/lib/utils/regexp.js b/tests/lib/utils/regexp.js index 830fa2a11..e27a0596f 100644 --- a/tests/lib/utils/regexp.js +++ b/tests/lib/utils/regexp.js @@ -1,6 +1,10 @@ 'use strict' -const { escape, toRegExp } = require('../../../lib/utils/regexp') +const { + escape, + toRegExp, + toRegExpGroupMatcher +} = require('../../../lib/utils/regexp') const assert = require('assert') const ESCAPED = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\' @@ -35,4 +39,120 @@ describe('toRegExp()', () => { assert.deepEqual(toRegExp(`${/^bar/i}`), /^bar/i) assert.deepEqual(toRegExp(`${/[\sA-Z]+/u}`), /[\sA-Z]+/u) }) + + it('should handle simple patterns', () => { + const regex = toRegExp('foo') + assert.strictEqual(regex.test('foo'), true) + assert.strictEqual(regex.test('bar'), false) + assert.strictEqual(regex.test('foobar'), false) + assert.strictEqual(regex.test('afoo'), false) + assert.strictEqual(regex.test('afoobar'), false) + assert.strictEqual(regex.test('Foo'), false) + }) + + it('should handle simple patterns with added flags', () => { + const regex = toRegExp('foo', { add: 'i' }) + assert.strictEqual(regex.test('foo'), true) + assert.strictEqual(regex.test('bar'), false) + assert.strictEqual(regex.test('foobar'), false) + assert.strictEqual(regex.test('afoo'), false) + assert.strictEqual(regex.test('afoobar'), false) + assert.strictEqual(regex.test('Foo'), true) + }) + + it('should handle regexp patterns', () => { + const regex = toRegExp('/^foo/') + assert.strictEqual(regex.test('foo'), true) + assert.strictEqual(regex.test('bar'), false) + assert.strictEqual(regex.test('foobar'), true) + assert.strictEqual(regex.test('afoo'), false) + assert.strictEqual(regex.test('afoobar'), false) + assert.strictEqual(regex.test('Foo'), false) + }) + + it('should handle regexp patterns with attached flags', () => { + const regex = toRegExp('/^foo/i') + assert.strictEqual(regex.test('foo'), true) + assert.strictEqual(regex.test('bar'), false) + assert.strictEqual(regex.test('foobar'), true) + assert.strictEqual(regex.test('afoo'), false) + assert.strictEqual(regex.test('afoobar'), false) + assert.strictEqual(regex.test('Foo'), true) + }) + + it('should handle regexp patterns with added flags', () => { + const regex = toRegExp('/^foo/', { add: 'i' }) + assert.deepEqual(regex, /^foo/i) + assert.strictEqual(regex.test('foo'), true) + assert.strictEqual(regex.test('bar'), false) + assert.strictEqual(regex.test('foobar'), true) + assert.strictEqual(regex.test('afoo'), false) + assert.strictEqual(regex.test('afoobar'), false) + assert.strictEqual(regex.test('Foo'), true) + }) + + it('should handle regexp patterns with removed flags', () => { + const regex = toRegExp('/^foo/i', { remove: 'i' }) + assert.deepEqual(regex, /^foo/) + assert.strictEqual(regex.test('foo'), true) + assert.strictEqual(regex.test('bar'), false) + assert.strictEqual(regex.test('foobar'), true) + assert.strictEqual(regex.test('afoo'), false) + assert.strictEqual(regex.test('afoobar'), false) + assert.strictEqual(regex.test('Foo'), false) + }) +}) + +describe('toRegExpGroupMatcher()', () => { + it('should return a function missing input', () => { + const groupMatcher = toRegExpGroupMatcher() + assert.strictEqual(groupMatcher(''), false) + assert.strictEqual(groupMatcher('foo'), false) + assert.strictEqual(groupMatcher('bar'), false) + }) + + it('should return a function for empty array', () => { + const groupMatcher = toRegExpGroupMatcher([]) + assert.strictEqual(groupMatcher(''), false) + assert.strictEqual(groupMatcher('foo'), false) + assert.strictEqual(groupMatcher('bar'), false) + }) + + it('should return a function for single simple pattern', () => { + const groupMatcher = toRegExpGroupMatcher(['foo']) + assert.strictEqual(groupMatcher(''), false) + assert.strictEqual(groupMatcher('foo'), true) + assert.strictEqual(groupMatcher('foo', 'early'), true) + assert.strictEqual(groupMatcher('late', 'matches', 'foo'), true) + assert.strictEqual(groupMatcher('foobar'), false) + assert.strictEqual(groupMatcher('afoo', 'fooa', 'afooa', 'bar'), false) + }) + + it('should return a function for multiple simple patterns', () => { + const groupMatcher = toRegExpGroupMatcher(['foo', 'bar']) + assert.strictEqual(groupMatcher('foo'), true) + assert.strictEqual(groupMatcher('bar', 'early'), true) + assert.strictEqual(groupMatcher('late', 'matches', 'foo'), true) + assert.strictEqual(groupMatcher('foobar'), false) + assert.strictEqual(groupMatcher('afoo', 'fooa', 'afooa'), false) + }) + + it('should return a function for single regexp pattern', () => { + const groupMatcher = toRegExpGroupMatcher(['/^foo/g']) + assert.strictEqual(groupMatcher(''), false) + assert.strictEqual(groupMatcher('foo'), true) + assert.strictEqual(groupMatcher('fooa', 'early'), true) + assert.strictEqual(groupMatcher('late', 'matches', 'fooa'), true) + assert.strictEqual(groupMatcher('barfoo'), false) + assert.strictEqual(groupMatcher('afoo', 'afooa', 'bar'), false) + }) + + it('should return a function for multiple regexp patterns', () => { + const groupMatcher = toRegExpGroupMatcher(['/^foo/', '/bar$/gi']) + assert.strictEqual(groupMatcher('foo'), true) + assert.strictEqual(groupMatcher('Bar', 'early'), true) + assert.strictEqual(groupMatcher('late', 'matches', 'foo'), true) + assert.strictEqual(groupMatcher('barfoo'), false) + assert.strictEqual(groupMatcher('afoo', 'afooa', 'bara'), false) + }) }) From 3d9e15ed867342f746a6139dd8d1e45abb0516bd Mon Sep 17 00:00:00 2001 From: 2nofa11 <47783146+2nofa11@users.noreply.github.com> Date: Wed, 9 Jul 2025 23:37:10 +0900 Subject: [PATCH 003/121] docs: add Project Setup section to Developer Guide (#2780) Co-authored-by: Flo Edelmann --- docs/developer-guide/index.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/developer-guide/index.md b/docs/developer-guide/index.md index 2e1bb7da9..9bfc68007 100644 --- a/docs/developer-guide/index.md +++ b/docs/developer-guide/index.md @@ -8,6 +8,15 @@ If you think you’ve found a bug in ESLint, please [create a new issue](https:/ Please include as much detail as possible to help us properly address your issue. If we need to triage issues and constantly ask people for more detail, that’s time taken away from actually fixing issues. Help us be as efficient as possible by including a lot of detail in your issues. +## :seedling: Project Setup + +To develop locally, fork the eslint-plugin-vue repository and clone it in your local machine. Use the [npm](https://www.npmjs.com/) package manager to install and link dependencies and the LTS version of [Node.js](https://nodejs.org/). + +To develop and test the `eslint-plugin-vue` package: + +1. Run `npm install` in the project's root folder. +2. Run `npm test` to make sure everything is set up correctly. + ## :sparkles: Proposing a new rule or a rule change In order to add a new rule or a rule change, you should: From 26d99fda70e81b8d328f46122b670582366783ff Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Fri, 11 Jul 2025 18:09:07 +0800 Subject: [PATCH 004/121] test(require-explicit-slots): import slot type (#2786) --- tests/fixtures/typescript/src/test01.ts | 5 +++ tests/lib/rules/require-explicit-slots.js | 40 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/tests/fixtures/typescript/src/test01.ts b/tests/fixtures/typescript/src/test01.ts index d14550843..917643c67 100644 --- a/tests/fixtures/typescript/src/test01.ts +++ b/tests/fixtures/typescript/src/test01.ts @@ -18,3 +18,8 @@ export type Props2 = { h?: string[] i?: readonly string[] } + +export type Slots1 = { + default(props: { msg: string }): any + foo(props: { msg: string }): any +} diff --git a/tests/lib/rules/require-explicit-slots.js b/tests/lib/rules/require-explicit-slots.js index f99614119..afee739a6 100644 --- a/tests/lib/rules/require-explicit-slots.js +++ b/tests/lib/rules/require-explicit-slots.js @@ -6,6 +6,9 @@ const RuleTester = require('../../eslint-compat').RuleTester const rule = require('../../../lib/rules/require-explicit-slots') +const { + getTypeScriptFixtureTestOptions +} = require('../../test-utils/typescript') const tester = new RuleTester({ languageOptions: { @@ -276,6 +279,21 @@ tester.run('require-explicit-slots', rule, { }) ` }, + { + filename: 'test.vue', + code: ` + + `, + ...getTypeScriptFixtureTestOptions() + }, { filename: 'test.vue', code: ` @@ -656,6 +674,28 @@ tester.run('require-explicit-slots', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + message: 'Slots must be explicitly defined.', + line: 5, + column: 11 + } + ], + ...getTypeScriptFixtureTestOptions() + }, { // ignore attribute binding except string literal filename: 'test.vue', From 9140c63532991b1cb6261a837871f1b5e80b04a3 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 13 Jul 2025 09:54:58 +0200 Subject: [PATCH 005/121] feat(no-deprecated-slot-attribute): add ignoreParents option (#2784) Co-authored-by: Flo Edelmann --- .changeset/beige-teams-camp.md | 5 + docs/rules/no-deprecated-slot-attribute.md | 38 +++++- lib/rules/no-deprecated-slot-attribute.js | 5 + lib/rules/syntaxes/slot-attribute.js | 15 ++- lib/utils/index.js | 2 +- .../lib/rules/no-deprecated-slot-attribute.js | 108 ++++++++++++++++++ 6 files changed, 167 insertions(+), 6 deletions(-) create mode 100644 .changeset/beige-teams-camp.md diff --git a/.changeset/beige-teams-camp.md b/.changeset/beige-teams-camp.md new file mode 100644 index 000000000..49c2a317b --- /dev/null +++ b/.changeset/beige-teams-camp.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-vue': minor +--- + +Added `ignoreParents` option to [`vue/no-deprecated-slot-attribute`](https://eslint.vuejs.org/rules/no-deprecated-slot-attribute.html) diff --git a/docs/rules/no-deprecated-slot-attribute.md b/docs/rules/no-deprecated-slot-attribute.md index df4575cc4..34f941ec4 100644 --- a/docs/rules/no-deprecated-slot-attribute.md +++ b/docs/rules/no-deprecated-slot-attribute.md @@ -43,16 +43,18 @@ This rule reports deprecated `slot` attribute in Vue.js v2.6.0+. ```json { "vue/no-deprecated-slot-attribute": ["error", { - "ignore": ["my-component"] + "ignore": ["my-component"], + "ignoreParents": ["my-web-component"], }] } ``` - `"ignore"` (`string[]`) An array of tags or regular expression patterns (e.g. `/^custom-/`) that ignore these rules. This option will check both kebab-case and PascalCase versions of the given tag names. Default is empty. +- `"ignoreParents"` (`string[]`) An array of tags or regular expression patterns (e.g. `/^custom-/`) for parents that ignore these rules. This option is especially useful for [Web-Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components). Default is empty. ### `"ignore": ["my-component"]` - + ```vue `, options: [{ ignore: ['/one/', '/^Two$/i', '/^my-.*/i'] }] + }, + { + code: ``, + options: [{ ignoreParents: ['LinkList'] }] + }, + { + code: ``, + options: [{ ignoreParents: ['/^Link/'] }] } ], invalid: [ @@ -732,6 +756,90 @@ tester.run('no-deprecated-slot-attribute', rule, { } ] }, + { + code: ` + `, + output: ` + `, + options: [ + { + ignoreParents: ['my-component'] + } + ], + errors: [ + { + message: '`slot` attributes are deprecated.', + line: 9, + column: 16, + endLine: 9, + endColumn: 20 + } + ] + }, + { + code: ` + `, + output: ` + `, + options: [ + { + ignoreParents: ['/component$/'] + } + ], + errors: [ + { + message: '`slot` attributes are deprecated.', + line: 9, + column: 16, + endLine: 9, + endColumn: 20 + } + ] + }, { code: ` `, errors: [ - '`slot` attributes are deprecated.', - '`slot` attributes are deprecated.' + { + message: '`slot` attributes are deprecated.', + line: 4, + column: 37, + endLine: 4, + endColumn: 42 + }, + { + message: '`slot` attributes are deprecated.', + line: 7, + column: 37, + endLine: 7, + endColumn: 42 + } ] }, { @@ -646,8 +784,20 @@ tester.run('no-deprecated-slot-attribute', rule, { `, errors: [ - '`slot` attributes are deprecated.', - '`slot` attributes are deprecated.' + { + message: '`slot` attributes are deprecated.', + line: 4, + column: 41, + endLine: 4, + endColumn: 46 + }, + { + message: '`slot` attributes are deprecated.', + line: 7, + column: 37, + endLine: 7, + endColumn: 42 + } ] }, { @@ -678,7 +828,15 @@ tester.run('no-deprecated-slot-attribute', rule, { ignore: ['one'] } ], - errors: ['`slot` attributes are deprecated.'] + errors: [ + { + message: '`slot` attributes are deprecated.', + line: 7, + column: 16, + endLine: 7, + endColumn: 20 + } + ] }, { code: ` @@ -863,7 +1021,15 @@ tester.run('no-deprecated-slot-attribute', rule, { `, - errors: ['`slot` attributes are deprecated.'] + errors: [ + { + message: '`slot` attributes are deprecated.', + line: 6, + column: 13, + endLine: 6, + endColumn: 18 + } + ] }, { code: ` @@ -876,7 +1042,15 @@ tester.run('no-deprecated-slot-attribute', rule, { `, output: null, - errors: ['`slot` attributes are deprecated.'] + errors: [ + { + message: '`slot` attributes are deprecated.', + line: 4, + column: 16, + endLine: 4, + endColumn: 20 + } + ] } ] }) From cf3c4eb97e83d7190a035275b3e2f339e2ade8af Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Fri, 18 Jul 2025 09:04:24 +0200 Subject: [PATCH 009/121] test(array-bracket-newline): make tests more strict (#2799) --- tests/lib/rules/array-bracket-newline.js | 124 ++++++++++++++++++++--- 1 file changed, 110 insertions(+), 14 deletions(-) diff --git a/tests/lib/rules/array-bracket-newline.js b/tests/lib/rules/array-bracket-newline.js index 380f61e4f..0334d2942 100644 --- a/tests/lib/rules/array-bracket-newline.js +++ b/tests/lib/rules/array-bracket-newline.js @@ -40,61 +40,145 @@ tester.run('array-bracket-newline', rule, { { code: '', output: '', - errors: ["There should be no linebreak after '['."] + errors: [ + { + message: "There should be no linebreak after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + } + ] }, { code: '', output: '', - errors: ["There should be no linebreak before ']'."] + errors: [ + { + message: "There should be no linebreak before ']'.", + line: 2, + column: 1, + endLine: 2, + endColumn: 2 + } + ] }, { code: '', output: '', errors: [ - "There should be no linebreak after '['.", - "There should be no linebreak before ']'." + { + message: "There should be no linebreak after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + }, + { + message: "There should be no linebreak before ']'.", + line: 3, + column: 1, + endLine: 3, + endColumn: 2 + } ] }, { code: '', output: '', options: ['never'], - errors: ["There should be no linebreak after '['."] + errors: [ + { + message: "There should be no linebreak after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + } + ] }, { code: '', output: '', options: ['never'], - errors: ["There should be no linebreak before ']'."] + errors: [ + { + message: "There should be no linebreak before ']'.", + line: 2, + column: 1, + endLine: 2, + endColumn: 2 + } + ] }, { code: '', output: '', options: ['never'], errors: [ - "There should be no linebreak after '['.", - "There should be no linebreak before ']'." + { + message: "There should be no linebreak after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + }, + { + message: "There should be no linebreak before ']'.", + line: 3, + column: 1, + endLine: 3, + endColumn: 2 + } ] }, { code: '', output: '', options: ['always'], - errors: ["A linebreak is required before ']'."] + errors: [ + { + message: "A linebreak is required before ']'.", + line: 2, + column: 2, + endLine: 2, + endColumn: 3 + } + ] }, { code: '', output: '', options: ['always'], - errors: ["A linebreak is required after '['."] + errors: [ + { + message: "A linebreak is required after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + } + ] }, { code: '', output: '', options: ['always'], errors: [ - "A linebreak is required after '['.", - "A linebreak is required before ']'." + { + message: "A linebreak is required after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + }, + { + message: "A linebreak is required before ']'.", + line: 1, + column: 25, + endLine: 1, + endColumn: 26 + } ] }, { @@ -102,8 +186,20 @@ tester.run('array-bracket-newline', rule, { output: '', options: ['always'], errors: [ - "A linebreak is required after '['.", - "A linebreak is required before ']'." + { + message: "A linebreak is required after '['.", + line: 1, + column: 27, + endLine: 1, + endColumn: 28 + }, + { + message: "A linebreak is required before ']'.", + line: 1, + column: 29, + endLine: 1, + endColumn: 30 + } ] } ] From 5bde25ae9995461bd75e29457573d63ea21b63ee Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Fri, 18 Jul 2025 11:23:11 +0200 Subject: [PATCH 010/121] test(array-bracket-spacing): make tests more strict (#2800) --- tests/lib/rules/array-bracket-spacing.js | 124 ++++++++++++++++++++--- 1 file changed, 110 insertions(+), 14 deletions(-) diff --git a/tests/lib/rules/array-bracket-spacing.js b/tests/lib/rules/array-bracket-spacing.js index 1eea108e6..6218d232e 100644 --- a/tests/lib/rules/array-bracket-spacing.js +++ b/tests/lib/rules/array-bracket-spacing.js @@ -39,61 +39,145 @@ tester.run('array-bracket-spacing', rule, { { code: '', output: '', - errors: ["There should be no space after '['."] + errors: [ + { + message: "There should be no space after '['.", + line: 1, + column: 24, + endLine: 1, + endColumn: 25 + } + ] }, { code: '', output: '', - errors: ["There should be no space before ']'."] + errors: [ + { + message: "There should be no space before ']'.", + line: 1, + column: 25, + endLine: 1, + endColumn: 26 + } + ] }, { code: '', output: '', errors: [ - "There should be no space after '['.", - "There should be no space before ']'." + { + message: "There should be no space after '['.", + line: 1, + column: 24, + endLine: 1, + endColumn: 25 + }, + { + message: "There should be no space before ']'.", + line: 1, + column: 26, + endLine: 1, + endColumn: 27 + } ] }, { code: '', output: '', options: ['never'], - errors: ["There should be no space after '['."] + errors: [ + { + message: "There should be no space after '['.", + line: 1, + column: 24, + endLine: 1, + endColumn: 25 + } + ] }, { code: '', output: '', options: ['never'], - errors: ["There should be no space before ']'."] + errors: [ + { + message: "There should be no space before ']'.", + line: 1, + column: 25, + endLine: 1, + endColumn: 26 + } + ] }, { code: '', output: '', options: ['never'], errors: [ - "There should be no space after '['.", - "There should be no space before ']'." + { + message: "There should be no space after '['.", + line: 1, + column: 24, + endLine: 1, + endColumn: 25 + }, + { + message: "There should be no space before ']'.", + line: 1, + column: 26, + endLine: 1, + endColumn: 27 + } ] }, { code: '', output: '', options: ['always'], - errors: ["A space is required before ']'."] + errors: [ + { + message: "A space is required before ']'.", + line: 1, + column: 26, + endLine: 1, + endColumn: 27 + } + ] }, { code: '', output: '', options: ['always'], - errors: ["A space is required after '['."] + errors: [ + { + message: "A space is required after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + } + ] }, { code: '', output: '', options: ['always'], errors: [ - "A space is required after '['.", - "A space is required before ']'." + { + message: "A space is required after '['.", + line: 1, + column: 23, + endLine: 1, + endColumn: 24 + }, + { + message: "A space is required before ']'.", + line: 1, + column: 25, + endLine: 1, + endColumn: 26 + } ] }, { @@ -101,8 +185,20 @@ tester.run('array-bracket-spacing', rule, { output: '', options: ['always'], errors: [ - "A space is required after '['.", - "A space is required before ']'." + { + message: "A space is required after '['.", + line: 1, + column: 27, + endLine: 1, + endColumn: 28 + }, + { + message: "A space is required before ']'.", + line: 1, + column: 29, + endLine: 1, + endColumn: 30 + } ] } ] From 468789bfbf67691d4163f5808ce960d7b16f3f83 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Fri, 18 Jul 2025 15:04:17 +0200 Subject: [PATCH 011/121] test(arrow-spacing): make tests more strict (#2801) --- tests/lib/rules/arrow-spacing.js | 40 +++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/tests/lib/rules/arrow-spacing.js b/tests/lib/rules/arrow-spacing.js index d80c255e8..d05c9f269 100644 --- a/tests/lib/rules/arrow-spacing.js +++ b/tests/lib/rules/arrow-spacing.js @@ -48,11 +48,17 @@ tester.run('arrow-spacing', rule, { errors: [ { message: 'Missing space before =>.', - line: 3 + line: 3, + column: 24, + endLine: 3, + endColumn: 25 }, { message: 'Missing space after =>.', - line: 3 + line: 3, + column: 27, + endLine: 3, + endColumn: 28 } ] }, @@ -68,11 +74,17 @@ tester.run('arrow-spacing', rule, { errors: [ { message: 'Missing space before =>.', - line: 3 + line: 3, + column: 25, + endLine: 3, + endColumn: 26 }, { message: 'Missing space after =>.', - line: 3 + line: 3, + column: 28, + endLine: 3, + endColumn: 29 } ] }, @@ -94,11 +106,17 @@ tester.run('arrow-spacing', rule, { errors: [ { message: 'Missing space before =>.', - line: 4 + line: 4, + column: 25, + endLine: 4, + endColumn: 26 }, { message: 'Missing space after =>.', - line: 4 + line: 4, + column: 28, + endLine: 4, + endColumn: 29 } ] }, @@ -115,11 +133,17 @@ tester.run('arrow-spacing', rule, { errors: [ { message: 'Unexpected space before =>.', - line: 3 + line: 3, + column: 24, + endLine: 3, + endColumn: 25 }, { message: 'Unexpected space after =>.', - line: 3 + line: 3, + column: 29, + endLine: 3, + endColumn: 30 } ] } From f75a0030657c49fda257c720fcf9bf43852291a8 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Fri, 18 Jul 2025 15:06:54 +0200 Subject: [PATCH 012/121] test(attribute-hyphenation): make tests more strict (#2802) --- tests/lib/rules/attribute-hyphenation.js | 138 ++++++++++++++++++----- 1 file changed, 110 insertions(+), 28 deletions(-) diff --git a/tests/lib/rules/attribute-hyphenation.js b/tests/lib/rules/attribute-hyphenation.js index 738d59ae9..eac974e4e 100644 --- a/tests/lib/rules/attribute-hyphenation.js +++ b/tests/lib/rules/attribute-hyphenation.js @@ -118,7 +118,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'my-prop' can't be hyphenated.", type: 'VIdentifier', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 37 } ] }, @@ -131,7 +134,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'MyProp' must be hyphenated.", type: 'VIdentifier', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 36 } ] }, @@ -145,7 +151,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':my-prop' can't be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 39 } ] }, @@ -158,7 +167,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':MyProp' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 38 } ] }, @@ -172,7 +184,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-bind:my-prop' can't be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 45 } ] }, @@ -185,7 +200,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-bind:MyProp' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 44 } ] }, @@ -198,7 +216,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-bind:MyProp' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 44 } ] }, @@ -212,7 +233,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':second-prop' can't be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 46, + endLine: 1, + endColumn: 65 } ] }, @@ -226,7 +250,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-bind:myProp' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 44 } ] }, @@ -240,7 +267,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-bind:propID' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 44 } ] }, @@ -255,7 +285,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-model:my-prop' can't be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 46 } ] }, @@ -269,7 +302,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-model:myProp' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 45 } ] }, @@ -282,7 +318,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'v-model:MyProp' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 45 } ] }, @@ -307,7 +346,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'third-custom' can't be hyphenated.", type: 'VIdentifier', - line: 3 + line: 3, + column: 111, + endLine: 3, + endColumn: 129 } ] }, @@ -332,12 +374,18 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'custom-hyphen' can't be hyphenated.", type: 'VIdentifier', - line: 3 + line: 3, + column: 71, + endLine: 3, + endColumn: 90 }, { message: "Attribute 'second-custom' can't be hyphenated.", type: 'VIdentifier', - line: 3 + line: 3, + column: 91, + endLine: 3, + endColumn: 110 } ] }, @@ -350,7 +398,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'my-prop' can't be hyphenated.", type: 'VIdentifier', - line: 1 + line: 1, + column: 22, + endLine: 1, + endColumn: 35 } ] }, @@ -363,7 +414,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute 'MyProp' must be hyphenated.", type: 'VIdentifier', - line: 1 + line: 1, + column: 22, + endLine: 1, + endColumn: 34 } ] }, @@ -376,7 +430,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':attr_Gg' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 39 } ] }, @@ -389,7 +446,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':Attr_Hh' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 39 } ] }, @@ -402,7 +462,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':_attr_Jj' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 40 } ] }, @@ -415,7 +478,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':_attrKk' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 39 } ] }, @@ -428,7 +494,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':_AttrLl' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 39 } ] }, @@ -441,7 +510,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':my-custom_prop' can't be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 46 } ] }, @@ -454,7 +526,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':myAge.sync' must be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 42 } ] }, @@ -467,7 +542,10 @@ ruleTester.run('attribute-hyphenation', rule, { { message: "Attribute ':my-age.sync' can't be hyphenated.", type: 'VDirectiveKey', - line: 1 + line: 1, + column: 24, + endLine: 1, + endColumn: 43 } ] }, @@ -490,7 +568,9 @@ ruleTester.run('attribute-hyphenation', rule, { message: "Attribute 'my-prop' can't be hyphenated.", type: 'VIdentifier', line: 3, - column: 17 + column: 17, + endLine: 3, + endColumn: 24 } ] }, @@ -513,7 +593,9 @@ ruleTester.run('attribute-hyphenation', rule, { message: "Attribute 'myProp' must be hyphenated.", type: 'VIdentifier', line: 3, - column: 17 + column: 17, + endLine: 3, + endColumn: 23 } ] } From c66d6b641d8dd79596d9b31d9223640827c0f870 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Fri, 18 Jul 2025 16:35:14 +0200 Subject: [PATCH 013/121] test(block-lang): make tests more strict (#2804) --- tests/lib/rules/block-lang.js | 52 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/tests/lib/rules/block-lang.js b/tests/lib/rules/block-lang.js index 5f7851b54..ad1b9842c 100644 --- a/tests/lib/rules/block-lang.js +++ b/tests/lib/rules/block-lang.js @@ -44,7 +44,9 @@ tester.run('block-lang', rule, { { message: `Only "ts" can be used for the 'lang' attribute of ''.", line: 4, - column: 6 + column: 6, + endLine: 4, + endColumn: 6 } ] }, @@ -86,22 +94,30 @@ tester.run('block-tag-newline', rule, { { message: "A line break is required after ''.", line: 2, - column: 7 + column: 7, + endLine: 2, + endColumn: 7 }, { message: "A line break is required after ''.", line: 4, - column: 6 + column: 6, + endLine: 4, + endColumn: 6 } ] }, @@ -113,22 +129,30 @@ tester.run('block-tag-newline', rule, { { message: "There should be no line break after ' `, errors: [ - 'Expected no line breaks before closing bracket, but 1 line break found.', - 'Expected no line breaks before closing bracket, but 2 line breaks found.' + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 3, + column: 15, + endLine: 4, + endColumn: 11 + }, + { + message: + 'Expected no line breaks before closing bracket, but 2 line breaks found.', + line: 4, + column: 17, + endLine: 6, + endColumn: 11 + } ] }, { @@ -195,7 +209,14 @@ tester.run('html-closing-bracket-newline', rule, { `, errors: [ - 'Expected 1 line break before closing bracket, but no line breaks found.' + { + message: + 'Expected 1 line break before closing bracket, but no line breaks found.', + line: 4, + column: 18, + endLine: 4, + endColumn: 18 + } ] }, { @@ -219,8 +240,22 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected no line breaks before closing bracket, but 1 line break found.', - 'Expected no line breaks before closing bracket, but 2 line breaks found.' + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 3, + column: 15, + endLine: 4, + endColumn: 11 + }, + { + message: + 'Expected no line breaks before closing bracket, but 2 line breaks found.', + line: 4, + column: 17, + endLine: 6, + endColumn: 11 + } ] }, { @@ -246,7 +281,14 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected no line breaks before closing bracket, but 1 line break found.' + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 4, + column: 18, + endLine: 5, + endColumn: 13 + } ] }, { @@ -272,7 +314,14 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected 1 line break before closing bracket, but no line breaks found.' + { + message: + 'Expected 1 line break before closing bracket, but no line breaks found.', + line: 4, + column: 18, + endLine: 4, + endColumn: 18 + } ] }, { @@ -297,8 +346,22 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected no line breaks before closing bracket, but 1 line break found.', - 'Expected no line breaks before closing bracket, but 1 line break found.' + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 3, + column: 21, + endLine: 4, + endColumn: 11 + }, + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 5, + column: 16, + endLine: 6, + endColumn: 11 + } ] }, { @@ -329,8 +392,22 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected no line breaks before closing bracket, but 1 line break found.', - 'Expected 1 line break before closing bracket, but no line breaks found.' + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 5, + column: 18, + endLine: 6, + endColumn: 13 + }, + { + message: + 'Expected 1 line break before closing bracket, but no line breaks found.', + line: 7, + column: 16, + endLine: 7, + endColumn: 16 + } ] }, { @@ -359,8 +436,22 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected 1 line break before closing bracket, but no line breaks found.', - 'Expected 1 line break before closing bracket, but no line breaks found.' + { + message: + 'Expected 1 line break before closing bracket, but no line breaks found.', + line: 4, + column: 21, + endLine: 4, + endColumn: 21 + }, + { + message: + 'Expected 1 line break before closing bracket, but no line breaks found.', + line: 5, + column: 16, + endLine: 5, + endColumn: 16 + } ] }, { @@ -474,42 +565,48 @@ tester.run('html-closing-bracket-newline', rule, { 'Expected 1 line break before closing bracket, but no line breaks found.', line: 2, column: 18, - endColumn: 18 + endColumn: 18, + endLine: 2 }, { message: 'Expected 1 line break before closing bracket, but no line breaks found.', line: 3, column: 19, - endColumn: 19 + endColumn: 19, + endLine: 3 }, { message: 'Expected 1 line break before closing bracket, but no line breaks found.', line: 4, column: 16, - endColumn: 16 + endColumn: 16, + endLine: 4 }, { message: 'Expected 1 line break before closing bracket, but no line breaks found.', line: 5, column: 17, - endColumn: 17 + endColumn: 17, + endLine: 5 }, { message: 'Expected 1 line break before closing bracket, but no line breaks found.', line: 6, column: 15, - endColumn: 15 + endColumn: 15, + endLine: 6 }, { message: 'Expected 1 line break before closing bracket, but no line breaks found.', line: 6, column: 23, - endColumn: 23 + endColumn: 23, + endLine: 6 } ] }, @@ -534,7 +631,14 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected no line breaks before closing bracket, but 1 line break found.' + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 3, + column: 18, + endLine: 4, + endColumn: 11 + } ] }, { @@ -560,7 +664,14 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected 1 line break before closing bracket, but no line breaks found.' + { + message: + 'Expected 1 line break before closing bracket, but no line breaks found.', + line: 4, + column: 23, + endLine: 4, + endColumn: 23 + } ] }, { @@ -584,7 +695,14 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected 1 line break before closing bracket, but no line breaks found.' + { + message: + 'Expected 1 line break before closing bracket, but no line breaks found.', + line: 3, + column: 29, + endLine: 3, + endColumn: 29 + } ] }, { @@ -610,7 +728,14 @@ tester.run('html-closing-bracket-newline', rule, { } ], errors: [ - 'Expected no line breaks before closing bracket, but 1 line break found.' + { + message: + 'Expected no line breaks before closing bracket, but 1 line break found.', + line: 4, + column: 23, + endLine: 5, + endColumn: 11 + } ] } ] From dca0477c721025c83b419141cb001deb12159e9f Mon Sep 17 00:00:00 2001 From: 2nofa11 <47783146+2nofa11@users.noreply.github.com> Date: Mon, 28 Jul 2025 15:05:56 +0900 Subject: [PATCH 040/121] docs: fix typo 'identifer' to 'identifier' (#2855) --- docs/rules/match-component-import-name.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/match-component-import-name.md b/docs/rules/match-component-import-name.md index 522b90a02..5ba837f41 100644 --- a/docs/rules/match-component-import-name.md +++ b/docs/rules/match-component-import-name.md @@ -12,7 +12,7 @@ since: v8.7.0 ## :book: Rule Details -By default, this rule will validate that the imported name matches the name of the components object property identifer. Note that "matches" means that the imported name matches either the PascalCase or kebab-case version of the components object property identifer. If you would like to enforce that it must match only one of PascalCase or kebab-case, use this rule in conjunction with the rule [vue/component-definition-name-casing](./component-definition-name-casing.md). +By default, this rule will validate that the imported name matches the name of the components object property identifier. Note that "matches" means that the imported name matches either the PascalCase or kebab-case version of the components object property identifier. If you would like to enforce that it must match only one of PascalCase or kebab-case, use this rule in conjunction with the rule [vue/component-definition-name-casing](./component-definition-name-casing.md). From 1243d23e93b7bf80bffaddd80c1171a41d6e327b Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Mon, 28 Jul 2025 16:34:26 +0200 Subject: [PATCH 041/121] docs: fix link formatting in `vue/require-explicit-slots` docs --- docs/rules/require-explicit-slots.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/require-explicit-slots.md b/docs/rules/require-explicit-slots.md index 4d40be209..2737e7e6a 100644 --- a/docs/rules/require-explicit-slots.md +++ b/docs/rules/require-explicit-slots.md @@ -12,7 +12,7 @@ since: v9.21.0 ## :book: Rule Details -This rule enforces all slots used in the template to be defined once either in the `script setup` block with the [`defineSlots`](https://vuejs.org/api/sfc-script-setup.html#defineslots) macro, or with the [`slots property`](https://vuejs.org/api/options-rendering.html#slots) in the Options API. +This rule enforces all slots used in the template to be defined once either in the `script setup` block with the [`defineSlots` macro](https://vuejs.org/api/sfc-script-setup.html#defineslots), or with the [`slots` property](https://vuejs.org/api/options-rendering.html#slots) in the Options API. From 1bd95d3b342239fc53a02fc099ea162e28e6deaf Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Tue, 29 Jul 2025 06:35:54 +0200 Subject: [PATCH 042/121] test(mustache-interpolation-spacing): make tests more strict (#2854) --- .../rules/mustache-interpolation-spacing.js | 88 ++++++++++++++++--- 1 file changed, 78 insertions(+), 10 deletions(-) diff --git a/tests/lib/rules/mustache-interpolation-spacing.js b/tests/lib/rules/mustache-interpolation-spacing.js index 421b5a0d1..6f390b1ae 100644 --- a/tests/lib/rules/mustache-interpolation-spacing.js +++ b/tests/lib/rules/mustache-interpolation-spacing.js @@ -80,28 +80,60 @@ ruleTester.run('mustache-interpolation-spacing', rule, { code: '', output: '', options: ['always'], - errors: ["Expected 1 space before '}}', but not found."] + errors: [ + { + message: "Expected 1 space before '}}', but not found.", + line: 1, + column: 23, + endLine: 1, + endColumn: 25 + } + ] }, { filename: 'test.vue', code: '', output: '', options: ['always'], - errors: ["Expected 1 space after '{{', but not found."] + errors: [ + { + message: "Expected 1 space after '{{', but not found.", + line: 1, + column: 16, + endLine: 1, + endColumn: 18 + } + ] }, { filename: 'test.vue', code: '', output: '', options: ['never'], - errors: ["Expected no space after '{{', but found."] + errors: [ + { + message: "Expected no space after '{{', but found.", + line: 1, + column: 16, + endLine: 1, + endColumn: 19 + } + ] }, { filename: 'test.vue', code: '', output: '', options: ['never'], - errors: ["Expected no space before '}}', but found."] + errors: [ + { + message: "Expected no space before '}}', but found.", + line: 1, + column: 22, + endLine: 1, + endColumn: 25 + } + ] }, { filename: 'test.vue', @@ -109,8 +141,20 @@ ruleTester.run('mustache-interpolation-spacing', rule, { output: '', options: ['always'], errors: [ - "Expected 1 space after '{{', but not found.", - "Expected 1 space before '}}', but not found." + { + message: "Expected 1 space after '{{', but not found.", + line: 1, + column: 16, + endLine: 1, + endColumn: 18 + }, + { + message: "Expected 1 space before '}}', but not found.", + line: 1, + column: 22, + endLine: 1, + endColumn: 24 + } ] }, { @@ -119,8 +163,20 @@ ruleTester.run('mustache-interpolation-spacing', rule, { output: '', options: ['never'], errors: [ - "Expected no space after '{{', but found.", - "Expected no space before '}}', but found." + { + message: "Expected no space after '{{', but found.", + line: 1, + column: 16, + endLine: 1, + endColumn: 19 + }, + { + message: "Expected no space before '}}', but found.", + line: 1, + column: 23, + endLine: 1, + endColumn: 26 + } ] }, { @@ -129,8 +185,20 @@ ruleTester.run('mustache-interpolation-spacing', rule, { output: '', options: ['never'], errors: [ - "Expected no space after '{{', but found.", - "Expected no space before '}}', but found." + { + message: "Expected no space after '{{', but found.", + line: 1, + column: 16, + endLine: 1, + endColumn: 21 + }, + { + message: "Expected no space before '}}', but found.", + line: 1, + column: 25, + endLine: 1, + endColumn: 30 + } ] } ] From 9ca49034b6f1d89d0e3808b1fee2990cec97b1ce Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Tue, 29 Jul 2025 06:37:42 +0200 Subject: [PATCH 043/121] test(multiline-ternary): make tests more strict (#2853) --- tests/lib/rules/multiline-ternary.js | 79 +++++++++++++++------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/tests/lib/rules/multiline-ternary.js b/tests/lib/rules/multiline-ternary.js index 87e3fe485..118cf6353 100644 --- a/tests/lib/rules/multiline-ternary.js +++ b/tests/lib/rules/multiline-ternary.js @@ -4,9 +4,8 @@ */ 'use strict' -const { RuleTester, ESLint } = require('../../eslint-compat') +const { RuleTester } = require('../../eslint-compat') const rule = require('../../../lib/rules/multiline-ternary') -const semver = require('semver') const tester = new RuleTester({ languageOptions: { @@ -80,8 +79,7 @@ tester.run('multiline-ternary', rule, { `, - output: semver.gte(ESLint.version, '7.1.0') - ? ` + output: ` - ` - : null, + `, options: ['always-multiline'], errors: [ { message: 'Expected newline between consequent and alternate of ternary expression.', line: 5, - column: 15 + column: 15, + endLine: 5, + endColumn: 30 } ] }, @@ -113,23 +112,23 @@ tester.run('multiline-ternary', rule, { `, - output: semver.gte(ESLint.version, '7.1.0') - ? ` + output: ` - ` - : null, + `, options: ['never'], errors: [ { message: 'Unexpected newline between test and consequent of ternary expression.', line: 4, - column: 21 + column: 21, + endLine: 4, + endColumn: 44 } ] }, @@ -143,8 +142,7 @@ tester.run('multiline-ternary', rule, { `, - output: semver.gte(ESLint.version, '7.1.0') - ? ` + output: ` - ` - : null, + `, errors: [ { message: 'Expected newline between test and consequent of ternary expression.', line: 4, - column: 21 + column: 21, + endLine: 4, + endColumn: 44 }, { message: 'Expected newline between consequent and alternate of ternary expression.', line: 4, - column: 47 + column: 47, + endLine: 4, + endColumn: 62 } ] }, @@ -180,8 +181,7 @@ tester.run('multiline-ternary', rule, { `, - output: semver.gte(ESLint.version, '7.1.0') - ? ` + output: ` - ` - : null, + `, errors: [ { message: 'Expected newline between test and consequent of ternary expression.', line: 4, - column: 21 + column: 21, + endLine: 4, + endColumn: 44 }, { message: 'Expected newline between consequent and alternate of ternary expression.', line: 4, - column: 47 + column: 47, + endLine: 4, + endColumn: 62 } ] }, @@ -220,8 +223,7 @@ tester.run('multiline-ternary', rule, { } `, - output: semver.gte(ESLint.version, '7.1.0') - ? ` + output: ` `, options: [anyWith({ html: { normal: 'always' } })], errors: [ - { message: 'Require self-closing on HTML elements (
).', line: 2 } + { + message: 'Require self-closing on HTML elements (
).', + line: 2, + column: 8, + endLine: 2, + endColumn: 14 + } ] }, { @@ -149,7 +196,13 @@ tester.run('html-self-closing', rule, { `, options: [anyWith({ html: { normal: 'never' } })], errors: [ - { message: 'Disallow self-closing on HTML elements (
).', line: 3 } + { + message: 'Disallow self-closing on HTML elements (
).', + line: 3, + column: 7, + endLine: 3, + endColumn: 9 + } ] }, { @@ -170,7 +223,10 @@ tester.run('html-self-closing', rule, { errors: [ { message: 'Require self-closing on HTML void elements ().', - line: 4 + line: 4, + column: 3, + endLine: 4, + endColumn: 8 } ] }, @@ -192,7 +248,10 @@ tester.run('html-self-closing', rule, { errors: [ { message: 'Disallow self-closing on HTML void elements ().', - line: 5 + line: 5, + column: 7, + endLine: 5, + endColumn: 9 } ] }, @@ -215,7 +274,10 @@ tester.run('html-self-closing', rule, { { message: 'Require self-closing on Vue.js custom components ().', - line: 6 + line: 6, + column: 11, + endLine: 6, + endColumn: 20 } ] }, @@ -238,7 +300,10 @@ tester.run('html-self-closing', rule, { { message: 'Disallow self-closing on Vue.js custom components ().', - line: 7 + line: 7, + column: 10, + endLine: 7, + endColumn: 12 } ] }, @@ -258,7 +323,13 @@ tester.run('html-self-closing', rule, { `, options: [anyWith({ svg: 'always' })], errors: [ - { message: 'Require self-closing on SVG elements ().', line: 8 } + { + message: 'Require self-closing on SVG elements ().', + line: 8, + column: 14, + endLine: 8, + endColumn: 21 + } ] }, { @@ -277,7 +348,13 @@ tester.run('html-self-closing', rule, { `, options: [anyWith({ svg: 'never' })], errors: [ - { message: 'Disallow self-closing on SVG elements ().', line: 9 } + { + message: 'Disallow self-closing on SVG elements ().', + line: 9, + column: 13, + endLine: 9, + endColumn: 15 + } ] }, { @@ -298,7 +375,10 @@ tester.run('html-self-closing', rule, { errors: [ { message: 'Require self-closing on MathML elements ().', - line: 10 + line: 10, + column: 17, + endLine: 10, + endColumn: 26 } ] }, @@ -320,7 +400,10 @@ tester.run('html-self-closing', rule, { errors: [ { message: 'Disallow self-closing on MathML elements ().', - line: 11 + line: 11, + column: 16, + endLine: 11, + endColumn: 18 } ] } From 6f1fae345ce5f8265822d8addf7fee2398f68b69 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Tue, 29 Jul 2025 06:45:12 +0200 Subject: [PATCH 056/121] test(html-quotes): make tests more strict (#2839) --- tests/lib/rules/html-quotes.js | 210 +++++++++++++++++++++++++++++---- 1 file changed, 189 insertions(+), 21 deletions(-) diff --git a/tests/lib/rules/html-quotes.js b/tests/lib/rules/html-quotes.js index 1c57f0a26..f6931f552 100644 --- a/tests/lib/rules/html-quotes.js +++ b/tests/lib/rules/html-quotes.js @@ -82,101 +82,221 @@ tester.run('html-quotes', rule, { filename: 'test.vue', code: '', output: '', - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 22, + endLine: 1, + endColumn: 25 + } + ] }, { filename: 'test.vue', code: "", output: '', - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 22, + endLine: 1, + endColumn: 27 + } + ] }, { filename: 'test.vue', code: '', output: '', - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 26 + } + ] }, { filename: 'test.vue', code: "", output: '', - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 28 + } + ] }, { filename: 'test.vue', code: '', output: '', - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 32 + } + ] }, { filename: 'test.vue', code: '', output: '', options: ['double'], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 22, + endLine: 1, + endColumn: 25 + } + ] }, { filename: 'test.vue', code: "", output: '', options: ['double'], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 22, + endLine: 1, + endColumn: 27 + } + ] }, { filename: 'test.vue', code: '', output: '', options: ['double'], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 26 + } + ] }, { filename: 'test.vue', code: "", output: '', options: ['double'], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 28 + } + ] }, { filename: 'test.vue', code: '', output: '', options: ['double'], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 32 + } + ] }, { filename: 'test.vue', code: '', output: "", options: ['single'], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 22, + endLine: 1, + endColumn: 25 + } + ] }, { filename: 'test.vue', code: '', output: "", options: ['single'], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 22, + endLine: 1, + endColumn: 27 + } + ] }, { filename: 'test.vue', code: '', output: "", options: ['single'], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 26 + } + ] }, { filename: 'test.vue', code: '', output: "", options: ['single'], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 28 + } + ] }, { filename: 'test.vue', code: "", output: "", options: ['single'], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 23, + endLine: 1, + endColumn: 32 + } + ] }, // avoidEscape { @@ -184,42 +304,90 @@ tester.run('html-quotes', rule, { code: "", output: '', options: ['double', { avoidEscape: true }], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 21, + endLine: 1, + endColumn: 26 + } + ] }, { filename: 'test.vue', code: '', output: "", options: ['single', { avoidEscape: true }], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 21, + endLine: 1, + endColumn: 26 + } + ] }, { filename: 'test.vue', code: '', output: "", options: ['double', { avoidEscape: true }], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 21, + endLine: 1, + endColumn: 28 + } + ] }, { filename: 'test.vue', code: "", output: '', options: ['single', { avoidEscape: true }], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 21, + endLine: 1, + endColumn: 28 + } + ] }, { filename: 'test.vue', code: '', output: '', options: ['double', { avoidEscape: true }], - errors: ['Expected to be enclosed by double quotes.'] + errors: [ + { + message: 'Expected to be enclosed by double quotes.', + line: 1, + column: 21, + endLine: 1, + endColumn: 32 + } + ] }, { filename: 'test.vue', code: '', output: "", options: ['single', { avoidEscape: true }], - errors: ['Expected to be enclosed by single quotes.'] + errors: [ + { + message: 'Expected to be enclosed by single quotes.', + line: 1, + column: 21, + endLine: 1, + endColumn: 32 + } + ] } ] }) From 1c3b24efadd452d02a121e446378146a378efadc Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 30 Jul 2025 04:33:47 +0200 Subject: [PATCH 057/121] test(html-closing-bracket-spacing): make tests more strict (#2833) --- .../lib/rules/html-closing-bracket-spacing.js | 66 ++++++++++++------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/tests/lib/rules/html-closing-bracket-spacing.js b/tests/lib/rules/html-closing-bracket-spacing.js index 09e2702e0..26139b225 100644 --- a/tests/lib/rules/html-closing-bracket-spacing.js +++ b/tests/lib/rules/html-closing-bracket-spacing.js @@ -50,19 +50,22 @@ ruleTester.run('html-closing-bracket-spacing', rule, { message: "Expected no space before '>', but found.", line: 2, column: 7, - endColumn: 9 + endColumn: 9, + endLine: 2 }, { message: "Expected no space before '>', but found.", line: 3, column: 8, - endColumn: 10 + endColumn: 10, + endLine: 3 }, { message: "Expected a space before '/>', but not found.", line: 4, column: 7, - endColumn: 9 + endColumn: 9, + endLine: 4 } ] }, @@ -74,13 +77,15 @@ ruleTester.run('html-closing-bracket-spacing', rule, { message: "Expected no space before '>', but found.", line: 2, column: 11, - endColumn: 13 + endColumn: 13, + endLine: 2 }, { message: "Expected a space before '/>', but not found.", line: 3, column: 11, - endColumn: 13 + endColumn: 13, + endLine: 3 } ] }, @@ -93,13 +98,15 @@ ruleTester.run('html-closing-bracket-spacing', rule, { message: "Expected no space before '>', but found.", line: 2, column: 15, - endColumn: 17 + endColumn: 17, + endLine: 2 }, { message: "Expected a space before '/>', but not found.", line: 3, column: 15, - endColumn: 17 + endColumn: 17, + endLine: 3 } ] }, @@ -119,37 +126,43 @@ ruleTester.run('html-closing-bracket-spacing', rule, { message: "Expected no space before '>', but found.", line: 2, column: 18, - endColumn: 20 + endColumn: 20, + endLine: 2 }, { message: "Expected no space before '>', but found.", line: 2, column: 30, - endColumn: 32 + endColumn: 32, + endLine: 2 }, { message: "Expected no space before '>', but found.", line: 3, column: 16, - endColumn: 18 + endColumn: 18, + endLine: 3 }, { message: "Expected no space before '>', but found.", line: 3, column: 26, - endColumn: 28 + endColumn: 28, + endLine: 3 }, { message: "Expected no space before '>', but found.", line: 4, column: 15, - endColumn: 17 + endColumn: 17, + endLine: 4 }, { message: "Expected no space before '>', but found.", line: 4, column: 24, - endColumn: 26 + endColumn: 26, + endLine: 4 } ] }, @@ -168,19 +181,22 @@ ruleTester.run('html-closing-bracket-spacing', rule, { message: "Expected a space before '>', but not found.", line: 2, column: 7, - endColumn: 8 + endColumn: 8, + endLine: 2 }, { message: "Expected a space before '>', but not found.", line: 3, column: 8, - endColumn: 9 + endColumn: 9, + endLine: 3 }, { message: "Expected no space before '/>', but found.", line: 4, column: 7, - endColumn: 10 + endColumn: 10, + endLine: 4 } ] }, @@ -207,37 +223,43 @@ ruleTester.run('html-closing-bracket-spacing', rule, { message: "Expected a space before '>', but not found.", line: 2, column: 18, - endColumn: 19 + endColumn: 19, + endLine: 2 }, { message: "Expected a space before '>', but not found.", line: 2, column: 29, - endColumn: 30 + endColumn: 30, + endLine: 2 }, { message: "Expected a space before '>', but not found.", line: 3, column: 16, - endColumn: 17 + endColumn: 17, + endLine: 3 }, { message: "Expected a space before '>', but not found.", line: 3, column: 25, - endColumn: 26 + endColumn: 26, + endLine: 3 }, { message: "Expected a space before '>', but not found.", line: 4, column: 15, - endColumn: 16 + endColumn: 16, + endLine: 4 }, { message: "Expected a space before '>', but not found.", line: 4, column: 23, - endColumn: 24 + endColumn: 24, + endLine: 4 } ] } From dce79ae0a33979e132ffef21424749bc4054317b Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 30 Jul 2025 04:34:14 +0200 Subject: [PATCH 058/121] test(html-comment-content-newline): make tests more strict (#2834) --- .../lib/rules/html-comment-content-newline.js | 96 +++++++++++++++---- 1 file changed, 78 insertions(+), 18 deletions(-) diff --git a/tests/lib/rules/html-comment-content-newline.js b/tests/lib/rules/html-comment-content-newline.js index 362e27adf..6d1c28279 100644 --- a/tests/lib/rules/html-comment-content-newline.js +++ b/tests/lib/rules/html-comment-content-newline.js @@ -264,13 +264,15 @@ tester.run('html-comment-content-newline', rule, { message: "Expected line break after ''.", line: 7, column: 20, - endColumn: 21 + endColumn: 21, + endLine: 7 } ] }, @@ -293,25 +295,29 @@ tester.run('html-comment-content-newline', rule, { message: "Expected line break after ''.", line: 3, column: 22, - endColumn: 22 + endColumn: 22, + endLine: 3 }, { message: "Expected line break after ''.", line: 4, column: 24, - endColumn: 26 + endColumn: 26, + endLine: 4 } ] }, @@ -363,13 +369,15 @@ comment message: "Expected line break after ''.", line: 3, column: 30, - endColumn: 38 + endColumn: 38, + endLine: 3 } ] }, @@ -383,8 +391,20 @@ comment output: null, options: ['always', { exceptions: ['+'] }], errors: [ - 'Expected line break after exception block.', - 'Expected line break before exception block.' + { + message: 'Expected line break after exception block.', + line: 3, + column: 31, + endLine: 3, + endColumn: 31 + }, + { + message: 'Expected line break before exception block.', + line: 3, + column: 38, + endLine: 3, + endColumn: 38 + } ] }, { @@ -396,8 +416,20 @@ comment output: null, options: ['always', { exceptions: ['*'] }], errors: [ - 'Expected line break after exception block.', - 'Expected line break before exception block.' + { + message: 'Expected line break after exception block.', + line: 3, + column: 20, + endLine: 3, + endColumn: 20 + }, + { + message: 'Expected line break before exception block.', + line: 3, + column: 27, + endLine: 3, + endColumn: 27 + } ] }, { @@ -413,8 +445,20 @@ comment `, options: ['always', { exceptions: ['#+#-'] }], errors: [ - 'Expected line break after exception block.', - "Expected line break before '-->'." + { + message: 'Expected line break after exception block.', + line: 3, + column: 27, + endLine: 3, + endColumn: 27 + }, + { + message: "Expected line break before '-->'.", + line: 3, + column: 38, + endLine: 3, + endColumn: 38 + } ] }, { @@ -426,11 +470,19 @@ comment output: null, options: ['always', { exceptions: ['*', '++'] }], errors: [ - 'Expected line break after exception block.', + { + message: 'Expected line break after exception block.', + line: 3, + column: 20, + endLine: 3, + endColumn: 20 + }, { message: 'Expected line break before exception block.', line: 3, - column: 27 + column: 27, + endLine: 3, + endColumn: 27 } ] }, @@ -443,11 +495,19 @@ comment output: null, options: ['always', { exceptions: ['*', '++'] }], errors: [ - 'Expected line break after exception block.', + { + message: 'Expected line break after exception block.', + line: 3, + column: 20, + endLine: 3, + endColumn: 20 + }, { message: 'Expected line break before exception block.', line: 3, - column: 28 + column: 28, + endLine: 3, + endColumn: 28 } ] } From 769cf78de6043496c316032df3aecc3b2f1bddae Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 30 Jul 2025 04:34:41 +0200 Subject: [PATCH 059/121] test(html-comment-content-spacing): make tests more strict (#2835) --- .../lib/rules/html-comment-content-spacing.js | 90 +++++++++++++++---- 1 file changed, 74 insertions(+), 16 deletions(-) diff --git a/tests/lib/rules/html-comment-content-spacing.js b/tests/lib/rules/html-comment-content-spacing.js index 1036555e8..754271d10 100644 --- a/tests/lib/rules/html-comment-content-spacing.js +++ b/tests/lib/rules/html-comment-content-spacing.js @@ -207,13 +207,15 @@ tester.run('html-comment-content-spacing', rule, { message: "Expected space after ''.", line: 3, column: 22, - endColumn: 22 + endColumn: 22, + endLine: 3 } ] }, @@ -234,13 +236,15 @@ tester.run('html-comment-content-spacing', rule, { message: "Unexpected space after ''.", line: 3, column: 23, - endColumn: 24 + endColumn: 24, + endLine: 3 } ] }, @@ -261,13 +265,15 @@ tester.run('html-comment-content-spacing', rule, { message: "Unexpected space after ''.", line: 3, column: 30, - endColumn: 38 + endColumn: 38, + endLine: 3 } ] }, @@ -281,8 +287,20 @@ tester.run('html-comment-content-spacing', rule, { output: null, options: ['always', { exceptions: ['+'] }], errors: [ - 'Expected space after exception block.', - 'Expected space before exception block.' + { + message: 'Expected space after exception block.', + line: 3, + column: 31, + endLine: 3, + endColumn: 31 + }, + { + message: 'Expected space before exception block.', + line: 3, + column: 38, + endLine: 3, + endColumn: 38 + } ] }, { @@ -294,8 +312,20 @@ tester.run('html-comment-content-spacing', rule, { output: null, options: ['always', { exceptions: ['*'] }], errors: [ - 'Expected space after exception block.', - 'Expected space before exception block.' + { + message: 'Expected space after exception block.', + line: 3, + column: 20, + endLine: 3, + endColumn: 20 + }, + { + message: 'Expected space before exception block.', + line: 3, + column: 27, + endLine: 3, + endColumn: 27 + } ] }, { @@ -311,8 +341,20 @@ tester.run('html-comment-content-spacing', rule, { `, options: ['always', { exceptions: ['#+#-'] }], errors: [ - 'Expected space after exception block.', - "Expected space before '-->'." + { + message: 'Expected space after exception block.', + line: 3, + column: 27, + endLine: 3, + endColumn: 27 + }, + { + message: "Expected space before '-->'.", + line: 3, + column: 38, + endLine: 3, + endColumn: 38 + } ] }, { @@ -324,11 +366,19 @@ tester.run('html-comment-content-spacing', rule, { output: null, options: ['always', { exceptions: ['*', '++'] }], errors: [ - 'Expected space after exception block.', + { + message: 'Expected space after exception block.', + line: 3, + column: 20, + endLine: 3, + endColumn: 20 + }, { message: 'Expected space before exception block.', line: 3, - column: 27 + column: 27, + endLine: 3, + endColumn: 27 } ] }, @@ -341,11 +391,19 @@ tester.run('html-comment-content-spacing', rule, { output: null, options: ['always', { exceptions: ['*', '++'] }], errors: [ - 'Expected space after exception block.', + { + message: 'Expected space after exception block.', + line: 3, + column: 20, + endLine: 3, + endColumn: 20 + }, { message: 'Expected space before exception block.', line: 3, - column: 28 + column: 28, + endLine: 3, + endColumn: 28 } ] } From e9015383b6503cdd428794e38adbfaa48401982b Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 30 Jul 2025 04:35:05 +0200 Subject: [PATCH 060/121] test(html-comment-indent): make tests more strict (#2836) --- tests/lib/rules/html-comment-indent.js | 80 ++++++++++++++++++++------ 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/tests/lib/rules/html-comment-indent.js b/tests/lib/rules/html-comment-indent.js index 27c93af8e..f90f2cf4c 100644 --- a/tests/lib/rules/html-comment-indent.js +++ b/tests/lib/rules/html-comment-indent.js @@ -504,22 +504,34 @@ tester.run('html-comment-indent', rule, { { message: 'Expected relative indentation of 2 spaces but found 0 spaces.', - line: 5 + line: 5, + column: 11, + endLine: 5, + endColumn: 11 }, { message: 'Expected relative indentation of 2 spaces but found 4 spaces.', - line: 7 + line: 7, + column: 11, + endLine: 7, + endColumn: 15 }, { message: 'Expected relative indentation of 0 spaces but found 2 spaces.', - line: 12 + line: 12, + column: 11, + endLine: 12, + endColumn: 13 }, { message: 'Expected base point indentation of 10 spaces, but found 8 spaces.', - line: 14 + line: 14, + column: 1, + endLine: 14, + endColumn: 9 } ] }, @@ -544,12 +556,18 @@ tester.run('html-comment-indent', rule, { { message: 'Expected relative indentation of 2 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 11, + endLine: 4, + endColumn: 11 }, { message: 'Expected relative indentation of 2 spaces but found 4 spaces.', - line: 6 + line: 6, + column: 11, + endLine: 6, + endColumn: 15 } ] }, @@ -575,15 +593,24 @@ comment --> errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 1 }, { message: 'Expected indentation of 0 spaces but found 2 spaces.', - line: 7 + line: 7, + column: 1, + endLine: 7, + endColumn: 3 } ] }, @@ -610,17 +637,26 @@ comment --> { message: 'Expected base point indentation of 2 spaces, but not found.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 }, { message: 'Expected base point indentation of 2 spaces, but not found.', - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 1 }, { message: 'Expected base point indentation of 2 spaces, but not found.', - line: 7 + line: 7, + column: 1, + endLine: 7, + endColumn: 1 } ] }, @@ -643,12 +679,18 @@ comment --> { message: 'Expected relative indentation of 2 spaces but found 1 space.', - line: 4 + line: 4, + column: 11, + endLine: 4, + endColumn: 12 }, { message: 'Expected relative indentation of 0 spaces but found 1 space.', - line: 5 + line: 5, + column: 11, + endLine: 5, + endColumn: 12 } ] }, @@ -670,11 +712,17 @@ comment --> errors: [ { message: String.raw`Expected base point indentation of " \t \t \t ", but found 7 spaces.`, - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 13 }, { message: String.raw`Expected base point indentation of " \t \t \t ", but found 7 spaces.`, - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 11 } ] } From b4ad756778eabcdf1dd873cab664c9961013587d Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 30 Jul 2025 04:35:28 +0200 Subject: [PATCH 061/121] test(html-end-tags): make tests more strict (#2837) --- tests/lib/rules/html-end-tags.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/lib/rules/html-end-tags.js b/tests/lib/rules/html-end-tags.js index ce5979632..42e13dc99 100644 --- a/tests/lib/rules/html-end-tags.js +++ b/tests/lib/rules/html-end-tags.js @@ -80,13 +80,29 @@ tester.run('html-end-tags', rule, { filename: 'test.vue', code: '', output: '', - errors: ["'
' should have end tag."] + errors: [ + { + message: "'
' should have end tag.", + line: 1, + column: 11, + endLine: 1, + endColumn: 16 + } + ] }, { filename: 'test.vue', code: '', output: '', - errors: ["'

' should have end tag."] + errors: [ + { + message: "'

' should have end tag.", + line: 1, + column: 16, + endLine: 1, + endColumn: 19 + } + ] } ] }) From c64ebb217e7cc15fe8d80da3541505ed13f7f745 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 30 Jul 2025 04:35:54 +0200 Subject: [PATCH 062/121] test(html-indent): make tests more strict (#2838) --- tests/lib/rules/html-indent.js | 220 ++++++++++++++++++++++++++------- 1 file changed, 176 insertions(+), 44 deletions(-) diff --git a/tests/lib/rules/html-indent.js b/tests/lib/rules/html-indent.js index 3a4c610cd..78c233f51 100644 --- a/tests/lib/rules/html-indent.js +++ b/tests/lib/rules/html-indent.js @@ -63,7 +63,10 @@ function loadPatterns(additionalValid, additionalInvalid) { message: `Expected indentation of ${line.indentSize} ${kind}${ line.indentSize === 1 ? '' : 's' } but found 0 ${kind}s.`, - line: line.number + 1 + line: line.number + 1, + column: 1, + endLine: line.number + 1, + endColumn: 1 } ) .filter(Boolean) @@ -447,7 +450,10 @@ tester.run( errors: [ { message: 'Expected indentation of 12 spaces but found 10 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 11 } ] }, @@ -472,7 +478,10 @@ tester.run( errors: [ { message: String.raw`Expected " " character, but found "\t" character.`, - line: 3 + line: 3, + column: 3, + endLine: 3, + endColumn: 4 } ] }, @@ -496,7 +505,10 @@ tester.run( errors: [ { message: String.raw`Expected "\t" character, but found " " character.`, - line: 3 + line: 3, + column: 2, + endLine: 3, + endColumn: 3 } ] }, @@ -527,27 +539,45 @@ tester.run( errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 2 + line: 2, + column: 1, + endLine: 2, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 6 + line: 6, + column: 1, + endLine: 6, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 7 + line: 7, + column: 1, + endLine: 7, + endColumn: 1 } ] }, @@ -576,11 +606,17 @@ tester.run( errors: [ { message: 'Expected indentation of 4 spaces but found 2 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 3 }, { message: 'Expected indentation of 4 spaces but found 2 spaces.', - line: 6 + line: 6, + column: 1, + endLine: 6, + endColumn: 3 } ] }, @@ -609,23 +645,38 @@ tester.run( errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 2 + line: 2, + column: 1, + endLine: 2, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 6 + line: 6, + column: 1, + endLine: 6, + endColumn: 1 } ] }, @@ -654,19 +705,31 @@ tester.run( errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 2 + line: 2, + column: 1, + endLine: 2, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 7 + line: 7, + column: 1, + endLine: 7, + endColumn: 1 } ] }, @@ -699,7 +762,10 @@ tester.run( errors: [ { message: 'Expected indentation of 4 spaces but found 8 spaces.', - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 9 } ] }, @@ -735,15 +801,24 @@ tester.run( errors: [ { message: 'Expected indentation of 8 spaces but found 6 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 7 }, { message: 'Expected indentation of 12 spaces but found 8 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 9 }, { message: 'Expected indentation of 12 spaces but found 8 spaces.', - line: 6 + line: 6, + column: 1, + endLine: 6, + endColumn: 9 } ] }, @@ -776,15 +851,24 @@ tester.run( errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 2 + line: 2, + column: 1, + endLine: 2, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 } ] }, @@ -823,31 +907,52 @@ tester.run( errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 2 + line: 2, + column: 1, + endLine: 2, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 1 }, { message: 'Expected indentation of 6 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 }, { message: 'Expected indentation of 6 spaces but found 0 spaces.', - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 1 }, { message: 'Expected indentation of 6 spaces but found 0 spaces.', - line: 6 + line: 6, + column: 1, + endLine: 6, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 7 + line: 7, + column: 1, + endLine: 7, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 8 + line: 8, + column: 1, + endLine: 8, + endColumn: 1 } ] }, @@ -886,31 +991,52 @@ tester.run( errors: [ { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 2 + line: 2, + column: 1, + endLine: 2, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 3 + line: 3, + column: 1, + endLine: 3, + endColumn: 1 }, { message: 'Expected indentation of 6 spaces but found 0 spaces.', - line: 4 + line: 4, + column: 1, + endLine: 4, + endColumn: 1 }, { message: 'Expected indentation of 6 spaces but found 0 spaces.', - line: 5 + line: 5, + column: 1, + endLine: 5, + endColumn: 1 }, { message: 'Expected indentation of 6 spaces but found 0 spaces.', - line: 6 + line: 6, + column: 1, + endLine: 6, + endColumn: 1 }, { message: 'Expected indentation of 4 spaces but found 0 spaces.', - line: 7 + line: 7, + column: 1, + endLine: 7, + endColumn: 1 }, { message: 'Expected indentation of 2 spaces but found 0 spaces.', - line: 8 + line: 8, + column: 1, + endLine: 8, + endColumn: 1 } ] }, @@ -932,7 +1058,10 @@ tester.run( errors: [ { message: String.raw`Expected "\t" character, but found " " character.`, - line: 2 + line: 2, + column: 2, + endLine: 2, + endColumn: 3 } ] }, @@ -951,7 +1080,10 @@ tester.run( errors: [ { message: 'Expected indentation of 2 spaces but found 4 spaces.', - line: 2 + line: 2, + column: 1, + endLine: 2, + endColumn: 5 } ] } From d2b201a20973c91f0076f443987664045275f744 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 30 Jul 2025 04:39:59 +0200 Subject: [PATCH 063/121] test(max-len): make tests more strict (#2847) --- tests/lib/rules/max-len.js | 313 +++++++++++++++++++++++++------------ 1 file changed, 217 insertions(+), 96 deletions(-) diff --git a/tests/lib/rules/max-len.js b/tests/lib/rules/max-len.js index ac634ff75..d2df6e62a 100644 --- a/tests/lib/rules/max-len.js +++ b/tests/lib/rules/max-len.js @@ -311,11 +311,13 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 2 + line: 2, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 } ] }, @@ -328,11 +330,13 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 2 + line: 2, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 } ] }, @@ -346,11 +350,13 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 121. Maximum allowed is 120.', - line: 2 + line: 2, + column: 1 }, { message: 'This line has a length of 121. Maximum allowed is 120.', - line: 3 + line: 3, + column: 1 } ] }, @@ -364,11 +370,13 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 121. Maximum allowed is 120.', - line: 2 + line: 2, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 } ] }, @@ -381,7 +389,8 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 121. Maximum allowed is 120.', - line: 2 + line: 2, + column: 1 } ] }, @@ -394,7 +403,8 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 121. Maximum allowed is 120.', - line: 2 + line: 2, + column: 1 } ] }, @@ -417,15 +427,18 @@ export default { name: 'fooooooooooooooooooooooooooooooooooooooooooooooooooooooo errors: [ { message: 'This line has a length of 82. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 84. Maximum allowed is 80.', - line: 5 + line: 5, + column: 1 }, { message: 'This line has a length of 94. Maximum allowed is 80.', - line: 10 + line: 10, + column: 1 } ] }, @@ -453,43 +466,53 @@ var b /* comment */ // trailing comments ....................................... errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 6 + line: 6, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 7 + line: 7, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 8 + line: 8, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 9 + line: 9, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 10 + line: 10, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 11 + line: 11, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 14 + line: 14, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 15 + line: 15, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 16 + line: 16, + column: 1 } ] }, @@ -516,43 +539,53 @@ var b /* comment */ // trailing comments ....................................... errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 5 + line: 5, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 8 + line: 8, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 11 + line: 11, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 12 + line: 12, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 13 + line: 13, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 14 + line: 14, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 15 + line: 15, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 16 + line: 16, + column: 1 } ] }, @@ -581,7 +614,8 @@ var b /* comment */ // trailing comments ....................................... errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 10 + line: 10, + column: 1 } ] }, @@ -609,7 +643,8 @@ var b /* comment */ // trailing comments ....................................... errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 15 + line: 15, + column: 1 } ] }, @@ -638,19 +673,23 @@ var b /* comment */ // trailing comments ....................................... errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 8 + line: 8, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 10 + line: 10, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 16 + line: 16, + column: 1 } ] }, @@ -678,19 +717,23 @@ var b /* comment */ // trailing comments ....................................... errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 5 + line: 5, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 8 + line: 8, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 13 + line: 13, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 15 + line: 15, + column: 1 } ] }, @@ -709,11 +752,13 @@ var a = 'https://www.example.com/long/long/long/long/long/long/long/long/long/lo errors: [ { message: 'This line has a length of 89. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 83. Maximum allowed is 80.', - line: 7 + line: 7, + column: 1 } ] }, @@ -731,11 +776,13 @@ var a = 'https://www.example.com/long/long/long/long/long/long/long/long/long/lo errors: [ { message: 'This line has a length of 83. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 89. Maximum allowed is 80.', - line: 6 + line: 6, + column: 1 } ] }, @@ -760,19 +807,23 @@ var a = 'str-loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 6 + line: 6, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 8 + line: 8, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 13 + line: 13, + column: 1 } ] }, @@ -796,19 +847,23 @@ var a = 'str-loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 6 + line: 6, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 9 + line: 9, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 11 + line: 11, + column: 1 } ] }, @@ -834,7 +889,8 @@ var a = 'str-loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 } ] }, @@ -859,7 +915,8 @@ var a = 'str-loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 6 + line: 6, + column: 1 } ] }, @@ -882,19 +939,23 @@ var b = \`template-looooooooooooooooooooooooooooooooooooooooooooooooooooooooooon errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 5 + line: 5, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 10 + line: 10, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 11 + line: 11, + column: 1 } ] }, @@ -916,19 +977,23 @@ var b = \`template-looooooooooooooooooooooooooooooooooooooooooooooooooooooooooon errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 8 + line: 8, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 9 + line: 9, + column: 1 } ] }, @@ -952,11 +1017,13 @@ var b = \`template-looooooooooooooooooooooooooooooooooooooooooooooooooooooooooon errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 10 + line: 10, + column: 1 } ] }, @@ -979,11 +1046,13 @@ var b = \`template-looooooooooooooooooooooooooooooooooooooooooooooooooooooooooon errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 8 + line: 8, + column: 1 } ] }, @@ -1004,11 +1073,13 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 9 + line: 9, + column: 1 } ] }, @@ -1028,11 +1099,13 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 7 + line: 7, + column: 1 } ] }, @@ -1048,7 +1121,8 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 } ] }, @@ -1066,11 +1140,13 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 }, { message: 'This line has a length of 88. Maximum allowed is 80.', - line: 5 + line: 5, + column: 1 } ] }, @@ -1079,32 +1155,62 @@ var a = /regexploooooooooooooooooooooooooooooooooooooooooooooooooooooong/.test(b filename: 'test.vue', code: ``, options: [40], - errors: ['This line has a length of 41. Maximum allowed is 40.'] + errors: [ + { + message: 'This line has a length of 41. Maximum allowed is 40.', + line: 1, + column: 1 + } + ] }, { filename: 'test.vue', code: ``, options: [{ code: 40 }], - errors: ['This line has a length of 41. Maximum allowed is 40.'] + errors: [ + { + message: 'This line has a length of 41. Maximum allowed is 40.', + line: 1, + column: 1 + } + ] }, // tabWidth { filename: 'test.vue', code: ``, options: [40, 4], - errors: ['This line has a length of 45. Maximum allowed is 40.'] + errors: [ + { + message: 'This line has a length of 45. Maximum allowed is 40.', + line: 1, + column: 1 + } + ] }, { filename: 'test.vue', code: ``, options: [{ code: 40, tabWidth: 4 }], - errors: ['This line has a length of 45. Maximum allowed is 40.'] + errors: [ + { + message: 'This line has a length of 45. Maximum allowed is 40.', + line: 1, + column: 1 + } + ] }, { filename: 'test.vue', code: ``, options: [{ code: 40, tabWidth: 3 }], - errors: ['This line has a length of 44. Maximum allowed is 40.'] + errors: [ + { + message: 'This line has a length of 44. Maximum allowed is 40.', + line: 1, + column: 1 + } + ] }, // comments { @@ -1130,27 +1236,32 @@ var a; // 41 cols comment * { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 4 + line: 4, + column: 1 }, { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 9 + line: 9, + column: 1 }, { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 12 + line: 12, + column: 1 }, { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 13 + line: 13, + column: 1 } ] }, @@ -1166,15 +1277,18 @@ var b = \`81 columns errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 2 + line: 2, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 } ] }, @@ -1189,11 +1303,13 @@ var b = \`81 columns errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 4 + line: 4, + column: 1 } ] }, @@ -1208,11 +1324,13 @@ var b = \`81 columns errors: [ { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 2 + line: 2, + column: 1 }, { message: 'This line has a length of 81. Maximum allowed is 80.', - line: 3 + line: 3, + column: 1 } ] }, @@ -1230,17 +1348,20 @@ var b = \`81 columns { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 2 + line: 2, + column: 1 }, { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 3 + line: 3, + column: 1 }, { message: 'This line has a comment length of 41. Maximum allowed is 40.', - line: 4 + line: 4, + column: 1 } ] } From 02890f3d2341c42e41df78ff789c5d85fbf4d270 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Thu, 31 Jul 2025 11:10:40 +0800 Subject: [PATCH 064/121] Add `vue/no-negated-v-if-condition` rule (#2794) Co-authored-by: Flo Edelmann --- .changeset/early-worlds-reply.md | 5 + docs/rules/index.md | 2 + docs/rules/no-negated-condition.md | 1 + docs/rules/no-negated-v-if-condition.md | 64 ++++ lib/index.js | 1 + lib/rules/no-negated-v-if-condition.js | 204 ++++++++++++ tests/lib/rules/no-negated-v-if-condition.js | 327 +++++++++++++++++++ 7 files changed, 604 insertions(+) create mode 100644 .changeset/early-worlds-reply.md create mode 100644 docs/rules/no-negated-v-if-condition.md create mode 100644 lib/rules/no-negated-v-if-condition.js create mode 100644 tests/lib/rules/no-negated-v-if-condition.js diff --git a/.changeset/early-worlds-reply.md b/.changeset/early-worlds-reply.md new file mode 100644 index 000000000..8a269de33 --- /dev/null +++ b/.changeset/early-worlds-reply.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-vue': minor +--- + +Added new [`vue/no-negated-v-if-condition`](https://eslint.vuejs.org/rules/no-negated-v-if-condition.html) rule diff --git a/docs/rules/index.md b/docs/rules/index.md index 34462fba0..26542db38 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -237,6 +237,7 @@ For example: | [vue/no-empty-component-block] | disallow the ``, output: null, - errors: ['`slot-scope` are deprecated.'] + errors: [ + { + message: '`slot-scope` are deprecated.', + line: 4, + column: 37, + endLine: 4, + endColumn: 47 + } + ] }, { code: ` @@ -163,7 +186,15 @@ tester.run('no-deprecated-slot-scope-attribute', rule, { `, output: null, - errors: ['`slot-scope` are deprecated.'] + errors: [ + { + message: '`slot-scope` are deprecated.', + line: 4, + column: 21, + endLine: 4, + endColumn: 31 + } + ] } ] }) From cb2ae5b9c09f366d54240ad1e6a710b0aaee720a Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:36:49 +0200 Subject: [PATCH 085/121] test(no-deprecated-slot-attribute): make tests more strict (#2880) --- tests/lib/rules/no-deprecated-slot-attribute.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/lib/rules/no-deprecated-slot-attribute.js b/tests/lib/rules/no-deprecated-slot-attribute.js index 01b8f31df..61f8f25d7 100644 --- a/tests/lib/rules/no-deprecated-slot-attribute.js +++ b/tests/lib/rules/no-deprecated-slot-attribute.js @@ -686,8 +686,20 @@ tester.run('no-deprecated-slot-attribute', rule, { `, errors: [ - '`slot` attributes are deprecated.', - '`slot` attributes are deprecated.' + { + message: '`slot` attributes are deprecated.', + line: 4, + column: 30, + endLine: 4, + endColumn: 34 + }, + { + message: '`slot` attributes are deprecated.', + line: 7, + column: 28, + endLine: 7, + endColumn: 32 + } ] }, { From 1f59ac97f5769653510a5748875a42bb4c19a106 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:37:07 +0200 Subject: [PATCH 086/121] test(no-deprecated-scope-attribute): make tests more strict (#2879) --- tests/lib/rules/no-deprecated-scope-attribute.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/lib/rules/no-deprecated-scope-attribute.js b/tests/lib/rules/no-deprecated-scope-attribute.js index f823a6878..845447cf6 100644 --- a/tests/lib/rules/no-deprecated-scope-attribute.js +++ b/tests/lib/rules/no-deprecated-scope-attribute.js @@ -66,7 +66,10 @@ tester.run('no-deprecated-scope-attribute', rule, { errors: [ { message: '`scope` attributes are deprecated.', - line: 4 + line: 4, + column: 21, + endLine: 4, + endColumn: 26 } ] }, @@ -90,7 +93,10 @@ tester.run('no-deprecated-scope-attribute', rule, { errors: [ { message: '`scope` attributes are deprecated.', - line: 4 + line: 4, + column: 33, + endLine: 4, + endColumn: 38 } ] } From d3498816a35260adc566b103091dbc90e64400d0 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:40:18 +0200 Subject: [PATCH 087/121] test(no-deprecated-inline-template): make tests more strict (#2877) --- .../rules/no-deprecated-inline-template.js | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/lib/rules/no-deprecated-inline-template.js b/tests/lib/rules/no-deprecated-inline-template.js index fad9c77a7..4c278d5a1 100644 --- a/tests/lib/rules/no-deprecated-inline-template.js +++ b/tests/lib/rules/no-deprecated-inline-template.js @@ -48,12 +48,28 @@ ruleTester.run('no-deprecated-inline-template', rule, { { filename: 'test.vue', code: '', - errors: [{ messageId: 'unexpected' }] + errors: [ + { + messageId: 'unexpected', + line: 1, + column: 25, + endLine: 1, + endColumn: 40 + } + ] }, { filename: 'test.vue', code: '', - errors: [{ messageId: 'unexpected' }] + errors: [ + { + messageId: 'unexpected', + line: 1, + column: 25, + endLine: 1, + endColumn: 40 + } + ] } ] }) From fe5692dcb5ba2b7fede1d5319586ed6edc93c6fb Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:40:42 +0200 Subject: [PATCH 088/121] test(no-deprecated-props-default-this): make tests more strict (#2878) --- .../rules/no-deprecated-props-default-this.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/lib/rules/no-deprecated-props-default-this.js b/tests/lib/rules/no-deprecated-props-default-this.js index b887868d5..ed0b2005d 100644 --- a/tests/lib/rules/no-deprecated-props-default-this.js +++ b/tests/lib/rules/no-deprecated-props-default-this.js @@ -199,8 +199,22 @@ ruleTester.run('no-deprecated-props-default-this', rule, { `, errors: [ - 'Props default value factory functions no longer have access to `this`.', - 'Props default value factory functions no longer have access to `this`.' + { + message: + 'Props default value factory functions no longer have access to `this`.', + line: 9, + column: 24, + endLine: 9, + endColumn: 28 + }, + { + message: + 'Props default value factory functions no longer have access to `this`.', + line: 14, + column: 24, + endLine: 14, + endColumn: 28 + } ] } ] From aca04e5c07c7631b80b6165cb01d834e4fb16975 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:41:00 +0200 Subject: [PATCH 089/121] test(no-deprecated-dollar-scopedslots-api): make tests more strict (#2872) Co-authored-by: Flo Edelmann --- .../no-deprecated-dollar-scopedslots-api.js | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/lib/rules/no-deprecated-dollar-scopedslots-api.js b/tests/lib/rules/no-deprecated-dollar-scopedslots-api.js index 7dea6146e..c235698f8 100644 --- a/tests/lib/rules/no-deprecated-dollar-scopedslots-api.js +++ b/tests/lib/rules/no-deprecated-dollar-scopedslots-api.js @@ -142,16 +142,16 @@ ruleTester.run('no-deprecated-dollar-scopedslots-api', rule, { `, errors: [ { + messageId: 'deprecated', line: 3, column: 22, - messageId: 'deprecated', endLine: 3, endColumn: 34 }, { + messageId: 'deprecated', line: 8, column: 25, - messageId: 'deprecated', endLine: 8, endColumn: 37 } @@ -191,23 +191,23 @@ ruleTester.run('no-deprecated-dollar-scopedslots-api', rule, { `, errors: [ { + messageId: 'deprecated', line: 3, column: 31, - messageId: 'deprecated', endLine: 3, endColumn: 43 }, { + messageId: 'deprecated', line: 4, column: 22, - messageId: 'deprecated', endLine: 4, endColumn: 34 }, { + messageId: 'deprecated', line: 10, column: 23, - messageId: 'deprecated', endLine: 10, endColumn: 35 } @@ -237,9 +237,11 @@ ruleTester.run('no-deprecated-dollar-scopedslots-api', rule, { `, errors: [ { + messageId: 'deprecated', line: 6, column: 23, - messageId: 'deprecated' + endLine: 6, + endColumn: 35 } ] }, @@ -273,9 +275,11 @@ ruleTester.run('no-deprecated-dollar-scopedslots-api', rule, { `, errors: [ { + messageId: 'deprecated', line: 7, column: 25, - messageId: 'deprecated' + endLine: 7, + endColumn: 37 } ] }, @@ -307,10 +311,18 @@ ruleTester.run('no-deprecated-dollar-scopedslots-api', rule, { `, errors: [ { - messageId: 'deprecated' + messageId: 'deprecated', + line: 6, + column: 27, + endLine: 6, + endColumn: 39 }, { - messageId: 'deprecated' + messageId: 'deprecated', + line: 7, + column: 29, + endLine: 7, + endColumn: 41 } ] } From e0683fd012a9170b359b00ccefd8d85bc615bcea Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:42:51 +0200 Subject: [PATCH 090/121] test(no-deprecated-html-element-is): make tests more strict (#2876) Co-authored-by: Flo Edelmann --- tests/lib/rules/no-deprecated-html-element-is.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/lib/rules/no-deprecated-html-element-is.js b/tests/lib/rules/no-deprecated-html-element-is.js index be8ea3e71..a108f224f 100644 --- a/tests/lib/rules/no-deprecated-html-element-is.js +++ b/tests/lib/rules/no-deprecated-html-element-is.js @@ -43,9 +43,9 @@ ruleTester.run('no-deprecated-html-element-is', rule, { code: '', errors: [ { + messageId: 'unexpected', line: 1, column: 16, - messageId: 'unexpected', endLine: 1, endColumn: 24 } @@ -56,9 +56,11 @@ ruleTester.run('no-deprecated-html-element-is', rule, { code: '', errors: [ { + messageId: 'unexpected', line: 1, column: 16, - messageId: 'unexpected' + endLine: 1, + endColumn: 25 } ] } From 0701213ee766599f4d42c5ef523a209ca116b91f Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:43:12 +0200 Subject: [PATCH 091/121] test(no-deprecated-functional-template): make tests more strict (#2875) Co-authored-by: Flo Edelmann --- tests/lib/rules/no-deprecated-functional-template.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/lib/rules/no-deprecated-functional-template.js b/tests/lib/rules/no-deprecated-functional-template.js index 00cf539ff..fae03fdb7 100644 --- a/tests/lib/rules/no-deprecated-functional-template.js +++ b/tests/lib/rules/no-deprecated-functional-template.js @@ -33,9 +33,9 @@ ruleTester.run('no-deprecated-functional-template', rule, { code: '', errors: [ { + messageId: 'unexpected', line: 1, column: 11, - messageId: 'unexpected', endLine: 1, endColumn: 21 } @@ -46,9 +46,11 @@ ruleTester.run('no-deprecated-functional-template', rule, { code: '', errors: [ { + messageId: 'unexpected', line: 1, column: 11, - messageId: 'unexpected' + endLine: 1, + endColumn: 21 } ] } From 87c7d8315c78868a31368afdc912f52e4a40c1d1 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 31 Jul 2025 09:49:02 +0200 Subject: [PATCH 092/121] test(func-call-spacing): remove obsolete compatibility code (#2830) --- tests/lib/rules/func-call-spacing.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/lib/rules/func-call-spacing.js b/tests/lib/rules/func-call-spacing.js index 6c219e372..7f06f72fc 100644 --- a/tests/lib/rules/func-call-spacing.js +++ b/tests/lib/rules/func-call-spacing.js @@ -3,8 +3,7 @@ */ 'use strict' -const { RuleTester, ESLint } = require('../../eslint-compat') -const semver = require('semver') +const { RuleTester } = require('../../eslint-compat') const rule = require('../../../lib/rules/func-call-spacing') const tester = new RuleTester({ @@ -61,9 +60,7 @@ tester.run('func-call-spacing', rule, { `, errors: [ { - message: semver.lt(ESLint.version, '7.0.0') - ? 'Unexpected newline between function name and paren.' - : 'Unexpected whitespace between function name and paren.', + message: 'Unexpected whitespace between function name and paren.', line: 3 } ] @@ -104,9 +101,7 @@ tester.run('func-call-spacing', rule, { `, errors: [ { - message: semver.lt(ESLint.version, '7.0.0') - ? 'Unexpected newline between function name and paren.' - : 'Unexpected whitespace between function name and paren.', + message: 'Unexpected whitespace between function name and paren.', line: 4 } ] From 15185f5924978b8db0b8bae8ecaa963874deb0ca Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:55:14 +0800 Subject: [PATCH 093/121] Version Packages (#2792) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/beige-teams-camp.md | 5 ----- .changeset/early-worlds-reply.md | 5 ----- .changeset/eight-camels-refuse.md | 5 ----- .changeset/strong-masks-fetch.md | 5 ----- .changeset/true-pumas-open.md | 5 ----- CHANGELOG.md | 16 ++++++++++++++++ docs/rules/no-negated-condition.md | 7 +++++-- docs/rules/no-negated-v-if-condition.md | 6 +++++- package.json | 2 +- 9 files changed, 27 insertions(+), 29 deletions(-) delete mode 100644 .changeset/beige-teams-camp.md delete mode 100644 .changeset/early-worlds-reply.md delete mode 100644 .changeset/eight-camels-refuse.md delete mode 100644 .changeset/strong-masks-fetch.md delete mode 100644 .changeset/true-pumas-open.md diff --git a/.changeset/beige-teams-camp.md b/.changeset/beige-teams-camp.md deleted file mode 100644 index 49c2a317b..000000000 --- a/.changeset/beige-teams-camp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-vue': minor ---- - -Added `ignoreParents` option to [`vue/no-deprecated-slot-attribute`](https://eslint.vuejs.org/rules/no-deprecated-slot-attribute.html) diff --git a/.changeset/early-worlds-reply.md b/.changeset/early-worlds-reply.md deleted file mode 100644 index 8a269de33..000000000 --- a/.changeset/early-worlds-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-vue': minor ---- - -Added new [`vue/no-negated-v-if-condition`](https://eslint.vuejs.org/rules/no-negated-v-if-condition.html) rule diff --git a/.changeset/eight-camels-refuse.md b/.changeset/eight-camels-refuse.md deleted file mode 100644 index 527b123e4..000000000 --- a/.changeset/eight-camels-refuse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-plugin-vue": patch ---- - -Resolved TypeScript compatibility issues introduced by eslint-typegen diff --git a/.changeset/strong-masks-fetch.md b/.changeset/strong-masks-fetch.md deleted file mode 100644 index b7b3b22a0..000000000 --- a/.changeset/strong-masks-fetch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-vue': patch ---- - -Fixed inconsistent quotes in [`vue/block-lang`](https://eslint.vuejs.org/rules/block-lang.html) error messages diff --git a/.changeset/true-pumas-open.md b/.changeset/true-pumas-open.md deleted file mode 100644 index 7a49b0f25..000000000 --- a/.changeset/true-pumas-open.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-vue': minor ---- - -Added new [`vue/no-negated-condition`](https://eslint.vuejs.org/rules/no-negated-condition.html) rule diff --git a/CHANGELOG.md b/CHANGELOG.md index d48439d99..fa7a29427 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # eslint-plugin-vue +## 10.4.0 + +### Minor Changes + +- Added `ignoreParents` option to [`vue/no-deprecated-slot-attribute`](https://eslint.vuejs.org/rules/no-deprecated-slot-attribute.html) ([#2784](https://github.com/vuejs/eslint-plugin-vue/pull/2784)) + +- Added new [`vue/no-negated-v-if-condition`](https://eslint.vuejs.org/rules/no-negated-v-if-condition.html) rule ([#2794](https://github.com/vuejs/eslint-plugin-vue/pull/2794)) + +- Added new [`vue/no-negated-condition`](https://eslint.vuejs.org/rules/no-negated-condition.html) rule ([#2795](https://github.com/vuejs/eslint-plugin-vue/pull/2795)) + +### Patch Changes + +- Resolved TypeScript compatibility issues introduced by eslint-typegen ([#2790](https://github.com/vuejs/eslint-plugin-vue/pull/2790)) + +- Fixed inconsistent quotes in [`vue/block-lang`](https://eslint.vuejs.org/rules/block-lang.html) error messages ([#2805](https://github.com/vuejs/eslint-plugin-vue/pull/2805)) + ## 10.3.0 ### Minor Changes diff --git a/docs/rules/no-negated-condition.md b/docs/rules/no-negated-condition.md index fa183bee7..17ffdba5d 100644 --- a/docs/rules/no-negated-condition.md +++ b/docs/rules/no-negated-condition.md @@ -3,14 +3,13 @@ pageClass: rule-details sidebarDepth: 0 title: vue/no-negated-condition description: Disallow negated conditions in ``, options: ['first', { exceptions: { ArrowFunctionExpression: false } }] }, - ` - - `, { code: `