simplabs-excellent 1.0.1 → 1.2.1

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 (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