knapsack_pro 6.0.3 → 7.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 +375 -28
- data/.github/pull_request_template.md +22 -0
- data/.gitignore +4 -0
- data/CHANGELOG.md +95 -0
- data/Gemfile +9 -0
- data/README.md +0 -7
- data/knapsack_pro.gemspec +2 -1
- data/lib/knapsack_pro/adapters/base_adapter.rb +7 -2
- data/lib/knapsack_pro/adapters/cucumber_adapter.rb +1 -3
- data/lib/knapsack_pro/adapters/rspec_adapter.rb +16 -9
- data/lib/knapsack_pro/config/env.rb +1 -9
- data/lib/knapsack_pro/extensions/rspec_extension.rb +137 -0
- data/lib/knapsack_pro/formatters/time_tracker.rb +10 -26
- data/lib/knapsack_pro/formatters/time_tracker_fetcher.rb +8 -0
- data/lib/knapsack_pro/presenter.rb +1 -1
- data/lib/knapsack_pro/pure/queue/rspec_pure.rb +92 -0
- data/lib/knapsack_pro/runners/queue/base_runner.rb +6 -1
- data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +6 -6
- data/lib/knapsack_pro/runners/queue/minitest_runner.rb +10 -6
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +124 -173
- data/lib/knapsack_pro/urls.rb +2 -0
- data/lib/knapsack_pro/version.rb +1 -1
- data/lib/knapsack_pro.rb +1 -0
- data/spec/integration/runners/queue/rspec_runner.rb +80 -0
- data/spec/integration/runners/queue/rspec_runner_spec.rb +2232 -0
- data/spec/knapsack_pro/adapters/base_adapter_spec.rb +17 -11
- data/spec/knapsack_pro/adapters/cucumber_adapter_spec.rb +2 -5
- data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +2 -24
- data/spec/knapsack_pro/config/env_spec.rb +1 -35
- data/spec/knapsack_pro/formatters/time_tracker_specs.rb +8 -37
- data/spec/knapsack_pro/hooks/queue_spec.rb +2 -2
- data/spec/knapsack_pro/presenter_spec.rb +1 -1
- data/spec/knapsack_pro/pure/queue/rspec_pure_spec.rb +224 -0
- data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +16 -16
- data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +14 -14
- data/spec/knapsack_pro_spec.rb +3 -3
- data/spec/spec_helper.rb +0 -1
- metadata +17 -12
- data/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb +0 -58
- data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +0 -145
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +0 -536
@@ -87,7 +87,7 @@ module KnapsackPro
|
|
87
87
|
|
88
88
|
def bind_time_tracker
|
89
89
|
ensure_no_focus!
|
90
|
-
|
90
|
+
log_tests_duration
|
91
91
|
end
|
92
92
|
|
93
93
|
def ensure_no_focus!
|
@@ -105,12 +105,14 @@ module KnapsackPro
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
def
|
108
|
+
def log_tests_duration
|
109
109
|
::RSpec.configure do |config|
|
110
|
-
config.
|
110
|
+
config.append_after(:suite) do
|
111
111
|
time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
|
112
|
-
|
113
|
-
|
112
|
+
if time_tracker
|
113
|
+
formatted = KnapsackPro::Presenter.global_time(time_tracker.duration)
|
114
|
+
KnapsackPro.logger.debug(formatted)
|
115
|
+
end
|
114
116
|
end
|
115
117
|
end
|
116
118
|
end
|
@@ -127,10 +129,15 @@ module KnapsackPro
|
|
127
129
|
def bind_before_queue_hook
|
128
130
|
::RSpec.configure do |config|
|
129
131
|
config.before(:suite) do
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
132
|
+
KnapsackPro::Hooks::Queue.call_before_queue
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def bind_after_queue_hook
|
138
|
+
::RSpec.configure do |config|
|
139
|
+
config.after(:suite) do
|
140
|
+
KnapsackPro::Hooks::Queue.call_after_queue
|
134
141
|
end
|
135
142
|
end
|
136
143
|
end
|
@@ -144,14 +144,6 @@ module KnapsackPro
|
|
144
144
|
test_files_encrypted == 'true'
|
145
145
|
end
|
146
146
|
|
147
|
-
def modify_default_rspec_formatters
|
148
|
-
ENV.fetch('KNAPSACK_PRO_MODIFY_DEFAULT_RSPEC_FORMATTERS', true)
|
149
|
-
end
|
150
|
-
|
151
|
-
def modify_default_rspec_formatters?
|
152
|
-
modify_default_rspec_formatters.to_s == 'true'
|
153
|
-
end
|
154
|
-
|
155
147
|
def branch_encrypted
|
156
148
|
ENV['KNAPSACK_PRO_BRANCH_ENCRYPTED']
|
157
149
|
end
|
@@ -276,7 +268,7 @@ module KnapsackPro
|
|
276
268
|
end
|
277
269
|
|
278
270
|
def log_level
|
279
|
-
LOG_LEVELS[ENV['KNAPSACK_PRO_LOG_LEVEL'].to_s.downcase] || ::Logger::
|
271
|
+
LOG_LEVELS[ENV['KNAPSACK_PRO_LOG_LEVEL'].to_s.downcase] || ::Logger::INFO
|
280
272
|
end
|
281
273
|
|
282
274
|
def log_dir
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KnapsackPro
|
4
|
+
module Extensions
|
5
|
+
# Facade to abstract calls to internal RSpec methods.
|
6
|
+
# To allow comparing the monkey patch with the original RSpec code, keep a similar method structure and permalink to the source.
|
7
|
+
module RSpecExtension
|
8
|
+
Seed = Struct.new(:value, :used?)
|
9
|
+
|
10
|
+
def self.setup!
|
11
|
+
RSpec::Core::World.prepend(World)
|
12
|
+
RSpec::Core::Runner.prepend(Runner)
|
13
|
+
RSpec::Core::Configuration.prepend(Configuration)
|
14
|
+
end
|
15
|
+
|
16
|
+
module World
|
17
|
+
# Based on:
|
18
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/world.rb#L171
|
19
|
+
#
|
20
|
+
# Filters are not announced because we do not load tests during setup. It would print `No examples found.` and we don't want that.
|
21
|
+
def knapsack__announce_filters
|
22
|
+
fail_if_config_and_cli_options_invalid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Runner
|
27
|
+
# Based on:
|
28
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L98
|
29
|
+
#
|
30
|
+
# `@configuration.load_spec_files` is not called because we load tests in batches with `knapsack__load_spec_files_batch` later on.
|
31
|
+
def knapsack__setup(stream_error = $stderr, stream_out = $stdout)
|
32
|
+
configure(stream_error, stream_out)
|
33
|
+
ensure
|
34
|
+
world.knapsack__announce_filters
|
35
|
+
end
|
36
|
+
|
37
|
+
def knapsack__wants_to_quit?
|
38
|
+
world.wants_to_quit
|
39
|
+
end
|
40
|
+
|
41
|
+
def knapsack__rspec_is_quitting?
|
42
|
+
world.respond_to?(:rspec_is_quitting) && world.rspec_is_quitting
|
43
|
+
end
|
44
|
+
|
45
|
+
def knapsack__exit_early
|
46
|
+
_exit_status = configuration.reporter.exit_early(exit_code)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Based on:
|
50
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/configuration.rb#L546
|
51
|
+
def knapsack__error_exit_code
|
52
|
+
configuration.error_exit_code # nil unless `--error-exit-code` is specified
|
53
|
+
end
|
54
|
+
|
55
|
+
# must be called after `Runner#knapsack__setup` that loads the `spec_helper.rb` configuration
|
56
|
+
def knapsack__deprecated_run_all_when_everything_filtered_enabled?
|
57
|
+
configuration.respond_to?(:run_all_when_everything_filtered) && !!configuration.run_all_when_everything_filtered
|
58
|
+
end
|
59
|
+
|
60
|
+
def knapsack__seed
|
61
|
+
Seed.new(configuration.seed.to_s, configuration.seed_used?)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param test_file_paths Array[String]
|
65
|
+
# Example: ['a_spec.rb', 'b_spec.rb[1:1]']
|
66
|
+
def knapsack__load_spec_files_batch(test_file_paths)
|
67
|
+
world.reset
|
68
|
+
|
69
|
+
# Reset filters, but do not reset `configuration.static_config_filter_manager` to preserve the --tag option
|
70
|
+
filter_manager = RSpec::Core::FilterManager.new
|
71
|
+
options.configure_filter_manager(filter_manager)
|
72
|
+
configuration.filter_manager = filter_manager
|
73
|
+
|
74
|
+
configuration.knapsack__load_spec_files(test_file_paths)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Based on:
|
78
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L113
|
79
|
+
#
|
80
|
+
# Ignore `configuration.fail_if_no_examples` in Queue Mode:
|
81
|
+
# * a late CI node, started after all tests were executed by other nodes, is expected to receive an empty batch
|
82
|
+
# * a batch could contain tests with no examples (e.g. commented out)
|
83
|
+
#
|
84
|
+
# @return [Fixnum] exit status code.
|
85
|
+
def knapsack__run_specs(queue_runner)
|
86
|
+
# Based on:
|
87
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/world.rb#L53
|
88
|
+
ordering_strategy = configuration.ordering_registry.fetch(:global)
|
89
|
+
node_examples_passed = true
|
90
|
+
|
91
|
+
configuration.reporter.report(_expected_example_count = 0) do |reporter|
|
92
|
+
configuration.with_suite_hooks do
|
93
|
+
queue_runner.with_batch do |test_file_paths|
|
94
|
+
knapsack__load_spec_files_batch(test_file_paths)
|
95
|
+
|
96
|
+
examples_passed = ordering_strategy.order(world.example_groups).map do |example_group|
|
97
|
+
queue_runner.handle_signal!
|
98
|
+
example_group.run(reporter)
|
99
|
+
end.all?
|
100
|
+
|
101
|
+
node_examples_passed = false unless examples_passed
|
102
|
+
|
103
|
+
knapsack__persist_example_statuses
|
104
|
+
|
105
|
+
if reporter.fail_fast_limit_met?
|
106
|
+
queue_runner.log_fail_fast_limit_met
|
107
|
+
break
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
exit_code(node_examples_passed)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Based on:
|
117
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L90
|
118
|
+
def knapsack__persist_example_statuses
|
119
|
+
persist_example_statuses
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
module Configuration
|
124
|
+
# Based on:
|
125
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/configuration.rb#L1619
|
126
|
+
def knapsack__load_spec_files(test_file_paths)
|
127
|
+
batch_of_files_to_run = get_files_to_run(test_file_paths)
|
128
|
+
batch_of_files_to_run.each do |f|
|
129
|
+
file = File.expand_path(f)
|
130
|
+
load_file_handling_errors(:load, file)
|
131
|
+
loaded_spec_files << file
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -9,24 +9,18 @@ module KnapsackPro
|
|
9
9
|
:example_group_started,
|
10
10
|
:example_started,
|
11
11
|
:example_finished,
|
12
|
-
:example_group_finished
|
13
|
-
:stop
|
12
|
+
:example_group_finished
|
14
13
|
|
15
14
|
attr_reader :output # RSpec < v3.10.2
|
16
15
|
|
17
|
-
# Called at the beginning of each batch,
|
18
|
-
# but only the first instance of this class is used,
|
19
|
-
# so don't rely on the initializer to reset values.
|
20
16
|
def initialize(_output)
|
21
17
|
@output = StringIO.new
|
22
18
|
@time_each = nil
|
23
19
|
@time_all = nil
|
24
20
|
@before_all = 0.0
|
25
21
|
@group = {}
|
26
|
-
@
|
27
|
-
@queue = {}
|
22
|
+
@paths = {}
|
28
23
|
@suite_started = now
|
29
|
-
@batch_started = now
|
30
24
|
end
|
31
25
|
|
32
26
|
def example_group_started(notification)
|
@@ -47,21 +41,15 @@ module KnapsackPro
|
|
47
41
|
def example_group_finished(notification)
|
48
42
|
return unless top_level_group?(notification.group)
|
49
43
|
|
50
|
-
|
51
|
-
@
|
44
|
+
after_all = @time_all.nil? ? 0.0 : now - @time_all
|
45
|
+
add_hooks_time(@group, @before_all, after_all)
|
52
46
|
@before_all = 0.0
|
47
|
+
@paths = merge(@paths, @group)
|
53
48
|
@group = {}
|
54
49
|
end
|
55
50
|
|
56
|
-
# Called at the end of each batch
|
57
|
-
def stop(_notification)
|
58
|
-
@queue = merge(@queue, @batch)
|
59
|
-
@batch = {}
|
60
|
-
@batch_started = now
|
61
|
-
end
|
62
|
-
|
63
51
|
def queue(scheduled_paths)
|
64
|
-
recorded_paths = @
|
52
|
+
recorded_paths = @paths.values.map do |example|
|
65
53
|
KnapsackPro::Adapters::RSpecAdapter.parse_file_path(example[:path])
|
66
54
|
end
|
67
55
|
|
@@ -69,13 +57,13 @@ module KnapsackPro
|
|
69
57
|
object[path] = { path: path, time_execution: 0.0 }
|
70
58
|
end
|
71
59
|
|
72
|
-
merge(@
|
60
|
+
merge(@paths, missing).values.map do |example|
|
73
61
|
example.transform_keys(&:to_s)
|
74
62
|
end
|
75
63
|
end
|
76
64
|
|
77
65
|
def batch
|
78
|
-
@
|
66
|
+
@paths.values.map do |example|
|
79
67
|
example.transform_keys(&:to_s)
|
80
68
|
end
|
81
69
|
end
|
@@ -84,17 +72,13 @@ module KnapsackPro
|
|
84
72
|
now - @suite_started
|
85
73
|
end
|
86
74
|
|
87
|
-
def batch_duration
|
88
|
-
now - @batch_started
|
89
|
-
end
|
90
|
-
|
91
75
|
def unexecuted_test_files(scheduled_paths)
|
92
|
-
pending_paths =
|
76
|
+
pending_paths = @paths.values
|
93
77
|
.filter { |example| example[:time_execution] == 0.0 }
|
94
78
|
.map { |example| example[:path] }
|
95
79
|
|
96
80
|
not_run_paths = scheduled_paths -
|
97
|
-
|
81
|
+
@paths.values
|
98
82
|
.map { |example| example[:path] }
|
99
83
|
|
100
84
|
pending_paths + not_run_paths
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module KnapsackPro
|
2
4
|
module Formatters
|
3
5
|
class TimeTrackerFetcher
|
@@ -7,6 +9,12 @@ module KnapsackPro
|
|
7
9
|
.formatters
|
8
10
|
.find { |f| f.class.to_s == "KnapsackPro::Formatters::TimeTracker" }
|
9
11
|
end
|
12
|
+
|
13
|
+
def self.unexecuted_test_files(scheduled_paths)
|
14
|
+
time_tracker = call
|
15
|
+
return [] unless time_tracker
|
16
|
+
time_tracker.unexecuted_test_files(scheduled_paths)
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
12
20
|
end
|
@@ -6,7 +6,7 @@ module KnapsackPro
|
|
6
6
|
def global_time(time = nil)
|
7
7
|
time = KnapsackPro.tracker.global_time if time.nil?
|
8
8
|
global_time = pretty_seconds(time)
|
9
|
-
"Global
|
9
|
+
"Global test execution duration: #{global_time}"
|
10
10
|
end
|
11
11
|
|
12
12
|
def pretty_seconds(seconds)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KnapsackPro
|
4
|
+
module Pure
|
5
|
+
module Queue
|
6
|
+
class RSpecPure
|
7
|
+
FAILURE_EXIT_CODE = 1
|
8
|
+
FORMATTERS = [
|
9
|
+
'KnapsackPro::Formatters::TimeTracker',
|
10
|
+
]
|
11
|
+
|
12
|
+
def add_knapsack_pro_formatters_to(spec_opts)
|
13
|
+
return spec_opts unless spec_opts
|
14
|
+
return spec_opts if FORMATTERS.all? { |formatter| spec_opts.include?(formatter) }
|
15
|
+
|
16
|
+
FORMATTERS.each do |formatter|
|
17
|
+
next if spec_opts.include?(formatter)
|
18
|
+
spec_opts += " --format #{formatter}"
|
19
|
+
end
|
20
|
+
|
21
|
+
spec_opts
|
22
|
+
end
|
23
|
+
|
24
|
+
def error_exit_code(rspec_error_exit_code)
|
25
|
+
rspec_error_exit_code || FAILURE_EXIT_CODE
|
26
|
+
end
|
27
|
+
|
28
|
+
def args_with_seed_option_added_when_viable(order_option, seed, args)
|
29
|
+
return args if order_option && !order_option.include?('rand')
|
30
|
+
return args if order_option && order_option.to_s.split(':')[1]
|
31
|
+
|
32
|
+
return args unless seed.used?
|
33
|
+
|
34
|
+
args + ['--seed', seed.value]
|
35
|
+
end
|
36
|
+
|
37
|
+
def prepare_cli_args(args, has_format_option, test_dir)
|
38
|
+
(args || '').split
|
39
|
+
.yield_self { args_with_at_least_one_formatter(_1, has_format_option) }
|
40
|
+
.yield_self { args_with_default_options(_1, test_dir) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def rspec_command(args, test_file_paths, scope)
|
44
|
+
messages = []
|
45
|
+
return messages if test_file_paths.empty?
|
46
|
+
|
47
|
+
case scope
|
48
|
+
when :batch_finished
|
49
|
+
messages << 'To retry the last batch of tests fetched from the Queue API, please run the following command on your machine:'
|
50
|
+
when :queue_finished
|
51
|
+
messages << 'To retry all the tests assigned to this CI node, please run the following command on your machine:'
|
52
|
+
end
|
53
|
+
|
54
|
+
stringified_cli_args = args.join(' ')
|
55
|
+
FORMATTERS.each do |formatter|
|
56
|
+
stringified_cli_args.sub!(" --format #{formatter}", '')
|
57
|
+
end
|
58
|
+
|
59
|
+
messages << "bundle exec rspec #{stringified_cli_args} " + KnapsackPro::TestFilePresenter.stringify_paths(test_file_paths)
|
60
|
+
|
61
|
+
messages
|
62
|
+
end
|
63
|
+
|
64
|
+
def exit_summary(unexecuted_test_files)
|
65
|
+
return if unexecuted_test_files.empty?
|
66
|
+
|
67
|
+
"Unexecuted tests on this CI node (including pending tests): #{unexecuted_test_files.join(' ')}"
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def args_with_at_least_one_formatter(cli_args, has_format_option)
|
73
|
+
return cli_args if has_format_option
|
74
|
+
|
75
|
+
cli_args + ['--format', 'progress']
|
76
|
+
end
|
77
|
+
|
78
|
+
def args_with_default_options(cli_args, test_dir)
|
79
|
+
new_cli_args = cli_args + [
|
80
|
+
'--default-path', test_dir,
|
81
|
+
]
|
82
|
+
|
83
|
+
FORMATTERS.each do |formatter|
|
84
|
+
new_cli_args += ['--format', formatter]
|
85
|
+
end
|
86
|
+
|
87
|
+
new_cli_args
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -4,6 +4,7 @@ module KnapsackPro
|
|
4
4
|
module Runners
|
5
5
|
module Queue
|
6
6
|
class BaseRunner
|
7
|
+
TerminationError = Class.new(StandardError)
|
7
8
|
TERMINATION_SIGNALS = %w(HUP INT TERM ABRT QUIT USR1 USR2)
|
8
9
|
|
9
10
|
@@terminate_process = false
|
@@ -42,13 +43,17 @@ module KnapsackPro
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def self.handle_signal!
|
45
|
-
raise 'Knapsack Pro process was terminated!' if @@terminate_process
|
46
|
+
raise TerminationError.new('Knapsack Pro process was terminated!') if @@terminate_process
|
46
47
|
end
|
47
48
|
|
48
49
|
def self.set_terminate_process
|
49
50
|
@@terminate_process = true
|
50
51
|
end
|
51
52
|
|
53
|
+
def set_terminate_process
|
54
|
+
self.class.set_terminate_process
|
55
|
+
end
|
56
|
+
|
52
57
|
def trap_signals
|
53
58
|
TERMINATION_SIGNALS.each do |signal|
|
54
59
|
Signal.trap(signal) {
|
@@ -21,7 +21,7 @@ module KnapsackPro
|
|
21
21
|
can_initialize_queue: true,
|
22
22
|
args: args,
|
23
23
|
exitstatus: 0,
|
24
|
-
|
24
|
+
node_test_file_paths: [],
|
25
25
|
}
|
26
26
|
while accumulator[:status] == :next
|
27
27
|
handle_signal!
|
@@ -36,15 +36,15 @@ module KnapsackPro
|
|
36
36
|
can_initialize_queue = accumulator.fetch(:can_initialize_queue)
|
37
37
|
args = accumulator.fetch(:args)
|
38
38
|
exitstatus = accumulator.fetch(:exitstatus)
|
39
|
-
|
39
|
+
node_test_file_paths = accumulator.fetch(:node_test_file_paths)
|
40
40
|
|
41
41
|
test_file_paths = runner.test_file_paths(
|
42
42
|
can_initialize_queue: can_initialize_queue,
|
43
|
-
executed_test_files:
|
43
|
+
executed_test_files: node_test_file_paths
|
44
44
|
)
|
45
45
|
|
46
46
|
if test_file_paths.empty?
|
47
|
-
unless
|
47
|
+
unless node_test_file_paths.empty?
|
48
48
|
KnapsackPro::Adapters::CucumberAdapter.verify_bind_method_called
|
49
49
|
end
|
50
50
|
|
@@ -65,7 +65,7 @@ module KnapsackPro
|
|
65
65
|
|
66
66
|
KnapsackPro::Hooks::Queue.call_before_subset_queue
|
67
67
|
|
68
|
-
|
68
|
+
node_test_file_paths += test_file_paths
|
69
69
|
|
70
70
|
result_exitstatus = cucumber_run(runner, test_file_paths, args)
|
71
71
|
exitstatus = result_exitstatus if result_exitstatus != 0
|
@@ -80,7 +80,7 @@ module KnapsackPro
|
|
80
80
|
can_initialize_queue: false,
|
81
81
|
args: args,
|
82
82
|
exitstatus: exitstatus,
|
83
|
-
|
83
|
+
node_test_file_paths: node_test_file_paths,
|
84
84
|
}
|
85
85
|
end
|
86
86
|
end
|
@@ -7,6 +7,10 @@ module KnapsackPro
|
|
7
7
|
def self.run(args)
|
8
8
|
require 'minitest'
|
9
9
|
|
10
|
+
# Avoid installing `at_exit` since we are calling `Minitest.run` ourselves.
|
11
|
+
# Without this, Minitest would run again (autorun) after `Minitest.run`.
|
12
|
+
::Minitest.class_variable_set('@@installed_at_exit', true)
|
13
|
+
|
10
14
|
ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_minitest
|
11
15
|
ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
|
12
16
|
ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
|
@@ -28,7 +32,7 @@ module KnapsackPro
|
|
28
32
|
can_initialize_queue: true,
|
29
33
|
args: cli_args,
|
30
34
|
exitstatus: 0,
|
31
|
-
|
35
|
+
node_test_file_paths: [],
|
32
36
|
}
|
33
37
|
while accumulator[:status] == :next
|
34
38
|
handle_signal!
|
@@ -43,15 +47,15 @@ module KnapsackPro
|
|
43
47
|
can_initialize_queue = accumulator.fetch(:can_initialize_queue)
|
44
48
|
args = accumulator.fetch(:args)
|
45
49
|
exitstatus = accumulator.fetch(:exitstatus)
|
46
|
-
|
50
|
+
node_test_file_paths = accumulator.fetch(:node_test_file_paths)
|
47
51
|
|
48
52
|
test_file_paths = runner.test_file_paths(
|
49
53
|
can_initialize_queue: can_initialize_queue,
|
50
|
-
executed_test_files:
|
54
|
+
executed_test_files: node_test_file_paths
|
51
55
|
)
|
52
56
|
|
53
57
|
if test_file_paths.empty?
|
54
|
-
unless
|
58
|
+
unless node_test_file_paths.empty?
|
55
59
|
KnapsackPro::Adapters::MinitestAdapter.verify_bind_method_called
|
56
60
|
end
|
57
61
|
|
@@ -72,7 +76,7 @@ module KnapsackPro
|
|
72
76
|
|
73
77
|
KnapsackPro::Hooks::Queue.call_before_subset_queue
|
74
78
|
|
75
|
-
|
79
|
+
node_test_file_paths += test_file_paths
|
76
80
|
|
77
81
|
result = minitest_run(runner, test_file_paths, args)
|
78
82
|
exitstatus = 1 unless result
|
@@ -87,7 +91,7 @@ module KnapsackPro
|
|
87
91
|
can_initialize_queue: false,
|
88
92
|
args: args,
|
89
93
|
exitstatus: exitstatus,
|
90
|
-
|
94
|
+
node_test_file_paths: node_test_file_paths,
|
91
95
|
}
|
92
96
|
end
|
93
97
|
end
|