rspec-expectations 3.0.4 → 3.12.3

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.
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