scss-lint 0.34.0 → 0.35.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d9d896111a17640c23d31de062d34329fd52a56a
4
- data.tar.gz: 6f34a07866cd4b7c77a18137f2bec2570e9f31e5
3
+ metadata.gz: b4c9a5150295e39ef201b5e859ec234fca634c4f
4
+ data.tar.gz: 7ba8ffe0e6d78046545adc099c8da31fa66ade90
5
5
  SHA512:
6
- metadata.gz: d100dfddcde8591cbff342d88bc37f685ac337eb32b9193b87f09c46cf50dc61c04717a4e67fe843f6135fb186f8c5e43b7c6711680d67e766e56e71bb04ff94
7
- data.tar.gz: 65e67618d2e00e428a38adb5243236dea6464f17df75914937da60afbf3eded4f3b0e7be4d526b4d05c264c9a0ef5f5ed1cc13cbab3dac4a5cde3673f4e991d0
6
+ metadata.gz: f845f596de85f75b73877b5119d7b489595235ae0bf528fc6b5d1bfa3a9d9876ae362a3971358fe3f3851b068fb61fad663ecf54360ed1c52ac0e3a0e1eaf4d4
7
+ data.tar.gz: 91ef3f85f89903fa81f3f6d125c6514af658da43c9ba13d46d86e11aa0cfcdafdb3f6f88ba5723ed634a9ca276523bdb689acbc49b351c631fdebc4b6669fda9
@@ -176,11 +176,11 @@ linters:
176
176
  enabled: false
177
177
  properties: []
178
178
 
179
- VendorPrefixes:
179
+ VendorPrefix:
180
180
  enabled: true
181
181
  identifier_list: base
182
- include: []
183
- exclude: []
182
+ additional_identifiers: []
183
+ excluded_identifiers: []
184
184
 
185
185
  ZeroUnit:
186
186
  enabled: true
@@ -22,6 +22,16 @@ clear
22
22
  transform
23
23
  transition
24
24
 
25
+ animation
26
+ animation-name
27
+ animation-duration
28
+ animation-timing-function
29
+ animation-delay
30
+ animation-iteration-count
31
+ animation-direction
32
+ animation-fill-mode
33
+ animation-play-state
34
+
25
35
  visibility
26
36
  opacity
27
37
  z-index
@@ -89,7 +89,6 @@ background-image
89
89
  background-repeat
90
90
  background-position
91
91
  background-size
92
- cursor
93
92
 
94
93
  # Text
95
94
 
@@ -88,11 +88,13 @@ module SCSSLint
88
88
  # the comment itself).
89
89
  child = node
90
90
  prev_child = node
91
- while (child = last_child(child)) != prev_child
91
+ until [nil, prev_child].include?(child = last_child(child))
92
92
  prev_child = child
93
93
  end
94
94
 
95
- end_line = child.line
95
+ # Fall back to prev_child if last_child() returned nil (i.e. node had no
96
+ # children with line numbers)
97
+ end_line = (child || prev_child).line
96
98
 
97
99
  @disabled_lines.merge(start_line..end_line)
98
100
  end
@@ -103,13 +105,22 @@ module SCSSLint
103
105
  # tree's {#children} method does not return nodes sorted by their line
104
106
  # number.
105
107
  #
108
+ # Returns `nil` if node has no children or no children with associated line
109
+ # numbers.
110
+ #
106
111
  # @param node [Sass::Tree::Node, Sass::Script::Tree::Node]
107
112
  # @return [Sass::Tree::Node, Sass::Script::Tree::Node]
108
113
  def last_child(node)
109
- node.children.inject(node) do |lowest, child|
114
+ last = node.children.inject(node) do |lowest, child|
110
115
  return lowest unless child.respond_to?(:line)
111
116
  lowest.line < child.line ? child : lowest
112
117
  end
118
+
119
+ # In this case, none of the children have associated line numbers or the
120
+ # node has no children at all, so return `nil`.
121
+ return if last == node
122
+
123
+ last
113
124
  end
114
125
  end
115
126
  end
@@ -13,12 +13,14 @@ module SCSSLint
13
13
  # Creates a parsed representation of an SCSS document from the given string
14
14
  # or file.
15
15
  #
16
- # @param scss_or_filename [String]
17
- def initialize(scss_or_filename)
18
- if File.exist?(scss_or_filename)
19
- build_from_file(scss_or_filename)
20
- else
21
- build_from_string(scss_or_filename)
16
+ # @param options [Hash]
17
+ # @option options [String] :file The file to load
18
+ # @option options [String] :code The code to parse
19
+ def initialize(options = {})
20
+ if options[:file]
21
+ build_from_file(options[:file])
22
+ elsif options[:code]
23
+ build_from_string(options[:code])
22
24
  end
23
25
 
24
26
  # Need to force encoding to avoid Windows-related bugs.
@@ -9,7 +9,7 @@ module SCSSLint
9
9
  # Source range sometimes includes closing parenthesis, so extract it
10
10
  color = source_from_range(node.source_range)[/(#?[a-z0-9]+)/i, 1]
11
11
 
12
- record_lint(node, color)
12
+ record_lint(node, color) if color?(color)
13
13
  end
14
14
 
15
15
  def visit_script_string(node)
@@ -1,6 +1,6 @@
1
1
  module SCSSLint
2
2
  # Checks for consistent indentation of nested declarations and rule sets.
3
- class Linter::Indentation < Linter
3
+ class Linter::Indentation < Linter # rubocop:disable ClassLength
4
4
  include LinterRegistry
5
5
 
6
6
  def visit_root(_node)
@@ -40,7 +40,7 @@ module SCSSLint
40
40
  end
41
41
 
42
42
  def check_indent_width(node, other_character, character_name, other_character_name)
43
- actual_indent = engine.lines[node.line - 1][/^(\s*)/, 1]
43
+ actual_indent = node_indent(node)
44
44
 
45
45
  if actual_indent.include?(other_character)
46
46
  add_lint(node.line,
@@ -49,14 +49,11 @@ module SCSSLint
49
49
  return true
50
50
  end
51
51
 
52
- unless allow_arbitrary_indent?(node) || actual_indent.length == @indent
53
- add_lint(node.line,
54
- "Line should be indented #{@indent} #{character_name}s, " \
55
- "but was indented #{actual_indent.length} #{character_name}s")
56
- return true
52
+ if config['allow_non_nested_indentation']
53
+ check_arbitrary_indent(node, actual_indent.length, character_name)
54
+ else
55
+ check_regular_indent(node, actual_indent.length, character_name)
57
56
  end
58
-
59
- false
60
57
  end
61
58
 
62
59
  # Deal with `else` statements
@@ -131,10 +128,70 @@ module SCSSLint
131
128
  same_position?(node.source_range.end_pos, first_child_source.start_pos)
132
129
  end
133
130
 
134
- def allow_arbitrary_indent?(node)
135
- @indent == 0 &&
136
- config['allow_non_nested_indentation'] &&
137
- node.is_a?(Sass::Tree::RuleNode)
131
+ def check_regular_indent(node, actual_indent, character_name)
132
+ return if actual_indent == @indent
133
+
134
+ add_lint(node.line,
135
+ "Line should be indented #{@indent} #{character_name}s, " \
136
+ "but was indented #{actual_indent} #{character_name}s")
137
+ true
138
+ end
139
+
140
+ def check_arbitrary_indent(node, actual_indent, character_name) # rubocop:disable CyclomaticComplexity, MethodLength, LineLength
141
+ # Allow rulesets to be indented any amount when the indent is zero, as
142
+ # long as it's a multiple of the indent width
143
+ if ruleset_under_root_node?(node)
144
+ unless actual_indent % @indent_width == 0
145
+ add_lint(node.line,
146
+ "Line must be indented a multiple of #{@indent_width} " \
147
+ "#{character_name}s, but was indented #{actual_indent} #{character_name}s")
148
+ return true
149
+ end
150
+ end
151
+
152
+ if @indent == 0
153
+ unless node.is_a?(Sass::Tree::RuleNode) || actual_indent == 0
154
+ add_lint(node.line,
155
+ "Line should be indented 0 #{character_name}s, " \
156
+ "but was indented #{actual_indent} #{character_name}s")
157
+ return true
158
+ end
159
+ elsif !one_shift_greater_than_parent?(node, actual_indent)
160
+ parent_indent = node_indent(node.node_parent).length
161
+ expected_indent = parent_indent + @indent_width
162
+
163
+ add_lint(node.line,
164
+ "Line should be indented #{expected_indent} #{character_name}s, " \
165
+ "but was indented #{actual_indent} #{character_name}s")
166
+ return true
167
+ end
168
+ end
169
+
170
+ # Returns whether node is a ruleset not nested within any other ruleset.
171
+ #
172
+ # @param node [Sass::Tree::Node]
173
+ # @return [true,false]
174
+ def ruleset_under_root_node?(node)
175
+ @indent == 0 && node.is_a?(Sass::Tree::RuleNode)
176
+ end
177
+
178
+ # Returns whether node is indented exactly one indent width greater than its
179
+ # parent.
180
+ #
181
+ # @param node [Sass::Tree::Node]
182
+ # @return [true,false]
183
+ def one_shift_greater_than_parent?(node, actual_indent)
184
+ parent_indent = node_indent(node.node_parent).length
185
+ expected_indent = parent_indent + @indent_width
186
+ expected_indent == actual_indent
187
+ end
188
+
189
+ # Return indentation of a node.
190
+ #
191
+ # @param node [Sass::Tree::Node]
192
+ # @return [Integer]
193
+ def node_indent(node)
194
+ engine.lines[node.line - 1][/^(\s*)/, 1]
138
195
  end
139
196
  end
140
197
  end
@@ -1,12 +1,12 @@
1
1
  module SCSSLint
2
2
  # Checks for vendor prefixes.
3
- class Linter::VendorPrefixes < Linter
3
+ class Linter::VendorPrefix < Linter
4
4
  include LinterRegistry
5
5
 
6
6
  def visit_root(_node)
7
7
  @identifiers = Set.new(extract_identifiers_from_config)
8
- @identifiers.merge(Set.new(config['include']))
9
- @exclusions = Set.new(config['exclude'])
8
+ @identifiers.merge(Set.new(config['additional_identifiers']))
9
+ @exclusions = Set.new(config['excluded_identifiers'])
10
10
  yield
11
11
  end
12
12
 
@@ -30,7 +30,7 @@ module SCSSLint
30
30
 
31
31
  # @param file [String]
32
32
  def find_lints(file)
33
- engine = Engine.new(file)
33
+ engine = Engine.new(file: file)
34
34
 
35
35
  @linters.each do |linter|
36
36
  begin
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module SCSSLint
3
- VERSION = '0.34.0'
3
+ VERSION = '0.35.0'
4
4
  end
@@ -34,6 +34,7 @@ describe SCSSLint::CLI do
34
34
 
35
35
  before do
36
36
  SCSSLint::FileFinder.any_instance.stub(:find).and_return(files)
37
+ SCSSLint::Runner.any_instance.stub(:find_lints)
37
38
  end
38
39
 
39
40
  def safe_run
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SCSSLint::Engine do
4
- let(:engine) { described_class.new(scss) }
4
+ let(:engine) { described_class.new(code: scss) }
5
5
 
6
6
  context 'when a @media directive is present' do
7
7
  let(:scss) { <<-SCSS }
@@ -99,4 +99,24 @@ describe SCSSLint::Linter::ColorVariable do
99
99
 
100
100
  it { should_not report_lint }
101
101
  end
102
+
103
+ context 'when a property contains "transparent"' do
104
+ let(:scss) { <<-SCSS }
105
+ p {
106
+ border: 1px solid transparent;
107
+ }
108
+ SCSS
109
+
110
+ it { should_not report_lint }
111
+ end
112
+
113
+ context 'when a property with function calls contains "transparent"' do
114
+ let(:scss) { <<-SCSS }
115
+ p {
116
+ border: 1px solid some-func(transparent);
117
+ }
118
+ SCSS
119
+
120
+ it { should_not report_lint }
121
+ end
102
122
  end
@@ -309,5 +309,39 @@ describe SCSSLint::Linter::Indentation do
309
309
 
310
310
  it { should report_lint line: 2 }
311
311
  end
312
+
313
+ context 'and a nested non-ruleset is correctly indented' do
314
+ let(:scss) { <<-SCSS }
315
+ .one {
316
+ color: #000;
317
+ }
318
+ .two {
319
+ margin: 0;
320
+ }
321
+ SCSS
322
+
323
+ it { should_not report_lint }
324
+ end
325
+
326
+ context 'and a nested non-ruleset is incorrectly indented' do
327
+ let(:scss) { <<-SCSS }
328
+ .one {
329
+ color: #000;
330
+ }
331
+ .two {
332
+ margin: 0;
333
+ }
334
+ SCSS
335
+
336
+ it { should report_lint line: 5 }
337
+ end
338
+
339
+ context 'and a non-nested non-ruleset is correctly indented' do
340
+ let(:scss) { <<-SCSS }
341
+ $var: 1
342
+ SCSS
343
+
344
+ it { should_not report_lint }
345
+ end
312
346
  end
313
347
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe SCSSLint::Linter::VendorPrefixes do
3
+ describe SCSSLint::Linter::VendorPrefix do
4
4
  context 'when no vendor-prefix is used' do
5
5
  let(:scss) { <<-SCSS }
6
6
  div {
@@ -280,11 +280,16 @@ describe SCSSLint::Linter::VendorPrefixes do
280
280
  # Excluding and Including
281
281
 
282
282
  context 'when manually excluding identifiers' do
283
- let(:linter_config) { { 'exclude' => %w[transform selection] } }
283
+ let(:linter_config) do
284
+ {
285
+ 'identifier_list' => 'base',
286
+ 'excluded_identifiers' => %w[transform selection],
287
+ }
288
+ end
284
289
 
285
290
  let(:scss) { <<-SCSS }
286
291
  div {
287
- -wekit-transform: translateZ(0);
292
+ -webkit-transform: translateZ(0);
288
293
  }
289
294
  ::-moz-selection {
290
295
  color: #000;
@@ -295,7 +300,13 @@ describe SCSSLint::Linter::VendorPrefixes do
295
300
  end
296
301
 
297
302
  context 'when manually including identifiers' do
298
- let(:linter_config) { { 'include' => ['padding-end'] } }
303
+ let(:linter_config) do
304
+ {
305
+ 'identifier_list' => 'base',
306
+ 'additional_identifiers' => ['padding-end'],
307
+ 'excluded_identifiers' => [],
308
+ }
309
+ end
299
310
 
300
311
  let(:scss) { <<-SCSS }
301
312
  div {
@@ -71,7 +71,7 @@ describe SCSSLint::Runner do
71
71
  end
72
72
 
73
73
  before do
74
- SCSSLint::Engine.stub(:new).with(files.last).and_raise(error)
74
+ SCSSLint::Engine.stub(:new).with(file: files.last).and_raise(error)
75
75
  end
76
76
 
77
77
  it 'records the error as a lint' do
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe SCSSLint::SelectorVisitor do
4
4
  describe '#visit' do
5
- let(:engine) { SCSSLint::Engine.new(scss) }
5
+ let(:engine) { SCSSLint::Engine.new(code: scss) }
6
6
  before { RuleVisitor.new(visitor).run(engine) }
7
7
 
8
8
  # Visits every rule in the given parse tree and passes the parsed selector
@@ -28,7 +28,7 @@ RSpec.configure do |config|
28
28
  SCSSLint::Config.default.linter_options(subject)
29
29
  end
30
30
 
31
- subject.run(SCSSLint::Engine.new(normalized_css), local_config)
31
+ subject.run(SCSSLint::Engine.new(code: normalized_css), local_config)
32
32
  end
33
33
  end
34
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scss-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.34.0
4
+ version: 0.35.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Causes Engineering
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-23 00:00:00.000000000 Z
12
+ date: 2015-03-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rainbow
@@ -142,7 +142,7 @@ files:
142
142
  - lib/scss_lint/linter/url_format.rb
143
143
  - lib/scss_lint/linter/url_quotes.rb
144
144
  - lib/scss_lint/linter/variable_for_property.rb
145
- - lib/scss_lint/linter/vendor_prefixes.rb
145
+ - lib/scss_lint/linter/vendor_prefix.rb
146
146
  - lib/scss_lint/linter/zero_unit.rb
147
147
  - lib/scss_lint/linter_registry.rb
148
148
  - lib/scss_lint/location.rb
@@ -211,7 +211,7 @@ files:
211
211
  - spec/scss_lint/linter/url_format_spec.rb
212
212
  - spec/scss_lint/linter/url_quotes_spec.rb
213
213
  - spec/scss_lint/linter/variable_for_property_spec.rb
214
- - spec/scss_lint/linter/vendor_prefixes_spec.rb
214
+ - spec/scss_lint/linter/vendor_prefix_spec.rb
215
215
  - spec/scss_lint/linter/zero_unit_spec.rb
216
216
  - spec/scss_lint/linter_registry_spec.rb
217
217
  - spec/scss_lint/linter_spec.rb
@@ -254,9 +254,7 @@ signing_key:
254
254
  specification_version: 4
255
255
  summary: SCSS lint tool
256
256
  test_files:
257
- - spec/scss_lint/cli_spec.rb
258
257
  - spec/scss_lint/config_spec.rb
259
- - spec/scss_lint/engine_spec.rb
260
258
  - spec/scss_lint/file_finder_spec.rb
261
259
  - spec/scss_lint/linter/bang_format_spec.rb
262
260
  - spec/scss_lint/linter/border_zero_spec.rb
@@ -277,7 +275,6 @@ test_files:
277
275
  - spec/scss_lint/linter/id_selector_spec.rb
278
276
  - spec/scss_lint/linter/import_path_spec.rb
279
277
  - spec/scss_lint/linter/important_rule_spec.rb
280
- - spec/scss_lint/linter/indentation_spec.rb
281
278
  - spec/scss_lint/linter/leading_zero_spec.rb
282
279
  - spec/scss_lint/linter/mergeable_selector_spec.rb
283
280
  - spec/scss_lint/linter/name_format_spec.rb
@@ -305,8 +302,9 @@ test_files:
305
302
  - spec/scss_lint/linter/url_format_spec.rb
306
303
  - spec/scss_lint/linter/url_quotes_spec.rb
307
304
  - spec/scss_lint/linter/variable_for_property_spec.rb
308
- - spec/scss_lint/linter/vendor_prefixes_spec.rb
305
+ - spec/scss_lint/linter/vendor_prefix_spec.rb
309
306
  - spec/scss_lint/linter/zero_unit_spec.rb
307
+ - spec/scss_lint/linter/indentation_spec.rb
310
308
  - spec/scss_lint/linter_registry_spec.rb
311
309
  - spec/scss_lint/linter_spec.rb
312
310
  - spec/scss_lint/location_spec.rb
@@ -318,9 +316,10 @@ test_files:
318
316
  - spec/scss_lint/reporter/json_reporter_spec.rb
319
317
  - spec/scss_lint/reporter/xml_reporter_spec.rb
320
318
  - spec/scss_lint/reporter_spec.rb
319
+ - spec/scss_lint/cli_spec.rb
320
+ - spec/scss_lint/engine_spec.rb
321
321
  - spec/scss_lint/runner_spec.rb
322
322
  - spec/scss_lint/selector_visitor_spec.rb
323
- - spec/spec_helper.rb
324
323
  - spec/support/isolated_environment.rb
325
324
  - spec/support/matchers/report_lint.rb
326
- has_rdoc:
325
+ - spec/spec_helper.rb