super_diff 0.5.3 → 0.8.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.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +46 -20
  3. data/lib/super_diff.rb +46 -7
  4. data/lib/super_diff/active_record.rb +7 -7
  5. data/lib/super_diff/active_record/differs/active_record_relation.rb +3 -13
  6. data/lib/super_diff/active_record/object_inspection.rb +2 -6
  7. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders.rb +16 -0
  8. data/lib/super_diff/active_record/object_inspection/{inspectors → inspection_tree_builders}/active_record_model.rb +19 -20
  9. data/lib/super_diff/active_record/object_inspection/{inspectors → inspection_tree_builders}/active_record_relation.rb +9 -8
  10. data/lib/super_diff/active_record/operation_tree_flatteners.rb +10 -0
  11. data/lib/super_diff/active_record/operation_tree_flatteners/active_record_relation.rb +17 -0
  12. data/lib/super_diff/active_record/operation_trees/active_record_relation.rb +8 -7
  13. data/lib/super_diff/active_support.rb +8 -8
  14. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +3 -13
  15. data/lib/super_diff/active_support/object_inspection.rb +2 -6
  16. data/lib/super_diff/active_support/object_inspection/{inspectors.rb → inspection_tree_builders.rb} +2 -2
  17. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders/hash_with_indifferent_access.rb +37 -0
  18. data/lib/super_diff/active_support/operation_tree_builders/hash_with_indifferent_access.rb +17 -0
  19. data/lib/super_diff/active_support/operation_tree_flatteners.rb +10 -0
  20. data/lib/super_diff/active_support/operation_tree_flatteners/hash_with_indifferent_access.rb +17 -0
  21. data/lib/super_diff/active_support/operation_trees/hash_with_indifferent_access.rb +4 -7
  22. data/lib/super_diff/colorized_document_extensions.rb +9 -6
  23. data/lib/super_diff/configuration.rb +102 -19
  24. data/lib/super_diff/csi.rb +1 -1
  25. data/lib/super_diff/csi/four_bit_color.rb +0 -2
  26. data/lib/super_diff/diff_formatters/collection.rb +2 -2
  27. data/lib/super_diff/diff_formatters/multiline_string.rb +4 -4
  28. data/lib/super_diff/differs/array.rb +1 -1
  29. data/lib/super_diff/differs/base.rb +3 -21
  30. data/lib/super_diff/differs/custom_object.rb +1 -1
  31. data/lib/super_diff/differs/default_object.rb +1 -1
  32. data/lib/super_diff/differs/hash.rb +1 -1
  33. data/lib/super_diff/differs/main.rb +1 -7
  34. data/lib/super_diff/differs/multiline_string.rb +1 -1
  35. data/lib/super_diff/differs/time_like.rb +1 -1
  36. data/lib/super_diff/equality_matchers/array.rb +4 -4
  37. data/lib/super_diff/equality_matchers/default.rb +4 -4
  38. data/lib/super_diff/equality_matchers/hash.rb +4 -4
  39. data/lib/super_diff/equality_matchers/multiline_string.rb +4 -4
  40. data/lib/super_diff/equality_matchers/primitive.rb +6 -9
  41. data/lib/super_diff/equality_matchers/singleline_string.rb +4 -4
  42. data/lib/super_diff/gem_version.rb +45 -0
  43. data/lib/super_diff/helpers.rb +52 -2
  44. data/lib/super_diff/line.rb +83 -0
  45. data/lib/super_diff/object_inspection.rb +12 -9
  46. data/lib/super_diff/object_inspection/inspection_tree.rb +183 -81
  47. data/lib/super_diff/object_inspection/inspection_tree_builders.rb +44 -0
  48. data/lib/super_diff/object_inspection/inspection_tree_builders/array.rb +38 -0
  49. data/lib/super_diff/object_inspection/inspection_tree_builders/base.rb +27 -0
  50. data/lib/super_diff/object_inspection/inspection_tree_builders/custom_object.rb +37 -0
  51. data/lib/super_diff/object_inspection/inspection_tree_builders/default_object.rb +63 -0
  52. data/lib/super_diff/object_inspection/{inspectors → inspection_tree_builders}/defaults.rb +1 -2
  53. data/lib/super_diff/object_inspection/inspection_tree_builders/hash.rb +46 -0
  54. data/lib/super_diff/object_inspection/{inspectors → inspection_tree_builders}/main.rb +5 -10
  55. data/lib/super_diff/object_inspection/inspection_tree_builders/primitive.rb +21 -0
  56. data/lib/super_diff/object_inspection/inspection_tree_builders/time_like.rb +64 -0
  57. data/lib/super_diff/object_inspection/nodes.rb +33 -32
  58. data/lib/super_diff/object_inspection/nodes/as_lines_when_rendering_to_lines.rb +97 -0
  59. data/lib/super_diff/object_inspection/nodes/as_prefix_when_rendering_to_lines.rb +27 -0
  60. data/lib/super_diff/object_inspection/nodes/as_prelude_when_rendering_to_lines.rb +27 -0
  61. data/lib/super_diff/object_inspection/nodes/as_single_line.rb +33 -0
  62. data/lib/super_diff/object_inspection/nodes/base.rb +55 -20
  63. data/lib/super_diff/object_inspection/nodes/inspection.rb +47 -7
  64. data/lib/super_diff/object_inspection/nodes/nesting.rb +16 -5
  65. data/lib/super_diff/object_inspection/nodes/only_when.rb +54 -0
  66. data/lib/super_diff/object_inspection/nodes/text.rb +16 -2
  67. data/lib/super_diff/object_inspection/nodes/when_empty.rb +21 -6
  68. data/lib/super_diff/object_inspection/nodes/when_non_empty.rb +20 -5
  69. data/lib/super_diff/object_inspection/nodes/when_rendering_to_lines.rb +27 -0
  70. data/lib/super_diff/object_inspection/nodes/when_rendering_to_string.rb +27 -0
  71. data/lib/super_diff/object_inspection/prefix_for_next_node.rb +6 -0
  72. data/lib/super_diff/object_inspection/prelude_for_next_node.rb +6 -0
  73. data/lib/super_diff/operation_tree_builders/array.rb +7 -10
  74. data/lib/super_diff/operation_tree_builders/base.rb +6 -6
  75. data/lib/super_diff/operation_tree_builders/custom_object.rb +5 -2
  76. data/lib/super_diff/operation_tree_builders/default_object.rb +1 -1
  77. data/lib/super_diff/operation_tree_builders/defaults.rb +1 -1
  78. data/lib/super_diff/operation_tree_builders/hash.rb +1 -8
  79. data/lib/super_diff/operation_tree_builders/multiline_string.rb +2 -6
  80. data/lib/super_diff/operation_tree_builders/time_like.rb +2 -2
  81. data/lib/super_diff/operation_tree_flatteners.rb +20 -0
  82. data/lib/super_diff/operation_tree_flatteners/array.rb +15 -0
  83. data/lib/super_diff/operation_tree_flatteners/base.rb +54 -0
  84. data/lib/super_diff/operation_tree_flatteners/collection.rb +139 -0
  85. data/lib/super_diff/operation_tree_flatteners/custom_object.rb +28 -0
  86. data/lib/super_diff/operation_tree_flatteners/default_object.rb +32 -0
  87. data/lib/super_diff/operation_tree_flatteners/hash.rb +41 -0
  88. data/lib/super_diff/operation_tree_flatteners/multiline_string.rb +17 -0
  89. data/lib/super_diff/operation_trees/array.rb +4 -7
  90. data/lib/super_diff/operation_trees/base.rb +39 -16
  91. data/lib/super_diff/operation_trees/custom_object.rb +4 -8
  92. data/lib/super_diff/operation_trees/default_object.rb +28 -13
  93. data/lib/super_diff/operation_trees/hash.rb +4 -7
  94. data/lib/super_diff/operation_trees/main.rb +1 -1
  95. data/lib/super_diff/operation_trees/multiline_string.rb +4 -7
  96. data/lib/super_diff/operations/binary_operation.rb +1 -6
  97. data/lib/super_diff/operations/unary_operation.rb +2 -30
  98. data/lib/super_diff/recursion_guard.rb +3 -3
  99. data/lib/super_diff/rspec.rb +41 -13
  100. data/lib/super_diff/rspec/differs/collection_including.rb +4 -2
  101. data/lib/super_diff/rspec/differs/hash_including.rb +4 -2
  102. data/lib/super_diff/rspec/matcher_text_builders/base.rb +7 -7
  103. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +6 -6
  104. data/lib/super_diff/rspec/matcher_text_builders/contain_exactly.rb +1 -1
  105. data/lib/super_diff/rspec/matcher_text_builders/have_predicate.rb +4 -4
  106. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +1 -1
  107. data/lib/super_diff/rspec/matcher_text_builders/respond_to.rb +5 -5
  108. data/lib/super_diff/rspec/monkey_patches.rb +353 -306
  109. data/lib/super_diff/rspec/object_inspection.rb +4 -1
  110. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders.rb +44 -0
  111. data/lib/super_diff/rspec/object_inspection/{inspectors → inspection_tree_builders}/collection_containing_exactly.rb +9 -8
  112. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/collection_including.rb +34 -0
  113. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/double.rb +103 -0
  114. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/hash_including.rb +36 -0
  115. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/instance_of.rb +26 -0
  116. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/kind_of.rb +26 -0
  117. data/lib/super_diff/rspec/object_inspection/{inspectors → inspection_tree_builders}/object_having_attributes.rb +10 -12
  118. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/primitive.rb +10 -0
  119. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/value_within.rb +33 -0
  120. data/lib/super_diff/rspec/operation_tree_builders/collection_containing_exactly.rb +12 -4
  121. data/lib/super_diff/rspec/operation_tree_builders/collection_including.rb +10 -3
  122. data/lib/super_diff/rspec/operation_tree_builders/hash_including.rb +10 -3
  123. data/lib/super_diff/tiered_lines.rb +4 -0
  124. data/lib/super_diff/tiered_lines_elider.rb +490 -0
  125. data/lib/super_diff/tiered_lines_formatter.rb +79 -0
  126. data/lib/super_diff/version.rb +1 -1
  127. data/spec/examples.txt +407 -5
  128. data/spec/integration/rails/active_support_spec.rb +19 -0
  129. data/spec/integration/rspec/be_falsey_matcher_spec.rb +10 -10
  130. data/spec/integration/rspec/be_matcher_spec.rb +100 -100
  131. data/spec/integration/rspec/be_nil_matcher_spec.rb +10 -10
  132. data/spec/integration/rspec/be_predicate_matcher_spec.rb +103 -103
  133. data/spec/integration/rspec/be_truthy_matcher_spec.rb +10 -10
  134. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +113 -107
  135. data/spec/integration/rspec/eq_matcher_spec.rb +223 -277
  136. data/spec/integration/rspec/have_attributes_matcher_spec.rb +138 -129
  137. data/spec/integration/rspec/have_predicate_matcher_spec.rb +65 -65
  138. data/spec/integration/rspec/include_matcher_spec.rb +73 -73
  139. data/spec/integration/rspec/match_array_matcher_spec.rb +126 -119
  140. data/spec/integration/rspec/match_matcher_spec.rb +362 -274
  141. data/spec/integration/rspec/raise_error_matcher_spec.rb +86 -86
  142. data/spec/integration/rspec/respond_to_matcher_spec.rb +240 -240
  143. data/spec/integration/rspec/third_party_matcher_spec.rb +8 -8
  144. data/spec/integration/rspec/unhandled_errors_spec.rb +5 -5
  145. data/spec/spec_helper.rb +33 -13
  146. data/spec/support/command_runner.rb +15 -25
  147. data/spec/support/helpers.rb +21 -0
  148. data/spec/support/integration/helpers.rb +8 -2
  149. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +4 -4
  150. data/spec/support/integration/test_programs/base.rb +38 -10
  151. data/spec/support/integration/test_programs/rspec_active_record.rb +1 -1
  152. data/spec/support/integration/test_programs/rspec_active_support.rb +17 -0
  153. data/spec/support/integration/test_programs/rspec_rails.rb +1 -1
  154. data/spec/support/shared_examples/active_record.rb +109 -108
  155. data/spec/support/shared_examples/active_support.rb +65 -0
  156. data/spec/support/shared_examples/elided_diffs.rb +914 -0
  157. data/spec/support/shared_examples/hash_with_indifferent_access.rb +196 -232
  158. data/spec/support/unit/helpers.rb +15 -0
  159. data/spec/support/unit/matchers/match_output.rb +41 -0
  160. data/spec/unit/active_record/object_inspection_spec.rb +273 -0
  161. data/spec/unit/equality_matchers/main_spec.rb +445 -465
  162. data/spec/unit/helpers_spec.rb +61 -0
  163. data/spec/unit/operation_tree_flatteners/array_spec.rb +604 -0
  164. data/spec/unit/operation_tree_flatteners/custom_object_spec.rb +667 -0
  165. data/spec/unit/operation_tree_flatteners/default_object_spec.rb +687 -0
  166. data/spec/unit/operation_tree_flatteners/hash_spec.rb +632 -0
  167. data/spec/unit/operation_tree_flatteners/multiline_string_spec.rb +121 -0
  168. data/spec/unit/rspec/object_inspection_spec.rb +446 -0
  169. data/spec/unit/super_diff_spec.rb +1958 -0
  170. data/spec/unit/tiered_lines_elider_spec.rb +6356 -0
  171. data/spec/unit/tiered_lines_formatter_spec.rb +193 -0
  172. data/super_diff.gemspec +1 -1
  173. metadata +95 -50
  174. data/lib/super_diff/active_record/diff_formatters.rb +0 -10
  175. data/lib/super_diff/active_record/diff_formatters/active_record_relation.rb +0 -23
  176. data/lib/super_diff/active_record/object_inspection/inspectors.rb +0 -16
  177. data/lib/super_diff/active_support/diff_formatters.rb +0 -10
  178. data/lib/super_diff/active_support/diff_formatters/hash_with_indifferent_access.rb +0 -36
  179. data/lib/super_diff/active_support/object_inspection/inspectors/hash_with_indifferent_access.rb +0 -28
  180. data/lib/super_diff/diff_formatters.rb +0 -14
  181. data/lib/super_diff/diff_formatters/array.rb +0 -21
  182. data/lib/super_diff/diff_formatters/base.rb +0 -33
  183. data/lib/super_diff/diff_formatters/custom_object.rb +0 -30
  184. data/lib/super_diff/diff_formatters/default_object.rb +0 -46
  185. data/lib/super_diff/diff_formatters/defaults.rb +0 -10
  186. data/lib/super_diff/diff_formatters/hash.rb +0 -34
  187. data/lib/super_diff/diff_formatters/main.rb +0 -41
  188. data/lib/super_diff/object_inspection/inspectors.rb +0 -23
  189. data/lib/super_diff/object_inspection/inspectors/array.rb +0 -32
  190. data/lib/super_diff/object_inspection/inspectors/base.rb +0 -36
  191. data/lib/super_diff/object_inspection/inspectors/custom_object.rb +0 -37
  192. data/lib/super_diff/object_inspection/inspectors/default_object.rb +0 -61
  193. data/lib/super_diff/object_inspection/inspectors/hash.rb +0 -32
  194. data/lib/super_diff/object_inspection/inspectors/primitive.rb +0 -28
  195. data/lib/super_diff/object_inspection/inspectors/string.rb +0 -23
  196. data/lib/super_diff/object_inspection/inspectors/time_like.rb +0 -23
  197. data/lib/super_diff/object_inspection/nodes/break.rb +0 -15
  198. data/lib/super_diff/object_inspection/nodes/when_multiline.rb +0 -22
  199. data/lib/super_diff/object_inspection/nodes/when_singleline.rb +0 -24
  200. data/lib/super_diff/rspec/object_inspection/inspectors.rb +0 -40
  201. data/lib/super_diff/rspec/object_inspection/inspectors/collection_including.rb +0 -28
  202. data/lib/super_diff/rspec/object_inspection/inspectors/hash_including.rb +0 -31
  203. data/lib/super_diff/rspec/object_inspection/inspectors/instance_of.rb +0 -23
  204. data/lib/super_diff/rspec/object_inspection/inspectors/kind_of.rb +0 -23
  205. data/lib/super_diff/rspec/object_inspection/inspectors/primitive.rb +0 -13
  206. data/lib/super_diff/rspec/object_inspection/inspectors/value_within.rb +0 -29
  207. data/spec/support/object_id.rb +0 -27
  208. data/spec/support/ruby_versions.rb +0 -11
  209. data/spec/unit/object_inspection_spec.rb +0 -1168
@@ -3,8 +3,10 @@ module SuperDiff
3
3
  module Differs
4
4
  class CollectionIncluding < SuperDiff::Differs::Array
5
5
  def self.applies_to?(expected, actual)
6
- SuperDiff::RSpec.a_collection_including_something?(expected) &&
7
- actual.is_a?(::Array)
6
+ (
7
+ SuperDiff::RSpec.a_collection_including_something?(expected) ||
8
+ SuperDiff::RSpec.array_including_something?(expected)
9
+ ) && actual.is_a?(::Array)
8
10
  end
9
11
 
10
12
  private
@@ -3,8 +3,10 @@ module SuperDiff
3
3
  module Differs
4
4
  class HashIncluding < SuperDiff::Differs::Hash
5
5
  def self.applies_to?(expected, actual)
6
- SuperDiff::RSpec.a_hash_including_something?(expected) &&
7
- actual.is_a?(::Hash)
6
+ (
7
+ SuperDiff::RSpec.a_hash_including_something?(expected) ||
8
+ SuperDiff::RSpec.hash_including_something?(expected)
9
+ ) && actual.is_a?(::Hash)
8
10
  end
9
11
 
10
12
  private
@@ -45,12 +45,12 @@ module SuperDiff
45
45
  def add_extra_after_error
46
46
  end
47
47
 
48
- def beta_color
49
- SuperDiff::COLORS.fetch(:beta)
48
+ def actual_color
49
+ SuperDiff.configuration.actual_color
50
50
  end
51
51
 
52
- def alpha_color
53
- SuperDiff::COLORS.fetch(:alpha)
52
+ def expected_color
53
+ SuperDiff.configuration.expected_color
54
54
  end
55
55
 
56
56
  private
@@ -91,7 +91,7 @@ module SuperDiff
91
91
  end
92
92
 
93
93
  def add_actual_value
94
- template.add_text_in_color(beta_color) { actual }
94
+ template.add_text_in_color(actual_color) { actual }
95
95
  end
96
96
 
97
97
  def expected_section
@@ -110,7 +110,7 @@ module SuperDiff
110
110
  else
111
111
  template.add_text " "
112
112
  template.add_text_in_color(
113
- alpha_color,
113
+ expected_color,
114
114
  expected_for_failure_message,
115
115
  )
116
116
  end
@@ -121,7 +121,7 @@ module SuperDiff
121
121
  add_expected_value_to(template, expected_for_description)
122
122
  else
123
123
  template.add_text " "
124
- template.add_text_in_color(alpha_color, expected_for_description)
124
+ template.add_text_in_color(expected_color, expected_for_description)
125
125
  end
126
126
  end
127
127
 
@@ -26,12 +26,12 @@ module SuperDiff
26
26
  end
27
27
  end
28
28
 
29
- def beta_color
29
+ def actual_color
30
30
  :yellow
31
31
  end
32
32
 
33
33
  def add_actual_value
34
- template.add_text_in_color(beta_color) do
34
+ template.add_text_in_color(actual_color) do
35
35
  description_of(actual)
36
36
  end
37
37
  end
@@ -39,12 +39,12 @@ module SuperDiff
39
39
  def add_expected_value_to_failure_message(template)
40
40
  template.add_text " "
41
41
  template.add_text_in_color(
42
- alpha_color,
42
+ expected_color,
43
43
  "#{expected_for_failure_message}?",
44
44
  )
45
45
  template.add_text " or "
46
46
  template.add_text_in_color(
47
- alpha_color,
47
+ expected_color,
48
48
  "#{expected_for_failure_message}s?",
49
49
  )
50
50
  end
@@ -52,12 +52,12 @@ module SuperDiff
52
52
  def add_expected_value_to_description(template)
53
53
  template.add_text " "
54
54
  template.add_text_in_color(
55
- alpha_color,
55
+ expected_color,
56
56
  "`#{expected_for_description}?`",
57
57
  )
58
58
  template.add_text " or "
59
59
  template.add_text_in_color(
60
- alpha_color,
60
+ expected_color,
61
61
  "`#{expected_for_description}s?`",
62
62
  )
63
63
  end
@@ -6,7 +6,7 @@ module SuperDiff
6
6
 
7
7
  def add_expected_value_to(template, expected)
8
8
  template.add_text " "
9
- template.add_list_in_color(alpha_color, expected)
9
+ template.add_list_in_color(expected_color, expected)
10
10
  end
11
11
  end
12
12
  end
@@ -20,12 +20,12 @@ module SuperDiff
20
20
  end
21
21
  end
22
22
 
23
- def beta_color
23
+ def actual_color
24
24
  :yellow
25
25
  end
26
26
 
27
27
  def add_actual_value
28
- template.add_text_in_color(beta_color) do
28
+ template.add_text_in_color(actual_color) do
29
29
  description_of(actual)
30
30
  end
31
31
  end
@@ -33,7 +33,7 @@ module SuperDiff
33
33
  def add_expected_value_to_failure_message(template)
34
34
  template.add_text " "
35
35
  template.add_text_in_color(
36
- alpha_color,
36
+ expected_color,
37
37
  expected_for_failure_message,
38
38
  )
39
39
  end
@@ -41,7 +41,7 @@ module SuperDiff
41
41
  def add_expected_value_to_description(template)
42
42
  template.add_text " "
43
43
  template.add_text_in_color(
44
- alpha_color,
44
+ expected_color,
45
45
  "`#{expected_for_description}`",
46
46
  )
47
47
  end
@@ -14,7 +14,7 @@ module SuperDiff
14
14
 
15
15
  def add_actual_value
16
16
  if actual
17
- template.add_text_in_color(beta_color) { actual }
17
+ template.add_text_in_color(actual_color) { actual }
18
18
  else
19
19
  template.add_text("block")
20
20
  end
@@ -20,7 +20,7 @@ module SuperDiff
20
20
 
21
21
  def add_expected_value_to(template, expected)
22
22
  template.add_text " "
23
- template.add_list_in_color(alpha_color, expected)
23
+ template.add_list_in_color(expected_color, expected)
24
24
  end
25
25
 
26
26
  def add_extra_after_expected_to(template)
@@ -57,14 +57,14 @@ module SuperDiff
57
57
 
58
58
  def add_arity_clause_to(template)
59
59
  template.add_text " with "
60
- template.add_text_in_color alpha_color, expected_arity
60
+ template.add_text_in_color expected_color, expected_arity
61
61
  template.add_text " "
62
62
  template.add_text pluralize("argument", expected_arity)
63
63
  end
64
64
 
65
65
  def add_arbitrary_keywords_clause_to(template)
66
66
  template.add_text " with "
67
- template.add_text_in_color alpha_color, "any"
67
+ template.add_text_in_color expected_color, "any"
68
68
  template.add_text " keywords"
69
69
  end
70
70
 
@@ -72,7 +72,7 @@ module SuperDiff
72
72
  template.add_text " with "
73
73
  template.add_text pluralize("keyword", expected_keywords.length)
74
74
  template.add_text " "
75
- template.add_list_in_color alpha_color, expected_keywords
75
+ template.add_list_in_color expected_color, expected_keywords
76
76
  end
77
77
 
78
78
  def add_unlimited_arguments_clause_to(template)
@@ -82,7 +82,7 @@ module SuperDiff
82
82
  template.add_text " with "
83
83
  end
84
84
 
85
- template.add_text_in_color alpha_color, "unlimited"
85
+ template.add_text_in_color expected_color, "unlimited"
86
86
  template.add_text " arguments"
87
87
  end
88
88
 
@@ -12,34 +12,38 @@ require "rspec/matchers/built_in/match"
12
12
 
13
13
  module RSpec
14
14
  module Expectations
15
- def self.differ
16
- SuperDiff::RSpec::Differ
15
+ SuperDiff.insert_singleton_overrides(self) do
16
+ def differ
17
+ SuperDiff::RSpec::Differ
18
+ end
17
19
  end
18
20
 
19
21
  module ExpectationHelper
20
- def self.handle_failure(matcher, message, failure_message_method)
21
- message = message.call if message.respond_to?(:call)
22
- message ||= matcher.__send__(failure_message_method)
23
-
24
- if matcher.respond_to?(:diffable?) && matcher.diffable?
25
- # Look for expected_for_diff and actual_for_diff if possible
26
- expected =
27
- if matcher.respond_to?(:expected_for_diff)
28
- matcher.expected_for_diff
29
- else
30
- matcher.expected
31
- end
22
+ SuperDiff.insert_singleton_overrides(self) do
23
+ def handle_failure(matcher, message, failure_message_method)
24
+ message = message.call if message.respond_to?(:call)
25
+ message ||= matcher.__send__(failure_message_method)
26
+
27
+ if matcher.respond_to?(:diffable?) && matcher.diffable?
28
+ # Look for expected_for_diff and actual_for_diff if possible
29
+ expected =
30
+ if matcher.respond_to?(:expected_for_diff)
31
+ matcher.expected_for_diff
32
+ else
33
+ matcher.expected
34
+ end
32
35
 
33
- actual =
34
- if matcher.respond_to?(:actual_for_diff)
35
- matcher.actual_for_diff
36
- else
37
- matcher.actual
38
- end
36
+ actual =
37
+ if matcher.respond_to?(:actual_for_diff)
38
+ matcher.actual_for_diff
39
+ else
40
+ matcher.actual
41
+ end
39
42
 
40
- ::RSpec::Expectations.fail_with(message, expected, actual)
41
- else
42
- ::RSpec::Expectations.fail_with(message)
43
+ ::RSpec::Expectations.fail_with(message, expected, actual)
44
+ else
45
+ ::RSpec::Expectations.fail_with(message)
46
+ end
43
47
  end
44
48
  end
45
49
  end
@@ -48,29 +52,31 @@ module RSpec
48
52
  module Core
49
53
  module Formatters
50
54
  module ConsoleCodes
51
- # Patch so it returns nothing if code_or_symbol is nil, and that it uses
52
- # code_or_symbol if it can't be found in VT100_CODE_VALUES to allow for
53
- # customization
54
- def self.console_code_for(code_or_symbol)
55
- if code_or_symbol
56
- if (config_method = config_colors_to_methods[code_or_symbol])
57
- console_code_for RSpec.configuration.__send__(config_method)
58
- elsif RSpec::Core::Formatters::ConsoleCodes::VT100_CODE_VALUES.key?(code_or_symbol)
59
- code_or_symbol
60
- else
61
- RSpec::Core::Formatters::ConsoleCodes::VT100_CODES.fetch(code_or_symbol) do
55
+ SuperDiff.insert_singleton_overrides(self) do
56
+ # Patch so it returns nothing if code_or_symbol is nil, and that it uses
57
+ # code_or_symbol if it can't be found in VT100_CODE_VALUES to allow for
58
+ # customization
59
+ def console_code_for(code_or_symbol)
60
+ if code_or_symbol
61
+ if (config_method = config_colors_to_methods[code_or_symbol])
62
+ console_code_for RSpec.configuration.__send__(config_method)
63
+ elsif RSpec::Core::Formatters::ConsoleCodes::VT100_CODE_VALUES.key?(code_or_symbol)
62
64
  code_or_symbol
65
+ else
66
+ RSpec::Core::Formatters::ConsoleCodes::VT100_CODES.fetch(code_or_symbol) do
67
+ code_or_symbol
68
+ end
63
69
  end
64
70
  end
65
71
  end
66
- end
67
72
 
68
- # Patch so it does not apply a color if code_or_symbol is nil
69
- def self.wrap(text, code_or_symbol)
70
- if RSpec.configuration.color_enabled? && code = console_code_for(code_or_symbol)
71
- "\e[#{code}m#{text}\e[0m"
72
- else
73
- text
73
+ # Patch so it does not apply a color if code_or_symbol is nil
74
+ def wrap(text, code_or_symbol)
75
+ if RSpec.configuration.color_enabled? && code = console_code_for(code_or_symbol)
76
+ "\e[#{code}m#{text}\e[0m"
77
+ else
78
+ text
79
+ end
74
80
  end
75
81
  end
76
82
  end
@@ -79,173 +85,177 @@ module RSpec
79
85
  # UPDATE: Copy from SyntaxHighlighter::CodeRayImplementation
80
86
  RESET_CODE = "\e[0m"
81
87
 
82
- def initialize(exception, example, options={})
83
- @exception = exception
84
- @example = example
85
- @message_color = options.fetch(:message_color) { RSpec.configuration.failure_color }
86
- @description = options.fetch(:description) { example.full_description }
87
- @detail_formatter = options.fetch(:detail_formatter) { Proc.new {} }
88
- @extra_detail_formatter = options.fetch(:extra_detail_formatter) { Proc.new {} }
89
- @backtrace_formatter = options.fetch(:backtrace_formatter) { RSpec.configuration.backtrace_formatter }
90
- @indentation = options.fetch(:indentation, 2)
91
- @skip_shared_group_trace = options.fetch(:skip_shared_group_trace, false)
92
- # Patch to convert options[:failure_lines] to groups
93
- if options.include?(:failure_lines)
94
- @failure_line_groups = [
95
- {
96
- lines: options[:failure_lines],
97
- already_colorized: false
98
- }
99
- ]
88
+ SuperDiff.insert_overrides(self) do
89
+ def initialize(exception, example, options={})
90
+ @exception = exception
91
+ @example = example
92
+ @message_color = options.fetch(:message_color) { RSpec.configuration.failure_color }
93
+ @description = options.fetch(:description) { example.full_description }
94
+ @detail_formatter = options.fetch(:detail_formatter) { Proc.new {} }
95
+ @extra_detail_formatter = options.fetch(:extra_detail_formatter) { Proc.new {} }
96
+ @backtrace_formatter = options.fetch(:backtrace_formatter) { RSpec.configuration.backtrace_formatter }
97
+ @indentation = options.fetch(:indentation, 2)
98
+ @skip_shared_group_trace = options.fetch(:skip_shared_group_trace, false)
99
+ # Patch to convert options[:failure_lines] to groups
100
+ if options.include?(:failure_lines)
101
+ @failure_line_groups = [
102
+ {
103
+ lines: options[:failure_lines],
104
+ already_colorized: false
105
+ }
106
+ ]
107
+ end
100
108
  end
101
- end
102
-
103
- # Override to only color uncolored lines in red
104
- # and to not color empty lines
105
- def colorized_message_lines(colorizer = ::RSpec::Core::Formatters::ConsoleCodes)
106
- lines = failure_line_groups.flat_map do |group|
107
- if group[:already_colorized]
108
- group[:lines]
109
- else
110
- group[:lines].map do |line|
111
- if line.strip.empty?
112
- line
113
- else
114
- indentation = line[/^[ ]+/]
115
- rest = colorizer.wrap(line.sub(/^[ ]+/, ''), message_color)
116
109
 
117
- if indentation
118
- indentation + rest
110
+ # Override to only color uncolored lines in red
111
+ # and to not color empty lines
112
+ def colorized_message_lines(colorizer = ::RSpec::Core::Formatters::ConsoleCodes)
113
+ lines = failure_line_groups.flat_map do |group|
114
+ if group[:already_colorized]
115
+ group[:lines]
116
+ else
117
+ group[:lines].map do |line|
118
+ if line.strip.empty?
119
+ line
119
120
  else
120
- rest
121
+ indentation = line[/^[ ]+/]
122
+ rest = colorizer.wrap(line.sub(/^[ ]+/, ''), message_color)
123
+
124
+ if indentation
125
+ indentation + rest
126
+ else
127
+ rest
128
+ end
121
129
  end
122
130
  end
123
131
  end
124
132
  end
125
- end
126
-
127
- add_shared_group_lines(lines, colorizer)
128
- end
129
-
130
- private
131
-
132
- def add_shared_group_lines(lines, colorizer)
133
- return lines if @skip_shared_group_trace
134
133
 
135
- example.metadata[:shared_group_inclusion_backtrace].each do |frame|
136
- # Use red instead of the default color
137
- lines << colorizer.wrap(frame.description, :failure)
134
+ add_shared_group_lines(lines, colorizer)
138
135
  end
139
136
 
140
- lines
141
- end
137
+ private
142
138
 
143
- # Considering that `failure_slash_error_lines` is already colored,
144
- # extract this from the other lines so that they, too, can be colored,
145
- # later
146
- #
147
- # TODO: Refactor this somehow
148
- #
149
- def failure_line_groups
150
- if defined?(@failure_line_groups)
151
- @failure_line_groups
152
- else
153
- @failure_line_groups = [
154
- {
155
- lines: failure_slash_error_lines,
156
- already_colorized: true
157
- }
158
- ]
159
-
160
- sections = [failure_slash_error_lines, exception_lines]
161
- separate_groups = (
162
- sections.any? { |section| section.size > 1 } &&
163
- !exception_lines.first.empty?
164
- )
139
+ def add_shared_group_lines(lines, colorizer)
140
+ return lines if @skip_shared_group_trace
165
141
 
166
- if separate_groups
167
- @failure_line_groups << { lines: [''], already_colorized: true }
142
+ example.metadata[:shared_group_inclusion_backtrace].each do |frame|
143
+ # Use red instead of the default color
144
+ lines << colorizer.wrap(frame.description, :failure)
168
145
  end
169
146
 
170
- already_colorized = exception_lines.any? do |line|
171
- SuperDiff::Csi.already_colorized?(line)
172
- end
147
+ lines
148
+ end
173
149
 
174
- if already_colorized
175
- @failure_line_groups << {
176
- lines: exception_lines,
177
- already_colorized: true
178
- }
150
+ # Considering that `failure_slash_error_lines` is already colored,
151
+ # extract this from the other lines so that they, too, can be colored,
152
+ # later
153
+ #
154
+ # TODO: Refactor this somehow
155
+ #
156
+ def failure_line_groups
157
+ if defined?(@failure_line_groups)
158
+ @failure_line_groups
179
159
  else
180
- locatable_exception_lines =
181
- exception_lines.each_with_index.map do |line, index|
182
- { text: line, index: index }
183
- end
160
+ @failure_line_groups = [
161
+ {
162
+ lines: failure_slash_error_lines,
163
+ already_colorized: true
164
+ }
165
+ ]
184
166
 
185
- boundary_line =
186
- locatable_exception_lines.find do |line, index|
187
- line[:text].strip.empty? || line[:text].match?(/^ /)
188
- end
167
+ sections = [failure_slash_error_lines, exception_lines]
168
+ separate_groups = (
169
+ sections.any? { |section| section.size > 1 } &&
170
+ !exception_lines.first.empty?
171
+ )
189
172
 
190
- if boundary_line
191
- @failure_line_groups << {
192
- lines: exception_lines[0..boundary_line[:index] - 1],
193
- already_colorized: false
194
- }
173
+ if separate_groups
174
+ @failure_line_groups << { lines: [''], already_colorized: true }
175
+ end
176
+
177
+ already_colorized = exception_lines.any? do |line|
178
+ SuperDiff::Csi.already_colorized?(line)
179
+ end
180
+
181
+ if already_colorized
195
182
  @failure_line_groups << {
196
- lines: exception_lines[boundary_line[:index]..-1],
183
+ lines: exception_lines,
197
184
  already_colorized: true
198
185
  }
199
186
  else
200
- @failure_line_groups << {
201
- lines: exception_lines,
202
- already_colorized: false
203
- }
187
+ locatable_exception_lines =
188
+ exception_lines.each_with_index.map do |line, index|
189
+ { text: line, index: index }
190
+ end
191
+
192
+ boundary_line =
193
+ locatable_exception_lines.find do |line, index|
194
+ line[:text].strip.empty? || line[:text].match?(/^ /)
195
+ end
196
+
197
+ if boundary_line
198
+ @failure_line_groups << {
199
+ lines: exception_lines[0..boundary_line[:index] - 1],
200
+ already_colorized: false
201
+ }
202
+ @failure_line_groups << {
203
+ lines: exception_lines[boundary_line[:index]..-1],
204
+ already_colorized: true
205
+ }
206
+ else
207
+ @failure_line_groups << {
208
+ lines: exception_lines,
209
+ already_colorized: false
210
+ }
211
+ end
204
212
  end
205
- end
206
213
 
207
- @failure_line_groups
214
+ @failure_line_groups
215
+ end
208
216
  end
209
- end
210
217
 
211
- # Style the first part in white and don't style the snippet of the line
212
- def failure_slash_error_lines
213
- lines = read_failed_lines
218
+ # Style the first part in white and don't style the snippet of the line
219
+ def failure_slash_error_lines
220
+ lines = read_failed_lines
214
221
 
215
- failure_slash_error = ConsoleCodes.wrap("Failure/Error: ", :bold)
222
+ failure_slash_error = ConsoleCodes.wrap("Failure/Error: ", :bold)
216
223
 
217
- if lines.count == 1
218
- lines[0] = failure_slash_error + lines[0].strip
219
- else
220
- least_indentation = SnippetExtractor.least_indentation_from(lines)
221
- lines = lines.map do |line|
222
- line.sub(/^#{least_indentation}/, ' ')
224
+ if lines.count == 1
225
+ lines[0] = failure_slash_error + lines[0].strip
226
+ else
227
+ least_indentation = SnippetExtractor.least_indentation_from(lines)
228
+ lines = lines.map do |line|
229
+ line.sub(/^#{least_indentation}/, ' ')
230
+ end
231
+ lines.unshift(failure_slash_error)
223
232
  end
224
- lines.unshift(failure_slash_error)
233
+
234
+ lines
225
235
  end
226
236
 
227
- lines
228
- end
237
+ # Exclude this file from being included in backtraces, so that the
238
+ # SnippetExtractor prints the right thing
239
+ def find_failed_line
240
+ line_regex = RSpec.configuration.in_project_source_dir_regex
241
+ loaded_spec_files = RSpec.configuration.loaded_spec_files
229
242
 
230
- # Exclude this file from being included in backtraces, so that the
231
- # SnippetExtractor prints the right thing
232
- def find_failed_line
233
- line_regex = RSpec.configuration.in_project_source_dir_regex
234
- loaded_spec_files = RSpec.configuration.loaded_spec_files
235
-
236
- exception_backtrace.find do |line|
237
- next unless (line_path = line[/(.+?):(\d+)(|:\d+)/, 1])
238
- path = File.expand_path(line_path)
239
- path != __FILE__ && (loaded_spec_files.include?(path) || path =~ line_regex)
240
- end || exception_backtrace.first
243
+ exception_backtrace.find do |line|
244
+ next unless (line_path = line[/(.+?):(\d+)(|:\d+)/, 1])
245
+ path = File.expand_path(line_path)
246
+ path != __FILE__ && (loaded_spec_files.include?(path) || path =~ line_regex)
247
+ end || exception_backtrace.first
248
+ end
241
249
  end
242
250
  end
243
251
 
244
252
  class SyntaxHighlighter
245
- private
253
+ SuperDiff.insert_overrides(self) do
254
+ private
246
255
 
247
- def implementation
248
- RSpec::Core::Formatters::SyntaxHighlighter::NoSyntaxHighlightingImplementation
256
+ def implementation
257
+ RSpec::Core::Formatters::SyntaxHighlighter::NoSyntaxHighlightingImplementation
258
+ end
249
259
  end
250
260
  end
251
261
  end
@@ -253,100 +263,108 @@ module RSpec
253
263
 
254
264
  module Support
255
265
  class ObjectFormatter
256
- # Override to use our formatting algorithm
257
- def self.format(value)
258
- SuperDiff::ObjectInspection.inspect(value, as_single_line: true)
266
+ SuperDiff.insert_singleton_overrides(self) do
267
+ # Override to use our formatting algorithm
268
+ def format(value)
269
+ SuperDiff.inspect_object(value, as_lines: false)
270
+ end
259
271
  end
260
272
 
261
- # Override to use our formatting algorithm
262
- def format(value)
263
- SuperDiff::ObjectInspection.inspect(value, as_single_line: true)
273
+ SuperDiff.insert_overrides(self) do
274
+ # Override to use our formatting algorithm
275
+ def format(value)
276
+ SuperDiff.inspect_object(value, as_lines: false)
277
+ end
264
278
  end
265
279
  end
266
280
  end
267
281
 
268
282
  module Matchers
269
283
  class ExpectedsForMultipleDiffs
270
- # Add a key for different sides
271
- def self.from(expected)
272
- return expected if self === expected
273
-
274
- text =
275
- colorizer.wrap("Diff:", SuperDiff::COLORS.fetch(:header)) +
276
- "\n\n" +
277
- colorizer.wrap(
278
- "┌ (Key) ──────────────────────────┐",
279
- SuperDiff::COLORS.fetch(:border)
280
- ) +
281
- "\n" +
282
- colorizer.wrap("", SuperDiff::COLORS.fetch(:border)) +
283
- colorizer.wrap(
284
- "‹-› in expected, not in actual",
285
- SuperDiff::COLORS.fetch(:alpha)
286
- ) +
287
- colorizer.wrap(" │", SuperDiff::COLORS.fetch(:border)) +
288
- "\n" +
289
- colorizer.wrap("", SuperDiff::COLORS.fetch(:border)) +
290
- colorizer.wrap(
291
- "‹+› in actual, not in expected",
292
- SuperDiff::COLORS.fetch(:beta)
293
- ) +
294
- colorizer.wrap(" │", SuperDiff::COLORS.fetch(:border)) +
295
- "\n" +
296
- colorizer.wrap("", SuperDiff::COLORS.fetch(:border)) +
297
- " in both expected and actual" +
298
- colorizer.wrap(" ", SuperDiff::COLORS.fetch(:border)) +
299
- "\n" +
300
- colorizer.wrap(
301
- "└─────────────────────────────────┘",
302
- SuperDiff::COLORS.fetch(:border)
303
- )
304
-
305
- new([[expected, text]])
306
- end
284
+ SuperDiff.insert_singleton_overrides(self) do
285
+ # Add a key for different sides
286
+ def from(expected)
287
+ return expected if self === expected
288
+
289
+ text =
290
+ colorizer.wrap("Diff:", SuperDiff.configuration.header_color) +
291
+ "\n\n" +
292
+ colorizer.wrap(
293
+ "┌ (Key) ──────────────────────────┐",
294
+ SuperDiff.configuration.border_color
295
+ ) +
296
+ "\n" +
297
+ colorizer.wrap("│ ", SuperDiff.configuration.border_color) +
298
+ colorizer.wrap(
299
+ "‹-› in expected, not in actual",
300
+ SuperDiff.configuration.expected_color
301
+ ) +
302
+ colorizer.wrap("", SuperDiff.configuration.border_color) +
303
+ "\n" +
304
+ colorizer.wrap("│ ", SuperDiff.configuration.border_color) +
305
+ colorizer.wrap(
306
+ "‹+› in actual, not in expected",
307
+ SuperDiff.configuration.actual_color
308
+ ) +
309
+ colorizer.wrap("", SuperDiff.configuration.border_color) +
310
+ "\n" +
311
+ colorizer.wrap(" ", SuperDiff.configuration.border_color) +
312
+ " › in both expected and actual" +
313
+ colorizer.wrap("", SuperDiff.configuration.border_color) +
314
+ "\n" +
315
+ colorizer.wrap(
316
+ "└─────────────────────────────────┘",
317
+ SuperDiff.configuration.border_color
318
+ )
319
+
320
+ new([[expected, text]])
321
+ end
307
322
 
308
- def self.colorizer
309
- RSpec::Core::Formatters::ConsoleCodes
323
+ def colorizer
324
+ RSpec::Core::Formatters::ConsoleCodes
325
+ end
310
326
  end
311
327
 
312
- # Add an extra line break
313
- def message_with_diff(message, differ, actual)
314
- diff = diffs(differ, actual)
328
+ SuperDiff.insert_overrides(self) do
329
+ # Add an extra line break
330
+ def message_with_diff(message, differ, actual)
331
+ diff = diffs(differ, actual)
315
332
 
316
- if diff.empty?
317
- message
318
- else
319
- "#{message.rstrip}\n\n#{diff}"
333
+ if diff.empty?
334
+ message
335
+ else
336
+ "#{message.rstrip}\n\n#{diff}"
337
+ end
320
338
  end
321
- end
322
339
 
323
- private
340
+ private
324
341
 
325
- # Add extra line breaks in between diffs, and colorize the word "Diff"
326
- def diffs(differ, actual)
327
- @expected_list.map do |(expected, diff_label)|
328
- diff = differ.diff(actual, expected)
329
- next if diff.strip.empty?
330
- diff_label + diff
331
- end.compact.join("\n\n")
342
+ # Add extra line breaks in between diffs, and colorize the word "Diff"
343
+ def diffs(differ, actual)
344
+ @expected_list.map do |(expected, diff_label)|
345
+ diff = differ.diff(actual, expected)
346
+ next if diff.strip.empty?
347
+ diff_label + diff
348
+ end.compact.join("\n\n")
349
+ end
332
350
  end
333
351
  end
334
352
 
335
353
  module BuiltIn
336
354
  class Be
337
- prepend SuperDiff::RSpec::AugmentedMatcher
355
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
338
356
 
339
- prepend(Module.new do
357
+ SuperDiff.insert_overrides(self) do
340
358
  def expected_for_matcher_text
341
359
  "truthy"
342
360
  end
343
- end)
361
+ end
344
362
  end
345
363
 
346
364
  class BeComparedTo
347
- prepend SuperDiff::RSpec::AugmentedMatcher
365
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
348
366
 
349
- prepend(Module.new do
367
+ SuperDiff.insert_overrides(self) do
350
368
  def expected_action_for_matcher_text
351
369
  if [:==, :===, :=~].include?(@operator)
352
370
  "#{@operator}"
@@ -354,13 +372,13 @@ module RSpec
354
372
  "be #{@operator}"
355
373
  end
356
374
  end
357
- end)
375
+ end
358
376
  end
359
377
 
360
378
  class BeFalsey
361
- prepend SuperDiff::RSpec::AugmentedMatcher
379
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
362
380
 
363
- prepend(Module.new do
381
+ SuperDiff.insert_overrides(self) do
364
382
  def expected_action_for_matcher_text
365
383
  "be"
366
384
  end
@@ -368,13 +386,13 @@ module RSpec
368
386
  def expected_for_matcher_text
369
387
  "falsey"
370
388
  end
371
- end)
389
+ end
372
390
  end
373
391
 
374
392
  class BeNil
375
- prepend SuperDiff::RSpec::AugmentedMatcher
393
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
376
394
 
377
- prepend(Module.new do
395
+ SuperDiff.insert_overrides(self) do
378
396
  def expected_action_for_matcher_text
379
397
  "be"
380
398
  end
@@ -382,19 +400,23 @@ module RSpec
382
400
  def expected_for_matcher_text
383
401
  "nil"
384
402
  end
385
- end)
403
+ end
386
404
  end
387
405
 
388
406
  class BePredicate
389
- prepend SuperDiff::RSpec::AugmentedMatcher
407
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
390
408
 
391
- prepend(Module.new do
409
+ SuperDiff.insert_overrides(self) do
392
410
  def actual_for_matcher_text
393
411
  actual
394
412
  end
395
413
 
396
414
  def expected_for_matcher_text
397
- expected
415
+ if SuperDiff::RSpec.rspec_version < "3.10"
416
+ expected
417
+ else
418
+ predicate.to_s.chomp('?')
419
+ end
398
420
  end
399
421
 
400
422
  def expected_action_for_matcher_text
@@ -412,13 +434,13 @@ module RSpec
412
434
  expected_predicate_method_name: predicate
413
435
  )
414
436
  end
415
- end)
437
+ end
416
438
  end
417
439
 
418
440
  class BeTruthy
419
- prepend SuperDiff::RSpec::AugmentedMatcher
441
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
420
442
 
421
- prepend(Module.new do
443
+ SuperDiff.insert_overrides(self) do
422
444
  def expected_action_for_matcher_text
423
445
  "be"
424
446
  end
@@ -426,13 +448,13 @@ module RSpec
426
448
  def expected_for_matcher_text
427
449
  "truthy"
428
450
  end
429
- end)
451
+ end
430
452
  end
431
453
 
432
454
  class ContainExactly
433
- prepend SuperDiff::RSpec::AugmentedMatcher
455
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
434
456
 
435
- prepend(Module.new do
457
+ SuperDiff.insert_overrides(self) do
436
458
  # Override this method so that the differ knows that this is a partial
437
459
  # collection
438
460
  def expected_for_diff
@@ -448,21 +470,26 @@ module RSpec
448
470
  def matcher_text_builder_class
449
471
  SuperDiff::RSpec::MatcherTextBuilders::ContainExactly
450
472
  end
451
- end)
473
+ end
452
474
  end
453
475
 
454
476
  class Eq
455
- prepend SuperDiff::RSpec::AugmentedMatcher
477
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
456
478
  end
457
479
 
458
480
  class Equal
459
- prepend SuperDiff::RSpec::AugmentedMatcher
481
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
460
482
  end
461
483
 
462
484
  class HaveAttributes
463
- prepend SuperDiff::RSpec::AugmentedMatcher
485
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
486
+
487
+ SuperDiff.insert_overrides(self) do
488
+ def initialize(*)
489
+ super
490
+ @actual = nil
491
+ end
464
492
 
465
- prepend(Module.new do
466
493
  # Use the message in the base matcher
467
494
  def failure_message
468
495
  respond_to_failure_message_or { super }
@@ -498,54 +525,58 @@ module RSpec
498
525
  matchers.an_object_having_attributes(@expected)
499
526
  end
500
527
  end
501
- end)
502
528
 
503
- # Override to force @values to get populated so that we can show a
504
- # proper diff
505
- def respond_to_attributes?
506
- cache_all_values
507
- matches = respond_to_matcher.matches?(@actual)
508
- @respond_to_failed = !matches
509
- matches
510
- end
529
+ # Override to force @values to get populated so that we can show a
530
+ # proper diff
531
+ def respond_to_attributes?
532
+ cache_all_values
533
+ matches = respond_to_matcher.matches?(@actual)
534
+ @respond_to_failed = !matches
535
+ matches
536
+ end
511
537
 
512
- # Override this method to skip non-existent attributes, and to use
513
- # public_send
514
- def cache_all_values
515
- @values = @expected.keys.inject({}) do |hash, attribute_key|
516
- if @actual.respond_to?(attribute_key)
517
- actual_value = @actual.public_send(attribute_key)
518
- hash.merge(attribute_key => actual_value)
519
- else
520
- hash
538
+ # Override this method to skip non-existent attributes, and to use
539
+ # public_send
540
+ def cache_all_values
541
+ @values = @expected.keys.inject({}) do |hash, attribute_key|
542
+ if @actual.respond_to?(attribute_key)
543
+ actual_value = @actual.public_send(attribute_key)
544
+ hash.merge(attribute_key => actual_value)
545
+ else
546
+ hash
547
+ end
521
548
  end
522
549
  end
523
- end
524
550
 
525
- def actual_has_attribute?(attribute_key, attribute_value)
526
- values_match?(attribute_value, @values.fetch(attribute_key))
527
- end
551
+ def actual_has_attribute?(attribute_key, attribute_value)
552
+ values_match?(attribute_value, @values.fetch(attribute_key))
553
+ end
528
554
 
529
- # Override to not improve_hash_formatting
530
- def respond_to_failure_message_or
531
- if respond_to_failed
532
- respond_to_matcher.failure_message
533
- else
534
- yield
555
+ # Override to not improve_hash_formatting
556
+ def respond_to_failure_message_or
557
+ if respond_to_failed
558
+ respond_to_matcher.failure_message
559
+ else
560
+ yield
561
+ end
535
562
  end
536
563
  end
537
564
  end
538
565
 
539
566
  class Has
540
- prepend SuperDiff::RSpec::AugmentedMatcher
567
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
541
568
 
542
- prepend(Module.new do
569
+ SuperDiff.insert_overrides(self) do
543
570
  def actual_for_matcher_text
544
571
  actual
545
572
  end
546
573
 
547
574
  def expected_for_matcher_text
548
- "#{predicate}#{failure_message_args_description}"
575
+ if SuperDiff::RSpec.rspec_version < "3.10"
576
+ "#{predicate}#{failure_message_args_description}"
577
+ else
578
+ "#{predicate}#{args_to_s}"
579
+ end
549
580
  end
550
581
 
551
582
  def expected_action_for_matcher_text
@@ -562,13 +593,18 @@ module RSpec
562
593
  private_predicate: private_predicate?
563
594
  )
564
595
  end
565
- end)
596
+ end
566
597
  end
567
598
 
568
599
  class Include
569
- prepend SuperDiff::RSpec::AugmentedMatcher
600
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
601
+
602
+ SuperDiff.insert_overrides(self) do
603
+ def initialize(*)
604
+ super
605
+ @actual = nil
606
+ end
570
607
 
571
- prepend(Module.new do
572
608
  # Override this method so that the differ knows that this is a partial
573
609
  # array or hash
574
610
  def expected_for_diff
@@ -603,7 +639,11 @@ module RSpec
603
639
  def expected_for_failure_message
604
640
  # TODO: Switch to using @divergent_items and handle this in the text
605
641
  # builder
606
- readable_list_of(@divergent_items).lstrip
642
+ if defined?(@divergent_items)
643
+ readable_list_of(@divergent_items).lstrip
644
+ else
645
+ ""
646
+ end
607
647
  end
608
648
 
609
649
  # Update to use (...) as delimiter instead of {...}
@@ -616,13 +656,13 @@ module RSpec
616
656
  super
617
657
  end
618
658
  end
619
- end)
659
+ end
620
660
  end
621
661
 
622
662
  class Match
623
- prepend SuperDiff::RSpec::AugmentedMatcher
663
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
624
664
 
625
- prepend(Module.new do
665
+ SuperDiff.insert_overrides(self) do
626
666
  def matcher_text_builder_class
627
667
  SuperDiff::RSpec::MatcherTextBuilders::Match
628
668
  end
@@ -630,7 +670,7 @@ module RSpec
630
670
  def matcher_text_builder_args
631
671
  super.merge(expected_captures: @expected_captures)
632
672
  end
633
- end)
673
+ end
634
674
  end
635
675
 
636
676
  class MatchArray < ContainExactly
@@ -644,9 +684,9 @@ module RSpec
644
684
  end
645
685
 
646
686
  class RaiseError
647
- prepend SuperDiff::RSpec::AugmentedMatcher
687
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
648
688
 
649
- prepend(Module.new do
689
+ SuperDiff.insert_overrides(self) do
650
690
  def actual_for_matcher_text
651
691
  if @actual_error
652
692
  "#<#{@actual_error.class.name} #{@actual_error.message.inspect}>"
@@ -688,7 +728,7 @@ module RSpec
688
728
  def matcher_text_builder_class
689
729
  SuperDiff::RSpec::MatcherTextBuilders::RaiseError
690
730
  end
691
- end)
731
+ end
692
732
 
693
733
  def self.matcher_name
694
734
  "raise error"
@@ -696,9 +736,9 @@ module RSpec
696
736
  end
697
737
 
698
738
  class RespondTo
699
- prepend SuperDiff::RSpec::AugmentedMatcher
739
+ SuperDiff.insert_overrides(self, SuperDiff::RSpec::AugmentedMatcher)
700
740
 
701
- prepend(Module.new do
741
+ SuperDiff.insert_overrides(self) do
702
742
  def initialize(*)
703
743
  super
704
744
  @failing_method_names = nil
@@ -724,13 +764,20 @@ module RSpec
724
764
  def expected_for_failure_message
725
765
  @failing_method_names
726
766
  end
727
- end)
767
+ end
728
768
  end
729
769
  end
730
770
 
731
- def match_array(items)
732
- BuiltIn::MatchArray.new(items.is_a?(String) ? [items] : items)
771
+ SuperDiff.insert_overrides(self) do
772
+ def self.prepended(base)
773
+ base.class_eval do
774
+ alias_matcher :an_array_matching, :match_array
775
+ end
776
+ end
777
+
778
+ def match_array(items)
779
+ BuiltIn::MatchArray.new(items.is_a?(String) ? [items] : items)
780
+ end
733
781
  end
734
- alias_matcher :an_array_matching, :match_array
735
782
  end
736
783
  end