rails_best_practices 0.6.1 → 0.6.5

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 (46) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec.example +2 -0
  3. data/.rvmrc.example +2 -0
  4. data/.watchr +65 -0
  5. data/.watchr.example +65 -0
  6. data/Gemfile +3 -0
  7. data/README.md +6 -0
  8. data/Rakefile +45 -0
  9. data/assets/result.html.haml +53 -0
  10. data/lib/rails_best_practices.rb +30 -11
  11. data/lib/rails_best_practices/checks/check.rb +10 -10
  12. data/lib/rails_best_practices/command.rb +9 -0
  13. data/lib/rails_best_practices/core/visitable_sexp.rb +9 -10
  14. data/lib/rails_best_practices/version.rb +1 -1
  15. data/rails_best_practices.gemspec +32 -0
  16. data/rubies_test.sh +10 -0
  17. data/spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb +113 -0
  18. data/spec/rails_best_practices/checks/always_add_db_index_check_spec.rb +172 -0
  19. data/spec/rails_best_practices/checks/check_spec.rb +57 -0
  20. data/spec/rails_best_practices/checks/dry_bundler_in_capistrano_check_spec.rb +39 -0
  21. data/spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb +105 -0
  22. data/spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb +103 -0
  23. data/spec/rails_best_practices/checks/law_of_demeter_check_spec.rb +101 -0
  24. data/spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb +33 -0
  25. data/spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb +28 -0
  26. data/spec/rails_best_practices/checks/move_code_into_model_check_spec.rb +55 -0
  27. data/spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb +82 -0
  28. data/spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb +49 -0
  29. data/spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb +140 -0
  30. data/spec/rails_best_practices/checks/not_use_default_route_check_spec.rb +63 -0
  31. data/spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb +159 -0
  32. data/spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb +76 -0
  33. data/spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb +36 -0
  34. data/spec/rails_best_practices/checks/use_before_filter_check_spec.rb +85 -0
  35. data/spec/rails_best_practices/checks/use_model_association_check_spec.rb +71 -0
  36. data/spec/rails_best_practices/checks/use_observer_check_spec.rb +155 -0
  37. data/spec/rails_best_practices/checks/use_query_attribute_check_spec.rb +192 -0
  38. data/spec/rails_best_practices/checks/use_say_with_time_in_migrations_check_spec.rb +113 -0
  39. data/spec/rails_best_practices/checks/use_scope_access_check_spec.rb +193 -0
  40. data/spec/rails_best_practices/core/error_spec.rb +7 -0
  41. data/spec/rails_best_practices/core/visitable_sexp_spec.rb +259 -0
  42. data/spec/rails_best_practices/core_ext/enumerable_spec.rb +7 -0
  43. data/spec/rails_best_practices/core_ext/nil_class_spec.rb +11 -0
  44. data/spec/rails_best_practices_spec.rb +44 -0
  45. data/spec/spec_helper.rb +4 -0
  46. metadata +114 -32
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsBestPractices::Checks::NeedlessDeepNestingCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::NeedlessDeepNestingCheck.new)
6
+ end
7
+
8
+ describe "rails2" do
9
+ it "should needless deep nesting" do
10
+ content = <<-EOF
11
+ map.resources :posts do |post|
12
+ post.resources :comments do |comment|
13
+ comment.resources :favorites
14
+ end
15
+ end
16
+ EOF
17
+ @runner.review('config/routes.rb', content)
18
+ errors = @runner.errors
19
+ errors.should_not be_empty
20
+ errors[0].to_s.should == "config/routes.rb:3 - needless deep nesting (nested_count > 2)"
21
+ end
22
+
23
+ it "should needless deep nesting with resource" do
24
+ content = <<-EOF
25
+ map.resources :posts do |post|
26
+ post.resources :comments do |comment|
27
+ comment.resource :vote
28
+ end
29
+ end
30
+ EOF
31
+ @runner.review('config/routes.rb', content)
32
+ errors = @runner.errors
33
+ errors.should_not be_empty
34
+ errors[0].to_s.should == "config/routes.rb:3 - needless deep nesting (nested_count > 2)"
35
+ end
36
+
37
+ it "should needless deep nesting with block node" do
38
+ content = <<-EOF
39
+ map.resources :posts do |post|
40
+ post.resources :comments do |comment|
41
+ comment.resources :favorites
42
+ end
43
+ post.resources :votes
44
+ end
45
+ EOF
46
+ @runner.review('config/routes.rb', content)
47
+ errors = @runner.errors
48
+ errors.should_not be_empty
49
+ errors[0].to_s.should == "config/routes.rb:3 - needless deep nesting (nested_count > 2)"
50
+ end
51
+
52
+ it "should no needless deep nesting" do
53
+ content = <<-EOF
54
+ map.resources :posts do |post|
55
+ post.resources :comments
56
+ end
57
+
58
+ map.resources :comments do |comment|
59
+ comment.resources :favorites
60
+ end
61
+ EOF
62
+ @runner.review('config/routes.rb', content)
63
+ errors = @runner.errors
64
+ errors.should be_empty
65
+ end
66
+
67
+ it "should no needless deep nesting with block node" do
68
+ content = <<-EOF
69
+ map.resources :comments do |comment|
70
+ comment.resources :favorites
71
+ comment.resources :votes
72
+ end
73
+ EOF
74
+ @runner.review('config/routes.rb', content)
75
+ errors = @runner.errors
76
+ errors.should be_empty
77
+ end
78
+ end
79
+
80
+ describe "rails3" do
81
+ it "should needless deep nesting" do
82
+ content = <<-EOF
83
+ resources :posts do
84
+ resources :comments do
85
+ resources :favorites
86
+ end
87
+ end
88
+ EOF
89
+ @runner.review('config/routes.rb', content)
90
+ errors = @runner.errors
91
+ errors.should_not be_empty
92
+ errors[0].to_s.should == "config/routes.rb:4 - needless deep nesting (nested_count > 2)"
93
+ end
94
+
95
+ it "should needless deep nesting with resource" do
96
+ content = <<-EOF
97
+ resources :posts do
98
+ resources :comments do
99
+ resource :vote
100
+ end
101
+ end
102
+ EOF
103
+ @runner.review('config/routes.rb', content)
104
+ errors = @runner.errors
105
+ errors.should_not be_empty
106
+ errors[0].to_s.should == "config/routes.rb:4 - needless deep nesting (nested_count > 2)"
107
+ end
108
+
109
+ it "should needless deep nesting with block node" do
110
+ content = <<-EOF
111
+ resources :posts do
112
+ resources :comments do
113
+ resources :favorites
114
+ end
115
+ resources :votes
116
+ end
117
+ EOF
118
+ @runner.review('config/routes.rb', content)
119
+ errors = @runner.errors
120
+ errors.should_not be_empty
121
+ errors[0].to_s.should == "config/routes.rb:4 - needless deep nesting (nested_count > 2)"
122
+ end
123
+
124
+ it "should no needless deep nesting" do
125
+ content = <<-EOF
126
+ resources :posts do
127
+ resources :comments
128
+ resources :votes
129
+ end
130
+
131
+ resources :comments do
132
+ resources :favorites
133
+ end
134
+ EOF
135
+ @runner.review('config/routes.rb', content)
136
+ errors = @runner.errors
137
+ errors.should be_empty
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsBestPractices::Checks::NotUseDefaultRouteCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::NotUseDefaultRouteCheck.new)
6
+ end
7
+
8
+ describe "rails2" do
9
+ it "should not use default route" do
10
+ content = <<-EOF
11
+ ActionController::Routing::Routes.draw do |map|
12
+ map.resources :posts, :member => { :push => :post }
13
+
14
+ map.connect ':controller/:action/:id'
15
+ map.connect ':controller/:action/:id.:format'
16
+ end
17
+ EOF
18
+ @runner.review('config/routes.rb', content)
19
+ errors = @runner.errors
20
+ errors.should_not be_empty
21
+ errors[0].to_s.should == "config/routes.rb:4 - not use default route"
22
+ errors[1].to_s.should == "config/routes.rb:5 - not use default route"
23
+ end
24
+
25
+ it "should no not use default route" do
26
+ content = <<-EOF
27
+ ActionController::Routing::Routes.draw do |map|
28
+ map.resources :posts, :member => { :push => :post }
29
+ end
30
+ EOF
31
+ @runner.review('config/routes.rb', content)
32
+ errors = @runner.errors
33
+ errors.should be_empty
34
+ end
35
+ end
36
+
37
+ describe "rails3" do
38
+ it "should not use default route" do
39
+ content = <<-EOF
40
+ RailsBestpracticesCom::Application.routes.draw do |map|
41
+ resources :posts
42
+
43
+ match ':controller(/:action(/:id(.:format)))'
44
+ end
45
+ EOF
46
+ @runner.review('config/routes.rb', content)
47
+ errors = @runner.errors
48
+ errors.should_not be_empty
49
+ errors[0].to_s.should == "config/routes.rb:5 - not use default route"
50
+ end
51
+
52
+ it "should no not use default route" do
53
+ content = <<-EOF
54
+ RailsBestpracticesCom::Application.routes.draw do |map|
55
+ resources :posts
56
+ end
57
+ EOF
58
+ @runner.review('config/routes.rb', content)
59
+ errors = @runner.errors
60
+ errors.should be_empty
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,159 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsBestPractices::Checks::OveruseRouteCustomizationsCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::OveruseRouteCustomizationsCheck.new)
6
+ end
7
+
8
+ describe "rails2" do
9
+ it "should overuse route customizations" do
10
+ content = <<-EOF
11
+ ActionController::Routing::Routes.draw do |map|
12
+ map.resources :posts, :member => { :comments => :get,
13
+ :create_comment => :post,
14
+ :update_comment => :update,
15
+ :delete_comment => :delete }
16
+ end
17
+ EOF
18
+ @runner.review('config/routes.rb', content)
19
+ errors = @runner.errors
20
+ errors.should_not be_empty
21
+ errors[0].to_s.should == "config/routes.rb:2 - overuse route customizations (customize_count > 3)"
22
+ end
23
+
24
+ it "should overuse route customizations with collection" do
25
+ content = <<-EOF
26
+ ActionController::Routing::Routes.draw do |map|
27
+ map.resources :posts, :member => { :create_comment => :post,
28
+ :update_comment => :update,
29
+ :delete_comment => :delete },
30
+ :collection => { :comments => :get }
31
+ end
32
+ EOF
33
+ @runner.review('config/routes.rb', content)
34
+ errors = @runner.errors
35
+ errors.should_not be_empty
36
+ errors[0].to_s.should == "config/routes.rb:2 - overuse route customizations (customize_count > 3)"
37
+ end
38
+
39
+ it "should overuse route customizations with collection 2" do
40
+ content = <<-EOF
41
+ ActionController::Routing::Routes.draw do |map|
42
+ map.resources :categories do |category|
43
+ category.resources :posts, :member => { :create_comment => :post,
44
+ :update_comment => :update,
45
+ :delete_comment => :delete },
46
+ :collection => { :comments => :get }
47
+ end
48
+ end
49
+ EOF
50
+ @runner.review('config/routes.rb', content)
51
+ errors = @runner.errors
52
+ errors.should_not be_empty
53
+ errors[0].to_s.should == "config/routes.rb:3 - overuse route customizations (customize_count > 3)"
54
+ end
55
+
56
+ it "should not overuse route customizations without customization" do
57
+ content = <<-EOF
58
+ ActionController::Routing::Routes.draw do |map|
59
+ map.resources :posts
60
+ end
61
+ EOF
62
+ @runner.review('config/routes.rb', content)
63
+ errors = @runner.errors
64
+ errors.should be_empty
65
+ end
66
+
67
+ it "should not overuse route customizations when customize route is only one" do
68
+ content = <<-EOF
69
+ ActionController::Routing::Routes.draw do |map|
70
+ map.resources :posts, :member => { :vote => :post }
71
+ end
72
+ EOF
73
+ @runner.review('config/routes.rb', content)
74
+ errors = @runner.errors
75
+ errors.should be_empty
76
+ end
77
+
78
+ it "should not raise error for constants in routes" do
79
+ content =<<-EOF
80
+ IP_PATTERN = /(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2}))|[\d]+/.freeze
81
+ map.resources :vlans do |vlan|
82
+ vlan.resources :ip_ranges, :member => {:move => [:get, :post]} do |range|
83
+ range.resources :ips, :requirements => { :id => IP_PATTERN }
84
+ end
85
+ end
86
+ EOF
87
+ @runner.review('config/routes.rb', content)
88
+ errors = @runner.errors
89
+ errors.should be_empty
90
+ end
91
+ end
92
+
93
+ describe "rails3" do
94
+ it "should overuse route customizations" do
95
+ content = <<-EOF
96
+ RailsBestpracticesCom::Application.routes.draw do |map|
97
+ resources :posts do
98
+ member do
99
+ post :create_comment
100
+ update :update_comment
101
+ delete :delete_comment
102
+ end
103
+
104
+ collection do
105
+ get :comments
106
+ end
107
+ end
108
+ end
109
+ EOF
110
+ @runner.review('config/routes.rb', content)
111
+ errors = @runner.errors
112
+ errors.should_not be_empty
113
+ errors[0].to_s.should == "config/routes.rb:2 - overuse route customizations (customize_count > 3)"
114
+ end
115
+
116
+ it "should overuse route customizations another way" do
117
+ content = <<-EOF
118
+ RailsBestpracticesCom::Application.routes.draw do |map|
119
+ resources :posts do
120
+ post :create_comment, :on => :member
121
+ update :update_comment, :on => :member
122
+ delete :delete_comment, :on => :member
123
+ get :comments, :on => :collection
124
+ end
125
+ end
126
+ EOF
127
+ @runner.review('config/routes.rb', content)
128
+ errors = @runner.errors
129
+ errors.should_not be_empty
130
+ errors[0].to_s.should == "config/routes.rb:2 - overuse route customizations (customize_count > 3)"
131
+ end
132
+
133
+ it "should not overuse route customizations without customization" do
134
+ content = <<-EOF
135
+ RailsBestpracticesCom::Application.routes.draw do |map|
136
+ resources :posts
137
+ end
138
+ EOF
139
+ @runner.review('config/routes.rb', content)
140
+ errors = @runner.errors
141
+ errors.should be_empty
142
+ end
143
+
144
+ it "should not overuse route customizations when customize route is only one" do
145
+ content = <<-EOF
146
+ RailsBestpracticesCom::Application.routes.draw do |map|
147
+ resources :posts do
148
+ member do
149
+ post :vote
150
+ end
151
+ end
152
+ end
153
+ EOF
154
+ @runner.review('config/routes.rb', content)
155
+ errors = @runner.errors
156
+ errors.should be_empty
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsBestPractices::Checks::ReplaceComplexCreationWithFactoryMethodCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::ReplaceComplexCreationWithFactoryMethodCheck.new)
6
+ end
7
+
8
+ it "should replace complex creation with factory method" do
9
+ content = <<-EOF
10
+ class InvoiceController < ApplicationController
11
+
12
+ def create
13
+ @invoice = Invoice.new(params[:invoice])
14
+ @invoice.address = current_user.address
15
+ @invoice.phone = current_user.phone
16
+ @invoice.vip = (@invoice.amount > 1000)
17
+
18
+ if Time.now.day > 15
19
+ @invoice.deliver_time = Time.now + 2.month
20
+ else
21
+ @invoice.deliver_time = Time.now + 1.month
22
+ end
23
+
24
+ @invoice.save
25
+ end
26
+ end
27
+ EOF
28
+ @runner.review('app/controllers/invoices_controller.rb', content)
29
+ errors = @runner.errors
30
+ errors.should_not be_empty
31
+ errors[0].to_s.should == "app/controllers/invoices_controller.rb:3 - replace complex creation with factory method (@invoice attribute_assignment_count > 2)"
32
+ end
33
+
34
+ it "should not replace complex creation with factory method with simple creation" do
35
+ content = <<-EOF
36
+ class InvoiceController < ApplicationController
37
+
38
+ def create
39
+ @invoice = Invoice.new(params[:invoice])
40
+ @invoice.address = current_user.address
41
+ @invoice.phone = current_user.phone
42
+ @invoice.save
43
+ end
44
+ end
45
+ EOF
46
+ @runner.review('app/controllers/invoices_controller.rb', content)
47
+ errors = @runner.errors
48
+ errors.should be_empty
49
+ end
50
+
51
+ it "should not replace complex creation with factory method when attrasgn_count is 5" do
52
+ content = <<-EOF
53
+ class InvoiceController < ApplicationController
54
+
55
+ def create
56
+ @invoice = Invoice.new(params[:invoice])
57
+ @invoice.address = current_user.address
58
+ @invoice.phone = current_user.phone
59
+ @invoice.vip = (@invoice.amount > 1000)
60
+
61
+ if Time.now.day > 15
62
+ @invoice.deliver_time = Time.now + 2.month
63
+ else
64
+ @invoice.deliver_time = Time.now + 1.month
65
+ end
66
+
67
+ @invoice.save
68
+ end
69
+ end
70
+ EOF
71
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::ReplaceComplexCreationWithFactoryMethodCheck.new('attribute_assignment_count' => 5))
72
+ @runner.review('app/controllers/invoices_controller.rb', content)
73
+ errors = @runner.errors
74
+ errors.should be_empty
75
+ end
76
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsBestPractices::Checks::ReplaceInstanceVariableWithLocalVariableCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::ReplaceInstanceVariableWithLocalVariableCheck.new)
6
+ end
7
+
8
+ it "should replace instance variable with local varialbe" do
9
+ content = <<-EOF
10
+ <%= @post.title %>
11
+ EOF
12
+ @runner.review('app/views/posts/_post.html.erb', content)
13
+ errors = @runner.errors
14
+ errors.should_not be_empty
15
+ errors[0].to_s.should == "app/views/posts/_post.html.erb:1 - replace instance variable with local variable"
16
+ end
17
+
18
+ it "should replace instance variable with local varialbe in haml file" do
19
+ content = <<-EOF
20
+ = @post.title
21
+ EOF
22
+ @runner.review('app/views/posts/_post.html.haml', content)
23
+ errors = @runner.errors
24
+ errors.should_not be_empty
25
+ errors[0].to_s.should == "app/views/posts/_post.html.haml:1 - replace instance variable with local variable"
26
+ end
27
+
28
+ it "should not replace instance variable with local varialbe" do
29
+ content = <<-EOF
30
+ <%= post.title %>
31
+ EOF
32
+ @runner.review('app/views/posts/_post.html.erb', content)
33
+ errors = @runner.errors
34
+ errors.should be_empty
35
+ end
36
+ end