super_diff 0.2.0 → 0.5.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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +108 -74
  3. data/lib/super_diff.rb +20 -11
  4. data/lib/super_diff/active_record.rb +21 -23
  5. data/lib/super_diff/active_record/diff_formatters/active_record_relation.rb +3 -3
  6. data/lib/super_diff/active_record/differs/active_record_relation.rb +3 -5
  7. data/lib/super_diff/active_record/monkey_patches.rb +9 -0
  8. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_model.rb +32 -22
  9. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_relation.rb +17 -7
  10. data/lib/super_diff/active_record/operation_tree_builders.rb +14 -0
  11. data/lib/super_diff/active_record/{operational_sequencers → operation_tree_builders}/active_record_model.rb +2 -2
  12. data/lib/super_diff/active_record/{operational_sequencers → operation_tree_builders}/active_record_relation.rb +4 -4
  13. data/lib/super_diff/active_record/{operation_sequences.rb → operation_trees.rb} +2 -2
  14. data/lib/super_diff/active_record/{operation_sequences → operation_trees}/active_record_relation.rb +2 -2
  15. data/lib/super_diff/active_support.rb +16 -19
  16. data/lib/super_diff/active_support/diff_formatters/hash_with_indifferent_access.rb +3 -3
  17. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +3 -5
  18. data/lib/super_diff/active_support/object_inspection/inspectors/hash_with_indifferent_access.rb +17 -7
  19. data/lib/super_diff/active_support/operation_tree_builders.rb +10 -0
  20. data/lib/super_diff/active_support/{operational_sequencers → operation_tree_builders}/hash_with_indifferent_access.rb +2 -2
  21. data/lib/super_diff/active_support/{operation_sequences.rb → operation_trees.rb} +2 -2
  22. data/lib/super_diff/active_support/{operation_sequences → operation_trees}/hash_with_indifferent_access.rb +2 -2
  23. data/lib/super_diff/configuration.rb +60 -0
  24. data/lib/super_diff/csi.rb +4 -0
  25. data/lib/super_diff/diff_formatters.rb +3 -3
  26. data/lib/super_diff/diff_formatters/array.rb +3 -3
  27. data/lib/super_diff/diff_formatters/base.rb +3 -2
  28. data/lib/super_diff/diff_formatters/collection.rb +2 -2
  29. data/lib/super_diff/diff_formatters/custom_object.rb +3 -3
  30. data/lib/super_diff/diff_formatters/default_object.rb +6 -8
  31. data/lib/super_diff/diff_formatters/defaults.rb +10 -0
  32. data/lib/super_diff/diff_formatters/hash.rb +3 -3
  33. data/lib/super_diff/diff_formatters/main.rb +41 -0
  34. data/lib/super_diff/diff_formatters/multiline_string.rb +3 -3
  35. data/lib/super_diff/differs.rb +4 -9
  36. data/lib/super_diff/differs/array.rb +2 -11
  37. data/lib/super_diff/differs/base.rb +20 -3
  38. data/lib/super_diff/differs/custom_object.rb +2 -11
  39. data/lib/super_diff/differs/default_object.rb +2 -8
  40. data/lib/super_diff/differs/defaults.rb +12 -0
  41. data/lib/super_diff/differs/hash.rb +2 -11
  42. data/lib/super_diff/differs/main.rb +48 -0
  43. data/lib/super_diff/differs/multiline_string.rb +2 -14
  44. data/lib/super_diff/differs/time_like.rb +15 -0
  45. data/lib/super_diff/equality_matchers.rb +3 -9
  46. data/lib/super_diff/equality_matchers/array.rb +1 -7
  47. data/lib/super_diff/equality_matchers/base.rb +1 -1
  48. data/lib/super_diff/equality_matchers/default.rb +2 -8
  49. data/lib/super_diff/equality_matchers/defaults.rb +12 -0
  50. data/lib/super_diff/equality_matchers/hash.rb +1 -7
  51. data/lib/super_diff/equality_matchers/main.rb +21 -0
  52. data/lib/super_diff/equality_matchers/multiline_string.rb +1 -7
  53. data/lib/super_diff/errors.rb +16 -0
  54. data/lib/super_diff/errors/no_diff_formatter_available_error.rb +21 -0
  55. data/lib/super_diff/errors/no_differ_available_error.rb +24 -0
  56. data/lib/super_diff/errors/no_operational_sequencer_available_error.rb +22 -0
  57. data/lib/super_diff/implementation_checks.rb +19 -0
  58. data/lib/super_diff/object_inspection.rb +1 -10
  59. data/lib/super_diff/object_inspection/inspection_tree.rb +6 -2
  60. data/lib/super_diff/object_inspection/inspectors.rb +5 -0
  61. data/lib/super_diff/object_inspection/inspectors/array.rb +20 -10
  62. data/lib/super_diff/object_inspection/inspectors/base.rb +36 -0
  63. data/lib/super_diff/object_inspection/inspectors/custom_object.rb +24 -14
  64. data/lib/super_diff/object_inspection/inspectors/default_object.rb +44 -30
  65. data/lib/super_diff/object_inspection/inspectors/defaults.rb +15 -0
  66. data/lib/super_diff/object_inspection/inspectors/hash.rb +20 -10
  67. data/lib/super_diff/object_inspection/inspectors/main.rb +35 -0
  68. data/lib/super_diff/object_inspection/inspectors/primitive.rb +20 -5
  69. data/lib/super_diff/object_inspection/inspectors/string.rb +15 -5
  70. data/lib/super_diff/object_inspection/inspectors/time_like.rb +23 -0
  71. data/lib/super_diff/object_inspection/nodes/inspection.rb +9 -2
  72. data/lib/super_diff/operation_tree_builders.rb +18 -0
  73. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/array.rb +38 -59
  74. data/lib/super_diff/operation_tree_builders/base.rb +98 -0
  75. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/custom_object.rb +3 -3
  76. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/default_object.rb +8 -3
  77. data/lib/super_diff/operation_tree_builders/defaults.rb +5 -0
  78. data/lib/super_diff/operation_tree_builders/hash.rb +226 -0
  79. data/lib/super_diff/operation_tree_builders/main.rb +42 -0
  80. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/multiline_string.rb +3 -3
  81. data/lib/super_diff/operation_tree_builders/time_like.rb +34 -0
  82. data/lib/super_diff/operation_trees.rb +13 -0
  83. data/lib/super_diff/{operation_sequences → operation_trees}/array.rb +5 -1
  84. data/lib/super_diff/operation_trees/base.rb +31 -0
  85. data/lib/super_diff/{operation_sequences → operation_trees}/custom_object.rb +5 -1
  86. data/lib/super_diff/{operation_sequences → operation_trees}/default_object.rb +10 -8
  87. data/lib/super_diff/operation_trees/defaults.rb +5 -0
  88. data/lib/super_diff/{operation_sequences → operation_trees}/hash.rb +5 -1
  89. data/lib/super_diff/operation_trees/main.rb +35 -0
  90. data/lib/super_diff/operation_trees/multiline_string.rb +18 -0
  91. data/lib/super_diff/operations/unary_operation.rb +3 -0
  92. data/lib/super_diff/rspec.rb +54 -22
  93. data/lib/super_diff/rspec/augmented_matcher.rb +1 -1
  94. data/lib/super_diff/rspec/differ.rb +2 -17
  95. data/lib/super_diff/rspec/differs.rb +9 -3
  96. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +3 -8
  97. data/lib/super_diff/rspec/differs/collection_including.rb +18 -0
  98. data/lib/super_diff/rspec/differs/hash_including.rb +18 -0
  99. data/lib/super_diff/rspec/differs/object_having_attributes.rb +17 -0
  100. data/lib/super_diff/rspec/matcher_text_builders.rb +4 -0
  101. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +26 -7
  102. data/lib/super_diff/rspec/matcher_text_builders/have_predicate.rb +61 -0
  103. data/lib/super_diff/rspec/matcher_text_builders/match.rb +1 -1
  104. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +13 -1
  105. data/lib/super_diff/rspec/matcher_text_builders/respond_to.rb +1 -1
  106. data/lib/super_diff/rspec/matcher_text_template.rb +1 -1
  107. data/lib/super_diff/rspec/monkey_patches.rb +226 -115
  108. data/lib/super_diff/rspec/object_inspection.rb +0 -1
  109. data/lib/super_diff/rspec/object_inspection/inspectors.rb +22 -6
  110. data/lib/super_diff/rspec/object_inspection/inspectors/collection_containing_exactly.rb +17 -8
  111. data/lib/super_diff/rspec/object_inspection/inspectors/collection_including.rb +28 -0
  112. data/lib/super_diff/rspec/object_inspection/inspectors/hash_including.rb +31 -0
  113. data/lib/super_diff/rspec/object_inspection/inspectors/instance_of.rb +23 -0
  114. data/lib/super_diff/rspec/object_inspection/inspectors/kind_of.rb +23 -0
  115. data/lib/super_diff/rspec/object_inspection/inspectors/object_having_attributes.rb +31 -0
  116. data/lib/super_diff/rspec/object_inspection/inspectors/primitive.rb +13 -0
  117. data/lib/super_diff/rspec/object_inspection/inspectors/value_within.rb +29 -0
  118. data/lib/super_diff/rspec/operation_tree_builders.rb +22 -0
  119. data/lib/super_diff/rspec/{operational_sequencers → operation_tree_builders}/collection_containing_exactly.rb +6 -6
  120. data/lib/super_diff/rspec/{operational_sequencers/partial_array.rb → operation_tree_builders/collection_including.rb} +4 -3
  121. data/lib/super_diff/rspec/operation_tree_builders/hash_including.rb +25 -0
  122. data/lib/super_diff/rspec/{operational_sequencers/partial_object.rb → operation_tree_builders/object_having_attributes.rb} +5 -11
  123. data/lib/super_diff/version.rb +1 -1
  124. data/spec/examples.txt +397 -328
  125. data/spec/integration/rails/active_record_spec.rb +1 -1
  126. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +1 -1
  127. data/spec/integration/rspec/be_predicate_matcher_spec.rb +111 -59
  128. data/spec/integration/rspec/eq_matcher_spec.rb +139 -3
  129. data/spec/integration/rspec/have_attributes_matcher_spec.rb +354 -227
  130. data/spec/integration/rspec/have_predicate_matcher_spec.rb +484 -0
  131. data/spec/integration/rspec/include_matcher_spec.rb +2 -2
  132. data/spec/integration/rspec/match_array_matcher_spec.rb +372 -0
  133. data/spec/integration/rspec/match_matcher_spec.rb +8 -8
  134. data/spec/integration/rspec/raise_error_matcher_spec.rb +605 -226
  135. data/spec/integration/rspec/third_party_matcher_spec.rb +241 -0
  136. data/spec/integration/rspec/unhandled_errors_spec.rb +110 -58
  137. data/spec/spec_helper.rb +18 -7
  138. data/spec/support/command_runner.rb +3 -0
  139. data/spec/support/integration/helpers.rb +14 -90
  140. data/spec/support/integration/matchers.rb +143 -0
  141. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +14 -29
  142. data/spec/support/integration/test_programs/base.rb +120 -0
  143. data/spec/support/integration/test_programs/plain.rb +13 -0
  144. data/spec/support/integration/test_programs/rspec_active_record.rb +17 -0
  145. data/spec/support/integration/test_programs/rspec_rails.rb +17 -0
  146. data/spec/support/models/active_record/person.rb +4 -11
  147. data/spec/support/models/active_record/query.rb +15 -0
  148. data/spec/support/models/active_record/shipping_address.rb +10 -14
  149. data/spec/support/object_id.rb +27 -0
  150. data/spec/support/ruby_versions.rb +4 -0
  151. data/spec/support/shared_examples/active_record.rb +71 -0
  152. data/spec/support/shared_examples/hash_with_indifferent_access.rb +724 -208
  153. data/spec/tmp/integration_spec.rb +15 -0
  154. data/spec/unit/{equality_matcher_spec.rb → equality_matchers/main_spec.rb} +165 -9
  155. data/spec/unit/object_inspection_spec.rb +94 -18
  156. data/spec/unit/rspec/matchers/have_predicate_spec.rb +21 -0
  157. data/spec/unit/rspec/matchers/match_array_spec.rb +11 -0
  158. data/spec/unit/rspec/matchers/raise_error_spec.rb +16 -0
  159. data/super_diff.gemspec +3 -6
  160. metadata +99 -91
  161. data/lib/super_diff/active_record/object_inspection/map_extension.rb +0 -18
  162. data/lib/super_diff/active_record/operational_sequencers.rb +0 -14
  163. data/lib/super_diff/active_support/object_inspection/map_extension.rb +0 -15
  164. data/lib/super_diff/active_support/operational_sequencers.rb +0 -10
  165. data/lib/super_diff/diff_formatter.rb +0 -32
  166. data/lib/super_diff/differ.rb +0 -51
  167. data/lib/super_diff/equality_matcher.rb +0 -32
  168. data/lib/super_diff/no_differ_available_error.rb +0 -22
  169. data/lib/super_diff/no_operational_sequencer_available_error.rb +0 -20
  170. data/lib/super_diff/object_inspection/inspector.rb +0 -27
  171. data/lib/super_diff/object_inspection/map.rb +0 -28
  172. data/lib/super_diff/operation_sequences.rb +0 -9
  173. data/lib/super_diff/operation_sequences/base.rb +0 -11
  174. data/lib/super_diff/operational_sequencer.rb +0 -48
  175. data/lib/super_diff/operational_sequencers.rb +0 -16
  176. data/lib/super_diff/operational_sequencers/base.rb +0 -89
  177. data/lib/super_diff/operational_sequencers/hash.rb +0 -85
  178. data/lib/super_diff/rspec/configuration.rb +0 -31
  179. data/lib/super_diff/rspec/differs/partial_array.rb +0 -22
  180. data/lib/super_diff/rspec/differs/partial_hash.rb +0 -22
  181. data/lib/super_diff/rspec/differs/partial_object.rb +0 -22
  182. data/lib/super_diff/rspec/object_inspection/inspectors/partial_array.rb +0 -22
  183. data/lib/super_diff/rspec/object_inspection/inspectors/partial_hash.rb +0 -21
  184. data/lib/super_diff/rspec/object_inspection/inspectors/partial_object.rb +0 -21
  185. data/lib/super_diff/rspec/object_inspection/map_extension.rb +0 -23
  186. data/lib/super_diff/rspec/operational_sequencers.rb +0 -22
  187. data/lib/super_diff/rspec/operational_sequencers/partial_hash.rb +0 -32
@@ -0,0 +1,241 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Integration with a third-party matcher", type: :integration do
4
+ context "when the matcher is used in the positive and fails" do
5
+ context "when the failure message spans multiple lines" do
6
+ context "and some of the message is indented" do
7
+ it "colorizes the non-indented part in red" do
8
+ as_both_colored_and_uncolored do |color_enabled|
9
+ snippet = <<~TEST.strip
10
+ expect(:anything).to fail_with_indented_multiline_failure_message
11
+ TEST
12
+ program = make_plain_test_program(
13
+ snippet,
14
+ color_enabled: color_enabled,
15
+ )
16
+
17
+ expected_output = build_expected_output(
18
+ color_enabled: color_enabled,
19
+ snippet: %|expect(:anything).to fail_with_indented_multiline_failure_message|,
20
+ newline_before_expectation: true,
21
+ expectation: proc {
22
+ red_line "This is a message that spans multiple lines."
23
+ red_line "Here is the next line."
24
+ plain_line " This part is indented, for whatever reason. It just kinda keeps"
25
+ plain_line " going until we finish saying whatever it is we want to say."
26
+ }
27
+ )
28
+
29
+ expect(program).
30
+ to produce_output_when_run(expected_output).
31
+ in_color(color_enabled)
32
+ end
33
+ end
34
+ end
35
+
36
+ context "and some of the message is not indented" do
37
+ context "and the message is divided into paragraphs" do
38
+ it "colorizes the first paragraph in red" do
39
+ as_both_colored_and_uncolored do |color_enabled|
40
+ snippet = <<~TEST.strip
41
+ expect(:anything).to fail_with_paragraphed_failure_message
42
+ TEST
43
+ program = make_plain_test_program(
44
+ snippet,
45
+ color_enabled: color_enabled,
46
+ )
47
+
48
+ expected_output = build_expected_output(
49
+ color_enabled: color_enabled,
50
+ snippet: %|expect(:anything).to fail_with_paragraphed_failure_message|,
51
+ newline_before_expectation: true,
52
+ expectation: proc {
53
+ red_line "This is a message that spans multiple paragraphs."
54
+ newline
55
+ plain_line "Here is the next paragraph."
56
+ }
57
+ )
58
+
59
+ expect(program).
60
+ to produce_output_when_run(expected_output).
61
+ in_color(color_enabled)
62
+ end
63
+ end
64
+ end
65
+
66
+ context "and the message is not divided into paragraphs" do
67
+ it "colorizes all of the message in red" do
68
+ as_both_colored_and_uncolored do |color_enabled|
69
+ snippet = <<~TEST.strip
70
+ expect(:anything).to fail_with_non_indented_multiline_failure_message
71
+ TEST
72
+ program = make_plain_test_program(
73
+ snippet,
74
+ color_enabled: color_enabled,
75
+ )
76
+
77
+ expected_output = build_expected_output(
78
+ color_enabled: color_enabled,
79
+ snippet: %|expect(:anything).to fail_with_non_indented_multiline_failure_message|,
80
+ newline_before_expectation: true,
81
+ expectation: proc {
82
+ red_line "This is a message that spans multiple lines."
83
+ red_line "Here is the next line."
84
+ }
85
+ )
86
+
87
+ expect(program).
88
+ to produce_output_when_run(expected_output).
89
+ in_color(color_enabled)
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ context "when the failure message does not span multiple lines" do
97
+ it "colorizes all of the message in red" do
98
+ as_both_colored_and_uncolored do |color_enabled|
99
+ snippet = <<~TEST.strip
100
+ expect(:anything).to fail_with_singleline_failure_message
101
+ TEST
102
+ program = make_plain_test_program(
103
+ snippet,
104
+ color_enabled: color_enabled,
105
+ )
106
+
107
+ expected_output = build_expected_output(
108
+ color_enabled: color_enabled,
109
+ snippet: %|expect(:anything).to fail_with_singleline_failure_message|,
110
+ expectation: proc {
111
+ red_line "This is a message that spans only one line."
112
+ }
113
+ )
114
+
115
+ expect(program).
116
+ to produce_output_when_run(expected_output).
117
+ in_color(color_enabled)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ context "when the matcher is used in the negative and fails" do
124
+ context "when the failure message spans multiple lines" do
125
+ context "and some of the message is indented" do
126
+ it "colorizes the non-indented part in red" do
127
+ as_both_colored_and_uncolored do |color_enabled|
128
+ snippet = <<~TEST.strip
129
+ expect(:anything).not_to pass_with_indented_multiline_failure_message
130
+ TEST
131
+ program = make_plain_test_program(
132
+ snippet,
133
+ color_enabled: color_enabled,
134
+ )
135
+
136
+ expected_output = build_expected_output(
137
+ color_enabled: color_enabled,
138
+ snippet: %|expect(:anything).not_to pass_with_indented_multiline_failure_message|,
139
+ newline_before_expectation: true,
140
+ expectation: proc {
141
+ red_line "This is a message that spans multiple lines."
142
+ red_line "Here is the next line."
143
+ plain_line " This part is indented, for whatever reason. It just kinda keeps"
144
+ plain_line " going until we finish saying whatever it is we want to say."
145
+ }
146
+ )
147
+
148
+ expect(program).
149
+ to produce_output_when_run(expected_output).
150
+ in_color(color_enabled)
151
+ end
152
+ end
153
+ end
154
+
155
+ context "and some of the message is not indented" do
156
+ context "and the message is divided into paragraphs" do
157
+ it "colorizes all of the message in red" do
158
+ as_both_colored_and_uncolored do |color_enabled|
159
+ snippet = <<~TEST.strip
160
+ expect(:anything).not_to pass_with_paragraphed_failure_message
161
+ TEST
162
+ program = make_plain_test_program(
163
+ snippet,
164
+ color_enabled: color_enabled,
165
+ )
166
+
167
+ expected_output = build_expected_output(
168
+ color_enabled: color_enabled,
169
+ snippet: %|expect(:anything).not_to pass_with_paragraphed_failure_message|,
170
+ newline_before_expectation: true,
171
+ expectation: proc {
172
+ red_line "This is a message that spans multiple paragraphs."
173
+ newline
174
+ plain_line "Here is the next paragraph."
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
+
185
+ context "and the message is not divided into paragraphs" do
186
+ it "colorizes all of the message in red" do
187
+ as_both_colored_and_uncolored do |color_enabled|
188
+ snippet = <<~TEST.strip
189
+ expect(:anything).not_to pass_with_non_indented_multiline_failure_message
190
+ TEST
191
+ program = make_plain_test_program(
192
+ snippet,
193
+ color_enabled: color_enabled,
194
+ )
195
+
196
+ expected_output = build_expected_output(
197
+ color_enabled: color_enabled,
198
+ snippet: %|expect(:anything).not_to pass_with_non_indented_multiline_failure_message|,
199
+ newline_before_expectation: true,
200
+ expectation: proc {
201
+ red_line "This is a message that spans multiple lines."
202
+ red_line "Here is the next line."
203
+ }
204
+ )
205
+
206
+ expect(program).
207
+ to produce_output_when_run(expected_output).
208
+ in_color(color_enabled)
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ context "when the failure message does not span multiple lines" do
216
+ it "colorizes all of the message in red" do
217
+ as_both_colored_and_uncolored do |color_enabled|
218
+ snippet = <<~TEST.strip
219
+ expect(:anything).not_to pass_with_singleline_failure_message
220
+ TEST
221
+ program = make_plain_test_program(
222
+ snippet,
223
+ color_enabled: color_enabled,
224
+ )
225
+
226
+ expected_output = build_expected_output(
227
+ color_enabled: color_enabled,
228
+ snippet: %|expect(:anything).not_to pass_with_singleline_failure_message|,
229
+ expectation: proc {
230
+ red_line "This is a message that spans only one line."
231
+ }
232
+ )
233
+
234
+ expect(program).
235
+ to produce_output_when_run(expected_output).
236
+ in_color(color_enabled)
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end
@@ -2,91 +2,143 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe "Integration with RSpec and unhandled errors", type: :integration do
4
4
  context "when a random exception occurs" do
5
- it "highlights the whole output after the code snippet in red" do
6
- as_both_colored_and_uncolored do |color_enabled|
7
- snippet = <<~TEST.strip
8
- raise "Some kind of error or whatever"
9
- TEST
10
- program = make_plain_test_program(
11
- snippet,
12
- color_enabled: color_enabled,
13
- )
14
-
15
- expected_output = colored(color_enabled: color_enabled) do
16
- line "Failures:\n"
17
-
18
- line "1) test passes", indent_by: 2
19
-
20
- line indent_by: 5 do
21
- bold "Failure/Error: "
22
- plain %|raise "Some kind of error or whatever"|
23
- end
24
-
25
- newline
26
-
27
- indent by: 5 do
28
- red_line "RuntimeError:"
29
- plain_line " Some kind of error or whatever"
30
- end
5
+ context "and the message spans multiple lines" do
6
+ it "highlights the first line in red, and then leaves the rest of the message alone" do
7
+ as_both_colored_and_uncolored do |color_enabled|
8
+ snippet = <<~TEST.strip
9
+ raise "Some kind of error or whatever\\n\\nThis is another line"
10
+ TEST
11
+ program = make_plain_test_program(
12
+ snippet,
13
+ color_enabled: color_enabled,
14
+ )
15
+
16
+ expected_output = build_expected_output(
17
+ color_enabled: color_enabled,
18
+ snippet: snippet,
19
+ newline_before_expectation: true,
20
+ indentation: 5,
21
+ expectation: proc {
22
+ red_line "RuntimeError:"
23
+ indent by: 2 do
24
+ red_line "Some kind of error or whatever"
25
+ newline
26
+ plain_line "This is another line"
27
+ end
28
+ },
29
+ )
30
+
31
+ expect(program).
32
+ to produce_output_when_run(expected_output).
33
+ in_color(color_enabled)
31
34
  end
35
+ end
36
+ end
32
37
 
33
- expect(program).
34
- to produce_output_when_run(expected_output).
35
- in_color(color_enabled)
38
+ context "and the message does not span multiple lines" do
39
+ it "highlights the whole output after the code snippet in red" do
40
+ as_both_colored_and_uncolored do |color_enabled|
41
+ snippet = <<~TEST.strip
42
+ raise "Some kind of error or whatever"
43
+ TEST
44
+ program = make_plain_test_program(
45
+ snippet,
46
+ color_enabled: color_enabled,
47
+ )
48
+
49
+ expected_output = build_expected_output(
50
+ color_enabled: color_enabled,
51
+ snippet: snippet,
52
+ newline_before_expectation: true,
53
+ indentation: 5,
54
+ expectation: proc {
55
+ red_line "RuntimeError:"
56
+ indent by: 2 do
57
+ red_line "Some kind of error or whatever"
58
+ end
59
+ },
60
+ )
61
+
62
+ expect(program).
63
+ to produce_output_when_run(expected_output).
64
+ in_color(color_enabled)
65
+ end
36
66
  end
37
67
  end
38
68
  end
39
69
 
40
- context "when a matcher that has a multi-line message fails" do
41
- it "highlights the first line of the failure message in red" do
70
+ context "when multiple exceptions occur" do
71
+ it "displays all exceptions, and for each exception, highlights the first line in red and leaves the rest of the message alone" do
42
72
  as_both_colored_and_uncolored do |color_enabled|
43
73
  snippet = <<~TEST.strip
44
- RSpec::Matchers.define :fail_with_multiline_message do
45
- match do
46
- false
74
+ raise "Some kind of error or whatever\\n\\nThis is another line"
75
+ TEST
76
+ code = <<~CODE
77
+ RSpec.describe "test" do
78
+ after(:each) do
79
+ #{snippet}
47
80
  end
48
81
 
49
- failure_message do
50
- <<\~MESSAGE
51
- First line
52
-
53
- Second line
54
-
55
- Third line
56
- MESSAGE
82
+ it "passes" do
83
+ #{snippet}
57
84
  end
58
85
  end
86
+ CODE
59
87
 
60
- expect(:foo).to fail_with_multiline_message
61
- TEST
62
88
  program = make_plain_test_program(
63
- snippet,
89
+ code,
64
90
  color_enabled: color_enabled,
91
+ preserve_as_whole_file: true,
65
92
  )
66
93
 
67
- expected_output = colored(color_enabled: color_enabled) do
68
- line "Failures:\n"
94
+ expected_output1 = colored(color_enabled: color_enabled) do
95
+ indent by: 5 do
96
+ line do
97
+ plain "1.1) "
98
+ bold "Failure/Error: "
99
+ plain snippet
100
+ end
69
101
 
70
- line "1) test passes", indent_by: 2
102
+ newline
71
103
 
72
- line indent_by: 5 do
73
- bold "Failure/Error: "
74
- plain %|expect(:foo).to fail_with_multiline_message|
104
+ indent by: 5 do
105
+ red_line "RuntimeError:"
106
+ indent by: 2 do
107
+ red_line "Some kind of error or whatever"
108
+ newline
109
+ line "This is another line"
110
+ end
111
+ end
75
112
  end
113
+ end
76
114
 
77
- newline
78
-
115
+ expected_output2 = colored(color_enabled: color_enabled) do
79
116
  indent by: 5 do
80
- red_line " First line"
81
- newline
82
- plain_line " Second line"
117
+ line do
118
+ plain "1.2) "
119
+ bold "Failure/Error: "
120
+ plain snippet
121
+ end
122
+
83
123
  newline
84
- plain_line " Third line"
124
+
125
+ indent by: 5 do
126
+ red_line "RuntimeError:"
127
+ indent by: 2 do
128
+ red_line "Some kind of error or whatever"
129
+ newline
130
+ line "This is another line"
131
+ end
132
+ end
85
133
  end
86
134
  end
87
135
 
88
136
  expect(program).
89
- to produce_output_when_run(expected_output).
137
+ to produce_output_when_run(expected_output1).
138
+ in_color(color_enabled)
139
+
140
+ expect(program).
141
+ to produce_output_when_run(expected_output2).
90
142
  in_color(color_enabled)
91
143
  end
92
144
  end
@@ -16,17 +16,26 @@ SuperDiff::CurrentBundle.instance.assert_appraisal!
16
16
 
17
17
  #---
18
18
 
19
- require "active_record"
19
+ begin
20
+ require "active_record"
21
+ active_record_available = true
22
+ rescue LoadError
23
+ active_record_available = false
24
+ end
20
25
 
21
- ActiveRecord::Base.establish_connection(
22
- adapter: "sqlite3",
23
- database: ":memory:",
24
- )
26
+ if active_record_available
27
+ ActiveRecord::Base.establish_connection(
28
+ adapter: "sqlite3",
29
+ database: ":memory:",
30
+ )
25
31
 
26
- $:.unshift(File.expand_path("../lib", __dir__))
27
- require "super_diff/rspec-rails"
32
+ require "super_diff/rspec-rails"
33
+ else
34
+ require "super_diff/rspec"
35
+ end
28
36
 
29
37
  Dir.glob(File.expand_path("support/**/*.rb", __dir__)).each do |file|
38
+ next if !active_record_available && file.include?('models/active_record')
30
39
  require file
31
40
  end
32
41
 
@@ -52,6 +61,8 @@ RSpec.configure do |config|
52
61
  config.default_formatter = "documentation"
53
62
  end
54
63
 
64
+ config.filter_run_excluding active_record: true unless active_record_available
65
+
55
66
  config.order = :random
56
67
  Kernel.srand config.seed
57
68
  end