diff --git a/Changelog.md b/Changelog.md index 9e151a65b..2e7de388e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ Breaking Changes: * Ruby < 2.3 is no longer supported. (Phil Pirozhkov, #1349) +* Extract monkey-patching `should_receive`/`stub` syntax. (Phil Pirozhkov, #1365) Bug Fixes: diff --git a/features/.nav b/features/.nav index c910a4276..602867062 100644 --- a/features/.nav +++ b/features/.nav @@ -32,12 +32,6 @@ - working_with_legacy_code: - any_instance.feature - message_chains.feature -- old_syntax: - - stub.feature - - should_receive.feature - - any_instance.feature - - stub_chain.feature - - unstub.feature - outside_rspec: - minitest.feature - any_test_framework.feature diff --git a/features/old_syntax/README.md b/features/old_syntax/README.md deleted file mode 100644 index a2ead9e4f..000000000 --- a/features/old_syntax/README.md +++ /dev/null @@ -1,35 +0,0 @@ -Historically, rspec-mocks has used a monkey-patched syntax to allow you to mock or stub any object: - -```ruby -obj.stub(:foo).and_return(15) -obj.should_receive(:bar) -``` - -Unfortunately, this is prone to weird, confusing failures when applied to [delegate/proxy -objects](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#delegation_issues). For a method like `stub` to work properly, it must be defined on every object in the -system, but RSpec does not own every object in the system and cannot ensure that it always -works consistently. - -For this reason, in RSpec 2.14, we introduced a new syntax that avoids monkey patching -altogether. It's the syntax shown in all examples of this documentation outside of this -directory. As of RSpec 3, we consider this to be the main, recommended syntax of rspec- -mocks. The old monkey-patched syntax continues to work, but you will get a deprecation -warning if you use it without explicitly opting-in to it: - -```ruby -# If you're using rspec-core: -RSpec.configure do |config| - config.mock_with :rspec do |mocks| - mocks.syntax = :should - end -end - -# Or, if you're using rspec-mocks in another context: -RSpec::Mocks.configuration.syntax = :should -``` - -We have no plans to ever kill the old syntax, but we may extract it into an external gem in -RSpec 4. - -If you have an old project that uses the old syntax and you want to update it to the current -syntax, checkout [transpec](http://yujinakayama.me/transpec/). diff --git a/features/old_syntax/any_instance.feature b/features/old_syntax/any_instance.feature deleted file mode 100644 index 0a4d85ff7..000000000 --- a/features/old_syntax/any_instance.feature +++ /dev/null @@ -1,105 +0,0 @@ -@allow-old-syntax -Feature: `any_instance` - - `any_instance` is the old way to stub or mock any instance of a class but carries the baggage of a global monkey patch on all classes. - Note that we [generally recommend against](../working-with-legacy-code/any-instance) using this feature. - - Background: - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.mock_with :rspec do |mocks| - mocks.syntax = :should - end - end - """ - And a file named ".rspec" with: - """ - --require spec_helper - """ - - Scenario: Stub a method on any instance of a class - Given a file named "spec/example_spec.rb" with: - """ruby - RSpec.describe "Stubbing a method with any_instance" do - it "returns the specified value on any instance of the class" do - Object.any_instance.stub(:foo).and_return(:return_value) - - o = Object.new - expect(o.foo).to eq(:return_value) - end - end - """ - When I run `rspec spec/example_spec.rb` - Then the examples should all pass - - Scenario: Stub multiple methods on any instance of a class - Given a file named "spec/example_spec.rb" with: - """ruby - RSpec.describe "Stubbing multiple methods with any_instance" do - it "returns the specified values for the givne messages" do - Object.any_instance.stub(:foo => 'foo', :bar => 'bar') - - o = Object.new - expect(o.foo).to eq('foo') - expect(o.bar).to eq('bar') - end - end - """ - When I run `rspec spec/example_spec.rb` - Then the examples should all pass - - Scenario: Stubbing any instance of a class with specific arguments - Given a file named "spec/example_spec.rb" with: - """ruby - RSpec.describe "Stubbing any instance with arguments" do - it "returns the stubbed value when arguments match" do - Object.any_instance.stub(:foo).with(:param_one, :param_two).and_return(:result_one) - Object.any_instance.stub(:foo).with(:param_three, :param_four).and_return(:result_two) - - o = Object.new - expect(o.foo(:param_one, :param_two)).to eq(:result_one) - expect(o.foo(:param_three, :param_four)).to eq(:result_two) - end - end - """ - When I run `rspec spec/example_spec.rb` - Then the examples should all pass - - Scenario: Block implementation is passed the receiver as first arg - Given a file named "spec/example_spec.rb" with: - """ruby - RSpec.describe "Stubbing any instance of a class" do - it 'yields the receiver to the block implementation' do - String.any_instance.stub(:slice) do |value, start, length| - value[start, length] - end - - expect('string'.slice(2, 3)).to eq('rin') - end - end - """ - When I run `rspec spec/example_spec.rb` - Then the examples should all pass - - Scenario: Expect a message on any instance of a class - Given a file named "spec/example_spec.rb" with: - """ruby - RSpec.describe "Expecting a message on any instance of a class" do - before do - Object.any_instance.should_receive(:foo) - end - - it "passes when an instance receives the message" do - Object.new.foo - end - - it "fails when no instance receives the message" do - Object.new.to_s - end - end - """ - When I run `rspec spec/example_spec.rb` - Then it should fail with the following output: - | 2 examples, 1 failure | - | Exactly one instance should have received the following message(s) but didn't: foo | diff --git a/features/old_syntax/should_receive.feature b/features/old_syntax/should_receive.feature deleted file mode 100644 index 9307c6b1b..000000000 --- a/features/old_syntax/should_receive.feature +++ /dev/null @@ -1,92 +0,0 @@ -@allow-old-syntax -Feature: `should_receive` - - `should_receive` is the old way to [expect messages](../basics/expecting-messages) but carries the - baggage of a global monkey patch on all objects. It supports the - same fluent interface for [setting constraints](../setting-constraints) and [configuring responses](../configuring-responses). - - Similarly, you can use `should_not_receive` to set a negative message expectation. - - Background: - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.mock_with :rspec do |mocks| - mocks.syntax = :should - end - end - """ - And a file named ".rspec" with: - """ - --require spec_helper - """ - - Scenario: Failing positive message expectation - Given a file named "spec/unfulfilled_message_expectation_spec.rb" with: - """ruby - RSpec.describe "An unfulfilled message expectation" do - it "triggers a failure" do - dbl = double("Some Collaborator") - dbl.should_receive(:foo) - end - end - """ - When I run `rspec spec/unfulfilled_message_expectation_spec.rb` - Then it should fail with: - """ - 1) An unfulfilled message expectation triggers a failure - Failure/Error: dbl.should_receive(:foo) - - (Double "Some Collaborator").foo(*(any args)) - expected: 1 time with any arguments - received: 0 times with any arguments - """ - - Scenario: Passing positive message expectation - Given a file named "spec/fulfilled_message_expectation_spec.rb" with: - """ruby - RSpec.describe "A fulfilled message expectation" do - it "passes" do - dbl = double("Some Collaborator") - dbl.should_receive(:foo) - dbl.foo - end - end - """ - When I run `rspec spec/fulfilled_message_expectation_spec.rb` - Then the examples should all pass - - Scenario: Failing negative message expectation - Given a file named "spec/negative_message_expectation_spec.rb" with: - """ruby - RSpec.describe "A negative message expectation" do - it "fails when the message is received" do - dbl = double("Some Collaborator").as_null_object - dbl.should_not_receive(:foo) - dbl.foo - end - end - """ - When I run `rspec spec/negative_message_expectation_spec.rb` - Then it should fail with: - """ - 1) A negative message expectation fails when the message is received - Failure/Error: dbl.foo - - (Double "Some Collaborator").foo(no args) - expected: 0 times with any arguments - received: 1 time - """ - - Scenario: Passing negative message expectation - Given a file named "spec/negative_message_expectation_spec.rb" with: - """ruby - RSpec.describe "A negative message expectation" do - it "passes if the message is never received" do - dbl = double("Some Collaborator").as_null_object - dbl.should_not_receive(:foo) - end - end - """ - When I run `rspec spec/negative_message_expectation_spec.rb` - Then the examples should all pass diff --git a/features/old_syntax/stub.feature b/features/old_syntax/stub.feature deleted file mode 100644 index e08ea5e94..000000000 --- a/features/old_syntax/stub.feature +++ /dev/null @@ -1,51 +0,0 @@ -@allow-old-syntax -Feature: `stub` - - `stub` is the old way to [allow messages](../basics/allowing-messages) but carries the baggage of a - global monkey patch on all objects. It supports the same fluent - interface for [setting constraints](../setting-constraints) and [configuring responses](../configuring-responses). You can also pass `stub` a hash - of message/return-value pairs, which acts like `allow(obj).to receive_messages(hash)`, - but does not support further customization through the fluent interface. - - Background: - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.mock_with :rspec do |mocks| - mocks.syntax = :should - end - end - """ - And a file named ".rspec" with: - """ - --require spec_helper - """ - - Scenario: Stub a method - Given a file named "spec/stub_spec.rb" with: - """ruby - RSpec.describe "Stubbing a method" do - it "configures how the object responds" do - dbl = double - dbl.stub(:foo).and_return(13) - expect(dbl.foo).to eq(13) - end - end - """ - When I run `rspec spec/stub_spec.rb` - Then the examples should all pass - - Scenario: Stub multiple methods by passing a hash - Given a file named "spec/stub_multiple_methods_spec.rb" with: - """ruby - RSpec.describe "Stubbing multiple methods" do - it "stubs each named method with the given return value" do - dbl = double - dbl.stub(:foo => 13, :bar => 10) - expect(dbl.foo).to eq(13) - expect(dbl.bar).to eq(10) - end - end - """ - When I run `rspec spec/stub_multiple_methods_spec.rb` - Then the examples should all pass diff --git a/features/old_syntax/stub_chain.feature b/features/old_syntax/stub_chain.feature deleted file mode 100644 index 036d52f74..000000000 --- a/features/old_syntax/stub_chain.feature +++ /dev/null @@ -1,69 +0,0 @@ -@allow-old-syntax -Feature: `stub_chain` - - `stub_chain` is the old way to [allow a message chain](../working-with-legacy-code/message-chains) but carries the - baggage of a global monkey patch on all objects. As with - `receive_message_chain`, use with care; we recommend treating usage of `stub_chain` as a - code smell. - - Background: - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.mock_with :rspec do |mocks| - mocks.syntax = :should - end - end - """ - And a file named ".rspec" with: - """ - --require spec_helper - """ - - Scenario: Use `stub_chain` on a double - Given a file named "spec/stub_chain_spec.rb" with: - """ruby - RSpec.describe "Using stub_chain on a double" do - let(:dbl) { double } - - example "using a string and a block" do - dbl.stub_chain("foo.bar") { :baz } - expect(dbl.foo.bar).to eq(:baz) - end - - example "using symbols and a hash" do - dbl.stub_chain(:foo, :bar => :baz) - expect(dbl.foo.bar).to eq(:baz) - end - - example "using symbols and a block" do - dbl.stub_chain(:foo, :bar) { :baz } - expect(dbl.foo.bar).to eq(:baz) - end - end - """ - When I run `rspec spec/stub_chain_spec.rb` - Then the examples should all pass - - Scenario: Use `stub_chain` on any instance of a class - Given a file named "spec/stub_chain_spec.rb" with: - """ruby - RSpec.describe "Using any_instance.stub_chain" do - example "using a string and a block" do - Object.any_instance.stub_chain("foo.bar") { :baz } - expect(Object.new.foo.bar).to eq(:baz) - end - - example "using symbols and a hash" do - Object.any_instance.stub_chain(:foo, :bar => :baz) - expect(Object.new.foo.bar).to eq(:baz) - end - - example "using symbols and a block" do - Object.any_instance.stub_chain(:foo, :bar) { :baz } - expect(Object.new.foo.bar).to eq(:baz) - end - end - """ - When I run `rspec spec/stub_chain_spec.rb` - Then the examples should all pass diff --git a/features/old_syntax/unstub.feature b/features/old_syntax/unstub.feature deleted file mode 100644 index fd6a45d0b..000000000 --- a/features/old_syntax/unstub.feature +++ /dev/null @@ -1,43 +0,0 @@ -@allow-old-syntax -Feature: `unstub` - - `unstub` removes a method stub, essentially cleaning up the method - stub early, rather than waiting for the cleanup that runs at the end - of the example. The newer non-monkey-patching syntax does not have a direct - equivalent but in most situations you can achieve the same behavior using - [`and_call_original`](../configuring-responses/calling-the-original-implementation). The difference is that `obj.unstub(:foo)` completely cleans up the `foo` - method stub, whereas `allow(obj).to receive(:foo).and_call_original` continues to - observe calls to the method (important when you are using [spies](../basics/spies)), which could affect the - method's behavior if it does anything with `caller` as it will include additional rspec stack - frames. - - Background: - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.mock_with :rspec do |mocks| - mocks.syntax = :should - end - end - """ - And a file named ".rspec" with: - """ - --require spec_helper - """ - - Scenario: Unstub a method - Given a file named "spec/unstub_spec.rb" with: - """ruby - RSpec.describe "Unstubbing a method" do - it "restores the original behavior" do - string = "hello world" - string.stub(:reverse) { "hello dlrow" } - - expect { - string.unstub(:reverse) - }.to change { string.reverse }.from("hello dlrow").to("dlrow olleh") - end - end - """ - When I run `rspec spec/unstub_spec.rb` - Then the examples should all pass diff --git a/features/support/disallow_certain_apis.rb b/features/support/disallow_certain_apis.rb deleted file mode 100644 index 85006995c..000000000 --- a/features/support/disallow_certain_apis.rb +++ /dev/null @@ -1,24 +0,0 @@ -# This file is designed to prevent the use of certain APIs that -# we don't want used from our cukes, since they function as documentation. - -if defined?(Cucumber) - require 'shellwords' - Before('~@allow-old-syntax') do - set_environment_variable('SPEC_OPTS', "-r#{Shellwords.escape(__FILE__)}") - end -else - module DisallowOneLinerShould - def should(*) - raise "one-liner should is not allowed" - end - - def should_not(*) - raise "one-liner should_not is not allowed" - end - end - - RSpec.configure do |rspec| - rspec.disable_monkey_patching! - rspec.include DisallowOneLinerShould - end -end diff --git a/lib/rspec/mocks.rb b/lib/rspec/mocks.rb index 32e56e077..668050ce4 100644 --- a/lib/rspec/mocks.rb +++ b/lib/rspec/mocks.rb @@ -18,7 +18,6 @@ space mutate_const targets - syntax configuration verifying_double version diff --git a/lib/rspec/mocks/configuration.rb b/lib/rspec/mocks/configuration.rb index 5962215f8..797cc0a06 100644 --- a/lib/rspec/mocks/configuration.rb +++ b/lib/rspec/mocks/configuration.rb @@ -45,69 +45,6 @@ def yield_receiver_to_any_instance_implementation_blocks? # end attr_writer :yield_receiver_to_any_instance_implementation_blocks - # Adds `stub` and `should_receive` to the given - # modules or classes. This is usually only necessary - # if you application uses some proxy classes that - # "strip themselves down" to a bare minimum set of - # methods and remove `stub` and `should_receive` in - # the process. - # - # @example - # RSpec.configure do |rspec| - # rspec.mock_with :rspec do |mocks| - # mocks.add_stub_and_should_receive_to Delegator - # end - # end - # - def add_stub_and_should_receive_to(*modules) - modules.each do |mod| - Syntax.enable_should(mod) - end - end - - # Provides the ability to set either `expect`, - # `should` or both syntaxes. RSpec uses `expect` - # syntax by default. This is needed if you want to - # explicitly enable `should` syntax and/or explicitly - # disable `expect` syntax. - # - # @example - # RSpec.configure do |rspec| - # rspec.mock_with :rspec do |mocks| - # mocks.syntax = [:expect, :should] - # end - # end - # - def syntax=(*values) - syntaxes = values.flatten - if syntaxes.include?(:expect) - Syntax.enable_expect - else - Syntax.disable_expect - end - - if syntaxes.include?(:should) - Syntax.enable_should - else - Syntax.disable_should - end - end - - # Returns an array with a list of syntaxes - # that are enabled. - # - # @example - # unless RSpec::Mocks.configuration.syntax.include?(:expect) - # raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax" - # end - # - def syntax - syntaxes = [] - syntaxes << :should if Syntax.should_enabled? - syntaxes << :expect if Syntax.expect_enabled? - syntaxes - end - def verify_doubled_constant_names? !!@verify_doubled_constant_names end @@ -192,13 +129,6 @@ def patch_marshal_to_support_partial_doubles=(val) RSpec::Mocks::MarshalExtension.unpatch! end end - - # @api private - # Resets the configured syntax to the default. - def reset_syntaxes_to_default - self.syntax = [:should, :expect] - RSpec::Mocks::Syntax.warn_about_should! - end end # Mocks specific configuration, as distinct from `RSpec.configuration` @@ -206,7 +136,5 @@ def reset_syntaxes_to_default def self.configuration @configuration ||= Configuration.new end - - configuration.reset_syntaxes_to_default end end diff --git a/lib/rspec/mocks/example_methods.rb b/lib/rspec/mocks/example_methods.rb index 5531b28bf..239ba4214 100644 --- a/lib/rspec/mocks/example_methods.rb +++ b/lib/rspec/mocks/example_methods.rb @@ -303,8 +303,7 @@ def without_partial_double_verification # # @note This method is usually provided by rspec-expectations. However, # if you use rspec-mocks without rspec-expectations, there's a definition - # of it that is made available here. If you disable the `:expect` syntax - # this method will be undefined. + # of it that is made available here. # @method allow # Used to wrap an object in preparation for stubbing a method @@ -312,28 +311,30 @@ def without_partial_double_verification # # @example # allow(dbl).to receive(:foo).with(5).and_return(:return_value) - # - # @note If you disable the `:expect` syntax this method will be undefined. + def allow(target) + AllowanceTarget.new(target) + end - # @method expect_any_instance_of # Used to wrap a class in preparation for setting a mock expectation # on instances of it. # # @example # expect_any_instance_of(MyClass).to receive(:foo) # - # @note If you disable the `:expect` syntax this method will be undefined. + def expect_any_instance_of(klass) + AnyInstanceExpectationTarget.new(klass) + end - # @method allow_any_instance_of # Used to wrap a class in preparation for stubbing a method # on instances of it. # # @example # allow_any_instance_of(MyClass).to receive(:foo) # - # @note This is only available when you have enabled the `expect` syntax. + def allow_any_instance_of(klass) + AnyInstanceAllowanceTarget.new(klass) + end - # @method receive # Used to specify a message that you expect or allow an object # to receive. The object returned by `receive` supports the same # fluent interface that `should_receive` and `stub` have always @@ -343,9 +344,10 @@ def without_partial_double_verification # @example # expect(obj).to receive(:hello).with("world").exactly(3).times # - # @note If you disable the `:expect` syntax this method will be undefined. + def receive(method_name, &block) + Matchers::Receive.new(method_name, block) + end - # @method receive_messages # Shorthand syntax used to setup message(s), and their return value(s), # that you expect or allow an object to receive. The method takes a hash # of messages and their respective return values. Unlike with `receive`, @@ -356,9 +358,12 @@ def without_partial_double_verification # allow(obj).to receive_messages(:speak => "Hello World") # allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow") # - # @note If you disable the `:expect` syntax this method will be undefined. + def receive_messages(message_return_value_hash) + matcher = Matchers::ReceiveMessages.new(message_return_value_hash) + matcher.warn_about_block if block_given? + matcher + end - # @method receive_message_chain # @overload receive_message_chain(method1, method2) # @overload receive_message_chain("method1.method2") # @overload receive_message_chain(method1, method_to_value_hash) @@ -386,7 +391,9 @@ def without_partial_double_verification # # Common use in Rails/ActiveRecord: # allow(Article).to receive_message_chain("recent.published") { [Article.new] } # - # @note If you disable the `:expect` syntax this method will be undefined. + def receive_message_chain(*messages, &block) + Matchers::ReceiveMessageChain.new(messages, &block) + end # @private def self.included(klass) @@ -425,9 +432,13 @@ def self.declare_double(type, *args) type.new(*args) end - # This module exists to host the `expect` method for cases where + # This module exists to provide the `expect` method for cases where # rspec-mocks is used w/o rspec-expectations. module ExpectHost + # @private + def expect(target) + ExpectationTarget.new(target) + end end end end diff --git a/lib/rspec/mocks/syntax.rb b/lib/rspec/mocks/syntax.rb deleted file mode 100644 index f728dcb6b..000000000 --- a/lib/rspec/mocks/syntax.rb +++ /dev/null @@ -1,300 +0,0 @@ -module RSpec - module Mocks - # @api private - # Provides methods for enabling and disabling the available syntaxes - # provided by rspec-mocks. - module Syntax - # @private - def self.warn_about_should! - @warn_about_should = true - end - - # @private - def self.warn_unless_should_configured(method_name , replacement="the new `:expect` syntax or explicitly enable `:should`") - if @warn_about_should - RSpec.deprecate( - "Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", - :replacement => replacement - ) - - @warn_about_should = false - end - end - - # @api private - # Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). - def self.enable_should(syntax_host=::BasicObject) - @warn_about_should = false if syntax_host == ::BasicObject - return if should_enabled?(syntax_host) - - syntax_host.class_exec do - def should_receive(message, opts={}, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.expect_message(self, message, opts, &block) - end - - def should_not_receive(message, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.expect_message(self, message, {}, &block).never - end - - def stub(message_or_hash, opts={}, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - if ::Hash === message_or_hash - message_or_hash.each { |message, value| stub(message).and_return value } - else - ::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block) - end - end - - def unstub(message) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to receive(...).and_call_original` or explicitly enable `:should`") - ::RSpec::Mocks.space.proxy_for(self).remove_stub(message) - end - - def stub_chain(*chain, &blk) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk) - end - - def as_null_object - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - @_null_object = true - ::RSpec::Mocks.space.proxy_for(self).as_null_object - end - - def null_object? - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - defined?(@_null_object) - end - - def received_message?(message, *args, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.space.proxy_for(self).received_message?(message, *args, &block) - end - - unless Class.respond_to? :any_instance - Class.class_exec do - def any_instance - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.space.any_instance_proxy_for(self) - end - end - end - end - end - - # @api private - # Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). - def self.disable_should(syntax_host=::BasicObject) - return unless should_enabled?(syntax_host) - - syntax_host.class_exec do - undef should_receive - undef should_not_receive - undef stub - undef unstub - undef stub_chain - undef as_null_object - undef null_object? - undef received_message? - end - - Class.class_exec do - undef any_instance - end - end - - # @api private - # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). - def self.enable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) - return if expect_enabled?(syntax_host) - - syntax_host.class_exec do - def receive(method_name, &block) - Matchers::Receive.new(method_name, block) - end - - def receive_messages(message_return_value_hash) - matcher = Matchers::ReceiveMessages.new(message_return_value_hash) - matcher.warn_about_block if block_given? - matcher - end - - def receive_message_chain(*messages, &block) - Matchers::ReceiveMessageChain.new(messages, &block) - end - - def allow(target) - AllowanceTarget.new(target) - end - - def expect_any_instance_of(klass) - AnyInstanceExpectationTarget.new(klass) - end - - def allow_any_instance_of(klass) - AnyInstanceAllowanceTarget.new(klass) - end - end - - RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do - def expect(target) - ExpectationTarget.new(target) - end - end - end - - # @api private - # Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). - def self.disable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) - return unless expect_enabled?(syntax_host) - - syntax_host.class_exec do - undef receive - undef receive_messages - undef receive_message_chain - undef allow - undef expect_any_instance_of - undef allow_any_instance_of - end - - RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do - undef expect - end - end - - # @api private - # Indicates whether or not the should syntax is enabled. - def self.should_enabled?(syntax_host=::BasicObject) - syntax_host.method_defined?(:should_receive) - end - - # @api private - # Indicates whether or not the expect syntax is enabled. - def self.expect_enabled?(syntax_host=::RSpec::Mocks::ExampleMethods) - syntax_host.method_defined?(:allow) - end - end - end -end - -# The legacy `:should` syntax adds the following methods directly to -# `BasicObject` so that they are available off of any object. Note, however, -# that this syntax does not always play nice with delegate/proxy objects. -# We recommend you use the non-monkeypatching `:expect` syntax instead. -# @see Class -class BasicObject - # @method should_receive - # Sets an expectation that this object should receive a message before - # the end of the example. - # - # @example - # logger = double('logger') - # thing_that_logs = ThingThatLogs.new(logger) - # logger.should_receive(:log) - # thing_that_logs.do_something_that_logs_a_message - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#expect - - # @method should_not_receive - # Sets and expectation that this object should _not_ receive a message - # during this example. - # @see RSpec::Mocks::ExampleMethods#expect - - # @method stub - # Tells the object to respond to the message with the specified value. - # - # @example - # counter.stub(:count).and_return(37) - # counter.stub(:count => 37) - # counter.stub(:count) { 37 } - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#allow - - # @method unstub - # Removes a stub. On a double, the object will no longer respond to - # `message`. On a real object, the original method (if it exists) is - # restored. - # - # This is rarely used, but can be useful when a stub is set up during a - # shared `before` hook for the common case, but you want to replace it - # for a special case. - # - # @note This is only available when you have enabled the `should` syntax. - - # @method stub_chain - # @overload stub_chain(method1, method2) - # @overload stub_chain("method1.method2") - # @overload stub_chain(method1, method_to_value_hash) - # - # Stubs a chain of methods. - # - # ## Warning: - # - # Chains can be arbitrarily long, which makes it quite painless to - # violate the Law of Demeter in violent ways, so you should consider any - # use of `stub_chain` a code smell. Even though not all code smells - # indicate real problems (think fluent interfaces), `stub_chain` still - # results in brittle examples. For example, if you write - # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the - # implementation calls `foo.baz.bar`, the stub will not work. - # - # @example - # double.stub_chain("foo.bar") { :baz } - # double.stub_chain(:foo, :bar => :baz) - # double.stub_chain(:foo, :bar) { :baz } - # - # # Given any of ^^ these three forms ^^: - # double.foo.bar # => :baz - # - # # Common use in Rails/ActiveRecord: - # Article.stub_chain("recent.published") { [Article.new] } - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#receive_message_chain - - # @method as_null_object - # Tells the object to respond to all messages. If specific stub values - # are declared, they'll work as expected. If not, the receiver is - # returned. - # - # @note This is only available when you have enabled the `should` syntax. - - # @method null_object? - # Returns true if this object has received `as_null_object` - # - # @note This is only available when you have enabled the `should` syntax. -end - -# The legacy `:should` syntax adds the `any_instance` to `Class`. -# We generally recommend you use the newer `:expect` syntax instead, -# which allows you to stub any instance of a class using -# `allow_any_instance_of(klass)` or mock any instance using -# `expect_any_instance_of(klass)`. -# @see BasicObject -class Class - # @method any_instance - # Used to set stubs and message expectations on any instance of a given - # class. Returns a [Recorder](Recorder), which records messages like - # `stub` and `should_receive` for later playback on instances of the - # class. - # - # @example - # Car.any_instance.should_receive(:go) - # race = Race.new - # race.cars << Car.new - # race.go # assuming this delegates to all of its cars - # # this example would pass - # - # Account.any_instance.stub(:balance) { Money.new(:USD, 25) } - # Account.new.balance # => Money.new(:USD, 25)) - # - # @return [Recorder] - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#expect_any_instance_of - # @see RSpec::Mocks::ExampleMethods#allow_any_instance_of -end diff --git a/spec/rspec/mocks/configuration_spec.rb b/spec/rspec/mocks/configuration_spec.rb index 0622f5b7a..7442f90d9 100644 --- a/spec/rspec/mocks/configuration_spec.rb +++ b/spec/rspec/mocks/configuration_spec.rb @@ -2,174 +2,6 @@ module RSpec module Mocks RSpec.describe Configuration do let(:config) { Configuration.new } - let(:mod_1) { Module.new } - let(:mod_2) { Module.new } - - def instance_methods_of(_mod) - mod_1.instance_methods.map(&:to_sym) - end - - it 'adds stub and should_receive to the given modules' do - expect(instance_methods_of(mod_1)).not_to include(:stub, :should_receive) - expect(instance_methods_of(mod_2)).not_to include(:stub, :should_receive) - - config.add_stub_and_should_receive_to(mod_1, mod_2) - - expect(instance_methods_of(mod_1)).to include(:stub, :should_receive) - expect(instance_methods_of(mod_2)).to include(:stub, :should_receive) - end - - shared_examples "configuring the syntax" do - def sandboxed - orig_syntax = RSpec::Mocks.configuration.syntax - yield - ensure - configure_syntax(orig_syntax) - end - - around(:each) { |ex| sandboxed(&ex) } - let(:dbl) { double } - let(:should_methods) { [:should_receive, :stub, :should_not_receive] } - let(:should_class_methods) { [:any_instance] } - let(:expect_methods) { [:receive, :allow, :expect_any_instance_of, :allow_any_instance_of] } - - it 'defaults to enabling both the :should and :expect syntaxes' do - # This is kinda a hack, but since we want to enforce use of - # the expect syntax within our specs here, we have modified the - # config setting, which makes it hard to get at the original - # default value. in spec_helper.rb we store the default value - # in $default_rspec_mocks_syntax so we can use it here. - RSpec::Mocks.configuration.syntax = $default_rspec_mocks_syntax - expect(dbl).to respond_to(*should_methods) - expect(self).to respond_to(*expect_methods) - end - - context 'when configured to :expect' do - before { configure_syntax :expect } - - it 'removes the should methods from every object' do - expect(dbl).not_to respond_to(*should_methods) - end - - it 'removes `any_instance` from every class' do - expect(Class.new).not_to respond_to(*should_class_methods) - end - - it 'adds the expect methods to the example group context' do - expect(self).to respond_to(*expect_methods) - end - - it 'reports that the syntax is :expect' do - expect(configured_syntax).to eq([:expect]) - end - - it 'is a no-op when configured a second time' do - expect(::BasicObject).not_to receive(:method_undefined) - expect(::RSpec::Mocks::ExampleMethods).not_to receive(:method_added) - configure_syntax :expect - end - end - - context 'when configured to :should' do - before { configure_syntax :should } - - it 'adds the should methods to every object' do - expect(dbl).to respond_to(*should_methods) - end - - it 'adds `any_instance` to every class' do - expect(Class.new).to respond_to(*should_class_methods) - end - - it 'removes the expect methods from the example group context' do - expect(self).not_to respond_to(*expect_methods) - end - - it 'reports that the syntax is :should' do - expect(configured_syntax).to eq([:should]) - end - - it "does not warn about the should syntax" do - RSpec.should_not_receive(:deprecate) - Object.new.should_not_receive(:bees) - end - - it 'is a no-op when configured a second time' do - ::BasicObject.should_not_receive(:method_added) - ::RSpec::Mocks::ExampleMethods.should_not_receive(:method_undefined) - configure_syntax :should - end - end - - context 'when configured to [:should, :expect]' do - before { configure_syntax [:should, :expect] } - - it 'adds the should methods to every object' do - expect(dbl).to respond_to(*should_methods) - end - - it 'adds `any_instance` to every class' do - expect(Class.new).to respond_to(*should_class_methods) - end - - it 'adds the expect methods to the example group context' do - expect(self).to respond_to(*expect_methods) - end - - it 'reports that both syntaxes are enabled' do - expect(configured_syntax).to eq([:should, :expect]) - end - - it "does not warn about the should syntax" do - expect(RSpec).not_to receive(:deprecate) - expect(Object.new).not_to receive(:bees) - end - end - end - - describe "configuring rspec-mocks directly" do - it_behaves_like "configuring the syntax" do - def configure_syntax(syntax) - RSpec::Mocks.configuration.syntax = syntax - end - - def configured_syntax - RSpec::Mocks.configuration.syntax - end - - def configure_default_syntax - RSpec::Mocks.configuration.reset_syntaxes_to_default - end - end - end - - describe "configuring using the rspec-core config API" do - it_behaves_like "configuring the syntax" do - def configure_syntax(syntax) - RSpec.configure do |rspec| - rspec.mock_with :rspec do |c| - c.syntax = syntax - end - end - end - - def configured_syntax - RSpec.configure do |rspec| - rspec.mock_with :rspec do |c| - return c.syntax - end - end - end - - def configure_default_syntax - RSpec.configure do |rspec| - rspec.mock_with :rspec do |c| - c.reset_syntaxes_to_default - end - end - end - end - end describe "#when_declaring_verifying_double" do include_context 'with isolated configuration' diff --git a/spec/rspec/mocks/matchers/receive_message_chain_spec.rb b/spec/rspec/mocks/matchers/receive_message_chain_spec.rb index a5ffa6c8e..f583201f1 100644 --- a/spec/rspec/mocks/matchers/receive_message_chain_spec.rb +++ b/spec/rspec/mocks/matchers/receive_message_chain_spec.rb @@ -2,241 +2,227 @@ module RSpec::Mocks::Matchers RSpec.describe "receive_message_chain" do let(:object) { double(:object) } - context "with only the expect syntax enabled" do - include_context "with syntax", :expect - - it "errors with a negative allowance" do - expect { - allow(object).not_to receive_message_chain(:to_a) - }.to raise_error(RSpec::Mocks::NegationUnsupportedError) - end - - it "errors with a negative expectation" do - expect { - expect(object).not_to receive_message_chain(:to_a) - }.to raise_error(RSpec::Mocks::NegationUnsupportedError) - end - - it "errors with a negative any_instance expectation" do - expect { - expect_any_instance_of(Object).not_to receive_message_chain(:to_a) - }.to raise_error(RSpec::Mocks::NegationUnsupportedError) - end - - it "errors with a negative any_instance allowance" do - expect { - allow_any_instance_of(Object).not_to receive_message_chain(:to_a) - }.to raise_error(RSpec::Mocks::NegationUnsupportedError) - end + it "errors with a negative allowance" do + expect { + allow(object).not_to receive_message_chain(:to_a) + }.to raise_error(RSpec::Mocks::NegationUnsupportedError) + end - it "works with a do block" do - allow(object).to receive_message_chain(:to_a, :length) do - 3 - end + it "errors with a negative expectation" do + expect { + expect(object).not_to receive_message_chain(:to_a) + }.to raise_error(RSpec::Mocks::NegationUnsupportedError) + end - expect(object.to_a.length).to eq(3) - end + it "errors with a negative any_instance expectation" do + expect { + expect_any_instance_of(Object).not_to receive_message_chain(:to_a) + }.to raise_error(RSpec::Mocks::NegationUnsupportedError) + end - it "works with a {} block" do - allow(object).to receive_message_chain(:to_a, :length) { 3 } + it "errors with a negative any_instance allowance" do + expect { + allow_any_instance_of(Object).not_to receive_message_chain(:to_a) + }.to raise_error(RSpec::Mocks::NegationUnsupportedError) + end - expect(object.to_a.length).to eq(3) + it "works with a do block" do + allow(object).to receive_message_chain(:to_a, :length) do + 3 end - it "gives the { } block prescedence over the do block" do - allow(object).to receive_message_chain(:to_a, :length) { 3 } do - 4 - end - - expect(object.to_a.length).to eq(3) - end + expect(object.to_a.length).to eq(3) + end - it "works with and_return" do - allow(object).to receive_message_chain(:to_a, :length).and_return(3) + it "works with a {} block" do + allow(object).to receive_message_chain(:to_a, :length) { 3 } - expect(object.to_a.length).to eq(3) - end + expect(object.to_a.length).to eq(3) + end - it "can constrain the return value by the argument to the last call" do - allow(object).to receive_message_chain(:one, :plus).with(1) { 2 } - allow(object).to receive_message_chain(:one, :plus).with(2) { 3 } - expect(object.one.plus(1)).to eq(2) - expect(object.one.plus(2)).to eq(3) + it "gives the { } block prescedence over the do block" do + allow(object).to receive_message_chain(:to_a, :length) { 3 } do + 4 end - it "works with and_call_original", :pending => "See https://github.com/rspec/rspec-mocks/pull/467#issuecomment-28631621" do - list = [1, 2, 3] - expect(list).to receive_message_chain(:to_a, :length).and_call_original - expect(list.to_a.length).to eq(3) - end + expect(object.to_a.length).to eq(3) + end - it "fails with and_call_original when the entire chain is not called", :pending => "See https://github.com/rspec/rspec-mocks/pull/467#issuecomment-28631621" do - list = [1, 2, 3] - expect(list).to receive_message_chain(:to_a, :length).and_call_original - expect(list.to_a).to eq([1, 2, 3]) - end + it "works with and_return" do + allow(object).to receive_message_chain(:to_a, :length).and_return(3) - it "works with and_raise" do - allow(object).to receive_message_chain(:to_a, :length).and_raise(StandardError.new("hi")) + expect(object.to_a.length).to eq(3) + end - expect { object.to_a.length }.to raise_error(StandardError, "hi") - end + it "can constrain the return value by the argument to the last call" do + allow(object).to receive_message_chain(:one, :plus).with(1) { 2 } + allow(object).to receive_message_chain(:one, :plus).with(2) { 3 } + expect(object.one.plus(1)).to eq(2) + expect(object.one.plus(2)).to eq(3) + end - it "works with and_throw" do - allow(object).to receive_message_chain(:to_a, :length).and_throw(:nope) + it "works with and_call_original", :pending => "See https://github.com/rspec/rspec-mocks/pull/467#issuecomment-28631621" do + list = [1, 2, 3] + expect(list).to receive_message_chain(:to_a, :length).and_call_original + expect(list.to_a.length).to eq(3) + end - expect { object.to_a.length }.to throw_symbol(:nope) - end + it "fails with and_call_original when the entire chain is not called", :pending => "See https://github.com/rspec/rspec-mocks/pull/467#issuecomment-28631621" do + list = [1, 2, 3] + expect(list).to receive_message_chain(:to_a, :length).and_call_original + expect(list.to_a).to eq([1, 2, 3]) + end - it "works with and_yield" do - allow(object).to receive_message_chain(:to_a, :length).and_yield(3) + it "works with and_raise" do + allow(object).to receive_message_chain(:to_a, :length).and_raise(StandardError.new("hi")) - expect { |blk| object.to_a.length(&blk) }.to yield_with_args(3) - end + expect { object.to_a.length }.to raise_error(StandardError, "hi") + end - it "works with a string of messages to chain" do - allow(object).to receive_message_chain("to_a.length").and_yield(3) + it "works with and_throw" do + allow(object).to receive_message_chain(:to_a, :length).and_throw(:nope) - expect { |blk| object.to_a.length(&blk) }.to yield_with_args(3) - end + expect { object.to_a.length }.to throw_symbol(:nope) + end - it "works with a hash return as the last argument in the chain" do - allow(object).to receive_message_chain(:to_a, :length => 3) + it "works with and_yield" do + allow(object).to receive_message_chain(:to_a, :length).and_yield(3) - expect(object.to_a.length).to eq(3) - end + expect { |blk| object.to_a.length(&blk) }.to yield_with_args(3) + end - it "accepts any number of arguments to the stubbed messages" do - allow(object).to receive_message_chain(:msg1, :msg2).and_return(:return_value) + it "works with a string of messages to chain" do + allow(object).to receive_message_chain("to_a.length").and_yield(3) - expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value) - end + expect { |blk| object.to_a.length(&blk) }.to yield_with_args(3) + end - it "accepts any number of arguments to the stubbed messages with an inline hash return value" do - allow(object).to receive_message_chain(:msg1, :msg2 => :return_value) + it "works with a hash return as the last argument in the chain" do + allow(object).to receive_message_chain(:to_a, :length => 3) - expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value) - end + expect(object.to_a.length).to eq(3) + end - it "raises when expect is used and some of the messages in the chain aren't called" do - expect { - expect(object).to receive_message_chain(:to_a, :farce, :length => 3) - object.to_a - verify_all - }.to fail - end + it "accepts any number of arguments to the stubbed messages" do + allow(object).to receive_message_chain(:msg1, :msg2).and_return(:return_value) - it "raises when expect is used and all but the last message in the chain are called" do - expect { - expect(object).to receive_message_chain(:foo, :bar, :baz) - object.foo.bar - verify_all - }.to fail - end + expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value) + end - it "does not raise when expect is used and the entire chain is called" do - expect { - expect(object).to receive_message_chain(:to_a, :length => 3) - object.to_a.length - verify_all - }.not_to raise_error - end + it "accepts any number of arguments to the stubbed messages with an inline hash return value" do + allow(object).to receive_message_chain(:msg1, :msg2 => :return_value) - it "works with allow_any_instance" do - o = Object.new + expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value) + end - allow_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3) + it "raises when expect is used and some of the messages in the chain aren't called" do + expect { + expect(object).to receive_message_chain(:to_a, :farce, :length => 3) + object.to_a + verify_all + }.to fail + end - expect(o.to_a.length).to eq(3) - end + it "raises when expect is used and all but the last message in the chain are called" do + expect { + expect(object).to receive_message_chain(:foo, :bar, :baz) + object.foo.bar + verify_all + }.to fail + end - it "stubs already stubbed instances when using `allow_any_instance_of`" do - o = Object.new - allow(o).to receive(:foo).and_return(dbl = double) - expect(o.foo).to be(dbl) + it "does not raise when expect is used and the entire chain is called" do + expect { + expect(object).to receive_message_chain(:to_a, :length => 3) + object.to_a.length + verify_all + }.not_to raise_error + end - allow_any_instance_of(Object).to receive_message_chain(:foo, :bar).and_return("bazz") - expect(o.foo.bar).to eq("bazz") - end + it "works with allow_any_instance" do + o = Object.new - it "fails when with expect_any_instance_of is used and the entire chain is not called" do - expect { - expect_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3) - verify_all - }.to fail - end + allow_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3) - it "affects previously stubbed instances when `expect_any_instance_of` is called" do - o = Object.new - allow(o).to receive(:foo).and_return(double) + expect(o.to_a.length).to eq(3) + end - expect_any_instance_of(Object).to receive_message_chain(:foo, :bar => 3) - expect(o.foo.bar).to eq(3) - end + it "stubs already stubbed instances when using `allow_any_instance_of`" do + o = Object.new + allow(o).to receive(:foo).and_return(dbl = double) + expect(o.foo).to be(dbl) - it "passes when with expect_any_instance_of is used and the entire chain is called" do - o = Object.new + allow_any_instance_of(Object).to receive_message_chain(:foo, :bar).and_return("bazz") + expect(o.foo.bar).to eq("bazz") + end + it "fails when with expect_any_instance_of is used and the entire chain is not called" do + expect { expect_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3) - o.to_a.length - end + verify_all + }.to fail + end - it "works with expect where the first level of the chain is already expected" do - o = Object.new - expect(o).to receive(:foo).and_return(double) - expect(o).to receive_message_chain(:foo, :bar, :baz) + it "affects previously stubbed instances when `expect_any_instance_of` is called" do + o = Object.new + allow(o).to receive(:foo).and_return(double) - o.foo.bar.baz - end + expect_any_instance_of(Object).to receive_message_chain(:foo, :bar => 3) + expect(o.foo.bar).to eq(3) + end - it "works with allow where the first level of the chain is already expected" do - o = Object.new - expect(o).to receive(:foo).and_return(double) - allow(o).to receive_message_chain(:foo, :bar, :baz).and_return(3) + it "passes when with expect_any_instance_of is used and the entire chain is called" do + o = Object.new - expect(o.foo.bar.baz).to eq(3) - end + expect_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3) + o.to_a.length + end - it "works with expect where the first level of the chain is already stubbed" do - o = Object.new - allow(o).to receive(:foo).and_return(double) - expect(o).to receive_message_chain(:foo, :bar, :baz) + it "works with expect where the first level of the chain is already expected" do + o = Object.new + expect(o).to receive(:foo).and_return(double) + expect(o).to receive_message_chain(:foo, :bar, :baz) - o.foo.bar.baz - end + o.foo.bar.baz + end - it "works with allow where the first level of the chain is already stubbed" do - o = Object.new - allow(o).to receive(:foo).and_return(double) - allow(o).to receive_message_chain(:foo, :bar, :baz).and_return(3) + it "works with allow where the first level of the chain is already expected" do + o = Object.new + expect(o).to receive(:foo).and_return(double) + allow(o).to receive_message_chain(:foo, :bar, :baz).and_return(3) - expect(o.foo.bar.baz).to eq(3) - end + expect(o.foo.bar.baz).to eq(3) + end - it "provides a matcher description (when passing a string)" do - matcher = receive_message_chain("foo.bar.bazz") - expect(matcher.description).to eq("receive message chain foo.bar.bazz") - end + it "works with expect where the first level of the chain is already stubbed" do + o = Object.new + allow(o).to receive(:foo).and_return(double) + expect(o).to receive_message_chain(:foo, :bar, :baz) - it "provides a matcher description (when passing symbols)" do - matcher = receive_message_chain(:foo, :bar, :bazz) - expect(matcher.description).to eq("receive message chain foo.bar.bazz") - end + o.foo.bar.baz + end - it "provides a matcher description (when passing symbols and a hash)" do - matcher = receive_message_chain(:foo, :bar, :bazz => 3) - expect(matcher.description).to eq("receive message chain foo.bar.bazz") - end + it "works with allow where the first level of the chain is already stubbed" do + o = Object.new + allow(o).to receive(:foo).and_return(double) + allow(o).to receive_message_chain(:foo, :bar, :baz).and_return(3) + + expect(o.foo.bar.baz).to eq(3) end - context "when the expect and should syntaxes are enabled" do - include_context "with syntax", [:expect, :should] + it "provides a matcher description (when passing a string)" do + matcher = receive_message_chain("foo.bar.bazz") + expect(matcher.description).to eq("receive message chain foo.bar.bazz") + end - it "stubs the message correctly" do - allow(object).to receive_message_chain(:to_a, :length) + it "provides a matcher description (when passing symbols)" do + matcher = receive_message_chain(:foo, :bar, :bazz) + expect(matcher.description).to eq("receive message chain foo.bar.bazz") + end - expect { object.to_a.length }.not_to raise_error - end + it "provides a matcher description (when passing symbols and a hash)" do + matcher = receive_message_chain(:foo, :bar, :bazz => 3) + expect(matcher.description).to eq("receive message chain foo.bar.bazz") end end end diff --git a/spec/rspec/mocks/matchers/receive_spec.rb b/spec/rspec/mocks/matchers/receive_spec.rb index 7937e666b..8b2dfdb44 100644 --- a/spec/rspec/mocks/matchers/receive_spec.rb +++ b/spec/rspec/mocks/matchers/receive_spec.rb @@ -1,36 +1,6 @@ module RSpec module Mocks RSpec.describe Matchers::Receive do - include_context "with syntax", :expect - - describe "expectations/allowances on any instance recorders" do - include_context "with syntax", [:expect, :should] - - it "warns about allow(Klass.any_instance).to receive..." do - expect(RSpec).to receive(:warning).with(/allow.*any_instance.*is probably not what you meant.*allow_any_instance_of.*instead/) - allow(Object.any_instance).to receive(:foo) - end - - it "includes the correct call site in the allow warning" do - expect_warning_with_call_site(__FILE__, __LINE__ + 1) - allow(Object.any_instance).to receive(:foo) - end - - it "warns about expect(Klass.any_instance).to receive..." do - expect(RSpec).to receive(:warning).with(/expect.*any_instance.*is probably not what you meant.*expect_any_instance_of.*instead/) - any_instance_proxy = Object.any_instance - expect(any_instance_proxy).to receive(:foo) - any_instance_proxy.foo - end - - it "includes the correct call site in the expect warning" do - any_instance_proxy = Object.any_instance - expect_warning_with_call_site(__FILE__, __LINE__ + 1) - expect(any_instance_proxy).to receive(:foo) - any_instance_proxy.foo - end - end - shared_examples "a receive matcher" do |*options| it 'allows the caller to configure how the subject responds' do wrapped.to receive(:foo).and_return(5) @@ -123,7 +93,7 @@ module Mocks end end - shared_examples "an expect syntax allowance" do |*options| + shared_examples "an allowance" do |*options| it_behaves_like "a receive matcher", *options it 'does not expect the message to be received' do @@ -132,7 +102,7 @@ module Mocks end end - shared_examples "an expect syntax negative allowance" do + shared_examples "a negative allowance" do it 'is disabled since this expression is confusing' do expect { wrapped.not_to receive(:foo) @@ -144,7 +114,7 @@ module Mocks end end - shared_examples "an expect syntax expectation" do |*options| + shared_examples "an expectation" do |*options| it_behaves_like "a receive matcher", *options it 'sets up a message expectation that passes if the message is received' do @@ -180,7 +150,7 @@ module Mocks end end - shared_examples "an expect syntax negative expectation" do + shared_examples "a negative expectation" do it 'sets up a negative message expectation that passes if the message is not received' do wrapped.not_to receive(:foo) verify_all @@ -266,7 +236,7 @@ def receiver.method_missing(*); end # a poor man's stub... end describe "allow(...).to receive" do - it_behaves_like "an expect syntax allowance" do + it_behaves_like "an allowance" do let(:receiver) { double } let(:wrapped) { allow(receiver) } end @@ -322,13 +292,13 @@ def receiver.method_missing(*); end # a poor man's stub... end describe "allow(...).not_to receive" do - it_behaves_like "an expect syntax negative allowance" do + it_behaves_like "a negative allowance" do let(:wrapped) { allow(double) } end end describe "allow_any_instance_of(...).to receive" do - it_behaves_like "an expect syntax allowance" do + it_behaves_like "an allowance" do let(:klass) { Class.new } let(:wrapped) { allow_any_instance_of(klass) } let(:receiver) { klass.new } @@ -340,13 +310,13 @@ def receiver.method_missing(*); end # a poor man's stub... end describe "allow_any_instance_of(...).not_to receive" do - it_behaves_like "an expect syntax negative allowance" do + it_behaves_like "a negative allowance" do let(:wrapped) { allow_any_instance_of(Class.new) } end end describe "expect(...).to receive" do - it_behaves_like "an expect syntax expectation", :allow_other_matchers do + it_behaves_like "an expectation", :allow_other_matchers do let(:receiver) { double } let(:wrapped) { expect(receiver) } @@ -461,7 +431,7 @@ def receiver.method_missing(*); end # a poor man's stub... end describe "expect_any_instance_of(...).to receive" do - it_behaves_like "an expect syntax expectation", :does_not_report_line_num do + it_behaves_like "an expectation", :does_not_report_line_num do let(:klass) { Class.new } let(:wrapped) { expect_any_instance_of(klass) } let(:receiver) { klass.new } @@ -477,14 +447,14 @@ def receiver.method_missing(*); end # a poor man's stub... end describe "expect(...).not_to receive" do - it_behaves_like "an expect syntax negative expectation" do + it_behaves_like "a negative expectation" do let(:receiver) { double } let(:wrapped) { expect(receiver) } end end describe "expect_any_instance_of(...).not_to receive" do - it_behaves_like "an expect syntax negative expectation" do + it_behaves_like "a negative expectation" do let(:klass) { Class.new } let(:wrapped) { expect_any_instance_of(klass) } let(:receiver) { klass.new } @@ -558,16 +528,6 @@ def eq(_) end }.to raise_error(/only the `receive`, `have_received` and `receive_messages` matchers are supported with `expect\(...\).to`/) end - - it 'can toggle the available syntax' do - expect(framework.new).to respond_to(:expect) - RSpec::Mocks.configuration.syntax = :should - expect(framework.new).not_to respond_to(:expect) - RSpec::Mocks.configuration.syntax = :expect - expect(framework.new).to respond_to(:expect) - end - - after { RSpec::Mocks.configuration.syntax = :expect } end context "when rspec-expectations is included in the test framework first" do diff --git a/spec/rspec/mocks/methods_spec.rb b/spec/rspec/mocks/methods_spec.rb deleted file mode 100644 index 09cb1dd91..000000000 --- a/spec/rspec/mocks/methods_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -module RSpec - module Mocks - RSpec.describe "Methods added to every object" do - include_context "with syntax", :expect - - def added_methods - host = Class.new - orig_instance_methods = host.instance_methods - Syntax.enable_should(host) - (host.instance_methods - orig_instance_methods).map(&:to_sym) - end - - it 'limits the number of methods that get added to all objects' do - # If really necessary, you can add to this list, but long term, - # we are hoping to cut down on the number of methods added to all objects - expect(added_methods).to match_array([ - :as_null_object, :null_object?, - :received_message?, :should_not_receive, :should_receive, - :stub, :stub_chain, :unstub - ]) - end - end - end -end diff --git a/spec/rspec/mocks/null_object_double_spec.rb b/spec/rspec/mocks/null_object_double_spec.rb index 0a8a06201..5eadc75a7 100644 --- a/spec/rspec/mocks/null_object_double_spec.rb +++ b/spec/rspec/mocks/null_object_double_spec.rb @@ -108,6 +108,11 @@ module Mocks obj = double('anything').as_null_object expect(obj).to be_null_object end + + it 'supports chainable calls' do + obj = double("foo").as_null_object + expect(obj.foo.bar.bazz).to be(obj) + end end RSpec.describe "#null_object?" do @@ -116,14 +121,5 @@ module Mocks expect(obj).not_to be_null_object end end - - RSpec.describe "when using the :expect syntax" do - include_context "with syntax", :expect - - it 'still supports null object doubles' do - obj = double("foo").as_null_object - expect(obj.foo.bar.bazz).to be(obj) - end - end end end diff --git a/spec/rspec/mocks/should_syntax_spec.rb b/spec/rspec/mocks/should_syntax_spec.rb deleted file mode 100644 index eb00597ed..000000000 --- a/spec/rspec/mocks/should_syntax_spec.rb +++ /dev/null @@ -1,543 +0,0 @@ -require 'support/before_all_shared_example_group' - -RSpec.describe "Using the legacy should syntax" do - include_context "with syntax", [:should, :expect] - - describe "#received_message?" do - let(:dbl) { double("double").as_null_object } - - it "answers false for received_message? when no messages received" do - expect(dbl.received_message?(:message)).to be_falsey - end - - it "answers true for received_message? when message received" do - dbl.message - expect(dbl.received_message?(:message)).to be_truthy - end - - it "answers true for received_message? when message received with correct args" do - dbl.message 1, 2, 3 - expect(dbl.received_message?(:message, 1, 2, 3)).to be_truthy - end - - it "answers false for received_message? when message received with incorrect args" do - dbl.message 1, 2, 3 - expect(dbl.received_message?(:message, 1, 2)).to be_falsey - end - end - - describe "#stub" do - it "supports options" do - double.stub(:foo, :expected_from => "bar") - end - - it 'returns `nil` from all terminal actions to discourage further configuration' do - expect(double.stub(:foo).and_return(1)).to be_nil - expect(double.stub(:foo).and_raise("boom")).to be_nil - expect(double.stub(:foo).and_throw(:foo)).to be_nil - end - - it 'sets up a canned response' do - dbl = double - dbl.stub(:foo).and_return(3) - expect(dbl.foo).to eq(3) - end - - it 'can stub multiple messages using a hash' do - dbl = double - dbl.stub(:foo => 2, :bar => 1) - expect(dbl.foo).to eq(2) - expect(dbl.bar).to eq(1) - end - - include_examples "fails in a before(:all) block" do - def use_rspec_mocks - Object.stub(:foo) - end - end - end - - describe "#stub_chain" do - it 'can stub a sequence of messages' do - dbl = double - dbl.stub_chain(:foo, :bar, :baz => 17) - expect(dbl.foo.bar.baz).to eq(17) - expect { - dbl.foo.baz.bar - }.to fail - end - - include_examples "fails in a before(:all) block" do - def use_rspec_mocks - Object.stub_chain(:foo, :bar) - end - end - end - - describe "#unstub" do - include_examples "fails in a before(:all) block" do - def use_rspec_mocks - Object.unstub(:foo) - end - end - - it "replaces the stubbed method with the original method" do - obj = Object.new - def obj.foo; :original; end - obj.stub(:foo) - obj.unstub(:foo) - expect(obj.foo).to eq :original - end - - it "removes all stubs with the supplied method name" do - obj = Object.new - def obj.foo; :original; end - obj.stub(:foo).with(1) - obj.stub(:foo).with(2) - obj.unstub(:foo) - expect(obj.foo).to eq :original - end - - it "does not remove any expectations with the same method name" do - obj = Object.new - def obj.foo; :original; end - obj.should_receive(:foo).with(3).and_return(:three) - obj.stub(:foo).with(1) - obj.stub(:foo).with(2) - obj.unstub(:foo) - expect(obj.foo(3)).to eq :three - end - - it "restores the correct implementations when stubbed and unstubbed on a parent and child class" do - parent = Class.new - child = Class.new(parent) - - parent.stub(:new) - child.stub(:new) - parent.unstub(:new) - child.unstub(:new) - - expect(parent.new).to be_an_instance_of parent - expect(child.new).to be_an_instance_of child - end - - it "raises a MockExpectationError if the method has not been stubbed" do - obj = Object.new - expect { - obj.unstub(:foo) - }.to fail - end - end - - describe "#should_receive" do - it 'fails on verification if the message is not received' do - dbl = double - dbl.should_receive(:foo) - expect { verify_all }.to fail - end - - it 'does not fail on verification if the message is received' do - dbl = double - dbl.should_receive(:foo) - dbl.foo - expect { verify_all }.not_to raise_error - end - - it 'can set a canned response' do - dbl = double - dbl.should_receive(:bar).and_return(3) - expect(dbl.bar).to eq(3) - end - - include_examples "fails in a before(:all) block" do - def use_rspec_mocks - Object.should_receive(:foo) - end - end - - context "with an options hash" do - it "reports the file and line submitted with :expected_from" do - begin - mock = RSpec::Mocks::Double.new("a mock") - mock.should_receive(:message, :expected_from => "/path/to/blah.ext:37") - verify mock - rescue Exception => e - ensure - expect(e.backtrace.to_s).to match(%r{/path/to/blah.ext:37}m) - end - end - - it "uses the message supplied with :message" do - expect { - m = RSpec::Mocks::Double.new("a mock") - m.should_receive(:message, :message => "recebi nada") - verify m - }.to raise_error("recebi nada") - end - - it "uses the message supplied with :message after a similar stub" do - expect { - m = RSpec::Mocks::Double.new("a mock") - m.stub(:message) - m.should_receive(:message, :message => "from mock") - verify m - }.to raise_error("from mock") - end - end - end - - describe "#should_not_receive" do - it "returns a negative message expectation" do - expect(Object.new.should_not_receive(:foobar)).to be_negative - end - - it 'fails when the message is received' do - with_unfulfilled_double do |dbl| - dbl.should_not_receive(:foo) - expect { dbl.foo }.to fail - end - end - - it 'does not fail on verification if the message is not received' do - dbl = double - dbl.should_not_receive(:foo) - expect { verify_all }.not_to raise_error - end - - include_examples "fails in a before(:all) block" do - def use_rspec_mocks - Object.should_not_receive(:foo) - end - end - end - - describe "#any_instance" do - let(:klass) do - Class.new do - def existing_method; :existing_method_return_value; end - def existing_method_with_arguments(_a, _b=nil); :existing_method_with_arguments_return_value; end - def another_existing_method; end - private - def private_method; :private_method_return_value; end - end - end - - include_examples "fails in a before(:all) block" do - def use_rspec_mocks - Object.any_instance.should_receive(:foo) - end - end - - it "adds a class to the current space" do - expect { - klass.any_instance - }.to change { RSpec::Mocks.space.any_instance_recorders.size }.by(1) - end - - it 'can stub a method' do - klass.any_instance.stub(:foo).and_return(2) - expect(klass.new.foo).to eq(2) - end - - it 'can mock a method' do - klass.any_instance.should_receive(:foo) - klass.new - expect { verify_all }.to fail - end - - it 'can get method objects for the fluent interface' do - and_return = klass.any_instance.stub(:foo).method(:and_return) - and_return.call(23) - - expect(klass.new.foo).to eq(23) - end - - it 'affects previously stubbed instances when stubbing a method' do - instance = klass.new - klass.any_instance.stub(:foo).and_return(2) - expect(instance.foo).to eq(2) - klass.any_instance.stub(:foo).and_return(1) - expect(instance.foo).to eq(1) - end - - it 'affects previously stubbed instances when mocking a method' do - instance = klass.new - klass.any_instance.stub(:foo).and_return(2) - expect(instance.foo).to eq(2) - klass.any_instance.should_receive(:foo).and_return(1) - expect(instance.foo).to eq(1) - end - - context "invocation order" do - describe "#stub" do - it "raises an error if 'stub' follows 'with'" do - expect { klass.any_instance.with("1").stub(:foo) }.to raise_error(NoMethodError) - end - - it "raises an error if 'with' follows 'and_return'" do - expect { klass.any_instance.stub(:foo).and_return(1).with("1") }.to raise_error(NoMethodError) - end - - it "raises an error if 'with' follows 'and_raise'" do - expect { klass.any_instance.stub(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError) - end - - it "raises an error if 'with' follows 'and_yield'" do - expect { klass.any_instance.stub(:foo).and_yield(1).with("1") }.to raise_error(NoMethodError) - end - - context "behaves as 'every instance'" do - let(:super_class) { Class.new { def foo; 'bar'; end } } - let(:sub_class) { Class.new(super_class) } - - it 'handles `unstub` on subclasses' do - super_class.any_instance.stub(:foo) - sub_class.any_instance.stub(:foo) - sub_class.any_instance.unstub(:foo) - expect(sub_class.new.foo).to eq("bar") - end - end - end - - describe "#stub_chain" do - it "raises an error if 'stub_chain' follows 'and_return'" do - expect { klass.any_instance.and_return("1").stub_chain(:foo, :bar) }.to raise_error(NoMethodError) - end - - context "allows a chain of methods to be stubbed using #stub_chain" do - example "given symbols representing the methods" do - klass.any_instance.stub_chain(:one, :two, :three).and_return(:four) - expect(klass.new.one.two.three).to eq(:four) - end - - example "given a hash as the last argument uses the value as the expected return value" do - klass.any_instance.stub_chain(:one, :two, :three => :four) - expect(klass.new.one.two.three).to eq(:four) - end - - example "given a string of '.' separated method names representing the chain" do - klass.any_instance.stub_chain('one.two.three').and_return(:four) - expect(klass.new.one.two.three).to eq(:four) - end - end - - it 'affects previously stubbed instances' do - instance = klass.new - dbl = double - klass.any_instance.stub(:foo).and_return(dbl) - expect(instance.foo).to eq(dbl) - klass.any_instance.stub_chain(:foo, :bar => 3) - expect(instance.foo.bar).to eq(3) - end - end - - describe "#should_receive" do - it "raises an error if 'should_receive' follows 'with'" do - expect { klass.any_instance.with("1").should_receive(:foo) }.to raise_error(NoMethodError) - end - end - - describe "#should_not_receive" do - it "fails if the method is called" do - klass.any_instance.should_not_receive(:existing_method) - instance = klass.new - expect_fast_failure_from(instance) do - instance.existing_method - end - end - - it "passes if no method is called" do - expect { klass.any_instance.should_not_receive(:existing_method) }.to_not raise_error - end - - it "passes if only a different method is called" do - klass.any_instance.should_not_receive(:existing_method) - expect { klass.new.another_existing_method }.to_not raise_error - end - - context "with constraints" do - it "fails if the method is called with the specified parameters" do - klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two) - instance = klass.new - expect_fast_failure_from(instance) do - instance.existing_method_with_arguments(:argument_one, :argument_two) - end - end - - it "passes if the method is called with different parameters" do - klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two) - expect { klass.new.existing_method_with_arguments(:argument_three, :argument_four) }.to_not raise_error - end - end - - context 'when used in combination with should_receive' do - it 'passes if only the expected message is received' do - klass.any_instance.should_receive(:foo) - klass.any_instance.should_not_receive(:bar) - klass.new.foo - verify_all - end - end - - it "prevents confusing double-negative expressions involving `never`" do - expect { - klass.any_instance.should_not_receive(:not_expected).never - }.to raise_error(/trying to negate it again/) - end - end - - describe "#unstub" do - it "replaces the stubbed method with the original method" do - klass.any_instance.stub(:existing_method) - klass.any_instance.unstub(:existing_method) - expect(klass.new.existing_method).to eq(:existing_method_return_value) - end - - it "removes all stubs with the supplied method name" do - klass.any_instance.stub(:existing_method).with(1) - klass.any_instance.stub(:existing_method).with(2) - klass.any_instance.unstub(:existing_method) - expect(klass.new.existing_method).to eq(:existing_method_return_value) - end - - it "removes stubs even if they have already been invoked" do - klass.any_instance.stub(:existing_method).and_return(:any_instance_value) - obj = klass.new - obj.existing_method - klass.any_instance.unstub(:existing_method) - expect(obj.existing_method).to eq(:existing_method_return_value) - end - - it "removes stubs from sub class after invokation when super class was originally stubbed" do - klass.any_instance.stub(:existing_method).and_return(:any_instance_value) - obj = Class.new(klass).new - expect(obj.existing_method).to eq(:any_instance_value) - klass.any_instance.unstub(:existing_method) - expect(obj.existing_method).to eq(:existing_method_return_value) - end - - it "removes stubs set directly on an instance" do - klass.any_instance.stub(:existing_method).and_return(:any_instance_value) - obj = klass.new - obj.stub(:existing_method).and_return(:local_method) - klass.any_instance.unstub(:existing_method) - expect(obj.existing_method).to eq(:existing_method_return_value) - end - - it "does not remove message expectations set directly on an instance" do - klass.any_instance.stub(:existing_method).and_return(:any_instance_value) - obj = klass.new - obj.should_receive(:existing_method).and_return(:local_method) - klass.any_instance.unstub(:existing_method) - expect(obj.existing_method).to eq(:local_method) - end - - it "does not remove any expectations with the same method name" do - klass.any_instance.should_receive(:existing_method_with_arguments).with(3).and_return(:three) - klass.any_instance.stub(:existing_method_with_arguments).with(1) - klass.any_instance.stub(:existing_method_with_arguments).with(2) - klass.any_instance.unstub(:existing_method_with_arguments) - expect(klass.new.existing_method_with_arguments(3)).to eq(:three) - end - - it "raises a MockExpectationError if the method has not been stubbed" do - expect { - klass.any_instance.unstub(:existing_method) - }.to fail_with 'The method `existing_method` was not stubbed or was already unstubbed' - end - - it 'does not get confused about string vs symbol usage for the message' do - klass.any_instance.stub(:existing_method) { :stubbed } - klass.any_instance.unstub("existing_method") - expect(klass.new.existing_method).to eq(:existing_method_return_value) - end - end - end - end -end - -RSpec.context "with default syntax configuration" do - orig_syntax = nil - - before(:all) { orig_syntax = RSpec::Mocks.configuration.syntax } - after(:all) { RSpec::Mocks.configuration.syntax = orig_syntax } - before { RSpec::Mocks.configuration.reset_syntaxes_to_default } - - let(:expected_arguments) { - [ - /Using.*without explicitly enabling/, - {:replacement => "the new `:expect` syntax or explicitly enable `:should`"} - ] - } - - it "it warns about should once, regardless of how many times it is called" do - expect(RSpec).to receive(:deprecate).with(*expected_arguments) - o = Object.new - o2 = Object.new - o.should_receive(:bees) - o2.should_receive(:bees) - - o.bees - o2.bees - end - - it "warns about should not once, regardless of how many times it is called" do - expect(RSpec).to receive(:deprecate).with(*expected_arguments) - o = Object.new - o2 = Object.new - o.should_not_receive(:bees) - o2.should_not_receive(:bees) - end - - it "warns about stubbing once, regardless of how many times it is called" do - expect(RSpec).to receive(:deprecate).with(*expected_arguments) - o = Object.new - o2 = Object.new - - o.stub(:faces) - o2.stub(:faces) - end - - it "warns about unstubbing once, regardless of how many times it is called" do - expect(RSpec).to receive(:deprecate).with(/Using.*without explicitly enabling/, - :replacement => "`allow(...).to receive(...).and_call_original` or explicitly enable `:should`") - o = Object.new - o2 = Object.new - - allow(o).to receive(:faces) - allow(o2).to receive(:faces) - - o.unstub(:faces) - o2.unstub(:faces) - end - - it "doesn't warn about stubbing after a reset and setting should" do - expect(RSpec).not_to receive(:deprecate) - RSpec::Mocks.configuration.reset_syntaxes_to_default - RSpec::Mocks.configuration.syntax = :should - o = Object.new - o2 = Object.new - o.stub(:faces) - o2.stub(:faces) - end - - it "includes the call site in the deprecation warning" do - obj = Object.new - expect_deprecation_with_call_site(__FILE__, __LINE__ + 1) - obj.stub(:faces) - end -end - -RSpec.context "when the should syntax is enabled on a non-default syntax host" do - include_context "with the default mocks syntax" - - it "continues to warn about the should syntax" do - my_host = Class.new - expect(RSpec).to receive(:deprecate) - RSpec::Mocks::Syntax.enable_should(my_host) - - o = Object.new - o.should_receive(:bees) - o.bees - end -end diff --git a/spec/rspec/mocks/test_double_spec.rb b/spec/rspec/mocks/test_double_spec.rb index 51c713642..3cbba56c2 100644 --- a/spec/rspec/mocks/test_double_spec.rb +++ b/spec/rspec/mocks/test_double_spec.rb @@ -30,7 +30,7 @@ module Mocks end end - RSpec.shared_examples_for "a copy method" do |method| + shared_examples_for "a copy method" do |method| it "copies the `as_null_object` state when #{method}'d" do dbl = double.as_null_object copy = dbl.__send__(method) @@ -38,20 +38,11 @@ module Mocks end end - include_examples "a copy method", :dup - include_examples "a copy method", :clone + it 'stubs the methods passed in the stubs hash' do + dbl = double("MyDouble", :a => 5, :b => 10) - [[:should, :expect], [:expect], [:should]].each do |syntax| - context "with syntax #{syntax.inspect}" do - include_context "with syntax", syntax - - it 'stubs the methods passed in the stubs hash' do - dbl = double("MyDouble", :a => 5, :b => 10) - - expect(dbl.a).to eq(5) - expect(dbl.b).to eq(10) - end - end + expect(dbl.a).to eq(5) + expect(dbl.b).to eq(10) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c4124bd28..136da71c6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -77,20 +77,10 @@ def self.fake_matcher_description require 'rspec/support/spec' RSpec.configure do |config| - config.expose_dsl_globally = false config.mock_with :rspec config.color = true config.order = :random - config.expect_with :rspec do |expectations| - expectations.syntax = :expect - end - - config.mock_with :rspec do |mocks| - $default_rspec_mocks_syntax = mocks.syntax - mocks.syntax = :expect - end - old_verbose = nil config.before(:each, :silence_warnings) do old_verbose = $VERBOSE @@ -124,19 +114,6 @@ def self.fake_matcher_description RSpec::Matchers.define_negated_matcher :a_string_excluding, :include end -RSpec.shared_context "with syntax" do |syntax| - orig_syntax = nil - - before(:all) do - orig_syntax = RSpec::Mocks.configuration.syntax - RSpec::Mocks.configuration.syntax = syntax - end - - after(:all) do - RSpec::Mocks.configuration.syntax = orig_syntax - end -end - RSpec.shared_context "with isolated configuration" do orig_configuration = nil before do @@ -158,16 +135,3 @@ def self.fake_matcher_description RSpec::Mocks.configuration.patch_marshal_to_support_partial_doubles = false end end - -RSpec.shared_context "with the default mocks syntax" do - orig_syntax = nil - - before(:all) do - orig_syntax = RSpec::Mocks.configuration.syntax - RSpec::Mocks.configuration.reset_syntaxes_to_default - end - - after(:all) do - RSpec::Mocks.configuration.syntax = orig_syntax - end -end