super_diff 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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