rubocop 0.49.0 → 0.49.1

Sign up to get free protection for your applications and to get access to all the features.
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