scss-lint 0.25.1 → 0.26.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 +10 -1
- data/data/property-sort-orders/concentric.txt +99 -0
- data/lib/scss_lint.rb +1 -0
- data/lib/scss_lint/cli.rb +9 -3
- data/lib/scss_lint/exceptions.rb +4 -0
- data/lib/scss_lint/linter.rb +10 -1
- data/lib/scss_lint/linter/capitalization_in_selector.rb +14 -6
- data/lib/scss_lint/linter/compass/property_with_mixin.rb +9 -2
- data/lib/scss_lint/linter/indentation.rb +28 -6
- data/lib/scss_lint/linter/property_sort_order.rb +61 -9
- data/lib/scss_lint/linter/single_line_per_property.rb +53 -0
- data/lib/scss_lint/linter/single_line_per_selector.rb +6 -1
- data/lib/scss_lint/linter/space_after_comma.rb +27 -19
- data/lib/scss_lint/linter/space_before_brace.rb +5 -4
- data/lib/scss_lint/linter/trailing_semicolon.rb +53 -0
- data/lib/scss_lint/linter/unnecessary_parent_reference.rb +36 -0
- data/lib/scss_lint/reporter/default_reporter.rb +7 -2
- data/lib/scss_lint/reporter/xml_reporter.rb +2 -1
- data/lib/scss_lint/runner.rb +7 -3
- data/lib/scss_lint/version.rb +1 -1
- data/spec/scss_lint/cli_spec.rb +314 -0
- data/spec/scss_lint/config_spec.rb +439 -0
- data/spec/scss_lint/engine_spec.rb +24 -0
- data/spec/scss_lint/linter/border_zero_spec.rb +84 -0
- data/spec/scss_lint/linter/capitalization_in_selector_spec.rb +71 -0
- data/spec/scss_lint/linter/color_keyword_spec.rb +83 -0
- data/spec/scss_lint/linter/comment_spec.rb +55 -0
- data/spec/scss_lint/linter/compass/property_with_mixin_spec.rb +55 -0
- data/spec/scss_lint/linter/debug_statement_spec.rb +21 -0
- data/spec/scss_lint/linter/declaration_order_spec.rb +94 -0
- data/spec/scss_lint/linter/duplicate_property_spec.rb +176 -0
- data/spec/scss_lint/linter/else_placement_spec.rb +106 -0
- data/spec/scss_lint/linter/empty_line_between_blocks_spec.rb +263 -0
- data/spec/scss_lint/linter/empty_rule_spec.rb +27 -0
- data/spec/scss_lint/linter/final_newline_spec.rb +49 -0
- data/spec/scss_lint/linter/hex_length_spec.rb +104 -0
- data/spec/scss_lint/linter/hex_notation_spec.rb +104 -0
- data/spec/scss_lint/linter/hex_validation_spec.rb +36 -0
- data/spec/scss_lint/linter/id_with_extraneous_selector_spec.rb +139 -0
- data/spec/scss_lint/linter/indentation_spec.rb +242 -0
- data/spec/scss_lint/linter/leading_zero_spec.rb +233 -0
- data/spec/scss_lint/linter/mergeable_selector_spec.rb +283 -0
- data/spec/scss_lint/linter/name_format_spec.rb +206 -0
- data/spec/scss_lint/linter/placeholder_in_extend_spec.rb +63 -0
- data/spec/scss_lint/linter/property_sort_order_spec.rb +246 -0
- data/spec/scss_lint/linter/property_spelling_spec.rb +57 -0
- data/spec/scss_lint/linter/selector_depth_spec.rb +159 -0
- data/spec/scss_lint/linter/shorthand_spec.rb +172 -0
- data/spec/scss_lint/linter/single_line_per_property_spec.rb +73 -0
- data/spec/scss_lint/linter/single_line_per_selector_spec.rb +121 -0
- data/spec/scss_lint/linter/space_after_comma_spec.rb +315 -0
- data/spec/scss_lint/linter/space_after_property_colon_spec.rb +238 -0
- data/spec/scss_lint/linter/space_after_property_name_spec.rb +23 -0
- data/spec/scss_lint/linter/space_before_brace_spec.rb +447 -0
- data/spec/scss_lint/linter/space_between_parens_spec.rb +263 -0
- data/spec/scss_lint/linter/string_quotes_spec.rb +303 -0
- data/spec/scss_lint/linter/trailing_semicolon_spec.rb +188 -0
- data/spec/scss_lint/linter/unnecessary_mantissa_spec.rb +67 -0
- data/spec/scss_lint/linter/unnecessary_parent_reference_spec.rb +67 -0
- data/spec/scss_lint/linter/url_format_spec.rb +55 -0
- data/spec/scss_lint/linter/url_quotes_spec.rb +63 -0
- data/spec/scss_lint/linter/zero_unit_spec.rb +113 -0
- data/spec/scss_lint/linter_registry_spec.rb +50 -0
- data/spec/scss_lint/location_spec.rb +42 -0
- data/spec/scss_lint/reporter/config_reporter_spec.rb +42 -0
- data/spec/scss_lint/reporter/default_reporter_spec.rb +73 -0
- data/spec/scss_lint/reporter/files_reporter_spec.rb +38 -0
- data/spec/scss_lint/reporter/xml_reporter_spec.rb +103 -0
- data/spec/scss_lint/reporter_spec.rb +11 -0
- data/spec/scss_lint/runner_spec.rb +132 -0
- data/spec/scss_lint/selector_visitor_spec.rb +264 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/isolated_environment.rb +25 -0
- data/spec/support/matchers/report_lint.rb +48 -0
- metadata +126 -8
- data/lib/scss_lint/linter/trailing_semicolon_after_property_value.rb +0 -40
@@ -0,0 +1,439 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
describe SCSSLint::Config do
|
5
|
+
class SCSSLint::Linter::FakeConfigLinter < SCSSLint::Linter; end
|
6
|
+
|
7
|
+
module SCSSLint::Linter::SomeNamespace
|
8
|
+
class FakeLinter1 < SCSSLint::Linter; end
|
9
|
+
class FakeLinter2 < SCSSLint::Linter; end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:default_file) { File.open(described_class::DEFAULT_FILE).read }
|
13
|
+
|
14
|
+
# This complex stubbing bypasses the built-in caching of the methods, and at
|
15
|
+
# the same time gives us full control over the "default" configuration.
|
16
|
+
before do
|
17
|
+
described_class
|
18
|
+
.stub(:load_file_contents)
|
19
|
+
.with(described_class::DEFAULT_FILE)
|
20
|
+
.and_return(default_file)
|
21
|
+
|
22
|
+
described_class
|
23
|
+
.stub(:default_options_hash)
|
24
|
+
.and_return(described_class.send(:load_options_hash_from_file, described_class::DEFAULT_FILE))
|
25
|
+
|
26
|
+
described_class
|
27
|
+
.stub(:default)
|
28
|
+
.and_return(described_class.load(described_class::DEFAULT_FILE, merge_with_default: false))
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.default' do
|
32
|
+
subject { described_class.default }
|
33
|
+
|
34
|
+
it 'has a configuration defined for all registered linters' do
|
35
|
+
SCSSLint::LinterRegistry.linters.map(&:new).each do |linter|
|
36
|
+
subject.linter_options(linter).should_not be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '.load' do
|
42
|
+
let(:config_dir) { '/path/to' }
|
43
|
+
let(:file_name) { "/#{config_dir}/config.yml" }
|
44
|
+
|
45
|
+
let(:default_file) { <<-FILE }
|
46
|
+
linters:
|
47
|
+
FakeConfigLinter:
|
48
|
+
enabled: true
|
49
|
+
OtherFakeConfigLinter:
|
50
|
+
enabled: false
|
51
|
+
FILE
|
52
|
+
|
53
|
+
subject { described_class.load(file_name) }
|
54
|
+
|
55
|
+
before do
|
56
|
+
described_class.stub(:load_file_contents)
|
57
|
+
.with(file_name)
|
58
|
+
.and_return(config_file)
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with an empty config file' do
|
62
|
+
let(:config_file) { '' }
|
63
|
+
|
64
|
+
it 'returns the default configuration' do
|
65
|
+
subject.should == described_class.default
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with a config file containing only comments' do
|
70
|
+
let(:config_file) { '# This is a comment' }
|
71
|
+
|
72
|
+
it 'returns the default configuration' do
|
73
|
+
subject.should == described_class.default
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'with a file configuring an unknown linter' do
|
78
|
+
let(:config_file) { 'linters: { MadeUpLinterName: { enabled: true } }' }
|
79
|
+
|
80
|
+
it 'stores a warning for the unknown linter' do
|
81
|
+
subject.warnings
|
82
|
+
.any? { |warning| warning.include?('MadeUpLinterName') }
|
83
|
+
.should be true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'with a config file setting the same configuration as the default' do
|
88
|
+
let(:config_file) { default_file }
|
89
|
+
|
90
|
+
it 'returns a configuration equivalent to the default' do
|
91
|
+
subject.should == described_class.default
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'with a config file setting the same subset of settings as the default' do
|
96
|
+
let(:config_file) { <<-FILE }
|
97
|
+
linters:
|
98
|
+
FakeConfigLinter:
|
99
|
+
enabled: true
|
100
|
+
FILE
|
101
|
+
|
102
|
+
it 'returns a configuration equivalent to the default' do
|
103
|
+
subject.should == described_class.default
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'with a file that includes another configuration file' do
|
108
|
+
let(:included_file_path) { '../included_file.yml' }
|
109
|
+
|
110
|
+
let(:config_file) { <<-FILE }
|
111
|
+
inherit_from: #{included_file_path}
|
112
|
+
|
113
|
+
linters:
|
114
|
+
FakeConfigLinter:
|
115
|
+
enabled: true
|
116
|
+
some_other_option: some_other_value
|
117
|
+
FILE
|
118
|
+
|
119
|
+
before do
|
120
|
+
described_class.stub(:load_file_contents)
|
121
|
+
.with("#{config_dir}/" + included_file_path)
|
122
|
+
.and_return(included_file)
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'and the included file has a different setting from the default' do
|
126
|
+
let(:included_file) { <<-FILE }
|
127
|
+
linters:
|
128
|
+
OtherFakeConfigLinter:
|
129
|
+
enabled: true
|
130
|
+
some_option: some_value
|
131
|
+
FILE
|
132
|
+
|
133
|
+
it 'reflects the different setting of the included file' do
|
134
|
+
subject.options['linters']['OtherFakeConfigLinter']
|
135
|
+
.should == { 'enabled' => true, 'some_option' => 'some_value' }
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'reflects the different setting of the file that included the file' do
|
139
|
+
subject.options['linters']['FakeConfigLinter']
|
140
|
+
.should == { 'enabled' => true, 'some_other_option' => 'some_other_value' }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'and the included file has the same setting as the default' do
|
145
|
+
let(:included_file) { <<-FILE }
|
146
|
+
linters:
|
147
|
+
OtherFakeConfigLinter:
|
148
|
+
enabled: false
|
149
|
+
FILE
|
150
|
+
|
151
|
+
it 'does not alter the default configuration' do
|
152
|
+
subject.options['linters']['OtherFakeConfigLinter']
|
153
|
+
.should == { 'enabled' => false }
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'reflects the different setting of the file that included the file' do
|
157
|
+
subject.options['linters']['FakeConfigLinter']
|
158
|
+
.should == { 'enabled' => true, 'some_other_option' => 'some_other_value' }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'and the included file includes another file' do
|
163
|
+
let(:other_included_file_path) { '/some/abs/other_included_file.yml' }
|
164
|
+
|
165
|
+
let(:other_included_file) { <<-FILE }
|
166
|
+
linters:
|
167
|
+
OtherFakeConfigLinter:
|
168
|
+
yet_another_option: yet_another_value
|
169
|
+
FILE
|
170
|
+
|
171
|
+
let(:included_file) { <<-FILE }
|
172
|
+
inherit_from: #{other_included_file_path}
|
173
|
+
|
174
|
+
linters:
|
175
|
+
OtherFakeConfigLinter:
|
176
|
+
enabled: true
|
177
|
+
some_option: some_value
|
178
|
+
FILE
|
179
|
+
|
180
|
+
before do
|
181
|
+
described_class.stub(:load_file_contents)
|
182
|
+
.with(other_included_file_path)
|
183
|
+
.and_return(other_included_file)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "reflects the different setting of the included file's included file" do
|
187
|
+
subject.options['linters']['OtherFakeConfigLinter']
|
188
|
+
.should == {
|
189
|
+
'enabled' => true,
|
190
|
+
'some_option' => 'some_value',
|
191
|
+
'yet_another_option' => 'yet_another_value',
|
192
|
+
}
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'reflects the different setting of the file that included the file' do
|
196
|
+
subject.options['linters']['FakeConfigLinter']
|
197
|
+
.should == { 'enabled' => true, 'some_other_option' => 'some_other_value' }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'with a file that includes multiple configuration files' do
|
203
|
+
let(:included_file_path) { '../included_file.yml' }
|
204
|
+
let(:other_included_file_path) { '/some/dir/other_included_file.yml' }
|
205
|
+
|
206
|
+
let(:config_file) { <<-FILE }
|
207
|
+
inherit_from:
|
208
|
+
- #{included_file_path}
|
209
|
+
- #{other_included_file_path}
|
210
|
+
|
211
|
+
linters:
|
212
|
+
FakeConfigLinter:
|
213
|
+
enabled: true
|
214
|
+
some_other_option: some_other_value
|
215
|
+
FILE
|
216
|
+
|
217
|
+
before do
|
218
|
+
described_class.stub(:load_file_contents)
|
219
|
+
.with("#{config_dir}/" + included_file_path)
|
220
|
+
.and_return(included_file)
|
221
|
+
|
222
|
+
described_class.stub(:load_file_contents)
|
223
|
+
.with(other_included_file_path)
|
224
|
+
.and_return(other_included_file)
|
225
|
+
end
|
226
|
+
|
227
|
+
context 'and the included files have settings different from each other' do
|
228
|
+
let(:included_file) { <<-FILE }
|
229
|
+
linters:
|
230
|
+
OtherFakeConfigLinter:
|
231
|
+
enabled: true
|
232
|
+
some_option: earlier_value
|
233
|
+
some_other_option: value
|
234
|
+
FILE
|
235
|
+
|
236
|
+
let(:other_included_file) { <<-FILE }
|
237
|
+
linters:
|
238
|
+
OtherFakeConfigLinter:
|
239
|
+
enabled: true
|
240
|
+
some_option: later_value
|
241
|
+
FILE
|
242
|
+
|
243
|
+
it 'uses the value of the file that was included last' do
|
244
|
+
subject.options['linters']['OtherFakeConfigLinter']['some_option']
|
245
|
+
.should == 'later_value'
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'loads settings from both included files' do
|
249
|
+
subject.options['linters']['OtherFakeConfigLinter']
|
250
|
+
.should == {
|
251
|
+
'enabled' => true,
|
252
|
+
'some_option' => 'later_value',
|
253
|
+
'some_other_option' => 'value',
|
254
|
+
}
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
context 'when a wildcard is used for a namespaced linter' do
|
260
|
+
let(:default_file) { <<-FILE }
|
261
|
+
linters:
|
262
|
+
SomeNamespace::*:
|
263
|
+
enabled: false
|
264
|
+
FILE
|
265
|
+
|
266
|
+
let(:config_file) { <<-FILE }
|
267
|
+
linters:
|
268
|
+
SomeNamespace::*:
|
269
|
+
enabled: true
|
270
|
+
FILE
|
271
|
+
|
272
|
+
before do
|
273
|
+
SCSSLint::LinterRegistry.stub(:linters)
|
274
|
+
.and_return([SCSSLint::Linter::SomeNamespace::FakeLinter1,
|
275
|
+
SCSSLint::Linter::SomeNamespace::FakeLinter2])
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'returns the same options for all linters under that namespace' do
|
279
|
+
subject.linter_options(SCSSLint::Linter::SomeNamespace::FakeLinter1)
|
280
|
+
.should eq('enabled' => true)
|
281
|
+
subject.linter_options(SCSSLint::Linter::SomeNamespace::FakeLinter2)
|
282
|
+
.should eq('enabled' => true)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe '.for_file' do
|
288
|
+
include_context 'isolated environment'
|
289
|
+
|
290
|
+
let(:linted_file) { File.join('foo', 'bar', 'baz', 'file-being-linted.scss') }
|
291
|
+
subject { described_class.for_file(linted_file) }
|
292
|
+
|
293
|
+
before do
|
294
|
+
described_class.instance_variable_set(:@dir_to_config, nil) # Clear cache
|
295
|
+
FileUtils.mkpath(File.dirname(linted_file))
|
296
|
+
FileUtils.touch(linted_file)
|
297
|
+
end
|
298
|
+
|
299
|
+
context 'when there are no configuration files in the directory hierarchy' do
|
300
|
+
it { should be_nil }
|
301
|
+
end
|
302
|
+
|
303
|
+
context 'when there is a configuration file in the same directory' do
|
304
|
+
let(:config_file) { File.join('foo', 'bar', 'baz', '.scss-lint.yml') }
|
305
|
+
before { FileUtils.touch(config_file) }
|
306
|
+
|
307
|
+
it 'loads that configuration file' do
|
308
|
+
described_class.should_receive(:load).with(File.expand_path(config_file))
|
309
|
+
subject
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context 'when there is a configuration file in the parent directory' do
|
314
|
+
let(:config_file) { File.join('foo', 'bar', '.scss-lint.yml') }
|
315
|
+
before { FileUtils.touch(config_file) }
|
316
|
+
|
317
|
+
it 'loads that configuration file' do
|
318
|
+
described_class.should_receive(:load).with(File.expand_path(config_file))
|
319
|
+
subject
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'when there is a configuration file in some ancestor directory' do
|
324
|
+
let(:config_file) { File.join('foo', '.scss-lint.yml') }
|
325
|
+
before { FileUtils.touch(config_file) }
|
326
|
+
|
327
|
+
it 'loads that configuration file' do
|
328
|
+
described_class.should_receive(:load).with(File.expand_path(config_file))
|
329
|
+
subject
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
describe '#linter_options' do
|
335
|
+
let(:config) { described_class.new(options) }
|
336
|
+
|
337
|
+
let(:linter_options) do
|
338
|
+
{
|
339
|
+
'enabled' => true,
|
340
|
+
'some_option' => 'some_value',
|
341
|
+
}
|
342
|
+
end
|
343
|
+
|
344
|
+
let(:options) do
|
345
|
+
{
|
346
|
+
'linters' => {
|
347
|
+
'FakeConfigLinter' => linter_options
|
348
|
+
}
|
349
|
+
}
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'returns the options for the specified linter' do
|
353
|
+
config.linter_options(SCSSLint::Linter::FakeConfigLinter.new)
|
354
|
+
.should == linter_options
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
describe '#excluded_file?' do
|
359
|
+
include_context 'isolated environment'
|
360
|
+
|
361
|
+
let(:config_dir) { 'path/to' }
|
362
|
+
let(:file_name) { "#{config_dir}/config.yml" }
|
363
|
+
let(:config) { described_class.load(file_name) }
|
364
|
+
|
365
|
+
before do
|
366
|
+
described_class.stub(:load_file_contents)
|
367
|
+
.with(file_name)
|
368
|
+
.and_return(config_file)
|
369
|
+
end
|
370
|
+
|
371
|
+
context 'when no exclusion is specified' do
|
372
|
+
let(:config_file) { 'linters: {}' }
|
373
|
+
|
374
|
+
it 'does not exclude any files' do
|
375
|
+
config.excluded_file?('anything/you/want.scss').should be false
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context 'when an exclusion is specified' do
|
380
|
+
let(:config_file) { "exclude: 'foo/bar/baz/**'" }
|
381
|
+
|
382
|
+
it 'does not exclude anything not matching the glob' do
|
383
|
+
config.excluded_file?("#{config_dir}/foo/bar/something.scss").should be false
|
384
|
+
config.excluded_file?("#{config_dir}/other/something.scss").should be false
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'excludes anything matching the glob' do
|
388
|
+
config.excluded_file?("#{config_dir}/foo/bar/baz/excluded.scss").should be true
|
389
|
+
config.excluded_file?("#{config_dir}/foo/bar/baz/dir/excluded.scss").should be true
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
describe '#excluded_file_for_linter?' do
|
395
|
+
include_context 'isolated environment'
|
396
|
+
|
397
|
+
let(:config_dir) { 'path/to' }
|
398
|
+
let(:file_name) { "#{config_dir}/config.yml" }
|
399
|
+
let(:config) { described_class.load(file_name) }
|
400
|
+
|
401
|
+
before do
|
402
|
+
described_class.stub(:load_file_contents)
|
403
|
+
.with(file_name)
|
404
|
+
.and_return(config_file)
|
405
|
+
end
|
406
|
+
|
407
|
+
context 'when no exclusion is specified in linter' do
|
408
|
+
let(:config_file) { <<-FILE }
|
409
|
+
linters:
|
410
|
+
FakeConfigLinter:
|
411
|
+
enabled: true
|
412
|
+
FILE
|
413
|
+
|
414
|
+
it 'does not exclude any files' do
|
415
|
+
config.excluded_file_for_linter?(
|
416
|
+
"#{config_dir}/anything/you/want.scss",
|
417
|
+
SCSSLint::Linter::FakeConfigLinter.new
|
418
|
+
).should == false
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
context 'when an exclusion is specified in linter' do
|
423
|
+
let(:config_file) { <<-FILE }
|
424
|
+
linters:
|
425
|
+
FakeConfigLinter:
|
426
|
+
enabled: true
|
427
|
+
exclude:
|
428
|
+
- 'anything/you/want.scss'
|
429
|
+
FILE
|
430
|
+
|
431
|
+
it 'excludes file for the linter' do
|
432
|
+
config.excluded_file_for_linter?(
|
433
|
+
"#{config_dir}/anything/you/want.scss",
|
434
|
+
SCSSLint::Linter::FakeConfigLinter.new
|
435
|
+
).should == true
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SCSSLint::Engine do
|
4
|
+
let(:engine) { described_class.new(css) }
|
5
|
+
|
6
|
+
context 'when a @media directive is present' do
|
7
|
+
let(:css) { <<-CSS }
|
8
|
+
@media only screen {
|
9
|
+
}
|
10
|
+
CSS
|
11
|
+
|
12
|
+
it 'has a parse tree' do
|
13
|
+
engine.tree.should_not be_nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the file being linted has an invalid byte sequence' do
|
18
|
+
let(:css) { "\xC0\u0001" }
|
19
|
+
|
20
|
+
it 'raises a SyntaxError' do
|
21
|
+
expect { engine }.to raise_error(SCSSLint::FileEncodingError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|