rspec-expectations 3.0.0.beta2 → 3.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -2
- data/.yardopts +0 -1
- data/Changelog.md +115 -35
- data/README.md +2 -2
- data/lib/rspec/expectations.rb +13 -8
- data/lib/rspec/{matchers → expectations}/configuration.rb +38 -13
- data/lib/rspec/expectations/expectation_target.rb +72 -8
- data/lib/rspec/expectations/fail_with.rb +10 -52
- data/lib/rspec/expectations/handler.rb +9 -11
- data/lib/rspec/expectations/syntax.rb +37 -35
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +60 -9
- data/lib/rspec/matchers/aliased_matcher.rb +6 -0
- data/lib/rspec/matchers/built_in.rb +9 -1
- data/lib/rspec/matchers/built_in/all.rb +78 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +39 -1
- data/lib/rspec/matchers/built_in/be.rb +117 -42
- data/lib/rspec/matchers/built_in/be_between.rb +22 -0
- data/lib/rspec/matchers/built_in/be_instance_of.rb +11 -3
- data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -0
- data/lib/rspec/matchers/built_in/be_within.rb +26 -6
- data/lib/rspec/matchers/built_in/change.rb +89 -13
- data/lib/rspec/matchers/built_in/compound.rb +19 -3
- data/lib/rspec/matchers/built_in/contain_exactly.rb +17 -6
- data/lib/rspec/matchers/built_in/cover.rb +3 -0
- data/lib/rspec/matchers/built_in/eq.rb +20 -5
- data/lib/rspec/matchers/built_in/eql.rb +15 -3
- data/lib/rspec/matchers/built_in/equal.rb +23 -6
- data/lib/rspec/matchers/built_in/exist.rb +74 -10
- data/lib/rspec/matchers/built_in/has.rb +58 -3
- data/lib/rspec/matchers/built_in/include.rb +16 -1
- data/lib/rspec/matchers/built_in/match.rb +14 -4
- data/lib/rspec/matchers/built_in/operators.rb +16 -0
- data/lib/rspec/matchers/built_in/output.rb +47 -5
- data/lib/rspec/matchers/built_in/raise_error.rb +40 -23
- data/lib/rspec/matchers/built_in/respond_to.rb +37 -16
- data/lib/rspec/matchers/built_in/satisfy.rb +15 -0
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +29 -14
- data/lib/rspec/matchers/built_in/throw_symbol.rb +32 -3
- data/lib/rspec/matchers/built_in/yield.rb +148 -44
- data/lib/rspec/matchers/composable.rb +48 -7
- data/lib/rspec/matchers/dsl.rb +45 -17
- data/lib/rspec/matchers/generated_descriptions.rb +7 -0
- data/lib/rspec/matchers/matcher_delegator.rb +6 -2
- data/lib/rspec/matchers/pretty.rb +15 -19
- metadata +33 -236
- metadata.gz.sig +0 -0
- data/features/README.md +0 -48
- data/features/Upgrade.md +0 -53
- data/features/built_in_matchers/README.md +0 -96
- data/features/built_in_matchers/be.feature +0 -175
- data/features/built_in_matchers/be_within.feature +0 -48
- data/features/built_in_matchers/comparisons.feature +0 -97
- data/features/built_in_matchers/contain_exactly.feature +0 -46
- data/features/built_in_matchers/cover.feature +0 -47
- data/features/built_in_matchers/end_with.feature +0 -48
- data/features/built_in_matchers/equality.feature +0 -136
- data/features/built_in_matchers/exist.feature +0 -45
- data/features/built_in_matchers/expect_change.feature +0 -59
- data/features/built_in_matchers/expect_error.feature +0 -144
- data/features/built_in_matchers/include.feature +0 -126
- data/features/built_in_matchers/match.feature +0 -51
- data/features/built_in_matchers/output.feature +0 -70
- data/features/built_in_matchers/predicates.feature +0 -161
- data/features/built_in_matchers/respond_to.feature +0 -84
- data/features/built_in_matchers/satisfy.feature +0 -33
- data/features/built_in_matchers/start_with.feature +0 -48
- data/features/built_in_matchers/throw_symbol.feature +0 -91
- data/features/built_in_matchers/types.feature +0 -116
- data/features/built_in_matchers/yield.feature +0 -161
- data/features/composing_matchers.feature +0 -250
- data/features/compound_expectations.feature +0 -45
- data/features/custom_matchers/access_running_example.feature +0 -53
- data/features/custom_matchers/define_diffable_matcher.feature +0 -27
- data/features/custom_matchers/define_matcher.feature +0 -340
- data/features/custom_matchers/define_matcher_outside_rspec.feature +0 -34
- data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
- data/features/customized_message.feature +0 -39
- data/features/diffing.feature +0 -85
- data/features/implicit_docstrings.feature +0 -52
- data/features/step_definitions/additional_cli_steps.rb +0 -22
- data/features/support/env.rb +0 -21
- data/features/support/rubinius.rb +0 -6
- data/features/syntax_configuration.feature +0 -71
- data/features/test_frameworks/minitest.feature +0 -44
- data/lib/rspec-expectations.rb +0 -1
- data/lib/rspec/expectations/diff_presenter.rb +0 -141
- data/lib/rspec/expectations/differ.rb +0 -44
- data/lib/rspec/expectations/encoded_string.rb +0 -56
- data/spec/rspec/expectations/diff_presenter_spec.rb +0 -249
- data/spec/rspec/expectations/encoded_string_spec.rb +0 -74
- data/spec/rspec/expectations/expectation_target_spec.rb +0 -82
- data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
- data/spec/rspec/expectations/fail_with_spec.rb +0 -114
- data/spec/rspec/expectations/handler_spec.rb +0 -205
- data/spec/rspec/expectations/minitest_integration_spec.rb +0 -27
- data/spec/rspec/expectations/syntax_spec.rb +0 -89
- data/spec/rspec/expectations_spec.rb +0 -12
- data/spec/rspec/matchers/aliased_matcher_spec.rb +0 -48
- data/spec/rspec/matchers/aliases_spec.rb +0 -449
- data/spec/rspec/matchers/built_in/base_matcher_spec.rb +0 -83
- data/spec/rspec/matchers/built_in/be_between_spec.rb +0 -159
- data/spec/rspec/matchers/built_in/be_instance_of_spec.rb +0 -63
- data/spec/rspec/matchers/built_in/be_kind_of_spec.rb +0 -41
- data/spec/rspec/matchers/built_in/be_spec.rb +0 -592
- data/spec/rspec/matchers/built_in/be_within_spec.rb +0 -141
- data/spec/rspec/matchers/built_in/change_spec.rb +0 -808
- data/spec/rspec/matchers/built_in/compound_spec.rb +0 -292
- data/spec/rspec/matchers/built_in/contain_exactly_spec.rb +0 -441
- data/spec/rspec/matchers/built_in/cover_spec.rb +0 -69
- data/spec/rspec/matchers/built_in/eq_spec.rb +0 -156
- data/spec/rspec/matchers/built_in/eql_spec.rb +0 -41
- data/spec/rspec/matchers/built_in/equal_spec.rb +0 -106
- data/spec/rspec/matchers/built_in/exist_spec.rb +0 -124
- data/spec/rspec/matchers/built_in/has_spec.rb +0 -161
- data/spec/rspec/matchers/built_in/include_spec.rb +0 -540
- data/spec/rspec/matchers/built_in/match_spec.rb +0 -102
- data/spec/rspec/matchers/built_in/operators_spec.rb +0 -252
- data/spec/rspec/matchers/built_in/output_spec.rb +0 -165
- data/spec/rspec/matchers/built_in/raise_error_spec.rb +0 -461
- data/spec/rspec/matchers/built_in/respond_to_spec.rb +0 -292
- data/spec/rspec/matchers/built_in/satisfy_spec.rb +0 -44
- data/spec/rspec/matchers/built_in/start_and_end_with_spec.rb +0 -253
- data/spec/rspec/matchers/built_in/throw_symbol_spec.rb +0 -135
- data/spec/rspec/matchers/built_in/yield_spec.rb +0 -627
- data/spec/rspec/matchers/configuration_spec.rb +0 -213
- data/spec/rspec/matchers/description_generation_spec.rb +0 -191
- data/spec/rspec/matchers/dsl_spec.rb +0 -895
- data/spec/rspec/matchers/legacy_spec.rb +0 -101
- data/spec/rspec/matchers_spec.rb +0 -74
- data/spec/spec_helper.rb +0 -85
- data/spec/support/matchers.rb +0 -22
- data/spec/support/shared_examples.rb +0 -35
@@ -1,12 +1,13 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `contain_exactly` and `match_array`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class ContainExactly < BaseMatcher
|
5
|
-
def match(expected, actual)
|
6
|
-
convert_actual_to_an_array or return false
|
7
|
-
match_when_sorted? || (extra_items.empty? && missing_items.empty?)
|
8
|
-
end
|
9
8
|
|
9
|
+
# @api private
|
10
|
+
# @return [String]
|
10
11
|
def failure_message
|
11
12
|
if Array === actual
|
12
13
|
message = "expected collection contained: #{safe_sort(surface_descriptions_in expected).inspect}\n"
|
@@ -20,16 +21,25 @@ module RSpec
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
24
|
+
# @api private
|
25
|
+
# @return [String]
|
23
26
|
def failure_message_when_negated
|
24
27
|
"`contain_exactly` does not support negation"
|
25
28
|
end
|
26
29
|
|
30
|
+
# @api private
|
31
|
+
# @return [String]
|
27
32
|
def description
|
28
|
-
"contain exactly
|
33
|
+
"contain exactly#{to_sentence(surface_descriptions_in expected)}"
|
29
34
|
end
|
30
35
|
|
31
36
|
private
|
32
37
|
|
38
|
+
def match(expected, actual)
|
39
|
+
convert_actual_to_an_array or return false
|
40
|
+
match_when_sorted? || (extra_items.empty? && missing_items.empty?)
|
41
|
+
end
|
42
|
+
|
33
43
|
# This cannot always work (e.g. when dealing with unsortable items,
|
34
44
|
# or matchers as expected items), but it's practically free compared to
|
35
45
|
# the slowness of the full matching algorithm, and in common cases this
|
@@ -102,7 +112,7 @@ module RSpec
|
|
102
112
|
# This should pass (because we can pair /fool/ with "fool" and /foo/ with "food"), but
|
103
113
|
# the original algorithm used by this matcher would pair the first elements it could
|
104
114
|
# (/foo/ with "fool"), which would leave /fool/ and "food" unmatched. When we have
|
105
|
-
# an expected
|
115
|
+
# an expected element which is a matcher that matches a superset of actual items
|
106
116
|
# compared to another expected element matcher, we need to consider every possible pairing.
|
107
117
|
#
|
108
118
|
# This class is designed to maximize the number of actual/expected pairings -- or,
|
@@ -191,6 +201,7 @@ module RSpec
|
|
191
201
|
|
192
202
|
private
|
193
203
|
|
204
|
+
# @private
|
194
205
|
# Starting solution that is worse than any other real solution.
|
195
206
|
NullSolution = Class.new do
|
196
207
|
def self.worse_than?(other); true; end
|
@@ -1,32 +1,48 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `eq`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class Eq < BaseMatcher
|
5
|
-
def match(expected, actual)
|
6
|
-
actual == expected
|
7
|
-
end
|
8
8
|
|
9
|
+
# @api private
|
10
|
+
# @return [String]
|
9
11
|
def failure_message
|
10
12
|
"\nexpected: #{format_object(expected)}\n got: #{format_object(actual)}\n\n(compared using ==)\n"
|
11
13
|
end
|
12
14
|
|
15
|
+
# @api private
|
16
|
+
# @return [String]
|
13
17
|
def failure_message_when_negated
|
14
18
|
"\nexpected: value != #{format_object(expected)}\n got: #{format_object(actual)}\n\n(compared using ==)\n"
|
15
19
|
end
|
16
20
|
|
21
|
+
# @api private
|
22
|
+
# @return [String]
|
17
23
|
def description
|
18
24
|
"#{name_to_sentence} #{@expected.inspect}"
|
19
25
|
end
|
20
26
|
|
21
|
-
|
27
|
+
# @api private
|
28
|
+
# @return [Boolean]
|
29
|
+
def diffable?
|
30
|
+
true
|
31
|
+
end
|
22
32
|
|
23
33
|
private
|
24
34
|
|
35
|
+
def match(expected, actual)
|
36
|
+
actual == expected
|
37
|
+
end
|
38
|
+
|
25
39
|
def format_object(object)
|
26
40
|
if Time === object
|
27
41
|
format_time(object)
|
28
42
|
elsif defined?(DateTime) && DateTime === object
|
29
43
|
format_date_time(object)
|
44
|
+
elsif defined?(BigDecimal) && BigDecimal === object
|
45
|
+
"#{object.to_s 'F'} (#{object.inspect})"
|
30
46
|
else
|
31
47
|
object.inspect
|
32
48
|
end
|
@@ -58,4 +74,3 @@ module RSpec
|
|
58
74
|
end
|
59
75
|
end
|
60
76
|
end
|
61
|
-
|
@@ -1,22 +1,34 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `eql`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class Eql < BaseMatcher
|
5
|
-
def match(expected, actual)
|
6
|
-
actual.eql? expected
|
7
|
-
end
|
8
8
|
|
9
|
+
# @api private
|
10
|
+
# @return [String]
|
9
11
|
def failure_message
|
10
12
|
"\nexpected: #{expected.inspect}\n got: #{actual.inspect}\n\n(compared using eql?)\n"
|
11
13
|
end
|
12
14
|
|
15
|
+
# @api private
|
16
|
+
# @return [String]
|
13
17
|
def failure_message_when_negated
|
14
18
|
"\nexpected: value != #{expected.inspect}\n got: #{actual.inspect}\n\n(compared using eql?)\n"
|
15
19
|
end
|
16
20
|
|
21
|
+
# @api private
|
22
|
+
# @return [Boolean]
|
17
23
|
def diffable?
|
18
24
|
true
|
19
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def match(expected, actual)
|
30
|
+
actual.eql? expected
|
31
|
+
end
|
20
32
|
end
|
21
33
|
end
|
22
34
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `equal`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class Equal < BaseMatcher
|
5
|
-
def match(expected, actual)
|
6
|
-
actual.equal? expected
|
7
|
-
end
|
8
8
|
|
9
|
+
# @api private
|
10
|
+
# @return [String]
|
9
11
|
def failure_message
|
10
12
|
if expected_is_a_literal_singleton?
|
11
13
|
simple_failure_message
|
@@ -14,6 +16,8 @@ module RSpec
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
19
|
+
# @api private
|
20
|
+
# @return [String]
|
17
21
|
def failure_message_when_negated
|
18
22
|
return <<-MESSAGE
|
19
23
|
|
@@ -25,11 +29,17 @@ Compared using equal?, which compares object identity.
|
|
25
29
|
MESSAGE
|
26
30
|
end
|
27
31
|
|
32
|
+
# @api private
|
33
|
+
# @return [Boolean]
|
28
34
|
def diffable?
|
29
35
|
!expected_is_a_literal_singleton?
|
30
36
|
end
|
31
37
|
|
32
|
-
|
38
|
+
private
|
39
|
+
|
40
|
+
def match(expected, actual)
|
41
|
+
actual.equal? expected
|
42
|
+
end
|
33
43
|
|
34
44
|
LITERAL_SINGLETONS = [true, false, nil]
|
35
45
|
|
@@ -37,8 +47,16 @@ MESSAGE
|
|
37
47
|
LITERAL_SINGLETONS.include?(expected)
|
38
48
|
end
|
39
49
|
|
50
|
+
def actual_inspected
|
51
|
+
if LITERAL_SINGLETONS.include?(actual)
|
52
|
+
actual.inspect
|
53
|
+
else
|
54
|
+
inspect_object(actual)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
40
58
|
def simple_failure_message
|
41
|
-
"\nexpected #{expected.inspect}\n got #{
|
59
|
+
"\nexpected #{expected.inspect}\n got #{actual_inspected}\n"
|
42
60
|
end
|
43
61
|
|
44
62
|
def detailed_failure_message
|
@@ -55,7 +73,6 @@ object identity in this example.
|
|
55
73
|
MESSAGE
|
56
74
|
end
|
57
75
|
|
58
|
-
|
59
76
|
def inspect_object(o)
|
60
77
|
"#<#{o.class}:#{o.object_id}> => #{o.inspect}"
|
61
78
|
end
|
@@ -1,25 +1,89 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `exist`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class Exist < BaseMatcher
|
5
8
|
def initialize(*expected)
|
6
9
|
@expected = expected
|
7
10
|
end
|
8
11
|
|
12
|
+
# @api private
|
13
|
+
# @return [Boolean]
|
9
14
|
def matches?(actual)
|
10
15
|
@actual = actual
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
@test = ExistenceTest.new @actual, @expected
|
17
|
+
@test.valid_test? && @test.actual_exists?
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
# @return [Boolean]
|
22
|
+
def does_not_match?(actual)
|
23
|
+
@actual = actual
|
24
|
+
@test = ExistenceTest.new @actual, @expected
|
25
|
+
@test.valid_test? && !@test.actual_exists?
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
# @return [String]
|
30
|
+
def failure_message
|
31
|
+
"expected #{@actual.inspect} to exist#{@test.validity_message}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api private
|
35
|
+
# @return [String]
|
36
|
+
def failure_message_when_negated
|
37
|
+
"expected #{@actual.inspect} not to exist#{@test.validity_message}"
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
# Simple class for memoizing actual/expected for this matcher
|
44
|
+
# and examining the match
|
45
|
+
class ExistenceTest < Struct.new(:actual, :expected)
|
46
|
+
|
47
|
+
# @api private
|
48
|
+
# @return [Boolean]
|
49
|
+
def valid_test?
|
50
|
+
uniq_truthy_values.size == 1
|
51
|
+
end
|
52
|
+
|
53
|
+
# @api private
|
54
|
+
# @return [Boolean]
|
55
|
+
def actual_exists?
|
56
|
+
existence_values.first
|
57
|
+
end
|
58
|
+
|
59
|
+
# @api private
|
60
|
+
# @return [String]
|
61
|
+
def validity_message
|
62
|
+
case uniq_truthy_values.size
|
63
|
+
when 0
|
64
|
+
" but it does not respond to either `exist?` or `exists?`"
|
65
|
+
when 2
|
66
|
+
" but `exist?` and `exists?` returned different values:\n\n"\
|
67
|
+
" exist?: #{existence_values.first}\n"\
|
68
|
+
"exists?: #{existence_values.last}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def uniq_truthy_values
|
75
|
+
@uniq_truthy_values ||= existence_values.map { |v| !!v }.uniq
|
76
|
+
end
|
77
|
+
|
78
|
+
def existence_values
|
79
|
+
@existence_values ||= predicates.map { |p| actual.__send__(p, *expected) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def predicates
|
83
|
+
@predicates ||= [:exist?, :exists?].select { |p| actual.respond_to?(p) }
|
21
84
|
end
|
22
85
|
end
|
86
|
+
|
23
87
|
end
|
24
88
|
end
|
25
89
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `has_<predicate>`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class Has
|
5
8
|
include Composable
|
6
9
|
|
@@ -8,24 +11,68 @@ module RSpec
|
|
8
11
|
@method_name, @args, @block = method_name, args, block
|
9
12
|
end
|
10
13
|
|
14
|
+
# @private
|
11
15
|
def matches?(actual, &block)
|
12
|
-
actual
|
16
|
+
@actual = actual
|
17
|
+
@block ||= block
|
18
|
+
predicate_accessible? && predicate_matches?
|
13
19
|
end
|
14
20
|
|
21
|
+
# @private
|
22
|
+
def does_not_match?(actual, &block)
|
23
|
+
@actual = actual
|
24
|
+
@block ||= block
|
25
|
+
predicate_accessible? && !predicate_matches?
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
# @return [String]
|
15
30
|
def failure_message
|
16
|
-
"expected ##{predicate}#{failure_message_args_description} to return true, got false"
|
31
|
+
validity_message || "expected ##{predicate}#{failure_message_args_description} to return true, got false"
|
17
32
|
end
|
18
33
|
|
34
|
+
# @api private
|
35
|
+
# @return [String]
|
19
36
|
def failure_message_when_negated
|
20
|
-
"expected ##{predicate}#{failure_message_args_description} to return false, got true"
|
37
|
+
validity_message || "expected ##{predicate}#{failure_message_args_description} to return false, got true"
|
21
38
|
end
|
22
39
|
|
40
|
+
# @api private
|
41
|
+
# @return [String]
|
23
42
|
def description
|
24
43
|
[method_description, args_description].compact.join(' ')
|
25
44
|
end
|
26
45
|
|
46
|
+
# @private
|
47
|
+
def supports_block_expectations?
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
27
51
|
private
|
28
52
|
|
53
|
+
def predicate_accessible?
|
54
|
+
!private_predicate? && predicate_exists?
|
55
|
+
end
|
56
|
+
|
57
|
+
# support 1.8.7, evaluate once at load time for performance
|
58
|
+
if String === methods.first
|
59
|
+
def private_predicate?
|
60
|
+
@actual.private_methods.include? predicate.to_s
|
61
|
+
end
|
62
|
+
else
|
63
|
+
def private_predicate?
|
64
|
+
@actual.private_methods.include? predicate
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def predicate_exists?
|
69
|
+
@actual.respond_to? predicate
|
70
|
+
end
|
71
|
+
|
72
|
+
def predicate_matches?
|
73
|
+
@actual.__send__(predicate, *@args, &@block)
|
74
|
+
end
|
75
|
+
|
29
76
|
def predicate
|
30
77
|
@predicate ||= :"has_#{@method_name.to_s.match(Matchers::HAS_REGEX).captures.first}?"
|
31
78
|
end
|
@@ -43,6 +90,14 @@ module RSpec
|
|
43
90
|
desc = args_description
|
44
91
|
"(#{desc})" if desc
|
45
92
|
end
|
93
|
+
|
94
|
+
def validity_message
|
95
|
+
if private_predicate?
|
96
|
+
"expected #{@actual} to respond to `#{predicate}` but `#{predicate}` is a private method"
|
97
|
+
elsif !predicate_exists?
|
98
|
+
"expected #{@actual} to respond to `#{predicate}`"
|
99
|
+
end
|
100
|
+
end
|
46
101
|
end
|
47
102
|
end
|
48
103
|
end
|
@@ -1,39 +1,54 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `include`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class Include < BaseMatcher
|
5
8
|
def initialize(*expected)
|
6
9
|
@expected = expected
|
7
10
|
end
|
8
11
|
|
12
|
+
# @api private
|
13
|
+
# @return [Boolean]
|
9
14
|
def matches?(actual)
|
10
15
|
@actual = actual
|
11
16
|
perform_match(:all?, :all?)
|
12
17
|
end
|
13
18
|
|
19
|
+
# @api private
|
20
|
+
# @return [Boolean]
|
14
21
|
def does_not_match?(actual)
|
15
22
|
@actual = actual
|
16
23
|
perform_match(:none?, :any?)
|
17
24
|
end
|
18
25
|
|
26
|
+
# @api private
|
27
|
+
# @return [String]
|
19
28
|
def description
|
20
29
|
described_items = surface_descriptions_in(expected)
|
21
30
|
improve_hash_formatting "include#{to_sentence(described_items)}"
|
22
31
|
end
|
23
32
|
|
33
|
+
# @api private
|
34
|
+
# @return [String]
|
24
35
|
def failure_message
|
25
36
|
improve_hash_formatting(super)
|
26
37
|
end
|
27
38
|
|
39
|
+
# @api private
|
40
|
+
# @return [String]
|
28
41
|
def failure_message_when_negated
|
29
42
|
improve_hash_formatting(super)
|
30
43
|
end
|
31
44
|
|
45
|
+
# @api private
|
46
|
+
# @return [Boolean]
|
32
47
|
def diffable?
|
33
48
|
true
|
34
49
|
end
|
35
50
|
|
36
|
-
|
51
|
+
private
|
37
52
|
|
38
53
|
def perform_match(predicate, hash_subset_predicate)
|
39
54
|
expected.__send__(predicate) do |expected_item|
|