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.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/super_diff/active_record.rb +2 -0
- data/lib/super_diff/active_record/monkey_patches.rb +9 -0
- data/lib/super_diff/csi.rb +4 -0
- data/lib/super_diff/equality_matchers/default.rb +1 -1
- data/lib/super_diff/operation_sequences/base.rb +14 -0
- data/lib/super_diff/rspec.rb +9 -9
- data/lib/super_diff/rspec/differ.rb +6 -6
- data/lib/super_diff/rspec/differs.rb +9 -3
- data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +1 -1
- data/lib/super_diff/rspec/differs/{partial_hash.rb → collection_including.rb} +4 -3
- data/lib/super_diff/rspec/differs/{partial_array.rb → hash_including.rb} +4 -3
- data/lib/super_diff/rspec/differs/{partial_object.rb → object_having_attributes.rb} +3 -3
- data/lib/super_diff/rspec/matcher_text_builders.rb +4 -0
- data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +26 -7
- data/lib/super_diff/rspec/matcher_text_builders/have_predicate.rb +61 -0
- data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +13 -1
- data/lib/super_diff/rspec/monkey_patches.rb +218 -111
- data/lib/super_diff/rspec/object_inspection/inspectors.rb +6 -6
- data/lib/super_diff/rspec/object_inspection/inspectors/{partial_array.rb → collection_including.rb} +2 -2
- data/lib/super_diff/rspec/object_inspection/inspectors/{partial_hash.rb → hash_including.rb} +1 -1
- data/lib/super_diff/rspec/object_inspection/inspectors/object_having_attributes.rb +22 -0
- data/lib/super_diff/rspec/object_inspection/map_extension.rb +7 -7
- data/lib/super_diff/rspec/operational_sequencers.rb +6 -6
- data/lib/super_diff/rspec/operational_sequencers/collection_containing_exactly.rb +1 -1
- data/lib/super_diff/rspec/operational_sequencers/{partial_array.rb → collection_including.rb} +3 -2
- data/lib/super_diff/rspec/operational_sequencers/{partial_hash.rb → hash_including.rb} +3 -2
- data/lib/super_diff/rspec/operational_sequencers/{partial_object.rb → object_having_attributes.rb} +2 -4
- data/lib/super_diff/version.rb +1 -1
- data/spec/integration/rails/active_record_spec.rb +1 -1
- data/spec/integration/rails/hash_with_indifferent_access_spec.rb +1 -1
- data/spec/integration/rspec/be_predicate_matcher_spec.rb +111 -59
- data/spec/integration/rspec/eq_matcher_spec.rb +1 -1
- data/spec/integration/rspec/have_predicate_matcher_spec.rb +484 -0
- data/spec/integration/rspec/match_array_matcher_spec.rb +372 -0
- data/spec/integration/rspec/match_matcher_spec.rb +8 -8
- data/spec/integration/rspec/raise_error_matcher_spec.rb +605 -226
- data/spec/integration/rspec/third_party_matcher_spec.rb +241 -0
- data/spec/integration/rspec/unhandled_errors_spec.rb +56 -81
- data/spec/spec_helper.rb +18 -7
- data/spec/support/integration/helpers.rb +10 -2
- data/spec/support/integration/matchers.rb +143 -0
- data/spec/support/models/active_record/query.rb +15 -0
- data/spec/support/object_id.rb +26 -0
- data/spec/support/ruby_versions.rb +4 -0
- data/spec/support/shared_examples/active_record.rb +71 -0
- data/spec/unit/equality_matcher_spec.rb +8 -8
- data/spec/unit/object_inspection_spec.rb +17 -17
- data/spec/unit/rspec/matchers/have_predicate_spec.rb +21 -0
- data/spec/unit/rspec/matchers/match_array_spec.rb +11 -0
- data/super_diff.gemspec +0 -1
- metadata +30 -34
- data/lib/super_diff/rspec/object_inspection/inspectors/partial_object.rb +0 -21
- 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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
19
|
+
begin
|
20
|
+
require "active_record"
|
21
|
+
active_record_available = true
|
22
|
+
rescue LoadError
|
23
|
+
active_record_available = false
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
if active_record_available
|
27
|
+
ActiveRecord::Base.establish_connection(
|
28
|
+
adapter: "sqlite3",
|
29
|
+
database: ":memory:",
|
30
|
+
)
|
25
31
|
|
26
|
-
|
27
|
-
|
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("{
|
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:
|
133
|
+
indent by: indentation do
|
126
134
|
evaluate_block(&expectation)
|
127
135
|
|
128
136
|
if diff
|