Skip to content

Commit

Permalink
Fix how "except" options are checked in *-empty-line-before rules
Browse files Browse the repository at this point in the history
  • Loading branch information
nwoltman committed Sep 23, 2017
1 parent c856d32 commit 1b9ec46
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 80 deletions.
18 changes: 18 additions & 0 deletions lib/rules/custom-property-empty-line-before/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,24 @@ testRule(rule, {
]
});

testRule(rule, {
ruleName,
config: ["always", { except: ["after-comment", "first-nested"] }],

accept: [
{
code: "a {\n --custom-prop: value;\n}"
},
{
code: "a {\n\n /* I am a comment */ \n --custom-prop2: value;}"
},
{
code: "a { /* comment */\n --custom-prop: value;\n}",
description: "shared-line comment"
}
]
});

testRule(rule, {
ruleName,
config: [
Expand Down
34 changes: 12 additions & 22 deletions lib/rules/custom-property-empty-line-before/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,29 +73,14 @@ const rule = function(expectation, options, context) {

let expectEmptyLineBefore = expectation === "always" ? true : false;

// Optionally reverse the expectation for the first nested node
// Optionally reverse the expectation if any exceptions apply
if (
optionsMatches(options, "except", "first-nested") &&
isFirstNested(decl)
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}

// Optionally reverse the expectation if a comment precedes this node
if (
optionsMatches(options, "except", "after-comment") &&
isAfterCommentLine(decl)
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}

// Optionally reverse the expectation if a custom property precedes this node
const prevNode = getPreviousNonSharedLineCommentNode(decl);
if (
optionsMatches(options, "except", "after-custom-property") &&
prevNode &&
prevNode.prop &&
isCustomProperty(prevNode.prop)
(optionsMatches(options, "except", "first-nested") &&
isFirstNested(decl)) ||
(optionsMatches(options, "except", "after-comment") &&
isAfterCommentLine(decl)) ||
(optionsMatches(options, "except", "after-custom-property") &&
isAfterCustomProperty(decl))
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}
Expand Down Expand Up @@ -131,6 +116,11 @@ const rule = function(expectation, options, context) {
};
};

function isAfterCustomProperty(decl) {
const prevNode = getPreviousNonSharedLineCommentNode(decl);
return prevNode && prevNode.prop && isCustomProperty(prevNode.prop);
}

rule.ruleName = ruleName;
rule.messages = messages;
module.exports = rule;
18 changes: 18 additions & 0 deletions lib/rules/declaration-empty-line-before/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,24 @@ testRule(rule, {
]
});

testRule(rule, {
ruleName,
config: ["always", { except: ["first-nested", "after-comment"] }],

accept: [
{
code: "a {\n top: 15px;\n}"
},
{
code: "a { /* comment */\n top: 15px;\n}",
description: "shared-line comment"
},
{
code: "a {\n /* I am a comment */ \n bottom: 5px;}"
}
]
});

testRule(rule, {
ruleName,
config: [
Expand Down
26 changes: 7 additions & 19 deletions lib/rules/declaration-empty-line-before/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,26 +85,14 @@ const rule = function(expectation, options, context) {

let expectEmptyLineBefore = expectation === "always" ? true : false;

// Optionally reverse the expectation for the first nested node
// Optionally reverse the expectation if any exceptions apply
if (
optionsMatches(options, "except", "first-nested") &&
isFirstNested(decl)
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}

// Optionally reverse the expectation if a comment precedes this node
if (
optionsMatches(options, "except", "after-comment") &&
isAfterCommentLine(decl)
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}

// Optionally reverse the expectation if a declaration precedes this node
if (
optionsMatches(options, "except", "after-declaration") &&
isAfterStandardPropertyDeclaration(decl)
(optionsMatches(options, "except", "first-nested") &&
isFirstNested(decl)) ||
(optionsMatches(options, "except", "after-comment") &&
isAfterCommentLine(decl)) ||
(optionsMatches(options, "except", "after-declaration") &&
isAfterStandardPropertyDeclaration(decl))
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}
Expand Down
102 changes: 97 additions & 5 deletions lib/rules/rule-empty-line-before/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ testRule(rule, {
{
code: "@media {\n\na {}\nb {} }",
description: "nested"
},
{
code: "a {} /* comment */\nb {}",
description: "shared-line comment"
}
],

Expand Down Expand Up @@ -199,7 +203,8 @@ testRule(rule, {
code: "/* comment */\na {}"
},
{
code: "@media { /* comment */\na {} }"
code: "@media { /* comment */\n\na {} }",
description: "nested shared-line comment"
}
],

Expand All @@ -215,9 +220,16 @@ testRule(rule, {
message: messages.rejected
},
{
code: "@media { /* comment */\n\na {} }",
fixed: "@media { /* comment */\na {} }",
message: messages.rejected
code: "@media { /* comment */\na {} }",
fixed: "@media { /* comment */\n\na {} }",
message: messages.expected,
description: "nested shared-line comment"
},
{
code: "a {} /* comment */\nb {}",
fixed: "a {} /* comment */\n\nb {}",
message: messages.expected,
description: "shared-line comment"
}
]
});
Expand All @@ -237,7 +249,7 @@ testRule(rule, {
},
{
code: "@media { /* comment */\n a {}\n\n}",
description: "shared-line comment boog"
description: "shared-line comment"
},
{
code: "@media {\n a {}\n\n b{}\n\n}"
Expand Down Expand Up @@ -312,6 +324,19 @@ testRule(rule, {
]
});

testRule(rule, {
ruleName,
config: ["always", { except: ["after-single-line-comment", "first-nested"] }],

accept: [
{
code:
"@media screen { /* comment */\n .foo {\n display: none;\n }\n}",
description: "shared-line comment - issue #2919"
}
]
});

testRule(rule, {
ruleName,
config: ["always", { except: ["inside-block-and-after-rule"] }],
Expand Down Expand Up @@ -448,6 +473,57 @@ testRule(rule, {
]
});

testRule(rule, {
ruleName,
config: ["never", { except: ["after-rule"] }],
fix: true,

accept: [
{
code: "a {}\n\nb {}"
},
{
code: "$var: pink;\nb {}",
description: "scss variable"
},
{
code: "@media {}\na{}",
description: "media rule"
},
{
code: "@media {\na {}\n\nb {} }",
description: "nested"
},
{
code: "a {} /* comment */\n\nb {}",
description: "shared-line comment"
}
],

reject: [
{
code: "a {}\nb {}",
fixed: "a {}\n\nb {}",
message: messages.expected
},
{
code: "$var: pink;\n\nb {}",
fixed: "$var: pink;\nb {}",
message: messages.rejected
},
{
code: "@media {}\n\na{}",
fixed: "@media {}\na{}",
message: messages.rejected
},
{
code: "@media {\na{}\nb{}}",
fixed: "@media {\na{}\n\nb{}}",
message: messages.expected
}
]
});

testRule(rule, {
ruleName,
config: ["never", { except: ["after-single-line-comment"] }],
Expand All @@ -460,6 +536,10 @@ testRule(rule, {
},
{
code: "/* comment */\n\na {}"
},
{
code: "@media { /* comment */\na {} }",
description: "nested shared-line comment"
}
],

Expand All @@ -473,6 +553,18 @@ testRule(rule, {
code: "/* comment */\na {}",
fixed: "/* comment */\n\na {}",
message: messages.expected
},
{
code: "@media { /* comment */\n\na {} }",
fixed: "@media { /* comment */\na {} }",
message: messages.rejected,
description: "nested shared-line comment"
},
{
code: "a {} /* comment */\n\nb {}",
fixed: "a {} /* comment */\nb {}",
message: messages.rejected,
description: "shared-line comment"
}
]
});
Expand Down
63 changes: 29 additions & 34 deletions lib/rules/rule-empty-line-before/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"use strict";

const addEmptyLineBefore = require("../../utils/addEmptyLineBefore");
const getPreviousNonSharedLineCommentNode = require("../../utils/getPreviousNonSharedLineCommentNode");
const hasEmptyLine = require("../../utils/hasEmptyLine");
const isFirstNested = require("../../utils/isFirstNested");
const isFirstNodeOfRoot = require("../../utils/isFirstNodeOfRoot");
const isSharedLineComment = require("../../utils/isSharedLineComment");
const isSingleLineString = require("../../utils/isSingleLineString");
const isStandardSyntaxRule = require("../../utils/isStandardSyntaxRule");
const optionsMatches = require("../../utils/optionsMatches");
Expand Down Expand Up @@ -57,9 +59,6 @@ const rule = function(expectation, options, context) {
return;
}

let expectEmptyLineBefore =
expectation.indexOf("always") !== -1 ? true : false;

// Optionally ignore the expectation if a comment precedes this node
if (
optionsMatches(options, "ignore", "after-comment") &&
Expand All @@ -84,39 +83,20 @@ const rule = function(expectation, options, context) {
return;
}

// Optionally reverse the expectation for the first nested node
if (
optionsMatches(options, "except", "first-nested") &&
isFirstNested(rule)
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}

// Optionally reverse the expectation if a rule precedes this node
if (
optionsMatches(options, "except", "after-rule") &&
rule.prev() &&
rule.prev().type === "rule"
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}

// Optionally reverse the expectation if a rule precedes this node and is inside a block
if (
optionsMatches(options, "except", "inside-block-and-after-rule") &&
rule.prev() &&
rule.prev().type === "rule" &&
rule.parent !== root
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}
let expectEmptyLineBefore =
expectation.indexOf("always") !== -1 ? true : false;

// Optionally reverse the expectation for single line comments
// Optionally reverse the expectation if any exceptions apply
if (
optionsMatches(options, "except", "after-single-line-comment") &&
rule.prev() &&
rule.prev().type === "comment" &&
isSingleLineString(rule.prev().toString())
(optionsMatches(options, "except", "first-nested") &&
isFirstNested(rule)) ||
(optionsMatches(options, "except", "after-rule") &&
isAfterRule(rule)) ||
(optionsMatches(options, "except", "inside-block-and-after-rule") &&
isNested &&
isAfterRule(rule)) ||
(optionsMatches(options, "except", "after-single-line-comment") &&
isAfterSingleLineComment(rule))
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}
Expand Down Expand Up @@ -153,6 +133,21 @@ const rule = function(expectation, options, context) {
};
};

function isAfterRule(rule) {
const prevNode = getPreviousNonSharedLineCommentNode(rule);
return prevNode && prevNode.type === "rule";
}

function isAfterSingleLineComment(rule) {
const prevNode = rule.prev();
return (
prevNode &&
prevNode.type === "comment" &&
!isSharedLineComment(prevNode) &&
isSingleLineString(prevNode.toString())
);
}

rule.ruleName = ruleName;
rule.messages = messages;
module.exports = rule;

0 comments on commit 1b9ec46

Please sign in to comment.