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.
- checksums.yaml +7 -0
- data/bin/scss-lint +6 -0
- data/config/default.yml +205 -0
- data/data/prefixed-identifiers/base.txt +107 -0
- data/data/prefixed-identifiers/bourbon.txt +71 -0
- data/data/properties.txt +477 -0
- data/data/property-sort-orders/concentric.txt +134 -0
- data/data/property-sort-orders/recess.txt +149 -0
- data/data/property-sort-orders/smacss.txt +137 -0
- data/lib/scss_lint.rb +31 -0
- data/lib/scss_lint/cli.rb +215 -0
- data/lib/scss_lint/config.rb +251 -0
- data/lib/scss_lint/constants.rb +8 -0
- data/lib/scss_lint/control_comment_processor.rb +126 -0
- data/lib/scss_lint/engine.rb +56 -0
- data/lib/scss_lint/exceptions.rb +21 -0
- data/lib/scss_lint/file_finder.rb +68 -0
- data/lib/scss_lint/lint.rb +24 -0
- data/lib/scss_lint/linter.rb +161 -0
- data/lib/scss_lint/linter/bang_format.rb +52 -0
- data/lib/scss_lint/linter/border_zero.rb +39 -0
- data/lib/scss_lint/linter/color_keyword.rb +32 -0
- data/lib/scss_lint/linter/color_variable.rb +60 -0
- data/lib/scss_lint/linter/comment.rb +21 -0
- data/lib/scss_lint/linter/compass.rb +7 -0
- data/lib/scss_lint/linter/compass/property_with_mixin.rb +47 -0
- data/lib/scss_lint/linter/debug_statement.rb +10 -0
- data/lib/scss_lint/linter/declaration_order.rb +71 -0
- data/lib/scss_lint/linter/duplicate_property.rb +58 -0
- data/lib/scss_lint/linter/else_placement.rb +48 -0
- data/lib/scss_lint/linter/empty_line_between_blocks.rb +85 -0
- data/lib/scss_lint/linter/empty_rule.rb +11 -0
- data/lib/scss_lint/linter/final_newline.rb +20 -0
- data/lib/scss_lint/linter/hex_length.rb +56 -0
- data/lib/scss_lint/linter/hex_notation.rb +38 -0
- data/lib/scss_lint/linter/hex_validation.rb +23 -0
- data/lib/scss_lint/linter/id_selector.rb +10 -0
- data/lib/scss_lint/linter/import_path.rb +62 -0
- data/lib/scss_lint/linter/important_rule.rb +12 -0
- data/lib/scss_lint/linter/indentation.rb +197 -0
- data/lib/scss_lint/linter/leading_zero.rb +49 -0
- data/lib/scss_lint/linter/mergeable_selector.rb +60 -0
- data/lib/scss_lint/linter/name_format.rb +117 -0
- data/lib/scss_lint/linter/nesting_depth.rb +24 -0
- data/lib/scss_lint/linter/placeholder_in_extend.rb +22 -0
- data/lib/scss_lint/linter/property_count.rb +44 -0
- data/lib/scss_lint/linter/property_sort_order.rb +198 -0
- data/lib/scss_lint/linter/property_spelling.rb +49 -0
- data/lib/scss_lint/linter/property_units.rb +59 -0
- data/lib/scss_lint/linter/qualifying_element.rb +42 -0
- data/lib/scss_lint/linter/selector_depth.rb +64 -0
- data/lib/scss_lint/linter/selector_format.rb +102 -0
- data/lib/scss_lint/linter/shorthand.rb +139 -0
- data/lib/scss_lint/linter/single_line_per_property.rb +59 -0
- data/lib/scss_lint/linter/single_line_per_selector.rb +35 -0
- data/lib/scss_lint/linter/space_after_comma.rb +110 -0
- data/lib/scss_lint/linter/space_after_property_colon.rb +92 -0
- data/lib/scss_lint/linter/space_after_property_name.rb +27 -0
- data/lib/scss_lint/linter/space_before_brace.rb +72 -0
- data/lib/scss_lint/linter/space_between_parens.rb +35 -0
- data/lib/scss_lint/linter/string_quotes.rb +94 -0
- data/lib/scss_lint/linter/trailing_semicolon.rb +67 -0
- data/lib/scss_lint/linter/trailing_zero.rb +41 -0
- data/lib/scss_lint/linter/unnecessary_mantissa.rb +42 -0
- data/lib/scss_lint/linter/unnecessary_parent_reference.rb +49 -0
- data/lib/scss_lint/linter/url_format.rb +56 -0
- data/lib/scss_lint/linter/url_quotes.rb +27 -0
- data/lib/scss_lint/linter/variable_for_property.rb +30 -0
- data/lib/scss_lint/linter/vendor_prefix.rb +64 -0
- data/lib/scss_lint/linter/zero_unit.rb +39 -0
- data/lib/scss_lint/linter_registry.rb +26 -0
- data/lib/scss_lint/location.rb +38 -0
- data/lib/scss_lint/options.rb +109 -0
- data/lib/scss_lint/rake_task.rb +106 -0
- data/lib/scss_lint/reporter.rb +18 -0
- data/lib/scss_lint/reporter/config_reporter.rb +26 -0
- data/lib/scss_lint/reporter/default_reporter.rb +27 -0
- data/lib/scss_lint/reporter/files_reporter.rb +8 -0
- data/lib/scss_lint/reporter/json_reporter.rb +30 -0
- data/lib/scss_lint/reporter/xml_reporter.rb +33 -0
- data/lib/scss_lint/runner.rb +51 -0
- data/lib/scss_lint/sass/script.rb +78 -0
- data/lib/scss_lint/sass/tree.rb +168 -0
- data/lib/scss_lint/selector_visitor.rb +34 -0
- data/lib/scss_lint/utils.rb +112 -0
- data/lib/scss_lint/version.rb +4 -0
- data/spec/scss_lint/cli_spec.rb +177 -0
- data/spec/scss_lint/config_spec.rb +253 -0
- data/spec/scss_lint/engine_spec.rb +24 -0
- data/spec/scss_lint/file_finder_spec.rb +134 -0
- data/spec/scss_lint/linter/bang_format_spec.rb +121 -0
- data/spec/scss_lint/linter/border_zero_spec.rb +118 -0
- data/spec/scss_lint/linter/color_keyword_spec.rb +83 -0
- data/spec/scss_lint/linter/color_variable_spec.rb +155 -0
- data/spec/scss_lint/linter/comment_spec.rb +79 -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 +575 -0
- data/spec/scss_lint/linter/duplicate_property_spec.rb +189 -0
- data/spec/scss_lint/linter/else_placement_spec.rb +106 -0
- data/spec/scss_lint/linter/empty_line_between_blocks_spec.rb +276 -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 +40 -0
- data/spec/scss_lint/linter/id_selector_spec.rb +62 -0
- data/spec/scss_lint/linter/import_path_spec.rb +300 -0
- data/spec/scss_lint/linter/important_rule_spec.rb +43 -0
- data/spec/scss_lint/linter/indentation_spec.rb +347 -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 +282 -0
- data/spec/scss_lint/linter/nesting_depth_spec.rb +114 -0
- data/spec/scss_lint/linter/placeholder_in_extend_spec.rb +63 -0
- data/spec/scss_lint/linter/property_count_spec.rb +104 -0
- data/spec/scss_lint/linter/property_sort_order_spec.rb +482 -0
- data/spec/scss_lint/linter/property_spelling_spec.rb +84 -0
- data/spec/scss_lint/linter/property_units_spec.rb +229 -0
- data/spec/scss_lint/linter/qualifying_element_spec.rb +125 -0
- data/spec/scss_lint/linter/selector_depth_spec.rb +159 -0
- data/spec/scss_lint/linter/selector_format_spec.rb +632 -0
- data/spec/scss_lint/linter/shorthand_spec.rb +198 -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 +130 -0
- data/spec/scss_lint/linter/space_after_comma_spec.rb +332 -0
- data/spec/scss_lint/linter/space_after_property_colon_spec.rb +373 -0
- data/spec/scss_lint/linter/space_after_property_name_spec.rb +37 -0
- data/spec/scss_lint/linter/space_before_brace_spec.rb +829 -0
- data/spec/scss_lint/linter/space_between_parens_spec.rb +263 -0
- data/spec/scss_lint/linter/string_quotes_spec.rb +335 -0
- data/spec/scss_lint/linter/trailing_semicolon_spec.rb +304 -0
- data/spec/scss_lint/linter/trailing_zero_spec.rb +176 -0
- data/spec/scss_lint/linter/unnecessary_mantissa_spec.rb +67 -0
- data/spec/scss_lint/linter/unnecessary_parent_reference_spec.rb +98 -0
- data/spec/scss_lint/linter/url_format_spec.rb +55 -0
- data/spec/scss_lint/linter/url_quotes_spec.rb +73 -0
- data/spec/scss_lint/linter/variable_for_property_spec.rb +145 -0
- data/spec/scss_lint/linter/vendor_prefix_spec.rb +371 -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/linter_spec.rb +292 -0
- data/spec/scss_lint/location_spec.rb +42 -0
- data/spec/scss_lint/options_spec.rb +34 -0
- data/spec/scss_lint/rake_task_spec.rb +43 -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/json_reporter_spec.rb +96 -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 +123 -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 +328 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SCSSLint::Location do
|
|
4
|
+
let(:engine) { described_class.new(css) }
|
|
5
|
+
|
|
6
|
+
describe '#<=>' do
|
|
7
|
+
let(:locations) do
|
|
8
|
+
[
|
|
9
|
+
SCSSLint::Location.new(2, 2, 2),
|
|
10
|
+
SCSSLint::Location.new(2, 2, 1),
|
|
11
|
+
SCSSLint::Location.new(2, 1, 2),
|
|
12
|
+
SCSSLint::Location.new(2, 1, 1),
|
|
13
|
+
SCSSLint::Location.new(1, 2, 2),
|
|
14
|
+
SCSSLint::Location.new(1, 2, 1),
|
|
15
|
+
SCSSLint::Location.new(1, 1, 2),
|
|
16
|
+
SCSSLint::Location.new(1, 1, 1)
|
|
17
|
+
]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'allows locations to be sorted' do
|
|
21
|
+
locations.sort.should == [
|
|
22
|
+
SCSSLint::Location.new(1, 1, 1),
|
|
23
|
+
SCSSLint::Location.new(1, 1, 2),
|
|
24
|
+
SCSSLint::Location.new(1, 2, 1),
|
|
25
|
+
SCSSLint::Location.new(1, 2, 2),
|
|
26
|
+
SCSSLint::Location.new(2, 1, 1),
|
|
27
|
+
SCSSLint::Location.new(2, 1, 2),
|
|
28
|
+
SCSSLint::Location.new(2, 2, 1),
|
|
29
|
+
SCSSLint::Location.new(2, 2, 2)
|
|
30
|
+
]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'when the same location is passed' do
|
|
34
|
+
let(:location) { SCSSLint::Location.new(1, 1, 1) }
|
|
35
|
+
let(:other_location) { SCSSLint::Location.new(1, 1, 1) }
|
|
36
|
+
|
|
37
|
+
it 'returns 0' do
|
|
38
|
+
(location <=> other_location).should == 0
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'scss_lint/options'
|
|
3
|
+
|
|
4
|
+
describe SCSSLint::Options do
|
|
5
|
+
describe '#parse' do
|
|
6
|
+
subject { super().parse(args) }
|
|
7
|
+
|
|
8
|
+
context 'when no arguments are specified' do
|
|
9
|
+
let(:args) { [] }
|
|
10
|
+
|
|
11
|
+
it { should be_a Hash }
|
|
12
|
+
|
|
13
|
+
it 'defines no files to lint by default' do
|
|
14
|
+
subject[:files].should be_empty
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'specifies the DefaultReporter by default' do
|
|
18
|
+
subject[:reporters].first.should include 'Default'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'outputs to STDOUT' do
|
|
22
|
+
subject[:reporters].first.should include :stdout
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context 'when a non-existent flag is specified' do
|
|
27
|
+
let(:args) { ['--totally-made-up-flag'] }
|
|
28
|
+
|
|
29
|
+
it 'raises an error' do
|
|
30
|
+
expect { subject }.to raise_error SCSSLint::Exceptions::InvalidCLIOption
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'scss_lint/rake_task'
|
|
3
|
+
require 'tempfile'
|
|
4
|
+
|
|
5
|
+
describe SCSSLint::RakeTask do
|
|
6
|
+
before(:all) do
|
|
7
|
+
SCSSLint::RakeTask.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
STDOUT.stub(:write) # Silence console output
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:file) do
|
|
15
|
+
Tempfile.new(%w[scss-file .scss]).tap do |f|
|
|
16
|
+
f.write(scss)
|
|
17
|
+
f.close
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def run_task
|
|
22
|
+
Rake::Task[:scss_lint].tap do |t|
|
|
23
|
+
t.reenable # Allows us to execute task multiple times
|
|
24
|
+
t.invoke(file.path)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'when SCSS document is valid with no lints' do
|
|
29
|
+
let(:scss) { '' }
|
|
30
|
+
|
|
31
|
+
it 'does not call Kernel.exit' do
|
|
32
|
+
expect { run_task }.not_to raise_error
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'when SCSS document is invalid' do
|
|
37
|
+
let(:scss) { '.class {' }
|
|
38
|
+
|
|
39
|
+
it 'calls Kernel.exit with the status code' do
|
|
40
|
+
expect { run_task }.to raise_error SystemExit
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SCSSLint::Reporter::ConfigReporter do
|
|
4
|
+
subject { YAML.load(result) }
|
|
5
|
+
let(:result) { described_class.new(lints).report_lints }
|
|
6
|
+
|
|
7
|
+
describe '#report_lints' do
|
|
8
|
+
context 'when there are no lints' do
|
|
9
|
+
let(:lints) { [] }
|
|
10
|
+
|
|
11
|
+
it 'returns nil' do
|
|
12
|
+
result.should be_nil
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'when there are lints' do
|
|
17
|
+
let(:linters) do
|
|
18
|
+
[SCSSLint::Linter::FinalNewline, SCSSLint::Linter::BorderZero,
|
|
19
|
+
SCSSLint::Linter::BorderZero, nil]
|
|
20
|
+
end
|
|
21
|
+
let(:lints) do
|
|
22
|
+
linters.each.map do |linter|
|
|
23
|
+
SCSSLint::Lint.new(linter ? linter.new : nil, '',
|
|
24
|
+
SCSSLint::Location.new, '')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'adds one entry per linter' do
|
|
29
|
+
subject['linters'].size.should eq 2
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'sorts linters by name' do
|
|
33
|
+
subject['linters'].map(&:first).should eq %w[BorderZero FinalNewline]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'disables all found linters' do
|
|
37
|
+
subject['linters']['BorderZero']['enabled'].should eq false
|
|
38
|
+
subject['linters']['FinalNewline']['enabled'].should eq false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SCSSLint::Reporter::DefaultReporter do
|
|
4
|
+
subject { SCSSLint::Reporter::DefaultReporter.new(lints) }
|
|
5
|
+
|
|
6
|
+
describe '#report_lints' do
|
|
7
|
+
context 'when there are no lints' do
|
|
8
|
+
let(:lints) { [] }
|
|
9
|
+
|
|
10
|
+
it 'returns nil' do
|
|
11
|
+
subject.report_lints.should be_nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'when there are lints' do
|
|
16
|
+
let(:filenames) { ['some-filename.scss', 'other-filename.scss'] }
|
|
17
|
+
let(:lines) { [502, 724] }
|
|
18
|
+
let(:descriptions) { ['Description of lint 1', 'Description of lint 2'] }
|
|
19
|
+
let(:severities) { [:warning] * 2 }
|
|
20
|
+
let(:lints) do
|
|
21
|
+
filenames.each_with_index.map do |filename, index|
|
|
22
|
+
location = SCSSLint::Location.new(lines[index])
|
|
23
|
+
SCSSLint::Lint.new(nil, filename, location, descriptions[index],
|
|
24
|
+
severities[index])
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'prints each lint on its own line' do
|
|
29
|
+
subject.report_lints.count("\n").should == 2
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'prints a trailing newline' do
|
|
33
|
+
subject.report_lints[-1].should == "\n"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'prints the filename for each lint' do
|
|
37
|
+
filenames.each do |filename|
|
|
38
|
+
subject.report_lints.scan(/#{filename}/).count.should == 1
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'prints the line number for each lint' do
|
|
43
|
+
lines.each do |line|
|
|
44
|
+
subject.report_lints.scan(/#{line}/).count.should == 1
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'prints the description for each lint' do
|
|
49
|
+
descriptions.each do |description|
|
|
50
|
+
subject.report_lints.scan(/#{description}/).count.should == 1
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context 'when lints are warnings' do
|
|
55
|
+
it 'prints the warning severity code on each line' do
|
|
56
|
+
subject.report_lints.split("\n").each do |line|
|
|
57
|
+
line.scan(/\[W\]/).count.should == 1
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'when lints are errors' do
|
|
63
|
+
let(:severities) { [:error] * 2 }
|
|
64
|
+
|
|
65
|
+
it 'prints the error severity code on each line' do
|
|
66
|
+
subject.report_lints.split("\n").each do |line|
|
|
67
|
+
line.scan(/\[E\]/).count.should == 1
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SCSSLint::Reporter::FilesReporter do
|
|
4
|
+
subject { described_class.new(lints) }
|
|
5
|
+
|
|
6
|
+
describe '#report_lints' do
|
|
7
|
+
context 'when there are no lints' do
|
|
8
|
+
let(:lints) { [] }
|
|
9
|
+
|
|
10
|
+
it 'returns nil' do
|
|
11
|
+
subject.report_lints.should be_nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'when there are lints' do
|
|
16
|
+
let(:filenames) { ['some-filename.scss', 'some-filename.scss', 'other-filename.scss'] }
|
|
17
|
+
let(:lints) do
|
|
18
|
+
filenames.map do |filename|
|
|
19
|
+
SCSSLint::Lint.new(nil, filename, SCSSLint::Location.new, '')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'prints each file on its own line' do
|
|
24
|
+
subject.report_lints.count("\n").should == 2
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'prints a trailing newline' do
|
|
28
|
+
subject.report_lints[-1].should == "\n"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'prints the filename for each lint' do
|
|
32
|
+
filenames.each do |filename|
|
|
33
|
+
subject.report_lints.scan(/#{filename}/).count.should == 1
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SCSSLint::Reporter::JSONReporter do
|
|
4
|
+
subject { SCSSLint::Reporter::JSONReporter.new(lints) }
|
|
5
|
+
|
|
6
|
+
describe '#report_lints' do
|
|
7
|
+
let(:json) { JSON.parse(subject.report_lints) }
|
|
8
|
+
|
|
9
|
+
shared_examples_for 'parsed JSON' do
|
|
10
|
+
it 'is a Hash' do
|
|
11
|
+
json.is_a?(Hash)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'when there are no lints' do
|
|
16
|
+
let(:lints) { [] }
|
|
17
|
+
|
|
18
|
+
it_should_behave_like 'parsed JSON'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'when there are lints' do
|
|
22
|
+
let(:filenames) { ['f1.scss', 'f2.scss', 'f1.scss'] }
|
|
23
|
+
# Include invalid XML characters in the third description to validate
|
|
24
|
+
# that escaping happens for preventing broken XML output
|
|
25
|
+
let(:descriptions) { ['lint 1', 'lint 2', 'lint 3 " \' < & >'] }
|
|
26
|
+
let(:severities) { [:warning] * 3 }
|
|
27
|
+
|
|
28
|
+
let(:locations) do
|
|
29
|
+
[
|
|
30
|
+
SCSSLint::Location.new(5, 2, 3),
|
|
31
|
+
SCSSLint::Location.new(7, 6, 2),
|
|
32
|
+
SCSSLint::Location.new(9, 10, 1)
|
|
33
|
+
]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
let(:lints) do
|
|
37
|
+
filenames.each_with_index.map do |filename, index|
|
|
38
|
+
SCSSLint::Lint.new(nil, filename, locations[index],
|
|
39
|
+
descriptions[index], severities[index])
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it_should_behave_like 'parsed JSON'
|
|
44
|
+
|
|
45
|
+
it 'contains an <issue> node for each lint' do
|
|
46
|
+
json.values.inject(0) { |sum, issues| sum + issues.size }.should == 3
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'contains a group of issues for each file' do
|
|
50
|
+
json.keys.should == filenames.uniq
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'contains <issue> nodes grouped by <file>' do
|
|
54
|
+
json.values.map(&:size).should == [2, 1]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'marks each issue with a line number' do
|
|
58
|
+
json.values.flat_map { |issues| issues.map { |issue| issue['line'] } }
|
|
59
|
+
.should =~ locations.map(&:line)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'marks each issue with a column number' do
|
|
63
|
+
json.values.flat_map { |issues| issues.map { |issue| issue['column'] } }
|
|
64
|
+
.should =~ locations.map(&:column)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'marks each issue with a length' do
|
|
68
|
+
json.values.flat_map { |issues| issues.map { |issue| issue['length'] } }
|
|
69
|
+
.should =~ locations.map(&:length)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'marks each issue with a reason containing the lint description' do
|
|
73
|
+
json.values.flat_map { |issues| issues.map { |issue| issue['reason'] } }
|
|
74
|
+
.should =~ descriptions
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'when lints are warnings' do
|
|
78
|
+
it 'marks each issue with a severity of "warning"' do
|
|
79
|
+
json.values.inject(0) do |sum, issues|
|
|
80
|
+
sum + issues.select { |i| i['severity'] == 'warning' }.size
|
|
81
|
+
end.should == 3
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context 'when lints are errors' do
|
|
86
|
+
let(:severities) { [:error] * 3 }
|
|
87
|
+
|
|
88
|
+
it 'marks each issue with a severity of "error"' do
|
|
89
|
+
json.values.inject(0) do |sum, issues|
|
|
90
|
+
sum + issues.select { |i| i['severity'] == 'error' }.size
|
|
91
|
+
end.should == 3
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SCSSLint::Reporter::XMLReporter do
|
|
4
|
+
subject { SCSSLint::Reporter::XMLReporter.new(lints) }
|
|
5
|
+
|
|
6
|
+
describe '#report_lints' do
|
|
7
|
+
let(:xml) { Nokogiri::XML(subject.report_lints) }
|
|
8
|
+
|
|
9
|
+
shared_examples_for 'XML document' do
|
|
10
|
+
it 'has an encoding of UTF-8' do
|
|
11
|
+
xml.encoding.should == 'utf-8'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'has an XML version of 1.0' do
|
|
15
|
+
xml.version.should == '1.0'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'contains a <lint> root element' do
|
|
19
|
+
xml.root.name.should == 'lint'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'when there are no lints' do
|
|
24
|
+
let(:lints) { [] }
|
|
25
|
+
|
|
26
|
+
it_should_behave_like 'XML document'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'when there are lints' do
|
|
30
|
+
let(:filenames) { ['f1.scss', 'f2.scss', 'f1.scss'] }
|
|
31
|
+
# Include invalid XML characters in the third description to validate
|
|
32
|
+
# that escaping happens for preventing broken XML output
|
|
33
|
+
let(:descriptions) { ['lint 1', 'lint 2', 'lint 3 " \' < & >'] }
|
|
34
|
+
let(:severities) { [:warning] * 3 }
|
|
35
|
+
|
|
36
|
+
let(:locations) do
|
|
37
|
+
[
|
|
38
|
+
SCSSLint::Location.new(5, 2, 3),
|
|
39
|
+
SCSSLint::Location.new(7, 6, 2),
|
|
40
|
+
SCSSLint::Location.new(9, 10, 1)
|
|
41
|
+
]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
let(:lints) do
|
|
45
|
+
filenames.each_with_index.map do |filename, index|
|
|
46
|
+
SCSSLint::Lint.new(nil, filename, locations[index],
|
|
47
|
+
descriptions[index], severities[index])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it_should_behave_like 'XML document'
|
|
52
|
+
|
|
53
|
+
it 'contains an <issue> node for each lint' do
|
|
54
|
+
xml.xpath('//issue').count.should == 3
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'contains a <file> node for each file' do
|
|
58
|
+
xml.xpath('//file').map { |node| node[:name] }
|
|
59
|
+
.should =~ filenames.uniq
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'contains <issue> nodes grouped by <file>' do
|
|
63
|
+
xml.xpath('//file').map do |file_node|
|
|
64
|
+
file_node.xpath('./issue').count
|
|
65
|
+
end.should =~ [1, 2]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'marks each issue with a line number' do
|
|
69
|
+
xml.xpath('//issue[@line]').map { |node| node[:line] }
|
|
70
|
+
.should =~ locations.map { |location| location.line.to_s }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'marks each issue with a column number' do
|
|
74
|
+
xml.xpath('//issue[@column]').map { |node| node[:column] }
|
|
75
|
+
.should =~ locations.map { |location| location.column.to_s }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'marks each issue with a length' do
|
|
79
|
+
xml.xpath('//issue[@length]').map { |node| node[:length] }
|
|
80
|
+
.should =~ locations.map { |location| location.length.to_s }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'marks each issue with a reason containing the lint description' do
|
|
84
|
+
xml.xpath('//issue[@reason]').map { |node| node[:reason] }
|
|
85
|
+
.should =~ descriptions
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context 'when lints are warnings' do
|
|
89
|
+
it 'marks each issue with a severity of "warning"' do
|
|
90
|
+
xml.xpath("//issue[@severity='warning']").count == 3
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context 'when lints are errors' do
|
|
95
|
+
let(:severities) { [:error] * 3 }
|
|
96
|
+
|
|
97
|
+
it 'marks each issue with a severity of "error"' do
|
|
98
|
+
xml.xpath("//issue[@severity='error']").count == 3
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|