super_diff 0.3.0 → 0.4.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/lib/super_diff/active_record.rb +2 -0
  4. data/lib/super_diff/active_record/monkey_patches.rb +9 -0
  5. data/lib/super_diff/csi.rb +4 -0
  6. data/lib/super_diff/equality_matchers/default.rb +1 -1
  7. data/lib/super_diff/operation_sequences/base.rb +14 -0
  8. data/lib/super_diff/rspec.rb +9 -9
  9. data/lib/super_diff/rspec/differ.rb +6 -6
  10. data/lib/super_diff/rspec/differs.rb +9 -3
  11. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +1 -1
  12. data/lib/super_diff/rspec/differs/{partial_hash.rb → collection_including.rb} +4 -3
  13. data/lib/super_diff/rspec/differs/{partial_array.rb → hash_including.rb} +4 -3
  14. data/lib/super_diff/rspec/differs/{partial_object.rb → object_having_attributes.rb} +3 -3
  15. data/lib/super_diff/rspec/matcher_text_builders.rb +4 -0
  16. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +26 -7
  17. data/lib/super_diff/rspec/matcher_text_builders/have_predicate.rb +61 -0
  18. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +13 -1
  19. data/lib/super_diff/rspec/monkey_patches.rb +218 -111
  20. data/lib/super_diff/rspec/object_inspection/inspectors.rb +6 -6
  21. data/lib/super_diff/rspec/object_inspection/inspectors/{partial_array.rb → collection_including.rb} +2 -2
  22. data/lib/super_diff/rspec/object_inspection/inspectors/{partial_hash.rb → hash_including.rb} +1 -1
  23. data/lib/super_diff/rspec/object_inspection/inspectors/object_having_attributes.rb +22 -0
  24. data/lib/super_diff/rspec/object_inspection/map_extension.rb +7 -7
  25. data/lib/super_diff/rspec/operational_sequencers.rb +6 -6
  26. data/lib/super_diff/rspec/operational_sequencers/collection_containing_exactly.rb +1 -1
  27. data/lib/super_diff/rspec/operational_sequencers/{partial_array.rb → collection_including.rb} +3 -2
  28. data/lib/super_diff/rspec/operational_sequencers/{partial_hash.rb → hash_including.rb} +3 -2
  29. data/lib/super_diff/rspec/operational_sequencers/{partial_object.rb → object_having_attributes.rb} +2 -4
  30. data/lib/super_diff/version.rb +1 -1
  31. data/spec/integration/rails/active_record_spec.rb +1 -1
  32. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +1 -1
  33. data/spec/integration/rspec/be_predicate_matcher_spec.rb +111 -59
  34. data/spec/integration/rspec/eq_matcher_spec.rb +1 -1
  35. data/spec/integration/rspec/have_predicate_matcher_spec.rb +484 -0
  36. data/spec/integration/rspec/match_array_matcher_spec.rb +372 -0
  37. data/spec/integration/rspec/match_matcher_spec.rb +8 -8
  38. data/spec/integration/rspec/raise_error_matcher_spec.rb +605 -226
  39. data/spec/integration/rspec/third_party_matcher_spec.rb +241 -0
  40. data/spec/integration/rspec/unhandled_errors_spec.rb +56 -81
  41. data/spec/spec_helper.rb +18 -7
  42. data/spec/support/integration/helpers.rb +10 -2
  43. data/spec/support/integration/matchers.rb +143 -0
  44. data/spec/support/models/active_record/query.rb +15 -0
  45. data/spec/support/object_id.rb +26 -0
  46. data/spec/support/ruby_versions.rb +4 -0
  47. data/spec/support/shared_examples/active_record.rb +71 -0
  48. data/spec/unit/equality_matcher_spec.rb +8 -8
  49. data/spec/unit/object_inspection_spec.rb +17 -17
  50. data/spec/unit/rspec/matchers/have_predicate_spec.rb +21 -0
  51. data/spec/unit/rspec/matchers/match_array_spec.rb +11 -0
  52. data/super_diff.gemspec +0 -1
  53. metadata +30 -34
  54. data/lib/super_diff/rspec/object_inspection/inspectors/partial_object.rb +0 -21
  55. data/spec/examples.txt +0 -350
@@ -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,92 +2,67 @@ 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: %|raise "Some kind of error or whatever\\n\\nThis is another line"|,
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
32
-
33
- expect(program).
34
- to produce_output_when_run(expected_output).
35
- in_color(color_enabled)
36
35
  end
37
36
  end
38
- end
39
-
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
42
- as_both_colored_and_uncolored do |color_enabled|
43
- snippet = <<~TEST.strip
44
- RSpec::Matchers.define :fail_with_multiline_message do
45
- match do
46
- false
47
- end
48
-
49
- failure_message do
50
- <<\~MESSAGE
51
- First line
52
37
 
53
- Second line
54
-
55
- Third line
56
- MESSAGE
57
- end
58
- end
59
-
60
- expect(:foo).to fail_with_multiline_message
61
- TEST
62
- program = make_plain_test_program(
63
- snippet,
64
- color_enabled: color_enabled,
65
- )
66
-
67
- expected_output = colored(color_enabled: color_enabled) do
68
- line "Failures:\n"
69
-
70
- line "1) test passes", indent_by: 2
71
-
72
- line indent_by: 5 do
73
- bold "Failure/Error: "
74
- plain %|expect(:foo).to fail_with_multiline_message|
75
- end
76
-
77
- newline
78
-
79
- indent by: 5 do
80
- red_line " First line"
81
- newline
82
- plain_line " Second line"
83
- newline
84
- plain_line " Third line"
85
- end
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: %|raise "Some kind of error or whatever"|,
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)
86
65
  end
87
-
88
- expect(program).
89
- to produce_output_when_run(expected_output).
90
- in_color(color_enabled)
91
66
  end
92
67
  end
93
68
  end
data/spec/spec_helper.rb CHANGED
@@ -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
@@ -79,15 +79,22 @@ module SuperDiff
79
79
  require "pry-nav"
80
80
  end
81
81
 
82
+ module SuperDiff
83
+ module IntegrationTests; end
84
+ end
85
+
82
86
  RSpec.configure do |config|
83
87
  config.color_mode = :#{color_enabled ? "on" : "off"}
88
+ config.include SuperDiff::IntegrationTests
84
89
  end
85
90
 
86
91
  #{libraries.map { |library| %( require "#{library}") }.join("\n")}
87
92
 
88
- Dir.glob(SUPPORT_DIR.join("{diff_formatters,models,operational_sequencers,operation_sequences}/*.rb")).each do |path|
93
+ Dir.glob(SUPPORT_DIR.join("{models,matchers}/*.rb")).each do |path|
89
94
  require path
90
95
  end
96
+
97
+ require SUPPORT_DIR.join("integration/matchers")
91
98
  SETUP
92
99
  end
93
100
 
@@ -106,6 +113,7 @@ module SuperDiff
106
113
  snippet:,
107
114
  expectation:,
108
115
  newline_before_expectation: false,
116
+ indentation: 7,
109
117
  diff: nil
110
118
  )
111
119
  colored(color_enabled: color_enabled) do
@@ -122,7 +130,7 @@ module SuperDiff
122
130
  newline
123
131
  end
124
132
 
125
- indent by: 7 do
133
+ indent by: indentation do
126
134
  evaluate_block(&expectation)
127
135
 
128
136
  if diff