wool 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +23 -0
- data/LICENSE +45 -0
- data/README.rdoc +17 -0
- data/Rakefile +77 -0
- data/TODO.md +17 -0
- data/VERSION +1 -0
- data/bin/wool +4 -0
- data/features/step_definitions/wool_steps.rb +39 -0
- data/features/support/env.rb +14 -0
- data/features/support/testdata/1_input +1 -0
- data/features/support/testdata/1_output +1 -0
- data/features/support/testdata/2_input +4 -0
- data/features/support/testdata/2_output +4 -0
- data/features/support/testdata/3_input +8 -0
- data/features/support/testdata/3_output +11 -0
- data/features/support/testdata/4_input +5 -0
- data/features/support/testdata/4_output +5 -0
- data/features/wool.feature +24 -0
- data/lib/wool.rb +40 -0
- data/lib/wool/advice/advice.rb +42 -0
- data/lib/wool/advice/comment_advice.rb +37 -0
- data/lib/wool/analysis/annotations.rb +34 -0
- data/lib/wool/analysis/annotations/next_annotation.rb +26 -0
- data/lib/wool/analysis/annotations/parent_annotation.rb +20 -0
- data/lib/wool/analysis/annotations/scope_annotation.rb +37 -0
- data/lib/wool/analysis/lexical_analysis.rb +165 -0
- data/lib/wool/analysis/protocol_registry.rb +32 -0
- data/lib/wool/analysis/protocols.rb +82 -0
- data/lib/wool/analysis/scope.rb +13 -0
- data/lib/wool/analysis/sexp_analysis.rb +98 -0
- data/lib/wool/analysis/signature.rb +16 -0
- data/lib/wool/analysis/symbol.rb +10 -0
- data/lib/wool/analysis/visitor.rb +36 -0
- data/lib/wool/analysis/wool_class.rb +47 -0
- data/lib/wool/rake/task.rb +42 -0
- data/lib/wool/runner.rb +156 -0
- data/lib/wool/scanner.rb +160 -0
- data/lib/wool/support/module_extensions.rb +84 -0
- data/lib/wool/third_party/trollop.rb +845 -0
- data/lib/wool/warning.rb +145 -0
- data/lib/wool/warnings/comment_spacing.rb +30 -0
- data/lib/wool/warnings/extra_blank_lines.rb +29 -0
- data/lib/wool/warnings/extra_whitespace.rb +15 -0
- data/lib/wool/warnings/line_length.rb +113 -0
- data/lib/wool/warnings/misaligned_unindentation.rb +16 -0
- data/lib/wool/warnings/operator_spacing.rb +63 -0
- data/lib/wool/warnings/rescue_exception.rb +41 -0
- data/lib/wool/warnings/semicolon.rb +24 -0
- data/lib/wool/warnings/useless_double_quotes.rb +37 -0
- data/spec/advice_specs/advice_spec.rb +69 -0
- data/spec/advice_specs/comment_advice_spec.rb +38 -0
- data/spec/advice_specs/spec_helper.rb +1 -0
- data/spec/analysis_specs/annotations_specs/next_prev_annotation_spec.rb +47 -0
- data/spec/analysis_specs/annotations_specs/parent_annotation_spec.rb +41 -0
- data/spec/analysis_specs/annotations_specs/spec_helper.rb +5 -0
- data/spec/analysis_specs/lexical_analysis_spec.rb +179 -0
- data/spec/analysis_specs/protocol_registry_spec.rb +58 -0
- data/spec/analysis_specs/protocols_spec.rb +49 -0
- data/spec/analysis_specs/scope_spec.rb +20 -0
- data/spec/analysis_specs/sexp_analysis_spec.rb +134 -0
- data/spec/analysis_specs/spec_helper.rb +2 -0
- data/spec/analysis_specs/visitor_spec.rb +53 -0
- data/spec/analysis_specs/wool_class_spec.rb +54 -0
- data/spec/rake_specs/spec_helper.rb +1 -0
- data/spec/rake_specs/task_spec.rb +67 -0
- data/spec/runner_spec.rb +171 -0
- data/spec/scanner_spec.rb +75 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +93 -0
- data/spec/support_specs/module_extensions_spec.rb +91 -0
- data/spec/support_specs/spec_helper.rb +1 -0
- data/spec/warning_spec.rb +95 -0
- data/spec/warning_specs/comment_spacing_spec.rb +57 -0
- data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
- data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
- data/spec/warning_specs/line_length_spec.rb +165 -0
- data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
- data/spec/warning_specs/operator_spacing_spec.rb +101 -0
- data/spec/warning_specs/rescue_exception_spec.rb +105 -0
- data/spec/warning_specs/semicolon_spec.rb +58 -0
- data/spec/warning_specs/spec_helper.rb +1 -0
- data/spec/warning_specs/useless_double_quotes_spec.rb +62 -0
- data/spec/wool_spec.rb +8 -0
- data/status_reports/2010/12/2010-12-14.md +163 -0
- data/test/third_party_tests/test_trollop.rb +1181 -0
- data/wool.gemspec +173 -0
- metadata +235 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe InlineCommentSpaceWarning do
|
4
|
+
SETTINGS = {InlineCommentSpaceWarning::OPTION_KEY => 2, :indent_size => 2}
|
5
|
+
it 'is a line-based warning' do
|
6
|
+
InlineCommentSpaceWarning.new('(stdin)', 'hello').should be_a(LineWarning)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'matches when there are less than 2 spaces between code and comment' do
|
10
|
+
InlineCommentSpaceWarning.should warn('a + b#comment', SETTINGS)
|
11
|
+
InlineCommentSpaceWarning.should warn('a + b # comment', SETTINGS)
|
12
|
+
InlineCommentSpaceWarning.should_not warn('a + b # comment', SETTINGS)
|
13
|
+
InlineCommentSpaceWarning.should_not warn('a +b # wool: ignore OperatorSpacing', SETTINGS)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has an option to specify the necessary spacing' do
|
17
|
+
InlineCommentSpaceWarning.options.size.should be > 0
|
18
|
+
InlineCommentSpaceWarning.options[0].first.should ==
|
19
|
+
InlineCommentSpaceWarning::OPTION_KEY
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'respects the option for specifying the necessary spacing' do
|
23
|
+
settings = {InlineCommentSpaceWarning::OPTION_KEY => 0}
|
24
|
+
InlineCommentSpaceWarning.should warn('a + b # comment', settings)
|
25
|
+
InlineCommentSpaceWarning.should_not warn('a + b# comment', settings)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'has a remotely useful description' do
|
29
|
+
InlineCommentSpaceWarning.new('(stdin)', 'hello #').desc.should =~ /inline.*comment/i
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when fixing' do
|
33
|
+
before do
|
34
|
+
@settings = {InlineCommentSpaceWarning::OPTION_KEY => 2}
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
InlineCommentSpaceWarning.should correct_to(@input, @output, @settings)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'adds spaces when necessary' do
|
42
|
+
@input = 'a + b#comment'
|
43
|
+
@output = 'a + b #comment'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'removes spaces when necessary' do
|
47
|
+
@input = 'a + b #comment'
|
48
|
+
@output = 'a + b #comment'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'respects the option for spacing' do
|
52
|
+
@settings = {InlineCommentSpaceWarning::OPTION_KEY => 0}
|
53
|
+
@input = 'a + b #comment'
|
54
|
+
@output = 'a + b#comment'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe ExtraBlankLinesWarning do
|
4
|
+
it 'is a file-based warning' do
|
5
|
+
ExtraBlankLinesWarning.new('(stdin)', 'hello').should be_a(FileWarning)
|
6
|
+
FileWarning.all_warnings.should include(ExtraBlankLinesWarning)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'matches when there is a single empty blank line' do
|
10
|
+
ExtraBlankLinesWarning.should warn("a + b\n")
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'matches when there is a single blank line with spaces' do
|
14
|
+
ExtraBlankLinesWarning.should warn("a + b\n ")
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'matches when there is are multiple blank lines' do
|
18
|
+
ExtraBlankLinesWarning.should warn("a + b\n \n\t\n")
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'counts the number of blank lines' do
|
22
|
+
ExtraBlankLinesWarning.new('(stdin)', "a + b\n").count_extra_lines.should == 1
|
23
|
+
ExtraBlankLinesWarning.new('(stdin)', "a + b\n\t\n").count_extra_lines.should == 2
|
24
|
+
ExtraBlankLinesWarning.new('(stdin)', "a + b\n\n").count_extra_lines.should == 2
|
25
|
+
ExtraBlankLinesWarning.new('(stdin)', "a + b\n \n\n").count_extra_lines.should == 3
|
26
|
+
ExtraBlankLinesWarning.new('(stdin)', "a + b\n \n\t\n").count_extra_lines.should == 3
|
27
|
+
ExtraBlankLinesWarning.new('(stdin)', "a + b\n\n\n\n\n").count_extra_lines.should == 5
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'has a remotely useful description' do
|
31
|
+
ExtraBlankLinesWarning.new('(stdin)', 'hello ').desc.should =~ /blank line/
|
32
|
+
end
|
33
|
+
|
34
|
+
INPUTS = ["a + b\n\n\t \t\n\t ", "a + b\n \n\t\n", "a + b\n \n\n",
|
35
|
+
"a + b\n\n\n\n\n", "a + b\n", "a + b\n " ]
|
36
|
+
|
37
|
+
INPUTS.each do |input|
|
38
|
+
context "When fixing #{input.inspect}" do
|
39
|
+
it 'fixes by removing all extra whitespace' do
|
40
|
+
ExtraBlankLinesWarning.should correct_to(input, 'a + b')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when fixing a realistic multiline block' do
|
46
|
+
before do
|
47
|
+
@original = <<-EOF
|
48
|
+
# Warning for using semicolons outside of class declarations.
|
49
|
+
class SemicolonWarning < LineWarning
|
50
|
+
|
51
|
+
def initialize(file, line)
|
52
|
+
severity = line =~ /['"]/ ? 2 : 4
|
53
|
+
super('Semicolon for multiple statements', file, line, 0, severity)
|
54
|
+
end
|
55
|
+
|
56
|
+
def desc
|
57
|
+
'The line uses a semicolon to separate multiple statements outside of a class declaration.'
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
EOF
|
62
|
+
@original.strip!
|
63
|
+
@invalid = @original + "\n \t\t\n \n\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'only removes the trailing whitespace' do
|
67
|
+
ExtraBlankLinesWarning.should correct_to(@invalid, @original)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe ExtraWhitespaceWarning do
|
4
|
+
it 'is a line-based warning' do
|
5
|
+
ExtraWhitespaceWarning.new('(stdin)', 'hello').should be_a(LineWarning)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'matches when there are spaces at the end of a line' do
|
9
|
+
ExtraWhitespaceWarning.should warn('a + b ')
|
10
|
+
ExtraWhitespaceWarning.should warn('a + b ')
|
11
|
+
ExtraWhitespaceWarning.should_not warn('a + b')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'matches when there are tabs at the end of a line' do
|
15
|
+
ExtraWhitespaceWarning.should warn("a + b\t\t")
|
16
|
+
ExtraWhitespaceWarning.should warn("a + b\t")
|
17
|
+
ExtraWhitespaceWarning.should_not warn('a + b')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'has a remotely useful description' do
|
21
|
+
ExtraWhitespaceWarning.new('(stdin)', 'hello ').desc.should =~ /whitespace/
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when fixing' do
|
25
|
+
it 'fixes by removing extra spaces' do
|
26
|
+
ExtraWhitespaceWarning.should correct_to('a + b ', 'a + b')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'fixes by removing extra tabs' do
|
30
|
+
ExtraWhitespaceWarning.should correct_to("a + b\t\t", 'a + b')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe GenericLineLengthWarning do
|
4
|
+
before do
|
5
|
+
@eighty_cap = LineLengthCustomSeverity(80, 2)
|
6
|
+
@eighty_cap.line_length_limit = 80
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'is a line-based warning' do
|
10
|
+
GenericLineLengthWarning.new('(stdin)', 'hello').should be_a(LineWarning)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'initializes to a file and line' do
|
14
|
+
warning = @eighty_cap.new('(stdin)', 'x' * 81)
|
15
|
+
warning.severity.should == @eighty_cap.severity
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'has a remotely useful description' do
|
19
|
+
@eighty_cap.new('(stdin)', 'x' * 80).desc.should =~ /line length/i
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'matches lines longer than the specified number of characters' do
|
23
|
+
@eighty_cap.should warn('x' * 82)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not match lines shorter than the specified number of characters' do
|
27
|
+
@eighty_cap.should_not warn('x' * 78)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'does not match lines equal to the specified number of characters' do
|
31
|
+
@eighty_cap.should_not warn('x' * 80)
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when fixing' do
|
35
|
+
before do
|
36
|
+
@twenty_cap = Class.new(GenericLineLengthWarning)
|
37
|
+
@twenty_cap.line_length_limit = 20
|
38
|
+
@settings = {}
|
39
|
+
end
|
40
|
+
|
41
|
+
after do
|
42
|
+
@twenty_cap.should correct_to(@input, @output, @settings)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'takes a line with just a comment on it and breaks it into many lines' do
|
46
|
+
@input = '# my comment is this and that and another thing'
|
47
|
+
@output = "# my comment is this\n# and that and\n# another thing"
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'creates new lines with the same indentation as the input' do
|
51
|
+
@input = ' # my comment is this and that and another thing'
|
52
|
+
@output = " # my comment is\n # this and that\n # and another\n # thing"
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'uses the same number of hashes to denote the comment' do
|
56
|
+
@input = ' ## my comment is this and that and another thing'
|
57
|
+
@output = " ## my comment is\n ## this and that\n ## and another\n ## thing"
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'splits up code with an overly long comment at the end' do
|
61
|
+
@input = ' a + b # this is a stupidly long comment lol'
|
62
|
+
@output = " # this is a\n # stupidly long\n # comment lol\n a + b"
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'uses the same indentation and hashes for the new comment' do
|
66
|
+
@input = ' a + b ### this is a stupidly long comment lol'
|
67
|
+
@output = " ### this is a\n ### stupidly long\n ### comment lol\n a + b"
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'fails to fix when if/unless are in a symbol' do
|
71
|
+
# This came from an actual bug from running wool on wool's source.
|
72
|
+
@input = " left, right = @class.new('').split_on_keyword('x = 5 unless y == 2', :unless)"
|
73
|
+
@output = @input
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with an indent size of 2' do
|
77
|
+
before { @settings = {:indent_size => 2} }
|
78
|
+
it "doesn't try to convert the 'end if foobar' technique" do
|
79
|
+
@input = ' end if should_run_block?'
|
80
|
+
@output = ' end if should_run_block?'
|
81
|
+
end
|
82
|
+
|
83
|
+
it "doesn't try to convert the 'end unless foobar' technique" do
|
84
|
+
@input = ' end unless should_run_block?'
|
85
|
+
@output = ' end unless should_run_block?'
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'converts lines with guarded ifs into 3 liners' do
|
89
|
+
@input = 'puts x if x > y && y.call'
|
90
|
+
@output = "if x > y && y.call\n puts x\nend"
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'converts lines with guarded unlesses into 3 liners' do
|
94
|
+
@input = 'puts x unless x > number'
|
95
|
+
@output = "unless x > number\n puts x\nend"
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'converts lines with guarded ifs while maintaining indentation' do
|
99
|
+
@input = ' puts x unless x > number'
|
100
|
+
@output = " unless x > number\n puts x\n end"
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'only converts when it finds a guard on the top level expression' do
|
104
|
+
@input = %Q[syms.each { |sym| raise ArgumentError, "unknown option '\#{sym}'" unless @specs[sym] }]
|
105
|
+
@output = %Q[syms.each { |sym| raise ArgumentError, "unknown option '\#{sym}'" unless @specs[sym] }]
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'only converts when it finds a guard on the real-world top level expression' do
|
109
|
+
@input = 'x.select { |x| x if 5 }'
|
110
|
+
@output = 'x.select { |x| x if 5 }'
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'converts nested if/unless as guards' do
|
114
|
+
@input = 'puts x if foo.bar unless baz.boo'
|
115
|
+
@output = "unless baz.boo\n if foo.bar\n puts x\n end\nend"
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'converts nested three if/unless as guards' do
|
119
|
+
@input = 'puts x if foo.bar unless baz.boo if alpha.beta'
|
120
|
+
@output = "if alpha.beta\n unless baz.boo\n if foo.bar\n puts x\n end\n end\nend"
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'converts nested three if/unless as guards maintaining indentation' do
|
124
|
+
@input = ' puts x if foo.bar unless baz.boo if alpha.beta'
|
125
|
+
@output = " if alpha.beta\n unless baz.boo\n if foo.bar\n puts x\n end\n end\n end"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe 'LineLengthMaximum' do
|
132
|
+
before do
|
133
|
+
@hundred_cap = LineLengthMaximum(100)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'matches lines longer than the specified maximum' do
|
137
|
+
@hundred_cap.should warn('x' * 101)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'has a high severity' do
|
141
|
+
@hundred_cap.severity.should >= 7.5
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'does not match lines smaller than the specified maximum' do
|
145
|
+
@hundred_cap.should_not warn('x' * 100)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'LineLengthWarning' do
|
150
|
+
before do
|
151
|
+
@hundred_cap = LineLengthWarning(80)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'matches lines longer than the specified maximum' do
|
155
|
+
@hundred_cap.should warn('x' * 81)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'has a lower severity' do
|
159
|
+
@hundred_cap.severity.should <= 4
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'does not match lines smaller than the specified maximum' do
|
163
|
+
@hundred_cap.should_not warn('x' * 80)
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe MisalignedUnindentationWarning do
|
4
|
+
context 'when fixing' do
|
5
|
+
it 'is a line-based warning' do
|
6
|
+
MisalignedUnindentationWarning.new('(stdin)', 'hello', 80).should be_a(LineWarning)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'matches nothing' do
|
10
|
+
MisalignedUnindentationWarning.should_not warn(' a + b', 2)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'fixes by removing more spaces than expected' do
|
14
|
+
MisalignedUnindentationWarning.should correct_to(' a + b', ' a + b', 2)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'fixes by adding a second space' do
|
18
|
+
MisalignedUnindentationWarning.should correct_to(' a + b', ' a + b', 2)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'fixes by adding indentation' do
|
22
|
+
MisalignedUnindentationWarning.should correct_to('a + b', ' a + b', 4)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'describes the incorrect indentation values' do
|
26
|
+
warning = MisalignedUnindentationWarning.new('(stdin)', ' a + b', 2)
|
27
|
+
other_warning = MisalignedUnindentationWarning.new('(stdin)', ' a + b', 2)
|
28
|
+
warning_3 = MisalignedUnindentationWarning.new('(stdin)', 'a + b', 4)
|
29
|
+
warning.desc.should =~ /Expected 2/
|
30
|
+
warning.desc.should =~ /found 3/
|
31
|
+
other_warning.desc.should =~ /Expected 2/
|
32
|
+
other_warning.desc.should =~ /found 1/
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe OperatorSpacing do
|
4
|
+
it 'is a line-based warning' do
|
5
|
+
OperatorSpacing.new('(stdin)', 'hello').should be_a(LineWarning)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "doesn't match block declarations" do
|
9
|
+
OperatorSpacing.should_not warn('[1, 2].each { |x| p x }')
|
10
|
+
OperatorSpacing.should_not warn('[1, 2].each {| y | p x }')
|
11
|
+
OperatorSpacing.should_not warn("[1, 2].each do |x|\n p x\nend")
|
12
|
+
OperatorSpacing.should_not warn("[1, 2].each do|x|\n p x\nend")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "doesn't match in a comment" do
|
16
|
+
OperatorSpacing.should_not warn('hello # a+b')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "doesn't match a <<- heredoc" do
|
20
|
+
OperatorSpacing.should_not warn('@original = <<-EOF')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "doesn't match a << heredoc" do
|
24
|
+
OperatorSpacing.should_not warn('@original = <<EOF')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "doesn't match adjacent negative numbers" do
|
28
|
+
OperatorSpacing.should_not warn(' exit(-1)')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "doesn't match *args in block parameters" do
|
32
|
+
OperatorSpacing.should_not warn('list.each do |*args|')
|
33
|
+
OperatorSpacing.should_not warn('list.each { |*args| }')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "doesn't match splat arguments" do
|
37
|
+
OperatorSpacing.should_not warn('x.call(*args)')
|
38
|
+
OperatorSpacing.should_not warn('x.call(a, *args)')
|
39
|
+
OperatorSpacing.should_not warn('x.call(*args, b)')
|
40
|
+
OperatorSpacing.should_not warn('x.call(a, *args, b)')
|
41
|
+
end
|
42
|
+
|
43
|
+
it "does match multiplication in an argument list" do
|
44
|
+
OperatorSpacing.should warn('x.call(a *b)')
|
45
|
+
OperatorSpacing.should warn('x.call(x, a *b)')
|
46
|
+
OperatorSpacing.should warn('x.call(a *b, z)')
|
47
|
+
end
|
48
|
+
|
49
|
+
it "doesn't match block arguments" do
|
50
|
+
OperatorSpacing.should_not warn('x.call(&b)')
|
51
|
+
OperatorSpacing.should_not warn('x.call(a, &b)')
|
52
|
+
OperatorSpacing.should_not warn('x.call(&b, b)')
|
53
|
+
OperatorSpacing.should_not warn('x.call(a, &b, b)')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "doesn't match the [*item] idiom" do
|
57
|
+
OperatorSpacing.should_not warn('[*args]')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'has a reasonable description' do
|
61
|
+
OperatorSpacing.new('(stdin)', 'a+ b').desc.should =~ /spacing/
|
62
|
+
end
|
63
|
+
|
64
|
+
OperatorSpacing::OPERATORS.each do |operator|
|
65
|
+
context "with #{operator}" do
|
66
|
+
it "matches when there is no space on the left side" do
|
67
|
+
OperatorSpacing.should warn("a#{operator} b")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "matches when there is no space on the right side" do
|
71
|
+
OperatorSpacing.should warn("a #{operator}b")
|
72
|
+
end unless operator == '/' # This confuses the shit out of the lexer
|
73
|
+
|
74
|
+
it "matches when there is no space on both sides" do
|
75
|
+
OperatorSpacing.should warn("a#{operator}b")
|
76
|
+
end
|
77
|
+
|
78
|
+
it "doesn't match when there is exactly one space on both sides" do
|
79
|
+
OperatorSpacing.should_not warn("a #{operator} b")
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when fixing' do
|
83
|
+
it 'changes nothing when there is one space on both sides' do
|
84
|
+
OperatorSpacing.should correct_to("a #{operator} b", "a #{operator} b")
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'fixes by inserting an extra space on the left' do
|
88
|
+
OperatorSpacing.should correct_to("a#{operator} b", "a #{operator} b")
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'fixes by inserting an extra space on the right' do
|
92
|
+
OperatorSpacing.should correct_to("a #{operator}b", "a #{operator} b")
|
93
|
+
end unless operator == '/' # This confuses the shit out of the lexer
|
94
|
+
|
95
|
+
it 'fixes by inserting an extra space on both sides' do
|
96
|
+
OperatorSpacing.should correct_to("a#{operator}b", "a #{operator} b")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|