rails_best_practices 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +41 -0
  3. data/Rakefile +31 -0
  4. data/VERSION +1 -0
  5. data/bin/rails_best_practices +6 -0
  6. data/lib/rails_best_practices.rb +5 -0
  7. data/lib/rails_best_practices/checks.rb +9 -0
  8. data/lib/rails_best_practices/checks/add_model_virtual_attribute_check.rb +57 -0
  9. data/lib/rails_best_practices/checks/check.rb +59 -0
  10. data/lib/rails_best_practices/checks/many_to_many_collection_check.rb +12 -0
  11. data/lib/rails_best_practices/checks/move_finder_to_named_scope_check.rb +33 -0
  12. data/lib/rails_best_practices/checks/move_model_logic_into_model_check.rb +48 -0
  13. data/lib/rails_best_practices/checks/nested_model_forms_check.rb +12 -0
  14. data/lib/rails_best_practices/checks/replace_complex_creation_with_factory_method_check.rb +55 -0
  15. data/lib/rails_best_practices/checks/use_model_association_check.rb +47 -0
  16. data/lib/rails_best_practices/checks/use_model_callback_check.rb +12 -0
  17. data/lib/rails_best_practices/checks/use_scope_access_check.rb +38 -0
  18. data/lib/rails_best_practices/command.rb +32 -0
  19. data/lib/rails_best_practices/core.rb +5 -0
  20. data/lib/rails_best_practices/core/checking_visitor.rb +26 -0
  21. data/lib/rails_best_practices/core/core_ext.rb +11 -0
  22. data/lib/rails_best_practices/core/error.rb +17 -0
  23. data/lib/rails_best_practices/core/runner.rb +59 -0
  24. data/lib/rails_best_practices/core/visitable_sexp.rb +102 -0
  25. data/rails_best_practices.yml +7 -0
  26. data/spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb +60 -0
  27. data/spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb +11 -0
  28. data/spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb +82 -0
  29. data/spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb +49 -0
  30. data/spec/rails_best_practices/checks/nested_model_forms_check_spec.rb +11 -0
  31. data/spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb +21 -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/use_model_association_check_spec.rb +71 -0
  34. data/spec/rails_best_practices/checks/use_model_callback_check_spec.rb +11 -0
  35. data/spec/rails_best_practices/checks/use_scope_access_check_spec.rb +171 -0
  36. data/spec/spec.opts +8 -0
  37. data/spec/spec_helper.rb +5 -0
  38. metadata +101 -0
@@ -0,0 +1,49 @@
1
+ require File.join(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe RailsBestPractices::Checks::MoveModelLogicIntoModelCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::MoveModelLogicIntoModelCheck.new)
6
+ end
7
+
8
+ it "should move model logic into model" do
9
+ content = <<-EOF
10
+ class PostsController < ApplicationController
11
+
12
+ def publish
13
+ @post = Post.find(params[:id])
14
+ @post.update_attributes(:is_published, true)
15
+ @post.approved_by = current_user
16
+ if @post.created_at > Time.now - 7.days
17
+ @post.popular = 100
18
+ else
19
+ @post.popular = 0
20
+ end
21
+ end
22
+
23
+ redirect_to post_url(@post)
24
+ end
25
+ EOF
26
+ @runner.check('app/controller/posts_controller.rb', content)
27
+ errors = @runner.errors
28
+ errors.should_not be_empty
29
+ errors[0].to_s.should == "app/controller/posts_controller.rb:3 - move model logic into model"
30
+ end
31
+
32
+ it "should not move model logic into model with simple model calling" do
33
+ content = <<-EOF
34
+ class PostsController < ApplicationController
35
+
36
+ def publish
37
+ @post = Post.find(params[:id])
38
+ @post.update_attributes(:is_published, true)
39
+ @post.approved_by = current_user
40
+ end
41
+
42
+ redirect_to post_url(@post)
43
+ end
44
+ EOF
45
+ @runner.check('app/controller/posts_controller.rb', content)
46
+ errors = @runner.errors
47
+ errors.should be_empty
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe RailsBestPractices::Checks::NestedModelFormsCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::NestedModelFormsCheck.new)
6
+ end
7
+
8
+ it "should nested model form check" do
9
+ pending
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__) + '/../../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
+ it "should overuse route customizations" do
9
+ content = <<-EOF
10
+ ActionController::Routing::Routes.draw do |map|
11
+ map.resources :posts, :member => { :comments => :get,
12
+ :create_comment => :post,
13
+ :udpate_comment => :post,
14
+ :delete_comment => :post }
15
+ end
16
+ EOF
17
+ @runner.check('config/routes.rb', content)
18
+ errors = @runner.errors
19
+ errors.should_not be_empty
20
+ end
21
+ end
@@ -0,0 +1,76 @@
1
+ require File.join(File.dirname(__FILE__) + '/../../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.check('app/controller/invoices_controller.rb', content)
29
+ errors = @runner.errors
30
+ errors.should_not be_empty
31
+ errors[0].to_s.should == "app/controller/invoices_controller.rb:3 - replace complex creation with factory method"
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.check('app/controller/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.check('app/controller/invoices_controller.rb', content)
73
+ errors = @runner.errors
74
+ errors.should be_empty
75
+ end
76
+ end
@@ -0,0 +1,71 @@
1
+ require File.join(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe RailsBestPractices::Checks::UseModelAssociationCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::UseModelAssociationCheck.new)
6
+ end
7
+
8
+ it "should use model association for instance variable" do
9
+ content = <<-EOF
10
+ class PostsController < ApplicationController
11
+
12
+ def create
13
+ @post = Post.new(params[:post])
14
+ @post.user_id = current_user.id
15
+ @post.save
16
+ end
17
+ end
18
+ EOF
19
+ @runner.check('app/controller/posts_controller.rb', content)
20
+ errors = @runner.errors
21
+ errors.should_not be_empty
22
+ errors[0].to_s.should == "app/controller/posts_controller.rb:3 - use model association"
23
+ end
24
+
25
+ it "should not use model association without association assign" do
26
+ content = <<-EOF
27
+ class PostsController < ApplicationController
28
+
29
+ def create
30
+ @post = Post.new(params[:post])
31
+ @post.save
32
+ end
33
+ end
34
+ EOF
35
+ @runner.check('app/controller/posts_controller.rb', content)
36
+ errors = @runner.errors
37
+ errors.should be_empty
38
+ end
39
+
40
+ it "should use model association for local variable" do
41
+ content = <<-EOF
42
+ class PostsController < ApplicationController
43
+
44
+ def create
45
+ post = Post.new(params[:post])
46
+ post.user_id = current_user.id
47
+ post.save
48
+ end
49
+ end
50
+ EOF
51
+ @runner.check('app/controller/posts_controller.rb', content)
52
+ errors = @runner.errors
53
+ errors.should_not be_empty
54
+ errors[0].to_s.should == "app/controller/posts_controller.rb:3 - use model association"
55
+ end
56
+
57
+ it "should not use model association" do
58
+ content = <<-EOF
59
+ class PostsController < ApplicationController
60
+
61
+ def create
62
+ post = current_user.posts.buid(params[:post])
63
+ post.save
64
+ end
65
+ end
66
+ EOF
67
+ @runner.check('app/controller/posts_controller.rb', content)
68
+ errors = @runner.errors
69
+ errors.should be_empty
70
+ end
71
+ end
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe RailsBestPractices::Checks::UseModelCallbackCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::UseModelCallbackCheck.new)
6
+ end
7
+
8
+ it "should use model callback check" do
9
+ pending
10
+ end
11
+ end
@@ -0,0 +1,171 @@
1
+ require File.join(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe RailsBestPractices::Checks::UseScopeAccessCheck do
4
+ before(:each) do
5
+ @runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::UseScopeAccessCheck.new)
6
+ end
7
+
8
+ context "if" do
9
+ it "shoud use scope access" do
10
+ content = <<-EOF
11
+ class PostsController < ApplicationController
12
+
13
+ def edit
14
+ @post = Post.find(params[:id])
15
+
16
+ if @post.user != current_user
17
+ flash[:warning] = 'Access Denied'
18
+ redirect_to posts_url
19
+ end
20
+ end
21
+ end
22
+ EOF
23
+ @runner.check('app/controller/posts_controller.rb', content)
24
+ errors = @runner.errors
25
+ errors.should_not be_empty
26
+ errors[0].to_s.should == "app/controller/posts_controller.rb:7 - use scope access"
27
+ end
28
+
29
+ it "shoud use scope access by comparing with id" do
30
+ content = <<-EOF
31
+ class PostsController < ApplicationController
32
+
33
+ def edit
34
+ @post = Post.find(params[:id])
35
+
36
+ if @post.user_id != current_user.id
37
+ flash[:warning] = 'Access Denied'
38
+ redirect_to posts_url
39
+ end
40
+ end
41
+ end
42
+ EOF
43
+ @runner.check('app/controller/posts_controller.rb', content)
44
+ errors = @runner.errors
45
+ errors.should_not be_empty
46
+ errors[0].to_s.should == "app/controller/posts_controller.rb:7 - use scope access"
47
+ end
48
+
49
+ it "shoud use scope access with current_user ==" do
50
+ content = <<-EOF
51
+ class PostsController < ApplicationController
52
+
53
+ def edit
54
+ @post = Post.find(params[:id])
55
+
56
+ if current_user != @post.user
57
+ flash[:warning] = 'Access Denied'
58
+ redirect_to posts_url
59
+ end
60
+ end
61
+ end
62
+ EOF
63
+ @runner.check('app/controller/posts_controller.rb', content)
64
+ errors = @runner.errors
65
+ errors.should_not be_empty
66
+ errors[0].to_s.should == "app/controller/posts_controller.rb:7 - use scope access"
67
+ end
68
+
69
+ it "shoud use scope access by current_user.id ==" do
70
+ content = <<-EOF
71
+ class PostsController < ApplicationController
72
+
73
+ def edit
74
+ @post = Post.find(params[:id])
75
+
76
+ if current_user.id != @post.user_id
77
+ flash[:warning] = 'Access Denied'
78
+ redirect_to posts_url
79
+ end
80
+ end
81
+ end
82
+ EOF
83
+ @runner.check('app/controller/posts_controller.rb', content)
84
+ errors = @runner.errors
85
+ errors.should_not be_empty
86
+ errors[0].to_s.should == "app/controller/posts_controller.rb:7 - use scope access"
87
+ end
88
+ end
89
+
90
+ context "unless" do
91
+ it "shoud use scope access" do
92
+ content = <<-EOF
93
+ class PostsController < ApplicationController
94
+
95
+ def edit
96
+ @post = Post.find(params[:id])
97
+
98
+ unless @post.user == current_user
99
+ flash[:warning] = 'Access Denied'
100
+ redirect_to posts_url
101
+ end
102
+ end
103
+ end
104
+ EOF
105
+ @runner.check('app/controller/posts_controller.rb', content)
106
+ errors = @runner.errors
107
+ errors.should_not be_empty
108
+ errors[0].to_s.should == "app/controller/posts_controller.rb:6 - use scope access"
109
+ end
110
+
111
+ it "shoud use scope access by comparing with id" do
112
+ content = <<-EOF
113
+ class PostsController < ApplicationController
114
+
115
+ def edit
116
+ @post = Post.find(params[:id])
117
+
118
+ unless @post.user_id == current_user.id
119
+ flash[:warning] = 'Access Denied'
120
+ redirect_to posts_url
121
+ end
122
+ end
123
+ end
124
+ EOF
125
+ @runner.check('app/controller/posts_controller.rb', content)
126
+ errors = @runner.errors
127
+ errors.should_not be_empty
128
+ errors[0].to_s.should == "app/controller/posts_controller.rb:6 - use scope access"
129
+ end
130
+
131
+ it "shoud use scope access with current_user ==" do
132
+ content = <<-EOF
133
+ class PostsController < ApplicationController
134
+
135
+ def edit
136
+ @post = Post.find(params[:id])
137
+
138
+ unless current_user == @post.user
139
+ flash[:warning] = 'Access Denied'
140
+ redirect_to posts_url
141
+ end
142
+ end
143
+ end
144
+ EOF
145
+ @runner.check('app/controller/posts_controller.rb', content)
146
+ errors = @runner.errors
147
+ errors.should_not be_empty
148
+ errors[0].to_s.should == "app/controller/posts_controller.rb:6 - use scope access"
149
+ end
150
+
151
+ it "shoud use scope access by current_user.id ==" do
152
+ content = <<-EOF
153
+ class PostsController < ApplicationController
154
+
155
+ def edit
156
+ @post = Post.find(params[:id])
157
+
158
+ unless current_user.id == @post.user_id
159
+ flash[:warning] = 'Access Denied'
160
+ redirect_to posts_url
161
+ end
162
+ end
163
+ end
164
+ EOF
165
+ @runner.check('app/controller/posts_controller.rb', content)
166
+ errors = @runner.errors
167
+ errors.should_not be_empty
168
+ errors[0].to_s.should == "app/controller/posts_controller.rb:6 - use scope access"
169
+ end
170
+ end
171
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,8 @@
1
+ --colour
2
+ --format
3
+ specdoc
4
+ --reverse
5
+ --timeout
6
+ 20
7
+ --loadby
8
+ mtime
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'spec/autorun'
3
+
4
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
5
+ require 'rails_best_practices'
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_best_practices
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Richard Huang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-05 00:00:00 +08:00
13
+ default_executable: rails_best_practices
14
+ dependencies: []
15
+
16
+ description: ""
17
+ email: flyerhzm@gmail.com
18
+ executables:
19
+ - rails_best_practices
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.textile
25
+ files:
26
+ - LICENSE
27
+ - README.textile
28
+ - Rakefile
29
+ - VERSION
30
+ - bin/rails_best_practices
31
+ - lib/rails_best_practices.rb
32
+ - lib/rails_best_practices/checks.rb
33
+ - lib/rails_best_practices/checks/add_model_virtual_attribute_check.rb
34
+ - lib/rails_best_practices/checks/check.rb
35
+ - lib/rails_best_practices/checks/many_to_many_collection_check.rb
36
+ - lib/rails_best_practices/checks/move_finder_to_named_scope_check.rb
37
+ - lib/rails_best_practices/checks/move_model_logic_into_model_check.rb
38
+ - lib/rails_best_practices/checks/nested_model_forms_check.rb
39
+ - lib/rails_best_practices/checks/replace_complex_creation_with_factory_method_check.rb
40
+ - lib/rails_best_practices/checks/use_model_association_check.rb
41
+ - lib/rails_best_practices/checks/use_model_callback_check.rb
42
+ - lib/rails_best_practices/checks/use_scope_access_check.rb
43
+ - lib/rails_best_practices/command.rb
44
+ - lib/rails_best_practices/core.rb
45
+ - lib/rails_best_practices/core/checking_visitor.rb
46
+ - lib/rails_best_practices/core/core_ext.rb
47
+ - lib/rails_best_practices/core/error.rb
48
+ - lib/rails_best_practices/core/runner.rb
49
+ - lib/rails_best_practices/core/visitable_sexp.rb
50
+ - rails_best_practices.yml
51
+ - spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb
52
+ - spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb
53
+ - spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb
54
+ - spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb
55
+ - spec/rails_best_practices/checks/nested_model_forms_check_spec.rb
56
+ - spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb
57
+ - spec/rails_best_practices/checks/use_model_association_check_spec.rb
58
+ - spec/rails_best_practices/checks/use_model_callback_check_spec.rb
59
+ - spec/rails_best_practices/checks/use_scope_access_check_spec.rb
60
+ - spec/spec.opts
61
+ - spec/spec_helper.rb
62
+ has_rdoc: true
63
+ homepage: http://github.com/flyerhzm/rails_best_practices
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.5
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: ""
90
+ test_files:
91
+ - spec/rails_best_practices/checks/use_scope_access_check_spec.rb
92
+ - spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb
93
+ - spec/rails_best_practices/checks/use_model_callback_check_spec.rb
94
+ - spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb
95
+ - spec/rails_best_practices/checks/use_model_association_check_spec.rb
96
+ - spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb
97
+ - spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb
98
+ - spec/rails_best_practices/checks/nested_model_forms_check_spec.rb
99
+ - spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb
100
+ - spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb
101
+ - spec/spec_helper.rb