rspec-expectations 3.8.6 → 3.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +56 -0
- data/README.md +35 -20
- data/lib/rspec/expectations/handler.rb +2 -2
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +27 -22
- data/lib/rspec/matchers/built_in/be.rb +15 -2
- data/lib/rspec/matchers/built_in/be_within.rb +2 -2
- data/lib/rspec/matchers/built_in/compound.rb +6 -1
- data/lib/rspec/matchers/built_in/has.rb +1 -0
- data/lib/rspec/matchers/built_in/have_attributes.rb +1 -1
- data/lib/rspec/matchers/built_in/respond_to.rb +37 -3
- data/lib/rspec/matchers/built_in/yield.rb +25 -16
- data/lib/rspec/matchers/dsl.rb +16 -3
- data/lib/rspec/matchers/english_phrasing.rb +1 -1
- data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +16 -7
- metadata +24 -10
- metadata.gz.sig +0 -0
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 0a7b90c1caeec07d53054eb0536482494c2584e6d7cb0fc9cfd3493ebc6b27a7
         | 
| 4 | 
            +
              data.tar.gz: 2eed511b0562ee702eb71bda98058c61d9ddda6c7b0337adde7acd72ddfb81df
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 7d0ea4666034e2901450f23fe706d1258f0b2c37ac7edd823477e31eae7c6d56e597a0b728cea0fe5f12ab80ee43ac4ed1a5c203ef34f66d180b40713adedf81
         | 
| 7 | 
            +
              data.tar.gz: 3b42d8706be59eb0dd511497941c34cebaff7476394f3f1ca80326d26c362bf3b37cca520ae0c6002a8efe167ee3fe7707e41e53072ac000c8c2a89f960fa6c0
         | 
    
        checksums.yaml.gz.sig
    CHANGED
    
    | Binary file | 
    
        data.tar.gz.sig
    CHANGED
    
    | Binary file | 
    
        data/Changelog.md
    CHANGED
    
    | @@ -1,3 +1,59 @@ | |
| 1 | 
            +
            ### 3.9.4 / 2020-10-29
         | 
| 2 | 
            +
            [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.9.4)
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Bug Fixes:
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            * Fix regression with `be_` and `have_` matchers and arguments implementing `to_hash`
         | 
| 7 | 
            +
              were they would act like keywords and be cast to a hash. (Jon Rowe, #1222)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ### 3.9.3 / 2020-10-23
         | 
| 10 | 
            +
            [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.2...v3.9.3)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            Bug Fixes:
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            * Swap the comparison of the delta vs the expected for the `be_within` matcher allowing
         | 
| 15 | 
            +
              more complicated oobjects to be compared providing they provide `abs` and other
         | 
| 16 | 
            +
              comparison methods. (Kelly Stannard, #1182)
         | 
| 17 | 
            +
            * Properly format expected in the description of the `be_within` matcher. (Jon Rowe, #1185)
         | 
| 18 | 
            +
            * Remove warning when using keyword arguments with `be_` and `have_` matchers on 2.7.x
         | 
| 19 | 
            +
              (Jon Rowe, #1187)
         | 
| 20 | 
            +
            * Prevent formatting a single hash as a list of key value pairs in default failure messages
         | 
| 21 | 
            +
              for custom matches (fixes formatting in `EnglishPhrasing#list`). (Robert Eshleman, #1193)
         | 
| 22 | 
            +
            * Prevent errors from causing false positives when using `be <operator>` comparison, e.g.
         | 
| 23 | 
            +
              `expect(1).not_to be < 'a'` will now correctly fail rather than pass. (Jon Rowe, #1208)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            ### 3.9.2 / 2020-05-08
         | 
| 26 | 
            +
            [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.1...v3.9.2)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            Bug Fixes:
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            * Issue a proper `ArgumentError` when invalid arguments are given to `yield_control`
         | 
| 31 | 
            +
              modifiers such as `at_least` et al. (Marc-André Lafortune, #1167)
         | 
| 32 | 
            +
            * Prevent Ruby 2.7 keyword arguments warning from being issued by custom
         | 
| 33 | 
            +
              matcher definitions. (Jon Rowe, #1176)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            ### 3.9.1 / 2020-03-13
         | 
| 36 | 
            +
            [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.0...v3.9.1)
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            Bug Fixes:
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            * Issue an improved warning when using `respond_to(...).with(n).arguments` and ignore
         | 
| 41 | 
            +
              the warning when using with `have_attributes(...)`. (Jon Rowe, #1164)
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            ### 3.9.0 / 2019-10-08
         | 
| 44 | 
            +
            [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.6...v3.9.0)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            Enhancements:
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            * The `respond_to` matcher now uses the signature from `initialize` to validate checks
         | 
| 49 | 
            +
              for `new` (unless `new` is non standard). (Jon Rowe, #1072)
         | 
| 50 | 
            +
            * Generated descriptions for matchers now use `is expected to` rather than `should` in
         | 
| 51 | 
            +
              line with our preferred DSL. (Pete Johns, #1080, rspec/rspec-core#2572)
         | 
| 52 | 
            +
            * Add the ability to re-raise expectation errors when matching
         | 
| 53 | 
            +
              with `match_when_negated` blocks. (Jon Rowe, #1130)
         | 
| 54 | 
            +
            * Add a warning when an empty diff is produce due to identical inspect output.
         | 
| 55 | 
            +
              (Benoit Tigeot, #1126)
         | 
| 56 | 
            +
             | 
| 1 57 | 
             
            ### 3.8.6 / 2019-10-07
         | 
| 2 58 |  | 
| 3 59 | 
             
            Bug Fixes:
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # RSpec Expectations [](http://travis-ci.org/rspec/rspec-expectations) [](https://codeclimate.com/github/rspec/rspec-expectations)
         | 
| 2 2 |  | 
| 3 3 | 
             
            RSpec::Expectations lets you express expected outcomes on an object in an
         | 
| 4 4 | 
             
            example.
         | 
| @@ -15,12 +15,12 @@ rspec-core and rspec-mocks): | |
| 15 15 |  | 
| 16 16 | 
             
                gem install rspec
         | 
| 17 17 |  | 
| 18 | 
            -
            Want to run against the ` | 
| 18 | 
            +
            Want to run against the `main` branch? You'll need to include the dependent
         | 
| 19 19 | 
             
            RSpec repos as well. Add the following to your `Gemfile`:
         | 
| 20 20 |  | 
| 21 21 | 
             
            ```ruby
         | 
| 22 22 | 
             
            %w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
         | 
| 23 | 
            -
              gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => ' | 
| 23 | 
            +
              gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main'
         | 
| 24 24 | 
             
            end
         | 
| 25 25 | 
             
            ```
         | 
| 26 26 |  | 
| @@ -175,30 +175,45 @@ expect(1..10).to cover(3) | |
| 175 175 | 
             
            ### Collection membership
         | 
| 176 176 |  | 
| 177 177 | 
             
            ```ruby
         | 
| 178 | 
            -
             | 
| 178 | 
            +
            # exact order, entire collection
         | 
| 179 | 
            +
            expect(actual).to eq(expected)
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            # exact order, partial collection (based on an exact position)
         | 
| 179 182 | 
             
            expect(actual).to start_with(expected)
         | 
| 180 183 | 
             
            expect(actual).to end_with(expected)
         | 
| 181 184 |  | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 185 | 
            +
            # any order, entire collection
         | 
| 186 | 
            +
            expect(actual).to match_array(expected)
         | 
| 187 | 
            +
             | 
| 188 | 
            +
            # You can also express this by passing the expected elements
         | 
| 189 | 
            +
            # as individual arguments
         | 
| 190 | 
            +
            expect(actual).to contain_exactly(expected_element1, expected_element2)
         | 
| 191 | 
            +
             | 
| 192 | 
            +
             # any order, partial collection
         | 
| 193 | 
            +
            expect(actual).to include(expected)
         | 
| 185 194 | 
             
            ```
         | 
| 186 195 |  | 
| 187 196 | 
             
            #### Examples
         | 
| 188 197 |  | 
| 189 198 | 
             
            ```ruby
         | 
| 190 | 
            -
            expect([1, 2, 3]).to  | 
| 191 | 
            -
            expect([1, 2, 3]).to include(1,  | 
| 192 | 
            -
            expect([1, 2, 3]).to  | 
| 193 | 
            -
            expect([1, 2, 3]).to start_with(1,  | 
| 194 | 
            -
            expect([1, 2, 3]).to  | 
| 195 | 
            -
            expect([1, 2, 3]).to end_with( | 
| 196 | 
            -
            expect( | 
| 197 | 
            -
            expect( | 
| 198 | 
            -
            expect("this string").to  | 
| 199 | 
            -
            expect("this string").to  | 
| 200 | 
            -
            expect( | 
| 201 | 
            -
            expect([1, 2, 3]).to  | 
| 199 | 
            +
            expect([1, 2, 3]).to eq([1, 2, 3])            # Order dependent equality check
         | 
| 200 | 
            +
            expect([1, 2, 3]).to include(1)               # Exact ordering, partial collection matches
         | 
| 201 | 
            +
            expect([1, 2, 3]).to include(2, 3)            #
         | 
| 202 | 
            +
            expect([1, 2, 3]).to start_with(1)            # As above, but from the start of the collection
         | 
| 203 | 
            +
            expect([1, 2, 3]).to start_with(1, 2)         #
         | 
| 204 | 
            +
            expect([1, 2, 3]).to end_with(3)              # As above but from the end of the collection
         | 
| 205 | 
            +
            expect([1, 2, 3]).to end_with(2, 3)           #
         | 
| 206 | 
            +
            expect({:a => 'b'}).to include(:a => 'b')     # Matching within hashes
         | 
| 207 | 
            +
            expect("this string").to include("is str")    # Matching within strings
         | 
| 208 | 
            +
            expect("this string").to start_with("this")   #
         | 
| 209 | 
            +
            expect("this string").to end_with("ring")     #
         | 
| 210 | 
            +
            expect([1, 2, 3]).to contain_exactly(2, 3, 1) # Order independent matches
         | 
| 211 | 
            +
            expect([1, 2, 3]).to match_array([3, 2, 1])   #
         | 
| 212 | 
            +
             | 
| 213 | 
            +
            # Order dependent compound matchers
         | 
| 214 | 
            +
            expect(
         | 
| 215 | 
            +
              [{:a => 'hash'},{:a => 'another'}]
         | 
| 216 | 
            +
            ).to match([a_hash_including(:a => 'hash'), a_hash_including(:a => 'another')])
         | 
| 202 217 | 
             
            ```
         | 
| 203 218 |  | 
| 204 219 | 
             
            ## `should` syntax
         | 
| @@ -212,7 +227,7 @@ actual.should be > 3 | |
| 212 227 | 
             
            [1, 2, 3].should_not include 4
         | 
| 213 228 | 
             
            ```
         | 
| 214 229 |  | 
| 215 | 
            -
            See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/ | 
| 230 | 
            +
            See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/main/Should.md)
         | 
| 216 231 |  | 
| 217 232 | 
             
            ## Compound Matcher Expressions
         | 
| 218 233 |  | 
| @@ -52,7 +52,7 @@ module RSpec | |
| 52 52 | 
             
                  end
         | 
| 53 53 |  | 
| 54 54 | 
             
                  def self.verb
         | 
| 55 | 
            -
                     | 
| 55 | 
            +
                    'is expected to'
         | 
| 56 56 | 
             
                  end
         | 
| 57 57 |  | 
| 58 58 | 
             
                  def self.should_method
         | 
| @@ -82,7 +82,7 @@ module RSpec | |
| 82 82 | 
             
                  end
         | 
| 83 83 |  | 
| 84 84 | 
             
                  def self.verb
         | 
| 85 | 
            -
                     | 
| 85 | 
            +
                    'is expected not to'
         | 
| 86 86 | 
             
                  end
         | 
| 87 87 |  | 
| 88 88 | 
             
                  def self.should_method
         | 
    
        data/lib/rspec/matchers.rb
    CHANGED
    
    | @@ -238,7 +238,7 @@ module RSpec | |
| 238 238 | 
             
              # best to find a more positive name for the negated form, such as
         | 
| 239 239 | 
             
              # `avoid_changing` rather than `not_change`.
         | 
| 240 240 | 
             
              #
         | 
| 241 | 
            -
              module Matchers
         | 
| 241 | 
            +
              module Matchers # rubocop:disable Metrics/ModuleLength
         | 
| 242 242 | 
             
                extend ::RSpec::Matchers::DSL
         | 
| 243 243 |  | 
| 244 244 | 
             
                # @!macro [attach] alias_matcher
         | 
| @@ -963,6 +963,7 @@ module RSpec | |
| 963 963 | 
             
                    super
         | 
| 964 964 | 
             
                  end
         | 
| 965 965 | 
             
                end
         | 
| 966 | 
            +
                ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
         | 
| 966 967 |  | 
| 967 968 | 
             
                if RUBY_VERSION.to_f >= 1.9
         | 
| 968 969 | 
             
                  def respond_to_missing?(method, *)
         | 
| @@ -1003,31 +1004,35 @@ module RSpec | |
| 1003 1004 | 
             
                  is_a_matcher?(obj) && obj.respond_to?(:description)
         | 
| 1004 1005 | 
             
                end
         | 
| 1005 1006 |  | 
| 1006 | 
            -
                 | 
| 1007 | 
            -
                   | 
| 1008 | 
            -
                  # Note that `included` doesn't work for this because it is triggered
         | 
| 1009 | 
            -
                  # _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather
         | 
| 1010 | 
            -
                  # than _before_, like `append_features`. It's important we check this before
         | 
| 1011 | 
            -
                  # in order to find the cases where it was already previously included.
         | 
| 1012 | 
            -
                  def self.append_features(mod)
         | 
| 1013 | 
            -
                    return super if mod < self # `mod < self` indicates a re-inclusion.
         | 
| 1007 | 
            +
                class << self
         | 
| 1008 | 
            +
                  private
         | 
| 1014 1009 |  | 
| 1015 | 
            -
             | 
| 1016 | 
            -
                     | 
| 1010 | 
            +
                  if RSpec::Support::Ruby.mri? && RUBY_VERSION[0, 3] == '1.9'
         | 
| 1011 | 
            +
                    # Note that `included` doesn't work for this because it is triggered
         | 
| 1012 | 
            +
                    # _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather
         | 
| 1013 | 
            +
                    # than _before_, like `append_features`. It's important we check this before
         | 
| 1014 | 
            +
                    # in order to find the cases where it was already previously included.
         | 
| 1015 | 
            +
                    # @api private
         | 
| 1016 | 
            +
                    def append_features(mod)
         | 
| 1017 | 
            +
                      return super if mod < self # `mod < self` indicates a re-inclusion.
         | 
| 1017 1018 |  | 
| 1018 | 
            -
             | 
| 1019 | 
            -
             | 
| 1019 | 
            +
                      subclasses = ObjectSpace.each_object(Class).select { |c| c < mod && c < self }
         | 
| 1020 | 
            +
                      return super unless subclasses.any?
         | 
| 1020 1021 |  | 
| 1021 | 
            -
             | 
| 1022 | 
            -
             | 
| 1023 | 
            -
                                  "which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \
         | 
| 1024 | 
            -
                                  "(https://redmine.ruby-lang.org/issues/3351). To work around this, " \
         | 
| 1025 | 
            -
                                  "either upgrade to MRI 2.0+, include a dup of the module (e.g. " \
         | 
| 1026 | 
            -
                                  "`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \
         | 
| 1027 | 
            -
                                  "before it is included in subclasses (#{subclasses}). See " \
         | 
| 1028 | 
            -
                                  "https://github.com/rspec/rspec-expectations/issues/814 for more info"
         | 
| 1022 | 
            +
                      subclasses.reject! { |s| subclasses.any? { |s2| s < s2 } } # Filter to the root ancestor.
         | 
| 1023 | 
            +
                      subclasses = subclasses.map { |s| "`#{s}`" }.join(", ")
         | 
| 1029 1024 |  | 
| 1030 | 
            -
             | 
| 1025 | 
            +
                      RSpec.warning "`#{self}` has been included in a superclass (`#{mod}`) " \
         | 
| 1026 | 
            +
                                    "after previously being included in subclasses (#{subclasses}), " \
         | 
| 1027 | 
            +
                                    "which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \
         | 
| 1028 | 
            +
                                    "(https://redmine.ruby-lang.org/issues/3351). To work around this, " \
         | 
| 1029 | 
            +
                                    "either upgrade to MRI 2.0+, include a dup of the module (e.g. " \
         | 
| 1030 | 
            +
                                    "`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \
         | 
| 1031 | 
            +
                                    "before it is included in subclasses (#{subclasses}). See " \
         | 
| 1032 | 
            +
                                    "https://github.com/rspec/rspec-expectations/issues/814 for more info"
         | 
| 1033 | 
            +
             | 
| 1034 | 
            +
                      super
         | 
| 1035 | 
            +
                    end
         | 
| 1031 1036 | 
             
                  end
         | 
| 1032 1037 | 
             
                end
         | 
| 1033 1038 | 
             
              end
         | 
| @@ -143,8 +143,13 @@ module RSpec | |
| 143 143 | 
             
                    end
         | 
| 144 144 |  | 
| 145 145 | 
             
                    def matches?(actual)
         | 
| 146 | 
            -
                       | 
| 147 | 
            -
             | 
| 146 | 
            +
                      perform_match(actual)
         | 
| 147 | 
            +
                    rescue ArgumentError, NoMethodError
         | 
| 148 | 
            +
                      false
         | 
| 149 | 
            +
                    end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                    def does_not_match?(actual)
         | 
| 152 | 
            +
                      !perform_match(actual)
         | 
| 148 153 | 
             
                    rescue ArgumentError, NoMethodError
         | 
| 149 154 | 
             
                      false
         | 
| 150 155 | 
             
                    end
         | 
| @@ -173,6 +178,13 @@ module RSpec | |
| 173 178 | 
             
                    def description
         | 
| 174 179 | 
             
                      "be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
         | 
| 175 180 | 
             
                    end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                  private
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                    def perform_match(actual)
         | 
| 185 | 
            +
                      @actual = actual
         | 
| 186 | 
            +
                      @actual.__send__ @operator, @expected
         | 
| 187 | 
            +
                    end
         | 
| 176 188 | 
             
                  end
         | 
| 177 189 |  | 
| 178 190 | 
             
                  # @api private
         | 
| @@ -186,6 +198,7 @@ module RSpec | |
| 186 198 | 
             
                      @args = args
         | 
| 187 199 | 
             
                      @block = block
         | 
| 188 200 | 
             
                    end
         | 
| 201 | 
            +
                    ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
         | 
| 189 202 |  | 
| 190 203 | 
             
                    def matches?(actual, &block)
         | 
| 191 204 | 
             
                      @actual  = actual
         | 
| @@ -23,7 +23,7 @@ module RSpec | |
| 23 23 | 
             
                    # a percent comparison.
         | 
| 24 24 | 
             
                    def percent_of(expected)
         | 
| 25 25 | 
             
                      @expected  = expected
         | 
| 26 | 
            -
                      @tolerance = @ | 
| 26 | 
            +
                      @tolerance = @expected.abs * @delta / 100.0
         | 
| 27 27 | 
             
                      @unit      = '%'
         | 
| 28 28 | 
             
                      self
         | 
| 29 29 | 
             
                    end
         | 
| @@ -50,7 +50,7 @@ module RSpec | |
| 50 50 | 
             
                    # @api private
         | 
| 51 51 | 
             
                    # @return [String]
         | 
| 52 52 | 
             
                    def description
         | 
| 53 | 
            -
                      "be within #{@delta}#{@unit} of #{ | 
| 53 | 
            +
                      "be within #{@delta}#{@unit} of #{expected_formatted}"
         | 
| 54 54 | 
             
                    end
         | 
| 55 55 |  | 
| 56 56 | 
             
                  private
         | 
| @@ -154,7 +154,12 @@ module RSpec | |
| 154 154 | 
             
                      end
         | 
| 155 155 |  | 
| 156 156 | 
             
                      def matcher_matches?(matcher)
         | 
| 157 | 
            -
                        @match_results.fetch(matcher)
         | 
| 157 | 
            +
                        @match_results.fetch(matcher) do
         | 
| 158 | 
            +
                          raise ArgumentError, "Your #{matcher.description} has no match " \
         | 
| 159 | 
            +
                           "results, this can occur when an unexpected call stack or " \
         | 
| 160 | 
            +
                           "local jump occurs. Prehaps one of your matchers needs to " \
         | 
| 161 | 
            +
                           "declare `expects_call_stack_jump?` as `true`?"
         | 
| 162 | 
            +
                        end
         | 
| 158 163 | 
             
                      end
         | 
| 159 164 |  | 
| 160 165 | 
             
                    private
         | 
| @@ -93,7 +93,7 @@ module RSpec | |
| 93 93 | 
             
                    end
         | 
| 94 94 |  | 
| 95 95 | 
             
                    def respond_to_matcher
         | 
| 96 | 
            -
                      @respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments
         | 
| 96 | 
            +
                      @respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments.tap { |m| m.ignoring_method_signature_failure! }
         | 
| 97 97 | 
             
                    end
         | 
| 98 98 |  | 
| 99 99 | 
             
                    def respond_to_failure_message_or
         | 
| @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            RSpec::Support.require_rspec_support "method_signature_verifier"
         | 
| 2 2 |  | 
| 3 | 
            +
            # TODO: Refactor this file to be under our class length
         | 
| 4 | 
            +
            # rubocop:disable ClassLength
         | 
| 3 5 | 
             
            module RSpec
         | 
| 4 6 | 
             
              module Matchers
         | 
| 5 7 | 
             
                module BuiltIn
         | 
| @@ -11,6 +13,7 @@ module RSpec | |
| 11 13 | 
             
                      @names = names
         | 
| 12 14 | 
             
                      @expected_arity = nil
         | 
| 13 15 | 
             
                      @expected_keywords = []
         | 
| 16 | 
            +
                      @ignoring_method_signature_failure = false
         | 
| 14 17 | 
             
                      @unlimited_arguments = nil
         | 
| 15 18 | 
             
                      @arbitrary_keywords = nil
         | 
| 16 19 | 
             
                    end
         | 
| @@ -100,6 +103,12 @@ module RSpec | |
| 100 103 | 
             
                      "respond to #{pp_names}#{with_arity}"
         | 
| 101 104 | 
             
                    end
         | 
| 102 105 |  | 
| 106 | 
            +
                    # @api private
         | 
| 107 | 
            +
                    # Used by other matchers to suppress a check
         | 
| 108 | 
            +
                    def ignoring_method_signature_failure!
         | 
| 109 | 
            +
                      @ignoring_method_signature_failure = true
         | 
| 110 | 
            +
                    end
         | 
| 111 | 
            +
             | 
| 103 112 | 
             
                  private
         | 
| 104 113 |  | 
| 105 114 | 
             
                    def find_failing_method_names(actual, filter_method)
         | 
| @@ -109,7 +118,7 @@ module RSpec | |
| 109 118 | 
             
                      end
         | 
| 110 119 | 
             
                    end
         | 
| 111 120 |  | 
| 112 | 
            -
                    def  | 
| 121 | 
            +
                    def setup_method_signature_expectation
         | 
| 113 122 | 
             
                      expectation = Support::MethodSignatureExpectation.new
         | 
| 114 123 |  | 
| 115 124 | 
             
                      if @expected_arity.is_a?(Range)
         | 
| @@ -123,11 +132,35 @@ module RSpec | |
| 123 132 | 
             
                      expectation.expect_unlimited_arguments = @unlimited_arguments
         | 
| 124 133 | 
             
                      expectation.expect_arbitrary_keywords  = @arbitrary_keywords
         | 
| 125 134 |  | 
| 135 | 
            +
                      expectation
         | 
| 136 | 
            +
                    end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                    def matches_arity?(actual, name)
         | 
| 139 | 
            +
                      expectation = setup_method_signature_expectation
         | 
| 140 | 
            +
             | 
| 126 141 | 
             
                      return true if expectation.empty?
         | 
| 127 142 |  | 
| 128 | 
            -
                       | 
| 143 | 
            +
                      begin
         | 
| 144 | 
            +
                        Support::StrictSignatureVerifier.new(method_signature_for(actual, name)).
         | 
| 145 | 
            +
                          with_expectation(expectation).valid?
         | 
| 146 | 
            +
                      rescue NameError
         | 
| 147 | 
            +
                        return true if @ignoring_method_signature_failure
         | 
| 148 | 
            +
                        raise ArgumentError, "The #{matcher_name} matcher requires that " \
         | 
| 149 | 
            +
                                             "the actual object define the method(s) in " \
         | 
| 150 | 
            +
                                             "order to check arity, but the method " \
         | 
| 151 | 
            +
                                             "`#{name}` is not defined. Remove the arity " \
         | 
| 152 | 
            +
                                             "check or define the method to continue."
         | 
| 153 | 
            +
                      end
         | 
| 154 | 
            +
                    end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                    def method_signature_for(actual, name)
         | 
| 157 | 
            +
                      method_handle = Support.method_handle_for(actual, name)
         | 
| 129 158 |  | 
| 130 | 
            -
                       | 
| 159 | 
            +
                      if name == :new && method_handle.owner === ::Class && ::Class === actual
         | 
| 160 | 
            +
                        Support::MethodSignature.new(actual.instance_method(:initialize))
         | 
| 161 | 
            +
                      else
         | 
| 162 | 
            +
                        Support::MethodSignature.new(method_handle)
         | 
| 163 | 
            +
                      end
         | 
| 131 164 | 
             
                    end
         | 
| 132 165 |  | 
| 133 166 | 
             
                    def with_arity
         | 
| @@ -163,3 +196,4 @@ module RSpec | |
| 163 196 | 
             
                end
         | 
| 164 197 | 
             
              end
         | 
| 165 198 | 
             
            end
         | 
| 199 | 
            +
            # rubocop:enable ClassLength
         | 
| @@ -98,7 +98,7 @@ module RSpec | |
| 98 98 | 
             
                  # Not intended to be instantiated directly.
         | 
| 99 99 | 
             
                  class YieldControl < BaseMatcher
         | 
| 100 100 | 
             
                    def initialize
         | 
| 101 | 
            -
                       | 
| 101 | 
            +
                      @expectation_type = @expected_yields_count = nil
         | 
| 102 102 | 
             
                    end
         | 
| 103 103 |  | 
| 104 104 | 
             
                    # @api public
         | 
| @@ -153,7 +153,7 @@ module RSpec | |
| 153 153 | 
             
                    def matches?(block)
         | 
| 154 154 | 
             
                      @probe = YieldProbe.probe(block)
         | 
| 155 155 | 
             
                      return false unless @probe.has_block?
         | 
| 156 | 
            -
             | 
| 156 | 
            +
                      return @probe.num_yields > 0 unless @expectation_type
         | 
| 157 157 | 
             
                      @probe.num_yields.__send__(@expectation_type, @expected_yields_count)
         | 
| 158 158 | 
             
                    end
         | 
| 159 159 |  | 
| @@ -182,35 +182,44 @@ module RSpec | |
| 182 182 | 
             
                  private
         | 
| 183 183 |  | 
| 184 184 | 
             
                    def set_expected_yields_count(relativity, n)
         | 
| 185 | 
            +
                      raise "Multiple count constraints are not supported" if @expectation_type
         | 
| 186 | 
            +
             | 
| 185 187 | 
             
                      @expectation_type = relativity
         | 
| 186 | 
            -
                      @expected_yields_count =  | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 | 
            -
             | 
| 188 | 
            +
                      @expected_yields_count = count_constraint_to_number(n)
         | 
| 189 | 
            +
                    end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                    def count_constraint_to_number(n)
         | 
| 192 | 
            +
                      case n
         | 
| 193 | 
            +
                      when Numeric then n
         | 
| 194 | 
            +
                      when :once then 1
         | 
| 195 | 
            +
                      when :twice then 2
         | 
| 196 | 
            +
                      when :thrice then 3
         | 
| 197 | 
            +
                      else
         | 
| 198 | 
            +
                        raise ArgumentError, "Expected a number, :once, :twice or :thrice," \
         | 
| 199 | 
            +
                          " but got #{n}"
         | 
| 200 | 
            +
                      end
         | 
| 192 201 | 
             
                    end
         | 
| 193 202 |  | 
| 194 203 | 
             
                    def failure_reason
         | 
| 195 204 | 
             
                      return ' but was not a block' unless @probe.has_block?
         | 
| 196 | 
            -
                       | 
| 197 | 
            -
                      " #{ | 
| 198 | 
            -
                      " but yielded #{human_readable_count(@probe.num_yields)}"
         | 
| 205 | 
            +
                      "#{human_readable_expectation_type}#{human_readable_count(@expected_yields_count)}" \
         | 
| 206 | 
            +
                      " but yielded#{human_readable_count(@probe.num_yields)}"
         | 
| 199 207 | 
             
                    end
         | 
| 200 208 |  | 
| 201 209 | 
             
                    def human_readable_expectation_type
         | 
| 202 210 | 
             
                      case @expectation_type
         | 
| 203 | 
            -
                      when :<= then 'at most | 
| 204 | 
            -
                      when :>= then 'at least | 
| 211 | 
            +
                      when :<= then ' at most'
         | 
| 212 | 
            +
                      when :>= then ' at least'
         | 
| 205 213 | 
             
                      else ''
         | 
| 206 214 | 
             
                      end
         | 
| 207 215 | 
             
                    end
         | 
| 208 216 |  | 
| 209 217 | 
             
                    def human_readable_count(count)
         | 
| 210 218 | 
             
                      case count
         | 
| 211 | 
            -
                      when  | 
| 212 | 
            -
                      when  | 
| 213 | 
            -
                       | 
| 219 | 
            +
                      when nil then ''
         | 
| 220 | 
            +
                      when 1 then ' once'
         | 
| 221 | 
            +
                      when 2 then ' twice'
         | 
| 222 | 
            +
                      else " #{count} times"
         | 
| 214 223 | 
             
                      end
         | 
| 215 224 | 
             
                    end
         | 
| 216 225 | 
             
                  end
         | 
    
        data/lib/rspec/matchers/dsl.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            RSpec::Support.require_rspec_support "with_keywords_when_needed"
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module RSpec
         | 
| 2 4 | 
             
              module Matchers
         | 
| 3 5 | 
             
                # Defines the custom matcher DSL.
         | 
| @@ -147,8 +149,14 @@ module RSpec | |
| 147 149 | 
             
                    # is rarely necessary, but can be helpful, for example, when specifying
         | 
| 148 150 | 
             
                    # asynchronous processes that require different timeouts.
         | 
| 149 151 | 
             
                    #
         | 
| 152 | 
            +
                    # By default the match block will swallow expectation errors (e.g.
         | 
| 153 | 
            +
                    # caused by using an expectation such as `expect(1).to eq 2`), if you
         | 
| 154 | 
            +
                    # with to allow these to bubble up, pass in the option
         | 
| 155 | 
            +
                    # `:notify_expectation_failures => true`.
         | 
| 156 | 
            +
                    #
         | 
| 157 | 
            +
                    # @param [Hash] options for defining the behavior of the match block.
         | 
| 150 158 | 
             
                    # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`)
         | 
| 151 | 
            -
                    def match_when_negated(&match_block)
         | 
| 159 | 
            +
                    def match_when_negated(options={}, &match_block)
         | 
| 152 160 | 
             
                      define_user_override(:does_not_match?, match_block) do |actual|
         | 
| 153 161 | 
             
                        begin
         | 
| 154 162 | 
             
                          @actual = actual
         | 
| @@ -156,6 +164,7 @@ module RSpec | |
| 156 164 | 
             
                            super(*actual_arg_for(match_block))
         | 
| 157 165 | 
             
                          end
         | 
| 158 166 | 
             
                        rescue RSpec::Expectations::ExpectationNotMetError
         | 
| 167 | 
            +
                          raise if options[:notify_expectation_failures]
         | 
| 159 168 | 
             
                          false
         | 
| 160 169 | 
             
                        end
         | 
| 161 170 | 
             
                      end
         | 
| @@ -453,11 +462,12 @@ module RSpec | |
| 453 462 | 
             
                      @chained_method_clauses = []
         | 
| 454 463 | 
             
                      @block_arg = block_arg
         | 
| 455 464 |  | 
| 456 | 
            -
                      class << self
         | 
| 465 | 
            +
                      klass = class << self
         | 
| 457 466 | 
             
                        # See `Macros#define_user_override` above, for an explanation.
         | 
| 458 467 | 
             
                        include(@user_method_defs = Module.new)
         | 
| 459 468 | 
             
                        self
         | 
| 460 | 
            -
                      end | 
| 469 | 
            +
                      end
         | 
| 470 | 
            +
                      RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *expected, &declarations)
         | 
| 461 471 | 
             
                    end
         | 
| 462 472 |  | 
| 463 473 | 
             
                    # Provides the expected value. This will return an array if
         | 
| @@ -521,6 +531,9 @@ module RSpec | |
| 521 531 | 
             
                        super(method, *args, &block)
         | 
| 522 532 | 
             
                      end
         | 
| 523 533 | 
             
                    end
         | 
| 534 | 
            +
                    # The method_missing method should be refactored to pass kw args in RSpec 4
         | 
| 535 | 
            +
                    # then this can be removed
         | 
| 536 | 
            +
                    ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
         | 
| 524 537 | 
             
                  end
         | 
| 525 538 | 
             
                end
         | 
| 526 539 | 
             
              end
         | 
| @@ -24,7 +24,7 @@ module RSpec | |
| 24 24 | 
             
                  #     list([]) #=> ""
         | 
| 25 25 | 
             
                  #
         | 
| 26 26 | 
             
                  def self.list(obj)
         | 
| 27 | 
            -
                    return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj
         | 
| 27 | 
            +
                    return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj || Hash === obj
         | 
| 28 28 | 
             
                    items = Array(obj).map { |w| RSpec::Support::ObjectFormatter.format(w) }
         | 
| 29 29 | 
             
                    case items.length
         | 
| 30 30 | 
             
                    when 0
         | 
| @@ -52,20 +52,29 @@ module RSpec | |
| 52 52 |  | 
| 53 53 | 
             
                private
         | 
| 54 54 |  | 
| 55 | 
            -
                   | 
| 56 | 
            -
                     | 
| 57 | 
            -
             | 
| 55 | 
            +
                  class << self
         | 
| 56 | 
            +
                    private
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    def diff_label_for(matcher)
         | 
| 59 | 
            +
                      "Diff for (#{truncated(RSpec::Support::ObjectFormatter.format(matcher))}):"
         | 
| 60 | 
            +
                    end
         | 
| 58 61 |  | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            +
                    def truncated(description)
         | 
| 63 | 
            +
                      return description if description.length <= DESCRIPTION_MAX_LENGTH
         | 
| 64 | 
            +
                      description[0...DESCRIPTION_MAX_LENGTH - 3] << "..."
         | 
| 65 | 
            +
                    end
         | 
| 62 66 | 
             
                  end
         | 
| 63 67 |  | 
| 64 68 | 
             
                  def diffs(differ, actual)
         | 
| 65 69 | 
             
                    @expected_list.map do |(expected, diff_label)|
         | 
| 66 70 | 
             
                      diff = differ.diff(actual, expected)
         | 
| 67 71 | 
             
                      next if diff.strip.empty?
         | 
| 68 | 
            -
                       | 
| 72 | 
            +
                      if diff == "\e[0m\n\e[0m"
         | 
| 73 | 
            +
                        "#{diff_label}\n" \
         | 
| 74 | 
            +
                          "  <The diff is empty, are your objects producing identical `#inspect` output?>"
         | 
| 75 | 
            +
                      else
         | 
| 76 | 
            +
                        "#{diff_label}#{diff}"
         | 
| 77 | 
            +
                      end
         | 
| 69 78 | 
             
                    end.compact.join("\n")
         | 
| 70 79 | 
             
                  end
         | 
| 71 80 | 
             
                end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rspec-expectations
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 3. | 
| 4 | 
            +
              version: 3.9.4
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Steven Baker
         | 
| 8 8 | 
             
            - David Chelimsky
         | 
| 9 9 | 
             
            - Myron Marston
         | 
| 10 | 
            -
            autorequire: | 
| 10 | 
            +
            autorequire:
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain:
         | 
| 13 13 | 
             
            - |
         | 
| @@ -45,7 +45,7 @@ cert_chain: | |
| 45 45 | 
             
              ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
         | 
| 46 46 | 
             
              F3MdtaDehhjC
         | 
| 47 47 | 
             
              -----END CERTIFICATE-----
         | 
| 48 | 
            -
            date:  | 
| 48 | 
            +
            date: 2020-10-29 00:00:00.000000000 Z
         | 
| 49 49 | 
             
            dependencies:
         | 
| 50 50 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 51 51 | 
             
              name: rspec-support
         | 
| @@ -53,14 +53,14 @@ dependencies: | |
| 53 53 | 
             
                requirements:
         | 
| 54 54 | 
             
                - - "~>"
         | 
| 55 55 | 
             
                  - !ruby/object:Gem::Version
         | 
| 56 | 
            -
                    version: 3. | 
| 56 | 
            +
                    version: 3.9.0
         | 
| 57 57 | 
             
              type: :runtime
         | 
| 58 58 | 
             
              prerelease: false
         | 
| 59 59 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 60 60 | 
             
                requirements:
         | 
| 61 61 | 
             
                - - "~>"
         | 
| 62 62 | 
             
                  - !ruby/object:Gem::Version
         | 
| 63 | 
            -
                    version: 3. | 
| 63 | 
            +
                    version: 3.9.0
         | 
| 64 64 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 65 65 | 
             
              name: diff-lcs
         | 
| 66 66 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -123,6 +123,20 @@ dependencies: | |
| 123 123 | 
             
                - - "~>"
         | 
| 124 124 | 
             
                  - !ruby/object:Gem::Version
         | 
| 125 125 | 
             
                    version: '5.2'
         | 
| 126 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 127 | 
            +
              name: rake
         | 
| 128 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 129 | 
            +
                requirements:
         | 
| 130 | 
            +
                - - ">"
         | 
| 131 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 132 | 
            +
                    version: 10.0.0
         | 
| 133 | 
            +
              type: :development
         | 
| 134 | 
            +
              prerelease: false
         | 
| 135 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 136 | 
            +
                requirements:
         | 
| 137 | 
            +
                - - ">"
         | 
| 138 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 139 | 
            +
                    version: 10.0.0
         | 
| 126 140 | 
             
            description: rspec-expectations provides a simple, readable API to express expected
         | 
| 127 141 | 
             
              outcomes of a code example.
         | 
| 128 142 | 
             
            email: rspec@googlegroups.com
         | 
| @@ -188,11 +202,11 @@ licenses: | |
| 188 202 | 
             
            - MIT
         | 
| 189 203 | 
             
            metadata:
         | 
| 190 204 | 
             
              bug_tracker_uri: https://github.com/rspec/rspec-expectations/issues
         | 
| 191 | 
            -
              changelog_uri: https://github.com/rspec/rspec-expectations/blob/v3. | 
| 205 | 
            +
              changelog_uri: https://github.com/rspec/rspec-expectations/blob/v3.9.4/Changelog.md
         | 
| 192 206 | 
             
              documentation_uri: https://rspec.info/documentation/
         | 
| 193 207 | 
             
              mailing_list_uri: https://groups.google.com/forum/#!forum/rspec
         | 
| 194 208 | 
             
              source_code_uri: https://github.com/rspec/rspec-expectations
         | 
| 195 | 
            -
            post_install_message: | 
| 209 | 
            +
            post_install_message:
         | 
| 196 210 | 
             
            rdoc_options:
         | 
| 197 211 | 
             
            - "--charset=UTF-8"
         | 
| 198 212 | 
             
            require_paths:
         | 
| @@ -208,8 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 208 222 | 
             
                - !ruby/object:Gem::Version
         | 
| 209 223 | 
             
                  version: '0'
         | 
| 210 224 | 
             
            requirements: []
         | 
| 211 | 
            -
            rubygems_version: 3. | 
| 212 | 
            -
            signing_key: | 
| 225 | 
            +
            rubygems_version: 3.1.3
         | 
| 226 | 
            +
            signing_key:
         | 
| 213 227 | 
             
            specification_version: 4
         | 
| 214 | 
            -
            summary: rspec-expectations-3. | 
| 228 | 
            +
            summary: rspec-expectations-3.9.4
         | 
| 215 229 | 
             
            test_files: []
         | 
    
        metadata.gz.sig
    CHANGED
    
    | Binary file |