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,299 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Integration with RSpec's #have_attributes matcher", type: :integration do
4
+ context "when given a small set of attributes" do
5
+ context "when all of the names are methods on the actual object" do
6
+ it "produces the correct output when used in the positive" do
7
+ as_both_colored_and_uncolored do |color_enabled|
8
+ snippet = <<~TEST.strip
9
+ expected = { name: "b" }
10
+ actual = SuperDiff::Test::Person.new(name: "a", age: 9)
11
+ expect(actual).to have_attributes(expected)
12
+ TEST
13
+ program = make_plain_test_program(
14
+ snippet,
15
+ color_enabled: color_enabled,
16
+ )
17
+
18
+ expected_output = build_expected_output(
19
+ color_enabled: color_enabled,
20
+ snippet: %|expect(actual).to have_attributes(expected)|,
21
+ expectation: proc {
22
+ line do
23
+ plain "Expected "
24
+ beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
25
+ plain " to have attributes "
26
+ alpha %|(name: "b")|
27
+ plain "."
28
+ end
29
+ },
30
+ diff: proc {
31
+ plain_line %| #<SuperDiff::Test::Person {|
32
+ # alpha_line %|- name: "b",| # FIXME
33
+ alpha_line %|- name: "b"|
34
+ beta_line %|+ name: "a",|
35
+ plain_line %| age: 9|
36
+ plain_line %| }>|
37
+ },
38
+ )
39
+
40
+ expect(program).
41
+ to produce_output_when_run(expected_output).
42
+ in_color(color_enabled)
43
+ end
44
+ end
45
+
46
+ it "produces the correct output when used in the negative" do
47
+ as_both_colored_and_uncolored do |color_enabled|
48
+ snippet = <<~TEST.strip
49
+ expected = { name: "a" }
50
+ actual = SuperDiff::Test::Person.new(name: "a", age: 9)
51
+ expect(actual).not_to have_attributes(expected)
52
+ TEST
53
+ program = make_plain_test_program(
54
+ snippet,
55
+ color_enabled: color_enabled,
56
+ )
57
+
58
+ expected_output = build_expected_output(
59
+ color_enabled: color_enabled,
60
+ snippet: %|expect(actual).not_to have_attributes(expected)|,
61
+ expectation: proc {
62
+ line do
63
+ plain "Expected "
64
+ beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
65
+ plain " not to have attributes "
66
+ alpha %|(name: "a")|
67
+ plain "."
68
+ end
69
+ },
70
+ )
71
+
72
+ expect(program).
73
+ to produce_output_when_run(expected_output).
74
+ in_color(color_enabled)
75
+ end
76
+ end
77
+ end
78
+
79
+ context "when some of the names are not methods on the actual object" do
80
+ it "produces the correct output" do
81
+ as_both_colored_and_uncolored do |color_enabled|
82
+ snippet = <<~TEST.strip
83
+ expected = { name: "b", foo: "bar" }
84
+ actual = SuperDiff::Test::Person.new(name: "a", age: 9)
85
+ expect(actual).to have_attributes(expected)
86
+ TEST
87
+ program = make_plain_test_program(
88
+ snippet,
89
+ color_enabled: color_enabled,
90
+ )
91
+
92
+ expected_output = build_expected_output(
93
+ color_enabled: color_enabled,
94
+ snippet: %|expect(actual).to have_attributes(expected)|,
95
+ expectation: proc {
96
+ line do
97
+ plain "Expected "
98
+ beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
99
+ plain " to respond to "
100
+ alpha %|:foo|
101
+ plain " with "
102
+ alpha %|0|
103
+ plain " arguments."
104
+ end
105
+ },
106
+ diff: proc {
107
+ plain_line %| #<SuperDiff::Test::Person {|
108
+ plain_line %| name: "a",|
109
+ # plain_line %| age: 9,| # FIXME
110
+ plain_line %| age: 9|
111
+ # alpha_line %|- foo: "bar",| # FIXME
112
+ alpha_line %|- foo: "bar"|
113
+ plain_line %| }>|
114
+ },
115
+ )
116
+
117
+ expect(program).
118
+ to produce_output_when_run(expected_output).
119
+ in_color(color_enabled)
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ context "when given a large set of attributes" do
126
+ context "when all of the names are methods on the actual object" do
127
+ it "produces the correct output when used in the positive" do
128
+ as_both_colored_and_uncolored do |color_enabled|
129
+ snippet = <<~TEST.strip
130
+ expected = {
131
+ line_1: "123 Main St.",
132
+ city: "Oakland",
133
+ state: "CA",
134
+ zip: "91234"
135
+ }
136
+ actual = SuperDiff::Test::ShippingAddress.new(
137
+ line_1: "456 Ponderosa Ct.",
138
+ line_2: nil,
139
+ city: "Hill Valley",
140
+ state: "CA",
141
+ zip: "90382"
142
+ )
143
+ expect(actual).to have_attributes(expected)
144
+ TEST
145
+ program = make_plain_test_program(
146
+ snippet,
147
+ color_enabled: color_enabled,
148
+ )
149
+
150
+ expected_output = build_expected_output(
151
+ color_enabled: color_enabled,
152
+ snippet: %|expect(actual).to have_attributes(expected)|,
153
+ expectation: proc {
154
+ line do
155
+ plain " Expected "
156
+ beta %|#<SuperDiff::Test::ShippingAddress line_1: "456 Ponderosa Ct.", line_2: nil, city: "Hill Valley", state: "CA", zip: "90382">|
157
+ end
158
+
159
+ line do
160
+ plain "to have attributes "
161
+ alpha %|(line_1: "123 Main St.", city: "Oakland", state: "CA", zip: "91234")|
162
+ end
163
+ },
164
+ diff: proc {
165
+ plain_line %| #<SuperDiff::Test::ShippingAddress {|
166
+ alpha_line %|- line_1: "123 Main St.",|
167
+ beta_line %|+ line_1: "456 Ponderosa Ct.",|
168
+ plain_line %| line_2: nil,|
169
+ alpha_line %|- city: "Oakland",|
170
+ beta_line %|+ city: "Hill Valley",|
171
+ plain_line %| state: "CA",|
172
+ # alpha_line %|- zip: "91234",| # FIXME
173
+ alpha_line %|- zip: "91234"|
174
+ beta_line %|+ zip: "90382"|
175
+ plain_line %| }>|
176
+ },
177
+ )
178
+
179
+ expect(program).
180
+ to produce_output_when_run(expected_output).
181
+ in_color(color_enabled)
182
+ end
183
+ end
184
+
185
+ it "produces the correct output when used in the negative" do
186
+ as_both_colored_and_uncolored do |color_enabled|
187
+ snippet = <<~TEST.strip
188
+ expected = {
189
+ line_1: "123 Main St.",
190
+ city: "Oakland",
191
+ state: "CA",
192
+ zip: "91234"
193
+ }
194
+ actual = SuperDiff::Test::ShippingAddress.new(
195
+ line_1: "123 Main St.",
196
+ line_2: nil,
197
+ city: "Oakland",
198
+ state: "CA",
199
+ zip: "91234"
200
+ )
201
+ expect(actual).not_to have_attributes(expected)
202
+ TEST
203
+ program = make_plain_test_program(
204
+ snippet,
205
+ color_enabled: color_enabled,
206
+ )
207
+
208
+ expected_output = build_expected_output(
209
+ color_enabled: color_enabled,
210
+ snippet: %|expect(actual).not_to have_attributes(expected)|,
211
+ newline_before_expectation: true,
212
+ expectation: proc {
213
+ line do
214
+ plain " Expected "
215
+ beta %|#<SuperDiff::Test::ShippingAddress line_1: "123 Main St.", line_2: nil, city: "Oakland", state: "CA", zip: "91234">|
216
+ end
217
+
218
+ line do
219
+ plain "not to have attributes "
220
+ alpha %|(line_1: "123 Main St.", city: "Oakland", state: "CA", zip: "91234")|
221
+ end
222
+ },
223
+ )
224
+
225
+ expect(program).
226
+ to produce_output_when_run(expected_output).
227
+ in_color(color_enabled)
228
+ end
229
+ end
230
+ end
231
+
232
+ context "when some of the names are not methods on the actual object" do
233
+ it "produces the correct output" do
234
+ as_both_colored_and_uncolored do |color_enabled|
235
+ snippet = <<~TEST.strip
236
+ expected = {
237
+ line_1: "123 Main St.",
238
+ city: "Oakland",
239
+ state: "CA",
240
+ zip: "91234",
241
+ foo: "bar",
242
+ baz: "qux"
243
+ }
244
+ actual = SuperDiff::Test::ShippingAddress.new(
245
+ line_1: "456 Ponderosa Ct.",
246
+ line_2: nil,
247
+ city: "Hill Valley",
248
+ state: "CA",
249
+ zip: "90382"
250
+ )
251
+ expect(actual).to have_attributes(expected)
252
+ TEST
253
+ program = make_plain_test_program(
254
+ snippet,
255
+ color_enabled: color_enabled,
256
+ )
257
+
258
+ expected_output = build_expected_output(
259
+ color_enabled: color_enabled,
260
+ snippet: %|expect(actual).to have_attributes(expected)|,
261
+ expectation: proc {
262
+ line do
263
+ plain " Expected "
264
+ beta %|#<SuperDiff::Test::ShippingAddress line_1: "456 Ponderosa Ct.", line_2: nil, city: "Hill Valley", state: "CA", zip: "90382">|
265
+ end
266
+
267
+ line do
268
+ plain "to respond to "
269
+ alpha %|:foo|
270
+ plain " and "
271
+ alpha %|:baz|
272
+ plain " with "
273
+ alpha %|0|
274
+ plain " arguments"
275
+ end
276
+ },
277
+ diff: proc {
278
+ plain_line %| #<SuperDiff::Test::ShippingAddress {|
279
+ plain_line %| line_1: "456 Ponderosa Ct.",|
280
+ plain_line %| line_2: nil,|
281
+ plain_line %| city: "Hill Valley",|
282
+ plain_line %| state: "CA",|
283
+ # plain_line %| zip: "90382",| # FIXME
284
+ plain_line %| zip: "90382"|
285
+ # alpha_line %|- foo: "bar",| # FIXME
286
+ alpha_line %|- foo: "bar"|
287
+ alpha_line %|- baz: "qux"|
288
+ plain_line %| }>|
289
+ },
290
+ )
291
+
292
+ expect(program).
293
+ to produce_output_when_run(expected_output).
294
+ in_color(color_enabled)
295
+ end
296
+ end
297
+ end
298
+ end
299
+ end
@@ -0,0 +1,350 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Integration with RSpec's #include matcher", type: :integration do
4
+ context "when used against an array" do
5
+ context "that is small" do
6
+ it "produces the correct failure message when used in the positive" do
7
+ as_both_colored_and_uncolored do |color_enabled|
8
+ snippet = <<~TEST.strip
9
+ expected = ["Marty", "Einie"]
10
+ actual = ["Marty", "Jennifer", "Doc"]
11
+ expect(actual).to include(*expected)
12
+ TEST
13
+ program = make_plain_test_program(
14
+ snippet,
15
+ color_enabled: color_enabled,
16
+ )
17
+
18
+ expected_output = build_expected_output(
19
+ color_enabled: color_enabled,
20
+ snippet: %|expect(actual).to include(*expected)|,
21
+ expectation: proc {
22
+ line do
23
+ plain "Expected "
24
+ beta %|["Marty", "Jennifer", "Doc"]|
25
+ plain " to include "
26
+ alpha %|"Einie"|
27
+ plain "."
28
+ end
29
+ },
30
+ diff: proc {
31
+ plain_line %| [|
32
+ plain_line %| "Marty",|
33
+ plain_line %| "Jennifer",|
34
+ # plain_line %| "Doc",| # FIXME
35
+ plain_line %| "Doc"|
36
+ alpha_line %|- "Einie"|
37
+ plain_line %| ]|
38
+ },
39
+ )
40
+
41
+ expect(program).
42
+ to produce_output_when_run(expected_output).
43
+ in_color(color_enabled)
44
+ end
45
+ end
46
+
47
+ it "produces the correct failure message when used in the negative" do
48
+ as_both_colored_and_uncolored do |color_enabled|
49
+ snippet = <<~TEST.strip
50
+ values = ["Marty", "Einie"]
51
+ expect(values).not_to include(*values)
52
+ TEST
53
+ program = make_plain_test_program(
54
+ snippet,
55
+ color_enabled: color_enabled,
56
+ )
57
+
58
+ expected_output = build_expected_output(
59
+ color_enabled: color_enabled,
60
+ snippet: %|expect(values).not_to include(*values)|,
61
+ expectation: proc {
62
+ line do
63
+ plain "Expected "
64
+ beta %|["Marty", "Einie"]|
65
+ plain " not to include "
66
+ alpha %|"Marty" and "Einie"|
67
+ plain "."
68
+ end
69
+ },
70
+ )
71
+
72
+ expect(program).
73
+ to produce_output_when_run(expected_output).
74
+ in_color(color_enabled)
75
+ end
76
+ end
77
+ end
78
+
79
+ context "that is large" do
80
+ it "produces the correct failure message when used in the positive" do
81
+ as_both_colored_and_uncolored do |color_enabled|
82
+ snippet = <<~TEST.strip
83
+ expected = [
84
+ "Marty McFly",
85
+ "Doc Brown",
86
+ "Einie",
87
+ "Biff Tannen",
88
+ "George McFly",
89
+ "Lorraine McFly"
90
+ ]
91
+ actual = [
92
+ "Marty McFly",
93
+ "Doc Brown",
94
+ "Einie",
95
+ "Lorraine McFly"
96
+ ]
97
+ expect(actual).to include(*expected)
98
+ TEST
99
+ program = make_plain_test_program(
100
+ snippet,
101
+ color_enabled: color_enabled,
102
+ )
103
+
104
+ expected_output = build_expected_output(
105
+ color_enabled: color_enabled,
106
+ snippet: %|expect(actual).to include(*expected)|,
107
+ expectation: proc {
108
+ line do
109
+ plain " Expected "
110
+ beta %|["Marty McFly", "Doc Brown", "Einie", "Lorraine McFly"]|
111
+ end
112
+
113
+ line do
114
+ plain "to include "
115
+ alpha %|"Biff Tannen" and "George McFly"|
116
+ end
117
+ },
118
+ diff: proc {
119
+ plain_line %| [|
120
+ plain_line %| "Marty McFly",|
121
+ plain_line %| "Doc Brown",|
122
+ plain_line %| "Einie",|
123
+ # plain_line %| "Lorraine McFly",| # FIXME
124
+ plain_line %| "Lorraine McFly"|
125
+ alpha_line %|- "Biff Tannen",|
126
+ alpha_line %|- "George McFly"|
127
+ plain_line %| ]|
128
+ },
129
+ )
130
+
131
+ expect(program).
132
+ to produce_output_when_run(expected_output).
133
+ in_color(color_enabled)
134
+ end
135
+ end
136
+
137
+ it "produces the correct failure message when used in the negative" do
138
+ as_both_colored_and_uncolored do |color_enabled|
139
+ snippet = <<~TEST.strip
140
+ expected = [
141
+ "Marty McFly",
142
+ "Doc Brown",
143
+ "Einie",
144
+ "Lorraine McFly"
145
+ ]
146
+ actual = [
147
+ "Marty McFly",
148
+ "Doc Brown",
149
+ "Einie",
150
+ "Biff Tannen",
151
+ "George McFly",
152
+ "Lorraine McFly"
153
+ ]
154
+ expect(actual).not_to include(*expected)
155
+ TEST
156
+ program = make_plain_test_program(
157
+ snippet,
158
+ color_enabled: color_enabled,
159
+ )
160
+
161
+ expected_output = build_expected_output(
162
+ color_enabled: color_enabled,
163
+ snippet: %|expect(actual).not_to include(*expected)|,
164
+ newline_before_expectation: true,
165
+ expectation: proc {
166
+ line do
167
+ plain " Expected "
168
+ beta %|["Marty McFly", "Doc Brown", "Einie", "Biff Tannen", "George McFly", "Lorraine McFly"]|
169
+ end
170
+
171
+ line do
172
+ plain "not to include "
173
+ alpha %|"Marty McFly", "Doc Brown", "Einie", and "Lorraine McFly"|
174
+ end
175
+ },
176
+ )
177
+
178
+ expect(program).
179
+ to produce_output_when_run(expected_output).
180
+ in_color(color_enabled)
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ context "when used against a hash" do
187
+ context "that is small" do
188
+ it "produces the correct failure message when used in the positive" do
189
+ as_both_colored_and_uncolored do |color_enabled|
190
+ snippet = <<~TEST.strip
191
+ expected = { city: "Hill Valley", state: "CA" }
192
+ actual = { city: "Burbank", zip: "90210" }
193
+ expect(actual).to include(expected)
194
+ TEST
195
+ program = make_plain_test_program(
196
+ snippet,
197
+ color_enabled: color_enabled,
198
+ )
199
+
200
+ expected_output = build_expected_output(
201
+ color_enabled: color_enabled,
202
+ snippet: %|expect(actual).to include(expected)|,
203
+ expectation: proc {
204
+ line do
205
+ plain "Expected "
206
+ beta %|{ city: "Burbank", zip: "90210" }|
207
+ plain " to include "
208
+ alpha %|(city: "Hill Valley", state: "CA")|
209
+ plain "."
210
+ end
211
+ },
212
+ diff: proc {
213
+ plain_line %| {|
214
+ alpha_line %|- city: "Hill Valley",|
215
+ beta_line %|+ city: "Burbank",|
216
+ # FIXME
217
+ # plain_line %| zip: "90210",|
218
+ plain_line %| zip: "90210"|
219
+ alpha_line %|- state: "CA"|
220
+ plain_line %| }|
221
+ },
222
+ )
223
+
224
+ expect(program).
225
+ to produce_output_when_run(expected_output).
226
+ in_color(color_enabled)
227
+ end
228
+ end
229
+
230
+ it "produces the correct failure message when used in the negative" do
231
+ as_both_colored_and_uncolored do |color_enabled|
232
+ snippet = <<~TEST.strip
233
+ expected = { city: "Burbank" }
234
+ actual = { city: "Burbank", zip: "90210" }
235
+ expect(actual).not_to include(expected)
236
+ TEST
237
+ program = make_plain_test_program(
238
+ snippet,
239
+ color_enabled: color_enabled,
240
+ )
241
+
242
+ expected_output = build_expected_output(
243
+ color_enabled: color_enabled,
244
+ snippet: %|expect(actual).not_to include(expected)|,
245
+ expectation: proc {
246
+ line do
247
+ plain "Expected "
248
+ beta %|{ city: "Burbank", zip: "90210" }|
249
+ plain " not to include "
250
+ alpha %|(city: "Burbank")|
251
+ plain "."
252
+ end
253
+ },
254
+ )
255
+
256
+ expect(program).
257
+ to produce_output_when_run(expected_output).
258
+ in_color(color_enabled)
259
+ end
260
+ end
261
+ end
262
+
263
+ context "that is large" do
264
+ it "produces the correct failure message when used in the positive" do
265
+ as_both_colored_and_uncolored do |color_enabled|
266
+ snippet = <<~TEST.strip
267
+ expected = {
268
+ city: "Hill Valley",
269
+ zip: "90382"
270
+ }
271
+ actual = {
272
+ city: "Burbank",
273
+ state: "CA",
274
+ zip: "90210"
275
+ }
276
+ expect(actual).to include(expected)
277
+ TEST
278
+ program = make_plain_test_program(
279
+ snippet,
280
+ color_enabled: color_enabled,
281
+ )
282
+
283
+ expected_output = build_expected_output(
284
+ color_enabled: color_enabled,
285
+ snippet: %|expect(actual).to include(expected)|,
286
+ expectation: proc {
287
+ line do
288
+ plain " Expected "
289
+ beta %|{ city: "Burbank", state: "CA", zip: "90210" }|
290
+ end
291
+
292
+ line do
293
+ plain "to include "
294
+ alpha %|(city: "Hill Valley", zip: "90382")|
295
+ end
296
+ },
297
+ diff: proc {
298
+ plain_line %| {|
299
+ alpha_line %|- city: "Hill Valley",|
300
+ beta_line %|+ city: "Burbank",|
301
+ plain_line %| state: "CA",|
302
+ alpha_line %|- zip: "90382"|
303
+ beta_line %|+ zip: "90210"|
304
+ plain_line %| }|
305
+ },
306
+ )
307
+
308
+ expect(program).
309
+ to produce_output_when_run(expected_output).
310
+ in_color(color_enabled)
311
+ end
312
+ end
313
+
314
+ it "produces the correct failure message when used in the negative" do
315
+ as_both_colored_and_uncolored do |color_enabled|
316
+ snippet = <<~TEST.strip
317
+ expected = { city: "Hill Valley", state: "CA" }
318
+ actual = { city: "Hill Valley", state: "CA", zip: "90210" }
319
+ expect(actual).not_to include(expected)
320
+ TEST
321
+ program = make_plain_test_program(
322
+ snippet,
323
+ color_enabled: color_enabled,
324
+ )
325
+
326
+ expected_output = build_expected_output(
327
+ color_enabled: color_enabled,
328
+ snippet: %|expect(actual).not_to include(expected)|,
329
+ newline_before_expectation: true,
330
+ expectation: proc {
331
+ line do
332
+ plain " Expected "
333
+ beta %|{ city: "Hill Valley", state: "CA", zip: "90210" }|
334
+ end
335
+
336
+ line do
337
+ plain "not to include "
338
+ alpha %|(city: "Hill Valley", state: "CA")|
339
+ end
340
+ },
341
+ )
342
+
343
+ expect(program).
344
+ to produce_output_when_run(expected_output).
345
+ in_color(color_enabled)
346
+ end
347
+ end
348
+ end
349
+ end
350
+ end