knapsack_pro 2.10.1 → 2.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/README.md +31 -1562
  4. data/lib/knapsack_pro/adapters/base_adapter.rb +22 -0
  5. data/lib/knapsack_pro/adapters/rspec_adapter.rb +6 -2
  6. data/lib/knapsack_pro/allocator.rb +1 -1
  7. data/lib/knapsack_pro/config/env.rb +1 -0
  8. data/lib/knapsack_pro/queue_allocator.rb +1 -1
  9. data/lib/knapsack_pro/report.rb +1 -1
  10. data/lib/knapsack_pro/runners/cucumber_runner.rb +4 -1
  11. data/lib/knapsack_pro/runners/minitest_runner.rb +4 -1
  12. data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +4 -0
  13. data/lib/knapsack_pro/runners/queue/minitest_runner.rb +4 -0
  14. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +25 -4
  15. data/lib/knapsack_pro/runners/rspec_runner.rb +4 -1
  16. data/lib/knapsack_pro/runners/spinach_runner.rb +4 -1
  17. data/lib/knapsack_pro/runners/test_unit_runner.rb +4 -1
  18. data/lib/knapsack_pro/slow_test_file_determiner.rb +1 -1
  19. data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +1 -1
  20. data/lib/knapsack_pro/tracker.rb +10 -6
  21. data/lib/knapsack_pro/version.rb +1 -1
  22. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +51 -0
  23. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +15 -9
  24. data/spec/knapsack_pro/runners/cucumber_runner_spec.rb +2 -0
  25. data/spec/knapsack_pro/runners/minitest_runner_spec.rb +4 -0
  26. data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +27 -7
  27. data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +27 -7
  28. data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +39 -7
  29. data/spec/knapsack_pro/runners/rspec_runner_spec.rb +2 -0
  30. data/spec/knapsack_pro/runners/spinach_runner_spec.rb +2 -0
  31. data/spec/knapsack_pro/runners/test_unit_runner_spec.rb +2 -0
  32. data/spec/knapsack_pro/tracker_spec.rb +7 -3
  33. metadata +5 -5
@@ -4,6 +4,11 @@ module KnapsackPro
4
4
  # Just example, please overwrite constant in subclass
5
5
  TEST_DIR_PATTERN = 'test/**{,/*/**}/*_test.rb'
6
6
 
7
+ def self.adapter_bind_method_called_file
8
+ adapter_name = self.to_s.gsub('::', '-')
9
+ "#{KnapsackPro::Config::Env::TMP_DIR}/#{adapter_name}-bind_method_called_for_node_#{KnapsackPro::Config::Env.ci_node_index}.txt"
10
+ end
11
+
7
12
  def self.slow_test_file?(adapter_class, test_file_path)
8
13
  @slow_test_file_paths ||=
9
14
  begin
@@ -26,7 +31,24 @@ module KnapsackPro
26
31
  adapter
27
32
  end
28
33
 
34
+ def self.verify_bind_method_called
35
+ ::Kernel.at_exit do
36
+ if File.exists?(adapter_bind_method_called_file)
37
+ File.delete(adapter_bind_method_called_file)
38
+ else
39
+ puts "\n\n"
40
+ KnapsackPro.logger.error('-'*10 + ' Configuration error ' + '-'*50)
41
+ KnapsackPro.logger.error("You forgot to call #{self}.bind method in your test runner configuration file. It is needed to record test files time execution. Please follow the installation guide to configure your project properly https://docs.knapsackpro.com/knapsack_pro-ruby/guide/")
42
+ KnapsackPro.logger.error("If you already have #{self}.bind method added and you still see this error then one of your tests must had to delete tmp/knapsack_pro directory from the disk accidentally. Please ensure you do not remove tmp/knapsack_pro directory: https://knapsackpro.com/faq/question/why-all-test-files-have-01s-time-execution-for-my-ci-build-in-user-dashboard")
43
+ Kernel.exit(1)
44
+ end
45
+ end
46
+ end
47
+
29
48
  def bind
49
+ FileUtils.mkdir_p(KnapsackPro::Config::Env::TMP_DIR)
50
+ File.write(self.class.adapter_bind_method_called_file, nil)
51
+
30
52
  if KnapsackPro::Config::Env.recording_enabled?
31
53
  KnapsackPro.logger.debug('Test suite time execution recording enabled.')
32
54
  bind_time_tracker
@@ -21,6 +21,10 @@ module KnapsackPro
21
21
 
22
22
  def bind_time_tracker
23
23
  ::RSpec.configure do |config|
24
+ config.prepend_before(:context) do
25
+ KnapsackPro.tracker.start_timer
26
+ end
27
+
24
28
  config.around(:each) do |example|
25
29
  current_example_group =
26
30
  if ::RSpec.respond_to?(:current_example)
@@ -38,10 +42,10 @@ module KnapsackPro
38
42
  current_test_path
39
43
  end
40
44
 
41
- KnapsackPro.tracker.start_timer
42
-
43
45
  example.run
46
+ end
44
47
 
48
+ config.append_after(:context) do
45
49
  KnapsackPro.tracker.stop_timer
46
50
  end
47
51
 
@@ -26,7 +26,7 @@ module KnapsackPro
26
26
  KnapsackPro.logger.error(message)
27
27
  raise message
28
28
  else
29
- KnapsackPro.logger.warn("Fallback mode started. We could not connect with Knapsack Pro API. Your tests will be executed based on directory names. Read more about fallback mode at https://github.com/KnapsackPro/knapsack_pro-ruby#what-happens-when-knapsack-pro-api-is-not-availablenot-reachable-temporarily")
29
+ KnapsackPro.logger.warn("Fallback mode started. We could not connect with Knapsack Pro API. Your tests will be executed based on directory names. Read more about fallback mode at https://knapsackpro.com/faq/question/what-happens-when-knapsack-pro-api-is-not-availablenot-reachable-temporarily")
30
30
  fallback_test_files
31
31
  end
32
32
  end
@@ -8,6 +8,7 @@ module KnapsackPro
8
8
  'info' => ::Logger::INFO,
9
9
  'debug' => ::Logger::DEBUG,
10
10
  }
11
+ TMP_DIR = 'tmp/knapsack_pro'
11
12
 
12
13
  class << self
13
14
  def ci_node_total
@@ -39,7 +39,7 @@ module KnapsackPro
39
39
  raise message
40
40
  else
41
41
  @fallback_activated = true
42
- KnapsackPro.logger.warn("Fallback mode started. We could not connect with Knapsack Pro API. Your tests will be executed based on directory names. If other CI nodes were able to connect with Knapsack Pro API then you may notice that some of the test files will be executed twice across CI nodes. The most important thing is to guarantee each of test files is run at least once! Read more about fallback mode at https://github.com/KnapsackPro/knapsack_pro-ruby#what-happens-when-knapsack-pro-api-is-not-availablenot-reachable-temporarily")
42
+ KnapsackPro.logger.warn("Fallback mode started. We could not connect with Knapsack Pro API. Your tests will be executed based on directory names. If other CI nodes were able to connect with Knapsack Pro API then you may notice that some of the test files will be executed twice across CI nodes. The most important thing is to guarantee each of test files is run at least once! Read more about fallback mode at https://knapsackpro.com/faq/question/what-happens-when-knapsack-pro-api-is-not-availablenot-reachable-temporarily")
43
43
  fallback_test_files(executed_test_files)
44
44
  end
45
45
  end
@@ -80,7 +80,7 @@ module KnapsackPro
80
80
 
81
81
  def self.queue_path
82
82
  queue_id = KnapsackPro::Config::Env.queue_id
83
- "tmp/knapsack_pro/queue/#{queue_id}"
83
+ "#{KnapsackPro::Config::Env::TMP_DIR}/queue/#{queue_id}"
84
84
  end
85
85
  end
86
86
  end
@@ -5,9 +5,12 @@ module KnapsackPro
5
5
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_cucumber
6
6
  ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
7
7
 
8
- runner = new(KnapsackPro::Adapters::CucumberAdapter)
8
+ adapter_class = KnapsackPro::Adapters::CucumberAdapter
9
+ runner = new(adapter_class)
9
10
 
10
11
  if runner.test_files_to_execute_exist?
12
+ adapter_class.verify_bind_method_called
13
+
11
14
  require 'cucumber/rake/task'
12
15
 
13
16
  task_name = 'knapsack_pro:cucumber_run'
@@ -5,9 +5,12 @@ module KnapsackPro
5
5
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_minitest
6
6
  ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
7
7
 
8
- runner = new(KnapsackPro::Adapters::MinitestAdapter)
8
+ adapter_class = KnapsackPro::Adapters::MinitestAdapter
9
+ runner = new(adapter_class)
9
10
 
10
11
  if runner.test_files_to_execute_exist?
12
+ adapter_class.verify_bind_method_called
13
+
11
14
  task_name = 'knapsack_pro:minitest_run'
12
15
 
13
16
  if Rake::Task.task_defined?(task_name)
@@ -39,6 +39,10 @@ module KnapsackPro
39
39
  )
40
40
 
41
41
  if test_file_paths.empty?
42
+ unless all_test_file_paths.empty?
43
+ KnapsackPro::Adapters::CucumberAdapter.verify_bind_method_called
44
+ end
45
+
42
46
  KnapsackPro::Hooks::Queue.call_after_queue
43
47
 
44
48
  KnapsackPro::Report.save_node_queue_to_api
@@ -46,6 +46,10 @@ module KnapsackPro
46
46
  )
47
47
 
48
48
  if test_file_paths.empty?
49
+ unless all_test_file_paths.empty?
50
+ KnapsackPro::Adapters::MinitestAdapter.verify_bind_method_called
51
+ end
52
+
49
53
  KnapsackPro::Hooks::Queue.call_after_queue
50
54
 
51
55
  KnapsackPro::Report.save_node_queue_to_api
@@ -14,12 +14,18 @@ module KnapsackPro
14
14
  runner = new(KnapsackPro::Adapters::RSpecAdapter)
15
15
 
16
16
  cli_args = (args || '').split
17
- # if user didn't provide the format then use explicitly default progress formatter
18
- # in order to avoid KnapsackPro::Formatters::RSpecQueueSummaryFormatter being the only default formatter
19
- if !cli_args.any? { |arg| arg.start_with?('-f') || arg.start_with?('--format')}
20
- cli_args += ['--format', 'progress']
17
+
18
+ if KnapsackPro::Config::Env.rspec_split_by_test_examples? && has_tag_option?(cli_args)
19
+ error_message = 'It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature. Please see: https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it#warning-dont-use-rspec-tag-option'
20
+ KnapsackPro.logger.error(error_message)
21
+ raise error_message
21
22
  end
23
+
24
+ # when format option is not defined by user then use progress formatter to show tests execution progress
25
+ cli_args += ['--format', 'progress'] unless has_format_option?(cli_args)
26
+
22
27
  cli_args += [
28
+ # shows summary of all tests executed in Queue Mode at the very end
23
29
  '--format', KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s,
24
30
  '--default-path', runner.test_dir,
25
31
  ]
@@ -53,6 +59,8 @@ module KnapsackPro
53
59
 
54
60
  if test_file_paths.empty?
55
61
  unless all_test_file_paths.empty?
62
+ KnapsackPro::Adapters::RSpecAdapter.verify_bind_method_called
63
+
56
64
  KnapsackPro::Formatters::RSpecQueueSummaryFormatter.print_summary
57
65
  KnapsackPro::Formatters::RSpecQueueProfileFormatterExtension.print_summary
58
66
 
@@ -146,6 +154,19 @@ module KnapsackPro
146
154
  ::RSpec.configuration.reset_filters
147
155
  end
148
156
  end
157
+
158
+ def self.has_tag_option?(cli_args)
159
+ # use start_with? because user can define tag option in a few ways:
160
+ # -t mytag
161
+ # -tmytag
162
+ # --tag mytag
163
+ # --tag=mytag
164
+ cli_args.any? { |arg| arg.start_with?('-t') || arg.start_with?('--tag') }
165
+ end
166
+
167
+ def self.has_format_option?(cli_args)
168
+ cli_args.any? { |arg| arg.start_with?('-f') || arg.start_with?('--format') }
169
+ end
149
170
  end
150
171
  end
151
172
  end
@@ -5,9 +5,12 @@ module KnapsackPro
5
5
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec
6
6
  ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
7
7
 
8
- runner = new(KnapsackPro::Adapters::RSpecAdapter)
8
+ adapter_class = KnapsackPro::Adapters::RSpecAdapter
9
+ runner = new(adapter_class)
9
10
 
10
11
  if runner.test_files_to_execute_exist?
12
+ adapter_class.verify_bind_method_called
13
+
11
14
  require 'rspec/core/rake_task'
12
15
 
13
16
  task_name = 'knapsack_pro:rspec_run'
@@ -4,9 +4,12 @@ module KnapsackPro
4
4
  def self.run(args)
5
5
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_spinach
6
6
 
7
- runner = new(KnapsackPro::Adapters::SpinachAdapter)
7
+ adapter_class = KnapsackPro::Adapters::SpinachAdapter
8
+ runner = new(adapter_class)
8
9
 
9
10
  if runner.test_files_to_execute_exist?
11
+ adapter_class.verify_bind_method_called
12
+
10
13
  cmd = %Q[KNAPSACK_PRO_RECORDING_ENABLED=true KNAPSACK_PRO_TEST_SUITE_TOKEN=#{ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN']} bundle exec spinach #{args} --features_path #{runner.test_dir} -- #{runner.stringify_test_file_paths}]
11
14
 
12
15
  Kernel.system(cmd)
@@ -5,9 +5,12 @@ module KnapsackPro
5
5
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_test_unit
6
6
  ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
7
7
 
8
- runner = new(KnapsackPro::Adapters::TestUnitAdapter)
8
+ adapter_class = KnapsackPro::Adapters::TestUnitAdapter
9
+ runner = new(adapter_class)
9
10
 
10
11
  if runner.test_files_to_execute_exist?
12
+ adapter_class.verify_bind_method_called
13
+
11
14
  require 'test/unit'
12
15
 
13
16
  cli_args =
@@ -1,7 +1,7 @@
1
1
  module KnapsackPro
2
2
  class SlowTestFileDeterminer
3
3
  TIME_THRESHOLD_PER_CI_NODE = 0.7 # 70%
4
- REPORT_DIR = 'tmp/knapsack_pro/slow_test_file_determiner'
4
+ REPORT_DIR = "#{KnapsackPro::Config::Env::TMP_DIR}/slow_test_file_determiner"
5
5
 
6
6
  # test_files: { 'path' => 'a_spec.rb', 'time_execution' => 0.0 }
7
7
  # time_execution: of build distribution (total time of CI build run)
@@ -1,7 +1,7 @@
1
1
  module KnapsackPro
2
2
  module TestCaseDetectors
3
3
  class RSpecTestExampleDetector
4
- REPORT_DIR = 'tmp/knapsack_pro/test_case_detectors/rspec'
4
+ REPORT_DIR = "#{KnapsackPro::Config::Env::TMP_DIR}/test_case_detectors/rspec"
5
5
 
6
6
  def generate_json_report
7
7
  require 'rspec/core'
@@ -4,7 +4,7 @@ module KnapsackPro
4
4
 
5
5
  # when test file is pending, empty with no tests or has syntax error then assume time execution
6
6
  # to better allocate it in Queue Mode for future CI build runs
7
- DEFAULT_TEST_FILE_TIME = 0.1 # seconds
7
+ DEFAULT_TEST_FILE_TIME = 0.0 # seconds
8
8
 
9
9
  attr_reader :global_time_since_beginning, :global_time, :test_files_with_time
10
10
  attr_writer :current_test_path
@@ -24,14 +24,18 @@ module KnapsackPro
24
24
 
25
25
  def stop_timer
26
26
  execution_time = @start_time ? now_without_mock_time.to_f - @start_time : 0.0
27
- update_global_time(execution_time)
28
- update_test_file_time(execution_time)
27
+
28
+ if current_test_path
29
+ update_global_time(execution_time)
30
+ update_test_file_time(execution_time)
31
+ @current_test_path = nil
32
+ end
33
+
29
34
  execution_time
30
35
  end
31
36
 
32
37
  def current_test_path
33
- raise("current_test_path needs to be set by Knapsack Pro Adapter's bind method") unless @current_test_path
34
- KnapsackPro::TestFileCleaner.clean(@current_test_path)
38
+ KnapsackPro::TestFileCleaner.clean(@current_test_path) if @current_test_path
35
39
  end
36
40
 
37
41
  def set_prerun_tests(test_file_paths)
@@ -63,7 +67,7 @@ module KnapsackPro
63
67
  def set_defaults
64
68
  @global_time = 0
65
69
  @test_files_with_time = {}
66
- @test_path = nil
70
+ @current_test_path = nil
67
71
  end
68
72
 
69
73
  def update_global_time(execution_time)
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '2.10.1'
2
+ VERSION = '2.15.0'
3
3
  end
@@ -22,6 +22,27 @@ describe KnapsackPro::Adapters::BaseAdapter do
22
22
  end
23
23
  end
24
24
 
25
+ describe '.adapter_bind_method_called_file' do
26
+ subject { described_class.adapter_bind_method_called_file }
27
+
28
+ before do
29
+ expect(KnapsackPro::Config::Env).to receive(:ci_node_index).and_return(ci_node_index)
30
+ end
31
+
32
+ context 'when CI node index 0' do
33
+ let(:ci_node_index) { 0 }
34
+
35
+ it { expect(subject).to eq 'tmp/knapsack_pro/KnapsackPro-Adapters-BaseAdapter-bind_method_called_for_node_0.txt' }
36
+
37
+ end
38
+
39
+ context 'when CI node index 1' do
40
+ let(:ci_node_index) { 1 }
41
+
42
+ it { expect(subject).to eq 'tmp/knapsack_pro/KnapsackPro-Adapters-BaseAdapter-bind_method_called_for_node_1.txt' }
43
+ end
44
+ end
45
+
25
46
  describe '.slow_test_file?' do
26
47
  let(:adapter_class) { double }
27
48
  let(:slow_test_files) do
@@ -71,11 +92,41 @@ describe KnapsackPro::Adapters::BaseAdapter do
71
92
  it { should eql adapter }
72
93
  end
73
94
 
95
+ describe '.verify_bind_method_called' do
96
+ subject { described_class.verify_bind_method_called }
97
+
98
+ before do
99
+ expect(::Kernel).to receive(:at_exit).and_yield
100
+ expect(File).to receive(:exists?).with('tmp/knapsack_pro/KnapsackPro-Adapters-BaseAdapter-bind_method_called_for_node_0.txt').and_return(adapter_bind_method_called_file_exists)
101
+ end
102
+
103
+ context 'when adapter bind method called' do
104
+ let(:adapter_bind_method_called_file_exists) { true }
105
+
106
+ it do
107
+ expect(File).to receive(:delete).with('tmp/knapsack_pro/KnapsackPro-Adapters-BaseAdapter-bind_method_called_for_node_0.txt')
108
+ subject
109
+ end
110
+ end
111
+
112
+ context 'when adapter bind method was not call' do
113
+ let(:adapter_bind_method_called_file_exists) { false }
114
+
115
+ it do
116
+ expect(Kernel).to receive(:exit).with(1)
117
+ subject
118
+ end
119
+ end
120
+ end
121
+
74
122
  describe '#bind' do
75
123
  let(:recording_enabled?) { false }
76
124
  let(:queue_recording_enabled?) { false }
77
125
 
78
126
  before do
127
+ expect(FileUtils).to receive(:mkdir_p).with('tmp/knapsack_pro')
128
+ expect(File).to receive(:write).with('tmp/knapsack_pro/KnapsackPro-Adapters-BaseAdapter-bind_method_called_for_node_0.txt', nil)
129
+
79
130
  expect(KnapsackPro::Config::Env).to receive(:recording_enabled?).and_return(recording_enabled?)
80
131
  expect(KnapsackPro::Config::Env).to receive(:queue_recording_enabled?).and_return(queue_recording_enabled?)
81
132
  end
@@ -86,7 +86,9 @@ describe KnapsackPro::Adapters::RSpecAdapter do
86
86
  end
87
87
 
88
88
  it 'records time for current test path' do
89
+ expect(config).to receive(:prepend_before).with(:context).and_yield
89
90
  expect(config).to receive(:around).with(:each).and_yield(example)
91
+ expect(config).to receive(:append_after).with(:context).and_yield
90
92
  expect(config).to receive(:after).with(:suite).and_yield
91
93
  expect(::RSpec).to receive(:configure).and_yield(config)
92
94
 
@@ -94,12 +96,12 @@ describe KnapsackPro::Adapters::RSpecAdapter do
94
96
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
95
97
 
96
98
  allow(KnapsackPro).to receive(:tracker).and_return(tracker)
97
- expect(tracker).to receive(:current_test_path=).with(test_path)
98
- expect(tracker).to receive(:start_timer)
99
+ expect(tracker).to receive(:start_timer).ordered
100
+ expect(tracker).to receive(:current_test_path=).with(test_path).ordered
99
101
 
100
102
  expect(example).to receive(:run)
101
103
 
102
- expect(tracker).to receive(:stop_timer)
104
+ expect(tracker).to receive(:stop_timer).ordered
103
105
 
104
106
  expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
105
107
  expect(KnapsackPro).to receive(:logger).and_return(logger)
@@ -124,7 +126,9 @@ describe KnapsackPro::Adapters::RSpecAdapter do
124
126
  it 'records time for example.id' do
125
127
  expect(example).to receive(:id).and_return(test_example_path)
126
128
 
129
+ expect(config).to receive(:prepend_before).with(:context).and_yield
127
130
  expect(config).to receive(:around).with(:each).and_yield(example)
131
+ expect(config).to receive(:append_after).with(:context).and_yield
128
132
  expect(config).to receive(:after).with(:suite).and_yield
129
133
  expect(::RSpec).to receive(:configure).and_yield(config)
130
134
 
@@ -132,12 +136,12 @@ describe KnapsackPro::Adapters::RSpecAdapter do
132
136
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
133
137
 
134
138
  allow(KnapsackPro).to receive(:tracker).and_return(tracker)
135
- expect(tracker).to receive(:current_test_path=).with(test_example_path)
136
- expect(tracker).to receive(:start_timer)
139
+ expect(tracker).to receive(:start_timer).ordered
140
+ expect(tracker).to receive(:current_test_path=).with(test_example_path).ordered
137
141
 
138
142
  expect(example).to receive(:run)
139
143
 
140
- expect(tracker).to receive(:stop_timer)
144
+ expect(tracker).to receive(:stop_timer).ordered
141
145
 
142
146
  expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
143
147
  expect(KnapsackPro).to receive(:logger).and_return(logger)
@@ -153,7 +157,9 @@ describe KnapsackPro::Adapters::RSpecAdapter do
153
157
  end
154
158
 
155
159
  it 'records time for current test path' do
160
+ expect(config).to receive(:prepend_before).with(:context).and_yield
156
161
  expect(config).to receive(:around).with(:each).and_yield(example)
162
+ expect(config).to receive(:append_after).with(:context).and_yield
157
163
  expect(config).to receive(:after).with(:suite).and_yield
158
164
  expect(::RSpec).to receive(:configure).and_yield(config)
159
165
 
@@ -161,12 +167,12 @@ describe KnapsackPro::Adapters::RSpecAdapter do
161
167
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
162
168
 
163
169
  allow(KnapsackPro).to receive(:tracker).and_return(tracker)
164
- expect(tracker).to receive(:current_test_path=).with(test_path)
165
- expect(tracker).to receive(:start_timer)
170
+ expect(tracker).to receive(:start_timer).ordered
171
+ expect(tracker).to receive(:current_test_path=).with(test_path).ordered
166
172
 
167
173
  expect(example).to receive(:run)
168
174
 
169
- expect(tracker).to receive(:stop_timer)
175
+ expect(tracker).to receive(:stop_timer).ordered
170
176
 
171
177
  expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
172
178
  expect(KnapsackPro).to receive(:logger).and_return(logger)