excellent 1.5.4

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 (106) hide show
  1. data/History.txt +69 -0
  2. data/README.rdoc +72 -0
  3. data/VERSION.yml +4 -0
  4. data/bin/excellent +34 -0
  5. data/lib/simplabs/excellent.rb +16 -0
  6. data/lib/simplabs/excellent/checks.rb +33 -0
  7. data/lib/simplabs/excellent/checks/abc_metric_method_check.rb +43 -0
  8. data/lib/simplabs/excellent/checks/assignment_in_conditional_check.rb +39 -0
  9. data/lib/simplabs/excellent/checks/base.rb +62 -0
  10. data/lib/simplabs/excellent/checks/case_missing_else_check.rb +34 -0
  11. data/lib/simplabs/excellent/checks/class_line_count_check.rb +36 -0
  12. data/lib/simplabs/excellent/checks/class_name_check.rb +38 -0
  13. data/lib/simplabs/excellent/checks/control_coupling_check.rb +35 -0
  14. data/lib/simplabs/excellent/checks/cyclomatic_complexity_block_check.rb +48 -0
  15. data/lib/simplabs/excellent/checks/cyclomatic_complexity_check.rb +23 -0
  16. data/lib/simplabs/excellent/checks/cyclomatic_complexity_method_check.rb +48 -0
  17. data/lib/simplabs/excellent/checks/empty_rescue_body_check.rb +31 -0
  18. data/lib/simplabs/excellent/checks/flog_block_check.rb +40 -0
  19. data/lib/simplabs/excellent/checks/flog_check.rb +27 -0
  20. data/lib/simplabs/excellent/checks/flog_class_check.rb +40 -0
  21. data/lib/simplabs/excellent/checks/flog_method_check.rb +40 -0
  22. data/lib/simplabs/excellent/checks/for_loop_check.rb +42 -0
  23. data/lib/simplabs/excellent/checks/global_variable_check.rb +33 -0
  24. data/lib/simplabs/excellent/checks/line_count_check.rb +27 -0
  25. data/lib/simplabs/excellent/checks/method_line_count_check.rb +36 -0
  26. data/lib/simplabs/excellent/checks/method_name_check.rb +38 -0
  27. data/lib/simplabs/excellent/checks/module_line_count_check.rb +36 -0
  28. data/lib/simplabs/excellent/checks/module_name_check.rb +38 -0
  29. data/lib/simplabs/excellent/checks/name_check.rb +27 -0
  30. data/lib/simplabs/excellent/checks/nested_iterators_check.rb +34 -0
  31. data/lib/simplabs/excellent/checks/parameter_number_check.rb +38 -0
  32. data/lib/simplabs/excellent/checks/rails.rb +22 -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/rails/custom_initialize_method_check.rb +37 -0
  36. data/lib/simplabs/excellent/checks/rails/instance_var_in_partial_check.rb +37 -0
  37. data/lib/simplabs/excellent/checks/rails/params_hash_in_view_check.rb +38 -0
  38. data/lib/simplabs/excellent/checks/rails/session_hash_in_view_check.rb +38 -0
  39. data/lib/simplabs/excellent/checks/rails/validations_check.rb +36 -0
  40. data/lib/simplabs/excellent/checks/singleton_variable_check.rb +33 -0
  41. data/lib/simplabs/excellent/command_line_runner.rb +37 -0
  42. data/lib/simplabs/excellent/extensions/sexp.rb +21 -0
  43. data/lib/simplabs/excellent/extensions/string.rb +28 -0
  44. data/lib/simplabs/excellent/formatters.rb +13 -0
  45. data/lib/simplabs/excellent/formatters/base.rb +49 -0
  46. data/lib/simplabs/excellent/formatters/html.rb +153 -0
  47. data/lib/simplabs/excellent/formatters/text.rb +40 -0
  48. data/lib/simplabs/excellent/parsing.rb +10 -0
  49. data/lib/simplabs/excellent/parsing/abc_measure.rb +52 -0
  50. data/lib/simplabs/excellent/parsing/block_context.rb +43 -0
  51. data/lib/simplabs/excellent/parsing/call_context.rb +52 -0
  52. data/lib/simplabs/excellent/parsing/case_context.rb +31 -0
  53. data/lib/simplabs/excellent/parsing/class_context.rb +99 -0
  54. data/lib/simplabs/excellent/parsing/code_processor.rb +165 -0
  55. data/lib/simplabs/excellent/parsing/conditional_context.rb +25 -0
  56. data/lib/simplabs/excellent/parsing/cvar_context.rb +28 -0
  57. data/lib/simplabs/excellent/parsing/cyclomatic_complexity_measure.rb +73 -0
  58. data/lib/simplabs/excellent/parsing/flog_measure.rb +192 -0
  59. data/lib/simplabs/excellent/parsing/for_loop_context.rb +15 -0
  60. data/lib/simplabs/excellent/parsing/gvar_context.rb +21 -0
  61. data/lib/simplabs/excellent/parsing/if_context.rb +38 -0
  62. data/lib/simplabs/excellent/parsing/ivar_context.rb +32 -0
  63. data/lib/simplabs/excellent/parsing/method_context.rb +50 -0
  64. data/lib/simplabs/excellent/parsing/module_context.rb +29 -0
  65. data/lib/simplabs/excellent/parsing/parser.rb +35 -0
  66. data/lib/simplabs/excellent/parsing/resbody_context.rb +39 -0
  67. data/lib/simplabs/excellent/parsing/scopeable.rb +34 -0
  68. data/lib/simplabs/excellent/parsing/sexp_context.rb +125 -0
  69. data/lib/simplabs/excellent/parsing/singleton_method_context.rb +55 -0
  70. data/lib/simplabs/excellent/parsing/until_context.rb +24 -0
  71. data/lib/simplabs/excellent/parsing/while_context.rb +24 -0
  72. data/lib/simplabs/excellent/rake.rb +1 -0
  73. data/lib/simplabs/excellent/rake/excellent_task.rb +61 -0
  74. data/lib/simplabs/excellent/runner.rb +143 -0
  75. data/lib/simplabs/excellent/warning.rb +53 -0
  76. data/spec/checks/abc_metric_method_check_spec.rb +122 -0
  77. data/spec/checks/assignment_in_conditional_check_spec.rb +90 -0
  78. data/spec/checks/case_missing_else_check_spec.rb +42 -0
  79. data/spec/checks/class_line_count_check_spec.rb +62 -0
  80. data/spec/checks/class_name_check_spec.rb +48 -0
  81. data/spec/checks/control_coupling_check_spec.rb +103 -0
  82. data/spec/checks/cyclomatic_complexity_block_check_spec.rb +47 -0
  83. data/spec/checks/cyclomatic_complexity_method_check_spec.rb +210 -0
  84. data/spec/checks/empty_rescue_body_check_spec.rb +170 -0
  85. data/spec/checks/flog_block_check_spec.rb +28 -0
  86. data/spec/checks/flog_class_check_spec.rb +28 -0
  87. data/spec/checks/flog_method_check_spec.rb +46 -0
  88. data/spec/checks/for_loop_check_spec.rb +52 -0
  89. data/spec/checks/global_variable_check_spec.rb +66 -0
  90. data/spec/checks/method_line_count_check_spec.rb +49 -0
  91. data/spec/checks/method_name_check_spec.rb +112 -0
  92. data/spec/checks/module_line_count_check_spec.rb +48 -0
  93. data/spec/checks/module_name_check_spec.rb +61 -0
  94. data/spec/checks/nested_iterators_check_spec.rb +44 -0
  95. data/spec/checks/parameter_number_check_spec.rb +97 -0
  96. data/spec/checks/rails/attr_accessible_check_spec.rb +79 -0
  97. data/spec/checks/rails/attr_protected_check_spec.rb +77 -0
  98. data/spec/checks/rails/custom_initialize_method_check_spec.rb +58 -0
  99. data/spec/checks/rails/instance_var_in_partial_check_spec.rb +40 -0
  100. data/spec/checks/rails/params_hash_in_view_check_spec.rb +40 -0
  101. data/spec/checks/rails/session_hash_in_view_check_spec.rb +40 -0
  102. data/spec/checks/rails/validations_check_spec.rb +81 -0
  103. data/spec/checks/singleton_variable_check_spec.rb +66 -0
  104. data/spec/extensions/string_spec.rb +13 -0
  105. data/spec/spec_helper.rb +13 -0
  106. metadata +189 -0
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::NestedIteratorsCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::NestedIteratorsCheck.new)
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should reject a block inside a block' do
12
+ code = <<-END
13
+ method1 do
14
+ method2 do
15
+ end
16
+ end
17
+ END
18
+ @excellent.check_code(code)
19
+ warnings = @excellent.warnings
20
+
21
+ warnings.should_not be_empty
22
+ warnings[0].info.should == { :block => 'block', :parent => 'block' }
23
+ warnings[0].line_number.should == 2
24
+ warnings[0].message.should == 'block inside of block.'
25
+ end
26
+
27
+ it 'should accept 2 blocks inside a method that are not nested' do
28
+ code = <<-END
29
+ def method
30
+ method1 do
31
+ end
32
+ method2 do
33
+ end
34
+ end
35
+ END
36
+ @excellent.check_code(code)
37
+ warnings = @excellent.warnings
38
+
39
+ warnings.should be_empty
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,97 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::ParameterNumberCheck do
4
+
5
+ before(:each) do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::ParameterNumberCheck.new({ :threshold => 1 }))
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should accept methods with less parameters than the threshold' do
12
+ code = <<-END
13
+ def zero_parameter_method
14
+ end
15
+ END
16
+ @excellent.check_code(code)
17
+
18
+ @excellent.warnings.should be_empty
19
+ end
20
+
21
+ it 'should accept methods with the same number of parameters as the threshold' do
22
+ code = <<-END
23
+ def one_parameter_method(first_parameter)
24
+ end
25
+ END
26
+ @excellent.check_code(code)
27
+
28
+ @excellent.warnings.should be_empty
29
+ end
30
+
31
+ it 'should reject methods with more parameters than the threshold' do
32
+ code = <<-END
33
+ def two_parameter_method(first_parameter, second_parameter)
34
+ end
35
+ END
36
+
37
+ verify_warning_found(code, 'two_parameter_method')
38
+ end
39
+
40
+ it 'should work with default values on parameters' do
41
+ code = <<-END
42
+ def two_parameter_method(first_parameter = 1, second_parameter = 2)
43
+ end
44
+ END
45
+
46
+ verify_warning_found(code, 'two_parameter_method')
47
+ end
48
+
49
+ it 'should work with methods defined on objects' do
50
+ code = <<-END
51
+ def object.two_parameter_method(first_parameter = 1, second_parameter = 2)
52
+ end
53
+ END
54
+
55
+ verify_warning_found(code, 'object.two_parameter_method')
56
+ end
57
+
58
+ it 'should work with methods defined directly on classes' do
59
+ code = <<-END
60
+ def Class.two_parameter_method(first_parameter = 1, second_parameter = 2)
61
+ end
62
+ END
63
+
64
+ verify_warning_found(code, 'Class.two_parameter_method')
65
+ end
66
+
67
+ it 'should reject yield calls with more parameters than the threshold' do
68
+ code = <<-END
69
+ two_parameter_method do |first_parameter, second_parameter|
70
+ end
71
+ END
72
+
73
+ verify_warning_found(code, 'block')
74
+ end
75
+
76
+ it 'should reject yield calls on a receiver with more parameters than the threshold' do
77
+ code = <<-END
78
+ receiver.two_parameter_method do |first_parameter, second_parameter|
79
+ end
80
+ END
81
+
82
+ verify_warning_found(code, 'block')
83
+ end
84
+
85
+ end
86
+
87
+ def verify_warning_found(code, name)
88
+ @excellent.check_code(code)
89
+ warnings = @excellent.warnings
90
+
91
+ warnings.should_not be_empty
92
+ warnings[0].info.should == { :method => name, :parameters => 2 }
93
+ warnings[0].line_number.should == 1
94
+ warnings[0].message.should == "#{name} has 2 parameters."
95
+ end
96
+
97
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::Rails::AttrAccessibleCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::Rails::AttrAccessibleCheck.new)
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should ignore classes that are not active record models' do
12
+ code = <<-END
13
+ class Test
14
+ end
15
+ END
16
+ @excellent.check_code(code)
17
+ warnings = @excellent.warnings
18
+
19
+ warnings.should be_empty
20
+ end
21
+
22
+ it 'should reject an active record model that does not specify attr_accessible' do
23
+ code = <<-END
24
+ class User < ActiveRecord::Base
25
+ end
26
+ END
27
+ @excellent.check_code(code)
28
+ warnings = @excellent.warnings
29
+
30
+ warnings.should_not be_empty
31
+ warnings[0].info.should == { :class => 'User' }
32
+ warnings[0].line_number.should == 1
33
+ warnings[0].message.should == 'User does not specify attr_accessible.'
34
+ end
35
+
36
+ it 'should reject an active record model that does specify attr_protected' do
37
+ code = <<-END
38
+ class User < ActiveRecord::Base
39
+ attr_protected :first_name
40
+ end
41
+ END
42
+ @excellent.check_code(code)
43
+ warnings = @excellent.warnings
44
+
45
+ warnings.should_not be_empty
46
+ warnings[0].info.should == { :class => 'User' }
47
+ warnings[0].line_number.should == 1
48
+ warnings[0].message.should == 'User does not specify attr_accessible.'
49
+ end
50
+
51
+ it 'should accept an active record model that does specify attr_accessible' do
52
+ code = <<-END
53
+ class User < ActiveRecord::Base
54
+ attr_accessible :first_name
55
+ end
56
+ END
57
+ @excellent.check_code(code)
58
+ warnings = @excellent.warnings
59
+
60
+ warnings.should be_empty
61
+ end
62
+
63
+ it 'should also work with namespaced models' do
64
+ code = <<-END
65
+ class Backend::User < ActiveRecord::Base
66
+ end
67
+ END
68
+ @excellent.check_code(code)
69
+ warnings = @excellent.warnings
70
+
71
+ warnings.should_not be_empty
72
+ warnings[0].info.should == { :class => 'Backend::User' }
73
+ warnings[0].line_number.should == 1
74
+ warnings[0].message.should == 'Backend::User does not specify attr_accessible.'
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,77 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::Rails::AttrProtectedCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::Rails::AttrProtectedCheck.new)
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should ignore classes that are not active record models' do
12
+ code = <<-END
13
+ class Test
14
+ end
15
+ END
16
+ @excellent.check_code(code)
17
+ warnings = @excellent.warnings
18
+
19
+ warnings.should be_empty
20
+ end
21
+
22
+ it 'should reject an active record model that does specify attr_protected' do
23
+ code = <<-END
24
+ class User < ActiveRecord::Base
25
+ attr_protected :first_name
26
+ end
27
+ END
28
+ @excellent.check_code(code)
29
+ warnings = @excellent.warnings
30
+
31
+ warnings.should_not be_empty
32
+ warnings[0].info.should == { :class => 'User' }
33
+ warnings[0].line_number.should == 1
34
+ warnings[0].message.should == 'User specifies attr_protected.'
35
+ end
36
+
37
+ it 'should accept an active record model that does specify attr_accessible' do
38
+ code = <<-END
39
+ class User < ActiveRecord::Base
40
+ attr_accessible :first_name
41
+ end
42
+ END
43
+ @excellent.check_code(code)
44
+ warnings = @excellent.warnings
45
+
46
+ warnings.should be_empty
47
+ end
48
+
49
+ it 'should accept an active record model that specifies neither attr_accessible not attr_protected' do
50
+ code = <<-END
51
+ class User < ActiveRecord::Base
52
+ end
53
+ END
54
+ @excellent.check_code(code)
55
+ warnings = @excellent.warnings
56
+
57
+ warnings.should be_empty
58
+ end
59
+
60
+ it 'should also work with namespaced models' do
61
+ code = <<-END
62
+ class Backend::User < ActiveRecord::Base
63
+ attr_protected :first_name
64
+ end
65
+ END
66
+ @excellent.check_code(code)
67
+ warnings = @excellent.warnings
68
+
69
+ warnings.should_not be_empty
70
+ warnings[0].info.should == { :class => 'Backend::User' }
71
+ warnings[0].line_number.should == 1
72
+ warnings[0].message.should == 'Backend::User specifies attr_protected.'
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::Rails::CustomInitializeMethodCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::Rails::CustomInitializeMethodCheck.new)
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should ignore classes that are not active record models' do
12
+ code = <<-END
13
+ class Test
14
+ def initialize
15
+ end
16
+ end
17
+ END
18
+ @excellent.check_code(code)
19
+ warnings = @excellent.warnings
20
+
21
+ warnings.should be_empty
22
+ end
23
+
24
+ it 'should reject an active record model that defines initialize' do
25
+ code = <<-END
26
+ class User < ActiveRecord::Base
27
+ def initialize
28
+ end
29
+ end
30
+ END
31
+ @excellent.check_code(code)
32
+ warnings = @excellent.warnings
33
+
34
+ warnings.should_not be_empty
35
+ warnings[0].info.should == { :class => 'User' }
36
+ warnings[0].line_number.should == 1
37
+ warnings[0].message.should == 'User defines initialize method.'
38
+ end
39
+
40
+ it 'should also work with namespaced models' do
41
+ code = <<-END
42
+ class Backend::User < ActiveRecord::Base
43
+ def initialize
44
+ end
45
+ end
46
+ END
47
+ @excellent.check_code(code)
48
+ warnings = @excellent.warnings
49
+
50
+ warnings.should_not be_empty
51
+ warnings[0].info.should == { :class => 'Backend::User' }
52
+ warnings[0].line_number.should == 1
53
+ warnings[0].message.should == 'Backend::User defines initialize method.'
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::Rails::InstanceVarInPartialCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::Rails::InstanceVarInPartialCheck.new)
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should accept partials that do not use instance variables' do
12
+ code = <<-END
13
+ <div>
14
+ <%= 'some text' %>
15
+ </div>
16
+ END
17
+ @excellent.check('_dummy-file.html.erb', code)
18
+ warnings = @excellent.warnings
19
+
20
+ warnings.should be_empty
21
+ end
22
+
23
+ it 'should reject partials that use instance variables' do
24
+ code = <<-END
25
+ <div>
26
+ <%= @ivar %>
27
+ </div>
28
+ END
29
+ @excellent.check('_dummy-file.html.erb', code)
30
+ warnings = @excellent.warnings
31
+
32
+ warnings.should_not be_empty
33
+ warnings[0].info.should == { :variable => 'ivar' }
34
+ warnings[0].line_number.should == 2
35
+ warnings[0].message.should == 'Instance variable ivar used in partial.'
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::Rails::ParamsHashInViewCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::Rails::ParamsHashInViewCheck.new)
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should accept views that do not use the params hash' do
12
+ code = <<-END
13
+ <div>
14
+ <%= 'some text' %>
15
+ </div>
16
+ END
17
+ @excellent.check('dummy-file.html.erb', code)
18
+ warnings = @excellent.warnings
19
+
20
+ warnings.should be_empty
21
+ end
22
+
23
+ it 'should reject views that use the params hash' do
24
+ code = <<-END
25
+ <div>
26
+ <%= params[:q] %>
27
+ </div>
28
+ END
29
+ @excellent.check('dummy-file.html.erb', code)
30
+ warnings = @excellent.warnings
31
+
32
+ warnings.should_not be_empty
33
+ warnings[0].info.should == {}
34
+ warnings[0].line_number.should == 2
35
+ warnings[0].message.should == 'Params hash used in view.'
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Simplabs::Excellent::Checks::Rails::SessionHashInViewCheck do
4
+
5
+ before do
6
+ @excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::Rails::SessionHashInViewCheck.new)
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ it 'should accept views that do not use the session hash' do
12
+ code = <<-END
13
+ <div>
14
+ <%= 'some text' %>
15
+ </div>
16
+ END
17
+ @excellent.check('dummy-file.html.erb', code)
18
+ warnings = @excellent.warnings
19
+
20
+ warnings.should be_empty
21
+ end
22
+
23
+ it 'should reject views that use the session hash' do
24
+ code = <<-END
25
+ <div>
26
+ <%= session[:someCount] %>
27
+ </div>
28
+ END
29
+ @excellent.check('dummy-file.html.erb', code)
30
+ warnings = @excellent.warnings
31
+
32
+ warnings.should_not be_empty
33
+ warnings[0].info.should == {}
34
+ warnings[0].line_number.should == 2
35
+ warnings[0].message.should == 'Session hash used in view.'
36
+ end
37
+
38
+ end
39
+
40
+ end