Skip to content

Commit

Permalink
Add singleDeclaration: "never" to declaration-block-trailing-semicolon
Browse files Browse the repository at this point in the history
  • Loading branch information
Mouvedia committed Feb 23, 2021
1 parent ae67767 commit 06f3694
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 13 deletions.
41 changes: 41 additions & 0 deletions lib/rules/declaration-block-trailing-semicolon/README.md
Expand Up @@ -88,3 +88,44 @@ a { color: pink }
```css
a { background: orange; color: pink }
```

## Optional secondary options

### `singleDeclaration: "never"`

#### `"never"`

The following patterns are _not_ considered violations:

<!-- prettier-ignore -->
```css
foo {
property: value
}
```

<!-- prettier-ignore -->
```css
foo { property: value }
```

The following patterns are considered violations:

<!-- prettier-ignore -->
```css
foo { property: value; }
```

With `"always"`:

The following patterns are considered violations:

<!-- prettier-ignore -->
```css
foo { property: value; bar: qux }
```

<!-- prettier-ignore -->
```css
@keyframes name { from { property: 0 } to { property: 1; } }
```
63 changes: 63 additions & 0 deletions lib/rules/declaration-block-trailing-semicolon/__tests__/index.js
Expand Up @@ -62,6 +62,69 @@ testRule({
],
});

testRule({
ruleName,
config: ['always', { singleDeclaration: 'never' }],
fix: true,

accept: [
{
code: 'foo { property: value }',
description: 'single declaration without trailing semicolon (single-line)',
},
{
code: `foo {
property: value
}`,
description: 'single declaration without trailing semicolon (multi-line)',
},
],

reject: [
{
code: 'foo { property: value; }',
fixed: 'foo { property: value }',
description: 'single declaration with trailing semicolon',
message: messages.rejected,
line: 1,
column: 21,
},
{
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,
},
{
code: '@keyframes name { from { property: 0 } to { property: 1; } }',
fixed: '@keyframes name { from { property: 0 } to { property: 1 } }',
description: 'inconsistent case (with and without)',
message: messages.rejected,
line: 1,
column: 55,
},
],
});

testRule({
ruleName,
config: ['never', { singleDeclaration: 'never' }],
fix: true,

reject: [
{
code: 'foo { property: value; }',
fixed: 'foo { property: value }',
description: 'single declaration without trailing semicolon',
message: messages.rejected,
line: 1,
column: 21,
},
],
});

testRule({
ruleName,
config: ['never'],
Expand Down
48 changes: 35 additions & 13 deletions lib/rules/declaration-block-trailing-semicolon/index.js
Expand Up @@ -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');
Expand All @@ -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: {
singleDeclaration: 'never',
},
optional: true,
},
);

if (!validOptions) {
return;
Expand Down Expand Up @@ -54,28 +66,38 @@ function rule(expectation, _, context) {
});

function checkLastNode(node) {
const hasSemicolon = node.parent.raws.semicolon;
let message;

if (expectation === 'always') {
if (node.parent.raws.semicolon) {
const singleDeclarationNeverEnabled = optionsMatches(options, 'singleDeclaration', 'never');
const isNeverException = singleDeclarationNeverEnabled && node.parent.first === node;

if (isNeverException) {
if (!hasSemicolon) return;
} else if (hasSemicolon) {
return;
}

// auto-fix
if (context.fix) {
node.parent.raws.semicolon = true;

if (node.type === 'atrule') {
node.raws.between = '';
node.parent.raws.after = ' ';
if (!isNeverException) {
node.parent.raws.semicolon = true;

if (node.type === 'atrule') {
node.raws.between = '';
node.parent.raws.after = ' ';
}
} else {
node.parent.raws.semicolon = false;
}

return;
}

message = messages.expected;
message = isNeverException ? messages.rejected : messages.expected;
} else if (expectation === 'never') {
if (!node.parent.raws.semicolon) {
if (!hasSemicolon) {
return;
}

Expand Down

0 comments on commit 06f3694

Please sign in to comment.