scss_lint 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.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/bin/scss-lint +6 -0
  3. data/config/default.yml +205 -0
  4. data/data/prefixed-identifiers/base.txt +107 -0
  5. data/data/prefixed-identifiers/bourbon.txt +71 -0
  6. data/data/properties.txt +477 -0
  7. data/data/property-sort-orders/concentric.txt +134 -0
  8. data/data/property-sort-orders/recess.txt +149 -0
  9. data/data/property-sort-orders/smacss.txt +137 -0
  10. data/lib/scss_lint.rb +31 -0
  11. data/lib/scss_lint/cli.rb +215 -0
  12. data/lib/scss_lint/config.rb +251 -0
  13. data/lib/scss_lint/constants.rb +8 -0
  14. data/lib/scss_lint/control_comment_processor.rb +126 -0
  15. data/lib/scss_lint/engine.rb +56 -0
  16. data/lib/scss_lint/exceptions.rb +21 -0
  17. data/lib/scss_lint/file_finder.rb +68 -0
  18. data/lib/scss_lint/lint.rb +24 -0
  19. data/lib/scss_lint/linter.rb +161 -0
  20. data/lib/scss_lint/linter/bang_format.rb +52 -0
  21. data/lib/scss_lint/linter/border_zero.rb +39 -0
  22. data/lib/scss_lint/linter/color_keyword.rb +32 -0
  23. data/lib/scss_lint/linter/color_variable.rb +60 -0
  24. data/lib/scss_lint/linter/comment.rb +21 -0
  25. data/lib/scss_lint/linter/compass.rb +7 -0
  26. data/lib/scss_lint/linter/compass/property_with_mixin.rb +47 -0
  27. data/lib/scss_lint/linter/debug_statement.rb +10 -0
  28. data/lib/scss_lint/linter/declaration_order.rb +71 -0
  29. data/lib/scss_lint/linter/duplicate_property.rb +58 -0
  30. data/lib/scss_lint/linter/else_placement.rb +48 -0
  31. data/lib/scss_lint/linter/empty_line_between_blocks.rb +85 -0
  32. data/lib/scss_lint/linter/empty_rule.rb +11 -0
  33. data/lib/scss_lint/linter/final_newline.rb +20 -0
  34. data/lib/scss_lint/linter/hex_length.rb +56 -0
  35. data/lib/scss_lint/linter/hex_notation.rb +38 -0
  36. data/lib/scss_lint/linter/hex_validation.rb +23 -0
  37. data/lib/scss_lint/linter/id_selector.rb +10 -0
  38. data/lib/scss_lint/linter/import_path.rb +62 -0
  39. data/lib/scss_lint/linter/important_rule.rb +12 -0
  40. data/lib/scss_lint/linter/indentation.rb +197 -0
  41. data/lib/scss_lint/linter/leading_zero.rb +49 -0
  42. data/lib/scss_lint/linter/mergeable_selector.rb +60 -0
  43. data/lib/scss_lint/linter/name_format.rb +117 -0
  44. data/lib/scss_lint/linter/nesting_depth.rb +24 -0
  45. data/lib/scss_lint/linter/placeholder_in_extend.rb +22 -0
  46. data/lib/scss_lint/linter/property_count.rb +44 -0
  47. data/lib/scss_lint/linter/property_sort_order.rb +198 -0
  48. data/lib/scss_lint/linter/property_spelling.rb +49 -0
  49. data/lib/scss_lint/linter/property_units.rb +59 -0
  50. data/lib/scss_lint/linter/qualifying_element.rb +42 -0
  51. data/lib/scss_lint/linter/selector_depth.rb +64 -0
  52. data/lib/scss_lint/linter/selector_format.rb +102 -0
  53. data/lib/scss_lint/linter/shorthand.rb +139 -0
  54. data/lib/scss_lint/linter/single_line_per_property.rb +59 -0
  55. data/lib/scss_lint/linter/single_line_per_selector.rb +35 -0
  56. data/lib/scss_lint/linter/space_after_comma.rb +110 -0
  57. data/lib/scss_lint/linter/space_after_property_colon.rb +92 -0
  58. data/lib/scss_lint/linter/space_after_property_name.rb +27 -0
  59. data/lib/scss_lint/linter/space_before_brace.rb +72 -0
  60. data/lib/scss_lint/linter/space_between_parens.rb +35 -0
  61. data/lib/scss_lint/linter/string_quotes.rb +94 -0
  62. data/lib/scss_lint/linter/trailing_semicolon.rb +67 -0
  63. data/lib/scss_lint/linter/trailing_zero.rb +41 -0
  64. data/lib/scss_lint/linter/unnecessary_mantissa.rb +42 -0
  65. data/lib/scss_lint/linter/unnecessary_parent_reference.rb +49 -0
  66. data/lib/scss_lint/linter/url_format.rb +56 -0
  67. data/lib/scss_lint/linter/url_quotes.rb +27 -0
  68. data/lib/scss_lint/linter/variable_for_property.rb +30 -0
  69. data/lib/scss_lint/linter/vendor_prefix.rb +64 -0
  70. data/lib/scss_lint/linter/zero_unit.rb +39 -0
  71. data/lib/scss_lint/linter_registry.rb +26 -0
  72. data/lib/scss_lint/location.rb +38 -0
  73. data/lib/scss_lint/options.rb +109 -0
  74. data/lib/scss_lint/rake_task.rb +106 -0
  75. data/lib/scss_lint/reporter.rb +18 -0
  76. data/lib/scss_lint/reporter/config_reporter.rb +26 -0
  77. data/lib/scss_lint/reporter/default_reporter.rb +27 -0
  78. data/lib/scss_lint/reporter/files_reporter.rb +8 -0
  79. data/lib/scss_lint/reporter/json_reporter.rb +30 -0
  80. data/lib/scss_lint/reporter/xml_reporter.rb +33 -0
  81. data/lib/scss_lint/runner.rb +51 -0
  82. data/lib/scss_lint/sass/script.rb +78 -0
  83. data/lib/scss_lint/sass/tree.rb +168 -0
  84. data/lib/scss_lint/selector_visitor.rb +34 -0
  85. data/lib/scss_lint/utils.rb +112 -0
  86. data/lib/scss_lint/version.rb +4 -0
  87. data/spec/scss_lint/cli_spec.rb +177 -0
  88. data/spec/scss_lint/config_spec.rb +253 -0
  89. data/spec/scss_lint/engine_spec.rb +24 -0
  90. data/spec/scss_lint/file_finder_spec.rb +134 -0
  91. data/spec/scss_lint/linter/bang_format_spec.rb +121 -0
  92. data/spec/scss_lint/linter/border_zero_spec.rb +118 -0
  93. data/spec/scss_lint/linter/color_keyword_spec.rb +83 -0
  94. data/spec/scss_lint/linter/color_variable_spec.rb +155 -0
  95. data/spec/scss_lint/linter/comment_spec.rb +79 -0
  96. data/spec/scss_lint/linter/compass/property_with_mixin_spec.rb +55 -0
  97. data/spec/scss_lint/linter/debug_statement_spec.rb +21 -0
  98. data/spec/scss_lint/linter/declaration_order_spec.rb +575 -0
  99. data/spec/scss_lint/linter/duplicate_property_spec.rb +189 -0
  100. data/spec/scss_lint/linter/else_placement_spec.rb +106 -0
  101. data/spec/scss_lint/linter/empty_line_between_blocks_spec.rb +276 -0
  102. data/spec/scss_lint/linter/empty_rule_spec.rb +27 -0
  103. data/spec/scss_lint/linter/final_newline_spec.rb +49 -0
  104. data/spec/scss_lint/linter/hex_length_spec.rb +104 -0
  105. data/spec/scss_lint/linter/hex_notation_spec.rb +104 -0
  106. data/spec/scss_lint/linter/hex_validation_spec.rb +40 -0
  107. data/spec/scss_lint/linter/id_selector_spec.rb +62 -0
  108. data/spec/scss_lint/linter/import_path_spec.rb +300 -0
  109. data/spec/scss_lint/linter/important_rule_spec.rb +43 -0
  110. data/spec/scss_lint/linter/indentation_spec.rb +347 -0
  111. data/spec/scss_lint/linter/leading_zero_spec.rb +233 -0
  112. data/spec/scss_lint/linter/mergeable_selector_spec.rb +283 -0
  113. data/spec/scss_lint/linter/name_format_spec.rb +282 -0
  114. data/spec/scss_lint/linter/nesting_depth_spec.rb +114 -0
  115. data/spec/scss_lint/linter/placeholder_in_extend_spec.rb +63 -0
  116. data/spec/scss_lint/linter/property_count_spec.rb +104 -0
  117. data/spec/scss_lint/linter/property_sort_order_spec.rb +482 -0
  118. data/spec/scss_lint/linter/property_spelling_spec.rb +84 -0
  119. data/spec/scss_lint/linter/property_units_spec.rb +229 -0
  120. data/spec/scss_lint/linter/qualifying_element_spec.rb +125 -0
  121. data/spec/scss_lint/linter/selector_depth_spec.rb +159 -0
  122. data/spec/scss_lint/linter/selector_format_spec.rb +632 -0
  123. data/spec/scss_lint/linter/shorthand_spec.rb +198 -0
  124. data/spec/scss_lint/linter/single_line_per_property_spec.rb +73 -0
  125. data/spec/scss_lint/linter/single_line_per_selector_spec.rb +130 -0
  126. data/spec/scss_lint/linter/space_after_comma_spec.rb +332 -0
  127. data/spec/scss_lint/linter/space_after_property_colon_spec.rb +373 -0
  128. data/spec/scss_lint/linter/space_after_property_name_spec.rb +37 -0
  129. data/spec/scss_lint/linter/space_before_brace_spec.rb +829 -0
  130. data/spec/scss_lint/linter/space_between_parens_spec.rb +263 -0
  131. data/spec/scss_lint/linter/string_quotes_spec.rb +335 -0
  132. data/spec/scss_lint/linter/trailing_semicolon_spec.rb +304 -0
  133. data/spec/scss_lint/linter/trailing_zero_spec.rb +176 -0
  134. data/spec/scss_lint/linter/unnecessary_mantissa_spec.rb +67 -0
  135. data/spec/scss_lint/linter/unnecessary_parent_reference_spec.rb +98 -0
  136. data/spec/scss_lint/linter/url_format_spec.rb +55 -0
  137. data/spec/scss_lint/linter/url_quotes_spec.rb +73 -0
  138. data/spec/scss_lint/linter/variable_for_property_spec.rb +145 -0
  139. data/spec/scss_lint/linter/vendor_prefix_spec.rb +371 -0
  140. data/spec/scss_lint/linter/zero_unit_spec.rb +113 -0
  141. data/spec/scss_lint/linter_registry_spec.rb +50 -0
  142. data/spec/scss_lint/linter_spec.rb +292 -0
  143. data/spec/scss_lint/location_spec.rb +42 -0
  144. data/spec/scss_lint/options_spec.rb +34 -0
  145. data/spec/scss_lint/rake_task_spec.rb +43 -0
  146. data/spec/scss_lint/reporter/config_reporter_spec.rb +42 -0
  147. data/spec/scss_lint/reporter/default_reporter_spec.rb +73 -0
  148. data/spec/scss_lint/reporter/files_reporter_spec.rb +38 -0
  149. data/spec/scss_lint/reporter/json_reporter_spec.rb +96 -0
  150. data/spec/scss_lint/reporter/xml_reporter_spec.rb +103 -0
  151. data/spec/scss_lint/reporter_spec.rb +11 -0
  152. data/spec/scss_lint/runner_spec.rb +123 -0
  153. data/spec/scss_lint/selector_visitor_spec.rb +264 -0
  154. data/spec/spec_helper.rb +34 -0
  155. data/spec/support/isolated_environment.rb +25 -0
  156. data/spec/support/matchers/report_lint.rb +48 -0
  157. metadata +328 -0
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::Reporter do
4
+ class SCSSLint::Reporter::FakeReporter < SCSSLint::Reporter; end
5
+
6
+ describe '#descendants' do
7
+ it 'contains FakeReporter' do
8
+ SCSSLint::Reporter.descendants.should include(SCSSLint::Reporter::FakeReporter)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::Runner do
4
+ let(:config_options) do
5
+ {
6
+ 'linters' => {
7
+ 'FakeLinter1' => { 'enabled' => true },
8
+ 'FakeLinter2' => { 'enabled' => false },
9
+ },
10
+ }
11
+ end
12
+
13
+ let(:config) { SCSSLint::Config.new(config_options) }
14
+ let(:runner) { described_class.new(config) }
15
+
16
+ before do
17
+ SCSSLint::LinterRegistry.stub(:linters)
18
+ .and_return([SCSSLint::Linter::FakeLinter1,
19
+ SCSSLint::Linter::FakeLinter2])
20
+ end
21
+
22
+ class SCSSLint::Linter::FakeLinter1 < SCSSLint::Linter; end
23
+ class SCSSLint::Linter::FakeLinter2 < SCSSLint::Linter; end
24
+
25
+ describe '#run' do
26
+ let(:files) { ['dummy1.scss', 'dummy2.scss'] }
27
+ subject { runner.run(files) }
28
+
29
+ before do
30
+ SCSSLint::Engine.stub(:new)
31
+ SCSSLint::Linter.any_instance.stub(:run)
32
+ end
33
+
34
+ it 'searches for lints in each file' do
35
+ runner.should_receive(:find_lints).exactly(files.size).times
36
+ subject
37
+ end
38
+
39
+ context 'when all linters are disabled' do
40
+ let(:config_options) do
41
+ {
42
+ 'linters' => {
43
+ 'FakeLinter1' => { 'enabled' => false },
44
+ 'FakeLinter2' => { 'enabled' => false },
45
+ },
46
+ }
47
+ end
48
+
49
+ before do
50
+ SCSSLint::Linter.any_instance
51
+ .stub(:run)
52
+ .and_raise(RuntimeError.new('Linter#run was called'))
53
+ end
54
+
55
+ it 'never runs a linter' do
56
+ expect { subject }.to_not raise_error
57
+ end
58
+ end
59
+
60
+ context 'when the engine raises a FileEncodingError' do
61
+ let(:error) do
62
+ SCSSLint::FileEncodingError.new('Some error message')
63
+ end
64
+
65
+ before do
66
+ SCSSLint::Engine.stub(:new).and_raise(error)
67
+ end
68
+
69
+ it 'records the error as a lint' do
70
+ subject.count.should == 2
71
+ end
72
+ end
73
+
74
+ context 'when files ere excluded for one linter' do
75
+ let(:config_options) do
76
+ {
77
+ 'linters' => {
78
+ 'FakeLinter1' => { 'enabled' => true,
79
+ 'exclude' => [File.expand_path('dummy1.scss'),
80
+ File.expand_path('dummy2.scss')] },
81
+ 'FakeLinter2' => { 'enabled' => false },
82
+ },
83
+ }
84
+ end
85
+
86
+ before do
87
+ SCSSLint::Linter::FakeLinter1.any_instance
88
+ .stub(:run)
89
+ .and_raise(RuntimeError.new('FakeLinter1#run was called'))
90
+ end
91
+
92
+ it 'does not run the linter for the disabled files' do
93
+ expect { subject }.to_not raise_error
94
+ end
95
+ end
96
+
97
+ context 'when a linter raises an error' do
98
+ let(:backtrace) { %w[file.rb:1 file.rb:2] }
99
+
100
+ let(:error) do
101
+ StandardError.new('Some error message').tap do |e|
102
+ e.set_backtrace(backtrace)
103
+ end
104
+ end
105
+
106
+ before do
107
+ runner.stub(:run_linter).and_raise(error)
108
+ end
109
+
110
+ it 'raises a LinterError' do
111
+ expect { subject }.to raise_error(SCSSLint::Exceptions::LinterError)
112
+ end
113
+
114
+ it 'has the name of the file the linter was checking' do
115
+ expect { subject }.to raise_error { |e| e.message.should include files.first }
116
+ end
117
+
118
+ it 'has the same backtrace as the original error' do
119
+ expect { subject }.to raise_error { |e| e.backtrace.should == backtrace }
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,264 @@
1
+ require 'spec_helper'
2
+
3
+ describe SCSSLint::SelectorVisitor do
4
+ describe '#visit' do
5
+ let(:engine) { SCSSLint::Engine.new(code: scss) }
6
+ before { RuleVisitor.new(visitor).run(engine) }
7
+
8
+ # Visits every rule in the given parse tree and passes the parsed selector
9
+ # to the given `selector_visitor`.
10
+ class RuleVisitor < Sass::Tree::Visitors::Base
11
+ def initialize(selector_visitor)
12
+ @selector_visitor = selector_visitor
13
+ end
14
+
15
+ def run(engine)
16
+ visit(engine.tree)
17
+ end
18
+
19
+ def visit_rule(node)
20
+ @selector_visitor.visit_selector(node.parsed_rules)
21
+ yield # Continue linting children
22
+ end
23
+ end
24
+
25
+ # Superclass for all the test selector visitors
26
+ class TrackingSelectorVisitor
27
+ include SCSSLint::SelectorVisitor
28
+
29
+ attr_reader :node_order
30
+
31
+ def initialize
32
+ @node_order = []
33
+ end
34
+ end
35
+
36
+ context 'when visitor defines visit_attribute' do
37
+ class TestAttributeVisitor < TrackingSelectorVisitor
38
+ def visit_attribute(attribute)
39
+ @node_order << attribute.name
40
+ end
41
+ end
42
+
43
+ let(:visitor) { TestAttributeVisitor.new }
44
+
45
+ let(:scss) { <<-SCSS }
46
+ [rel="nofollow"] {}
47
+ a[href="http"] {}
48
+ .class [data-count] {}
49
+ SCSS
50
+
51
+ it 'visits all attribute nodes' do
52
+ visitor.node_order.should == %w[rel href data-count]
53
+ end
54
+ end
55
+
56
+ context 'when visitor defines visit_class' do
57
+ class TestClassVisitor < TrackingSelectorVisitor
58
+ def visit_class(klass)
59
+ @node_order << klass.name
60
+ end
61
+ end
62
+
63
+ let(:visitor) { TestClassVisitor.new }
64
+
65
+ let(:scss) { <<-SCSS }
66
+ a.link {}
67
+ .menu .menu-item {}
68
+ .button[data-source], .overlay {}
69
+ SCSS
70
+
71
+ it 'visits all class nodes' do
72
+ visitor.node_order.should == %w[link menu menu-item button overlay]
73
+ end
74
+ end
75
+
76
+ context 'when visitor defines visit_element' do
77
+ class TestElementVisitor < TrackingSelectorVisitor
78
+ def visit_element(element)
79
+ @node_order << element.name
80
+ end
81
+ end
82
+
83
+ let(:visitor) { TestElementVisitor.new }
84
+
85
+ let(:scss) { <<-SCSS }
86
+ a, b {}
87
+ .class {}
88
+ i + p {}
89
+ SCSS
90
+
91
+ it 'visits all element nodes' do
92
+ visitor.node_order.should == %w[a b i p]
93
+ end
94
+ end
95
+
96
+ context 'when visitor defines visit_id' do
97
+ class TestIdVisitor < TrackingSelectorVisitor
98
+ def visit_id(id)
99
+ @node_order << id.name
100
+ end
101
+ end
102
+
103
+ let(:visitor) { TestIdVisitor.new }
104
+
105
+ let(:scss) { <<-SCSS }
106
+ #something, #thing {}
107
+ #object + #entity {}
108
+ SCSS
109
+
110
+ it 'visits all id nodes' do
111
+ visitor.node_order.should == %w[something thing object entity]
112
+ end
113
+ end
114
+
115
+ context 'when visitor defines visit_parent' do
116
+ class TestParentVisitor < TrackingSelectorVisitor
117
+ def visit_parent(parent)
118
+ @node_order << parent.line
119
+ end
120
+ end
121
+
122
+ let(:visitor) { TestParentVisitor.new }
123
+
124
+ let(:scss) { <<-SCSS }
125
+ p {
126
+ &.class {}
127
+ .container & {}
128
+ .nothing {}
129
+ }
130
+ SCSS
131
+
132
+ it 'visits all parent nodes' do
133
+ visitor.node_order.should == [2, 3]
134
+ end
135
+ end
136
+
137
+ context 'when visitor defines visit_placeholder' do
138
+ class TestPlaceholderVisitor < TrackingSelectorVisitor
139
+ def visit_placeholder(placeholder)
140
+ @node_order << placeholder.name
141
+ end
142
+ end
143
+
144
+ let(:visitor) { TestPlaceholderVisitor.new }
145
+
146
+ let(:scss) { <<-SCSS }
147
+ %placeholder, %other-placeholder {}
148
+ .button, %button {}
149
+ SCSS
150
+
151
+ it 'visits all placeholder nodes' do
152
+ visitor.node_order.should == %w[placeholder other-placeholder button]
153
+ end
154
+ end
155
+
156
+ context 'when visitor defines visit_pseudo' do
157
+ class TestPseudoVisitor < TrackingSelectorVisitor
158
+ def visit_pseudo(pseudo)
159
+ @node_order << pseudo.name
160
+ end
161
+ end
162
+
163
+ let(:visitor) { TestPseudoVisitor.new }
164
+
165
+ let(:scss) { <<-SCSS }
166
+ li:first-child, li:last-child {}
167
+ p {
168
+ &:first-letter {}
169
+ }
170
+ SCSS
171
+
172
+ it 'visits all pseudo-selector nodes' do
173
+ visitor.node_order.should == %w[first-child last-child first-letter]
174
+ end
175
+ end
176
+
177
+ context 'when visitor defines visit_universal' do
178
+ class TestUniversalVisitor < TrackingSelectorVisitor
179
+ def visit_universal(universal)
180
+ @node_order << universal.line
181
+ end
182
+ end
183
+
184
+ let(:visitor) { TestUniversalVisitor.new }
185
+
186
+ let(:scss) { <<-SCSS }
187
+ p > * {}
188
+ * {}
189
+ li {}
190
+ *:first-child {}
191
+ SCSS
192
+
193
+ it 'visits all universal-selector nodes' do
194
+ visitor.node_order.should == [1, 2, 4]
195
+ end
196
+ end
197
+
198
+ context 'when visitor defines visit_simple_sequence' do
199
+ class TestSimpleSequenceVisitor < TrackingSelectorVisitor
200
+ def visit_simple_sequence(seq)
201
+ @node_order << seq
202
+ end
203
+ end
204
+
205
+ let(:visitor) { TestSimpleSequenceVisitor.new }
206
+
207
+ let(:scss) { <<-SCSS }
208
+ a, b, p[lang] {}
209
+ a.link + b.word {}
210
+ li {}
211
+ ul > li {}
212
+ p span {}
213
+ SCSS
214
+
215
+ it 'visits all simple sequences' do
216
+ visitor.node_order.count.should == 10
217
+ end
218
+ end
219
+
220
+ context 'when visitor defines visit_sequence' do
221
+ class TestSequenceVisitor < TrackingSelectorVisitor
222
+ def visit_sequence(seq)
223
+ @node_order << seq
224
+ end
225
+ end
226
+
227
+ let(:visitor) { TestSequenceVisitor.new }
228
+
229
+ let(:scss) { <<-SCSS }
230
+ a, b, p[lang] {}
231
+ a.link + b.word {}
232
+ li {}
233
+ ul > li {}
234
+ p span {}
235
+ SCSS
236
+
237
+ it 'visits all sequences' do
238
+ visitor.node_order.count.should == 7
239
+ end
240
+ end
241
+
242
+ context 'when visitor defines visit_comma_sequence' do
243
+ class TestCommaSequenceVisitor < TrackingSelectorVisitor
244
+ def visit_comma_sequence(seq)
245
+ @node_order << seq
246
+ end
247
+ end
248
+
249
+ let(:visitor) { TestCommaSequenceVisitor.new }
250
+
251
+ let(:scss) { <<-SCSS }
252
+ a, b, p[lang] {}
253
+ a.link + b.word {}
254
+ li {}
255
+ ul > li {}
256
+ p span {}
257
+ SCSS
258
+
259
+ it 'visits all comma (i.e. selector) sequences' do
260
+ visitor.node_order.count.should == 5
261
+ end
262
+ end
263
+ end
264
+ end
@@ -0,0 +1,34 @@
1
+ require 'scss_lint'
2
+ require 'nokogiri'
3
+
4
+ Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
5
+
6
+ RSpec.configure do |config|
7
+ config.expect_with :rspec do |c|
8
+ c.syntax = [:expect, :should]
9
+ end
10
+
11
+ config.mock_with :rspec do |c|
12
+ c.syntax = :should
13
+ end
14
+
15
+ config.before(:each) do
16
+ # If running a linter spec, run the described linter against the CSS code
17
+ # for each example. This significantly DRYs up our linter specs to contain
18
+ # only tests, since all the setup code is now centralized here.
19
+ if described_class <= SCSSLint::Linter
20
+ initial_indent = scss[/\A(\s*)/, 1]
21
+ normalized_css = scss.gsub(/^#{initial_indent}/, '')
22
+
23
+ # Use the configuration settings defined by default unless a specific
24
+ # configuration has been provided for the test.
25
+ local_config = if respond_to?(:linter_config)
26
+ linter_config
27
+ else
28
+ SCSSLint::Config.default.linter_options(subject)
29
+ end
30
+
31
+ subject.run(SCSSLint::Engine.new(code: normalized_css), local_config)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ require 'fileutils'
2
+ require 'tmpdir'
3
+
4
+ shared_context 'isolated environment' do
5
+ around do |example|
6
+ Dir.mktmpdir do |tmpdir|
7
+ original_home = ENV['HOME']
8
+
9
+ begin
10
+ virtual_home = File.expand_path(File.join(tmpdir, 'home'))
11
+ Dir.mkdir(virtual_home)
12
+ ENV['HOME'] = virtual_home
13
+
14
+ working_dir = File.join(tmpdir, 'work')
15
+ Dir.mkdir(working_dir)
16
+
17
+ Dir.chdir(working_dir) do
18
+ example.run
19
+ end
20
+ ensure
21
+ ENV['HOME'] = original_home
22
+ end
23
+ end
24
+ end
25
+ end