knapsack_pro 5.6.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.
@@ -8,6 +8,8 @@ module KnapsackPro
8
8
 
9
9
  def self.run(args)
10
10
  require 'rspec/core'
11
+ require_relative '../../formatters/time_tracker'
12
+ require_relative '../../formatters/time_tracker_fetcher'
11
13
  require_relative '../../formatters/rspec_queue_summary_formatter'
12
14
  require_relative '../../formatters/rspec_queue_profile_formatter_extension'
13
15
 
@@ -27,6 +29,7 @@ module KnapsackPro
27
29
  cli_args += [
28
30
  # shows summary of all tests executed in Queue Mode at the very end
29
31
  '--format', KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s,
32
+ '--format', KnapsackPro::Formatters::TimeTracker.to_s,
30
33
  '--default-path', runner.test_dir,
31
34
  ]
32
35
 
@@ -72,7 +75,8 @@ module KnapsackPro
72
75
 
73
76
  KnapsackPro::Hooks::Queue.call_after_queue
74
77
 
75
- KnapsackPro::Report.save_node_queue_to_api
78
+ time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
79
+ KnapsackPro::Report.save_node_queue_to_api(time_tracker&.queue(all_test_file_paths) || [])
76
80
 
77
81
  return {
78
82
  status: :completed,
@@ -82,15 +86,12 @@ module KnapsackPro
82
86
  subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
83
87
  ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
84
88
 
85
- KnapsackPro.tracker.reset!
86
- KnapsackPro.tracker.set_prerun_tests(test_file_paths)
87
-
88
89
  KnapsackPro::Hooks::Queue.call_before_subset_queue
89
90
 
90
91
  all_test_file_paths += test_file_paths
91
92
  cli_args = args + test_file_paths
92
93
 
93
- ensure_spec_opts_have_rspec_queue_summary_formatter
94
+ ensure_spec_opts_have_knapsack_pro_formatters
94
95
  options = ::RSpec::Core::ConfigurationOptions.new(cli_args)
95
96
  rspec_runner = ::RSpec::Core::Runner.new(options)
96
97
 
@@ -99,7 +100,7 @@ module KnapsackPro
99
100
  exitstatus = exit_code if exit_code != 0
100
101
  rescue Exception => exception
101
102
  KnapsackPro.logger.error("Having exception when running RSpec: #{exception.inspect}")
102
- KnapsackPro::Formatters::RSpecQueueSummaryFormatter.print_exit_summary
103
+ KnapsackPro::Formatters::RSpecQueueSummaryFormatter.print_exit_summary(all_test_file_paths)
103
104
  KnapsackPro::Hooks::Queue.call_after_subset_queue
104
105
  KnapsackPro::Hooks::Queue.call_after_queue
105
106
  Kernel.exit(1)
@@ -121,8 +122,6 @@ module KnapsackPro
121
122
 
122
123
  KnapsackPro::Hooks::Queue.call_after_subset_queue
123
124
 
124
- KnapsackPro::Report.save_subset_queue_to_file
125
-
126
125
  return {
127
126
  status: :next,
128
127
  runner: runner,
@@ -135,13 +134,23 @@ module KnapsackPro
135
134
  end
136
135
  end
137
136
 
138
- def self.ensure_spec_opts_have_rspec_queue_summary_formatter
139
- spec_opts = ENV['SPEC_OPTS']
137
+ def self.ensure_spec_opts_have_knapsack_pro_formatters
138
+ return unless ENV['SPEC_OPTS']
139
+
140
+ if [
141
+ ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s),
142
+ ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::TimeTracker.to_s),
143
+ ].all?
144
+ return
145
+ end
140
146
 
141
- return unless spec_opts
142
- return if spec_opts.include?(KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s)
147
+ unless ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s)
148
+ ENV['SPEC_OPTS'] = "#{ENV['SPEC_OPTS']} --format #{KnapsackPro::Formatters::RSpecQueueSummaryFormatter}"
149
+ end
143
150
 
144
- ENV['SPEC_OPTS'] = "#{spec_opts} --format #{KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s}"
151
+ unless ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::TimeTracker.to_s)
152
+ ENV['SPEC_OPTS'] = "#{ENV['SPEC_OPTS']} --format #{KnapsackPro::Formatters::TimeTracker}"
153
+ end
145
154
  end
146
155
 
147
156
  private
@@ -158,7 +167,9 @@ module KnapsackPro
158
167
  KnapsackPro.logger.info("To retry all the tests assigned to this CI node, please run the following command on your machine:")
159
168
  end
160
169
 
161
- stringified_cli_args = cli_args.join(' ').sub(" --format #{KnapsackPro::Formatters::RSpecQueueSummaryFormatter}", '')
170
+ stringified_cli_args = cli_args.join(' ')
171
+ .sub(" --format #{KnapsackPro::Formatters::RSpecQueueSummaryFormatter}", '')
172
+ .sub(" --format #{KnapsackPro::Formatters::TimeTracker}", '')
162
173
 
163
174
  KnapsackPro.logger.info(
164
175
  "bundle exec rspec #{stringified_cli_args} " +
@@ -19,8 +19,6 @@ module KnapsackPro
19
19
  cli_args = (args || '').split
20
20
  adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
21
21
 
22
- KnapsackPro.tracker.set_prerun_tests(runner.test_file_paths)
23
-
24
22
  require 'rspec/core/rake_task'
25
23
 
26
24
  task_name = 'knapsack_pro:rspec_run'
@@ -33,12 +31,30 @@ module KnapsackPro
33
31
  # because pattern does not accept test example path like spec/a_spec.rb[1:2]
34
32
  # instead we pass test files and test example paths to t.rspec_opts
35
33
  t.pattern = []
36
- t.rspec_opts = "#{args} --default-path #{runner.test_dir} #{runner.stringify_test_file_paths}"
34
+ t.rspec_opts = "#{args} #{self.formatters} --default-path #{runner.test_dir} #{runner.stringify_test_file_paths}"
37
35
  t.verbose = KnapsackPro::Config::Env.log_level < ::Logger::WARN
38
36
  end
39
37
  Rake::Task[task_name].invoke
40
38
  end
41
39
  end
40
+
41
+ # Use RSpec::Core::ConfigurationOptions to respect external configurations like .rspec
42
+ def self.formatters
43
+ require_relative '../formatters/time_tracker'
44
+
45
+ formatters = ::RSpec::Core::ConfigurationOptions
46
+ .new([])
47
+ .options
48
+ .fetch(:formatters, [])
49
+ .map do |formatter, output|
50
+ arg = "--format #{formatter}"
51
+ arg += " --out #{output}" if output
52
+ arg
53
+ end
54
+ formatters = ['--format progress'] if formatters.empty?
55
+ formatters += ["--format #{KnapsackPro::Formatters::TimeTracker}"]
56
+ formatters.join(' ')
57
+ end
42
58
  end
43
59
  end
44
60
  end
@@ -8,11 +8,10 @@ module KnapsackPro
8
8
  # to better allocate it in Queue Mode for future CI build runs
9
9
  DEFAULT_TEST_FILE_TIME = 0.0 # seconds
10
10
 
11
- attr_reader :global_time_since_beginning, :global_time, :test_files_with_time, :prerun_tests_loaded
11
+ attr_reader :global_time, :test_files_with_time, :prerun_tests_loaded
12
12
  attr_writer :current_test_path
13
13
 
14
14
  def initialize
15
- @global_time_since_beginning = 0
16
15
  KnapsackPro::Config::TempFiles.ensure_temp_directory_exists!
17
16
  FileUtils.mkdir_p(tracker_dir_path)
18
17
  set_defaults
@@ -70,12 +69,6 @@ module KnapsackPro
70
69
  @prerun_tests_loaded = true
71
70
  end
72
71
 
73
- def unexecuted_test_files
74
- @test_files_with_time.map do |path, hash|
75
- path unless hash[:measured_time]
76
- end.compact
77
- end
78
-
79
72
  def to_a
80
73
  # When the test files are not loaded in the memory then load them from the disk.
81
74
  # Useful for the Regular Mode when the memory is not shared between tracker instances.
@@ -141,7 +134,6 @@ module KnapsackPro
141
134
 
142
135
  def update_global_time(execution_time)
143
136
  @global_time += execution_time
144
- @global_time_since_beginning += execution_time
145
137
  end
146
138
 
147
139
  def update_test_file_time(execution_time)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KnapsackPro
4
- VERSION = '5.6.0'
4
+ VERSION = '6.0.0'
5
5
  end
data/lib/knapsack_pro.rb CHANGED
@@ -11,7 +11,6 @@ require 'securerandom'
11
11
  require 'timeout'
12
12
  require_relative 'knapsack_pro/urls'
13
13
  require_relative 'knapsack_pro/version'
14
- require_relative 'knapsack_pro/extensions/time'
15
14
  require_relative 'knapsack_pro/hooks/queue'
16
15
  require_relative 'knapsack_pro/utils'
17
16
  require_relative 'knapsack_pro/config/ci/base'
@@ -42,6 +42,18 @@ describe KnapsackPro::Adapters::BaseAdapter do
42
42
  end
43
43
  end
44
44
 
45
+ describe '.split_by_test_cases_enabled?' do
46
+ subject { described_class.split_by_test_cases_enabled? }
47
+
48
+ it { expect(subject).to be false }
49
+ end
50
+
51
+ describe '.test_file_cases_for' do
52
+ subject { described_class.test_file_cases_for([]) }
53
+
54
+ it { expect { subject }.to raise_error NotImplementedError }
55
+ end
56
+
45
57
  describe '.slow_test_file?' do
46
58
  let(:adapter_class) { double }
47
59
  let(:slow_test_files) do
@@ -1,3 +1,5 @@
1
+ require_relative '../../../lib/knapsack_pro/formatters/time_tracker'
2
+
1
3
  describe KnapsackPro::Adapters::RSpecAdapter do
2
4
  it 'backwards compatibility with knapsack gem old rspec adapter name' do
3
5
  expect(KnapsackPro::Adapters::RspecAdapter.new).to be_kind_of(described_class)
@@ -8,10 +10,85 @@ describe KnapsackPro::Adapters::RSpecAdapter do
8
10
  end
9
11
 
10
12
  context do
11
- before { expect(::RSpec).to receive(:configure) }
13
+ before { expect(::RSpec).to receive(:configure).at_least(:once) }
12
14
  it_behaves_like 'adapter'
13
15
  end
14
16
 
17
+ describe '.split_by_test_cases_enabled?' do
18
+ subject { described_class.split_by_test_cases_enabled? }
19
+
20
+ before do
21
+ expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(rspec_split_by_test_examples_enabled)
22
+ end
23
+
24
+ context 'when the RSpec split by test examples is enabled' do
25
+ let(:rspec_split_by_test_examples_enabled) { true }
26
+
27
+ it { expect(subject).to be true }
28
+
29
+ context 'when the RSpec version is < 3.3.0' do
30
+ before do
31
+ stub_const('RSpec::Core::Version::STRING', '3.2.0')
32
+ end
33
+
34
+ it do
35
+ expect { subject }.to raise_error RuntimeError, 'RSpec >= 3.3.0 is required to split test files by test examples. Learn more: https://knapsackpro.com/perma/ruby/split-by-test-examples'
36
+ end
37
+ end
38
+ end
39
+
40
+ context 'when the RSpec split by test examples is disabled' do
41
+ let(:rspec_split_by_test_examples_enabled) { false }
42
+
43
+ it { expect(subject).to be false }
44
+ end
45
+ end
46
+
47
+ describe '.test_file_cases_for' do
48
+ let(:slow_test_files) do
49
+ [
50
+ '1_spec.rb',
51
+ '2_spec.rb',
52
+ '3_spec.rb',
53
+ '4_spec.rb',
54
+ '5_spec.rb',
55
+ ]
56
+ end
57
+
58
+ subject { described_class.test_file_cases_for(slow_test_files) }
59
+
60
+ before do
61
+ logger = instance_double(Logger)
62
+ expect(KnapsackPro).to receive(:logger).and_return(logger)
63
+ expect(logger).to receive(:info).with("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual test cases). Thanks to that, a single slow test file can be split across parallel CI nodes. Analyzing 5 slow test files.")
64
+
65
+ cmd = 'RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector'
66
+ expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
67
+ end
68
+
69
+ context 'when the rake task to detect RSpec test examples succeeded' do
70
+ let(:cmd_result) { true }
71
+
72
+ it 'returns test example paths for slow test files' do
73
+ rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
74
+ expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
75
+
76
+ test_file_example_paths = double
77
+ expect(rspec_test_example_detector).to receive(:test_file_example_paths).and_return(test_file_example_paths)
78
+
79
+ expect(subject).to eq test_file_example_paths
80
+ end
81
+ end
82
+
83
+ context 'when the rake task to detect RSpec test examples failed' do
84
+ let(:cmd_result) { false }
85
+
86
+ it do
87
+ expect { subject }.to raise_error(RuntimeError, 'Could not generate JSON report for RSpec. Rake task failed when running RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector')
88
+ end
89
+ end
90
+ end
91
+
15
92
  describe '.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!' do
16
93
  let(:cli_args) { double }
17
94
 
@@ -162,59 +239,70 @@ describe KnapsackPro::Adapters::RSpecAdapter do
162
239
  end
163
240
  end
164
241
 
165
- describe '.test_path' do
166
- let(:example_group) do
167
- {
168
- file_path: '1_shared_example.rb',
169
- parent_example_group: {
170
- file_path: '2_shared_example.rb',
171
- parent_example_group: {
172
- file_path: 'a_spec.rb'
173
- }
174
- }
175
- }
242
+ describe '.file_path_for' do
243
+ let(:current_example) { ::RSpec.describe.example }
244
+
245
+ subject { described_class.file_path_for(current_example) }
246
+
247
+ context "when id ends in _spec.rb" do
248
+ it "returns the first part of the id" do
249
+ allow(current_example).to receive(:id).and_return("./foo_spec.rb[1:1]")
250
+
251
+ expect(subject).to eq('./foo_spec.rb')
252
+ end
176
253
  end
177
- let(:current_example) do
178
- OpenStruct.new(metadata: {
179
- example_group: example_group
180
- })
254
+
255
+ context "when id does not end in _spec.rb" do
256
+ it "returns the file_path" do
257
+ allow(current_example).to receive(:id).and_return("./foo.rb")
258
+ allow(current_example).to receive(:metadata).and_return(file_path: "./foo_spec.rb")
259
+
260
+ expect(subject).to eq('./foo_spec.rb')
261
+ end
181
262
  end
182
263
 
183
- subject { described_class.test_path(current_example) }
264
+ context "when id and file_path do not end in _spec.rb" do
265
+ it "returns the example_group's file_path" do
266
+ allow(current_example).to receive(:id).and_return("./foo.rb")
267
+ allow(current_example).to receive(:metadata).and_return(
268
+ file_path: "./foo.rb", example_group: { file_path: "./foo_spec.rb" }
269
+ )
184
270
 
185
- it { should eql 'a_spec.rb' }
271
+ expect(subject).to eq('./foo_spec.rb')
272
+ end
273
+ end
186
274
 
187
- context 'with turnip features' do
188
- describe 'when the turnip version is less than 2' do
189
- let(:example_group) do
190
- {
191
- file_path: "./spec/features/logging_in.feature",
192
- turnip: true,
275
+ context "when id, file_path, and example_group's file_path do not end in _spec.rb" do
276
+ it "returns the top_level_group's file_path" do
277
+ allow(current_example).to receive(:id).and_return("./foo.rb")
278
+ allow(current_example).to receive(:metadata).and_return(
279
+ file_path: "./foo.rb",
280
+ example_group: {
281
+ file_path: "./foo.rb",
193
282
  parent_example_group: {
194
- file_path: "gems/turnip-1.2.4/lib/turnip/rspec.rb"
283
+ file_path: "./foo_spec.rb",
195
284
  }
196
285
  }
197
- end
286
+ )
198
287
 
199
- before { stub_const("Turnip::VERSION", '1.2.4') }
200
-
201
- it { should eql './spec/features/logging_in.feature' }
288
+ expect(subject).to eq('./foo_spec.rb')
202
289
  end
290
+ end
203
291
 
204
- describe 'when turnip is version 2 or greater' do
205
- let(:example_group) do
206
- {
207
- file_path: "gems/turnip-2.0.0/lib/turnip/rspec.rb",
208
- turnip: true,
292
+ context "when id, file_path, example_group's, and top_level_group's file_path do not end in _spec.rb" do
293
+ it "returns empty string" do
294
+ allow(current_example).to receive(:id).and_return("./foo.rb")
295
+ allow(current_example).to receive(:metadata).and_return(
296
+ file_path: "./foo.rb",
297
+ example_group: {
298
+ file_path: "./foo.rb",
209
299
  parent_example_group: {
210
- file_path: "./spec/features/logging_in.feature",
300
+ file_path: "./foo.rb",
211
301
  }
212
302
  }
213
- end
214
-
215
- before { stub_const("Turnip::VERSION", '2.0.0') }
303
+ )
216
304
 
217
- it { should eql './spec/features/logging_in.feature' }
305
+ expect(subject).to eq('')
218
306
  end
219
307
  end
220
308
  end
@@ -223,155 +311,48 @@ describe KnapsackPro::Adapters::RSpecAdapter do
223
311
  let(:config) { double }
224
312
 
225
313
  describe '#bind_time_tracker' do
226
- let(:tracker) { instance_double(KnapsackPro::Tracker) }
227
- let(:logger) { instance_double(Logger) }
228
- let(:global_time) { 'Global time: 01m 05s' }
229
- let(:test_path) { 'spec/a_spec.rb' }
230
314
  let(:current_example) { double(metadata: {}) }
231
315
 
232
316
  context "when the example's metadata has :focus tag AND RSpec inclusion rule includes :focus" do
233
317
  let(:current_example) { double(metadata: { focus: true }) }
318
+ let(:test_path) { 'spec/a_spec.rb' }
234
319
 
235
320
  it do
236
- expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(false)
237
-
238
- expect(config).to receive(:prepend_before).with(:context).and_yield
239
-
240
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
241
- expect(tracker).to receive(:start_timer).ordered
242
-
243
321
  expect(config).to receive(:around).with(:each).and_yield(current_example)
244
322
  expect(::RSpec).to receive(:configure).and_yield(config)
245
323
 
246
- expect(tracker).to receive(:current_test_path).ordered.and_return(test_path)
247
- expect(tracker).to receive(:stop_timer).ordered
248
-
249
- expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
250
-
251
- expect(tracker).to receive(:current_test_path=).with(test_path).ordered
324
+ expect(described_class).to receive(:file_path_for).with(current_example).and_return(test_path)
252
325
 
253
326
  expect(described_class).to receive_message_chain(:rspec_configuration, :filter, :rules, :[]).with(:focus).and_return(true)
254
327
 
255
328
  expect {
256
329
  subject.bind_time_tracker
257
- }.to raise_error /We detected a test file path spec\/a_spec\.rb with a test using the metadata `:focus` tag/
330
+ }.to raise_error /Knapsack Pro found an example tagged with focus in spec\/a_spec\.rb/i
258
331
  end
259
332
  end
260
333
 
261
- context 'when rspec split by test examples is disabled' do
262
- before do
263
- expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(false)
264
- end
334
+ context 'with no focus' do
335
+ let(:logger) { instance_double(Logger) }
336
+ let(:duration) { 65 }
337
+ let(:global_time) { 'Global time execution for tests: 01m 05s' }
338
+ let(:time_tracker) { instance_double(KnapsackPro::Formatters::TimeTracker) }
265
339
 
266
340
  it 'records time for current test path' do
267
- expect(config).to receive(:prepend_before).with(:context).and_yield
268
-
269
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
270
- expect(tracker).to receive(:start_timer).ordered
271
-
272
341
  expect(config).to receive(:around).with(:each).and_yield(current_example)
273
- expect(config).to receive(:append_after).with(:context).and_yield
274
342
  expect(config).to receive(:after).with(:suite).and_yield
275
- expect(::RSpec).to receive(:configure).and_yield(config)
276
-
277
- expect(tracker).to receive(:current_test_path).ordered.and_return(test_path)
278
- expect(tracker).to receive(:stop_timer).ordered
279
-
280
- expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
281
-
282
- expect(tracker).to receive(:current_test_path=).with(test_path).ordered
343
+ expect(::RSpec).to receive(:configure).twice.and_yield(config)
283
344
 
284
345
  expect(current_example).to receive(:run)
285
346
 
286
- expect(tracker).to receive(:stop_timer).ordered
347
+ expect(time_tracker).to receive(:batch_duration).and_return(duration)
348
+ expect(KnapsackPro::Formatters::TimeTrackerFetcher).to receive(:call).and_return(time_tracker)
287
349
 
288
- expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
289
350
  expect(KnapsackPro).to receive(:logger).and_return(logger)
290
351
  expect(logger).to receive(:debug).with(global_time)
291
352
 
292
353
  subject.bind_time_tracker
293
354
  end
294
355
  end
295
-
296
- context 'when rspec split by test examples is enabled' do
297
- let(:test_example_path) { 'spec/a_spec.rb[1:1]' }
298
-
299
- before do
300
- expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(true)
301
- end
302
-
303
- context 'when current test_path is a slow test file' do
304
- before do
305
- expect(described_class).to receive(:slow_test_file?).with(described_class, test_path).and_return(true)
306
- end
307
-
308
- it 'records time for example.id' do
309
- expect(current_example).to receive(:id).and_return(test_example_path)
310
-
311
- expect(config).to receive(:prepend_before).with(:context).and_yield
312
-
313
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
314
- expect(tracker).to receive(:start_timer).ordered
315
-
316
- expect(config).to receive(:around).with(:each).and_yield(current_example)
317
- expect(config).to receive(:append_after).with(:context).and_yield
318
- expect(config).to receive(:after).with(:suite).and_yield
319
- expect(::RSpec).to receive(:configure).and_yield(config)
320
-
321
- expect(tracker).to receive(:current_test_path).ordered.and_return(test_path)
322
- expect(tracker).to receive(:stop_timer).ordered
323
-
324
- expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
325
-
326
- expect(tracker).to receive(:current_test_path=).with(test_example_path).ordered
327
-
328
- expect(current_example).to receive(:run)
329
-
330
- expect(tracker).to receive(:stop_timer).ordered
331
-
332
- expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
333
- expect(KnapsackPro).to receive(:logger).and_return(logger)
334
- expect(logger).to receive(:debug).with(global_time)
335
-
336
- subject.bind_time_tracker
337
- end
338
- end
339
-
340
- context 'when current test_path is not a slow test file' do
341
- before do
342
- expect(described_class).to receive(:slow_test_file?).with(described_class, test_path).and_return(false)
343
- end
344
-
345
- it 'records time for current test path' do
346
- expect(config).to receive(:prepend_before).with(:context).and_yield
347
-
348
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
349
- expect(tracker).to receive(:start_timer).ordered
350
-
351
- expect(config).to receive(:around).with(:each).and_yield(current_example)
352
- expect(config).to receive(:append_after).with(:context).and_yield
353
- expect(config).to receive(:after).with(:suite).and_yield
354
- expect(::RSpec).to receive(:configure).and_yield(config)
355
-
356
- expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
357
-
358
- expect(tracker).to receive(:current_test_path).ordered.and_return(test_path)
359
- expect(tracker).to receive(:stop_timer).ordered
360
-
361
- expect(tracker).to receive(:current_test_path=).with(test_path).ordered
362
-
363
- expect(current_example).to receive(:run)
364
-
365
- expect(tracker).to receive(:stop_timer).ordered
366
-
367
- expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
368
- expect(KnapsackPro).to receive(:logger).and_return(logger)
369
- expect(logger).to receive(:debug).with(global_time)
370
-
371
- subject.bind_time_tracker
372
- end
373
- end
374
- end
375
356
  end
376
357
 
377
358
  describe '#bind_save_report' do
@@ -379,7 +360,11 @@ describe KnapsackPro::Adapters::RSpecAdapter do
379
360
  expect(config).to receive(:after).with(:suite).and_yield
380
361
  expect(::RSpec).to receive(:configure).and_yield(config)
381
362
 
382
- expect(KnapsackPro::Report).to receive(:save)
363
+ time_tracker = instance_double(KnapsackPro::Formatters::TimeTracker)
364
+ times = [{ path: "foo_spec.rb", time_execution: 1.0 }]
365
+ expect(time_tracker).to receive(:batch).and_return(times)
366
+ expect(KnapsackPro::Formatters::TimeTrackerFetcher).to receive(:call).and_return(time_tracker)
367
+ expect(KnapsackPro::Report).to receive(:save).with(times)
383
368
 
384
369
  subject.bind_save_report
385
370
  end