knapsack_pro 6.0.3 → 7.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 +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
|