simplabs-excellent 1.0.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/History.txt +19 -0
  2. data/README.rdoc +34 -0
  3. data/VERSION.yml +1 -1
  4. data/bin/excellent +21 -6
  5. data/lib/simplabs/excellent.rb +7 -5
  6. data/lib/simplabs/excellent/checks.rb +18 -1
  7. data/lib/simplabs/excellent/checks/abc_metric_method_check.rb +19 -56
  8. data/lib/simplabs/excellent/checks/assignment_in_conditional_check.rb +16 -16
  9. data/lib/simplabs/excellent/checks/base.rb +30 -21
  10. data/lib/simplabs/excellent/checks/case_missing_else_check.rb +13 -5
  11. data/lib/simplabs/excellent/checks/class_line_count_check.rb +10 -8
  12. data/lib/simplabs/excellent/checks/class_name_check.rb +11 -10
  13. data/lib/simplabs/excellent/checks/control_coupling_check.rb +13 -10
  14. data/lib/simplabs/excellent/checks/cyclomatic_complexity_block_check.rb +25 -9
  15. data/lib/simplabs/excellent/checks/cyclomatic_complexity_check.rb +4 -20
  16. data/lib/simplabs/excellent/checks/cyclomatic_complexity_method_check.rb +25 -10
  17. data/lib/simplabs/excellent/checks/duplication_check.rb +50 -0
  18. data/lib/simplabs/excellent/checks/empty_rescue_body_check.rb +10 -18
  19. data/lib/simplabs/excellent/checks/flog_block_check.rb +40 -0
  20. data/lib/simplabs/excellent/checks/flog_check.rb +27 -0
  21. data/lib/simplabs/excellent/checks/flog_class_check.rb +40 -0
  22. data/lib/simplabs/excellent/checks/flog_method_check.rb +40 -0
  23. data/lib/simplabs/excellent/checks/for_loop_check.rb +20 -4
  24. data/lib/simplabs/excellent/checks/line_count_check.rb +3 -21
  25. data/lib/simplabs/excellent/checks/method_line_count_check.rb +9 -7
  26. data/lib/simplabs/excellent/checks/method_name_check.rb +13 -9
  27. data/lib/simplabs/excellent/checks/module_line_count_check.rb +9 -7
  28. data/lib/simplabs/excellent/checks/module_name_check.rb +11 -7
  29. data/lib/simplabs/excellent/checks/name_check.rb +3 -8
  30. data/lib/simplabs/excellent/checks/nested_iterators_check.rb +33 -0
  31. data/lib/simplabs/excellent/checks/parameter_number_check.rb +13 -12
  32. data/lib/simplabs/excellent/checks/rails.rb +17 -0
  33. data/lib/simplabs/excellent/checks/rails/attr_accessible_check.rb +38 -0
  34. data/lib/simplabs/excellent/checks/rails/attr_protected_check.rb +39 -0
  35. data/lib/simplabs/excellent/checks/singleton_variable_check.rb +32 -0
  36. data/lib/simplabs/excellent/extensions/sexp.rb +21 -0
  37. data/lib/simplabs/excellent/extensions/string.rb +23 -0
  38. data/lib/simplabs/excellent/parsing.rb +12 -0
  39. data/lib/simplabs/excellent/parsing/abc_measure.rb +52 -0
  40. data/lib/simplabs/excellent/parsing/block_context.rb +43 -0
  41. data/lib/simplabs/excellent/parsing/call_context.rb +36 -0
  42. data/lib/simplabs/excellent/parsing/case_context.rb +31 -0
  43. data/lib/simplabs/excellent/parsing/class_context.rb +68 -0
  44. data/lib/simplabs/excellent/parsing/code_processor.rb +154 -0
  45. data/lib/simplabs/excellent/parsing/conditional_context.rb +25 -0
  46. data/lib/simplabs/excellent/parsing/cvar_context.rb +28 -0
  47. data/lib/simplabs/excellent/parsing/cyclomatic_complexity_measure.rb +73 -0
  48. data/lib/simplabs/excellent/parsing/flog_measure.rb +192 -0
  49. data/lib/simplabs/excellent/parsing/for_loop_context.rb +15 -0
  50. data/lib/simplabs/excellent/parsing/if_context.rb +38 -0
  51. data/lib/simplabs/excellent/parsing/method_context.rb +50 -0
  52. data/lib/simplabs/excellent/parsing/module_context.rb +29 -0
  53. data/lib/simplabs/excellent/{core → parsing}/parser.rb +4 -2
  54. data/lib/simplabs/excellent/parsing/resbody_context.rb +39 -0
  55. data/lib/simplabs/excellent/parsing/scopeable.rb +34 -0
  56. data/lib/simplabs/excellent/parsing/sexp_context.rb +125 -0
  57. data/lib/simplabs/excellent/parsing/singleton_method_context.rb +55 -0
  58. data/lib/simplabs/excellent/parsing/until_context.rb +24 -0
  59. data/lib/simplabs/excellent/parsing/while_context.rb +24 -0
  60. data/lib/simplabs/excellent/runner.rb +105 -0
  61. data/lib/simplabs/excellent/warning.rb +53 -0
  62. data/spec/checks/abc_metric_method_check_spec.rb +36 -8
  63. data/spec/checks/assignment_in_conditional_check_spec.rb +31 -14
  64. data/spec/checks/case_missing_else_check_spec.rb +8 -8
  65. data/spec/checks/class_line_count_check_spec.rb +24 -11
  66. data/spec/checks/class_name_check_spec.rb +9 -9
  67. data/spec/checks/control_coupling_check_spec.rb +84 -13
  68. data/spec/checks/cyclomatic_complexity_block_check_spec.rb +13 -17
  69. data/spec/checks/cyclomatic_complexity_method_check_spec.rb +32 -6
  70. data/spec/checks/duplication_check_spec.rb +139 -0
  71. data/spec/checks/empty_rescue_body_check_spec.rb +54 -16
  72. data/spec/checks/flog_block_check_spec.rb +28 -0
  73. data/spec/checks/flog_class_check_spec.rb +28 -0
  74. data/spec/checks/flog_method_check_spec.rb +46 -0
  75. data/spec/checks/for_loop_check_spec.rb +11 -11
  76. data/spec/checks/method_line_count_check_spec.rb +11 -12
  77. data/spec/checks/method_name_check_spec.rb +34 -13
  78. data/spec/checks/module_line_count_check_spec.rb +11 -12
  79. data/spec/checks/module_name_check_spec.rb +31 -7
  80. data/spec/checks/nested_iterators_check_spec.rb +44 -0
  81. data/spec/checks/parameter_number_check_spec.rb +48 -12
  82. data/spec/checks/rails/attr_accessible_check_spec.rb +79 -0
  83. data/spec/checks/rails/attr_protected_check_spec.rb +77 -0
  84. data/spec/checks/singleton_variable_check_spec.rb +66 -0
  85. data/spec/{core/extensions/underscore_spec.rb → extensions/string_spec.rb} +1 -1
  86. metadata +58 -15
  87. data/README.markdown +0 -30
  88. data/lib/simplabs/excellent/checks/class_variable_check.rb +0 -25
  89. data/lib/simplabs/excellent/core.rb +0 -2
  90. data/lib/simplabs/excellent/core/checking_visitor.rb +0 -34
  91. data/lib/simplabs/excellent/core/error.rb +0 -31
  92. data/lib/simplabs/excellent/core/extensions/underscore.rb +0 -27
  93. data/lib/simplabs/excellent/core/iterator_visitor.rb +0 -29
  94. data/lib/simplabs/excellent/core/parse_tree_runner.rb +0 -88
  95. data/lib/simplabs/excellent/core/visitable_sexp.rb +0 -31
  96. data/spec/checks/class_variable_check_spec.rb +0 -26
@@ -0,0 +1,139 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::DuplicationCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::DuplicationCheck.new({ :threshold => 1 }))
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should accept multiple calls to new' do
12
+ content = <<-END
13
+ def double_thing
14
+ @thing.new + @thing.new
15
+ end
16
+ END
17
+ @excellent.check_content(content)
18
+ warnings = @excellent.warnings
19
+
20
+ warnings.should be_empty
21
+ end
22
+
23
+ it 'should reject multiple calls to the same method and receiver' do
24
+ content = <<-END
25
+ def double_thing
26
+ @other.thing + @other.thing
27
+ end
28
+ END
29
+
30
+ verify_warning_found(content, '@other.thing')
31
+ end
32
+
33
+ it 'should reject multiple calls to the same lvar' do
34
+ content = <<-END
35
+ def double_thing
36
+ thing[1] + thing[2]
37
+ end
38
+ END
39
+
40
+ verify_warning_found(content, 'thing.[]')
41
+ end
42
+
43
+ it 'should reject multiple calls to the same singleton method' do
44
+ content = <<-END
45
+ def double_thing
46
+ Class.thing[1] + Class.thing[2]
47
+ end
48
+ END
49
+
50
+ verify_warning_found(content, 'Class.thing')
51
+ end
52
+
53
+ it 'should reject multiple calls to the same method without a receiver' do
54
+ content = <<-END
55
+ def double_thing
56
+ thing + thing
57
+ end
58
+ END
59
+
60
+ verify_warning_found(content, 'thing')
61
+ end
62
+
63
+ it 'should reject multiple calls to the same method with the same parameters' do
64
+ content = <<-END
65
+ def double_thing
66
+ thing(1) + thing(1)
67
+ end
68
+ END
69
+
70
+ verify_warning_found(content, 'thing')
71
+ end
72
+
73
+ it 'should reject multiple calls to the same method with different parameters' do
74
+ content = <<-END
75
+ def double_thing
76
+ thing(1) + thing(2)
77
+ end
78
+ END
79
+
80
+ verify_warning_found(content, 'thing')
81
+ end
82
+
83
+ it 'should work with singleton methods on objects' do
84
+ content = <<-END
85
+ def object.double_thing
86
+ thing(1) + thing(2)
87
+ end
88
+ END
89
+
90
+ verify_warning_found(content, 'thing', 'object.double_thing')
91
+ end
92
+
93
+ it 'should work with singleton methods on classes' do
94
+ content = <<-END
95
+ def Class.double_thing
96
+ thing(1) + thing(2)
97
+ end
98
+ END
99
+
100
+ verify_warning_found(content, 'thing', 'Class.double_thing')
101
+ end
102
+
103
+ it 'should work with singleton methods on classes' do
104
+ content = <<-END
105
+ class Class
106
+ def self.double_thing
107
+ thing(1) + thing(2)
108
+ end
109
+ end
110
+ END
111
+
112
+ verify_warning_found(content, 'thing', 'Class.double_thing', 2)
113
+ end
114
+
115
+ it 'should also work with blocks' do
116
+ content = <<-END
117
+ def method
118
+ double_thing do
119
+ thing(1) + thing(2)
120
+ end
121
+ end
122
+ END
123
+
124
+ verify_warning_found(content, 'thing', 'block', 2)
125
+ end
126
+
127
+ end
128
+
129
+ def verify_warning_found(content, statement, method = 'double_thing', line = 1)
130
+ @excellent.check_content(content)
131
+ warnings = @excellent.warnings
132
+
133
+ warnings.should_not be_empty
134
+ warnings[0].info.should == { :method => method, :statement => statement, :duplication_number => 2 }
135
+ warnings[0].line_number.should == line
136
+ warnings[0].message.should == "#{method} calls #{statement} 2 times."
137
+ end
138
+
139
+ end
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
4
4
 
5
5
  before do
6
- @excellent = Simplabs::Excellent::Core::ParseTreeRunner.new(Simplabs::Excellent::Checks::EmptyRescueBodyCheck.new)
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::EmptyRescueBodyCheck.new)
7
7
  end
8
8
 
9
9
  describe '#evaluate' do
@@ -18,7 +18,7 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
18
18
  END
19
19
  @excellent.check_content(content)
20
20
 
21
- @excellent.errors.should be_empty
21
+ @excellent.warnings.should be_empty
22
22
  end
23
23
 
24
24
  it 'should accept a rescue body with a return' do
@@ -31,7 +31,7 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
31
31
  END
32
32
  @excellent.check_content(content)
33
33
 
34
- @excellent.errors.should be_empty
34
+ @excellent.warnings.should be_empty
35
35
  end
36
36
 
37
37
  it "should accept a virtual method call" do
@@ -44,7 +44,7 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
44
44
  END
45
45
  @excellent.check_content(content)
46
46
 
47
- @excellent.errors.should be_empty
47
+ @excellent.warnings.should be_empty
48
48
  end
49
49
 
50
50
  it 'should accept a rescue body with content and a parameter' do
@@ -57,7 +57,7 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
57
57
  END
58
58
  @excellent.check_content(content)
59
59
 
60
- @excellent.errors.should be_empty
60
+ @excellent.warnings.should be_empty
61
61
  end
62
62
 
63
63
  it 'should accept a rescue body with an assignment' do
@@ -70,7 +70,7 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
70
70
  END
71
71
  @excellent.check_content(content)
72
72
 
73
- @excellent.errors.should be_empty
73
+ @excellent.warnings.should be_empty
74
74
  end
75
75
 
76
76
  it 'should accept a rescue body with an attribute assignment' do
@@ -83,7 +83,7 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
83
83
  END
84
84
  @excellent.check_content(content)
85
85
 
86
- @excellent.errors.should be_empty
86
+ @excellent.warnings.should be_empty
87
87
  end
88
88
 
89
89
  it 'should accept an inline rescue statement' do
@@ -92,7 +92,45 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
92
92
  END
93
93
  @excellent.check_content(content)
94
94
 
95
- @excellent.errors.should be_empty
95
+ @excellent.warnings.should be_empty
96
+ end
97
+
98
+ it 'should accept an empty array as a statement' do
99
+ content = <<-END
100
+ value = call_method rescue []
101
+ END
102
+
103
+ @excellent.check_content(content)
104
+
105
+ @excellent.warnings.should be_empty
106
+ end
107
+
108
+ it 'should accept an empty hash as a statement' do
109
+ content = <<-END
110
+ value = call_method rescue {}
111
+ END
112
+
113
+ @excellent.check_content(content)
114
+
115
+ @excellent.warnings.should be_empty
116
+ end
117
+
118
+ it 'should accept a boolean as a statement' do
119
+ content = <<-END
120
+ value = call_method rescue false
121
+ END
122
+ @excellent.check_content(content)
123
+
124
+ @excellent.warnings.should be_empty
125
+ end
126
+
127
+ it 'should accept nil as a statement' do
128
+ content = <<-END
129
+ value = call_method rescue nil
130
+ END
131
+ @excellent.check_content(content)
132
+
133
+ @excellent.warnings.should be_empty
96
134
  end
97
135
 
98
136
  it 'should reject an empty rescue block with no parameter' do
@@ -103,7 +141,7 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
103
141
  end
104
142
  END
105
143
 
106
- verify_error_found(content)
144
+ verify_warning_found(content)
107
145
  end
108
146
 
109
147
  it 'should reject an empty rescue block with a parameter' do
@@ -114,19 +152,19 @@ describe Simplabs::Excellent::Checks::EmptyRescueBodyCheck do
114
152
  end
115
153
  END
116
154
 
117
- verify_error_found(content)
155
+ verify_warning_found(content)
118
156
  end
119
157
 
120
158
  end
121
159
 
122
- def verify_error_found(content)
160
+ def verify_warning_found(content)
123
161
  @excellent.check_content(content)
124
- errors = @excellent.errors
162
+ warnings = @excellent.warnings
125
163
 
126
- errors.should_not be_empty
127
- errors[0].info.should == {}
128
- errors[0].line_number.should == 3
129
- errors[0].message.should == 'Rescue block is empty.'
164
+ warnings.should_not be_empty
165
+ warnings[0].info.should == {}
166
+ warnings[0].line_number.should == 3
167
+ warnings[0].message.should == 'Rescue block is empty.'
130
168
  end
131
169
 
132
170
  end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::FlogBlockCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::FlogBlockCheck.new({ :threshold => 0 }))
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should calculate the score correctly' do
12
+ content = <<-END
13
+ method_name do
14
+ puts 'test'
15
+ end
16
+ END
17
+ @excellent.check_content(content)
18
+ warnings = @excellent.warnings
19
+
20
+ warnings.should_not be_empty
21
+ warnings[0].info.should == { :block => 'block', :score => 3 }
22
+ warnings[0].line_number.should == 1
23
+ warnings[0].message.should == "block has flog score of 3."
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::FlogClassCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::FlogClassCheck.new({ :threshold => 0 }))
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should calculate the score correctly' do
12
+ content = <<-END
13
+ class User < ActiveRecord::Base
14
+ has_many :projects
15
+ end
16
+ END
17
+ @excellent.check_content(content)
18
+ warnings = @excellent.warnings
19
+
20
+ warnings.should_not be_empty
21
+ warnings[0].info.should == { :class => 'User', :score => 1 }
22
+ warnings[0].line_number.should == 1
23
+ warnings[0].message.should == "User has flog score of 1."
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::FlogMethodCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::FlogMethodCheck.new({ :threshold => 0 }))
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should calculate the score correctly' do
12
+ content = <<-END
13
+ def method_name
14
+ puts 'test'
15
+ end
16
+ END
17
+
18
+ verify_content_score(content, 1)
19
+ end
20
+
21
+ it 'should calculate the score that uses special metaprogramming methods correctly' do
22
+ content = <<-END
23
+ def method_name
24
+ @instance.instance_eval do
25
+ def some_method
26
+ end
27
+ end
28
+ end
29
+ END
30
+
31
+ verify_content_score(content, 6)
32
+ end
33
+
34
+ end
35
+
36
+ def verify_content_score(content, score)
37
+ @excellent.check_content(content)
38
+ warnings = @excellent.warnings
39
+
40
+ warnings.should_not be_empty
41
+ warnings[0].info.should == { :method => 'method_name', :score => score }
42
+ warnings[0].line_number.should == 1
43
+ warnings[0].message.should == "method_name has flog score of #{score}."
44
+ end
45
+
46
+ end
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  describe Simplabs::Excellent::Checks::ForLoopCheck do
4
4
 
5
5
  before do
6
- @excellent = Simplabs::Excellent::Core::ParseTreeRunner.new(Simplabs::Excellent::Checks::ForLoopCheck.new)
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::ForLoopCheck.new)
7
7
  end
8
8
 
9
9
  describe '#evaluate' do
@@ -14,9 +14,9 @@ describe Simplabs::Excellent::Checks::ForLoopCheck do
14
14
  end
15
15
  END
16
16
  @excellent.check_content(content)
17
- errors = @excellent.errors
17
+ warnings = @excellent.warnings
18
18
 
19
- errors.should be_empty
19
+ warnings.should be_empty
20
20
  end
21
21
 
22
22
  it 'should reject for loops on ranges' do
@@ -25,7 +25,7 @@ describe Simplabs::Excellent::Checks::ForLoopCheck do
25
25
  end
26
26
  END
27
27
 
28
- verify_error_found(content)
28
+ verify_warning_found(content)
29
29
  end
30
30
 
31
31
  it 'should reject for loops on enumerations' do
@@ -34,19 +34,19 @@ describe Simplabs::Excellent::Checks::ForLoopCheck do
34
34
  end
35
35
  END
36
36
 
37
- verify_error_found(content)
37
+ verify_warning_found(content)
38
38
  end
39
39
 
40
40
  end
41
41
 
42
- def verify_error_found(content)
42
+ def verify_warning_found(content)
43
43
  @excellent.check_content(content)
44
- errors = @excellent.errors
44
+ warnings = @excellent.warnings
45
45
 
46
- errors.should_not be_empty
47
- errors[0].info.should == {}
48
- errors[0].line_number.should == 1
49
- errors[0].message.should == 'For loop used.'
46
+ warnings.should_not be_empty
47
+ warnings[0].info.should == {}
48
+ warnings[0].line_number.should == 1
49
+ warnings[0].message.should == 'For loop used.'
50
50
  end
51
51
 
52
52
  end
@@ -3,46 +3,45 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  describe Simplabs::Excellent::Checks::MethodLineCountCheck do
4
4
 
5
5
  before do
6
- @excellent = Simplabs::Excellent::Core::ParseTreeRunner.new(Simplabs::Excellent::Checks::MethodLineCountCheck.new({ :threshold => 1 }))
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::MethodLineCountCheck.new({ :threshold => 2 }))
7
7
  end
8
8
 
9
9
  describe '#evaluate' do
10
10
 
11
11
  it 'should accept methods with less lines than the threshold' do
12
12
  content = <<-END
13
- def zero_line_method
13
+ def one_line_method
14
14
  end
15
15
  END
16
16
  @excellent.check_content(content)
17
17
 
18
- @excellent.errors.should be_empty
18
+ @excellent.warnings.should be_empty
19
19
  end
20
20
 
21
21
  it 'should accept methods with the same number of lines as the threshold' do
22
22
  content = <<-END
23
- def one_line_method
24
- 1
23
+ def two_line_method
25
24
  end
26
25
  END
27
26
  @excellent.check_content(content)
28
27
 
29
- @excellent.errors.should be_empty
28
+ @excellent.warnings.should be_empty
30
29
  end
31
30
 
32
31
  it 'should reject methods with more lines than the threshold' do
33
32
  content = <<-END
34
- def two_line_method
33
+ def four_line_method
35
34
  puts 1
36
35
  puts 2
37
36
  end
38
37
  END
39
38
  @excellent.check_content(content)
40
- errors = @excellent.errors
39
+ warnings = @excellent.warnings
41
40
 
42
- errors.should_not be_empty
43
- errors[0].info.should == { :method => :two_line_method, :count => 2 }
44
- errors[0].line_number.should == 1
45
- errors[0].message.should == 'Method two_line_method has 2 lines.'
41
+ warnings.should_not be_empty
42
+ warnings[0].info.should == { :method => 'four_line_method', :count => 4 }
43
+ warnings[0].line_number.should == 1
44
+ warnings[0].message.should == 'four_line_method has 4 lines.'
46
45
  end
47
46
 
48
47
  end