rubocop 0.28.0 → 0.29.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +7 -7
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +59 -0
  5. data/README.md +62 -28
  6. data/config/default.yml +31 -0
  7. data/config/disabled.yml +1 -1
  8. data/config/enabled.yml +17 -0
  9. data/lib/rubocop.rb +4 -0
  10. data/lib/rubocop/cli.rb +1 -1
  11. data/lib/rubocop/config.rb +12 -8
  12. data/lib/rubocop/config_loader.rb +20 -10
  13. data/lib/rubocop/cop/cop.rb +13 -7
  14. data/lib/rubocop/cop/corrector.rb +10 -10
  15. data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -1
  16. data/lib/rubocop/cop/lint/block_alignment.rb +9 -2
  17. data/lib/rubocop/cop/lint/debugger.rb +13 -1
  18. data/lib/rubocop/cop/lint/duplicate_methods.rb +104 -0
  19. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  20. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -3
  21. data/lib/rubocop/cop/mixin/access_modifier_node.rb +27 -0
  22. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +0 -4
  23. data/lib/rubocop/cop/rails/delegate.rb +4 -5
  24. data/lib/rubocop/cop/rails/read_write_attribute.rb +33 -0
  25. data/lib/rubocop/cop/style/access_modifier_indentation.rb +0 -7
  26. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +4 -2
  27. data/lib/rubocop/cop/style/class_methods.rb +25 -9
  28. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +7 -1
  29. data/lib/rubocop/cop/style/empty_literal.rb +25 -10
  30. data/lib/rubocop/cop/style/even_odd.rb +32 -14
  31. data/lib/rubocop/cop/style/first_parameter_indentation.rb +106 -0
  32. data/lib/rubocop/cop/style/format_string.rb +2 -2
  33. data/lib/rubocop/cop/style/global_vars.rb +1 -5
  34. data/lib/rubocop/cop/style/hash_syntax.rb +0 -4
  35. data/lib/rubocop/cop/style/indentation_consistency.rb +5 -5
  36. data/lib/rubocop/cop/style/indentation_width.rb +13 -14
  37. data/lib/rubocop/cop/style/lambda.rb +48 -2
  38. data/lib/rubocop/cop/style/line_end_concatenation.rb +43 -47
  39. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -3
  40. data/lib/rubocop/cop/style/module_function.rb +3 -3
  41. data/lib/rubocop/cop/style/multiline_block_layout.rb +65 -17
  42. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +2 -1
  43. data/lib/rubocop/cop/style/perl_backrefs.rb +2 -2
  44. data/lib/rubocop/cop/style/redundant_exception.rb +12 -0
  45. data/lib/rubocop/cop/style/self_assignment.rb +27 -0
  46. data/lib/rubocop/cop/style/semicolon.rb +2 -1
  47. data/lib/rubocop/cop/style/space_around_block_parameters.rb +92 -0
  48. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +0 -8
  49. data/lib/rubocop/cop/style/struct_inheritance.rb +42 -0
  50. data/lib/rubocop/cop/style/trivial_accessors.rb +10 -4
  51. data/lib/rubocop/cop/util.rb +32 -7
  52. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -15
  53. data/lib/rubocop/options.rb +28 -41
  54. data/lib/rubocop/processed_source.rb +6 -0
  55. data/lib/rubocop/rake_task.rb +6 -3
  56. data/lib/rubocop/runner.rb +55 -15
  57. data/lib/rubocop/version.rb +1 -1
  58. data/relnotes/v0.29.0.md +116 -0
  59. data/rubocop.gemspec +3 -3
  60. data/spec/rubocop/cli_spec.rb +329 -25
  61. data/spec/rubocop/config_loader_spec.rb +20 -0
  62. data/spec/rubocop/cop/lint/assignment_in_condition_spec.rb +27 -3
  63. data/spec/rubocop/cop/lint/block_alignment_spec.rb +3 -4
  64. data/spec/rubocop/cop/lint/condition_position_spec.rb +1 -1
  65. data/spec/rubocop/cop/lint/debugger_spec.rb +20 -7
  66. data/spec/rubocop/cop/lint/duplicate_methods_spec.rb +189 -0
  67. data/spec/rubocop/cop/lint/empty_interpolation_spec.rb +1 -1
  68. data/spec/rubocop/cop/lint/end_in_method_spec.rb +1 -1
  69. data/spec/rubocop/cop/lint/eval_spec.rb +4 -4
  70. data/spec/rubocop/cop/lint/literal_in_condition_spec.rb +18 -0
  71. data/spec/rubocop/cop/lint/literal_in_interpolation_spec.rb +2 -2
  72. data/spec/rubocop/cop/lint/loop_spec.rb +4 -4
  73. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +7 -7
  74. data/spec/rubocop/cop/lint/space_before_first_arg_spec.rb +5 -4
  75. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +3 -9
  76. data/spec/rubocop/cop/lint/useless_comparison_spec.rb +1 -1
  77. data/spec/rubocop/cop/lint/void_spec.rb +1 -1
  78. data/spec/rubocop/cop/metrics/abc_size_spec.rb +10 -0
  79. data/spec/rubocop/cop/metrics/line_length_spec.rb +2 -2
  80. data/spec/rubocop/cop/metrics/parameter_lists_spec.rb +2 -2
  81. data/spec/rubocop/cop/rails/action_filter_spec.rb +6 -12
  82. data/spec/rubocop/cop/rails/default_scope_spec.rb +5 -5
  83. data/spec/rubocop/cop/rails/delegate_spec.rb +8 -0
  84. data/spec/rubocop/cop/rails/has_and_belongs_to_many_spec.rb +1 -1
  85. data/spec/rubocop/cop/rails/read_write_attribute_spec.rb +119 -8
  86. data/spec/rubocop/cop/rails/scope_args_spec.rb +3 -3
  87. data/spec/rubocop/cop/rails/validation_spec.rb +3 -3
  88. data/spec/rubocop/cop/style/alias_spec.rb +5 -5
  89. data/spec/rubocop/cop/style/align_hash_spec.rb +1 -1
  90. data/spec/rubocop/cop/style/align_parameters_spec.rb +8 -8
  91. data/spec/rubocop/cop/style/and_or_spec.rb +15 -30
  92. data/spec/rubocop/cop/style/array_join_spec.rb +4 -4
  93. data/spec/rubocop/cop/style/ascii_comments_spec.rb +1 -2
  94. data/spec/rubocop/cop/style/ascii_identifiers_spec.rb +2 -2
  95. data/spec/rubocop/cop/style/begin_block_spec.rb +1 -1
  96. data/spec/rubocop/cop/style/block_comments_spec.rb +1 -1
  97. data/spec/rubocop/cop/style/block_end_newline_spec.rb +1 -1
  98. data/spec/rubocop/cop/style/blocks_spec.rb +2 -2
  99. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +38 -33
  100. data/spec/rubocop/cop/style/case_equality_spec.rb +1 -1
  101. data/spec/rubocop/cop/style/character_literal_spec.rb +4 -4
  102. data/spec/rubocop/cop/style/class_and_module_children_spec.rb +4 -2
  103. data/spec/rubocop/cop/style/class_methods_spec.rb +12 -0
  104. data/spec/rubocop/cop/style/class_vars_spec.rb +2 -2
  105. data/spec/rubocop/cop/style/collection_methods_spec.rb +4 -4
  106. data/spec/rubocop/cop/style/colon_method_call_spec.rb +8 -8
  107. data/spec/rubocop/cop/style/comment_annotation_spec.rb +10 -10
  108. data/spec/rubocop/cop/style/constant_name_spec.rb +7 -7
  109. data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +1 -1
  110. data/spec/rubocop/cop/style/deprecated_hash_methods_spec.rb +4 -4
  111. data/spec/rubocop/cop/style/dot_position_spec.rb +8 -6
  112. data/spec/rubocop/cop/style/each_with_object_spec.rb +2 -2
  113. data/spec/rubocop/cop/style/else_alignment_spec.rb +2 -4
  114. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +78 -0
  115. data/spec/rubocop/cop/style/empty_lines_around_class_body_spec.rb +60 -0
  116. data/spec/rubocop/cop/style/empty_lines_spec.rb +3 -3
  117. data/spec/rubocop/cop/style/empty_literal_spec.rb +29 -12
  118. data/spec/rubocop/cop/style/encoding_spec.rb +3 -3
  119. data/spec/rubocop/cop/style/end_block_spec.rb +1 -1
  120. data/spec/rubocop/cop/style/end_of_line_spec.rb +2 -2
  121. data/spec/rubocop/cop/style/even_odd_spec.rb +109 -20
  122. data/spec/rubocop/cop/style/extra_spacing_spec.rb +3 -3
  123. data/spec/rubocop/cop/style/first_parameter_indentation_spec.rb +293 -0
  124. data/spec/rubocop/cop/style/for_spec.rb +2 -2
  125. data/spec/rubocop/cop/style/format_string_spec.rb +45 -21
  126. data/spec/rubocop/cop/style/global_vars_spec.rb +4 -4
  127. data/spec/rubocop/cop/style/guard_clause_spec.rb +17 -0
  128. data/spec/rubocop/cop/style/hash_syntax_spec.rb +15 -15
  129. data/spec/rubocop/cop/{metrics → style}/if_unless_modifier_spec.rb +2 -2
  130. data/spec/rubocop/cop/style/if_with_semicolon_spec.rb +2 -2
  131. data/spec/rubocop/cop/style/indent_array_spec.rb +3 -6
  132. data/spec/rubocop/cop/style/indent_hash_spec.rb +4 -4
  133. data/spec/rubocop/cop/style/indentation_consistency_spec.rb +1 -2
  134. data/spec/rubocop/cop/style/indentation_width_spec.rb +1 -2
  135. data/spec/rubocop/cop/style/infinite_loop_spec.rb +1 -1
  136. data/spec/rubocop/cop/style/lambda_call_spec.rb +4 -4
  137. data/spec/rubocop/cop/style/lambda_spec.rb +37 -2
  138. data/spec/rubocop/cop/style/leading_comment_space_spec.rb +7 -12
  139. data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +41 -1
  140. data/spec/rubocop/cop/style/method_call_parentheses_spec.rb +4 -4
  141. data/spec/rubocop/cop/style/method_called_on_do_end_block_spec.rb +3 -3
  142. data/spec/rubocop/cop/style/method_name_spec.rb +1 -1
  143. data/spec/rubocop/cop/style/multiline_block_layout_spec.rb +61 -0
  144. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +1 -3
  145. data/spec/rubocop/cop/style/multiline_operation_indentation_spec.rb +8 -0
  146. data/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +1 -1
  147. data/spec/rubocop/cop/style/nested_ternary_operator_spec.rb +1 -1
  148. data/spec/rubocop/cop/style/next_spec.rb +16 -0
  149. data/spec/rubocop/cop/style/numeric_literals_spec.rb +5 -5
  150. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +1 -1
  151. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +22 -4
  152. data/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +31 -31
  153. data/spec/rubocop/cop/style/percent_q_literals_spec.rb +12 -12
  154. data/spec/rubocop/cop/style/perl_backrefs_spec.rb +3 -3
  155. data/spec/rubocop/cop/style/proc_spec.rb +3 -3
  156. data/spec/rubocop/cop/style/raise_args_spec.rb +9 -9
  157. data/spec/rubocop/cop/style/redundant_begin_spec.rb +1 -1
  158. data/spec/rubocop/cop/style/redundant_exception_spec.rb +36 -4
  159. data/spec/rubocop/cop/style/redundant_self_spec.rb +89 -45
  160. data/spec/rubocop/cop/style/regexp_literal_spec.rb +9 -9
  161. data/spec/rubocop/cop/style/rescue_modifier_spec.rb +2 -2
  162. data/spec/rubocop/cop/style/self_assignment_spec.rb +16 -10
  163. data/spec/rubocop/cop/style/semicolon_spec.rb +9 -9
  164. data/spec/rubocop/cop/style/single_line_block_params_spec.rb +2 -2
  165. data/spec/rubocop/cop/style/single_space_before_first_arg_spec.rb +1 -1
  166. data/spec/rubocop/cop/style/space_after_colon_spec.rb +5 -5
  167. data/spec/rubocop/cop/style/space_after_comma_spec.rb +3 -3
  168. data/spec/rubocop/cop/style/space_after_control_keyword_spec.rb +4 -4
  169. data/spec/rubocop/cop/style/space_after_not_spec.rb +2 -2
  170. data/spec/rubocop/cop/style/space_after_semicolon_spec.rb +2 -2
  171. data/spec/rubocop/cop/style/space_around_block_parameters_spec.rb +150 -0
  172. data/spec/rubocop/cop/style/space_around_equals_in_parameter_default_spec.rb +18 -9
  173. data/spec/rubocop/cop/style/space_around_operators_spec.rb +24 -21
  174. data/spec/rubocop/cop/style/space_before_block_braces_spec.rb +4 -4
  175. data/spec/rubocop/cop/style/space_before_comma_spec.rb +4 -4
  176. data/spec/rubocop/cop/style/space_before_comment_spec.rb +3 -3
  177. data/spec/rubocop/cop/style/space_before_semicolon_spec.rb +2 -2
  178. data/spec/rubocop/cop/style/space_inside_block_braces_spec.rb +33 -24
  179. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +2 -2
  180. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +9 -9
  181. data/spec/rubocop/cop/style/space_inside_parens_spec.rb +1 -1
  182. data/spec/rubocop/cop/style/special_global_vars_spec.rb +6 -6
  183. data/spec/rubocop/cop/style/string_literals_in_interpolation_spec.rb +3 -3
  184. data/spec/rubocop/cop/style/string_literals_spec.rb +16 -16
  185. data/spec/rubocop/cop/style/struct_inheritance_spec.rb +44 -0
  186. data/spec/rubocop/cop/style/symbol_array_spec.rb +9 -9
  187. data/spec/rubocop/cop/style/symbol_proc_spec.rb +12 -12
  188. data/spec/rubocop/cop/style/tab_spec.rb +4 -4
  189. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +2 -2
  190. data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +2 -2
  191. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +16 -0
  192. data/spec/rubocop/cop/style/unneeded_capital_w_spec.rb +11 -22
  193. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +7 -7
  194. data/spec/rubocop/cop/style/while_until_do_spec.rb +2 -2
  195. data/spec/rubocop/cop/{metrics → style}/while_until_modifier_spec.rb +2 -2
  196. data/spec/rubocop/cop/style/word_array_spec.rb +11 -11
  197. data/spec/rubocop/cop/util_spec.rb +51 -0
  198. data/spec/rubocop/cop/variable_force/reference_spec.rb +19 -0
  199. data/spec/rubocop/cop/variable_force/variable_table_spec.rb +7 -0
  200. data/spec/rubocop/formatter/disabled_lines_formatter_spec.rb +7 -8
  201. data/spec/rubocop/formatter/text_util_spec.rb +55 -0
  202. data/spec/rubocop/options_spec.rb +26 -20
  203. data/spec/rubocop/rake_task_spec.rb +122 -0
  204. data/spec/rubocop/runner_spec.rb +37 -2
  205. data/spec/rubocop/token_spec.rb +5 -1
  206. data/spec/spec_helper.rb +5 -2
  207. data/spec/support/cop_helper.rb +3 -0
  208. data/spec/support/cops/class_must_be_a_module_cop.rb +19 -0
  209. data/spec/support/cops/module_must_be_a_class_cop.rb +19 -0
  210. data/spec/support/custom_matchers.rb +1 -1
  211. metadata +35 -12
@@ -24,7 +24,7 @@ module RuboCop
24
24
  all_passed = runner.run(paths)
25
25
  display_error_summary(runner.errors)
26
26
 
27
- all_passed && !runner.aborting? ? 0 : 1
27
+ all_passed && !runner.aborting? && runner.errors.empty? ? 0 : 1
28
28
  rescue Cop::AmbiguousCopName => e
29
29
  $stderr.puts "Ambiguous cop name #{e.message} needs namespace " \
30
30
  'qualifier.'
@@ -25,13 +25,15 @@ module RuboCop
25
25
  end
26
26
 
27
27
  def make_excludes_absolute
28
- return unless self['AllCops'] && self['AllCops']['Exclude']
29
-
30
- self['AllCops']['Exclude'].map! do |exclude_elem|
31
- if exclude_elem.is_a?(String) && !exclude_elem.start_with?('/')
32
- File.join(base_dir_for_path_parameters, exclude_elem)
33
- else
34
- exclude_elem
28
+ keys.each do |key|
29
+ next unless self[key]['Exclude']
30
+
31
+ self[key]['Exclude'].map! do |exclude_elem|
32
+ if exclude_elem.is_a?(String) && !exclude_elem.start_with?('/')
33
+ File.join(base_dir_for_path_parameters, exclude_elem)
34
+ else
35
+ exclude_elem
36
+ end
35
37
  end
36
38
  end
37
39
  end
@@ -109,9 +111,11 @@ module RuboCop
109
111
  end
110
112
 
111
113
  def file_to_include?(file)
114
+ absolute_file_path = File.expand_path(file)
112
115
  relative_file_path = path_relative_to_config(file)
113
116
  patterns_to_include.any? do |pattern|
114
- match_path?(pattern, relative_file_path, loaded_path)
117
+ match_path?(pattern, relative_file_path, loaded_path) ||
118
+ match_path?(pattern, absolute_file_path, loaded_path)
115
119
  end
116
120
  end
117
121
 
@@ -24,15 +24,7 @@ module RuboCop
24
24
 
25
25
  def load_file(path)
26
26
  path = File.absolute_path(path)
27
- yaml_code = IO.read(path)
28
- # At one time, there was a problem with the psych YAML engine under
29
- # Ruby 1.9.3. YAML.load_file would crash when reading empty .yml files
30
- # or files that only contained comments and blank lines. This problem
31
- # is not possible to reproduce now, but we want to avoid it in case
32
- # it's still there. So we only load the YAML code if we find some real
33
- # code in there.
34
- hash = yaml_code =~ /^[A-Z]/i ? YAML.load(yaml_code) : {}
35
- puts "configuration from #{path}" if debug?
27
+ hash = load_yaml_configuration(path)
36
28
 
37
29
  resolve_inheritance(path, hash)
38
30
 
@@ -66,7 +58,7 @@ module RuboCop
66
58
 
67
59
  def base_configs(path, inherit_from)
68
60
  configs = Array(inherit_from).map do |f|
69
- f = File.join(File.dirname(path), f) unless f.start_with?('/')
61
+ f = File.expand_path(f, File.dirname(path))
70
62
 
71
63
  if auto_gen_config?
72
64
  next if f.include?(AUTO_GENERATED_FILE)
@@ -114,6 +106,24 @@ module RuboCop
114
106
 
115
107
  private
116
108
 
109
+ def load_yaml_configuration(absolute_path)
110
+ yaml_code = IO.read(absolute_path)
111
+ # At one time, there was a problem with the psych YAML engine under
112
+ # Ruby 1.9.3. YAML.load_file would crash when reading empty .yml files
113
+ # or files that only contained comments and blank lines. This problem
114
+ # is not possible to reproduce now, but we want to avoid it in case
115
+ # it's still there. So we only load the YAML code if we find some real
116
+ # code in there.
117
+ hash = yaml_code =~ /^[A-Z]/i ? YAML.load(yaml_code) : {}
118
+ puts "configuration from #{absolute_path}" if debug?
119
+
120
+ unless hash.is_a?(Hash)
121
+ fail(TypeError, "Malformed configuration in #{absolute_path}")
122
+ end
123
+
124
+ hash
125
+ end
126
+
117
127
  def resolve_inheritance(path, hash)
118
128
  base_configs(path, hash['inherit_from']).reverse_each do |base_config|
119
129
  base_config.each do |k, v|
@@ -15,12 +15,12 @@ module RuboCop
15
15
 
16
16
  # @return [Array<Cop>] Cops for that specific type.
17
17
  def with_type(type)
18
- select { |c| c.cop_type == type }
18
+ CopStore.new(select { |c| c.cop_type == type })
19
19
  end
20
20
 
21
21
  # @return [Array<Cop>] Cops not for a specific type.
22
22
  def without_type(type)
23
- reject { |c| c.cop_type == type }
23
+ CopStore.new(reject { |c| c.cop_type == type })
24
24
  end
25
25
  end
26
26
 
@@ -54,11 +54,11 @@ module RuboCop
54
54
  @all = CopStore.new
55
55
 
56
56
  def self.all
57
- @all.clone
57
+ @all.without_type(:test)
58
58
  end
59
59
 
60
60
  def self.qualified_cop_name(name, origin)
61
- @cop_names ||= Set.new(@all.map(&:cop_name))
61
+ @cop_names ||= Set.new(all.map(&:cop_name))
62
62
  basename = File.basename(name)
63
63
  found_ns = @all.types.map(&:capitalize).select do |ns|
64
64
  @cop_names.include?("#{ns}/#{basename}")
@@ -80,7 +80,7 @@ module RuboCop
80
80
  end
81
81
 
82
82
  def self.non_rails
83
- @all.without_type(:rails)
83
+ all.without_type(:rails)
84
84
  end
85
85
 
86
86
  def self.inherited(subclass)
@@ -128,7 +128,8 @@ module RuboCop
128
128
  end
129
129
 
130
130
  def display_cop_names?
131
- debug? || @options[:display_cop_names]
131
+ debug? || @options[:display_cop_names] ||
132
+ config['AllCops'] && config['AllCops']['DisplayCopNames']
132
133
  end
133
134
 
134
135
  def message(_node = nil)
@@ -187,8 +188,13 @@ module RuboCop
187
188
  def file_name_matches_any?(file, parameter, default_result)
188
189
  patterns = cop_config && cop_config[parameter]
189
190
  return default_result unless patterns
190
- path = config.path_relative_to_config(file)
191
+ path = nil
191
192
  patterns.any? do |pattern|
193
+ # Try to match the absolute path, as Exclude properties are absolute.
194
+ next true if match_path?(pattern, file, config.loaded_path)
195
+
196
+ # Try with relative path.
197
+ path ||= config.path_relative_to_config(file)
192
198
  match_path?(pattern, path, config.loaded_path)
193
199
  end
194
200
  end
@@ -17,19 +17,19 @@ module RuboCop
17
17
  #
18
18
  # @example
19
19
  #
20
- # class AndOrCorrector
21
- # def initialize(node)
22
- # @node = node
23
- # end
20
+ # class AndOrCorrector
21
+ # def initialize(node)
22
+ # @node = node
23
+ # end
24
24
  #
25
- # def call(corrector)
26
- # replacement = (@node.type == :and ? '&&' : '||')
27
- # corrector.replace(@node.loc.operator, replacement)
25
+ # def call(corrector)
26
+ # replacement = (@node.type == :and ? '&&' : '||')
27
+ # corrector.replace(@node.loc.operator, replacement)
28
+ # end
28
29
  # end
29
- # end
30
30
  #
31
- # corrections = [AndOrCorrector.new(node)]
32
- # corrector = Corrector.new(source_buffer, corrections)
31
+ # corrections = [AndOrCorrector.new(node)]
32
+ # corrector = Corrector.new(source_buffer, corrections)
33
33
  def initialize(source_buffer, corrections)
34
34
  @source_buffer = source_buffer
35
35
  @corrections = corrections
@@ -30,7 +30,12 @@ module RuboCop
30
30
  # assignments inside blocks are not what we're looking for
31
31
  return if condition.type == :block
32
32
 
33
- condition.each_node(:begin, *EQUALS_ASGN_NODES) do |asgn_node|
33
+ condition.each_node(:begin, *EQUALS_ASGN_NODES, :send) do |asgn_node|
34
+ if asgn_node.type == :send
35
+ _receiver, method_name, *_args = *asgn_node
36
+ return if method_name != :[]=
37
+ end
38
+
34
39
  # skip safe assignment nodes if safe assignment is allowed
35
40
  return if safe_assignment_allowed? && safe_assignment?(asgn_node)
36
41
 
@@ -149,11 +149,11 @@ module RuboCop
149
149
  end
150
150
 
151
151
  def autocorrect(node)
152
- key = node.children.first
152
+ ancestor_node = ancestor_on_same_line(node)
153
153
  source = node.loc.expression.source_buffer
154
154
 
155
155
  @corrections << lambda do |corrector|
156
- start_col = key.loc.expression.column
156
+ start_col = (ancestor_node || node).loc.expression.column
157
157
  starting_position_of_block_end = node.loc.end.begin_pos
158
158
  end_col = node.loc.end.column
159
159
 
@@ -168,6 +168,13 @@ module RuboCop
168
168
  end
169
169
  end
170
170
  end
171
+
172
+ def ancestor_on_same_line(node)
173
+ node.ancestors.reverse.find do |ancestor|
174
+ next unless ancestor.loc.respond_to?(:line)
175
+ ancestor.loc.line == node.loc.line
176
+ end
177
+ end
171
178
  end
172
179
  end
173
180
  end
@@ -35,12 +35,24 @@ module RuboCop
35
35
  # (send nil :binding) :pry_remote)
36
36
  PRY_REMOTE_NODE = s(:send, s(:send, nil, :binding), :pry_remote)
37
37
 
38
+ # save_and_open_page
39
+ #
40
+ # (send nil :save_and_open_page)
41
+ CAPYBARA_SAVE_PAGE = s(:send, nil, :save_and_open_page)
42
+
43
+ # save_and_open_screenshot
44
+ #
45
+ # (send nil :save_and_open_screenshot)
46
+ CAPYBARA_SAVE_SCREENSHOT = s(:send, nil, :save_and_open_screenshot)
47
+
38
48
  DEBUGGER_NODES = [
39
49
  DEBUGGER_NODE,
40
50
  BYEBUG_NODE,
41
51
  PRY_NODE,
42
52
  REMOTE_PRY_NODE,
43
- PRY_REMOTE_NODE
53
+ PRY_REMOTE_NODE,
54
+ CAPYBARA_SAVE_PAGE,
55
+ CAPYBARA_SAVE_SCREENSHOT
44
56
  ]
45
57
 
46
58
  def on_send(node)
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for duplicate methods in classes and modules.
7
+ #
8
+ # @example Duplicate methods in class
9
+ #
10
+ # class SomeClass
11
+ # def some_method
12
+ # end
13
+ #
14
+ # def some_method
15
+ # end
16
+ # end
17
+ #
18
+ # @example Duplicate methods in module
19
+ #
20
+ # module SomeClass
21
+ # def some_method
22
+ # end
23
+ #
24
+ # def some_method
25
+ # end
26
+ # end
27
+ #
28
+ # @example Duplicate class methods in class
29
+ #
30
+ # class SomeClass
31
+ # def self.some_method
32
+ # end
33
+ #
34
+ # def self.some_method
35
+ # end
36
+ # end
37
+ #
38
+ # @example Duplicate private and public methods in class
39
+ #
40
+ # class SomeClass
41
+ # def some_method
42
+ # end
43
+ #
44
+ # private def some_method
45
+ # end
46
+ # end
47
+ class DuplicateMethods < Cop
48
+ MSG = 'Duplicate methods `%s` at lines `%s` detected.'
49
+
50
+ def on_class(node)
51
+ _klass_name, _parent, body = *node
52
+ return unless body
53
+ names = method_names(body)
54
+ check_duplicate_methods(names)
55
+ end
56
+
57
+ def on_module(node)
58
+ _klass_name, body = *node
59
+ return unless body
60
+ names = method_names(body)
61
+ check_duplicate_methods(names)
62
+ end
63
+
64
+ private
65
+
66
+ def method_names(body)
67
+ body.child_nodes.map do |node|
68
+ _receiver, node, body = *node if node.send_type?
69
+
70
+ if node.is_a? Symbol
71
+ next if body.nil?
72
+ node = body
73
+ end
74
+
75
+ if node.def_type?
76
+ method, _args, _body = *node
77
+ elsif node.defs_type?
78
+ _receiver, method = *node
79
+ method = "self.#{ method }"
80
+ end
81
+
82
+ method ? [method, node] : nil
83
+ end.compact
84
+ end
85
+
86
+ def check_duplicate_methods(names)
87
+ dups = names.each_with_object({}) do |item, accum|
88
+ accum[item[0]] ||= []
89
+ accum[item[0]] << item[1]
90
+ end
91
+
92
+ dups.each do |method, nodes|
93
+ next if nodes.size < 2
94
+ lines = nodes.map { |node| node.loc.line }
95
+
96
+ add_offense(nodes.last,
97
+ :keyword,
98
+ format(MSG, method, lines.join(', ')))
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -8,7 +8,7 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
- # puts (x + y)
11
+ # puts (x + y)
12
12
  class ParenthesesAsGroupedExpression < Cop
13
13
  MSG = '`(...)` interpreted as grouped expression.'
14
14
 
@@ -14,9 +14,9 @@ module RuboCop
14
14
  #
15
15
  # @example
16
16
  #
17
- # if day.is? :tuesday && month == :jan
18
- # ...
19
- # end
17
+ # if day.is? :tuesday && month == :jan
18
+ # ...
19
+ # end
20
20
  class RequireParentheses < Cop
21
21
  include IfNode
22
22
 
@@ -11,12 +11,39 @@ module RuboCop
11
11
  PUBLIC_NODE = s(:send, nil, :public)
12
12
  MODULE_FUNCTION_NODE = s(:send, nil, :module_function)
13
13
 
14
+ # Returns true when the node is an access modifier.
14
15
  def modifier_node?(node)
16
+ modifier_structure?(node) && class_or_module_parent?(node)
17
+ end
18
+
19
+ # Returns true when the node looks like an access modifier.
20
+ def modifier_structure?(node)
15
21
  [PRIVATE_NODE,
16
22
  PROTECTED_NODE,
17
23
  PUBLIC_NODE,
18
24
  MODULE_FUNCTION_NODE].include?(node)
19
25
  end
26
+
27
+ # Returns true when the parent of what looks like an access modifier
28
+ # is a Class or Module. Filters out simple method calls to similarly
29
+ # named private, protected or public.
30
+ def class_or_module_parent?(node)
31
+ node.each_ancestor do |a|
32
+ if a.type == :block
33
+ return true if class_constructor?(a)
34
+ elsif a.type != :begin
35
+ return [:casgn, :sclass, :class, :module].include?(a.type)
36
+ end
37
+ end
38
+ end
39
+
40
+ # Returns true when the block node looks like Class or Module.new do ... .
41
+ def class_constructor?(block_node)
42
+ send_node = block_node.children.first
43
+ receiver_node, method_name, *_ = *send_node
44
+ return false unless method_name == :new
45
+ %w(Class Module).include?(Util.const_name(receiver_node))
46
+ end
20
47
  end
21
48
  end
22
49
  end
@@ -10,10 +10,6 @@ module RuboCop
10
10
  invoke_hook_for_normal_if_unless(node)
11
11
  end
12
12
 
13
- def on_unless(node)
14
- invoke_hook_for_normal_if_unless(node)
15
- end
16
-
17
13
  def invoke_hook_for_normal_if_unless(node)
18
14
  # We won't check modifier or ternary conditionals.
19
15
  return if modifier_if?(node) || ternary_op?(node)
@@ -29,18 +29,17 @@ module RuboCop
29
29
  # foo.bar
30
30
  # end
31
31
  class Delegate < Cop
32
- include OnMethodDef
33
-
34
32
  MSG = 'Use `delegate` to define delegations.'
35
33
 
36
- private
37
-
38
- def on_method_def(node, method_name, args, body)
34
+ def on_def(node)
35
+ method_name, args, body = *node
39
36
  return unless trivial_delegate?(method_name, args, body)
40
37
  return if private_or_protected_delegation(node)
41
38
  add_offense(node, :keyword, MSG)
42
39
  end
43
40
 
41
+ private
42
+
44
43
  def autocorrect(node)
45
44
  method_name, args, body = *node
46
45
  return unless trivial_delegate?(method_name, args, body)