From c5843e4013ef4fa9dba2a706dbab204835236f8c Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 17:31:25 +0000 Subject: [PATCH 01/36] Extract gemfiles/Gemfile.rubocop Most of the complication in the default `Gemfile` was to do with rubocop dependencies/compatibility. Extracting this separate `gemfiles/Gemfile.rubocop` simplifies the default `Gemfile` at the cost of making it slightly more complicated to run the `lint` rake task. --- .circleci/config.yml | 4 ++-- Gemfile | 17 ----------------- Rakefile | 2 +- gemfiles/Gemfile.rubocop | 22 ++++++++++++++++++++++ 4 files changed, 25 insertions(+), 20 deletions(-) create mode 100644 gemfiles/Gemfile.rubocop diff --git a/.circleci/config.yml b/.circleci/config.yml index 9bba1906..15bc67a5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -59,8 +59,8 @@ jobs: - run: ruby --version - run: gem --version - run: bundle --version - - run: bundle install --gemfile=Gemfile - - run: bundle exec rake lint + - run: bundle install --gemfile=gemfiles/Gemfile.rubocop + - run: bundle exec --gemfile=gemfiles/Gemfile.rubocop rake lint workflows: build-all: diff --git a/Gemfile b/Gemfile index 49161e38..b609c1a6 100644 --- a/Gemfile +++ b/Gemfile @@ -3,25 +3,8 @@ source 'https://rubygems.org' gemspec gem 'introspection', '~> 0.0.1' -gem 'jaro_winkler', '>= 1.5.5' gem 'minitest' gem 'rake' -gem 'rubocop', '> 0.56', '<= 0.58.2' - -# Avoid breaking change in psych v4 (https://bugs.ruby-lang.org/issues/17866) -if RUBY_VERSION >= '3.1.0' - gem 'psych', '< 4' -end - -# Avoid base64 gem warning about it not being available in Ruby v3.4 -if RUBY_VERSION >= '3.3.0' - gem 'base64' -end - -# Avoid ostruct gem warning about it not being available in Ruby v3.5 -if RUBY_VERSION >= '3.4.0' - gem 'ostruct' -end if RUBY_ENGINE == 'jruby' # Workaround for https://github.com/jruby/jruby/issues/8488 diff --git a/Rakefile b/Rakefile index b9ba8778..d56cd9d8 100644 --- a/Rakefile +++ b/Rakefile @@ -6,7 +6,7 @@ require 'bundler/setup' require 'rake/testtask' begin - # Only available with default Gemfile + # Only available with `gemfiles/Gemfile.rubocop` require 'rubocop/rake_task' rescue LoadError # rubocop:disable Lint/HandleExceptions end diff --git a/gemfiles/Gemfile.rubocop b/gemfiles/Gemfile.rubocop new file mode 100644 index 00000000..434d97fb --- /dev/null +++ b/gemfiles/Gemfile.rubocop @@ -0,0 +1,22 @@ +source 'https://rubygems.org' + +gemspec path: '../' + +gem 'jaro_winkler', '>= 1.5.5' +gem 'rake' +gem 'rubocop', '> 0.56', '<= 0.58.2' + +# Avoid breaking change in psych v4 (https://bugs.ruby-lang.org/issues/17866) +if RUBY_VERSION >= '3.1.0' + gem 'psych', '< 4' +end + +# Avoid base64 gem warning about it not being available in Ruby v3.4 +if RUBY_VERSION >= '3.3.0' + gem 'base64' +end + +# Avoid ostruct gem warning about it not being available in Ruby v3.5 +if RUBY_VERSION >= '3.4.0' + gem 'ostruct' +end From b78c92b832f4e0a233553ca79bc9b017d6c3de02 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 17:47:15 +0000 Subject: [PATCH 02/36] Run rubocop linting on Ruby v3.3 in CI build This is what I've been using locally for some time without any problems. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 15bc67a5..fea4dd1d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,7 +53,7 @@ jobs: - run: MOCHA_GENERATE_DOCS=1 rake yardoc lint: docker: - - image: ruby:2.6 + - image: ruby:3.3 steps: - checkout - run: ruby --version From 571daa1affc90f25e06ec6ff5c86bc208dc40932 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:31:32 +0000 Subject: [PATCH 03/36] Use latest rubocop for linting * This means we can considerably simplify `gemfiles/Gemfile.rubocop`, because we no longer need any of the workarounds. * I've regenerated the `.rubocop_todo.yml` file. * `Metrics/LineLength` has moved to `Layout/LineLength`. * The equivalent of the `IgnoredPatterns` attribute in `Metrics/LineLength` for `Layout/LineLength` is `AllowedPatterns`. * I have not *yet* opted in to a bunch of *new* cops, so the output is quite verbose. * Similarly, I haven't *yet* opted in to new cops by default by enabling the `AllCops/NewCops` config option. * There is a tip suggesting the `rubocop-rake` extension might be useful which I plan to address separately. --- .rubocop.yml | 4 +- .rubocop_todo.yml | 168 ++++++++++++++++++++++++++++++++++++--- gemfiles/Gemfile.rubocop | 18 +---- 3 files changed, 162 insertions(+), 28 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 97a704e9..769c3b58 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -60,8 +60,8 @@ Layout/AccessModifierIndentation: Enabled: false # Allow long comment lines, e.g. YARD documentation -Metrics/LineLength: - IgnoredPatterns: ['\A\s*#'] +Layout/LineLength: + AllowedPatterns: ['\A\s*#'] # It's not possible to set TargetRubyVersion to Ruby < v2.2 Gemspec/RequiredRubyVersion: diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 81202083..011c90cc 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,27 +1,177 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-12-22 11:51:08 +0000 using RuboCop version 0.58.2. +# on 2024-12-24 18:24:19 UTC using RuboCop version 1.69.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 63 +# Offense count: 28 +# This cop supports safe autocorrection (--autocorrect). +Layout/EmptyLineAfterGuardClause: + Enabled: false + +# Offense count: 5 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowAliasSyntax, AllowedMethods. +# AllowedMethods: alias_method, public, protected, private +Layout/EmptyLinesAroundAttributeAccessor: + Exclude: + - 'test/minitest_result_pre_v5.rb' + - 'test/test_unit_result.rb' + - 'test/unit/instance_method_test.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Lint/IdentityComparison: + Exclude: + - 'lib/mocha/stubbed_method.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: standard_error, runtime_error +Lint/InheritException: + Exclude: + - 'test/unit/expectation_test.rb' + +# Offense count: 19 +# Configuration parameters: AllowedParentClasses. +Lint/MissingSuper: + Enabled: false + +# Offense count: 48 +# This cop supports safe autocorrection (--autocorrect). +Lint/RedundantCopDisableDirective: + Enabled: false + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Lint/SendWithMixinArgument: + Exclude: + - 'lib/mocha/api.rb' + +# Offense count: 3 +# Configuration parameters: AllowComments, AllowNil. +Lint/SuppressedException: + Exclude: + - 'Rakefile' + - 'lib/mocha/detection/test_unit.rb' + - 'test/test_helper.rb' + +# Offense count: 17 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: AutoCorrect. +Lint/UselessTimes: + Exclude: + - 'test/acceptance/expected_invocation_count_test.rb' + - 'test/acceptance/multiple_expectations_failure_message_test.rb' + - 'test/unit/expectation_test.rb' + - 'test/unit/mockery_test.rb' + +# Offense count: 34 +# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: - Max: 26 + Max: 27 -# Offense count: 29 -# Configuration parameters: CountComments. +# Offense count: 28 +# Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: Max: 381 +# Offense count: 2 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 11 + # Offense count: 200 -# Configuration parameters: CountComments. +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 27 -# Offense count: 699 -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/PerceivedComplexity: + Max: 13 + +# Offense count: 303 +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. +# SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 +Naming/VariableNumber: + Enabled: false + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: AllowedMethods, AllowedPatterns. +# AllowedMethods: ==, equal?, eql? +Style/ClassEqualityComparison: + Exclude: + - 'lib/mocha/stubbed_method.rb' + +# Offense count: 2 +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/CombinableLoops: + Exclude: + - 'test/unit/mock_test.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/ExplicitBlockArgument: + Exclude: + - 'lib/mocha/argument_iterator.rb' + +# Offense count: 4 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: literals, strict +Style/MutableConstant: + Exclude: + - 'test/minitest_result_pre_v5.rb' + +# Offense count: 24 +# Configuration parameters: AllowedMethods. +# AllowedMethods: respond_to_missing? +Style/OptionalBooleanParameter: + Exclude: + - 'lib/mocha/class_methods.rb' + - 'lib/mocha/inspect.rb' + - 'lib/mocha/object_methods.rb' + - 'test/acceptance/stub_any_instance_method_test.rb' + - 'test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb' + - 'test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb' + - 'test/acceptance/stub_module_method_test.rb' + - 'test/acceptance/stubbing_non_existent_any_instance_method_test.rb' + - 'test/acceptance/stubbing_non_existent_class_method_test.rb' + - 'test/acceptance/stubbing_non_existent_instance_method_test.rb' + - 'test/acceptance/stubbing_non_public_class_method_test.rb' + - 'test/acceptance/stubbing_non_public_instance_method_test.rb' + - 'test/unit/sequence_test.rb' + +# Offense count: 12 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantRegexpEscape: + Exclude: + - 'test/minitest_result_pre_v5.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowMultipleReturnValues. +Style/RedundantReturn: + Exclude: + - 'lib/mocha/parameter_matchers/includes.rb' + +# Offense count: 5 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: Mode. +Style/StringConcatenation: + Exclude: + - 'test/acceptance/prepend_test.rb' + - 'test/unit/backtrace_filter_test.rb' + +# Offense count: 68 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. # URISchemes: http, https -Metrics/LineLength: +Layout/LineLength: Max: 173 diff --git a/gemfiles/Gemfile.rubocop b/gemfiles/Gemfile.rubocop index 434d97fb..61f5d370 100644 --- a/gemfiles/Gemfile.rubocop +++ b/gemfiles/Gemfile.rubocop @@ -2,21 +2,5 @@ source 'https://rubygems.org' gemspec path: '../' -gem 'jaro_winkler', '>= 1.5.5' gem 'rake' -gem 'rubocop', '> 0.56', '<= 0.58.2' - -# Avoid breaking change in psych v4 (https://bugs.ruby-lang.org/issues/17866) -if RUBY_VERSION >= '3.1.0' - gem 'psych', '< 4' -end - -# Avoid base64 gem warning about it not being available in Ruby v3.4 -if RUBY_VERSION >= '3.3.0' - gem 'base64' -end - -# Avoid ostruct gem warning about it not being available in Ruby v3.5 -if RUBY_VERSION >= '3.4.0' - gem 'ostruct' -end +gem 'rubocop' From e18b3f0e4cbb20721f60ae8a7d8ef44a508b1b9f Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:41:51 +0000 Subject: [PATCH 04/36] Opt in to new rubocop cops by default And re-generate to-do list. --- .rubocop.yml | 2 ++ .rubocop_todo.yml | 58 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 769c3b58..6bcb4003 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -13,6 +13,8 @@ AllCops: Exclude: - '**/Gemfile*.lock' + NewCops: enable + # Even the reference in the documentation suggests that you should prefer # `alias_method` vs `alias`, so I don't understand why that isn't the default. Style/Alias: diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 011c90cc..cfca2f49 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,11 +1,27 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-12-24 18:24:19 UTC using RuboCop version 1.69.2. +# on 2024-12-24 18:41:27 UTC using RuboCop version 1.69.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Include. +# Include: **/*.gemspec +Gemspec/AddRuntimeDependency: + Exclude: + - 'mocha.gemspec' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Severity, Include. +# Include: **/*.gemspec +Gemspec/RequireMFA: + Exclude: + - 'mocha.gemspec' + # Offense count: 28 # This cop supports safe autocorrection (--autocorrect). Layout/EmptyLineAfterGuardClause: @@ -21,6 +37,23 @@ Layout/EmptyLinesAroundAttributeAccessor: - 'test/test_unit_result.rb' - 'test/unit/instance_method_test.rb' +# Offense count: 13 +# Configuration parameters: AllowComments, AllowEmptyLambdas. +Lint/EmptyBlock: + Exclude: + - 'test/acceptance/display_matching_invocations_alongside_expectations_test.rb' + - 'test/test_runner.rb' + - 'test/unit/any_instance_method_test.rb' + - 'test/unit/instance_method_test.rb' + - 'test/unit/mock_test.rb' + +# Offense count: 2 +# Configuration parameters: AllowComments. +Lint/EmptyClass: + Exclude: + - 'test/acceptance/failure_messages_test.rb' + - 'test/unit/mockery_test.rb' + # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). Lint/IdentityComparison: @@ -59,6 +92,14 @@ Lint/SuppressedException: - 'lib/mocha/detection/test_unit.rb' - 'test/test_helper.rb' +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: strict, consistent +Lint/SymbolConversion: + Exclude: + - 'lib/mocha/configuration.rb' + # Offense count: 17 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AutoCorrect. @@ -121,6 +162,13 @@ Style/ExplicitBlockArgument: Exclude: - 'lib/mocha/argument_iterator.rb' +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowedVars. +Style/FetchEnvVar: + Exclude: + - 'Rakefile' + # Offense count: 4 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. @@ -148,7 +196,13 @@ Style/OptionalBooleanParameter: - 'test/acceptance/stubbing_non_public_instance_method_test.rb' - 'test/unit/sequence_test.rb' -# Offense count: 12 +# Offense count: 7 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantDoubleSplatHashBraces: + Exclude: + - 'test/acceptance/keyword_argument_matching_test.rb' + +# Offense count: 8 # This cop supports safe autocorrection (--autocorrect). Style/RedundantRegexpEscape: Exclude: From 2b88818ed1354aa78b1fb865188b3f600fbb0fa9 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 05/36] Auto-correct Gemspec/AddRuntimeDependency violation --- .rubocop_todo.yml | 8 -------- mocha.gemspec | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index cfca2f49..c07b4c7a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,14 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Include. -# Include: **/*.gemspec -Gemspec/AddRuntimeDependency: - Exclude: - - 'mocha.gemspec' - # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Severity, Include. diff --git a/mocha.gemspec b/mocha.gemspec index 08e1e949..5b480a84 100644 --- a/mocha.gemspec +++ b/mocha.gemspec @@ -35,5 +35,5 @@ Gem::Specification.new do |s| 'source_code_uri' => 'https://github.com/freerange/mocha' } - s.add_runtime_dependency 'ruby2_keywords', '>= 0.0.5' + s.add_dependency 'ruby2_keywords', '>= 0.0.5' end From ea957ee881db76983f23e64856d24fea921e737d Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 06/36] Auto-correct Gemspec/RequireMFA violation --- .rubocop_todo.yml | 8 -------- mocha.gemspec | 3 ++- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c07b4c7a..225fbb46 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,14 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Severity, Include. -# Include: **/*.gemspec -Gemspec/RequireMFA: - Exclude: - - 'mocha.gemspec' - # Offense count: 28 # This cop supports safe autocorrection (--autocorrect). Layout/EmptyLineAfterGuardClause: diff --git a/mocha.gemspec b/mocha.gemspec index 5b480a84..5ce10bb6 100644 --- a/mocha.gemspec +++ b/mocha.gemspec @@ -32,7 +32,8 @@ Gem::Specification.new do |s| 'documentation_uri' => 'https://mocha.jamesmead.org/', 'funding_uri' => 'https://github.com/sponsors/floehopper', 'homepage_uri' => s.homepage, - 'source_code_uri' => 'https://github.com/freerange/mocha' + 'source_code_uri' => 'https://github.com/freerange/mocha', + 'rubygems_mfa_required' => 'true' } s.add_dependency 'ruby2_keywords', '>= 0.0.5' From f988e6f0981cfb76bb0c2fda0521a10eb8a06744 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 07/36] Auto-correct Layout/EmptyLineAfterGuardClause violations I had to change the line numbers of a couple of assertions to match the new line numbers after the blank lines were added. --- .rubocop_todo.yml | 5 ----- lib/mocha/central.rb | 2 ++ lib/mocha/class_methods.rb | 1 + lib/mocha/configuration.rb | 1 + lib/mocha/deprecation.rb | 1 + lib/mocha/exception_raiser.rb | 1 + lib/mocha/integration/minitest/adapter.rb | 1 + lib/mocha/integration/minitest/exception_translation.rb | 1 + lib/mocha/integration/test_unit/adapter.rb | 1 + lib/mocha/invocation.rb | 1 + lib/mocha/mockery.rb | 2 ++ lib/mocha/object_methods.rb | 2 ++ lib/mocha/parameter_matchers/has_entry.rb | 1 + lib/mocha/parameter_matchers/has_key.rb | 1 + lib/mocha/parameter_matchers/has_value.rb | 1 + lib/mocha/parameter_matchers/includes.rb | 1 + lib/mocha/parameter_matchers/optionally.rb | 1 + lib/mocha/parameter_matchers/regexp_matches.rb | 1 + lib/mocha/stubbed_method.rb | 4 ++++ test/execution_point.rb | 1 + test/method_definer.rb | 1 + test/minitest_result_pre_v5.rb | 2 ++ test/unit/any_instance_method_test.rb | 2 +- test/unit/instance_method_test.rb | 2 +- 24 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 225fbb46..94d7f0de 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,11 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 28 -# This cop supports safe autocorrection (--autocorrect). -Layout/EmptyLineAfterGuardClause: - Enabled: false - # Offense count: 5 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowAliasSyntax, AllowedMethods. diff --git a/lib/mocha/central.rb b/lib/mocha/central.rb index c5bc3c68..0ccb32f9 100644 --- a/lib/mocha/central.rb +++ b/lib/mocha/central.rb @@ -23,12 +23,14 @@ def initialize def stub(method) return if stubba_methods.detect { |m| m.matches?(method) } + method.stub stubba_methods.push(method) end def unstub(method) return unless (existing = stubba_methods.detect { |m| m.matches?(method) }) + existing.unstub stubba_methods.delete(existing) end diff --git a/lib/mocha/class_methods.rb b/lib/mocha/class_methods.rb index 2ccd58fd..5e503555 100644 --- a/lib/mocha/class_methods.rb +++ b/lib/mocha/class_methods.rb @@ -46,6 +46,7 @@ def any_instance if frozen? raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}.any_instance", caller) end + @any_instance ||= AnyInstance.new(self) end diff --git a/lib/mocha/configuration.rb b/lib/mocha/configuration.rb index a6a12cc4..107d3487 100644 --- a/lib/mocha/configuration.rb +++ b/lib/mocha/configuration.rb @@ -266,6 +266,7 @@ def display_matching_invocations_on_failure? # # This now fails as expected def strict_keyword_argument_matching=(value) raise 'Strict keyword argument matching requires Ruby 2.7 and above.' unless Mocha::RUBY_V27_PLUS + @options[:strict_keyword_argument_matching] = value end diff --git a/lib/mocha/deprecation.rb b/lib/mocha/deprecation.rb index 8a1e55e2..49596be8 100644 --- a/lib/mocha/deprecation.rb +++ b/lib/mocha/deprecation.rb @@ -9,6 +9,7 @@ def warning(*messages) message = messages.join @messages << message return if mode == :disabled + filter = BacktraceFilter.new location = filter.filtered(caller)[0] warn "Mocha deprecation warning at #{location}: #{message}" diff --git a/lib/mocha/exception_raiser.rb b/lib/mocha/exception_raiser.rb index 8b2430df..794d8c16 100644 --- a/lib/mocha/exception_raiser.rb +++ b/lib/mocha/exception_raiser.rb @@ -9,6 +9,7 @@ def evaluate(invocation) invocation.raised(@exception) raise @exception, @exception.to_s if @exception.is_a?(Module) && (@exception < Interrupt) raise @exception, @message if @message + raise @exception end end diff --git a/lib/mocha/integration/minitest/adapter.rb b/lib/mocha/integration/minitest/adapter.rb index ee000a35..9f578875 100644 --- a/lib/mocha/integration/minitest/adapter.rb +++ b/lib/mocha/integration/minitest/adapter.rb @@ -35,6 +35,7 @@ def before_setup # @private def before_teardown return unless passed? + assertion_counter = Integration::AssertionCounter.new(self) mocha_verify(assertion_counter) ensure diff --git a/lib/mocha/integration/minitest/exception_translation.rb b/lib/mocha/integration/minitest/exception_translation.rb index 2c48ac7c..fca8a4b8 100644 --- a/lib/mocha/integration/minitest/exception_translation.rb +++ b/lib/mocha/integration/minitest/exception_translation.rb @@ -5,6 +5,7 @@ module Integration module Minitest def self.translate(exception) return exception unless exception.is_a?(::Mocha::ExpectationError) + translated_exception = ::Minitest::Assertion.new(exception.message) translated_exception.set_backtrace(exception.backtrace) translated_exception diff --git a/lib/mocha/integration/test_unit/adapter.rb b/lib/mocha/integration/test_unit/adapter.rb index 38da4774..eab49ef5 100644 --- a/lib/mocha/integration/test_unit/adapter.rb +++ b/lib/mocha/integration/test_unit/adapter.rb @@ -45,6 +45,7 @@ def mocha_test_name # @private def handle_mocha_expectation_error(exception) return false unless exception.is_a?(Mocha::ExpectationError) + problem_occurred add_failure(exception.message, exception.backtrace) true diff --git a/lib/mocha/invocation.rb b/lib/mocha/invocation.rb index a45dcaa7..cc15c8ba 100644 --- a/lib/mocha/invocation.rb +++ b/lib/mocha/invocation.rb @@ -21,6 +21,7 @@ def call(yield_parameters = YieldParameters.new, return_values = ReturnValues.ne yield_parameters.next_invocation.each do |yield_args| @yields << ParametersMatcher.new(yield_args) raise LocalJumpError unless @block + @block.call(*yield_args) end return_values.next(self) diff --git a/lib/mocha/mockery.rb b/lib/mocha/mockery.rb index 12ffa601..2ae49a0f 100644 --- a/lib/mocha/mockery.rb +++ b/lib/mocha/mockery.rb @@ -143,9 +143,11 @@ def logger def check(action, description, signature_proc, backtrace = caller) treatment = Mocha.configuration.send(action) return if (treatment == :allow) || (block_given? && !yield) + method_signature = signature_proc.call message = "stubbing #{description}: #{method_signature}" raise StubbingError.new(message, backtrace) if treatment == :prevent + logger.warn(message) if treatment == :warn end diff --git a/lib/mocha/object_methods.rb b/lib/mocha/object_methods.rb index 77c6cafe..269cdb60 100644 --- a/lib/mocha/object_methods.rb +++ b/lib/mocha/object_methods.rb @@ -75,6 +75,7 @@ def expects(expected_methods_vs_return_values) if frozen? raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller) end + expectation = nil mockery = Mocha::Mockery.instance iterator = ArgumentIterator.new(expected_methods_vs_return_values) @@ -121,6 +122,7 @@ def stubs(stubbed_methods_vs_return_values) if frozen? raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller) end + expectation = nil mockery = Mocha::Mockery.instance iterator = ArgumentIterator.new(stubbed_methods_vs_return_values) diff --git a/lib/mocha/parameter_matchers/has_entry.rb b/lib/mocha/parameter_matchers/has_entry.rb index 6bf9a22e..85d24a97 100644 --- a/lib/mocha/parameter_matchers/has_entry.rb +++ b/lib/mocha/parameter_matchers/has_entry.rb @@ -66,6 +66,7 @@ def initialize(key, value) def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:keys) && parameter.respond_to?(:[]) + matching_keys = parameter.keys.select { |key| @key.to_matcher.matches?([key]) } matching_keys.any? { |key| @value.to_matcher.matches?([parameter[key]]) } end diff --git a/lib/mocha/parameter_matchers/has_key.rb b/lib/mocha/parameter_matchers/has_key.rb index 52a751f2..712062bc 100644 --- a/lib/mocha/parameter_matchers/has_key.rb +++ b/lib/mocha/parameter_matchers/has_key.rb @@ -36,6 +36,7 @@ def initialize(key) def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:keys) + parameter.keys.any? { |key| @key.to_matcher.matches?([key]) } end diff --git a/lib/mocha/parameter_matchers/has_value.rb b/lib/mocha/parameter_matchers/has_value.rb index 8541c553..4c358ada 100644 --- a/lib/mocha/parameter_matchers/has_value.rb +++ b/lib/mocha/parameter_matchers/has_value.rb @@ -36,6 +36,7 @@ def initialize(value) def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:values) + parameter.values.any? { |value| @value.to_matcher.matches?([value]) } end diff --git a/lib/mocha/parameter_matchers/includes.rb b/lib/mocha/parameter_matchers/includes.rb index fd8c6bc0..dced0aca 100644 --- a/lib/mocha/parameter_matchers/includes.rb +++ b/lib/mocha/parameter_matchers/includes.rb @@ -76,6 +76,7 @@ def initialize(*items) def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:include?) + if @items.size == 1 # rubocop:disable Style/GuardClause if parameter.respond_to?(:any?) && !parameter.is_a?(String) diff --git a/lib/mocha/parameter_matchers/optionally.rb b/lib/mocha/parameter_matchers/optionally.rb index 89ceae1c..78a18872 100644 --- a/lib/mocha/parameter_matchers/optionally.rb +++ b/lib/mocha/parameter_matchers/optionally.rb @@ -47,6 +47,7 @@ def matches?(available_parameters) while !available_parameters.empty? && (index < @matchers.length) matcher = @matchers[index] return false unless matcher.matches?(available_parameters) + index += 1 end true diff --git a/lib/mocha/parameter_matchers/regexp_matches.rb b/lib/mocha/parameter_matchers/regexp_matches.rb index 70366217..98ddcb55 100644 --- a/lib/mocha/parameter_matchers/regexp_matches.rb +++ b/lib/mocha/parameter_matchers/regexp_matches.rb @@ -36,6 +36,7 @@ def initialize(regexp) def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:=~) + parameter =~ @regexp end diff --git a/lib/mocha/stubbed_method.rb b/lib/mocha/stubbed_method.rb index 75f773ff..04992b1a 100644 --- a/lib/mocha/stubbed_method.rb +++ b/lib/mocha/stubbed_method.rb @@ -23,6 +23,7 @@ def unstub remove_new_method mock.unstub(method_name.to_sym) return if mock.any_expectations? + reset_mocha end @@ -36,6 +37,7 @@ def reset_mocha def hide_original_method return unless original_method_owner.__method_exists__?(method_name) + store_original_method_visibility use_prepended_module_for_stub_method end @@ -56,6 +58,7 @@ def remove_new_method def matches?(other) return false unless other.class == self.class + (stubbee.object_id == other.stubbee.object_id) && (method_name == other.method_name) end @@ -69,6 +72,7 @@ def to_s def retain_original_visibility(method_owner) return unless @original_visibility + Module.instance_method(@original_visibility).bind(method_owner).call(method_name) end diff --git a/test/execution_point.rb b/test/execution_point.rb index 42e9b912..75bbec44 100644 --- a/test/execution_point.rb +++ b/test/execution_point.rb @@ -23,6 +23,7 @@ def line_number def ==(other) return false unless other.is_a?(ExecutionPoint) + (file_name == other.file_name) && (line_number == other.line_number) end diff --git a/test/method_definer.rb b/test/method_definer.rb index bd0050a4..5190e1fd 100644 --- a/test/method_definer.rb +++ b/test/method_definer.rb @@ -5,6 +5,7 @@ def define_instance_method(object, method_symbol, &block) def replace_instance_method(object, method_symbol, &block) raise "Cannot replace #{method_symbol} as #{self} does not respond to it." unless object.respond_to?(method_symbol) + define_instance_method(object, method_symbol, &block) end diff --git a/test/minitest_result_pre_v5.rb b/test/minitest_result_pre_v5.rb index 2e599d95..a3a44282 100644 --- a/test/minitest_result_pre_v5.rb +++ b/test/minitest_result_pre_v5.rb @@ -16,12 +16,14 @@ class MinitestResult def self.parse_failure(raw) matches = FAILURE_PATTERN.match(raw) return nil unless matches + Failure.new(matches[PATTERN_INDICES[:method]], matches[PATTERN_INDICES[:testcase]], [matches[4]], matches[5]) end def self.parse_error(raw) matches = ERROR_PATTERN.match(raw) return nil unless matches + backtrace = raw.gsub(ERROR_PATTERN, '').split("\n").map(&:strip) Error.new(matches[PATTERN_INDICES[:method]], matches[PATTERN_INDICES[:testcase]], matches[4], backtrace) end diff --git a/test/unit/any_instance_method_test.rb b/test/unit/any_instance_method_test.rb index 92624f23..3ce875d5 100644 --- a/test/unit/any_instance_method_test.rb +++ b/test/unit/any_instance_method_test.rb @@ -56,7 +56,7 @@ def test_should_include_the_filename_and_line_number_in_exceptions method.define_new_method expected_filename = 'stubbed_method.rb' - expected_line_number = 47 + expected_line_number = 49 exception = assert_raises(Exception) { klass.new.method_x } matching_line = exception.backtrace.find do |line| diff --git a/test/unit/instance_method_test.rb b/test/unit/instance_method_test.rb index 2c04e92f..37683481 100644 --- a/test/unit/instance_method_test.rb +++ b/test/unit/instance_method_test.rb @@ -59,7 +59,7 @@ def test_should_include_the_filename_and_line_number_in_exceptions method.define_new_method expected_filename = 'stubbed_method.rb' - expected_line_number = 47 + expected_line_number = 49 exception = assert_raises(Exception) { klass.method_x } matching_line = exception.backtrace.find do |line| From dfc877b5f62f9db0edb0e6047efbc74c9adf154b Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 08/36] Auto-correct Layout/EmptyLinesAroundAttributeAccessor violations --- .rubocop_todo.yml | 10 ---------- test/minitest_result_pre_v5.rb | 3 +++ test/test_unit_result.rb | 1 + test/unit/instance_method_test.rb | 1 + 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 94d7f0de..6d349ebd 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,16 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 5 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowAliasSyntax, AllowedMethods. -# AllowedMethods: alias_method, public, protected, private -Layout/EmptyLinesAroundAttributeAccessor: - Exclude: - - 'test/minitest_result_pre_v5.rb' - - 'test/test_unit_result.rb' - - 'test/unit/instance_method_test.rb' - # Offense count: 13 # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: diff --git a/test/minitest_result_pre_v5.rb b/test/minitest_result_pre_v5.rb index a3a44282..c7fc362f 100644 --- a/test/minitest_result_pre_v5.rb +++ b/test/minitest_result_pre_v5.rb @@ -30,6 +30,7 @@ def self.parse_error(raw) class Failure attr_reader :method, :test_case, :location, :message + def initialize(method, test_case, location, message) @method = method @test_case = test_case @@ -41,6 +42,7 @@ def initialize(method, test_case, location, message) class Error class Exception attr_reader :message, :backtrace + def initialize(message, location) @message = message @backtrace = location @@ -48,6 +50,7 @@ def initialize(message, location) end attr_reader :method, :test_case, :exception + def initialize(method, test_case, message, backtrace) @method = method @test_case = test_case diff --git a/test/test_unit_result.rb b/test/test_unit_result.rb index 4439dfd9..528fb08c 100644 --- a/test/test_unit_result.rb +++ b/test/test_unit_result.rb @@ -5,6 +5,7 @@ def self.build_test_result test_result = Test::Unit::TestResult.new class << test_result attr_reader :failures, :errors + def failure_messages failures.map(&:message) end diff --git a/test/unit/instance_method_test.rb b/test/unit/instance_method_test.rb index 37683481..1ef5dce6 100644 --- a/test/unit/instance_method_test.rb +++ b/test/unit/instance_method_test.rb @@ -177,6 +177,7 @@ def test_should_call_stubbee_reset_mocha_if_no_expectations_remaining replace_instance_method(method, :mock) { mocha } stubbee = Class.new do attr_accessor :reset_mocha_called + def reset_mocha self.reset_mocha_called = true end From a9c403ce59a6e31dc1a4e2e8314e08958190cd5d Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 09/36] Auto-correct Lint/InheritException violation --- .rubocop_todo.yml | 8 -------- test/unit/expectation_test.rb | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6d349ebd..ebebdd90 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -29,14 +29,6 @@ Lint/IdentityComparison: Exclude: - 'lib/mocha/stubbed_method.rb' -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: standard_error, runtime_error -Lint/InheritException: - Exclude: - - 'test/unit/expectation_test.rb' - # Offense count: 19 # Configuration parameters: AllowedParentClasses. Lint/MissingSuper: diff --git a/test/unit/expectation_test.rb b/test/unit/expectation_test.rb index 4bc93129..4010006c 100644 --- a/test/unit/expectation_test.rb +++ b/test/unit/expectation_test.rb @@ -192,7 +192,7 @@ def test_should_raise_runtime_exception end def test_should_raise_custom_exception - exception = Class.new(Exception) + exception = Class.new(StandardError) assert_raises(exception) { invoke(new_expectation.raises(exception)) } end From 13a4886f967b16800751ff65db6e6bac4df1e41d Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 10/36] Auto-correct Lint/IdentityComparison violations --- .rubocop_todo.yml | 5 ---- Rakefile | 5 +--- lib/mocha/cardinality.rb | 2 -- lib/mocha/class_methods.rb | 2 -- lib/mocha/detection/test_unit.rb | 2 +- lib/mocha/mock.rb | 4 +-- lib/mocha/parameter_matchers/includes.rb | 2 -- .../keyword_argument_matching_test.rb | 20 ++++++------- ...positional_and_keyword_has_inspect_test.rb | 16 +++++----- ...stub_class_method_defined_on_class_test.rb | 2 -- ...class_method_defined_on_superclass_test.rb | 2 -- ...nce_method_defined_on_object_class_test.rb | 2 -- test/acceptance/stub_module_method_test.rb | 2 -- ...stubbing_non_existent_class_method_test.rb | 2 -- .../stubbing_non_public_class_method_test.rb | 2 -- test/test_helper.rb | 3 -- test/unit/date_time_inspect_test.rb | 2 +- .../positional_or_keyword_hash_test.rb | 30 +++++++++---------- 18 files changed, 38 insertions(+), 67 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ebebdd90..a6eb564a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -34,11 +34,6 @@ Lint/IdentityComparison: Lint/MissingSuper: Enabled: false -# Offense count: 48 -# This cop supports safe autocorrection (--autocorrect). -Lint/RedundantCopDisableDirective: - Enabled: false - # Offense count: 2 # This cop supports safe autocorrection (--autocorrect). Lint/SendWithMixinArgument: diff --git a/Rakefile b/Rakefile index d56cd9d8..3327cb9c 100644 --- a/Rakefile +++ b/Rakefile @@ -8,7 +8,7 @@ require 'rake/testtask' begin # Only available with `gemfiles/Gemfile.rubocop` require 'rubocop/rake_task' -rescue LoadError # rubocop:disable Lint/HandleExceptions +rescue LoadError end desc 'Run all linters and tests' @@ -90,7 +90,6 @@ task 'lint' do end end -# rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity def benchmark_test_case(klass, iterations) require 'benchmark' require 'mocha/detection/minitest' @@ -119,8 +118,6 @@ def benchmark_test_case(klass, iterations) Benchmark.realtime { iterations.times { Test::Unit::UI::Console::TestRunner.run(klass, @silent_option) } } end end -# rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity - if ENV['MOCHA_GENERATE_DOCS'] require 'yard' diff --git a/lib/mocha/cardinality.rb b/lib/mocha/cardinality.rb index fa8fb99d..cd64b926 100644 --- a/lib/mocha/cardinality.rb +++ b/lib/mocha/cardinality.rb @@ -58,7 +58,6 @@ def used? @invocations.any? || maximum.zero? end - # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity def anticipated_times if allowed_any_number_of_times? 'allowed any number of times' @@ -74,7 +73,6 @@ def anticipated_times "expected between #{required} and #{count(maximum)}" end end - # rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity def invoked_times "invoked #{count(@invocations.size)}" diff --git a/lib/mocha/class_methods.rb b/lib/mocha/class_methods.rb index 5e503555..735e190c 100644 --- a/lib/mocha/class_methods.rb +++ b/lib/mocha/class_methods.rb @@ -51,13 +51,11 @@ def any_instance end # @private - # rubocop:disable Metrics/CyclomaticComplexity def __method_visibility__(method, include_public_methods = true) (include_public_methods && public_method_defined?(method) && :public) || (protected_method_defined?(method) && :protected) || (private_method_defined?(method) && :private) end - # rubocop:enable Metrics/CyclomaticComplexity alias_method :__method_exists__?, :__method_visibility__ end end diff --git a/lib/mocha/detection/test_unit.rb b/lib/mocha/detection/test_unit.rb index b7be2e41..cc2e6778 100644 --- a/lib/mocha/detection/test_unit.rb +++ b/lib/mocha/detection/test_unit.rb @@ -14,7 +14,7 @@ def self.version if testcase begin require 'test/unit/version' - rescue LoadError # rubocop:disable Lint/HandleExceptions + rescue LoadError end if defined?(::Test::Unit::VERSION) version = ::Test::Unit::VERSION diff --git a/lib/mocha/mock.rb b/lib/mocha/mock.rb index 059dc24d..fc37494f 100644 --- a/lib/mocha/mock.rb +++ b/lib/mocha/mock.rb @@ -315,13 +315,13 @@ def all_expectations end # @private - def method_missing(symbol, *arguments, &block) # rubocop:disable Style/MethodMissingSuper + def method_missing(symbol, *arguments, &block) handle_method_call(symbol, arguments, block) end ruby2_keywords(:method_missing) # @private - def handle_method_call(symbol, arguments, block) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + def handle_method_call(symbol, arguments, block) check_expiry check_responder_responds_to(symbol) invocation = Invocation.new(self, symbol, arguments, block) diff --git a/lib/mocha/parameter_matchers/includes.rb b/lib/mocha/parameter_matchers/includes.rb index dced0aca..842d3a32 100644 --- a/lib/mocha/parameter_matchers/includes.rb +++ b/lib/mocha/parameter_matchers/includes.rb @@ -72,7 +72,6 @@ def initialize(*items) end # @private - # rubocop:disable Metrics/PerceivedComplexity def matches?(available_parameters) parameter = available_parameters.shift return false unless parameter.respond_to?(:include?) @@ -91,7 +90,6 @@ def matches?(available_parameters) AllOf.new(*includes_matchers).matches?([parameter]) end end - # rubocop:enable Metrics/PerceivedComplexity # @private def mocha_inspect diff --git a/test/acceptance/keyword_argument_matching_test.rb b/test/acceptance/keyword_argument_matching_test.rb index 67dda752..8949a422 100644 --- a/test/acceptance/keyword_argument_matching_test.rb +++ b/test/acceptance/keyword_argument_matching_test.rb @@ -21,7 +21,7 @@ def test_should_match_hash_parameter_with_keyword_args mock = mock() mock.expects(:method).with(key: 42); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do - mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method({ key: 42 }) end if Mocha::RUBY_V27_PLUS location = execution_point.location @@ -38,7 +38,7 @@ def test_should_not_match_hash_parameter_with_keyword_args_when_strict_keyword_m mock = mock() mock.expects(:method).with(key: 42) Mocha::Configuration.override(strict_keyword_argument_matching: true) do - mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method({ key: 42 }) end end assert_failed(test_result) @@ -50,7 +50,7 @@ def test_should_match_hash_parameter_with_splatted_keyword_args mock = mock() mock.expects(:method).with(**{ key: 42 }); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do - mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method({ key: 42 }) end if Mocha::RUBY_V27_PLUS location = execution_point.location @@ -67,7 +67,7 @@ def test_should_not_match_hash_parameter_with_splatted_keyword_args_when_strict_ mock = mock() mock.expects(:method).with(**{ key: 42 }) Mocha::Configuration.override(strict_keyword_argument_matching: true) do - mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method({ key: 42 }) end end assert_failed(test_result) @@ -95,7 +95,7 @@ def test_should_match_splatted_hash_parameter_with_splatted_hash def test_should_match_positional_and_keyword_args_with_last_positional_hash test_result = run_as_test do mock = mock() - mock.expects(:method).with(1, { key: 42 }); execution_point = ExecutionPoint.current # rubocop:disable Style/BracesAroundHashParameters + mock.expects(:method).with(1, { key: 42 }); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do mock.method(1, key: 42) end @@ -112,7 +112,7 @@ def test_should_match_positional_and_keyword_args_with_last_positional_hash def test_should_not_match_positional_and_keyword_args_with_last_positional_hash_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock() - mock.expects(:method).with(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.expects(:method).with(1, { key: 42 }) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method(1, key: 42) end @@ -126,7 +126,7 @@ def test_should_match_last_positional_hash_with_keyword_args mock = mock() mock.expects(:method).with(1, key: 42); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do - mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method(1, { key: 42 }) end if Mocha::RUBY_V27_PLUS location = execution_point.location @@ -143,7 +143,7 @@ def test_should_not_match_last_positional_hash_with_keyword_args_when_strict_key mock = mock() mock.expects(:method).with(1, key: 42) Mocha::Configuration.override(strict_keyword_argument_matching: true) do - mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method(1, { key: 42 }) end end assert_failed(test_result) @@ -163,7 +163,7 @@ def test_should_match_hash_parameter_with_hash_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:key)) - mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method({ key: 42 }) end assert_passed(test_result) end @@ -217,7 +217,7 @@ def test_should_match_last_positional_hash_with_hash_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(1, has_key(:key)) - mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method(1, { key: 42 }) end assert_passed(test_result) end diff --git a/test/acceptance/positional_and_keyword_has_inspect_test.rb b/test/acceptance/positional_and_keyword_has_inspect_test.rb index d1c4cc94..49f86394 100644 --- a/test/acceptance/positional_and_keyword_has_inspect_test.rb +++ b/test/acceptance/positional_and_keyword_has_inspect_test.rb @@ -12,8 +12,8 @@ def teardown def test_single_hash_parameters_in_invocation_and_expectation_print_correctly test_result = run_as_test do mock = mock('mock') - mock.expects(:method).with({ foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters - mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.expects(:method).with({ foo: 42 }) + mock.method({ key: 42 }) end assert_equal [ 'unexpected invocation: #.method({:key => 42})', @@ -46,8 +46,8 @@ def test_unexpected_keyword_arguments_in_invocation_and_expectation_print_correc def test_last_hash_parameters_in_invocation_and_expectation_print_correctly test_result = run_as_test do mock = mock('mock') - mock.expects(:method).with(1, { foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters - mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.expects(:method).with(1, { foo: 42 }) + mock.method(1, { key: 42 }) end assert_equal [ 'unexpected invocation: #.method(1, {:key => 42})', @@ -81,9 +81,9 @@ def test_unexpected_keyword_arguments_with_other_positionals_in_invocation_and_e def test_single_hash_parameters_in_invocation_and_expectation_print_correctly_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock('mock') - mock.expects(:method).with({ foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.expects(:method).with({ foo: 42 }) Mocha::Configuration.override(strict_keyword_argument_matching: true) do - mock.method({ key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method({ key: 42 }) end end assert_equal [ @@ -111,9 +111,9 @@ def test_unexpected_keyword_arguments_in_invocation_and_expectation_print_correc def test_last_hash_parameters_in_invocation_and_expectation_print_correctly_when_strict_keyword_args_is_enabled test_result = run_as_test do mock = mock('mock') - mock.expects(:method).with(1, { foo: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.expects(:method).with(1, { foo: 42 }) Mocha::Configuration.override(strict_keyword_argument_matching: true) do - mock.method(1, { key: 42 }) # rubocop:disable Style/BracesAroundHashParameters + mock.method(1, { key: 42 }) end end assert_equal [ diff --git a/test/acceptance/stub_class_method_defined_on_class_test.rb b/test/acceptance/stub_class_method_defined_on_class_test.rb index 3d8084e0..a7682991 100644 --- a/test/acceptance/stub_class_method_defined_on_class_test.rb +++ b/test/acceptance/stub_class_method_defined_on_class_test.rb @@ -11,7 +11,6 @@ def teardown teardown_acceptance_test end - # rubocop:disable Lint/DuplicateMethods def test_should_stub_public_method_and_leave_it_unchanged_after_test klass = Class.new do class << self @@ -74,5 +73,4 @@ def self.private(*args); end end assert_equal :original_return_value, klass.send(:my_class_method) end - # rubocop:enable Lint/DuplicateMethods end diff --git a/test/acceptance/stub_class_method_defined_on_superclass_test.rb b/test/acceptance/stub_class_method_defined_on_superclass_test.rb index 53b74fd1..661bebc1 100644 --- a/test/acceptance/stub_class_method_defined_on_superclass_test.rb +++ b/test/acceptance/stub_class_method_defined_on_superclass_test.rb @@ -11,7 +11,6 @@ def teardown teardown_acceptance_test end - # rubocop:disable Lint/DuplicateMethods def test_should_stub_public_method_on_child_class_and_leave_it_unchanged_after_test superklass = Class.new do class << self @@ -140,5 +139,4 @@ def self.my_class_method; end '- expected exactly once, invoked never: superklass.my_class_method(any_parameters)' ], test_result.failure_message_lines end - # rubocop:enable Lint/DuplicateMethods end diff --git a/test/acceptance/stub_instance_method_defined_on_object_class_test.rb b/test/acceptance/stub_instance_method_defined_on_object_class_test.rb index ad25df2b..2a2dd0ea 100644 --- a/test/acceptance/stub_instance_method_defined_on_object_class_test.rb +++ b/test/acceptance/stub_instance_method_defined_on_object_class_test.rb @@ -11,7 +11,6 @@ def teardown teardown_acceptance_test end - # rubocop:disable Lint/DuplicateMethods def test_should_stub_public_method_and_leave_it_unchanged_after_test Object.class_eval do def my_instance_method @@ -71,5 +70,4 @@ def my_instance_method ensure Object.class_eval { remove_method :my_instance_method } end - # rubocop:enable Lint/DuplicateMethods end diff --git a/test/acceptance/stub_module_method_test.rb b/test/acceptance/stub_module_method_test.rb index 33c2066d..d4de8165 100644 --- a/test/acceptance/stub_module_method_test.rb +++ b/test/acceptance/stub_module_method_test.rb @@ -11,7 +11,6 @@ def teardown teardown_acceptance_test end - # rubocop:disable Lint/DuplicateMethods def test_should_stub_method_within_test mod = Module.new do def self.my_module_method @@ -151,5 +150,4 @@ def private_methods(_include_superclass = true) end assert_passed(test_result) end - # rubocop:enable Lint/DuplicateMethods end diff --git a/test/acceptance/stubbing_non_existent_class_method_test.rb b/test/acceptance/stubbing_non_existent_class_method_test.rb index eba960d3..2fa8a06f 100644 --- a/test/acceptance/stubbing_non_existent_class_method_test.rb +++ b/test/acceptance/stubbing_non_existent_class_method_test.rb @@ -51,7 +51,6 @@ def test_should_default_to_allow_stubbing_non_existent_class_method assert_passed(test_result) end - # rubocop:disable Lint/DuplicateMethods def test_should_allow_stubbing_existing_public_class_method Mocha.configure { |c| c.stubbing_non_existent_method = :prevent } klass = Class.new do @@ -153,5 +152,4 @@ def existing_private_method; end end assert_passed(test_result) end - # rubocop:enable Lint/DuplicateMethods end diff --git a/test/acceptance/stubbing_non_public_class_method_test.rb b/test/acceptance/stubbing_non_public_class_method_test.rb index 23b5114a..222ca0f5 100644 --- a/test/acceptance/stubbing_non_public_class_method_test.rb +++ b/test/acceptance/stubbing_non_public_class_method_test.rb @@ -12,7 +12,6 @@ def teardown teardown_acceptance_test end - # rubocop:disable Lint/DuplicateMethods def test_should_allow_stubbing_private_class_method Mocha.configure { |c| c.stubbing_non_public_method = :allow } klass = Class.new do @@ -144,7 +143,6 @@ def public_method; end end assert_passed(test_result) end - # rubocop:enable Lint/DuplicateMethods def test_should_allow_stubbing_method_to_which_class_responds Mocha.configure { |c| c.stubbing_non_public_method = :prevent } diff --git a/test/test_helper.rb b/test/test_helper.rb index 8002aba0..41e68ae3 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -12,11 +12,8 @@ begin require 'minitest' -# rubocop:disable Lint/HandleExceptions rescue LoadError end -# rubocop:enable Lint/HandleExceptions - module Mocha; end if (minitest_testcase = Mocha::Detection::Minitest.testcase) && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit') diff --git a/test/unit/date_time_inspect_test.rb b/test/unit/date_time_inspect_test.rb index 90373699..dc083387 100644 --- a/test/unit/date_time_inspect_test.rb +++ b/test/unit/date_time_inspect_test.rb @@ -13,7 +13,7 @@ def test_should_use_to_s_for_date end def test_should_use_to_s_for_datetime - datetime = DateTime.new(2006, 1, 1) # rubocop:disable Style/DateTime + datetime = DateTime.new(2006, 1, 1) assert_equal datetime.to_s, datetime.mocha_inspect end end diff --git a/test/unit/parameter_matchers/positional_or_keyword_hash_test.rb b/test/unit/parameter_matchers/positional_or_keyword_hash_test.rb index 14dc2a25..dd261824 100644 --- a/test/unit/parameter_matchers/positional_or_keyword_hash_test.rb +++ b/test/unit/parameter_matchers/positional_or_keyword_hash_test.rb @@ -41,28 +41,28 @@ def test_should_not_match_hash_arg_with_different_hash_arg end def test_should_match_keyword_args_with_keyword_args - matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })) # rubocop:disable Style/BracesAroundHashParameters - assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })) + assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) end def test_should_not_match_keyword_args_with_different_keyword_args - matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1 })) # rubocop:disable Style/BracesAroundHashParameters - assert !matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1 })) + assert !matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) end def test_should_match_keyword_args_with_matchers_using_keyword_args - matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: is_a(String), key_2: is_a(Integer) })) # rubocop:disable Style/BracesAroundHashParameters - assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 'foo', key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: is_a(String), key_2: is_a(Integer) })) + assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 'foo', key_2: 2 })]) end def test_should_not_match_keyword_args_with_matchers_using_keyword_args_when_not_all_entries_are_matched - matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: is_a(String) })) # rubocop:disable Style/BracesAroundHashParameters - assert !matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 'foo', key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: is_a(String) })) + assert !matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 'foo', key_2: 2 })]) end def test_should_match_hash_arg_with_keyword_args_but_display_deprecation_warning_if_appropriate expectation = Mocha::Expectation.new(self, :foo) - matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 }), expectation) # rubocop:disable Style/BracesAroundHashParameters + matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 }), expectation) DeprecationDisabler.disable_deprecations do assert matcher.matches?([{ key_1: 1, key_2: 2 }]) end @@ -80,7 +80,7 @@ def test_should_match_keyword_args_with_hash_arg_but_display_deprecation_warning expectation = Mocha::Expectation.new(self, :foo) matcher = build_matcher({ key_1: 1, key_2: 2 }, expectation) DeprecationDisabler.disable_deprecations do - assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) end return unless Mocha::RUBY_V27_PLUS @@ -118,14 +118,14 @@ def test_should_match_hash_arg_with_hash_arg_when_strict_keyword_args_is_enabled end def test_should_match_keyword_args_with_keyword_args_when_strict_keyword_args_is_enabled - matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })) # rubocop:disable Style/BracesAroundHashParameters + matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })) Mocha::Configuration.override(strict_keyword_argument_matching: true) do - assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) end end def test_should_not_match_hash_arg_with_keyword_args_when_strict_keyword_args_is_enabled - matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })) # rubocop:disable Style/BracesAroundHashParameters + matcher = build_matcher(Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })) Mocha::Configuration.override(strict_keyword_argument_matching: true) do assert !matcher.matches?([{ key_1: 1, key_2: 2 }]) end @@ -135,7 +135,7 @@ def test_should_not_match_keyword_args_with_hash_arg_when_strict_keyword_args_is hash = { key_1: 1, key_2: 2 } matcher = build_matcher(hash) Mocha::Configuration.override(strict_keyword_argument_matching: true) do - assert !matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + assert !matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) end end @@ -143,7 +143,7 @@ def test_should_display_deprecation_warning_even_if_parent_expectation_is_nil expectation = nil matcher = build_matcher({ key_1: 1, key_2: 2 }, expectation) DeprecationDisabler.disable_deprecations do - matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters + matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) end message = Mocha::Deprecation.messages.last From 0fe6076b96ff22d7c2c7cde13b1b510f71508b9f Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 11/36] Auto-correct Style/ClassEqualityComparison violation --- .rubocop_todo.yml | 8 -------- lib/mocha/stubbed_method.rb | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a6eb564a..b4ea3dbc 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -98,14 +98,6 @@ Metrics/PerceivedComplexity: Naming/VariableNumber: Enabled: false -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AllowedMethods, AllowedPatterns. -# AllowedMethods: ==, equal?, eql? -Style/ClassEqualityComparison: - Exclude: - - 'lib/mocha/stubbed_method.rb' - # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). Style/CombinableLoops: diff --git a/lib/mocha/stubbed_method.rb b/lib/mocha/stubbed_method.rb index 04992b1a..bb5e831b 100644 --- a/lib/mocha/stubbed_method.rb +++ b/lib/mocha/stubbed_method.rb @@ -57,7 +57,7 @@ def remove_new_method end def matches?(other) - return false unless other.class == self.class + return false unless other.instance_of?(self.class) (stubbee.object_id == other.stubbee.object_id) && (method_name == other.method_name) end From 19c1ca8a21a57ccbdfb6eb2d05069dc14c8f490a Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 12/36] Auto-correct Style/CombinableLoops violations --- .rubocop_todo.yml | 6 ------ test/unit/mock_test.rb | 12 ++++++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index b4ea3dbc..680870fc 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -98,12 +98,6 @@ Metrics/PerceivedComplexity: Naming/VariableNumber: Enabled: false -# Offense count: 2 -# This cop supports unsafe autocorrection (--autocorrect-all). -Style/CombinableLoops: - Exclude: - - 'test/unit/mock_test.rb' - # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). Style/ExplicitBlockArgument: diff --git a/test/unit/mock_test.rb b/test/unit/mock_test.rb index d10e87f8..ef9a009e 100644 --- a/test/unit/mock_test.rb +++ b/test/unit/mock_test.rb @@ -64,15 +64,19 @@ def test_should_be_equal def test_should_be_able_to_mock_standard_object_methods mock = build_mock - OBJECT_METHODS.each { |method| mock.__expects__(method.to_sym).returns(method) } - OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) } + OBJECT_METHODS.each do |method| + mock.__expects__(method.to_sym).returns(method) + assert_equal method, mock.__send__(method.to_sym) + end assert mock.__verified__? end def test_should_be_able_to_stub_standard_object_methods mock = build_mock - OBJECT_METHODS.each { |method| mock.__stubs__(method.to_sym).returns(method) } - OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) } + OBJECT_METHODS.each do |method| + mock.__stubs__(method.to_sym).returns(method) + assert_equal method, mock.__send__(method.to_sym) + end end def test_should_create_and_add_expectations From b1f9ff15620b27632311192255d6f714905a9716 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 13/36] Auto-correct Style/ExplicitBlockArgument violation I had to tweak the callsites for `ArgumentIterator#each` to make this work. Also I chose to change the code in the `else` branch in `ArgumentIterator#each` to use the explicit block argument for consistency. --- .rubocop_todo.yml | 6 ------ lib/mocha/argument_iterator.rb | 8 +++----- lib/mocha/mock.rb | 6 ++---- lib/mocha/object_methods.rb | 6 ++---- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 680870fc..e151f0b0 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -98,12 +98,6 @@ Metrics/PerceivedComplexity: Naming/VariableNumber: Enabled: false -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Style/ExplicitBlockArgument: - Exclude: - - 'lib/mocha/argument_iterator.rb' - # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowedVars. diff --git a/lib/mocha/argument_iterator.rb b/lib/mocha/argument_iterator.rb index 8bca04a4..50eb95d9 100644 --- a/lib/mocha/argument_iterator.rb +++ b/lib/mocha/argument_iterator.rb @@ -4,13 +4,11 @@ def initialize(argument) @argument = argument end - def each + def each(&block) if @argument.is_a?(Hash) - @argument.each do |method_name, return_value| - yield method_name, return_value - end + @argument.each(&block) else - yield @argument + block.call(@argument) end end end diff --git a/lib/mocha/mock.rb b/lib/mocha/mock.rb index fc37494f..374fdca5 100644 --- a/lib/mocha/mock.rb +++ b/lib/mocha/mock.rb @@ -114,8 +114,7 @@ class Mock def expects(method_name_or_hash, backtrace = nil) expectation = nil iterator = ArgumentIterator.new(method_name_or_hash) - iterator.each do |*args| - method_name = args.shift + iterator.each do |method_name, *args| ensure_method_not_already_defined(method_name) expectation = Expectation.new(self, method_name, backtrace) expectation.in_sequence(@mockery.sequences.last) if @mockery.sequences.any? @@ -153,8 +152,7 @@ def expects(method_name_or_hash, backtrace = nil) def stubs(method_name_or_hash, backtrace = nil) expectation = nil iterator = ArgumentIterator.new(method_name_or_hash) - iterator.each do |*args| - method_name = args.shift + iterator.each do |method_name, *args| ensure_method_not_already_defined(method_name) expectation = Expectation.new(self, method_name, backtrace) expectation.at_least(0) diff --git a/lib/mocha/object_methods.rb b/lib/mocha/object_methods.rb index 269cdb60..8f153ce6 100644 --- a/lib/mocha/object_methods.rb +++ b/lib/mocha/object_methods.rb @@ -79,8 +79,7 @@ def expects(expected_methods_vs_return_values) expectation = nil mockery = Mocha::Mockery.instance iterator = ArgumentIterator.new(expected_methods_vs_return_values) - iterator.each do |*args| - method_name = args.shift + iterator.each do |method_name, *args| mockery.on_stubbing(self, method_name) method = stubba_method.new(stubba_object, method_name) mockery.stubba.stub(method) @@ -126,8 +125,7 @@ def stubs(stubbed_methods_vs_return_values) expectation = nil mockery = Mocha::Mockery.instance iterator = ArgumentIterator.new(stubbed_methods_vs_return_values) - iterator.each do |*args| - method_name = args.shift + iterator.each do |method_name, *args| mockery.on_stubbing(self, method_name) method = stubba_method.new(stubba_object, method_name) mockery.stubba.stub(method) From ec3f2abac2177c92eb5e7a2b6b6e65d5cb608cf4 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 14/36] Auto-correct Style/MutableConstant violations --- .rubocop_todo.yml | 8 -------- test/minitest_result_pre_v5.rb | 8 ++++---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e151f0b0..6d299d32 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -105,14 +105,6 @@ Style/FetchEnvVar: Exclude: - 'Rakefile' -# Offense count: 4 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: literals, strict -Style/MutableConstant: - Exclude: - - 'test/minitest_result_pre_v5.rb' - # Offense count: 24 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? diff --git a/test/minitest_result_pre_v5.rb b/test/minitest_result_pre_v5.rb index c7fc362f..4b408998 100644 --- a/test/minitest_result_pre_v5.rb +++ b/test/minitest_result_pre_v5.rb @@ -4,12 +4,12 @@ class MinitestResult minitest_version = Gem::Version.new(Mocha::Detection::Minitest.version) if Gem::Requirement.new('<= 4.6.1').satisfied_by?(minitest_version) - FAILURE_PATTERN = /(Failure)\:\n([^\(]+)\(([^\)]+)\) \[([^\]]+)\]\:\n(.*)\n/m - ERROR_PATTERN = /(Error)\:\n([^\(]+)\(([^\)]+)\)\:\n(.+?)\n/m + FAILURE_PATTERN = /(Failure)\:\n([^\(]+)\(([^\)]+)\) \[([^\]]+)\]\:\n(.*)\n/m.freeze + ERROR_PATTERN = /(Error)\:\n([^\(]+)\(([^\)]+)\)\:\n(.+?)\n/m.freeze PATTERN_INDICES = { method: 2, testcase: 3 }.freeze else - FAILURE_PATTERN = /(Failure)\:\n.([^#]+)\#([^ ]+) \[([^\]]+)\]\:\n(.*)\n/m - ERROR_PATTERN = /(Error)\:\n.([^#]+)\#([^ ]+)\:\n(.+?)\n/m + FAILURE_PATTERN = /(Failure)\:\n.([^#]+)\#([^ ]+) \[([^\]]+)\]\:\n(.*)\n/m.freeze + ERROR_PATTERN = /(Error)\:\n.([^#]+)\#([^ ]+)\:\n(.+?)\n/m.freeze PATTERN_INDICES = { method: 3, testcase: 2 }.freeze end From a127b95811d1cfecb223261857030474e7764865 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 15/36] Auto-correct Style/RedundantRegexpEscape violations --- .rubocop_todo.yml | 6 ------ test/minitest_result_pre_v5.rb | 8 ++++---- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6d299d32..93d584ba 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -130,12 +130,6 @@ Style/RedundantDoubleSplatHashBraces: Exclude: - 'test/acceptance/keyword_argument_matching_test.rb' -# Offense count: 8 -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantRegexpEscape: - Exclude: - - 'test/minitest_result_pre_v5.rb' - # Offense count: 2 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowMultipleReturnValues. diff --git a/test/minitest_result_pre_v5.rb b/test/minitest_result_pre_v5.rb index 4b408998..665cf1f8 100644 --- a/test/minitest_result_pre_v5.rb +++ b/test/minitest_result_pre_v5.rb @@ -4,12 +4,12 @@ class MinitestResult minitest_version = Gem::Version.new(Mocha::Detection::Minitest.version) if Gem::Requirement.new('<= 4.6.1').satisfied_by?(minitest_version) - FAILURE_PATTERN = /(Failure)\:\n([^\(]+)\(([^\)]+)\) \[([^\]]+)\]\:\n(.*)\n/m.freeze - ERROR_PATTERN = /(Error)\:\n([^\(]+)\(([^\)]+)\)\:\n(.+?)\n/m.freeze + FAILURE_PATTERN = /(Failure):\n([^\(]+)\(([^\)]+)\) \[([^\]]+)\]:\n(.*)\n/m.freeze + ERROR_PATTERN = /(Error):\n([^\(]+)\(([^\)]+)\):\n(.+?)\n/m.freeze PATTERN_INDICES = { method: 2, testcase: 3 }.freeze else - FAILURE_PATTERN = /(Failure)\:\n.([^#]+)\#([^ ]+) \[([^\]]+)\]\:\n(.*)\n/m.freeze - ERROR_PATTERN = /(Error)\:\n.([^#]+)\#([^ ]+)\:\n(.+?)\n/m.freeze + FAILURE_PATTERN = /(Failure):\n.([^#]+)\#([^ ]+) \[([^\]]+)\]:\n(.*)\n/m.freeze + ERROR_PATTERN = /(Error):\n.([^#]+)\#([^ ]+):\n(.+?)\n/m.freeze PATTERN_INDICES = { method: 3, testcase: 2 }.freeze end From 5cf3b9a829c207402d7b940ad4eb98d78b3c85e2 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 16/36] Auto-correct Style/RedundantReturn violations --- .rubocop_todo.yml | 7 ------- lib/mocha/parameter_matchers/includes.rb | 6 ++---- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 93d584ba..cc1150b9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -130,13 +130,6 @@ Style/RedundantDoubleSplatHashBraces: Exclude: - 'test/acceptance/keyword_argument_matching_test.rb' -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowMultipleReturnValues. -Style/RedundantReturn: - Exclude: - - 'lib/mocha/parameter_matchers/includes.rb' - # Offense count: 5 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Mode. diff --git a/lib/mocha/parameter_matchers/includes.rb b/lib/mocha/parameter_matchers/includes.rb index 842d3a32..d730566c 100644 --- a/lib/mocha/parameter_matchers/includes.rb +++ b/lib/mocha/parameter_matchers/includes.rb @@ -77,14 +77,12 @@ def matches?(available_parameters) return false unless parameter.respond_to?(:include?) if @items.size == 1 - # rubocop:disable Style/GuardClause if parameter.respond_to?(:any?) && !parameter.is_a?(String) parameter = parameter.keys if parameter.is_a?(Hash) - return parameter.any? { |p| @items.first.to_matcher.matches?([p]) } + parameter.any? { |p| @items.first.to_matcher.matches?([p]) } else - return parameter.include?(@items.first) + parameter.include?(@items.first) end - # rubocop:enable Style/GuardClause else includes_matchers = @items.map { |item| Includes.new(item) } AllOf.new(*includes_matchers).matches?([parameter]) From ca973d0e88117d6f9140b72e6be80dc003ee8d7b Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 18:46:54 +0000 Subject: [PATCH 17/36] Auto-correct Style/StringConcatenation violations --- .rubocop_todo.yml | 8 -------- test/acceptance/prepend_test.rb | 4 ++-- test/unit/backtrace_filter_test.rb | 2 +- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index cc1150b9..c53c6885 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -130,14 +130,6 @@ Style/RedundantDoubleSplatHashBraces: Exclude: - 'test/acceptance/keyword_argument_matching_test.rb' -# Offense count: 5 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: Mode. -Style/StringConcatenation: - Exclude: - - 'test/acceptance/prepend_test.rb' - - 'test/unit/backtrace_filter_test.rb' - # Offense count: 68 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. diff --git a/test/acceptance/prepend_test.rb b/test/acceptance/prepend_test.rb index 03216d61..ebfbdb6a 100644 --- a/test/acceptance/prepend_test.rb +++ b/test/acceptance/prepend_test.rb @@ -14,13 +14,13 @@ def teardown module Mod1 def my_method - super + ' World' + "#{super} World" end end module Mod2 def my_method - super + ' Wide' + "#{super} Wide" end end diff --git a/test/unit/backtrace_filter_test.rb b/test/unit/backtrace_filter_test.rb index 40afdf7b..e9ea926e 100644 --- a/test/unit/backtrace_filter_test.rb +++ b/test/unit/backtrace_filter_test.rb @@ -6,7 +6,7 @@ class BacktraceFilterTest < Mocha::TestCase def test_should_exclude_mocha_locations_from_backtrace mocha_lib = '/username/workspace/mocha_wibble/lib/' - backtrace = [mocha_lib + 'exclude/me/1', mocha_lib + 'exclude/me/2', '/keep/me', mocha_lib + 'exclude/me/3'] + backtrace = ["#{mocha_lib}exclude/me/1", "#{mocha_lib}exclude/me/2", '/keep/me', "#{mocha_lib}exclude/me/3"] filter = BacktraceFilter.new(mocha_lib) assert_equal ['/keep/me'], filter.filtered(backtrace) end From 236eae7456c7409d9c0c82c2412d71c388fc9deb Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 22:15:57 +0000 Subject: [PATCH 18/36] Move trailing slash out of lib directory string I think this makes the interpolation in the backtrace strings easier to read. --- test/unit/backtrace_filter_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/backtrace_filter_test.rb b/test/unit/backtrace_filter_test.rb index e9ea926e..6f024a62 100644 --- a/test/unit/backtrace_filter_test.rb +++ b/test/unit/backtrace_filter_test.rb @@ -5,8 +5,8 @@ class BacktraceFilterTest < Mocha::TestCase include Mocha def test_should_exclude_mocha_locations_from_backtrace - mocha_lib = '/username/workspace/mocha_wibble/lib/' - backtrace = ["#{mocha_lib}exclude/me/1", "#{mocha_lib}exclude/me/2", '/keep/me', "#{mocha_lib}exclude/me/3"] + mocha_lib = '/username/workspace/mocha_wibble/lib' + backtrace = ["#{mocha_lib}/exclude/me/1", "#{mocha_lib}/exclude/me/2", '/keep/me', "#{mocha_lib}/exclude/me/3"] filter = BacktraceFilter.new(mocha_lib) assert_equal ['/keep/me'], filter.filtered(backtrace) end @@ -16,9 +16,9 @@ def test_should_determine_path_for_mocha_lib_directory end def test_should_handle_special_characters - lib_directory = '/tmp/bundle/ruby/3.2.0+3/gems/mocha-2.0.2/lib/' + lib_directory = '/tmp/bundle/ruby/3.2.0+3/gems/mocha-2.0.2/lib' filter = BacktraceFilter.new(lib_directory) - backtrace = ['/keep/me', "#{lib_directory}mocha/deprecation.rb"] + backtrace = ['/keep/me', "#{lib_directory}/mocha/deprecation.rb"] assert_equal ['/keep/me'], filter.filtered(backtrace) end end From 8a10d2ba8a0738cb4bfb8e2a27d549febe9581be Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 22:31:17 +0000 Subject: [PATCH 19/36] Re-genenerate rubocop to-do list --- .rubocop_todo.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c53c6885..d21c023f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-12-24 18:41:27 UTC using RuboCop version 1.69.2. +# on 2024-12-24 22:31:06 UTC using RuboCop version 1.69.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -81,12 +81,12 @@ Metrics/ClassLength: Metrics/CyclomaticComplexity: Max: 11 -# Offense count: 200 +# Offense count: 199 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 27 -# Offense count: 1 +# Offense count: 3 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: Max: 13 From 52e93acff71f296304a3a3e882c2f82a14e6791e Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 22:48:30 +0000 Subject: [PATCH 20/36] Use kwarg for optional boolean `instantiate` arg This fixes a number of `Style/OptionalBooleanParameter` violations and so I have re-generated the rubocop to-do list. --- .rubocop_todo.yml | 5 ++--- lib/mocha/class_methods.rb | 2 +- lib/mocha/object_methods.rb | 2 +- lib/mocha/receivers.rb | 4 ++-- test/unit/class_methods_test.rb | 4 ++-- test/unit/object_methods_test.rb | 4 ++-- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d21c023f..268df62c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-12-24 22:31:06 UTC using RuboCop version 1.69.2. +# on 2024-12-24 22:47:54 UTC using RuboCop version 1.69.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -105,14 +105,13 @@ Style/FetchEnvVar: Exclude: - 'Rakefile' -# Offense count: 24 +# Offense count: 22 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: Exclude: - 'lib/mocha/class_methods.rb' - 'lib/mocha/inspect.rb' - - 'lib/mocha/object_methods.rb' - 'test/acceptance/stub_any_instance_method_test.rb' - 'test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb' - 'test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb' diff --git a/lib/mocha/class_methods.rb b/lib/mocha/class_methods.rb index 735e190c..aa3eebe2 100644 --- a/lib/mocha/class_methods.rb +++ b/lib/mocha/class_methods.rb @@ -10,7 +10,7 @@ def initialize(klass) @stubba_object = klass end - def mocha(instantiate = true) + def mocha(instantiate: true) if instantiate @mocha ||= Mocha::Mockery.instance.mock_impersonating_any_instance_of(@stubba_object) else diff --git a/lib/mocha/object_methods.rb b/lib/mocha/object_methods.rb index 8f153ce6..487ac2c2 100644 --- a/lib/mocha/object_methods.rb +++ b/lib/mocha/object_methods.rb @@ -12,7 +12,7 @@ module ObjectMethods alias_method :_method, :method # @private - def mocha(instantiate = true) + def mocha(instantiate: true) if instantiate @mocha ||= Mocha::Mockery.instance.mock_impersonating(self) else diff --git a/lib/mocha/receivers.rb b/lib/mocha/receivers.rb index f98e2781..f0159904 100644 --- a/lib/mocha/receivers.rb +++ b/lib/mocha/receivers.rb @@ -8,7 +8,7 @@ def mocks object = @object mocks = [] while object - mocha = object.mocha(false) + mocha = object.mocha(instantiate: false) mocks << mocha if mocha object = object.is_a?(Class) ? object.superclass : nil end @@ -25,7 +25,7 @@ def mocks klass = @klass mocks = [] while klass - mocha = klass.any_instance.mocha(false) + mocha = klass.any_instance.mocha(instantiate: false) mocks << mocha if mocha klass = klass.superclass end diff --git a/test/unit/class_methods_test.rb b/test/unit/class_methods_test.rb index 298470f5..5fa02884 100644 --- a/test/unit/class_methods_test.rb +++ b/test/unit/class_methods_test.rb @@ -35,7 +35,7 @@ def test_any_instance_should_build_mocha_referring_to_klass end def test_any_instance_should_not_build_mocha_if_instantiate_is_false - assert_nil @klass.any_instance.mocha(false) + assert_nil @klass.any_instance.mocha(instantiate: false) end def test_any_instance_should_reuse_existing_mocha @@ -46,7 +46,7 @@ def test_any_instance_should_reuse_existing_mocha def test_any_instance_should_reuse_existing_mocha_even_if_instantiate_is_false mocha1 = @klass.any_instance.mocha - mocha2 = @klass.any_instance.mocha(false) + mocha2 = @klass.any_instance.mocha(instantiate: false) assert_equal mocha1, mocha2 end diff --git a/test/unit/object_methods_test.rb b/test/unit/object_methods_test.rb index 13b603a0..3af7a688 100644 --- a/test/unit/object_methods_test.rb +++ b/test/unit/object_methods_test.rb @@ -24,7 +24,7 @@ def test_should_build_mocha_referring_to_self end def test_should_not_build_mocha_if_instantiate_is_false - assert_nil @object.mocha(false) + assert_nil @object.mocha(instantiate: false) end def test_should_reuse_existing_mocha @@ -35,7 +35,7 @@ def test_should_reuse_existing_mocha def test_should_reuse_existing_mocha_even_if_instantiate_is_false mocha1 = @object.mocha - mocha2 = @object.mocha(false) + mocha2 = @object.mocha(instantiate: false) assert_equal mocha1, mocha2 end From 1ea3d1727824ea85af63d560195a258300942d90 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 22:48:30 +0000 Subject: [PATCH 21/36] Use kwarg for optional boolean `include_public_methods` arg This fixes a `Style/OptionalBooleanParameter` violation and so I have re-generated the rubocop to-do list. --- .rubocop_todo.yml | 4 ++-- lib/mocha/class_methods.rb | 2 +- lib/mocha/mockery.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 268df62c..7fbf2ada 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-12-24 22:47:54 UTC using RuboCop version 1.69.2. +# on 2024-12-24 22:52:55 UTC using RuboCop version 1.69.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -105,7 +105,7 @@ Style/FetchEnvVar: Exclude: - 'Rakefile' -# Offense count: 22 +# Offense count: 21 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: diff --git a/lib/mocha/class_methods.rb b/lib/mocha/class_methods.rb index aa3eebe2..05669fa7 100644 --- a/lib/mocha/class_methods.rb +++ b/lib/mocha/class_methods.rb @@ -51,7 +51,7 @@ def any_instance end # @private - def __method_visibility__(method, include_public_methods = true) + def __method_visibility__(method, include_public_methods: true) (include_public_methods && public_method_defined?(method) && :public) || (protected_method_defined?(method) && :protected) || (private_method_defined?(method) && :private) diff --git a/lib/mocha/mockery.rb b/lib/mocha/mockery.rb index 2ae49a0f..31839a74 100644 --- a/lib/mocha/mockery.rb +++ b/lib/mocha/mockery.rb @@ -124,10 +124,10 @@ def mocha_inspect def on_stubbing(object, method) signature_proc = lambda { "#{object.mocha_inspect}.#{method}" } check(:stubbing_non_existent_method, 'non-existent method', signature_proc) do - !(object.stubba_class.__method_exists__?(method, true) || object.respond_to?(method)) + !(object.stubba_class.__method_exists__?(method) || object.respond_to?(method)) end check(:stubbing_non_public_method, 'non-public method', signature_proc) do - object.stubba_class.__method_exists__?(method, false) + object.stubba_class.__method_exists__?(method, include_public_methods: false) end check(:stubbing_method_on_non_mock_object, 'method on non-mock object', signature_proc) end From 51922ea5148aa896982ad3c00b777af75a3b8f2a Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 22:48:30 +0000 Subject: [PATCH 22/36] Use kwarg for optional boolean `wrapped` arg This fixes a `Style/OptionalBooleanParameter` violation and so I have re-generated the rubocop to-do list. --- .rubocop_todo.yml | 5 ++--- lib/mocha/inspect.rb | 2 +- lib/mocha/parameter_matchers/has_keys.rb | 2 +- test/unit/array_inspect_test.rb | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 7fbf2ada..c2cb141b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-12-24 22:52:55 UTC using RuboCop version 1.69.2. +# on 2024-12-24 23:02:01 UTC using RuboCop version 1.69.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -105,13 +105,12 @@ Style/FetchEnvVar: Exclude: - 'Rakefile' -# Offense count: 21 +# Offense count: 20 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: Exclude: - 'lib/mocha/class_methods.rb' - - 'lib/mocha/inspect.rb' - 'test/acceptance/stub_any_instance_method_test.rb' - 'test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb' - 'test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb' diff --git a/lib/mocha/inspect.rb b/lib/mocha/inspect.rb index 469f3b3f..246fe8b8 100755 --- a/lib/mocha/inspect.rb +++ b/lib/mocha/inspect.rb @@ -11,7 +11,7 @@ def mocha_inspect end module ArrayMethods - def mocha_inspect(wrapped = true) + def mocha_inspect(wrapped: true) unwrapped = collect(&:mocha_inspect).join(', ') wrapped ? "[#{unwrapped}]" : unwrapped end diff --git a/lib/mocha/parameter_matchers/has_keys.rb b/lib/mocha/parameter_matchers/has_keys.rb index 9e17f107..6b09124d 100644 --- a/lib/mocha/parameter_matchers/has_keys.rb +++ b/lib/mocha/parameter_matchers/has_keys.rb @@ -46,7 +46,7 @@ def matches?(available_parameters) # @private def mocha_inspect - "has_keys(#{@keys.mocha_inspect(false)})" + "has_keys(#{@keys.mocha_inspect(wrapped: false)})" end end end diff --git a/test/unit/array_inspect_test.rb b/test/unit/array_inspect_test.rb index b53cc453..4159caaf 100644 --- a/test/unit/array_inspect_test.rb +++ b/test/unit/array_inspect_test.rb @@ -9,7 +9,7 @@ def test_should_return_string_representation_of_array def test_should_return_unwrapped_array_when_wrapped_is_false array = [1, 2] - assert_equal '1, 2', array.mocha_inspect(false) + assert_equal '1, 2', array.mocha_inspect(wrapped: false) end def test_should_use_mocha_inspect_on_each_item From 54766b1dd0066adb25fadc34921b69415e6b0faa Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 22:48:30 +0000 Subject: [PATCH 23/36] Use kwarg for optional boolean `satisfied` arg This fixes a `Style/OptionalBooleanParameter` violation and so I have re-generated the rubocop to-do list. --- .rubocop_todo.yml | 5 ++--- test/unit/sequence_test.rb | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c2cb141b..326164f5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-12-24 23:02:01 UTC using RuboCop version 1.69.2. +# on 2024-12-24 23:06:22 UTC using RuboCop version 1.69.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -105,7 +105,7 @@ Style/FetchEnvVar: Exclude: - 'Rakefile' -# Offense count: 20 +# Offense count: 19 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: @@ -120,7 +120,6 @@ Style/OptionalBooleanParameter: - 'test/acceptance/stubbing_non_existent_instance_method_test.rb' - 'test/acceptance/stubbing_non_public_class_method_test.rb' - 'test/acceptance/stubbing_non_public_instance_method_test.rb' - - 'test/unit/sequence_test.rb' # Offense count: 7 # This cop supports safe autocorrection (--autocorrect). diff --git a/test/unit/sequence_test.rb b/test/unit/sequence_test.rb index 29e0bc93..6c2aadfd 100644 --- a/test/unit/sequence_test.rb +++ b/test/unit/sequence_test.rb @@ -8,7 +8,7 @@ class SequenceTest < Mocha::TestCase class FakeExpectation attr_reader :ordering_constraints - def initialize(satisfied = false) + def initialize(satisfied: false) @satisfied = satisfied @ordering_constraints = [] end @@ -29,29 +29,29 @@ def test_should_be_satisfied_if_no_expectations_added def test_should_be_satisfied_if_one_unsatisfied_expectations_added_but_it_is_not_included_by_index sequence = Sequence.new('name') - expectation = FakeExpectation.new(false) + expectation = FakeExpectation.new(satisfied: false) sequence.constrain_as_next_in_sequence(expectation) assert sequence.satisfied_to_index?(0) end def test_should_not_be_satisfied_if_one_unsatisfied_expectations_added_and_it_is_included_by_index sequence = Sequence.new('name') - expectation = FakeExpectation.new(false) + expectation = FakeExpectation.new(satisfied: false) sequence.constrain_as_next_in_sequence(expectation) assert !sequence.satisfied_to_index?(1) end def test_should_be_satisfied_if_one_satisfied_expectations_added_and_it_is_included_by_index sequence = Sequence.new('name') - expectation = FakeExpectation.new(true) + expectation = FakeExpectation.new(satisfied: true) sequence.constrain_as_next_in_sequence(expectation) assert sequence.satisfied_to_index?(1) end def test_should_not_be_satisfied_if_one_satisfied_and_one_unsatisfied_expectation_added_and_both_are_included_by_index sequence = Sequence.new('name') - expectation_one = FakeExpectation.new(true) - expectation_two = FakeExpectation.new(false) + expectation_one = FakeExpectation.new(satisfied: true) + expectation_two = FakeExpectation.new(satisfied: false) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert !sequence.satisfied_to_index?(2) @@ -59,8 +59,8 @@ def test_should_not_be_satisfied_if_one_satisfied_and_one_unsatisfied_expectatio def test_should_be_satisfied_if_two_satisfied_expectations_added_and_both_are_included_by_index sequence = Sequence.new('name') - expectation_one = FakeExpectation.new(true) - expectation_two = FakeExpectation.new(true) + expectation_one = FakeExpectation.new(satisfied: true) + expectation_two = FakeExpectation.new(satisfied: true) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert sequence.satisfied_to_index?(2) @@ -75,8 +75,8 @@ def test_should_add_ordering_constraint_to_expectation def test_should_not_allow_invocation_of_second_method_when_first_n_sequence_has_not_been_invoked sequence = Sequence.new('name') - expectation_one = FakeExpectation.new(false) - expectation_two = FakeExpectation.new(false) + expectation_one = FakeExpectation.new(satisfied: false) + expectation_two = FakeExpectation.new(satisfied: false) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert !expectation_two.ordering_constraints[0].allows_invocation_now? @@ -84,8 +84,8 @@ def test_should_not_allow_invocation_of_second_method_when_first_n_sequence_has_ def test_should_allow_invocation_of_second_method_when_first_in_sequence_has_been_invoked sequence = Sequence.new('name') - expectation_one = FakeExpectation.new(true) - expectation_two = FakeExpectation.new(false) + expectation_one = FakeExpectation.new(satisfied: true) + expectation_two = FakeExpectation.new(satisfied: false) sequence.constrain_as_next_in_sequence(expectation_one) sequence.constrain_as_next_in_sequence(expectation_two) assert expectation_two.ordering_constraints[0].allows_invocation_now? From 1fb0ee3b7018a0b5ca863efe08b13fa6dbc0a51d Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 24 Dec 2024 23:18:07 +0000 Subject: [PATCH 24/36] Fix Style/RedundantDoubleSplatHashBraces violations --- .rubocop_todo.yml | 6 ------ .../keyword_argument_matching_test.rb | 20 ++++++++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 326164f5..1d624fdf 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -121,12 +121,6 @@ Style/OptionalBooleanParameter: - 'test/acceptance/stubbing_non_public_class_method_test.rb' - 'test/acceptance/stubbing_non_public_instance_method_test.rb' -# Offense count: 7 -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantDoubleSplatHashBraces: - Exclude: - - 'test/acceptance/keyword_argument_matching_test.rb' - # Offense count: 68 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. diff --git a/test/acceptance/keyword_argument_matching_test.rb b/test/acceptance/keyword_argument_matching_test.rb index 8949a422..5e1478a9 100644 --- a/test/acceptance/keyword_argument_matching_test.rb +++ b/test/acceptance/keyword_argument_matching_test.rb @@ -48,7 +48,8 @@ def test_should_not_match_hash_parameter_with_keyword_args_when_strict_keyword_m def test_should_match_hash_parameter_with_splatted_keyword_args test_result = run_as_test do mock = mock() - mock.expects(:method).with(**{ key: 42 }); execution_point = ExecutionPoint.current + kwargs = { key: 42 } + mock.expects(:method).with(**kwargs); execution_point = ExecutionPoint.current DeprecationDisabler.disable_deprecations do mock.method({ key: 42 }) end @@ -65,7 +66,8 @@ def test_should_match_hash_parameter_with_splatted_keyword_args def test_should_not_match_hash_parameter_with_splatted_keyword_args_when_strict_keyword_matching_is_enabled test_result = run_as_test do mock = mock() - mock.expects(:method).with(**{ key: 42 }) + kwargs = { key: 42 } + mock.expects(:method).with(**kwargs) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method({ key: 42 }) end @@ -78,7 +80,8 @@ def test_should_match_splatted_hash_parameter_with_keyword_args test_result = run_as_test do mock = mock() mock.expects(:method).with(key: 42) - mock.method(**{ key: 42 }) + kwargs = { key: 42 } + mock.method(**kwargs) end assert_passed(test_result) end @@ -86,8 +89,9 @@ def test_should_match_splatted_hash_parameter_with_keyword_args def test_should_match_splatted_hash_parameter_with_splatted_hash test_result = run_as_test do mock = mock() - mock.expects(:method).with(**{ key: 42 }) - mock.method(**{ key: 42 }) + kwargs = { key: 42 } + mock.expects(:method).with(**kwargs) + mock.method(**kwargs) end assert_passed(test_result) end @@ -172,7 +176,8 @@ def test_should_match_splatted_hash_parameter_with_hash_matcher test_result = run_as_test do mock = mock() mock.expects(:method).with(has_key(:key)) - mock.method(**{ key: 42 }) + kwargs = { key: 42 } + mock.method(**kwargs) end assert_passed(test_result) end @@ -226,7 +231,8 @@ def test_should_match_last_positional_hash_with_hash_matcher def test_should_not_match_non_hash_args_with_keyword_args test_result = run_as_test do mock = mock() - mock.expects(:method).with(**{ key: 1 }) + kwargs = { key: 1 } + mock.expects(:method).with(**kwargs) Mocha::Configuration.override(strict_keyword_argument_matching: true) do mock.method([2]) end From 9c19b237bc295bf854c820be8d5d01c2f662b8af Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:01:16 +0000 Subject: [PATCH 25/36] Allow one Lint/IdentityComparison violation `InstanceMethodTest#test_should_match_if_other_instance_method_has_same_stubbee_and_same_method_but_stubbee_equal_method_lies_like_active_record_association_proxy` suggests that we need to retain the implementation which compares the `#object_id` of the two stubbees rather than using `#equal?`. It's possible this is no longer necessary with recent versions of ActiveRecord, but I'm going to leave this in place for now. --- .rubocop_todo.yml | 6 ------ lib/mocha/stubbed_method.rb | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 1d624fdf..341a0277 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -23,12 +23,6 @@ Lint/EmptyClass: - 'test/acceptance/failure_messages_test.rb' - 'test/unit/mockery_test.rb' -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Lint/IdentityComparison: - Exclude: - - 'lib/mocha/stubbed_method.rb' - # Offense count: 19 # Configuration parameters: AllowedParentClasses. Lint/MissingSuper: diff --git a/lib/mocha/stubbed_method.rb b/lib/mocha/stubbed_method.rb index bb5e831b..1f3fa350 100644 --- a/lib/mocha/stubbed_method.rb +++ b/lib/mocha/stubbed_method.rb @@ -59,7 +59,8 @@ def remove_new_method def matches?(other) return false unless other.instance_of?(self.class) - (stubbee.object_id == other.stubbee.object_id) && (method_name == other.method_name) + (stubbee.object_id == other.stubbee.object_id) && # rubocop:disable Lint/IdentityComparison + (method_name == other.method_name) end alias_method :==, :eql? From cc0fe38b0ad6ff2ca1a5aa71cc9aaec401563e65 Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:10:24 +0000 Subject: [PATCH 26/36] Auto-correct Lint/SendWithMixinArgument violations --- .rubocop_todo.yml | 6 ------ lib/mocha/api.rb | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 341a0277..2d3a3655 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -28,12 +28,6 @@ Lint/EmptyClass: Lint/MissingSuper: Enabled: false -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -Lint/SendWithMixinArgument: - Exclude: - - 'lib/mocha/api.rb' - # Offense count: 3 # Configuration parameters: AllowComments, AllowNil. Lint/SuppressedException: diff --git a/lib/mocha/api.rb b/lib/mocha/api.rb index 856f7733..a2347a14 100644 --- a/lib/mocha/api.rb +++ b/lib/mocha/api.rb @@ -37,8 +37,8 @@ module API # @private def self.included(_mod) - Object.send(:include, Mocha::ObjectMethods) - Class.send(:include, Mocha::ClassMethods) + Object.include Mocha::ObjectMethods + Class.include Mocha::ClassMethods end # @private From dabca5181fbb95013e24e9adc019df61c9734fff Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:10:24 +0000 Subject: [PATCH 27/36] Auto-correct Lint/SymbolConversion violations --- .rubocop_todo.yml | 8 -------- lib/mocha/configuration.rb | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2d3a3655..924ae404 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -36,14 +36,6 @@ Lint/SuppressedException: - 'lib/mocha/detection/test_unit.rb' - 'test/test_helper.rb' -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: strict, consistent -Lint/SymbolConversion: - Exclude: - - 'lib/mocha/configuration.rb' - # Offense count: 17 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AutoCorrect. diff --git a/lib/mocha/configuration.rb b/lib/mocha/configuration.rb index 107d3487..7108a6ee 100644 --- a/lib/mocha/configuration.rb +++ b/lib/mocha/configuration.rb @@ -313,7 +313,7 @@ def change_config(action, new_value, &block) if block_given? temporarily_change_config action, new_value, &block else - configuration.send("#{action}=".to_sym, new_value) + configuration.send(:"#{action}=", new_value) end end @@ -321,7 +321,7 @@ def change_config(action, new_value, &block) def temporarily_change_config(action, new_value) original_configuration = configuration new_configuration = configuration.dup - new_configuration.send("#{action}=".to_sym, new_value) + new_configuration.send(:"#{action}=", new_value) @configuration = new_configuration yield ensure From 8d428e04798b6f91b8b1aace209f119147cdb586 Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:15:17 +0000 Subject: [PATCH 28/36] Disable Lint/UselessTimes in tests It can be useful to violate this cop in tests in order to be more explicit --- .rubocop.yml | 5 +++++ .rubocop_todo.yml | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 6bcb4003..6a68689b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -68,3 +68,8 @@ Layout/LineLength: # It's not possible to set TargetRubyVersion to Ruby < v2.2 Gemspec/RequiredRubyVersion: Enabled: false + +# It can be useful to violate this cop in tests in order to be more explicit +Lint/UselessTimes: + Exclude: + - 'test/**/*.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 924ae404..ce165702 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -36,16 +36,6 @@ Lint/SuppressedException: - 'lib/mocha/detection/test_unit.rb' - 'test/test_helper.rb' -# Offense count: 17 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AutoCorrect. -Lint/UselessTimes: - Exclude: - - 'test/acceptance/expected_invocation_count_test.rb' - - 'test/acceptance/multiple_expectations_failure_message_test.rb' - - 'test/unit/expectation_test.rb' - - 'test/unit/mockery_test.rb' - # Offense count: 34 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: From cac3e6cfc7b1587fae4f5579e8e8cad239f63bfe Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:24:34 +0000 Subject: [PATCH 29/36] Fix Lint/MissingSuper violations Strictly speaking there's no need to call `super` from the constructors of all these `Mocha::ParameterMatchers::Base` subclasses, because the latter has no state and does not implement its own constructor. However, I can see that adding the calls to `super` make the code a bit more future-proof. I did also consider converting `Mocha::ParameterMatchers::Base` from a class into a module, but I couldn't immediately work out how to change the YARD documentation about how to implement a custom matcher, so I've gone with this less invasive change for now. --- .rubocop_todo.yml | 5 ----- lib/mocha/parameter_matchers/all_of.rb | 1 + lib/mocha/parameter_matchers/any_of.rb | 1 + lib/mocha/parameter_matchers/equals.rb | 1 + lib/mocha/parameter_matchers/equivalent_uri.rb | 1 + lib/mocha/parameter_matchers/has_entries.rb | 1 + lib/mocha/parameter_matchers/has_entry.rb | 1 + lib/mocha/parameter_matchers/has_key.rb | 1 + lib/mocha/parameter_matchers/has_keys.rb | 1 + lib/mocha/parameter_matchers/has_value.rb | 1 + lib/mocha/parameter_matchers/includes.rb | 1 + lib/mocha/parameter_matchers/instance_of.rb | 1 + lib/mocha/parameter_matchers/is_a.rb | 1 + lib/mocha/parameter_matchers/kind_of.rb | 1 + lib/mocha/parameter_matchers/not.rb | 1 + lib/mocha/parameter_matchers/optionally.rb | 1 + lib/mocha/parameter_matchers/positional_or_keyword_hash.rb | 1 + lib/mocha/parameter_matchers/regexp_matches.rb | 1 + lib/mocha/parameter_matchers/responds_with.rb | 1 + lib/mocha/parameter_matchers/yaml_equivalent.rb | 1 + 20 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ce165702..f0e28cad 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -23,11 +23,6 @@ Lint/EmptyClass: - 'test/acceptance/failure_messages_test.rb' - 'test/unit/mockery_test.rb' -# Offense count: 19 -# Configuration parameters: AllowedParentClasses. -Lint/MissingSuper: - Enabled: false - # Offense count: 3 # Configuration parameters: AllowComments, AllowNil. Lint/SuppressedException: diff --git a/lib/mocha/parameter_matchers/all_of.rb b/lib/mocha/parameter_matchers/all_of.rb index 98145f7a..35f19a81 100644 --- a/lib/mocha/parameter_matchers/all_of.rb +++ b/lib/mocha/parameter_matchers/all_of.rb @@ -28,6 +28,7 @@ def all_of(*matchers) class AllOf < Base # @private def initialize(*matchers) + super() @matchers = matchers end diff --git a/lib/mocha/parameter_matchers/any_of.rb b/lib/mocha/parameter_matchers/any_of.rb index fbe328e8..394250e7 100644 --- a/lib/mocha/parameter_matchers/any_of.rb +++ b/lib/mocha/parameter_matchers/any_of.rb @@ -34,6 +34,7 @@ def any_of(*matchers) class AnyOf < Base # @private def initialize(*matchers) + super() @matchers = matchers end diff --git a/lib/mocha/parameter_matchers/equals.rb b/lib/mocha/parameter_matchers/equals.rb index 8495b961..54053b23 100644 --- a/lib/mocha/parameter_matchers/equals.rb +++ b/lib/mocha/parameter_matchers/equals.rb @@ -29,6 +29,7 @@ def equals(value) class Equals < Base # @private def initialize(value) + super() @value = value end diff --git a/lib/mocha/parameter_matchers/equivalent_uri.rb b/lib/mocha/parameter_matchers/equivalent_uri.rb index 40db86ef..bbfc2847 100644 --- a/lib/mocha/parameter_matchers/equivalent_uri.rb +++ b/lib/mocha/parameter_matchers/equivalent_uri.rb @@ -30,6 +30,7 @@ def equivalent_uri(uri) class EquivalentUri < Base # @private def initialize(uri) + super() @uri = URI.parse(uri) end diff --git a/lib/mocha/parameter_matchers/has_entries.rb b/lib/mocha/parameter_matchers/has_entries.rb index 917ea712..8a04853d 100644 --- a/lib/mocha/parameter_matchers/has_entries.rb +++ b/lib/mocha/parameter_matchers/has_entries.rb @@ -31,6 +31,7 @@ def has_entries(entries) # rubocop:disable Naming/PredicateName class HasEntries < Base # @private def initialize(entries, exact: false) + super() @entries = entries @exact = exact end diff --git a/lib/mocha/parameter_matchers/has_entry.rb b/lib/mocha/parameter_matchers/has_entry.rb index 85d24a97..40a1026c 100644 --- a/lib/mocha/parameter_matchers/has_entry.rb +++ b/lib/mocha/parameter_matchers/has_entry.rb @@ -58,6 +58,7 @@ def has_entry(*options) # rubocop:disable Naming/PredicateName class HasEntry < Base # @private def initialize(key, value) + super() @key = key @value = value end diff --git a/lib/mocha/parameter_matchers/has_key.rb b/lib/mocha/parameter_matchers/has_key.rb index 712062bc..02d05678 100644 --- a/lib/mocha/parameter_matchers/has_key.rb +++ b/lib/mocha/parameter_matchers/has_key.rb @@ -29,6 +29,7 @@ def has_key(key) # rubocop:disable Naming/PredicateName class HasKey < Base # @private def initialize(key) + super() @key = key end diff --git a/lib/mocha/parameter_matchers/has_keys.rb b/lib/mocha/parameter_matchers/has_keys.rb index 6b09124d..561e8809 100644 --- a/lib/mocha/parameter_matchers/has_keys.rb +++ b/lib/mocha/parameter_matchers/has_keys.rb @@ -29,6 +29,7 @@ def has_keys(*keys) # rubocop:disable Naming/PredicateName class HasKeys < Base # @private def initialize(*keys) + super() raise ArgumentError, 'No arguments. Expecting at least one.' if keys.empty? @keys = keys diff --git a/lib/mocha/parameter_matchers/has_value.rb b/lib/mocha/parameter_matchers/has_value.rb index 4c358ada..40e2c33b 100644 --- a/lib/mocha/parameter_matchers/has_value.rb +++ b/lib/mocha/parameter_matchers/has_value.rb @@ -29,6 +29,7 @@ def has_value(value) # rubocop:disable Naming/PredicateName class HasValue < Base # @private def initialize(value) + super() @value = value end diff --git a/lib/mocha/parameter_matchers/includes.rb b/lib/mocha/parameter_matchers/includes.rb index d730566c..07857789 100644 --- a/lib/mocha/parameter_matchers/includes.rb +++ b/lib/mocha/parameter_matchers/includes.rb @@ -68,6 +68,7 @@ def includes(*items) class Includes < Base # @private def initialize(*items) + super() @items = items end diff --git a/lib/mocha/parameter_matchers/instance_of.rb b/lib/mocha/parameter_matchers/instance_of.rb index 82315a02..0baf86e2 100644 --- a/lib/mocha/parameter_matchers/instance_of.rb +++ b/lib/mocha/parameter_matchers/instance_of.rb @@ -29,6 +29,7 @@ def instance_of(klass) class InstanceOf < Base # @private def initialize(klass) + super() @klass = klass end diff --git a/lib/mocha/parameter_matchers/is_a.rb b/lib/mocha/parameter_matchers/is_a.rb index 82ee0a8c..c724bdf0 100644 --- a/lib/mocha/parameter_matchers/is_a.rb +++ b/lib/mocha/parameter_matchers/is_a.rb @@ -30,6 +30,7 @@ def is_a(klass) # rubocop:disable Naming/PredicateName class IsA < Base # @private def initialize(klass) + super() @klass = klass end diff --git a/lib/mocha/parameter_matchers/kind_of.rb b/lib/mocha/parameter_matchers/kind_of.rb index 98ff1a41..3af67ef4 100644 --- a/lib/mocha/parameter_matchers/kind_of.rb +++ b/lib/mocha/parameter_matchers/kind_of.rb @@ -29,6 +29,7 @@ def kind_of(klass) class KindOf < Base # @private def initialize(klass) + super() @klass = klass end diff --git a/lib/mocha/parameter_matchers/not.rb b/lib/mocha/parameter_matchers/not.rb index c9168b04..d803a396 100644 --- a/lib/mocha/parameter_matchers/not.rb +++ b/lib/mocha/parameter_matchers/not.rb @@ -29,6 +29,7 @@ def Not(matcher) # rubocop:disable Naming/MethodName class Not < Base # @private def initialize(matcher) + super() @matcher = matcher end diff --git a/lib/mocha/parameter_matchers/optionally.rb b/lib/mocha/parameter_matchers/optionally.rb index 78a18872..4c640c06 100644 --- a/lib/mocha/parameter_matchers/optionally.rb +++ b/lib/mocha/parameter_matchers/optionally.rb @@ -38,6 +38,7 @@ def optionally(*matchers) class Optionally < Base # @private def initialize(*parameters) + super() @matchers = parameters.map(&:to_matcher) end diff --git a/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb b/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb index 341d314b..333e2901 100644 --- a/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb +++ b/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb @@ -8,6 +8,7 @@ module ParameterMatchers # @private class PositionalOrKeywordHash < Base def initialize(value, expectation) + super() @value = value @expectation = expectation end diff --git a/lib/mocha/parameter_matchers/regexp_matches.rb b/lib/mocha/parameter_matchers/regexp_matches.rb index 98ddcb55..debbceeb 100644 --- a/lib/mocha/parameter_matchers/regexp_matches.rb +++ b/lib/mocha/parameter_matchers/regexp_matches.rb @@ -29,6 +29,7 @@ def regexp_matches(regexp) class RegexpMatches < Base # @private def initialize(regexp) + super() @regexp = regexp end diff --git a/lib/mocha/parameter_matchers/responds_with.rb b/lib/mocha/parameter_matchers/responds_with.rb index 21243232..ff18e8a8 100644 --- a/lib/mocha/parameter_matchers/responds_with.rb +++ b/lib/mocha/parameter_matchers/responds_with.rb @@ -57,6 +57,7 @@ def responds_with(*options) class RespondsWith < Base # @private def initialize(message, result) + super() @message = message @result = result end diff --git a/lib/mocha/parameter_matchers/yaml_equivalent.rb b/lib/mocha/parameter_matchers/yaml_equivalent.rb index fd5cedc7..acb22ced 100644 --- a/lib/mocha/parameter_matchers/yaml_equivalent.rb +++ b/lib/mocha/parameter_matchers/yaml_equivalent.rb @@ -29,6 +29,7 @@ def yaml_equivalent(object) class YamlEquivalent < Base # @private def initialize(object) + super() @object = object end From d09d5ca2226a880027dea5b8a3282f0f4b8be32e Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:39:28 +0000 Subject: [PATCH 30/36] Disable Lint/EmptyClass in tests It can be useful to violate this cop in tests. --- .rubocop.yml | 5 +++++ .rubocop_todo.yml | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 6a68689b..aaa6a6d9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -73,3 +73,8 @@ Gemspec/RequiredRubyVersion: Lint/UselessTimes: Exclude: - 'test/**/*.rb' + +# It can be useful to violate this cop in tests +Lint/EmptyClass: + Exclude: + - 'test/**/*.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f0e28cad..6ff9e181 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -16,13 +16,6 @@ Lint/EmptyBlock: - 'test/unit/instance_method_test.rb' - 'test/unit/mock_test.rb' -# Offense count: 2 -# Configuration parameters: AllowComments. -Lint/EmptyClass: - Exclude: - - 'test/acceptance/failure_messages_test.rb' - - 'test/unit/mockery_test.rb' - # Offense count: 3 # Configuration parameters: AllowComments, AllowNil. Lint/SuppressedException: From 92ec1c101a68d3dd9d9c717840b9309335c8e577 Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:39:28 +0000 Subject: [PATCH 31/36] Disable Lint/EmptyBlock in tests It can be useful to violate this cop in tests when testing methods that accept a block. --- .rubocop.yml | 5 +++++ .rubocop_todo.yml | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index aaa6a6d9..95f50555 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -78,3 +78,8 @@ Lint/UselessTimes: Lint/EmptyClass: Exclude: - 'test/**/*.rb' + +# It can be useful to violate this cop in tests when testing methods that accept a block +Lint/EmptyBlock: + Exclude: + - 'test/**/*.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6ff9e181..28145d71 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,16 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 13 -# Configuration parameters: AllowComments, AllowEmptyLambdas. -Lint/EmptyBlock: - Exclude: - - 'test/acceptance/display_matching_invocations_alongside_expectations_test.rb' - - 'test/test_runner.rb' - - 'test/unit/any_instance_method_test.rb' - - 'test/unit/instance_method_test.rb' - - 'test/unit/mock_test.rb' - # Offense count: 3 # Configuration parameters: AllowComments, AllowNil. Lint/SuppressedException: From d4e37dab63f8f315f028181655172458caa54d46 Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 11:55:07 +0000 Subject: [PATCH 32/36] Fix Lint/SuppressedException violations Printing some debug output in these two scenarios seems like a reasonable approach given that it will not appear for the majority of users since Ruby's debug mode is disabled by default. --- .rubocop_todo.yml | 8 -------- Rakefile | 1 + lib/mocha/detection/test_unit.rb | 1 + test/test_helper.rb | 1 + 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 28145d71..0e9fb4de 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,14 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 3 -# Configuration parameters: AllowComments, AllowNil. -Lint/SuppressedException: - Exclude: - - 'Rakefile' - - 'lib/mocha/detection/test_unit.rb' - - 'test/test_helper.rb' - # Offense count: 34 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: diff --git a/Rakefile b/Rakefile index 3327cb9c..91b9e051 100644 --- a/Rakefile +++ b/Rakefile @@ -9,6 +9,7 @@ begin # Only available with `gemfiles/Gemfile.rubocop` require 'rubocop/rake_task' rescue LoadError + warn "Unable to load 'rubocop/rake_task', but continuing anyway" if $DEBUG end desc 'Run all linters and tests' diff --git a/lib/mocha/detection/test_unit.rb b/lib/mocha/detection/test_unit.rb index cc2e6778..c113b5d3 100644 --- a/lib/mocha/detection/test_unit.rb +++ b/lib/mocha/detection/test_unit.rb @@ -15,6 +15,7 @@ def self.version begin require 'test/unit/version' rescue LoadError + warn "Unable to load 'test/unit/version', but continuing anyway" if $DEBUG end if defined?(::Test::Unit::VERSION) version = ::Test::Unit::VERSION diff --git a/test/test_helper.rb b/test/test_helper.rb index 41e68ae3..e52df86d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -13,6 +13,7 @@ begin require 'minitest' rescue LoadError + warn "Unable to load 'minitest', but continuing anyway" if $DEBUG end module Mocha; end From 1d2c32c003595c5b4640fecd851fda2471349864 Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 12:01:22 +0000 Subject: [PATCH 33/36] Disable Naming/VariableNumber in tests There are a mix of styles in the tests and many violations whether I set `EnforcedStyle` to `snake_case` or `normalcase`. So, although it would be nice to make them all consistent at some point, I don't think it's worth enforcing for now. --- .rubocop.yml | 5 +++++ .rubocop_todo.yml | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 95f50555..a28b6c99 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -83,3 +83,8 @@ Lint/EmptyClass: Lint/EmptyBlock: Exclude: - 'test/**/*.rb' + +# There are a mix of styles in the tests and so I don't think it's worth enforcing for now +Naming/VariableNumber: + Exclude: + - 'test/**/*.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 0e9fb4de..e0347ae1 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -31,13 +31,6 @@ Metrics/MethodLength: Metrics/PerceivedComplexity: Max: 13 -# Offense count: 303 -# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. -# SupportedStyles: snake_case, normalcase, non_integer -# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 -Naming/VariableNumber: - Enabled: false - # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowedVars. From fddebc3815fe3bba69b24cedc575720196f7c4b6 Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 12:29:29 +0000 Subject: [PATCH 34/36] Allow some core Ruby methods to be overridden These core Ruby method signatures violate the `Style/OptionalBooleanParameter` cop and a bunch of tests legitimately override them. The one exception is `Mocha::ClassMethods::AnyInstance#respond_to?` which is in library code. I've opened an issue (#713) to investigate whether that class should define `#respond_to_missing?` instead. Ideally I would've configured the extra `AllowedMethods` to only apply to the tests, but I couldn't find a simple way to do that with the rubocop configuration. It might be worth extracting a separate rubocop configuration for the tests...? --- .rubocop.yml | 11 +++++++++++ .rubocop_todo.yml | 16 ---------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a28b6c99..38b6fd90 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -88,3 +88,14 @@ Lint/EmptyBlock: Naming/VariableNumber: Exclude: - 'test/**/*.rb' + +# These methods from Ruby core are legitimately overridden in the tests +Style/OptionalBooleanParameter: + AllowedMethods: + - respond_to? + - public_methods + - protected_methods + - private_methods + - public_instance_methods + - protected_instance_methods + - private_instance_methods diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e0347ae1..2b76ce45 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,22 +38,6 @@ Style/FetchEnvVar: Exclude: - 'Rakefile' -# Offense count: 19 -# Configuration parameters: AllowedMethods. -# AllowedMethods: respond_to_missing? -Style/OptionalBooleanParameter: - Exclude: - - 'lib/mocha/class_methods.rb' - - 'test/acceptance/stub_any_instance_method_test.rb' - - 'test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb' - - 'test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb' - - 'test/acceptance/stub_module_method_test.rb' - - 'test/acceptance/stubbing_non_existent_any_instance_method_test.rb' - - 'test/acceptance/stubbing_non_existent_class_method_test.rb' - - 'test/acceptance/stubbing_non_existent_instance_method_test.rb' - - 'test/acceptance/stubbing_non_public_class_method_test.rb' - - 'test/acceptance/stubbing_non_public_instance_method_test.rb' - # Offense count: 68 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. From d98375c9185dc9ab4cc61794635a48ad4b423ebe Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 12:38:17 +0000 Subject: [PATCH 35/36] Disable Style/FetchEnvVar for env var in Rakefile This cop is useful for required environment variables, but not for optional ones like `MOCHA_RUN_INTEGRATION_TESTS`. --- .rubocop.yml | 5 +++++ .rubocop_todo.yml | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 38b6fd90..7354247c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -99,3 +99,8 @@ Style/OptionalBooleanParameter: - public_instance_methods - protected_instance_methods - private_instance_methods + +# This cop is useful for required environment variables, but not for optional ones +Style/FetchEnvVar: + AllowedVars: + - MOCHA_RUN_INTEGRATION_TESTS diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2b76ce45..11a346e6 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -31,13 +31,6 @@ Metrics/MethodLength: Metrics/PerceivedComplexity: Max: 13 -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowedVars. -Style/FetchEnvVar: - Exclude: - - 'Rakefile' - # Offense count: 68 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. From 835caa257de86f313f63dcf3d83badaf75bed9fa Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 1 Jan 2025 13:00:21 +0000 Subject: [PATCH 36/36] Add rubocop-rake & fix Rake/Desc violations Previously I was seeing the following output when running rubocop: Tip: Based on detected gems, the following RuboCop extension libraries might be helpful: * rubocop-rake (https://rubygems.org/gems/rubocop-rake) You can opt out of this message by adding the following to your config (see https://docs.rubocop.org/rubocop/extensions.html#extension-suggestions for more options): AllCops: SuggestExtensions: false --- .rubocop.yml | 3 +++ Rakefile | 3 +++ gemfiles/Gemfile.rubocop | 1 + 3 files changed, 7 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 7354247c..8c3e71ab 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,6 @@ +require: + - rubocop-rake + inherit_from: .rubocop_todo.yml inherit_mode: diff --git a/Rakefile b/Rakefile index 91b9e051..d36e1221 100644 --- a/Rakefile +++ b/Rakefile @@ -82,6 +82,7 @@ namespace 'test' do # rubocop:disable Metrics/BlockLength end end +desc 'Run linters' task 'lint' do if defined?(RuboCop::RakeTask) RuboCop::RakeTask.new @@ -132,10 +133,12 @@ if ENV['MOCHA_GENERATE_DOCS'] task.options = ['--title', "Mocha #{Mocha::VERSION}", '--fail-on-warning'] end + desc 'Ensure custom domain remains in place for docs on GitHub Pages' task 'checkout_docs_cname' do `git checkout docs/CNAME` end + desc 'Ensure custom JavaScript files remain in place for docs on GitHub Pages' task 'checkout_docs_js' do `git checkout docs/js/app.js` `git checkout docs/js/jquery.js` diff --git a/gemfiles/Gemfile.rubocop b/gemfiles/Gemfile.rubocop index 61f5d370..ac47c262 100644 --- a/gemfiles/Gemfile.rubocop +++ b/gemfiles/Gemfile.rubocop @@ -4,3 +4,4 @@ gemspec path: '../' gem 'rake' gem 'rubocop' +gem 'rubocop-rake'