scss-lint 0.37.0 → 0.38.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 +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
|