rspec-expectations 2.11.3 → 3.11.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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.document +1 -1
- data/.yardopts +1 -1
- data/Changelog.md +1026 -21
- data/{License.txt → LICENSE.md} +5 -3
- data/README.md +174 -78
- data/lib/rspec/expectations/block_snippet_extractor.rb +253 -0
- data/lib/rspec/expectations/configuration.rb +230 -0
- data/lib/rspec/expectations/expectation_target.rb +130 -55
- data/lib/rspec/expectations/fail_with.rb +17 -33
- data/lib/rspec/expectations/failure_aggregator.rb +212 -0
- data/lib/rspec/expectations/handler.rb +163 -29
- data/lib/rspec/expectations/minitest_integration.rb +58 -0
- data/lib/rspec/expectations/syntax.rb +68 -54
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/expectations.rb +59 -24
- data/lib/rspec/matchers/aliased_matcher.rb +116 -0
- data/lib/rspec/matchers/built_in/all.rb +86 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +150 -20
- data/lib/rspec/matchers/built_in/be.rb +115 -109
- data/lib/rspec/matchers/built_in/be_between.rb +77 -0
- data/lib/rspec/matchers/built_in/be_instance_of.rb +16 -1
- data/lib/rspec/matchers/built_in/be_kind_of.rb +10 -1
- data/lib/rspec/matchers/built_in/be_within.rb +43 -17
- data/lib/rspec/matchers/built_in/change.rb +392 -75
- data/lib/rspec/matchers/built_in/compound.rb +290 -0
- data/lib/rspec/matchers/built_in/contain_exactly.rb +302 -0
- data/lib/rspec/matchers/built_in/count_expectation.rb +169 -0
- data/lib/rspec/matchers/built_in/cover.rb +3 -0
- data/lib/rspec/matchers/built_in/eq.rb +26 -8
- data/lib/rspec/matchers/built_in/eql.rb +19 -8
- data/lib/rspec/matchers/built_in/equal.rb +56 -19
- data/lib/rspec/matchers/built_in/exist.rb +74 -10
- data/lib/rspec/matchers/built_in/has.rb +141 -22
- data/lib/rspec/matchers/built_in/have_attributes.rb +114 -0
- data/lib/rspec/matchers/built_in/include.rb +175 -20
- data/lib/rspec/matchers/built_in/match.rb +95 -1
- data/lib/rspec/matchers/built_in/operators.rb +128 -0
- data/lib/rspec/matchers/built_in/output.rb +207 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +212 -38
- data/lib/rspec/matchers/built_in/respond_to.rb +155 -29
- data/lib/rspec/matchers/built_in/satisfy.rb +39 -9
- data/lib/rspec/matchers/built_in/start_or_end_with.rb +94 -0
- data/lib/rspec/matchers/built_in/throw_symbol.rb +58 -14
- data/lib/rspec/matchers/built_in/yield.rb +252 -98
- data/lib/rspec/matchers/built_in.rb +47 -33
- data/lib/rspec/matchers/composable.rb +171 -0
- data/lib/rspec/matchers/dsl.rb +530 -10
- data/lib/rspec/matchers/english_phrasing.rb +58 -0
- data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +82 -0
- data/lib/rspec/matchers/fail_matchers.rb +42 -0
- data/lib/rspec/matchers/generated_descriptions.rb +15 -10
- data/lib/rspec/matchers/matcher_delegator.rb +35 -0
- data/lib/rspec/matchers/matcher_protocol.rb +105 -0
- data/lib/rspec/matchers.rb +604 -252
- data.tar.gz.sig +0 -0
- metadata +178 -278
- metadata.gz.sig +0 -0
- data/features/README.md +0 -49
- data/features/Upgrade.md +0 -53
- data/features/built_in_matchers/README.md +0 -90
- data/features/built_in_matchers/be.feature +0 -173
- data/features/built_in_matchers/be_within.feature +0 -46
- data/features/built_in_matchers/cover.feature +0 -45
- data/features/built_in_matchers/end_with.feature +0 -46
- data/features/built_in_matchers/equality.feature +0 -145
- data/features/built_in_matchers/exist.feature +0 -43
- data/features/built_in_matchers/expect_change.feature +0 -59
- data/features/built_in_matchers/expect_error.feature +0 -138
- data/features/built_in_matchers/have.feature +0 -103
- data/features/built_in_matchers/include.feature +0 -121
- data/features/built_in_matchers/match.feature +0 -50
- data/features/built_in_matchers/operators.feature +0 -221
- data/features/built_in_matchers/predicates.feature +0 -128
- data/features/built_in_matchers/respond_to.feature +0 -78
- data/features/built_in_matchers/satisfy.feature +0 -31
- data/features/built_in_matchers/start_with.feature +0 -46
- data/features/built_in_matchers/throw_symbol.feature +0 -85
- data/features/built_in_matchers/types.feature +0 -114
- data/features/built_in_matchers/yield.feature +0 -146
- 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 -38
- data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
- data/features/customized_message.feature +0 -22
- 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 -5
- data/features/syntax_configuration.feature +0 -68
- data/features/test_frameworks/test_unit.feature +0 -46
- data/lib/rspec/expectations/deprecation.rb +0 -38
- data/lib/rspec/expectations/differ.rb +0 -81
- data/lib/rspec/expectations/errors.rb +0 -9
- data/lib/rspec/expectations/extensions/array.rb +0 -9
- data/lib/rspec/expectations/extensions/object.rb +0 -39
- data/lib/rspec/expectations/extensions.rb +0 -2
- data/lib/rspec/matchers/be_close.rb +0 -9
- data/lib/rspec/matchers/built_in/have.rb +0 -108
- data/lib/rspec/matchers/built_in/match_array.rb +0 -45
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +0 -48
- data/lib/rspec/matchers/compatibility.rb +0 -14
- data/lib/rspec/matchers/configuration.rb +0 -66
- data/lib/rspec/matchers/extensions/instance_eval_with_args.rb +0 -39
- data/lib/rspec/matchers/matcher.rb +0 -299
- data/lib/rspec/matchers/method_missing.rb +0 -12
- data/lib/rspec/matchers/operator_matcher.rb +0 -84
- data/lib/rspec/matchers/pretty.rb +0 -60
- data/lib/rspec-expectations.rb +0 -1
- data/spec/rspec/expectations/differ_spec.rb +0 -153
- data/spec/rspec/expectations/expectation_target_spec.rb +0 -65
- data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
- data/spec/rspec/expectations/fail_with_spec.rb +0 -70
- data/spec/rspec/expectations/handler_spec.rb +0 -206
- data/spec/rspec/matchers/base_matcher_spec.rb +0 -60
- data/spec/rspec/matchers/be_close_spec.rb +0 -22
- data/spec/rspec/matchers/be_instance_of_spec.rb +0 -40
- data/spec/rspec/matchers/be_kind_of_spec.rb +0 -37
- data/spec/rspec/matchers/be_spec.rb +0 -452
- data/spec/rspec/matchers/be_within_spec.rb +0 -80
- data/spec/rspec/matchers/change_spec.rb +0 -528
- data/spec/rspec/matchers/configuration_spec.rb +0 -202
- data/spec/rspec/matchers/cover_spec.rb +0 -69
- data/spec/rspec/matchers/description_generation_spec.rb +0 -176
- data/spec/rspec/matchers/dsl_spec.rb +0 -57
- data/spec/rspec/matchers/eq_spec.rb +0 -54
- data/spec/rspec/matchers/eql_spec.rb +0 -41
- data/spec/rspec/matchers/equal_spec.rb +0 -60
- data/spec/rspec/matchers/exist_spec.rb +0 -110
- data/spec/rspec/matchers/has_spec.rb +0 -118
- data/spec/rspec/matchers/have_spec.rb +0 -461
- data/spec/rspec/matchers/include_spec.rb +0 -367
- data/spec/rspec/matchers/match_array_spec.rb +0 -124
- data/spec/rspec/matchers/match_spec.rb +0 -61
- data/spec/rspec/matchers/matcher_spec.rb +0 -434
- data/spec/rspec/matchers/matchers_spec.rb +0 -31
- data/spec/rspec/matchers/method_missing_spec.rb +0 -24
- data/spec/rspec/matchers/operator_matcher_spec.rb +0 -221
- data/spec/rspec/matchers/raise_error_spec.rb +0 -344
- data/spec/rspec/matchers/respond_to_spec.rb +0 -295
- data/spec/rspec/matchers/satisfy_spec.rb +0 -44
- data/spec/rspec/matchers/start_with_end_with_spec.rb +0 -182
- data/spec/rspec/matchers/throw_symbol_spec.rb +0 -116
- data/spec/rspec/matchers/yield_spec.rb +0 -402
- data/spec/spec_helper.rb +0 -27
- data/spec/support/classes.rb +0 -56
- data/spec/support/in_sub_process.rb +0 -31
- data/spec/support/matchers.rb +0 -22
- data/spec/support/ruby_version.rb +0 -10
- data/spec/support/shared_examples.rb +0 -13
@@ -1,74 +1,78 @@
|
|
1
|
-
require 'rspec/matchers/dsl'
|
2
|
-
|
3
1
|
module RSpec
|
4
2
|
module Matchers
|
5
3
|
module BuiltIn
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `be_truthy`.
|
6
|
+
# Not intended to be instantiated directly.
|
7
|
+
class BeTruthy < BaseMatcher
|
8
|
+
# @api private
|
9
|
+
# @return [String]
|
10
|
+
def failure_message
|
11
|
+
"expected: truthy value\n got: #{actual_formatted}"
|
9
12
|
end
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
# @api private
|
15
|
+
# @return [String]
|
16
|
+
def failure_message_when_negated
|
17
|
+
"expected: falsey value\n got: #{actual_formatted}"
|
13
18
|
end
|
14
19
|
|
15
|
-
|
16
|
-
"expected: non-true value\n got: #{actual.inspect}"
|
17
|
-
end
|
18
|
-
end
|
20
|
+
private
|
19
21
|
|
20
|
-
class BeFalse < BaseMatcher
|
21
22
|
def match(_, actual)
|
22
|
-
|
23
|
+
!!actual
|
23
24
|
end
|
25
|
+
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
+
# @api private
|
28
|
+
# Provides the implementation for `be_falsey`.
|
29
|
+
# Not intended to be instantiated directly.
|
30
|
+
class BeFalsey < BaseMatcher
|
31
|
+
# @api private
|
32
|
+
# @return [String]
|
33
|
+
def failure_message
|
34
|
+
"expected: falsey value\n got: #{actual_formatted}"
|
27
35
|
end
|
28
36
|
|
29
|
-
|
30
|
-
|
37
|
+
# @api private
|
38
|
+
# @return [String]
|
39
|
+
def failure_message_when_negated
|
40
|
+
"expected: truthy value\n got: #{actual_formatted}"
|
31
41
|
end
|
32
|
-
end
|
33
42
|
|
34
|
-
|
43
|
+
private
|
44
|
+
|
35
45
|
def match(_, actual)
|
36
|
-
actual
|
46
|
+
!actual
|
37
47
|
end
|
48
|
+
end
|
38
49
|
|
39
|
-
|
40
|
-
|
50
|
+
# @api private
|
51
|
+
# Provides the implementation for `be_nil`.
|
52
|
+
# Not intended to be instantiated directly.
|
53
|
+
class BeNil < BaseMatcher
|
54
|
+
# @api private
|
55
|
+
# @return [String]
|
56
|
+
def failure_message
|
57
|
+
"expected: nil\n got: #{actual_formatted}"
|
41
58
|
end
|
42
59
|
|
43
|
-
|
60
|
+
# @api private
|
61
|
+
# @return [String]
|
62
|
+
def failure_message_when_negated
|
44
63
|
"expected: not nil\n got: nil"
|
45
64
|
end
|
46
|
-
end
|
47
65
|
|
48
|
-
|
49
|
-
def initialize(*args, &block)
|
50
|
-
@args = args
|
51
|
-
end
|
66
|
+
private
|
52
67
|
|
53
68
|
def match(_, actual)
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def failure_message_for_should
|
58
|
-
"expected #{@actual.inspect} to evaluate to true"
|
59
|
-
end
|
60
|
-
|
61
|
-
def failure_message_for_should_not
|
62
|
-
"expected #{@actual.inspect} to evaluate to false"
|
63
|
-
end
|
64
|
-
|
65
|
-
[:==, :<, :<=, :>=, :>, :===].each do |operator|
|
66
|
-
define_method operator do |operand|
|
67
|
-
BeComparedTo.new(operand, operator)
|
68
|
-
end
|
69
|
+
actual.nil?
|
69
70
|
end
|
71
|
+
end
|
70
72
|
|
71
|
-
|
73
|
+
# @private
|
74
|
+
module BeHelpers
|
75
|
+
private
|
72
76
|
|
73
77
|
def args_to_s
|
74
78
|
@args.empty? ? "" : parenthesize(inspected_args.join(', '))
|
@@ -79,105 +83,107 @@ module RSpec
|
|
79
83
|
end
|
80
84
|
|
81
85
|
def inspected_args
|
82
|
-
@args.
|
86
|
+
@args.map { |a| RSpec::Support::ObjectFormatter.format(a) }
|
83
87
|
end
|
84
88
|
|
85
89
|
def expected_to_sentence
|
86
|
-
split_words(@expected)
|
90
|
+
EnglishPhrasing.split_words(@expected)
|
87
91
|
end
|
88
92
|
|
89
93
|
def args_to_sentence
|
90
|
-
|
94
|
+
EnglishPhrasing.list(@args)
|
91
95
|
end
|
92
96
|
end
|
93
97
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
def matches?(actual)
|
101
|
-
@actual = actual
|
102
|
-
@actual.send @operator, @expected
|
103
|
-
end
|
98
|
+
# @api private
|
99
|
+
# Provides the implementation for `be`.
|
100
|
+
# Not intended to be instantiated directly.
|
101
|
+
class Be < BaseMatcher
|
102
|
+
include BeHelpers
|
104
103
|
|
105
|
-
def
|
106
|
-
|
104
|
+
def initialize(*args)
|
105
|
+
@args = args
|
107
106
|
end
|
108
107
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
MESSAGE
|
114
|
-
|
115
|
-
raise message << ([:===,:==].include?(@operator) ?
|
116
|
-
"It might be more clearly expressed without the \"be\"?" :
|
117
|
-
"It might be more clearly expressed in the positive?")
|
108
|
+
# @api private
|
109
|
+
# @return [String]
|
110
|
+
def failure_message
|
111
|
+
"expected #{actual_formatted} to evaluate to true"
|
118
112
|
end
|
119
113
|
|
120
|
-
|
121
|
-
|
114
|
+
# @api private
|
115
|
+
# @return [String]
|
116
|
+
def failure_message_when_negated
|
117
|
+
"expected #{actual_formatted} to evaluate to false"
|
122
118
|
end
|
123
|
-
end
|
124
119
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
@block = block
|
120
|
+
[:==, :<, :<=, :>=, :>, :===, :=~].each do |operator|
|
121
|
+
define_method operator do |operand|
|
122
|
+
BeComparedTo.new(operand, operator)
|
123
|
+
end
|
130
124
|
end
|
131
125
|
|
132
|
-
|
133
|
-
@actual = actual
|
134
|
-
begin
|
135
|
-
return @result = actual.__send__(predicate, *@args, &@block)
|
136
|
-
rescue NameError => predicate_missing_error
|
137
|
-
"this needs to be here or rcov will not count this branch even though it's executed in a code example"
|
138
|
-
end
|
126
|
+
private
|
139
127
|
|
140
|
-
|
141
|
-
|
142
|
-
rescue NameError
|
143
|
-
raise predicate_missing_error
|
144
|
-
end
|
128
|
+
def match(_, actual)
|
129
|
+
!!actual
|
145
130
|
end
|
131
|
+
end
|
146
132
|
|
147
|
-
|
148
|
-
|
149
|
-
|
133
|
+
# @api private
|
134
|
+
# Provides the implementation of `be <operator> value`.
|
135
|
+
# Not intended to be instantiated directly.
|
136
|
+
class BeComparedTo < BaseMatcher
|
137
|
+
include BeHelpers
|
150
138
|
|
151
|
-
def
|
152
|
-
|
139
|
+
def initialize(operand, operator)
|
140
|
+
@expected = operand
|
141
|
+
@operator = operator
|
142
|
+
@args = []
|
153
143
|
end
|
154
144
|
|
155
|
-
def
|
156
|
-
|
145
|
+
def matches?(actual)
|
146
|
+
perform_match(actual)
|
147
|
+
rescue ArgumentError, NoMethodError
|
148
|
+
false
|
157
149
|
end
|
158
150
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
151
|
+
def does_not_match?(actual)
|
152
|
+
!perform_match(actual)
|
153
|
+
rescue ArgumentError, NoMethodError
|
154
|
+
false
|
163
155
|
end
|
164
156
|
|
165
|
-
|
166
|
-
|
157
|
+
# @api private
|
158
|
+
# @return [String]
|
159
|
+
def failure_message
|
160
|
+
"expected: #{@operator} #{expected_formatted}\n" \
|
161
|
+
" got: #{@operator.to_s.gsub(/./, ' ')} #{actual_formatted}"
|
167
162
|
end
|
168
163
|
|
169
|
-
|
170
|
-
|
171
|
-
|
164
|
+
# @api private
|
165
|
+
# @return [String]
|
166
|
+
def failure_message_when_negated
|
167
|
+
message = "`expect(#{actual_formatted}).not_to " \
|
168
|
+
"be #{@operator} #{expected_formatted}`"
|
169
|
+
if [:<, :>, :<=, :>=].include?(@operator)
|
170
|
+
message + " not only FAILED, it is a bit confusing."
|
171
|
+
else
|
172
|
+
message
|
173
|
+
end
|
172
174
|
end
|
173
175
|
|
174
|
-
|
175
|
-
|
176
|
-
|
176
|
+
# @api private
|
177
|
+
# @return [String]
|
178
|
+
def description
|
179
|
+
"be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
|
177
180
|
end
|
178
181
|
|
179
|
-
|
180
|
-
|
182
|
+
private
|
183
|
+
|
184
|
+
def perform_match(actual)
|
185
|
+
@actual = actual
|
186
|
+
@actual.__send__ @operator, @expected
|
181
187
|
end
|
182
188
|
end
|
183
189
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Matchers
|
3
|
+
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `be_between`.
|
6
|
+
# Not intended to be instantiated directly.
|
7
|
+
class BeBetween < BaseMatcher
|
8
|
+
def initialize(min, max)
|
9
|
+
@min, @max = min, max
|
10
|
+
inclusive
|
11
|
+
end
|
12
|
+
|
13
|
+
# @api public
|
14
|
+
# Makes the between comparison inclusive.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# expect(3).to be_between(2, 3).inclusive
|
18
|
+
#
|
19
|
+
# @note The matcher is inclusive by default; this simply provides
|
20
|
+
# a way to be more explicit about it.
|
21
|
+
def inclusive
|
22
|
+
@less_than_operator = :<=
|
23
|
+
@greater_than_operator = :>=
|
24
|
+
@mode = :inclusive
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api public
|
29
|
+
# Makes the between comparison exclusive.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# expect(3).to be_between(2, 4).exclusive
|
33
|
+
def exclusive
|
34
|
+
@less_than_operator = :<
|
35
|
+
@greater_than_operator = :>
|
36
|
+
@mode = :exclusive
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api private
|
41
|
+
# @return [Boolean]
|
42
|
+
def matches?(actual)
|
43
|
+
@actual = actual
|
44
|
+
comparable? && compare
|
45
|
+
rescue ArgumentError
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
# @return [String]
|
51
|
+
def failure_message
|
52
|
+
"#{super}#{not_comparable_clause}"
|
53
|
+
end
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
# @return [String]
|
57
|
+
def description
|
58
|
+
"be between #{description_of @min} and #{description_of @max} (#{@mode})"
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def comparable?
|
64
|
+
@actual.respond_to?(@less_than_operator) && @actual.respond_to?(@greater_than_operator)
|
65
|
+
end
|
66
|
+
|
67
|
+
def not_comparable_clause
|
68
|
+
", but it does not respond to `#{@less_than_operator}` and `#{@greater_than_operator}`" unless comparable?
|
69
|
+
end
|
70
|
+
|
71
|
+
def compare
|
72
|
+
@actual.__send__(@greater_than_operator, @min) && @actual.__send__(@less_than_operator, @max)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,9 +1,24 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `be_an_instance_of`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class BeAnInstanceOf < BaseMatcher
|
8
|
+
# @api private
|
9
|
+
# @return [String]
|
10
|
+
def description
|
11
|
+
"be an instance of #{expected}"
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
5
16
|
def match(expected, actual)
|
6
|
-
actual.instance_of?
|
17
|
+
actual.instance_of?(expected)
|
18
|
+
rescue NoMethodError
|
19
|
+
raise ::ArgumentError, "The #{matcher_name} matcher requires that " \
|
20
|
+
"the actual object responds to #instance_of? method " \
|
21
|
+
"but a `NoMethodError` was encountered instead."
|
7
22
|
end
|
8
23
|
end
|
9
24
|
end
|
@@ -1,9 +1,18 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `be_a_kind_of`.
|
6
|
+
# Not intended to be instantiated directly.
|
4
7
|
class BeAKindOf < BaseMatcher
|
8
|
+
private
|
9
|
+
|
5
10
|
def match(expected, actual)
|
6
|
-
actual.kind_of?
|
11
|
+
actual.kind_of?(expected)
|
12
|
+
rescue NoMethodError
|
13
|
+
raise ::ArgumentError, "The #{matcher_name} matcher requires that " \
|
14
|
+
"the actual object responds to #kind_of? method " \
|
15
|
+
"but a `NoMethodError` was encountered instead."
|
7
16
|
end
|
8
17
|
end
|
9
18
|
end
|
@@ -1,45 +1,71 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
|
4
|
+
# @api private
|
5
|
+
# Provides the implementation for `be_within`.
|
6
|
+
# Not intended to be instantiated directly.
|
7
|
+
class BeWithin < BaseMatcher
|
5
8
|
def initialize(delta)
|
6
9
|
@delta = delta
|
7
10
|
end
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
# @api public
|
13
|
+
# Sets the expected value.
|
14
|
+
def of(expected)
|
15
|
+
@expected = expected
|
16
|
+
@tolerance = @delta
|
17
|
+
@unit = ''
|
18
|
+
self
|
14
19
|
end
|
15
|
-
alias == matches?
|
16
20
|
|
17
|
-
|
18
|
-
|
21
|
+
# @api public
|
22
|
+
# Sets the expected value, and makes the matcher do
|
23
|
+
# a percent comparison.
|
24
|
+
def percent_of(expected)
|
25
|
+
@expected = expected
|
26
|
+
@tolerance = @expected.abs * @delta / 100.0
|
27
|
+
@unit = '%'
|
19
28
|
self
|
20
29
|
end
|
21
30
|
|
22
|
-
|
23
|
-
|
31
|
+
# @private
|
32
|
+
def matches?(actual)
|
33
|
+
@actual = actual
|
34
|
+
raise needs_expected unless defined? @expected
|
35
|
+
numeric? && (@actual - @expected).abs <= @tolerance
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
# @return [String]
|
40
|
+
def failure_message
|
41
|
+
"expected #{actual_formatted} to #{description}#{not_numeric_clause}"
|
24
42
|
end
|
25
43
|
|
26
|
-
|
27
|
-
|
44
|
+
# @api private
|
45
|
+
# @return [String]
|
46
|
+
def failure_message_when_negated
|
47
|
+
"expected #{actual_formatted} not to #{description}"
|
28
48
|
end
|
29
49
|
|
50
|
+
# @api private
|
51
|
+
# @return [String]
|
30
52
|
def description
|
31
|
-
"be within #{@delta} of #{
|
53
|
+
"be within #{@delta}#{@unit} of #{expected_formatted}"
|
32
54
|
end
|
33
55
|
|
34
|
-
|
56
|
+
private
|
35
57
|
|
36
|
-
def
|
37
|
-
|
58
|
+
def numeric?
|
59
|
+
@actual.respond_to?(:-)
|
38
60
|
end
|
39
61
|
|
40
62
|
def needs_expected
|
41
63
|
ArgumentError.new "You must set an expected value using #of: be_within(#{@delta}).of(expected_value)"
|
42
64
|
end
|
65
|
+
|
66
|
+
def not_numeric_clause
|
67
|
+
", but it could not be treated as a numeric value" unless numeric?
|
68
|
+
end
|
43
69
|
end
|
44
70
|
end
|
45
71
|
end
|