rails_best_practices 1.20.0 → 1.22.1

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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +49 -43
  5. data/Guardfile +2 -0
  6. data/Rakefile +2 -0
  7. data/assets/result.html.erb +2 -0
  8. data/lib/rails_best_practices/analyzer.rb +59 -48
  9. data/lib/rails_best_practices/core/check.rb +39 -32
  10. data/lib/rails_best_practices/core/checks_loader.rb +8 -6
  11. data/lib/rails_best_practices/core/configs.rb +1 -2
  12. data/lib/rails_best_practices/core/controllers.rb +1 -2
  13. data/lib/rails_best_practices/core/error.rb +1 -1
  14. data/lib/rails_best_practices/core/helpers.rb +1 -2
  15. data/lib/rails_best_practices/core/mailers.rb +1 -2
  16. data/lib/rails_best_practices/core/methods.rb +21 -16
  17. data/lib/rails_best_practices/core/model_associations.rb +9 -4
  18. data/lib/rails_best_practices/core/models.rb +1 -2
  19. data/lib/rails_best_practices/core/modules.rb +1 -1
  20. data/lib/rails_best_practices/core/routes.rb +2 -2
  21. data/lib/rails_best_practices/core/runner.rb +49 -34
  22. data/lib/rails_best_practices/inline_disables/comment_ripper.rb +19 -0
  23. data/lib/rails_best_practices/inline_disables/inline_disable.rb +50 -0
  24. data/lib/rails_best_practices/inline_disables.rb +3 -0
  25. data/lib/rails_best_practices/lexicals/long_line_check.rb +7 -3
  26. data/lib/rails_best_practices/option_parser.rb +22 -6
  27. data/lib/rails_best_practices/prepares/controller_prepare.rb +15 -3
  28. data/lib/rails_best_practices/prepares/gemfile_prepare.rb +1 -1
  29. data/lib/rails_best_practices/prepares/helper_prepare.rb +6 -1
  30. data/lib/rails_best_practices/prepares/initializer_prepare.rb +2 -2
  31. data/lib/rails_best_practices/prepares/mailer_prepare.rb +1 -0
  32. data/lib/rails_best_practices/prepares/model_prepare.rb +52 -12
  33. data/lib/rails_best_practices/prepares/route_prepare.rb +16 -10
  34. data/lib/rails_best_practices/prepares.rb +1 -1
  35. data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +15 -13
  36. data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +34 -29
  37. data/lib/rails_best_practices/reviews/check_destroy_return_value_review.rb +14 -5
  38. data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +19 -8
  39. data/lib/rails_best_practices/reviews/hash_syntax_review.rb +5 -5
  40. data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +4 -4
  41. data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +7 -8
  42. data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +6 -6
  43. data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +1 -1
  44. data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +6 -7
  45. data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +7 -8
  46. data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +12 -10
  47. data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +1 -2
  48. data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +5 -5
  49. data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +5 -2
  50. data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +6 -3
  51. data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +6 -4
  52. data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +29 -9
  53. data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +3 -3
  54. data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +17 -15
  55. data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +1 -2
  56. data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +3 -3
  57. data/lib/rails_best_practices/reviews/use_before_filter_review.rb +2 -1
  58. data/lib/rails_best_practices/reviews/use_model_association_review.rb +5 -5
  59. data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +9 -8
  60. data/lib/rails_best_practices/reviews/use_observer_review.rb +9 -9
  61. data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +26 -26
  62. data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +8 -7
  63. data/lib/rails_best_practices/reviews/use_scope_access_review.rb +17 -15
  64. data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +2 -1
  65. data/lib/rails_best_practices/version.rb +1 -1
  66. data/lib/rails_best_practices.rb +2 -2
  67. data/rails_best_practices.gemspec +39 -38
  68. data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +1 -2
  69. data/spec/rails_best_practices/analyzer_spec.rb +73 -42
  70. data/spec/rails_best_practices/core/check_spec.rb +5 -5
  71. data/spec/rails_best_practices/core/checks_loader_spec.rb +3 -3
  72. data/spec/rails_best_practices/core/configs_spec.rb +1 -1
  73. data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
  74. data/spec/rails_best_practices/core/error_spec.rb +21 -21
  75. data/spec/rails_best_practices/core/except_methods_spec.rb +7 -7
  76. data/spec/rails_best_practices/core/gems_spec.rb +4 -4
  77. data/spec/rails_best_practices/core/helpers_spec.rb +1 -1
  78. data/spec/rails_best_practices/core/klasses_spec.rb +3 -3
  79. data/spec/rails_best_practices/core/mailers_spec.rb +1 -1
  80. data/spec/rails_best_practices/core/methods_spec.rb +6 -6
  81. data/spec/rails_best_practices/core/model_associations_spec.rb +10 -6
  82. data/spec/rails_best_practices/core/model_attributes_spec.rb +4 -4
  83. data/spec/rails_best_practices/core/models_spec.rb +1 -1
  84. data/spec/rails_best_practices/core/modules_spec.rb +5 -5
  85. data/spec/rails_best_practices/core/routes_spec.rb +5 -5
  86. data/spec/rails_best_practices/core/runner_spec.rb +9 -7
  87. data/spec/rails_best_practices/core_ext/erubis_spec.rb +10 -10
  88. data/spec/rails_best_practices/inline_disables/inline_disable_spec.rb +62 -0
  89. data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +11 -10
  90. data/spec/rails_best_practices/lexicals/remove_tab_check_spec.rb +6 -6
  91. data/spec/rails_best_practices/lexicals/remove_trailing_whitespace_check_spec.rb +6 -6
  92. data/spec/rails_best_practices/prepares/config_prepare_spec.rb +2 -2
  93. data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +18 -10
  94. data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +2 -2
  95. data/spec/rails_best_practices/prepares/helper_prepare_spec.rb +3 -3
  96. data/spec/rails_best_practices/prepares/initializer_prepare_spec.rb +3 -3
  97. data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +2 -2
  98. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +79 -43
  99. data/spec/rails_best_practices/prepares/route_prepare_spec.rb +138 -77
  100. data/spec/rails_best_practices/prepares/schema_prepare_spec.rb +2 -2
  101. data/spec/rails_best_practices/reviews/add_model_virtual_attribute_review_spec.rb +18 -12
  102. data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +28 -22
  103. data/spec/rails_best_practices/reviews/check_destroy_return_value_review_spec.rb +15 -13
  104. data/spec/rails_best_practices/reviews/check_save_return_value_review_spec.rb +31 -21
  105. data/spec/rails_best_practices/reviews/default_scope_is_evil_review_spec.rb +6 -6
  106. data/spec/rails_best_practices/reviews/dry_bundler_in_capistrano_review_spec.rb +5 -5
  107. data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +9 -9
  108. data/spec/rails_best_practices/reviews/isolate_seed_data_review_spec.rb +7 -7
  109. data/spec/rails_best_practices/reviews/keep_finders_on_their_own_model_review_spec.rb +9 -9
  110. data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +21 -14
  111. data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +6 -6
  112. data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +11 -6
  113. data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +26 -16
  114. data/spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb +7 -7
  115. data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +9 -7
  116. data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +9 -9
  117. data/spec/rails_best_practices/reviews/not_rescue_exception_review_spec.rb +9 -9
  118. data/spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb +5 -5
  119. data/spec/rails_best_practices/reviews/not_use_time_ago_in_words_review_spec.rb +7 -7
  120. data/spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb +7 -7
  121. data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +24 -19
  122. data/spec/rails_best_practices/reviews/remove_empty_helpers_review_spec.rb +6 -6
  123. data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +44 -31
  124. data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +17 -12
  125. data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +46 -44
  126. data/spec/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review_spec.rb +10 -8
  127. data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +16 -10
  128. data/spec/rails_best_practices/reviews/restrict_auto_generated_routes_review_spec.rb +54 -31
  129. data/spec/rails_best_practices/reviews/simplify_render_in_controllers_review_spec.rb +9 -9
  130. data/spec/rails_best_practices/reviews/simplify_render_in_views_review_spec.rb +13 -13
  131. data/spec/rails_best_practices/reviews/use_before_filter_review_spec.rb +11 -9
  132. data/spec/rails_best_practices/reviews/use_model_association_review_spec.rb +7 -7
  133. data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +21 -17
  134. data/spec/rails_best_practices/reviews/use_observer_review_spec.rb +6 -6
  135. data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +9 -7
  136. data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +31 -24
  137. data/spec/rails_best_practices/reviews/use_say_with_time_in_migrations_review_spec.rb +15 -11
  138. data/spec/rails_best_practices/reviews/use_scope_access_review_spec.rb +14 -14
  139. data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +10 -8
  140. metadata +12 -7
@@ -20,15 +20,17 @@ module RailsBestPractices
20
20
  def initialize(options = {})
21
21
  super
22
22
  @helper_methods = Prepares.helper_methods
23
- self.class.interesting_files Prepares.helpers.map(&:descendants)
23
+ self.class.interesting_files *Prepares.helpers.map(&:descendants)
24
24
  end
25
25
 
26
26
  # get all unused methods at the end of review process
27
27
  add_callback :after_check do
28
28
  @helper_methods.get_all_unused_methods.each do |method|
29
- unless excepted?(method)
30
- add_error "remove unused methods (#{method.class_name}##{method.method_name})", method.file, method.line_number
31
- end
29
+ next if excepted?(method)
30
+
31
+ add_error "remove unused methods (#{method.class_name}##{method.method_name})",
32
+ method.file,
33
+ method.line_number
32
34
  end
33
35
  end
34
36
 
@@ -80,9 +80,11 @@ module RailsBestPractices
80
80
  # get all unused methods at the end of review process.
81
81
  add_callback :after_check do
82
82
  @model_methods.get_all_unused_methods.each do |method|
83
- if !excepted?(method) && method.method_name !~ /=$/
84
- add_error "remove unused methods (#{method.class_name}##{method.method_name})", method.file, method.line_number
85
- end
83
+ next unless !excepted?(method) && method.method_name !~ /=$/
84
+
85
+ add_error "remove unused methods (#{method.class_name}##{method.method_name})",
86
+ method.file,
87
+ method.line_number
86
88
  end
87
89
  end
88
90
 
@@ -95,13 +97,31 @@ module RailsBestPractices
95
97
  def internal_except_methods
96
98
  %w[
97
99
  initialize
98
- validate validate_each validate_on_create validate_on_update
99
- human_attribute_name assign_attributes attributes attribute
100
- to_xml to_json as_json to_param
101
- before_save before_create before_update before_destroy after_save after_create
102
- after_update after_destroy after_find after_initialize
100
+ validate
101
+ validate_each
102
+ validate_on_create
103
+ validate_on_update
104
+ human_attribute_name
105
+ assign_attributes
106
+ attributes
107
+ attribute
108
+ to_xml
109
+ to_json
110
+ as_json
111
+ to_param
112
+ before_save
113
+ before_create
114
+ before_update
115
+ before_destroy
116
+ after_save
117
+ after_create
118
+ after_update
119
+ after_destroy
120
+ after_find
121
+ after_initialize
103
122
  method_missing
104
- table_name module_prefix
123
+ table_name
124
+ module_prefix
105
125
  ].map { |method_name| "*\##{method_name}" }
106
126
  end
107
127
  end
@@ -49,9 +49,9 @@ module RailsBestPractices
49
49
 
50
50
  private
51
51
 
52
- # check the call node to see if it is with message "save" or "save!",
53
- # and the count attribute assignment on the receiver of the call node is greater than @assign_count defined,
54
- # then it is a complex creation, should be replaced with factory method.
52
+ # check the call node to see if it is with message "save" or "save!",
53
+ # and the count attribute assignment on the receiver of the call node is greater than @assign_count defined,
54
+ # then it is a complex creation, should be replaced with factory method.
55
55
  def check_variable_save(node)
56
56
  if ['save', 'save!'].include? node.message.to_s
57
57
  variable = node.receiver.to_s
@@ -95,32 +95,33 @@ module RailsBestPractices
95
95
 
96
96
  private
97
97
 
98
- # check resources call, if the routes generated by resources does not exist in the controller.
98
+ # check resources call, if the routes generated by resources does not exist in the controller.
99
99
  def check_resources(node)
100
100
  _check(node, resources_methods)
101
101
  end
102
102
 
103
- # check resource call, if the routes generated by resources does not exist in the controller.
103
+ # check resource call, if the routes generated by resources does not exist in the controller.
104
104
  def check_resource(node)
105
105
  _check(node, resource_methods)
106
106
  end
107
107
 
108
- # get the controller name.
108
+ # get the controller name.
109
109
  def controller_name(node)
110
110
  if option_with_hash(node)
111
111
  option_node = node.arguments.all[1]
112
- if hash_key_exist?(option_node, 'controller')
113
- name = option_node.hash_value('controller').to_s
114
- else
115
- name = node.arguments.all.first.to_s.gsub('::', '').tableize
116
- end
112
+ name =
113
+ if hash_key_exist?(option_node, 'controller')
114
+ option_node.hash_value('controller').to_s
115
+ else
116
+ node.arguments.all.first.to_s.gsub('::', '').tableize
117
+ end
117
118
  else
118
119
  name = node.arguments.all.first.to_s.gsub('::', '').tableize
119
120
  end
120
121
  namespaced_class_name(name)
121
122
  end
122
123
 
123
- # get the class name with namespace.
124
+ # get the class name with namespace.
124
125
  def namespaced_class_name(name)
125
126
  class_name = "#{name.split('/').map(&:camelize).join('::')}Controller"
126
127
  if @namespaces.empty?
@@ -138,11 +139,12 @@ module RailsBestPractices
138
139
  unless _methods.all? { |meth| Prepares.controller_methods.has_method?(controller_name, meth) }
139
140
  prepared_method_names = Prepares.controller_methods.get_methods(controller_name).map(&:method_name)
140
141
  only_methods = (_methods & prepared_method_names).map { |meth| ":#{meth}" }
141
- routes_message = if only_methods.size > 3
142
- "except: [#{(methods.map { |meth| ':' + meth } - only_methods).join(', ')}]"
143
- else
144
- "only: [#{only_methods.join(', ')}]"
145
- end
142
+ routes_message =
143
+ if only_methods.size > 3
144
+ "except: [#{(methods.map { |meth| ':' + meth } - only_methods).join(', ')}]"
145
+ else
146
+ "only: [#{only_methods.join(', ')}]"
147
+ end
146
148
  add_error "restrict auto-generated routes #{friendly_route_name(node)} (#{routes_message})"
147
149
  end
148
150
  end
@@ -178,7 +180,7 @@ module RailsBestPractices
178
180
  end
179
181
 
180
182
  def hash_key_exist?(node, key)
181
- node.hash_keys && node.hash_keys.include?(key)
183
+ node.hash_keys&.include?(key)
182
184
  end
183
185
 
184
186
  def friendly_route_name(node)
@@ -23,8 +23,7 @@ module RailsBestPractices
23
23
  add_callback :start_command do |node|
24
24
  if node.message.to_s == 'render'
25
25
  keys = node.arguments.all.first.hash_keys
26
- if keys && keys.size == 1 &&
27
- (keys.include?('action') || keys.include?('template') || keys.include?('file'))
26
+ if keys && keys.size == 1 && (keys.include?('action') || keys.include?('template') || keys.include?('file'))
28
27
  add_error 'simplify render in controllers'
29
28
  end
30
29
  end
@@ -23,9 +23,9 @@ module RailsBestPractices
23
23
  # then it should be replaced by simplified syntax.
24
24
  add_callback :start_command do |node|
25
25
  if node.message.to_s == 'render'
26
- hash_node = node.arguments.all.first
27
- if hash_node && hash_node.sexp_type == :bare_assoc_hash &&
28
- include_partial?(hash_node) && valid_hash?(hash_node)
26
+ hash_node = node.arguments.all.first
27
+ if hash_node && hash_node.sexp_type == :bare_assoc_hash && include_partial?(hash_node) &&
28
+ valid_hash?(hash_node)
29
29
  add_error 'simplify render in views'
30
30
  end
31
31
  end
@@ -12,6 +12,7 @@ module RailsBestPractices
12
12
  # Review process:
13
13
  # check all first code line_number in method definitions (actions),
14
14
  # if they are duplicated, then they should be moved to before_filter.
15
+
15
16
  class UseBeforeFilterReview < Review
16
17
  interesting_nodes :class
17
18
  interesting_files CONTROLLER_FILES
@@ -48,7 +49,7 @@ module RailsBestPractices
48
49
 
49
50
  private
50
51
 
51
- # check method define node, and remember the first sentence.
52
+ # check method define node, and remember the first sentence.
52
53
  def remember_first_sentence(node)
53
54
  first_sentence = node.body.statements.first
54
55
  return unless first_sentence
@@ -43,8 +43,8 @@ module RailsBestPractices
43
43
 
44
44
  private
45
45
 
46
- # check an attribute assignment node, if its message is xxx_id,
47
- # then remember the receiver of the attribute assignment in @assignments.
46
+ # check an attribute assignment node, if its message is xxx_id,
47
+ # then remember the receiver of the attribute assignment in @assignments.
48
48
  def attribute_assignment(node)
49
49
  if node.left_value.message.is_a?(Sexp) && node.left_value.message.to_s =~ /_id$/
50
50
  receiver = node.left_value.receiver.to_s
@@ -52,9 +52,9 @@ module RailsBestPractices
52
52
  end
53
53
  end
54
54
 
55
- # check a call node with message "save" or "save!",
56
- # if the receiver of call node exists in @assignments,
57
- # then the attribute assignment should be replaced by using model association.
55
+ # check a call node with message "save" or "save!",
56
+ # if the receiver of call node exists in @assignments,
57
+ # then the attribute assignment should be replaced by using model association.
58
58
  def call_assignment(node)
59
59
  if ['save', 'save!'].include? node.message.to_s
60
60
  receiver = node.receiver.to_s
@@ -11,6 +11,7 @@ module RailsBestPractices
11
11
  # Review process:
12
12
  # check class node to remember the class name,
13
13
  # and check the method definition nodes to see if the corresponding mailer views exist or not.
14
+
14
15
  class UseMultipartAlternativeAsContentTypeOfEmailReview < Review
15
16
  interesting_nodes :class, :def
16
17
  interesting_files MAILER_FILES
@@ -31,14 +32,14 @@ module RailsBestPractices
31
32
 
32
33
  private
33
34
 
34
- # check if rails's syntax mailer views are canonical.
35
- #
36
- # @param [String] name method name in action_mailer
35
+ # check if rails's syntax mailer views are canonical.
36
+ #
37
+ # @param [String] name method name in action_mailer
37
38
  def rails_canonical_mailer_views?(name); end
38
39
 
39
- # check if rails3's syntax mailer views are canonical.
40
- #
41
- # @param [String] name method name in action_mailer
40
+ # check if rails3's syntax mailer views are canonical.
41
+ #
42
+ # @param [String] name method name in action_mailer
42
43
  def rails3_canonical_mailer_views?(name)
43
44
  return true if mailer_files(name).empty?
44
45
  return true if mailer_files(name).none? { |filename| filename.index 'html' }
@@ -47,12 +48,12 @@ module RailsBestPractices
47
48
  mailer_files(name).any? { |filename| filename.index 'text' }
48
49
  end
49
50
 
50
- # all mail view files for a method name.
51
+ # all mail view files for a method name.
51
52
  def mailer_files(name)
52
53
  Dir.entries(mailer_directory) { |filename| filename.index name.to_s }
53
54
  end
54
55
 
55
- # the view directory of mailer.
56
+ # the view directory of mailer.
56
57
  def mailer_directory
57
58
  File.join(Core::Runner.base_path, "app/views/#{@klazz_name.to_s.underscore}")
58
59
  end
@@ -49,8 +49,8 @@ module RailsBestPractices
49
49
 
50
50
  private
51
51
 
52
- # check a command node, if it is a callback definition, such as after_create, before_create,
53
- # then save the callback methods in @callbacks
52
+ # check a command node, if it is a callback definition, such as after_create, before_create,
53
+ # then save the callback methods in @callbacks
54
54
  def remember_callback(node)
55
55
  if node.message.to_s =~ /^after_|^before_/
56
56
  node.arguments.all.each do |argument|
@@ -60,21 +60,21 @@ module RailsBestPractices
60
60
  end
61
61
  end
62
62
 
63
- # check a defn node to see if the method name exists in the @callbacks.
63
+ # check a defn node to see if the method name exists in the @callbacks.
64
64
  def callback_method?(node)
65
65
  @callbacks.find { |callback| callback == node.method_name.to_s }
66
66
  end
67
67
 
68
- # check a def node to see if it contains a actionmailer deliver call.
69
- #
70
- # if the message of call node is deliver,
71
- # and the receiver of the call node is with receiver node who exists in @callbacks,
72
- # then the call node is actionmailer deliver call.
68
+ # check a def node to see if it contains a actionmailer deliver call.
69
+ #
70
+ # if the message of call node is deliver,
71
+ # and the receiver of the call node is with receiver node who exists in @callbacks,
72
+ # then the call node is actionmailer deliver call.
73
73
  def deliver_mailer?(node)
74
74
  node.grep_nodes(sexp_type: :call) do |child_node|
75
75
  if child_node.message.to_s == 'deliver'
76
76
  if child_node.receiver.sexp_type == :method_add_arg &&
77
- mailers.include?(child_node.receiver[1].receiver.to_s)
77
+ mailers.include?(child_node.receiver[1].receiver.to_s)
78
78
  return true
79
79
  end
80
80
  end
@@ -34,11 +34,12 @@ module RailsBestPractices
34
34
  #
35
35
  # then the call node can use query attribute instead.
36
36
  add_callback :start_if, :start_unless, :start_elsif, :start_ifop, :start_if_mod, :start_unless_mod do |node|
37
- all_conditions = if node.conditional_statement == node.conditional_statement.all_conditions
38
- [node.conditional_statement]
39
- else
40
- node.conditional_statement.all_conditions
41
- end
37
+ all_conditions =
38
+ if node.conditional_statement == node.conditional_statement.all_conditions
39
+ [node.conditional_statement]
40
+ else
41
+ node.conditional_statement.all_conditions
42
+ end
42
43
  all_conditions.each do |condition_node|
43
44
  next unless query_attribute_node = query_attribute_node(condition_node)
44
45
 
@@ -51,13 +52,13 @@ module RailsBestPractices
51
52
 
52
53
  private
53
54
 
54
- # recursively check conditional statement nodes to see if there is a call node that may be
55
- # possible query attribute.
55
+ # recursively check conditional statement nodes to see if there is a call node that may be
56
+ # possible query attribute.
56
57
  def query_attribute_node(conditional_statement_node)
57
58
  case conditional_statement_node.sexp_type
58
59
  when :and, :or
59
- node = query_attribute_node(conditional_statement_node[1]) ||
60
- query_attribute_node(conditional_statement_node[2])
60
+ node =
61
+ query_attribute_node(conditional_statement_node[1]) || query_attribute_node(conditional_statement_node[2])
61
62
  node.file = conditional_statement_code.file
62
63
  return node
63
64
  when :not
@@ -71,17 +72,17 @@ module RailsBestPractices
71
72
  nil
72
73
  end
73
74
 
74
- # check if the node may use query attribute instead.
75
- #
76
- # if the node contains two method calls, e.g. @user.login.nil?
77
- #
78
- # for the first call, the receiver should be one of the class names and
79
- # the message should be one of the attribute name.
80
- #
81
- # for the second call, the message should be one of nil?, blank? or present? or
82
- # it is compared with an empty string.
83
- #
84
- # the node that may use query attribute.
75
+ # check if the node may use query attribute instead.
76
+ #
77
+ # if the node contains two method calls, e.g. @user.login.nil?
78
+ #
79
+ # for the first call, the receiver should be one of the class names and
80
+ # the message should be one of the attribute name.
81
+ #
82
+ # for the second call, the message should be one of nil?, blank? or present? or
83
+ # it is compared with an empty string.
84
+ #
85
+ # the node that may use query attribute.
85
86
  def possible_query_attribute?(node)
86
87
  return false unless node.receiver.sexp_type == :call
87
88
 
@@ -92,7 +93,7 @@ module RailsBestPractices
92
93
  (QUERY_METHODS.include?(node.message.to_s) || compare_with_empty_string?(node))
93
94
  end
94
95
 
95
- # check if the receiver is one of the models.
96
+ # check if the receiver is one of the models.
96
97
  def is_model?(variable_node)
97
98
  return false if variable_node.const?
98
99
 
@@ -100,18 +101,17 @@ module RailsBestPractices
100
101
  models.include?(class_name)
101
102
  end
102
103
 
103
- # check if the receiver and message is one of the model's attribute.
104
- # the receiver should match one of the class model name, and the message should match one of attribute name.
104
+ # check if the receiver and message is one of the model's attribute.
105
+ # the receiver should match one of the class model name, and the message should match one of attribute name.
105
106
  def model_attribute?(variable_node, message)
106
107
  class_name = variable_node.to_s.sub(/^@/, '').classify
107
108
  attribute_type = model_attributes.get_attribute_type(class_name, message)
108
109
  attribute_type && !%w[integer float].include?(attribute_type)
109
110
  end
110
111
 
111
- # check if the node is with node type :binary, node message :== and node argument is empty string.
112
+ # check if the node is with node type :binary, node message :== and node argument is empty string.
112
113
  def compare_with_empty_string?(node)
113
- node.sexp_type == :binary &&
114
- ['==', '!='].include?(node.message.to_s) &&
114
+ node.sexp_type == :binary && ['==', '!='].include?(node.message.to_s) &&
115
115
  s(:string_literal, s(:string_content)) == node.argument
116
116
  end
117
117
  end
@@ -31,13 +31,14 @@ module RailsBestPractices
31
31
  node.body.statements.each do |child_node|
32
32
  next if child_node.grep_nodes_count(sexp_type: %i[fcall command], message: WITH_SAY_METHODS) > 0
33
33
 
34
- receiver_node = if child_node.sexp_type == :method_add_block
35
- child_node[1]
36
- elsif child_node.sexp_type == :method_add_arg
37
- child_node[1]
38
- else
39
- child_node
40
- end
34
+ receiver_node =
35
+ if child_node.sexp_type == :method_add_block
36
+ child_node[1]
37
+ elsif child_node.sexp_type == :method_add_arg
38
+ child_node[1]
39
+ else
40
+ child_node
41
+ end
41
42
  if receiver_node.sexp_type == :call
42
43
  add_error('use say with time in migrations', node.file, child_node.line_number)
43
44
  end
@@ -30,25 +30,27 @@ module RailsBestPractices
30
30
 
31
31
  private
32
32
 
33
- # check a if node to see
34
- #
35
- # if the conditional statement is compared with current_user or current_user.id,
36
- # and there is a redirect_to method call in the block body,
37
- # then it should be replaced by using scope access.
33
+ # check a if node to see
34
+ #
35
+ # if the conditional statement is compared with current_user or current_user.id,
36
+ # and there is a redirect_to method call in the block body,
37
+ # then it should be replaced by using scope access.
38
38
  def current_user_redirect?(node)
39
- all_conditions = if node.conditional_statement == node.conditional_statement.all_conditions
40
- [node.conditional_statement]
41
- else
42
- node.conditional_statement.all_conditions
43
- end
44
- results = all_conditions.map do |condition_node|
45
- ['==', '!='].include?(condition_node.message.to_s) &&
46
- (current_user?(condition_node.argument) || current_user?(condition_node.receiver))
47
- end
39
+ all_conditions =
40
+ if node.conditional_statement == node.conditional_statement.all_conditions
41
+ [node.conditional_statement]
42
+ else
43
+ node.conditional_statement.all_conditions
44
+ end
45
+ results =
46
+ all_conditions.map do |condition_node|
47
+ ['==', '!='].include?(condition_node.message.to_s) &&
48
+ (current_user?(condition_node.argument) || current_user?(condition_node.receiver))
49
+ end
48
50
  results.any? { |result| result == true } && node.body.grep_node(message: 'redirect_to')
49
51
  end
50
52
 
51
- # check a call node to see if it uses current_user, or current_user.id.
53
+ # check a call node to see if it uses current_user, or current_user.id.
52
54
  def current_user?(node)
53
55
  node.to_s == 'current_user' || (node.receiver.to_s == 'current_user' && node.message.to_s == 'id')
54
56
  end
@@ -18,7 +18,8 @@ module RailsBestPractices
18
18
  # check command node to see if load 'deploy/assets'
19
19
  add_callback :start_command do |node|
20
20
  if Prepares.gems.gem_version('rails').to_i == 3
21
- if !Prepares.gems.has_gem?('turbo-sprockets-rails3') && node.message.to_s == 'load' && node.arguments.to_s == 'deploy/assets'
21
+ if !Prepares.gems.has_gem?('turbo-sprockets-rails3') && node.message.to_s == 'load' &&
22
+ node.arguments.to_s == 'deploy/assets'
22
23
  add_error 'speed up assets precompile with turbo-sprockets-rails3'
23
24
  end
24
25
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsBestPractices
4
- VERSION = '1.20.0'
4
+ VERSION = '1.22.1'
5
5
  end
@@ -8,8 +8,8 @@ require 'rails_best_practices/analyzer'
8
8
  require 'rails_best_practices/lexicals'
9
9
  require 'rails_best_practices/prepares'
10
10
  require 'rails_best_practices/reviews'
11
+ require 'rails_best_practices/inline_disables'
11
12
  require 'rails_best_practices/option_parser'
12
13
  require 'rails_best_practices/cli'
13
14
 
14
- module RailsBestPractices
15
- end
15
+ module RailsBestPractices; end
@@ -1,43 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('lib/rails_best_practices/version', __dir__)
4
-
5
- Gem::Specification.new do |s|
6
- s.name = 'rails_best_practices'
7
- s.version = RailsBestPractices::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ['Richard Huang']
10
- s.email = ['flyerhzm@gmail.com']
11
- s.homepage = 'http://rails-bestpractices.com'
12
- s.summary = 'a code metric tool for rails codes.'
13
- s.description = 'a code metric tool for rails codes, written in Ruby.'
14
- s.license = 'MIT'
15
-
16
- s.required_ruby_version = '>= 1.9.0'
17
- s.required_rubygems_version = '>= 1.3.6'
18
-
19
- s.add_dependency('activesupport')
20
- # TODO: add a dependency for Rails >= 3 ?
21
- s.add_dependency('code_analyzer', '>= 0.5.1')
22
- s.add_dependency('erubis')
23
- s.add_dependency('i18n')
24
- s.add_dependency('json')
25
- s.add_dependency('require_all', '~> 3.0')
26
- s.add_dependency('ruby-progressbar')
27
-
28
- s.add_development_dependency('awesome_print')
29
- s.add_development_dependency('bundler')
30
- s.add_development_dependency('haml')
31
- s.add_development_dependency('rake')
32
- s.add_development_dependency('rspec')
33
- s.add_development_dependency('slim')
34
-
35
- s.files = `git ls-files`.split("\n")
36
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
37
- s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
38
- s.require_paths = %w[lib assets]
39
-
40
- s.post_install_message = <<~POST_INSTALL_MESSAGE
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'rails_best_practices/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'rails_best_practices'
9
+ spec.version = RailsBestPractices::VERSION
10
+ spec.platform = Gem::Platform::RUBY
11
+ spec.authors = ['Richard Huang']
12
+ spec.email = ['flyerhzm@gmail.com']
13
+ spec.homepage = 'http://rails-bestpractices.com'
14
+ spec.summary = 'a code metric tool for rails codes.'
15
+ spec.description = 'a code metric tool for rails codes, written in Ruby.'
16
+ spec.license = 'MIT'
17
+
18
+ spec.required_ruby_version = '>= 1.9.0'
19
+ spec.required_rubygems_version = '>= 1.3.6'
20
+
21
+ spec.add_runtime_dependency('activesupport')
22
+ spec.add_runtime_dependency('code_analyzer', '>= 0.5.2')
23
+ spec.add_runtime_dependency('erubis')
24
+ spec.add_runtime_dependency('i18n')
25
+ spec.add_runtime_dependency('json')
26
+ spec.add_runtime_dependency('require_all', '~> 3.0')
27
+ spec.add_runtime_dependency('ruby-progressbar')
28
+
29
+ spec.add_development_dependency('awesome_print')
30
+ spec.add_development_dependency('bundler')
31
+ spec.add_development_dependency('haml')
32
+ spec.add_development_dependency('rake')
33
+ spec.add_development_dependency('rspec')
34
+ spec.add_development_dependency('slim')
35
+
36
+ spec.files = `git ls-files`.split($/)
37
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
38
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
39
+ spec.require_paths = %w[lib assets]
40
+
41
+ spec.post_install_message = <<~POST_INSTALL_MESSAGE
41
42
  #{'*' * 80}
42
43
 
43
44
  rails_best_practices is a code metric tool to check the quality of rails codes.
@@ -5,8 +5,7 @@ require 'rails_best_practices/reviews/review'
5
5
  module RailsBestPractices
6
6
  module Plugins
7
7
  module Reviews
8
- class NotUseRailsRootReview < RailsBestPractices::Reviews::Review
9
- end
8
+ class NotUseRailsRootReview < RailsBestPractices::Reviews::Review; end
10
9
  end
11
10
  end
12
11
  end