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,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module TAP
|
5
|
+
module Formatters
|
6
|
+
# Test stats calculator
|
7
|
+
class TestStats
|
8
|
+
# @!attribute
|
9
|
+
# @return [Hash<Integer, Array<Integer, 4>>] example stats
|
10
|
+
attr_reader :data
|
11
|
+
|
12
|
+
# Constructor
|
13
|
+
def initialize
|
14
|
+
@data = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Populates total number of examples and one of
|
18
|
+
# passing, failing, and, pending example.
|
19
|
+
# Traverses bottom up to populate each of the parent example group
|
20
|
+
# stats.
|
21
|
+
#
|
22
|
+
# @param notification [ExampleNotification] example notification
|
23
|
+
# @param index [Integer] the example status index
|
24
|
+
# (1 - Passing, 2 - Failing, 3 - Pending)
|
25
|
+
def populate(notification, index)
|
26
|
+
metadata = notification.example.metadata[:example_group]
|
27
|
+
increment(metadata[:line_number], index)
|
28
|
+
|
29
|
+
while (parent_metadata = metadata[:parent_example_group])
|
30
|
+
metadata = parent_metadata
|
31
|
+
increment(metadata[:line_number], index)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Increments the stats for a line number and example status.
|
38
|
+
#
|
39
|
+
# @param line_number [Integer] the example or group line number
|
40
|
+
# @param index [Integer] the example status index
|
41
|
+
# (1 - Passing, 2 - Failing, 3 - Pending)
|
42
|
+
def increment(line_number, index)
|
43
|
+
@data[line_number] ||= [0, 0, 0, 0]
|
44
|
+
@data[line_number][0] += 1
|
45
|
+
@data[line_number][index] += 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Namespace for the parent module.
|
4
|
+
module RSpec
|
5
|
+
# Namespace for the submodule TAP.
|
6
|
+
module TAP
|
7
|
+
# Namespace for all the formatters code.
|
8
|
+
module Formatters
|
9
|
+
# Namespace for the version.
|
10
|
+
module Version
|
11
|
+
# The current version
|
12
|
+
STRING = '0.1.0'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,399 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
RSpec.describe RSpec::TAP::Formatters::Compact 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
|
+
let(:report_test_stats) { RSpec::TAP::Formatters::TestStats.new }
|
11
|
+
|
12
|
+
before do
|
13
|
+
formatter.instance_variable_set(:@printer, report_printer)
|
14
|
+
formatter.instance_variable_set(:@test_stats, report_test_stats)
|
15
|
+
formatter.instance_variable_set(:@seed, nil)
|
16
|
+
formatter.instance_variable_set(:@level, 0)
|
17
|
+
formatter.instance_variable_set(:@example_number, 0)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#seed' do
|
21
|
+
let(:seed) { SecureRandom.random_number(10_000) }
|
22
|
+
|
23
|
+
context 'with seed used' do
|
24
|
+
let(:notification) { OpenStruct.new(seed: seed, seed_used?: true) }
|
25
|
+
|
26
|
+
it 'updates instance variable' do
|
27
|
+
expect { formatter.seed(notification) }
|
28
|
+
.to change { formatter.instance_variable_get(:@seed) }
|
29
|
+
.from(nil)
|
30
|
+
.to(seed)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'without seed used' do
|
35
|
+
let(:notification) { OpenStruct.new(seed: seed, seed_used?: false) }
|
36
|
+
|
37
|
+
it 'does not update instance variable' do
|
38
|
+
expect { formatter.seed(notification) }
|
39
|
+
.not_to change { formatter.instance_variable_get(:@seed) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#start' do
|
45
|
+
let(:count) { 1 + SecureRandom.random_number(5) }
|
46
|
+
let(:notification) { OpenStruct.new(count: count) }
|
47
|
+
|
48
|
+
it 'delegates to printer' do
|
49
|
+
allow(report_printer).to receive(:start_output)
|
50
|
+
|
51
|
+
formatter.start(notification)
|
52
|
+
|
53
|
+
expect(report_printer).to have_received(:start_output).with(no_args)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#start_dump' do
|
58
|
+
it 'delegates to printer' do
|
59
|
+
allow(report_printer).to receive(:example_progress_dump)
|
60
|
+
|
61
|
+
formatter.start_dump(OpenStruct.new)
|
62
|
+
|
63
|
+
expect(report_printer).to have_received(:example_progress_dump)
|
64
|
+
.with(no_args)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#example_group_started' do
|
69
|
+
let(:level) { 1 + SecureRandom.random_number(5) }
|
70
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
71
|
+
|
72
|
+
let(:description) { 'test-or-group-foo' }
|
73
|
+
let(:group) { OpenStruct.new(description: description) }
|
74
|
+
let(:notification) { OpenStruct.new(group: group) }
|
75
|
+
|
76
|
+
before do
|
77
|
+
formatter.instance_variable_set(:@level, level)
|
78
|
+
formatter.instance_variable_set(:@example_number, example_number)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'delegates to printer' do
|
82
|
+
allow(report_printer).to receive(:group_start_output)
|
83
|
+
|
84
|
+
formatter.example_group_started(notification)
|
85
|
+
|
86
|
+
expect(report_printer).to have_received(:group_start_output)
|
87
|
+
.with(notification, level)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'increments level by one' do
|
91
|
+
expect { formatter.example_group_started(notification) }
|
92
|
+
.to change { formatter.instance_variable_get(:@level) }
|
93
|
+
.by(1)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'resets example number to zero' do
|
97
|
+
expect { formatter.example_group_started(notification) }
|
98
|
+
.to change { formatter.instance_variable_get(:@example_number) }
|
99
|
+
.from(example_number)
|
100
|
+
.to(0)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#example_group_finished' do
|
105
|
+
let(:passed) { 1 + SecureRandom.random_number(5) }
|
106
|
+
let(:failed) { 1 + SecureRandom.random_number(5) }
|
107
|
+
let(:pending) { 1 + SecureRandom.random_number(5) }
|
108
|
+
let(:tests) { passed + failed + pending }
|
109
|
+
let(:stats_data) { { line_number => [tests, passed, failed, pending] } }
|
110
|
+
|
111
|
+
let(:group) { OpenStruct.new(metadata: { line_number: line_number }) }
|
112
|
+
let(:notification) { OpenStruct.new(group: group) }
|
113
|
+
|
114
|
+
before do
|
115
|
+
formatter.instance_variable_set(:@level, level)
|
116
|
+
formatter.instance_variable_get(:@test_stats)
|
117
|
+
.instance_variable_set(:@data, stats_data)
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when root level test' do
|
121
|
+
let(:level) { 0 }
|
122
|
+
let(:line_number) { 1 + SecureRandom.random_number(5) }
|
123
|
+
|
124
|
+
it 'delegates to printer' do
|
125
|
+
allow(report_printer).to receive(:group_finished_output)
|
126
|
+
|
127
|
+
formatter.example_group_finished(notification)
|
128
|
+
|
129
|
+
expect(report_printer).to have_received(:group_finished_output)
|
130
|
+
.with(stats_data[line_number], level)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'does not decrement level' do
|
134
|
+
expect { formatter.example_group_finished(notification) }
|
135
|
+
.not_to change { formatter.instance_variable_get(:@level) }
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'instantiates test stats object' do
|
139
|
+
expect { formatter.example_group_finished(notification) }
|
140
|
+
.to change {
|
141
|
+
formatter.instance_variable_get(:@test_stats).object_id
|
142
|
+
}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when non-root level test' do
|
147
|
+
let(:level) { 2 }
|
148
|
+
let(:line_number) { 1 + SecureRandom.random_number(5) }
|
149
|
+
|
150
|
+
it 'delegates to printer' do
|
151
|
+
allow(report_printer).to receive(:group_finished_output)
|
152
|
+
|
153
|
+
formatter.example_group_finished(notification)
|
154
|
+
|
155
|
+
expect(report_printer).to have_received(:group_finished_output)
|
156
|
+
.with(stats_data[line_number], level)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'decrements level' do
|
160
|
+
expect { formatter.example_group_finished(notification) }
|
161
|
+
.to change { formatter.instance_variable_get(:@level) }
|
162
|
+
.by(-1)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'does not instantiate test stats object' do
|
166
|
+
expect { formatter.example_group_finished(notification) }
|
167
|
+
.not_to change {
|
168
|
+
formatter.instance_variable_get(:@test_stats).object_id
|
169
|
+
}
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe '#example_started' do
|
175
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
176
|
+
|
177
|
+
it 'increments example number by one' do
|
178
|
+
expect { formatter.example_started(OpenStruct.new) }
|
179
|
+
.to change { formatter.instance_variable_get(:@example_number) }
|
180
|
+
.by(1)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#example_passed' do
|
185
|
+
let(:level) { 1 + SecureRandom.random_number(5) }
|
186
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
187
|
+
let(:example_status) { :success }
|
188
|
+
let(:example_status_index) { 1 }
|
189
|
+
|
190
|
+
let(:description) { 'example-foo' }
|
191
|
+
let(:example) { OpenStruct.new(description: description) }
|
192
|
+
let(:notification) { OpenStruct.new(example: example) }
|
193
|
+
|
194
|
+
before do
|
195
|
+
formatter.instance_variable_set(:@level, level)
|
196
|
+
formatter.instance_variable_set(:@example_number, example_number)
|
197
|
+
|
198
|
+
allow(report_test_stats).to receive(:populate)
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'populates test stats' do
|
202
|
+
formatter.example_passed(notification)
|
203
|
+
|
204
|
+
expect(report_test_stats).to have_received(:populate)
|
205
|
+
.with(notification, example_status_index)
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'delegates progress report to printer' do
|
209
|
+
allow(report_printer).to receive(:example_progress_output)
|
210
|
+
|
211
|
+
formatter.example_passed(notification)
|
212
|
+
|
213
|
+
expect(report_printer).to have_received(:example_progress_output)
|
214
|
+
.with(example_status)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'delegates status report to printer' do
|
218
|
+
allow(report_printer).to receive(:success_output)
|
219
|
+
|
220
|
+
formatter.example_passed(notification)
|
221
|
+
|
222
|
+
expect(report_printer).to have_received(:success_output)
|
223
|
+
.with(description, example_number, level)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe '#example_failed' do
|
228
|
+
let(:level) { 1 + SecureRandom.random_number(5) }
|
229
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
230
|
+
let(:example_status) { :failure }
|
231
|
+
let(:example_status_index) { 2 }
|
232
|
+
|
233
|
+
let(:description) { 'example-foo' }
|
234
|
+
let(:example) { OpenStruct.new(description: description) }
|
235
|
+
let(:notification) { OpenStruct.new(example: example) }
|
236
|
+
|
237
|
+
before do
|
238
|
+
formatter.instance_variable_set(:@level, level)
|
239
|
+
formatter.instance_variable_set(:@example_number, example_number)
|
240
|
+
|
241
|
+
allow(report_test_stats).to receive(:populate)
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'populates test stats' do
|
245
|
+
formatter.example_failed(notification)
|
246
|
+
|
247
|
+
expect(report_test_stats).to have_received(:populate)
|
248
|
+
.with(notification, example_status_index)
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'delegates progress report to printer' do
|
252
|
+
allow(report_printer).to receive(:example_progress_output)
|
253
|
+
|
254
|
+
formatter.example_failed(notification)
|
255
|
+
|
256
|
+
expect(report_printer).to have_received(:example_progress_output)
|
257
|
+
.with(example_status)
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'delegates status report to printer' do
|
261
|
+
allow(report_printer).to receive(:failure_output)
|
262
|
+
|
263
|
+
formatter.example_failed(notification)
|
264
|
+
|
265
|
+
expect(report_printer).to have_received(:failure_output)
|
266
|
+
.with(description, example_number, level)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe '#example_pending' do
|
271
|
+
let(:level) { 1 + SecureRandom.random_number(5) }
|
272
|
+
let(:example_number) { 1 + SecureRandom.random_number(5) }
|
273
|
+
let(:example_status) { :pending }
|
274
|
+
let(:example_status_index) { 3 }
|
275
|
+
|
276
|
+
let(:description) { 'example-foo' }
|
277
|
+
let(:example) do
|
278
|
+
OpenStruct.new(
|
279
|
+
description: description,
|
280
|
+
execution_result: execution_result
|
281
|
+
)
|
282
|
+
end
|
283
|
+
let(:notification) { OpenStruct.new(example: example) }
|
284
|
+
|
285
|
+
before do
|
286
|
+
formatter.instance_variable_set(:@level, level)
|
287
|
+
formatter.instance_variable_set(:@example_number, example_number)
|
288
|
+
|
289
|
+
allow(report_test_stats).to receive(:populate)
|
290
|
+
end
|
291
|
+
|
292
|
+
shared_examples_for 'pending example' do
|
293
|
+
it 'populates test stats' do
|
294
|
+
formatter.example_pending(notification)
|
295
|
+
|
296
|
+
expect(report_test_stats).to have_received(:populate)
|
297
|
+
.with(notification, example_status_index)
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'delegates progress report to printer' do
|
301
|
+
allow(report_printer).to receive(:example_progress_output)
|
302
|
+
|
303
|
+
formatter.example_pending(notification)
|
304
|
+
|
305
|
+
expect(report_printer).to have_received(:example_progress_output)
|
306
|
+
.with(example_status)
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'delegates status report to printer' do
|
310
|
+
allow(report_printer).to receive(:pending_output)
|
311
|
+
|
312
|
+
formatter.example_pending(notification)
|
313
|
+
|
314
|
+
expect(report_printer).to have_received(:pending_output)
|
315
|
+
.with(notification, description, example_number, level)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
context 'with pending' do
|
320
|
+
let(:pending_message) { "pending-#{SecureRandom.hex}" }
|
321
|
+
let(:directive) { "TODO: #{pending_message}" }
|
322
|
+
let(:execution_result) do
|
323
|
+
OpenStruct.new(
|
324
|
+
pending_message: pending_message,
|
325
|
+
example_skipped?: false
|
326
|
+
)
|
327
|
+
end
|
328
|
+
|
329
|
+
include_examples('pending example')
|
330
|
+
end
|
331
|
+
|
332
|
+
context 'with skipped' do
|
333
|
+
let(:pending_message) { "skip-#{SecureRandom.hex}" }
|
334
|
+
let(:directive) { "SKIP: #{pending_message}" }
|
335
|
+
let(:execution_result) do
|
336
|
+
OpenStruct.new(
|
337
|
+
pending_message: pending_message,
|
338
|
+
example_skipped?: true
|
339
|
+
)
|
340
|
+
end
|
341
|
+
|
342
|
+
include_examples('pending example')
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
describe '#message' do
|
347
|
+
let(:notification) { OpenStruct.new }
|
348
|
+
|
349
|
+
it 'delegates to printer' do
|
350
|
+
allow(report_printer).to receive(:message_output)
|
351
|
+
|
352
|
+
formatter.message(notification)
|
353
|
+
|
354
|
+
expect(report_printer).to have_received(:message_output)
|
355
|
+
.with(notification)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
describe '#dump_failures' do
|
360
|
+
let(:notification) { OpenStruct.new }
|
361
|
+
|
362
|
+
it 'delegates to printer' do
|
363
|
+
allow(report_printer).to receive(:store_failed_examples_summary)
|
364
|
+
|
365
|
+
formatter.dump_failures(notification)
|
366
|
+
|
367
|
+
expect(report_printer).to have_received(:store_failed_examples_summary)
|
368
|
+
.with(notification)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
describe '#dump_pending' do
|
373
|
+
let(:notification) { OpenStruct.new }
|
374
|
+
|
375
|
+
it 'delegates to printer' do
|
376
|
+
allow(report_printer).to receive(:store_pending_examples_summary)
|
377
|
+
|
378
|
+
formatter.dump_pending(notification)
|
379
|
+
|
380
|
+
expect(report_printer).to have_received(:store_pending_examples_summary)
|
381
|
+
.with(notification)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
describe '#dump_summary' do
|
386
|
+
let(:seed) { 1 + SecureRandom.random_number(10_000) }
|
387
|
+
let(:notification) { OpenStruct.new }
|
388
|
+
|
389
|
+
it 'delegates to printer' do
|
390
|
+
allow(report_printer).to receive(:summary_output)
|
391
|
+
|
392
|
+
formatter.instance_variable_set(:@seed, seed)
|
393
|
+
formatter.dump_summary(notification)
|
394
|
+
|
395
|
+
expect(report_printer).to have_received(:summary_output)
|
396
|
+
.with(notification, seed)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|