super_diff 0.11.0 → 0.12.1

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 (231) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -166
  3. data/lib/super_diff/active_record/differs/active_record_relation.rb +1 -1
  4. data/lib/super_diff/active_record/inspection_tree_builders/active_record_model.rb +57 -0
  5. data/lib/super_diff/active_record/inspection_tree_builders/active_record_relation.rb +34 -0
  6. data/lib/super_diff/active_record/inspection_tree_builders.rb +14 -0
  7. data/lib/super_diff/active_record/monkey_patches.rb +6 -3
  8. data/lib/super_diff/active_record/object_inspection.rb +16 -4
  9. data/lib/super_diff/active_record/operation_tree_builders/active_record_model.rb +6 -2
  10. data/lib/super_diff/active_record/operation_tree_builders/active_record_relation.rb +1 -1
  11. data/lib/super_diff/active_record/operation_tree_flatteners/active_record_relation.rb +1 -1
  12. data/lib/super_diff/active_record/operation_trees/active_record_relation.rb +1 -1
  13. data/lib/super_diff/active_record.rb +12 -16
  14. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +1 -1
  15. data/lib/super_diff/active_support/inspection_tree_builders/hash_with_indifferent_access.rb +44 -0
  16. data/lib/super_diff/active_support/inspection_tree_builders/ordered_options.rb +44 -0
  17. data/lib/super_diff/active_support/inspection_tree_builders.rb +14 -0
  18. data/lib/super_diff/active_support/object_inspection.rb +16 -4
  19. data/lib/super_diff/active_support/operation_tree_builders/hash_with_indifferent_access.rb +1 -1
  20. data/lib/super_diff/active_support/operation_tree_flatteners/hash_with_indifferent_access.rb +1 -1
  21. data/lib/super_diff/active_support/operation_trees/hash_with_indifferent_access.rb +1 -1
  22. data/lib/super_diff/active_support.rb +11 -15
  23. data/lib/super_diff/basic/diff_formatters/collection.rb +135 -0
  24. data/lib/super_diff/basic/diff_formatters/multiline_string.rb +34 -0
  25. data/lib/super_diff/basic/diff_formatters.rb +11 -0
  26. data/lib/super_diff/basic/differs/array.rb +17 -0
  27. data/lib/super_diff/basic/differs/custom_object.rb +19 -0
  28. data/lib/super_diff/basic/differs/date_like.rb +17 -0
  29. data/lib/super_diff/basic/differs/default_object.rb +24 -0
  30. data/lib/super_diff/basic/differs/hash.rb +17 -0
  31. data/lib/super_diff/basic/differs/multiline_string.rb +18 -0
  32. data/lib/super_diff/basic/differs/time_like.rb +17 -0
  33. data/lib/super_diff/basic/differs.rb +24 -0
  34. data/lib/super_diff/{object_inspection → basic}/inspection_tree_builders/array.rb +3 -3
  35. data/lib/super_diff/{object_inspection → basic}/inspection_tree_builders/custom_object.rb +3 -3
  36. data/lib/super_diff/{object_inspection → basic}/inspection_tree_builders/date_like.rb +3 -3
  37. data/lib/super_diff/{object_inspection → basic}/inspection_tree_builders/default_object.rb +5 -7
  38. data/lib/super_diff/{object_inspection → basic}/inspection_tree_builders/hash.rb +3 -3
  39. data/lib/super_diff/{object_inspection → basic}/inspection_tree_builders/primitive.rb +3 -3
  40. data/lib/super_diff/{object_inspection → basic}/inspection_tree_builders/time_like.rb +3 -3
  41. data/lib/super_diff/basic/inspection_tree_builders.rb +20 -0
  42. data/lib/super_diff/basic/operation_tree_builders/array.rb +111 -0
  43. data/lib/super_diff/basic/operation_tree_builders/custom_object.rb +42 -0
  44. data/lib/super_diff/basic/operation_tree_builders/date_like.rb +17 -0
  45. data/lib/super_diff/basic/operation_tree_builders/default_object.rb +117 -0
  46. data/lib/super_diff/basic/operation_tree_builders/hash.rb +222 -0
  47. data/lib/super_diff/basic/operation_tree_builders/multiline_string.rb +90 -0
  48. data/lib/super_diff/basic/operation_tree_builders/time_like.rb +26 -0
  49. data/lib/super_diff/basic/operation_tree_builders.rb +34 -0
  50. data/lib/super_diff/basic/operation_tree_flatteners/array.rb +17 -0
  51. data/lib/super_diff/basic/operation_tree_flatteners/collection.rb +140 -0
  52. data/lib/super_diff/basic/operation_tree_flatteners/custom_object.rb +30 -0
  53. data/lib/super_diff/basic/operation_tree_flatteners/default_object.rb +32 -0
  54. data/lib/super_diff/basic/operation_tree_flatteners/hash.rb +35 -0
  55. data/lib/super_diff/basic/operation_tree_flatteners/multiline_string.rb +20 -0
  56. data/lib/super_diff/basic/operation_tree_flatteners.rb +24 -0
  57. data/lib/super_diff/basic/operation_trees/array.rb +17 -0
  58. data/lib/super_diff/basic/operation_trees/custom_object.rb +17 -0
  59. data/lib/super_diff/basic/operation_trees/default_object.rb +42 -0
  60. data/lib/super_diff/basic/operation_trees/hash.rb +17 -0
  61. data/lib/super_diff/basic/operation_trees/multiline_string.rb +17 -0
  62. data/lib/super_diff/basic/operation_trees.rb +25 -0
  63. data/lib/super_diff/basic.rb +48 -0
  64. data/lib/super_diff/{differs/base.rb → core/abstract_differ.rb} +2 -2
  65. data/lib/super_diff/core/abstract_inspection_tree_builder.rb +26 -0
  66. data/lib/super_diff/{operation_trees/base.rb → core/abstract_operation_tree.rb} +6 -2
  67. data/lib/super_diff/{operation_tree_builders/base.rb → core/abstract_operation_tree_builder.rb} +4 -8
  68. data/lib/super_diff/{operation_tree_flatteners/base.rb → core/abstract_operation_tree_flattener.rb} +2 -2
  69. data/lib/super_diff/{operations → core}/binary_operation.rb +1 -1
  70. data/lib/super_diff/core/colorized_document_extensions.rb +20 -0
  71. data/lib/super_diff/core/configuration.rb +192 -0
  72. data/lib/super_diff/core/differ_dispatcher.rb +31 -0
  73. data/lib/super_diff/core/gem_version.rb +47 -0
  74. data/lib/super_diff/core/helpers.rb +88 -0
  75. data/lib/super_diff/core/implementation_checks.rb +21 -0
  76. data/lib/super_diff/{object_inspection → core}/inspection_tree.rb +7 -6
  77. data/lib/super_diff/core/inspection_tree_builder_dispatcher.rb +23 -0
  78. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_lines_when_rendering_to_lines.rb +9 -3
  79. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_prefix_when_rendering_to_lines.rb +3 -3
  80. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_prelude_when_rendering_to_lines.rb +3 -3
  81. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_single_line.rb +3 -3
  82. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/base.rb +2 -2
  83. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/inspection.rb +7 -11
  84. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/nesting.rb +2 -2
  85. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/only_when.rb +2 -2
  86. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/text.rb +2 -2
  87. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_empty.rb +2 -2
  88. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_non_empty.rb +2 -2
  89. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_rendering_to_lines.rb +2 -2
  90. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_rendering_to_string.rb +2 -2
  91. data/lib/super_diff/core/inspection_tree_nodes.rb +55 -0
  92. data/lib/super_diff/core/line.rb +85 -0
  93. data/lib/super_diff/{errors → core}/no_differ_available_error.rb +1 -1
  94. data/lib/super_diff/core/no_inspection_tree_builder_available_error.rb +21 -0
  95. data/lib/super_diff/core/no_operation_tree_available_error.rb +20 -0
  96. data/lib/super_diff/core/no_operation_tree_builder_available_error.rb +24 -0
  97. data/lib/super_diff/{operation_tree_builders/main.rb → core/operation_tree_builder_dispatcher.rb} +9 -13
  98. data/lib/super_diff/core/operation_tree_finder.rb +27 -0
  99. data/lib/super_diff/core/prefix_for_next_inspection_tree_node.rb +6 -0
  100. data/lib/super_diff/core/prelude_for_next_inspection_tree_node.rb +6 -0
  101. data/lib/super_diff/core/recursion_guard.rb +52 -0
  102. data/lib/super_diff/core/tiered_lines.rb +6 -0
  103. data/lib/super_diff/core/tiered_lines_elider.rb +472 -0
  104. data/lib/super_diff/core/tiered_lines_formatter.rb +77 -0
  105. data/lib/super_diff/{operations → core}/unary_operation.rb +1 -1
  106. data/lib/super_diff/core.rb +69 -0
  107. data/lib/super_diff/differs.rb +19 -12
  108. data/lib/super_diff/equality_matchers/array.rb +3 -3
  109. data/lib/super_diff/equality_matchers/default.rb +8 -3
  110. data/lib/super_diff/equality_matchers/hash.rb +3 -3
  111. data/lib/super_diff/equality_matchers/multiline_string.rb +3 -3
  112. data/lib/super_diff/equality_matchers/primitive.rb +3 -3
  113. data/lib/super_diff/equality_matchers/singleline_string.rb +2 -2
  114. data/lib/super_diff/errors.rb +12 -8
  115. data/lib/super_diff/object_inspection.rb +63 -14
  116. data/lib/super_diff/operation_tree_builders.rb +19 -15
  117. data/lib/super_diff/operation_tree_flatteners.rb +19 -16
  118. data/lib/super_diff/operation_trees.rb +19 -9
  119. data/lib/super_diff/operations.rb +12 -2
  120. data/lib/super_diff/rspec/augmented_matcher.rb +1 -1
  121. data/lib/super_diff/rspec/differ.rb +4 -5
  122. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +1 -1
  123. data/lib/super_diff/rspec/differs/collection_including.rb +1 -1
  124. data/lib/super_diff/rspec/differs/hash_including.rb +1 -1
  125. data/lib/super_diff/rspec/differs/object_having_attributes.rb +1 -1
  126. data/lib/super_diff/rspec/inspection_tree_builders/collection_containing_exactly.rb +34 -0
  127. data/lib/super_diff/rspec/inspection_tree_builders/collection_including.rb +40 -0
  128. data/lib/super_diff/rspec/inspection_tree_builders/double.rb +100 -0
  129. data/lib/super_diff/rspec/inspection_tree_builders/generic_describable_matcher.rb +17 -0
  130. data/lib/super_diff/rspec/inspection_tree_builders/hash_including.rb +40 -0
  131. data/lib/super_diff/rspec/inspection_tree_builders/instance_of.rb +25 -0
  132. data/lib/super_diff/rspec/inspection_tree_builders/kind_of.rb +25 -0
  133. data/lib/super_diff/rspec/inspection_tree_builders/object_having_attributes.rb +34 -0
  134. data/lib/super_diff/rspec/inspection_tree_builders/primitive.rb +9 -0
  135. data/lib/super_diff/rspec/inspection_tree_builders/value_within.rb +30 -0
  136. data/lib/super_diff/rspec/inspection_tree_builders.rb +40 -0
  137. data/lib/super_diff/rspec/object_inspection.rb +14 -4
  138. data/lib/super_diff/rspec/operation_tree_builders/collection_containing_exactly.rb +4 -4
  139. data/lib/super_diff/rspec/operation_tree_builders/collection_including.rb +1 -1
  140. data/lib/super_diff/rspec/operation_tree_builders/hash_including.rb +1 -1
  141. data/lib/super_diff/rspec/operation_tree_builders/object_having_attributes.rb +2 -2
  142. data/lib/super_diff/rspec.rb +20 -18
  143. data/lib/super_diff/version.rb +1 -1
  144. data/lib/super_diff.rb +69 -21
  145. data/spec/examples.txt +704 -543
  146. data/spec/support/integration/helpers.rb +4 -1
  147. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +1 -1
  148. data/spec/support/models/active_record/person.rb +8 -1
  149. data/spec/support/shared_examples/active_record.rb +5 -5
  150. data/spec/support/unit/helpers.rb +12 -1
  151. data/spec/support/unit/matchers/be_deprecated_in_favor_of.rb +39 -0
  152. data/spec/unit/active_record/object_inspection_spec.rb +5 -5
  153. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/array_spec.rb +8 -8
  154. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/custom_object_spec.rb +9 -9
  155. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/default_object_spec.rb +9 -9
  156. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/hash_spec.rb +8 -8
  157. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/multiline_string_spec.rb +4 -4
  158. data/spec/unit/{helpers_spec.rb → core/helpers_spec.rb} +2 -2
  159. data/spec/unit/{tiered_lines_elider_spec.rb → core/tiered_lines_elider_spec.rb} +2 -2
  160. data/spec/unit/{tiered_lines_formatter_spec.rb → core/tiered_lines_formatter_spec.rb} +1 -1
  161. data/spec/unit/deprecations_spec.rb +176 -0
  162. data/spec/unit/equality_matchers/main_spec.rb +5 -5
  163. data/super_diff.gemspec +6 -0
  164. metadata +127 -115
  165. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders/active_record_model.rb +0 -51
  166. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders/active_record_relation.rb +0 -36
  167. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders.rb +0 -16
  168. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders/hash_with_indifferent_access.rb +0 -46
  169. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders/ordered_options.rb +0 -46
  170. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders.rb +0 -16
  171. data/lib/super_diff/colorized_document_extensions.rb +0 -18
  172. data/lib/super_diff/configuration.rb +0 -149
  173. data/lib/super_diff/diff_formatters/collection.rb +0 -132
  174. data/lib/super_diff/diff_formatters/multiline_string.rb +0 -31
  175. data/lib/super_diff/differs/array.rb +0 -15
  176. data/lib/super_diff/differs/custom_object.rb +0 -17
  177. data/lib/super_diff/differs/date_like.rb +0 -15
  178. data/lib/super_diff/differs/default_object.rb +0 -19
  179. data/lib/super_diff/differs/defaults.rb +0 -13
  180. data/lib/super_diff/differs/empty.rb +0 -13
  181. data/lib/super_diff/differs/hash.rb +0 -15
  182. data/lib/super_diff/differs/main.rb +0 -31
  183. data/lib/super_diff/differs/multiline_string.rb +0 -16
  184. data/lib/super_diff/differs/time_like.rb +0 -15
  185. data/lib/super_diff/gem_version.rb +0 -45
  186. data/lib/super_diff/helpers.rb +0 -86
  187. data/lib/super_diff/implementation_checks.rb +0 -19
  188. data/lib/super_diff/line.rb +0 -83
  189. data/lib/super_diff/object_inspection/inspection_tree_builders/base.rb +0 -27
  190. data/lib/super_diff/object_inspection/inspection_tree_builders/defaults.rb +0 -15
  191. data/lib/super_diff/object_inspection/inspection_tree_builders/main.rb +0 -30
  192. data/lib/super_diff/object_inspection/inspection_tree_builders.rb +0 -48
  193. data/lib/super_diff/object_inspection/nodes.rb +0 -50
  194. data/lib/super_diff/object_inspection/prefix_for_next_node.rb +0 -6
  195. data/lib/super_diff/object_inspection/prelude_for_next_node.rb +0 -6
  196. data/lib/super_diff/operation_tree_builders/array.rb +0 -107
  197. data/lib/super_diff/operation_tree_builders/custom_object.rb +0 -40
  198. data/lib/super_diff/operation_tree_builders/date_like.rb +0 -15
  199. data/lib/super_diff/operation_tree_builders/default_object.rb +0 -119
  200. data/lib/super_diff/operation_tree_builders/defaults.rb +0 -5
  201. data/lib/super_diff/operation_tree_builders/hash.rb +0 -218
  202. data/lib/super_diff/operation_tree_builders/multiline_string.rb +0 -86
  203. data/lib/super_diff/operation_tree_builders/time_like.rb +0 -24
  204. data/lib/super_diff/operation_tree_flatteners/array.rb +0 -15
  205. data/lib/super_diff/operation_tree_flatteners/collection.rb +0 -136
  206. data/lib/super_diff/operation_tree_flatteners/custom_object.rb +0 -28
  207. data/lib/super_diff/operation_tree_flatteners/default_object.rb +0 -31
  208. data/lib/super_diff/operation_tree_flatteners/hash.rb +0 -33
  209. data/lib/super_diff/operation_tree_flatteners/multiline_string.rb +0 -18
  210. data/lib/super_diff/operation_trees/array.rb +0 -15
  211. data/lib/super_diff/operation_trees/custom_object.rb +0 -15
  212. data/lib/super_diff/operation_trees/default_object.rb +0 -40
  213. data/lib/super_diff/operation_trees/defaults.rb +0 -5
  214. data/lib/super_diff/operation_trees/hash.rb +0 -15
  215. data/lib/super_diff/operation_trees/main.rb +0 -35
  216. data/lib/super_diff/operation_trees/multiline_string.rb +0 -15
  217. data/lib/super_diff/recursion_guard.rb +0 -50
  218. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/collection_containing_exactly.rb +0 -36
  219. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/collection_including.rb +0 -42
  220. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/double.rb +0 -102
  221. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/generic_describable_matcher.rb +0 -19
  222. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/hash_including.rb +0 -42
  223. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/instance_of.rb +0 -27
  224. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/kind_of.rb +0 -27
  225. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/object_having_attributes.rb +0 -36
  226. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/primitive.rb +0 -10
  227. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/value_within.rb +0 -32
  228. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders.rb +0 -48
  229. data/lib/super_diff/tiered_lines.rb +0 -4
  230. data/lib/super_diff/tiered_lines_elider.rb +0 -462
  231. data/lib/super_diff/tiered_lines_formatter.rb +0 -75
@@ -0,0 +1,140 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTreeFlatteners
4
+ class Collection < Core::AbstractOperationTreeFlattener
5
+ protected
6
+
7
+ def build_tiered_lines
8
+ [
9
+ Core::Line.new(
10
+ type: :noop,
11
+ indentation_level: indentation_level,
12
+ value: open_token,
13
+ collection_bookend: :open
14
+ ),
15
+ *inner_lines,
16
+ Core::Line.new(
17
+ type: :noop,
18
+ indentation_level: indentation_level,
19
+ value: close_token,
20
+ collection_bookend: :close
21
+ )
22
+ ]
23
+ end
24
+
25
+ def inner_lines
26
+ @_inner_lines ||=
27
+ operation_tree.flat_map do |operation|
28
+ lines =
29
+ if operation.name == :change
30
+ build_lines_for_change_operation(operation)
31
+ else
32
+ build_lines_for_non_change_operation(operation)
33
+ end
34
+
35
+ maybe_add_prefix_at_beginning_of_lines(
36
+ maybe_add_comma_at_end_of_lines(lines, operation),
37
+ operation
38
+ )
39
+ end
40
+ end
41
+
42
+ def maybe_add_prefix_at_beginning_of_lines(lines, operation)
43
+ if add_prefix_at_beginning_of_lines?(operation)
44
+ add_prefix_at_beginning_of_lines(lines, operation)
45
+ else
46
+ lines
47
+ end
48
+ end
49
+
50
+ def add_prefix_at_beginning_of_lines?(operation)
51
+ !!item_prefix_for(operation)
52
+ end
53
+
54
+ def add_prefix_at_beginning_of_lines(lines, operation)
55
+ [lines[0].prefixed_with(item_prefix_for(operation))] + lines[1..-1]
56
+ end
57
+
58
+ def maybe_add_comma_at_end_of_lines(lines, operation)
59
+ if last_item_in_collection?(operation)
60
+ lines
61
+ else
62
+ add_comma_at_end_of_lines(lines)
63
+ end
64
+ end
65
+
66
+ def last_item_in_collection?(operation)
67
+ if operation.name == :change
68
+ operation.left_index == operation.left_collection.size - 1 &&
69
+ operation.right_index == operation.right_collection.size - 1
70
+ else
71
+ operation.index == operation.collection.size - 1
72
+ end
73
+ end
74
+
75
+ def add_comma_at_end_of_lines(lines)
76
+ lines[0..-2] + [lines[-1].with_comma]
77
+ end
78
+
79
+ def build_lines_for_change_operation(operation)
80
+ Core::RecursionGuard.guarding_recursion_of(
81
+ operation.left_collection,
82
+ operation.right_collection
83
+ ) do |already_seen|
84
+ if already_seen
85
+ raise InfiniteRecursionError
86
+ else
87
+ operation.children.flatten(
88
+ indentation_level: indentation_level + 1
89
+ )
90
+ end
91
+ end
92
+ end
93
+
94
+ def build_lines_for_non_change_operation(operation)
95
+ indentation_level = @indentation_level + 1
96
+
97
+ if recursive_operation?(operation)
98
+ [
99
+ Core::Line.new(
100
+ type: operation.name,
101
+ indentation_level: indentation_level,
102
+ value: Core::RecursionGuard::PLACEHOLDER
103
+ )
104
+ ]
105
+ else
106
+ build_lines_from_inspection_of(
107
+ operation.value,
108
+ type: operation.name,
109
+ indentation_level: indentation_level
110
+ )
111
+ end
112
+ end
113
+
114
+ def recursive_operation?(operation)
115
+ operation.value.equal?(operation.collection) ||
116
+ Core::RecursionGuard.already_seen?(operation.value)
117
+ end
118
+
119
+ def item_prefix_for(_operation)
120
+ ""
121
+ end
122
+
123
+ def build_lines_from_inspection_of(value, type:, indentation_level:)
124
+ SuperDiff.inspect_object(
125
+ value,
126
+ as_lines: true,
127
+ type: type,
128
+ indentation_level: indentation_level
129
+ )
130
+ end
131
+
132
+ class InfiniteRecursionError < StandardError
133
+ def initialize(_message = nil)
134
+ super("Unhandled recursive data structure encountered!")
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,30 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTreeFlatteners
4
+ class CustomObject < Collection
5
+ protected
6
+
7
+ def open_token
8
+ "#<%<class>s {" % { class: operation_tree.underlying_object.class }
9
+ end
10
+
11
+ def close_token
12
+ "}>"
13
+ end
14
+
15
+ def item_prefix_for(operation)
16
+ key =
17
+ # Note: We could have used the right_key here too, they're both the
18
+ # same keys
19
+ if operation.respond_to?(:left_key)
20
+ operation.left_key
21
+ else
22
+ operation.key
23
+ end
24
+
25
+ "#{key}: "
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTreeFlatteners
4
+ class DefaultObject < Collection
5
+ protected
6
+
7
+ def open_token
8
+ "#<#{operation_tree.underlying_object.class.name}:" +
9
+ Core::Helpers.object_address_for(operation_tree.underlying_object) +
10
+ " {"
11
+ end
12
+
13
+ def close_token
14
+ "}>"
15
+ end
16
+
17
+ def item_prefix_for(operation)
18
+ key =
19
+ # Note: We could have used the right_key here too, they're both the
20
+ # same keys
21
+ if operation.respond_to?(:left_key)
22
+ operation.left_key
23
+ else
24
+ operation.key
25
+ end
26
+
27
+ "@#{key}="
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTreeFlatteners
4
+ class Hash < Collection
5
+ protected
6
+
7
+ def open_token
8
+ "{"
9
+ end
10
+
11
+ def close_token
12
+ "}"
13
+ end
14
+
15
+ def item_prefix_for(operation)
16
+ key = key_for(operation)
17
+
18
+ format_keys_as_kwargs? ? "#{key}: " : "#{key.inspect} => "
19
+ end
20
+
21
+ private
22
+
23
+ def format_keys_as_kwargs?
24
+ operation_tree.all? { |operation| key_for(operation).is_a?(Symbol) }
25
+ end
26
+
27
+ def key_for(operation)
28
+ # Note: We could have used the right_key here too, they're both the
29
+ # same keys
30
+ operation.respond_to?(:left_key) ? operation.left_key : operation.key
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTreeFlatteners
4
+ class MultilineString < Core::AbstractOperationTreeFlattener
5
+ def build_tiered_lines
6
+ operation_tree.map do |operation|
7
+ Core::Line.new(
8
+ type: operation.name,
9
+ indentation_level: indentation_level,
10
+ # TODO: Test that quotes and things don't get escaped but escape
11
+ # characters do
12
+ value:
13
+ operation.value.inspect[1..-2].gsub(/\\"/, '"').gsub(/\\'/, "'")
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTreeFlatteners
4
+ autoload :Array, "super_diff/basic/operation_tree_flatteners/array"
5
+ autoload(
6
+ :Collection,
7
+ "super_diff/basic/operation_tree_flatteners/collection"
8
+ )
9
+ autoload(
10
+ :CustomObject,
11
+ "super_diff/basic/operation_tree_flatteners/custom_object"
12
+ )
13
+ autoload(
14
+ :DefaultObject,
15
+ "super_diff/basic/operation_tree_flatteners/default_object"
16
+ )
17
+ autoload :Hash, "super_diff/basic/operation_tree_flatteners/hash"
18
+ autoload(
19
+ :MultilineString,
20
+ "super_diff/basic/operation_tree_flatteners/multiline_string"
21
+ )
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTrees
4
+ class Array < Core::AbstractOperationTree
5
+ def self.applies_to?(value)
6
+ value.is_a?(::Array)
7
+ end
8
+
9
+ protected
10
+
11
+ def operation_tree_flattener_class
12
+ OperationTreeFlatteners::Array
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTrees
4
+ class CustomObject < DefaultObject
5
+ def self.applies_to?(value)
6
+ value.respond_to?(:attributes_for_super_diff)
7
+ end
8
+
9
+ protected
10
+
11
+ def operation_tree_flattener_class
12
+ OperationTreeFlatteners::CustomObject
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTrees
4
+ class DefaultObject < Core::AbstractOperationTree
5
+ def self.applies_to?(*)
6
+ true
7
+ end
8
+
9
+ attr_reader :underlying_object
10
+
11
+ def initialize(operations, underlying_object:)
12
+ super(operations)
13
+ @underlying_object = underlying_object
14
+ end
15
+
16
+ def pretty_print(pp)
17
+ pp.text "#<#{self.class.name} "
18
+ pp.nest(1) do
19
+ pp.breakable
20
+ pp.text ":operations=>"
21
+ pp.group(1, "[", "]") do
22
+ pp.breakable
23
+ pp.seplist(self) { |value| pp.pp value }
24
+ end
25
+ pp.comma_breakable
26
+ pp.text ":underlying_object=>"
27
+ pp.object_address_group underlying_object do
28
+ # do nothing
29
+ end
30
+ end
31
+ pp.text ">"
32
+ end
33
+
34
+ protected
35
+
36
+ def operation_tree_flattener_class
37
+ OperationTreeFlatteners::DefaultObject
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTrees
4
+ class Hash < Core::AbstractOperationTree
5
+ def self.applies_to?(value)
6
+ value.is_a?(::Hash)
7
+ end
8
+
9
+ protected
10
+
11
+ def operation_tree_flattener_class
12
+ OperationTreeFlatteners::Hash
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTrees
4
+ class MultilineString < Core::AbstractOperationTree
5
+ def self.applies_to?(value)
6
+ value.is_a?(::String) && value.is_a?(::String)
7
+ end
8
+
9
+ protected
10
+
11
+ def operation_tree_flattener_class
12
+ OperationTreeFlatteners::MultilineString
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ module SuperDiff
2
+ module Basic
3
+ module OperationTrees
4
+ autoload :Array, "super_diff/basic/operation_trees/array"
5
+ autoload :CustomObject, "super_diff/basic/operation_trees/custom_object"
6
+ autoload :DefaultObject, "super_diff/basic/operation_trees/default_object"
7
+ autoload :Hash, "super_diff/basic/operation_trees/hash"
8
+ autoload(
9
+ :MultilineString,
10
+ "super_diff/basic/operation_trees/multiline_string"
11
+ )
12
+
13
+ class Main
14
+ def self.call(*args)
15
+ warn <<~EOT
16
+ WARNING: SuperDiff::OperationTrees::Main.call(...) is deprecated and will be removed in the next major release.
17
+ Please use SuperDiff.find_operation_tree_for(...) instead.
18
+ #{caller_locations.join("\n")}
19
+ EOT
20
+ SuperDiff.find_operation_tree_for(*args)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,48 @@
1
+ require "super_diff/basic/differs"
2
+ require "super_diff/basic/inspection_tree_builders"
3
+ require "super_diff/basic/operation_tree_builders"
4
+ require "super_diff/basic/operation_tree_flatteners"
5
+ require "super_diff/basic/operation_trees"
6
+
7
+ module SuperDiff
8
+ module Basic
9
+ autoload :DiffFormatters, "super_diff/basic/diff_formatters"
10
+
11
+ SuperDiff.configuration.tap do |config|
12
+ config.add_extra_differ_classes(
13
+ Differs::Array,
14
+ Differs::Hash,
15
+ Differs::TimeLike,
16
+ Differs::DateLike,
17
+ Differs::MultilineString,
18
+ Differs::CustomObject,
19
+ Differs::DefaultObject
20
+ )
21
+
22
+ config.add_extra_inspection_tree_builder_classes(
23
+ InspectionTreeBuilders::CustomObject,
24
+ InspectionTreeBuilders::Array,
25
+ InspectionTreeBuilders::Hash,
26
+ InspectionTreeBuilders::Primitive,
27
+ InspectionTreeBuilders::TimeLike,
28
+ InspectionTreeBuilders::DateLike,
29
+ InspectionTreeBuilders::DefaultObject
30
+ )
31
+
32
+ config.add_extra_operation_tree_builder_classes(
33
+ OperationTreeBuilders::Array,
34
+ OperationTreeBuilders::Hash,
35
+ OperationTreeBuilders::TimeLike,
36
+ OperationTreeBuilders::DateLike,
37
+ OperationTreeBuilders::CustomObject
38
+ )
39
+
40
+ config.add_extra_operation_tree_classes(
41
+ OperationTrees::Array,
42
+ OperationTrees::Hash,
43
+ OperationTrees::CustomObject,
44
+ OperationTrees::DefaultObject
45
+ )
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,6 @@
1
1
  module SuperDiff
2
- module Differs
3
- class Base
2
+ module Core
3
+ class AbstractDiffer
4
4
  def self.applies_to?(_expected, _actual)
5
5
  raise NotImplementedError
6
6
  end
@@ -0,0 +1,26 @@
1
+ module SuperDiff
2
+ module Core
3
+ class AbstractInspectionTreeBuilder
4
+ extend AttrExtras.mixin
5
+ extend ImplementationChecks
6
+ include ImplementationChecks
7
+ include Helpers
8
+
9
+ def self.applies_to?(_value)
10
+ unimplemented_class_method!
11
+ end
12
+
13
+ method_object :object
14
+
15
+ def call
16
+ unimplemented_instance_method!
17
+ end
18
+
19
+ protected
20
+
21
+ def inspection_tree
22
+ unimplemented_instance_method!
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,8 +1,8 @@
1
1
  require "forwardable"
2
2
 
3
3
  module SuperDiff
4
- module OperationTrees
5
- class Base
4
+ module Core
5
+ class AbstractOperationTree
6
6
  def self.applies_to?(*)
7
7
  unimplemented_class_method!
8
8
  end
@@ -46,6 +46,10 @@ module SuperDiff
46
46
  end
47
47
  end
48
48
 
49
+ def ==(other)
50
+ other.is_a?(self.class) && other.to_a == to_a
51
+ end
52
+
49
53
  private
50
54
 
51
55
  attr_reader :operations
@@ -1,6 +1,6 @@
1
1
  module SuperDiff
2
- module OperationTreeBuilders
3
- class Base
2
+ module Core
3
+ class AbstractOperationTreeBuilder
4
4
  def self.applies_to?(_expected, _actual)
5
5
  raise NotImplementedError
6
6
  end
@@ -48,7 +48,7 @@ module SuperDiff
48
48
  possible_comparison_of(delete_operation, insert_operation)
49
49
  )
50
50
  operation_tree.delete(delete_operation)
51
- operation_tree << Operations::BinaryOperation.new(
51
+ operation_tree << BinaryOperation.new(
52
52
  name: :change,
53
53
  left_collection: delete_operation.collection,
54
54
  right_collection: insert_operation.collection,
@@ -89,11 +89,7 @@ module SuperDiff
89
89
  end
90
90
 
91
91
  def compare(expected, actual)
92
- OperationTreeBuilders::Main.call(
93
- expected: expected,
94
- actual: actual,
95
- all_or_nothing: false
96
- )
92
+ SuperDiff.build_operation_tree_for(expected, actual)
97
93
  end
98
94
  end
99
95
  end
@@ -1,6 +1,6 @@
1
1
  module SuperDiff
2
- module OperationTreeFlatteners
3
- class Base
2
+ module Core
3
+ class AbstractOperationTreeFlattener
4
4
  include ImplementationChecks
5
5
  extend AttrExtras.mixin
6
6
 
@@ -1,5 +1,5 @@
1
1
  module SuperDiff
2
- module Operations
2
+ module Core
3
3
  class BinaryOperation
4
4
  extend AttrExtras.mixin
5
5
 
@@ -0,0 +1,20 @@
1
+ module SuperDiff
2
+ module Core
3
+ module ColorizedDocumentExtensions
4
+ def self.extended(extendee)
5
+ extendee.singleton_class.class_eval { alias_method :normal, :text }
6
+ end
7
+
8
+ %i[actual border elision_marker expected header].each do |method_name|
9
+ define_method(method_name) do |*args, **opts, &block|
10
+ colorize(
11
+ *args,
12
+ **opts,
13
+ fg: SuperDiff.configuration.public_send("#{method_name}_color"),
14
+ &block
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end