scss-lint 0.37.0 → 0.38.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/default.yml +2 -0
- data/lib/scss_lint/config.rb +0 -2
- data/lib/scss_lint/linter.rb +5 -1
- data/lib/scss_lint/linter/color_variable.rb +11 -0
- data/lib/scss_lint/linter/comment.rb +12 -1
- data/lib/scss_lint/linter/declaration_order.rb +1 -0
- data/lib/scss_lint/linter/property_sort_order.rb +16 -7
- data/lib/scss_lint/linter/shorthand.rb +50 -5
- data/lib/scss_lint/linter/space_after_property_colon.rb +24 -16
- data/lib/scss_lint/linter/variable_for_property.rb +11 -1
- data/lib/scss_lint/runner.rb +1 -5
- data/lib/scss_lint/version.rb +1 -1
- data/spec/scss_lint/config_spec.rb +13 -0
- data/spec/scss_lint/linter/color_variable_spec.rb +10 -0
- data/spec/scss_lint/linter/comment_spec.rb +24 -0
- data/spec/scss_lint/linter/declaration_order_spec.rb +15 -0
- data/spec/scss_lint/linter/property_sort_order_spec.rb +56 -0
- data/spec/scss_lint/linter/shorthand_spec.rb +26 -0
- data/spec/scss_lint/linter/space_after_property_colon_spec.rb +109 -0
- data/spec/scss_lint/linter/variable_for_property_spec.rb +30 -0
- data/spec/scss_lint/runner_spec.rb +2 -2
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c296b7c4e859d94fbe7405503da8c09f1584f880
|
4
|
+
data.tar.gz: e668053e660664110f8e8c08674d06c1c4d88edc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89a42c235c81ae88a655f298d87aee1ac5ef9b1b0c4ebac6b7bbb413b6be84a1e9324ecf2c055d6b7b49a76d8739cd08b0bef1a098d792bb16f9f4e14d149c73
|
7
|
+
data.tar.gz: 692dd0036d9a7cad4642d4c5a6db7277c6b5464750e6f7928f18b1a3924c8334312b4881cb7e0bd5179c7d0cc891c98151982061cc7b4d103c3187ee5b1537db
|
data/config/default.yml
CHANGED
@@ -115,6 +115,7 @@ linters:
|
|
115
115
|
PropertySortOrder:
|
116
116
|
enabled: true
|
117
117
|
ignore_unspecified: false
|
118
|
+
min_properties: 2
|
118
119
|
separate_groups: false
|
119
120
|
|
120
121
|
PropertySpelling:
|
@@ -137,6 +138,7 @@ linters:
|
|
137
138
|
|
138
139
|
Shorthand:
|
139
140
|
enabled: true
|
141
|
+
allowed_shorthands: [1, 2, 3]
|
140
142
|
|
141
143
|
SingleLinePerProperty:
|
142
144
|
enabled: true
|
data/lib/scss_lint/config.rb
CHANGED
data/lib/scss_lint/linter.rb
CHANGED
@@ -6,15 +6,19 @@ module SCSSLint
|
|
6
6
|
|
7
7
|
attr_reader :config, :engine, :lints
|
8
8
|
|
9
|
+
# Create a linter.
|
9
10
|
def initialize
|
10
11
|
@lints = []
|
11
12
|
end
|
12
13
|
|
13
|
-
# Run this linter against a parsed document with
|
14
|
+
# Run this linter against a parsed document with the given configuration,
|
15
|
+
# returning the lints that were found.
|
14
16
|
#
|
15
17
|
# @param engine [Engine]
|
16
18
|
# @param config [Config]
|
19
|
+
# @return [Array<Lint>]
|
17
20
|
def run(engine, config)
|
21
|
+
@lints = []
|
18
22
|
@config = config
|
19
23
|
@engine = engine
|
20
24
|
@comment_processor = ControlCommentProcessor.new(self)
|
@@ -15,6 +15,8 @@ module SCSSLint
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def visit_script_string(node)
|
18
|
+
return if literal_string?(node)
|
19
|
+
|
18
20
|
remove_quoted_strings(node.value)
|
19
21
|
.scan(/(^|\s)(#[a-f0-9]+|[a-z]+)(?=\s|$)/i)
|
20
22
|
.select { |_, word| color?(word) }
|
@@ -29,6 +31,15 @@ module SCSSLint
|
|
29
31
|
'variable everywhere else.'
|
30
32
|
end
|
31
33
|
|
34
|
+
def literal_string?(script_string)
|
35
|
+
return unless script_string.respond_to?(:source_range) &&
|
36
|
+
source_range = script_string.source_range
|
37
|
+
|
38
|
+
# If original source starts with a quote character, it's a string, not a
|
39
|
+
# color
|
40
|
+
%w[' "].include?(source_from_range(source_range)[0])
|
41
|
+
end
|
42
|
+
|
32
43
|
def in_variable_declaration?(node)
|
33
44
|
parent = node.node_parent
|
34
45
|
parent.is_a?(Sass::Script::Tree::Literal) &&
|
@@ -4,7 +4,18 @@ module SCSSLint
|
|
4
4
|
include LinterRegistry
|
5
5
|
|
6
6
|
def visit_comment(node)
|
7
|
-
add_lint(node, 'Use `//` comments everywhere') unless node.invisible?
|
7
|
+
add_lint(node, 'Use `//` comments everywhere') unless node.invisible? || allowed?(node)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# @param node [CommentNode]
|
13
|
+
# @return [Boolean]
|
14
|
+
def allowed?(node)
|
15
|
+
return false unless config['allowed']
|
16
|
+
re = Regexp.new(config['allowed'])
|
17
|
+
|
18
|
+
node.value.join.match(re)
|
8
19
|
end
|
9
20
|
end
|
10
21
|
end
|
@@ -18,14 +18,14 @@ module SCSSLint
|
|
18
18
|
child.is_a?(Sass::Tree::PropNode) && !ignore_property?(child)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
if sortable_props.count >= config.fetch('min_properties', 2)
|
22
|
+
sortable_prop_info = sortable_props
|
23
|
+
.map do |child|
|
24
|
+
name = child.name.join
|
25
|
+
/^(?<vendor>-\w+(-osx)?-)?(?<property>.+)/ =~ name
|
26
|
+
{ name: name, vendor: vendor, property: "#{@nested_under}#{property}", node: child }
|
27
|
+
end
|
27
28
|
|
28
|
-
if sortable_props.any?
|
29
29
|
check_sort_order(sortable_prop_info)
|
30
30
|
check_group_separation(sortable_prop_info) if @group
|
31
31
|
end
|
@@ -36,6 +36,15 @@ module SCSSLint
|
|
36
36
|
alias_method :visit_media, :check_order
|
37
37
|
alias_method :visit_mixin, :check_order
|
38
38
|
alias_method :visit_rule, :check_order
|
39
|
+
alias_method :visit_prop, :check_order
|
40
|
+
|
41
|
+
def visit_prop(node, &block)
|
42
|
+
# Handle nested properties by appending the parent property they are
|
43
|
+
# nested under to the name
|
44
|
+
@nested_under = "#{node.name.join}-"
|
45
|
+
check_order(node, &block)
|
46
|
+
@nested_under = nil
|
47
|
+
end
|
39
48
|
|
40
49
|
def visit_if(node, &block)
|
41
50
|
check_order(node, &block)
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
1
2
|
module SCSSLint
|
2
3
|
# Checks for the use of the shortest form for properties that can be written
|
3
4
|
# in shorthand.
|
4
5
|
class Linter::Shorthand < Linter
|
5
6
|
include LinterRegistry
|
6
7
|
|
8
|
+
# @param node [Sass::Tree::Node]
|
7
9
|
def visit_prop(node)
|
8
10
|
property_name = node.name.join
|
9
11
|
return unless SHORTHANDABLE_PROPERTIES.include?(property_name)
|
@@ -27,10 +29,14 @@ module SCSSLint
|
|
27
29
|
padding
|
28
30
|
]
|
29
31
|
|
32
|
+
# @param prop [String]
|
33
|
+
# @param list [Sass::Script::Tree::ListLiteral]
|
30
34
|
def check_script_list(prop, list)
|
31
35
|
check_shorthand(prop, list, list.children.map(&:to_sass))
|
32
36
|
end
|
33
37
|
|
38
|
+
# @param prop [String]
|
39
|
+
# @param literal [Sass::Script::Tree::Literal]
|
34
40
|
def check_script_literal(prop, literal)
|
35
41
|
value = literal.value
|
36
42
|
|
@@ -49,6 +55,8 @@ module SCSSLint
|
|
49
55
|
\z
|
50
56
|
/x
|
51
57
|
|
58
|
+
# @param prop [String]
|
59
|
+
# @param script_string [Sass::Script::Value::String]
|
52
60
|
def check_script_string(prop, script_string)
|
53
61
|
return unless script_string.type == :identifier
|
54
62
|
return unless values = script_string.value.strip[LIST_LITERAL_REGEX, 1]
|
@@ -56,6 +64,9 @@ module SCSSLint
|
|
56
64
|
check_shorthand(prop, script_string, values.split)
|
57
65
|
end
|
58
66
|
|
67
|
+
# @param prop [String]
|
68
|
+
# @param node [Sass::Script::Value::String]
|
69
|
+
# @param values [Array<String>]
|
59
70
|
def check_shorthand(prop, node, values)
|
60
71
|
return unless (2..4).member?(values.count)
|
61
72
|
|
@@ -67,28 +78,62 @@ module SCSSLint
|
|
67
78
|
"instead of `#{values.join(' ')}`")
|
68
79
|
end
|
69
80
|
|
81
|
+
# @param top [String]
|
82
|
+
# @param right [String]
|
83
|
+
# @param bottom [String]
|
84
|
+
# @param left [String]
|
85
|
+
# @return [Array]
|
70
86
|
def condensed_shorthand(top, right, bottom = nil, left = nil)
|
71
|
-
if
|
87
|
+
if condense_to_one_value?(top, right, bottom, left)
|
72
88
|
[top]
|
73
|
-
elsif
|
89
|
+
elsif condense_to_two_values?(top, right, bottom, left)
|
74
90
|
[top, right]
|
75
|
-
elsif right
|
91
|
+
elsif condense_to_three_values?(top, right, bottom, left)
|
76
92
|
[top, right, bottom]
|
77
93
|
else
|
78
94
|
[top, right, bottom, left].compact
|
79
95
|
end
|
80
96
|
end
|
81
97
|
|
82
|
-
|
98
|
+
# @param top [String]
|
99
|
+
# @param right [String]
|
100
|
+
# @param bottom [String]
|
101
|
+
# @param left [String]
|
102
|
+
# @return [Boolean]
|
103
|
+
def condense_to_one_value?(top, right, bottom, left)
|
104
|
+
return unless allowed?(1)
|
83
105
|
return unless top == right
|
84
106
|
|
85
107
|
top == bottom && (bottom == left || left.nil?) ||
|
86
108
|
bottom.nil? && left.nil?
|
87
109
|
end
|
88
110
|
|
89
|
-
|
111
|
+
# @param top [String]
|
112
|
+
# @param right [String]
|
113
|
+
# @param bottom [String]
|
114
|
+
# @param left [String]
|
115
|
+
# @return [Boolean]
|
116
|
+
def condense_to_two_values?(top, right, bottom, left)
|
117
|
+
return unless allowed?(2)
|
118
|
+
|
90
119
|
top == bottom && right == left ||
|
91
120
|
top == bottom && left.nil? && top != right
|
92
121
|
end
|
122
|
+
|
123
|
+
# @param right [String]
|
124
|
+
# @param left [String]
|
125
|
+
# @return [Boolean]
|
126
|
+
def condense_to_three_values?(_, right, __, left)
|
127
|
+
return unless allowed?(3)
|
128
|
+
|
129
|
+
right == left
|
130
|
+
end
|
131
|
+
|
132
|
+
# @param size [Number]
|
133
|
+
# @return [Boolean]
|
134
|
+
def allowed?(size)
|
135
|
+
return false unless config['allowed_shorthands']
|
136
|
+
config['allowed_shorthands'].map(&:to_i).include?(size)
|
137
|
+
end
|
93
138
|
end
|
94
139
|
end
|
@@ -13,15 +13,17 @@ module SCSSLint
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def visit_prop(node)
|
16
|
-
|
16
|
+
whitespace = whitespace_after_colon(node)
|
17
17
|
|
18
18
|
case config['style']
|
19
19
|
when 'no_space'
|
20
|
-
check_for_no_spaces(node,
|
20
|
+
check_for_no_spaces(node, whitespace)
|
21
21
|
when 'one_space'
|
22
|
-
check_for_one_space(node,
|
22
|
+
check_for_one_space(node, whitespace)
|
23
23
|
when 'at_least_one_space'
|
24
|
-
check_for_at_least_one_space(node,
|
24
|
+
check_for_at_least_one_space(node, whitespace)
|
25
|
+
when 'one_space_or_newline'
|
26
|
+
check_for_one_space_or_newline(node, whitespace)
|
25
27
|
end
|
26
28
|
|
27
29
|
yield # Continue linting children
|
@@ -29,21 +31,27 @@ module SCSSLint
|
|
29
31
|
|
30
32
|
private
|
31
33
|
|
32
|
-
def check_for_no_spaces(node,
|
33
|
-
return if
|
34
|
+
def check_for_no_spaces(node, whitespace)
|
35
|
+
return if whitespace == []
|
34
36
|
add_lint(node, 'Colon after property should not be followed by any spaces')
|
35
37
|
end
|
36
38
|
|
37
|
-
def check_for_one_space(node,
|
38
|
-
return if
|
39
|
+
def check_for_one_space(node, whitespace)
|
40
|
+
return if whitespace == [' ']
|
39
41
|
add_lint(node, 'Colon after property should be followed by one space')
|
40
42
|
end
|
41
43
|
|
42
|
-
def check_for_at_least_one_space(node,
|
43
|
-
return if
|
44
|
+
def check_for_at_least_one_space(node, whitespace)
|
45
|
+
return if whitespace.uniq == [' ']
|
44
46
|
add_lint(node, 'Colon after property should be followed by at least one space')
|
45
47
|
end
|
46
48
|
|
49
|
+
def check_for_one_space_or_newline(node, whitespace)
|
50
|
+
return if whitespace == [' '] || whitespace == ["\n"]
|
51
|
+
return if whitespace[0] == "\n" && whitespace[1..-1].uniq == [' ']
|
52
|
+
add_lint(node, 'Colon after property should be followed by one space or a newline')
|
53
|
+
end
|
54
|
+
|
47
55
|
def check_properties_alignment(rule_node)
|
48
56
|
properties = rule_node.children.select { |node| node.is_a?(Sass::Tree::PropNode) }
|
49
57
|
|
@@ -60,11 +68,11 @@ module SCSSLint
|
|
60
68
|
src_range = prop.name_source_range
|
61
69
|
src_range.start_pos.offset +
|
62
70
|
(src_range.end_pos.offset - src_range.start_pos.offset) +
|
63
|
-
|
71
|
+
whitespace_after_colon(prop).take_while { |w| w == ' ' }.size
|
64
72
|
end
|
65
73
|
|
66
|
-
def
|
67
|
-
|
74
|
+
def whitespace_after_colon(node)
|
75
|
+
whitespace = []
|
68
76
|
offset = 1
|
69
77
|
|
70
78
|
# Find the colon after the property name
|
@@ -73,12 +81,12 @@ module SCSSLint
|
|
73
81
|
end
|
74
82
|
|
75
83
|
# Count spaces after the colon
|
76
|
-
while character_at(node.name_source_range.start_pos, offset)
|
77
|
-
|
84
|
+
while [' ', "\t", "\n"].include? character_at(node.name_source_range.start_pos, offset)
|
85
|
+
whitespace << character_at(node.name_source_range.start_pos, offset)
|
78
86
|
offset += 1
|
79
87
|
end
|
80
88
|
|
81
|
-
|
89
|
+
whitespace
|
82
90
|
end
|
83
91
|
end
|
84
92
|
end
|
@@ -3,6 +3,8 @@ module SCSSLint
|
|
3
3
|
class Linter::VariableForProperty < Linter
|
4
4
|
include LinterRegistry
|
5
5
|
|
6
|
+
IGNORED_VALUES = %w[currentColor inherit transparent]
|
7
|
+
|
6
8
|
def visit_root(_node)
|
7
9
|
@properties = Set.new(config['properties'])
|
8
10
|
yield if @properties.any?
|
@@ -10,11 +12,19 @@ module SCSSLint
|
|
10
12
|
|
11
13
|
def visit_prop(node)
|
12
14
|
property_name = node.name.join
|
13
|
-
return unless @properties.include?
|
15
|
+
return unless @properties.include?(property_name)
|
16
|
+
return if ignored_value?(node.value)
|
14
17
|
return if node.children.first.is_a?(Sass::Script::Tree::Variable)
|
15
18
|
|
16
19
|
add_lint(node, "Property #{property_name} should use " \
|
17
20
|
'a variable rather than a literal value')
|
18
21
|
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def ignored_value?(value)
|
26
|
+
value.respond_to?(:value) &&
|
27
|
+
IGNORED_VALUES.include?(value.value.to_s)
|
28
|
+
end
|
19
29
|
end
|
20
30
|
end
|
data/lib/scss_lint/runner.rb
CHANGED
@@ -16,10 +16,6 @@ module SCSSLint
|
|
16
16
|
files.each do |file|
|
17
17
|
find_lints(file)
|
18
18
|
end
|
19
|
-
|
20
|
-
@linters.each do |linter|
|
21
|
-
@lints += linter.lints
|
22
|
-
end
|
23
19
|
end
|
24
20
|
|
25
21
|
private
|
@@ -49,7 +45,7 @@ module SCSSLint
|
|
49
45
|
def run_linter(linter, engine, file)
|
50
46
|
return unless @config.linter_enabled?(linter)
|
51
47
|
return if @config.excluded_file_for_linter?(file, linter)
|
52
|
-
linter.run(engine, @config.linter_options(linter))
|
48
|
+
@lints += linter.run(engine, @config.linter_options(linter))
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
data/lib/scss_lint/version.rb
CHANGED
@@ -46,6 +46,7 @@ describe SCSSLint::Config do
|
|
46
46
|
linters:
|
47
47
|
FakeConfigLinter:
|
48
48
|
enabled: true
|
49
|
+
list: [1, 2, 3]
|
49
50
|
OtherFakeConfigLinter:
|
50
51
|
enabled: false
|
51
52
|
FILE
|
@@ -104,6 +105,18 @@ describe SCSSLint::Config do
|
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
108
|
+
context 'with a config file setting a list value different from the default' do
|
109
|
+
let(:config_file) { <<-FILE }
|
110
|
+
linters:
|
111
|
+
FakeConfigLinter:
|
112
|
+
list: [4, 5, 6]
|
113
|
+
FILE
|
114
|
+
|
115
|
+
it 'overrides the default value with the new value' do
|
116
|
+
subject.options['linters']['FakeConfigLinter']['list'].should == [4, 5, 6]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
107
120
|
context 'when a wildcard is used for a namespaced linter' do
|
108
121
|
let(:default_file) { <<-FILE }
|
109
122
|
linters:
|
@@ -142,4 +142,14 @@ describe SCSSLint::Linter::ColorVariable do
|
|
142
142
|
|
143
143
|
it { should_not report_lint }
|
144
144
|
end
|
145
|
+
|
146
|
+
context 'when a string with a color name is used in a function call' do
|
147
|
+
let(:scss) { <<-SCSS }
|
148
|
+
p {
|
149
|
+
color: my-func('blue');
|
150
|
+
}
|
151
|
+
SCSS
|
152
|
+
|
153
|
+
it { should_not report_lint }
|
154
|
+
end
|
145
155
|
end
|
@@ -52,4 +52,28 @@ describe SCSSLint::Linter::Comment do
|
|
52
52
|
|
53
53
|
it { should report_lint line: 2 }
|
54
54
|
end
|
55
|
+
|
56
|
+
context 'when multi-line comment is allowed by config' do
|
57
|
+
let(:linter_config) { { 'allowed' => '^[/\\* ]*Copyright' } }
|
58
|
+
let(:scss) { <<-SCSS }
|
59
|
+
/* Copyright someone. */
|
60
|
+
a {
|
61
|
+
color: #DDD;
|
62
|
+
}
|
63
|
+
SCSS
|
64
|
+
|
65
|
+
it { should_not report_lint }
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when multi-line comment is not allowed by config' do
|
69
|
+
let(:linter_config) { { 'allowed' => '^[/\\* ]*Copyright' } }
|
70
|
+
let(:scss) { <<-SCSS }
|
71
|
+
/* Other multiline. */
|
72
|
+
p {
|
73
|
+
color: #DDD;
|
74
|
+
}
|
75
|
+
SCSS
|
76
|
+
|
77
|
+
it { should report_lint }
|
78
|
+
end
|
55
79
|
end
|
@@ -557,4 +557,19 @@ describe SCSSLint::Linter::DeclarationOrder do
|
|
557
557
|
|
558
558
|
it { should report_lint line: 5 }
|
559
559
|
end
|
560
|
+
|
561
|
+
context 'when order within a media query is incorrect' do
|
562
|
+
let(:scss) { <<-SCSS }
|
563
|
+
@media screen and (max-width: 600px) {
|
564
|
+
@include mix1();
|
565
|
+
|
566
|
+
width: 100%;
|
567
|
+
height: 100%;
|
568
|
+
|
569
|
+
@include mix2();
|
570
|
+
}
|
571
|
+
SCSS
|
572
|
+
|
573
|
+
it { should report_lint }
|
574
|
+
end
|
560
575
|
end
|
@@ -23,6 +23,20 @@ describe SCSSLint::Linter::PropertySortOrder do
|
|
23
23
|
it { should_not report_lint }
|
24
24
|
end
|
25
25
|
|
26
|
+
context 'when rule contains nested properties in unsorted order' do
|
27
|
+
let(:scss) { <<-SCSS }
|
28
|
+
p {
|
29
|
+
font: {
|
30
|
+
family: Arial;
|
31
|
+
weight: bold;
|
32
|
+
size: 1.2em;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
SCSS
|
36
|
+
|
37
|
+
it { should report_lint line: 4 }
|
38
|
+
end
|
39
|
+
|
26
40
|
context 'when rule contains mixins followed by properties in sorted order' do
|
27
41
|
let(:scss) { <<-SCSS }
|
28
42
|
p {
|
@@ -423,4 +437,46 @@ describe SCSSLint::Linter::PropertySortOrder do
|
|
423
437
|
end
|
424
438
|
end
|
425
439
|
end
|
440
|
+
|
441
|
+
context 'when a minimum number of properties is required' do
|
442
|
+
let(:linter_config) { { 'min_properties' => 3 } }
|
443
|
+
|
444
|
+
context 'when fewer than the minimum number of properties are out of order' do
|
445
|
+
let(:scss) { <<-SCSS }
|
446
|
+
p {
|
447
|
+
margin: 0;
|
448
|
+
display: none;
|
449
|
+
}
|
450
|
+
SCSS
|
451
|
+
|
452
|
+
it { should_not report_lint }
|
453
|
+
end
|
454
|
+
|
455
|
+
context 'when at least the minimum number of properties are out of order' do
|
456
|
+
let(:scss) { <<-SCSS }
|
457
|
+
p {
|
458
|
+
margin: 0;
|
459
|
+
position: absolute;
|
460
|
+
display: none;
|
461
|
+
}
|
462
|
+
SCSS
|
463
|
+
|
464
|
+
it { should report_lint line: 2 }
|
465
|
+
end
|
466
|
+
|
467
|
+
context 'when the minimum number of properties are out of order in a nested property' do
|
468
|
+
let(:scss) { <<-SCSS }
|
469
|
+
p {
|
470
|
+
margin: 0;
|
471
|
+
font: {
|
472
|
+
size: 16px;
|
473
|
+
weight: bold;
|
474
|
+
family: Arial;
|
475
|
+
}
|
476
|
+
}
|
477
|
+
SCSS
|
478
|
+
|
479
|
+
it { should report_lint line: 4 }
|
480
|
+
end
|
481
|
+
end
|
426
482
|
end
|
@@ -169,4 +169,30 @@ describe SCSSLint::Linter::Shorthand do
|
|
169
169
|
it { should report_lint line: 3 }
|
170
170
|
end
|
171
171
|
end
|
172
|
+
|
173
|
+
context 'when configured with allowed_shorthands, and a rule' do
|
174
|
+
let(:linter_config) { { 'allowed_shorthands' => allowed } }
|
175
|
+
|
176
|
+
context 'can be shortened to 1, 2, or 3, but 1 is not allowed' do
|
177
|
+
let(:allowed) { [2, 3] }
|
178
|
+
let(:scss) { <<-SCSS }
|
179
|
+
p {
|
180
|
+
margin: 4px 4px 4px 4px;
|
181
|
+
}
|
182
|
+
SCSS
|
183
|
+
|
184
|
+
it { should report_lint }
|
185
|
+
end
|
186
|
+
|
187
|
+
context 'can be shortened to 1, but 1 is not allowed' do
|
188
|
+
let(:allowed) { [2, 3] }
|
189
|
+
let(:scss) { <<-SCSS }
|
190
|
+
p {
|
191
|
+
margin: 4px 4px 4px;
|
192
|
+
}
|
193
|
+
SCSS
|
194
|
+
|
195
|
+
it { should_not report_lint }
|
196
|
+
end
|
197
|
+
end
|
172
198
|
end
|
@@ -81,6 +81,27 @@ describe SCSSLint::Linter::SpaceAfterPropertyColon do
|
|
81
81
|
|
82
82
|
it { should report_lint line: 3 }
|
83
83
|
end
|
84
|
+
|
85
|
+
context 'when the colon after a property is followed by a space and a newline' do
|
86
|
+
let(:scss) { <<-SCSS }
|
87
|
+
p {
|
88
|
+
margin:\s
|
89
|
+
0;
|
90
|
+
}
|
91
|
+
SCSS
|
92
|
+
|
93
|
+
it { should report_lint line: 2 }
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when the colon after a property is followed by a tab' do
|
97
|
+
let(:scss) { <<-SCSS }
|
98
|
+
p {
|
99
|
+
margin:\t0;
|
100
|
+
}
|
101
|
+
SCSS
|
102
|
+
|
103
|
+
it { should report_lint line: 2 }
|
104
|
+
end
|
84
105
|
end
|
85
106
|
|
86
107
|
context 'when no spaces are allowed' do
|
@@ -135,6 +156,27 @@ describe SCSSLint::Linter::SpaceAfterPropertyColon do
|
|
135
156
|
|
136
157
|
it { should report_lint line: 2 }
|
137
158
|
end
|
159
|
+
|
160
|
+
context 'when the colon after a property is followed by a newline' do
|
161
|
+
let(:scss) { <<-SCSS }
|
162
|
+
p {
|
163
|
+
margin:
|
164
|
+
0;
|
165
|
+
}
|
166
|
+
SCSS
|
167
|
+
|
168
|
+
it { should report_lint line: 2 }
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'when the colon after a property is followed by a tab' do
|
172
|
+
let(:scss) { <<-SCSS }
|
173
|
+
p {
|
174
|
+
margin:\t0;
|
175
|
+
}
|
176
|
+
SCSS
|
177
|
+
|
178
|
+
it { should report_lint line: 2 }
|
179
|
+
end
|
138
180
|
end
|
139
181
|
|
140
182
|
context 'when at least one space is preferred' do
|
@@ -189,6 +231,73 @@ describe SCSSLint::Linter::SpaceAfterPropertyColon do
|
|
189
231
|
|
190
232
|
it { should_not report_lint }
|
191
233
|
end
|
234
|
+
|
235
|
+
context 'when the colon after a property is followed by multiple spaces and a tab' do
|
236
|
+
let(:scss) { <<-SCSS }
|
237
|
+
p {
|
238
|
+
margin: \tbold;
|
239
|
+
}
|
240
|
+
SCSS
|
241
|
+
|
242
|
+
it { should report_lint line: 2 }
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'when one space or newline is preferred' do
|
247
|
+
let(:style) { 'one_space_or_newline' }
|
248
|
+
|
249
|
+
context 'when the colon after a property is not followed by space' do
|
250
|
+
let(:scss) { <<-SCSS }
|
251
|
+
p {
|
252
|
+
margin:0;
|
253
|
+
}
|
254
|
+
SCSS
|
255
|
+
|
256
|
+
it { should report_lint line: 2 }
|
257
|
+
end
|
258
|
+
|
259
|
+
context 'when the colon after a property is followed by a space' do
|
260
|
+
let(:scss) { <<-SCSS }
|
261
|
+
p {
|
262
|
+
margin: 0;
|
263
|
+
}
|
264
|
+
SCSS
|
265
|
+
|
266
|
+
it { should_not report_lint }
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'when the colon after a property is followed by a newline and spaces' do
|
270
|
+
let(:scss) { <<-SCSS }
|
271
|
+
p {
|
272
|
+
background-image:
|
273
|
+
url(https://something.crazy.long/with/paths?and=queries)
|
274
|
+
}
|
275
|
+
SCSS
|
276
|
+
|
277
|
+
it { should_not report_lint }
|
278
|
+
end
|
279
|
+
|
280
|
+
context 'when the colon after a property is followed by a newline and no spaces' do
|
281
|
+
let(:scss) { <<-SCSS }
|
282
|
+
p {
|
283
|
+
background-image:
|
284
|
+
url(https://something.crazy.long/with/paths?and=queries)
|
285
|
+
}
|
286
|
+
SCSS
|
287
|
+
|
288
|
+
it { should_not report_lint }
|
289
|
+
end
|
290
|
+
|
291
|
+
context 'when the colon after a property is followed by a space and then a newline' do
|
292
|
+
let(:scss) { <<-SCSS }
|
293
|
+
p {
|
294
|
+
background-image:\s
|
295
|
+
url(https://something.crazy.long/with/paths?and=queries)
|
296
|
+
}
|
297
|
+
SCSS
|
298
|
+
|
299
|
+
it { should report_lint line: 2 }
|
300
|
+
end
|
192
301
|
end
|
193
302
|
|
194
303
|
context 'when aligned property values are preferred' do
|
@@ -87,6 +87,36 @@ describe SCSSLint::Linter::VariableForProperty do
|
|
87
87
|
|
88
88
|
it { should report_lint line: 3 }
|
89
89
|
end
|
90
|
+
|
91
|
+
context 'when property specifies `currentColor`' do
|
92
|
+
let(:scss) { <<-SCSS }
|
93
|
+
p {
|
94
|
+
background-color: currentColor;
|
95
|
+
}
|
96
|
+
SCSS
|
97
|
+
|
98
|
+
it { should_not report_lint }
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when property specifies `inherit`' do
|
102
|
+
let(:scss) { <<-SCSS }
|
103
|
+
p {
|
104
|
+
color: inherit;
|
105
|
+
}
|
106
|
+
SCSS
|
107
|
+
|
108
|
+
it { should_not report_lint }
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when property specifies `transparent`' do
|
112
|
+
let(:scss) { <<-SCSS }
|
113
|
+
p {
|
114
|
+
color: transparent;
|
115
|
+
}
|
116
|
+
SCSS
|
117
|
+
|
118
|
+
it { should_not report_lint }
|
119
|
+
end
|
90
120
|
end
|
91
121
|
|
92
122
|
context 'when properties are not specified' do
|
@@ -63,11 +63,11 @@ describe SCSSLint::Runner do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
before do
|
66
|
-
SCSSLint::Engine.stub(:new).
|
66
|
+
SCSSLint::Engine.stub(:new).and_raise(error)
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'records the error as a lint' do
|
70
|
-
|
70
|
+
subject.count.should == 2
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
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.
|
4
|
+
version: 0.38.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: 2015-
|
12
|
+
date: 2015-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rainbow
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '3.0'
|
70
|
-
description:
|
70
|
+
description: 'MOVED: See `scss_lint` (with an underscore) for up-to-date project'
|
71
71
|
email:
|
72
72
|
- eng@brigade.com
|
73
73
|
- shane.dasilva@brigade.com
|
@@ -235,7 +235,9 @@ homepage: https://github.com/brigade/scss-lint
|
|
235
235
|
licenses:
|
236
236
|
- MIT
|
237
237
|
metadata: {}
|
238
|
-
post_install_message:
|
238
|
+
post_install_message: 'WARNING: `scss-lint` has been renamed to `scss_lint` to follow
|
239
|
+
proper RubyGems naming conventions. Update your Gemfile or relevant install scripts
|
240
|
+
to install `scss_lint`.'
|
239
241
|
rdoc_options: []
|
240
242
|
require_paths:
|
241
243
|
- lib
|
@@ -251,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
251
253
|
version: '0'
|
252
254
|
requirements: []
|
253
255
|
rubyforge_project:
|
254
|
-
rubygems_version: 2.
|
256
|
+
rubygems_version: 2.4.5
|
255
257
|
signing_key:
|
256
258
|
specification_version: 4
|
257
259
|
summary: SCSS lint tool
|