super_diff 0.1.0 → 0.2.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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +117 -89
  3. data/lib/super_diff.rb +33 -47
  4. data/lib/super_diff/active_record.rb +41 -0
  5. data/lib/super_diff/active_record/diff_formatters.rb +10 -0
  6. data/lib/super_diff/active_record/diff_formatters/active_record_relation.rb +23 -0
  7. data/lib/super_diff/active_record/differs.rb +10 -0
  8. data/lib/super_diff/active_record/differs/active_record_relation.rb +30 -0
  9. data/lib/super_diff/active_record/object_inspection.rb +14 -0
  10. data/lib/super_diff/active_record/object_inspection/inspectors.rb +16 -0
  11. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_model.rb +38 -0
  12. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_relation.rb +18 -0
  13. data/lib/super_diff/active_record/object_inspection/map_extension.rb +18 -0
  14. data/lib/super_diff/active_record/operation_sequences.rb +10 -0
  15. data/lib/super_diff/active_record/operation_sequences/active_record_relation.rb +16 -0
  16. data/lib/super_diff/active_record/operational_sequencers.rb +14 -0
  17. data/lib/super_diff/active_record/operational_sequencers/active_record_model.rb +19 -0
  18. data/lib/super_diff/active_record/operational_sequencers/active_record_relation.rb +24 -0
  19. data/lib/super_diff/active_support.rb +33 -0
  20. data/lib/super_diff/active_support/diff_formatters.rb +10 -0
  21. data/lib/super_diff/active_support/diff_formatters/hash_with_indifferent_access.rb +36 -0
  22. data/lib/super_diff/active_support/differs.rb +10 -0
  23. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +36 -0
  24. data/lib/super_diff/active_support/object_inspection.rb +14 -0
  25. data/lib/super_diff/active_support/object_inspection/inspectors.rb +12 -0
  26. data/lib/super_diff/active_support/object_inspection/inspectors/hash_with_indifferent_access.rb +18 -0
  27. data/lib/super_diff/active_support/object_inspection/map_extension.rb +15 -0
  28. data/lib/super_diff/active_support/operation_sequences.rb +10 -0
  29. data/lib/super_diff/active_support/operation_sequences/hash_with_indifferent_access.rb +16 -0
  30. data/lib/super_diff/active_support/operational_sequencers.rb +10 -0
  31. data/lib/super_diff/active_support/operational_sequencers/hash_with_indifferent_access.rb +21 -0
  32. data/lib/super_diff/colorized_document_extensions.rb +17 -0
  33. data/lib/super_diff/csi.rb +45 -15
  34. data/lib/super_diff/csi/bold_sequence.rb +9 -0
  35. data/lib/super_diff/csi/color.rb +62 -0
  36. data/lib/super_diff/csi/color_sequence_block.rb +28 -0
  37. data/lib/super_diff/csi/colorized_document.rb +72 -0
  38. data/lib/super_diff/csi/document.rb +183 -0
  39. data/lib/super_diff/csi/eight_bit_color.rb +72 -26
  40. data/lib/super_diff/csi/four_bit_color.rb +63 -29
  41. data/lib/super_diff/csi/twenty_four_bit_color.rb +79 -18
  42. data/lib/super_diff/csi/uncolorized_document.rb +29 -0
  43. data/lib/super_diff/diff_formatter.rb +10 -15
  44. data/lib/super_diff/diff_formatters.rb +10 -1
  45. data/lib/super_diff/diff_formatters/base.rb +12 -17
  46. data/lib/super_diff/diff_formatters/collection.rb +81 -50
  47. data/lib/super_diff/diff_formatters/{object.rb → custom_object.rb} +12 -9
  48. data/lib/super_diff/diff_formatters/default_object.rb +48 -0
  49. data/lib/super_diff/diff_formatters/multiline_string.rb +31 -0
  50. data/lib/super_diff/differ.rb +35 -32
  51. data/lib/super_diff/differs.rb +16 -1
  52. data/lib/super_diff/differs/array.rb +2 -2
  53. data/lib/super_diff/differs/base.rb +11 -21
  54. data/lib/super_diff/differs/custom_object.rb +26 -0
  55. data/lib/super_diff/differs/default_object.rb +25 -0
  56. data/lib/super_diff/differs/empty.rb +1 -1
  57. data/lib/super_diff/differs/hash.rb +2 -2
  58. data/lib/super_diff/differs/{multi_line_string.rb → multiline_string.rb} +6 -5
  59. data/lib/super_diff/equality_matcher.rb +9 -22
  60. data/lib/super_diff/equality_matchers.rb +19 -1
  61. data/lib/super_diff/equality_matchers/array.rb +6 -4
  62. data/lib/super_diff/equality_matchers/base.rb +8 -16
  63. data/lib/super_diff/equality_matchers/default.rb +60 -0
  64. data/lib/super_diff/equality_matchers/hash.rb +6 -4
  65. data/lib/super_diff/equality_matchers/{multi_line_string.rb → multiline_string.rb} +9 -6
  66. data/lib/super_diff/equality_matchers/primitive.rb +34 -0
  67. data/lib/super_diff/equality_matchers/{single_line_string.rb → singleline_string.rb} +7 -5
  68. data/lib/super_diff/helpers.rb +17 -81
  69. data/lib/super_diff/no_differ_available_error.rb +22 -0
  70. data/lib/super_diff/{errors.rb → no_operational_sequencer_available_error.rb} +0 -0
  71. data/lib/super_diff/object_inspection.rb +24 -0
  72. data/lib/super_diff/object_inspection/inspection_tree.rb +144 -0
  73. data/lib/super_diff/object_inspection/inspector.rb +27 -0
  74. data/lib/super_diff/object_inspection/inspectors.rb +18 -0
  75. data/lib/super_diff/object_inspection/inspectors/array.rb +22 -0
  76. data/lib/super_diff/object_inspection/inspectors/custom_object.rb +27 -0
  77. data/lib/super_diff/object_inspection/inspectors/default_object.rb +47 -0
  78. data/lib/super_diff/object_inspection/inspectors/hash.rb +22 -0
  79. data/lib/super_diff/object_inspection/inspectors/primitive.rb +13 -0
  80. data/lib/super_diff/object_inspection/inspectors/string.rb +13 -0
  81. data/lib/super_diff/object_inspection/map.rb +28 -0
  82. data/lib/super_diff/object_inspection/nodes.rb +49 -0
  83. data/lib/super_diff/object_inspection/nodes/base.rb +86 -0
  84. data/lib/super_diff/object_inspection/nodes/break.rb +15 -0
  85. data/lib/super_diff/object_inspection/nodes/inspection.rb +15 -0
  86. data/lib/super_diff/object_inspection/nodes/nesting.rb +16 -0
  87. data/lib/super_diff/object_inspection/nodes/text.rb +15 -0
  88. data/lib/super_diff/object_inspection/nodes/when_empty.rb +30 -0
  89. data/lib/super_diff/object_inspection/nodes/when_multiline.rb +22 -0
  90. data/lib/super_diff/object_inspection/nodes/when_non_empty.rb +30 -0
  91. data/lib/super_diff/object_inspection/nodes/when_singleline.rb +24 -0
  92. data/lib/super_diff/operation_sequences.rb +9 -0
  93. data/lib/super_diff/operation_sequences/base.rb +1 -1
  94. data/lib/super_diff/operation_sequences/{object.rb → custom_object.rb} +4 -3
  95. data/lib/super_diff/operation_sequences/default_object.rb +25 -0
  96. data/lib/super_diff/operational_sequencer.rb +23 -18
  97. data/lib/super_diff/operational_sequencers.rb +12 -1
  98. data/lib/super_diff/operational_sequencers/array.rb +65 -62
  99. data/lib/super_diff/operational_sequencers/base.rb +18 -26
  100. data/lib/super_diff/operational_sequencers/custom_object.rb +35 -0
  101. data/lib/super_diff/operational_sequencers/{object.rb → default_object.rb} +21 -11
  102. data/lib/super_diff/operational_sequencers/hash.rb +8 -5
  103. data/lib/super_diff/operational_sequencers/{multi_line_string.rb → multiline_string.rb} +11 -6
  104. data/lib/super_diff/operations.rb +6 -0
  105. data/lib/super_diff/operations/binary_operation.rb +14 -34
  106. data/lib/super_diff/operations/unary_operation.rb +11 -2
  107. data/lib/super_diff/rails.rb +1 -0
  108. data/lib/super_diff/recursion_guard.rb +47 -0
  109. data/lib/super_diff/rspec-rails.rb +2 -0
  110. data/lib/super_diff/rspec.rb +52 -8
  111. data/lib/super_diff/rspec/augmented_matcher.rb +98 -0
  112. data/lib/super_diff/rspec/configuration.rb +31 -0
  113. data/lib/super_diff/rspec/differ.rb +60 -16
  114. data/lib/super_diff/rspec/differs.rb +13 -0
  115. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +23 -0
  116. data/lib/super_diff/rspec/differs/partial_array.rb +22 -0
  117. data/lib/super_diff/rspec/differs/partial_hash.rb +22 -0
  118. data/lib/super_diff/rspec/differs/partial_object.rb +22 -0
  119. data/lib/super_diff/rspec/matcher_text_builders.rb +24 -0
  120. data/lib/super_diff/rspec/matcher_text_builders/base.rb +155 -0
  121. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +78 -0
  122. data/lib/super_diff/rspec/matcher_text_builders/contain_exactly.rb +14 -0
  123. data/lib/super_diff/rspec/matcher_text_builders/match.rb +23 -0
  124. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +13 -0
  125. data/lib/super_diff/rspec/matcher_text_builders/respond_to.rb +99 -0
  126. data/lib/super_diff/rspec/matcher_text_template.rb +240 -0
  127. data/lib/super_diff/rspec/monkey_patches.rb +601 -98
  128. data/lib/super_diff/rspec/object_inspection.rb +8 -0
  129. data/lib/super_diff/rspec/object_inspection/inspectors.rb +24 -0
  130. data/lib/super_diff/rspec/object_inspection/inspectors/collection_containing_exactly.rb +19 -0
  131. data/lib/super_diff/rspec/object_inspection/inspectors/partial_array.rb +22 -0
  132. data/lib/super_diff/rspec/object_inspection/inspectors/partial_hash.rb +21 -0
  133. data/lib/super_diff/rspec/object_inspection/inspectors/partial_object.rb +21 -0
  134. data/lib/super_diff/rspec/object_inspection/map_extension.rb +23 -0
  135. data/lib/super_diff/rspec/operational_sequencers.rb +22 -0
  136. data/lib/super_diff/rspec/operational_sequencers/collection_containing_exactly.rb +97 -0
  137. data/lib/super_diff/rspec/operational_sequencers/partial_array.rb +23 -0
  138. data/lib/super_diff/rspec/operational_sequencers/partial_hash.rb +32 -0
  139. data/lib/super_diff/rspec/operational_sequencers/partial_object.rb +64 -0
  140. data/lib/super_diff/version.rb +1 -1
  141. data/spec/examples.txt +328 -46
  142. data/spec/integration/rails/active_record_spec.rb +19 -0
  143. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +19 -0
  144. data/spec/integration/rspec/be_falsey_matcher_spec.rb +53 -0
  145. data/spec/integration/rspec/be_matcher_spec.rb +565 -0
  146. data/spec/integration/rspec/be_nil_matcher_spec.rb +53 -0
  147. data/spec/integration/rspec/be_predicate_matcher_spec.rb +546 -0
  148. data/spec/integration/rspec/be_truthy_matcher_spec.rb +57 -0
  149. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +368 -0
  150. data/spec/integration/rspec/eq_matcher_spec.rb +874 -0
  151. data/spec/integration/rspec/have_attributes_matcher_spec.rb +299 -0
  152. data/spec/integration/rspec/include_matcher_spec.rb +350 -0
  153. data/spec/integration/rspec/match_matcher_spec.rb +1258 -0
  154. data/spec/integration/rspec/raise_error_matcher_spec.rb +350 -0
  155. data/spec/integration/rspec/respond_to_matcher_spec.rb +994 -0
  156. data/spec/integration/rspec/unhandled_errors_spec.rb +94 -0
  157. data/spec/spec_helper.rb +19 -4
  158. data/spec/support/colorizer.rb +9 -0
  159. data/spec/support/command_runner.rb +4 -0
  160. data/spec/support/integration/helpers.rb +179 -0
  161. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +79 -41
  162. data/spec/support/models/a.rb +11 -0
  163. data/spec/support/models/active_record/person.rb +26 -0
  164. data/spec/support/models/active_record/shipping_address.rb +29 -0
  165. data/spec/support/models/customer.rb +24 -0
  166. data/spec/support/models/empty_class.rb +6 -0
  167. data/spec/support/models/item.rb +10 -0
  168. data/spec/support/models/order.rb +9 -0
  169. data/spec/support/models/person.rb +20 -0
  170. data/spec/support/models/player.rb +33 -0
  171. data/spec/support/models/shipping_address.rb +34 -0
  172. data/spec/support/ruby_versions.rb +7 -0
  173. data/spec/support/shared_examples/active_record.rb +338 -0
  174. data/spec/support/shared_examples/hash_with_indifferent_access.rb +233 -0
  175. data/spec/unit/equality_matcher_spec.rb +579 -171
  176. data/spec/unit/object_inspection_spec.rb +1092 -0
  177. data/spec/unit/rspec/matchers/be_compared_to_spec.rb +23 -0
  178. data/spec/unit/rspec/matchers/be_falsey_spec.rb +9 -0
  179. data/spec/unit/rspec/matchers/be_nil_spec.rb +9 -0
  180. data/spec/unit/rspec/matchers/be_predicate_spec.rb +31 -0
  181. data/spec/unit/rspec/matchers/be_spec.rb +17 -0
  182. data/spec/unit/rspec/matchers/be_truthy_spec.rb +9 -0
  183. data/spec/unit/rspec/matchers/contain_exactly_spec.rb +11 -0
  184. data/spec/unit/rspec/matchers/eq_spec.rb +9 -0
  185. data/spec/unit/rspec/matchers/have_attributes_spec.rb +11 -0
  186. data/spec/unit/rspec/matchers/include_spec.rb +21 -0
  187. data/spec/unit/rspec/matchers/match_spec.rb +9 -0
  188. data/spec/unit/rspec/matchers/raise_error_spec.rb +29 -0
  189. data/spec/unit/rspec/matchers/respond_to_spec.rb +78 -0
  190. data/super_diff.gemspec +4 -2
  191. metadata +231 -34
  192. data/lib/super_diff/csi/color_helper.rb +0 -52
  193. data/lib/super_diff/csi/eight_bit_sequence.rb +0 -27
  194. data/lib/super_diff/csi/four_bit_sequence.rb +0 -24
  195. data/lib/super_diff/csi/sequence.rb +0 -22
  196. data/lib/super_diff/csi/twenty_four_bit_sequence.rb +0 -27
  197. data/lib/super_diff/diff_formatters/multi_line_string.rb +0 -31
  198. data/lib/super_diff/differs/object.rb +0 -68
  199. data/lib/super_diff/equality_matchers/object.rb +0 -18
  200. data/lib/super_diff/value_inspection.rb +0 -11
  201. data/spec/integration/rspec_spec.rb +0 -261
  202. data/spec/support/color_helper.rb +0 -49
  203. data/spec/support/person.rb +0 -23
  204. data/spec/support/person_diff_formatter.rb +0 -15
  205. data/spec/support/person_operation_sequence.rb +0 -14
  206. data/spec/support/person_operational_sequencer.rb +0 -19
@@ -1,6 +1,6 @@
1
1
  module SuperDiff
2
2
  module EqualityMatchers
3
- class SingleLineString < Base
3
+ class SinglelineString < Base
4
4
  def self.applies_to?(value)
5
5
  value.class == ::String
6
6
  end
@@ -11,14 +11,16 @@ module SuperDiff
11
11
 
12
12
  #{
13
13
  Helpers.style(
14
- :deleted,
15
- "Expected: #{Helpers.inspect_object(expected)}",
14
+ :alpha,
15
+ "Expected: " +
16
+ ObjectInspection.inspect(expected, as_single_line: true),
16
17
  )
17
18
  }
18
19
  #{
19
20
  Helpers.style(
20
- :inserted,
21
- " Actual: #{Helpers.inspect_object(actual)}",
21
+ :beta,
22
+ " Actual: " +
23
+ ObjectInspection.inspect(actual, as_single_line: true),
22
24
  )
23
25
  }
24
26
  OUTPUT
@@ -1,9 +1,23 @@
1
1
  module SuperDiff
2
2
  module Helpers
3
- COLORS = { normal: :plain, inserted: :green, deleted: :red }.freeze
3
+ # TODO: Simplify this
4
+ def self.style(*args, color_enabled: true, **opts, &block)
5
+ klass =
6
+ if color_enabled && Csi.color_enabled?
7
+ Csi::ColorizedDocument
8
+ else
9
+ Csi::UncolorizedDocument
10
+ end
11
+
12
+ document = klass.new.extend(ColorizedDocumentExtensions)
13
+
14
+ if block
15
+ document.__send__(:evaluate_block, &block)
16
+ else
17
+ document.colorize(*args, **opts)
18
+ end
4
19
 
5
- def self.style(style_name, text)
6
- Csi::ColorHelper.public_send(COLORS.fetch(style_name), text)
20
+ document
7
21
  end
8
22
 
9
23
  def self.plural_type_for(value)
@@ -14,83 +28,5 @@ module SuperDiff
14
28
  else "objects"
15
29
  end
16
30
  end
17
-
18
- def self.inspect_object(value_to_inspect, single_line: true)
19
- case value_to_inspect
20
- when ::Hash
21
- inspect_hash(value_to_inspect, single_line: single_line)
22
- when String
23
- inspect_string(value_to_inspect)
24
- when ::Array
25
- inspect_array(value_to_inspect)
26
- else
27
- inspect_unclassified_object(value_to_inspect, single_line: single_line)
28
- end
29
- end
30
-
31
- def self.inspect_hash(hash, single_line: true)
32
- contents = hash.map do |key, value|
33
- if key.is_a?(Symbol)
34
- "#{key}: #{inspect_object(value)}"
35
- else
36
- "#{inspect_object(key)} => #{inspect_object(value)}"
37
- end
38
- end
39
-
40
- if single_line
41
- ["{", contents.join(", "), "}"].join(" ")
42
- else
43
- ValueInspection.new(
44
- beginning: "{",
45
- middle: contents.map.with_index do |line, index|
46
- if index < contents.size - 1
47
- line + ","
48
- else
49
- line
50
- end
51
- end,
52
- end: "}",
53
- )
54
- end
55
- end
56
- private_class_method :inspect_hash
57
-
58
- def self.inspect_string(string)
59
- newline = "⏎"
60
- string.gsub(/\r\n/, newline).gsub(/\n/, newline).inspect
61
- end
62
- private_class_method :inspect_string
63
-
64
- def self.inspect_array(array)
65
- "[" + array.map { |element| inspect_object(element) }.join(", ") + "]"
66
- end
67
- private_class_method :inspect_array
68
-
69
- def self.inspect_unclassified_object(object, single_line: true)
70
- if object.respond_to?(:attributes_for_super_diff)
71
- attributes = object.attributes_for_super_diff
72
- inspected_attributes =
73
- attributes.map.with_index do |(key, value), index|
74
- "#{key}: #{value.inspect}".tap do |line|
75
- if index < attributes.size - 1
76
- line << ","
77
- end
78
- end
79
- end
80
-
81
- if single_line
82
- "#<#{object.class} #{inspected_attributes.join(" ")}>"
83
- else
84
- ValueInspection.new(
85
- beginning: "#<#{object.class} {",
86
- middle: inspected_attributes,
87
- end: "}>",
88
- )
89
- end
90
- else
91
- object.inspect
92
- end
93
- end
94
- private_class_method :inspect_unclassified_object
95
31
  end
96
32
  end
@@ -0,0 +1,22 @@
1
+ module SuperDiff
2
+ class NoDifferAvailableError < StandardError
3
+ def self.create(expected, actual)
4
+ allocate.tap do |error|
5
+ error.expected = expected
6
+ error.actual = actual
7
+ error.__send__(:initialize)
8
+ end
9
+ end
10
+
11
+ attr_accessor :expected, :actual
12
+
13
+ def initialize
14
+ super(<<-MESSAGE)
15
+ There is no differ available to handle an "expected" value of type
16
+ #{expected.class}
17
+ and an "actual" value of type
18
+ #{actual.class}.
19
+ MESSAGE
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ autoload :InspectionTree, "super_diff/object_inspection/inspection_tree"
4
+ autoload :Inspector, "super_diff/object_inspection/inspector"
5
+ autoload :Inspectors, "super_diff/object_inspection/inspectors"
6
+ autoload :Map, "super_diff/object_inspection/map"
7
+ autoload :Nodes, "super_diff/object_inspection/nodes"
8
+
9
+ class << self
10
+ attr_accessor :map
11
+ end
12
+
13
+ def self.inspect(object, as_single_line:, indent_level: 0)
14
+ Inspector.call(
15
+ map,
16
+ object,
17
+ as_single_line: as_single_line,
18
+ indent_level: indent_level,
19
+ )
20
+ end
21
+
22
+ self.map = Map.new
23
+ end
24
+ end
@@ -0,0 +1,144 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ class InspectionTree
4
+ include Enumerable
5
+
6
+ def initialize(&block)
7
+ @nodes = []
8
+
9
+ if block
10
+ instance_eval(&block)
11
+ end
12
+ end
13
+
14
+ def each(&block)
15
+ nodes.each(&block)
16
+ end
17
+
18
+ def before_each_callbacks
19
+ @_before_each_callbacks ||= Hash.new { |h, k| h[k] = [] }
20
+ end
21
+
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
+ end
30
+ end
31
+
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
58
+ end
59
+
60
+ def when_non_empty(&block)
61
+ add_node :when_non_empty, &block
62
+ end
63
+
64
+ def insert_array_inspection_of(array)
65
+ # FIXME: why must this be inside the `nested`?
66
+ add_break
67
+
68
+ insert_separated_list(array) do |value|
69
+ add_inspection_of value
70
+ end
71
+ end
72
+
73
+ def insert_hash_inspection_of(hash, initial_break: " ")
74
+ # FIXME: why must this be inside the `nested`?
75
+ add_break initial_break
76
+
77
+ format_keys_as_kwargs = hash.keys.all? do |key|
78
+ key.is_a?(Symbol)
79
+ end
80
+
81
+ insert_separated_list(hash) do |(key, value)|
82
+ if format_keys_as_kwargs
83
+ add_text key
84
+ add_text ": "
85
+ else
86
+ add_inspection_of key
87
+ add_text " => "
88
+ end
89
+
90
+ add_inspection_of value
91
+ end
92
+ end
93
+
94
+ def insert_separated_list(enumerable, separator: ",")
95
+ 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
101
+ end
102
+
103
+ add_break " "
104
+ end
105
+
106
+ yield value
107
+ end
108
+ end
109
+
110
+ def add_inspection_of(value)
111
+ add_node :inspection, value
112
+ end
113
+
114
+ def apply_tree(tree)
115
+ tree.each do |node|
116
+ append_node(node.clone_with(tree: self))
117
+ end
118
+ end
119
+
120
+ private
121
+
122
+ attr_reader :nodes
123
+
124
+ def add_node(type, *args, &block)
125
+ append_node(build_node(type, *args, &block))
126
+ end
127
+
128
+ def append_node(node)
129
+ nodes.push(node)
130
+ end
131
+
132
+ def build_node(type, *args, &block)
133
+ Nodes.fetch(type).new(self, *args, &block)
134
+ end
135
+
136
+ class BlockArgument
137
+ extend AttrExtras.mixin
138
+
139
+ rattr_initialize [:object!, :as_single_line!]
140
+ attr_query :as_single_line?
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,27 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ class Inspector
4
+ extend AttrExtras.mixin
5
+
6
+ method_object :map, :object, [:indent_level!, :as_single_line!]
7
+
8
+ def call
9
+ SuperDiff::RecursionGuard.substituting_recursion_of(object) do
10
+ inspector.evaluate(
11
+ object,
12
+ as_single_line: as_single_line,
13
+ indent_level: indent_level,
14
+ )
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ attr_query :as_single_line?
21
+
22
+ def inspector
23
+ @_inspector ||= map.call(object)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ module Inspectors
4
+ autoload :Array, "super_diff/object_inspection/inspectors/array"
5
+ autoload(
6
+ :CustomObject,
7
+ "super_diff/object_inspection/inspectors/custom_object",
8
+ )
9
+ autoload(
10
+ :DefaultObject,
11
+ "super_diff/object_inspection/inspectors/default_object",
12
+ )
13
+ autoload :Hash, "super_diff/object_inspection/inspectors/hash"
14
+ autoload :Primitive, "super_diff/object_inspection/inspectors/primitive"
15
+ autoload :String, "super_diff/object_inspection/inspectors/string"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ module Inspectors
4
+ Array = InspectionTree.new do
5
+ when_empty do
6
+ add_text "[]"
7
+ end
8
+
9
+ when_non_empty do
10
+ add_text "["
11
+
12
+ nested do |array|
13
+ insert_array_inspection_of(array)
14
+ end
15
+
16
+ add_break
17
+ add_text "]"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ module Inspectors
4
+ CustomObject = InspectionTree.new do
5
+ add_text do |object|
6
+ "#<#{object.class}"
7
+ end
8
+
9
+ when_multiline do
10
+ add_text " {"
11
+ end
12
+
13
+ nested do |object|
14
+ insert_hash_inspection_of(object.attributes_for_super_diff)
15
+ end
16
+
17
+ add_break
18
+
19
+ when_multiline do
20
+ add_text "}"
21
+ end
22
+
23
+ add_text ">"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ module SuperDiff
2
+ module ObjectInspection
3
+ module Inspectors
4
+ DefaultObject = InspectionTree.new do
5
+ when_empty do
6
+ add_text do |object|
7
+ object.inspect
8
+ end
9
+ end
10
+
11
+ when_non_empty do
12
+ when_singleline do
13
+ add_text do |object|
14
+ object.inspect
15
+ end
16
+ end
17
+
18
+ when_multiline do
19
+ add_text do |object|
20
+ "#<%<class>s:0x%<id>x {" % {
21
+ class: object.class,
22
+ id: object.object_id * 2,
23
+ }
24
+ end
25
+
26
+ nested do |object|
27
+ add_break " "
28
+
29
+ insert_separated_list(
30
+ object.instance_variables.sort,
31
+ separator: ","
32
+ ) do |name|
33
+ add_text name.to_s
34
+ add_text "="
35
+ add_inspection_of object.instance_variable_get(name)
36
+ end
37
+ end
38
+
39
+ add_break
40
+
41
+ add_text "}>"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end