knapsack_pro 5.6.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|