knapsack_pro 5.7.0 → 6.0.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.
@@ -0,0 +1,453 @@
1
+ # Named _specs.rb on purpose because it hangs if run as part of `bundle exec rspec`.
2
+ # Use `bundle exec ruby spec/knapsack_pro/formatters/time_tracker_specs.rb` instead.
3
+
4
+ require 'rspec/core'
5
+ require 'knapsack_pro'
6
+ require 'stringio'
7
+ require_relative '../../../lib/knapsack_pro/formatters/time_tracker'
8
+
9
+ class TestTimeTracker
10
+ def test_single_example
11
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
12
+ false
13
+ end
14
+
15
+ spec = <<~SPEC
16
+ describe "KnapsackPro::Formatters::TimeTracker" do
17
+ it do
18
+ sleep 0.1
19
+ expect(1).to eq 1
20
+ end
21
+ end
22
+ SPEC
23
+
24
+ run_specs(spec) do |spec_paths, times|
25
+ raise unless times.size == 1
26
+ raise unless times[0]["path"] == spec_paths.first
27
+ raise unless times[0]["time_execution"] > 0.10
28
+ raise unless times[0]["time_execution"] < 0.15
29
+ end
30
+ end
31
+
32
+ def test_two_files
33
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
34
+ false
35
+ end
36
+
37
+ spec_1 = <<~SPEC
38
+ describe "KnapsackPro::Formatters::TimeTracker 1" do
39
+ it do
40
+ sleep 0.1
41
+ expect(1).to eq 1
42
+ end
43
+ end
44
+ SPEC
45
+
46
+ spec_2 = <<~SPEC
47
+ describe "KnapsackPro::Formatters::TimeTracker 2" do
48
+ it do
49
+ sleep 0.2
50
+ expect(1).to eq 1
51
+ end
52
+ end
53
+ SPEC
54
+
55
+ run_specs([spec_1, spec_2]) do |spec_paths, times|
56
+ raise unless times.size == 2
57
+ raise unless times.first["path"] == spec_paths.first
58
+ raise unless times.first["time_execution"] > 0.10
59
+ raise unless times.first["time_execution"] < 0.15
60
+ raise unless times.last["path"] == spec_paths.last
61
+ raise unless times.last["time_execution"] > 0.20
62
+ raise unless times.last["time_execution"] < 0.25
63
+ end
64
+ end
65
+
66
+ def test_failing_example
67
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
68
+ false
69
+ end
70
+
71
+ spec = <<~SPEC
72
+ describe "KnapsackPro::Formatters::TimeTracker" do
73
+ it do
74
+ sleep 0.1
75
+ expect(1).to eq 2
76
+ end
77
+ end
78
+ SPEC
79
+
80
+ run_specs(spec) do |spec_paths, times|
81
+ raise unless times.size == 1
82
+ raise unless times[0]["path"] == spec_paths.first
83
+ raise unless times[0]["time_execution"] > 0.10
84
+ raise unless times[0]["time_execution"] < 0.15
85
+ end
86
+ end
87
+
88
+ def test_pending_example
89
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
90
+ false
91
+ end
92
+
93
+ spec = <<~SPEC
94
+ describe "KnapsackPro::Formatters::TimeTracker" do
95
+ xit do
96
+ sleep 0.1
97
+ expect(1).to eq 2
98
+ end
99
+ end
100
+ SPEC
101
+
102
+ run_specs(spec) do |spec_paths, times|
103
+ raise unless times.size == 1
104
+ raise unless times[0]["path"] == spec_paths.first
105
+ raise unless times[0]["time_execution"] == 0.0
106
+ end
107
+ end
108
+
109
+ def test_multiple_top_level_groups
110
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
111
+ false
112
+ end
113
+
114
+ spec = <<~SPEC
115
+ describe "KnapsackPro::Formatters::TimeTracker 1" do
116
+ it do
117
+ sleep 0.1
118
+ expect(1).to eq 1
119
+ end
120
+ end
121
+
122
+ describe "KnapsackPro::Formatters::TimeTracker 2" do
123
+ it do
124
+ sleep 0.2
125
+ expect(1).to eq 1
126
+ end
127
+ end
128
+ SPEC
129
+
130
+ run_specs(spec) do |spec_paths, times|
131
+ raise unless times.size == 1
132
+ raise unless times[0]["path"] == spec_paths.first
133
+ raise unless times[0]["time_execution"] > 0.30
134
+ raise unless times[0]["time_execution"] < 0.35
135
+ end
136
+ end
137
+
138
+ def test_rspec_split_by_test_example
139
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
140
+ true
141
+ end
142
+
143
+ spec = <<~SPEC
144
+ describe "KnapsackPro::Formatters::TimeTracker 1" do
145
+ it do
146
+ expect(1).to eq 1
147
+ end
148
+
149
+ it do
150
+ sleep 0.1
151
+ expect(1).to eq 1
152
+ end
153
+ end
154
+
155
+ describe "KnapsackPro::Formatters::TimeTracker 2" do
156
+ it do
157
+ sleep 0.2
158
+ expect(1).to eq 1
159
+ end
160
+
161
+ it do
162
+ sleep 0.3
163
+ expect(1).to eq 1
164
+ end
165
+ end
166
+ SPEC
167
+
168
+ run_specs(spec) do |spec_paths, times|
169
+ raise unless times.size == 4
170
+ spec_path = spec_paths.first
171
+ raise unless times.find { |time| time["path"] == "#{spec_path}[1:1]" }["time_execution"] < 0.05
172
+ raise unless times.find { |time| time["path"] == "#{spec_path}[1:2]" }["time_execution"] > 0.10
173
+ raise unless times.find { |time| time["path"] == "#{spec_path}[1:2]" }["time_execution"] < 0.15
174
+ raise unless times.find { |time| time["path"] == "#{spec_path}[2:1]" }["time_execution"] > 0.20
175
+ raise unless times.find { |time| time["path"] == "#{spec_path}[2:1]" }["time_execution"] < 0.25
176
+ raise unless times.find { |time| time["path"] == "#{spec_path}[2:2]" }["time_execution"] > 0.30
177
+ raise unless times.find { |time| time["path"] == "#{spec_path}[2:2]" }["time_execution"] < 0.35
178
+ end
179
+ end
180
+
181
+ def test_hooks
182
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
183
+ false
184
+ end
185
+
186
+ spec = <<~SPEC
187
+ describe "KnapsackPro::Formatters::TimeTracker" do
188
+ before(:all) do
189
+ sleep 0.1
190
+ end
191
+
192
+ before(:each) do
193
+ sleep 0.1
194
+ end
195
+
196
+ after(:each) do
197
+ sleep 0.1
198
+ end
199
+
200
+ it do
201
+ expect(1).to eq 1
202
+ end
203
+
204
+ it do
205
+ expect(1).to eq 1
206
+ end
207
+
208
+ after(:all) do
209
+ sleep 0.1
210
+ end
211
+ end
212
+ SPEC
213
+
214
+ run_specs(spec) do |spec_paths, times|
215
+ raise unless times.size == 1
216
+ raise unless times[0]["path"] == spec_paths.first
217
+ raise unless times[0]["time_execution"] > 0.60
218
+ raise unless times[0]["time_execution"] < 0.65
219
+ end
220
+ end
221
+
222
+ def test_hooks_with_rspec_split_by_test_example
223
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
224
+ true
225
+ end
226
+
227
+ spec = <<~SPEC
228
+ describe "KnapsackPro::Formatters::TimeTracker" do
229
+ before(:all) do
230
+ sleep 0.1
231
+ end
232
+
233
+ before(:each) do
234
+ sleep 0.1
235
+ end
236
+
237
+ after(:each) do
238
+ sleep 0.1
239
+ end
240
+
241
+ it do
242
+ expect(1).to eq 1
243
+ end
244
+
245
+ it do
246
+ expect(1).to eq 1
247
+ end
248
+
249
+ after(:all) do
250
+ sleep 0.1
251
+ end
252
+ end
253
+ SPEC
254
+
255
+ run_specs(spec) do |spec_paths, times|
256
+ raise unless times.size == 2
257
+ spec_path = spec_paths.first
258
+ raise unless times.find { |time| time["path"] == "#{spec_path}[1:1]" }["time_execution"] > 0.40
259
+ raise unless times.find { |time| time["path"] == "#{spec_path}[1:1]" }["time_execution"] < 0.45
260
+ raise unless times.find { |time| time["path"] == "#{spec_path}[1:2]" }["time_execution"] > 0.40
261
+ raise unless times.find { |time| time["path"] == "#{spec_path}[1:2]" }["time_execution"] < 0.45
262
+ end
263
+ end
264
+
265
+ def test_unknown_path
266
+ KnapsackPro::Formatters::TimeTracker.class_eval do
267
+ alias_method :original_file_path_for, :file_path_for
268
+
269
+ define_method(:file_path_for) do |_example|
270
+ ""
271
+ end
272
+ end
273
+
274
+ spec = <<~SPEC
275
+ describe "KnapsackPro::Formatters::TimeTracker" do
276
+ it do
277
+ expect(1).to eq 1
278
+ end
279
+ end
280
+ SPEC
281
+
282
+ run_specs(spec) do |spec_paths, times|
283
+ raise unless times.size == 2
284
+ raise unless times[0]["path"] == "UNKNOWN_PATH"
285
+ raise unless times[1]["path"] == spec_paths.first
286
+ end
287
+
288
+ ensure
289
+ KnapsackPro::Formatters::TimeTracker.class_eval do
290
+ undef :file_path_for
291
+ alias_method :file_path_for, :original_file_path_for
292
+ end
293
+ end
294
+
295
+ def test_empty_group
296
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
297
+ false
298
+ end
299
+
300
+ spec = <<~SPEC
301
+ describe "KnapsackPro::Formatters::TimeTracker" do
302
+ end
303
+ SPEC
304
+
305
+ run_specs(spec) do |spec_paths, times|
306
+ raise unless times.size == 1
307
+ raise unless times[0]["path"] == spec_paths.first
308
+ raise unless times[0]["time_execution"] == 0.0
309
+ end
310
+ end
311
+
312
+ def test_duration
313
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
314
+ false
315
+ end
316
+
317
+ spec = <<~SPEC
318
+ describe "KnapsackPro::Formatters::TimeTracker" do
319
+ it do
320
+ expect(1).to eq 1
321
+ end
322
+ end
323
+ SPEC
324
+
325
+ run_specs(spec) do |_, _, time_tracker|
326
+ raise unless time_tracker.duration > 0.0
327
+ end
328
+ end
329
+
330
+ def test_batch_duration
331
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
332
+ false
333
+ end
334
+
335
+ spec = <<~SPEC
336
+ describe "KnapsackPro::Formatters::TimeTracker" do
337
+ it do
338
+ expect(1).to eq 1
339
+ end
340
+ end
341
+ SPEC
342
+
343
+ run_specs(spec) do |_, _, time_tracker|
344
+ raise unless time_tracker.batch_duration > 0.0
345
+ end
346
+ end
347
+
348
+ def test_unexecuted_test_files
349
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
350
+ false
351
+ end
352
+
353
+ spec = <<~SPEC
354
+ describe "KnapsackPro::Formatters::TimeTracker" do
355
+ xit do
356
+ end
357
+ end
358
+ SPEC
359
+
360
+ run_specs(spec) do |spec_paths, _, time_tracker|
361
+ unexecuted_test_files = ["foo_spec.rb", "bar_spec.rb"]
362
+ # Need to filter because RSpec keeps accumulating state.
363
+ files = time_tracker
364
+ .unexecuted_test_files(spec_paths + unexecuted_test_files)
365
+ .filter { |file| spec_paths.include?(file) || unexecuted_test_files.include?(file) }
366
+
367
+ raise unless files.size == 3
368
+ end
369
+ end
370
+
371
+ def test_subset
372
+ KnapsackPro::Formatters::TimeTracker.define_method(:rspec_split_by_test_example?) do |_file|
373
+ false
374
+ end
375
+ KnapsackPro::Formatters::TimeTracker.class_eval do
376
+ alias_method :original_stop, :stop
377
+
378
+ # In Regular Mode, #subset is called before #stop.
379
+ # This test makes #stop a noop to simulate that behavior.
380
+ define_method(:stop) do |_|
381
+ end
382
+ end
383
+
384
+ spec = <<~SPEC
385
+ describe "KnapsackPro::Formatters::TimeTracker" do
386
+ it "works" do
387
+ sleep 0.1
388
+ expect(1).to eq 1
389
+ end
390
+ end
391
+ SPEC
392
+
393
+ run_specs(spec) do |spec_paths, times, time_tracker|
394
+ # Need to filter because RSpec keeps accumulating state.
395
+ files = time_tracker
396
+ .batch
397
+ .filter { |file| spec_paths.include?(file["path"]) }
398
+
399
+ raise unless files.size == 1
400
+ raise unless files[0]["path"] == spec_paths.first
401
+ raise unless files[0]["time_execution"] > 0.10
402
+ raise unless files[0]["time_execution"] < 0.15
403
+ end
404
+
405
+ ensure
406
+ KnapsackPro::Formatters::TimeTracker.class_eval do
407
+ undef :stop
408
+ alias_method :stop, :original_stop
409
+ end
410
+ end
411
+
412
+ private
413
+
414
+ def run_specs(specs)
415
+ paths = Array(specs).map.with_index do |spec, i|
416
+ path = "spec/knapsack_pro/formatters/#{i}_#{SecureRandom.uuid}_spec.rb"
417
+ File.open(path, 'w') { |file| file.write(spec) }
418
+ path
419
+ end
420
+
421
+ options = ::RSpec::Core::ConfigurationOptions.new([
422
+ "--format", KnapsackPro::Formatters::TimeTracker.to_s,
423
+ *paths,
424
+ ])
425
+ runner = ::RSpec::Core::Runner.new(options)
426
+ runner.run(StringIO.new, StringIO.new)
427
+
428
+ time_tracker = runner.configuration.formatters.find { |f| f.class.to_s == KnapsackPro::Formatters::TimeTracker.to_s }
429
+ # Need to filter because RSpec keeps accumulating state.
430
+ times = time_tracker
431
+ .queue(paths)
432
+ .sort_by { |time| time["path"] }
433
+ .filter do |time|
434
+ paths.any? { |path| time["path"].start_with?(path) || time["path"] == "UNKNOWN_PATH" }
435
+ end
436
+ yield(paths, times, time_tracker)
437
+
438
+ ensure
439
+ paths.each { |path| File.delete(path) }
440
+ # Need to reset because RSpec keeps reusing the same instance.
441
+ time_tracker.instance_variable_set(:@queue, {}) if time_tracker
442
+ time_tracker.instance_variable_set(:@started, time_tracker.send(:now)) if time_tracker
443
+ end
444
+ end
445
+
446
+ TestTimeTracker
447
+ .instance_methods
448
+ .filter { |method| method.to_s.start_with?("test_") }
449
+ .shuffle
450
+ .each do |method|
451
+ puts method
452
+ TestTimeTracker.new.public_send(method)
453
+ end
@@ -6,6 +6,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
6
6
 
7
7
  require KnapsackPro.root + '/lib/knapsack_pro/formatters/rspec_queue_summary_formatter'
8
8
  require KnapsackPro.root + '/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension'
9
+ require KnapsackPro.root + '/lib/knapsack_pro/formatters/time_tracker'
9
10
  end
10
11
 
11
12
  describe '.run' do
@@ -45,7 +46,13 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
45
46
  status: :next,
46
47
  runner: runner,
47
48
  can_initialize_queue: true,
48
- args: ['--example-arg', 'example-value', '--format', 'progress', '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter', '--default-path', 'fake-test-dir'],
49
+ args: [
50
+ '--example-arg', 'example-value',
51
+ '--format', 'progress',
52
+ '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter',
53
+ '--format', 'KnapsackPro::Formatters::TimeTracker',
54
+ '--default-path', 'fake-test-dir',
55
+ ],
49
56
  exitstatus: 0,
50
57
  all_test_file_paths: [],
51
58
  }
@@ -71,7 +78,12 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
71
78
  status: :next,
72
79
  runner: runner,
73
80
  can_initialize_queue: true,
74
- args: ['--format', 'documentation', '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter', '--default-path', 'fake-test-dir'],
81
+ args: [
82
+ '--format', 'documentation',
83
+ '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter',
84
+ '--format', 'KnapsackPro::Formatters::TimeTracker',
85
+ '--default-path', 'fake-test-dir',
86
+ ],
75
87
  exitstatus: 0,
76
88
  all_test_file_paths: [],
77
89
  }
@@ -97,7 +109,12 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
97
109
  status: :next,
98
110
  runner: runner,
99
111
  can_initialize_queue: true,
100
- args: ['-f', 'd', '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter', '--default-path', 'fake-test-dir'],
112
+ args: [
113
+ '-f', 'd',
114
+ '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter',
115
+ '--format', 'KnapsackPro::Formatters::TimeTracker',
116
+ '--default-path', 'fake-test-dir',
117
+ ],
101
118
  exitstatus: 0,
102
119
  all_test_file_paths: [],
103
120
  }
@@ -123,7 +140,12 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
123
140
  status: :next,
124
141
  runner: runner,
125
142
  can_initialize_queue: true,
126
- args: ['-fMyCustomFormatter', '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter', '--default-path', 'fake-test-dir'],
143
+ args: [
144
+ '-fMyCustomFormatter',
145
+ '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter',
146
+ '--format', 'KnapsackPro::Formatters::TimeTracker',
147
+ '--default-path', 'fake-test-dir',
148
+ ],
127
149
  exitstatus: 0,
128
150
  all_test_file_paths: [],
129
151
  }
@@ -165,7 +187,12 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
165
187
  status: :next,
166
188
  runner: runner,
167
189
  can_initialize_queue: true,
168
- args: ['--format', 'progress', '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter', '--default-path', 'fake-test-dir'],
190
+ args: [
191
+ '--format', 'progress',
192
+ '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter',
193
+ '--format', 'KnapsackPro::Formatters::TimeTracker',
194
+ '--default-path', 'fake-test-dir',
195
+ ],
169
196
  exitstatus: 0,
170
197
  all_test_file_paths: [],
171
198
  }
@@ -219,12 +246,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
219
246
 
220
247
  expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_SUBSET_QUEUE_ID', subset_queue_id)
221
248
 
222
- tracker = instance_double(KnapsackPro::Tracker)
223
- expect(KnapsackPro).to receive(:tracker).twice.and_return(tracker)
224
- expect(tracker).to receive(:reset!)
225
- expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
226
-
227
- expect(described_class).to receive(:ensure_spec_opts_have_rspec_queue_summary_formatter)
249
+ expect(described_class).to receive(:ensure_spec_opts_have_knapsack_pro_formatters)
228
250
  options = double
229
251
  expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
230
252
  '--no-color',
@@ -241,8 +263,6 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
241
263
 
242
264
  expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
243
265
 
244
- expect(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
245
-
246
266
  configuration = double
247
267
  expect(rspec_core_runner).to receive(:configuration).twice.and_return(configuration)
248
268
  expect(configuration).to receive(:seed_used?).and_return(true)
@@ -344,12 +364,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
344
364
 
345
365
  expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_SUBSET_QUEUE_ID', subset_queue_id)
346
366
 
347
- tracker = instance_double(KnapsackPro::Tracker)
348
- expect(KnapsackPro).to receive(:tracker).twice.and_return(tracker)
349
- expect(tracker).to receive(:reset!)
350
- expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
351
-
352
- expect(described_class).to receive(:ensure_spec_opts_have_rspec_queue_summary_formatter)
367
+ expect(described_class).to receive(:ensure_spec_opts_have_knapsack_pro_formatters)
353
368
  options = double
354
369
  expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
355
370
  '--no-color',
@@ -361,16 +376,14 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
361
376
  expect(RSpec::Core::Runner).to receive(:new).with(options).and_return(rspec_core_runner)
362
377
  expect(rspec_core_runner).to receive(:run).with($stderr, $stdout).and_raise SystemExit
363
378
  expect(KnapsackPro::Hooks::Queue).to receive(:call_before_subset_queue)
364
- allow(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
365
379
  allow(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
366
380
  allow(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
367
381
  allow(KnapsackPro::Formatters::RSpecQueueSummaryFormatter).to receive(:print_exit_summary)
368
382
  expect(Kernel).to receive(:exit).with(1)
369
383
  end
370
384
 
371
- it 'does not call #save_subset_queue_to_file or #rspec_clear_examples' do
385
+ it 'does not call #rspec_clear_examples' do
372
386
  expect(described_class).not_to receive(:rspec_clear_examples)
373
- expect(KnapsackPro::Report).not_to receive(:save_subset_queue_to_file)
374
387
  expect { subject }.to raise_error SystemExit
375
388
  end
376
389
 
@@ -411,7 +424,14 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
411
424
  expect(KnapsackPro::Formatters::RSpecQueueProfileFormatterExtension).to receive(:print_summary)
412
425
 
413
426
  expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
414
- expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
427
+
428
+ time_tracker = instance_double(KnapsackPro::Formatters::TimeTracker)
429
+ times = all_test_file_paths.map do |path|
430
+ [{ path: path, time_execution: 1.0 }]
431
+ end
432
+ expect(time_tracker).to receive(:queue).and_return(times)
433
+ expect(KnapsackPro::Formatters::TimeTrackerFetcher).to receive(:call).and_return(time_tracker)
434
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api).with(times)
415
435
 
416
436
  expect(logger).to receive(:info)
417
437
  .with('To retry all the tests assigned to this CI node, please run the following command on your machine:')
@@ -448,7 +468,15 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
448
468
 
449
469
  it do
450
470
  expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
451
- expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
471
+
472
+ time_tracker = instance_double(KnapsackPro::Formatters::TimeTracker)
473
+ times = all_test_file_paths.map do |path|
474
+ [{ path: path, time_execution: 0.0 }]
475
+ end
476
+ expect(time_tracker).to receive(:queue).and_return(times)
477
+ expect(KnapsackPro::Formatters::TimeTrackerFetcher).to receive(:call).and_return(time_tracker)
478
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api).with(times)
479
+
452
480
  expect(KnapsackPro).to_not receive(:logger)
453
481
 
454
482
  expect(subject).to eq({
@@ -460,29 +488,40 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
460
488
  end
461
489
  end
462
490
 
463
- describe '.ensure_spec_opts_have_rspec_queue_summary_formatter' do
464
- subject { described_class.ensure_spec_opts_have_rspec_queue_summary_formatter }
491
+ describe '.ensure_spec_opts_have_knapsack_pro_formatters' do
492
+ subject { described_class.ensure_spec_opts_have_knapsack_pro_formatters }
465
493
 
466
494
  context 'when `SPEC_OPTS` is set' do
467
- context 'when `SPEC_OPTS` has RSpec Queue Summary Formatter' do
495
+ context 'when `SPEC_OPTS` has RSpecQueueSummaryFormatter' do
468
496
  before do
469
497
  stub_const('ENV', { 'SPEC_OPTS' => '--format json --format KnapsackPro::Formatters::RSpecQueueSummaryFormatter' })
470
498
  end
471
499
 
472
- it 'does nothing' do
500
+ it 'adds TimeTracker' do
501
+ subject
502
+ expect(ENV['SPEC_OPTS']).to eq '--format json --format KnapsackPro::Formatters::RSpecQueueSummaryFormatter --format KnapsackPro::Formatters::TimeTracker'
503
+ end
504
+ end
505
+
506
+ context 'when `SPEC_OPTS` has TimeTracker' do
507
+ before do
508
+ stub_const('ENV', { 'SPEC_OPTS' => '--format json --format KnapsackPro::Formatters::TimeTracker' })
509
+ end
510
+
511
+ it 'adds RSpecQueueSummaryFormatter' do
473
512
  subject
474
- expect(ENV['SPEC_OPTS']).to eq '--format json --format KnapsackPro::Formatters::RSpecQueueSummaryFormatter'
513
+ expect(ENV['SPEC_OPTS']).to eq '--format json --format KnapsackPro::Formatters::TimeTracker --format KnapsackPro::Formatters::RSpecQueueSummaryFormatter'
475
514
  end
476
515
  end
477
516
 
478
- context 'when `SPEC_OPTS` has no RSpec Queue Summary Formatter' do
517
+ context 'when `SPEC_OPTS` has no Knapsack Pro formatters' do
479
518
  before do
480
519
  stub_const('ENV', { 'SPEC_OPTS' => '--format json' })
481
520
  end
482
521
 
483
- it 'adds RSpec Queue Summary Formatter to `SPEC_OPTS`' do
522
+ it 'adds RSpecQueueSummaryFormatter and TimeTracker to `SPEC_OPTS`' do
484
523
  subject
485
- expect(ENV['SPEC_OPTS']).to eq '--format json --format KnapsackPro::Formatters::RSpecQueueSummaryFormatter'
524
+ expect(ENV['SPEC_OPTS']).to eq '--format json --format KnapsackPro::Formatters::RSpecQueueSummaryFormatter --format KnapsackPro::Formatters::TimeTracker'
486
525
  end
487
526
  end
488
527
  end
@@ -42,14 +42,11 @@ describe KnapsackPro::Runners::RSpecRunner do
42
42
  expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:verify_bind_method_called).ordered
43
43
  expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!).with(['--profile', '--color']).ordered
44
44
 
45
- tracker = instance_double(KnapsackPro::Tracker)
46
- expect(KnapsackPro).to receive(:tracker).and_return(tracker)
47
- expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
48
-
49
45
  expect(Rake::Task).to receive(:[]).with('knapsack_pro:rspec_run').at_least(1).and_return(task)
50
46
 
51
47
  expect(RSpec::Core::RakeTask).to receive(:new).with('knapsack_pro:rspec_run').and_yield(task_config)
52
- expect(task_config).to receive(:rspec_opts=).with('--profile --color --default-path fake-test-dir spec/a_spec.rb spec/b_spec.rb[1:1]')
48
+ expect(RSpec::Core::ConfigurationOptions).to receive_message_chain(:new, :options).and_return({})
49
+ expect(task_config).to receive(:rspec_opts=).with('--profile --color --format progress --format KnapsackPro::Formatters::TimeTracker --default-path fake-test-dir spec/a_spec.rb spec/b_spec.rb[1:1]')
53
50
  expect(task_config).to receive(:pattern=).with([])
54
51
  end
55
52