rspec-expectations 3.9.4 → 3.10.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +21 -1
- data/lib/rspec/expectations/configuration.rb +15 -0
- data/lib/rspec/expectations/failure_aggregator.rb +19 -1
- data/lib/rspec/expectations/handler.rb +18 -6
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +41 -39
- data/lib/rspec/matchers/built_in.rb +2 -1
- data/lib/rspec/matchers/built_in/be.rb +0 -110
- data/lib/rspec/matchers/built_in/count_expectation.rb +169 -0
- data/lib/rspec/matchers/built_in/has.rb +87 -24
- data/lib/rspec/matchers/built_in/include.rb +72 -15
- data/lib/rspec/matchers/built_in/raise_error.rb +42 -13
- data/lib/rspec/matchers/built_in/respond_to.rb +46 -45
- data/lib/rspec/matchers/built_in/yield.rb +6 -92
- metadata +7 -6
- metadata.gz.sig +4 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7aa5ece24e4b7264047d888a2cee103146afe93a99a6f2b8a8eb18e668a53660
|
4
|
+
data.tar.gz: 12517aab36f0f0d698af5aa1fff130fc1caf3273be010375cbfbbd9c534243cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5518381caa98706fa70dab05072d52722ff2511d249c848cd10564eb8ce63e80ddab0146b66528bb383a89563a900ad25dc5ea854fd0f3af12524c46fd9e7ad7
|
7
|
+
data.tar.gz: 73b7195cf0e86c040a33d2729ec51ca97cb062e6c066458732e7dbe5e957a5ce3f25e6aadb1d8af5e18b65051f79662d223bd9b6e4270e7793155629b9e0d491
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
### 3.10.0 / 2020-10-30
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.10.0)
|
3
|
+
|
4
|
+
Enhancements:
|
5
|
+
|
6
|
+
* Allow `include` matcher to be chained with `once`, `at_least`, etc. for simple cases.
|
7
|
+
(Marc-André Lafortune, #1168)
|
8
|
+
* Add an explicit warning when `nil` is passed to `raise_error`. (Phil Pirozhkov, #1143)
|
9
|
+
* Improve `include` matcher's composability. (Phil Pirozhkov, #1155)
|
10
|
+
* Mocks expectations can now set a custom failure message.
|
11
|
+
(Benoit Tigeot and Nicolas Zermati, #1156)
|
12
|
+
* `aggregate_failures` now shows the backtrace line for each failure. (Fabricio Bedin, #1163)
|
13
|
+
* Support multiple combinations of `yield_control` modifiers like `at_least`, `at_most`.
|
14
|
+
(Jon Rowe, #1169)
|
15
|
+
* Dynamic `have_<n>` matchers now have output consistent with other dynamic matchers.
|
16
|
+
(Marc-André Lafortune, #1195)
|
17
|
+
* New config option `strict_predicate_matchers` allows predicate matcher to be strict
|
18
|
+
(i.e. match for `true` or `false`) instead of the default (match truthy vs `false` or `nil`).
|
19
|
+
(Marc-André Lafortune, #1196)
|
20
|
+
|
1
21
|
### 3.9.4 / 2020-10-29
|
2
22
|
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.9.4)
|
3
23
|
|
@@ -7,7 +27,6 @@ Bug Fixes:
|
|
7
27
|
were they would act like keywords and be cast to a hash. (Jon Rowe, #1222)
|
8
28
|
|
9
29
|
### 3.9.3 / 2020-10-23
|
10
|
-
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.2...v3.9.3)
|
11
30
|
|
12
31
|
Bug Fixes:
|
13
32
|
|
@@ -22,6 +41,7 @@ Bug Fixes:
|
|
22
41
|
* Prevent errors from causing false positives when using `be <operator>` comparison, e.g.
|
23
42
|
`expect(1).not_to be < 'a'` will now correctly fail rather than pass. (Jon Rowe, #1208)
|
24
43
|
|
44
|
+
|
25
45
|
### 3.9.2 / 2020-05-08
|
26
46
|
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.1...v3.9.2)
|
27
47
|
|
@@ -28,6 +28,7 @@ module RSpec
|
|
28
28
|
|
29
29
|
def initialize
|
30
30
|
@on_potential_false_positives = :warn
|
31
|
+
@strict_predicate_matchers = false
|
31
32
|
end
|
32
33
|
|
33
34
|
# Configures the supported syntax.
|
@@ -185,6 +186,20 @@ module RSpec
|
|
185
186
|
@on_potential_false_positives = behavior
|
186
187
|
end
|
187
188
|
|
189
|
+
# Configures RSpec to check predicate matchers to `be(true)` / `be(false)` (strict),
|
190
|
+
# or `be_truthy` / `be_falsey` (not strict).
|
191
|
+
# Historically, the default was `false`, but `true` is recommended.
|
192
|
+
def strict_predicate_matchers=(flag)
|
193
|
+
raise ArgumentError, "Pass `true` or `false`" unless flag == true || flag == false
|
194
|
+
@strict_predicate_matchers = flag
|
195
|
+
end
|
196
|
+
|
197
|
+
attr_reader :strict_predicate_matchers
|
198
|
+
|
199
|
+
def strict_predicate_matchers?
|
200
|
+
@strict_predicate_matchers
|
201
|
+
end
|
202
|
+
|
188
203
|
# Indicates what RSpec will do about matcher use which will
|
189
204
|
# potentially cause false positives in tests, generally you want to
|
190
205
|
# avoid such scenarios so this defaults to `true`.
|
@@ -150,11 +150,29 @@ module RSpec
|
|
150
150
|
def enumerated(exceptions, index_offset)
|
151
151
|
exceptions.each_with_index.map do |exception, index|
|
152
152
|
index += index_offset
|
153
|
-
formatted_message = yield exception
|
153
|
+
formatted_message = "#{yield exception}\n#{format_backtrace(exception.backtrace).first}"
|
154
154
|
"#{index_label index}#{indented formatted_message, index}"
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
158
|
+
def exclusion_patterns
|
159
|
+
patterns = %w[/lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle:]
|
160
|
+
patterns << "org/jruby/" if RSpec::Support::Ruby.jruby?
|
161
|
+
patterns.map! { |s| Regexp.new(s.gsub('/', File::SEPARATOR)) }
|
162
|
+
end
|
163
|
+
|
164
|
+
def format_backtrace(backtrace)
|
165
|
+
backtrace.map { |l| backtrace_line(l) }.compact.tap { |filtered| filtered.concat backtrace if filtered.empty? }
|
166
|
+
end
|
167
|
+
|
168
|
+
def backtrace_line(line)
|
169
|
+
return if [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *exclusion_patterns)].any? { |p| line =~ p }
|
170
|
+
|
171
|
+
# It changes the current path that is relative to
|
172
|
+
# system root to be relative to the project root.
|
173
|
+
line.sub(/(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/, '\\1.\\2'.freeze).sub(/\A([^:]+:\d+)$/, '\\1'.freeze)
|
174
|
+
end
|
175
|
+
|
158
176
|
def enumerated_failures
|
159
177
|
enumerated(failures, 0, &:message)
|
160
178
|
end
|
@@ -44,10 +44,16 @@ module RSpec
|
|
44
44
|
|
45
45
|
# @private
|
46
46
|
class PositiveExpectationHandler
|
47
|
-
def self.handle_matcher(actual, initial_matcher,
|
48
|
-
ExpectationHelper.with_matcher(self, initial_matcher,
|
47
|
+
def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block)
|
48
|
+
ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher|
|
49
49
|
return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) unless initial_matcher
|
50
|
-
|
50
|
+
|
51
|
+
match_result = matcher.matches?(actual, &block)
|
52
|
+
if custom_message && match_result.respond_to?(:error_generator)
|
53
|
+
match_result.error_generator.opts[:message] = custom_message
|
54
|
+
end
|
55
|
+
|
56
|
+
match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message)
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
@@ -66,10 +72,16 @@ module RSpec
|
|
66
72
|
|
67
73
|
# @private
|
68
74
|
class NegativeExpectationHandler
|
69
|
-
def self.handle_matcher(actual, initial_matcher,
|
70
|
-
ExpectationHelper.with_matcher(self, initial_matcher,
|
75
|
+
def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block)
|
76
|
+
ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher|
|
71
77
|
return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) unless initial_matcher
|
72
|
-
|
78
|
+
|
79
|
+
negated_match_result = does_not_match?(matcher, actual, &block)
|
80
|
+
if custom_message && negated_match_result.respond_to?(:error_generator)
|
81
|
+
negated_match_result.error_generator.opts[:message] = custom_message
|
82
|
+
end
|
83
|
+
|
84
|
+
negated_match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message_when_negated)
|
73
85
|
end
|
74
86
|
end
|
75
87
|
|
data/lib/rspec/matchers.rb
CHANGED
@@ -316,9 +316,9 @@ module RSpec
|
|
316
316
|
def be_falsey
|
317
317
|
BuiltIn::BeFalsey.new
|
318
318
|
end
|
319
|
-
alias_matcher :be_falsy,
|
319
|
+
alias_matcher :be_falsy, :be_falsey
|
320
320
|
alias_matcher :a_falsey_value, :be_falsey
|
321
|
-
alias_matcher :a_falsy_value,
|
321
|
+
alias_matcher :a_falsy_value, :be_falsey
|
322
322
|
|
323
323
|
# Passes if actual is nil
|
324
324
|
def be_nil
|
@@ -379,7 +379,7 @@ module RSpec
|
|
379
379
|
BuiltIn::BeAKindOf.new(expected)
|
380
380
|
end
|
381
381
|
alias_method :be_kind_of, :be_a_kind_of
|
382
|
-
alias_matcher :a_kind_of,
|
382
|
+
alias_matcher :a_kind_of, :be_a_kind_of
|
383
383
|
|
384
384
|
# Passes if actual.between?(min, max). Works with any Comparable object,
|
385
385
|
# including String, Symbol, Time, or Numeric (Fixnum, Bignum, Integer,
|
@@ -406,7 +406,7 @@ module RSpec
|
|
406
406
|
BuiltIn::BeWithin.new(delta)
|
407
407
|
end
|
408
408
|
alias_matcher :a_value_within, :be_within
|
409
|
-
alias_matcher :within,
|
409
|
+
alias_matcher :within, :be_within
|
410
410
|
|
411
411
|
# Applied to a proc, specifies that its execution will cause some value to
|
412
412
|
# change.
|
@@ -492,8 +492,8 @@ module RSpec
|
|
492
492
|
def change(receiver=nil, message=nil, &block)
|
493
493
|
BuiltIn::Change.new(receiver, message, &block)
|
494
494
|
end
|
495
|
-
alias_matcher :a_block_changing,
|
496
|
-
alias_matcher :changing,
|
495
|
+
alias_matcher :a_block_changing, :change
|
496
|
+
alias_matcher :changing, :change
|
497
497
|
|
498
498
|
# Passes if actual contains all of the expected regardless of order.
|
499
499
|
# This works for collections. Pass in multiple args and it will only
|
@@ -511,7 +511,7 @@ module RSpec
|
|
511
511
|
BuiltIn::ContainExactly.new(items)
|
512
512
|
end
|
513
513
|
alias_matcher :a_collection_containing_exactly, :contain_exactly
|
514
|
-
alias_matcher :containing_exactly,
|
514
|
+
alias_matcher :containing_exactly, :contain_exactly
|
515
515
|
|
516
516
|
# Passes if actual covers expected. This works for
|
517
517
|
# Ranges. You can also pass in multiple args
|
@@ -529,7 +529,7 @@ module RSpec
|
|
529
529
|
BuiltIn::Cover.new(*values)
|
530
530
|
end
|
531
531
|
alias_matcher :a_range_covering, :cover
|
532
|
-
alias_matcher :covering,
|
532
|
+
alias_matcher :covering, :cover
|
533
533
|
|
534
534
|
# Matches if the actual value ends with the expected value(s). In the case
|
535
535
|
# of a string, matches against the last `expected.length` characters of the
|
@@ -544,8 +544,8 @@ module RSpec
|
|
544
544
|
BuiltIn::EndWith.new(*expected)
|
545
545
|
end
|
546
546
|
alias_matcher :a_collection_ending_with, :end_with
|
547
|
-
alias_matcher :a_string_ending_with,
|
548
|
-
alias_matcher :ending_with,
|
547
|
+
alias_matcher :a_string_ending_with, :end_with
|
548
|
+
alias_matcher :ending_with, :end_with
|
549
549
|
|
550
550
|
# Passes if <tt>actual == expected</tt>.
|
551
551
|
#
|
@@ -559,7 +559,7 @@ module RSpec
|
|
559
559
|
BuiltIn::Eq.new(expected)
|
560
560
|
end
|
561
561
|
alias_matcher :an_object_eq_to, :eq
|
562
|
-
alias_matcher :eq_to,
|
562
|
+
alias_matcher :eq_to, :eq
|
563
563
|
|
564
564
|
# Passes if `actual.eql?(expected)`
|
565
565
|
#
|
@@ -573,7 +573,7 @@ module RSpec
|
|
573
573
|
BuiltIn::Eql.new(expected)
|
574
574
|
end
|
575
575
|
alias_matcher :an_object_eql_to, :eql
|
576
|
-
alias_matcher :eql_to,
|
576
|
+
alias_matcher :eql_to, :eql
|
577
577
|
|
578
578
|
# Passes if <tt>actual.equal?(expected)</tt> (object identity).
|
579
579
|
#
|
@@ -587,7 +587,7 @@ module RSpec
|
|
587
587
|
BuiltIn::Equal.new(expected)
|
588
588
|
end
|
589
589
|
alias_matcher :an_object_equal_to, :equal
|
590
|
-
alias_matcher :equal_to,
|
590
|
+
alias_matcher :equal_to, :equal
|
591
591
|
|
592
592
|
# Passes if `actual.exist?` or `actual.exists?`
|
593
593
|
#
|
@@ -597,7 +597,7 @@ module RSpec
|
|
597
597
|
BuiltIn::Exist.new(*args)
|
598
598
|
end
|
599
599
|
alias_matcher :an_object_existing, :exist
|
600
|
-
alias_matcher :existing,
|
600
|
+
alias_matcher :existing, :exist
|
601
601
|
|
602
602
|
# Passes if actual's attribute values match the expected attributes hash.
|
603
603
|
# This works no matter how you define your attribute readers.
|
@@ -617,7 +617,7 @@ module RSpec
|
|
617
617
|
BuiltIn::HaveAttributes.new(expected)
|
618
618
|
end
|
619
619
|
alias_matcher :an_object_having_attributes, :have_attributes
|
620
|
-
alias_matcher :having_attributes,
|
620
|
+
alias_matcher :having_attributes, :have_attributes
|
621
621
|
|
622
622
|
# Passes if actual includes expected. This works for
|
623
623
|
# collections and Strings. You can also pass in multiple args
|
@@ -640,9 +640,9 @@ module RSpec
|
|
640
640
|
BuiltIn::Include.new(*expected)
|
641
641
|
end
|
642
642
|
alias_matcher :a_collection_including, :include
|
643
|
-
alias_matcher :a_string_including,
|
644
|
-
alias_matcher :a_hash_including,
|
645
|
-
alias_matcher :including,
|
643
|
+
alias_matcher :a_string_including, :include
|
644
|
+
alias_matcher :a_hash_including, :include
|
645
|
+
alias_matcher :including, :include
|
646
646
|
|
647
647
|
# Passes if the provided matcher passes when checked against all
|
648
648
|
# elements of the collection.
|
@@ -697,10 +697,10 @@ module RSpec
|
|
697
697
|
def match(expected)
|
698
698
|
BuiltIn::Match.new(expected)
|
699
699
|
end
|
700
|
-
alias_matcher :match_regex,
|
700
|
+
alias_matcher :match_regex, :match
|
701
701
|
alias_matcher :an_object_matching, :match
|
702
|
-
alias_matcher :a_string_matching,
|
703
|
-
alias_matcher :matching,
|
702
|
+
alias_matcher :a_string_matching, :match
|
703
|
+
alias_matcher :matching, :match
|
704
704
|
|
705
705
|
# An alternate form of `contain_exactly` that accepts
|
706
706
|
# the expected contents as a single array arg rather
|
@@ -761,20 +761,22 @@ module RSpec
|
|
761
761
|
# expect { do_something_risky }.to raise_error
|
762
762
|
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError)
|
763
763
|
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError) { |error| expect(error.data).to eq 42 }
|
764
|
+
# expect { do_something_risky }.to raise_error { |error| expect(error.data).to eq 42 }
|
764
765
|
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError, "that was too risky")
|
765
766
|
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError, /oo ri/)
|
767
|
+
# expect { do_something_risky }.to raise_error("that was too risky")
|
766
768
|
#
|
767
769
|
# expect { do_something_risky }.not_to raise_error
|
768
|
-
def raise_error(error=
|
770
|
+
def raise_error(error=BuiltIn::RaiseError::UndefinedValue, message=nil, &block)
|
769
771
|
BuiltIn::RaiseError.new(error, message, &block)
|
770
772
|
end
|
771
|
-
alias_method :raise_exception,
|
773
|
+
alias_method :raise_exception, :raise_error
|
772
774
|
|
773
|
-
alias_matcher :a_block_raising,
|
775
|
+
alias_matcher :a_block_raising, :raise_error do |desc|
|
774
776
|
desc.sub("raise", "a block raising")
|
775
777
|
end
|
776
778
|
|
777
|
-
alias_matcher :raising,
|
779
|
+
alias_matcher :raising, :raise_error do |desc|
|
778
780
|
desc.sub("raise", "raising")
|
779
781
|
end
|
780
782
|
|
@@ -788,7 +790,7 @@ module RSpec
|
|
788
790
|
BuiltIn::RespondTo.new(*names)
|
789
791
|
end
|
790
792
|
alias_matcher :an_object_responding_to, :respond_to
|
791
|
-
alias_matcher :responding_to,
|
793
|
+
alias_matcher :responding_to, :respond_to
|
792
794
|
|
793
795
|
# Passes if the submitted block returns true. Yields target to the
|
794
796
|
# block.
|
@@ -809,7 +811,7 @@ module RSpec
|
|
809
811
|
BuiltIn::Satisfy.new(description, &block)
|
810
812
|
end
|
811
813
|
alias_matcher :an_object_satisfying, :satisfy
|
812
|
-
alias_matcher :satisfying,
|
814
|
+
alias_matcher :satisfying, :satisfy
|
813
815
|
|
814
816
|
# Matches if the actual value starts with the expected value(s). In the
|
815
817
|
# case of a string, matches against the first `expected.length` characters
|
@@ -824,8 +826,8 @@ module RSpec
|
|
824
826
|
BuiltIn::StartWith.new(*expected)
|
825
827
|
end
|
826
828
|
alias_matcher :a_collection_starting_with, :start_with
|
827
|
-
alias_matcher :a_string_starting_with,
|
828
|
-
alias_matcher :starting_with,
|
829
|
+
alias_matcher :a_string_starting_with, :start_with
|
830
|
+
alias_matcher :starting_with, :start_with
|
829
831
|
|
830
832
|
# Given no argument, matches if a proc throws any Symbol.
|
831
833
|
#
|
@@ -850,7 +852,7 @@ module RSpec
|
|
850
852
|
desc.sub("throw", "a block throwing")
|
851
853
|
end
|
852
854
|
|
853
|
-
alias_matcher :throwing,
|
855
|
+
alias_matcher :throwing, :throw_symbol do |desc|
|
854
856
|
desc.sub("throw", "throwing")
|
855
857
|
end
|
856
858
|
|
@@ -866,8 +868,8 @@ module RSpec
|
|
866
868
|
def yield_control
|
867
869
|
BuiltIn::YieldControl.new
|
868
870
|
end
|
869
|
-
alias_matcher :a_block_yielding_control,
|
870
|
-
alias_matcher :yielding_control,
|
871
|
+
alias_matcher :a_block_yielding_control, :yield_control
|
872
|
+
alias_matcher :yielding_control, :yield_control
|
871
873
|
|
872
874
|
# Passes if the method called in the expect block yields with
|
873
875
|
# no arguments. Fails if it does not yield, or yields with arguments.
|
@@ -884,8 +886,8 @@ module RSpec
|
|
884
886
|
def yield_with_no_args
|
885
887
|
BuiltIn::YieldWithNoArgs.new
|
886
888
|
end
|
887
|
-
alias_matcher :a_block_yielding_with_no_args,
|
888
|
-
alias_matcher :yielding_with_no_args,
|
889
|
+
alias_matcher :a_block_yielding_with_no_args, :yield_with_no_args
|
890
|
+
alias_matcher :yielding_with_no_args, :yield_with_no_args
|
889
891
|
|
890
892
|
# Given no arguments, matches if the method called in the expect
|
891
893
|
# block yields with arguments (regardless of what they are or how
|
@@ -914,8 +916,8 @@ module RSpec
|
|
914
916
|
def yield_with_args(*args)
|
915
917
|
BuiltIn::YieldWithArgs.new(*args)
|
916
918
|
end
|
917
|
-
alias_matcher :a_block_yielding_with_args,
|
918
|
-
alias_matcher :yielding_with_args,
|
919
|
+
alias_matcher :a_block_yielding_with_args, :yield_with_args
|
920
|
+
alias_matcher :yielding_with_args, :yield_with_args
|
919
921
|
|
920
922
|
# Designed for use with methods that repeatedly yield (such as
|
921
923
|
# iterators). Passes if the method called in the expect block yields
|
@@ -935,8 +937,8 @@ module RSpec
|
|
935
937
|
def yield_successive_args(*args)
|
936
938
|
BuiltIn::YieldSuccessiveArgs.new(*args)
|
937
939
|
end
|
938
|
-
alias_matcher :a_block_yielding_successive_args,
|
939
|
-
alias_matcher :yielding_successive_args,
|
940
|
+
alias_matcher :a_block_yielding_successive_args, :yield_successive_args
|
941
|
+
alias_matcher :yielding_successive_args, :yield_successive_args
|
940
942
|
|
941
943
|
# Delegates to {RSpec::Expectations.configuration}.
|
942
944
|
# This is here because rspec-core's `expect_with` option
|
@@ -949,7 +951,7 @@ module RSpec
|
|
949
951
|
|
950
952
|
private
|
951
953
|
|
952
|
-
BE_PREDICATE_REGEX = /^(be_(?:an?_)?)(.*)/
|
954
|
+
BE_PREDICATE_REGEX = /^(?:be_(?:an?_)?)(.*)/
|
953
955
|
HAS_REGEX = /^(?:have_)(.*)/
|
954
956
|
DYNAMIC_MATCHER_REGEX = Regexp.union(BE_PREDICATE_REGEX, HAS_REGEX)
|
955
957
|
|
@@ -16,8 +16,9 @@ module RSpec
|
|
16
16
|
autoload :Be, 'rspec/matchers/built_in/be'
|
17
17
|
autoload :BeComparedTo, 'rspec/matchers/built_in/be'
|
18
18
|
autoload :BeFalsey, 'rspec/matchers/built_in/be'
|
19
|
+
autoload :BeHelpers, 'rspec/matchers/built_in/be'
|
19
20
|
autoload :BeNil, 'rspec/matchers/built_in/be'
|
20
|
-
autoload :BePredicate, 'rspec/matchers/built_in/
|
21
|
+
autoload :BePredicate, 'rspec/matchers/built_in/has'
|
21
22
|
autoload :BeTruthy, 'rspec/matchers/built_in/be'
|
22
23
|
autoload :BeWithin, 'rspec/matchers/built_in/be_within'
|
23
24
|
autoload :Change, 'rspec/matchers/built_in/change'
|
@@ -186,116 +186,6 @@ module RSpec
|
|
186
186
|
@actual.__send__ @operator, @expected
|
187
187
|
end
|
188
188
|
end
|
189
|
-
|
190
|
-
# @api private
|
191
|
-
# Provides the implementation of `be_<predicate>`.
|
192
|
-
# Not intended to be instantiated directly.
|
193
|
-
class BePredicate < BaseMatcher
|
194
|
-
include BeHelpers
|
195
|
-
|
196
|
-
def initialize(*args, &block)
|
197
|
-
@expected = parse_expected(args.shift)
|
198
|
-
@args = args
|
199
|
-
@block = block
|
200
|
-
end
|
201
|
-
ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
|
202
|
-
|
203
|
-
def matches?(actual, &block)
|
204
|
-
@actual = actual
|
205
|
-
@block ||= block
|
206
|
-
predicate_accessible? && predicate_matches?
|
207
|
-
end
|
208
|
-
|
209
|
-
def does_not_match?(actual, &block)
|
210
|
-
@actual = actual
|
211
|
-
@block ||= block
|
212
|
-
predicate_accessible? && !predicate_matches?
|
213
|
-
end
|
214
|
-
|
215
|
-
# @api private
|
216
|
-
# @return [String]
|
217
|
-
def failure_message
|
218
|
-
failure_message_expecting(true)
|
219
|
-
end
|
220
|
-
|
221
|
-
# @api private
|
222
|
-
# @return [String]
|
223
|
-
def failure_message_when_negated
|
224
|
-
failure_message_expecting(false)
|
225
|
-
end
|
226
|
-
|
227
|
-
# @api private
|
228
|
-
# @return [String]
|
229
|
-
def description
|
230
|
-
"#{prefix_to_sentence}#{expected_to_sentence}#{args_to_sentence}"
|
231
|
-
end
|
232
|
-
|
233
|
-
private
|
234
|
-
|
235
|
-
def predicate_accessible?
|
236
|
-
actual.respond_to?(predicate) || actual.respond_to?(present_tense_predicate)
|
237
|
-
end
|
238
|
-
|
239
|
-
# support 1.8.7, evaluate once at load time for performance
|
240
|
-
if String === methods.first
|
241
|
-
# :nocov:
|
242
|
-
def private_predicate?
|
243
|
-
@actual.private_methods.include? predicate.to_s
|
244
|
-
end
|
245
|
-
# :nocov:
|
246
|
-
else
|
247
|
-
def private_predicate?
|
248
|
-
@actual.private_methods.include? predicate
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def predicate_matches?
|
253
|
-
method_name = actual.respond_to?(predicate) ? predicate : present_tense_predicate
|
254
|
-
@predicate_matches = actual.__send__(method_name, *@args, &@block)
|
255
|
-
end
|
256
|
-
|
257
|
-
def predicate
|
258
|
-
:"#{@expected}?"
|
259
|
-
end
|
260
|
-
|
261
|
-
def present_tense_predicate
|
262
|
-
:"#{@expected}s?"
|
263
|
-
end
|
264
|
-
|
265
|
-
def parse_expected(expected)
|
266
|
-
@prefix, expected = prefix_and_expected(expected)
|
267
|
-
expected
|
268
|
-
end
|
269
|
-
|
270
|
-
def prefix_and_expected(symbol)
|
271
|
-
Matchers::BE_PREDICATE_REGEX.match(symbol.to_s).captures.compact
|
272
|
-
end
|
273
|
-
|
274
|
-
def prefix_to_sentence
|
275
|
-
EnglishPhrasing.split_words(@prefix)
|
276
|
-
end
|
277
|
-
|
278
|
-
def failure_message_expecting(value)
|
279
|
-
validity_message ||
|
280
|
-
"expected `#{actual_formatted}.#{predicate}#{args_to_s}` to return #{value}, got #{description_of @predicate_matches}"
|
281
|
-
end
|
282
|
-
|
283
|
-
def validity_message
|
284
|
-
return nil if predicate_accessible?
|
285
|
-
|
286
|
-
msg = "expected #{actual_formatted} to respond to `#{predicate}`".dup
|
287
|
-
|
288
|
-
if private_predicate?
|
289
|
-
msg << " but `#{predicate}` is a private method"
|
290
|
-
elsif predicate == :true?
|
291
|
-
msg << " or perhaps you meant `be true` or `be_truthy`"
|
292
|
-
elsif predicate == :false?
|
293
|
-
msg << " or perhaps you meant `be false` or `be_falsey`"
|
294
|
-
end
|
295
|
-
|
296
|
-
msg
|
297
|
-
end
|
298
|
-
end
|
299
189
|
end
|
300
190
|
end
|
301
191
|
end
|