rspec-expectations 3.5.0 → 3.9.0
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +138 -2
- data/README.md +37 -20
- data/lib/rspec/expectations.rb +2 -1
- data/lib/rspec/expectations/block_snippet_extractor.rb +253 -0
- data/lib/rspec/expectations/configuration.rb +14 -0
- data/lib/rspec/expectations/expectation_target.rb +2 -2
- data/lib/rspec/expectations/fail_with.rb +9 -1
- data/lib/rspec/expectations/handler.rb +2 -2
- data/lib/rspec/expectations/minitest_integration.rb +1 -1
- data/lib/rspec/expectations/syntax.rb +2 -2
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +97 -97
- data/lib/rspec/matchers/built_in/all.rb +1 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +14 -2
- data/lib/rspec/matchers/built_in/be.rb +2 -2
- data/lib/rspec/matchers/built_in/be_instance_of.rb +5 -1
- data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -1
- data/lib/rspec/matchers/built_in/change.rb +127 -53
- data/lib/rspec/matchers/built_in/compound.rb +6 -2
- data/lib/rspec/matchers/built_in/contain_exactly.rb +18 -2
- data/lib/rspec/matchers/built_in/exist.rb +5 -1
- data/lib/rspec/matchers/built_in/has.rb +1 -1
- data/lib/rspec/matchers/built_in/include.rb +6 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +1 -1
- data/lib/rspec/matchers/built_in/respond_to.rb +13 -4
- data/lib/rspec/matchers/built_in/satisfy.rb +27 -4
- data/lib/rspec/matchers/built_in/yield.rb +43 -30
- data/lib/rspec/matchers/composable.rb +6 -20
- data/lib/rspec/matchers/dsl.rb +72 -4
- data/lib/rspec/matchers/english_phrasing.rb +3 -3
- data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +16 -7
- data/lib/rspec/matchers/generated_descriptions.rb +1 -2
- metadata +22 -18
- metadata.gz.sig +0 -0
@@ -56,6 +56,20 @@ module RSpec
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
# Configures the maximum character length that RSpec will print while
|
60
|
+
# formatting an object. You can set length to nil to prevent RSpec from
|
61
|
+
# doing truncation.
|
62
|
+
# @param [Fixnum] length the number of characters to limit the formatted output to.
|
63
|
+
# @example
|
64
|
+
# RSpec.configure do |rspec|
|
65
|
+
# rspec.expect_with :rspec do |c|
|
66
|
+
# c.max_formatted_output_length = 200
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
def max_formatted_output_length=(length)
|
70
|
+
RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = length
|
71
|
+
end
|
72
|
+
|
59
73
|
# The list of configured syntaxes.
|
60
74
|
# @return [Array<Symbol>] the list of configured syntaxes.
|
61
75
|
# @example
|
@@ -48,7 +48,7 @@ module RSpec
|
|
48
48
|
|
49
49
|
# Defines instance {ExpectationTarget} instance methods. These are defined
|
50
50
|
# in a module so we can include it in `Minitest::Expectation` when
|
51
|
-
# `rspec/expectations/minitest_integration` is
|
51
|
+
# `rspec/expectations/minitest_integration` is loaded in order to
|
52
52
|
# support usage with Minitest.
|
53
53
|
module InstanceMethods
|
54
54
|
# Runs the given expectation, passing if `matcher` returns true.
|
@@ -112,7 +112,7 @@ module RSpec
|
|
112
112
|
def enforce_block_expectation(matcher)
|
113
113
|
return if supports_block_expectations?(matcher)
|
114
114
|
|
115
|
-
raise ExpectationNotMetError, "You must pass an argument rather than a block to use the provided " \
|
115
|
+
raise ExpectationNotMetError, "You must pass an argument rather than a block to `expect` to use the provided " \
|
116
116
|
"matcher (#{RSpec::Support::ObjectFormatter.format(matcher)}), or the matcher must implement " \
|
117
117
|
"`supports_block_expectations?`."
|
118
118
|
end
|
@@ -1,10 +1,18 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Expectations
|
3
3
|
class << self
|
4
|
+
# @private
|
5
|
+
class Differ
|
6
|
+
# @private
|
7
|
+
OBJECT_PREPARER = lambda do |object|
|
8
|
+
RSpec::Matchers::Composable.surface_descriptions_in(object)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
4
12
|
# @private
|
5
13
|
def differ
|
6
14
|
RSpec::Support::Differ.new(
|
7
|
-
:object_preparer =>
|
15
|
+
:object_preparer => Differ::OBJECT_PREPARER,
|
8
16
|
:color => RSpec::Matchers.configuration.color?
|
9
17
|
)
|
10
18
|
end
|
@@ -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
|
@@ -106,7 +106,7 @@ if defined?(BasicObject)
|
|
106
106
|
# that this syntax does not always play nice with delegate/proxy objects.
|
107
107
|
# We recommend you use the non-monkeypatching `:expect` syntax instead.
|
108
108
|
class BasicObject
|
109
|
-
# @method should
|
109
|
+
# @method should(matcher, message)
|
110
110
|
# Passes if `matcher` returns true. Available on every `Object`.
|
111
111
|
# @example
|
112
112
|
# actual.should eq expected
|
@@ -118,7 +118,7 @@ if defined?(BasicObject)
|
|
118
118
|
# @note This is only available when you have enabled the `:should` syntax.
|
119
119
|
# @see RSpec::Matchers
|
120
120
|
|
121
|
-
# @method should_not
|
121
|
+
# @method should_not(matcher, message)
|
122
122
|
# Passes if `matcher` returns false. Available on every `Object`.
|
123
123
|
# @example
|
124
124
|
# actual.should_not eq expected
|
data/lib/rspec/matchers.rb
CHANGED
@@ -41,9 +41,9 @@ module RSpec
|
|
41
41
|
#
|
42
42
|
# expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes
|
43
43
|
#
|
44
|
-
# expect(3).to be_a_kind_of(
|
45
|
-
# expect(3).to be_a_kind_of(Numeric)
|
46
|
-
# expect(3).to be_an_instance_of(
|
44
|
+
# expect(3).to be_a_kind_of(Integer) # => 3.kind_of?(Numeric) | passes
|
45
|
+
# expect(3).to be_a_kind_of(Numeric) # => 3.kind_of?(Numeric) | passes
|
46
|
+
# expect(3).to be_an_instance_of(Integer) # => 3.instance_of?(Integer) | passes
|
47
47
|
# expect(3).not_to be_an_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails
|
48
48
|
#
|
49
49
|
# RSpec will also create custom matchers for predicates like `has_key?`. To
|
@@ -62,6 +62,26 @@ module RSpec
|
|
62
62
|
# RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin
|
63
63
|
# expect(user_list).to include(a_user_who_is_an_admin)
|
64
64
|
#
|
65
|
+
# ## Alias Matchers
|
66
|
+
#
|
67
|
+
# With {RSpec::Matchers.alias_matcher}, you can easily create an
|
68
|
+
# alternate name for a given matcher.
|
69
|
+
#
|
70
|
+
# The description will also change according to the new name:
|
71
|
+
#
|
72
|
+
# RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to
|
73
|
+
# sum_to(3).description # => "sum to 3"
|
74
|
+
# a_list_that_sums_to(3).description # => "a list that sums to 3"
|
75
|
+
#
|
76
|
+
# or you can specify a custom description like this:
|
77
|
+
#
|
78
|
+
# RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description|
|
79
|
+
# description.sub("be sorted by", "a list sorted by")
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# be_sorted_by(:age).description # => "be sorted by age"
|
83
|
+
# a_list_sorted_by(:age).description # => "a list sorted by age"
|
84
|
+
#
|
65
85
|
# ## Custom Matchers
|
66
86
|
#
|
67
87
|
# When you find that none of the stock matchers provide a natural feeling
|
@@ -202,80 +222,53 @@ module RSpec
|
|
202
222
|
# expressions, and also uses the noun-phrase wording in the matcher's `description`,
|
203
223
|
# for readable failure messages. You can alias your custom matchers in similar fashion
|
204
224
|
# using {RSpec::Matchers.alias_matcher}.
|
225
|
+
#
|
226
|
+
# ## Negated Matchers
|
227
|
+
#
|
228
|
+
# Sometimes if you want to test for the opposite using a more descriptive name
|
229
|
+
# instead of using `not_to`, you can use {RSpec::Matchers.define_negated_matcher}:
|
230
|
+
#
|
231
|
+
# RSpec::Matchers.define_negated_matcher :exclude, :include
|
232
|
+
# include(1, 2).description # => "include 1 and 2"
|
233
|
+
# exclude(1, 2).description # => "exclude 1 and 2"
|
234
|
+
#
|
235
|
+
# While the most obvious negated form may be to add a `not_` prefix,
|
236
|
+
# the failure messages you get with that form can be confusing (e.g.
|
237
|
+
# "expected [actual] to not [verb], but did not"). We've found it works
|
238
|
+
# best to find a more positive name for the negated form, such as
|
239
|
+
# `avoid_changing` rather than `not_change`.
|
240
|
+
#
|
205
241
|
module Matchers
|
206
|
-
|
207
|
-
# Supports `expect(actual).to matcher` syntax by wrapping `actual` in an
|
208
|
-
# `ExpectationTarget`.
|
209
|
-
# @example
|
210
|
-
# expect(actual).to eq(expected)
|
211
|
-
# expect(actual).not_to eq(expected)
|
212
|
-
# @return [ExpectationTarget]
|
213
|
-
# @see ExpectationTarget#to
|
214
|
-
# @see ExpectationTarget#not_to
|
242
|
+
extend ::RSpec::Matchers::DSL
|
215
243
|
|
216
|
-
# Defines a matcher alias. The returned matcher's `description` will be overriden
|
217
|
-
# to reflect the phrasing of the new name, which will be used in failure messages
|
218
|
-
# when passed as an argument to another matcher in a composed matcher expression.
|
219
|
-
#
|
220
|
-
# @param new_name [Symbol] the new name for the matcher
|
221
|
-
# @param old_name [Symbol] the original name for the matcher
|
222
|
-
# @param options [Hash] options for the aliased matcher
|
223
|
-
# @option options [Class] :klass the ruby class to use as the decorator. (Not normally used).
|
224
|
-
# @yield [String] optional block that, when given, is used to define the overriden
|
225
|
-
# logic. The yielded arg is the original description or failure message. If no
|
226
|
-
# block is provided, a default override is used based on the old and new names.
|
227
|
-
#
|
228
|
-
# @example
|
229
|
-
# RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to
|
230
|
-
# sum_to(3).description # => "sum to 3"
|
231
|
-
# a_list_that_sums_to(3).description # => "a list that sums to 3"
|
232
|
-
#
|
233
|
-
# @example
|
234
|
-
# RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description|
|
235
|
-
# description.sub("be sorted by", "a list sorted by")
|
236
|
-
# end
|
237
|
-
#
|
238
|
-
# be_sorted_by(:age).description # => "be sorted by age"
|
239
|
-
# a_list_sorted_by(:age).description # => "a list sorted by age"
|
240
|
-
#
|
241
244
|
# @!macro [attach] alias_matcher
|
242
245
|
# @!parse
|
243
246
|
# alias $1 $2
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
define_method(new_name) do |*args, &block|
|
251
|
-
matcher = __send__(old_name, *args, &block)
|
252
|
-
klass.new(matcher, description_override)
|
253
|
-
end
|
247
|
+
# @!visibility private
|
248
|
+
# We define this override here so we can attach a YARD macro to it.
|
249
|
+
# It ensures that our docs list all the matcher aliases.
|
250
|
+
def self.alias_matcher(*args, &block)
|
251
|
+
super(*args, &block)
|
254
252
|
end
|
255
253
|
|
256
|
-
#
|
257
|
-
#
|
258
|
-
|
259
|
-
#
|
260
|
-
#
|
261
|
-
|
262
|
-
#
|
263
|
-
#
|
264
|
-
|
265
|
-
#
|
254
|
+
# @!method self.alias_matcher(new_name, old_name, options={}, &description_override)
|
255
|
+
# Extended from {RSpec::Matchers::DSL#alias_matcher}.
|
256
|
+
|
257
|
+
# @!method self.define(name, &declarations)
|
258
|
+
# Extended from {RSpec::Matchers::DSL#define}.
|
259
|
+
|
260
|
+
# @!method self.define_negated_matcher(negated_name, base_name, &description_override)
|
261
|
+
# Extended from {RSpec::Matchers::DSL#define_negated_matcher}.
|
262
|
+
|
263
|
+
# @method expect
|
264
|
+
# Supports `expect(actual).to matcher` syntax by wrapping `actual` in an
|
265
|
+
# `ExpectationTarget`.
|
266
266
|
# @example
|
267
|
-
#
|
268
|
-
#
|
269
|
-
#
|
270
|
-
#
|
271
|
-
# @
|
272
|
-
# the failure messages you get with that form can be confusing (e.g.
|
273
|
-
# "expected [actual] to not [verb], but did not"). We've found it works
|
274
|
-
# best to find a more positive name for the negated form, such as
|
275
|
-
# `avoid_changing` rather than `not_change`.
|
276
|
-
def self.define_negated_matcher(negated_name, base_name, &description_override)
|
277
|
-
alias_matcher(negated_name, base_name, :klass => AliasedNegatedMatcher, &description_override)
|
278
|
-
end
|
267
|
+
# expect(actual).to eq(expected)
|
268
|
+
# expect(actual).not_to eq(expected)
|
269
|
+
# @return [Expectations::ExpectationTarget]
|
270
|
+
# @see Expectations::ExpectationTarget#to
|
271
|
+
# @see Expectations::ExpectationTarget#not_to
|
279
272
|
|
280
273
|
# Allows multiple expectations in the provided block to fail, and then
|
281
274
|
# aggregates them into a single exception, rather than aborting on the
|
@@ -367,7 +360,7 @@ module RSpec
|
|
367
360
|
# Passes if actual.instance_of?(expected)
|
368
361
|
#
|
369
362
|
# @example
|
370
|
-
# expect(5).to be_an_instance_of(
|
363
|
+
# expect(5).to be_an_instance_of(Integer)
|
371
364
|
# expect(5).not_to be_an_instance_of(Numeric)
|
372
365
|
# expect(5).not_to be_an_instance_of(Float)
|
373
366
|
def be_an_instance_of(expected)
|
@@ -379,7 +372,7 @@ module RSpec
|
|
379
372
|
# Passes if actual.kind_of?(expected)
|
380
373
|
#
|
381
374
|
# @example
|
382
|
-
# expect(5).to be_a_kind_of(
|
375
|
+
# expect(5).to be_a_kind_of(Integer)
|
383
376
|
# expect(5).to be_a_kind_of(Numeric)
|
384
377
|
# expect(5).not_to be_a_kind_of(Float)
|
385
378
|
def be_a_kind_of(expected)
|
@@ -487,7 +480,10 @@ module RSpec
|
|
487
480
|
# == Notes
|
488
481
|
#
|
489
482
|
# Evaluates `receiver.message` or `block` before and after it
|
490
|
-
# evaluates the block passed to `expect`.
|
483
|
+
# evaluates the block passed to `expect`. If the value is the same
|
484
|
+
# object, its before/after `hash` value is used to see if it has changed.
|
485
|
+
# Therefore, your object needs to properly implement `hash` to work correctly
|
486
|
+
# with this matcher.
|
491
487
|
#
|
492
488
|
# `expect( ... ).not_to change` supports the form that specifies `from`
|
493
489
|
# (which specifies what you expect the starting, unchanged value to be)
|
@@ -585,7 +581,7 @@ module RSpec
|
|
585
581
|
# information about equality in Ruby.
|
586
582
|
#
|
587
583
|
# @example
|
588
|
-
# expect(5).to equal(5) #
|
584
|
+
# expect(5).to equal(5) # Integers are equal
|
589
585
|
# expect("5").not_to equal("5") # Strings that look the same are not the same object
|
590
586
|
def equal(expected)
|
591
587
|
BuiltIn::Equal.new(expected)
|
@@ -688,7 +684,7 @@ module RSpec
|
|
688
684
|
# :a => {
|
689
685
|
# :b => a_collection_containing_exactly(
|
690
686
|
# a_string_starting_with("f"),
|
691
|
-
# an_instance_of(
|
687
|
+
# an_instance_of(Integer)
|
692
688
|
# ),
|
693
689
|
# :c => { :d => (a_value < 3) }
|
694
690
|
# }
|
@@ -809,7 +805,7 @@ module RSpec
|
|
809
805
|
# @example
|
810
806
|
# expect(5).to satisfy { |n| n > 3 }
|
811
807
|
# expect(5).to satisfy("be greater than 3") { |n| n > 3 }
|
812
|
-
def satisfy(description=
|
808
|
+
def satisfy(description=nil, &block)
|
813
809
|
BuiltIn::Satisfy.new(description, &block)
|
814
810
|
end
|
815
811
|
alias_matcher :an_object_satisfying, :satisfy
|
@@ -905,7 +901,7 @@ module RSpec
|
|
905
901
|
# @example
|
906
902
|
# expect { |b| 5.tap(&b) }.to yield_with_args # because #tap yields an arg
|
907
903
|
# expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5
|
908
|
-
# expect { |b| 5.tap(&b) }.to yield_with_args(
|
904
|
+
# expect { |b| 5.tap(&b) }.to yield_with_args(Integer) # because Integer === 5
|
909
905
|
# expect { |b| File.open("f.txt", &b) }.to yield_with_args(/txt/) # because /txt/ === "f.txt"
|
910
906
|
#
|
911
907
|
# expect { |b| User.transaction(&b) }.not_to yield_with_args # because it yields no args
|
@@ -1007,31 +1003,35 @@ module RSpec
|
|
1007
1003
|
is_a_matcher?(obj) && obj.respond_to?(:description)
|
1008
1004
|
end
|
1009
1005
|
|
1010
|
-
|
1011
|
-
|
1012
|
-
# Note that `included` doesn't work for this because it is triggered
|
1013
|
-
# _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather
|
1014
|
-
# than _before_, like `append_features`. It's important we check this before
|
1015
|
-
# in order to find the cases where it was already previously included.
|
1016
|
-
def self.append_features(mod)
|
1017
|
-
return super if mod < self # `mod < self` indicates a re-inclusion.
|
1006
|
+
class << self
|
1007
|
+
private
|
1018
1008
|
|
1019
|
-
|
1020
|
-
|
1009
|
+
if RSpec::Support::Ruby.mri? && RUBY_VERSION[0, 3] == '1.9'
|
1010
|
+
# Note that `included` doesn't work for this because it is triggered
|
1011
|
+
# _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather
|
1012
|
+
# than _before_, like `append_features`. It's important we check this before
|
1013
|
+
# in order to find the cases where it was already previously included.
|
1014
|
+
# @api private
|
1015
|
+
def append_features(mod)
|
1016
|
+
return super if mod < self # `mod < self` indicates a re-inclusion.
|
1021
1017
|
|
1022
|
-
|
1023
|
-
|
1018
|
+
subclasses = ObjectSpace.each_object(Class).select { |c| c < mod && c < self }
|
1019
|
+
return super unless subclasses.any?
|
1024
1020
|
|
1025
|
-
|
1026
|
-
|
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"
|
1021
|
+
subclasses.reject! { |s| subclasses.any? { |s2| s < s2 } } # Filter to the root ancestor.
|
1022
|
+
subclasses = subclasses.map { |s| "`#{s}`" }.join(", ")
|
1033
1023
|
|
1034
|
-
|
1024
|
+
RSpec.warning "`#{self}` has been included in a superclass (`#{mod}`) " \
|
1025
|
+
"after previously being included in subclasses (#{subclasses}), " \
|
1026
|
+
"which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \
|
1027
|
+
"(https://redmine.ruby-lang.org/issues/3351). To work around this, " \
|
1028
|
+
"either upgrade to MRI 2.0+, include a dup of the module (e.g. " \
|
1029
|
+
"`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \
|
1030
|
+
"before it is included in subclasses (#{subclasses}). See " \
|
1031
|
+
"https://github.com/rspec/rspec-expectations/issues/814 for more info"
|
1032
|
+
|
1033
|
+
super
|
1034
|
+
end
|
1035
1035
|
end
|
1036
1036
|
end
|
1037
1037
|
end
|
@@ -22,6 +22,9 @@ module RSpec
|
|
22
22
|
# @private
|
23
23
|
attr_reader :actual, :expected, :rescued_exception
|
24
24
|
|
25
|
+
# @private
|
26
|
+
attr_writer :matcher_name
|
27
|
+
|
25
28
|
def initialize(expected=UNDEFINED)
|
26
29
|
@expected = expected unless UNDEFINED.equal?(expected)
|
27
30
|
end
|
@@ -95,6 +98,15 @@ module RSpec
|
|
95
98
|
@matcher_name ||= underscore(name.split('::').last)
|
96
99
|
end
|
97
100
|
|
101
|
+
# @private
|
102
|
+
def matcher_name
|
103
|
+
if defined?(@matcher_name)
|
104
|
+
@matcher_name
|
105
|
+
else
|
106
|
+
self.class.matcher_name
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
98
110
|
# @private
|
99
111
|
# Borrowed from ActiveSupport.
|
100
112
|
def self.underscore(camel_cased_word)
|
@@ -153,7 +165,7 @@ module RSpec
|
|
153
165
|
# you often only need to override `description`.
|
154
166
|
# @return [String]
|
155
167
|
def failure_message
|
156
|
-
"expected #{description_of @actual} to #{description}"
|
168
|
+
"expected #{description_of @actual} to #{description}".dup
|
157
169
|
end
|
158
170
|
|
159
171
|
# @api private
|
@@ -162,7 +174,7 @@ module RSpec
|
|
162
174
|
# you often only need to override `description`.
|
163
175
|
# @return [String]
|
164
176
|
def failure_message_when_negated
|
165
|
-
"expected #{description_of @actual} not to #{description}"
|
177
|
+
"expected #{description_of @actual} not to #{description}".dup
|
166
178
|
end
|
167
179
|
|
168
180
|
# @private
|
@@ -145,7 +145,7 @@ module RSpec
|
|
145
145
|
def matches?(actual)
|
146
146
|
@actual = actual
|
147
147
|
@actual.__send__ @operator, @expected
|
148
|
-
rescue ArgumentError
|
148
|
+
rescue ArgumentError, NoMethodError
|
149
149
|
false
|
150
150
|
end
|
151
151
|
|
@@ -270,7 +270,7 @@ module RSpec
|
|
270
270
|
def validity_message
|
271
271
|
return nil if predicate_accessible?
|
272
272
|
|
273
|
-
msg = "expected #{actual_formatted} to respond to `#{predicate}`"
|
273
|
+
msg = "expected #{actual_formatted} to respond to `#{predicate}`".dup
|
274
274
|
|
275
275
|
if private_predicate?
|
276
276
|
msg << " but `#{predicate}` is a private method"
|