rubocop 0.49.0 → 0.49.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b593dc9fec24a2f53061b6e5579f49e6597e564
4
- data.tar.gz: 72f662af431c19f0811db82ec40b6b461057b237
3
+ metadata.gz: 19d303a2e571971385e48eab0517fd03f0273c9c
4
+ data.tar.gz: 30129d935542762c11820ad7386ff213d4944cd2
5
5
  SHA512:
6
- metadata.gz: 1a9d358a6e049e185056789b1b82c1fb5cdbe1f2358fb5138646f46df6376136e7819f3ea8edc4ae1b730ef2ca57a2a488449a40db2b5849625d974a8929ad2b
7
- data.tar.gz: f8563e03d90a81c1f7f9cd587ec32e91838ce938b3cc936dd8f490c4c4756910350beef1a1de7c286f9c36bac7bab748b49018b413a02bcfa617eaf5093cb943
6
+ metadata.gz: 8725c2dc3d92496b06acd39cc8efc4fd25e45e5ea7b3e3e3f565cf923de82c46f5efec1e279b75151f3a81341b94b9c70c0c3c66af60c3ab2bd2b844963993b9
7
+ data.tar.gz: d51e988da1e14e4b9477a2f5bec04cbd9509bcc09bb8febfc3e8d2df9957e8c98bb5c94e90fa3bacf9b0d848d496427bf6c57206c48a9c7acc3490bfade5d7c6
data/README.md CHANGED
@@ -51,7 +51,7 @@ haven't reached version 1.0 yet). To prevent an unwanted RuboCop update you
51
51
  might want to use a conservative version locking in your `Gemfile`:
52
52
 
53
53
  ```rb
54
- gem 'rubocop', '~> 0.49.0', require: false
54
+ gem 'rubocop', '~> 0.49.1', require: false
55
55
  ```
56
56
 
57
57
  ## Quickstart
@@ -63,6 +63,7 @@ require 'rubocop/cop/commissioner'
63
63
  require 'rubocop/cop/corrector'
64
64
  require 'rubocop/cop/force'
65
65
  require 'rubocop/cop/severity'
66
+ require 'rubocop/cop/generator'
66
67
 
67
68
  require 'rubocop/cop/variable_force'
68
69
  require 'rubocop/cop/variable_force/branch'
@@ -165,6 +165,12 @@ module RuboCop
165
165
  def handle_disabled_by_default(config, new_default_configuration)
166
166
  department_config = config.to_hash.reject { |cop| cop.include?('/') }
167
167
  department_config.each do |dept, dept_params|
168
+ # Rails is always disabled by default and the department's Enabled
169
+ # flag works like the --rails command line option, which is that when
170
+ # AllCops:DisabledByDefault is true, each Rails cop must still be
171
+ # explicitly mentioned in user configuration in order to be enabled.
172
+ next if dept == 'Rails'
173
+
168
174
  next unless dept_params['Enabled']
169
175
 
170
176
  new_default_configuration.each do |cop, params|
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Source and spec generator for new cops
6
+ #
7
+ # This generator will take a cop name and generate a source file
8
+ # and spec file when given a valid qualified cop name.
9
+ class Generator
10
+ SOURCE_TEMPLATE = <<-RUBY.strip_indent
11
+ # frozen_string_literal: true
12
+
13
+ # TODO: when finished, run `rake generate_cops_documentation` to update the docs
14
+ module RuboCop
15
+ module Cop
16
+ module %<department>s
17
+ # TODO: Write cop description and example of bad / good code.
18
+ #
19
+ # @example
20
+ # # bad
21
+ # bad_method()
22
+ #
23
+ # # bad
24
+ # bad_method(args)
25
+ #
26
+ # # good
27
+ # good_method()
28
+ #
29
+ # # good
30
+ # good_method(args)
31
+ class %<cop_name>s < Cop
32
+ # TODO: Implement the cop into here.
33
+ #
34
+ # In many cases, you can use a node matcher for matching node pattern.
35
+ # See. https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/node_pattern.rb
36
+ #
37
+ # For example
38
+ MSG = 'Message of %<cop_name>s'.freeze
39
+
40
+ def_node_matcher :bad_method?, <<-PATTERN
41
+ (send nil :bad_method ...)
42
+ PATTERN
43
+
44
+ def on_send(node)
45
+ return unless bad_method?(node)
46
+ add_offense(node, :expression)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ RUBY
53
+
54
+ SPEC_TEMPLATE = <<-RUBY.strip_indent
55
+ # frozen_string_literal: true
56
+
57
+ describe RuboCop::Cop::%<department>s::%<cop_name>s do
58
+ let(:config) { RuboCop::Config.new }
59
+ subject(:cop) { described_class.new(config) }
60
+
61
+ # TODO: Write test code
62
+ #
63
+ # For example
64
+ it 'registers an offense for offending code' do
65
+ inspect_source(cop, 'bad_method')
66
+ expect(cop.offenses.size).to eq(1)
67
+ expect(cop.messages)
68
+ .to eq(['Message of %<cop_name>s'])
69
+ end
70
+
71
+ it 'accepts' do
72
+ inspect_source(cop, 'good_method')
73
+ expect(cop.offenses).to be_empty
74
+ end
75
+ end
76
+ RUBY
77
+
78
+ def initialize(name)
79
+ @badge = Badge.parse(name)
80
+
81
+ return if badge.qualified?
82
+
83
+ raise ArgumentError, 'Specify a cop name with Department/Name style'
84
+ end
85
+
86
+ def write_source
87
+ write_unless_file_exists(source_path, generated_source)
88
+ end
89
+
90
+ def write_spec
91
+ write_unless_file_exists(spec_path, generated_spec)
92
+ end
93
+
94
+ def todo
95
+ <<-TODO.strip_indent
96
+ created
97
+ - #{source_path}
98
+ - #{spec_path}
99
+
100
+ Do 4 steps
101
+ - Add an entry to `New feature` section in CHANGELOG.md
102
+ - e.g. Add new `#{badge.cop_name}` cop. ([@your_id][])
103
+ - Add `require '#{require_path}'` into lib/rubocop.rb
104
+ - Add an entry into config/enabled.yml or config/disabled.yml
105
+ - Implement a new cop to the generated file!
106
+ TODO
107
+ end
108
+
109
+ private
110
+
111
+ attr_reader :badge
112
+
113
+ def write_unless_file_exists(path, contents)
114
+ raise "#{path} already exists!" if File.exist?(path)
115
+
116
+ File.write(path, contents)
117
+ end
118
+
119
+ def generated_source
120
+ generate(SOURCE_TEMPLATE)
121
+ end
122
+
123
+ def generated_spec
124
+ generate(SPEC_TEMPLATE)
125
+ end
126
+
127
+ def generate(template)
128
+ format(template, department: badge.department, cop_name: badge.cop_name)
129
+ end
130
+
131
+ def require_path
132
+ source_path.sub('lib/', '').sub('.rb', '')
133
+ end
134
+
135
+ def spec_path
136
+ File.join(
137
+ 'spec',
138
+ 'rubocop',
139
+ 'cop',
140
+ snake_case(badge.department.to_s),
141
+ "#{snake_case(badge.cop_name.to_s)}_spec.rb"
142
+ )
143
+ end
144
+
145
+ def source_path
146
+ File.join(
147
+ 'lib',
148
+ 'rubocop',
149
+ 'cop',
150
+ snake_case(badge.department.to_s),
151
+ "#{snake_case(badge.cop_name.to_s)}.rb"
152
+ )
153
+ end
154
+
155
+ def snake_case(camel_case_string)
156
+ camel_case_string
157
+ .gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
158
+ .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2')
159
+ .downcase
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubocop/cop/internal_affairs/node_type_predicate'
4
+ require 'rubocop/cop/internal_affairs/useless_message_assertion'
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks that node types are checked using the predicate helpers.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # node.type == :send
12
+ #
13
+ # # good
14
+ # node.send_type?
15
+ #
16
+ class NodeTypePredicate < Cop
17
+ MSG = 'Use `#%s_type?` to check node type.'.freeze
18
+
19
+ def_node_search :node_type_check, <<-PATTERN
20
+ (send (send _ :type) :== (sym $_))
21
+ PATTERN
22
+
23
+ def on_send(node)
24
+ node_type_check(node) do |node_type|
25
+ return unless Parser::Meta::NODE_TYPES.include?(node_type)
26
+
27
+ add_offense(node, :expression, format(MSG, node_type))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks that cops are not tested using `described_class::MSG`.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # expect(cop.messages).to eq([described_class::MSG])
12
+ #
13
+ # # good
14
+ # expect(cop.messages).to eq(['Do not write bad code like that.'])
15
+ #
16
+ class UselessMessageAssertion < Cop
17
+ MSG = 'Do not specify cop behavior using `described_class::MSG`.'.freeze
18
+
19
+ def_node_search :described_class_msg, <<-PATTERN
20
+ (const (send nil :described_class) :MSG)
21
+ PATTERN
22
+
23
+ def_node_matcher :rspec_expectation_on_msg?, <<-PATTERN
24
+ (send (send nil :expect #contains_described_class_msg?) :to ...)
25
+ PATTERN
26
+
27
+ def investigate(_processed_source)
28
+ assertions_using_described_class_msg.each do |node|
29
+ add_offense(node, :expression)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def contains_described_class_msg?(node)
36
+ described_class_msg(node).any?
37
+ end
38
+
39
+ def assertions_using_described_class_msg
40
+ described_class_msg(processed_source.ast).reject do |node|
41
+ node.ancestors.any?(&method(:rspec_expectation_on_msg?))
42
+ end
43
+ end
44
+
45
+ # Only process spec files
46
+ def relevant_file?(file)
47
+ file.end_with?('_spec.rb')
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -7,11 +7,27 @@ module RuboCop
7
7
  #
8
8
  # @example
9
9
  #
10
+ # # EnforcedStyleInsidePipes: no_space (default)
11
+ #
10
12
  # # bad
11
13
  # {}.each { | x, y |puts x }
14
+ # ->( x, y ) { puts x }
12
15
  #
13
16
  # # good
14
17
  # {}.each { |x, y| puts x }
18
+ # ->(x, y) { puts x }
19
+ #
20
+ # @example
21
+ #
22
+ # # EnforcedStyleInsidePipes: space
23
+ #
24
+ # # bad
25
+ # {}.each { |x, y| puts x }
26
+ # ->(x, y) { puts x }
27
+ #
28
+ # # good
29
+ # {}.each { | x, y | puts x }
30
+ # ->( x, y ) { puts x }
15
31
  class SpaceAroundBlockParameters < Cop
16
32
  include ConfigurableEnforcedStyle
17
33
 
@@ -22,6 +38,7 @@ module RuboCop
22
38
 
23
39
  opening_pipe = args.loc.begin
24
40
  closing_pipe = args.loc.end
41
+ return if opening_pipe.nil? || closing_pipe.nil?
25
42
 
26
43
  check_inside_pipes(args.children, opening_pipe, closing_pipe)
27
44
 
@@ -136,7 +136,7 @@ module RuboCop
136
136
  def arguments_count(args)
137
137
  if args.empty?
138
138
  0
139
- elsif args.last.type == :splat
139
+ elsif args.last.splat_type?
140
140
  -(args.count - 1)
141
141
  else
142
142
  args.count
@@ -69,7 +69,7 @@ module RuboCop
69
69
  def_node_matcher :match_method?, <<-PATTERN
70
70
  {
71
71
  (send _recv :match _)
72
- (send _recv :match _ (:int ...))
72
+ (send _recv :match _ (int ...))
73
73
  }
74
74
  PATTERN
75
75
 
@@ -57,7 +57,7 @@ module RuboCop
57
57
  end
58
58
 
59
59
  def string_with_slash?(node)
60
- node.type == :str && node.source =~ %r{/}
60
+ node.str_type? && node.source =~ %r{/}
61
61
  end
62
62
 
63
63
  def register_offense(node)
@@ -56,11 +56,11 @@ module RuboCop
56
56
  end
57
57
 
58
58
  def special_keyword_arg?(node)
59
- KEYWORD_ARGS.include?(node.children.first) if node.type == :sym
59
+ KEYWORD_ARGS.include?(node.children.first) if node.sym_type?
60
60
  end
61
61
 
62
62
  def format_arg?(node)
63
- node.children.first == :format if node.type == :sym
63
+ node.children.first == :format if node.sym_type?
64
64
  end
65
65
 
66
66
  def convert_hash_data(data, type)
@@ -301,6 +301,9 @@ module RuboCop
301
301
  def assignment_node(node)
302
302
  *_variable, assignment = *node
303
303
 
304
+ # ignore pseudo-assignments without rhs in for nodes
305
+ return if node.parent && node.parent.for_type?
306
+
304
307
  if assignment.begin_type? && assignment.children.one?
305
308
  assignment, = *assignment
306
309
  end
@@ -6,37 +6,42 @@ module RuboCop
6
6
  # This cop checks for the formatting of empty method definitions.
7
7
  # By default it enforces empty method definitions to go on a single
8
8
  # line (compact style), but it can be configured to enforce the `end`
9
- # to go on its own line (expanded style.)
9
+ # to go on its own line (expanded style).
10
10
  #
11
11
  # Note: A method definition is not considered empty if it contains
12
12
  # comments.
13
13
  #
14
14
  # @example
15
15
  #
16
- # EnforcedStyle: compact (default)
16
+ # # EnforcedStyle: compact (default)
17
17
  #
18
18
  # @bad
19
19
  # def foo(bar)
20
20
  # end
21
+ #
21
22
  # def self.foo(bar)
22
23
  # end
23
24
  #
24
25
  # @good
25
26
  # def foo(bar); end
27
+ #
26
28
  # def foo(bar)
27
29
  # # baz
28
30
  # end
31
+ #
29
32
  # def self.foo(bar); end
30
33
  #
31
- # EnforcedStyle: expanded
34
+ # # EnforcedStyle: expanded
32
35
  #
33
36
  # @bad
34
37
  # def foo(bar); end
38
+ #
35
39
  # def self.foo(bar); end
36
40
  #
37
41
  # @good
38
42
  # def foo(bar)
39
43
  # end
44
+ #
40
45
  # def self.foo(bar)
41
46
  # end
42
47
  class EmptyMethod < Cop
@@ -70,9 +75,10 @@ module RuboCop
70
75
  def corrected(node)
71
76
  method_name, args, _body, scope = method_def_node_parts(node)
72
77
 
73
- arguments = args.source unless args.children.empty?
74
- joint = compact_style? ? '; ' : "\n"
75
- scope = scope ? 'self.' : ''
78
+ arguments = !args.children.empty? ? args.source : ''
79
+ indent = ' ' * node.loc.column
80
+ joint = compact_style? ? '; ' : "\n#{indent}"
81
+ scope = scope ? 'self.' : ''
76
82
 
77
83
  ["def #{scope}#{method_name}#{arguments}", 'end'].join(joint)
78
84
  end
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # a = 'a'
16
16
  # foo if ['a', 'b', 'c'].include?(a)
17
17
  class MultipleComparison < Cop
18
- MSG = 'Avoid comparing a variable with multiple items' \
18
+ MSG = 'Avoid comparing a variable with multiple items ' \
19
19
  'in a conditional, use `Array#include?` instead.'.freeze
20
20
 
21
21
  def on_if(node)
@@ -153,7 +153,7 @@ module RuboCop
153
153
  def end_range(node)
154
154
  source_buffer = node.source_range.source_buffer
155
155
  end_pos = node.loc.end.end_pos
156
- begin_pos = node.loc.end.begin_pos - node.source_range.column
156
+ begin_pos = node.loc.end.begin_pos - node.loc.end.column
157
157
  begin_pos -= 1 if end_followed_by_whitespace_only?(source_buffer,
158
158
  end_pos)
159
159
 
@@ -99,7 +99,7 @@ module RuboCop
99
99
  # If the condition is parenthesized we recurse and check for any
100
100
  # complex expressions within it.
101
101
  def complex_condition?(condition)
102
- if condition.type == :begin
102
+ if condition.begin_type?
103
103
  condition.to_a.any? { |x| complex_condition?(x) }
104
104
  else
105
105
  non_complex_type?(condition) ? false : true
@@ -93,7 +93,8 @@ module RuboCop
93
93
  def complex_content?(strings)
94
94
  strings.any? do |s|
95
95
  string = s.str_content
96
- !string.valid_encoding? || string !~ word_regex || string =~ / /
96
+ !string.dup.force_encoding(::Encoding::UTF_8).valid_encoding? ||
97
+ string !~ word_regex || string =~ / /
97
98
  end
98
99
  end
99
100
 
@@ -22,7 +22,7 @@ module RuboCop
22
22
  # for <= 42
23
23
  class YodaCondition < Cop
24
24
  MSG = 'Reverse the order of the operands `%s`.'.freeze
25
- WHITELIST_TYPES = %i[lvar ivar send const regexp begin].freeze
25
+
26
26
  REVERSE_COMPARISON = {
27
27
  '<' => '>',
28
28
  '<=' => '>=',
@@ -41,7 +41,7 @@ module RuboCop
41
41
  def yoda_condition?(node)
42
42
  return false unless comparison_operator?(node)
43
43
 
44
- !WHITELIST_TYPES.include?(node.receiver.type)
44
+ node.receiver.literal? && !node.arguments.first.literal?
45
45
  end
46
46
 
47
47
  def comparison_operator?(node)
@@ -49,7 +49,7 @@ module RuboCop
49
49
  # Warms up the RuboCop cache by forking a suitable number of rubocop
50
50
  # instances that each inspects its alotted group of files.
51
51
  def warm_cache(target_files)
52
- puts 'Running parallel inspection'
52
+ puts 'Running parallel inspection' if @options[:debug]
53
53
  Parallel.each(target_files, &method(:file_offenses))
54
54
  end
55
55
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.49.0'.freeze
6
+ STRING = '0.49.1'.freeze
7
7
 
8
8
  MSG = '%s (using Parser %s, running on %s %s %s)'.freeze
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.49.0
4
+ version: 0.49.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-05-24 00:00:00.000000000 Z
13
+ date: 2017-05-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rainbow
@@ -191,7 +191,11 @@ files:
191
191
  - lib/rubocop/cop/cop.rb
192
192
  - lib/rubocop/cop/corrector.rb
193
193
  - lib/rubocop/cop/force.rb
194
+ - lib/rubocop/cop/generator.rb
194
195
  - lib/rubocop/cop/ignored_node.rb
196
+ - lib/rubocop/cop/internal_affairs.rb
197
+ - lib/rubocop/cop/internal_affairs/node_type_predicate.rb
198
+ - lib/rubocop/cop/internal_affairs/useless_message_assertion.rb
195
199
  - lib/rubocop/cop/layout/access_modifier_indentation.rb
196
200
  - lib/rubocop/cop/layout/align_array.rb
197
201
  - lib/rubocop/cop/layout/align_hash.rb