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
@@ -0,0 +1,1092 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe SuperDiff::ObjectInspection do
4
+ describe ".inspect" do
5
+ context "given nil" do
6
+ context "given as_single_line: true" do
7
+ it "returns nil, inspected" do
8
+ inspection = described_class.inspect(nil, as_single_line: true)
9
+ expect(inspection).to eq("nil")
10
+ end
11
+ end
12
+
13
+ context "given as_single_line: false" do
14
+ it "returns nil, inspected" do
15
+ inspection = described_class.inspect(nil, as_single_line: false)
16
+ expect(inspection).to eq("nil")
17
+ end
18
+ end
19
+ end
20
+
21
+ context "given true" do
22
+ context "given as_single_line: true" do
23
+ it "returns nil, inspected" do
24
+ inspection = described_class.inspect(nil, as_single_line: true)
25
+ expect(inspection).to eq("nil")
26
+ end
27
+ end
28
+
29
+ context "given as_single_line: false" do
30
+ it "returns nil, inspected" do
31
+ inspection = described_class.inspect(nil, as_single_line: false)
32
+ expect(inspection).to eq("nil")
33
+ end
34
+ end
35
+ end
36
+
37
+ context "given false" do
38
+ context "given as_single_line: false" do
39
+ it "returns false, inspected" do
40
+ inspection = described_class.inspect(false, as_single_line: false)
41
+ expect(inspection).to eq("false")
42
+ end
43
+ end
44
+
45
+ context "given as_single_line: false" do
46
+ it "returns false, inspected" do
47
+ inspection = described_class.inspect(false, as_single_line: false)
48
+ expect(inspection).to eq("false")
49
+ end
50
+ end
51
+ end
52
+
53
+ context "given a number" do
54
+ context "given as_single_line: true" do
55
+ it "returns the number as a string" do
56
+ inspection = described_class.inspect(3, as_single_line: true)
57
+ expect(inspection).to eq("3")
58
+ end
59
+ end
60
+
61
+ context "given as_single_line: false" do
62
+ it "returns the number as a string" do
63
+ inspection = described_class.inspect(3, as_single_line: false)
64
+ expect(inspection).to eq("3")
65
+ end
66
+ end
67
+ end
68
+
69
+ context "given a symbol" do
70
+ context "given as_single_line: true" do
71
+ it "returns the symbol, inspected" do
72
+ inspection = described_class.inspect(:foo, as_single_line: true)
73
+ expect(inspection).to eq(":foo")
74
+ end
75
+ end
76
+
77
+ context "given as_single_line: false" do
78
+ it "returns the symbol, inspected" do
79
+ inspection = described_class.inspect(:foo, as_single_line: false)
80
+ expect(inspection).to eq(":foo")
81
+ end
82
+ end
83
+ end
84
+
85
+ context "given a regex" do
86
+ context "given as_single_line: true" do
87
+ it "returns the regex, inspected" do
88
+ inspection = described_class.inspect(/foo/, as_single_line: true)
89
+ expect(inspection).to eq("/foo/")
90
+ end
91
+ end
92
+
93
+ context "given as_single_line: false" do
94
+ it "returns the regex, inspected" do
95
+ inspection = described_class.inspect(/foo/, as_single_line: false)
96
+ expect(inspection).to eq("/foo/")
97
+ end
98
+ end
99
+ end
100
+
101
+ context "given a single-line string" do
102
+ it "returns the string surrounded by quotes" do
103
+ inspection = described_class.inspect("Marty", as_single_line: true)
104
+ expect(inspection).to eq('"Marty"')
105
+ end
106
+ end
107
+
108
+ context "given a multi-line string" do
109
+ context "that does not contain color codes" do
110
+ it "returns the string surrounded by quotes, with newline characters escaped" do
111
+ inspection = described_class.inspect(
112
+ "This is a line\nAnd that's a line\nAnd there's a line too",
113
+ as_single_line: true,
114
+ )
115
+ expect(inspection).to eq(
116
+ %("This is a line\\nAnd that's a line\\nAnd there's a line too"),
117
+ )
118
+ end
119
+ end
120
+
121
+ context "that contains color codes" do
122
+ it "escapes the color codes" do
123
+ colors = [
124
+ SuperDiff::Csi::FourBitColor.new(:blue, layer: :foreground),
125
+ SuperDiff::Csi::EightBitColor.new(
126
+ red: 3,
127
+ green: 8,
128
+ blue: 4,
129
+ layer: :foreground,
130
+ ),
131
+ SuperDiff::Csi::TwentyFourBitColor.new(
132
+ red: 47,
133
+ green: 164,
134
+ blue: 59,
135
+ layer: :foreground,
136
+ ),
137
+ ]
138
+ string_to_inspect = [
139
+ colorize("This is a line", colors[0]),
140
+ colorize("And that's a line", colors[1]),
141
+ colorize("And there's a line too", colors[2]),
142
+ ].join("\n")
143
+
144
+ inspection = described_class.inspect(
145
+ string_to_inspect,
146
+ as_single_line: true,
147
+ )
148
+ # TODO: Figure out how to represent a colorized string inside of an
149
+ # already colorized string
150
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
151
+ "\\e[34mThis is a line\\e[0m\\n\\e[38;5;176mAnd that's a line\\e[0m\\n\\e[38;2;47;59;164mAnd there's a line too\\e[0m"
152
+ INSPECTION
153
+ end
154
+ end
155
+ end
156
+
157
+ context "given an array" do
158
+ context "containing only primitive values" do
159
+ context "given as_single_line: true" do
160
+ it "returns a representation of the array on a single line" do
161
+ inspection = described_class.inspect(
162
+ ["foo", 2, :baz],
163
+ as_single_line: true,
164
+ )
165
+ expect(inspection).to eq(%(["foo", 2, :baz]))
166
+ end
167
+ end
168
+
169
+ context "given as_single_line: false" do
170
+ it "returns a representation of the array across multiple lines" do
171
+ inspection = described_class.inspect(
172
+ ["foo", 2, :baz],
173
+ as_single_line: false,
174
+ )
175
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
176
+ [
177
+ "foo",
178
+ 2,
179
+ :baz
180
+ ]
181
+ INSPECTION
182
+ end
183
+ end
184
+ end
185
+
186
+ context "containing other arrays" do
187
+ context "given as_single_line: true" do
188
+ it "returns a representation of the array on a single line" do
189
+ inspection = described_class.inspect(
190
+ [
191
+ "foo",
192
+ ["bar", "baz"],
193
+ "qux",
194
+ ],
195
+ as_single_line: true,
196
+ )
197
+ expect(inspection).to eq(%(["foo", ["bar", "baz"], "qux"]))
198
+ end
199
+ end
200
+
201
+ context "given as_single_line: false" do
202
+ it "returns a representation of the array across multiple lines" do
203
+ inspection = described_class.inspect(
204
+ [
205
+ "foo",
206
+ ["bar", "baz"],
207
+ "qux",
208
+ ],
209
+ as_single_line: false,
210
+ )
211
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
212
+ [
213
+ "foo",
214
+ [
215
+ "bar",
216
+ "baz"
217
+ ],
218
+ "qux"
219
+ ]
220
+ INSPECTION
221
+ end
222
+ end
223
+ end
224
+
225
+ context "which is empty" do
226
+ context "given as_single_line: true" do
227
+ it "returns a representation of the array on a single line" do
228
+ inspection = described_class.inspect([], as_single_line: true)
229
+ expect(inspection).to eq(%([]))
230
+ end
231
+ end
232
+
233
+ context "given as_single_line: false" do
234
+ it "returns a representation of the array on a single line" do
235
+ inspection = described_class.inspect([], as_single_line: false)
236
+ expect(inspection).to eq(%([]))
237
+ end
238
+ end
239
+ end
240
+ end
241
+
242
+ context "given a hash" do
243
+ context "containing only primitive values" do
244
+ context "where all of the keys are symbols" do
245
+ context "given as_single_line: true" do
246
+ it "returns a representation of the hash on a single line" do
247
+ inspection = described_class.inspect(
248
+ # rubocop:disable Style/HashSyntax
249
+ { :foo => "bar", :baz => "qux" },
250
+ # rubocop:enable Style/HashSyntax
251
+ as_single_line: true,
252
+ )
253
+ expect(inspection).to eq(%({ foo: "bar", baz: "qux" }))
254
+ end
255
+ end
256
+
257
+ context "given as_single_line: false" do
258
+ it "returns a representation of the hash across multiple lines" do
259
+ inspection = described_class.inspect(
260
+ # rubocop:disable Style/HashSyntax
261
+ { :foo => "bar", :baz => "qux" },
262
+ # rubocop:enable Style/HashSyntax
263
+ as_single_line: false,
264
+ )
265
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
266
+ {
267
+ foo: "bar",
268
+ baz: "qux"
269
+ }
270
+ INSPECTION
271
+ end
272
+ end
273
+ end
274
+
275
+ context "where only some of the keys are symbols" do
276
+ context "given as_single_line: true" do
277
+ it "returns a representation of the hash on a single line" do
278
+ inspection = described_class.inspect(
279
+ { :foo => "bar", 2 => "baz" },
280
+ as_single_line: true,
281
+ )
282
+ expect(inspection).to eq(%({ :foo => "bar", 2 => "baz" }))
283
+ end
284
+ end
285
+
286
+ context "given as_single_line: false" do
287
+ it "returns a representation of the hash across multiple lines" do
288
+ inspection = described_class.inspect(
289
+ { :foo => "bar", 2 => "baz" },
290
+ as_single_line: false,
291
+ )
292
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
293
+ {
294
+ :foo => "bar",
295
+ 2 => "baz"
296
+ }
297
+ INSPECTION
298
+ end
299
+ end
300
+ end
301
+ end
302
+
303
+ context "containing other hashes" do
304
+ context "given as_single_line: true" do
305
+ it "returns a representation of the hash on a single line" do
306
+ # TODO: Update this with a key/value pair before AND after
307
+ value_to_inspect = {
308
+ # rubocop:disable Style/HashSyntax
309
+ :category_name => "Appliances",
310
+ :products_by_sku => {
311
+ "EMDL-2934" => { :id => 4, :name => "Jordan Air" },
312
+ "KDS-3912" => { :id => 8, :name => "Chevy Impala" },
313
+ },
314
+ :number_of_products => 2,
315
+ # rubocop:enable Style/HashSyntax
316
+ }
317
+ inspection = described_class.inspect(
318
+ value_to_inspect,
319
+ as_single_line: true,
320
+ )
321
+ # rubocop:disable Metrics/LineLength
322
+ expect(inspection).to eq(
323
+ %({ category_name: "Appliances", products_by_sku: { "EMDL-2934" => { id: 4, name: "Jordan Air" }, "KDS-3912" => { id: 8, name: "Chevy Impala" } }, number_of_products: 2 }),
324
+ )
325
+ # rubocop:enable Metrics/LineLength
326
+ end
327
+ end
328
+
329
+ context "given as_single_line: false" do
330
+ it "returns a representation of the array across multiple lines" do
331
+ value_to_inspect = {
332
+ # rubocop:disable Style/HashSyntax
333
+ :category_name => "Appliances",
334
+ :products_by_sku => {
335
+ "EMDL-2934" => { :id => 4, :name => "George Foreman Grill" },
336
+ "KDS-3912" => { :id => 8, :name => "Magic Bullet" },
337
+ },
338
+ :number_of_products => 2,
339
+ # rubocop:enable Style/HashSyntax
340
+ }
341
+ inspection = described_class.inspect(
342
+ value_to_inspect,
343
+ as_single_line: false,
344
+ )
345
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
346
+ {
347
+ category_name: "Appliances",
348
+ products_by_sku: {
349
+ "EMDL-2934" => {
350
+ id: 4,
351
+ name: "George Foreman Grill"
352
+ },
353
+ "KDS-3912" => {
354
+ id: 8,
355
+ name: "Magic Bullet"
356
+ }
357
+ },
358
+ number_of_products: 2
359
+ }
360
+ INSPECTION
361
+ end
362
+ end
363
+ end
364
+
365
+ context "which is empty" do
366
+ context "given as_single_line: true" do
367
+ it "returns a representation of the array on a single line" do
368
+ inspection = described_class.inspect({}, as_single_line: true)
369
+ expect(inspection).to eq(%({}))
370
+ end
371
+ end
372
+
373
+ context "given as_single_line: false" do
374
+ it "returns a representation of the array on a single line" do
375
+ inspection = described_class.inspect({}, as_single_line: false)
376
+ expect(inspection).to eq(%({}))
377
+ end
378
+ end
379
+ end
380
+ end
381
+
382
+ context "given a class" do
383
+ context "given as_single_line: true" do
384
+ it "returns a representation of the object on a single line" do
385
+ inspection = described_class.inspect(
386
+ SuperDiff::Test::Person,
387
+ as_single_line: true,
388
+ )
389
+ expect(inspection).to eq("SuperDiff::Test::Person")
390
+ end
391
+ end
392
+
393
+ context "given as_single_line: false" do
394
+ it "returns a representation of the object on a single line" do
395
+ inspection = described_class.inspect(
396
+ SuperDiff::Test::Person,
397
+ as_single_line: false,
398
+ )
399
+ expect(inspection).to eq("SuperDiff::Test::Person")
400
+ end
401
+ end
402
+ end
403
+
404
+ context "given a custom object" do
405
+ context "containing only primitive values" do
406
+ context "given as_single_line: true" do
407
+ it "returns a representation of the object on a single line" do
408
+ inspection = described_class.inspect(
409
+ SuperDiff::Test::Person.new(name: "Doc", age: 58),
410
+ as_single_line: true,
411
+ )
412
+ expect(inspection).to eq(
413
+ %(#<SuperDiff::Test::Person name: "Doc", age: 58>),
414
+ )
415
+ end
416
+ end
417
+
418
+ context "given as_single_line: false" do
419
+ it "returns a representation of the object across multiple lines" do
420
+ inspection = described_class.inspect(
421
+ SuperDiff::Test::Person.new(name: "Doc", age: 58),
422
+ as_single_line: false,
423
+ )
424
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
425
+ #<SuperDiff::Test::Person {
426
+ name: "Doc",
427
+ age: 58
428
+ }>
429
+ INSPECTION
430
+ end
431
+ end
432
+ end
433
+
434
+ context "containing other custom objects" do
435
+ context "given as_single_line: true" do
436
+ it "returns a representation of the object on a single line" do
437
+ inspection = described_class.inspect(
438
+ SuperDiff::Test::Customer.new(
439
+ name: "Marty McFly",
440
+ shipping_address: SuperDiff::Test::ShippingAddress.new(
441
+ line_1: "123 Main St.",
442
+ line_2: "",
443
+ city: "Hill Valley",
444
+ state: "CA",
445
+ zip: "90382",
446
+ ),
447
+ phone: "111-222-3333",
448
+ ),
449
+ as_single_line: true,
450
+ )
451
+ expect(inspection).to eq(
452
+ # rubocop:disable Metrics/LineLength
453
+ %(#<SuperDiff::Test::Customer name: "Marty McFly", shipping_address: #<SuperDiff::Test::ShippingAddress line_1: "123 Main St.", line_2: "", city: "Hill Valley", state: "CA", zip: "90382">, phone: "111-222-3333">),
454
+ # rubocop:enable Metrics/LineLength
455
+ )
456
+ end
457
+ end
458
+
459
+ context "given as_single_line: false" do
460
+ it "returns a representation of the object across multiple lines" do
461
+ inspection = described_class.inspect(
462
+ SuperDiff::Test::Customer.new(
463
+ name: "Marty McFly",
464
+ shipping_address: SuperDiff::Test::ShippingAddress.new(
465
+ line_1: "123 Main St.",
466
+ line_2: "",
467
+ city: "Hill Valley",
468
+ state: "CA",
469
+ zip: "90382",
470
+ ),
471
+ phone: "111-222-3333",
472
+ ),
473
+ as_single_line: false,
474
+ )
475
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
476
+ #<SuperDiff::Test::Customer {
477
+ name: "Marty McFly",
478
+ shipping_address: #<SuperDiff::Test::ShippingAddress {
479
+ line_1: "123 Main St.",
480
+ line_2: "",
481
+ city: "Hill Valley",
482
+ state: "CA",
483
+ zip: "90382"
484
+ }>,
485
+ phone: "111-222-3333"
486
+ }>
487
+ INSPECTION
488
+ end
489
+ end
490
+ end
491
+ end
492
+
493
+ context "given a non-custom object" do
494
+ context "containing only primitive values" do
495
+ context "given as_single_line: true" do
496
+ it "returns a representation of the object on a single line" do
497
+ inspection = described_class.inspect(
498
+ SuperDiff::Test::Item.new(
499
+ name: "mac and cheese",
500
+ quantity: 2,
501
+ ),
502
+ as_single_line: true,
503
+ )
504
+ expect(inspection).to match(
505
+ # rubocop:disable Metrics/LineLength
506
+ /\A#<SuperDiff::Test::Item:0x[a-z0-9]+ @name="mac and cheese", @quantity=2>\Z/,
507
+ # rubocop:enable Metrics/LineLength
508
+ )
509
+ end
510
+ end
511
+
512
+ context "given as_single_line: false" do
513
+ it "returns a representation of the object across multiple lines" do
514
+ inspection = described_class.inspect(
515
+ SuperDiff::Test::Item.new(
516
+ name: "mac and cheese",
517
+ quantity: 2,
518
+ ),
519
+ as_single_line: false,
520
+ )
521
+ regexp = <<~INSPECTION.rstrip
522
+ #<SuperDiff::Test::Item:0x[a-z0-9]+ \\{
523
+ @name="mac and cheese",
524
+ @quantity=2
525
+ \\}>
526
+ INSPECTION
527
+ expect(inspection).to match(/\A#{regexp}\Z/)
528
+ end
529
+ end
530
+ end
531
+
532
+ context "containing other custom objects" do
533
+ context "given as_single_line: true" do
534
+ it "returns a representation of the object on a single line" do
535
+ inspection = described_class.inspect(
536
+ SuperDiff::Test::Order.new([
537
+ SuperDiff::Test::Item.new(name: "ham", quantity: 1),
538
+ SuperDiff::Test::Item.new(name: "eggs", quantity: 2),
539
+ SuperDiff::Test::Item.new(name: "cheese", quantity: 1),
540
+ ]),
541
+ as_single_line: true,
542
+ )
543
+ expect(inspection).to match(
544
+ # rubocop:disable Metrics/LineLength
545
+ /\A#<SuperDiff::Test::Order:0x[a-z0-9]+ @items=\[#<SuperDiff::Test::Item:0x[a-z0-9]+ @name="ham", @quantity=1>, #<SuperDiff::Test::Item:0x[a-z0-9]+ @name="eggs", @quantity=2>, #<SuperDiff::Test::Item:0x[a-z0-9]+ @name="cheese", @quantity=1>\]>\Z/,
546
+ # rubocop:enable Metrics/LineLength
547
+ )
548
+ end
549
+ end
550
+
551
+ context "given as_single_line: false" do
552
+ it "returns a representation of the object across multiple lines" do
553
+ inspection = described_class.inspect(
554
+ SuperDiff::Test::Order.new([
555
+ SuperDiff::Test::Item.new(name: "ham", quantity: 1),
556
+ SuperDiff::Test::Item.new(name: "eggs", quantity: 2),
557
+ SuperDiff::Test::Item.new(name: "cheese", quantity: 1),
558
+ ]),
559
+ as_single_line: false,
560
+ )
561
+ regexp = <<~INSPECTION.rstrip
562
+ #<SuperDiff::Test::Order:0x[a-z0-9]+ \\{
563
+ @items=\\[
564
+ #<SuperDiff::Test::Item:0x[a-z0-9]+ \\{
565
+ @name="ham",
566
+ @quantity=1
567
+ \\}>,
568
+ #<SuperDiff::Test::Item:0x[a-z0-9]+ \\{
569
+ @name="eggs",
570
+ @quantity=2
571
+ \\}>,
572
+ #<SuperDiff::Test::Item:0x[a-z0-9]+ \\{
573
+ @name="cheese",
574
+ @quantity=1
575
+ \\}>
576
+ \\]
577
+ }>
578
+ INSPECTION
579
+ expect(inspection).to match(/\A#{regexp}\Z/)
580
+ end
581
+ end
582
+ end
583
+
584
+ context "which is empty" do
585
+ context "given as_single_line: true" do
586
+ it "returns a representation of the array on a single line" do
587
+ inspection = described_class.inspect(
588
+ SuperDiff::Test::EmptyClass.new,
589
+ as_single_line: true,
590
+ )
591
+ expect(inspection).to match(
592
+ /#<SuperDiff::Test::EmptyClass:0x[a-z0-9]+>/
593
+ )
594
+ end
595
+ end
596
+
597
+ context "given as_single_line: false" do
598
+ it "returns a representation of the array on a single line" do
599
+ inspection = described_class.inspect(
600
+ SuperDiff::Test::EmptyClass.new,
601
+ as_single_line: false,
602
+ )
603
+ expect(inspection).to match(
604
+ /#<SuperDiff::Test::EmptyClass:0x[a-z0-9]+>/
605
+ )
606
+ end
607
+ end
608
+ end
609
+ end
610
+
611
+ context "given a partial hash" do
612
+ context "given as_single_line: true" do
613
+ it "returns a representation of the partial hash on a single line" do
614
+ inspection = described_class.inspect(
615
+ a_hash_including(foo: "bar", baz: "qux"),
616
+ as_single_line: true,
617
+ )
618
+
619
+ expect(inspection).to eq(
620
+ %(#<a hash including (foo: "bar", baz: "qux")>),
621
+ )
622
+ end
623
+ end
624
+
625
+ context "given as_single_line: false" do
626
+ it "returns a representation of the partial hash across multiple lines" do
627
+ inspection = described_class.inspect(
628
+ a_hash_including(foo: "bar", baz: "qux"),
629
+ as_single_line: false,
630
+ )
631
+
632
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
633
+ #<a hash including (
634
+ foo: "bar",
635
+ baz: "qux"
636
+ )>
637
+ INSPECTION
638
+ end
639
+ end
640
+ end
641
+
642
+ context "given a partial array" do
643
+ context "given as_single_line: true" do
644
+ it "returns a representation of the partial hash on a single line" do
645
+ inspection = described_class.inspect(
646
+ a_collection_including(1, 2, 3),
647
+ as_single_line: true,
648
+ )
649
+
650
+ expect(inspection).to eq(
651
+ %(#<a collection including (1, 2, 3)>),
652
+ )
653
+ end
654
+ end
655
+
656
+ context "given as_single_line: false" do
657
+ it "returns a representation of the partial hash across multiple lines" do
658
+ inspection = described_class.inspect(
659
+ a_collection_including(1, 2, 3),
660
+ as_single_line: false,
661
+ )
662
+
663
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
664
+ #<a collection including (
665
+ 1,
666
+ 2,
667
+ 3
668
+ )>
669
+ INSPECTION
670
+ end
671
+ end
672
+ end
673
+
674
+ context "given a partial object" do
675
+ context "given as_single_line: true" do
676
+ it "returns a representation of the partial object on a single line" do
677
+ inspection = described_class.inspect(
678
+ an_object_having_attributes(foo: "bar", baz: "qux"),
679
+ as_single_line: true,
680
+ )
681
+
682
+ expect(inspection).to eq(
683
+ %(#<an object having attributes (foo: "bar", baz: "qux")>),
684
+ )
685
+ end
686
+ end
687
+
688
+ context "given as_single_line: false" do
689
+ it "returns a representation of the partial object across multiple lines" do
690
+ inspection = described_class.inspect(
691
+ an_object_having_attributes(foo: "bar", baz: "qux"),
692
+ as_single_line: false,
693
+ )
694
+
695
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
696
+ #<an object having attributes (
697
+ foo: "bar",
698
+ baz: "qux"
699
+ )>
700
+ INSPECTION
701
+ end
702
+ end
703
+ end
704
+
705
+ context "given a fuzzy object matching a collection containing exactly <something>" do
706
+ context "given as_single_line: true" do
707
+ it "returns a representation of the partial object on a single line" do
708
+ inspection = described_class.inspect(
709
+ a_collection_containing_exactly("foo", "bar", "baz"),
710
+ as_single_line: true,
711
+ )
712
+
713
+ expect(inspection).to eq(
714
+ %(#<a collection containing exactly ("foo", "bar", "baz")>),
715
+ )
716
+ end
717
+ end
718
+
719
+ context "given as_single_line: false" do
720
+ it "returns a representation of the partial object across multiple lines" do
721
+ inspection = described_class.inspect(
722
+ a_collection_containing_exactly("foo", "bar", "baz"),
723
+ as_single_line: false,
724
+ )
725
+
726
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
727
+ #<a collection containing exactly (
728
+ "foo",
729
+ "bar",
730
+ "baz"
731
+ )>
732
+ INSPECTION
733
+ end
734
+ end
735
+ end
736
+
737
+ context "given a Double" do
738
+ context "that is anonymous" do
739
+ context "given as_single_line: true" do
740
+ it "returns a representation of the partial object on a single line" do
741
+ inspection = described_class.inspect(
742
+ double(foo: "bar", baz: "qux"),
743
+ as_single_line: true,
744
+ )
745
+
746
+ expect(inspection).to eq("#<Double (anonymous)>")
747
+ end
748
+ end
749
+
750
+ context "given as_single_line: false" do
751
+ it "returns a representation of the partial object across multiple lines" do
752
+ inspection = described_class.inspect(
753
+ double(foo: "bar", baz: "qux"),
754
+ as_single_line: false,
755
+ )
756
+
757
+ expect(inspection).to eq("#<Double (anonymous)>")
758
+ end
759
+ end
760
+ end
761
+ end
762
+
763
+ context "given an ActiveRecord object" do
764
+ context "given as_single_line: true" do
765
+ it "returns a representation of the object on a single line" do
766
+ inspection = described_class.inspect(
767
+ SuperDiff::Test::Models::ActiveRecord::Person.new(
768
+ name: "Elliot",
769
+ age: 31,
770
+ ),
771
+ as_single_line: true,
772
+ )
773
+
774
+ expect(inspection).to eq(
775
+ %(#<SuperDiff::Test::Models::ActiveRecord::Person id: nil, age: 31, name: "Elliot">)
776
+ )
777
+ end
778
+ end
779
+
780
+ context "given as_single_line: false" do
781
+ it "returns a representation of the object across multiple lines" do
782
+ inspection = described_class.inspect(
783
+ SuperDiff::Test::Models::ActiveRecord::Person.new(
784
+ name: "Elliot",
785
+ age: 31,
786
+ ),
787
+ as_single_line: false,
788
+ )
789
+
790
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
791
+ #<SuperDiff::Test::Models::ActiveRecord::Person {
792
+ id: nil,
793
+ age: 31,
794
+ name: "Elliot"
795
+ }>
796
+ INSPECTION
797
+ end
798
+ end
799
+ end
800
+
801
+ context "given an ActiveRecord::Relation object" do
802
+ context "given as_single_line: true" do
803
+ it "returns a representation of the Relation on a single line" do
804
+ SuperDiff::Test::Models::ActiveRecord::Person.create!(
805
+ name: "Marty",
806
+ age: 19,
807
+ )
808
+ SuperDiff::Test::Models::ActiveRecord::Person.create!(
809
+ name: "Jennifer",
810
+ age: 17,
811
+ )
812
+
813
+ inspection = described_class.inspect(
814
+ SuperDiff::Test::Models::ActiveRecord::Person.all,
815
+ as_single_line: true,
816
+ )
817
+
818
+ expect(inspection).to eq(
819
+ %(#<ActiveRecord::Relation [#<SuperDiff::Test::Models::ActiveRecord::Person id: 1, age: 19, name: "Marty">, #<SuperDiff::Test::Models::ActiveRecord::Person id: 2, age: 17, name: "Jennifer">]>)
820
+ )
821
+ end
822
+ end
823
+
824
+ context "given as_single_line: false" do
825
+ it "returns a representation of the Relation across multiple lines" do
826
+ SuperDiff::Test::Models::ActiveRecord::Person.create!(
827
+ name: "Marty",
828
+ age: 19,
829
+ )
830
+ SuperDiff::Test::Models::ActiveRecord::Person.create!(
831
+ name: "Jennifer",
832
+ age: 17,
833
+ )
834
+
835
+ inspection = described_class.inspect(
836
+ SuperDiff::Test::Models::ActiveRecord::Person.all,
837
+ as_single_line: false,
838
+ )
839
+
840
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
841
+ #<ActiveRecord::Relation [
842
+ #<SuperDiff::Test::Models::ActiveRecord::Person {
843
+ id: 1,
844
+ age: 19,
845
+ name: "Marty"
846
+ }>,
847
+ #<SuperDiff::Test::Models::ActiveRecord::Person {
848
+ id: 2,
849
+ age: 17,
850
+ name: "Jennifer"
851
+ }>
852
+ ]>
853
+ INSPECTION
854
+ end
855
+ end
856
+ end
857
+
858
+ context "given a HashWithIndifferentAccess" do
859
+ context "given as_single_line: true" do
860
+ it "returns a representation of the object on a single line" do
861
+ inspection = described_class.inspect(
862
+ HashWithIndifferentAccess.new({
863
+ line_1: "123 Main St.",
864
+ city: "Hill Valley",
865
+ state: "CA",
866
+ zip: "90382",
867
+ }),
868
+ as_single_line: true,
869
+ )
870
+
871
+ expect(inspection).to eq(
872
+ %(#<HashWithIndifferentAccess { "line_1" => "123 Main St.", "city" => "Hill Valley", "state" => "CA", "zip" => "90382" }>)
873
+ )
874
+ end
875
+ end
876
+
877
+ context "given as_single_line: false" do
878
+ it "returns a representation of the object across multiple lines" do
879
+ inspection = described_class.inspect(
880
+ HashWithIndifferentAccess.new({
881
+ line_1: "123 Main St.",
882
+ city: "Hill Valley",
883
+ state: "CA",
884
+ zip: "90382",
885
+ }),
886
+ as_single_line: false,
887
+ )
888
+
889
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
890
+ #<HashWithIndifferentAccess {
891
+ "line_1" => "123 Main St.",
892
+ "city" => "Hill Valley",
893
+ "state" => "CA",
894
+ "zip" => "90382"
895
+ }>
896
+ INSPECTION
897
+ end
898
+ end
899
+ end
900
+
901
+ context "given a combination of all kinds of values" do
902
+ context "given as_single_line: true" do
903
+ it "returns a representation of the object on a single line" do
904
+ inspection = described_class.inspect(
905
+ {
906
+ state: :down,
907
+ errors: [
908
+ "Container A-234 is partially damaged",
909
+ "Vessel B042 was attacked by raccoons",
910
+ "Product FDK-3429 is out of stock",
911
+ ],
912
+ mission_critical: true,
913
+ serviceable: false,
914
+ outstanding_orders: [
915
+ SuperDiff::Test::Order.new([
916
+ SuperDiff::Test::Item.new(name: "ham", quantity: 1),
917
+ SuperDiff::Test::Item.new(name: "eggs", quantity: 2),
918
+ SuperDiff::Test::Item.new(name: "cheese", quantity: 1),
919
+ ]),
920
+ ],
921
+ customers: [
922
+ SuperDiff::Test::Customer.new(
923
+ name: "Marty McFly",
924
+ shipping_address: SuperDiff::Test::ShippingAddress.new(
925
+ line_1: "123 Baltic Ave.",
926
+ line_2: "",
927
+ city: "Hill Valley",
928
+ state: "CA",
929
+ zip: "90382",
930
+ ),
931
+ phone: "111-111-1111",
932
+ ),
933
+ SuperDiff::Test::Customer.new(
934
+ name: "Doc Brown",
935
+ shipping_address: SuperDiff::Test::ShippingAddress.new(
936
+ line_1: "456 Park Place",
937
+ line_2: "",
938
+ city: "Beverly Hills",
939
+ state: "CA",
940
+ zip: "90210",
941
+ ),
942
+ phone: "222-222-2222",
943
+ ),
944
+ ],
945
+ },
946
+ as_single_line: true,
947
+ )
948
+ expect(inspection).to match(
949
+ # rubocop:disable Metrics/LineLength
950
+ /\A\{ state: :down, errors: \["Container A-234 is partially damaged", "Vessel B042 was attacked by raccoons", "Product FDK-3429 is out of stock"\], mission_critical: true, serviceable: false, outstanding_orders: \[#<SuperDiff::Test::Order:0x[a-z0-9]+ @items=\[#<SuperDiff::Test::Item:0x[a-z0-9]+ @name="ham", @quantity=1>, #<SuperDiff::Test::Item:0x[a-z0-9]+ @name="eggs", @quantity=2>, #<SuperDiff::Test::Item:0x[a-z0-9]+ @name="cheese", @quantity=1>\]>\], customers: \[#<SuperDiff::Test::Customer name: "Marty McFly", shipping_address: #<SuperDiff::Test::ShippingAddress line_1: "123 Baltic Ave.", line_2: "", city: "Hill Valley", state: "CA", zip: "90382">, phone: "111-111-1111">, #<SuperDiff::Test::Customer name: "Doc Brown", shipping_address: #<SuperDiff::Test::ShippingAddress line_1: "456 Park Place", line_2: "", city: "Beverly Hills", state: "CA", zip: "90210">, phone: "222-222-2222">\] \}\Z/,
951
+ # rubocop:enable Metrics/LineLength
952
+ )
953
+ end
954
+ end
955
+
956
+ context "given as_single_line: false" do
957
+ it "returns a representation of the object across multiple lines" do
958
+ inspection = described_class.inspect(
959
+ {
960
+ state: :down,
961
+ errors: [
962
+ "Container A-234 is partially damaged",
963
+ "Vessel B042 was attacked by raccoons",
964
+ "Product FDK-3429 is out of stock",
965
+ ],
966
+ mission_critical: true,
967
+ serviceable: false,
968
+ outstanding_orders: [
969
+ SuperDiff::Test::Order.new([
970
+ SuperDiff::Test::Item.new(name: "ham", quantity: 1),
971
+ SuperDiff::Test::Item.new(name: "eggs", quantity: 2),
972
+ SuperDiff::Test::Item.new(name: "cheese", quantity: 1),
973
+ ]),
974
+ ],
975
+ customers: [
976
+ SuperDiff::Test::Customer.new(
977
+ name: "Marty McFly",
978
+ shipping_address: SuperDiff::Test::ShippingAddress.new(
979
+ line_1: "123 Baltic Ave.",
980
+ line_2: "",
981
+ city: "Hill Valley",
982
+ state: "CA",
983
+ zip: "90382",
984
+ ),
985
+ phone: "111-111-1111",
986
+ ),
987
+ SuperDiff::Test::Customer.new(
988
+ name: "Doc Brown",
989
+ shipping_address: SuperDiff::Test::ShippingAddress.new(
990
+ line_1: "456 Park Place",
991
+ line_2: "",
992
+ city: "Beverly Hills",
993
+ state: "CA",
994
+ zip: "90210",
995
+ ),
996
+ phone: "222-222-2222",
997
+ ),
998
+ ],
999
+ },
1000
+ as_single_line: false,
1001
+ )
1002
+ regexp = <<~INSPECTION.rstrip
1003
+ \\{
1004
+ state: :down,
1005
+ errors: \\[
1006
+ "Container A-234 is partially damaged",
1007
+ "Vessel B042 was attacked by raccoons",
1008
+ "Product FDK-3429 is out of stock"
1009
+ \\],
1010
+ mission_critical: true,
1011
+ serviceable: false,
1012
+ outstanding_orders: \\[
1013
+ #<SuperDiff::Test::Order:0x[a-z0-9]+ \\{
1014
+ @items=\\[
1015
+ #<SuperDiff::Test::Item:0x[a-z0-9]+ \\{
1016
+ @name="ham",
1017
+ @quantity=1
1018
+ \\}>,
1019
+ #<SuperDiff::Test::Item:0x[a-z0-9]+ \\{
1020
+ @name="eggs",
1021
+ @quantity=2
1022
+ \\}>,
1023
+ #<SuperDiff::Test::Item:0x[a-z0-9]+ \\{
1024
+ @name="cheese",
1025
+ @quantity=1
1026
+ \\}>
1027
+ \\]
1028
+ \\}>
1029
+ \\],
1030
+ customers: \\[
1031
+ #<SuperDiff::Test::Customer \\{
1032
+ name: "Marty McFly",
1033
+ shipping_address: #<SuperDiff::Test::ShippingAddress \\{
1034
+ line_1: "123 Baltic Ave.",
1035
+ line_2: "",
1036
+ city: "Hill Valley",
1037
+ state: "CA",
1038
+ zip: "90382"
1039
+ \\}>,
1040
+ phone: "111-111-1111"
1041
+ \\}>,
1042
+ #<SuperDiff::Test::Customer \\{
1043
+ name: "Doc Brown",
1044
+ shipping_address: #<SuperDiff::Test::ShippingAddress \\{
1045
+ line_1: "456 Park Place",
1046
+ line_2: "",
1047
+ city: "Beverly Hills",
1048
+ state: "CA",
1049
+ zip: "90210"
1050
+ \\}>,
1051
+ phone: "222-222-2222"
1052
+ \\}>
1053
+ \\]
1054
+ \\}
1055
+ INSPECTION
1056
+ expect(inspection).to match(/\A#{regexp}\Z/)
1057
+ end
1058
+ end
1059
+ end
1060
+ end
1061
+
1062
+ context "given a data structure that refers to itself somewhere inside of it" do
1063
+ context "given as_single_line: true" do
1064
+ it "replaces the reference with ∙∙∙" do
1065
+ value = ["a", "b", "c"]
1066
+ value.insert(1, value)
1067
+ inspection = described_class.inspect(value, as_single_line: true)
1068
+ expect(inspection).to eq(%(["a", ∙∙∙, "b", "c"]))
1069
+ end
1070
+ end
1071
+
1072
+ context "given as_single_line: false" do
1073
+ it "replaces the reference with ∙∙∙" do
1074
+ value = ["a", "b", "c"]
1075
+ value.insert(1, value)
1076
+ inspection = described_class.inspect(value, as_single_line: false)
1077
+ expect(inspection).to eq(<<~INSPECTION.rstrip)
1078
+ [
1079
+ "a",
1080
+ ∙∙∙,
1081
+ "b",
1082
+ "c"
1083
+ ]
1084
+ INSPECTION
1085
+ end
1086
+ end
1087
+ end
1088
+
1089
+ def colorize(*args, **opts, &block)
1090
+ SuperDiff::Helpers.style(*args, **opts, &block).to_s.chomp
1091
+ end
1092
+ end