rspec-tap-formatters 0.1.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 +7 -0
- data/.document +5 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.md +23 -0
- data/README.md +127 -0
- data/lib/rspec/tap/formatters.rb +14 -0
- data/lib/rspec/tap/formatters/compact.rb +168 -0
- data/lib/rspec/tap/formatters/core_ext/hash.rb +52 -0
- data/lib/rspec/tap/formatters/core_ext/string.rb +48 -0
- data/lib/rspec/tap/formatters/default.rb +169 -0
- data/lib/rspec/tap/formatters/flat.rb +139 -0
- data/lib/rspec/tap/formatters/flat_compact.rb +138 -0
- data/lib/rspec/tap/formatters/printer.rb +445 -0
- data/lib/rspec/tap/formatters/test_stats.rb +50 -0
- data/lib/rspec/tap/formatters/version.rb +16 -0
- data/spec/rspec/tap/formatters/compact_spec.rb +399 -0
- data/spec/rspec/tap/formatters/default_spec.rb +407 -0
- data/spec/rspec/tap/formatters/flat_compact_spec.rb +257 -0
- data/spec/rspec/tap/formatters/flat_spec.rb +266 -0
- data/spec/rspec/tap/formatters/printer_spec.rb +1075 -0
- data/spec/rspec/tap/formatters/test_stats_spec.rb +92 -0
- metadata +138 -0
@@ -0,0 +1,266 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
RSpec.describe RSpec::TAP::Formatters::Flat do
|
6
|
+
subject(:formatter) { described_class.new(report_output) }
|
7
|
+
|
8
|
+
let(:report_output) { StringIO.new }
|
9
|
+
let(:report_printer) { RSpec::TAP::Formatters::Printer.new(report_output) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
formatter.instance_variable_set(:@printer, report_printer)
|
13
|
+
formatter.instance_variable_set(:@seed, nil)
|
14
|
+
formatter.instance_variable_set(:@example_number, 0)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#seed' do
|
18
|
+
let(:seed) { SecureRandom.random_number(10_000) }
|
19
|
+
|
20
|
+
context 'with seed used' do
|
21
|
+
let(:notification) { OpenStruct.new(seed: seed, seed_used?: true) }
|
22
|
+
|
23
|
+
it 'updates instance variable' do
|
24
|
+
expect { formatter.seed(notification) }
|
25
|
+
.to change { formatter.instance_variable_get(:@seed) }
|
26
|
+
.from(nil)
|
27
|
+
.to(seed)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'without seed used' do
|
32
|
+
let(:notification) { OpenStruct.new(seed: seed, seed_used?: false) }
|
33
|
+
|
34
|
+
it 'does not update instance variable' do
|
35
|
+
expect { formatter.seed(notification) }
|
36
|
+
.not_to change { formatter.instance_variable_get(:@seed) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#start' do
|
42
|
+
let(:count) { 1 + SecureRandom.random_number(5) }
|
43
|
+
let(:notification) { OpenStruct.new(count: count) }
|
44
|
+
|
45
|
+
it 'delegates to printer' do
|
46
|
+
allow(report_printer).to receive(:start_output)
|
47
|
+
|
48
|
+
formatter.start(notification)
|
49
|
+
|
50
|
+
expect(report_printer).to have_received(:start_output).with(no_args)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#start_dump' do
|
55
|
+
it 'delegates to printer' do
|
56
|
+
allow(report_printer).to receive(:example_progress_dump)
|
57
|
+
|
58
|
+
formatter.start_dump(OpenStruct.new)
|
59
|
+
|
60
|
+
expect(report_printer).to have_received(:example_progress_dump)
|
61
|
+
.with(no_args)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#example_started' do
|
66
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
67
|
+
|
68
|
+
it 'increments example number by one' do
|
69
|
+
expect { formatter.example_started(OpenStruct.new) }
|
70
|
+
.to change { formatter.instance_variable_get(:@example_number) }
|
71
|
+
.by(1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#example_passed' do
|
76
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
77
|
+
let(:example_status) { :success }
|
78
|
+
let(:example_status_index) { 1 }
|
79
|
+
|
80
|
+
let(:description) { 'example-foo' }
|
81
|
+
let(:example) { OpenStruct.new(full_description: description) }
|
82
|
+
let(:notification) { OpenStruct.new(example: example) }
|
83
|
+
|
84
|
+
before do
|
85
|
+
formatter.instance_variable_set(:@example_number, example_number)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'delegates progress report to printer' do
|
89
|
+
allow(report_printer).to receive(:example_progress_output)
|
90
|
+
|
91
|
+
formatter.example_passed(notification)
|
92
|
+
|
93
|
+
expect(report_printer).to have_received(:example_progress_output)
|
94
|
+
.with(example_status)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'delegates status report to printer' do
|
98
|
+
allow(report_printer).to receive(:success_output)
|
99
|
+
|
100
|
+
formatter.example_passed(notification)
|
101
|
+
|
102
|
+
expect(report_printer).to have_received(:success_output)
|
103
|
+
.with(description, example_number, 0)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#example_failed' do
|
108
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
109
|
+
let(:example_status) { :failure }
|
110
|
+
let(:example_status_index) { 2 }
|
111
|
+
|
112
|
+
let(:description) { 'example-foo' }
|
113
|
+
let(:example) { OpenStruct.new(full_description: description) }
|
114
|
+
let(:notification) { OpenStruct.new(example: example) }
|
115
|
+
|
116
|
+
before do
|
117
|
+
formatter.instance_variable_set(:@example_number, example_number)
|
118
|
+
|
119
|
+
allow(report_printer).to receive(:failure_reason_output)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'delegates progress report to printer' do
|
123
|
+
allow(report_printer).to receive(:example_progress_output)
|
124
|
+
|
125
|
+
formatter.example_failed(notification)
|
126
|
+
|
127
|
+
expect(report_printer).to have_received(:example_progress_output)
|
128
|
+
.with(example_status)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'delegates status report to printer' do
|
132
|
+
allow(report_printer).to receive(:failure_output)
|
133
|
+
|
134
|
+
formatter.example_failed(notification)
|
135
|
+
|
136
|
+
expect(report_printer).to have_received(:failure_output)
|
137
|
+
.with(description, example_number, 0)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'delegates reason to printer' do
|
141
|
+
formatter.example_failed(notification)
|
142
|
+
|
143
|
+
expect(report_printer).to have_received(:failure_reason_output)
|
144
|
+
.with(notification, 1)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#example_pending' do
|
149
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
150
|
+
let(:example_status) { :pending }
|
151
|
+
let(:example_status_index) { 3 }
|
152
|
+
|
153
|
+
let(:description) { 'example-foo' }
|
154
|
+
let(:example) do
|
155
|
+
OpenStruct.new(
|
156
|
+
full_description: description,
|
157
|
+
execution_result: execution_result
|
158
|
+
)
|
159
|
+
end
|
160
|
+
let(:notification) { OpenStruct.new(example: example) }
|
161
|
+
|
162
|
+
before do
|
163
|
+
formatter.instance_variable_set(:@example_number, example_number)
|
164
|
+
end
|
165
|
+
|
166
|
+
shared_examples_for 'pending example' do
|
167
|
+
it 'delegates progress report to printer' do
|
168
|
+
allow(report_printer).to receive(:example_progress_output)
|
169
|
+
|
170
|
+
formatter.example_pending(notification)
|
171
|
+
|
172
|
+
expect(report_printer).to have_received(:example_progress_output)
|
173
|
+
.with(example_status)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'delegates status report to printer' do
|
177
|
+
allow(report_printer).to receive(:pending_output)
|
178
|
+
|
179
|
+
formatter.example_pending(notification)
|
180
|
+
|
181
|
+
expect(report_printer).to have_received(:pending_output)
|
182
|
+
.with(notification, description, example_number, 0)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context 'with pending' do
|
187
|
+
let(:pending_message) { "pending-#{SecureRandom.hex}" }
|
188
|
+
let(:directive) { "TODO: #{pending_message}" }
|
189
|
+
let(:execution_result) do
|
190
|
+
OpenStruct.new(
|
191
|
+
pending_message: pending_message,
|
192
|
+
example_skipped?: false
|
193
|
+
)
|
194
|
+
end
|
195
|
+
|
196
|
+
include_examples('pending example')
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'with skipped' do
|
200
|
+
let(:pending_message) { "skip-#{SecureRandom.hex}" }
|
201
|
+
let(:directive) { "SKIP: #{pending_message}" }
|
202
|
+
let(:execution_result) do
|
203
|
+
OpenStruct.new(
|
204
|
+
pending_message: pending_message,
|
205
|
+
example_skipped?: true
|
206
|
+
)
|
207
|
+
end
|
208
|
+
|
209
|
+
include_examples('pending example')
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe '#message' do
|
214
|
+
let(:notification) { OpenStruct.new }
|
215
|
+
|
216
|
+
it 'delegates to printer' do
|
217
|
+
allow(report_printer).to receive(:message_output)
|
218
|
+
|
219
|
+
formatter.message(notification)
|
220
|
+
|
221
|
+
expect(report_printer).to have_received(:message_output)
|
222
|
+
.with(notification)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe '#dump_failures' do
|
227
|
+
let(:notification) { OpenStruct.new }
|
228
|
+
|
229
|
+
it 'delegates to printer' do
|
230
|
+
allow(report_printer).to receive(:store_failed_examples_summary)
|
231
|
+
|
232
|
+
formatter.dump_failures(notification)
|
233
|
+
|
234
|
+
expect(report_printer).to have_received(:store_failed_examples_summary)
|
235
|
+
.with(notification)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe '#dump_pending' do
|
240
|
+
let(:notification) { OpenStruct.new }
|
241
|
+
|
242
|
+
it 'delegates to printer' do
|
243
|
+
allow(report_printer).to receive(:store_pending_examples_summary)
|
244
|
+
|
245
|
+
formatter.dump_pending(notification)
|
246
|
+
|
247
|
+
expect(report_printer).to have_received(:store_pending_examples_summary)
|
248
|
+
.with(notification)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '#dump_summary' do
|
253
|
+
let(:seed) { 1 + SecureRandom.random_number(10_000) }
|
254
|
+
let(:notification) { OpenStruct.new }
|
255
|
+
|
256
|
+
it 'delegates to printer' do
|
257
|
+
allow(report_printer).to receive(:summary_output)
|
258
|
+
|
259
|
+
formatter.instance_variable_set(:@seed, seed)
|
260
|
+
formatter.dump_summary(notification)
|
261
|
+
|
262
|
+
expect(report_printer).to have_received(:summary_output)
|
263
|
+
.with(notification, seed)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
@@ -0,0 +1,1075 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
RSpec.shared_context 'when writing to file' do
|
6
|
+
before do
|
7
|
+
report_printer.instance_variable_set(:@write_to_file, true)
|
8
|
+
report_printer.instance_variable_set(:@display_colors, false)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.shared_context 'when not writing to file' do
|
13
|
+
before do
|
14
|
+
report_printer.instance_variable_set(:@write_to_file, false)
|
15
|
+
report_printer.instance_variable_set(:@display_colors, true)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec.describe RSpec::TAP::Formatters::Printer do
|
20
|
+
subject(:report_printer) { described_class.new(report_output) }
|
21
|
+
|
22
|
+
let(:report_output) { StringIO.new }
|
23
|
+
|
24
|
+
before do
|
25
|
+
report_printer.instance_variable_set(:@output, report_output)
|
26
|
+
report_printer.instance_variable_set(:@write_to_file, false)
|
27
|
+
report_printer.instance_variable_set(:@display_colors, true)
|
28
|
+
report_printer.instance_variable_set(:@force_colors, false)
|
29
|
+
report_printer.instance_variable_set(:@bailed_out, false)
|
30
|
+
report_printer.instance_variable_set(:@failed_examples, '')
|
31
|
+
report_printer.instance_variable_set(:@pending_examples, '')
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#start_output' do
|
35
|
+
context 'when bailed out' do
|
36
|
+
it 'outputs nothing' do
|
37
|
+
report_printer.instance_variable_set(:@bailed_out, true)
|
38
|
+
report_printer.start_output
|
39
|
+
|
40
|
+
expect(report_output.string).to be_empty
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when not bailed out' do
|
45
|
+
let(:output_line) { 'TAP version 13' }
|
46
|
+
|
47
|
+
it 'outputs tap version with tests count' do
|
48
|
+
report_printer.start_output
|
49
|
+
|
50
|
+
expect(report_output.string.chomp).to eq(output_line)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#group_start_output' do
|
56
|
+
let(:description) { 'test-or-group-foo' }
|
57
|
+
let(:group) { OpenStruct.new(description: description) }
|
58
|
+
let(:notification) { OpenStruct.new(group: group) }
|
59
|
+
|
60
|
+
shared_context 'when root level test' do
|
61
|
+
let(:padding) { 0 }
|
62
|
+
let(:indentation) { ' ' * padding }
|
63
|
+
|
64
|
+
before do
|
65
|
+
report_printer.group_start_output(notification, padding)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
shared_context 'when non-root level test' do
|
70
|
+
let(:padding) { 1 + SecureRandom.random_number(5) }
|
71
|
+
let(:indentation) { ' ' * padding }
|
72
|
+
|
73
|
+
before do
|
74
|
+
report_printer.group_start_output(notification, padding)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with colorized outputs' do
|
79
|
+
before do
|
80
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
81
|
+
.to receive(:wrap) do |string, status|
|
82
|
+
"<#{status}>#{string}</#{status}>"
|
83
|
+
end
|
84
|
+
|
85
|
+
report_printer.instance_variable_set(:@display_colors, true)
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when root level test' do
|
89
|
+
let(:uncolorized_output_line) do
|
90
|
+
"#{indentation}# test: #{description} {"
|
91
|
+
end
|
92
|
+
let(:output_line) do
|
93
|
+
"<detail>#{uncolorized_output_line}</detail>"
|
94
|
+
end
|
95
|
+
|
96
|
+
include_context('when root level test')
|
97
|
+
|
98
|
+
it 'outputs test information' do
|
99
|
+
expect(report_output.string.chomp).to eq(output_line)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'outputs colorized test information' do
|
103
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
104
|
+
.to have_received(:wrap)
|
105
|
+
.with(a_string_equal_to(uncolorized_output_line), :detail)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when non-root level test' do
|
110
|
+
let(:uncolorized_output_line) do
|
111
|
+
"#{indentation}# group: #{description} {"
|
112
|
+
end
|
113
|
+
let(:output_line) do
|
114
|
+
"<detail>#{uncolorized_output_line}</detail>"
|
115
|
+
end
|
116
|
+
|
117
|
+
include_context('when non-root level test')
|
118
|
+
|
119
|
+
it 'outputs group information' do
|
120
|
+
expect(report_output.string.chomp).to eq(output_line)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'outputs colorized group information' do
|
124
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
125
|
+
.to have_received(:wrap)
|
126
|
+
.with(a_string_equal_to(uncolorized_output_line), :detail)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'without colorized outputs' do
|
132
|
+
before do
|
133
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
134
|
+
.to receive(:wrap).with(String, Symbol)
|
135
|
+
|
136
|
+
report_printer.instance_variable_set(:@display_colors, false)
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when root level test' do
|
140
|
+
let(:output_line) { "#{indentation}# test: #{group.description} {" }
|
141
|
+
|
142
|
+
include_context('when root level test')
|
143
|
+
|
144
|
+
it 'outputs test information' do
|
145
|
+
expect(report_output.string.chomp).to eq(output_line)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'outputs non-colorized test information' do
|
149
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
150
|
+
.not_to have_received(:wrap)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'when non-root level test' do
|
155
|
+
let(:output_line) { "#{indentation}# group: #{group.description} {" }
|
156
|
+
|
157
|
+
include_context('when non-root level test')
|
158
|
+
|
159
|
+
it 'outputs group information' do
|
160
|
+
expect(report_output.string.chomp).to eq(output_line)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'outputs non-colorized group information' do
|
164
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
165
|
+
.not_to have_received(:wrap)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe '#group_finished_output' do
|
172
|
+
let(:padding) { 1 + SecureRandom.random_number(5) }
|
173
|
+
let(:indentation) { ' ' * padding }
|
174
|
+
let(:indentation_one_level_up) { ' ' * (padding - 1) }
|
175
|
+
|
176
|
+
let(:passed) { 1 + SecureRandom.random_number(5) }
|
177
|
+
let(:failed) { 1 + SecureRandom.random_number(5) }
|
178
|
+
let(:pending) { 0 }
|
179
|
+
let(:tests) { passed + failed + pending }
|
180
|
+
let(:test_stats) { [tests, passed, failed, pending] }
|
181
|
+
|
182
|
+
context 'with colorized outputs' do
|
183
|
+
let(:uncolorized_output_line) { "#{indentation_one_level_up}}" }
|
184
|
+
let(:output_line) do
|
185
|
+
<<-OUTPUT.gsub(/^\s+\|/, '').chomp
|
186
|
+
|#{indentation}1..#{tests}
|
187
|
+
|#{indentation}# tests: #{tests}, passed: #{passed}, failed: #{failed}
|
188
|
+
|<detail>#{uncolorized_output_line}</detail>
|
189
|
+
OUTPUT
|
190
|
+
end
|
191
|
+
|
192
|
+
before do
|
193
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
194
|
+
.to receive(:wrap) do |string, status|
|
195
|
+
"<#{status}>#{string}</#{status}>"
|
196
|
+
end
|
197
|
+
|
198
|
+
report_printer.instance_variable_set(:@display_colors, true)
|
199
|
+
report_printer.group_finished_output(test_stats, padding)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'outputs tests summary' do
|
203
|
+
expect(report_output.string.chomp).to eq(output_line)
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'outputs colorized tests summary' do
|
207
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
208
|
+
.to have_received(:wrap)
|
209
|
+
.with(a_string_equal_to(uncolorized_output_line), :detail)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'without colorized outputs' do
|
214
|
+
let(:output_line) do
|
215
|
+
<<-OUTPUT.gsub(/^\s+\|/, '').chomp
|
216
|
+
|#{indentation}1..#{tests}
|
217
|
+
|#{indentation}# tests: #{tests}, passed: #{passed}, failed: #{failed}
|
218
|
+
|#{indentation_one_level_up}}
|
219
|
+
OUTPUT
|
220
|
+
end
|
221
|
+
|
222
|
+
before do
|
223
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
224
|
+
.to receive(:wrap).with(String, Symbol)
|
225
|
+
|
226
|
+
report_printer.instance_variable_set(:@display_colors, false)
|
227
|
+
report_printer.group_finished_output(test_stats, padding)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'outputs tests summary' do
|
231
|
+
expect(report_output.string.chomp).to eq(output_line)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'outputs non-colorized tests summary' do
|
235
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
236
|
+
.not_to have_received(:wrap)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe '#example_progress_output' do
|
242
|
+
shared_examples_for 'example progress output' do |char, status|
|
243
|
+
context 'when writing to file' do
|
244
|
+
include_context('when writing to file')
|
245
|
+
|
246
|
+
context 'with forced colorized outputs' do
|
247
|
+
let(:progress_output) { "<#{status}>#{char}</#{status}>" }
|
248
|
+
|
249
|
+
before do
|
250
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
251
|
+
.to receive(:wrap) do |string, color|
|
252
|
+
"<#{color}>#{string}</#{color}>"
|
253
|
+
end
|
254
|
+
|
255
|
+
allow(RSpec).to receive(:configuration)
|
256
|
+
.with(no_args)
|
257
|
+
.and_return(OpenStruct.new(color_enabled?: true))
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'outputs example progress' do
|
261
|
+
expect { report_printer.example_progress_output(status) }
|
262
|
+
.to output(progress_output).to_stdout
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'outputs colorized example progress' do
|
266
|
+
report_printer.example_progress_output(status)
|
267
|
+
|
268
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
269
|
+
.to have_received(:wrap)
|
270
|
+
.with(a_string_equal_to(char), status)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'outputs forced colorized example progress' do
|
274
|
+
report_printer.example_progress_output(status)
|
275
|
+
|
276
|
+
expect(RSpec).to have_received(:configuration).with(no_args)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
context 'without colorized outputs' do
|
281
|
+
let(:progress_output) { char }
|
282
|
+
|
283
|
+
before do
|
284
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
285
|
+
.to receive(:wrap).with(String, Symbol)
|
286
|
+
|
287
|
+
allow(RSpec).to receive(:configuration)
|
288
|
+
.with(no_args).and_return(OpenStruct.new(color_enabled?: false))
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'outputs example progress' do
|
292
|
+
expect { report_printer.example_progress_output(status) }
|
293
|
+
.to output(progress_output).to_stdout
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'outputs non-colorized example progress' do
|
297
|
+
report_printer.example_progress_output(status)
|
298
|
+
|
299
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
300
|
+
.not_to have_received(:wrap)
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'outputs non-forced colorized example progress' do
|
304
|
+
report_printer.example_progress_output(status)
|
305
|
+
|
306
|
+
expect(RSpec).to have_received(:configuration).with(no_args)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'when not writing to file' do
|
312
|
+
before do
|
313
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
314
|
+
.to receive(:wrap).with(String, Symbol)
|
315
|
+
|
316
|
+
allow(RSpec).to receive(:configuration)
|
317
|
+
.with(no_args).and_return(OpenStruct.new)
|
318
|
+
end
|
319
|
+
|
320
|
+
include_context('when not writing to file')
|
321
|
+
|
322
|
+
it 'does not output example progress' do
|
323
|
+
expect { report_printer.example_progress_output(status) }
|
324
|
+
.not_to output.to_stdout
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'does not attempt to colorize output' do
|
328
|
+
report_printer.example_progress_output(status)
|
329
|
+
|
330
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
331
|
+
.not_to have_received(:wrap)
|
332
|
+
end
|
333
|
+
|
334
|
+
it 'does not attempt to force colorize output' do
|
335
|
+
report_printer.example_progress_output(status)
|
336
|
+
|
337
|
+
expect(RSpec).not_to have_received(:configuration)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
context 'with success progress' do
|
343
|
+
include_examples('example progress output', '.', :success)
|
344
|
+
end
|
345
|
+
|
346
|
+
context 'with failure progress' do
|
347
|
+
include_examples('example progress output', 'F', :failure)
|
348
|
+
end
|
349
|
+
|
350
|
+
context 'with success progress' do
|
351
|
+
include_examples('example progress output', '*', :pending)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe '#example_progress_dump' do
|
356
|
+
context 'when writing to file' do
|
357
|
+
include_context('when writing to file')
|
358
|
+
|
359
|
+
it 'outputs a blank line' do
|
360
|
+
expect { report_printer.example_progress_dump }
|
361
|
+
.to output("\n").to_stdout
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context 'without writing to file' do
|
366
|
+
include_context('when not writing to file')
|
367
|
+
|
368
|
+
it 'outputs nothing' do
|
369
|
+
expect { report_printer.example_progress_dump }
|
370
|
+
.not_to output.to_stdout
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
describe '#success_output' do
|
376
|
+
let(:padding) { 3 }
|
377
|
+
let(:indentation) { ' ' * padding }
|
378
|
+
let(:description) { 'example-foo' }
|
379
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
380
|
+
|
381
|
+
context 'with colorized outputs' do
|
382
|
+
let(:uncolorized_output_line) do
|
383
|
+
"#{indentation}ok #{example_number} - #{description}"
|
384
|
+
end
|
385
|
+
let(:output_line) do
|
386
|
+
"<success>#{uncolorized_output_line}</success>"
|
387
|
+
end
|
388
|
+
|
389
|
+
before do
|
390
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
391
|
+
.to receive(:wrap) do |string, status|
|
392
|
+
"<#{status}>#{string}</#{status}>"
|
393
|
+
end
|
394
|
+
|
395
|
+
report_printer.instance_variable_set(:@display_colors, true)
|
396
|
+
end
|
397
|
+
|
398
|
+
it 'outputs example status' do
|
399
|
+
report_printer.success_output(description, example_number, padding)
|
400
|
+
|
401
|
+
expect(report_output.string.chomp).to eq(output_line)
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'outputs colorized status' do
|
405
|
+
report_printer.success_output(description, example_number, padding)
|
406
|
+
|
407
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
408
|
+
.to have_received(:wrap)
|
409
|
+
.with(a_string_equal_to(uncolorized_output_line), :success)
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
context 'without colorized outputs' do
|
414
|
+
let(:output_line) do
|
415
|
+
"#{indentation}ok #{example_number} - #{description}"
|
416
|
+
end
|
417
|
+
|
418
|
+
before do
|
419
|
+
allow(RSpec::Core::Formatters::ConsoleCodes).to receive(:wrap)
|
420
|
+
|
421
|
+
report_printer.instance_variable_set(:@display_colors, false)
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'outputs example status' do
|
425
|
+
report_printer.success_output(description, example_number, padding)
|
426
|
+
|
427
|
+
expect(report_output.string.chomp).to eq(output_line)
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'outputs non-colorized example status' do
|
431
|
+
report_printer.success_output(description, example_number, padding)
|
432
|
+
|
433
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
434
|
+
.not_to have_received(:wrap)
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
describe '#failure_output' do
|
440
|
+
let(:padding) { 3 }
|
441
|
+
let(:indentation) { ' ' * padding }
|
442
|
+
let(:description) { 'example-foo' }
|
443
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
444
|
+
|
445
|
+
context 'with colorized outputs' do
|
446
|
+
let(:uncolorized_output_line) do
|
447
|
+
"#{indentation}not ok #{example_number} - #{description}"
|
448
|
+
end
|
449
|
+
let(:output_line) do
|
450
|
+
"<failure>#{uncolorized_output_line}</failure>"
|
451
|
+
end
|
452
|
+
|
453
|
+
before do
|
454
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
455
|
+
.to receive(:wrap) do |string, status|
|
456
|
+
"<#{status}>#{string}</#{status}>"
|
457
|
+
end
|
458
|
+
|
459
|
+
report_printer.instance_variable_set(:@display_colors, true)
|
460
|
+
end
|
461
|
+
|
462
|
+
it 'outputs example status' do
|
463
|
+
report_printer.failure_output(description, example_number, padding)
|
464
|
+
|
465
|
+
expect(report_output.string.chomp).to eq(output_line)
|
466
|
+
end
|
467
|
+
|
468
|
+
it 'outputs colorized status' do
|
469
|
+
report_printer.failure_output(description, example_number, padding)
|
470
|
+
|
471
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
472
|
+
.to have_received(:wrap)
|
473
|
+
.with(a_string_equal_to(uncolorized_output_line), :failure)
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
context 'without colorized outputs' do
|
478
|
+
let(:output_line) do
|
479
|
+
"#{indentation}not ok #{example_number} - #{description}"
|
480
|
+
end
|
481
|
+
|
482
|
+
before do
|
483
|
+
allow(RSpec::Core::Formatters::ConsoleCodes).to receive(:wrap)
|
484
|
+
|
485
|
+
report_printer.instance_variable_set(:@display_colors, false)
|
486
|
+
end
|
487
|
+
|
488
|
+
it 'outputs example status' do
|
489
|
+
report_printer.failure_output(description, example_number, padding)
|
490
|
+
|
491
|
+
expect(report_output.string.chomp).to eq(output_line)
|
492
|
+
end
|
493
|
+
|
494
|
+
it 'outputs non-colorized example status' do
|
495
|
+
report_printer.failure_output(description, example_number, padding)
|
496
|
+
|
497
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
498
|
+
.not_to have_received(:wrap)
|
499
|
+
end
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
describe '#failure_reason_output' do
|
504
|
+
let(:padding) { 4 }
|
505
|
+
let(:indentation) { ' ' * padding }
|
506
|
+
let(:indentation_one_level_down) { ' ' * (padding + 1) }
|
507
|
+
let(:location) do
|
508
|
+
"./spec/foo_spec.rb:#{1 + SecureRandom.random_number(5)}"
|
509
|
+
end
|
510
|
+
|
511
|
+
shared_examples_for 'failure reason for non-aggregate failures' do
|
512
|
+
context 'without aggregate failures' do
|
513
|
+
let(:message_lines) { %w[first_line second_line] }
|
514
|
+
let(:formatted_backtrace) { %w[trace_first trace_second trace_third] }
|
515
|
+
let(:exception) { RSpec::Expectations::ExpectationNotMetError.new }
|
516
|
+
let(:example) do
|
517
|
+
OpenStruct.new(
|
518
|
+
execution_result: OpenStruct.new(exception: exception),
|
519
|
+
metadata: {
|
520
|
+
location: location
|
521
|
+
}
|
522
|
+
)
|
523
|
+
end
|
524
|
+
let(:notification) do
|
525
|
+
OpenStruct.new(
|
526
|
+
message_lines: message_lines,
|
527
|
+
formatted_backtrace: formatted_backtrace,
|
528
|
+
example: example
|
529
|
+
)
|
530
|
+
end
|
531
|
+
|
532
|
+
let(:failure_diagnostics) do
|
533
|
+
diagnostics = <<-DIAGNOSTICS.gsub(/^\s+\|/, '').chomp
|
534
|
+
|---
|
535
|
+
|location: "#{location}"
|
536
|
+
|error: |-
|
537
|
+
| first_line
|
538
|
+
| second_line
|
539
|
+
|backtrace: |-
|
540
|
+
| trace_first
|
541
|
+
| trace_second
|
542
|
+
| trace_third
|
543
|
+
|...
|
544
|
+
DIAGNOSTICS
|
545
|
+
|
546
|
+
diagnostics.lines
|
547
|
+
.map { |line| "#{indentation_one_level_down}#{line}" }
|
548
|
+
.join
|
549
|
+
end
|
550
|
+
|
551
|
+
it 'outputs failure diagnostics' do
|
552
|
+
report_printer.failure_reason_output(notification, padding + 1)
|
553
|
+
|
554
|
+
expect(report_output.string.chomp).to eq(failure_diagnostics)
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
shared_examples_for 'failure reason output without diagnostics' do
|
560
|
+
context 'without diagnostics' do
|
561
|
+
let(:example) do
|
562
|
+
OpenStruct.new(
|
563
|
+
execution_result: OpenStruct.new(
|
564
|
+
exception: RSpec::Expectations::ExpectationNotMetError.new
|
565
|
+
),
|
566
|
+
metadata: {
|
567
|
+
location: location
|
568
|
+
}
|
569
|
+
)
|
570
|
+
end
|
571
|
+
let(:notification) do
|
572
|
+
OpenStruct.new(
|
573
|
+
message_lines: [],
|
574
|
+
formatted_backtrace: [],
|
575
|
+
example: example
|
576
|
+
)
|
577
|
+
end
|
578
|
+
|
579
|
+
it 'outputs nothing' do
|
580
|
+
report_printer.failure_reason_output(notification, padding)
|
581
|
+
|
582
|
+
expect(report_output.string).to be_empty
|
583
|
+
end
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
if Gem::Version.new(RSpec::Core::Version::STRING) >=
|
588
|
+
Gem::Version.new('3.3.0')
|
589
|
+
context 'with RSpec version >= 3.3.0' do
|
590
|
+
before do
|
591
|
+
stub_const('RSpec::Core::Version::STRING', '3.3.1')
|
592
|
+
end
|
593
|
+
|
594
|
+
context 'with diagnostics' do
|
595
|
+
context 'with aggregate failures' do
|
596
|
+
let(:exception) do
|
597
|
+
RSpec::Expectations::MultipleExpectationsNotMetError.new
|
598
|
+
end
|
599
|
+
let(:example) do
|
600
|
+
OpenStruct.new(
|
601
|
+
execution_result: OpenStruct.new(exception: exception),
|
602
|
+
metadata: {
|
603
|
+
location: location
|
604
|
+
}
|
605
|
+
)
|
606
|
+
end
|
607
|
+
let(:notification) { OpenStruct.new(example: example) }
|
608
|
+
|
609
|
+
let(:failure_diagnostics) do
|
610
|
+
diagnostics = <<-DIAGNOSTICS.gsub(/^\s+\|/, '').chomp
|
611
|
+
|---
|
612
|
+
|location: "#{location}"
|
613
|
+
|error: RSpec::Expectations::MultipleExpectationsNotMetError
|
614
|
+
|...
|
615
|
+
DIAGNOSTICS
|
616
|
+
|
617
|
+
diagnostics.lines
|
618
|
+
.map { |line| "#{indentation_one_level_down}#{line}" }
|
619
|
+
.join
|
620
|
+
end
|
621
|
+
|
622
|
+
it 'outputs failure diagnostics' do
|
623
|
+
report_printer.failure_reason_output(notification, padding + 1)
|
624
|
+
|
625
|
+
expect(report_output.string.chomp).to eq(failure_diagnostics)
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
include_examples('failure reason for non-aggregate failures')
|
630
|
+
end
|
631
|
+
|
632
|
+
include_examples('failure reason output without diagnostics')
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
context 'with RSpec version less than 3.3.0' do
|
637
|
+
before do
|
638
|
+
stub_const('RSpec::Core::Version::STRING', '3.2.9')
|
639
|
+
end
|
640
|
+
|
641
|
+
context 'with diagnostics' do
|
642
|
+
include_examples('failure reason for non-aggregate failures')
|
643
|
+
end
|
644
|
+
|
645
|
+
include_examples('failure reason output without diagnostics')
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
describe '#pending_output' do
|
650
|
+
let(:padding) { 3 }
|
651
|
+
let(:indentation) { ' ' * padding }
|
652
|
+
let(:description) { 'example-foo' }
|
653
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
654
|
+
let(:pending_message) { "pending-#{SecureRandom.hex}" }
|
655
|
+
let(:directive) { "TODO: #{pending_message}" }
|
656
|
+
let(:execution_result) do
|
657
|
+
OpenStruct.new(
|
658
|
+
pending_message: pending_message,
|
659
|
+
example_skipped?: false
|
660
|
+
)
|
661
|
+
end
|
662
|
+
let(:example) do
|
663
|
+
OpenStruct.new(
|
664
|
+
description: description,
|
665
|
+
execution_result: execution_result
|
666
|
+
)
|
667
|
+
end
|
668
|
+
let(:notification) { OpenStruct.new(example: example) }
|
669
|
+
|
670
|
+
context 'with colorized outputs' do
|
671
|
+
let(:uncolorized_output_line) do
|
672
|
+
"#{indentation}ok #{example_number} - #{description} # #{directive}"
|
673
|
+
end
|
674
|
+
let(:output_line) do
|
675
|
+
"<pending>#{uncolorized_output_line}</pending>"
|
676
|
+
end
|
677
|
+
|
678
|
+
before do
|
679
|
+
allow(RSpec::Core::Formatters::ConsoleCodes)
|
680
|
+
.to receive(:wrap) do |string, status|
|
681
|
+
"<#{status}>#{string}</#{status}>"
|
682
|
+
end
|
683
|
+
|
684
|
+
report_printer.instance_variable_set(:@display_colors, true)
|
685
|
+
end
|
686
|
+
|
687
|
+
it 'outputs example status' do
|
688
|
+
report_printer.pending_output(
|
689
|
+
notification,
|
690
|
+
description,
|
691
|
+
example_number,
|
692
|
+
padding
|
693
|
+
)
|
694
|
+
|
695
|
+
expect(report_output.string.chomp).to eq(output_line)
|
696
|
+
end
|
697
|
+
|
698
|
+
it 'outputs colorized status' do
|
699
|
+
report_printer.pending_output(
|
700
|
+
notification,
|
701
|
+
description,
|
702
|
+
example_number,
|
703
|
+
padding
|
704
|
+
)
|
705
|
+
|
706
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
707
|
+
.to have_received(:wrap)
|
708
|
+
.with(a_string_equal_to(uncolorized_output_line), :pending)
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
context 'without colorized outputs' do
|
713
|
+
let(:output_line) do
|
714
|
+
"#{indentation}ok #{example_number} - #{description} # #{directive}"
|
715
|
+
end
|
716
|
+
|
717
|
+
before do
|
718
|
+
allow(RSpec::Core::Formatters::ConsoleCodes).to receive(:wrap)
|
719
|
+
|
720
|
+
report_printer.instance_variable_set(:@display_colors, false)
|
721
|
+
end
|
722
|
+
|
723
|
+
it 'outputs example status' do
|
724
|
+
report_printer.pending_output(
|
725
|
+
notification,
|
726
|
+
description,
|
727
|
+
example_number,
|
728
|
+
padding
|
729
|
+
)
|
730
|
+
|
731
|
+
expect(report_output.string.chomp).to eq(output_line)
|
732
|
+
end
|
733
|
+
|
734
|
+
it 'outputs non-colorized example status' do
|
735
|
+
report_printer.pending_output(
|
736
|
+
notification,
|
737
|
+
description,
|
738
|
+
example_number,
|
739
|
+
padding
|
740
|
+
)
|
741
|
+
|
742
|
+
expect(RSpec::Core::Formatters::ConsoleCodes)
|
743
|
+
.not_to have_received(:wrap)
|
744
|
+
end
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
748
|
+
describe '#message_output' do
|
749
|
+
context 'when bailed out' do
|
750
|
+
it 'outputs nothing' do
|
751
|
+
report_printer.instance_variable_set(:@bailed_out, true)
|
752
|
+
report_printer.message_output(OpenStruct.new)
|
753
|
+
|
754
|
+
expect(report_output.string).to be_empty
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
context 'when failure inside example' do
|
759
|
+
before do
|
760
|
+
allow(RSpec).to receive(:world).with(no_args)
|
761
|
+
.and_return(OpenStruct.new(non_example_failure: false))
|
762
|
+
end
|
763
|
+
|
764
|
+
it 'outputs nothing' do
|
765
|
+
report_printer.message_output(OpenStruct.new)
|
766
|
+
|
767
|
+
expect(report_output.string).to be_empty
|
768
|
+
end
|
769
|
+
|
770
|
+
it 'verifies failure type' do
|
771
|
+
report_printer.message_output(OpenStruct.new)
|
772
|
+
|
773
|
+
expect(RSpec).to have_received(:world)
|
774
|
+
end
|
775
|
+
end
|
776
|
+
|
777
|
+
context 'when failure outside example' do
|
778
|
+
let(:message) do
|
779
|
+
<<-MESSAGE.gsub(/^\s+\|/, '').chomp
|
780
|
+
|message foo
|
781
|
+
|
|
782
|
+
|bar message
|
783
|
+
|# baz qux message
|
784
|
+
|\033[0;31m# colored message quux\033[0m
|
785
|
+
MESSAGE
|
786
|
+
end
|
787
|
+
let(:notification) { OpenStruct.new(message: message) }
|
788
|
+
|
789
|
+
let(:output_line) do
|
790
|
+
<<-OUTPUT.gsub(/^\s+\|/, '').chomp
|
791
|
+
|TAP version 13
|
792
|
+
|1..0
|
793
|
+
|Bail out!
|
794
|
+
|# message foo
|
795
|
+
|# bar message
|
796
|
+
|# baz qux message
|
797
|
+
|# colored message quux
|
798
|
+
OUTPUT
|
799
|
+
end
|
800
|
+
|
801
|
+
before do
|
802
|
+
allow(RSpec).to receive(:world).with(no_args)
|
803
|
+
.and_return(OpenStruct.new(non_example_failure: true))
|
804
|
+
end
|
805
|
+
|
806
|
+
it 'outputs message' do
|
807
|
+
report_printer.message_output(notification)
|
808
|
+
|
809
|
+
expect(report_output.string.chomp).to eq(output_line)
|
810
|
+
end
|
811
|
+
|
812
|
+
it 'verifies failure type' do
|
813
|
+
report_printer.message_output(notification)
|
814
|
+
|
815
|
+
expect(RSpec).to have_received(:world)
|
816
|
+
end
|
817
|
+
|
818
|
+
it 'marks execution bailed-out' do
|
819
|
+
expect { report_printer.message_output(notification) }
|
820
|
+
.to change { report_printer.instance_variable_get(:@bailed_out) }
|
821
|
+
.from(false)
|
822
|
+
.to(true)
|
823
|
+
end
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
describe '#store_failed_examples_summary' do
|
828
|
+
context 'with failed examples' do
|
829
|
+
let(:failed_examples) do
|
830
|
+
<<-FAILURES.gsub(/^\s+\|/, '').chomp
|
831
|
+
|Failure:
|
832
|
+
|
|
833
|
+
| 1) sample spec fails
|
834
|
+
| Failure/Error: expect(1).to eq(2)
|
835
|
+
|
|
836
|
+
| expected: 2
|
837
|
+
| got: 1
|
838
|
+
|
|
839
|
+
| (compared using ==)
|
840
|
+
| # ./spec/rspec/string_spec.rb:13
|
841
|
+
| 2) sample spec fails twice
|
842
|
+
| Got 2 failures:
|
843
|
+
|
|
844
|
+
| 2.1) Failure/Error: expect(1).to eq(2)
|
845
|
+
|
|
846
|
+
| expected: 2
|
847
|
+
| got: 1
|
848
|
+
|
|
849
|
+
| (compared using ==)
|
850
|
+
| # ./spec/rspec/string_spec.rb:23
|
851
|
+
|
|
852
|
+
| 2.2) Failure/Error: expect(3).to eq(4)
|
853
|
+
|
|
854
|
+
| expected: 4
|
855
|
+
| got: 3
|
856
|
+
|
|
857
|
+
| (compared using ==)
|
858
|
+
| # ./spec/rspec/string_spec.rb:24
|
859
|
+
FAILURES
|
860
|
+
end
|
861
|
+
let(:notification) do
|
862
|
+
OpenStruct.new(
|
863
|
+
failure_notifications: %i[failure-foo failure-baz],
|
864
|
+
fully_formatted_failed_examples: failed_examples
|
865
|
+
)
|
866
|
+
end
|
867
|
+
|
868
|
+
it 'updates failed examples' do
|
869
|
+
expect { report_printer.store_failed_examples_summary(notification) }
|
870
|
+
.to change {
|
871
|
+
report_printer.instance_variable_get(:@failed_examples)
|
872
|
+
}
|
873
|
+
.from('')
|
874
|
+
.to(failed_examples)
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
context 'without failed examples' do
|
879
|
+
let(:notification) do
|
880
|
+
OpenStruct.new(failure_notifications: [])
|
881
|
+
end
|
882
|
+
|
883
|
+
it 'does not update failed examples' do
|
884
|
+
expect { report_printer.store_failed_examples_summary(notification) }
|
885
|
+
.not_to change {
|
886
|
+
report_printer.instance_variable_get(:@failed_examples)
|
887
|
+
}
|
888
|
+
end
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
describe '#store_pending_examples_summary' do
|
893
|
+
context 'with pending examples' do
|
894
|
+
let(:pending_examples) do
|
895
|
+
<<-PENDING.gsub(/^\s+\|/, '').chomp
|
896
|
+
|Pending: (Failures listed here are expected and do not affect your suite's status)
|
897
|
+
|
|
898
|
+
| 1) sample spec without implementation succeeds
|
899
|
+
| # Not yet implemented
|
900
|
+
| # ./spec/rspec/string_spec.rb:8
|
901
|
+
|
|
902
|
+
| 2) sample spec with unmet expectation also succeeds
|
903
|
+
| # No reason given
|
904
|
+
| Failure/Error: expect(1).to eq(2)
|
905
|
+
|
|
906
|
+
| expected: 2
|
907
|
+
| got: 1
|
908
|
+
|
|
909
|
+
| (compared using ==)
|
910
|
+
| # ./spec/rspec/string_spec.rb:18
|
911
|
+
PENDING
|
912
|
+
end
|
913
|
+
let(:notification) do
|
914
|
+
OpenStruct.new(
|
915
|
+
pending_examples: %i[peding-baz pending-qux],
|
916
|
+
fully_formatted_pending_examples: pending_examples
|
917
|
+
)
|
918
|
+
end
|
919
|
+
|
920
|
+
it 'updates pending examples' do
|
921
|
+
expect { report_printer.store_pending_examples_summary(notification) }
|
922
|
+
.to change {
|
923
|
+
report_printer.instance_variable_get(:@pending_examples)
|
924
|
+
}
|
925
|
+
.from('')
|
926
|
+
.to(pending_examples)
|
927
|
+
end
|
928
|
+
end
|
929
|
+
|
930
|
+
context 'without pending examples' do
|
931
|
+
let(:notification) do
|
932
|
+
OpenStruct.new(pending_examples: [])
|
933
|
+
end
|
934
|
+
|
935
|
+
it 'does not update pending examples' do
|
936
|
+
expect { report_printer.store_pending_examples_summary(notification) }
|
937
|
+
.not_to change {
|
938
|
+
report_printer.instance_variable_get(:@pending_examples)
|
939
|
+
}
|
940
|
+
end
|
941
|
+
end
|
942
|
+
end
|
943
|
+
|
944
|
+
describe '#summary_output' do
|
945
|
+
context 'when bailed out' do
|
946
|
+
it 'outputs nothing' do
|
947
|
+
report_printer.instance_variable_set(:@bailed_out, true)
|
948
|
+
report_printer.summary_output(OpenStruct.new, nil)
|
949
|
+
|
950
|
+
expect(report_output.string).to be_empty
|
951
|
+
end
|
952
|
+
end
|
953
|
+
|
954
|
+
context 'when not bailed out' do
|
955
|
+
let(:seed) { 1 + SecureRandom.random_number(10_000) }
|
956
|
+
let(:tests) { 5 + SecureRandom.random_number(6) }
|
957
|
+
let(:examples) { Array.new(tests).map { "example-#{SecureRandom.hex}" } }
|
958
|
+
let(:failed) { 2 }
|
959
|
+
let(:failed_examples) { examples.sample(2) }
|
960
|
+
let(:pending) { 2 }
|
961
|
+
let(:pending_examples) { (examples - failed_examples).sample(2) }
|
962
|
+
let(:passed) { tests - failed - pending }
|
963
|
+
let(:duration) { SecureRandom.random_number.round(6) }
|
964
|
+
let(:notification) do
|
965
|
+
OpenStruct.new(
|
966
|
+
examples: examples,
|
967
|
+
failed_examples: failed_examples,
|
968
|
+
pending_examples: pending_examples,
|
969
|
+
duration: duration
|
970
|
+
)
|
971
|
+
end
|
972
|
+
|
973
|
+
let(:failed_examples_summary) do
|
974
|
+
<<-FAILURES.gsub(/^\s+\|/, '').chomp
|
975
|
+
|Failure:
|
976
|
+
|
|
977
|
+
| 1) sample spec fails
|
978
|
+
| Failure/Error: expect(1).to eq(2)
|
979
|
+
|
|
980
|
+
| expected: 2
|
981
|
+
| got: 1
|
982
|
+
|
|
983
|
+
| (compared using ==)
|
984
|
+
| # ./spec/rspec/string_spec.rb:13
|
985
|
+
| 2) sample spec fails twice
|
986
|
+
| Got 2 failures:
|
987
|
+
|
|
988
|
+
| 2.1) Failure/Error: expect(1).to eq(2)
|
989
|
+
|
|
990
|
+
| expected: 2
|
991
|
+
| got: 1
|
992
|
+
|
|
993
|
+
| (compared using ==)
|
994
|
+
| # ./spec/rspec/string_spec.rb:23
|
995
|
+
|
|
996
|
+
| 2.2) Failure/Error: expect(3).to eq(4)
|
997
|
+
|
|
998
|
+
| expected: 4
|
999
|
+
| got: 3
|
1000
|
+
|
|
1001
|
+
| (compared using ==)
|
1002
|
+
| # ./spec/rspec/string_spec.rb:24
|
1003
|
+
FAILURES
|
1004
|
+
end
|
1005
|
+
let(:pending_examples_summary) do
|
1006
|
+
<<-PENDING.gsub(/^\s+\|/, '').chomp
|
1007
|
+
|Pending: (Failures listed here are expected and do not affect your suite's status)
|
1008
|
+
|
|
1009
|
+
| 1) sample spec without implementation succeeds
|
1010
|
+
| # Not yet implemented
|
1011
|
+
| # ./spec/rspec/string_spec.rb:8
|
1012
|
+
|
|
1013
|
+
| 2) sample spec with unmet expectation also succeeds
|
1014
|
+
| # No reason given
|
1015
|
+
| Failure/Error: expect(1).to eq(2)
|
1016
|
+
|
|
1017
|
+
| expected: 2
|
1018
|
+
| got: 1
|
1019
|
+
|
|
1020
|
+
| (compared using ==)
|
1021
|
+
| # ./spec/rspec/string_spec.rb:18
|
1022
|
+
PENDING
|
1023
|
+
end
|
1024
|
+
let(:failed_and_pending_summary) do
|
1025
|
+
"#{failed_examples_summary}\n#{pending_examples_summary}"
|
1026
|
+
end
|
1027
|
+
let(:output_line) do
|
1028
|
+
<<-OUTPUT.gsub(/^\s+\|/, '').chomp
|
1029
|
+
|1..#{tests}
|
1030
|
+
|# tests: #{tests}, passed: #{passed}, failed: #{failed}, pending: #{pending}
|
1031
|
+
|# duration: #{duration} seconds
|
1032
|
+
|# seed: #{seed}
|
1033
|
+
OUTPUT
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
before do
|
1037
|
+
report_printer.instance_variable_set(
|
1038
|
+
:@failed_examples,
|
1039
|
+
failed_examples_summary
|
1040
|
+
)
|
1041
|
+
|
1042
|
+
report_printer.instance_variable_set(
|
1043
|
+
:@pending_examples,
|
1044
|
+
pending_examples_summary
|
1045
|
+
)
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
context 'when writing to file' do
|
1049
|
+
include_context('when writing to file')
|
1050
|
+
|
1051
|
+
it 'outputs tests stats to file' do
|
1052
|
+
report_printer.summary_output(notification, seed)
|
1053
|
+
|
1054
|
+
expect(report_output.string.chomp).to eq(output_line)
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
it 'outputs failed and pending examples to stdout' do
|
1058
|
+
expect { report_printer.summary_output(notification, seed) }
|
1059
|
+
.to output(failed_and_pending_summary + "\n").to_stdout
|
1060
|
+
end
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
context 'when not writing to file' do
|
1064
|
+
include_context('when not writing to file')
|
1065
|
+
|
1066
|
+
it 'outputs tests stats, failed and pending examples' do
|
1067
|
+
report_printer.summary_output(notification, seed)
|
1068
|
+
|
1069
|
+
expect(report_output.string.chomp)
|
1070
|
+
.to eq("#{output_line}\n#{failed_and_pending_summary}")
|
1071
|
+
end
|
1072
|
+
end
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
end
|