scss_lint 0.49.0 → 0.50.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: 881e2595ce6e859e53e9148db36e2f3d11bcb429
4
- data.tar.gz: e28e168aa7ec435017b415278fe3fc68c8b911ca
3
+ metadata.gz: 8c6dc8c5fb0f7ed2ced515528060a877c6c7fbaa
4
+ data.tar.gz: ac668a73f2506c96684d0ff3e5451256980ac6e3
5
5
  SHA512:
6
- metadata.gz: f27ed9d01d9a7920c3d88d0d9345b8ba107978fd536d90618d406af9cc8209221cc220054d1f118320af98927fce38b91144c4af1c4686d2a09b7dda2394aaaa
7
- data.tar.gz: c6cfb9ba3bf3a0957cbd756b7e0cf9b4702432a94275214b97c98fd2884e63bc225adaec713148d41fae2b0078e070ed6e77ded6d3c4c4139b0cb8e4aaa0b3ec
6
+ metadata.gz: e1e8735bf5dedb6d82cebed74dc9e100aa21f50978d54fda8f3d814def9f6377889d86bc2f9be1617dcf42e4ee0a56c999e8bc981e1d23388a00c08fb5980a54
7
+ data.tar.gz: 91b2605482f554c157b5c98f583bfaadede6e5c003d1c37bfe78d51e39abb570b38374e25dd811c5d3b48cd49580cfc610f1f0cfd027fe097551c30b50e564d3
data/config/default.yml CHANGED
@@ -181,6 +181,11 @@ linters:
181
181
  enabled: true
182
182
  style: one_space # or 'no_space', or 'at_least_one_space'
183
183
 
184
+ SpaceAfterComment:
185
+ enabled: true
186
+ style: at_least_one_space # or 'no_space', or 'at_least_one_space'
187
+ allow_empty_comments: true
188
+
184
189
  SpaceAfterPropertyColon:
185
190
  enabled: true
186
191
  style: one_space # or 'no_space', or 'at_least_one_space', or 'aligned'
data/lib/scss_lint/cli.rb CHANGED
@@ -63,14 +63,7 @@ module SCSSLint
63
63
 
64
64
  def scan_for_lints(options, config)
65
65
  runner = Runner.new(config)
66
- files =
67
- if options[:stdin_file_path]
68
- [{ file: STDIN, path: options[:stdin_file_path] }]
69
- else
70
- FileFinder.new(config).find(options[:files]).map do |file_path|
71
- { path: file_path }
72
- end
73
- end
66
+ files = files_to_lint(options, config)
74
67
  runner.run(files)
75
68
  report_lints(options, runner.lints, files)
76
69
 
@@ -83,6 +76,17 @@ module SCSSLint
83
76
  end
84
77
  end
85
78
 
79
+ def files_to_lint(options, config)
80
+ if options[:stdin_file_path]
81
+ [{ file: STDIN, path: options[:stdin_file_path] }]
82
+ else
83
+ patterns = Array(options[:files]).any? ? Array(options[:files]) : config.scss_files
84
+ FileFinder.new(config).find(patterns).map do |file_path|
85
+ { path: file_path }
86
+ end
87
+ end
88
+ end
89
+
86
90
  def handle_runtime_exception(exception, options) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/LineLength, Metrics/MethodLength
87
91
  case exception
88
92
  when SCSSLint::Exceptions::InvalidCLIOption
@@ -270,9 +270,9 @@ module SCSSLint
270
270
  end
271
271
 
272
272
  def linter_options(linter)
273
- { 'severity' => @options['severity'] }.merge(
274
- @options['linters'].fetch(self.class.linter_name(linter), {})
275
- )
273
+ options = @options['linters'].fetch(self.class.linter_name(linter), {})
274
+ options['severity'] ||= @options['severity']
275
+ options
276
276
  end
277
277
 
278
278
  def excluded_file?(file_path)
@@ -304,8 +304,8 @@ module SCSSLint
304
304
 
305
305
  # @return Array
306
306
  def scss_files
307
- if path = @options['scss_files']
308
- Dir[path]
307
+ if path = @options['scss_files'] && Array(path).any?
308
+ Array(path).map { |p| Dir[p] }.flatten.uniq
309
309
  else
310
310
  []
311
311
  end
@@ -28,11 +28,10 @@ module SCSSLint
28
28
 
29
29
  # Need to force encoding to avoid Windows-related bugs.
30
30
  # Need to encode with universal newline to avoid other Windows-related bugs.
31
- # Need `to_a` for Ruby 1.9.3.
32
31
  encoding = 'UTF-8'
33
32
  @lines = @contents.force_encoding(encoding)
34
33
  .encode(encoding, universal_newline: true)
35
- .lines.to_a
34
+ .lines
36
35
  @tree = @engine.to_tree
37
36
  find_any_control_commands
38
37
  rescue Encoding::UndefinedConversionError, Sass::SyntaxError, ArgumentError => error
@@ -19,8 +19,10 @@ module SCSSLint
19
19
  #
20
20
  # @param patterns [Array<String>] a list of file paths and glob patterns
21
21
  def find(patterns)
22
- # If no explicit patterns given, use patterns listed in config
23
- patterns = @config.scss_files if patterns.empty?
22
+ if patterns.empty?
23
+ raise SCSSLint::Exceptions::NoFilesError,
24
+ 'No files, paths, or patterns were specified'
25
+ end
24
26
 
25
27
  matched_files = extract_files_from(patterns)
26
28
  if matched_files.empty?
@@ -52,7 +52,8 @@ module SCSSLint
52
52
 
53
53
  # Helper for creating lint from a parse tree node
54
54
  #
55
- # @param node_or_line_or_location [Sass::Script::Tree::Node, Fixnum, SCSSLint::Location]
55
+ # @param node_or_line_or_location [Sass::Script::Tree::Node, Fixnum,
56
+ # SCSSLint::Location, Sass::Source::Position]
56
57
  # @param message [String]
57
58
  def add_lint(node_or_line_or_location, message)
58
59
  @lints << Lint.new(self,
@@ -165,6 +166,8 @@ module SCSSLint
165
166
  def extract_location(node_or_line_or_location)
166
167
  if node_or_line_or_location.is_a?(Location)
167
168
  node_or_line_or_location
169
+ elsif node_or_line_or_location.is_a?(Sass::Source::Position)
170
+ Location.new(node_or_line_or_location.line, node_or_line_or_location.offset)
168
171
  elsif node_or_line_or_location.respond_to?(:source_range) &&
169
172
  node_or_line_or_location.source_range
170
173
  location_from_range(node_or_line_or_location.source_range)
@@ -4,6 +4,12 @@ module SCSSLint
4
4
  class Linter::ColorKeyword < Linter
5
5
  include LinterRegistry
6
6
 
7
+ FUNCTIONS_ALLOWING_COLOR_KEYWORD_ARGS = %w[
8
+ map-get
9
+ map-has-key
10
+ map-remove
11
+ ].to_set
12
+
7
13
  def visit_script_color(node)
8
14
  word = source_from_range(node.source_range)[/([a-z]+)/i, 1]
9
15
  add_color_lint(node, word) if color_keyword?(word)
@@ -20,7 +26,7 @@ module SCSSLint
20
26
  private
21
27
 
22
28
  def add_color_lint(node, original)
23
- return if in_map?(node)
29
+ return if in_map?(node) || in_allowed_function_call?(node)
24
30
 
25
31
  hex_form = Sass::Script::Value::Color.new(color_keyword_to_code(original)).tap do |color|
26
32
  color.options = {} # `inspect` requires options to be set
@@ -34,5 +40,11 @@ module SCSSLint
34
40
  def in_map?(node)
35
41
  node_ancestor(node, 2).is_a?(Sass::Script::Tree::MapLiteral)
36
42
  end
43
+
44
+ def in_allowed_function_call?(node)
45
+ if (funcall = node_ancestor(node, 2)).is_a?(Sass::Script::Tree::Funcall)
46
+ FUNCTIONS_ALLOWING_COLOR_KEYWORD_ARGS.include?(funcall.name)
47
+ end
48
+ end
37
49
  end
38
50
  end
@@ -12,11 +12,13 @@ module SCSSLint
12
12
  # every word boundary (so %placeholder becomes ['%', 'placeholder']).
13
13
  selector = node.selector.join
14
14
 
15
- # Ignore if this is a placeholder
16
- return if selector.start_with?('%')
17
-
18
- add_lint(node, 'Prefer using placeholder selectors (e.g. ' \
19
- '%some-placeholder) with @extend')
15
+ if selector.include?(',')
16
+ add_lint(node, 'Avoid comma sequences in `@extend` directives; ' \
17
+ 'prefer single placeholder selectors (e.g. `%some-placeholder`)')
18
+ elsif !selector.start_with?('%')
19
+ add_lint(node, 'Prefer using placeholder selectors (e.g. ' \
20
+ '%some-placeholder) with @extend')
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -27,9 +27,9 @@ module SCSSLint
27
27
  node.children.each_with_object([]) do |child_node|
28
28
  if DEFINITIONS.key?(child_node.class)
29
29
  register_node child_node
30
- else
31
- yield
32
30
  end
31
+
32
+ yield
33
33
  end
34
34
 
35
35
  # After we have visited everything, we want to see if any private things
@@ -5,11 +5,23 @@ module SCSSLint
5
5
  class Linter::Shorthand < Linter
6
6
  include LinterRegistry
7
7
 
8
+ def visit_root(*)
9
+ @shorthands_forbidden = @config['allowed_shorthands'] == []
10
+ yield # Continue linting children
11
+ end
12
+
8
13
  # @param node [Sass::Tree::Node]
9
14
  def visit_prop(node)
10
15
  property_name = node.name.join
11
16
  return unless SHORTHANDABLE_PROPERTIES.include?(property_name)
12
17
 
18
+ if @shorthands_forbidden
19
+ add_lint(node, "The `#{property_name}` shorthand property is " \
20
+ 'forbidden since the `allowed_shorthands` option ' \
21
+ 'is set to an empty list.')
22
+
23
+ end
24
+
13
25
  case node.value
14
26
  when Sass::Script::Tree::Literal
15
27
  check_script_literal(property_name, node.value)
@@ -68,6 +80,8 @@ module SCSSLint
68
80
  # @param node [Sass::Script::Value::String]
69
81
  # @param values [Array<String>]
70
82
  def check_shorthand(prop, node, values)
83
+ values = shorthand_values(values)
84
+
71
85
  add_lint(node, "Shorthands of length `#{values.count}` are not allowed. " \
72
86
  "Value was `#{values.join(' ')}`") unless allowed?(values.count)
73
87
 
@@ -138,5 +152,9 @@ module SCSSLint
138
152
  return false unless config['allowed_shorthands']
139
153
  config['allowed_shorthands'].map(&:to_i).include?(size)
140
154
  end
155
+
156
+ def shorthand_values(values)
157
+ values.take(4).take_while { |value| !value.to_s.start_with?('!') }
158
+ end
141
159
  end
142
160
  end
@@ -89,7 +89,8 @@ module SCSSLint
89
89
  next if char == "\n" || # Ignore trailing spaces
90
90
  valid_spaces_after_comma?(spaces)
91
91
 
92
- add_lint comma_position, "Commas in #{arg_type} should be followed by a single space"
92
+ style_message = config['style'].tr('_', ' ')
93
+ add_lint comma_position, "Commas in #{arg_type} should be followed by #{style_message}"
93
94
  end
94
95
  end
95
96
 
@@ -0,0 +1,69 @@
1
+ module SCSSLint
2
+ # Checks for a space after comment literals
3
+ class Linter::SpaceAfterComment < Linter
4
+ include LinterRegistry
5
+
6
+ def visit_comment(node)
7
+ source = source_from_range(node.source_range).strip
8
+ check_method = "check_#{node.type}_comment"
9
+ send(check_method, node, source)
10
+ end
11
+
12
+ private
13
+
14
+ def check_silent_comment(node, source)
15
+ source.split("\n").each_with_index do |line, index|
16
+ next if config['allow_empty_comments'] && line.strip.length <= 2
17
+ whitespace = whitespace_after_comment(line, 2)
18
+ check_for_space(node.line + index, whitespace)
19
+ end
20
+ end
21
+
22
+ def check_normal_comment(node, source)
23
+ whitespace = whitespace_after_comment(source, 2)
24
+ check_for_space(node, whitespace)
25
+ end
26
+
27
+ def check_loud_comment(node, source)
28
+ whitespace = whitespace_after_comment(source, 3)
29
+ check_for_space(node, whitespace)
30
+ end
31
+
32
+ def check_for_no_spaces(node_or_line, whitespace)
33
+ return if whitespace == 0
34
+ add_lint(node_or_line, 'Comment literal should not be followed by any spaces')
35
+ end
36
+
37
+ def check_for_one_space(node_or_line, whitespace)
38
+ return if whitespace == 1
39
+ add_lint(node_or_line, 'Comment literal should be followed by one space')
40
+ end
41
+
42
+ def check_for_at_least_one_space(node_or_line, whitespace)
43
+ return if whitespace >= 1
44
+ add_lint(node_or_line, 'Comment literal should be followed by at least one space')
45
+ end
46
+
47
+ def check_for_space(node_or_line, spaces)
48
+ case config['style']
49
+ when 'one_space'
50
+ check_for_one_space(node_or_line, spaces)
51
+ when 'no_space'
52
+ check_for_no_spaces(node_or_line, spaces)
53
+ when 'at_least_one_space'
54
+ check_for_at_least_one_space(node_or_line, spaces)
55
+ end
56
+ end
57
+
58
+ def whitespace_after_comment(source, offset)
59
+ whitespace = 0
60
+
61
+ while [' ', "\t"].include? source[offset]
62
+ whitespace += 1
63
+ offset += 1
64
+ end
65
+
66
+ whitespace
67
+ end
68
+ end
69
+ end
@@ -34,7 +34,7 @@ module SCSSLint
34
34
  '`{` should be preceded by at least one space')
35
35
  else
36
36
  return unless chars_before_incorrect(string)
37
- style_message = (config['style'] == 'new_line') ? 'a new line' : 'one space'
37
+ style_message = config['style'] == 'new_line' ? 'a new line' : 'one space'
38
38
  add_lint(line, 'Opening curly brace `{` should be ' \
39
39
  "preceded by #{style_message}")
40
40
  end
@@ -102,7 +102,7 @@ module SCSSLint
102
102
  # An unrelated right paren will sneak into the source of a node if there is no
103
103
  # whitespace between the node and the right paren.
104
104
  def trim_right_paren(source)
105
- (source.count(')') == source.count('(') + 1) ? source[0..-2] : source
105
+ source.count(')') == source.count('(') + 1 ? source[0..-2] : source
106
106
  end
107
107
 
108
108
  def expected_spaces
@@ -3,8 +3,6 @@ module SCSSLint
3
3
  class Linter::StringQuotes < Linter
4
4
  include LinterRegistry
5
5
 
6
- CHARSET_DIRECTIVE_LENGTH = '@charset'.length
7
-
8
6
  def visit_script_stringinterpolation(node)
9
7
  # We can't statically determine what the resultant string looks like when
10
8
  # string interpolation is used, e.g. "one #{$var} three" could be a very
@@ -26,13 +24,6 @@ module SCSSLint
26
24
  check_quotes(node, source_from_range(node.source_range))
27
25
  end
28
26
 
29
- def visit_charset(node)
30
- # `@charset` source range includes entire declaration, so exclude that prefix
31
- source = source_from_range(node.source_range)[CHARSET_DIRECTIVE_LENGTH..-1]
32
-
33
- check_quotes(node, source)
34
- end
35
-
36
27
  private
37
28
 
38
29
  def check_quotes(node, source)
@@ -9,6 +9,7 @@ module SCSSLint
9
9
  def visit_script_string(node)
10
10
  return unless node.type == :identifier
11
11
  return if node.value =~ /^'|"/
12
+ return if url_literal?(node)
12
13
 
13
14
  node.value.scan(REAL_NUMBER_REGEX) do |number, integer, mantissa, units|
14
15
  if unnecessary_mantissa?(mantissa)
@@ -41,5 +42,9 @@ module SCSSLint
41
42
  def unnecessary_mantissa?(mantissa)
42
43
  mantissa !~ /[^0]/
43
44
  end
45
+
46
+ def url_literal?(node)
47
+ node.value.start_with?('url(')
48
+ end
44
49
  end
45
50
  end
@@ -50,7 +50,7 @@ module SCSSLint
50
50
  # Create the task so it is accessible via +Rake::Task['scss_lint']+.
51
51
  def initialize(name = :scss_lint)
52
52
  @name = name
53
- @files = ['.'] # Search for everything under current directory by default
53
+ @files = []
54
54
  @quiet = false
55
55
 
56
56
  yield self if block_given?
@@ -102,7 +102,13 @@ module SCSSLint
102
102
  # command line or in a custom task definition.
103
103
  explicit_files = Array(task_args[:files]) + Array(task_args.extras)
104
104
 
105
- explicit_files.any? ? explicit_files : files
105
+ if explicit_files.any?
106
+ explicit_files
107
+ elsif files.any?
108
+ files
109
+ else
110
+ [] # Will fall back to scss_files option if defined
111
+ end
106
112
  end
107
113
 
108
114
  # Friendly description that shows the full command that will be executed.
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the gem version.
4
4
  module SCSSLint
5
- VERSION = '0.49.0'.freeze
5
+ VERSION = '0.50.0'.freeze
6
6
  end
@@ -14,30 +14,8 @@ describe SCSSLint::FileFinder do
14
14
  context 'when no patterns are given' do
15
15
  let(:patterns) { [] }
16
16
 
17
- context 'and there are no SCSS files under the current directory' do
18
- it 'raises an error' do
19
- expect { subject }.to raise_error SCSSLint::Exceptions::NoFilesError
20
- end
21
- end
22
-
23
- context 'and there are SCSS files under the current directory' do
24
- before do
25
- FileUtils.touch('blah.scss')
26
- FileUtils.mkdir_p('more')
27
- FileUtils.touch(File.join('more', 'more.scss'))
28
- end
29
-
30
- it { should == ['blah.scss', File.join('more', 'more.scss')] }
31
- end
32
-
33
- context 'and a default set of files is specified in the config' do
34
- let(:files) { ['file1.scss', 'file2.scss'] }
35
-
36
- before do
37
- config.stub(:scss_files).and_return(files)
38
- end
39
-
40
- it { should == files }
17
+ it 'raises an error' do
18
+ expect { subject }.to raise_error SCSSLint::Exceptions::NoFilesError
41
19
  end
42
20
  end
43
21
 
@@ -99,4 +99,14 @@ describe SCSSLint::Linter::ColorKeyword do
99
99
 
100
100
  it { should_not report_lint }
101
101
  end
102
+
103
+ context 'when color keyword is used in a map function call' do
104
+ let(:scss) { <<-SCSS }
105
+ p {
106
+ color: map-get($my-colors, green);
107
+ }
108
+ SCSS
109
+
110
+ it { should_not report_lint }
111
+ end
102
112
  end
@@ -31,6 +31,16 @@ describe SCSSLint::Linter::PlaceholderInExtend do
31
31
  it { should report_lint line: 2 }
32
32
  end
33
33
 
34
+ context 'when extending with a comma sequence starting with a placeholder' do
35
+ let(:scss) { <<-SCSS }
36
+ p {
37
+ @extend %placeholder, .item;
38
+ }
39
+ SCSS
40
+
41
+ it { should report_lint line: 2 }
42
+ end
43
+
34
44
  context 'when extending with a placeholder' do
35
45
  let(:scss) { <<-SCSS }
36
46
  p {
@@ -465,6 +465,22 @@ describe SCSSLint::Linter::PrivateNamingConvention do
465
465
 
466
466
  it { should_not report_lint }
467
467
  end
468
+
469
+ context 'is defined and used within another private function' do
470
+ let(:scss) { <<-SCSS }
471
+ @function _foo() {
472
+ @return red;
473
+ }
474
+
475
+ @function _bar() {
476
+ @return _foo();
477
+ }
478
+
479
+ $use: _bar();
480
+ SCSS
481
+
482
+ it { should_not report_lint }
483
+ end
468
484
  end
469
485
 
470
486
  context 'when a public function' do
@@ -193,6 +193,16 @@ describe SCSSLint::Linter::Shorthand do
193
193
  SCSS
194
194
 
195
195
  it { should_not report_lint }
196
+
197
+ context 'and ends with !important' do
198
+ let(:scss) { <<-SCSS }
199
+ p {
200
+ margin: 4px 4px 4px !important;
201
+ }
202
+ SCSS
203
+
204
+ it { should_not report_lint }
205
+ end
196
206
  end
197
207
 
198
208
  context 'is fine but length is not allowed' do
@@ -205,5 +215,16 @@ describe SCSSLint::Linter::Shorthand do
205
215
 
206
216
  it { should report_lint }
207
217
  end
218
+
219
+ context 'when allowed_shorthands is a empty list' do
220
+ let(:allowed) { [] }
221
+ let(:scss) { <<-SCSS }
222
+ p {
223
+ margin: 0;
224
+ }
225
+ SCSS
226
+
227
+ it { should report_lint line: 2, message: /forbidden/ }
228
+ end
208
229
  end
209
230
  end
@@ -346,6 +346,30 @@ describe SCSSLint::Linter::SpaceAfterComma do
346
346
 
347
347
  it { should report_lint line: 4 }
348
348
  end
349
+
350
+ context 'column number' do
351
+ let(:scss) { <<-SCSS }
352
+ p {
353
+ property: $a,$b;
354
+ }
355
+ SCSS
356
+
357
+ it 'is the correct column' do
358
+ subject.lints.first.location.column.should == 15
359
+ end
360
+ end
361
+
362
+ context 'linter message' do
363
+ let(:scss) { <<-SCSS }
364
+ p {
365
+ property: $a,$b;
366
+ }
367
+ SCSS
368
+
369
+ it 'specifies the style' do
370
+ subject.lints.first.description.should == 'Commas in lists should be followed by one space'
371
+ end
372
+ end
349
373
  end
350
374
 
351
375
  context 'when more than one space is preferred' do
@@ -745,6 +769,19 @@ describe SCSSLint::Linter::SpaceAfterComma do
745
769
  it { should_not report_lint }
746
770
  end
747
771
  end
772
+
773
+ context 'linter message' do
774
+ let(:scss) { <<-SCSS }
775
+ p {
776
+ property: $a,$b;
777
+ }
778
+ SCSS
779
+
780
+ it 'specifies the style' do
781
+ subject.lints.first.description.should ==
782
+ 'Commas in lists should be followed by at least one space'
783
+ end
784
+ end
748
785
  end
749
786
 
750
787
  context 'when no space is preferred' do
@@ -1078,5 +1115,17 @@ describe SCSSLint::Linter::SpaceAfterComma do
1078
1115
  it { should_not report_lint }
1079
1116
  end
1080
1117
  end
1118
+
1119
+ context 'linter message' do
1120
+ let(:scss) { <<-SCSS }
1121
+ p {
1122
+ property: $a, $b;
1123
+ }
1124
+ SCSS
1125
+
1126
+ it 'specifies the style' do
1127
+ subject.lints.first.description.should == 'Commas in lists should be followed by no space'
1128
+ end
1129
+ end
1081
1130
  end
1082
1131
  end
@@ -0,0 +1,480 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::Linter::SpaceAfterComment do
4
+ context 'when no comments exist' do
5
+ let(:scss) { <<-SCSS }
6
+ p {
7
+ margin: 0;
8
+ }
9
+ SCSS
10
+
11
+ it { should_not report_lint }
12
+ end
13
+
14
+ context 'when one space is preferred' do
15
+ let(:linter_config) { { 'style' => 'one_space' } }
16
+
17
+ context 'when silent comment and no space' do
18
+ let(:scss) { <<-SCSS }
19
+ //no space
20
+ SCSS
21
+
22
+ it { should report_lint line: 1 }
23
+ end
24
+
25
+ context 'when silent comment and one space' do
26
+ let(:scss) { <<-SCSS }
27
+ // one space
28
+ SCSS
29
+
30
+ it { should_not report_lint line: 1 }
31
+ end
32
+
33
+ context 'when silent comment and multiple spaces' do
34
+ let(:scss) { <<-SCSS }
35
+ // multiple spaces
36
+ SCSS
37
+
38
+ it { should report_lint line: 1 }
39
+ end
40
+
41
+ context 'when inline silent comment and no space' do
42
+ let(:scss) { <<-SCSS }
43
+ p {
44
+ margin:0; //no space
45
+ }
46
+ SCSS
47
+
48
+ it { should report_lint line: 2 }
49
+ end
50
+
51
+ context 'when inline silent comment and one space' do
52
+ let(:scss) { <<-SCSS }
53
+ p {
54
+ margin:0; // one space
55
+ }
56
+ SCSS
57
+
58
+ it { should_not report_lint line: 2 }
59
+ end
60
+
61
+ context 'when inline silent comment and multiple spaces' do
62
+ let(:scss) { <<-SCSS }
63
+ p {
64
+ margin:0; // multiple spaces
65
+ }
66
+ SCSS
67
+
68
+ it { should report_lint line: 2 }
69
+ end
70
+
71
+ context 'when multiple silent comments' do
72
+ let(:scss) { <<-SCSS }
73
+ //no space
74
+ // space
75
+ //no space
76
+ // multiple spaces
77
+ SCSS
78
+
79
+ it { should report_lint line: 1 }
80
+ it { should_not report_lint line: 2 }
81
+ it { should report_lint line: 3 }
82
+ it { should report_lint line: 4 }
83
+ end
84
+
85
+ context 'when multiple silent comments and allow_empty_comments' do
86
+ let(:linter_config) { { 'style' => 'one_space', 'allow_empty_comments' => true } }
87
+ let(:scss) { <<-SCSS }
88
+ //
89
+ //no space
90
+ // space
91
+ //no space
92
+ // multiple spaces
93
+ SCSS
94
+
95
+ it { should_not report_lint line: 1 }
96
+ it { should report_lint line: 2 }
97
+ it { should_not report_lint line: 3 }
98
+ it { should report_lint line: 4 }
99
+ it { should report_lint line: 5 }
100
+ end
101
+
102
+ context 'when normal comment and no space' do
103
+ let(:scss) { <<-SCSS }
104
+ /*no space */
105
+ SCSS
106
+
107
+ it { should report_lint line: 1 }
108
+ end
109
+
110
+ context 'when normal comment and one space' do
111
+ let(:scss) { <<-SCSS }
112
+ /* one space */
113
+ SCSS
114
+
115
+ it { should_not report_lint line: 1 }
116
+ end
117
+
118
+ context 'when normal comment and multiple spaces' do
119
+ let(:scss) { <<-SCSS }
120
+ /* multiple spaces */
121
+ SCSS
122
+
123
+ it { should report_lint line: 1 }
124
+ end
125
+
126
+ context 'when inline normal comment and no space' do
127
+ let(:scss) { <<-SCSS }
128
+ p {
129
+ margin:0; /*no space */
130
+ }
131
+ SCSS
132
+
133
+ it { should report_lint line: 2 }
134
+ end
135
+
136
+ context 'when inline normal comment and one space' do
137
+ let(:scss) { <<-SCSS }
138
+ p {
139
+ margin:0; /* one space */
140
+ }
141
+ SCSS
142
+
143
+ it { should_not report_lint line: 2 }
144
+ end
145
+
146
+ context 'when inline normal comment and multiple space' do
147
+ let(:scss) { <<-SCSS }
148
+ p {
149
+ margin:0; /* multiple spaces */
150
+ }
151
+ SCSS
152
+
153
+ it { should report_lint line: 2 }
154
+ end
155
+
156
+ context 'when loud comment and no space' do
157
+ let(:scss) { <<-SCSS }
158
+ /*!no space */
159
+ SCSS
160
+
161
+ it { should report_lint line: 1 }
162
+ end
163
+
164
+ context 'when loud comment and one space' do
165
+ let(:scss) { <<-SCSS }
166
+ /*! one space */
167
+ SCSS
168
+
169
+ it { should_not report_lint line: 1 }
170
+ end
171
+
172
+ context 'when loud comment and multiple spaces' do
173
+ let(:scss) { <<-SCSS }
174
+ /*! multiple spaces */
175
+ SCSS
176
+
177
+ it { should report_lint line: 1 }
178
+ end
179
+ end
180
+
181
+ context 'when no spaces are allowed' do
182
+ let(:linter_config) { { 'style' => 'no_space' } }
183
+
184
+ context 'when silent comment and no space' do
185
+ let(:scss) { <<-SCSS }
186
+ //no space
187
+ SCSS
188
+
189
+ it { should_not report_lint line: 1 }
190
+ end
191
+
192
+ context 'when silent comment and one space' do
193
+ let(:scss) { <<-SCSS }
194
+ // one space
195
+ SCSS
196
+
197
+ it { should report_lint line: 1 }
198
+ end
199
+
200
+ context 'when silent comment and multiple spaces' do
201
+ let(:scss) { <<-SCSS }
202
+ // multiple spaces
203
+ SCSS
204
+
205
+ it { should report_lint line: 1 }
206
+ end
207
+
208
+ context 'when inline silent comment and no space' do
209
+ let(:scss) { <<-SCSS }
210
+ p {
211
+ margin:0; //no space
212
+ }
213
+ SCSS
214
+
215
+ it { should_not report_lint line: 2 }
216
+ end
217
+
218
+ context 'when inline silent comment and one space' do
219
+ let(:scss) { <<-SCSS }
220
+ p {
221
+ margin:0; // one space
222
+ }
223
+ SCSS
224
+
225
+ it { should report_lint line: 2 }
226
+ end
227
+
228
+ context 'when inline silent comment and multiple spaces' do
229
+ let(:scss) { <<-SCSS }
230
+ p {
231
+ margin:0; // multiple spaces
232
+ }
233
+ SCSS
234
+
235
+ it { should report_lint line: 2 }
236
+ end
237
+
238
+ context 'when multiple silent comments' do
239
+ let(:scss) { <<-SCSS }
240
+ //no space
241
+ // space
242
+ //no space
243
+ // multiple spaces
244
+ SCSS
245
+
246
+ it { should_not report_lint line: 1 }
247
+ it { should report_lint line: 2 }
248
+ it { should_not report_lint line: 3 }
249
+ it { should report_lint line: 4 }
250
+ end
251
+
252
+ context 'when normal comment and no space' do
253
+ let(:scss) { <<-SCSS }
254
+ /*no space */
255
+ SCSS
256
+
257
+ it { should_not report_lint line: 1 }
258
+ end
259
+
260
+ context 'when normal comment and one space' do
261
+ let(:scss) { <<-SCSS }
262
+ /* one space */
263
+ SCSS
264
+
265
+ it { should report_lint line: 1 }
266
+ end
267
+
268
+ context 'when normal comment and multiple spaces' do
269
+ let(:scss) { <<-SCSS }
270
+ /* multiple spaces */
271
+ SCSS
272
+
273
+ it { should report_lint line: 1 }
274
+ end
275
+
276
+ context 'when inline normal comment and no space' do
277
+ let(:scss) { <<-SCSS }
278
+ p {
279
+ margin:0; /*no space */
280
+ }
281
+ SCSS
282
+
283
+ it { should_not report_lint line: 2 }
284
+ end
285
+
286
+ context 'when inline normal comment and one space' do
287
+ let(:scss) { <<-SCSS }
288
+ p {
289
+ margin:0; /* one space */
290
+ }
291
+ SCSS
292
+
293
+ it { should report_lint line: 2 }
294
+ end
295
+
296
+ context 'when inline normal comment and multiple space' do
297
+ let(:scss) { <<-SCSS }
298
+ p {
299
+ margin:0; /* multiple spaces */
300
+ }
301
+ SCSS
302
+
303
+ it { should report_lint line: 2 }
304
+ end
305
+
306
+ context 'when loud comment and no space' do
307
+ let(:scss) { <<-SCSS }
308
+ /*!no space */
309
+ SCSS
310
+
311
+ it { should_not report_lint line: 1 }
312
+ end
313
+
314
+ context 'when loud comment and one space' do
315
+ let(:scss) { <<-SCSS }
316
+ /*! one space */
317
+ SCSS
318
+
319
+ it { should report_lint line: 1 }
320
+ end
321
+
322
+ context 'when loud comment and multiple spaces' do
323
+ let(:scss) { <<-SCSS }
324
+ /*! multiple spaces */
325
+ SCSS
326
+
327
+ it { should report_lint line: 1 }
328
+ end
329
+ end
330
+
331
+ context 'when at least one space is preferred' do
332
+ let(:linter_config) { { 'style' => 'at_least_one_space' } }
333
+
334
+ context 'when silent comment and no space' do
335
+ let(:scss) { <<-SCSS }
336
+ //no space
337
+ SCSS
338
+
339
+ it { should report_lint line: 1 }
340
+ end
341
+
342
+ context 'when silent comment and one space' do
343
+ let(:scss) { <<-SCSS }
344
+ // one space
345
+ SCSS
346
+
347
+ it { should_not report_lint line: 1 }
348
+ end
349
+
350
+ context 'when silent comment and multiple spaces' do
351
+ let(:scss) { <<-SCSS }
352
+ // multiple spaces
353
+ SCSS
354
+
355
+ it { should_not report_lint line: 1 }
356
+ end
357
+
358
+ context 'when inline silent comment and no space' do
359
+ let(:scss) { <<-SCSS }
360
+ p {
361
+ margin:0; //no space
362
+ }
363
+ SCSS
364
+
365
+ it { should report_lint line: 2 }
366
+ end
367
+
368
+ context 'when inline silent comment and one space' do
369
+ let(:scss) { <<-SCSS }
370
+ p {
371
+ margin:0; // one space
372
+ }
373
+ SCSS
374
+
375
+ it { should_not report_lint line: 2 }
376
+ end
377
+
378
+ context 'when inline silent comment and multiple spaces' do
379
+ let(:scss) { <<-SCSS }
380
+ p {
381
+ margin:0; // multiple spaces
382
+ }
383
+ SCSS
384
+
385
+ it { should_not report_lint line: 2 }
386
+ end
387
+
388
+ context 'when multiple silent comments' do
389
+ let(:scss) { <<-SCSS }
390
+ //no space
391
+ // space
392
+ //no space
393
+ // multiple spaces
394
+ SCSS
395
+
396
+ it { should report_lint line: 1 }
397
+ it { should_not report_lint line: 2 }
398
+ it { should report_lint line: 3 }
399
+ it { should_not report_lint line: 4 }
400
+ end
401
+
402
+ context 'when normal comment and no space' do
403
+ let(:scss) { <<-SCSS }
404
+ /*no space */
405
+ SCSS
406
+
407
+ it { should report_lint line: 1 }
408
+ end
409
+
410
+ context 'when normal comment and one space' do
411
+ let(:scss) { <<-SCSS }
412
+ /* one space */
413
+ SCSS
414
+
415
+ it { should_not report_lint line: 1 }
416
+ end
417
+
418
+ context 'when normal comment and multiple spaces' do
419
+ let(:scss) { <<-SCSS }
420
+ /* multiple spaces */
421
+ SCSS
422
+
423
+ it { should_not report_lint line: 1 }
424
+ end
425
+
426
+ context 'when inline normal comment and no space' do
427
+ let(:scss) { <<-SCSS }
428
+ p {
429
+ margin:0; /*no space */
430
+ }
431
+ SCSS
432
+
433
+ it { should report_lint line: 2 }
434
+ end
435
+
436
+ context 'when inline normal comment and one space' do
437
+ let(:scss) { <<-SCSS }
438
+ p {
439
+ margin:0; /* one space */
440
+ }
441
+ SCSS
442
+
443
+ it { should_not report_lint line: 2 }
444
+ end
445
+
446
+ context 'when inline normal comment and multiple space' do
447
+ let(:scss) { <<-SCSS }
448
+ p {
449
+ margin:0; /* multiple spaces */
450
+ }
451
+ SCSS
452
+
453
+ it { should_not report_lint line: 2 }
454
+ end
455
+
456
+ context 'when loud comment and no space' do
457
+ let(:scss) { <<-SCSS }
458
+ /*!no space */
459
+ SCSS
460
+
461
+ it { should report_lint line: 1 }
462
+ end
463
+
464
+ context 'when loud comment and one space' do
465
+ let(:scss) { <<-SCSS }
466
+ /*! one space */
467
+ SCSS
468
+
469
+ it { should_not report_lint line: 1 }
470
+ end
471
+
472
+ context 'when loud comment and multiple spaces' do
473
+ let(:scss) { <<-SCSS }
474
+ /*! multiple spaces */
475
+ SCSS
476
+
477
+ it { should_not report_lint line: 1 }
478
+ end
479
+ end
480
+ end
@@ -63,12 +63,6 @@ describe SCSSLint::Linter::StringQuotes do
63
63
  end
64
64
  end
65
65
 
66
- context 'when @charset uses single quotes' do
67
- let(:scss) { "@charset 'UTF-8';" }
68
-
69
- it { should_not report_lint }
70
- end
71
-
72
66
  context 'when string is written with double quotes' do
73
67
  let(:scss) { <<-SCSS }
74
68
  p {
@@ -131,12 +125,6 @@ describe SCSSLint::Linter::StringQuotes do
131
125
  end
132
126
  end
133
127
 
134
- context 'when @charset uses double quotes' do
135
- let(:scss) { '@charset "UTF-8";' }
136
-
137
- it { should report_lint }
138
- end
139
-
140
128
  context 'when property has a literal identifier' do
141
129
  let(:scss) { <<-SCSS }
142
130
  p {
@@ -84,4 +84,14 @@ describe SCSSLint::Linter::UnnecessaryMantissa do
84
84
 
85
85
  it { should_not report_lint }
86
86
  end
87
+
88
+ context 'when a decimal value appears in a URL' do
89
+ let(:scss) { <<-SCSS }
90
+ p {
91
+ background: url(https://www.example.com/v1.0/image.jpg);
92
+ }
93
+ SCSS
94
+
95
+ it { should_not report_lint }
96
+ end
87
97
  end
@@ -32,7 +32,7 @@ describe SCSSLint::Reporter::StatsReporter do
32
32
  end
33
33
 
34
34
  it 'prints the name of each linter with lints' do
35
- subject.report_lints.scan(linter_1.name).count.should eq 1
35
+ subject.report_lints.should include linter_1.name
36
36
  end
37
37
 
38
38
  it 'prints the number of lints per linter' do
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.49.0
4
+ version: 0.50.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brigade Engineering
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-07-05 00:00:00.000000000 Z
12
+ date: 2016-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -118,6 +118,7 @@ files:
118
118
  - lib/scss_lint/linter/single_line_per_property.rb
119
119
  - lib/scss_lint/linter/single_line_per_selector.rb
120
120
  - lib/scss_lint/linter/space_after_comma.rb
121
+ - lib/scss_lint/linter/space_after_comment.rb
121
122
  - lib/scss_lint/linter/space_after_property_colon.rb
122
123
  - lib/scss_lint/linter/space_after_property_name.rb
123
124
  - lib/scss_lint/linter/space_after_variable_colon.rb
@@ -207,6 +208,7 @@ files:
207
208
  - spec/scss_lint/linter/single_line_per_property_spec.rb
208
209
  - spec/scss_lint/linter/single_line_per_selector_spec.rb
209
210
  - spec/scss_lint/linter/space_after_comma_spec.rb
211
+ - spec/scss_lint/linter/space_after_comment_spec.rb
210
212
  - spec/scss_lint/linter/space_after_property_colon_spec.rb
211
213
  - spec/scss_lint/linter/space_after_property_name_spec.rb
212
214
  - spec/scss_lint/linter/space_after_variable_colon_spec.rb
@@ -262,7 +264,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
264
  requirements:
263
265
  - - ">="
264
266
  - !ruby/object:Gem::Version
265
- version: 1.9.3
267
+ version: '2'
266
268
  required_rubygems_version: !ruby/object:Gem::Requirement
267
269
  requirements:
268
270
  - - ">="
@@ -323,6 +325,7 @@ test_files:
323
325
  - spec/scss_lint/linter/single_line_per_property_spec.rb
324
326
  - spec/scss_lint/linter/single_line_per_selector_spec.rb
325
327
  - spec/scss_lint/linter/space_after_comma_spec.rb
328
+ - spec/scss_lint/linter/space_after_comment_spec.rb
326
329
  - spec/scss_lint/linter/space_after_property_colon_spec.rb
327
330
  - spec/scss_lint/linter/space_after_property_name_spec.rb
328
331
  - spec/scss_lint/linter/space_after_variable_colon_spec.rb