rspec-expectations 3.0.4 → 3.12.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +1 -1
  5. data/Changelog.md +530 -5
  6. data/{License.txt → LICENSE.md} +5 -4
  7. data/README.md +73 -31
  8. data/lib/rspec/expectations/block_snippet_extractor.rb +253 -0
  9. data/lib/rspec/expectations/configuration.rb +96 -1
  10. data/lib/rspec/expectations/expectation_target.rb +82 -38
  11. data/lib/rspec/expectations/fail_with.rb +11 -6
  12. data/lib/rspec/expectations/failure_aggregator.rb +229 -0
  13. data/lib/rspec/expectations/handler.rb +36 -15
  14. data/lib/rspec/expectations/minitest_integration.rb +43 -2
  15. data/lib/rspec/expectations/syntax.rb +5 -5
  16. data/lib/rspec/expectations/version.rb +1 -1
  17. data/lib/rspec/expectations.rb +15 -1
  18. data/lib/rspec/matchers/aliased_matcher.rb +79 -4
  19. data/lib/rspec/matchers/built_in/all.rb +11 -0
  20. data/lib/rspec/matchers/built_in/base_matcher.rb +111 -28
  21. data/lib/rspec/matchers/built_in/be.rb +28 -114
  22. data/lib/rspec/matchers/built_in/be_between.rb +1 -1
  23. data/lib/rspec/matchers/built_in/be_instance_of.rb +5 -1
  24. data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -1
  25. data/lib/rspec/matchers/built_in/be_within.rb +5 -12
  26. data/lib/rspec/matchers/built_in/change.rb +171 -63
  27. data/lib/rspec/matchers/built_in/compound.rb +201 -30
  28. data/lib/rspec/matchers/built_in/contain_exactly.rb +73 -12
  29. data/lib/rspec/matchers/built_in/count_expectation.rb +169 -0
  30. data/lib/rspec/matchers/built_in/eq.rb +3 -38
  31. data/lib/rspec/matchers/built_in/eql.rb +2 -2
  32. data/lib/rspec/matchers/built_in/equal.rb +3 -3
  33. data/lib/rspec/matchers/built_in/exist.rb +7 -3
  34. data/lib/rspec/matchers/built_in/has.rb +93 -30
  35. data/lib/rspec/matchers/built_in/have_attributes.rb +114 -0
  36. data/lib/rspec/matchers/built_in/include.rb +133 -25
  37. data/lib/rspec/matchers/built_in/match.rb +79 -2
  38. data/lib/rspec/matchers/built_in/operators.rb +14 -5
  39. data/lib/rspec/matchers/built_in/output.rb +59 -2
  40. data/lib/rspec/matchers/built_in/raise_error.rb +130 -27
  41. data/lib/rspec/matchers/built_in/respond_to.rb +117 -15
  42. data/lib/rspec/matchers/built_in/satisfy.rb +28 -14
  43. data/lib/rspec/matchers/built_in/{start_and_end_with.rb → start_or_end_with.rb} +20 -8
  44. data/lib/rspec/matchers/built_in/throw_symbol.rb +15 -5
  45. data/lib/rspec/matchers/built_in/yield.rb +129 -156
  46. data/lib/rspec/matchers/built_in.rb +5 -3
  47. data/lib/rspec/matchers/composable.rb +24 -36
  48. data/lib/rspec/matchers/dsl.rb +203 -37
  49. data/lib/rspec/matchers/english_phrasing.rb +58 -0
  50. data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +82 -0
  51. data/lib/rspec/matchers/fail_matchers.rb +42 -0
  52. data/lib/rspec/matchers/generated_descriptions.rb +1 -2
  53. data/lib/rspec/matchers/matcher_delegator.rb +3 -4
  54. data/lib/rspec/matchers/matcher_protocol.rb +105 -0
  55. data/lib/rspec/matchers.rb +267 -144
  56. data.tar.gz.sig +0 -0
  57. metadata +71 -49
  58. metadata.gz.sig +0 -0
  59. data/lib/rspec/matchers/pretty.rb +0 -77
@@ -23,19 +23,94 @@ module RSpec
23
23
  # used.
24
24
  def method_missing(*)
25
25
  return_val = super
26
- return return_val unless return_val.respond_to?(:description)
27
- AliasedMatcher.new(return_val, @description_block)
26
+ return return_val unless RSpec::Matchers.is_a_matcher?(return_val)
27
+ self.class.new(return_val, @description_block)
28
28
  end
29
29
 
30
30
  # Provides the description of the aliased matcher. Aliased matchers
31
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.
32
+ # for the description and failure messages. The description is different
33
+ # to reflect the aliased name.
34
34
  #
35
35
  # @api private
36
36
  def description
37
37
  @description_block.call(super)
38
38
  end
39
+
40
+ # Provides the failure_message of the aliased matcher. Aliased matchers
41
+ # are designed to behave identically to the original matcher except
42
+ # for the description and failure messages. The failure_message is different
43
+ # to reflect the aliased name.
44
+ #
45
+ # @api private
46
+ def failure_message
47
+ @description_block.call(super)
48
+ end
49
+
50
+ # Provides the failure_message_when_negated of the aliased matcher. Aliased matchers
51
+ # are designed to behave identically to the original matcher except
52
+ # for the description and failure messages. The failure_message_when_negated is different
53
+ # to reflect the aliased name.
54
+ #
55
+ # @api private
56
+ def failure_message_when_negated
57
+ @description_block.call(super)
58
+ end
59
+ end
60
+
61
+ # Decorator used for matchers that have special implementations of
62
+ # operators like `==` and `===`.
63
+ # @private
64
+ class AliasedMatcherWithOperatorSupport < AliasedMatcher
65
+ # We undef these so that they get delegated via `method_missing`.
66
+ undef ==
67
+ undef ===
68
+ end
69
+
70
+ # @private
71
+ class AliasedNegatedMatcher < AliasedMatcher
72
+ def matches?(*args, &block)
73
+ if @base_matcher.respond_to?(:does_not_match?)
74
+ @base_matcher.does_not_match?(*args, &block)
75
+ else
76
+ !super
77
+ end
78
+ end
79
+
80
+ def does_not_match?(*args, &block)
81
+ @base_matcher.matches?(*args, &block)
82
+ end
83
+
84
+ def failure_message
85
+ optimal_failure_message(__method__, :failure_message_when_negated)
86
+ end
87
+
88
+ def failure_message_when_negated
89
+ optimal_failure_message(__method__, :failure_message)
90
+ end
91
+
92
+ private
93
+
94
+ DefaultFailureMessages = BuiltIn::BaseMatcher::DefaultFailureMessages
95
+
96
+ # For a matcher that uses the default failure messages, we prefer to
97
+ # use the override provided by the `description_block`, because it
98
+ # includes the phrasing that the user has expressed a preference for
99
+ # by going through the effort of defining a negated matcher.
100
+ #
101
+ # However, if the override didn't actually change anything, then we
102
+ # should return the opposite failure message instead -- the overridden
103
+ # message is going to be confusing if we return it as-is, as it represents
104
+ # the non-negated failure message for a negated match (or vice versa).
105
+ def optimal_failure_message(same, inverted)
106
+ if DefaultFailureMessages.has_default_failure_messages?(@base_matcher)
107
+ base_message = @base_matcher.__send__(same)
108
+ overridden = @description_block.call(base_message)
109
+ return overridden if overridden != base_message
110
+ end
111
+
112
+ @base_matcher.__send__(inverted)
113
+ end
39
114
  end
40
115
  end
41
116
  end
@@ -21,6 +21,10 @@ module RSpec
21
21
  # @api private
22
22
  # @return [String]
23
23
  def failure_message
24
+ unless iterable?
25
+ return "#{improve_hash_formatting(super)}, but was not iterable"
26
+ end
27
+
24
28
  all_messages = [improve_hash_formatting(super)]
25
29
  failed_objects.each do |index, matcher_failure_message|
26
30
  all_messages << failure_message_for_item(index, matcher_failure_message)
@@ -37,6 +41,8 @@ module RSpec
37
41
  private
38
42
 
39
43
  def match(_expected, _actual)
44
+ return false unless iterable?
45
+
40
46
  index_failed_objects
41
47
  failed_objects.empty?
42
48
  end
@@ -67,8 +73,13 @@ module RSpec
67
73
 
68
74
  def initialize_copy(other)
69
75
  @matcher = @matcher.clone
76
+ @failed_objects = @failed_objects.clone
70
77
  super
71
78
  end
79
+
80
+ def iterable?
81
+ @actual.respond_to?(:each_with_index)
82
+ end
72
83
  end
73
84
  end
74
85
  end
@@ -8,11 +8,10 @@ module RSpec
8
8
  #
9
9
  # ### Warning:
10
10
  #
11
- # This class is for internal use, and subject to change without notice. We
12
- # strongly recommend that you do not base your custom matchers on this
11
+ # This class is for internal use, and subject to change without notice.
12
+ # We strongly recommend that you do not base your custom matchers on this
13
13
  # class. If/when this changes, we will announce it and remove this warning.
14
14
  class BaseMatcher
15
- include RSpec::Matchers::Pretty
16
15
  include RSpec::Matchers::Composable
17
16
 
18
17
  # @api private
@@ -23,6 +22,9 @@ module RSpec
23
22
  # @private
24
23
  attr_reader :actual, :expected, :rescued_exception
25
24
 
25
+ # @private
26
+ attr_writer :matcher_name
27
+
26
28
  def initialize(expected=UNDEFINED)
27
29
  @expected = expected unless UNDEFINED.equal?(expected)
28
30
  end
@@ -53,31 +55,12 @@ module RSpec
53
55
  end
54
56
 
55
57
  # @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]
60
- def failure_message
61
- assert_ivars :@actual
62
- "expected #{@actual.inspect} to #{description}"
63
- end
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]
70
- def failure_message_when_negated
71
- assert_ivars :@actual
72
- "expected #{@actual.inspect} not to #{description}"
73
- end
74
-
75
- # @api private
76
- # Generates a "pretty" description using the logic in {Pretty}.
58
+ # Generates a description using {EnglishPhrasing}.
77
59
  # @return [String]
78
60
  def description
79
- return name_to_sentence unless defined?(@expected)
80
- "#{name_to_sentence}#{to_sentence @expected}"
61
+ desc = EnglishPhrasing.split_words(self.class.matcher_name)
62
+ desc << EnglishPhrasing.list(@expected) if defined?(@expected)
63
+ desc
81
64
  end
82
65
 
83
66
  # @api private
@@ -95,20 +78,120 @@ module RSpec
95
78
  false
96
79
  end
97
80
 
81
+ # @private
82
+ def supports_value_expectations?
83
+ true
84
+ end
85
+
86
+ # @api private
87
+ def expects_call_stack_jump?
88
+ false
89
+ end
90
+
91
+ # @private
92
+ def expected_formatted
93
+ RSpec::Support::ObjectFormatter.format(@expected)
94
+ end
95
+
96
+ # @private
97
+ def actual_formatted
98
+ RSpec::Support::ObjectFormatter.format(@actual)
99
+ end
100
+
101
+ # @private
102
+ def self.matcher_name
103
+ @matcher_name ||= underscore(name.split('::').last)
104
+ end
105
+
106
+ # @private
107
+ def matcher_name
108
+ if defined?(@matcher_name)
109
+ @matcher_name
110
+ else
111
+ self.class.matcher_name
112
+ end
113
+ end
114
+
115
+ # @private
116
+ # Borrowed from ActiveSupport.
117
+ def self.underscore(camel_cased_word)
118
+ word = camel_cased_word.to_s.dup
119
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
120
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
121
+ word.tr!('-', '_')
122
+ word.downcase!
123
+ word
124
+ end
125
+ private_class_method :underscore
126
+
98
127
  private
99
128
 
100
129
  def assert_ivars(*expected_ivars)
101
130
  return unless (expected_ivars - present_ivars).any?
102
- raise "#{self.class.name} needs to supply#{to_sentence expected_ivars}"
131
+ ivar_list = EnglishPhrasing.list(expected_ivars)
132
+ raise "#{self.class.name} needs to supply#{ivar_list}"
103
133
  end
104
134
 
105
135
  if RUBY_VERSION.to_f < 1.9
136
+ # :nocov:
106
137
  def present_ivars
107
- instance_variables.map { |v| v.to_sym }
138
+ instance_variables.map(&:to_sym)
108
139
  end
140
+ # :nocov:
109
141
  else
110
142
  alias present_ivars instance_variables
111
143
  end
144
+
145
+ # @private
146
+ module HashFormatting
147
+ # `{ :a => 5, :b => 2 }.inspect` produces:
148
+ #
149
+ # {:a=>5, :b=>2}
150
+ #
151
+ # ...but it looks much better as:
152
+ #
153
+ # {:a => 5, :b => 2}
154
+ #
155
+ # This is idempotent and safe to run on a string multiple times.
156
+ def improve_hash_formatting(inspect_string)
157
+ inspect_string.gsub(/(\S)=>(\S)/, '\1 => \2')
158
+ end
159
+ module_function :improve_hash_formatting
160
+ end
161
+
162
+ include HashFormatting
163
+
164
+ # @api private
165
+ # Provides default implementations of failure messages, based on the `description`.
166
+ module DefaultFailureMessages
167
+ # @api private
168
+ # Provides a good generic failure message. Based on `description`.
169
+ # When subclassing, if you are not satisfied with this failure message
170
+ # you often only need to override `description`.
171
+ # @return [String]
172
+ def failure_message
173
+ "expected #{description_of @actual} to #{description}".dup
174
+ end
175
+
176
+ # @api private
177
+ # Provides a good generic negative failure message. Based on `description`.
178
+ # When subclassing, if you are not satisfied with this failure message
179
+ # you often only need to override `description`.
180
+ # @return [String]
181
+ def failure_message_when_negated
182
+ "expected #{description_of @actual} not to #{description}".dup
183
+ end
184
+
185
+ # @private
186
+ def self.has_default_failure_messages?(matcher)
187
+ matcher.method(:failure_message).owner == self &&
188
+ matcher.method(:failure_message_when_negated).owner == self
189
+ rescue NameError
190
+ false
191
+ end
192
+ end
193
+
194
+ include DefaultFailureMessages
112
195
  end
113
196
  end
114
197
  end
@@ -8,13 +8,13 @@ module RSpec
8
8
  # @api private
9
9
  # @return [String]
10
10
  def failure_message
11
- "expected: truthy value\n got: #{actual.inspect}"
11
+ "expected: truthy value\n got: #{actual_formatted}"
12
12
  end
13
13
 
14
14
  # @api private
15
15
  # @return [String]
16
16
  def failure_message_when_negated
17
- "expected: falsey value\n got: #{actual.inspect}"
17
+ "expected: falsey value\n got: #{actual_formatted}"
18
18
  end
19
19
 
20
20
  private
@@ -31,13 +31,13 @@ module RSpec
31
31
  # @api private
32
32
  # @return [String]
33
33
  def failure_message
34
- "expected: falsey value\n got: #{actual.inspect}"
34
+ "expected: falsey value\n got: #{actual_formatted}"
35
35
  end
36
36
 
37
37
  # @api private
38
38
  # @return [String]
39
39
  def failure_message_when_negated
40
- "expected: truthy value\n got: #{actual.inspect}"
40
+ "expected: truthy value\n got: #{actual_formatted}"
41
41
  end
42
42
 
43
43
  private
@@ -54,7 +54,7 @@ module RSpec
54
54
  # @api private
55
55
  # @return [String]
56
56
  def failure_message
57
- "expected: nil\n got: #{actual.inspect}"
57
+ "expected: nil\n got: #{actual_formatted}"
58
58
  end
59
59
 
60
60
  # @api private
@@ -83,15 +83,15 @@ module RSpec
83
83
  end
84
84
 
85
85
  def inspected_args
86
- @args.map { |a| a.inspect }
86
+ @args.map { |a| RSpec::Support::ObjectFormatter.format(a) }
87
87
  end
88
88
 
89
89
  def expected_to_sentence
90
- split_words(@expected)
90
+ EnglishPhrasing.split_words(@expected)
91
91
  end
92
92
 
93
93
  def args_to_sentence
94
- to_sentence(@args)
94
+ EnglishPhrasing.list(@args)
95
95
  end
96
96
  end
97
97
 
@@ -108,13 +108,13 @@ module RSpec
108
108
  # @api private
109
109
  # @return [String]
110
110
  def failure_message
111
- "expected #{@actual.inspect} to evaluate to true"
111
+ "expected #{actual_formatted} to evaluate to true"
112
112
  end
113
113
 
114
114
  # @api private
115
115
  # @return [String]
116
116
  def failure_message_when_negated
117
- "expected #{@actual.inspect} to evaluate to false"
117
+ "expected #{actual_formatted} to evaluate to false"
118
118
  end
119
119
 
120
120
  [:==, :<, :<=, :>=, :>, :===, :=~].each do |operator|
@@ -137,25 +137,35 @@ module RSpec
137
137
  include BeHelpers
138
138
 
139
139
  def initialize(operand, operator)
140
- @expected, @operator = operand, operator
140
+ @expected = operand
141
+ @operator = operator
141
142
  @args = []
142
143
  end
143
144
 
144
145
  def matches?(actual)
145
- @actual = actual
146
- @actual.__send__ @operator, @expected
146
+ perform_match(actual)
147
+ rescue ArgumentError, NoMethodError
148
+ false
149
+ end
150
+
151
+ def does_not_match?(actual)
152
+ !perform_match(actual)
153
+ rescue ArgumentError, NoMethodError
154
+ false
147
155
  end
148
156
 
149
157
  # @api private
150
158
  # @return [String]
151
159
  def failure_message
152
- "expected: #{@operator} #{@expected.inspect}\n got: #{@operator.to_s.gsub(/./, ' ')} #{@actual.inspect}"
160
+ "expected: #{@operator} #{expected_formatted}\n" \
161
+ " got: #{@operator.to_s.gsub(/./, ' ')} #{actual_formatted}"
153
162
  end
154
163
 
155
164
  # @api private
156
165
  # @return [String]
157
166
  def failure_message_when_negated
158
- message = "`expect(#{@actual.inspect}).not_to be #{@operator} #{@expected.inspect}`"
167
+ message = "`expect(#{actual_formatted}).not_to " \
168
+ "be #{@operator} #{expected_formatted}`"
159
169
  if [:<, :>, :<=, :>=].include?(@operator)
160
170
  message + " not only FAILED, it is a bit confusing."
161
171
  else
@@ -168,108 +178,12 @@ module RSpec
168
178
  def description
169
179
  "be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
170
180
  end
171
- end
172
-
173
- # @api private
174
- # Provides the implementation of `be_<predicate>`.
175
- # Not intended to be instantiated directly.
176
- class BePredicate < BaseMatcher
177
- include BeHelpers
178
-
179
- def initialize(*args, &block)
180
- @expected = parse_expected(args.shift)
181
- @args = args
182
- @block = block
183
- end
184
-
185
- def matches?(actual, &block)
186
- @actual = actual
187
- @block ||= block
188
- predicate_accessible? && predicate_matches?
189
- end
190
-
191
- def does_not_match?(actual, &block)
192
- @actual = actual
193
- @block ||= block
194
- predicate_accessible? && !predicate_matches?
195
- end
196
-
197
- # @api private
198
- # @return [String]
199
- def failure_message
200
- failure_message_expecting(true)
201
- end
202
-
203
- # @api private
204
- # @return [String]
205
- def failure_message_when_negated
206
- failure_message_expecting(false)
207
- end
208
-
209
- # @api private
210
- # @return [String]
211
- def description
212
- "#{prefix_to_sentence}#{expected_to_sentence}#{args_to_sentence}"
213
- end
214
181
 
215
182
  private
216
183
 
217
- def predicate_accessible?
218
- !private_predicate? && predicate_exists?
219
- end
220
-
221
- # support 1.8.7, evaluate once at load time for performance
222
- if String === methods.first
223
- def private_predicate?
224
- @actual.private_methods.include? predicate.to_s
225
- end
226
- else
227
- def private_predicate?
228
- @actual.private_methods.include? predicate
229
- end
230
- end
231
-
232
- def predicate_exists?
233
- actual.respond_to?(predicate) || actual.respond_to?(present_tense_predicate)
234
- end
235
-
236
- def predicate_matches?
237
- method_name = actual.respond_to?(predicate) ? predicate : present_tense_predicate
238
- @predicate_matches = actual.__send__(method_name, *@args, &@block)
239
- end
240
-
241
- def predicate
242
- :"#{@expected}?"
243
- end
244
-
245
- def present_tense_predicate
246
- :"#{@expected}s?"
247
- end
248
-
249
- def parse_expected(expected)
250
- @prefix, expected = prefix_and_expected(expected)
251
- expected
252
- end
253
-
254
- def prefix_and_expected(symbol)
255
- Matchers::BE_PREDICATE_REGEX.match(symbol.to_s).captures.compact
256
- end
257
-
258
- def prefix_to_sentence
259
- split_words(@prefix)
260
- end
261
-
262
- def failure_message_expecting(value)
263
- validity_message ||
264
- "expected `#{@actual.inspect}.#{predicate}#{args_to_s}` to return #{value}, got #{@predicate_matches.inspect}"
265
- end
266
-
267
- def validity_message
268
- if private_predicate?
269
- "expected #{@actual} to respond to `#{predicate}` but `#{predicate}` is a private method"
270
- elsif !predicate_exists?
271
- "expected #{@actual} to respond to `#{predicate}`"
272
- end
184
+ def perform_match(actual)
185
+ @actual = actual
186
+ @actual.__send__ @operator, @expected
273
187
  end
274
188
  end
275
189
  end
@@ -55,7 +55,7 @@ module RSpec
55
55
  # @api private
56
56
  # @return [String]
57
57
  def description
58
- "be between #{@min.inspect} and #{@max.inspect} (#{@mode})"
58
+ "be between #{description_of @min} and #{description_of @max} (#{@mode})"
59
59
  end
60
60
 
61
61
  private
@@ -14,7 +14,11 @@ module RSpec
14
14
  private
15
15
 
16
16
  def match(expected, actual)
17
- actual.instance_of? expected
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."
18
22
  end
19
23
  end
20
24
  end
@@ -8,7 +8,11 @@ module RSpec
8
8
  private
9
9
 
10
10
  def match(expected, actual)
11
- actual.kind_of? expected
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."
12
16
  end
13
17
  end
14
18
  end
@@ -4,9 +4,7 @@ module RSpec
4
4
  # @api private
5
5
  # Provides the implementation for `be_within`.
6
6
  # Not intended to be instantiated directly.
7
- class BeWithin
8
- include Composable
9
-
7
+ class BeWithin < BaseMatcher
10
8
  def initialize(delta)
11
9
  @delta = delta
12
10
  end
@@ -25,7 +23,7 @@ module RSpec
25
23
  # a percent comparison.
26
24
  def percent_of(expected)
27
25
  @expected = expected
28
- @tolerance = @delta * @expected.abs / 100.0
26
+ @tolerance = @expected.abs * @delta / 100.0
29
27
  @unit = '%'
30
28
  self
31
29
  end
@@ -40,24 +38,19 @@ module RSpec
40
38
  # @api private
41
39
  # @return [String]
42
40
  def failure_message
43
- "expected #{@actual.inspect} to #{description}#{not_numeric_clause}"
41
+ "expected #{actual_formatted} to #{description}#{not_numeric_clause}"
44
42
  end
45
43
 
46
44
  # @api private
47
45
  # @return [String]
48
46
  def failure_message_when_negated
49
- "expected #{@actual.inspect} not to #{description}"
47
+ "expected #{actual_formatted} not to #{description}"
50
48
  end
51
49
 
52
50
  # @api private
53
51
  # @return [String]
54
52
  def description
55
- "be within #{@delta}#{@unit} of #{@expected}"
56
- end
57
-
58
- # @private
59
- def supports_block_expectations?
60
- false
53
+ "be within #{@delta}#{@unit} of #{expected_formatted}"
61
54
  end
62
55
 
63
56
  private