rails_best_practices 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile.lock +1 -1
  3. data/README.md +2 -0
  4. data/assets/result.html.erb +25 -2
  5. data/lib/rails_best_practices.rb +20 -9
  6. data/lib/rails_best_practices/core.rb +1 -0
  7. data/lib/rails_best_practices/core/check.rb +106 -25
  8. data/lib/rails_best_practices/core/controllers.rb +2 -1
  9. data/lib/rails_best_practices/core/error.rb +3 -2
  10. data/lib/rails_best_practices/core/klasses.rb +34 -0
  11. data/lib/rails_best_practices/core/mailers.rb +2 -1
  12. data/lib/rails_best_practices/core/methods.rb +113 -9
  13. data/lib/rails_best_practices/core/model_associations.rb +17 -0
  14. data/lib/rails_best_practices/core/model_attributes.rb +16 -0
  15. data/lib/rails_best_practices/core/models.rb +3 -2
  16. data/lib/rails_best_practices/core/nil.rb +9 -1
  17. data/lib/rails_best_practices/core/runner.rb +65 -26
  18. data/lib/rails_best_practices/core_ext/sexp.rb +57 -0
  19. data/lib/rails_best_practices/prepares.rb +12 -1
  20. data/lib/rails_best_practices/prepares/controller_prepare.rb +13 -8
  21. data/lib/rails_best_practices/prepares/mailer_prepare.rb +3 -3
  22. data/lib/rails_best_practices/prepares/model_prepare.rb +44 -16
  23. data/lib/rails_best_practices/reviews.rb +1 -0
  24. data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +5 -2
  25. data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +77 -0
  26. data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +2 -2
  27. data/lib/rails_best_practices/reviews/review.rb +1 -1
  28. data/lib/rails_best_practices/version.rb +1 -1
  29. data/rails_best_practices.yml +1 -0
  30. data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +11 -0
  31. data/spec/rails_best_practices/core/check_spec.rb +22 -0
  32. data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
  33. data/spec/rails_best_practices/core/error_spec.rb +1 -1
  34. data/spec/rails_best_practices/core/klasses_spec.rb +12 -0
  35. data/spec/rails_best_practices/core/mailers_spec.rb +5 -0
  36. data/spec/rails_best_practices/core/methods_spec.rb +26 -4
  37. data/spec/rails_best_practices/core/models_spec.rb +2 -2
  38. data/spec/rails_best_practices/core/runner_spec.rb +13 -0
  39. data/spec/rails_best_practices/core_ext/sexp_spec.rb +26 -2
  40. data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +72 -60
  41. data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +1 -1
  42. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +150 -59
  43. data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +20 -3
  44. data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +14 -0
  45. data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +387 -0
  46. metadata +15 -3
@@ -9,6 +9,6 @@ describe RailsBestPractices::Prepares::MailerPrepare do
9
9
  end
10
10
  EOF
11
11
  runner.prepare('app/mailers/project_mailer.rb', content)
12
- RailsBestPractices::Prepares.mailers.should == ["ProjectMailer"]
12
+ RailsBestPractices::Prepares.mailers.map(&:to_s).should == ["ProjectMailer"]
13
13
  end
14
14
  end
@@ -7,98 +7,189 @@ describe RailsBestPractices::Prepares::ModelPrepare do
7
7
  runner.whiny = true
8
8
  end
9
9
 
10
- it "should parse model associations" do
11
- content =<<-EOF
12
- class Project < ActiveRecord::Base
13
- belongs_to :portfolio
14
- has_one :project_manager
15
- has_many :milestones
16
- has_and_belongs_to_many :categories
10
+ context "models" do
11
+ it "class_name with modules ::" do
12
+ content =<<-EOF
13
+ class Blog::Post < ActiveRecord::Base
14
+ end
15
+ EOF
16
+ runner.prepare("app/models/admin/post.rb", content)
17
+ models = RailsBestPractices::Prepares.models
18
+ models.map(&:to_s).should == ["Blog::Post"]
17
19
  end
18
- EOF
19
- runner.prepare('app/models/project.rb', content)
20
- model_associations = RailsBestPractices::Prepares.model_associations
21
- model_associations.get_association("Project", "portfolio").should == {"meta" => "belongs_to", "class_name" => "Portfolio"}
22
- model_associations.get_association("Project", "project_manager").should == {"meta" => "has_one", "class_name" => "ProjectManager"}
23
- model_associations.get_association("Project", "milestones").should == {"meta" => "has_many", "class_name" => "Milestone"}
24
- model_associations.get_association("Project", "categories").should == {"meta" => "has_and_belongs_to_many", "class_name" => "Category"}
25
- end
26
20
 
27
- it "should not raise error for finder_sql option" do
28
- content =<<-EOF
29
- class EventSubscription < ActiveRecord::Base
30
- has_many :event_notification_template, :finder_sql => ?
21
+ it "class_name with modules" do
22
+ content =<<-EOF
23
+ module Blog
24
+ class Post < ActiveRecord::Base
25
+ end
26
+ end
27
+ EOF
28
+ runner.prepare("app/models/admin/post.rb", content)
29
+ models = RailsBestPractices::Prepares.models
30
+ models.map(&:to_s).should == ["Blog::Post"]
31
31
  end
32
- EOF
33
- content.sub!('?', '\'SELECT event_notification_templates.* from event_notification_templates where event_type_id=#{event_type_id} and delivery_method_id=#{delivery_method_id}\'')
34
- lambda { runner.prepare('app/models/event_subscription.rb', content) }.should_not raise_error
35
32
  end
36
33
 
37
- it "class_name with modules ::" do
38
- content =<<-EOF
39
- class Blog::Post < ActiveRecord::Base
34
+ context "associations" do
35
+ it "should parse model associations" do
36
+ content =<<-EOF
37
+ class Project < ActiveRecord::Base
38
+ belongs_to :portfolio
39
+ has_one :project_manager
40
+ has_many :milestones
41
+ has_and_belongs_to_many :categories
42
+ end
43
+ EOF
44
+ runner.prepare('app/models/project.rb', content)
45
+ model_associations = RailsBestPractices::Prepares.model_associations
46
+ model_associations.get_association("Project", "portfolio").should == {"meta" => "belongs_to", "class_name" => "Portfolio"}
47
+ model_associations.get_association("Project", "project_manager").should == {"meta" => "has_one", "class_name" => "ProjectManager"}
48
+ model_associations.get_association("Project", "milestones").should == {"meta" => "has_many", "class_name" => "Milestone"}
49
+ model_associations.get_association("Project", "categories").should == {"meta" => "has_and_belongs_to_many", "class_name" => "Category"}
50
+ end
51
+
52
+ context "with class_name option" do
53
+ it "should parse belongs_to" do
54
+ content =<<-EOF
55
+ class Post < ActiveRecord::Base
56
+ belongs_to :author, "class_name" => "Person"
57
+ end
58
+ EOF
59
+ runner.prepare("app/models/post.rb", content)
60
+ model_associations = RailsBestPractices::Prepares.model_associations
61
+ model_associations.get_association("Post", "author").should == {"meta" => "belongs_to", "class_name" => "Person"}
62
+ end
63
+
64
+ it "should parse has_one" do
65
+ content =<<-EOF
66
+ class Project < ActiveRecord::Base
67
+ has_one :project_manager, "class_name" => "Person"
68
+ end
69
+ EOF
70
+ runner.prepare("app/models/post.rb", content)
71
+ model_associations = RailsBestPractices::Prepares.model_associations
72
+ model_associations.get_association("Project", "project_manager").should == {"meta" => "has_one", "class_name" => "Person"}
73
+ end
74
+
75
+ it "should parse has_many" do
76
+ content =<<-EOF
77
+ class Project < ActiveRecord::Base
78
+ has_many :people, "class_name" => "Person"
79
+ end
80
+ EOF
81
+ runner.prepare("app/models/project.rb", content)
82
+ model_associations = RailsBestPractices::Prepares.model_associations
83
+ model_associations.get_association("Project", "people").should == {"meta" => "has_many", "class_name" => "Person"}
84
+ end
85
+
86
+ it "should parse has_and_belongs_to_many" do
87
+ content =<<-EOF
88
+ class Citizen < ActiveRecord::Base
89
+ has_and_belongs_to_many :nations, "class_name" => "Country"
90
+ end
91
+ EOF
92
+ runner.prepare("app/models/citizen.rb", content)
93
+ model_associations = RailsBestPractices::Prepares.model_associations
94
+ model_associations.get_association("Citizen", "nations").should == {"meta" => "has_and_belongs_to_many", "class_name" => "Country"}
95
+ end
40
96
  end
41
- EOF
42
- runner.prepare("app/models/admin/post.rb", content)
43
- models = RailsBestPractices::Prepares.models
44
- models.should == ["Blog::Post"]
45
97
  end
46
98
 
47
- it "class_name with modules" do
48
- content =<<-EOF
49
- module Blog
99
+ context "methods" do
100
+ it "should parse model methods" do
101
+ content =<<-EOF
50
102
  class Post < ActiveRecord::Base
103
+ def save; end
104
+ def find; end
51
105
  end
106
+ EOF
107
+ runner.prepare("app/models/post.rb", content)
108
+ methods = RailsBestPractices::Prepares.model_methods
109
+ methods.get_methods("Post").map(&:method_name).should == ["save", "find"]
52
110
  end
53
- EOF
54
- runner.prepare("app/models/admin/post.rb", content)
55
- models = RailsBestPractices::Prepares.models
56
- models.should == ["Blog::Post"]
57
- end
58
111
 
59
- context "class_name" do
60
- it "should parse belongs_to" do
112
+ it "should parse model methods with access control" do
61
113
  content =<<-EOF
62
114
  class Post < ActiveRecord::Base
63
- belongs_to :author, "class_name" => "Person"
115
+ def save; end
116
+ def find; end
117
+ protected
118
+ def create_or_update; end
119
+ private
120
+ def find_by_sql; end
64
121
  end
65
122
  EOF
66
123
  runner.prepare("app/models/post.rb", content)
67
- model_associations = RailsBestPractices::Prepares.model_associations
68
- model_associations.get_association("Post", "author").should == {"meta" => "belongs_to", "class_name" => "Person"}
124
+ methods = RailsBestPractices::Prepares.model_methods
125
+ methods.get_methods("Post").map(&:method_name).should == ["save", "find", "create_or_update", "find_by_sql"]
126
+ methods.get_methods("Post", "public").map(&:method_name).should == ["save", "find"]
127
+ methods.get_methods("Post", "protected").map(&:method_name).should == ["create_or_update"]
128
+ methods.get_methods("Post", "private").map(&:method_name).should == ["find_by_sql"]
69
129
  end
70
130
 
71
- it "should parse has_one" do
131
+ it "should parse model methods with module ::" do
72
132
  content =<<-EOF
73
- class Project < ActiveRecord::Base
74
- has_one :project_manager, "class_name" => "Person"
133
+ class Admin::Blog::Post < ActiveRecord::Base
134
+ def save; end
135
+ def find; end
136
+ end
137
+ EOF
138
+ runner.prepare("app/models/admin/blog/post.rb", content)
139
+ methods = RailsBestPractices::Prepares.model_methods
140
+ methods.get_methods("Admin::Blog::Post").map(&:method_name).should == ["save", "find"]
141
+ end
142
+
143
+ it "should parse model methods with module" do
144
+ content =<<-EOF
145
+ module Admin
146
+ module Blog
147
+ class Post < ActiveRecord::Base
148
+ def save; end
149
+ def find; end
150
+ end
151
+ end
152
+ end
153
+ EOF
154
+ runner.prepare("app/models/admin/blog/post.rb", content)
155
+ methods = RailsBestPractices::Prepares.model_methods
156
+ methods.get_methods("Admin::Blog::Post").map(&:method_name).should == ["save", "find"]
157
+ end
158
+ end
159
+
160
+ context "scope" do
161
+ it "should treat named_scope as method" do
162
+ content =<<-EOF
163
+ class Post < ActiveRecord::Base
164
+ named_scope :active, :conditions => {:active => true}
75
165
  end
76
166
  EOF
77
167
  runner.prepare("app/models/post.rb", content)
78
- model_associations = RailsBestPractices::Prepares.model_associations
79
- model_associations.get_association("Project", "project_manager").should == {"meta" => "has_one", "class_name" => "Person"}
168
+ methods = RailsBestPractices::Prepares.model_methods
169
+ methods.get_methods("Post").map(&:method_name).should == ["active"]
80
170
  end
81
171
 
82
- it "should parse has_many" do
172
+ it "should treat scope as method" do
83
173
  content =<<-EOF
84
- class Project < ActiveRecord::Base
85
- has_many :people, "class_name" => "Person"
174
+ class Post < ActiveRecord::Base
175
+ scope :active, where(:active => true)
86
176
  end
87
177
  EOF
88
- runner.prepare("app/models/project.rb", content)
89
- model_associations = RailsBestPractices::Prepares.model_associations
90
- model_associations.get_association("Project", "people").should == {"meta" => "has_many", "class_name" => "Person"}
178
+ runner.prepare("app/models/post.rb", content)
179
+ methods = RailsBestPractices::Prepares.model_methods
180
+ methods.get_methods("Post").map(&:method_name).should == ["active"]
91
181
  end
182
+ end
92
183
 
93
- it "should parse has_and_belongs_to_many" do
184
+ context "no error" do
185
+ it "should raised for finder_sql option" do
94
186
  content =<<-EOF
95
- class Citizen < ActiveRecord::Base
96
- has_and_belongs_to_many :nations, "class_name" => "Country"
187
+ class EventSubscription < ActiveRecord::Base
188
+ has_many :event_notification_template, :finder_sql => ?
97
189
  end
98
190
  EOF
99
- runner.prepare("app/models/citizen.rb", content)
100
- model_associations = RailsBestPractices::Prepares.model_associations
101
- model_associations.get_association("Citizen", "nations").should == {"meta" => "has_and_belongs_to_many", "class_name" => "Country"}
191
+ content.sub!('?', '\'SELECT event_notification_templates.* from event_notification_templates where event_type_id=#{event_type_id} and delivery_method_id=#{delivery_method_id}\'')
192
+ lambda { runner.prepare('app/models/event_subscription.rb', content) }.should_not raise_error
102
193
  end
103
194
  end
104
195
  end
@@ -16,9 +16,9 @@ describe RailsBestPractices::Reviews::MoveModelLogicIntoModelReview do
16
16
  else
17
17
  @post.popular = 0
18
18
  end
19
- end
20
19
 
21
- redirect_to post_url(@post)
20
+ redirect_to post_url(@post)
21
+ end
22
22
  end
23
23
  EOF
24
24
  runner.review('app/controllers/posts_controller.rb', content)
@@ -34,9 +34,26 @@ describe RailsBestPractices::Reviews::MoveModelLogicIntoModelReview do
34
34
  @post = Post.find(params[:id])
35
35
  @post.update_attributes(:is_published, true)
36
36
  @post.approved_by = current_user
37
+
38
+ redirect_to post_url(@post)
37
39
  end
40
+ end
41
+ EOF
42
+ runner.review('app/controllers/posts_controller.rb', content)
43
+ runner.should have(0).errors
44
+ end
45
+
46
+ it "should not move model logic into model with self calling" do
47
+ content = <<-EOF
48
+ class PostsController < ApplicationController
38
49
 
39
- redirect_to post_url(@post)
50
+ def publish
51
+ self.step1
52
+ self.step2
53
+ self.step3
54
+ self.step4
55
+ self.step5
56
+ end
40
57
  end
41
58
  EOF
42
59
  runner.review('app/controllers/posts_controller.rb', content)
@@ -108,6 +108,20 @@ describe RailsBestPractices::Reviews::NeedlessDeepNestingReview do
108
108
  runner.should have(0).errors
109
109
  end
110
110
 
111
+ it "should not needless deep nesting for shallow 4 levels" do
112
+ content = <<-EOF
113
+ resources :applications, shallow: true, only: [:index, :show, :create] do
114
+ resources :events, only: [:index, :show, :create, :subscribe, :push] do
115
+ resources :executions, only: [:index, :show] do
116
+ resources :execution_statuses, only: :index
117
+ end
118
+ end
119
+ end
120
+ EOF
121
+ runner.review('config/routes.rb', content)
122
+ runner.should have(0).errors
123
+ end
124
+
111
125
  it "should needless deep nesting with resource" do
112
126
  content = <<-EOF
113
127
  resources :posts do
@@ -0,0 +1,387 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsBestPractices::Reviews::RemoveUnusedMethodsInModelsReview do
4
+ let(:runner) { RailsBestPractices::Core::Runner.new(
5
+ :prepares => [RailsBestPractices::Prepares::ModelPrepare.new, RailsBestPractices::Prepares::ControllerPrepare.new],
6
+ :reviews => RailsBestPractices::Reviews::RemoveUnusedMethodsInModelsReview.new({'except_methods' => ['set_cache']})
7
+ ) }
8
+
9
+ context "private" do
10
+ it "should remove unused methods" do
11
+ content =<<-EOF
12
+ class Post < ActiveRecord::Base
13
+ def find; end
14
+ private
15
+ def find_by_sql; end
16
+ end
17
+ EOF
18
+ runner.prepare('app/models/post.rb', content)
19
+ runner.review('app/models/post.rb', content)
20
+ content =<<-EOF
21
+ class PostsController < ApplicationController
22
+ def get
23
+ Post.new.find
24
+ end
25
+ end
26
+ EOF
27
+ runner.review('app/controllers/posts_controller.rb', content)
28
+ runner.on_complete
29
+ runner.should have(1).errors
30
+ runner.errors[0].to_s.should == "app/models/post.rb:4 - remove unused methods (Post#find_by_sql)"
31
+ end
32
+
33
+ it "should not remove unused methods with except_methods" do
34
+ content =<<-EOF
35
+ class Post < ActiveRecord::Base
36
+ def set_cache; end
37
+ end
38
+ EOF
39
+ runner.prepare('app/models/post.rb', content)
40
+ runner.review('app/models/post.rb', content)
41
+ runner.on_complete
42
+ runner.should have(0).errors
43
+ end
44
+
45
+ it "should not remove unused methods with var_ref" do
46
+ content =<<-EOF
47
+ class Post < ActiveRecord::Base
48
+ def find;
49
+ find_by_sql
50
+ end
51
+ private
52
+ def find_by_sql; end
53
+ end
54
+ EOF
55
+ runner.prepare('app/models/post.rb', content)
56
+ runner.review('app/models/post.rb', content)
57
+ content =<<-EOF
58
+ class PostsController < ApplicationController
59
+ def get
60
+ Post.new.find
61
+ end
62
+ end
63
+ EOF
64
+ runner.review('app/controllers/posts_controller.rb', content)
65
+ runner.on_complete
66
+ runner.should have(0).errors
67
+ end
68
+
69
+ it "should not remove unused methods with callback" do
70
+ content =<<-EOF
71
+ class Post < ActiveRecord::Base
72
+ after_save :expire_cache
73
+ private
74
+ def expire_cache; end
75
+ end
76
+ EOF
77
+ runner.prepare('app/models/post.rb', content)
78
+ runner.review('app/models/post.rb', content)
79
+ runner.on_complete
80
+ runner.should have(0).errors
81
+ end
82
+
83
+ it "should not remove unused method with command" do
84
+ content =<<-EOF
85
+ class Post < ActiveRecord::Base
86
+ def fetch
87
+ get(:position => 'first')
88
+ end
89
+ private
90
+ def get(options={}); end
91
+ end
92
+ EOF
93
+ runner.prepare('app/models/post.rb', content)
94
+ runner.review('app/models/post.rb', content)
95
+ content =<<-EOF
96
+ class PostsController < ApplicationController
97
+ def get
98
+ Post.new.fetch
99
+ end
100
+ end
101
+ EOF
102
+ runner.review('app/controllers/posts_controller.rb', content)
103
+ runner.on_complete
104
+ runner.should have(0).errors
105
+ end
106
+
107
+ it "should not remove unused method with call" do
108
+ content =<<-EOF
109
+ class Post < ActiveRecord::Base
110
+ def conditions
111
+ self.build_conditions({})
112
+ end
113
+ private
114
+ def build_conditions(conditions={}); end
115
+ end
116
+ EOF
117
+ runner.prepare('app/models/post.rb', content)
118
+ runner.review('app/models/post.rb', content)
119
+ content =<<-EOF
120
+ class PostsController < ApplicationController
121
+ def get
122
+ Post.new.conditions
123
+ end
124
+ end
125
+ EOF
126
+ runner.review('app/controllers/posts_controller.rb', content)
127
+ runner.on_complete
128
+ runner.should have(0).errors
129
+ end
130
+
131
+ it "should not remove unused method with message" do
132
+ content =<<-EOF
133
+ class Post < ActiveRecord::Base
134
+ def save
135
+ transaction true do
136
+ self.update
137
+ end
138
+ end
139
+ private
140
+ def transaction(force); end
141
+ end
142
+ EOF
143
+ runner.prepare('app/models/post.rb', content)
144
+ runner.review('app/models/post.rb', content)
145
+ content =<<-EOF
146
+ class PostsController < ApplicationController
147
+ def create
148
+ Post.new.save
149
+ end
150
+ end
151
+ EOF
152
+ runner.review('app/controllers/posts_controller.rb', content)
153
+ runner.on_complete
154
+ runner.should have(0).errors
155
+ end
156
+
157
+ it "should not remove unused method with validation condition" do
158
+ content =<<-EOF
159
+ class Post < ActiveRecord::Base
160
+ validates_uniqueness_of :login, :if => :email_blank?
161
+ private
162
+ def email_blank?; end
163
+ end
164
+ EOF
165
+ runner.prepare('app/models/post.rb', content)
166
+ runner.review('app/models/post.rb', content)
167
+ runner.on_complete
168
+ runner.should have(0).errors
169
+ end
170
+
171
+ it "should not remove unused method with aasm" do
172
+ content =<<-EOF
173
+ class Post < ActiveRecord::Base
174
+ aasm_state :accepted, :enter => [:update_datetime]
175
+ private
176
+ def update_datetime; end
177
+ end
178
+ EOF
179
+ runner.prepare('app/models/post.rb', content)
180
+ runner.review('app/models/post.rb', content)
181
+ runner.on_complete
182
+ runner.should have(0).errors
183
+ end
184
+
185
+ it "should not remove unused method with initialize" do
186
+ content =<<-EOF
187
+ class Post < ActiveRecord::Base
188
+ private
189
+ def initialize; end
190
+ end
191
+ EOF
192
+ runner.prepare('app/models/post.rb', content)
193
+ runner.review('app/models/post.rb', content)
194
+ runner.on_complete
195
+ runner.should have(0).errors
196
+ end
197
+ end
198
+
199
+ context "public" do
200
+ it "should remove unused methods" do
201
+ content =<<-EOF
202
+ class Post < ActiveRecord::Base
203
+ def fetch; end
204
+ end
205
+ EOF
206
+ runner.prepare('app/models/post.rb', content)
207
+ runner.on_complete
208
+ runner.should have(1).errors
209
+ runner.errors[0].to_s.should == "app/models/post.rb:2 - remove unused methods (Post#fetch)"
210
+ end
211
+
212
+ it "should not remove unused methods" do
213
+ content =<<-EOF
214
+ class Post < ActiveRecord::Base
215
+ def fetch; end
216
+ end
217
+ EOF
218
+ runner.prepare('app/models/post.rb', content)
219
+ content =<<-EOF
220
+ class PostsController < ApplicationController
221
+ def show
222
+ @post.fetch
223
+ end
224
+ end
225
+ EOF
226
+ runner.review('app/controllers/posts_controller.rb', content)
227
+ runner.on_complete
228
+ runner.should have(0).errors
229
+ end
230
+
231
+ it "should not remove unused methods for attribute assignment" do
232
+ content =<<-EOF
233
+ class Post < ActiveRecord::Base
234
+ def user=(user); end
235
+ end
236
+ EOF
237
+ runner.prepare('app/models/post.rb', content)
238
+ runner.review('app/models/post.rb', content)
239
+ runner.on_complete
240
+ runner.should have(0).errors
241
+ end
242
+
243
+ it "should not remove unused methods for try" do
244
+ content =<<-EOF
245
+ class Post < ActiveRecord::Base
246
+ def find(user_id); end
247
+ end
248
+ EOF
249
+ runner.prepare('app/models/post.rb', content)
250
+ runner.review('app/models/post.rb', content)
251
+ content =<<-EOF
252
+ class PostsController < ApplicationController
253
+ def find
254
+ Post.new.try(:find, current_user.id)
255
+ end
256
+ end
257
+ EOF
258
+ runner.review('app/controllers/posts_controller.rb', content)
259
+ runner.on_complete
260
+ runner.should have(0).errors
261
+ end
262
+ end
263
+
264
+ context "protected" do
265
+ it "should not remove unused methods" do
266
+ content =<<-EOF
267
+ class Post < ActiveRecord::Base
268
+ protected
269
+ def test; end
270
+ end
271
+ EOF
272
+ runner.prepare("app/models/post.rb", content)
273
+ runner.review("app/models/post.rb", content)
274
+ content =<<-EOF
275
+ class PostsController < ApplicationController
276
+ def test
277
+ Post.new.test
278
+ end
279
+ end
280
+ EOF
281
+ runner.review('app/controllers/posts_controller.rb', content)
282
+ runner.on_complete
283
+ runner.should have(1).errors
284
+ runner.errors[0].to_s.should == "app/models/post.rb:3 - remove unused methods (Post#test)"
285
+ end
286
+
287
+ it "should not remove unused methods" do
288
+ post_content =<<-EOF
289
+ class Post < ActiveRecord::Base
290
+ protected
291
+ def test; end
292
+ end
293
+ EOF
294
+ blog_post_content =<<-EOF
295
+ class BlogPost < Post
296
+ def play
297
+ test
298
+ end
299
+ end
300
+ EOF
301
+ runner.prepare("app/models/post.rb", post_content)
302
+ runner.prepare("app/models/blog_post.rb", blog_post_content)
303
+ runner.review("app/models/post.rb", post_content)
304
+ runner.review("app/models/blog_post.rb", blog_post_content)
305
+ content =<<-EOF
306
+ class BlogPostsController < ApplicationController
307
+ def play
308
+ BlogPost.new.play
309
+ end
310
+ end
311
+ EOF
312
+ runner.review('app/controllers/posts_controller.rb', content)
313
+ runner.on_complete
314
+ runner.should have(0).errors
315
+ end
316
+ end
317
+
318
+ context "named_scope" do
319
+ it "should not remove unused named_scope" do
320
+ content =<<-EOF
321
+ class Post < ActiveRecord::Base
322
+ named_scope :active, :conditions => {:active => true}
323
+ end
324
+ EOF
325
+ runner.prepare("app/models/post.rb", content)
326
+ runner.review("app/models/post.rb", content)
327
+ content =<<-EOF
328
+ class PostsController < ApplicationController
329
+ def index
330
+ @posts = Post.active
331
+ end
332
+ end
333
+ EOF
334
+ runner.review("app/controllers/posts_controller.rb", content)
335
+ runner.on_complete
336
+ runner.should have(0).errors
337
+ end
338
+
339
+ it "should remove unused named_scope" do
340
+ content =<<-EOF
341
+ class Post < ActiveRecord::Base
342
+ named_scope :active, :conditions => {:active => true}
343
+ end
344
+ EOF
345
+ runner.prepare("app/models/post.rb", content)
346
+ runner.review("app/models/post.rb", content)
347
+ runner.on_complete
348
+ runner.should have(1).errors
349
+ runner.errors[0].to_s.should == "app/models/post.rb:2 - remove unused methods (Post#active)"
350
+ end
351
+ end
352
+
353
+ context "scope" do
354
+ it "should not remove unused scope" do
355
+ content =<<-EOF
356
+ class Post < ActiveRecord::Base
357
+ scope :active, where(:active => true)
358
+ end
359
+ EOF
360
+ runner.prepare("app/models/post.rb", content)
361
+ runner.review("app/models/post.rb", content)
362
+ content =<<-EOF
363
+ class PostsController < ApplicationController
364
+ def index
365
+ @posts = Post.active
366
+ end
367
+ end
368
+ EOF
369
+ runner.review("app/controllers/posts_controller.rb", content)
370
+ runner.on_complete
371
+ runner.should have(0).errors
372
+ end
373
+
374
+ it "should remove unused named_scope" do
375
+ content =<<-EOF
376
+ class Post < ActiveRecord::Base
377
+ scope :active, where(:active => true)
378
+ end
379
+ EOF
380
+ runner.prepare("app/models/post.rb", content)
381
+ runner.review("app/models/post.rb", content)
382
+ runner.on_complete
383
+ runner.should have(1).errors
384
+ runner.errors[0].to_s.should == "app/models/post.rb:2 - remove unused methods (Post#active)"
385
+ end
386
+ end
387
+ end