rspec-expectations 3.0.0.beta2 → 3.0.0.rc1
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 +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
@@ -27,6 +27,12 @@ module RSpec
|
|
27
27
|
AliasedMatcher.new(return_val, @description_block)
|
28
28
|
end
|
29
29
|
|
30
|
+
# Provides the description of the aliased matcher. Aliased matchers
|
31
|
+
# are designed to behave identically to the original matcher except
|
32
|
+
# for this method. The description is different to reflect the aliased
|
33
|
+
# name.
|
34
|
+
#
|
35
|
+
# @api private
|
30
36
|
def description
|
31
37
|
@description_block.call(super)
|
32
38
|
end
|
@@ -1,7 +1,14 @@
|
|
1
|
-
|
1
|
+
RSpec::Support.require_rspec_matchers "built_in/base_matcher"
|
2
2
|
|
3
3
|
module RSpec
|
4
4
|
module Matchers
|
5
|
+
# Container module for all built-in matchers. The matcher classes are here
|
6
|
+
# (rather than directly under `RSpec::Matchers`) in order to prevent name
|
7
|
+
# collisions, since `RSpec::Matchers` gets included into the user's namespace.
|
8
|
+
#
|
9
|
+
# Autoloading is used to delay when the matcher classes get loaded, allowing
|
10
|
+
# rspec-matchers to boot faster, and avoiding loading matchers the user is
|
11
|
+
# not using.
|
5
12
|
module BuiltIn
|
6
13
|
autoload :BeAKindOf, 'rspec/matchers/built_in/be_kind_of'
|
7
14
|
autoload :BeAnInstanceOf, 'rspec/matchers/built_in/be_instance_of'
|
@@ -24,6 +31,7 @@ module RSpec
|
|
24
31
|
autoload :Exist, 'rspec/matchers/built_in/exist'
|
25
32
|
autoload :Has, 'rspec/matchers/built_in/has'
|
26
33
|
autoload :Include, 'rspec/matchers/built_in/include'
|
34
|
+
autoload :All, 'rspec/matchers/built_in/all'
|
27
35
|
autoload :Match, 'rspec/matchers/built_in/match'
|
28
36
|
autoload :NegativeOperatorMatcher, 'rspec/matchers/built_in/operators'
|
29
37
|
autoload :OperatorMatcher, 'rspec/matchers/built_in/operators'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Matchers
|
3
|
+
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `all`.
|
6
|
+
# Not intended to be instantiated directly.
|
7
|
+
class All < BaseMatcher
|
8
|
+
|
9
|
+
# @private
|
10
|
+
attr_reader :matcher, :failed_objects
|
11
|
+
|
12
|
+
def initialize(matcher)
|
13
|
+
@matcher = matcher
|
14
|
+
@failed_objects = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# @private
|
18
|
+
def does_not_match?(actual)
|
19
|
+
raise NotImplementedError, '`expect().not_to all( matcher )` is not supported.'
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
# @return [String]
|
24
|
+
def failure_message
|
25
|
+
all_messages = [improve_hash_formatting(super)]
|
26
|
+
failed_objects.each do |index, matcher_failure_message|
|
27
|
+
all_messages << failure_message_for_item(index, matcher_failure_message)
|
28
|
+
end
|
29
|
+
all_messages.join("\n\n")
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
# @return [String]
|
34
|
+
def description
|
35
|
+
described_items = surface_descriptions_in(matcher)
|
36
|
+
improve_hash_formatting "all#{to_sentence(described_items)}"
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def match(_, actual)
|
42
|
+
index_failed_objects
|
43
|
+
failed_objects.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
def index_failed_objects
|
47
|
+
actual.each_with_index do |actual_item, index|
|
48
|
+
cloned_matcher = matcher.clone
|
49
|
+
matches = cloned_matcher.matches?(actual_item)
|
50
|
+
failed_objects[index] = cloned_matcher.failure_message unless matches
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def failure_message_for_item(index, failure_message)
|
55
|
+
failure_message = indent_multiline_message( add_new_line_if_needed(failure_message) )
|
56
|
+
indent_multiline_message("object at index #{index} failed to match:#{failure_message}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_new_line_if_needed(message)
|
60
|
+
message.start_with?("\n") ? message : "\n#{message}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def indent_multiline_message(message)
|
64
|
+
message = message.sub(/\n+\z/, '')
|
65
|
+
message.lines.map do |line|
|
66
|
+
line =~ /\S/ ? ' ' + line : line
|
67
|
+
end.join
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize_copy(other)
|
71
|
+
@matcher = @matcher.clone
|
72
|
+
super
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -4,7 +4,7 @@ module RSpec
|
|
4
4
|
# @api private
|
5
5
|
#
|
6
6
|
# Used _internally_ as a base class for matchers that ship with
|
7
|
-
# rspec-expectations.
|
7
|
+
# rspec-expectations and rspec-rails.
|
8
8
|
#
|
9
9
|
# ### Warning:
|
10
10
|
#
|
@@ -15,19 +15,33 @@ module RSpec
|
|
15
15
|
include RSpec::Matchers::Pretty
|
16
16
|
include RSpec::Matchers::Composable
|
17
17
|
|
18
|
+
# @api private
|
19
|
+
# Used to detect when no arg is passed to `initialize`.
|
20
|
+
# `nil` cannot be used because it's a valid value to pass.
|
18
21
|
UNDEFINED = Object.new.freeze
|
19
22
|
|
23
|
+
# @private
|
20
24
|
attr_reader :actual, :expected, :rescued_exception
|
21
25
|
|
22
26
|
def initialize(expected = UNDEFINED)
|
23
27
|
@expected = expected unless UNDEFINED.equal?(expected)
|
24
28
|
end
|
25
29
|
|
30
|
+
# @api private
|
31
|
+
# Indicates if the match is successful. Delegates to `match`, which
|
32
|
+
# should be defined on a subclass. Takes care of consistently
|
33
|
+
# initializing the `actual` attribute.
|
26
34
|
def matches?(actual)
|
27
35
|
@actual = actual
|
28
36
|
match(expected, actual)
|
29
37
|
end
|
30
38
|
|
39
|
+
# @api private
|
40
|
+
# Used to wrap a block of code that will indicate failure by
|
41
|
+
# raising one of the named exceptions.
|
42
|
+
#
|
43
|
+
# This is used by rspec-rails for some of its matchers that
|
44
|
+
# wrap rails' assertions.
|
31
45
|
def match_unless_raises(*exceptions)
|
32
46
|
exceptions.unshift Exception if exceptions.empty?
|
33
47
|
begin
|
@@ -38,25 +52,49 @@ module RSpec
|
|
38
52
|
end
|
39
53
|
end
|
40
54
|
|
55
|
+
# @api private
|
56
|
+
# Provides a good generic failure message. Based on `description`.
|
57
|
+
# When subclassing, if you are not satisfied with this failure message
|
58
|
+
# you often only need to override `description`.
|
59
|
+
# @return [String]
|
41
60
|
def failure_message
|
42
61
|
assert_ivars :@actual
|
43
62
|
"expected #{@actual.inspect} to #{description}"
|
44
63
|
end
|
45
64
|
|
65
|
+
# @api private
|
66
|
+
# Provides a good generic negative failure message. Based on `description`.
|
67
|
+
# When subclassing, if you are not satisfied with this failure message
|
68
|
+
# you often only need to override `description`.
|
69
|
+
# @return [String]
|
46
70
|
def failure_message_when_negated
|
47
71
|
assert_ivars :@actual
|
48
72
|
"expected #{@actual.inspect} not to #{description}"
|
49
73
|
end
|
50
74
|
|
75
|
+
# @api private
|
76
|
+
# Generates a "pretty" description using the logic in {Pretty}.
|
77
|
+
# @return [String]
|
51
78
|
def description
|
52
79
|
return name_to_sentence unless defined?(@expected)
|
53
80
|
"#{name_to_sentence}#{to_sentence @expected}"
|
54
81
|
end
|
55
82
|
|
83
|
+
# @api private
|
84
|
+
# Matchers are not diffable by default. Override this to make your
|
85
|
+
# subclass diffable.
|
56
86
|
def diffable?
|
57
87
|
false
|
58
88
|
end
|
59
89
|
|
90
|
+
# @api private
|
91
|
+
# Most matchers are value matchers (i.e. meant to work with `expect(value)`)
|
92
|
+
# rather than block matchers (i.e. meant to work with `expect { }`), so
|
93
|
+
# this defaults to false. Block matchers must override this to return true.
|
94
|
+
def supports_block_expectations?
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
60
98
|
private
|
61
99
|
|
62
100
|
def assert_ivars(*expected_ivars)
|
@@ -1,50 +1,79 @@
|
|
1
|
-
require 'rspec/matchers/dsl'
|
2
|
-
|
3
1
|
module RSpec
|
4
2
|
module Matchers
|
5
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `be_truthy`.
|
6
|
+
# Not intended to be instantiated directly.
|
6
7
|
class BeTruthy < BaseMatcher
|
7
|
-
def match(_, actual)
|
8
|
-
!!actual
|
9
|
-
end
|
10
8
|
|
9
|
+
# @api private
|
10
|
+
# @return [String]
|
11
11
|
def failure_message
|
12
12
|
"expected: truthy value\n got: #{actual.inspect}"
|
13
13
|
end
|
14
14
|
|
15
|
+
# @api private
|
16
|
+
# @return [String]
|
15
17
|
def failure_message_when_negated
|
16
18
|
"expected: falsey value\n got: #{actual.inspect}"
|
17
19
|
end
|
18
|
-
end
|
19
20
|
|
20
|
-
|
21
|
+
private
|
22
|
+
|
21
23
|
def match(_, actual)
|
22
|
-
|
24
|
+
!!actual
|
23
25
|
end
|
26
|
+
end
|
24
27
|
|
28
|
+
# @api private
|
29
|
+
# Provides the implementation for `be_falsey`.
|
30
|
+
# Not intended to be instantiated directly.
|
31
|
+
class BeFalsey < BaseMatcher
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
# @return [String]
|
25
35
|
def failure_message
|
26
36
|
"expected: falsey value\n got: #{actual.inspect}"
|
27
37
|
end
|
28
38
|
|
39
|
+
# @api private
|
40
|
+
# @return [String]
|
29
41
|
def failure_message_when_negated
|
30
42
|
"expected: truthy value\n got: #{actual.inspect}"
|
31
43
|
end
|
32
|
-
end
|
33
44
|
|
34
|
-
|
45
|
+
private
|
46
|
+
|
35
47
|
def match(_, actual)
|
36
|
-
actual
|
48
|
+
!actual
|
37
49
|
end
|
50
|
+
end
|
38
51
|
|
52
|
+
# @api private
|
53
|
+
# Provides the implementation for `be_nil`.
|
54
|
+
# Not intended to be instantiated directly.
|
55
|
+
class BeNil < BaseMatcher
|
56
|
+
|
57
|
+
# @api private
|
58
|
+
# @return [String]
|
39
59
|
def failure_message
|
40
60
|
"expected: nil\n got: #{actual.inspect}"
|
41
61
|
end
|
42
62
|
|
63
|
+
# @api private
|
64
|
+
# @return [String]
|
43
65
|
def failure_message_when_negated
|
44
66
|
"expected: not nil\n got: nil"
|
45
67
|
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def match(_, actual)
|
72
|
+
actual.nil?
|
73
|
+
end
|
46
74
|
end
|
47
75
|
|
76
|
+
# @private
|
48
77
|
module BeHelpers
|
49
78
|
private
|
50
79
|
|
@@ -69,6 +98,9 @@ module RSpec
|
|
69
98
|
end
|
70
99
|
end
|
71
100
|
|
101
|
+
# @api private
|
102
|
+
# Provides the implementation for `be`.
|
103
|
+
# Not intended to be instantiated directly.
|
72
104
|
class Be < BaseMatcher
|
73
105
|
include BeHelpers
|
74
106
|
|
@@ -76,14 +108,14 @@ module RSpec
|
|
76
108
|
@args = args
|
77
109
|
end
|
78
110
|
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
|
111
|
+
# @api private
|
112
|
+
# @return [String]
|
83
113
|
def failure_message
|
84
114
|
"expected #{@actual.inspect} to evaluate to true"
|
85
115
|
end
|
86
116
|
|
117
|
+
# @api private
|
118
|
+
# @return [String]
|
87
119
|
def failure_message_when_negated
|
88
120
|
"expected #{@actual.inspect} to evaluate to false"
|
89
121
|
end
|
@@ -93,8 +125,17 @@ module RSpec
|
|
93
125
|
BeComparedTo.new(operand, operator)
|
94
126
|
end
|
95
127
|
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def match(_, actual)
|
132
|
+
!!actual
|
133
|
+
end
|
96
134
|
end
|
97
135
|
|
136
|
+
# @api private
|
137
|
+
# Provides the implementation of `be <operator> value`.
|
138
|
+
# Not intended to be instantiated directly.
|
98
139
|
class BeComparedTo < BaseMatcher
|
99
140
|
include BeHelpers
|
100
141
|
|
@@ -108,10 +149,14 @@ module RSpec
|
|
108
149
|
@actual.__send__ @operator, @expected
|
109
150
|
end
|
110
151
|
|
152
|
+
# @api private
|
153
|
+
# @return [String]
|
111
154
|
def failure_message
|
112
155
|
"expected: #{@operator} #{@expected.inspect}\n got: #{@operator.to_s.gsub(/./, ' ')} #{@actual.inspect}"
|
113
156
|
end
|
114
157
|
|
158
|
+
# @api private
|
159
|
+
# @return [String]
|
115
160
|
def failure_message_when_negated
|
116
161
|
message = "`expect(#{@actual.inspect}).not_to be #{@operator} #{@expected.inspect}`"
|
117
162
|
if [:<, :>, :<=, :>=].include?(@operator)
|
@@ -121,11 +166,16 @@ module RSpec
|
|
121
166
|
end
|
122
167
|
end
|
123
168
|
|
169
|
+
# @api private
|
170
|
+
# @return [String]
|
124
171
|
def description
|
125
172
|
"be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
|
126
173
|
end
|
127
174
|
end
|
128
175
|
|
176
|
+
# @api private
|
177
|
+
# Provides the implementation of `be_<predicate>`.
|
178
|
+
# Not intended to be instantiated directly.
|
129
179
|
class BePredicate < BaseMatcher
|
130
180
|
include BeHelpers
|
131
181
|
|
@@ -135,56 +185,68 @@ module RSpec
|
|
135
185
|
@block = block
|
136
186
|
end
|
137
187
|
|
138
|
-
def matches?(actual)
|
139
|
-
@actual
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
144
|
-
|
145
|
-
begin
|
146
|
-
return @result = actual.__send__(predicate, *@args, &@block)
|
147
|
-
rescue NameError => predicate_missing_error
|
148
|
-
end
|
188
|
+
def matches?(actual, &block)
|
189
|
+
@actual = actual
|
190
|
+
@block ||= block
|
191
|
+
predicate_accessible? && predicate_matches?
|
192
|
+
end
|
149
193
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
end
|
194
|
+
def does_not_match?(actual, &block)
|
195
|
+
@actual = actual
|
196
|
+
@block ||= block
|
197
|
+
predicate_accessible? && !predicate_matches?
|
155
198
|
end
|
156
199
|
|
200
|
+
# @api private
|
201
|
+
# @return [String]
|
157
202
|
def failure_message
|
158
|
-
|
203
|
+
failure_message_expecting(true)
|
159
204
|
end
|
160
205
|
|
206
|
+
# @api private
|
207
|
+
# @return [String]
|
161
208
|
def failure_message_when_negated
|
162
|
-
|
209
|
+
failure_message_expecting(false)
|
163
210
|
end
|
164
211
|
|
212
|
+
# @api private
|
213
|
+
# @return [String]
|
165
214
|
def description
|
166
215
|
"#{prefix_to_sentence}#{expected_to_sentence}#{args_to_sentence}"
|
167
216
|
end
|
168
217
|
|
169
|
-
|
218
|
+
private
|
219
|
+
|
220
|
+
def predicate_accessible?
|
221
|
+
!private_predicate? && predicate_exists?
|
222
|
+
end
|
170
223
|
|
171
|
-
# support 1.8.7
|
172
|
-
if methods.first
|
173
|
-
def
|
174
|
-
actual.private_methods.include? predicate.to_s
|
224
|
+
# support 1.8.7, evaluate once at load time for performance
|
225
|
+
if String === methods.first
|
226
|
+
def private_predicate?
|
227
|
+
@actual.private_methods.include? predicate.to_s
|
175
228
|
end
|
176
229
|
else
|
177
|
-
def
|
178
|
-
actual.private_methods.include? predicate
|
230
|
+
def private_predicate?
|
231
|
+
@actual.private_methods.include? predicate
|
179
232
|
end
|
180
233
|
end
|
181
234
|
|
235
|
+
def predicate_exists?
|
236
|
+
actual.respond_to?(predicate) || actual.respond_to?(present_tense_predicate)
|
237
|
+
end
|
238
|
+
|
239
|
+
def predicate_matches?
|
240
|
+
method_name = actual.respond_to?(predicate) ? predicate : present_tense_predicate
|
241
|
+
@predicate_matches = actual.__send__(method_name, *@args, &@block)
|
242
|
+
end
|
243
|
+
|
182
244
|
def predicate
|
183
|
-
"#{@expected}?"
|
245
|
+
:"#{@expected}?"
|
184
246
|
end
|
185
247
|
|
186
248
|
def present_tense_predicate
|
187
|
-
"#{@expected}s?"
|
249
|
+
:"#{@expected}s?"
|
188
250
|
end
|
189
251
|
|
190
252
|
def parse_expected(expected)
|
@@ -199,6 +261,19 @@ module RSpec
|
|
199
261
|
def prefix_to_sentence
|
200
262
|
split_words(@prefix)
|
201
263
|
end
|
264
|
+
|
265
|
+
def failure_message_expecting(value)
|
266
|
+
validity_message ||
|
267
|
+
"expected `#{@actual.inspect}.#{predicate}#{args_to_s}` to return #{value}, got #{@predicate_matches.inspect}"
|
268
|
+
end
|
269
|
+
|
270
|
+
def validity_message
|
271
|
+
if private_predicate?
|
272
|
+
"expected #{@actual} to respond to `#{predicate}` but `#{predicate}` is a private method"
|
273
|
+
elsif !predicate_exists?
|
274
|
+
"expected #{@actual} to respond to `#{predicate}`"
|
275
|
+
end
|
276
|
+
end
|
202
277
|
end
|
203
278
|
end
|
204
279
|
end
|