From 2ba27acd85a4eb0ccc5d6d1a5e88e324c3adf3df Mon Sep 17 00:00:00 2001 From: dev1437 Date: Sat, 10 Sep 2022 11:24:00 +0800 Subject: [PATCH 01/43] Create space-between-siblings rule --- docs/rules/README.md | 1 + docs/rules/space-between-siblings.md | 123 +++++++ lib/index.js | 1 + lib/rules/space-between-siblings.js | 117 +++++++ tests/lib/rules/space-between-siblings.js | 384 ++++++++++++++++++++++ 5 files changed, 626 insertions(+) create mode 100644 docs/rules/space-between-siblings.md create mode 100644 lib/rules/space-between-siblings.js create mode 100644 tests/lib/rules/space-between-siblings.js diff --git a/docs/rules/README.md b/docs/rules/README.md index 4343ba647..4ab05b398 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -257,6 +257,7 @@ For example: | [vue/require-name-property](./require-name-property.md) | require a name property in Vue components | | :hammer: | | [vue/script-indent](./script-indent.md) | enforce consistent indentation in ` + `, } ], invalid: [ From d17ec54f569632fa06f60d3badb21e7e46245676 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Mon, 12 Sep 2022 19:39:29 +0800 Subject: [PATCH 29/43] Remove testing stuff --- lib/rules/padding-line-between-tags.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index 00dd37a26..edbb9279c 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -214,23 +214,6 @@ module.exports = { }, /** @param {RuleContext} context */ create(context) { - if (!context.parserServices.getDocumentFragment) { - return {} - } - const df = context.parserServices.getDocumentFragment() - if (!df) { - return {} - } - const documentFragment = df - - /** - * @returns {VElement[]} - */ - function getTopLevelHTMLElements() { - return documentFragment.children.filter(utils.isVElement) - } - - // console.log(getTopLevelHTMLElements()); return utils.defineTemplateBodyVisitor(context, { VElement: checkNewline(context) }) From cfa916fcea737773fd2db22de129dc835a7756cf Mon Sep 17 00:00:00 2001 From: dev1437 Date: Mon, 12 Sep 2022 20:21:25 +0800 Subject: [PATCH 30/43] Simplify logic and make last configuration apply --- lib/rules/padding-line-between-tags.js | 110 +++++-------------------- 1 file changed, 21 insertions(+), 89 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index edbb9279c..52c6371b7 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -65,39 +65,16 @@ function removeExcessLines(context, endTag, sibling) { */ function checkNewline(context) { /** @type {Array<{blankLine: "always" | "never", prev: string, next: string}>} */ - const options = context.options[0] || [ + const configureList = context.options[0] || [ { blankLine: 'always', prev: '*', next: '*' } ] - /** @type {Map} */ - const alwaysBlankLine = new Map() - /** @type {Map} */ - const neverBlankLine = new Map() - - for (const option of options) { - if (option.blankLine === 'always') { - const tagValue = alwaysBlankLine.get(option.prev) - if (tagValue) { - alwaysBlankLine.set(option.prev, [...tagValue, option.next]) - } else { - alwaysBlankLine.set(option.prev, [option.next]) - } - } else { - const tagValue = neverBlankLine.get(option.prev) - if (tagValue) { - neverBlankLine.set(option.prev, [...tagValue, option.next]) - } else { - neverBlankLine.set(option.prev, [option.next]) - } - } - } - /** * @param {VElement} block */ return (block) => { if (!block.parent.parent) { - return; + return } const endTag = block.endTag || block.startTag @@ -112,71 +89,26 @@ function checkNewline(context) { return } - const closestSibling = lowerSiblings[0] - - const element = /** @type {VElement} */ (closestSibling) - const lineDifference = element.loc.start.line - endTag.loc.end.line - - if ( - neverBlankLine.has('*') && - // @ts-ignore - (neverBlankLine.get('*').includes('*') || - // @ts-ignore - neverBlankLine.get('*').includes(element.name)) - ) { - if ( - alwaysBlankLine.has(block.name) && - // @ts-ignore - (alwaysBlankLine.get(block.name).includes('*') || - // @ts-ignore - alwaysBlankLine.get(block.name).includes(element.name)) - ) { - if (lineDifference === 1) { - insertNewLine(context, block, element) - } - } else if (lineDifference > 1) { - removeExcessLines(context, endTag, element) - } - } else if ( - alwaysBlankLine.has('*') && - // @ts-ignore - (alwaysBlankLine.get('*').includes('*') || - // @ts-ignore - alwaysBlankLine.get('*').includes(element.name)) - ) { - if ( - neverBlankLine.has(block.name) && - // @ts-ignore - (neverBlankLine.get(block.name).includes('*') || - // @ts-ignore - neverBlankLine.get(block.name).includes(element.name)) - ) { - if (lineDifference > 1) { - removeExcessLines(context, endTag, element) - } - } else if (lineDifference === 1) { - insertNewLine(context, block, element) - } - } else { - if ( - neverBlankLine.has(block.name) && - // @ts-ignore - (neverBlankLine.get(block.name).includes('*') || - // @ts-ignore - neverBlankLine.get(block.name).includes(element.name)) - ) { - if (lineDifference > 1) { - removeExcessLines(context, endTag, element) + const closestSibling = /** @type {VElement} */ (lowerSiblings[0]) + + for (let i = configureList.length - 1; i >= 0; --i) { + const configure = configureList[i] + const matched = + (configure.prev === '*' || block.name === configure.prev) && + (configure.next === '*' || closestSibling.name === configure.next) + + if (matched) { + const lineDifference = closestSibling.loc.start.line - endTag.loc.end.line + if (configure.blankLine === 'always') { + if (lineDifference === 1) { + insertNewLine(context, block, closestSibling) + } + } else { + if (lineDifference > 1) { + removeExcessLines(context, endTag, closestSibling) + } } - } else if ( - alwaysBlankLine.has(block.name) && - // @ts-ignore - (alwaysBlankLine.get(block.name).includes('*') || - // @ts-ignore - alwaysBlankLine.get(block.name).includes(element.name)) && - lineDifference === 1 - ) { - insertNewLine(context, block, element) + break } } } From e152ceb0a95bf5bf49b74a9458a019f432ffb34d Mon Sep 17 00:00:00 2001 From: dev1437 Date: Mon, 12 Sep 2022 20:21:38 +0800 Subject: [PATCH 31/43] Add test for last configuration applying --- tests/lib/rules/padding-line-between-tags.js | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index 5453c6e4e..707d2d118 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -152,7 +152,31 @@ tester.run('padding-line-between-tags', rule, { + ` + }, + { + filename: 'test.vue', + code: ` + `, + options: [ + [ + { blankLine: 'never', prev: 'br', next: 'img' }, + { blankLine: 'always', prev: 'br', next: 'img' } + ] + ] } ], invalid: [ From 40be55ca704b4c37e276a999e637bea29052a73b Mon Sep 17 00:00:00 2001 From: dev1437 Date: Mon, 12 Sep 2022 20:23:57 +0800 Subject: [PATCH 32/43] Update docs --- docs/rules/padding-line-between-tags.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/padding-line-between-tags.md b/docs/rules/padding-line-between-tags.md index 9fa38bca9..8e3a5554a 100644 --- a/docs/rules/padding-line-between-tags.md +++ b/docs/rules/padding-line-between-tags.md @@ -50,7 +50,7 @@ This rule requires or disallows newlines between sibling HTML tags This rule requires blank lines between each sibling HTML tag by default. -A configuration is an object which has 3 properties; blankLine, prev and next. For example, { blankLine: "always", prev: "br", next: "div" } means “one or more blank lines are required between a br tag and a div tag.” You can supply any number of configurations. +A configuration is an object which has 3 properties; blankLine, prev and next. For example, { blankLine: "always", prev: "br", next: "div" } means “one or more blank lines are required between a br tag and a div tag.” You can supply any number of configurations. If a statement pair matches multiple configurations, the last matched configuration will be used. - `blankLine` is one of the following: - `always` requires one or more blank lines. From b5fd572e2b58c1142e8f450b8238719075c1baef Mon Sep 17 00:00:00 2001 From: dev1437 Date: Mon, 12 Sep 2022 21:23:52 +0800 Subject: [PATCH 33/43] Add newlines between siblings on same line --- lib/rules/padding-line-between-tags.js | 34 +++++++++++++++++++- tests/lib/rules/padding-line-between-tags.js | 28 +++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index 52c6371b7..5336ab017 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -69,6 +69,23 @@ function checkNewline(context) { { blankLine: 'always', prev: '*', next: '*' } ] + // Copied from padding-line-between-tags + if (!context.parserServices.getDocumentFragment) { + return + } + const df = context.parserServices.getDocumentFragment() + if (!df) { + return + } + const documentFragment = df + + /** + * @returns {VElement[]} + */ + function getTopLevelHTMLElements() { + return documentFragment.children.filter(utils.isVElement) + } + /** * @param {VElement} block */ @@ -83,7 +100,7 @@ function checkNewline(context) { (element) => element.type === 'VElement' && element.range !== block.range ) - .filter((sibling) => sibling.range[0] - endTag.range[1] > 0) + .filter((sibling) => sibling.range[0] - endTag.range[1] >= 0) if (lowerSiblings.length === 0) { return @@ -102,6 +119,21 @@ function checkNewline(context) { if (configure.blankLine === 'always') { if (lineDifference === 1) { insertNewLine(context, block, closestSibling) + } else if (lineDifference === 0) { + let templateTag = getTopLevelHTMLElements().filter((element) => element.name === 'template')[0] + context.report({ + messageId: 'always', + loc: closestSibling.loc, + // @ts-ignore + fix(fixer) { + const start = templateTag.range[0] + const end = endTag.range[0] + const paddingText = context.getSourceCode().text.slice(start, end) + const lastSpaces = splitLines(paddingText).pop() + + return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`) + } + }) } } else { if (lineDifference > 1) { diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index 707d2d118..b3583402c 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -840,6 +840,32 @@ tester.run('padding-line-between-tags', rule, { } ], options: [[{ blankLine: 'always', prev: '*', next: 'br' }]] - } + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Expected blank line before this tag.', + line: 4, + column: 18 + } + ], + }, ] }) From e6094bd0132e3e515a1979b4de3f91885fa9a371 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Mon, 12 Sep 2022 21:23:58 +0800 Subject: [PATCH 34/43] Update docs --- docs/rules/padding-line-between-tags.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/rules/padding-line-between-tags.md b/docs/rules/padding-line-between-tags.md index 8e3a5554a..393316ed9 100644 --- a/docs/rules/padding-line-between-tags.md +++ b/docs/rules/padding-line-between-tags.md @@ -26,12 +26,14 @@ This rule requires or disallows newlines between sibling HTML tags
+
+
-
+
``` From 261ed4d7afca1648a010e7fb66e69a42847556e6 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Mon, 12 Sep 2022 21:27:11 +0800 Subject: [PATCH 35/43] Lint --- lib/rules/padding-line-between-tags.js | 16 ++++++++++++---- tests/lib/rules/padding-line-between-tags.js | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index 5336ab017..ad2967421 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -106,7 +106,7 @@ function checkNewline(context) { return } - const closestSibling = /** @type {VElement} */ (lowerSiblings[0]) + const closestSibling = /** @type {VElement} */ (lowerSiblings[0]) for (let i = configureList.length - 1; i >= 0; --i) { const configure = configureList[i] @@ -115,20 +115,28 @@ function checkNewline(context) { (configure.next === '*' || closestSibling.name === configure.next) if (matched) { - const lineDifference = closestSibling.loc.start.line - endTag.loc.end.line + const lineDifference = + closestSibling.loc.start.line - endTag.loc.end.line if (configure.blankLine === 'always') { if (lineDifference === 1) { insertNewLine(context, block, closestSibling) } else if (lineDifference === 0) { - let templateTag = getTopLevelHTMLElements().filter((element) => element.name === 'template')[0] + const templateTag = getTopLevelHTMLElements().find( + (element) => element.name === 'template' + ) context.report({ messageId: 'always', loc: closestSibling.loc, // @ts-ignore fix(fixer) { + if (!templateTag) { + return + } const start = templateTag.range[0] const end = endTag.range[0] - const paddingText = context.getSourceCode().text.slice(start, end) + const paddingText = context + .getSourceCode() + .text.slice(start, end) const lastSpaces = splitLines(paddingText).pop() return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`) diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index b3583402c..b8c98aad9 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -865,7 +865,7 @@ tester.run('padding-line-between-tags', rule, { line: 4, column: 18 } - ], - }, + ] + } ] }) From 5688564d4b0f26b6f46bdbb79e684ec677ecc154 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Tue, 13 Sep 2022 19:14:08 +0800 Subject: [PATCH 36/43] Fix doc --- docs/rules/padding-line-between-tags.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/padding-line-between-tags.md b/docs/rules/padding-line-between-tags.md index 7181175a7..6e84a1953 100644 --- a/docs/rules/padding-line-between-tags.md +++ b/docs/rules/padding-line-between-tags.md @@ -52,7 +52,7 @@ This rule requires or disallows newlines between sibling HTML tags. This rule requires blank lines between each sibling HTML tag by default. -A configuration is an object which has 3 properties; blankLine, prev and next. For example, { blankLine: "always", prev: "br", next: "div" } means “one or more blank lines are required between a br tag and a div tag.” You can supply any number of configurations. If a statement pair matches multiple configurations, the last matched configuration will be used. +A configuration is an object which has 3 properties; blankLine, prev and next. For example, { blankLine: "always", prev: "br", next: "div" } means “one or more blank lines are required between a br tag and a div tag.” You can supply any number of configurations. If a tag pair matches multiple configurations, the last matched configuration will be used. - `blankLine` is one of the following: - `always` requires one or more blank lines. From 1c621c41c8c5852b5571b61aac38a8d1d900a405 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Tue, 13 Sep 2022 19:24:07 +0800 Subject: [PATCH 37/43] Fix spaces on line diff = 0 --- lib/rules/padding-line-between-tags.js | 13 +--------- tests/lib/rules/padding-line-between-tags.js | 26 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index ad2967421..d38e6067a 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -121,23 +121,12 @@ function checkNewline(context) { if (lineDifference === 1) { insertNewLine(context, block, closestSibling) } else if (lineDifference === 0) { - const templateTag = getTopLevelHTMLElements().find( - (element) => element.name === 'template' - ) context.report({ messageId: 'always', loc: closestSibling.loc, // @ts-ignore fix(fixer) { - if (!templateTag) { - return - } - const start = templateTag.range[0] - const end = endTag.range[0] - const paddingText = context - .getSourceCode() - .text.slice(start, end) - const lastSpaces = splitLines(paddingText).pop() + const lastSpaces = /** @type {RegExpExecArray} */(/^\s*/.exec(context.getSourceCode().lines[endTag.loc.start.line-1]))[0] return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`) } diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index b8c98aad9..07b7eb7ad 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -866,6 +866,32 @@ tester.run('padding-line-between-tags', rule, { column: 18 } ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Expected blank line before this tag.', + line: 4, + column: 23 + } + ] } ] }) From a3f314f5a703fdd5a2caf0be7df4e73d2a29c6e4 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Tue, 13 Sep 2022 20:24:14 +0800 Subject: [PATCH 38/43] Remove only space between tags --- lib/rules/padding-line-between-tags.js | 18 +++++++-- tests/lib/rules/padding-line-between-tags.js | 41 ++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index d38e6067a..af629f9b6 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -50,8 +50,14 @@ function removeExcessLines(context, endTag, sibling) { const start = endTag.range[1] const end = sibling.range[0] const paddingText = context.getSourceCode().text.slice(start, end) - const lastSpaces = splitLines(paddingText).pop() - return fixer.replaceTextRange([start, end], `\n${lastSpaces}`) + let textBetween = splitLines(paddingText); + let newTextBetween = `\n${textBetween.pop()}` + for (let i = 0; i < textBetween.length; i++) { + if (!(/^\s*$/.test(textBetween[i]))) { + newTextBetween = `${i === 0 ? '': '\n'}${textBetween[i]}${newTextBetween}` + } + } + return fixer.replaceTextRange([start, end], `${newTextBetween}`) } }) } @@ -134,7 +140,13 @@ function checkNewline(context) { } } else { if (lineDifference > 1) { - removeExcessLines(context, endTag, closestSibling) + let hasOnlyTextBetween = false; + for (let i = endTag.loc.start.line; i < closestSibling.loc.start.line - 1; i++) { + hasOnlyTextBetween = !(/^\s*$/.test(context.getSourceCode().lines[i])) + } + if (!hasOnlyTextBetween) { + removeExcessLines(context, endTag, closestSibling) + } } } break diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index 07b7eb7ad..404475a8c 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -177,6 +177,19 @@ tester.run('padding-line-between-tags', rule, { { blankLine: 'always', prev: 'br', next: 'img' } ] ] + }, + { + filename: 'test.vue', + code: ` + + `, + options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] } ], invalid: [ @@ -892,6 +905,34 @@ tester.run('padding-line-between-tags', rule, { column: 23 } ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Unexpected blank line before this tag.', + line: 6, + column: 12 + } + ], + options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] } ] }) From b94e599668f8a22a9520e163a5684e7c937d5eeb Mon Sep 17 00:00:00 2001 From: dev1437 Date: Tue, 13 Sep 2022 20:43:55 +0800 Subject: [PATCH 39/43] Append text backwards --- lib/rules/padding-line-between-tags.js | 2 +- tests/lib/rules/padding-line-between-tags.js | 1762 +++++++++--------- 2 files changed, 897 insertions(+), 867 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index af629f9b6..a24837a26 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -52,7 +52,7 @@ function removeExcessLines(context, endTag, sibling) { const paddingText = context.getSourceCode().text.slice(start, end) let textBetween = splitLines(paddingText); let newTextBetween = `\n${textBetween.pop()}` - for (let i = 0; i < textBetween.length; i++) { + for (let i = textBetween.length - 1; i >= 0; i--) { if (!(/^\s*$/.test(textBetween[i]))) { newTextBetween = `${i === 0 ? '': '\n'}${textBetween[i]}${newTextBetween}` } diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index 404475a8c..ac470891e 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -17,520 +17,911 @@ const tester = new RuleTester({ tester.run('padding-line-between-tags', rule, { valid: [ - { - filename: 'test.vue', - code: ` - - ` - }, - { - filename: 'test.vue', - code: ` - - ` - }, - { - filename: 'test.vue', - code: ` - - `, - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: '*', next: 'br' }, - { blankLine: 'never', prev: 'br', next: '*' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: 'div' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - [ - { blankLine: 'never', prev: '*', next: '*' }, - { blankLine: 'always', prev: 'br', next: 'div' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [[{ blankLine: 'always', prev: 'br', next: 'img' }]] - }, - { - filename: 'test.vue', - code: ` - - - ` - }, - { - filename: 'test.vue', - code: ` - - `, - options: [ - [ - { blankLine: 'never', prev: 'br', next: 'img' }, - { blankLine: 'always', prev: 'br', next: 'img' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] - } + // { + // filename: 'test.vue', + // code: ` + // + // ` + // }, + // { + // filename: 'test.vue', + // code: ` + // + // ` + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // options: [ + // [ + // { blankLine: 'always', prev: '*', next: '*' }, + // { blankLine: 'never', prev: '*', next: 'br' }, + // { blankLine: 'never', prev: 'br', next: '*' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // options: [ + // [ + // { blankLine: 'always', prev: '*', next: '*' }, + // { blankLine: 'never', prev: 'br', next: 'div' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // options: [ + // [ + // { blankLine: 'never', prev: '*', next: '*' }, + // { blankLine: 'always', prev: 'br', next: 'div' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // options: [[{ blankLine: 'always', prev: 'br', next: 'img' }]] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // + // ` + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // options: [ + // [ + // { blankLine: 'never', prev: 'br', next: 'img' }, + // { blankLine: 'always', prev: 'br', next: 'img' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] + // } ], invalid: [ + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 5, + // column: 11 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 7, + // column: 11 + // } + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 7, + // column: 13 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 9, + // column: 13 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 10, + // column: 13 + // } + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 6, + // column: 11 + // } + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 6, + // column: 11 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 10, + // column: 15 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 15, + // column: 9 + // } + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 7, + // column: 13 + // } + // ], + // options: [ + // [ + // { blankLine: 'always', prev: '*', next: '*' }, + // { blankLine: 'never', prev: 'br', next: '*' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 8, + // column: 13 + // } + // ], + // options: [ + // [ + // { blankLine: 'always', prev: '*', next: '*' }, + // { blankLine: 'never', prev: '*', next: 'br' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Unexpected blank line before this tag.', + // line: 9, + // column: 13 + // }, + // { + // message: 'Unexpected blank line before this tag.', + // line: 11, + // column: 13 + // } + // ], + // options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Unexpected blank line before this tag.', + // line: 6, + // column: 11 + // }, + // { + // message: 'Unexpected blank line before this tag.', + // line: 9, + // column: 11 + // } + // ], + // options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 8, + // column: 13 + // } + // ], + // options: [ + // [ + // { blankLine: 'never', prev: '*', next: '*' }, + // { blankLine: 'always', prev: 'br', next: 'div' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 5, + // column: 11 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 7, + // column: 11 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 9, + // column: 11 + // } + // ], + // options: [ + // [ + // { blankLine: 'always', prev: '*', next: '*' }, + // { blankLine: 'never', prev: 'br', next: 'div' }, + // { blankLine: 'never', prev: 'br', next: 'img' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 8, + // column: 11 + // } + // ], + // options: [ + // [ + // { blankLine: 'always', prev: 'br', next: 'div' }, + // { blankLine: 'always', prev: 'div', next: 'br' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 9, + // column: 11 + // } + // ], + // options: [ + // [ + // { blankLine: 'always', prev: 'br', next: 'div' }, + // { blankLine: 'always', prev: 'br', next: 'br' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 5, + // column: 11 + // }, + // { + // message: 'Expected blank line before this tag.', + // line: 8, + // column: 11 + // }, + // { + // message: 'Unexpected blank line before this tag.', + // line: 10, + // column: 11 + // } + // ], + // options: [ + // [ + // { blankLine: 'always', prev: '*', next: '*' }, + // { blankLine: 'never', prev: 'br', next: 'br' } + // ] + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Unexpected blank line before this tag.', + // line: 11, + // column: 11 + // } + // ], + // options: [[{ blankLine: 'never', prev: 'br', next: 'br' }]] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 7, + // column: 11 + // } + // ], + // options: [[{ blankLine: 'always', prev: '*', next: 'br' }]] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 4, + // column: 18 + // } + // ] + // }, + // { + // filename: 'test.vue', + // code: ` + // + // `, + // output: ` + // + // `, + // errors: [ + // { + // message: 'Expected blank line before this tag.', + // line: 4, + // column: 23 + // } + // ] + // }, { filename: 'test.vue', code: ` - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 5, - column: 11 - }, - { - message: 'Expected blank line before this tag.', - line: 7, - column: 11 - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 7, - column: 13 - }, - { - message: 'Expected blank line before this tag.', - line: 9, - column: 13 - }, - { - message: 'Expected blank line before this tag.', - line: 10, - column: 13 - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 6, - column: 11 - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 6, - column: 11 - }, - { - message: 'Expected blank line before this tag.', - line: 10, - column: 15 - }, - { - message: 'Expected blank line before this tag.', - line: 15, - column: 9 - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 7, - column: 13 - } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: '*' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 8, - column: 13 - } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: '*', next: 'br' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Unexpected blank line before this tag.', - line: 9, - column: 13 - }, - { - message: 'Unexpected blank line before this tag.', - line: 11, - column: 13 - } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] - }, - { - filename: 'test.vue', - code: ` - `, output: ` `, @@ -538,373 +929,10 @@ tester.run('padding-line-between-tags', rule, { { message: 'Unexpected blank line before this tag.', line: 6, - column: 11 - }, - { - message: 'Unexpected blank line before this tag.', - line: 9, - column: 11 - } - ], - options: [[{ blankLine: 'never', prev: '*', next: '*' }]] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 8, - column: 13 - } - ], - options: [ - [ - { blankLine: 'never', prev: '*', next: '*' }, - { blankLine: 'always', prev: 'br', next: 'div' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 5, - column: 11 - }, - { - message: 'Expected blank line before this tag.', - line: 7, - column: 11 - }, - { - message: 'Expected blank line before this tag.', - line: 9, - column: 11 - } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: 'div' }, - { blankLine: 'never', prev: 'br', next: 'img' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 8, - column: 11 - } - ], - options: [ - [ - { blankLine: 'always', prev: 'br', next: 'div' }, - { blankLine: 'always', prev: 'div', next: 'br' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 9, - column: 11 - } - ], - options: [ - [ - { blankLine: 'always', prev: 'br', next: 'div' }, - { blankLine: 'always', prev: 'br', next: 'br' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 5, - column: 11 - }, - { - message: 'Expected blank line before this tag.', - line: 8, - column: 11 - }, - { - message: 'Unexpected blank line before this tag.', - line: 10, - column: 11 - } - ], - options: [ - [ - { blankLine: 'always', prev: '*', next: '*' }, - { blankLine: 'never', prev: 'br', next: 'br' } - ] - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Unexpected blank line before this tag.', - line: 11, - column: 11 - } - ], - options: [[{ blankLine: 'never', prev: 'br', next: 'br' }]] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 7, - column: 11 + column: 12 } ], - options: [[{ blankLine: 'always', prev: '*', next: 'br' }]] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 4, - column: 18 - } - ] - }, - { - filename: 'test.vue', - code: ` - - `, - output: ` - - `, - errors: [ - { - message: 'Expected blank line before this tag.', - line: 4, - column: 23 - } - ] + options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] }, { filename: 'test.vue', @@ -912,6 +940,7 @@ tester.run('padding-line-between-tags', rule, { `, - options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] + options: [[{ blankLine: 'never', prev: '*', next: '*' }]] } ], invalid: [ @@ -932,7 +932,7 @@ tester.run('padding-line-between-tags', rule, { column: 12 } ], - options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] + options: [[{ blankLine: 'never', prev: '*', next: '*' }]] }, { filename: 'test.vue', @@ -962,7 +962,7 @@ tester.run('padding-line-between-tags', rule, { column: 12 } ], - options: [[{ "blankLine": "never", "prev": "*", "next": "*" }]] + options: [[{ blankLine: 'never', prev: '*', next: '*' }]] } ] }) From 19d365b7d1310ae5bb5eef54cd18c1c7f54483e6 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Thu, 15 Sep 2022 19:49:39 +0800 Subject: [PATCH 42/43] Fix loop and add test --- lib/rules/padding-line-between-tags.js | 4 +-- tests/lib/rules/padding-line-between-tags.js | 31 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js index a37793c0a..3e0994a12 100644 --- a/lib/rules/padding-line-between-tags.js +++ b/lib/rules/padding-line-between-tags.js @@ -129,10 +129,10 @@ function checkNewline(context) { } } else { if (lineDifference > 1) { - let hasOnlyTextBetween = false + let hasOnlyTextBetween = true for ( let i = endTag.loc.start.line; - i < closestSibling.loc.start.line - 1; + i < closestSibling.loc.start.line - 1 && hasOnlyTextBetween; i++ ) { hasOnlyTextBetween = !/^\s*$/.test( diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index 95b0b9bfc..3c1395661 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -963,6 +963,37 @@ tester.run('padding-line-between-tags', rule, { } ], options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Unexpected blank line before this tag.', + line: 8, + column: 12 + } + ], + options: [[{ blankLine: 'never', prev: '*', next: '*' }]] } ] }) From b05e3ea82dd743f8f9c78c51e66b7edec1671433 Mon Sep 17 00:00:00 2001 From: dev1437 Date: Thu, 15 Sep 2022 19:52:19 +0800 Subject: [PATCH 43/43] Add another test --- tests/lib/rules/padding-line-between-tags.js | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js index 3c1395661..18d6743a0 100644 --- a/tests/lib/rules/padding-line-between-tags.js +++ b/tests/lib/rules/padding-line-between-tags.js @@ -994,6 +994,39 @@ tester.run('padding-line-between-tags', rule, { } ], options: [[{ blankLine: 'never', prev: '*', next: '*' }]] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Unexpected blank line before this tag.', + line: 10, + column: 12 + } + ], + options: [[{ blankLine: 'never', prev: '*', next: '*' }]] } ] })