From bead6f3ac1f1c70d33da6e88ac16e3a84e2662b7 Mon Sep 17 00:00:00 2001 From: Marc G Date: Thu, 25 Feb 2021 12:37:04 +0100 Subject: [PATCH] Add ignore: [single-declaration] to declaration-block-trailing-semicolon (#5165) --- .../README.md | 35 +++++++++++++ .../__tests__/index.js | 52 +++++++++++++++++++ .../index.js | 32 +++++++++--- 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/lib/rules/declaration-block-trailing-semicolon/README.md b/lib/rules/declaration-block-trailing-semicolon/README.md index 576f57e256..4aed91c3ce 100644 --- a/lib/rules/declaration-block-trailing-semicolon/README.md +++ b/lib/rules/declaration-block-trailing-semicolon/README.md @@ -88,3 +88,38 @@ a { color: pink } ```css a { background: orange; color: pink } ``` + +## Optional secondary options + +### `ignore: ["single-declaration"]` + +#### `"single-declaration"` + +The following patterns are _not_ considered violations: + + +```css +foo { property: value } +``` + + +```css +foo { property: value; } +``` + + +```css +@keyframes name { from { property: 0 } to { property: 1; } } +``` + +With `"always"`: + +The following pattern is _still_ considered a violation: + + +```css +foo { + property: value; + bar: qux +} +``` diff --git a/lib/rules/declaration-block-trailing-semicolon/__tests__/index.js b/lib/rules/declaration-block-trailing-semicolon/__tests__/index.js index e5d47a9566..31850b71a5 100644 --- a/lib/rules/declaration-block-trailing-semicolon/__tests__/index.js +++ b/lib/rules/declaration-block-trailing-semicolon/__tests__/index.js @@ -62,6 +62,58 @@ testRule({ ], }); +testRule({ + ruleName, + config: ['always', { ignore: 'single-declaration' }], + fix: true, + + accept: [ + { + code: 'foo { property: value }', + description: 'single declaration without trailing semicolon', + }, + { + code: 'foo { property: value; }', + description: 'single declaration with trailing semicolon', + }, + { + code: '@keyframes name { from { property: 0 } to { property: 1; } }', + description: 'inconsistent case (with and without)', + }, + ], + + reject: [ + { + code: 'a { background: orange; color: pink }', + fixed: 'a { background: orange; color: pink; }', + description: 'multi declaration block without trailing semicolon', + message: messages.expected, + line: 1, + column: 35, + }, + ], +}); + +testRule({ + ruleName, + config: ['never', { ignore: ['single-declaration'] }], + + accept: [ + { + code: 'foo { property: value }', + description: 'single declaration without trailing semicolon', + }, + { + code: 'foo { property: value; }', + description: 'single declaration with trailing semicolon', + }, + { + code: '@keyframes name { from { property: 0 } to { property: 1; } }', + description: 'inconsistent case (with and without)', + }, + ], +}); + testRule({ ruleName, config: ['never'], diff --git a/lib/rules/declaration-block-trailing-semicolon/index.js b/lib/rules/declaration-block-trailing-semicolon/index.js index 509295dc31..02df6dfb02 100644 --- a/lib/rules/declaration-block-trailing-semicolon/index.js +++ b/lib/rules/declaration-block-trailing-semicolon/index.js @@ -3,6 +3,7 @@ 'use strict'; const hasBlock = require('../../utils/hasBlock'); +const optionsMatches = require('../../utils/optionsMatches'); const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); const validateOptions = require('../../utils/validateOptions'); @@ -14,12 +15,23 @@ const messages = ruleMessages(ruleName, { rejected: 'Unexpected trailing semicolon', }); -function rule(expectation, _, context) { +function rule(expectation, options, context) { return (root, result) => { - const validOptions = validateOptions(result, ruleName, { - actual: expectation, - possible: ['always', 'never'], - }); + const validOptions = validateOptions( + result, + ruleName, + { + actual: expectation, + possible: ['always', 'never'], + }, + { + actual: options, + possible: { + ignore: ['single-declaration'], + }, + optional: true, + }, + ); if (!validOptions) { return; @@ -54,10 +66,16 @@ function rule(expectation, _, context) { }); function checkLastNode(node) { + const hasSemicolon = node.parent.raws.semicolon; + const ignoreSingleDeclaration = optionsMatches(options, 'ignore', 'single-declaration'); let message; + if (ignoreSingleDeclaration && node.parent.first === node) { + return; + } + if (expectation === 'always') { - if (node.parent.raws.semicolon) { + if (hasSemicolon) { return; } @@ -75,7 +93,7 @@ function rule(expectation, _, context) { message = messages.expected; } else if (expectation === 'never') { - if (!node.parent.raws.semicolon) { + if (!hasSemicolon) { return; }