scss-lint 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/scss-lint +1 -4
- data/config/default.yml +5 -4
- data/data/property-sort-orders/recess.txt +149 -0
- data/data/property-sort-orders/smacss.txt +138 -0
- data/lib/scss_lint.rb +1 -0
- data/lib/scss_lint/cli.rb +93 -153
- data/lib/scss_lint/config.rb +16 -13
- data/lib/scss_lint/control_comment_processor.rb +83 -0
- data/lib/scss_lint/engine.rb +21 -5
- data/lib/scss_lint/exceptions.rb +6 -0
- data/lib/scss_lint/linter.rb +6 -2
- data/lib/scss_lint/linter/bang_format.rb +20 -9
- data/lib/scss_lint/linter/duplicate_property.rb +35 -30
- data/lib/scss_lint/linter/empty_line_between_blocks.rb +1 -1
- data/lib/scss_lint/linter/id_selector.rb +10 -0
- data/lib/scss_lint/linter/indentation.rb +2 -1
- data/lib/scss_lint/linter/leading_zero.rb +6 -6
- data/lib/scss_lint/linter/name_format.rb +11 -0
- data/lib/scss_lint/linter/selector_format.rb +0 -4
- data/lib/scss_lint/linter/single_line_per_property.rb +13 -7
- data/lib/scss_lint/linter/single_line_per_selector.rb +19 -11
- data/lib/scss_lint/linter/trailing_semicolon.rb +5 -3
- data/lib/scss_lint/linter/trailing_zero.rb +4 -4
- data/lib/scss_lint/options.rb +113 -0
- data/lib/scss_lint/reporter/default_reporter.rb +15 -7
- data/lib/scss_lint/reporter/json_reporter.rb +15 -8
- data/lib/scss_lint/reporter/xml_reporter.rb +12 -6
- data/lib/scss_lint/runner.rb +4 -5
- data/lib/scss_lint/version.rb +1 -1
- data/spec/scss_lint/cli_spec.rb +9 -229
- data/spec/scss_lint/linter/bang_format_spec.rb +20 -0
- data/spec/scss_lint/linter/duplicate_property_spec.rb +13 -0
- data/spec/scss_lint/linter/empty_line_between_blocks_spec.rb +12 -11
- data/spec/scss_lint/linter/id_selector_spec.rb +62 -0
- data/spec/scss_lint/linter/indentation_spec.rb +11 -0
- data/spec/scss_lint/linter/name_format_spec.rb +147 -117
- data/spec/scss_lint/linter/selector_format_spec.rb +3 -66
- data/spec/scss_lint/linter/trailing_semicolon_spec.rb +20 -0
- data/spec/scss_lint/linter_spec.rb +248 -0
- data/spec/scss_lint/options_spec.rb +42 -0
- data/spec/spec_helper.rb +1 -1
- metadata +177 -183
- data/lib/scss_lint/linter/id_with_extraneous_selector.rb +0 -20
- data/spec/scss_lint/linter/id_with_extraneous_selector_spec.rb +0 -139
@@ -76,4 +76,24 @@ describe SCSSLint::Linter::BangFormat do
|
|
76
76
|
|
77
77
|
it { should_not report_lint }
|
78
78
|
end
|
79
|
+
|
80
|
+
context 'when ! appears within a string' do
|
81
|
+
let(:css) { <<-CSS }
|
82
|
+
p:before { content: "!important"; }
|
83
|
+
p:before { content: "imp!ortant"; }
|
84
|
+
p:after { content: '!'; }
|
85
|
+
div:before { content: 'important!'; }
|
86
|
+
div:after { content: ' ! '; }
|
87
|
+
p[attr="foo!bar"] {};
|
88
|
+
p[attr='foo!bar'] {};
|
89
|
+
p[attr="!foobar"] {};
|
90
|
+
p[attr='foobar!'] {};
|
91
|
+
$foo: 'bar!';
|
92
|
+
$foo: "bar!";
|
93
|
+
$foo: "!bar";
|
94
|
+
$foo: "b!ar";
|
95
|
+
CSS
|
96
|
+
|
97
|
+
it { should_not report_lint }
|
98
|
+
end
|
79
99
|
end
|
@@ -173,4 +173,17 @@ describe SCSSLint::Linter::DuplicateProperty do
|
|
173
173
|
|
174
174
|
it { should report_lint line: 3 }
|
175
175
|
end
|
176
|
+
|
177
|
+
context 'when property contains a duplicate value in a nested rule set' do
|
178
|
+
let(:css) { <<-CSS }
|
179
|
+
.outer {
|
180
|
+
.inner {
|
181
|
+
color: $some-color;
|
182
|
+
color: $some-color;
|
183
|
+
}
|
184
|
+
}
|
185
|
+
CSS
|
186
|
+
|
187
|
+
it { should report_lint line: 4 }
|
188
|
+
end
|
176
189
|
end
|
@@ -179,38 +179,39 @@ describe SCSSLint::Linter::EmptyLineBetweenBlocks do
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
-
context 'when a rule set is
|
182
|
+
context 'when a rule set is preceded by a comment' do
|
183
183
|
let(:css) { <<-CSS }
|
184
184
|
a {
|
185
185
|
}
|
186
|
+
|
186
187
|
// This is a comment
|
187
188
|
p {
|
188
189
|
}
|
189
190
|
CSS
|
190
191
|
|
191
|
-
it {
|
192
|
+
it { should_not report_lint }
|
192
193
|
end
|
193
194
|
|
194
|
-
context 'when a rule set is
|
195
|
+
context 'when a rule set is immediately followed by a comment' do
|
195
196
|
let(:css) { <<-CSS }
|
196
197
|
a {
|
197
|
-
}
|
198
|
+
} // A comment
|
198
199
|
|
199
|
-
|
200
|
-
|
201
|
-
}
|
200
|
+
a {
|
201
|
+
} /* Another comment */
|
202
202
|
CSS
|
203
203
|
|
204
204
|
it { should_not report_lint }
|
205
205
|
end
|
206
206
|
|
207
|
-
context 'when
|
207
|
+
context 'when rule set is followed by a comment on the next line' do
|
208
208
|
let(:css) { <<-CSS }
|
209
209
|
a {
|
210
|
-
}
|
210
|
+
}
|
211
|
+
// A trailing comment (often a control comment)
|
211
212
|
|
212
|
-
|
213
|
-
}
|
213
|
+
b {
|
214
|
+
}
|
214
215
|
CSS
|
215
216
|
|
216
217
|
it { should_not report_lint }
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SCSSLint::Linter::IdSelector do
|
4
|
+
context 'when rule is a type' do
|
5
|
+
let(:css) { 'p {}' }
|
6
|
+
|
7
|
+
it { should_not report_lint }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when rule is an ID' do
|
11
|
+
let(:css) { '#identifier {}' }
|
12
|
+
|
13
|
+
it { should report_lint line: 1 }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when rule is a class' do
|
17
|
+
let(:css) { '.class {}' }
|
18
|
+
|
19
|
+
it { should_not report_lint }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when rule is a type with a class' do
|
23
|
+
let(:css) { 'a.class {}' }
|
24
|
+
|
25
|
+
it { should_not report_lint }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when rule is a type with an ID' do
|
29
|
+
let(:css) { 'a#identifier {}' }
|
30
|
+
|
31
|
+
it { should report_lint line: 1 }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when rule is an ID with a pseudo-selector' do
|
35
|
+
let(:css) { '#identifier:active {}' }
|
36
|
+
|
37
|
+
it { should report_lint line: 1 }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when rule contains a nested rule with type and ID' do
|
41
|
+
let(:css) { <<-CSS }
|
42
|
+
p {
|
43
|
+
a#identifier {}
|
44
|
+
}
|
45
|
+
CSS
|
46
|
+
|
47
|
+
it { should report_lint line: 2 }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when rule contains multiple selectors' do
|
51
|
+
context 'when all of the selectors are just IDs, classes, or types' do
|
52
|
+
let(:css) { <<-CSS }
|
53
|
+
#identifier,
|
54
|
+
.class,
|
55
|
+
a {
|
56
|
+
}
|
57
|
+
CSS
|
58
|
+
|
59
|
+
it { should report_lint line: 1 }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -142,6 +142,17 @@ describe SCSSLint::Linter::Indentation do
|
|
142
142
|
it { should_not report_lint }
|
143
143
|
end
|
144
144
|
|
145
|
+
context 'when @at-root directive with no inline selector contains comment' do
|
146
|
+
let(:css) { <<-CSS }
|
147
|
+
@at-root {
|
148
|
+
// A comment that causes a crash
|
149
|
+
.something-else {}
|
150
|
+
}
|
151
|
+
CSS
|
152
|
+
|
153
|
+
it { should_not report_lint }
|
154
|
+
end
|
155
|
+
|
145
156
|
context 'when the indentation width has been explicitly set' do
|
146
157
|
let(:linter_config) { { 'width' => 3 } }
|
147
158
|
|
@@ -1,167 +1,197 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SCSSLint::Linter::NameFormat do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
it { should_not report_lint }
|
12
|
-
end
|
4
|
+
shared_examples 'hyphenated_lowercase' do
|
5
|
+
context 'when no variable, functions, or mixin declarations exist' do
|
6
|
+
let(:css) { <<-CSS }
|
7
|
+
p {
|
8
|
+
margin: 0;
|
9
|
+
}
|
10
|
+
CSS
|
13
11
|
|
14
|
-
|
15
|
-
|
12
|
+
it { should_not report_lint }
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
context 'when a variable name contains a hyphen' do
|
16
|
+
let(:css) { '$content-padding: 10px;' }
|
19
17
|
|
20
|
-
|
21
|
-
|
18
|
+
it { should_not report_lint }
|
19
|
+
end
|
22
20
|
|
23
|
-
|
24
|
-
|
21
|
+
context 'when a variable name contains an underscore' do
|
22
|
+
let(:css) { '$content_padding: 10px;' }
|
25
23
|
|
26
|
-
|
27
|
-
|
24
|
+
it { should report_lint line: 1 }
|
25
|
+
end
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
context 'when a variable name contains an uppercase character' do
|
28
|
+
let(:css) { '$contentPadding: 10px;' }
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
@function badFunction() {
|
35
|
-
}
|
36
|
-
CSS
|
30
|
+
it { should report_lint line: 1 }
|
31
|
+
end
|
37
32
|
|
38
|
-
|
39
|
-
|
33
|
+
context 'when a function is declared with a capital letter' do
|
34
|
+
let(:css) { <<-CSS }
|
35
|
+
@function badFunction() {
|
36
|
+
}
|
37
|
+
CSS
|
40
38
|
|
41
|
-
|
42
|
-
|
43
|
-
@function bad_function() {
|
44
|
-
}
|
45
|
-
CSS
|
39
|
+
it { should report_lint line: 1 }
|
40
|
+
end
|
46
41
|
|
47
|
-
|
48
|
-
|
42
|
+
context 'when a function is declared with an underscore' do
|
43
|
+
let(:css) { <<-CSS }
|
44
|
+
@function bad_function() {
|
45
|
+
}
|
46
|
+
CSS
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
@mixin badMixin() {
|
53
|
-
}
|
54
|
-
CSS
|
48
|
+
it { should report_lint line: 1 }
|
49
|
+
end
|
55
50
|
|
56
|
-
|
57
|
-
|
51
|
+
context 'when a mixin is declared with a capital letter' do
|
52
|
+
let(:css) { <<-CSS }
|
53
|
+
@mixin badMixin() {
|
54
|
+
}
|
55
|
+
CSS
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
@mixin bad_mixin() {
|
62
|
-
}
|
63
|
-
CSS
|
57
|
+
it { should report_lint line: 1 }
|
58
|
+
end
|
64
59
|
|
65
|
-
|
66
|
-
|
60
|
+
context 'when a mixin is declared with an underscore' do
|
61
|
+
let(:css) { <<-CSS }
|
62
|
+
@mixin bad_mixin() {
|
63
|
+
}
|
64
|
+
CSS
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
p {
|
71
|
-
margin: 0;
|
72
|
-
}
|
73
|
-
CSS
|
66
|
+
it { should report_lint line: 1 }
|
67
|
+
end
|
74
68
|
|
75
|
-
|
76
|
-
|
69
|
+
context 'when no invalid usages exist' do
|
70
|
+
let(:css) { <<-CSS }
|
71
|
+
p {
|
72
|
+
margin: 0;
|
73
|
+
}
|
74
|
+
CSS
|
77
75
|
|
78
|
-
|
79
|
-
|
80
|
-
p {
|
81
|
-
margin: $badVar;
|
82
|
-
}
|
83
|
-
CSS
|
76
|
+
it { should_not report_lint }
|
77
|
+
end
|
84
78
|
|
85
|
-
|
86
|
-
|
79
|
+
context 'when a referenced variable name has a capital letter' do
|
80
|
+
let(:css) { <<-CSS }
|
81
|
+
p {
|
82
|
+
margin: $badVar;
|
83
|
+
}
|
84
|
+
CSS
|
87
85
|
|
88
|
-
|
89
|
-
|
90
|
-
p {
|
91
|
-
margin: $bad_var;
|
92
|
-
}
|
93
|
-
CSS
|
86
|
+
it { should report_lint line: 2 }
|
87
|
+
end
|
94
88
|
|
95
|
-
|
96
|
-
|
89
|
+
context 'when a referenced variable name has an underscore' do
|
90
|
+
let(:css) { <<-CSS }
|
91
|
+
p {
|
92
|
+
margin: $bad_var;
|
93
|
+
}
|
94
|
+
CSS
|
97
95
|
|
98
|
-
|
99
|
-
|
100
|
-
p {
|
101
|
-
margin: badFunc();
|
102
|
-
}
|
103
|
-
CSS
|
96
|
+
it { should report_lint line: 2 }
|
97
|
+
end
|
104
98
|
|
105
|
-
|
106
|
-
|
99
|
+
context 'when a referenced function name has a capital letter' do
|
100
|
+
let(:css) { <<-CSS }
|
101
|
+
p {
|
102
|
+
margin: badFunc();
|
103
|
+
}
|
104
|
+
CSS
|
107
105
|
|
108
|
-
|
109
|
-
|
110
|
-
p {
|
111
|
-
margin: bad_func();
|
112
|
-
}
|
113
|
-
CSS
|
106
|
+
it { should report_lint line: 2 }
|
107
|
+
end
|
114
108
|
|
115
|
-
|
116
|
-
|
109
|
+
context 'when a referenced function name has an underscore' do
|
110
|
+
let(:css) { <<-CSS }
|
111
|
+
p {
|
112
|
+
margin: bad_func();
|
113
|
+
}
|
114
|
+
CSS
|
117
115
|
|
118
|
-
|
119
|
-
|
116
|
+
it { should report_lint line: 2 }
|
117
|
+
end
|
120
118
|
|
121
|
-
|
122
|
-
|
119
|
+
context 'when an included mixin name has a capital letter' do
|
120
|
+
let(:css) { '@include badMixin();' }
|
123
121
|
|
124
|
-
|
125
|
-
|
122
|
+
it { should report_lint line: 1 }
|
123
|
+
end
|
126
124
|
|
127
|
-
|
128
|
-
|
125
|
+
context 'when an included mixin name has an underscore' do
|
126
|
+
let(:css) { '@include bad_mixin();' }
|
129
127
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
128
|
+
it { should report_lint line: 1 }
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'when function is a transform function' do
|
132
|
+
%w[rotateX rotateY rotateZ
|
133
|
+
scaleX scaleY scaleZ
|
134
|
+
skewX skewY
|
135
|
+
translateX translateY translateZ].each do |function|
|
136
|
+
let(:css) { <<-CSS }
|
137
|
+
p {
|
138
|
+
transform: #{function}(2);
|
139
|
+
}
|
140
|
+
CSS
|
141
|
+
|
142
|
+
it { should_not report_lint }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when mixin is a transform function' do
|
135
147
|
let(:css) { <<-CSS }
|
136
148
|
p {
|
137
|
-
|
149
|
+
@include translateX(2);
|
138
150
|
}
|
139
151
|
CSS
|
140
152
|
|
141
153
|
it { should_not report_lint }
|
142
154
|
end
|
143
|
-
end
|
144
155
|
|
145
|
-
|
146
|
-
|
147
|
-
p {
|
148
|
-
@include translateX(2);
|
149
|
-
}
|
150
|
-
CSS
|
156
|
+
context 'when a mixin contains keyword arguments with underscores' do
|
157
|
+
let(:css) { '@include mixin($some_var: 4);' }
|
151
158
|
|
152
|
-
|
159
|
+
it { should report_lint }
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'when a mixin contains keyword arguments with hyphens' do
|
163
|
+
let(:css) { '@include mixin($some-var: 4);' }
|
164
|
+
|
165
|
+
it { should_not report_lint }
|
166
|
+
end
|
153
167
|
end
|
154
168
|
|
155
|
-
context 'when
|
156
|
-
|
169
|
+
context 'when no configuration is specified' do
|
170
|
+
it_behaves_like 'hyphenated_lowercase'
|
171
|
+
|
172
|
+
context 'when a name contains a leading underscore' do
|
173
|
+
let(:css) { <<-CSS }
|
174
|
+
@function _private-method() {
|
175
|
+
}
|
176
|
+
CSS
|
157
177
|
|
158
|
-
|
178
|
+
it { should_not report_lint }
|
179
|
+
end
|
159
180
|
end
|
160
181
|
|
161
|
-
context 'when
|
162
|
-
let(:
|
182
|
+
context 'when leading underscores are not allowed' do
|
183
|
+
let(:linter_config) { { 'allow_leading_underscore' => false } }
|
184
|
+
|
185
|
+
it_behaves_like 'hyphenated_lowercase'
|
163
186
|
|
164
|
-
|
187
|
+
context 'when a name contains a leading underscore' do
|
188
|
+
let(:css) { <<-CSS }
|
189
|
+
@function _private-method() {
|
190
|
+
}
|
191
|
+
CSS
|
192
|
+
|
193
|
+
it { should report_lint line: 1 }
|
194
|
+
end
|
165
195
|
end
|
166
196
|
|
167
197
|
context 'when the BEM convention is specified' do
|