rails_best_practices 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/Gemfile +0 -1
  2. data/README.md +28 -24
  3. data/Rakefile +0 -8
  4. data/install_supported_rubies.sh +2 -3
  5. data/lib/rails_best_practices.rb +8 -7
  6. data/lib/rails_best_practices/core.rb +1 -0
  7. data/lib/rails_best_practices/core/check.rb +68 -0
  8. data/lib/rails_best_practices/core/checking_visitor.rb +18 -15
  9. data/lib/rails_best_practices/core/runner.rb +22 -12
  10. data/lib/rails_best_practices/core/visitable_sexp.rb +6 -2
  11. data/lib/rails_best_practices/prepares.rb +11 -0
  12. data/lib/rails_best_practices/prepares/mailer_prepare.rb +33 -0
  13. data/lib/rails_best_practices/prepares/model_prepare.rb +60 -0
  14. data/lib/rails_best_practices/reviews.rb +23 -0
  15. data/lib/rails_best_practices/{checks/add_model_virtual_attribute_check.rb → reviews/add_model_virtual_attribute_review.rb} +6 -9
  16. data/lib/rails_best_practices/{checks/always_add_db_index_check.rb → reviews/always_add_db_index_review.rb} +9 -12
  17. data/lib/rails_best_practices/{checks/dry_bundler_in_capistrano_check.rb → reviews/dry_bundler_in_capistrano_review.rb} +8 -11
  18. data/lib/rails_best_practices/{checks/isolate_seed_data_check.rb → reviews/isolate_seed_data_review.rb} +11 -14
  19. data/lib/rails_best_practices/{checks/keep_finders_on_their_own_model_check.rb → reviews/keep_finders_on_their_own_model_review.rb} +7 -10
  20. data/lib/rails_best_practices/{checks/law_of_demeter_check.rb → reviews/law_of_demeter_review.rb} +10 -14
  21. data/lib/rails_best_practices/{checks/move_code_into_controller_check.rb → reviews/move_code_into_controller_review.rb} +8 -11
  22. data/lib/rails_best_practices/{checks/move_code_into_helper_check.rb → reviews/move_code_into_helper_review.rb} +7 -10
  23. data/lib/rails_best_practices/{checks/move_code_into_model_check.rb → reviews/move_code_into_model_review.rb} +7 -10
  24. data/lib/rails_best_practices/{checks/move_finder_to_named_scope_check.rb → reviews/move_finder_to_named_scope_review.rb} +7 -10
  25. data/lib/rails_best_practices/{checks/move_model_logic_into_model_check.rb → reviews/move_model_logic_into_model_review.rb} +8 -11
  26. data/lib/rails_best_practices/{checks/needless_deep_nesting_check.rb → reviews/needless_deep_nesting_review.rb} +8 -11
  27. data/lib/rails_best_practices/{checks/not_use_default_route_check.rb → reviews/not_use_default_route_review.rb} +7 -10
  28. data/lib/rails_best_practices/{checks/overuse_route_customizations_check.rb → reviews/overuse_route_customizations_review.rb} +10 -13
  29. data/lib/rails_best_practices/{checks/replace_complex_creation_with_factory_method_check.rb → reviews/replace_complex_creation_with_factory_method_review.rb} +8 -11
  30. data/lib/rails_best_practices/{checks/replace_instance_variable_with_local_variable_check.rb → reviews/replace_instance_variable_with_local_variable_review.rb} +7 -10
  31. data/lib/rails_best_practices/reviews/review.rb +92 -0
  32. data/lib/rails_best_practices/{checks/use_before_filter_check.rb → reviews/use_before_filter_review.rb} +8 -11
  33. data/lib/rails_best_practices/{checks/use_model_association_check.rb → reviews/use_model_association_review.rb} +8 -11
  34. data/lib/rails_best_practices/{checks/use_observer_check.rb → reviews/use_observer_review.rb} +14 -41
  35. data/lib/rails_best_practices/{checks/use_query_attribute_check.rb → reviews/use_query_attribute_review.rb} +20 -16
  36. data/lib/rails_best_practices/{checks/use_say_with_time_in_migrations_check.rb → reviews/use_say_with_time_in_migrations_review.rb} +8 -11
  37. data/lib/rails_best_practices/{checks/use_scope_access_check.rb → reviews/use_scope_access_review.rb} +8 -11
  38. data/lib/rails_best_practices/version.rb +1 -1
  39. data/rails_best_practices.gemspec +3 -2
  40. data/rails_best_practices.yml +22 -22
  41. data/rake_rubies.sh +3 -2
  42. data/spec/rails_best_practices/core/check_spec.rb +41 -0
  43. data/spec/rails_best_practices/core/checking_visitor_spec.rb +78 -0
  44. data/spec/rails_best_practices/core/visitable_sexp_spec.rb +39 -36
  45. data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +14 -0
  46. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +22 -0
  47. data/spec/rails_best_practices/{checks/add_model_virtual_attribute_check_spec.rb → reviews/add_model_virtual_attribute_review_spec.rb} +17 -25
  48. data/spec/rails_best_practices/{checks/always_add_db_index_check_spec.rb → reviews/always_add_db_index_review_spec.rb} +28 -41
  49. data/spec/rails_best_practices/{checks/dry_bundler_in_capistrano_check_spec.rb → reviews/dry_bundler_in_capistrano_review_spec.rb} +7 -11
  50. data/spec/rails_best_practices/{checks/isolate_seed_data_check_spec.rb → reviews/isolate_seed_data_review_spec.rb} +13 -20
  51. data/spec/rails_best_practices/{checks/keep_finders_on_their_own_model_check_spec.rb → reviews/keep_finders_on_their_own_model_review_spec.rb} +16 -24
  52. data/spec/rails_best_practices/{checks/law_of_demeter_check_spec.rb → reviews/law_of_demeter_review_spec.rb} +24 -26
  53. data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +29 -0
  54. data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +24 -0
  55. data/spec/rails_best_practices/{checks/move_code_into_model_check_spec.rb → reviews/move_code_into_model_review_spec.rb} +12 -18
  56. data/spec/rails_best_practices/{checks/move_finder_to_named_scope_check_spec.rb → reviews/move_finder_to_named_scope_review_spec.rb} +12 -16
  57. data/spec/rails_best_practices/{checks/move_model_logic_into_model_check_spec.rb → reviews/move_model_logic_into_model_review_spec.rb} +7 -11
  58. data/spec/rails_best_practices/{checks/needless_deep_nesting_check_spec.rb → reviews/needless_deep_nesting_review_spec.rb} +26 -37
  59. data/spec/rails_best_practices/{checks/not_use_default_route_check_spec.rb → reviews/not_use_default_route_review_spec.rb} +13 -19
  60. data/spec/rails_best_practices/{checks/overuse_route_customizations_check_spec.rb → reviews/overuse_route_customizations_review_spec.rb} +27 -39
  61. data/spec/rails_best_practices/{checks/replace_complex_creation_with_factory_method_check_spec.rb → reviews/replace_complex_creation_with_factory_method_review_spec.rb} +10 -15
  62. data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +31 -0
  63. data/spec/rails_best_practices/reviews/review_spec.rb +11 -0
  64. data/spec/rails_best_practices/{checks/use_before_filter_check_spec.rb → reviews/use_before_filter_review_spec.rb} +11 -17
  65. data/spec/rails_best_practices/{checks/use_model_association_check_spec.rb → reviews/use_model_association_review_spec.rb} +12 -18
  66. data/spec/rails_best_practices/{checks/use_observer_check_spec.rb → reviews/use_observer_review_spec.rb} +28 -29
  67. data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +190 -0
  68. data/spec/rails_best_practices/{checks/use_say_with_time_in_migrations_check_spec.rb → reviews/use_say_with_time_in_migrations_review_spec.rb} +14 -23
  69. data/spec/rails_best_practices/{checks/use_scope_access_check_spec.rb → reviews/use_scope_access_review_spec.rb} +28 -37
  70. data/spec/rails_best_practices_spec.rb +4 -4
  71. data/spec/spec_helper.rb +1 -0
  72. metadata +128 -102
  73. data/lib/rails_best_practices/checks.rb +0 -23
  74. data/lib/rails_best_practices/checks/check.rb +0 -203
  75. data/spec/rails_best_practices/checks/check_spec.rb +0 -57
  76. data/spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb +0 -33
  77. data/spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb +0 -28
  78. data/spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb +0 -36
  79. data/spec/rails_best_practices/checks/use_query_attribute_check_spec.rb +0 -192
@@ -1,31 +1,28 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check a view file to make sure there is no complex logic call for model.
5
+ module Reviews
6
+ # Review a view file to make sure there is no complex logic call for model.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/25-move-code-into-model.
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # check if there are multiple method calls or attribute assignments apply to one subject,
17
14
  # and the subject is a local variable or instance variable,
18
15
  # then they should be moved into model.
19
- class MoveCodeIntoModelCheck < Check
16
+ class MoveCodeIntoModelReview < Review
20
17
  def url
21
18
  "http://rails-bestpractices.com/posts/25-move-code-into-model"
22
19
  end
23
20
 
24
- def interesting_review_nodes
21
+ def interesting_nodes
25
22
  [:if]
26
23
  end
27
24
 
28
- def interesting_review_files
25
+ def interesting_files
29
26
  VIEW_FILES
30
27
  end
31
28
 
@@ -41,7 +38,7 @@ module RailsBestPractices
41
38
  # if there are multiple call and attrasgn nodes who have the same subject,
42
39
  # and the subject is a local variable or an instance variable,
43
40
  # then the conditional statement nodes should be moved into model.
44
- def review_start_if(node)
41
+ def start_if(node)
45
42
  node.conditional_statement.grep_nodes(:node_type => [:call, :attrasgn]) { |child_node| remember_variable_use_count(child_node) }
46
43
 
47
44
  variable_use_count.each do |variable_node, count|
@@ -1,23 +1,20 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check a controller file to make sure there are no complex finder.
5
+ module Reviews
6
+ # Review a controller file to make sure there are no complex finder.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/1-move-finder-to-named_scope.
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # check all method calls in controller files.
17
14
  # if there is any call node with message find, all, first or last,
18
15
  # and it has a hash argument,
19
16
  # then it is a complex finder, and should be moved to model's named scope.
20
- class MoveFinderToNamedScopeCheck < Check
17
+ class MoveFinderToNamedScopeReview < Review
21
18
 
22
19
  FINDER = [:find, :all, :first, :last]
23
20
 
@@ -25,18 +22,18 @@ module RailsBestPractices
25
22
  "http://rails-bestpractices.com/posts/1-move-finder-to-named_scope"
26
23
  end
27
24
 
28
- def interesting_review_nodes
25
+ def interesting_nodes
29
26
  [:call]
30
27
  end
31
28
 
32
- def interesting_review_files
29
+ def interesting_files
33
30
  CONTROLLER_FILES
34
31
  end
35
32
 
36
33
  # check call node if its message is one of :find, :all, :first or :last,
37
34
  # and it has a hash argument,
38
35
  # then the call node is the finder that should be moved to model's named_scope.
39
- def review_start_call(node)
36
+ def start_call(node)
40
37
  add_error "move finder to named_scope" if finder?(node)
41
38
  end
42
39
 
@@ -1,32 +1,29 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check a controller file to make sure that complex model logic should not exist in controller, should be moved into a model.
5
+ module Reviews
6
+ # Review a controller file to make sure that complex model logic should not exist in controller, should be moved into a model.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/7-move-model-logic-into-the-model.
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # check all method defines in the controller files,
17
14
  # if there are multiple method calls or attribute assignments apply to one subject,
18
15
  # and the subject is a local variable or an instance variable,
19
16
  # then they are complex model logic, and they should be moved into model.
20
- class MoveModelLogicIntoModelCheck < Check
17
+ class MoveModelLogicIntoModelReview < Review
21
18
  def url
22
19
  "http://rails-bestpractices.com/posts/7-move-model-logic-into-the-model"
23
20
  end
24
21
 
25
- def interesting_review_nodes
22
+ def interesting_nodes
26
23
  [:defn]
27
24
  end
28
25
 
29
- def interesting_review_files
26
+ def interesting_files
30
27
  CONTROLLER_FILES
31
28
  end
32
29
 
@@ -35,13 +32,13 @@ module RailsBestPractices
35
32
  @use_count = options['use_count'] || 4
36
33
  end
37
34
 
38
- # check method define node to see if there are multiple method calls and attribute assignments (more than @use_count defined) on one local variable or instance varialbe in review process.
35
+ # check method define node to see if there are multiple method calls and attribute assignments (more than @use_count defined) on one local variable or instance varialbe.
39
36
  #
40
37
  # it will check every call and attrasgn nodes,
41
38
  # if there are multiple call and attrasgn nodes who have the same subject,
42
39
  # and the subject is a local variable or an instance variable,
43
40
  # then these method calls and attribute assignments should be moved into model.
44
- def review_start_defn(node)
41
+ def start_defn(node)
45
42
  node.grep_nodes(:node_type => [:call, :attrasgn]) do |child_node|
46
43
  remember_variable_use_count(child_node)
47
44
  end
@@ -1,17 +1,14 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check config/routes.rb file to make sure not to use too deep nesting routes.
5
+ module Reviews
6
+ # Review config/routes.rb file to make sure not to use too deep nesting routes.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/11-needless-deep-nesting.
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # chech all iter nodes in route file.
17
14
  #
@@ -29,16 +26,16 @@ module RailsBestPractices
29
26
  # and the message of the node is :resources or :resource,
30
27
  # and the @counter is greater than @nested_count defined,
31
28
  # then it is a needless deep nesting.
32
- class NeedlessDeepNestingCheck < Check
29
+ class NeedlessDeepNestingReview < Review
33
30
  def url
34
31
  "http://rails-bestpractices.com/posts/11-needless-deep-nesting"
35
32
  end
36
33
 
37
- def interesting_review_nodes
34
+ def interesting_nodes
38
35
  [:call, :iter]
39
36
  end
40
37
 
41
- def interesting_review_files
38
+ def interesting_files
42
39
  ROUTE_FILE
43
40
  end
44
41
 
@@ -48,7 +45,7 @@ module RailsBestPractices
48
45
  @nested_count = options['nested_count'] || 2
49
46
  end
50
47
 
51
- # check all iter node in review process.
48
+ # check all iter node.
52
49
  #
53
50
  # It is a recursively check,
54
51
  #
@@ -76,7 +73,7 @@ module RailsBestPractices
76
73
  #
77
74
  # test if the @counter is greater than or equal to @nested_count,
78
75
  # if so, it is a needless deep nesting.
79
- def review_start_iter(node)
76
+ def start_iter(node)
80
77
  recursively_check(node)
81
78
  end
82
79
 
@@ -1,17 +1,14 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check config/routes file to make sure not use default route that rails generated.
5
+ module Reviews
6
+ # Review config/routes file to make sure not use default route that rails generated.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/12-not-use-default-route-if-you-use-restful-design
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # check all method call to see if any method call is the same as rails default route.
17
14
  #
@@ -21,16 +18,16 @@ module RailsBestPractices
21
18
  # or
22
19
  #
23
20
  # match ':controller(/:action(/:id(.:format)))'
24
- class NotUseDefaultRouteCheck < Check
21
+ class NotUseDefaultRouteReview < Review
25
22
  def url
26
23
  "http://rails-bestpractices.com/posts/12-not-use-default-route-if-you-use-restful-design"
27
24
  end
28
25
 
29
- def interesting_review_nodes
26
+ def interesting_nodes
30
27
  [:call]
31
28
  end
32
29
 
33
- def interesting_review_files
30
+ def interesting_files
34
31
  ROUTE_FILE
35
32
  end
36
33
 
@@ -50,7 +47,7 @@ module RailsBestPractices
50
47
  # s(:call, nil, :match,
51
48
  # s(:arglist, s(:str, ":controller(/:action(/:id(.:format)))"))
52
49
  # )
53
- def review_start_call(node)
50
+ def start_call(node)
54
51
  if s(:call, s(:lvar, :map), :connect, s(:arglist, s(:str, ":controller/:action/:id"))) == node ||
55
52
  s(:call, s(:lvar, :map), :connect, s(:arglist, s(:str, ":controller/:action/:id.:format"))) == node ||
56
53
  s(:call, nil, :match, s(:arglist, s(:str, ":controller(/:action(/:id(.:format)))"))) == node
@@ -1,17 +1,14 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check config/routes.rb file to make sure there are no overuse route customizations.
5
+ module Reviews
6
+ # Review config/routes.rb file to make sure there are no overuse route customizations.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/10-overuse-route-customizations.
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # the check methods are different for rails2 and rails3 syntax.
17
14
  #
@@ -30,7 +27,7 @@ module RailsBestPractices
30
27
  # and in the block body of iter node, there are more than @customize_count call nodes,
31
28
  # whose message is :get, :post, :update or :delete,
32
29
  # then these custom routes are overuse.
33
- class OveruseRouteCustomizationsCheck < Check
30
+ class OveruseRouteCustomizationsReview < Review
34
31
 
35
32
  VERBS = [:get, :post, :update, :delete]
36
33
 
@@ -38,11 +35,11 @@ module RailsBestPractices
38
35
  "http://rails-bestpractices.com/posts/10-overuse-route-customizations"
39
36
  end
40
37
 
41
- def interesting_review_nodes
38
+ def interesting_nodes
42
39
  [:call, :iter]
43
40
  end
44
41
 
45
- def interesting_review_files
42
+ def interesting_files
46
43
  ROUTE_FILE
47
44
  end
48
45
 
@@ -51,7 +48,7 @@ module RailsBestPractices
51
48
  @customize_count = options['customize_count'] || 3
52
49
  end
53
50
 
54
- # check call node to see if the count of member and collection custom routes is more than @customize_count defined in review process.
51
+ # check call node to see if the count of member and collection custom routes is more than @customize_count defined.
55
52
  # this is for rails2 syntax.
56
53
  #
57
54
  # if the message of call node is :resources,
@@ -64,13 +61,13 @@ module RailsBestPractices
64
61
  # :collection => { :comments => :get }
65
62
  #
66
63
  # then they are overuse route customizations.
67
- def review_start_call(node)
64
+ def start_call(node)
68
65
  if member_and_collection_count_for_rails2(node) > @customize_count
69
66
  add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.subject.line
70
67
  end
71
68
  end
72
69
 
73
- # check iter node to see if the count of member and collection custom routes is more than @customize_count defined in review process.
70
+ # check iter node to see if the count of member and collection custom routes is more than @customize_count defined.
74
71
  # this is for rails3 syntax.
75
72
  #
76
73
  # if the subject of iter node is with message :resources,
@@ -90,7 +87,7 @@ module RailsBestPractices
90
87
  # end
91
88
  #
92
89
  # then they are overuse route customizations.
93
- def review_start_iter(node)
90
+ def start_iter(node)
94
91
  if member_and_collection_count_for_rails3(node) > @customize_count
95
92
  add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.subject.line
96
93
  end
@@ -1,33 +1,30 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check a controller file to make sure that complex model creation should not exist in controller, should be replaced with factory method.
5
+ module Reviews
6
+ # Review a controller file to make sure that complex model creation should not exist in controller, should be replaced with factory method.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/6-replace-complex-creation-with-factory-method.
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # check all method defines in the controller files,
17
14
  # if there are multiple attribute assignments apply to one subject,
18
15
  # and the subject is a local variable or an instance variable,
19
16
  # and after them there is a call node with message :save or :save!,
20
17
  # then these attribute assignments are complex creation, should be replaced with factory method.
21
- class ReplaceComplexCreationWithFactoryMethodCheck < Check
18
+ class ReplaceComplexCreationWithFactoryMethodReview < Review
22
19
  def url
23
20
  "http://rails-bestpractices.com/posts/6-replace-complex-creation-with-factory-method"
24
21
  end
25
22
 
26
- def interesting_review_nodes
23
+ def interesting_nodes
27
24
  [:defn]
28
25
  end
29
26
 
30
- def interesting_review_files
27
+ def interesting_files
31
28
  CONTROLLER_FILES
32
29
  end
33
30
 
@@ -36,14 +33,14 @@ module RailsBestPractices
36
33
  @attrasgn_count = options['attribute_assignment_count'] || 2
37
34
  end
38
35
 
39
- # check method define node to see if there are multiple attribute assignments, more than @attrasgn_count, on one local variable or instance variable before save in review process.
36
+ # check method define node to see if there are multiple attribute assignments, more than @attrasgn_count, on one local variable or instance variable before save.
40
37
  #
41
38
  # it wll check every attrasgn nodes in method define node,
42
39
  # if there are multiple attrasgn nodes who have the same subject,
43
40
  # and the subject is a local variable or an instance variable,
44
41
  # and after them, there is a call node with message :save or :save!,
45
42
  # then these attribute assignments are complex creation, should be replaced with factory method.
46
- def review_start_defn(node)
43
+ def start_defn(node)
47
44
  node.recursive_children do |child_node|
48
45
  case child_node.node_type
49
46
  when :attrasgn
@@ -1,36 +1,33 @@
1
1
  # encoding: utf-8
2
- require 'rails_best_practices/checks/check'
2
+ require 'rails_best_practices/reviews/review'
3
3
 
4
4
  module RailsBestPractices
5
- module Checks
6
- # Check a partail view file to make sure there is no instance variable.
5
+ module Reviews
6
+ # Review a partail view file to make sure there is no instance variable.
7
7
  #
8
8
  # See the best practice details here http://rails-bestpractices.com/posts/27-replace-instance-variable-with-local-variable.
9
9
  #
10
10
  # Implementation:
11
11
  #
12
- # Prepare process:
13
- # none
14
- #
15
12
  # Review process:
16
13
  # check all instance variable in partial view files,
17
14
  # if exist, then they should be replaced with local variable
18
- class ReplaceInstanceVariableWithLocalVariableCheck < Check
15
+ class ReplaceInstanceVariableWithLocalVariableReview < Review
19
16
  def url
20
17
  "http://rails-bestpractices.com/posts/27-replace-instance-variable-with-local-variable"
21
18
  end
22
19
 
23
- def interesting_review_nodes
20
+ def interesting_nodes
24
21
  [:ivar]
25
22
  end
26
23
 
27
- def interesting_review_files
24
+ def interesting_files
28
25
  PARTIAL_VIEW_FILES
29
26
  end
30
27
 
31
28
  # check ivar node in partial view file,
32
29
  # it is an instance variable, and should be replaced with local variable.
33
- def review_start_ivar(node)
30
+ def start_ivar(node)
34
31
  add_error "replace instance variable with local variable"
35
32
  end
36
33
  end
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+ require 'rails_best_practices/core/check'
3
+ require 'rails_best_practices/core/error'
4
+
5
+ module RailsBestPractices
6
+ module Reviews
7
+ # A Review class that takes charge of reviewing one rails best practice.
8
+ class Review < Core::Check
9
+ attr_reader :errors
10
+
11
+ def initialize
12
+ super
13
+ @errors = []
14
+ end
15
+
16
+ # add error if source code violates rails best practice.
17
+ # error is the string message for violation of the rails best practice
18
+ # file is the filename of source code
19
+ # line is the line number of the source code which is reviewing
20
+ def add_error(error, file = @node.file, line = @node.line)
21
+ @errors << RailsBestPractices::Core::Error.new("#{file}", "#{line}", error, url)
22
+ end
23
+
24
+ # remember use count for the local or instance variable in the call or attrasgn node.
25
+ #
26
+ # find the local variable or instance variable in the call or attrasgn node,
27
+ # then save it to as key in @variable_use_count hash, and add the call count (hash value).
28
+ def remember_variable_use_count(node)
29
+ variable_node = variable(node)
30
+ if variable_node
31
+ variable_use_count[variable_node] ||= 0
32
+ variable_use_count[variable_node] += 1
33
+ end
34
+ end
35
+
36
+ # return @variable_use_count hash.
37
+ def variable_use_count
38
+ @variable_use_count ||= {}
39
+ end
40
+
41
+ # reset @variable_use_count hash.
42
+ def reset_variable_use_count
43
+ @variable_use_count = nil
44
+ end
45
+
46
+ # find local variable or instance variable in the most inner call node, e.g.
47
+ #
48
+ # if the call node is
49
+ #
50
+ # s(:call, s(:ivar, :@post), :editors, s(:arglist)),
51
+ #
52
+ # or it is
53
+ #
54
+ # s(:call,
55
+ # s(:call, s(:ivar, :@post), :editors, s(:arglist)),
56
+ # :include?,
57
+ # s(:arglist, s(:call, nil, :current_user, s(:arglist)))
58
+ # )
59
+ #
60
+ # then the variable both are s(:ivar, :@post).
61
+ #
62
+ def variable(node)
63
+ while node.subject.node_type == :call
64
+ node = node.subject
65
+ end
66
+ subject_node = node.subject
67
+ if [:ivar, :lvar].include?(subject_node.node_type) and subject_node[1] != :_erbout
68
+ subject_node
69
+ else
70
+ nil
71
+ end
72
+ end
73
+
74
+ # get the model associations from Prepares.
75
+ #
76
+ # @return [Hash]
77
+ def model_associations
78
+ @model_associations ||= Prepares.model_associations
79
+ end
80
+
81
+ # compare two sexp nodes' to_s.
82
+ #
83
+ # equal?(":test", :test) => true
84
+ # equai?("@test", :test) => true
85
+ def equal?(node, expected_node)
86
+ actual = node.to_s.downcase
87
+ expected = expected_node.to_s.downcase
88
+ actual == expected || actual == ':' + expected || actual == '@' + expected
89
+ end
90
+ end
91
+ end
92
+ end