diff --git a/.rubocop_rspec_base.yml b/.rubocop_rspec_base.yml index 1d323b623..29d06e357 100644 --- a/.rubocop_rspec_base.yml +++ b/.rubocop_rspec_base.yml @@ -1,4 +1,4 @@ -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. # This file contains defaults for RSpec projects. Individual projects diff --git a/.travis.yml b/.travis.yml index c5b1a114b..2194559ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. # In order to install old Rubies, we need to use old Ubuntu distibution. @@ -22,10 +22,10 @@ rvm: - 2.1 - 2.2.10 - 2.3.8 - - 2.4.9 - - 2.5.7 - - 2.6.5 - - 2.7.0 + - 2.4.10 + - 2.5.8 + - 2.6.6 + - 2.7.1 - ruby-head - ree - rbx-3 @@ -38,6 +38,8 @@ matrix: include: - rvm: jruby-1.7 env: JRUBY_OPTS='--dev --1.8' + - rvm: 2.7.1 + env: DIFF_LCS_VERSION='~> 1.3.0' allow_failures: - rvm: jruby-head - rvm: ruby-head diff --git a/Changelog.md b/Changelog.md index 4933612da..3c6d8641a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,8 @@ Enhancements: * Add the ability to set a custom error generator in `MessageExpectation`. This will allow rspec-expectations to inject a custom failure message. (Benoit Tigeot and Nicolas Zermati, #1312) +* Return the result of the block passed to `RSpec::Mocks.with_temporary_scope` + when block run. (@expeehaa, #1329) ### 3.9.1 / 2019-12-31 [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.0...v3.9.1) diff --git a/Gemfile b/Gemfile index 727fdfb11..14f719846 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,20 @@ branch = File.read(File.expand_path("../maintenance-branch", __FILE__)).chomp end end +if RUBY_VERSION < '1.9.3' + gem 'rake', '< 11.0.0' # rake 11 requires Ruby 1.9.3 or later +elsif RUBY_VERSION < '2.0.0' + gem 'rake', '< 12.0.0' # rake 12 requires Ruby 2.0.0 or later +else + gem 'rake', '> 12.3.2' +end + +if ENV['DIFF_LCS_VERSION'] + gem 'diff-lcs', ENV['DIFF_LCS_VERSION'] +else + gem 'diff-lcs', '~> 1.4', '>= 1.4.3' +end + gem 'yard', '~> 0.9.24', :require => false # No need to run rubocop on earlier versions diff --git a/appveyor.yml b/appveyor.yml index 13e397a17..06cc874aa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. version: "{build}" diff --git a/lib/rspec/mocks.rb b/lib/rspec/mocks.rb index 95ea1de4c..297779e5a 100644 --- a/lib/rspec/mocks.rb +++ b/lib/rspec/mocks.rb @@ -87,12 +87,15 @@ def self.expect_message(subject, message, opts={}, &block) # Call the passed block and verify mocks after it has executed. This allows # mock usage in arbitrary places, such as a `before(:all)` hook. + # + # @return [Object] the return value from the block def self.with_temporary_scope setup begin - yield + result = yield verify + result ensure teardown end diff --git a/lib/rspec/mocks/message_expectation.rb b/lib/rspec/mocks/message_expectation.rb index cb5a39922..d999dc0f8 100644 --- a/lib/rspec/mocks/message_expectation.rb +++ b/lib/rspec/mocks/message_expectation.rb @@ -98,7 +98,7 @@ def and_return(first_value, *values) # expect(counter.count).to eq(original_count + 1) def and_call_original wrap_original(__method__) do |original, *args, &block| - original.call(*args, &block) + __call_original(original, *args, &block) end end @@ -354,6 +354,25 @@ def to_s end alias inspect to_s + private + + if RSpec::Support::RubyFeatures.kw_args_supported? + def __call_original(original, *args, &block) + if RSpec::Support::MethodSignature.new(original).has_kw_args_in?(args) + binding.eval(<<-CODE, __FILE__, __LINE__) + kwargs = args.pop + original.call(*args, **kwargs, &block) + CODE + else + original.call(*args, &block) + end + end + else + def __call_original(original, *args, &block) + original.call(*args, &block) + end + end + # @private # Contains the parts of `MessageExpectation` that aren't part of # rspec-mocks' public API. The class is very big and could really use diff --git a/rspec-mocks.gemspec b/rspec-mocks.gemspec index 21e9a50e9..9fd5e9a95 100644 --- a/rspec-mocks.gemspec +++ b/rspec-mocks.gemspec @@ -45,7 +45,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency "diff-lcs", ">= 1.2.0", "< 2.0" - s.add_development_dependency 'rake', '~> 10.0.0' + s.add_development_dependency 'rake', '> 10.0.0' s.add_development_dependency 'cucumber', '~> 1.3.15' s.add_development_dependency 'aruba', '~> 0.14.10' s.add_development_dependency 'minitest', '~> 5.2' diff --git a/script/clone_all_rspec_repos b/script/clone_all_rspec_repos index a6e915e81..97741443b 100755 --- a/script/clone_all_rspec_repos +++ b/script/clone_all_rspec_repos @@ -1,5 +1,5 @@ #!/bin/bash -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. set -e diff --git a/script/functions.sh b/script/functions.sh index efc219177..06e8320c0 100644 --- a/script/functions.sh +++ b/script/functions.sh @@ -1,4 +1,4 @@ -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" diff --git a/script/predicate_functions.sh b/script/predicate_functions.sh index 4e40628e4..6320130f2 100644 --- a/script/predicate_functions.sh +++ b/script/predicate_functions.sh @@ -1,4 +1,4 @@ -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. function is_mri { diff --git a/script/run_build b/script/run_build index 851d576ce..493fc3bd1 100755 --- a/script/run_build +++ b/script/run_build @@ -1,5 +1,5 @@ #!/bin/bash -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. set -e diff --git a/script/travis_functions.sh b/script/travis_functions.sh index 7f0b6d965..3426b5562 100644 --- a/script/travis_functions.sh +++ b/script/travis_functions.sh @@ -1,4 +1,4 @@ -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. # Taken from: diff --git a/script/update_rubygems_and_install_bundler b/script/update_rubygems_and_install_bundler index c256d80c3..ae94b87a6 100755 --- a/script/update_rubygems_and_install_bundler +++ b/script/update_rubygems_and_install_bundler @@ -1,5 +1,5 @@ #!/bin/bash -# This file was generated on 2020-03-30T16:31:25+02:00 from the rspec-dev repo. +# This file was generated on 2020-04-03T18:53:23+03:00 from the rspec-dev repo. # DO NOT modify it by hand as your changes will get lost the next time it is generated. set -e diff --git a/spec/rspec/mocks/and_call_original_spec.rb b/spec/rspec/mocks/and_call_original_spec.rb index 8bb20d563..25c5a85cc 100644 --- a/spec/rspec/mocks/and_call_original_spec.rb +++ b/spec/rspec/mocks/and_call_original_spec.rb @@ -12,6 +12,19 @@ def meth_2(x) yield x, :additional_yielded_arg end + if RSpec::Support::RubyFeatures.kw_args_supported? + binding.eval(<<-CODE, __FILE__, __LINE__) + def meth_3(keyword_arg: nil) + keyword_arg + end + + def initialize(initialize_arg: nil) + @initialize_arg = initialize_arg + end + attr_reader :initialize_arg + CODE + end + def self.new_instance new end @@ -59,6 +72,24 @@ def self.new_instance expect(value).to eq([:submitted_arg, :additional_yielded_arg]) end + if RSpec::Support::RubyFeatures.kw_args_supported? + it 'works with keyword arguments' do + expect(instance).to receive(:meth_3).and_call_original + binding.eval(<<-CODE, __FILE__, __LINE__) + expect(instance.meth_3(keyword_arg: :original_arg)).to eq :original_arg + CODE + end + + it 'works with keyword arguments for .initialize' do + expect(klass).to receive(:new).with(initialize_arg: :initialize_arg) + .and_call_original + binding.eval(<<-CODE, __FILE__, __LINE__) + instance = klass.new(initialize_arg: :initialize_arg) + expect(instance.initialize_arg).to eq :initialize_arg + CODE + end + end + it 'errors when you pass through the wrong number of args' do expect(instance).to receive(:meth_1).and_call_original expect(instance).to receive(:meth_2).twice.and_call_original diff --git a/spec/rspec/mocks/diffing_spec.rb b/spec/rspec/mocks/diffing_spec.rb index e2a1b8a49..3b1f91edf 100644 --- a/spec/rspec/mocks/diffing_spec.rb +++ b/spec/rspec/mocks/diffing_spec.rb @@ -2,6 +2,8 @@ require "pp" RSpec.describe "Diffs printed when arguments don't match" do + include RSpec::Support::Spec::DiffHelpers + before do allow(RSpec::Mocks.configuration).to receive(:color?).and_return(false) end @@ -68,7 +70,7 @@ expect(d).to receive(:foo).with(expected_hash) expect { d.foo(:bad => :hash) - }.to fail_with(/\A# received :foo with unexpected arguments\n expected: \(#{hash_regex_inspect expected_hash}\)\n got: \(#{hash_regex_inspect actual_hash}\)\nDiff:\n@@ \-1\,2 \+1\,2 @@\n\-\[#{hash_regex_inspect expected_hash}\]\n\+\[#{hash_regex_inspect actual_hash}\]\n\z/) + }.to fail_with(/\A# received :foo with unexpected arguments\n expected: \(#{hash_regex_inspect expected_hash}\)\n got: \(#{hash_regex_inspect actual_hash}\)\nDiff:\n@@ #{Regexp.escape one_line_header} @@\n\-\[#{hash_regex_inspect expected_hash}\]\n\+\[#{hash_regex_inspect actual_hash}\]\n\z/) end end @@ -101,7 +103,7 @@ def hash_regex_inspect(hash) expect(d).to receive(:foo).with([:a, :b, :c]) expect { d.foo([]) - }.to fail_with("# received :foo with unexpected arguments\n expected: ([:a, :b, :c])\n got: ([])\nDiff:\n@@ -1,2 +1,2 @@\n-[[:a, :b, :c]]\n+[[]]\n") + }.to fail_with("# received :foo with unexpected arguments\n expected: ([:a, :b, :c])\n got: ([])\nDiff:\n@@ #{one_line_header} @@\n-[[:a, :b, :c]]\n+[[]]\n") end end @@ -117,7 +119,7 @@ def hash_regex_inspect(hash) d.foo([]) }.to fail_with("# received :foo with unexpected arguments\n" \ " expected: (#{collab_inspect})\n" \ - " got: ([])\nDiff:\n@@ -1,2 +1,2 @@\n-[#{collab_inspect}]\n+[[]]\n") + " got: ([])\nDiff:\n@@ #{one_line_header} @@\n-[#{collab_inspect}]\n+[[]]\n") end end end @@ -136,7 +138,7 @@ def hash_regex_inspect(hash) d.foo([:a, :b]) }.to fail_with("# received :foo with unexpected arguments\n" \ " expected: (#{collab_description})\n" \ - " got: ([:a, :b])\nDiff:\n@@ -1,2 +1,2 @@\n-[\"#{collab_description}\"]\n+[[:a, :b]]\n") + " got: ([:a, :b])\nDiff:\n@@ #{one_line_header} @@\n-[\"#{collab_description}\"]\n+[[:a, :b]]\n") end end end @@ -164,7 +166,7 @@ def inspect d.foo([:a, :b]) }.to fail_with("# received :foo with unexpected arguments\n" \ " expected: (#{collab_inspect})\n" \ - " got: ([:a, :b])\nDiff:\n@@ -1,2 +1,2 @@\n-[#{collab_pp}]\n+[[:a, :b]]\n") + " got: ([:a, :b])\nDiff:\n@@ #{one_line_header} @@\n-[#{collab_pp}]\n+[[:a, :b]]\n") end end end diff --git a/spec/rspec/mocks/formatting_spec.rb b/spec/rspec/mocks/formatting_spec.rb index a08b1776e..aed05bed3 100644 --- a/spec/rspec/mocks/formatting_spec.rb +++ b/spec/rspec/mocks/formatting_spec.rb @@ -3,6 +3,7 @@ RSpec.describe "Test doubles format well in failure messages" do include RSpec::Matchers::FailMatchers + include RSpec::Support::Spec::DiffHelpers RSpec::Matchers.define :format_in_failures_as do |expected| match do |dbl| @@ -101,7 +102,7 @@ def actual_formatting(double) }.to fail_with(<<-EOS.gsub(/^\s+\|/, '')) |expected [#] to include # |Diff: - |@@ -1,2 +1,2 @@ + |@@ #{one_line_header} @@ |-[#] |+[#] EOS diff --git a/spec/rspec/mocks_spec.rb b/spec/rspec/mocks_spec.rb index 8257ba994..771431e63 100644 --- a/spec/rspec/mocks_spec.rb +++ b/spec/rspec/mocks_spec.rb @@ -209,6 +209,10 @@ }.to raise_error("boom") # rather than MockExpectationError end + it 'returns the result of the passed block' do + expect(RSpec::Mocks.with_temporary_scope { 5 }).to eq 5 + end + def capture_error yield rescue Exception => @error