scss_lint 0.42.2 → 0.43.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +9 -1
  3. data/data/properties.txt +1 -1
  4. data/lib/scss_lint/cli.rb +11 -5
  5. data/lib/scss_lint/config.rb +1 -2
  6. data/lib/scss_lint/control_comment_processor.rb +33 -28
  7. data/lib/scss_lint/engine.rb +10 -7
  8. data/lib/scss_lint/linter.rb +56 -12
  9. data/lib/scss_lint/linter/chained_classes.rb +21 -0
  10. data/lib/scss_lint/linter/color_variable.rb +0 -7
  11. data/lib/scss_lint/linter/comment.rb +15 -1
  12. data/lib/scss_lint/linter/empty_line_between_blocks.rb +10 -0
  13. data/lib/scss_lint/linter/indentation.rb +47 -53
  14. data/lib/scss_lint/linter/mergeable_selector.rb +29 -0
  15. data/lib/scss_lint/linter/property_spelling.rb +18 -6
  16. data/lib/scss_lint/linter/pseudo_element.rb +18 -0
  17. data/lib/scss_lint/linter/single_line_per_selector.rb +23 -7
  18. data/lib/scss_lint/linter/space_after_property_colon.rb +5 -6
  19. data/lib/scss_lint/linter/space_after_property_name.rb +1 -7
  20. data/lib/scss_lint/linter/space_after_variable_name.rb +1 -1
  21. data/lib/scss_lint/linter/space_around_operator.rb +23 -7
  22. data/lib/scss_lint/linter/string_quotes.rb +2 -9
  23. data/lib/scss_lint/linter/trailing_semicolon.rb +10 -0
  24. data/lib/scss_lint/options.rb +5 -0
  25. data/lib/scss_lint/runner.rb +10 -8
  26. data/lib/scss_lint/selector_visitor.rb +11 -3
  27. data/lib/scss_lint/version.rb +1 -1
  28. data/spec/scss_lint/cli_spec.rb +14 -0
  29. data/spec/scss_lint/linter/chained_classes_spec.rb +45 -0
  30. data/spec/scss_lint/linter/comment_spec.rb +16 -0
  31. data/spec/scss_lint/linter/empty_line_between_blocks_spec.rb +62 -0
  32. data/spec/scss_lint/linter/indentation_spec.rb +1 -9
  33. data/spec/scss_lint/linter/leading_zero_spec.rb +12 -0
  34. data/spec/scss_lint/linter/mergeable_selector_spec.rb +59 -0
  35. data/spec/scss_lint/linter/property_spelling_spec.rb +28 -0
  36. data/spec/scss_lint/linter/pseudo_element_spec.rb +71 -0
  37. data/spec/scss_lint/linter/single_line_per_selector_spec.rb +28 -1
  38. data/spec/scss_lint/linter/space_after_variable_name_spec.rb +12 -0
  39. data/spec/scss_lint/linter/space_around_operator_spec.rb +51 -0
  40. data/spec/scss_lint/linter/trailing_semicolon_spec.rb +28 -0
  41. data/spec/scss_lint/linter_spec.rb +17 -0
  42. data/spec/scss_lint/runner_spec.rb +2 -2
  43. metadata +9 -3
@@ -76,4 +76,20 @@ describe SCSSLint::Linter::Comment do
76
76
 
77
77
  it { should report_lint }
78
78
  end
79
+
80
+ context 'when multi-line comments are preferred' do
81
+ let(:linter_config) { { 'style' => 'loud' } }
82
+
83
+ context 'and silent comments are present' do
84
+ let(:scss) { '// A silent comment' }
85
+
86
+ it { should report_lint }
87
+ end
88
+
89
+ context 'and loud comments are present' do
90
+ let(:scss) { '/* A loud comment */' }
91
+
92
+ it { should_not report_lint }
93
+ end
94
+ end
79
95
  end
@@ -102,6 +102,68 @@ describe SCSSLint::Linter::EmptyLineBetweenBlocks do
102
102
  it { should_not report_lint }
103
103
  end
104
104
 
105
+ context 'when at-roots are defined' do
106
+ context 'and there is no blank line between them' do
107
+ let(:scss) { <<-SCSS }
108
+ div {
109
+ @at-root {
110
+ p {
111
+ }
112
+ }
113
+ @at-root {
114
+ p {
115
+ }
116
+ }
117
+ }
118
+ SCSS
119
+
120
+ it { should report_lint line: 5 }
121
+ end
122
+
123
+ context 'and there is a blank line between them' do
124
+ let(:scss) { <<-SCSS }
125
+ div {
126
+ @at-root {
127
+ p {
128
+ }
129
+ }
130
+
131
+ @at-root {
132
+ p {
133
+ }
134
+ }
135
+ }
136
+ SCSS
137
+
138
+ it { should_not report_lint }
139
+ end
140
+ end
141
+
142
+ context 'when media blocks are defined' do
143
+ context 'and there is no blank line between them' do
144
+ let(:scss) { <<-SCSS }
145
+ @media screen {
146
+ }
147
+ @media print {
148
+ }
149
+ SCSS
150
+
151
+ it { should report_lint line: 2 }
152
+ end
153
+
154
+ context 'and there is a blank line between them' do
155
+ let(:scss) { <<-SCSS }
156
+ @media screen {
157
+ }
158
+
159
+ @media print {
160
+ }
161
+ SCSS
162
+
163
+ it { should_not report_lint }
164
+ end
165
+ end
166
+
105
167
  context 'when mixins are defined' do
106
168
  context 'and there is no blank line between them' do
107
169
  let(:scss) { <<-SCSS }
@@ -287,6 +287,7 @@ describe SCSSLint::Linter::Indentation do
287
287
  .component {}
288
288
  .component__image {}
289
289
  .component__text {}
290
+ $some-variable: 0;
290
291
  .component-subblock {}
291
292
  .component-subblock__text {}
292
293
  .component-category {}
@@ -324,15 +325,6 @@ describe SCSSLint::Linter::Indentation do
324
325
  it { should report_lint line: 4 }
325
326
  end
326
327
 
327
- context 'and a non-nested non-ruleset is incorrectly indented' do
328
- let(:scss) { <<-SCSS }
329
- p {}
330
- $var: one;
331
- SCSS
332
-
333
- it { should report_lint line: 2 }
334
- end
335
-
336
328
  context 'and a nested non-ruleset is correctly indented' do
337
329
  let(:scss) { <<-SCSS }
338
330
  .one {
@@ -177,6 +177,18 @@ describe SCSSLint::Linter::LeadingZero do
177
177
  it { should report_lint count: 1, line: 1 }
178
178
  end
179
179
 
180
+ context 'when a leading zero exists in interpolation in a comment' do
181
+ let(:scss) { <<-SCSS }
182
+ .outer {
183
+ .inner {
184
+ /* \#{0.5} */
185
+ }
186
+ }
187
+ SCSS
188
+
189
+ it { should_not report_lint }
190
+ end
191
+
180
192
  context 'when leading zeros are preferred' do
181
193
  let(:linter_config) { { 'style' => 'include_zero' } }
182
194
 
@@ -241,6 +241,21 @@ describe SCSSLint::Linter::MergeableSelector do
241
241
  it { should report_lint }
242
242
  end
243
243
 
244
+ context 'when there are two parent selectors in a single selector' do
245
+ let(:scss) { <<-SCSS }
246
+ .b-some {
247
+ &__image {
248
+ width: 100%;
249
+ }
250
+ &__image + &__buttons {
251
+ margin-top: 14px;
252
+ }
253
+ }
254
+ SCSS
255
+
256
+ it { should_not report_lint }
257
+ end
258
+
244
259
  context 'when force_nesting is enabled' do
245
260
  let(:linter_config) { { 'force_nesting' => true } }
246
261
 
@@ -280,4 +295,48 @@ describe SCSSLint::Linter::MergeableSelector do
280
295
  it { should_not report_lint }
281
296
  end
282
297
  end
298
+
299
+ context 'when a whitelist list is defined' do
300
+ let(:linter_config) { { 'whitelist' => ['polyfill-rule'] } }
301
+
302
+ context 'when a rule is found in the whitelist' do
303
+ let(:scss) { <<-SCSS }
304
+ polyfill-rule { content: '.foo'; color: red; }
305
+ polyfill-rule { content: '.foo'; color: red; }
306
+ SCSS
307
+
308
+ it { should_not report_lint }
309
+ end
310
+
311
+ context 'when a rule is not found in the whitelist' do
312
+ let(:scss) { <<-SCSS }
313
+ .foo polyfill-rule { content: '.foo'; color: red; }
314
+ .foo polyfill-rule { content: '.foo'; color: red; }
315
+ SCSS
316
+
317
+ it { should report_lint }
318
+ end
319
+ end
320
+
321
+ context 'when a single whitelist selector is defined' do
322
+ let(:linter_config) { { 'whitelist' => 'polyfill-rule' } }
323
+
324
+ context 'when a rule is found in the whitelist' do
325
+ let(:scss) { <<-SCSS }
326
+ polyfill-rule { content: '.foo'; color: red; }
327
+ polyfill-rule { content: '.foo'; color: red; }
328
+ SCSS
329
+
330
+ it { should_not report_lint }
331
+ end
332
+
333
+ context 'when a rule is not found in the whitelist' do
334
+ let(:scss) { <<-SCSS }
335
+ .foo polyfill-rule { content: '.foo'; color: red; }
336
+ .foo polyfill-rule { content: '.foo'; color: red; }
337
+ SCSS
338
+
339
+ it { should report_lint }
340
+ end
341
+ end
283
342
  end
@@ -55,6 +55,34 @@ describe SCSSLint::Linter::PropertySpelling do
55
55
  end
56
56
  end
57
57
 
58
+ context 'when disabled properties are specified' do
59
+ let(:linter_config) do
60
+ {
61
+ 'disabled_properties' => ['margin'],
62
+ }
63
+ end
64
+
65
+ context 'with a non-existent property' do
66
+ let(:scss) { <<-SCSS }
67
+ p {
68
+ peanut-butter: jelly-time;
69
+ }
70
+ SCSS
71
+
72
+ it { should report_lint }
73
+ end
74
+
75
+ context 'with a property listed as an disabled property' do
76
+ let(:scss) { <<-SCSS }
77
+ p {
78
+ margin: 0;
79
+ }
80
+ SCSS
81
+
82
+ it { should report_lint }
83
+ end
84
+ end
85
+
58
86
  context 'with valid nested properties' do
59
87
  let(:scss) { <<-SCSS }
60
88
  p {
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::Linter::PseudoElement do
4
+ context 'when a pseudo-element has two colons' do
5
+ let(:scss) { <<-SCSS }
6
+ ::before {}
7
+ p::before {}
8
+ p#nav::before {}
9
+ p div::before {}
10
+ p::before div {}
11
+ p, div::before {}
12
+ p::before, div {}
13
+ SCSS
14
+
15
+ it { should_not report_lint }
16
+ end
17
+
18
+ context 'when a pseudo-element has one colon' do
19
+ let(:scss) { <<-SCSS }
20
+ :before {}
21
+ p:before {}
22
+ p#nav:before {}
23
+ p div:before {}
24
+ p:before div {}
25
+ p, div:before {}
26
+ p:before, div {}
27
+ SCSS
28
+
29
+ it { should report_lint line: 1 }
30
+ it { should report_lint line: 2 }
31
+ it { should report_lint line: 3 }
32
+ it { should report_lint line: 4 }
33
+ it { should report_lint line: 5 }
34
+ it { should report_lint line: 6 }
35
+ it { should report_lint line: 7 }
36
+ end
37
+
38
+ context 'when a pseudo-selector has one colon' do
39
+ let(:scss) { <<-SCSS }
40
+ :hover {}
41
+ p:hover {}
42
+ p#nav:hover {}
43
+ p div:hover {}
44
+ p:hover div {}
45
+ p, div:hover {}
46
+ p:hover, div {}
47
+ SCSS
48
+
49
+ it { should_not report_lint }
50
+ end
51
+
52
+ context 'when a pseudo-selector has two colons' do
53
+ let(:scss) { <<-SCSS }
54
+ ::hover {}
55
+ p::hover {}
56
+ p#nav::hover {}
57
+ p div::hover {}
58
+ p::hover div {}
59
+ p, div::hover {}
60
+ p::hover, div {}
61
+ SCSS
62
+
63
+ it { should report_lint line: 1 }
64
+ it { should report_lint line: 2 }
65
+ it { should report_lint line: 3 }
66
+ it { should report_lint line: 4 }
67
+ it { should report_lint line: 5 }
68
+ it { should report_lint line: 6 }
69
+ it { should report_lint line: 7 }
70
+ end
71
+ end
@@ -148,6 +148,33 @@ describe SCSSLint::Linter::SingleLinePerSelector do
148
148
  }
149
149
  SCSS
150
150
 
151
- it { should report_lint }
151
+ it { should report_lint line: 1 }
152
+ end
153
+
154
+ context 'when a selector sequence spans multiple lines in the middle of a comma sequence' do
155
+ let(:scss) { <<-SCSS }
156
+ .one,
157
+ .two,
158
+ .a
159
+ .b,
160
+ .other {
161
+ }
162
+ SCSS
163
+
164
+ it { should report_lint line: 3 }
165
+ end
166
+
167
+ context 'when a lot of selectors are on a single line over multiple lines' do
168
+ let(:scss) { <<-SCSS }
169
+ html, body,
170
+ h1, h2, h3, h4 {
171
+ border: 0;
172
+ }
173
+ SCSS
174
+
175
+ it { should report_lint line: 1 }
176
+ it { should report_lint line: 2 }
177
+ it { should_not report_lint line: 3 }
178
+ it { should_not report_lint line: 4 }
152
179
  end
153
180
  end
@@ -10,4 +10,16 @@ describe SCSSLint::Linter::SpaceAfterVariableName do
10
10
  it { should_not report_lint line: 1 }
11
11
  it { should report_lint line: 2 }
12
12
  it { should report_lint line: 3 }
13
+
14
+ context 'when a map contains aligned colons' do
15
+ let(:scss) { <<-SCSS }
16
+ $map: (
17
+ 'one' : 350px,
18
+ 'two' : 450px,
19
+ 'three' : 560px,
20
+ );
21
+ SCSS
22
+
23
+ it { should_not report_lint }
24
+ end
13
25
  end
@@ -242,6 +242,57 @@ describe SCSSLint::Linter::SpaceAroundOperator do
242
242
  end
243
243
  end
244
244
 
245
+ context 'when at least one space is preferred' do
246
+ let(:style) { 'at_least_one_space' }
247
+
248
+ context 'when values with single-spaced infix operators exist' do
249
+ let(:scss) { <<-SCSS }
250
+ $x: 2px + 2px;
251
+
252
+ p {
253
+ margin: 5px + 5px;
254
+ }
255
+ SCSS
256
+
257
+ it { should_not report_lint }
258
+ end
259
+
260
+ context 'when numeric values with infix operators exist' do
261
+ let(:scss) { <<-SCSS }
262
+ p {
263
+ margin: 5px+5px;
264
+ margin: 5px + 5px;
265
+ margin: 4px*2;
266
+ margin: 20px%3;
267
+ font-family: sans-+serif;
268
+ }
269
+
270
+ $x: 10px+10px;
271
+ $x: 20px-10px;
272
+ SCSS
273
+
274
+ it { should report_lint line: 2 }
275
+ it { should_not report_lint line: 3 }
276
+ it { should report_lint line: 4 }
277
+ it { should report_lint line: 5 }
278
+ it { should report_lint line: 6 }
279
+ it { should_not report_lint line: 7 }
280
+ it { should report_lint line: 9 }
281
+ it { should report_lint line: 10 }
282
+ end
283
+
284
+ context 'when expression spread over two lines' do
285
+ let(:scss) { <<-SCSS }
286
+ p {
287
+ margin: 7px +
288
+ 7px;
289
+ }
290
+ SCSS
291
+
292
+ it { should_not report_lint }
293
+ end
294
+ end
295
+
245
296
  context 'when no space is preferred' do
246
297
  let(:style) { 'no_space' }
247
298
 
@@ -470,6 +470,34 @@ describe SCSSLint::Linter::TrailingSemicolon do
470
470
  it { should report_lint }
471
471
  end
472
472
  end
473
+
474
+ context 'and a nested list' do
475
+ context 'and ends with a semicolon' do
476
+ let(:scss) { <<-SCSS }
477
+ $foo: (
478
+ "a": (
479
+ "b",
480
+ "c"
481
+ )
482
+ );
483
+ SCSS
484
+
485
+ it { should_not report_lint }
486
+ end
487
+
488
+ context 'and is missing a semicolon' do
489
+ let(:scss) { <<-SCSS }
490
+ $foo: (
491
+ "a": (
492
+ "b",
493
+ "c"
494
+ )
495
+ )
496
+ SCSS
497
+
498
+ it { should report_lint }
499
+ end
500
+ end
473
501
  end
474
502
 
475
503
  context 'with an @extend directive' do