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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/README.md +1 -1
- data/bin/test +15 -0
- data/knapsack_pro.gemspec +5 -5
- data/lib/knapsack_pro/adapters/base_adapter.rb +8 -0
- data/lib/knapsack_pro/adapters/rspec_adapter.rb +74 -44
- data/lib/knapsack_pro/base_allocator_builder.rb +6 -25
- data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +6 -3
- data/lib/knapsack_pro/formatters/time_tracker.rb +161 -0
- data/lib/knapsack_pro/formatters/time_tracker_fetcher.rb +12 -0
- data/lib/knapsack_pro/presenter.rb +3 -2
- data/lib/knapsack_pro/report.rb +13 -9
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +25 -14
- data/lib/knapsack_pro/runners/rspec_runner.rb +19 -3
- data/lib/knapsack_pro/tracker.rb +1 -9
- data/lib/knapsack_pro/version.rb +1 -1
- data/lib/knapsack_pro.rb +0 -1
- data/spec/knapsack_pro/adapters/base_adapter_spec.rb +12 -0
- data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +143 -158
- data/spec/knapsack_pro/base_allocator_builder_spec.rb +22 -48
- data/spec/knapsack_pro/client/connection_spec.rb +54 -7
- data/spec/knapsack_pro/formatters/time_tracker_specs.rb +453 -0
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +71 -32
- data/spec/knapsack_pro/runners/rspec_runner_spec.rb +2 -5
- data/spec/knapsack_pro/tracker_spec.rb +0 -21
- metadata +9 -7
- data/lib/knapsack_pro/extensions/time.rb +0 -9
- data/spec/knapsack_pro/extensions/time_spec.rb +0 -5
@@ -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::
|
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
|
-
|
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.
|
139
|
-
|
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
|
-
|
142
|
-
|
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']
|
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(' ')
|
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
|
data/lib/knapsack_pro/tracker.rb
CHANGED
@@ -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 :
|
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)
|
data/lib/knapsack_pro/version.rb
CHANGED
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 '.
|
166
|
-
let(:
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
-
|
178
|
-
|
179
|
-
|
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
|
-
|
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
|
-
|
271
|
+
expect(subject).to eq('./foo_spec.rb')
|
272
|
+
end
|
273
|
+
end
|
186
274
|
|
187
|
-
context
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
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: "
|
283
|
+
file_path: "./foo_spec.rb",
|
195
284
|
}
|
196
285
|
}
|
197
|
-
|
286
|
+
)
|
198
287
|
|
199
|
-
|
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
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
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: "./
|
300
|
+
file_path: "./foo.rb",
|
211
301
|
}
|
212
302
|
}
|
213
|
-
|
214
|
-
|
215
|
-
before { stub_const("Turnip::VERSION", '2.0.0') }
|
303
|
+
)
|
216
304
|
|
217
|
-
|
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(
|
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 /
|
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 '
|
262
|
-
|
263
|
-
|
264
|
-
|
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(
|
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
|
-
|
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
|