diff --git a/.circleci/config.yml b/.circleci/config.yml index ade82f94667..734b7f83a9c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,29 +44,6 @@ rubocop_steps: &rubocop_steps jobs: - # Ruby 2.3 - ruby-2.3-spec: - docker: - - image: circleci/ruby:2.3 - environment: - <<: *common_env - steps: - *spec_steps - ruby-2.3-ascii_spec: - docker: - - image: circleci/ruby:2.3 - environment: - <<: *common_env - steps: - *ascii_spec_steps - ruby-2.3-rubocop: - docker: - - image: circleci/ruby:2.3 - environment: - <<: *common_env - steps: - *rubocop_steps - # Ruby 2.4 ruby-2.4-spec: docker: @@ -240,7 +217,7 @@ jobs: - run: name: Upload coverage results to Code Climate command: | - ./tmp/cc-test-reporter sum-coverage tmp/codeclimate.*.json --parts 6 --output tmp/codeclimate.total.json + ./tmp/cc-test-reporter sum-coverage tmp/codeclimate.*.json --parts 5 --output tmp/codeclimate.total.json ./tmp/cc-test-reporter upload-coverage --input tmp/codeclimate.total.json # Miscellaneous tasks @@ -265,11 +242,6 @@ workflows: jobs: - documentation-checks - cc-setup - - ruby-2.3-spec: - requires: - - cc-setup - - ruby-2.3-ascii_spec - - ruby-2.3-rubocop - ruby-2.4-spec: requires: - cc-setup @@ -303,7 +275,6 @@ workflows: - cc-upload-coverage: requires: - - ruby-2.3-spec - ruby-2.4-spec - ruby-2.5-spec - ruby-2.6-spec diff --git a/.rubocop.yml b/.rubocop.yml index 564fe88d901..02c5557651d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -12,7 +12,7 @@ AllCops: - 'spec/fixtures/**/*' - 'tmp/**/*' - '.git/**/*' - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.4 Naming/PredicateName: # Method define macros for dynamically generated method. diff --git a/CHANGELOG.md b/CHANGELOG.md index 74f08fb1ac5..562eb854c02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ * [#7834](https://github.com/rubocop-hq/rubocop/issues/7834): Fix `Lint/UriRegexp` to register offense with array arguments. ([@tejasbubane][]) * [#7841](https://github.com/rubocop-hq/rubocop/issues/7841): Fix an error for `Style/TrailingCommaInBlockArgs` when lambda literal (`->`) has multiple arguments. ([@koic][]) +### Changes + +* [#7840](https://github.com/rubocop-hq/rubocop/pull/7840): **(BREAKING)** Drop support for Ruby 2.3. ([@koic][]) + ## 0.81.0 (2020-04-01) ### New features diff --git a/README.md b/README.md index 33a99b5e21f..215913a3500 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ You can read a lot more about RuboCop in its [official docs](https://docs.ruboco RuboCop supports the following Ruby implementations: -* MRI 2.3+ +* MRI 2.4+ * JRuby 9.2+ ## Team diff --git a/config/default.yml b/config/default.yml index 44ca0d6599b..0d6ff3d0906 100644 --- a/config/default.yml +++ b/config/default.yml @@ -133,7 +133,7 @@ AllCops: # followed by the Gemfile.lock or gems.locked file. (Although the Ruby version # is specified in the Gemfile or gems.rb file, RuboCop reads the final value # from the lock file.) If the Ruby version is still unresolved, RuboCop will - # use the oldest officially supported Ruby version (currently Ruby 2.3). + # use the oldest officially supported Ruby version (currently Ruby 2.4). TargetRubyVersion: ~ #################### Bundler ############################### @@ -2831,7 +2831,7 @@ Style/FrozenStringLiteralComment: # `always` will always add the frozen string literal comment to a file # regardless of the Ruby version or if `freeze` or `<<` are called on a # string literal. If you run code against multiple versions of Ruby, it is - # possible that this will create errors in Ruby 2.3.0+. + # possible that this will create errors in Ruby 2.4.0+. - always # `always_true` will add the frozen string literal comment to a file, # similarly to the `always` style, but will also change any disabled diff --git a/lib/rubocop/config_loader.rb b/lib/rubocop/config_loader.rb index e9b23ffb249..f1230f67122 100644 --- a/lib/rubocop/config_loader.rb +++ b/lib/rubocop/config_loader.rb @@ -79,10 +79,8 @@ def merge(base_hash, derived_hash) # user's home directory is checked. If there's no .rubocop.yml # there either, the path to the default file is returned. def configuration_file_for(target_dir) - find_project_dotfile(target_dir) || - find_user_dotfile || - find_user_xdg_config || - DEFAULT_FILE + find_project_dotfile(target_dir) || find_user_dotfile || + find_user_xdg_config || DEFAULT_FILE end def configuration_from_file(config_file) @@ -208,7 +206,9 @@ def existing_configuration(config_file) def write_config_file(file_name, file_string, rubocop_yml_contents) File.open(file_name, 'w') do |f| f.write "inherit_from:#{file_string}\n" - f.write "\n#{rubocop_yml_contents}" if rubocop_yml_contents =~ /\S/ + if /\S/.match?(rubocop_yml_contents) + f.write "\n#{rubocop_yml_contents}" + end end end diff --git a/lib/rubocop/cop/correctors/alignment_corrector.rb b/lib/rubocop/cop/correctors/alignment_corrector.rb index db19b452dcc..b297d5adec2 100644 --- a/lib/rubocop/cop/correctors/alignment_corrector.rb +++ b/lib/rubocop/cop/correctors/alignment_corrector.rb @@ -51,7 +51,7 @@ def autocorrect_line(corrector, line_begin_pos, expr, column_delta, unless range.resize(1).source == "\n" corrector.insert_before(range, ' ' * column_delta) end - elsif range.source =~ /\A[ \t]+\z/ + elsif /\A[ \t]+\z/.match?(range.source) remove(range, corrector) end end @@ -112,7 +112,7 @@ def remove(range, corrector) corrector.remove(range) rescue RuntimeError range = range_between(range.begin_pos + 1, range.end_pos + 1) - retry if range.source =~ /^ +$/ + retry if /^ +$/.match?(range.source) ensure $stderr = original_stderr end diff --git a/lib/rubocop/cop/layout/end_of_line.rb b/lib/rubocop/cop/layout/end_of_line.rb index 17227c4c645..b00dd920a45 100644 --- a/lib/rubocop/cop/layout/end_of_line.rb +++ b/lib/rubocop/cop/layout/end_of_line.rb @@ -75,8 +75,8 @@ def offense_message(line) style end case effective_style - when :lf then MSG_DETECTED if line =~ /\r$/ - else MSG_MISSING if line !~ /\r$/ + when :lf then MSG_DETECTED if /\r$/.match?(line) + else MSG_MISSING unless /\r$/.match?(line) end end diff --git a/lib/rubocop/cop/layout/first_array_element_indentation.rb b/lib/rubocop/cop/layout/first_array_element_indentation.rb index bb42428d83c..00ca4d85394 100644 --- a/lib/rubocop/cop/layout/first_array_element_indentation.rb +++ b/lib/rubocop/cop/layout/first_array_element_indentation.rb @@ -125,21 +125,15 @@ def check(array_node, left_parenthesis) def check_right_bracket(right_bracket, left_bracket, left_parenthesis) # if the right bracket is on the same line as the last value, accept - return if right_bracket.source_line[0...right_bracket.column] =~ /\S/ + if /\S/.match?(right_bracket.source_line[0...right_bracket.column]) + return + end expected_column = base_column(left_bracket, left_parenthesis) @column_delta = expected_column - right_bracket.column return if @column_delta.zero? - msg = if style == :align_brackets - 'Indent the right bracket the same as the left bracket.' - elsif style == :special_inside_parentheses && left_parenthesis - 'Indent the right bracket the same as the first position ' \ - 'after the preceding left parenthesis.' - else - 'Indent the right bracket the same as the start of the line' \ - ' where the left bracket is.' - end + msg = msg(left_parenthesis) add_offense(right_bracket, location: right_bracket, message: msg) end @@ -161,6 +155,18 @@ def message(base_description) base_description: base_description ) end + + def msg(left_parenthesis) + if style == :align_brackets + 'Indent the right bracket the same as the left bracket.' + elsif style == :special_inside_parentheses && left_parenthesis + 'Indent the right bracket the same as the first position ' \ + 'after the preceding left parenthesis.' + else + 'Indent the right bracket the same as the start of the line' \ + ' where the left bracket is.' + end + end end end end diff --git a/lib/rubocop/cop/layout/first_hash_element_indentation.rb b/lib/rubocop/cop/layout/first_hash_element_indentation.rb index bcd70a47cba..bc91a85e1f3 100644 --- a/lib/rubocop/cop/layout/first_hash_element_indentation.rb +++ b/lib/rubocop/cop/layout/first_hash_element_indentation.rb @@ -128,7 +128,7 @@ def check(hash_node, left_parenthesis) def check_right_brace(right_brace, left_brace, left_parenthesis) # if the right brace is on the same line as the last value, accept - return if right_brace.source_line[0...right_brace.column] =~ /\S/ + return if /\S/.match?(right_brace.source_line[0...right_brace.column]) expected_column = base_column(left_brace, left_parenthesis) @column_delta = expected_column - right_brace.column diff --git a/lib/rubocop/cop/layout/leading_comment_space.rb b/lib/rubocop/cop/layout/leading_comment_space.rb index 14d2a15b930..efdf2f2773a 100644 --- a/lib/rubocop/cop/layout/leading_comment_space.rb +++ b/lib/rubocop/cop/layout/leading_comment_space.rb @@ -56,7 +56,7 @@ class LeadingCommentSpace < Cop def investigate(processed_source) processed_source.each_comment do |comment| - next unless comment.text =~ /\A#+[^#\s=:+-]/ + next unless /\A#+[^#\s=:+-]/.match?(comment.text) next if comment.loc.line == 1 && allowed_on_first_line?(comment) next if doxygen_comment_style?(comment) next if gemfile_ruby_comment?(comment) diff --git a/lib/rubocop/cop/layout/line_length.rb b/lib/rubocop/cop/layout/line_length.rb index 503ca44255b..dfc807ad414 100644 --- a/lib/rubocop/cop/layout/line_length.rb +++ b/lib/rubocop/cop/layout/line_length.rb @@ -145,7 +145,7 @@ def breakable_range_after_semicolon(semicolon_token) return nil unless next_range.line == range.line next_char = next_range.source - return nil if /[\r\n]/ =~ next_char + return nil if /[\r\n]/.match?(next_char) return nil if next_char == ';' next_range diff --git a/lib/rubocop/cop/layout/space_around_block_parameters.rb b/lib/rubocop/cop/layout/space_around_block_parameters.rb index d17276c7df8..b35185c4164 100644 --- a/lib/rubocop/cop/layout/space_around_block_parameters.rb +++ b/lib/rubocop/cop/layout/space_around_block_parameters.rb @@ -47,7 +47,7 @@ def autocorrect(target) else corrector.insert_after(target, ' ') end - elsif target.source =~ /^\s+$/ + elsif /^\s+$/.match?(target.source) corrector.remove(target) else corrector.insert_after(target, ' ') diff --git a/lib/rubocop/cop/layout/space_around_operators.rb b/lib/rubocop/cop/layout/space_around_operators.rb index 51d9415151b..30d870d8e27 100644 --- a/lib/rubocop/cop/layout/space_around_operators.rb +++ b/lib/rubocop/cop/layout/space_around_operators.rb @@ -175,7 +175,7 @@ def offense_message(type, operator, with_space, right_operand) return if with_space.is?(operator.source) "Space around operator `#{operator.source}` detected." - elsif with_space.source !~ /^\s.*\s$/ + elsif !/^\s.*\s$/.match?(with_space.source) "Surrounding space missing for operator `#{operator.source}`." elsif excess_leading_space?(type, operator, with_space) || excess_trailing_space?(right_operand, with_space) diff --git a/lib/rubocop/cop/layout/space_inside_block_braces.rb b/lib/rubocop/cop/layout/space_inside_block_braces.rb index 7d0e3ca17c6..94ba60be3bc 100644 --- a/lib/rubocop/cop/layout/space_inside_block_braces.rb +++ b/lib/rubocop/cop/layout/space_inside_block_braces.rb @@ -117,7 +117,7 @@ def check_inside(node, left_brace, right_brace) range = range_between(left_brace.end_pos, right_brace.begin_pos) inner = range.source - if inner =~ /\S/ + if /\S/.match?(inner) braces_with_contents_inside(node, inner) elsif style_for_empty_braces == :no_space offense(range.begin_pos, range.end_pos, @@ -142,7 +142,7 @@ def braces_with_contents_inside(node, inner) end def check_left_brace(inner, left_brace, args_delimiter) - if inner =~ /\A\S/ + if /\A\S/.match?(inner) no_space_inside_left_brace(left_brace, args_delimiter) else space_inside_left_brace(left_brace, args_delimiter) diff --git a/lib/rubocop/cop/layout/space_inside_range_literal.rb b/lib/rubocop/cop/layout/space_inside_range_literal.rb index 22e97b46d78..c061481b6cd 100644 --- a/lib/rubocop/cop/layout/space_inside_range_literal.rb +++ b/lib/rubocop/cop/layout/space_inside_range_literal.rb @@ -53,7 +53,7 @@ def check(node) # account for multiline range literals expression.sub!(/#{escaped_op}\n\s*/, op) - return unless expression =~ /(\s#{escaped_op})|(#{escaped_op}\s)/ + return unless /(\s#{escaped_op})|(#{escaped_op}\s)/.match?(expression) add_offense(node) end diff --git a/lib/rubocop/cop/lint/debugger.rb b/lib/rubocop/cop/lint/debugger.rb index f3e95d1193e..d1df5ba45fe 100644 --- a/lib/rubocop/cop/lint/debugger.rb +++ b/lib/rubocop/cop/lint/debugger.rb @@ -69,7 +69,7 @@ def message(node) end def binding_irb?(node) - target_ruby_version >= 2.4 && binding_irb_call?(node) + binding_irb_call?(node) end end end diff --git a/lib/rubocop/cop/lint/implicit_string_concatenation.rb b/lib/rubocop/cop/lint/implicit_string_concatenation.rb index 610ae21221c..df0fd2647c7 100644 --- a/lib/rubocop/cop/lint/implicit_string_concatenation.rb +++ b/lib/rubocop/cop/lint/implicit_string_concatenation.rb @@ -81,7 +81,7 @@ def string_literals?(node1, node2) end def display_str(node) - if node.source =~ /\n/ + if /\n/.match?(node.source) str_content(node).inspect else node.source diff --git a/lib/rubocop/cop/lint/interpolation_check.rb b/lib/rubocop/cop/lint/interpolation_check.rb index e7ce39b529e..2ca41f8ae8a 100644 --- a/lib/rubocop/cop/lint/interpolation_check.rb +++ b/lib/rubocop/cop/lint/interpolation_check.rb @@ -25,7 +25,7 @@ def on_str(node) parent = node.parent return if parent && (parent.dstr_type? || parent.regexp_type?) - return unless node.source.scrub =~ /(? false } over { production?: false } and # similarly for other non-alnum final characters (except quotes, # to prefer { "x y": 1 } over { :"x y" => 1 }). - return false unless sym_name =~ /[\p{Alnum}"']\z/ + return false unless /[\p{Alnum}"']\z/.match?(sym_name) end # Most hash keys can be matched against a simple regex. - return true if sym_name =~ /\A[_a-z]\w*[?!]?\z/i + return true if /\A[_a-z]\w*[?!]?\z/i.match?(sym_name) # For more complicated hash keys, let the parser validate the syntax. parse("{ #{sym_name}: :foo }").valid_syntax? diff --git a/lib/rubocop/cop/style/hash_transform_values.rb b/lib/rubocop/cop/style/hash_transform_values.rb index d77986cd63c..f5cd1c1c4c8 100644 --- a/lib/rubocop/cop/style/hash_transform_values.rb +++ b/lib/rubocop/cop/style/hash_transform_values.rb @@ -24,11 +24,8 @@ module Style # {a: 1, b: 2}.transform_values { |v| foo(v) } # {a: 1, b: 2}.transform_values { |v| v * v } class HashTransformValues < Cop - extend TargetRubyVersion include HashTransformMethod - minimum_target_ruby_version 2.4 - def_node_matcher :on_bad_each_with_object, <<~PATTERN (block ({send csend} diff --git a/lib/rubocop/cop/style/mixin_grouping.rb b/lib/rubocop/cop/style/mixin_grouping.rb index d4877e938dd..1386d8e1634 100644 --- a/lib/rubocop/cop/style/mixin_grouping.rb +++ b/lib/rubocop/cop/style/mixin_grouping.rb @@ -72,7 +72,7 @@ def range_to_remove_for_subsequent_mixin(mixins, node) between = prev_mixin.loc.expression.end .join(range.begin) # if separated from previous mixin with only whitespace? - if between.source !~ /\S/ + unless /\S/.match?(between.source) range = range.join(between) # then remove that too end range diff --git a/lib/rubocop/cop/style/multiline_memoization.rb b/lib/rubocop/cop/style/multiline_memoization.rb index 6816cb0f6ff..b8e85ae2db3 100644 --- a/lib/rubocop/cop/style/multiline_memoization.rb +++ b/lib/rubocop/cop/style/multiline_memoization.rb @@ -82,7 +82,7 @@ def keyword_begin_str(node, node_buf) end def keyword_end_str(node, node_buf) - if node_buf.source_line(node.loc.end.line) =~ /[^\s\)]/ + if /[^\s\)]/.match?(node_buf.source_line(node.loc.end.line)) "\n" + (' ' * node.loc.column) + 'end' else 'end' diff --git a/lib/rubocop/cop/style/redundant_percent_q.rb b/lib/rubocop/cop/style/redundant_percent_q.rb index fb9f60bb2f9..2bbaf292462 100644 --- a/lib/rubocop/cop/style/redundant_percent_q.rb +++ b/lib/rubocop/cop/style/redundant_percent_q.rb @@ -47,7 +47,7 @@ def on_str(node) def autocorrect(node) delimiter = - node.source =~ /^%Q[^"]+$|'/ ? QUOTE : SINGLE_QUOTE + /^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE lambda do |corrector| corrector.replace(node.loc.begin, delimiter) corrector.replace(node.loc.end, delimiter) @@ -95,7 +95,7 @@ def start_with_percent_q_variant?(string) def acceptable_q?(node) src = node.source - return true if src =~ STRING_INTERPOLATION_REGEXP + return true if STRING_INTERPOLATION_REGEXP.match?(src) src.scan(/\\./).any? { |s| s =~ ESCAPED_NON_BACKSLASH } end diff --git a/lib/rubocop/cop/style/symbol_literal.rb b/lib/rubocop/cop/style/symbol_literal.rb index 40e0afe327a..606f9922ec4 100644 --- a/lib/rubocop/cop/style/symbol_literal.rb +++ b/lib/rubocop/cop/style/symbol_literal.rb @@ -16,7 +16,7 @@ class SymbolLiteral < Cop MSG = 'Do not use strings for word-like symbol literals.' def on_sym(node) - return unless node.source =~ /\A:["'][A-Za-z_]\w*["']\z/ + return unless /\A:["'][A-Za-z_]\w*["']\z/.match?(node.source) add_offense(node) end diff --git a/lib/rubocop/cop/style/unpack_first.rb b/lib/rubocop/cop/style/unpack_first.rb index 7ec8f98ec31..5b15fba7edd 100644 --- a/lib/rubocop/cop/style/unpack_first.rb +++ b/lib/rubocop/cop/style/unpack_first.rb @@ -18,10 +18,6 @@ module Style # 'foo'.unpack1('h*') # class UnpackFirst < Cop - extend TargetRubyVersion - - minimum_target_ruby_version 2.4 - MSG = 'Use `%s.unpack1(%s)` instead of '\ '`%s.unpack(%s)%s`.' diff --git a/lib/rubocop/formatter/pacman_formatter.rb b/lib/rubocop/formatter/pacman_formatter.rb index a6b6fb0939c..4c8afb22ce8 100644 --- a/lib/rubocop/formatter/pacman_formatter.rb +++ b/lib/rubocop/formatter/pacman_formatter.rb @@ -69,7 +69,7 @@ def step(character) regex = /#{Regexp.quote(PACMAN)}|#{Regexp.quote(PACDOT)}/ @progress_line = @progress_line.sub(regex, character) output.printf("%s\r", line: @progress_line) - return unless @progress_line[-1] =~ /ᗣ|\./ + return unless /ᗣ|\./.match?(@progress_line[-1]) @repetitions += 1 output.puts diff --git a/lib/rubocop/options.rb b/lib/rubocop/options.rb index 2db38382d18..d1527080c99 100644 --- a/lib/rubocop/options.rb +++ b/lib/rubocop/options.rb @@ -366,7 +366,7 @@ def incompatible_options end def validate_exclude_limit_option - return if @options[:exclude_limit] =~ /^\d+$/ + return if /^\d+$/.match?(@options[:exclude_limit]) # Emulate OptionParser's behavior to make failures consistent regardless # of option order. diff --git a/lib/rubocop/processed_source.rb b/lib/rubocop/processed_source.rb index 9822018f433..0b78368b955 100644 --- a/lib/rubocop/processed_source.rb +++ b/lib/rubocop/processed_source.rb @@ -175,9 +175,6 @@ def tokenize(parser) # rubocop:disable Metrics/MethodLength def parser_class(ruby_version) case ruby_version - when 2.3 - require 'parser/ruby23' - Parser::Ruby23 when 2.4 require 'parser/ruby24' Parser::Ruby24 diff --git a/lib/rubocop/rspec/cop_helper.rb b/lib/rubocop/rspec/cop_helper.rb index 17008ca06b5..be1f93b0949 100644 --- a/lib/rubocop/rspec/cop_helper.rb +++ b/lib/rubocop/rspec/cop_helper.rb @@ -6,7 +6,7 @@ module CopHelper extend RSpec::SharedContext - let(:ruby_version) { 2.3 } + let(:ruby_version) { 2.4 } let(:rails_version) { false } def inspect_source_file(source) diff --git a/lib/rubocop/rspec/expect_offense.rb b/lib/rubocop/rspec/expect_offense.rb index 1eb9be50cbd..fc952a5c4ea 100644 --- a/lib/rubocop/rspec/expect_offense.rb +++ b/lib/rubocop/rspec/expect_offense.rb @@ -153,7 +153,7 @@ def self.parse(annotated_source) annotations = [] annotated_source.each_line do |source_line| - if source_line =~ ANNOTATION_PATTERN + if ANNOTATION_PATTERN.match?(source_line) annotations << [source.size, source_line] else source << source_line diff --git a/lib/rubocop/rspec/shared_contexts.rb b/lib/rubocop/rspec/shared_contexts.rb index bacc55ec097..7a73589dce7 100644 --- a/lib/rubocop/rspec/shared_contexts.rb +++ b/lib/rubocop/rspec/shared_contexts.rb @@ -74,10 +74,6 @@ end end -RSpec.shared_context 'ruby 2.3', :ruby23 do - let(:ruby_version) { 2.3 } -end - RSpec.shared_context 'ruby 2.4', :ruby24 do let(:ruby_version) { 2.4 } end diff --git a/lib/rubocop/target_ruby.rb b/lib/rubocop/target_ruby.rb index ef0811172dc..0a602a89dec 100644 --- a/lib/rubocop/target_ruby.rb +++ b/lib/rubocop/target_ruby.rb @@ -3,11 +3,11 @@ module RuboCop # The kind of Ruby that code inspected by RuboCop is written in. class TargetRuby - KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze + KNOWN_RUBIES = [2.4, 2.5, 2.6, 2.7].freeze DEFAULT_VERSION = KNOWN_RUBIES.first OBSOLETE_RUBIES = { - 1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69' + 1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69', 2.3 => '0.81' }.freeze private_constant :KNOWN_RUBIES, :OBSOLETE_RUBIES diff --git a/rubocop.gemspec b/rubocop.gemspec index 288a2517c10..5cfb6e3b9e4 100644 --- a/rubocop.gemspec +++ b/rubocop.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.name = 'rubocop' s.version = RuboCop::Version::STRING s.platform = Gem::Platform::RUBY - s.required_ruby_version = '>= 2.3.0' + s.required_ruby_version = '>= 2.4.0' s.authors = ['Bozhidar Batsov', 'Jonas Arvidsson', 'Yuji Nakayama'] s.description = <<-DESCRIPTION Automatic Ruby code style checking tool. diff --git a/spec/rubocop/cli/cli_autocorrect_spec.rb b/spec/rubocop/cli/cli_autocorrect_spec.rb index 059402a37a1..3bafc9a9a0f 100644 --- a/spec/rubocop/cli/cli_autocorrect_spec.rb +++ b/spec/rubocop/cli/cli_autocorrect_spec.rb @@ -431,7 +431,7 @@ def verify_section it 'corrects Style/Next and Style/SafeNavigation offenses' do create_file('.rubocop.yml', <<~YAML) AllCops: - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.4 YAML source = <<~'RUBY' until x @@ -1346,7 +1346,7 @@ def self.some_method(foo, bar: 1) RUBY create_file('.rubocop.yml', <<~YAML) AllCops: - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.4 YAML create_file('example.rb', src) exit_status = cli.run( diff --git a/spec/rubocop/cli_spec.rb b/spec/rubocop/cli_spec.rb index 1719f7ea83f..3b816b49bab 100644 --- a/spec/rubocop/cli_spec.rb +++ b/spec/rubocop/cli_spec.rb @@ -154,7 +154,7 @@ def and_with_args expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1) expect($stdout.string) .to eq(["#{abs('example.rb')}:3:1: E: Lint/Syntax: unexpected " \ - 'token $end (Using Ruby 2.3 parser; configure using ' \ + 'token $end (Using Ruby 2.4 parser; configure using ' \ '`TargetRubyVersion` parameter, under `AllCops`)', ''].join("\n")) end @@ -1633,7 +1633,7 @@ def method(foo, bar, qux, fred, arg5, f) end #{'#' * 45} 'Error: RuboCop found unknown Ruby version 2.8 in `TargetRubyVersion`' ) expect($stderr.string.strip).to match( - /Supported versions: 2.3, 2.4, 2.5, 2.6, 2.7/ + /Supported versions: 2.4, 2.5, 2.6, 2.7/ ) end end @@ -1656,7 +1656,7 @@ def method(foo, bar, qux, fred, arg5, f) end #{'#' * 45} ) expect($stderr.string.strip).to match( - /Supported versions: 2.3, 2.4/ + /Supported versions: 2.4/ ) end end diff --git a/spec/rubocop/config_store_spec.rb b/spec/rubocop/config_store_spec.rb index 778b44e17f8..c5d22010e08 100644 --- a/spec/rubocop/config_store_spec.rb +++ b/spec/rubocop/config_store_spec.rb @@ -10,7 +10,7 @@ # dir/.rubocop.yml # dir/file2 # dir/subdir/file3 - (arg =~ /dir/ ? 'dir' : '.') + '/.rubocop.yml' + (/dir/.match?(arg) ? 'dir' : '.') + '/.rubocop.yml' end allow(RuboCop::ConfigLoader) .to receive(:configuration_from_file) { |arg| arg } diff --git a/spec/rubocop/cop/gemspec/required_ruby_version_spec.rb b/spec/rubocop/cop/gemspec/required_ruby_version_spec.rb index 762f4bb15f3..24ee2a44cca 100644 --- a/spec/rubocop/cop/gemspec/required_ruby_version_spec.rb +++ b/spec/rubocop/cop/gemspec/required_ruby_version_spec.rb @@ -3,13 +3,13 @@ RSpec.describe RuboCop::Cop::Gemspec::RequiredRubyVersion, :config do subject(:cop) { described_class.new(config) } - context 'target ruby version > 2.6', :ruby26 do + context 'target ruby version > 2.7', :ruby27 do it 'registers an offense when `required_ruby_version` is lower than ' \ '`TargetRubyVersion`' do expect_offense(<<~RUBY, '/path/to/foo.gemspec') Gem::Specification.new do |spec| - spec.required_ruby_version = '>= 2.5.0' - ^^^^^^^^^^ `required_ruby_version` (2.5, declared in foo.gemspec) and `TargetRubyVersion` (2.6, which may be specified in .rubocop.yml) should be equal. + spec.required_ruby_version = '>= 2.6.0' + ^^^^^^^^^^ `required_ruby_version` (2.6, declared in foo.gemspec) and `TargetRubyVersion` (2.7, which may be specified in .rubocop.yml) should be equal. end RUBY end @@ -19,7 +19,7 @@ 'is assigned as a variable (string literal)' do expect_no_offenses(<<~RUBY) Gem::Specification.new do |spec| - version = '>= 2.5.0' + version = '>= 2.6.0' spec.required_ruby_version = version end RUBY @@ -29,8 +29,8 @@ 'is assigned as a variable (an array of string literal)' do expect_no_offenses(<<~RUBY) Gem::Specification.new do |spec| - lowest_version = '>= 2.5.0' - highest_version = '< 2.7.0' + lowest_version = '>= 2.6.0' + highest_version = '< 2.8.0' spec.required_ruby_version = [lowest_version, highest_version] end RUBY @@ -38,24 +38,24 @@ end end - context 'target ruby version > 2.4', :ruby24 do + context 'target ruby version > 2.5', :ruby25 do it 'registers an offense when `required_ruby_version` is higher than ' \ '`TargetRubyVersion`' do expect_offense(<<~RUBY, '/path/to/bar.gemspec') Gem::Specification.new do |spec| - spec.required_ruby_version = '>= 2.5.0' - ^^^^^^^^^^ `required_ruby_version` (2.5, declared in bar.gemspec) and `TargetRubyVersion` (2.4, which may be specified in .rubocop.yml) should be equal. + spec.required_ruby_version = '>= 2.6.0' + ^^^^^^^^^^ `required_ruby_version` (2.6, declared in bar.gemspec) and `TargetRubyVersion` (2.5, which may be specified in .rubocop.yml) should be equal. end RUBY end end - context 'target ruby version > 2.5', :ruby25 do + context 'target ruby version > 2.6', :ruby26 do it 'does not register an offense when `required_ruby_version` equals ' \ '`TargetRubyVersion`' do expect_no_offenses(<<~RUBY) Gem::Specification.new do |spec| - spec.required_ruby_version = '>= 2.5.0' + spec.required_ruby_version = '>= 2.6.0' end RUBY end @@ -64,7 +64,7 @@ '(omit patch version) equals `TargetRubyVersion`' do expect_no_offenses(<<~RUBY) Gem::Specification.new do |spec| - spec.required_ruby_version = '>= 2.5' + spec.required_ruby_version = '>= 2.6' end RUBY end @@ -73,7 +73,7 @@ '`required_ruby_version` equals `TargetRubyVersion`' do expect_no_offenses(<<~RUBY) Gem::Specification.new do |spec| - spec.required_ruby_version = ['>= 2.5.0', '< 2.7.0'] + spec.required_ruby_version = ['>= 2.6.0', '< 2.8.0'] end RUBY end diff --git a/spec/rubocop/cop/lint/debugger_spec.rb b/spec/rubocop/cop/lint/debugger_spec.rb index 79cea6a4c45..4aa470f6cda 100644 --- a/spec/rubocop/cop/lint/debugger_spec.rb +++ b/spec/rubocop/cop/lint/debugger_spec.rb @@ -91,8 +91,6 @@ def method RUBY end - context 'target_ruby_version >= 2.4', :ruby24 do - include_examples 'debugger', 'irb binding', 'binding.irb' - include_examples 'debugger', 'binding.irb with Kernel', 'Kernel.binding.irb' - end + include_examples 'debugger', 'irb binding', 'binding.irb' + include_examples 'debugger', 'binding.irb with Kernel', 'Kernel.binding.irb' end diff --git a/spec/rubocop/cop/lint/unified_integer_spec.rb b/spec/rubocop/cop/lint/unified_integer_spec.rb index df1233e27c8..930dcddb524 100644 --- a/spec/rubocop/cop/lint/unified_integer_spec.rb +++ b/spec/rubocop/cop/lint/unified_integer_spec.rb @@ -4,82 +4,40 @@ subject(:cop) { described_class.new(config) } shared_examples 'registers an offense' do |klass| - context 'target ruby version < 2.4', :ruby23 do - context "when #{klass}" do - context 'without any decorations' do - let(:source) { "1.is_a?(#{klass})" } - - it 'registers an offense' do - inspect_source(source) - expect(cop.offenses.size).to eq(1) - expect(cop.messages).to eq(["Use `Integer` instead of `#{klass}`."]) - end - - it 'does not autocorrect' do - new_source = autocorrect_source(source) - expect(new_source).to eq(source) - end - end - - context 'when explicitly specified as toplevel constant' do - let(:source) { "1.is_a?(::#{klass})" } - - it 'registers an offense' do - inspect_source(source) - expect(cop.offenses.size).to eq(1) - expect(cop.messages).to eq(["Use `Integer` instead of `#{klass}`."]) - end - - it 'autocorrects' do - new_source = autocorrect_source(source) - expect(new_source).to eq(source) - end + context "when #{klass}" do + context 'without any decorations' do + let(:source) { "1.is_a?(#{klass})" } + + it 'registers an offense' do + inspect_source(source) + expect(cop.offenses.size).to eq(1) + expect(cop.messages).to eq(["Use `Integer` instead of `#{klass}`."]) end - context 'with MyNamespace' do - it 'does not register an offense' do - expect_no_offenses("1.is_a?(MyNamespace::#{klass})") - end + it 'autocorrects' do + new_source = autocorrect_source(source) + expect(new_source).to eq('1.is_a?(Integer)') end end - end - - context 'target ruby version >= 2.4', :ruby24 do - context "when #{klass}" do - context 'without any decorations' do - let(:source) { "1.is_a?(#{klass})" } - it 'registers an offense' do - inspect_source(source) - expect(cop.offenses.size).to eq(1) - expect(cop.messages).to eq(["Use `Integer` instead of `#{klass}`."]) - end + context 'when explicitly specified as toplevel constant' do + let(:source) { "1.is_a?(::#{klass})" } - it 'autocorrects' do - new_source = autocorrect_source(source) - expect(new_source).to eq('1.is_a?(Integer)') - end + it 'registers an offense' do + inspect_source(source) + expect(cop.offenses.size).to eq(1) + expect(cop.messages).to eq(["Use `Integer` instead of `#{klass}`."]) end - context 'when explicitly specified as toplevel constant' do - let(:source) { "1.is_a?(::#{klass})" } - - it 'registers an offense' do - inspect_source(source) - expect(cop.offenses.size).to eq(1) - expect(cop.messages).to eq(["Use `Integer` instead of `#{klass}`."]) - end - - it 'autocorrects' do - new_source = autocorrect_source(source) - expect(new_source).to eq('1.is_a?(::Integer)') - end + it 'autocorrects' do + new_source = autocorrect_source(source) + expect(new_source).to eq('1.is_a?(::Integer)') end + end - context 'with MyNamespace' do - it 'does not register an offense' do - expect_no_offenses("1.is_a?(MyNamespace::#{klass})") - end + context 'with MyNamespace' do + it 'does not register an offense' do + expect_no_offenses("1.is_a?(MyNamespace::#{klass})") end end end diff --git a/spec/rubocop/cop/style/hash_transform_values_spec.rb b/spec/rubocop/cop/style/hash_transform_values_spec.rb index 6f57392cf05..6a8417ce12e 100644 --- a/spec/rubocop/cop/style/hash_transform_values_spec.rb +++ b/spec/rubocop/cop/style/hash_transform_values_spec.rb @@ -3,138 +3,130 @@ RSpec.describe RuboCop::Cop::Style::HashTransformValues, :config do subject(:cop) { described_class.new(config) } - context 'when using Ruby 2.4 or newer', :ruby24 do - context 'with inline block' do - it 'flags each_with_object when transform_values could be used' do - expect_offense(<<~RUBY) - x.each_with_object({}) {|(k, v), h| h[k] = foo(v)} - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `each_with_object`. - RUBY - end - end - - context 'with multiline block' do - it 'flags each_with_object when transform_values could be used' do - expect_offense(<<~RUBY) - some_hash.each_with_object({}) do |(key, val), memo| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `each_with_object`. - memo[key] = val * val - end - RUBY - end - end - - context 'with safe navigation operator' do - it 'flags each_with_object when transform_values could be used' do - expect_offense(<<~RUBY) - x&.each_with_object({}) {|(k, v), h| h[k] = foo(v)} - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `each_with_object`. - RUBY - end + context 'with inline block' do + it 'flags each_with_object when transform_values could be used' do + expect_offense(<<~RUBY) + x.each_with_object({}) {|(k, v), h| h[k] = foo(v)} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `each_with_object`. + RUBY end + end - it 'does not flag each_with_object when both key & value are transformed' do - expect_no_offenses(<<~RUBY) - x.each_with_object({}) {|(k, v), h| h[k.to_sym] = foo(v)} + context 'with multiline block' do + it 'flags each_with_object when transform_values could be used' do + expect_offense(<<~RUBY) + some_hash.each_with_object({}) do |(key, val), memo| + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `each_with_object`. + memo[key] = val * val + end RUBY end + end - it 'does not flag each_with_object when value transformation uses key' do - expect_no_offenses('x.each_with_object({}) {|(k, v), h| h[k] = k.to_s}') + context 'with safe navigation operator' do + it 'flags each_with_object when transform_values could be used' do + expect_offense(<<~RUBY) + x&.each_with_object({}) {|(k, v), h| h[k] = foo(v)} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `each_with_object`. + RUBY end + end - it 'does not flag each_with_object when no transformation occurs' do - expect_no_offenses('x.each_with_object({}) {|(k, v), h| h[k] = v}') - end + it 'does not flag each_with_object when both key & value are transformed' do + expect_no_offenses(<<~RUBY) + x.each_with_object({}) {|(k, v), h| h[k.to_sym] = foo(v)} + RUBY + end - it 'does not flag each_with_object when its argument is not modified' do - expect_no_offenses(<<~RUBY) - x.each_with_object({}) {|(k, v), h| other_h[k] = v * v} - RUBY - end + it 'does not flag each_with_object when value transformation uses key' do + expect_no_offenses('x.each_with_object({}) {|(k, v), h| h[k] = k.to_s}') + end - it 'does not flag each_with_object when receiver is array literal' do - expect_no_offenses(<<~RUBY) - [1, 2, 3].each_with_object({}) {|(k, v), h| h[k] = foo(v)} - RUBY - end + it 'does not flag each_with_object when no transformation occurs' do + expect_no_offenses('x.each_with_object({}) {|(k, v), h| h[k] = v}') + end - it 'flags _.map {...}.to_h when transform_values could be used' do - expect_offense(<<~RUBY) - x.map {|k, v| [k, foo(v)]}.to_h - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `map {...}.to_h`. - RUBY - end + it 'does not flag each_with_object when its argument is not modified' do + expect_no_offenses(<<~RUBY) + x.each_with_object({}) {|(k, v), h| other_h[k] = v * v} + RUBY + end - it 'does not flag _.map{...}.to_h when both key & value are transformed' do - expect_no_offenses('x.map {|k, v| [k.to_sym, foo(v)]}.to_h') - end + it 'does not flag each_with_object when receiver is array literal' do + expect_no_offenses(<<~RUBY) + [1, 2, 3].each_with_object({}) {|(k, v), h| h[k] = foo(v)} + RUBY + end - it 'flags Hash[_.map{...}] when transform_values could be used' do - expect_offense(<<~RUBY) - Hash[x.map {|k, v| [k, foo(v)]}] - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `Hash[_.map {...}]`. - RUBY - end + it 'flags _.map {...}.to_h when transform_values could be used' do + expect_offense(<<~RUBY) + x.map {|k, v| [k, foo(v)]}.to_h + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `map {...}.to_h`. + RUBY + end - it 'does not flag Hash[_.map{...}] when both key & value are transformed' do - expect_no_offenses('Hash[x.map {|k, v| [k.to_sym, foo(v)]}]') - end + it 'does not flag _.map{...}.to_h when both key & value are transformed' do + expect_no_offenses('x.map {|k, v| [k.to_sym, foo(v)]}.to_h') + end - it 'does not flag value transformation in the absence of to_h' do - expect_no_offenses('x.map {|k, v| [k, foo(v)]}') - end + it 'flags Hash[_.map{...}] when transform_values could be used' do + expect_offense(<<~RUBY) + Hash[x.map {|k, v| [k, foo(v)]}] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `transform_values` over `Hash[_.map {...}]`. + RUBY + end - it 'does not flag value transformation when receiver is array literal' do - expect_no_offenses(<<~RUBY) - [1, 2, 3].map {|k, v| [k, foo(v)]}.to_h - RUBY - end + it 'does not flag Hash[_.map{...}] when both key & value are transformed' do + expect_no_offenses('Hash[x.map {|k, v| [k.to_sym, foo(v)]}]') + end - it 'correctly autocorrects each_with_object' do - corrected = autocorrect_source(<<~RUBY) - {a: 1, b: 2}.each_with_object({}) {|(k, v), h| h[k] = foo(v)} - RUBY + it 'does not flag value transformation in the absence of to_h' do + expect_no_offenses('x.map {|k, v| [k, foo(v)]}') + end - expect(corrected).to eq(<<~RUBY) - {a: 1, b: 2}.transform_values {|v| foo(v)} - RUBY - end + it 'does not flag value transformation when receiver is array literal' do + expect_no_offenses(<<~RUBY) + [1, 2, 3].map {|k, v| [k, foo(v)]}.to_h + RUBY + end - it 'correctly autocorrects _.map{...}.to_h without block' do - corrected = autocorrect_source(<<~RUBY) - {a: 1, b: 2}.map {|k, v| [k, foo(v)]}.to_h - RUBY + it 'correctly autocorrects each_with_object' do + corrected = autocorrect_source(<<~RUBY) + {a: 1, b: 2}.each_with_object({}) {|(k, v), h| h[k] = foo(v)} + RUBY - expect(corrected).to eq(<<~RUBY) - {a: 1, b: 2}.transform_values {|v| foo(v)} - RUBY - end + expect(corrected).to eq(<<~RUBY) + {a: 1, b: 2}.transform_values {|v| foo(v)} + RUBY + end - it 'correctly autocorrects _.map{...}.to_h with block' do - corrected = autocorrect_source(<<~RUBY) - {a: 1, b: 2}.map {|k, v| [k, foo(v)]}.to_h {|k, v| [v, k]} - RUBY + it 'correctly autocorrects _.map{...}.to_h without block' do + corrected = autocorrect_source(<<~RUBY) + {a: 1, b: 2}.map {|k, v| [k, foo(v)]}.to_h + RUBY - expect(corrected).to eq(<<~RUBY) - {a: 1, b: 2}.transform_values {|v| foo(v)}.to_h {|k, v| [v, k]} - RUBY - end + expect(corrected).to eq(<<~RUBY) + {a: 1, b: 2}.transform_values {|v| foo(v)} + RUBY + end - it 'correctly autocorrects Hash[_.map{...}]' do - corrected = autocorrect_source(<<~RUBY) - Hash[{a: 1, b: 2}.map {|k, v| [k, foo(v)]}] - RUBY + it 'correctly autocorrects _.map{...}.to_h with block' do + corrected = autocorrect_source(<<~RUBY) + {a: 1, b: 2}.map {|k, v| [k, foo(v)]}.to_h {|k, v| [v, k]} + RUBY - expect(corrected).to eq(<<~RUBY) - {a: 1, b: 2}.transform_values {|v| foo(v)} - RUBY - end + expect(corrected).to eq(<<~RUBY) + {a: 1, b: 2}.transform_values {|v| foo(v)}.to_h {|k, v| [v, k]} + RUBY end - context 'below Ruby 2.4', :ruby23 do - it 'does not flag even if transform_values could be used' do - expect_no_offenses('x.each_with_object({}) {|(k, v), h| h[k] = foo(v)}') - end + it 'correctly autocorrects Hash[_.map{...}]' do + corrected = autocorrect_source(<<~RUBY) + Hash[{a: 1, b: 2}.map {|k, v| [k, foo(v)]}] + RUBY + + expect(corrected).to eq(<<~RUBY) + {a: 1, b: 2}.transform_values {|v| foo(v)} + RUBY end end diff --git a/spec/rubocop/cop/style/unpack_first_spec.rb b/spec/rubocop/cop/style/unpack_first_spec.rb index c424b4a7e1e..61fefa05bc7 100644 --- a/spec/rubocop/cop/style/unpack_first_spec.rb +++ b/spec/rubocop/cop/style/unpack_first_spec.rb @@ -3,83 +3,81 @@ RSpec.describe RuboCop::Cop::Style::UnpackFirst, :config do subject(:cop) { described_class.new(config) } - context 'ruby version >= 2.4', :ruby24 do - context 'registers offense' do - it 'when using `#unpack` with `#first`' do - expect_offense(<<~RUBY) - x.unpack('h*').first - ^^^^^^^^^^^^^^^^^^^^ Use `x.unpack1('h*')` instead of `x.unpack('h*').first`. - RUBY - end + context 'registers offense' do + it 'when using `#unpack` with `#first`' do + expect_offense(<<~RUBY) + x.unpack('h*').first + ^^^^^^^^^^^^^^^^^^^^ Use `x.unpack1('h*')` instead of `x.unpack('h*').first`. + RUBY + end - it 'when using `#unpack` with square brackets' do - expect_offense(<<~RUBY) - ''.unpack(y)[0] - ^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y)[0]`. - RUBY - end + it 'when using `#unpack` with square brackets' do + expect_offense(<<~RUBY) + ''.unpack(y)[0] + ^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y)[0]`. + RUBY + end - it 'when using `#unpack` with dot and square brackets' do - expect_offense(<<~RUBY) - ''.unpack(y).[](0) - ^^^^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y).[](0)`. - RUBY - end + it 'when using `#unpack` with dot and square brackets' do + expect_offense(<<~RUBY) + ''.unpack(y).[](0) + ^^^^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y).[](0)`. + RUBY + end - it 'when using `#unpack` with `#slice`' do - expect_offense(<<~RUBY) - ''.unpack(y).slice(0) - ^^^^^^^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y).slice(0)`. - RUBY - end + it 'when using `#unpack` with `#slice`' do + expect_offense(<<~RUBY) + ''.unpack(y).slice(0) + ^^^^^^^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y).slice(0)`. + RUBY + end - it 'when using `#unpack` with `#at`' do - expect_offense(<<~RUBY) - ''.unpack(y).at(0) - ^^^^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y).at(0)`. - RUBY - end + it 'when using `#unpack` with `#at`' do + expect_offense(<<~RUBY) + ''.unpack(y).at(0) + ^^^^^^^^^^^^^^^^^^ Use `''.unpack1(y)` instead of `''.unpack(y).at(0)`. + RUBY end + end - context 'does not register offense' do - it 'when using `#unpack1`' do - expect_no_offenses(<<~RUBY) - x.unpack1(y) - RUBY - end + context 'does not register offense' do + it 'when using `#unpack1`' do + expect_no_offenses(<<~RUBY) + x.unpack1(y) + RUBY + end - it 'when using `#unpack` accessing second element' do - expect_no_offenses(<<~RUBY) - ''.unpack('h*')[1] - RUBY - end + it 'when using `#unpack` accessing second element' do + expect_no_offenses(<<~RUBY) + ''.unpack('h*')[1] + RUBY end + end - context 'autocorrects' do - it '`#unpack` with `#first to `#unpack1`' do - expect(autocorrect_source("x.unpack('h*').first")) - .to eq("x.unpack1('h*')") - end + context 'autocorrects' do + it '`#unpack` with `#first to `#unpack1`' do + expect(autocorrect_source("x.unpack('h*').first")) + .to eq("x.unpack1('h*')") + end - it 'autocorrects `#unpack` with square brackets' do - expect(autocorrect_source("x.unpack('h*')[0]")) - .to eq("x.unpack1('h*')") - end + it 'autocorrects `#unpack` with square brackets' do + expect(autocorrect_source("x.unpack('h*')[0]")) + .to eq("x.unpack1('h*')") + end - it 'autocorrects `#unpack` with dot and square brackets' do - expect(autocorrect_source("x.unpack('h*').[](0)")) - .to eq("x.unpack1('h*')") - end + it 'autocorrects `#unpack` with dot and square brackets' do + expect(autocorrect_source("x.unpack('h*').[](0)")) + .to eq("x.unpack1('h*')") + end - it 'autocorrects `#unpack` with `#slice`' do - expect(autocorrect_source("x.unpack('h*').slice(0)")) - .to eq("x.unpack1('h*')") - end + it 'autocorrects `#unpack` with `#slice`' do + expect(autocorrect_source("x.unpack('h*').slice(0)")) + .to eq("x.unpack1('h*')") + end - it 'autocorrects `#unpack` with `#at`' do - expect(autocorrect_source("x.unpack('h*').at(0)")) - .to eq("x.unpack1('h*')") - end + it 'autocorrects `#unpack` with `#at`' do + expect(autocorrect_source("x.unpack('h*').at(0)")) + .to eq("x.unpack1('h*')") end end end diff --git a/spec/rubocop/node_pattern_spec.rb b/spec/rubocop/node_pattern_spec.rb index 88b7c1a8520..1e39c0471be 100644 --- a/spec/rubocop/node_pattern_spec.rb +++ b/spec/rubocop/node_pattern_spec.rb @@ -616,7 +616,7 @@ end context 'on a node which meets all requirements of the second []' do - let(:ruby) { '2.3' } + let(:ruby) { '2.4' } it_behaves_like 'matching' end diff --git a/spec/rubocop/target_ruby_spec.rb b/spec/rubocop/target_ruby_spec.rb index ebee6263e3d..ddd2d8fae2a 100644 --- a/spec/rubocop/target_ruby_spec.rb +++ b/spec/rubocop/target_ruby_spec.rb @@ -12,7 +12,7 @@ let(:loaded_path) { 'example/.rubocop.yml' } context 'when TargetRubyVersion is set' do - let(:ruby_version) { 2.3 } + let(:ruby_version) { 2.4 } let(:hash) do {