diff --git a/Changelog.md b/Changelog.md index a2ee4608b..10a7b736d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Breaking Changes: * Ruby < 2.3 is no longer supported. (Phil Pirozhkov, #1231) +* Remove `should` and `should_not` syntax (including one-liners). (Phil Pirozhkov, #1245) Enhancements: diff --git a/README.md b/README.md index 3888c9377..03c3ffcae 100644 --- a/README.md +++ b/README.md @@ -216,18 +216,6 @@ expect( ).to match([a_hash_including(:a => 'hash'), a_hash_including(:a => 'another')]) ``` -## `should` syntax - -In addition to the `expect` syntax, rspec-expectations continues to support the -`should` syntax: - -```ruby -actual.should eq expected -actual.should be > 3 -[1, 2, 3].should_not include 4 -``` - -See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/main/Should.md) ## Compound Matcher Expressions diff --git a/Should.md b/Should.md deleted file mode 100644 index ec8d66811..000000000 --- a/Should.md +++ /dev/null @@ -1,176 +0,0 @@ -# `should` and `should_not` syntax - -From the beginning RSpec::Expectations provided `should` and `should_not` methods -to define expectations on any object. In version 2.11 `expect` method was -introduced which is now the recommended way to define expectations on an object. - -### Why switch over from `should` to `expect` - -#### Fix edge case issues - -`should` and `should_not` work by being added to every object. However, RSpec -does not own every object and cannot ensure they work consistently on every object. -In particular, they can lead to surprising failures when used with BasicObject-subclassed -proxy objects. - -`expect` avoids these problems altogether by not needing to be available on all objects. - -#### Unification of block and value syntaxes - -Before version 2.11 `expect` was just a more readable alternative for block -expectations. Since version 2.11 `expect` can be used for both block and value -expectations. - -```ruby -expect(actual).to eq(expected) -expect { ... }.to raise_error(ErrorClass) -``` - -See -[http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax) -For a detailed explanation - -### One-liners - -The one-liner syntax supported by -[rspec-core](http://rubydoc.info/gems/rspec-core) uses `should` even when -`config.syntax = :expect`. It reads better than the alternative, and does not -require a global monkey patch: - -```ruby -describe User do - it { should validate_presence_of :email } -end -``` - -It can also be expressed with the `is_expected` syntax: - -```ruby -describe User do - it { is_expected.to validate_presence_of :email } -end -``` - -### Using either `expect` or `should` or both - -By default, both `expect` and `should` syntaxes are available. In the future, -the default may be changed to only enable the `expect` syntax. - -If you want your project to only use any one of these syntaxes, you can configure -it: - -```ruby -RSpec.configure do |config| - config.expect_with :rspec do |c| - c.syntax = :expect # disables `should` - # or - c.syntax = :should # disables `expect` - # or - c.syntax = [:should, :expect] # default, enables both `should` and `expect` - end -end -``` - -See -[RSpec::Expectations::Syntax#expect](http://rubydoc.info/gems/rspec-expectations/RSpec/Expectations/Syntax:expect) -for more information. - -## Usage - -The `should` and `should_not` methods can be used to define expectations on any -object. - -```ruby -actual.should eq expected -actual.should be > 3 -[1, 2, 3].should_not include 4 -``` - -## Using Built-in matchers - -### Equivalence - -```ruby -actual.should eq(expected) # passes if actual == expected -actual.should == expected # passes if actual == expected -actual.should_not eql(expected) # passes if actual.eql?(expected) -``` - -Note: we recommend the `eq` matcher over `==` to avoid Ruby's "== in a -useless context" warning when the `==` matcher is used anywhere but the -last statement of an example. - -### Identity - -```ruby -actual.should be(expected) # passes if actual.equal?(expected) -actual.should_not equal(expected) # passes if actual.equal?(expected) -``` - -### Comparisons - -```ruby -actual.should be > expected -actual.should be >= expected -actual.should be <= expected -actual.should be < expected -actual.should be_within(delta).of(expected) -``` - -### Regular expressions - -```ruby -actual.should match(/expression/) -actual.should =~ /expression/ -``` - -### Types/classes - -```ruby -actual.should be_an_instance_of(expected) -actual.should_not be_a_kind_of(expected) -``` - -### Truthiness - -```ruby -actual.should be_true # passes if actual is truthy (not nil or false) -actual.should be_false # passes if actual is falsy (nil or false) -actual.should be_nil # passes if actual is nil -``` - -### Predicate matchers - -```ruby -actual.should be_xxx # passes if actual.xxx? -actual.should_not have_xxx(:arg) # passes if actual.has_xxx?(:arg) -``` - -### Ranges (Ruby >= 1.9 only) - -```ruby -(1..10).should cover(3) -``` - -### Collection membership - -```ruby -actual.should include(expected) -actual.should start_with(expected) -actual.should end_with(expected) -``` - -#### Examples - -```ruby -[1,2,3].should include(1) -[1,2,3].should include(1, 2) -[1,2,3].should start_with(1) -[1,2,3].should start_with(1,2) -[1,2,3].should end_with(3) -[1,2,3].should end_with(2,3) -{:a => 'b'}.should include(:a => 'b') -"this string".should include("is str") -"this string".should start_with("this") -"this string".should end_with("ring") -``` diff --git a/features/.nav b/features/.nav index 21aeb70c8..e14a50cbb 100644 --- a/features/.nav +++ b/features/.nav @@ -16,7 +16,6 @@ - have_attributes.feature - include.feature - match.feature - - operators.feature - raise_error.feature - respond_to.feature - satisfy.feature @@ -36,7 +35,6 @@ - customized_message.feature - diffing.feature - implicit_docstrings.feature -- syntax_configuration.feature - test_frameworks: - test_unit.feature - Changelog.md diff --git a/features/built_in_matchers/README.md b/features/built_in_matchers/README.md index a9cda832d..5f6684649 100644 --- a/features/built_in_matchers/README.md +++ b/features/built_in_matchers/README.md @@ -1,13 +1,11 @@ rspec-expectations ships with a number of built-in matchers. Each matcher can be used with `expect(..).to` or `expect(..).not_to` to define positive and negative expectations -respectively on an object. Most matchers can also be accessed using the `(...).should` and -`(...).should_not` syntax; see [using should syntax](https://github.com/rspec/rspec-expectations/blob/main/Should.md) for why we recommend using `expect`. +respectively on an object. e.g. expect(result).to eq(3) expect(list).not_to be_empty - pi.should be > 3 ## Object identity diff --git a/features/built_in_matchers/predicates.feature b/features/built_in_matchers/predicates.feature index 0e0256a6c..41d78abe1 100644 --- a/features/built_in_matchers/predicates.feature +++ b/features/built_in_matchers/predicates.feature @@ -47,8 +47,8 @@ Feature: Predicate matchers Any arguments passed to the matcher will be passed on to the predicate method. - Scenario: should be_zero (based on Integer#zero?) - Given a file named "should_be_zero_spec.rb" with: + Scenario: is_expected.to be_zero (based on Integer#zero?) + Given a file named "be_zero_spec.rb" with: """ruby RSpec.describe 0 do it { is_expected.to be_zero } @@ -58,12 +58,12 @@ Feature: Predicate matchers it { is_expected.to be_zero } # deliberate failure end """ - When I run `rspec should_be_zero_spec.rb` + When I run `rspec be_zero_spec.rb` Then the output should contain "2 examples, 1 failure" And the output should contain "expected `7.zero?` to be truthy, got false" - Scenario: should_not be_empty (based on Array#empty?) - Given a file named "should_not_be_empty_spec.rb" with: + Scenario: is_expected.not_to be_empty (based on Array#empty?) + Given a file named "not_to_be_empty_spec.rb" with: """ruby RSpec.describe [1, 2, 3] do it { is_expected.not_to be_empty } @@ -73,12 +73,12 @@ Feature: Predicate matchers it { is_expected.not_to be_empty } # deliberate failure end """ - When I run `rspec should_not_be_empty_spec.rb` + When I run `rspec not_to_be_empty_spec.rb` Then the output should contain "2 examples, 1 failure" And the output should contain "expected `[].empty?` to be falsey, got true" - Scenario: should have_key (based on Hash#has_key?) - Given a file named "should_have_key_spec.rb" with: + Scenario: is_expected.to have_key (based on Hash#has_key?) + Given a file named "have_key_spec.rb" with: """ruby RSpec.describe Hash do subject { { :foo => 7 } } @@ -86,12 +86,12 @@ Feature: Predicate matchers it { is_expected.to have_key(:bar) } # deliberate failure end """ - When I run `rspec should_have_key_spec.rb` + When I run `rspec have_key_spec.rb` Then the output should contain "2 examples, 1 failure" And the output should contain "expected `{:foo=>7}.has_key?(:bar)` to be truthy, got false" - Scenario: should_not have_all_string_keys (based on custom #has_all_string_keys? method) - Given a file named "should_not_have_all_string_keys_spec.rb" with: + Scenario: is_expected.to have_decimals (based on custom #have_decimals? method) + Given a file named "have_decimals_spec.rb" with: """ruby class Float def has_decimals? @@ -112,7 +112,7 @@ Feature: Predicate matchers end end """ - When I run `rspec should_not_have_all_string_keys_spec.rb` + When I run `rspec have_decimals_spec.rb` Then the output should contain "2 examples, 1 failure" And the output should contain "expected `42.0.has_decimals?` to be truthy, got false" diff --git a/features/custom_matchers/define_matcher.feature b/features/custom_matchers/define_matcher.feature index 52f9252d0..73ce7ee44 100644 --- a/features/custom_matchers/define_matcher.feature +++ b/features/custom_matchers/define_matcher.feature @@ -203,7 +203,7 @@ Feature: Define a custom matcher end RSpec.describe "these two arrays" do - specify "should be similar" do + it "is similar" do expect([1,2,3]).to have_same_elements_as([2,3,1]) end end @@ -278,7 +278,7 @@ Feature: Define a custom matcher Then the output should contain "3 examples, 0 failures" Scenario: Matcher with separate logic for expect().to and expect().not_to - Given a file named "matcher_with_separate_should_not_logic_spec.rb" with: + Given a file named "matcher_with_separate_not_to_logic_spec.rb" with: """ruby RSpec::Matchers.define :contain do |*expected| match do |actual| @@ -299,7 +299,7 @@ Feature: Define a custom matcher it { is_expected.not_to contain(1, 4) } end """ - When I run `rspec matcher_with_separate_should_not_logic_spec.rb` + When I run `rspec matcher_with_separate_not_to_logic_spec.rb` Then the output should contain all of these: | 4 examples, 2 failures | | expected [1, 2, 3] to contain 1 and 4 | diff --git a/features/customized_message.feature b/features/customized_message.feature index c96a3ea0f..ec40f8137 100644 --- a/features/customized_message.feature +++ b/features/customized_message.feature @@ -1,8 +1,7 @@ Feature: customized message RSpec tries to provide useful failure messages, but for cases in which you want more - specific information, you can define your own message right in the example.This works for - any matcher _other than the operator matchers_. + specific information, you can define your own message right in the example. Scenario: customize failure message Given a file named "example_spec.rb" with: diff --git a/features/support/disallow_certain_apis.rb b/features/support/disallow_certain_apis.rb deleted file mode 100644 index 958c0775c..000000000 --- a/features/support/disallow_certain_apis.rb +++ /dev/null @@ -1,33 +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-disallowed-api') 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.expose_dsl_globally = false if rspec.respond_to?(:expose_dsl_globally) - - rspec.mock_with :rspec do |mocks| - mocks.syntax = :expect if mocks.respond_to?(:syntax=) # RSpec 4 removed `syntax=` - end - - rspec.expect_with :rspec do |expectations| - expectations.syntax = :expect - end - - rspec.include DisallowOneLinerShould - end -end diff --git a/features/syntax_configuration.feature b/features/syntax_configuration.feature deleted file mode 100644 index d7ef728a8..000000000 --- a/features/syntax_configuration.feature +++ /dev/null @@ -1,92 +0,0 @@ -@allow-disallowed-api -Feature: Syntax Configuration - - The primary syntax provided by rspec-expectations is based on - the `expect` method, which explicitly wraps an object or block - of code in order to set an expectation on it. - - There's also an older `should`-based syntax, which relies upon `should` being - monkey-patched onto every object in the system. However, this syntax can at times lead to - some surprising failures, since RSpec does not own every object in the system and cannot - guarantee that it will always work consistently. - - We recommend you use the `expect` syntax unless you have a specific reason you prefer the - `should` syntax. We have no plans to ever completely remove the `should` syntax but starting - in RSpec 3, a deprecation warning will be issued if you do not explicitly enable it, with the - plan to disable it by default in RSpec 4 (and potentially move it into an external gem). - - If you have an old `should`-based project that you would like to upgrade to the `expect`, - check out [transpec](http://yujinakayama.me/transpec/), which can perform the conversion automatically for you. - - Background: - Given a file named "spec/syntaxes_spec.rb" with: - """ruby - require 'spec_helper' - - RSpec.describe "using the should syntax" do - specify { 3.should eq(3) } - specify { 3.should_not eq(4) } - specify { lambda { raise "boom" }.should raise_error("boom") } - specify { lambda { }.should_not raise_error } - end - - RSpec.describe "using the expect syntax" do - specify { expect(3).to eq(3) } - specify { expect(3).not_to eq(4) } - specify { expect { raise "boom" }.to raise_error("boom") } - specify { expect { }.not_to raise_error } - end - """ - - Scenario: Both syntaxes are available by default - Given a file named "spec/spec_helper.rb" with: - """ruby - """ - When I run `rspec` - Then the examples should all pass - And the output should contain "Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated" - - Scenario: Disable should syntax - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.expect_with :rspec do |expectations| - expectations.syntax = :expect - end - end - """ - When I run `rspec` - Then the output should contain all of these: - | 8 examples, 4 failures | - | undefined method `should' | - - Scenario: Disable expect syntax - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.expect_with :rspec do |expectations| - expectations.syntax = :should - end - config.mock_with :rspec do |mocks| - mocks.syntax = :should if mocks.respond_to?(:syntax=) # RSpec 4 removed `syntax=` - end - end - """ - When I run `rspec` - Then the output should contain all of these: - | 8 examples, 4 failures | - | undefined method `expect' | - - Scenario: Explicitly enable both syntaxes - Given a file named "spec/spec_helper.rb" with: - """ruby - RSpec.configure do |config| - config.expect_with :rspec do |expectations| - expectations.syntax = [:should, :expect] - end - end - """ - When I run `rspec` - Then the examples should all pass - And the output should not contain "deprecated" - diff --git a/lib/rspec/expectations/configuration.rb b/lib/rspec/expectations/configuration.rb index a16b5b5e4..ddfbb5313 100644 --- a/lib/rspec/expectations/configuration.rb +++ b/lib/rspec/expectations/configuration.rb @@ -1,5 +1,3 @@ -RSpec::Support.require_rspec_expectations "syntax" - module RSpec module Expectations # Provides configuration options for rspec-expectations. @@ -31,32 +29,6 @@ def initialize @strict_predicate_matchers = false end - # Configures the supported syntax. - # @param [Array, Symbol] values the syntaxes to enable - # @example - # RSpec.configure do |rspec| - # rspec.expect_with :rspec do |c| - # c.syntax = :should - # # or - # c.syntax = :expect - # # or - # c.syntax = [:should, :expect] - # end - # end - def syntax=(values) - if Array(values).include?(:expect) - Expectations::Syntax.enable_expect - else - Expectations::Syntax.disable_expect - end - - if Array(values).include?(:should) - Expectations::Syntax.enable_should - else - Expectations::Syntax.disable_should - end - end - # Configures the maximum character length that RSpec will print while # formatting an object. You can set length to nil to prevent RSpec from # doing truncation. @@ -71,19 +43,6 @@ def max_formatted_output_length=(length) RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = length end - # The list of configured syntaxes. - # @return [Array] the list of configured syntaxes. - # @example - # unless RSpec::Matchers.configuration.syntax.include?(:expect) - # raise "this RSpec extension gem requires the rspec-expectations `:expect` syntax" - # end - def syntax - syntaxes = [] - syntaxes << :should if Expectations::Syntax.should_enabled? - syntaxes << :expect if Expectations::Syntax.expect_enabled? - syntaxes - end - if ::RSpec.respond_to?(:configuration) def color? ::RSpec.configuration.color_enabled? @@ -102,18 +61,6 @@ def color? end end - # Adds `should` and `should_not` to the given classes - # or modules. This can be used to ensure `should` works - # properly on things like proxy objects. - # - # @param [Array] modules the list of classes or modules - # to add `should` and `should_not` to. - def add_should_and_should_not_to(*modules) - modules.each do |mod| - Expectations::Syntax.enable_should(mod) - end - end - # Sets or gets the backtrace formatter. The backtrace formatter should # implement `#format_backtrace(Array)`. This is used # to format backtraces of errors handled by the `raise_error` @@ -145,12 +92,6 @@ def include_chain_clauses_in_custom_matcher_descriptions? @include_chain_clauses_in_custom_matcher_descriptions ||= false end - # @private - def reset_syntaxes_to_default - self.syntax = [:should, :expect] - RSpec::Expectations::Syntax.warn_about_should! - end - # @api private # Null implementation of a backtrace formatter used by default # when rspec-core is not loaded. Does no filtering. @@ -222,8 +163,5 @@ def false_positives_handler def self.configuration @configuration ||= Configuration.new end - - # set default syntax - configuration.reset_syntaxes_to_default end end diff --git a/lib/rspec/expectations/handler.rb b/lib/rspec/expectations/handler.rb index a8f7c0531..3ff9b129f 100644 --- a/lib/rspec/expectations/handler.rb +++ b/lib/rspec/expectations/handler.rb @@ -46,8 +46,6 @@ def self.handle_failure(matcher, message, failure_message_method) class PositiveExpectationHandler def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| - return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) unless initial_matcher - match_result = matcher.matches?(actual, &block) if custom_message && match_result.respond_to?(:error_generator) match_result.error_generator.opts[:message] = custom_message @@ -74,8 +72,6 @@ def self.opposite_should_method class NegativeExpectationHandler def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| - return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) unless initial_matcher - negated_match_result = does_not_match?(matcher, actual, &block) if custom_message && negated_match_result.respond_to?(:error_generator) negated_match_result.error_generator.opts[:message] = custom_message diff --git a/lib/rspec/expectations/syntax.rb b/lib/rspec/expectations/syntax.rb deleted file mode 100644 index c61670cd4..000000000 --- a/lib/rspec/expectations/syntax.rb +++ /dev/null @@ -1,130 +0,0 @@ -module RSpec - module Expectations - # @api private - # Provides methods for enabling and disabling the available - # syntaxes provided by rspec-expectations. - module Syntax - module_function - - # @api private - # Determines where we add `should` and `should_not`. - def default_should_host - @default_should_host ||= ::Object.ancestors.last - end - - # @api private - # Instructs rspec-expectations to warn on first usage of `should` or `should_not`. - # Enabled by default. This is largely here to facilitate testing. - def warn_about_should! - @warn_about_should = true - end - - # @api private - # Generates a deprecation warning for the given method if no warning - # has already been issued. - def warn_about_should_unless_configured(method_name) - return unless @warn_about_should - - RSpec.deprecate( - "Using `#{method_name}` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax", - :replacement => "the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }`" - ) - - @warn_about_should = false - end - - # @api private - # Enables the `should` syntax. - def enable_should(syntax_host=default_should_host) - @warn_about_should = false if syntax_host == default_should_host - return if should_enabled?(syntax_host) - - syntax_host.module_exec do - def should(matcher=nil, message=nil, &block) - ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) - ::RSpec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block) - end - - def should_not(matcher=nil, message=nil, &block) - ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) - ::RSpec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block) - end - end - end - - # @api private - # Disables the `should` syntax. - def disable_should(syntax_host=default_should_host) - return unless should_enabled?(syntax_host) - - syntax_host.module_exec do - undef should - undef should_not - end - end - - # @api private - # Enables the `expect` syntax. - def enable_expect(syntax_host=::RSpec::Matchers) - return if expect_enabled?(syntax_host) - - syntax_host.module_exec do - def expect(value=::RSpec::Expectations::ExpectationTarget::UndefinedValue, &block) - ::RSpec::Expectations::ExpectationTarget.for(value, block) - end - end - end - - # @api private - # Disables the `expect` syntax. - def disable_expect(syntax_host=::RSpec::Matchers) - return unless expect_enabled?(syntax_host) - - syntax_host.module_exec do - undef expect - end - end - - # @api private - # Indicates whether or not the `should` syntax is enabled. - def should_enabled?(syntax_host=default_should_host) - syntax_host.method_defined?(:should) - end - - # @api private - # Indicates whether or not the `expect` syntax is enabled. - def expect_enabled?(syntax_host=::RSpec::Matchers) - syntax_host.method_defined?(:expect) - 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. -class BasicObject - # @method should(matcher, message) - # Passes if `matcher` returns true. Available on every `Object`. - # @example - # actual.should eq expected - # actual.should match /expression/ - # @param [Matcher] - # matcher - # @param [String] message optional message to display when the expectation fails - # @return [Boolean] true if the expectation succeeds (else raises) - # @note This is only available when you have enabled the `:should` syntax. - # @see RSpec::Matchers - - # @method should_not(matcher, message) - # Passes if `matcher` returns false. Available on every `Object`. - # @example - # actual.should_not eq expected - # @param [Matcher] - # matcher - # @param [String] message optional message to display when the expectation fails - # @return [Boolean] false if the negative expectation succeeds (else raises) - # @note This is only available when you have enabled the `:should` syntax. - # @see RSpec::Matchers -end diff --git a/lib/rspec/matchers.rb b/lib/rspec/matchers.rb index dc978411a..444c83f11 100644 --- a/lib/rspec/matchers.rb +++ b/lib/rspec/matchers.rb @@ -260,7 +260,6 @@ def self.alias_matcher(*args, &block) # @!method self.define_negated_matcher(negated_name, base_name, &description_override) # Extended from {RSpec::Matchers::DSL#define_negated_matcher}. - # @method expect # Supports `expect(actual).to matcher` syntax by wrapping `actual` in an # `ExpectationTarget`. # @example @@ -269,6 +268,9 @@ def self.alias_matcher(*args, &block) # @return [Expectations::ExpectationTarget] # @see Expectations::ExpectationTarget#to # @see Expectations::ExpectationTarget#not_to + def expect(value=::RSpec::Expectations::ExpectationTarget::UndefinedValue, &block) + ::RSpec::Expectations::ExpectationTarget.for(value, block) + end # Allows multiple expectations in the provided block to fail, and then # aggregates them into a single exception, rather than aborting on the @@ -499,9 +501,6 @@ def change(receiver=nil, message=nil, &block) # This works for collections. Pass in multiple args and it will only # pass if all args are found in collection. # - # @note This is also available using the `=~` operator with `should`, - # but `=~` is not supported with `expect`. - # # @example # expect([1, 2, 3]).to contain_exactly(1, 2, 3) # expect([1, 2, 3]).to contain_exactly(1, 3, 2) diff --git a/lib/rspec/matchers/built_in.rb b/lib/rspec/matchers/built_in.rb index e6237ff08..4cd7dfee9 100644 --- a/lib/rspec/matchers/built_in.rb +++ b/lib/rspec/matchers/built_in.rb @@ -35,10 +35,7 @@ module BuiltIn autoload :Include, 'rspec/matchers/built_in/include' autoload :All, 'rspec/matchers/built_in/all' autoload :Match, 'rspec/matchers/built_in/match' - autoload :NegativeOperatorMatcher, 'rspec/matchers/built_in/operators' - autoload :OperatorMatcher, 'rspec/matchers/built_in/operators' autoload :Output, 'rspec/matchers/built_in/output' - autoload :PositiveOperatorMatcher, 'rspec/matchers/built_in/operators' autoload :RaiseError, 'rspec/matchers/built_in/raise_error' autoload :RespondTo, 'rspec/matchers/built_in/respond_to' autoload :Satisfy, 'rspec/matchers/built_in/satisfy' diff --git a/lib/rspec/matchers/built_in/operators.rb b/lib/rspec/matchers/built_in/operators.rb deleted file mode 100644 index 64f8f3b23..000000000 --- a/lib/rspec/matchers/built_in/operators.rb +++ /dev/null @@ -1,128 +0,0 @@ -require 'rspec/support' - -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for operator matchers. - # Not intended to be instantiated directly. - # Only available for use with `should`. - class OperatorMatcher - class << self - # @private - def registry - @registry ||= {} - end - - # @private - def register(klass, operator, matcher) - registry[klass] ||= {} - registry[klass][operator] = matcher - end - - # @private - def unregister(klass, operator) - registry[klass] && registry[klass].delete(operator) - end - - # @private - def get(klass, operator) - klass.ancestors.each do |ancestor| - matcher = registry[ancestor] && registry[ancestor][operator] - return matcher if matcher - end - - nil - end - end - - register Enumerable, '=~', BuiltIn::ContainExactly - - def initialize(actual) - @actual = actual - end - - # @private - def self.use_custom_matcher_or_delegate(operator) - define_method(operator) do |expected| - if !has_non_generic_implementation_of?(operator) && (matcher = OperatorMatcher.get(@actual.class, operator)) - @actual.__send__(::RSpec::Matchers.last_expectation_handler.should_method, matcher.new(expected)) - else - eval_match(@actual, operator, expected) - end - end - - negative_operator = operator.sub(/^=/, '!') - if negative_operator != operator && respond_to?(negative_operator) - define_method(negative_operator) do |_expected| - opposite_should = ::RSpec::Matchers.last_expectation_handler.opposite_should_method - raise "RSpec does not support `#{::RSpec::Matchers.last_expectation_handler.should_method} #{negative_operator} expected`. " \ - "Use `#{opposite_should} #{operator} expected` instead." - end - end - end - - ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator| - use_custom_matcher_or_delegate operator - end - - # @private - def fail_with_message(message) - RSpec::Expectations.fail_with(message, @expected, @actual) - end - - # @api private - # @return [String] - def description - "#{@operator} #{RSpec::Support::ObjectFormatter.format(@expected)}" - end - - private - - def has_non_generic_implementation_of?(op) - Support.method_handle_for(@actual, op).owner != ::Kernel - rescue NameError - false - end - - def eval_match(actual, operator, expected) - ::RSpec::Matchers.last_matcher = self - @operator, @expected = operator, expected - __delegate_operator(actual, operator, expected) - end - end - - # @private - # Handles operator matcher for `should`. - class PositiveOperatorMatcher < OperatorMatcher - def __delegate_operator(actual, operator, expected) - if actual.__send__(operator, expected) - true - else - expected_formatted = RSpec::Support::ObjectFormatter.format(expected) - actual_formatted = RSpec::Support::ObjectFormatter.format(actual) - - if ['==', '===', '=~'].include?(operator) - fail_with_message("expected: #{expected_formatted}\n got: #{actual_formatted} (using #{operator})") - else - fail_with_message("expected: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") - end - end - end - end - - # @private - # Handles operator matcher for `should_not`. - class NegativeOperatorMatcher < OperatorMatcher - def __delegate_operator(actual, operator, expected) - return false unless actual.__send__(operator, expected) - - expected_formatted = RSpec::Support::ObjectFormatter.format(expected) - actual_formatted = RSpec::Support::ObjectFormatter.format(actual) - - fail_with_message("expected not: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") - end - end - end - end -end diff --git a/lib/rspec/matchers/dsl.rb b/lib/rspec/matchers/dsl.rb index 641a637e9..c6119ac1b 100644 --- a/lib/rspec/matchers/dsl.rb +++ b/lib/rspec/matchers/dsl.rb @@ -373,7 +373,7 @@ module DefaultImplementations include BuiltIn::BaseMatcher::DefaultFailureMessages # @api private - # Used internally by objects returns by `should` and `should_not`. + # Used internally by handlers and compound matchers. def diffable? false end diff --git a/spec/integration/kw_argument_delegation_spec.rb b/spec/integration/kw_argument_delegation_spec.rb new file mode 100644 index 000000000..a9204ecfb --- /dev/null +++ b/spec/integration/kw_argument_delegation_spec.rb @@ -0,0 +1,11 @@ +RSpec.describe "keyword argument delegation" do + # We erroneously introduced keyword argument helpers to try to remove + # the warnings generated with our normal delegation, these can cause + # the arguments to be cast as hash and need to not be + + it "does not coerce to hash when passed through an equal? expectation" do + cls = Class.new { def to_hash; {a:1}; end } + obj = cls.new + expect(obj).to be_equal(obj) + end +end diff --git a/spec/rspec/expectations/configuration_spec.rb b/spec/rspec/expectations/configuration_spec.rb index a488068f4..59ced1c05 100644 --- a/spec/rspec/expectations/configuration_spec.rb +++ b/spec/rspec/expectations/configuration_spec.rb @@ -121,146 +121,6 @@ class << rspec_dup; undef configuration; end expect(config.on_potential_false_positives).to eq :raise end end - - shared_examples "configuring the expectation syntax" do - before do - @orig_syntax = RSpec::Matchers.configuration.syntax - end - - after do - configure_syntax(@orig_syntax) - end - - it 'can limit the syntax to :should' do - configure_syntax :should - configured_syntax.should eq([:should]) - - 3.should eq(3) - 3.should_not eq(4) - lambda { expect(6).to eq(6) }.should raise_error(NameError) - end - - it 'is a no-op when configured to :should twice' do - configure_syntax :should - method_added_count = 0 - allow(Expectations::Syntax.default_should_host).to receive(:method_added) { method_added_count += 1 } - configure_syntax :should - - method_added_count.should eq(0) - end - - it 'can limit the syntax to :expect' do - configure_syntax :expect - expect(configured_syntax).to eq([:expect]) - - expect(3).to eq(3) - expect { 3.should eq(3) }.to raise_error(NameError) - expect { 3.should_not eq(3) }.to raise_error(NameError) - end - - it 'is a no-op when configured to :expect twice' do - allow(RSpec::Matchers).to receive(:method_added).and_raise("no methods should be added here") - - configure_syntax :expect - configure_syntax :expect - end - - describe "`:should` being enabled by default deprecation" do - before { configure_default_syntax } - - it "warns when the should syntax is called by default" do - expected_arguments = [ - /Using.*without explicitly enabling/, - { :replacement => "the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }`" } - ] - - expect(RSpec).to receive(:deprecate).with(*expected_arguments) - 3.should eq(3) - end - - it "includes the call site in the deprecation warning by default" do - expect_deprecation_with_call_site(__FILE__, __LINE__ + 1) - 3.should eq(3) - end - - it "does not warn when only the should syntax is explicitly configured" do - configure_syntax(:should) - RSpec.should_not receive(:deprecate) - 3.should eq(3) - end - - it "does not warn when both the should and expect syntaxes are explicitly configured" do - configure_syntax([:should, :expect]) - expect(RSpec).not_to receive(:deprecate) - 3.should eq(3) - end - end - - it 'can re-enable the :should syntax' do - configure_syntax :expect - configure_syntax [:should, :expect] - configured_syntax.should eq([:should, :expect]) - - 3.should eq(3) - 3.should_not eq(4) - expect(3).to eq(3) - end - - it 'can re-enable the :expect syntax' do - configure_syntax :should - configure_syntax [:should, :expect] - configured_syntax.should eq([:should, :expect]) - - 3.should eq(3) - 3.should_not eq(4) - expect(3).to eq(3) - end - end - - def configure_default_syntax - RSpec::Matchers.configuration.reset_syntaxes_to_default - end - - describe "configuring rspec-expectations directly" do - it_behaves_like "configuring the expectation syntax" do - def configure_syntax(syntax) - RSpec::Matchers.configuration.syntax = syntax - end - - def configured_syntax - RSpec::Matchers.configuration.syntax - end - end - end - - describe "configuring using the rspec-core config API" do - it_behaves_like "configuring the expectation syntax" do - def configure_syntax(syntax) - RSpec.configure do |rspec| - rspec.expect_with :rspec do |c| - c.syntax = syntax - end - end - end - - def configured_syntax - RSpec.configure do |rspec| - rspec.expect_with :rspec do |c| - return c.syntax - end - end - end - end - end - - it 'enables both syntaxes by default' 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_expectation_syntax so we can use it here. - expect($default_expectation_syntax).to contain_exactly(:expect, :should) # rubocop:disable Style/GlobalVars - end end end end diff --git a/spec/rspec/expectations/expectation_target_spec.rb b/spec/rspec/expectations/expectation_target_spec.rb index 26e432896..e4c2b6755 100644 --- a/spec/rspec/expectations/expectation_target_spec.rb +++ b/spec/rspec/expectations/expectation_target_spec.rb @@ -68,13 +68,13 @@ module Expectations it 'does not support operator matchers from #to' do expect { expect(3).to == 3 - }.to raise_error(ArgumentError) + }.to raise_error(ArgumentError, /The expect syntax does not support operator matchers, so you must pass a matcher to `#to`/) end it 'does not support operator matchers from #not_to' do expect { expect(3).not_to == 4 - }.to raise_error(ArgumentError) + }.to raise_error(ArgumentError, /The expect syntax does not support operator matchers, so you must pass a matcher to `#not_to`/) end end diff --git a/spec/rspec/expectations/extensions/kernel_spec.rb b/spec/rspec/expectations/extensions/kernel_spec.rb deleted file mode 100644 index c8c4e20b5..000000000 --- a/spec/rspec/expectations/extensions/kernel_spec.rb +++ /dev/null @@ -1,79 +0,0 @@ -RSpec.describe Object, "#should" do - before(:example) do - @target = "target" - @matcher = double("matcher") - allow(@matcher).to receive(:matches?).and_return(true) - allow(@matcher).to receive(:failure_message) - end - - it "accepts and interacts with a matcher" do - expect(@matcher).to receive(:matches?).with(@target).and_return(true) - expect(@target).to @matcher - end - - it "asks for a failure_message when matches? returns false" do - expect(@matcher).to receive(:matches?).with(@target).and_return(false) - expect(@matcher).to receive(:failure_message).and_return("the failure message") - expect { - expect(@target).to @matcher - }.to fail_with("the failure message") - end - - context "on interpretters that have BasicObject" do - let(:proxy_class) do - Class.new(BasicObject) do - def initialize(target) - @target = target - end - - def proxied? - true - end - - def respond_to?(method, *args) - method.to_sym == :proxied? || @target.respond_to?(symbol, *args) - end - - def method_missing(name, *args) - @target.send(name, *args) - end - end - end - - it 'works properly on BasicObject-subclassed proxy objects' do - expect(proxy_class.new(Object.new)).to be_proxied - end - - it 'does not break the deprecation check on BasicObject-subclassed proxy objects' do - begin - should_enabled = RSpec::Expectations::Syntax.should_enabled? - RSpec::Expectations::Syntax.enable_should unless should_enabled - proxy_class.new(BasicObject.new).should be_proxied - ensure - RSpec::Expectations::Syntax.disable_should if should_enabled - end - end - end -end - -RSpec.describe Object, "#should_not" do - before(:example) do - @target = "target" - @matcher = double("matcher") - end - - it "accepts and interacts with a matcher" do - expect(@matcher).to receive(:matches?).with(@target).and_return(false) - allow(@matcher).to receive(:failure_message_when_negated) - - expect(@target).not_to @matcher - end - - it "asks for a failure_message_when_negated when matches? returns true" do - expect(@matcher).to receive(:matches?).with(@target).and_return(true) - expect(@matcher).to receive(:failure_message_when_negated).and_return("the failure message for should not") - expect { - expect(@target).not_to @matcher - }.to fail_with("the failure message for should not") - end -end diff --git a/spec/rspec/expectations/syntax_spec.rb b/spec/rspec/expectations/syntax_spec.rb index a931aee4f..19cd87494 100644 --- a/spec/rspec/expectations/syntax_spec.rb +++ b/spec/rspec/expectations/syntax_spec.rb @@ -1,6 +1,6 @@ module RSpec module Expectations - RSpec.describe Syntax do + RSpec.describe 'Syntax' do context "when passing a message to an expectation" do let(:warner) { ::Kernel } @@ -70,18 +70,6 @@ module Expectations end end end - - describe "enabling the should syntax on something other than the default syntax host" do - include_context "with the default expectation syntax" - - it "continues to warn about the should syntax" do - my_host = Class.new - expect(RSpec).to receive(:deprecate) - Syntax.enable_should(my_host) - - 3.should eq 3 - end - end end end end diff --git a/spec/rspec/matchers/built_in/be_spec.rb b/spec/rspec/matchers/built_in/be_spec.rb index 7ef0d9762..d80a8eef8 100644 --- a/spec/rspec/matchers/built_in/be_spec.rb +++ b/spec/rspec/matchers/built_in/be_spec.rb @@ -746,18 +746,6 @@ def send end end -RSpec.describe "should be =~", :uses_should do - it "passes when =~ operator returns true" do - "a string".should be =~ /str/ - end - - it "fails when =~ operator returns false" do - expect { - "a string".should be =~ /blah/ - }.to fail_with(%(expected: =~ /blah/\n got: "a string")) - end -end - RSpec.describe "expect(...).to be ===" do it "passes when === operator returns true" do expect(Hash).to be === {} diff --git a/spec/rspec/matchers/built_in/contain_exactly_spec.rb b/spec/rspec/matchers/built_in/contain_exactly_spec.rb index 075d7469c..cee758c73 100644 --- a/spec/rspec/matchers/built_in/contain_exactly_spec.rb +++ b/spec/rspec/matchers/built_in/contain_exactly_spec.rb @@ -24,76 +24,6 @@ def to_ary end end -RSpec.describe "should =~ array", :uses_should do - it "passes a valid positive expectation" do - [1, 2].should =~ [2, 1] - end - - it "fails an invalid positive expectation" do - expect { - [1, 2, 3].should =~ [2, 1] - }.to fail_with(/expected collection contained/) - end - - context "when the array defines a `=~` method" do - it 'delegates to that method rather than using the contain_exactly matcher' do - array = [] - def array.=~(other) - other == :foo - end - - array.should =~ :foo - expect { - array.should =~ :bar - }.to fail_with(/expected: :bar/) - end - end - - context 'when the array defines a `send` method' do - it 'still works' do - array = [1, 2] - def array.send; :sent; end - - array.should =~ array - end - end - - context "when the array undefines `=~`" do - it 'still works' do - array_klass = Class.new(Array) { undef =~ } - array = array_klass.new([1, 2]) - - array.should =~ [1, 2] - - expect { - array.should =~ [0, 1, 2] - }.to fail_with(/expected collection contained/) - end - end -end - -RSpec.describe "should_not =~ [:with, :multiple, :args]", :uses_should do - it "fails when the arrays match" do - expect { - [1, 2, 3].should_not =~ [1, 2, 3] - }.to fail_with "expected [1, 2, 3] not to contain exactly 1, 2, and 3" - end - - it "fails when the arrays match in a different order" do - expect { - [1, 3, 2].should_not =~ [1, 2, 3] - }.to fail_with "expected [1, 3, 2] not to contain exactly 1, 2, and 3" - end - - it "passes when there are extra elements in the array" do - [1, 3].should_not =~ [1, 2, 3] - end - - it "passes when there are elements missing from the array" do - [1, 2, 3, 4].should_not =~ [1, 2, 3] - end -end - RSpec.describe "using contain_exactly with expect" do it "passes a valid positive expectation" do expect([1, 2]).to contain_exactly(2, 1) diff --git a/spec/rspec/matchers/built_in/operators_spec.rb b/spec/rspec/matchers/built_in/operators_spec.rb deleted file mode 100644 index 830ff38d8..000000000 --- a/spec/rspec/matchers/built_in/operators_spec.rb +++ /dev/null @@ -1,249 +0,0 @@ -class MethodOverrideObject - def method - :foo - end -end - -class MethodMissingObject < Struct.new(:original) - undef == - - def method_missing(name, *args, &block) - original.__send__ name, *args, &block - end -end - -RSpec.describe "operator matchers", :uses_should do - describe "should ==" do - it "delegates message to target" do - subject = "apple".dup - expect(subject).to receive(:==).with("apple").and_return(true) - subject.should == "apple" - end - - it "returns true on success" do - subject = "apple" - (subject.should == "apple").should be_truthy - end - - it "fails when target.==(actual) returns false" do - subject = "apple" - expect(RSpec::Expectations).to receive(:fail_with).with(%{expected: "orange"\n got: "apple" (using ==)}, "orange", "apple") - subject.should == "orange" - end - - it "works when #method is overriden" do - myobj = MethodOverrideObject.new - expect { - myobj.should == myobj - }.to_not raise_error - end - - it "works when implemented via method_missing" do - obj = Object.new - - myobj = MethodMissingObject.new(obj) - (myobj.should == obj).nil? # just to avoid `useless use of == in void context` warning - myobj.should_not == Object.new - end - end - - describe "unsupported operators" do - it "raises an appropriate error for should != expected" do - expect { - "apple".should != "pear" - }.to raise_error(/does not support `should != expected`. Use `should_not == expected`/) - end - - it "raises an appropriate error for should_not != expected" do - expect { - "apple".should_not != "pear" - }.to raise_error(/does not support `should_not != expected`. Use `should == expected`/) - end - - it "raises an appropriate error for should !~ expected" do - expect { - "apple".should !~ /regex/ - }.to raise_error(/does not support `should !~ expected`. Use `should_not =~ expected`/) - end - - it "raises an appropriate error for should_not !~ expected" do - expect { - "apple".should_not !~ /regex/ - }.to raise_error(/does not support `should_not !~ expected`. Use `should =~ expected`/) - end - end - - describe "should_not ==" do - it "delegates message to target" do - subject = "orange".dup - expect(subject).to receive(:==).with("apple").and_return(false) - subject.should_not == "apple" - end - - it "returns true on success" do - subject = "apple" - (subject.should_not == "orange").should be_falsey - end - - it "fails when target.==(actual) returns false" do - subject = "apple" - expect(RSpec::Expectations).to receive(:fail_with).with(%(expected not: == "apple"\n got: "apple"), "apple", "apple") - subject.should_not == "apple" - end - end - - describe "should ===" do - it "delegates message to target" do - subject = "apple".dup - expect(subject).to receive(:===).with("apple").and_return(true) - subject.should === "apple" - end - - it "fails when target.===(actual) returns false" do - subject = "apple".dup - expect(subject).to receive(:===).with("orange").and_return(false) - expect(RSpec::Expectations).to receive(:fail_with).with(%{expected: "orange"\n got: "apple" (using ===)}, "orange", "apple") - subject.should === "orange" - end - end - - describe "should_not ===" do - it "delegates message to target" do - subject = "orange".dup - expect(subject).to receive(:===).with("apple").and_return(false) - subject.should_not === "apple" - end - - it "fails when target.===(actual) returns false" do - subject = "apple".dup - expect(subject).to receive(:===).with("apple").and_return(true) - expect(RSpec::Expectations).to receive(:fail_with).with(%(expected not: === "apple"\n got: "apple"), "apple", "apple") - subject.should_not === "apple" - end - end - - describe "should =~" do - it "delegates message to target" do - subject = "foo".dup - expect(subject).to receive(:=~).with(/oo/).and_return(true) - subject.should =~ /oo/ - end - - it "fails when target.=~(actual) returns false" do - subject = "fu".dup - expect(subject).to receive(:=~).with(/oo/).and_return(false) - expect(RSpec::Expectations).to receive(:fail_with).with(%{expected: /oo/\n got: "fu" (using =~)}, /oo/, "fu") - subject.should =~ /oo/ - end - end - - describe "should_not =~" do - it "delegates message to target" do - subject = "fu".dup - expect(subject).to receive(:=~).with(/oo/).and_return(false) - subject.should_not =~ /oo/ - end - - it "fails when target.=~(actual) returns false" do - subject = "foo".dup - expect(subject).to receive(:=~).with(/oo/).and_return(true) - expect(RSpec::Expectations).to receive(:fail_with).with(%(expected not: =~ /oo/\n got: "foo"), /oo/, "foo") - subject.should_not =~ /oo/ - end - end - - describe "should >" do - it "passes if > passes" do - 4.should > 3 - end - - it "fails if > fails" do - expect(RSpec::Expectations).to receive(:fail_with).with("expected: > 5\n got: 4", 5, 4) - 4.should > 5 - end - end - - describe "should >=" do - it "passes if actual == expected" do - 4.should >= 4 - end - - it "passes if actual > expected" do - 4.should >= 3 - end - - it "fails if > fails" do - expect(RSpec::Expectations).to receive(:fail_with).with("expected: >= 5\n got: 4", 5, 4) - 4.should >= 5 - end - end - - describe "should <" do - it "passes if < passes" do - 4.should < 5 - end - - it "fails if > fails" do - expect(RSpec::Expectations).to receive(:fail_with).with("expected: < 3\n got: 4", 3, 4) - 4.should < 3 - end - end - - describe "should <=" do - it "passes if actual == expected" do - 4.should <= 4 - end - - it "passes if actual < expected" do - 4.should <= 5 - end - - it "fails if > fails" do - expect(RSpec::Expectations).to receive(:fail_with).with("expected: <= 3\n got: 4", 3, 4) - 4.should <= 3 - end - end - - describe "OperatorMatcher registry" do - let(:custom_klass) { Class.new } - let(:custom_subklass) { Class.new(custom_klass) } - - after { - RSpec::Matchers::BuiltIn::OperatorMatcher.unregister(custom_klass, "=~") - } - - it "allows operator matchers to be registered for classes" do - RSpec::Matchers::BuiltIn::OperatorMatcher.register(custom_klass, "=~", RSpec::Matchers::BuiltIn::Match) - expect(RSpec::Matchers::BuiltIn::OperatorMatcher.get(custom_klass, "=~")).to eq(RSpec::Matchers::BuiltIn::Match) - end - - it "considers ancestors when finding an operator matcher" do - RSpec::Matchers::BuiltIn::OperatorMatcher.register(custom_klass, "=~", RSpec::Matchers::BuiltIn::Match) - expect(RSpec::Matchers::BuiltIn::OperatorMatcher.get(custom_subklass, "=~")).to eq(RSpec::Matchers::BuiltIn::Match) - end - - it "returns nil if there is no matcher registered for a class" do - expect(RSpec::Matchers::BuiltIn::OperatorMatcher.get(custom_klass, "=~")).to be_nil - end - end - - describe RSpec::Matchers::BuiltIn::PositiveOperatorMatcher do - it "works when the target has implemented #send" do - o = Object.new - def o.send(*_args); raise "DOH! Library developers shouldn't use #send!" end - expect { - o.should == o - }.not_to raise_error - end - end - - describe RSpec::Matchers::BuiltIn::NegativeOperatorMatcher do - it "works when the target has implemented #send" do - o = Object.new - def o.send(*_args); raise "DOH! Library developers shouldn't use #send!" end - expect { - o.should_not == :foo - }.not_to raise_error - end - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 66498271e..2a64f429d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -39,8 +39,6 @@ def hash_inspect(hash) config.include RSpec::Support::InSubProcess config.expect_with :rspec do |expectations| - $default_expectation_syntax = expectations.syntax # rubocop:disable Style/GlobalVars - expectations.syntax = :expect expectations.include_chain_clauses_in_custom_matcher_descriptions = true expectations.strict_predicate_matchers = true end @@ -49,9 +47,6 @@ def hash_inspect(hash) mocks.verify_partial_doubles = true end - config.shared_context_metadata_behavior = :apply_to_host_groups if config.respond_to?(:shared_context_metadata_behavior=) # RSpec 4 dropped this setting - config.disable_monkey_patching! if config.respond_to?(:disable_monkey_patching!) # RSpec 4 dropped this method - # We don't want rspec-core to look in our `lib` for failure snippets. # When it does that, it inevitably finds this line: # `RSpec::Support.notify_failure(RSpec::Expectations::ExpectationNotMetError.new message)` @@ -60,45 +55,6 @@ def hash_inspect(hash) config.project_source_dirs -= ["lib"] end -RSpec.shared_context "with #should enabled" do - orig_syntax = nil - - before(:all) do - orig_syntax = RSpec::Matchers.configuration.syntax - RSpec::Matchers.configuration.syntax = [:expect, :should] - end - - after(:context) do - RSpec::Matchers.configuration.syntax = orig_syntax - end -end - -RSpec.shared_context "with the default expectation syntax" do - orig_syntax = nil - - before(:context) do - orig_syntax = RSpec::Matchers.configuration.syntax - RSpec::Matchers.configuration.reset_syntaxes_to_default - end - - after(:context) do - RSpec::Matchers.configuration.syntax = orig_syntax - end -end - -RSpec.shared_context "with #should exclusively enabled" do - orig_syntax = nil - - before(:context) do - orig_syntax = RSpec::Matchers.configuration.syntax - RSpec::Matchers.configuration.syntax = :should - end - - after(:context) do - RSpec::Matchers.configuration.syntax = orig_syntax - end -end - RSpec.shared_context "isolate include_chain_clauses_in_custom_matcher_descriptions" do around do |ex| orig = RSpec::Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions? @@ -112,12 +68,7 @@ def hash_inspect(hash) after(:context) { RSpec::Expectations.configuration.warn_about_potential_false_positives = original_value } end - -RSpec.configure do |config| - config.include_context "with #should enabled", :uses_should - config.include_context "with #should exclusively enabled", :uses_only_should - config.include_context "with warn_about_potential_false_positives set to false", :warn_about_potential_false_positives -end +RSpec.configuration.include_context "with warn_about_potential_false_positives set to false", :warn_about_potential_false_positives module MinitestIntegration include ::RSpec::Support::InSubProcess