rails_best_practices 1.1.0 → 1.2.0

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