rubocop 0.19.1 → 0.20.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 (192) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -0
  3. data/CHANGELOG.md +60 -1
  4. data/CONTRIBUTING.md +2 -1
  5. data/README.md +9 -7
  6. data/config/default.yml +3 -3
  7. data/config/disabled.yml +4 -0
  8. data/config/enabled.yml +45 -21
  9. data/lib/rubocop.rb +30 -9
  10. data/lib/rubocop/cli.rb +1 -1
  11. data/lib/rubocop/comment_config.rb +4 -2
  12. data/lib/rubocop/config.rb +16 -22
  13. data/lib/rubocop/config_loader.rb +29 -26
  14. data/lib/rubocop/cop/commissioner.rb +1 -1
  15. data/lib/rubocop/cop/cop.rb +6 -6
  16. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -1
  17. data/lib/rubocop/cop/lint/condition_position.rb +1 -1
  18. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  19. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +9 -7
  20. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  21. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  22. data/lib/rubocop/cop/lint/empty_interpolation.rb +22 -0
  23. data/lib/rubocop/cop/lint/end_in_method.rb +1 -1
  24. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  25. data/lib/rubocop/cop/lint/eval.rb +1 -1
  26. data/lib/rubocop/cop/lint/literal_in_condition.rb +2 -2
  27. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +9 -0
  28. data/lib/rubocop/cop/lint/loop.rb +2 -2
  29. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  30. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  31. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
  32. data/lib/rubocop/cop/lint/space_before_first_arg.rb +36 -0
  33. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +14 -2
  34. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -0
  35. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  36. data/lib/rubocop/cop/lint/void.rb +3 -3
  37. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  38. data/lib/rubocop/cop/offense.rb +3 -21
  39. data/lib/rubocop/cop/rails/action_filter.rb +1 -1
  40. data/lib/rubocop/cop/rails/default_scope.rb +1 -1
  41. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -1
  42. data/lib/rubocop/cop/rails/read_write_attribute.rb +43 -0
  43. data/lib/rubocop/cop/rails/scope_args.rb +1 -1
  44. data/lib/rubocop/cop/rails/validation.rb +1 -1
  45. data/lib/rubocop/cop/severity.rb +76 -0
  46. data/lib/rubocop/cop/style/access_modifier_indentation.rb +1 -1
  47. data/lib/rubocop/cop/style/accessor_method_name.rb +2 -2
  48. data/lib/rubocop/cop/style/alias.rb +1 -1
  49. data/lib/rubocop/cop/style/align_hash.rb +1 -1
  50. data/lib/rubocop/cop/style/and_or.rb +1 -1
  51. data/lib/rubocop/cop/style/{favor_join.rb → array_join.rb} +2 -2
  52. data/lib/rubocop/cop/style/begin_block.rb +1 -1
  53. data/lib/rubocop/cop/style/block_nesting.rb +12 -8
  54. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
  55. data/lib/rubocop/cop/style/case_equality.rb +1 -1
  56. data/lib/rubocop/cop/style/case_indentation.rb +5 -5
  57. data/lib/rubocop/cop/style/class_methods.rb +19 -3
  58. data/lib/rubocop/cop/style/class_vars.rb +1 -1
  59. data/lib/rubocop/cop/style/collection_methods.rb +17 -7
  60. data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
  61. data/lib/rubocop/cop/style/{def_parentheses.rb → def_with_parentheses.rb} +0 -0
  62. data/lib/rubocop/cop/style/{hash_methods.rb → deprecated_hash_methods.rb} +5 -4
  63. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  64. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +1 -1
  65. data/lib/rubocop/cop/style/end_block.rb +1 -1
  66. data/lib/rubocop/cop/style/even_odd.rb +2 -2
  67. data/lib/rubocop/cop/style/file_name.rb +1 -1
  68. data/lib/rubocop/cop/style/for.rb +2 -2
  69. data/lib/rubocop/cop/style/format_string.rb +1 -1
  70. data/lib/rubocop/cop/style/guard_clause.rb +69 -0
  71. data/lib/rubocop/cop/style/hash_syntax.rb +6 -10
  72. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  73. data/lib/rubocop/cop/style/lambda.rb +2 -2
  74. data/lib/rubocop/cop/style/line_end_concatenation.rb +16 -9
  75. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  76. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +2 -2
  77. data/lib/rubocop/cop/style/negated_if.rb +37 -0
  78. data/lib/rubocop/cop/style/negated_while.rb +33 -0
  79. data/lib/rubocop/cop/style/nested_ternary_operator.rb +1 -1
  80. data/lib/rubocop/cop/style/nil_comparison.rb +14 -10
  81. data/lib/rubocop/cop/style/non_nil_check.rb +70 -0
  82. data/lib/rubocop/cop/style/not.rb +25 -1
  83. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  84. data/lib/rubocop/cop/style/op_method.rb +4 -4
  85. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -1
  86. data/lib/rubocop/cop/style/predicate_name.rb +1 -1
  87. data/lib/rubocop/cop/style/proc.rb +1 -1
  88. data/lib/rubocop/cop/style/raise_args.rb +3 -2
  89. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  90. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  91. data/lib/rubocop/cop/style/signal_exception.rb +6 -3
  92. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  93. data/lib/rubocop/cop/style/single_line_methods.rb +6 -5
  94. data/lib/rubocop/cop/style/single_space_before_first_arg.rb +41 -0
  95. data/lib/rubocop/cop/style/space_around_operators.rb +1 -2
  96. data/lib/rubocop/cop/style/special_global_vars.rb +8 -8
  97. data/lib/rubocop/cop/style/trailing_comma.rb +1 -1
  98. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  99. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  100. data/lib/rubocop/cop/style/variable_interpolation.rb +10 -5
  101. data/lib/rubocop/cop/style/when_then.rb +1 -1
  102. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  103. data/lib/rubocop/cop/style/word_array.rb +1 -1
  104. data/lib/rubocop/cop/team.rb +12 -13
  105. data/lib/rubocop/cop/util.rb +4 -0
  106. data/lib/rubocop/cop/variable_inspector/locatable.rb +1 -1
  107. data/lib/rubocop/cop/variable_inspector/variable_table.rb +1 -1
  108. data/lib/rubocop/file_inspector.rb +46 -10
  109. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  110. data/lib/rubocop/formatter/disabled_lines_formatter.rb +56 -0
  111. data/lib/rubocop/formatter/emacs_style_formatter.rb +1 -1
  112. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  113. data/lib/rubocop/formatter/fuubar_style_formatter.rb +2 -4
  114. data/lib/rubocop/formatter/json_formatter.rb +3 -7
  115. data/lib/rubocop/formatter/progress_formatter.rb +1 -3
  116. data/lib/rubocop/formatter/simple_text_formatter.rb +7 -3
  117. data/lib/rubocop/options.rb +29 -10
  118. data/lib/rubocop/path_util.rb +2 -1
  119. data/lib/rubocop/processed_source.rb +8 -0
  120. data/lib/rubocop/target_finder.rb +33 -12
  121. data/lib/rubocop/version.rb +1 -1
  122. data/relnotes/v0.20.0.md +69 -0
  123. data/rubocop-todo.yml +2 -2
  124. data/spec/rubocop/cli_spec.rb +269 -94
  125. data/spec/rubocop/config_loader_spec.rb +14 -14
  126. data/spec/rubocop/config_spec.rb +8 -8
  127. data/spec/rubocop/cop/lint/deprecated_class_methods_spec.rb +11 -6
  128. data/spec/rubocop/cop/lint/empty_interpolation_spec.rb +18 -0
  129. data/spec/rubocop/cop/lint/eval_spec.rb +2 -4
  130. data/spec/rubocop/cop/lint/literal_in_interpolation_spec.rb +10 -0
  131. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +0 -8
  132. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +4 -4
  133. data/spec/rubocop/cop/lint/space_before_first_arg_spec.rb +48 -0
  134. data/spec/rubocop/cop/lint/string_conversion_in_interpolation_spec.rb +10 -0
  135. data/spec/rubocop/cop/lint/useless_access_modifier_spec.rb +154 -0
  136. data/spec/rubocop/cop/offense_spec.rb +1 -1
  137. data/spec/rubocop/cop/rails/read_write_attribute_spec.rb +19 -0
  138. data/spec/rubocop/cop/severity_spec.rb +113 -0
  139. data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +10 -10
  140. data/spec/rubocop/cop/style/alias_spec.rb +2 -2
  141. data/spec/rubocop/cop/style/and_or_spec.rb +2 -2
  142. data/spec/rubocop/cop/style/{favor_join_spec.rb → array_join_spec.rb} +1 -3
  143. data/spec/rubocop/cop/style/block_nesting_spec.rb +4 -4
  144. data/spec/rubocop/cop/style/case_equality_spec.rb +1 -0
  145. data/spec/rubocop/cop/style/case_indentation_spec.rb +12 -9
  146. data/spec/rubocop/cop/style/class_methods_spec.rb +23 -0
  147. data/spec/rubocop/cop/style/collection_methods_spec.rb +2 -2
  148. data/spec/rubocop/cop/style/{hash_methods_spec.rb → deprecated_hash_methods_spec.rb} +3 -3
  149. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +2 -2
  150. data/spec/rubocop/cop/style/even_odd_spec.rb +8 -8
  151. data/spec/rubocop/cop/style/file_name_spec.rb +55 -42
  152. data/spec/rubocop/cop/style/for_spec.rb +4 -4
  153. data/spec/rubocop/cop/style/format_string_spec.rb +10 -10
  154. data/spec/rubocop/cop/style/guard_clause_spec.rb +77 -0
  155. data/spec/rubocop/cop/style/hash_syntax_spec.rb +4 -2
  156. data/spec/rubocop/cop/style/if_unless_modifier_spec.rb +4 -4
  157. data/spec/rubocop/cop/style/lambda_spec.rb +2 -2
  158. data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +21 -0
  159. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +1 -1
  160. data/spec/rubocop/cop/style/{favor_unless_over_negated_if_spec.rb → negated_if_spec.rb} +8 -3
  161. data/spec/rubocop/cop/style/{favor_until_over_negated_while_spec.rb → negated_while_spec.rb} +8 -3
  162. data/spec/rubocop/cop/style/nil_comparison_spec.rb +7 -13
  163. data/spec/rubocop/cop/style/non_nil_check_spec.rb +35 -0
  164. data/spec/rubocop/cop/style/not_spec.rb +11 -0
  165. data/spec/rubocop/cop/style/numeric_literals_spec.rb +0 -2
  166. data/spec/rubocop/cop/style/op_method_spec.rb +10 -2
  167. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +2 -2
  168. data/spec/rubocop/cop/style/predicate_name_spec.rb +2 -1
  169. data/spec/rubocop/cop/style/raise_args_spec.rb +5 -0
  170. data/spec/rubocop/cop/style/rescue_modifier_spec.rb +2 -2
  171. data/spec/rubocop/cop/style/self_assignment_spec.rb +4 -4
  172. data/spec/rubocop/cop/style/signal_exception_spec.rb +24 -0
  173. data/spec/rubocop/cop/style/single_line_block_params_spec.rb +2 -0
  174. data/spec/rubocop/cop/style/single_space_before_first_arg_spec.rb +63 -0
  175. data/spec/rubocop/cop/style/special_global_vars_spec.rb +6 -5
  176. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +6 -3
  177. data/spec/rubocop/cop/style/unless_else_spec.rb +2 -4
  178. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +15 -6
  179. data/spec/rubocop/cop/style/when_then_spec.rb +3 -4
  180. data/spec/rubocop/cop/team_spec.rb +4 -18
  181. data/spec/rubocop/file_inspector_spec.rb +4 -0
  182. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +1 -1
  183. data/spec/rubocop/formatter/disabled_lines_formatter_spec.rb +69 -0
  184. data/spec/rubocop/options_spec.rb +5 -0
  185. data/spec/rubocop/target_finder_spec.rb +42 -11
  186. data/spec/support/shared_context.rb +1 -1
  187. data/spec/support/statement_modifier_helper.rb +1 -1
  188. metadata +75 -50
  189. data/lib/rubocop/cop/rails/read_attribute.rb +0 -28
  190. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +0 -24
  191. data/lib/rubocop/cop/style/favor_until_over_negated_while.rb +0 -20
  192. data/spec/rubocop/cop/rails/read_attribute_spec.rb +0 -13
@@ -7,6 +7,8 @@ module Rubocop
7
7
  module Formatter
8
8
  # This formatter formats the report data in JSON format.
9
9
  class JSONFormatter < BaseFormatter
10
+ include PathUtil
11
+
10
12
  attr_reader :output_hash
11
13
 
12
14
  def initialize(output)
@@ -51,7 +53,7 @@ module Rubocop
51
53
 
52
54
  def hash_for_offense(offense)
53
55
  {
54
- severity: offense.severity,
56
+ severity: offense.severity.name,
55
57
  message: offense.message,
56
58
  cop_name: offense.cop_name,
57
59
  corrected: offense.corrected?,
@@ -67,12 +69,6 @@ module Rubocop
67
69
  length: offense.location.length
68
70
  }
69
71
  end
70
-
71
- private
72
-
73
- def relative_path(path)
74
- Pathname.new(path).relative_path_from(Pathname.getwd).to_s
75
- end
76
72
  end
77
73
  end
78
74
  end
@@ -44,9 +44,7 @@ module Rubocop
44
44
  mark = if offenses.empty?
45
45
  green('.')
46
46
  else
47
- highest_offense = offenses.max do |a, b|
48
- a.severity_level <=> b.severity_level
49
- end
47
+ highest_offense = offenses.max_by { |o| o.severity }
50
48
  colored_severity_code(highest_offense)
51
49
  end
52
50
 
@@ -85,13 +85,17 @@ module Rubocop
85
85
  end
86
86
 
87
87
  def colored_severity_code(offense)
88
- color = COLOR_FOR_SEVERITY[offense.severity]
89
- colorize(offense.severity_code, color)
88
+ color = COLOR_FOR_SEVERITY[offense.severity.name]
89
+ colorize(offense.severity.code, color)
90
+ end
91
+
92
+ def annotate_message(msg)
93
+ msg.gsub(/`(.*?)`/, Rainbow('\1').yellow)
90
94
  end
91
95
 
92
96
  def message(offense)
93
97
  message = offense.corrected? ? green('[Corrected] ') : ''
94
- message << offense.message
98
+ message << annotate_message(offense.message)
95
99
  end
96
100
 
97
101
  def pluralize(number, thing, options = {})
@@ -23,14 +23,14 @@ module Rubocop
23
23
  validate_only_option
24
24
  end
25
25
 
26
- option(opts, '-c', '--config FILE', 'Specify configuration file.')
27
-
26
+ add_configuration_options(opts, args)
28
27
  add_formatting_options(opts, args)
29
28
 
30
29
  option(opts, '-r', '--require FILE', 'Require Ruby file.') do |f|
31
30
  require f
32
31
  end
33
32
 
33
+ add_severity_option(opts)
34
34
  add_flags_with_optional_args(opts)
35
35
  add_boolean_flags(opts)
36
36
  end.parse!(args)
@@ -44,12 +44,30 @@ module Rubocop
44
44
 
45
45
  private
46
46
 
47
+ def add_configuration_options(opts, args)
48
+ option(opts, '-c', '--config FILE', 'Specify configuration file.')
49
+
50
+ option(opts, '--auto-gen-config',
51
+ 'Generate a configuration file acting as a', 'TODO list.') do
52
+ validate_auto_gen_config_option(args)
53
+ @options[:formatters] = [[DEFAULT_FORMATTER],
54
+ [Formatter::DisabledConfigFormatter,
55
+ ConfigLoader::AUTO_GENERATED_FILE]]
56
+ end
57
+
58
+ option(opts, '--force-exclusion',
59
+ 'Force excluding files specified in the',
60
+ 'configuration `Exclude` even if they are',
61
+ 'explicitly passed as arguments.')
62
+ end
63
+
47
64
  FORMAT_HELP = ['Choose an output formatter. This option',
48
65
  'can be specified multiple times to enable',
49
66
  'multiple formatters at the same time.',
50
67
  ' [p]rogress (default)',
51
68
  ' [s]imple',
52
69
  ' [c]lang',
70
+ ' [d]isabled cops via inline comments',
53
71
  ' [fu]ubar',
54
72
  ' [e]macs',
55
73
  ' [j]son',
@@ -58,14 +76,6 @@ module Rubocop
58
76
  ' custom formatter class name']
59
77
 
60
78
  def add_formatting_options(opts, args)
61
- option(opts, '--auto-gen-config',
62
- 'Generate a configuration file acting as a', 'TODO list.') do
63
- validate_auto_gen_config_option(args)
64
- @options[:formatters] = [[DEFAULT_FORMATTER],
65
- [Formatter::DisabledConfigFormatter,
66
- ConfigLoader::AUTO_GENERATED_FILE]]
67
- end
68
-
69
79
  option(opts, '-f', '--format FORMATTER', *FORMAT_HELP) do |key|
70
80
  @options[:formatters] ||= []
71
81
  @options[:formatters] << [key]
@@ -81,6 +91,15 @@ module Rubocop
81
91
  end
82
92
  end
83
93
 
94
+ def add_severity_option(opts)
95
+ opts.on('--fail-level SEVERITY',
96
+ Rubocop::Cop::Severity::NAMES,
97
+ Rubocop::Cop::Severity::CODE_TABLE,
98
+ 'Minimum severity for exit with error code.') do |severity|
99
+ @options[:fail_level] = severity
100
+ end
101
+ end
102
+
84
103
  def add_flags_with_optional_args(opts)
85
104
  option(opts, '--show-cops [cop1,cop2,...]',
86
105
  'Shows the given cops, or all cops by',
@@ -6,7 +6,8 @@ module Rubocop
6
6
  module_function
7
7
 
8
8
  def relative_path(path, base_dir = Dir.pwd)
9
- Pathname.new(path).relative_path_from(Pathname.new(base_dir)).to_s
9
+ path_name = Pathname.new(File.expand_path(path))
10
+ path_name.relative_path_from(Pathname.new(base_dir)).to_s
10
11
  end
11
12
 
12
13
  def match_path?(pattern, path)
@@ -17,6 +17,10 @@ module Rubocop
17
17
  @comment_config = CommentConfig.new(self)
18
18
  end
19
19
 
20
+ def disabled_line_ranges
21
+ comment_config.cop_disabled_line_ranges
22
+ end
23
+
20
24
  def lines
21
25
  if @lines
22
26
  @lines
@@ -43,6 +47,10 @@ module Rubocop
43
47
  @diagnostics.none? { |d| [:error, :fatal].include?(d.level) }
44
48
  end
45
49
 
50
+ def file_path
51
+ @buffer.name
52
+ end
53
+
46
54
  private
47
55
 
48
56
  def init_lines
@@ -4,9 +4,17 @@ module Rubocop
4
4
  # This class finds target files to inspect by scanning the directory tree
5
5
  # and picking ruby files.
6
6
  class TargetFinder
7
- def initialize(config_store, debug = false)
7
+ def initialize(config_store, options = {})
8
8
  @config_store = config_store
9
- @debug = debug
9
+ @options = { force_exclusion: false, debug: false }.merge(options)
10
+ end
11
+
12
+ def force_exclusion?
13
+ @options[:force_exclusion]
14
+ end
15
+
16
+ def debug?
17
+ @options[:debug]
10
18
  end
11
19
 
12
20
  # Generate a list of target files by expanding globbing patterns
@@ -19,13 +27,11 @@ module Rubocop
19
27
  files = []
20
28
 
21
29
  args.uniq.each do |arg|
22
- if File.directory?(arg)
23
- files += target_files_in_dir(arg.chomp(File::SEPARATOR))
24
- elsif arg.include?('*')
25
- files += Dir[arg]
26
- else
27
- files << arg
28
- end
30
+ files += if File.directory?(arg)
31
+ target_files_in_dir(arg.chomp(File::SEPARATOR))
32
+ else
33
+ process_explicit_path(arg)
34
+ end
29
35
  end
30
36
 
31
37
  files.map { |f| File.expand_path(f) }.uniq
@@ -46,7 +52,7 @@ module Rubocop
46
52
  base_dir.gsub!(File::ALT_SEPARATOR, File::SEPARATOR)
47
53
  end
48
54
  files = Dir["#{base_dir}/**/*"].select { |path| FileTest.file?(path) }
49
- base_dir_config = @config_store.for("#{base_dir}/foobar.rb")
55
+ base_dir_config = @config_store.for(base_dir)
50
56
 
51
57
  target_files = files.select do |file|
52
58
  next false if base_dir_config.file_to_exclude?(file)
@@ -55,7 +61,7 @@ module Rubocop
55
61
  @config_store.for(file).file_to_include?(file)
56
62
  end
57
63
 
58
- target_files.uniq
64
+ target_files
59
65
  end
60
66
 
61
67
  def ruby_executable?(file)
@@ -63,8 +69,23 @@ module Rubocop
63
69
  first_line = File.open(file) { |f| f.readline }
64
70
  first_line =~ /#!.*ruby/
65
71
  rescue EOFError, ArgumentError => e
66
- warn "Unprocessable file #{file}: #{e.class}, #{e.message}" if @debug
72
+ warn "Unprocessable file #{file}: #{e.class}, #{e.message}" if debug?
67
73
  false
68
74
  end
75
+
76
+ def process_explicit_path(path)
77
+ files = if path.include?('*')
78
+ Dir[path]
79
+ else
80
+ [path]
81
+ end
82
+
83
+ return files unless force_exclusion?
84
+
85
+ files.reject do |file|
86
+ config = @config_store.for(file)
87
+ config.file_to_exclude?(file)
88
+ end
89
+ end
69
90
  end
70
91
  end
@@ -3,7 +3,7 @@
3
3
  module Rubocop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.19.1'
6
+ STRING = '0.20.0'
7
7
 
8
8
  MSG = '%s (using Parser %s, running on %s %s %s)'
9
9
 
@@ -0,0 +1,69 @@
1
+ There aren't many exciting new features this time around - our focus in 0.20 has been fixing most of the problems we
2
+ introduced in 0.19. Apart from that we've added a few new cops and implemented auto-correct for a bunch of the existing cops.
3
+ You'll also notice that the messages produced by most formatters a bit more colorful (and hopefully more readable as well).
4
+
5
+ You should also note that `AllCops/Includes` and `AllCops/Excludes` have been renamed, so you'll have to update your config files
6
+ accordingly.
7
+
8
+ Below is the list of all the gory details. Enjoy!
9
+
10
+ ### New features
11
+
12
+ * New cop `GuardClause` checks for conditionals that can be replaced by guard clauses. ([@bbatsov][])
13
+ * New cop `EmptyInterpolation` checks for empty interpolation in double-quoted strings. ([@bbatsov][])
14
+ * [#899](https://github.com/bbatsov/rubocop/issues/899): Make `LineEndConcatenation` cop `<<` aware. ([@mockdeep][])
15
+ * [#896](https://github.com/bbatsov/rubocop/issues/896): New option `--fail-level` changes minimum severity for exit with error code. ([@hiroponz][])
16
+ * [#893](https://github.com/bbatsov/rubocop/issues/893): New option `--force-exclusion` forces excluding files specified in the configuration `Exclude` even if they are explicitly passed as arguments. ([@yujinakayama][])
17
+ * `VariableInterpolation` cop does auto-correction. ([@bbatsov][])
18
+ * `Not` cop does auto-correction. ([@bbatsov][])
19
+ * `ClassMethods` cop does auto-correction. ([@bbatsov][])
20
+ * `StringConversionInInterpolation` cop does auto-correction. ([@bbatsov][])
21
+ * `NilComparison` cop does auto-correction. ([@bbatsov][])
22
+ * `NonNilComparison` cop does auto-correction. ([@bbatsov][])
23
+ * `NegatedIf` cop does auto-correction. ([@bbatsov][])
24
+ * `NegatedWhile` cop does auto-correction. ([@bbatsov][])
25
+ * New lint cop `SpaceBeforeFirstArg` checks for space between the method name and the first argument in method calls without parentheses. ([@jonas054][])
26
+ * New style cop `SingleSpaceBeforeFirstArg` checks that no more than one space is used between the method name and the first argument in method calls without parentheses. ([@jonas054][])
27
+ * New formatter `disabled_lines` displays cops and line ranges disabled by inline comments. ([@fshowalter][])
28
+ * New cop `UselessAccessModifiers` checks for access modifiers that have no effect. ([@fshowalter][])
29
+
30
+ ### Changes
31
+
32
+ * [#913](https://github.com/bbatsov/rubocop/issues/913): `FileName` accepts multiple extensions. ([@tamird][])
33
+ * `AllCops/Excludes` and `AllCops/Includes` were renamed to `AllCops/Exclude` and `AllCops/Include` for consistency with standard cop params. ([@bbatsov][])
34
+ * Extract `NonNilCheck` cop from `NilComparison`. ([@bbatsov][])
35
+ * Renamed `FavorJoin` to `ArrayJoin`. ([@bbatsov][])
36
+ * Renamed `FavorUnlessOverNegatedIf` to `NegatedIf`. ([@bbatsov][])
37
+ * Renamed `FavorUntilOverNegatedWhile`to `NegatedWhile`. ([@bbatsov][])
38
+ * Renamed `HashMethods` to `DeprecatedHashMethods`. ([@bbatsov][])
39
+ * Renamed `ReadAttribute` to `ReadWriteAttribute` and extended it to check for uses of `write_attribute`. ([@bbatsov][])
40
+ * Add experimental support for Ruby 2.2 (development version) by falling back to Ruby 2.1 parser. ([@yujinakayama][])
41
+
42
+ ### Bugs fixed
43
+
44
+ * [#926](https://github.com/bbatsov/rubocop/issues/926): Fixed `BlockNesting` not auto-generating correctly. ([@tmorris-fiksu][])
45
+ * [#904](https://github.com/bbatsov/rubocop/issues/904): Fixed a NPE in `LiteralInInterpolation`. ([@bbatsov][])
46
+ * [#904](https://github.com/bbatsov/rubocop/issues/904): Fixed a NPE in `StringConversionInInterpolation`. ([@bbatsov][])
47
+ * [#892](https://github.com/bbatsov/rubocop/issues/892): Make sure `Include` and `Exclude` paths in a `.rubocop.yml` are interpreted as relative to the directory of that file. ([@jonas054][])
48
+ * [#906](https://github.com/bbatsov/rubocop/issues/906): Fixed a false positive in `LiteralInInterpolation`. ([@bbatsov][])
49
+ * [#909](https://github.com/bbatsov/rubocop/issues/909): Handle properly multiple `rescue` clauses in `SignalException`. ([@bbatsov][])
50
+ * [#876](https://github.com/bbatsov/rubocop/issues/876): Do a deep merge of hashes when overriding default configuration in a `.rubocop.yml` file. ([@jonas054][])
51
+ * [#912](https://github.com/bbatsov/rubocop/issues/912): Fix a false positive in `LineEndConcatenation` for `%` string literals. ([@bbatsov][])
52
+ * [#912](https://github.com/bbatsov/rubocop/issues/912): Handle top-level constant resolution in `DeprecatedClassMethods` (e.g. `::File.exists?`). ([@bbatsov][])
53
+ * [#914](https://github.com/bbatsov/rubocop/issues/914): Fixed rdoc error during gem installation. ([@bbatsov][])
54
+ * The `--only` option now enables the given cop in case it is disabled in configuration. ([@jonas054][])
55
+ * Fix path resolution so that the default exclusion of `vendor` directories works. ([@jonas054][])
56
+ * [#908](https://github.com/bbatsov/rubocop/issues/908): Fixed hanging while auto correct for `SpaceAfterComma` and `SpaceInsideBrackets`. ([@hiroponz][])
57
+ * [#919](https://github.com/bbatsov/rubocop/issues/919): Don't avoid auto-correction in `HashSyntax` when there is missing space around operator. ([@jonas054][])
58
+ * Fixed handling of floats in `NumericLiterals`. ([@bbatsov][])
59
+ * [#927](https://github.com/bbatsov/rubocop/issues/927): Let `--auto-gen-config` overwrite an existing `rubocop-todo.yml` file instead of asking the user to remove it. ([@jonas054][])
60
+ * [#936](https://github.com/bbatsov/rubocop/issues/936): Allow `_other` as well as `other` in `OpMethod`. ([@bbatsov][])
61
+
62
+ [@bbatsov]: https://github.com/bbatsov
63
+ [@jonas054]: https://github.com/jonas054
64
+ [@yujinakayama]: https://github.com/yujinakayama
65
+ [@tmorris-fiksu]: https://github.com/tmorris-fiksu
66
+ [@mockdeep]: https://github.com/mockdeep
67
+ [@hiroponz]: https://github.com/hiroponz
68
+ [@tamird]: https://github.com/tamird
69
+ [@fshowalter]: https://github.com/fshowalter
@@ -8,7 +8,7 @@
8
8
  # Offense count: 6
9
9
  # Configuration parameters: CountComments.
10
10
  ClassLength:
11
- Max: 130
11
+ Max: 146
12
12
 
13
13
  # Offense count: 16
14
14
  CyclomaticComplexity:
@@ -17,4 +17,4 @@ CyclomaticComplexity:
17
17
  # Offense count: 105
18
18
  # Configuration parameters: CountComments.
19
19
  MethodLength:
20
- Max: 20
20
+ Max: 22
@@ -110,12 +110,15 @@ describe Rubocop::CLI, :isolated_environment do
110
110
  .to eq(["#{e}:2:1: C: Missing top-level class documentation " \
111
111
  'comment.',
112
112
  "#{e}:3:1: C: [Corrected] Indent access modifiers like " \
113
- 'private.',
114
- "#{e}:3:1: C: Keep a blank line before and after private.",
113
+ '`private`.',
114
+ "#{e}:3:1: C: Keep a blank line before and after `private`.",
115
+ "#{e}:3:1: W: Useless `private` access modifier.",
115
116
  # An offense that moves around during auto-correction will
116
117
  # appear to be duplicated:
117
- "#{e}:3:3: C: Keep a blank line before and after private.",
118
- "#{e}:4:7: C: [Corrected] Use %w or %W for array of words.",
118
+ "#{e}:3:3: C: Keep a blank line before and after `private`.",
119
+ "#{e}:3:3: W: Useless `private` access modifier.",
120
+ "#{e}:4:7: C: [Corrected] Use `%w` or `%W` " \
121
+ 'for array of words.',
119
122
  "#{e}:4:8: C: [Corrected] Prefer single-quoted strings " \
120
123
  "when you don't need string interpolation or special " \
121
124
  'symbols.',
@@ -185,8 +188,8 @@ describe Rubocop::CLI, :isolated_environment do
185
188
  '',
186
189
  'Offenses:',
187
190
  '',
188
- 'example.rb:2:1: C: [Corrected] Use `fail` instead of ' \
189
- '`raise` to signal exceptions.',
191
+ 'example.rb:2:1: C: [Corrected] Use fail instead of ' \
192
+ 'raise to signal exceptions.',
190
193
  'raise NotImplementedError,',
191
194
  '^^^^^',
192
195
  'example.rb:3:7: C: [Corrected] Align the parameters of a ' \
@@ -273,7 +276,6 @@ describe Rubocop::CLI, :isolated_environment do
273
276
  ['# encoding: utf-8',
274
277
  '{ :b=>1 }'])
275
278
  expect(cli.run(%w(-D --auto-correct --format emacs))).to eq(1)
276
- expect($stderr.string).to eq('')
277
279
  expect(IO.read('example.rb')).to eq(['# encoding: utf-8',
278
280
  '{ b: 1 }',
279
281
  ''].join("\n"))
@@ -286,6 +288,21 @@ describe Rubocop::CLI, :isolated_environment do
286
288
  ''].join("\n"))
287
289
  end
288
290
 
291
+ it 'can correct HashSyntax when --only is used' do
292
+ create_file('example.rb',
293
+ ['# encoding: utf-8',
294
+ '{ :b=>1 }'])
295
+ expect(cli.run(%w(--auto-correct -f emacs --only HashSyntax))).to eq(1)
296
+ expect($stderr.string).to eq('')
297
+ expect(IO.read('example.rb')).to eq(['# encoding: utf-8',
298
+ '{ b: 1 }',
299
+ ''].join("\n"))
300
+ expect($stdout.string)
301
+ .to eq(["#{abs('example.rb')}:2:3: C: [Corrected] Use the new " \
302
+ "Ruby 1.9 hash syntax.",
303
+ ''].join("\n"))
304
+ end
305
+
289
306
  it 'can correct TrailingBlankLines and TrailingWhitespace offenses' do
290
307
  create_file('example.rb',
291
308
  ['# encoding: utf-8',
@@ -357,29 +374,51 @@ describe Rubocop::CLI, :isolated_environment do
357
374
  'some_method(a,)',
358
375
  ''].join("\n"))
359
376
  end
377
+
378
+ it 'should not hang SpaceAfterPunctuation and SpaceInsideBrackets' do
379
+ create_file('example.rb',
380
+ ['# encoding: utf-8',
381
+ 'puts [1, ]'])
382
+ Timeout.timeout(10) do
383
+ expect(cli.run(%w(--auto-correct))).to eq(1)
384
+ end
385
+ expect($stderr.string).to eq('')
386
+ expect(IO.read('example.rb')).to eq(['# encoding: utf-8',
387
+ 'puts [1,]',
388
+ ''].join("\n"))
389
+ end
360
390
  end
361
391
 
362
392
  describe '--auto-gen-config' do
363
- it 'exits with error if asked to re-generate a todo list that is in ' \
364
- 'use' do
393
+ it 'overwrites an existing todo file' do
365
394
  create_file('example1.rb', ['# encoding: utf-8',
366
395
  'x= 0 ',
367
396
  '#' * 85,
368
397
  'y ',
369
398
  'puts x'])
370
- todo_contents = ['# This configuration was generated with `rubocop' \
371
- ' --auto-gen-config`',
372
- '',
373
- 'LineLength:',
374
- ' Enabled: false']
375
- create_file('rubocop-todo.yml', todo_contents)
376
- expect(IO.read('rubocop-todo.yml'))
377
- .to eq(todo_contents.join("\n") + "\n")
399
+ create_file('rubocop-todo.yml', ['LineLength:',
400
+ ' Enabled: false'])
378
401
  create_file('.rubocop.yml', ['inherit_from: rubocop-todo.yml'])
379
- expect { cli.run(['--auto-gen-config']) }.to exit_with_code(1)
380
- expect($stderr.string).to eq('Remove rubocop-todo.yml from the ' \
381
- 'current configuration before ' \
382
- "generating it again.\n")
402
+ expect(cli.run(['--auto-gen-config'])).to eq(1)
403
+ expect(IO.readlines('rubocop-todo.yml')[7..-1].map(&:chomp))
404
+ .to eq(['# Offense count: 1',
405
+ 'LineLength:',
406
+ ' Max: 85',
407
+ '',
408
+ '# Offense count: 1',
409
+ '# Cop supports --auto-correct.',
410
+ 'SpaceAroundOperators:',
411
+ ' Enabled: false',
412
+ '',
413
+ '# Offense count: 2',
414
+ '# Cop supports --auto-correct.',
415
+ 'TrailingWhitespace:',
416
+ ' Enabled: false'])
417
+
418
+ # Create new CLI instance to avoid using cached configuration.
419
+ new_cli = described_class.new
420
+
421
+ expect(new_cli.run(['example1.rb'])).to eq(0)
383
422
  end
384
423
 
385
424
  it 'exits with error if file arguments are given' do
@@ -410,7 +449,7 @@ describe Rubocop::CLI, :isolated_environment do
410
449
  expect($stderr.string).to eq('')
411
450
  expect($stdout.string)
412
451
  .to include(['Created rubocop-todo.yml.',
413
- 'Run rubocop with --config rubocop-todo.yml, or',
452
+ 'Run `rubocop --config rubocop-todo.yml`, or',
414
453
  'add inherit_from: rubocop-todo.yml in a ' \
415
454
  '.rubocop.yml file.',
416
455
  ''].join("\n"))
@@ -508,13 +547,34 @@ describe Rubocop::CLI, :isolated_environment do
508
547
  'example.rb'])).to eq(1)
509
548
  expect($stdout.string)
510
549
  .to eq(['== example.rb ==',
511
- 'C: 1: 1: Favor modifier if usage when you ' \
512
- 'have a single-line body. Another good alternative is ' \
550
+ 'C: 1: 1: Favor modifier if usage when ' \
551
+ 'having a single-line body. Another good alternative is ' \
513
552
  'the usage of control flow &&/||.',
514
553
  '',
515
554
  '1 file inspected, 1 offense detected',
516
555
  ''].join("\n"))
517
556
  end
557
+
558
+ it 'enables the given cop' do
559
+ create_file('example.rb', ['x = 0 ',
560
+ # Disabling comments still apply.
561
+ '# rubocop:disable TrailingWhitespace',
562
+ 'y = 1 '])
563
+
564
+ create_file('.rubocop.yml', ['TrailingWhitespace:',
565
+ ' Enabled: false'])
566
+
567
+ expect(cli.run(['--format', 'simple',
568
+ '--only', 'TrailingWhitespace',
569
+ 'example.rb'])).to eq(1)
570
+ expect($stderr.string).to eq('')
571
+ expect($stdout.string)
572
+ .to eq(['== example.rb ==',
573
+ 'C: 1: 6: Trailing whitespace detected.',
574
+ '',
575
+ '1 file inspected, 1 offense detected',
576
+ ''].join("\n"))
577
+ end
518
578
  end
519
579
 
520
580
  describe '--lint' do
@@ -759,7 +819,7 @@ describe Rubocop::CLI, :isolated_environment do
759
819
  'def badName',
760
820
  ' ^^^^^^^',
761
821
  'example3.rb:3:3: C: Favor modifier if usage ' \
762
- 'when you have a single-line body. Another good ' \
822
+ 'when having a single-line body. Another good ' \
763
823
  'alternative is the usage of control flow &&/||.',
764
824
  ' if something',
765
825
  ' ^^',
@@ -888,6 +948,42 @@ describe Rubocop::CLI, :isolated_environment do
888
948
  .to eq("#{abs(target_file)}:2:80: C: Line is too long. [90/79]\n")
889
949
  end
890
950
  end
951
+
952
+ describe '--fail-level option' do
953
+ let(:target_file) { 'example.rb' }
954
+
955
+ before do
956
+ create_file(target_file, ['# encoding: utf-8',
957
+ '#' * 90])
958
+ end
959
+
960
+ it 'should be failed when option is less than the severity level' do
961
+ expect(cli.run(['--fail-level', 'convention', target_file])).to eq(1)
962
+ end
963
+
964
+ it 'should be success when option is greater than the severity level' do
965
+ expect(cli.run(['--fail-level', 'warning', target_file])).to eq(0)
966
+ end
967
+ end
968
+
969
+ describe '--force-exclusion' do
970
+ let(:target_file) { 'example.rb' }
971
+
972
+ before do
973
+ create_file(target_file, ['# encoding: utf-8',
974
+ '#' * 90])
975
+
976
+ create_file('.rubocop.yml', ['AllCops:',
977
+ ' Exclude:',
978
+ " - #{target_file}"])
979
+
980
+ end
981
+
982
+ it 'excludes files specified in the configuration Exclude ' \
983
+ 'even if they are explicitly passed as arguments' do
984
+ expect(cli.run(['--force-exclusion', target_file])).to eq(0)
985
+ end
986
+ end
891
987
  end
892
988
 
893
989
  describe '#wants_to_quit?' do
@@ -1090,57 +1186,100 @@ describe Rubocop::CLI, :isolated_environment do
1090
1186
  .to eq(['', '1 file inspected, no offenses detected', ''].join("\n"))
1091
1187
  end
1092
1188
 
1093
- describe 'enabling/disabling rails cops' do
1094
- it 'by default does not run rails cops' do
1095
- create_file('app/models/example1.rb', ['# encoding: utf-8',
1096
- 'read_attribute(:test)'])
1097
- expect(cli.run(['--format', 'simple', 'app/models/example1.rb']))
1098
- .to eq(0)
1099
- end
1189
+ describe 'rails cops' do
1190
+ describe 'enabling/disabling' do
1191
+ it 'by default does not run rails cops' do
1192
+ create_file('app/models/example1.rb', ['# encoding: utf-8',
1193
+ 'read_attribute(:test)'])
1194
+ expect(cli.run(['--format', 'simple', 'app/models/example1.rb']))
1195
+ .to eq(0)
1196
+ end
1100
1197
 
1101
- it 'with -R given runs rails cops' do
1102
- create_file('app/models/example1.rb', ['# encoding: utf-8',
1103
- 'read_attribute(:test)'])
1104
- expect(cli.run(['--format', 'simple', '-R', 'app/models/example1.rb']))
1105
- .to eq(1)
1106
- expect($stdout.string).to include('Prefer self[:attribute]')
1107
- end
1198
+ it 'with -R given runs rails cops' do
1199
+ create_file('app/models/example1.rb', ['# encoding: utf-8',
1200
+ 'read_attribute(:test)'])
1201
+ expect(cli.run(['--format', 'simple', '-R', 'app/models/example1.rb']))
1202
+ .to eq(1)
1203
+ expect($stdout.string).to include('Prefer self[:attr]')
1204
+ end
1108
1205
 
1109
- it 'with configation option true in one dir runs rails cops there' do
1110
- create_file('dir1/app/models/example1.rb', ['# encoding: utf-8',
1111
- 'read_attribute(:test)'])
1112
- create_file('dir1/.rubocop.yml', ['AllCops:',
1113
- ' RunRailsCops: true',
1114
- '',
1115
- 'ReadAttribute:',
1116
- ' Include:',
1117
- ' - dir1/app/models/*.rb'])
1118
- create_file('dir2/app/models/example2.rb', ['# encoding: utf-8',
1119
- 'read_attribute(:test)'])
1120
- create_file('dir2/.rubocop.yml', ['AllCops:',
1121
- ' RunRailsCops: false',
1122
- '',
1123
- 'ReadAttribute:',
1124
- ' Include:',
1125
- ' - dir2/app/models/*.rb'])
1126
- expect(cli.run(%w(--format simple dir1 dir2))).to eq(1)
1127
- expect($stdout.string)
1128
- .to eq(['== dir1/app/models/example1.rb ==',
1129
- 'C: 2: 1: Prefer self[:attribute] over read_attribute' \
1130
- '(:attribute).',
1131
- '',
1132
- '2 files inspected, 1 offense detected',
1133
- ''].join("\n"))
1206
+ it 'with configation option true in one dir runs rails cops there' do
1207
+ source = ['# encoding: utf-8',
1208
+ 'read_attribute(:test)']
1209
+ create_file('dir1/app/models/example1.rb', source)
1210
+ create_file('dir1/.rubocop.yml', ['AllCops:',
1211
+ ' RunRailsCops: true',
1212
+ '',
1213
+ 'ReadAttribute:',
1214
+ ' Include:',
1215
+ ' - app/models/*.rb'])
1216
+ create_file('dir2/app/models/example2.rb', source)
1217
+ create_file('dir2/.rubocop.yml', ['AllCops:',
1218
+ ' RunRailsCops: false',
1219
+ '',
1220
+ 'ReadAttribute:',
1221
+ ' Include:',
1222
+ ' - app/models/*.rb'])
1223
+ expect(cli.run(%w(--format simple dir1 dir2))).to eq(1)
1224
+ expect($stdout.string)
1225
+ .to eq(['== dir1/app/models/example1.rb ==',
1226
+ 'C: 2: 1: Prefer self[:attr] over read_attribute' \
1227
+ '(:attr).',
1228
+ '',
1229
+ '2 files inspected, 1 offense detected',
1230
+ ''].join("\n"))
1231
+ end
1232
+
1233
+ it 'with configation option false but -R given runs rails cops' do
1234
+ create_file('app/models/example1.rb', ['# encoding: utf-8',
1235
+ 'read_attribute(:test)'])
1236
+ create_file('.rubocop.yml', ['AllCops:',
1237
+ ' RunRailsCops: false'])
1238
+ expect(cli.run(['--format', 'simple', '-R', 'app/models/example1.rb']))
1239
+ .to eq(1)
1240
+ expect($stdout.string).to include('Prefer self[:attr]')
1241
+ end
1134
1242
  end
1135
1243
 
1136
- it 'with configation option false but -R given runs rails cops' do
1137
- create_file('app/models/example1.rb', ['# encoding: utf-8',
1138
- 'read_attribute(:test)'])
1139
- create_file('.rubocop.yml', ['AllCops:',
1140
- ' RunRailsCops: false'])
1141
- expect(cli.run(['--format', 'simple', '-R', 'app/models/example1.rb']))
1142
- .to eq(1)
1143
- expect($stdout.string).to include('Prefer self[:attribute]')
1244
+ describe 'including/excluding' do
1245
+ it 'includes some directories by default' do
1246
+ source = ['# encoding: utf-8',
1247
+ 'read_attribute(:test)',
1248
+ "default_scope order: 'position'"]
1249
+ # Several rails cops include app/models by default.
1250
+ create_file('dir1/app/models/example1.rb', source)
1251
+ create_file('dir1/app/models/example2.rb', source)
1252
+ # No rails cops include app/views by default.
1253
+ create_file('dir1/app/views/example3.rb', source)
1254
+ # The .rubocop.yml file inherits from default.yml where the Include
1255
+ # config parameter is set for the rails cops. The paths are interpreted
1256
+ # as relative to dir1 because .rubocop.yml is placed there.
1257
+ create_file('dir1/.rubocop.yml', ['AllCops:',
1258
+ ' RunRailsCops: true',
1259
+ '',
1260
+ 'ReadWriteAttribute:',
1261
+ ' Exclude:',
1262
+ ' - example2.rb',
1263
+ '',
1264
+ 'DefaultScope:',
1265
+ ' Exclude:',
1266
+ ' - "**/example2.rb"'])
1267
+ # No .rubocop.yml file in dir2 means that the paths from default.yml
1268
+ # are interpreted as relative to the current directory, so they don't
1269
+ # match.
1270
+ create_file('dir2/app/models/example4.rb', source)
1271
+
1272
+ expect(cli.run(%w(--format simple dir1 dir2))).to eq(1)
1273
+ expect($stdout.string)
1274
+ .to eq(['== dir1/app/models/example1.rb ==',
1275
+ 'C: 2: 1: Prefer self[:attr] over read_attribute' \
1276
+ '(:attr).',
1277
+ 'C: 3: 15: default_scope expects a block as its sole' \
1278
+ ' argument.',
1279
+ '',
1280
+ '4 files inspected, 2 offenses detected',
1281
+ ''].join("\n"))
1282
+ end
1144
1283
  end
1145
1284
  end
1146
1285
 
@@ -1180,7 +1319,7 @@ describe Rubocop::CLI, :isolated_environment do
1180
1319
  'puts x'
1181
1320
  ])
1182
1321
  create_file('.rubocop.yml', ['AllCops:',
1183
- ' Includes:',
1322
+ ' Include:',
1184
1323
  ' - example',
1185
1324
  ' - !ruby/regexp /regexp$/'
1186
1325
  ])
@@ -1205,7 +1344,7 @@ describe Rubocop::CLI, :isolated_environment do
1205
1344
  'puts x'
1206
1345
  ])
1207
1346
  create_file('.rubocop.yml', ['AllCops:',
1208
- ' Excludes:',
1347
+ ' Exclude:',
1209
1348
  ' - example.rb',
1210
1349
  ' - !ruby/regexp /regexp.rb$/',
1211
1350
  ' - "exclude_*"'
@@ -1226,7 +1365,7 @@ describe Rubocop::CLI, :isolated_environment do
1226
1365
  end
1227
1366
 
1228
1367
  create_file('example/.rubocop.yml', ['AllCops:',
1229
- ' Excludes:',
1368
+ ' Exclude:',
1230
1369
  ' - ignored/**'])
1231
1370
  expect(File).not_to receive(:open).with(%r{/ignored/})
1232
1371
  allow(File).to receive(:open).and_call_original
@@ -1277,23 +1416,48 @@ describe Rubocop::CLI, :isolated_environment do
1277
1416
  expect($stdout.string).to include('unexpected token $end')
1278
1417
  end
1279
1418
 
1280
- it 'can be configured to override a parameter that is a hash' do
1419
+ it 'can be configured to merge a parameter that is a hash' do
1281
1420
  create_file('example1.rb',
1282
1421
  ['# encoding: utf-8',
1283
- 'arr.find_all { |e| e > 0 }.collect { |e| -e }'])
1284
- # We only care about select over find_all. All other preferred methods
1285
- # appearing in the default config are gone when we override
1286
- # PreferredMethods. We get no report about collect.
1422
+ 'puts %w(a b c)',
1423
+ 'puts %q|hi|'])
1424
+ # We want to change the preferred delimiters for word arrays. The other
1425
+ # settings from default.yml are unchanged.
1426
+ create_file('rubocop.yml',
1427
+ ['PercentLiteralDelimiters:',
1428
+ ' PreferredDelimiters:',
1429
+ " '%w': '[]'",
1430
+ " '%W': '[]'"])
1431
+ cli.run(['--format', 'simple', '-c', 'rubocop.yml', 'example1.rb'])
1432
+ expect($stdout.string)
1433
+ .to eq(['== example1.rb ==',
1434
+ 'C: 2: 6: %w-literals should be delimited by [ and ]',
1435
+ 'C: 3: 6: %q-literals should be delimited by ( and )',
1436
+ '',
1437
+ '1 file inspected, 2 offenses detected',
1438
+ ''].join("\n"))
1439
+ end
1440
+
1441
+ it 'can be configured to override a parameter that is a hash in a ' \
1442
+ 'special case' do
1443
+ create_file('example1.rb',
1444
+ ['# encoding: utf-8',
1445
+ 'arr.select { |e| e > 0 }.collect { |e| -e }',
1446
+ 'a2.find_all { |e| e > 0 }'])
1447
+ # We prefer find_all over select. This setting overrides the default
1448
+ # select over find_all. Other preferred methods appearing in the default
1449
+ # config (e.g., map over collect) are kept.
1287
1450
  create_file('rubocop.yml',
1288
1451
  ['CollectionMethods:',
1289
1452
  ' PreferredMethods:',
1290
- ' find_all: select'])
1453
+ ' select: find_all'])
1291
1454
  cli.run(['--format', 'simple', '-c', 'rubocop.yml', 'example1.rb'])
1292
1455
  expect($stdout.string)
1293
1456
  .to eq(['== example1.rb ==',
1294
- 'C: 2: 5: Prefer select over find_all.',
1457
+ 'C: 2: 5: Prefer find_all over select.',
1458
+ 'C: 2: 26: Prefer map over collect.',
1295
1459
  '',
1296
- '1 file inspected, 1 offense detected',
1460
+ '1 file inspected, 2 offenses detected',
1297
1461
  ''].join("\n"))
1298
1462
  end
1299
1463
 
@@ -1311,7 +1475,7 @@ describe Rubocop::CLI, :isolated_environment do
1311
1475
  '-c', 'rubocop.yml', 'example1.rb'])
1312
1476
  expect($stdout.string)
1313
1477
  .to eq(['== example1.rb ==',
1314
- 'C: 1: 1: Favor modifier if usage when you have ' \
1478
+ 'C: 1: 1: Favor modifier if usage when having ' \
1315
1479
  'a single-line body. Another good alternative is the ' \
1316
1480
  'usage of control flow &&/||.',
1317
1481
  '',
@@ -1397,7 +1561,7 @@ describe Rubocop::CLI, :isolated_environment do
1397
1561
  end
1398
1562
 
1399
1563
  create_file('example/.rubocop.yml', ['AllCops:',
1400
- ' Excludes:',
1564
+ ' Exclude:',
1401
1565
  ' - src/**',
1402
1566
  ' - etc/**',
1403
1567
  ' - tmp/spec/**'])
@@ -1414,7 +1578,7 @@ describe Rubocop::CLI, :isolated_environment do
1414
1578
  it 'can exclude a typical vendor directory' do
1415
1579
  create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
1416
1580
  ['AllCops:',
1417
- ' Excludes:',
1581
+ ' Exclude:',
1418
1582
  ' - lib/parser/lexer.rb'])
1419
1583
 
1420
1584
  create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
@@ -1423,7 +1587,7 @@ describe Rubocop::CLI, :isolated_environment do
1423
1587
 
1424
1588
  create_file('.rubocop.yml',
1425
1589
  ['AllCops:',
1426
- ' Excludes:',
1590
+ ' Exclude:',
1427
1591
  ' - vendor/**'])
1428
1592
 
1429
1593
  cli.run(%w(--format simple))
@@ -1432,6 +1596,17 @@ describe Rubocop::CLI, :isolated_environment do
1432
1596
  ''].join("\n"))
1433
1597
  end
1434
1598
 
1599
+ it 'excludes the vendor directory by default' do
1600
+ create_file('vendor/ex.rb',
1601
+ ['# encoding: utf-8',
1602
+ '#' * 90])
1603
+
1604
+ cli.run(%w(--format simple))
1605
+ expect($stdout.string)
1606
+ .to eq(['', '0 files inspected, no offenses detected',
1607
+ ''].join("\n"))
1608
+ end
1609
+
1435
1610
  # Being immune to bad configuration files in excluded directories has
1436
1611
  # become important due to a bug in rubygems
1437
1612
  # (https://github.com/rubygems/rubygems/issues/680) that makes
@@ -1447,7 +1622,7 @@ describe Rubocop::CLI, :isolated_environment do
1447
1622
 
1448
1623
  create_file('.rubocop.yml',
1449
1624
  ['AllCops:',
1450
- ' Excludes:',
1625
+ ' Exclude:',
1451
1626
  ' - vendor/**'])
1452
1627
 
1453
1628
  cli.run(%w(--format simple))
@@ -1463,7 +1638,7 @@ describe Rubocop::CLI, :isolated_environment do
1463
1638
  it 'can exclude a vendor directory indirectly' do
1464
1639
  create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
1465
1640
  ['AllCops:',
1466
- ' Excludes:',
1641
+ ' Exclude:',
1467
1642
  ' - lib/parser/lexer.rb'])
1468
1643
 
1469
1644
  create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
@@ -1475,7 +1650,7 @@ describe Rubocop::CLI, :isolated_environment do
1475
1650
 
1476
1651
  create_file('config/default.yml',
1477
1652
  ['AllCops:',
1478
- ' Excludes:',
1653
+ ' Exclude:',
1479
1654
  ' - vendor/**'])
1480
1655
 
1481
1656
  cli.run(%w(--format simple))
@@ -1516,13 +1691,13 @@ describe Rubocop::CLI, :isolated_environment do
1516
1691
  ''].join("\n"))
1517
1692
  end
1518
1693
 
1519
- it 'works when a configuration file passed by -c specifies Excludes ' \
1694
+ it 'works when a configuration file passed by -c specifies Exclude ' \
1520
1695
  'with regexp' do
1521
1696
  create_file('example/example1.rb', ['# encoding: utf-8',
1522
1697
  '#' * 90])
1523
1698
 
1524
1699
  create_file('rubocop.yml', ['AllCops:',
1525
- ' Excludes:',
1700
+ ' Exclude:',
1526
1701
  ' - !ruby/regexp /example1\.rb$/'])
1527
1702
 
1528
1703
  cli.run(%w(--format simple -c rubocop.yml))
@@ -1531,13 +1706,13 @@ describe Rubocop::CLI, :isolated_environment do
1531
1706
  ''].join("\n"))
1532
1707
  end
1533
1708
 
1534
- it 'works when a configuration file passed by -c specifies Excludes ' \
1709
+ it 'works when a configuration file passed by -c specifies Exclude ' \
1535
1710
  'with strings' do
1536
1711
  create_file('example/example1.rb', ['# encoding: utf-8',
1537
1712
  '#' * 90])
1538
1713
 
1539
1714
  create_file('rubocop.yml', ['AllCops:',
1540
- ' Excludes:',
1715
+ ' Exclude:',
1541
1716
  ' - example/**'])
1542
1717
 
1543
1718
  cli.run(%w(--format simple -c rubocop.yml))