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
@@ -1,15 +1,18 @@
1
1
  module SuperDiff
2
2
  module ObjectInspection
3
3
  autoload :InspectionTree, "super_diff/object_inspection/inspection_tree"
4
- autoload :Inspectors, "super_diff/object_inspection/inspectors"
4
+ autoload(
5
+ :InspectionTreeBuilders,
6
+ "super_diff/object_inspection/inspection_tree_builders",
7
+ )
5
8
  autoload :Nodes, "super_diff/object_inspection/nodes"
6
-
7
- def self.inspect(object, as_single_line:, indent_level: 0)
8
- Inspectors::Main.call(
9
- object,
10
- as_single_line: as_single_line,
11
- indent_level: indent_level,
12
- )
13
- end
9
+ autoload(
10
+ :PrefixForNextNode,
11
+ "super_diff/object_inspection/prefix_for_next_node",
12
+ )
13
+ autoload(
14
+ :PreludeForNextNode,
15
+ "super_diff/object_inspection/prelude_for_next_node",
16
+ )
14
17
  end
15
18
  end
@@ -3,7 +3,8 @@ module SuperDiff
3
3
  class InspectionTree
4
4
  include Enumerable
5
5
 
6
- def initialize(&block)
6
+ def initialize(disallowed_node_names: [], &block)
7
+ @disallowed_node_names = disallowed_node_names
7
8
  @nodes = []
8
9
 
9
10
  if block
@@ -11,6 +12,12 @@ module SuperDiff
11
12
  end
12
13
  end
13
14
 
15
+ Nodes.registry.each do |node_class|
16
+ define_method(node_class.method_name) do |*args, **options, &block|
17
+ add_node(node_class, *args, **options, &block)
18
+ end
19
+ end
20
+
14
21
  def each(&block)
15
22
  nodes.each(&block)
16
23
  end
@@ -19,129 +26,224 @@ module SuperDiff
19
26
  @_before_each_callbacks ||= Hash.new { |h, k| h[k] = [] }
20
27
  end
21
28
 
22
- def evaluate(object, as_single_line:, indent_level:)
23
- nodes.reduce("") do |str, node|
24
- str << node.evaluate(
25
- object,
26
- as_single_line: as_single_line,
27
- indent_level: indent_level,
28
- )
29
+ def render_to_string(object)
30
+ nodes.reduce("") do |string, node|
31
+ result = node.render_to_string(object)
32
+ string + result
29
33
  end
30
34
  end
31
35
 
32
- def evaluate_block(object, &block)
33
- instance_exec(object, &block)
34
- end
35
-
36
- def add_text(*args, &block)
37
- add_node :text, *args, &block
38
- end
39
-
40
- def when_multiline(&block)
41
- add_node :when_multiline, &block
42
- end
43
-
44
- def when_singleline(&block)
45
- add_node :when_singleline, &block
46
- end
47
-
48
- def add_break(*args, &block)
49
- add_node :break, *args, &block
50
- end
51
-
52
- def nested(&block)
53
- add_node :nesting, &block
54
- end
55
-
56
- def when_empty(&block)
57
- add_node :when_empty, &block
36
+ def render_to_lines(object, type:, indentation_level:)
37
+ nodes.
38
+ each_with_index.
39
+ reduce([TieredLines.new, "", ""]) do |
40
+ (tiered_lines, prelude, prefix),
41
+ (node, index)
42
+ |
43
+ UpdateTieredLines.call(
44
+ object: object,
45
+ type: type,
46
+ indentation_level: indentation_level,
47
+ nodes: nodes,
48
+ tiered_lines: tiered_lines,
49
+ prelude: prelude,
50
+ prefix: prefix,
51
+ node: node,
52
+ index: index,
53
+ )
54
+ end.
55
+ first
58
56
  end
59
57
 
60
- def when_non_empty(&block)
61
- add_node :when_non_empty, &block
58
+ def evaluate_block(object, &block)
59
+ instance_exec(object, &block)
62
60
  end
63
61
 
64
62
  def insert_array_inspection_of(array)
65
- # FIXME: why must this be inside the `nested`?
66
- add_break
67
-
68
63
  insert_separated_list(array) do |value|
69
- add_inspection_of value
64
+ # Have to do these shenanigans so that if value is a hash, Ruby
65
+ # doesn't try to interpret it as keyword args
66
+ if SuperDiff::Helpers.ruby_version_matches?(">= 2.7.1")
67
+ add_inspection_of(value, **{})
68
+ else
69
+ add_inspection_of(*[value, {}])
70
+ end
70
71
  end
71
72
  end
72
73
 
73
- def insert_hash_inspection_of(hash, initial_break: " ")
74
- # FIXME: why must this be inside the `nested`?
75
- add_break initial_break
74
+ def insert_hash_inspection_of(hash)
75
+ keys = hash.keys
76
76
 
77
- format_keys_as_kwargs = hash.keys.all? do |key|
77
+ format_keys_as_kwargs = keys.all? do |key|
78
78
  key.is_a?(Symbol)
79
79
  end
80
80
 
81
- insert_separated_list(hash) do |(key, value)|
81
+ insert_separated_list(keys) do |key|
82
82
  if format_keys_as_kwargs
83
- add_text key
84
- add_text ": "
83
+ as_prefix_when_rendering_to_lines do
84
+ add_text "#{key}: "
85
+ end
85
86
  else
86
- add_inspection_of key
87
- add_text " => "
87
+ as_prefix_when_rendering_to_lines do
88
+ add_inspection_of key, as_lines: false
89
+ add_text " => "
90
+ end
88
91
  end
89
92
 
90
- add_inspection_of value
93
+ # Have to do these shenanigans so that if hash[key] is a hash, Ruby
94
+ # doesn't try to interpret it as keyword args
95
+ if SuperDiff::Helpers.ruby_version_matches?(">= 2.7.1")
96
+ add_inspection_of(hash[key], **{})
97
+ else
98
+ add_inspection_of(*[hash[key], {}])
99
+ end
91
100
  end
92
101
  end
93
102
 
94
- def insert_separated_list(enumerable, separator: ",")
103
+ def insert_separated_list(enumerable, &block)
95
104
  enumerable.each_with_index do |value, index|
96
- if index > 0
97
- if separator.is_a?(Nodes::Base)
98
- append_node separator
99
- else
100
- add_text separator
105
+ as_lines_when_rendering_to_lines(
106
+ add_comma: index < enumerable.size - 1,
107
+ ) do
108
+ if index > 0
109
+ when_rendering_to_string do
110
+ add_text " "
111
+ end
101
112
  end
102
113
 
103
- add_break " "
114
+ evaluate_block(value, &block)
104
115
  end
105
-
106
- yield value
107
- end
108
- end
109
-
110
- def add_inspection_of(value = nil, &block)
111
- if block
112
- add_node :inspection, &block
113
- else
114
- add_node :inspection, value
115
- end
116
- end
117
-
118
- def apply_tree(tree)
119
- tree.each do |node|
120
- append_node(node.clone_with(tree: self))
121
116
  end
122
117
  end
123
118
 
124
119
  private
125
120
 
126
- attr_reader :nodes
121
+ attr_reader :disallowed_node_names, :nodes
127
122
 
128
- def add_node(type, *args, &block)
129
- append_node(build_node(type, *args, &block))
123
+ def add_node(node_class, *args, **options, &block)
124
+ if disallowed_node_names.include?(node_class.name)
125
+ raise DisallowedNodeError.create(node_name: node_class.name)
126
+ end
127
+
128
+ append_node(build_node(node_class, *args, **options, &block))
130
129
  end
131
130
 
132
131
  def append_node(node)
133
132
  nodes.push(node)
134
133
  end
135
134
 
136
- def build_node(type, *args, &block)
137
- Nodes.fetch(type).new(self, *args, &block)
135
+ def build_node(node_class, *args, **options, &block)
136
+ node_class.new(self, *args, **options, &block)
138
137
  end
139
138
 
140
- class BlockArgument
139
+ class UpdateTieredLines
141
140
  extend AttrExtras.mixin
142
141
 
143
- rattr_initialize [:object!, :as_single_line!]
144
- attr_query :as_single_line?
142
+ method_object [
143
+ :object!,
144
+ :type!,
145
+ :indentation_level!,
146
+ :nodes!,
147
+ :tiered_lines!,
148
+ :prelude!,
149
+ :prefix!,
150
+ :node!,
151
+ :index!
152
+ ]
153
+
154
+ def call
155
+ if rendering.is_a?(Array)
156
+ concat_with_lines
157
+ elsif rendering.is_a?(PrefixForNextNode)
158
+ add_to_prefix
159
+ elsif tiered_lines.any?
160
+ add_to_last_line
161
+ elsif index < nodes.size - 1 || rendering.is_a?(PreludeForNextNode)
162
+ add_to_prelude
163
+ else
164
+ add_to_lines
165
+ end
166
+ end
167
+
168
+ private
169
+
170
+ def concat_with_lines
171
+ additional_lines = prefix_with(
172
+ prefix,
173
+ prepend_with(prelude, rendering),
174
+ )
175
+ [tiered_lines + additional_lines, "", ""]
176
+ end
177
+
178
+ def prefix_with(prefix, text)
179
+ if prefix.empty?
180
+ text
181
+ else
182
+ [text[0].prefixed_with(prefix)] + text[1..-1]
183
+ end
184
+ end
185
+
186
+ def prepend_with(prelude, text)
187
+ if prelude.empty?
188
+ text
189
+ else
190
+ [text[0].with_value_prepended(prelude)] + text[1..-1]
191
+ end
192
+ end
193
+
194
+ def add_to_prefix
195
+ [tiered_lines, prelude, rendering + prefix]
196
+ end
197
+
198
+ def add_to_last_line
199
+ new_lines = tiered_lines[0..-2] + [
200
+ tiered_lines[-1].with_value_appended(rendering),
201
+ ]
202
+ [new_lines, prelude, prefix]
203
+ end
204
+
205
+ def add_to_prelude
206
+ [tiered_lines, prelude + rendering, prefix]
207
+ end
208
+
209
+ def add_to_lines
210
+ new_lines = tiered_lines + [
211
+ Line.new(
212
+ type: type,
213
+ indentation_level: indentation_level,
214
+ value: rendering,
215
+ ),
216
+ ]
217
+ [new_lines, prelude, prefix]
218
+ end
219
+
220
+ def rendering
221
+ if defined?(@_rendering)
222
+ @_rendering
223
+ else
224
+ @_rendering = node.render(
225
+ object,
226
+ preferably_as_lines: true,
227
+ type: type,
228
+ indentation_level: indentation_level,
229
+ )
230
+ end
231
+ end
232
+ end
233
+
234
+ class DisallowedNodeError < StandardError
235
+ def self.create(node_name:)
236
+ allocate.tap do |error|
237
+ error.node_name = node_name
238
+ error.__send__(:initialize)
239
+ end
240
+ end
241
+
242
+ attr_accessor :node_name
243
+
244
+ def initialize(_message = nil)
245
+ super("#{node_name} is not allowed to be used here!")
246
+ end
145
247
  end
146
248
  end
147
249
  end
@@ -0,0 +1,44 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ module InspectionTreeBuilders
4
+ autoload(
5
+ :Base,
6
+ "super_diff/object_inspection/inspection_tree_builders/base",
7
+ )
8
+ autoload(
9
+ :Array,
10
+ "super_diff/object_inspection/inspection_tree_builders/array",
11
+ )
12
+ autoload(
13
+ :CustomObject,
14
+ "super_diff/object_inspection/inspection_tree_builders/custom_object",
15
+ )
16
+ autoload(
17
+ :DefaultObject,
18
+ "super_diff/object_inspection/inspection_tree_builders/default_object",
19
+ )
20
+ autoload(
21
+ :Hash,
22
+ "super_diff/object_inspection/inspection_tree_builders/hash",
23
+ )
24
+ autoload(
25
+ :Main,
26
+ "super_diff/object_inspection/inspection_tree_builders/main",
27
+ )
28
+ autoload(
29
+ :Primitive,
30
+ "super_diff/object_inspection/inspection_tree_builders/primitive",
31
+ )
32
+ autoload(
33
+ :String,
34
+ "super_diff/object_inspection/inspection_tree_builders/string",
35
+ )
36
+ autoload(
37
+ :TimeLike,
38
+ "super_diff/object_inspection/inspection_tree_builders/time_like",
39
+ )
40
+ end
41
+ end
42
+ end
43
+
44
+ require "super_diff/object_inspection/inspection_tree_builders/defaults"
@@ -0,0 +1,38 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ module InspectionTreeBuilders
4
+ class Array < Base
5
+ def self.applies_to?(value)
6
+ value.is_a?(::Array)
7
+ end
8
+
9
+ def call
10
+ empty = -> { object.empty? }
11
+ nonempty = -> { !object.empty? }
12
+
13
+ InspectionTree.new do
14
+ only_when empty do
15
+ as_lines_when_rendering_to_lines do
16
+ add_text "[]"
17
+ end
18
+ end
19
+
20
+ only_when nonempty do
21
+ as_lines_when_rendering_to_lines(collection_bookend: :open) do
22
+ add_text "["
23
+ end
24
+
25
+ nested do |array|
26
+ insert_array_inspection_of(array)
27
+ end
28
+
29
+ as_lines_when_rendering_to_lines(collection_bookend: :close) do
30
+ add_text "]"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,27 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ module InspectionTreeBuilders
4
+ class Base
5
+ extend AttrExtras.mixin
6
+ extend ImplementationChecks
7
+ include ImplementationChecks
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
27
+ end