scss_lint 0.40.1 → 0.41.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +20 -10
  3. data/data/property-sort-orders/recess.txt +12 -0
  4. data/data/property-sort-orders/smacss.txt +13 -0
  5. data/lib/scss_lint/cli.rb +4 -3
  6. data/lib/scss_lint/control_comment_processor.rb +34 -25
  7. data/lib/scss_lint/linter/border_zero.rb +1 -1
  8. data/lib/scss_lint/linter/disable_linter_reason.rb +39 -0
  9. data/lib/scss_lint/linter/mergeable_selector.rb +3 -1
  10. data/lib/scss_lint/linter/nesting_depth.rb +1 -0
  11. data/lib/scss_lint/linter/selector_depth.rb +1 -1
  12. data/lib/scss_lint/linter/single_line_per_property.rb +1 -1
  13. data/lib/scss_lint/linter/single_line_per_selector.rb +9 -1
  14. data/lib/scss_lint/linter/space_after_variable_name.rb +1 -1
  15. data/lib/scss_lint/linter/space_around_operator.rb +86 -0
  16. data/lib/scss_lint/linter/space_between_parens.rb +96 -20
  17. data/lib/scss_lint/linter/transition_all.rb +30 -0
  18. data/lib/scss_lint/linter/unnecessary_mantissa.rb +1 -0
  19. data/lib/scss_lint/reporter/clean_files_reporter.rb +10 -0
  20. data/lib/scss_lint/reporter.rb +5 -2
  21. data/lib/scss_lint/runner.rb +3 -2
  22. data/lib/scss_lint/sass/script.rb +19 -0
  23. data/lib/scss_lint/version.rb +1 -1
  24. data/spec/scss_lint/linter/bang_format_spec.rb +1 -1
  25. data/spec/scss_lint/linter/disable_linter_reason_spec.rb +63 -0
  26. data/spec/scss_lint/linter/nesting_depth_spec.rb +16 -0
  27. data/spec/scss_lint/linter/single_line_per_selector_spec.rb +23 -0
  28. data/spec/scss_lint/linter/space_after_variable_name_spec.rb +1 -1
  29. data/spec/scss_lint/linter/space_around_operator_spec.rb +240 -0
  30. data/spec/scss_lint/linter/space_between_parens_spec.rb +195 -1
  31. data/spec/scss_lint/linter/transition_all_spec.rb +81 -0
  32. data/spec/scss_lint/linter/unnecessary_mantissa_spec.rb +20 -0
  33. data/spec/scss_lint/linter_spec.rb +21 -0
  34. data/spec/scss_lint/report_lint_spec.rb +268 -0
  35. data/spec/scss_lint/reporter/clean_files_reporter_spec.rb +73 -0
  36. data/spec/scss_lint/reporter/config_reporter_spec.rb +1 -1
  37. data/spec/scss_lint/reporter/default_reporter_spec.rb +1 -1
  38. data/spec/scss_lint/reporter/files_reporter_spec.rb +3 -2
  39. data/spec/scss_lint/reporter/json_reporter_spec.rb +1 -1
  40. data/spec/spec_helper.rb +1 -1
  41. data/spec/support/matchers/report_lint.rb +11 -2
  42. metadata +20 -6
@@ -74,5 +74,24 @@ module Sass::Script
74
74
  [value]
75
75
  end
76
76
  end
77
+
78
+ # This monkey patch can be removed once scss-lint depends on a minimum
79
+ # version of the sass gem that includes a fix for
80
+ # https://github.com/sass/sass/issues/1799
81
+ class ListLiteral
82
+ def source_range
83
+ return @source_range if @elements.empty?
84
+ @source_range.end_pos = @elements.last.source_range.end_pos
85
+ @source_range
86
+ end
87
+ end
88
+
89
+ class MapLiteral
90
+ def source_range
91
+ return @source_range if @pairs.empty?
92
+ @source_range.end_pos = @pairs.last.last.source_range.end_pos
93
+ @source_range
94
+ end
95
+ end
77
96
  end
78
97
  end
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module SCSSLint
3
- VERSION = '0.40.1'
3
+ VERSION = '0.41.0'
4
4
  end
@@ -105,7 +105,7 @@ describe SCSSLint::Linter::BangFormat do
105
105
  SCSS
106
106
 
107
107
  it 'does not loop forever' do
108
- subject.should_not report_lint
108
+ should_not report_lint
109
109
  end
110
110
  end
111
111
 
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::Linter::DisableLinterReason do
4
+ context 'when no disabling instructions exist' do
5
+ let(:scss) { <<-SCSS }
6
+ // Comment.
7
+ p {
8
+ margin: 0;
9
+ }
10
+ SCSS
11
+
12
+ it { should_not report_lint }
13
+ end
14
+
15
+ context 'when no reason accompanies a disabling comment' do
16
+ let(:scss) { <<-SCSS }
17
+ // scss-lint:disable BorderZero
18
+ p {
19
+ margin: 0;
20
+ }
21
+ SCSS
22
+
23
+ it { should report_lint line: 1 }
24
+ end
25
+
26
+ context 'when a reason immediately precedes a disabling comment' do
27
+ let(:scss) { <<-SCSS }
28
+ // We like using `border: none` in our CSS.
29
+ // scss-lint:disable BorderZero
30
+ p {
31
+ margin: 0;
32
+ }
33
+ SCSS
34
+
35
+ it { should_not report_lint }
36
+ end
37
+
38
+ context 'when a reason precedes a disabling comment, at a distance' do
39
+ let(:scss) { <<-SCSS }
40
+ // We like using `border: none` in our CSS.
41
+
42
+ // scss-lint:disable BorderZero
43
+ p {
44
+ margin: 0;
45
+ }
46
+ SCSS
47
+
48
+ it { should_not report_lint }
49
+ end
50
+
51
+ context 'when no reason precedes an enabling comment' do
52
+ let(:scss) { <<-SCSS }
53
+ // Disable for now
54
+ // scss-lint:disable BorderZero
55
+ p {
56
+ border: none;
57
+ }
58
+ // scss-lint:enable BorderZero
59
+ SCSS
60
+
61
+ it { should_not report_lint }
62
+ end
63
+ end
@@ -155,6 +155,22 @@ describe SCSSLint::Linter::NestingDepth do
155
155
 
156
156
  it { should_not report_lint }
157
157
  end
158
+
159
+ context 'and sequence contains a keyframe' do
160
+ let(:linter_config) { super().merge('max_depth' => 1) }
161
+ let(:scss) { <<-SCSS }
162
+ @keyframe my_keyframe {
163
+ 0% {
164
+ background: none;
165
+ }
166
+ 50% {
167
+ background: red;
168
+ }
169
+ }
170
+ SCSS
171
+
172
+ it { should_not report_lint }
173
+ end
158
174
  end
159
175
 
160
176
  context 'when not ignoring parent selectors' do
@@ -127,4 +127,27 @@ describe SCSSLint::Linter::SingleLinePerSelector do
127
127
 
128
128
  it { should_not report_lint }
129
129
  end
130
+
131
+ context 'when a selector sequence spans multiple lines' do
132
+ let(:scss) { <<-SCSS }
133
+ .one
134
+ .two
135
+ .three {
136
+ }
137
+ SCSS
138
+
139
+ it { should report_lint }
140
+ end
141
+
142
+ context 'when a selector sequence spans multiple lines in a comma sequence' do
143
+ let(:scss) { <<-SCSS }
144
+ .one
145
+ .two
146
+ .three,
147
+ .other {
148
+ }
149
+ SCSS
150
+
151
+ it { should report_lint }
152
+ end
130
153
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe SCSSLint::SpaceAfterVariableName do
3
+ describe SCSSLint::Linter::SpaceAfterVariableName do
4
4
  let(:scss) { <<-SCSS }
5
5
  $none: #fff;
6
6
  $one : #fff;
@@ -0,0 +1,240 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::Linter::SpaceAroundOperator do
4
+ let(:linter_config) { { 'style' => style } }
5
+
6
+ context 'when one space is preferred' do
7
+ let(:style) { 'one_space' }
8
+
9
+ context 'when no properties exist' do
10
+ let(:scss) { <<-SCSS }
11
+ p {
12
+ }
13
+ SCSS
14
+
15
+ it { should_not report_lint }
16
+ end
17
+
18
+ context 'when values without infix operators exist' do
19
+ let(:scss) { <<-SCSS }
20
+ p {
21
+ margin: 5px;
22
+ }
23
+ SCSS
24
+
25
+ it { should_not report_lint }
26
+ end
27
+
28
+ context 'when values with properly-spaced infix operators exist' do
29
+ let(:scss) { <<-SCSS }
30
+ $x: 2px + 2px;
31
+
32
+ p {
33
+ margin: 5px + 5px;
34
+ }
35
+ SCSS
36
+
37
+ it { should_not report_lint }
38
+ end
39
+
40
+ context 'when numeric values with infix operators exist' do
41
+ let(:scss) { <<-SCSS }
42
+ p {
43
+ margin: 5px+5px;
44
+ margin: 5px + 5px;
45
+ margin: 4px*2;
46
+ margin: 20px%3;
47
+ font-family: sans-+serif;
48
+ }
49
+
50
+ $x: 10px+10px;
51
+ $x: 20px-10px;
52
+ SCSS
53
+
54
+ it { should report_lint line: 2 }
55
+ it { should report_lint line: 3 }
56
+ it { should report_lint line: 4 }
57
+ it { should report_lint line: 5 }
58
+ it { should report_lint line: 6 }
59
+ it { should report_lint line: 9 }
60
+ it { should report_lint line: 10 }
61
+ end
62
+
63
+ context 'when numeric values with infix operators and newlines exist' do
64
+ let(:scss) { <<-SCSS }
65
+ p {
66
+ margin: 7px+
67
+ 7px;
68
+ padding: 9px
69
+ + 9px;
70
+ }
71
+ SCSS
72
+
73
+ it { should report_lint line: 2 }
74
+ it { should report_lint line: 4 }
75
+ end
76
+
77
+ context 'when numeric values with multiple infix operators exist' do
78
+ let(:scss) { <<-SCSS }
79
+ p {
80
+ margin: 5px*2+8px;
81
+ }
82
+ SCSS
83
+
84
+ it { should report_lint line: 2, count: 2 }
85
+ end
86
+
87
+ context 'when if nodes with comparison infix operators exist' do
88
+ let(:scss) { <<-SCSS }
89
+ p {
90
+ @if 3==2 {
91
+ margin: 5px;
92
+ }
93
+
94
+ @if 5>4 {
95
+ margin: 5px;
96
+ }
97
+ }
98
+ SCSS
99
+
100
+ it { should report_lint line: 2 }
101
+ it { should report_lint line: 6 }
102
+ end
103
+
104
+ context 'when values containing multiple operators exist' do
105
+ let(:scss) { <<-SCSS }
106
+ p {
107
+ margin: 2px+8px 18px+12px;
108
+ }
109
+ SCSS
110
+
111
+ it { should report_lint line: 2, count: 2 }
112
+ end
113
+
114
+ context 'when a function call contains a value with infix operators' do
115
+ let(:scss) { <<-SCSS }
116
+ p {
117
+ margin: some-function(2em+1em);
118
+ }
119
+ SCSS
120
+
121
+ it { should report_lint line: 2 }
122
+ end
123
+
124
+ context 'when mixin include contains a value with infix operators' do
125
+ let(:scss) { <<-SCSS }
126
+ p {
127
+ @include some-mixin(4em-2em);
128
+ }
129
+ SCSS
130
+
131
+ it { should report_lint line: 2 }
132
+ end
133
+
134
+ context 'when string contains an infix operator' do
135
+ let(:scss) { <<-SCSS }
136
+ p {
137
+ content: func("4em-2em");
138
+ }
139
+ SCSS
140
+
141
+ it { should_not report_lint }
142
+ end
143
+
144
+ context 'when string contains an interpolated infix operator' do
145
+ let(:scss) { <<-SCSS }
146
+ p {
147
+ content: "There are \#{11+1} months."
148
+ }
149
+ SCSS
150
+
151
+ it { should report_lint line: 2 }
152
+ end
153
+
154
+ context 'when values with non-evaluated operations exist' do
155
+ let(:scss) { <<-SCSS }
156
+ $my-variable: 10px;
157
+
158
+ p {
159
+ font: 12px/10px;
160
+ margin: 2em-1em;
161
+ padding: $my-variable;
162
+ font-size: em(16px / $base-font-size);
163
+ }
164
+ SCSS
165
+
166
+ it { should report_lint line: 5 }
167
+ end
168
+
169
+ context 'when values with nested operators and proper space exist' do
170
+ let(:scss) { <<-SCSS }
171
+ p {
172
+ top: ($number) * -2;
173
+ top: (($number)) * ((2));
174
+ top: (($number ) ) * ( ( 2 ) );
175
+ top: ($number
176
+ ) * ( 2 );
177
+ top: 2px + 3px + 4px;
178
+ top: (2px + 3px) + 4px;
179
+ top: ( 2px + 3px ) + 4px;
180
+ top: 2px + (3px + 4px);
181
+ top: 2px + ( 3px + 4px );
182
+ top: (2px) + (3px) + (4px);
183
+ top: ( 2px ) + ( 3px ) + ( 4px );
184
+ }
185
+
186
+ @if $var == 1 or $var == 2 {
187
+ }
188
+ SCSS
189
+
190
+ it { should_not report_lint }
191
+ end
192
+
193
+ context 'when values with proper division operations exist' do
194
+ let(:scss) { <<-SCSS }
195
+ $x: 20px;
196
+ p {
197
+ width: $x/2;
198
+ width: round(1.5)/2;
199
+ width: (50px/2);
200
+ width: 10px + 20px/2;
201
+ }
202
+ SCSS
203
+
204
+ it { should report_lint line: 3 }
205
+ it { should report_lint line: 4 }
206
+ it { should report_lint line: 5 }
207
+ it { should report_lint line: 6 }
208
+ end
209
+ end
210
+ context 'when one space is preferred' do
211
+ let(:style) { 'no_space' }
212
+
213
+ context 'when values with single-spaced infix operators exist' do
214
+ let(:scss) { <<-SCSS }
215
+ $x: 2px + 2px;
216
+
217
+ p {
218
+ margin: 5px + 5px;
219
+ width: 5px + 5px;
220
+ }
221
+ SCSS
222
+
223
+ it { should report_lint line: 1 }
224
+ it { should report_lint line: 4 }
225
+ it { should report_lint line: 5 }
226
+ end
227
+
228
+ context 'when values with no-spaced infix operators exist' do
229
+ let(:scss) { <<-SCSS }
230
+ $x: 2px+2px;
231
+
232
+ p {
233
+ margin: 5px+5px;
234
+ }
235
+ SCSS
236
+
237
+ it { should_not report_lint }
238
+ end
239
+ end
240
+ end
@@ -119,6 +119,26 @@ describe SCSSLint::Linter::SpaceBetweenParens do
119
119
  it { should_not report_lint }
120
120
  end
121
121
 
122
+ context 'when a 0-argument function has nothing between parens' do
123
+ let(:scss) { <<-SCSS }
124
+ p {
125
+ property: unique-id();
126
+ }
127
+ SCSS
128
+
129
+ it { should_not report_lint }
130
+ end
131
+
132
+ context 'when a 0-argument function has space between parens' do
133
+ let(:scss) { <<-SCSS }
134
+ p {
135
+ property: unique-id( );
136
+ }
137
+ SCSS
138
+
139
+ it { should report_lint line: 2 }
140
+ end
141
+
122
142
  context 'when parens exist in a silent comment' do
123
143
  let(:scss) { <<-SCSS }
124
144
  p {
@@ -132,13 +152,167 @@ describe SCSSLint::Linter::SpaceBetweenParens do
132
152
  context 'when parens exist in an outputted comment' do
133
153
  let(:scss) { <<-SCSS }
134
154
  p {
135
- margin: 0; /* Some comment ( with parens ) */
155
+ /*
156
+ * Some comment ( with parens )
157
+ */
158
+ margin: 0;
136
159
  }
137
160
  SCSS
138
161
 
139
162
  it { should_not report_lint }
140
163
  end
141
164
 
165
+ context 'when an import uses parens' do
166
+ let(:scss) { <<-SCSS }
167
+ @import url( foo );
168
+ @import url(bar);
169
+ SCSS
170
+
171
+ it { should report_lint line: 1, count: 2 }
172
+ end
173
+
174
+ context 'when a variable definition uses parens' do
175
+ let(:scss) { <<-SCSS }
176
+ $family: unquote( "Droid+Sans" );
177
+ $family: unquote("Droid+Sans");
178
+ SCSS
179
+
180
+ it { should report_lint line: 1, count: 2 }
181
+ end
182
+
183
+ context 'when a variable definition is wrapped in parens' do
184
+ let(:scss) { <<-SCSS }
185
+ $value-map: (text: #00ff00, background: #0000ff, border: #ff0000);
186
+ $value-map: ( text: #00ff00, background: #0000ff, border: #ff0000 );
187
+ SCSS
188
+
189
+ it { should report_lint line: 2, count: 2 }
190
+ end
191
+
192
+ context 'when a url uses parens' do
193
+ let(:scss) { <<-SCSS }
194
+ p {
195
+ background-image: url( 'bg1.png' );
196
+ }
197
+
198
+ code {
199
+ background-image: url('bg2.png');
200
+ }
201
+ SCSS
202
+
203
+ it { should report_lint line: 2, count: 2 }
204
+ end
205
+
206
+ context 'when a @media directive uses parens' do
207
+ let(:scss) { <<-SCSS }
208
+ @media screen and (orientation: landscape) {
209
+ // Stuff.
210
+ }
211
+
212
+ @media screen and ( orientation: landscape ) {
213
+ // Stuff.
214
+ }
215
+ SCSS
216
+
217
+ it { should report_lint line: 5, count: 2 }
218
+ end
219
+
220
+ context 'when an @at-root directive uses parens' do
221
+ let(:scss) { <<-SCSS }
222
+ @media screen {
223
+ @at-root (without: media) {
224
+ // Stuff.
225
+ }
226
+ @at-root ( with: media ) {
227
+ // Stuff.
228
+ }
229
+ }
230
+ SCSS
231
+
232
+ it { should report_lint line: 5, count: 2 }
233
+ end
234
+
235
+ context 'when an @if directive uses parens' do
236
+ let(:scss) { <<-SCSS }
237
+ p {
238
+ @if (1 + 2 == 2) { border: 1px; }
239
+
240
+ @if ( 1 + 2 == 2 ) { border: 1px; }
241
+ }
242
+ SCSS
243
+
244
+ it { should report_lint line: 4, count: 2 }
245
+ end
246
+
247
+ context 'when an @each directive uses parens around a list' do
248
+ let(:scss) { <<-SCSS }
249
+ @each $animal in (puma, sea-slug, egret) {
250
+ // Stuff.
251
+ }
252
+
253
+ @each $animal in ( puma, sea-slug, egret ) {
254
+ // Stuff.
255
+ }
256
+ SCSS
257
+
258
+ it { should report_lint line: 5, count: 2 }
259
+ end
260
+
261
+ context 'when an @each directive uses parens' do
262
+ let(:scss) { <<-SCSS }
263
+ /*@each $color, $cursor in (black, default), (blue, pointer) {
264
+ // Stuff.
265
+ }*/
266
+
267
+ @each $color, $cursor in ( black, default ), ( blue, pointer ) {
268
+ // Stuff.
269
+ }
270
+ SCSS
271
+
272
+ it { should report_lint line: 5, count: 4 }
273
+ end
274
+
275
+ context 'when a @mixin uses parens' do
276
+ let(:scss) { <<-SCSS }
277
+ @mixin sexy-border($color, $width) {
278
+ // Stuff.
279
+ }
280
+
281
+ @mixin rockin-border( $color, $width ) {
282
+ // Stuff.
283
+ }
284
+ SCSS
285
+
286
+ it { should report_lint line: 5, count: 2 }
287
+ end
288
+
289
+ context 'when an @include uses parens' do
290
+ let(:scss) { <<-SCSS }
291
+ @mixin sexy-border($color, $width) {
292
+ // Stuff.
293
+ }
294
+
295
+ a { @include sexy-border(blue, 1in); }
296
+ p { @include sexy-border( blue, 1in ); }
297
+ SCSS
298
+
299
+ it { should report_lint line: 6, count: 2 }
300
+ end
301
+
302
+ context 'when a @function uses parens' do
303
+ let(:scss) { <<-SCSS }
304
+ @function grid-width($n) {
305
+ @return $n * 2;
306
+ }
307
+
308
+ @function grid-height( $n ) {
309
+ @return $n * 2;
310
+ }
311
+ SCSS
312
+
313
+ it { should report_lint line: 5, count: 2 }
314
+ end
315
+
142
316
  context 'when the number of spaces has been explicitly set' do
143
317
  let(:linter_config) { { 'spaces' => 1 } }
144
318
 
@@ -259,5 +433,25 @@ describe SCSSLint::Linter::SpaceBetweenParens do
259
433
 
260
434
  it { should_not report_lint }
261
435
  end
436
+
437
+ context 'when a 0-argument function has nothing between parens' do
438
+ let(:scss) { <<-SCSS }
439
+ p {
440
+ property: unique-id();
441
+ }
442
+ SCSS
443
+
444
+ it { should report_lint line: 2 }
445
+ end
446
+
447
+ context 'when a 0-argument function has one space between parens' do
448
+ let(:scss) { <<-SCSS }
449
+ p {
450
+ property: unique-id( );
451
+ }
452
+ SCSS
453
+
454
+ it { should_not report_lint }
455
+ end
262
456
  end
263
457
  end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::Linter::TransitionAll do
4
+ context 'when transition-property is not set' do
5
+ let(:scss) { <<-SCSS }
6
+ p {
7
+ }
8
+ SCSS
9
+
10
+ it { should_not report_lint }
11
+ end
12
+
13
+ context 'when transition-property is set to none' do
14
+ let(:scss) { <<-SCSS }
15
+ p {
16
+ transition-property: none;
17
+ }
18
+ SCSS
19
+
20
+ it { should_not report_lint }
21
+ end
22
+
23
+ context 'when transition-property is not set to all' do
24
+ let(:scss) { <<-SCSS }
25
+ p {
26
+ transition-property: color;
27
+ }
28
+ SCSS
29
+
30
+ it { should_not report_lint }
31
+ end
32
+
33
+ context 'when transition-property is set to all' do
34
+ let(:scss) { <<-SCSS }
35
+ p {
36
+ transition-property: all;
37
+ }
38
+ SCSS
39
+
40
+ it { should report_lint line: 2 }
41
+ end
42
+
43
+ context 'when transition shorthand for transition-property is not set' do
44
+ let(:scss) { <<-SCSS }
45
+ p {
46
+ }
47
+ SCSS
48
+
49
+ it { should_not report_lint }
50
+ end
51
+
52
+ context 'when transition shorthand for transition-property is set to none' do
53
+ let(:scss) { <<-SCSS }
54
+ p {
55
+ transition: none;
56
+ }
57
+ SCSS
58
+
59
+ it { should_not report_lint }
60
+ end
61
+
62
+ context 'when transition shorthand for transition-property is not set to all' do
63
+ let(:scss) { <<-SCSS }
64
+ p {
65
+ transition: color 1s linear;
66
+ }
67
+ SCSS
68
+
69
+ it { should_not report_lint }
70
+ end
71
+
72
+ context 'when transition shorthand for transition-property is set to all' do
73
+ let(:scss) { <<-SCSS }
74
+ p {
75
+ transition: all 1s linear;
76
+ }
77
+ SCSS
78
+
79
+ it { should report_lint line: 2 }
80
+ end
81
+ end