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.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -2
  4. data/.yardopts +0 -1
  5. data/Changelog.md +115 -35
  6. data/README.md +2 -2
  7. data/lib/rspec/expectations.rb +13 -8
  8. data/lib/rspec/{matchers → expectations}/configuration.rb +38 -13
  9. data/lib/rspec/expectations/expectation_target.rb +72 -8
  10. data/lib/rspec/expectations/fail_with.rb +10 -52
  11. data/lib/rspec/expectations/handler.rb +9 -11
  12. data/lib/rspec/expectations/syntax.rb +37 -35
  13. data/lib/rspec/expectations/version.rb +1 -1
  14. data/lib/rspec/matchers.rb +60 -9
  15. data/lib/rspec/matchers/aliased_matcher.rb +6 -0
  16. data/lib/rspec/matchers/built_in.rb +9 -1
  17. data/lib/rspec/matchers/built_in/all.rb +78 -0
  18. data/lib/rspec/matchers/built_in/base_matcher.rb +39 -1
  19. data/lib/rspec/matchers/built_in/be.rb +117 -42
  20. data/lib/rspec/matchers/built_in/be_between.rb +22 -0
  21. data/lib/rspec/matchers/built_in/be_instance_of.rb +11 -3
  22. data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -0
  23. data/lib/rspec/matchers/built_in/be_within.rb +26 -6
  24. data/lib/rspec/matchers/built_in/change.rb +89 -13
  25. data/lib/rspec/matchers/built_in/compound.rb +19 -3
  26. data/lib/rspec/matchers/built_in/contain_exactly.rb +17 -6
  27. data/lib/rspec/matchers/built_in/cover.rb +3 -0
  28. data/lib/rspec/matchers/built_in/eq.rb +20 -5
  29. data/lib/rspec/matchers/built_in/eql.rb +15 -3
  30. data/lib/rspec/matchers/built_in/equal.rb +23 -6
  31. data/lib/rspec/matchers/built_in/exist.rb +74 -10
  32. data/lib/rspec/matchers/built_in/has.rb +58 -3
  33. data/lib/rspec/matchers/built_in/include.rb +16 -1
  34. data/lib/rspec/matchers/built_in/match.rb +14 -4
  35. data/lib/rspec/matchers/built_in/operators.rb +16 -0
  36. data/lib/rspec/matchers/built_in/output.rb +47 -5
  37. data/lib/rspec/matchers/built_in/raise_error.rb +40 -23
  38. data/lib/rspec/matchers/built_in/respond_to.rb +37 -16
  39. data/lib/rspec/matchers/built_in/satisfy.rb +15 -0
  40. data/lib/rspec/matchers/built_in/start_and_end_with.rb +29 -14
  41. data/lib/rspec/matchers/built_in/throw_symbol.rb +32 -3
  42. data/lib/rspec/matchers/built_in/yield.rb +148 -44
  43. data/lib/rspec/matchers/composable.rb +48 -7
  44. data/lib/rspec/matchers/dsl.rb +45 -17
  45. data/lib/rspec/matchers/generated_descriptions.rb +7 -0
  46. data/lib/rspec/matchers/matcher_delegator.rb +6 -2
  47. data/lib/rspec/matchers/pretty.rb +15 -19
  48. metadata +33 -236
  49. metadata.gz.sig +0 -0
  50. data/features/README.md +0 -48
  51. data/features/Upgrade.md +0 -53
  52. data/features/built_in_matchers/README.md +0 -96
  53. data/features/built_in_matchers/be.feature +0 -175
  54. data/features/built_in_matchers/be_within.feature +0 -48
  55. data/features/built_in_matchers/comparisons.feature +0 -97
  56. data/features/built_in_matchers/contain_exactly.feature +0 -46
  57. data/features/built_in_matchers/cover.feature +0 -47
  58. data/features/built_in_matchers/end_with.feature +0 -48
  59. data/features/built_in_matchers/equality.feature +0 -136
  60. data/features/built_in_matchers/exist.feature +0 -45
  61. data/features/built_in_matchers/expect_change.feature +0 -59
  62. data/features/built_in_matchers/expect_error.feature +0 -144
  63. data/features/built_in_matchers/include.feature +0 -126
  64. data/features/built_in_matchers/match.feature +0 -51
  65. data/features/built_in_matchers/output.feature +0 -70
  66. data/features/built_in_matchers/predicates.feature +0 -161
  67. data/features/built_in_matchers/respond_to.feature +0 -84
  68. data/features/built_in_matchers/satisfy.feature +0 -33
  69. data/features/built_in_matchers/start_with.feature +0 -48
  70. data/features/built_in_matchers/throw_symbol.feature +0 -91
  71. data/features/built_in_matchers/types.feature +0 -116
  72. data/features/built_in_matchers/yield.feature +0 -161
  73. data/features/composing_matchers.feature +0 -250
  74. data/features/compound_expectations.feature +0 -45
  75. data/features/custom_matchers/access_running_example.feature +0 -53
  76. data/features/custom_matchers/define_diffable_matcher.feature +0 -27
  77. data/features/custom_matchers/define_matcher.feature +0 -340
  78. data/features/custom_matchers/define_matcher_outside_rspec.feature +0 -34
  79. data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
  80. data/features/customized_message.feature +0 -39
  81. data/features/diffing.feature +0 -85
  82. data/features/implicit_docstrings.feature +0 -52
  83. data/features/step_definitions/additional_cli_steps.rb +0 -22
  84. data/features/support/env.rb +0 -21
  85. data/features/support/rubinius.rb +0 -6
  86. data/features/syntax_configuration.feature +0 -71
  87. data/features/test_frameworks/minitest.feature +0 -44
  88. data/lib/rspec-expectations.rb +0 -1
  89. data/lib/rspec/expectations/diff_presenter.rb +0 -141
  90. data/lib/rspec/expectations/differ.rb +0 -44
  91. data/lib/rspec/expectations/encoded_string.rb +0 -56
  92. data/spec/rspec/expectations/diff_presenter_spec.rb +0 -249
  93. data/spec/rspec/expectations/encoded_string_spec.rb +0 -74
  94. data/spec/rspec/expectations/expectation_target_spec.rb +0 -82
  95. data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
  96. data/spec/rspec/expectations/fail_with_spec.rb +0 -114
  97. data/spec/rspec/expectations/handler_spec.rb +0 -205
  98. data/spec/rspec/expectations/minitest_integration_spec.rb +0 -27
  99. data/spec/rspec/expectations/syntax_spec.rb +0 -89
  100. data/spec/rspec/expectations_spec.rb +0 -12
  101. data/spec/rspec/matchers/aliased_matcher_spec.rb +0 -48
  102. data/spec/rspec/matchers/aliases_spec.rb +0 -449
  103. data/spec/rspec/matchers/built_in/base_matcher_spec.rb +0 -83
  104. data/spec/rspec/matchers/built_in/be_between_spec.rb +0 -159
  105. data/spec/rspec/matchers/built_in/be_instance_of_spec.rb +0 -63
  106. data/spec/rspec/matchers/built_in/be_kind_of_spec.rb +0 -41
  107. data/spec/rspec/matchers/built_in/be_spec.rb +0 -592
  108. data/spec/rspec/matchers/built_in/be_within_spec.rb +0 -141
  109. data/spec/rspec/matchers/built_in/change_spec.rb +0 -808
  110. data/spec/rspec/matchers/built_in/compound_spec.rb +0 -292
  111. data/spec/rspec/matchers/built_in/contain_exactly_spec.rb +0 -441
  112. data/spec/rspec/matchers/built_in/cover_spec.rb +0 -69
  113. data/spec/rspec/matchers/built_in/eq_spec.rb +0 -156
  114. data/spec/rspec/matchers/built_in/eql_spec.rb +0 -41
  115. data/spec/rspec/matchers/built_in/equal_spec.rb +0 -106
  116. data/spec/rspec/matchers/built_in/exist_spec.rb +0 -124
  117. data/spec/rspec/matchers/built_in/has_spec.rb +0 -161
  118. data/spec/rspec/matchers/built_in/include_spec.rb +0 -540
  119. data/spec/rspec/matchers/built_in/match_spec.rb +0 -102
  120. data/spec/rspec/matchers/built_in/operators_spec.rb +0 -252
  121. data/spec/rspec/matchers/built_in/output_spec.rb +0 -165
  122. data/spec/rspec/matchers/built_in/raise_error_spec.rb +0 -461
  123. data/spec/rspec/matchers/built_in/respond_to_spec.rb +0 -292
  124. data/spec/rspec/matchers/built_in/satisfy_spec.rb +0 -44
  125. data/spec/rspec/matchers/built_in/start_and_end_with_spec.rb +0 -253
  126. data/spec/rspec/matchers/built_in/throw_symbol_spec.rb +0 -135
  127. data/spec/rspec/matchers/built_in/yield_spec.rb +0 -627
  128. data/spec/rspec/matchers/configuration_spec.rb +0 -213
  129. data/spec/rspec/matchers/description_generation_spec.rb +0 -191
  130. data/spec/rspec/matchers/dsl_spec.rb +0 -895
  131. data/spec/rspec/matchers/legacy_spec.rb +0 -101
  132. data/spec/rspec/matchers_spec.rb +0 -74
  133. data/spec/spec_helper.rb +0 -85
  134. data/spec/support/matchers.rb +0 -22
  135. 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 #{_pretty_print(surface_descriptions_in expected)}"
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 elements which is a matcher that matches a superset of actual items
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,6 +1,9 @@
1
1
  module RSpec
2
2
  module Matchers
3
3
  module BuiltIn
4
+ # @api private
5
+ # Provides the implementation for `cover`.
6
+ # Not intended to be instantiated directly.
4
7
  class Cover < BaseMatcher
5
8
  def initialize(*expected)
6
9
  @expected = expected
@@ -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
- def diffable?; true; end
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
- private
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 #{inspect_object(actual)}\n"
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
- predicates = [:exist?, :exists?].select { |p| @actual.respond_to?(p) }
12
- existence_values = predicates.map { |p| @actual.__send__(p, *@expected) }
13
- uniq_truthy_values = existence_values.map { |v| !!v }.uniq
14
-
15
- case uniq_truthy_values.size
16
- when 0; raise NoMethodError.new("#{@actual.inspect} does not respond to either #exist? or #exists?")
17
- when 1; existence_values.first
18
- else raise "#exist? and #exists? returned different values:\n\n" +
19
- " exist?: #{existence_values.first}\n" +
20
- "exists?: #{existence_values.last}"
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.__send__(predicate, *@args, &(@block || block))
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
- private
51
+ private
37
52
 
38
53
  def perform_match(predicate, hash_subset_predicate)
39
54
  expected.__send__(predicate) do |expected_item|