knapsack_pro 7.14.0 → 8.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +36 -2
  3. data/CHANGELOG.md +18 -0
  4. data/knapsack_pro.gemspec +5 -5
  5. data/lib/knapsack_pro/adapters/base_adapter.rb +2 -2
  6. data/lib/knapsack_pro/adapters/rspec_adapter.rb +34 -16
  7. data/lib/knapsack_pro/base_allocator_builder.rb +5 -5
  8. data/lib/knapsack_pro/config/env.rb +12 -17
  9. data/lib/knapsack_pro/formatters/time_tracker.rb +27 -13
  10. data/lib/knapsack_pro/formatters/time_tracker_fetcher.rb +2 -2
  11. data/lib/knapsack_pro/runners/cucumber_runner.rb +1 -1
  12. data/lib/knapsack_pro/runners/minitest_runner.rb +1 -1
  13. data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +1 -1
  14. data/lib/knapsack_pro/runners/queue/minitest_runner.rb +1 -1
  15. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +8 -4
  16. data/lib/knapsack_pro/runners/rspec_runner.rb +2 -4
  17. data/lib/knapsack_pro/runners/spinach_runner.rb +1 -1
  18. data/lib/knapsack_pro/runners/test_unit_runner.rb +1 -1
  19. data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +8 -2
  20. data/lib/knapsack_pro/test_case_mergers/rspec_merger.rb +1 -7
  21. data/lib/knapsack_pro/tracker.rb +1 -1
  22. data/lib/knapsack_pro/urls.rb +0 -2
  23. data/lib/knapsack_pro/version.rb +1 -1
  24. data/lib/tasks/rspec.rake +1 -1
  25. data/spec/integration/runners/queue/rspec_runner_spec.rb +126 -44
  26. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +9 -9
  27. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +54 -70
  28. data/spec/knapsack_pro/config/env_spec.rb +51 -105
  29. data/spec/knapsack_pro/formatters/time_tracker_fetcher_spec.rb +2 -5
  30. data/spec/knapsack_pro/formatters/time_tracker_specs.rb +4 -2
  31. data/spec/knapsack_pro/runners/cucumber_runner_spec.rb +1 -1
  32. data/spec/knapsack_pro/runners/minitest_runner_spec.rb +1 -1
  33. data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +1 -1
  34. data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +1 -1
  35. data/spec/knapsack_pro/runners/rspec_runner_spec.rb +2 -2
  36. data/spec/knapsack_pro/runners/spinach_runner_spec.rb +1 -1
  37. data/spec/knapsack_pro/runners/test_unit_runner_spec.rb +1 -1
  38. data/spec/knapsack_pro/test_case_detectors/rspec_test_example_detector_spec.rb +35 -11
  39. metadata +48 -48
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 113e9ca31d058ab9623d6a0bb278768ad0a864db8bb8776440d00ceb2a648b37
4
- data.tar.gz: '084be6d88bf072c8ece112b3de2a6707b240816e993f039701cd68e7920f7988'
3
+ metadata.gz: c531fc28ddde021a2417447b60d2feaec8924994bb5575cf1f3cd63484d2fa2b
4
+ data.tar.gz: 28eb5e92aff6522f1dfb31b2c2c076bb54f6e50daec25985a09286fb337fec90
5
5
  SHA512:
6
- metadata.gz: 97015f7b3db931f3a9f68e7ef59aecb99f0befa5202b148d5aa56736d256048c842c00babc265c47c583534f2a0dafc488c49b748b4b3084f93a2d42f6013d84
7
- data.tar.gz: 62fd8be74b14f402840ea4b9b6866a9ac008daa09d279e2cee21bd3f513d8f746f635c770c83e65db36139aa6e9ebb362301794e6aad70a9d59796dd86167d90
6
+ metadata.gz: 5b66568ea07f6ab6ef881e61d3f3affa5d9ba0c0201c64c2292573fc11afc8e212e4d848e63c22b2596b9e4ea36780ad4f5b72a25f729370e463f865aed324c4
7
+ data.tar.gz: '0021619b437b7815807667549ee8a49ffcfca23358b3456e3cbbc5331f2a03a535f271c9cdbf5c83db632709c47ec82e50f3806aab30a0660763011efe9e7800'
data/.circleci/config.yml CHANGED
@@ -62,6 +62,8 @@ jobs:
62
62
  - setup_knapsack_pro_ruby
63
63
  - run: gem install rubocop
64
64
  - run: rubocop --fail-level A --only Style/FrozenStringLiteralComment,Layout/EmptyLineAfterMagicComment lib/
65
+ - run: bundle update rspec
66
+ - run: bundle exec rspec --version
65
67
  - run: bundle exec rspec spec
66
68
  - run: bundle exec ruby spec/knapsack_pro/formatters/time_tracker_specs.rb
67
69
 
@@ -192,6 +194,15 @@ jobs:
192
194
  export KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
193
195
  export KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="spec/features/calculator_spec.rb"
194
196
  bundle exec rake knapsack_pro:rspec
197
+ - run:
198
+ working_directory: ~/rails-app-with-knapsack_pro
199
+ command: |
200
+ # split custom files by test examples AND the --tag option passed ||
201
+ export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--regular--split-custom-files--tag-option"
202
+ export KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
203
+ export KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="spec/bar_spec.rb"
204
+ export SKIP_ME_OR_I_WILL_FAIL=true
205
+ bundle exec rake "knapsack_pro:rspec[--tag tag_x -t ~tag_y --tag ~skip_me_or_i_will_fail --format documentation]"
195
206
 
196
207
  e2e-queue-rspec:
197
208
  parameters:
@@ -287,24 +298,47 @@ jobs:
287
298
  export KNAPSACK_PRO_CI_NODE_TOTAL=1
288
299
  export KNAPSACK_PRO_CI_NODE_INDEX=0
289
300
  bundle exec rake knapsack_pro:queue:rspec
301
+ - run:
302
+ working_directory: ~/rails-app-with-knapsack_pro
303
+ command: |
304
+ # split custom files by test examples AND the --tag option passed ||
305
+ export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--queue--split-custom-files--tag-option"
306
+ export KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
307
+ export KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="spec/bar_spec.rb"
308
+ export SKIP_ME_OR_I_WILL_FAIL=true
309
+ bundle exec rake "knapsack_pro:queue:rspec[--tag tag_x -t ~tag_y --tag ~skip_me_or_i_will_fail --format documentation]"
290
310
  - run:
291
311
  working_directory: ~/rails-app-with-knapsack_pro
292
312
  command: |
293
313
  # turnip ||
314
+ mv .rspec .rspec.off
315
+ cp .rspec.turnip .rspec
294
316
  export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--queue--turnip"
295
317
  export KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true
296
318
  export KNAPSACK_PRO_TEST_DIR=turnip
297
319
  export KNAPSACK_PRO_TEST_FILE_PATTERN="turnip/**/*.feature"
298
- bundle exec rake "knapsack_pro:queue:rspec[-r turnip/rspec]"
320
+ export KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="turnip/acceptance/foo.feature"
321
+ bundle exec rake knapsack_pro:queue:rspec
322
+ RSPEC_EXIT_CODE=$?
323
+ rm .rspec
324
+ mv .rspec.off .rspec
325
+ exit $RSPEC_EXIT_CODE
299
326
  - run:
300
327
  working_directory: ~/rails-app-with-knapsack_pro
301
328
  command: |
302
329
  # turnip retry ||
330
+ mv .rspec .rspec.off
331
+ cp .rspec.turnip .rspec
303
332
  export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--queue--turnip"
304
333
  export KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true
305
334
  export KNAPSACK_PRO_TEST_DIR=turnip
306
335
  export KNAPSACK_PRO_TEST_FILE_PATTERN="turnip/**/*.feature"
307
- bundle exec rake "knapsack_pro:queue:rspec[-r turnip/rspec]"
336
+ export KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="turnip/acceptance/foo.feature"
337
+ bundle exec rake knapsack_pro:queue:rspec
338
+ RSPEC_EXIT_CODE=$?
339
+ rm .rspec
340
+ mv .rspec.off .rspec
341
+ exit $RSPEC_EXIT_CODE
308
342
 
309
343
  e2e-regular-minitest:
310
344
  parallelism: 2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ### 8.0.0
4
+
5
+ * Enable [`KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES`](https://docs.knapsackpro.com/ruby/split-by-test-examples/) by default
6
+ * This should improve the speed of your builds, but you can disable it with [`KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=false`](https://docs.knapsackpro.com/ruby/reference/#knapsack_pro_rspec_split_by_test_examples-rspec)
7
+ * Support RSpec tags when using [RSpec split by examples](https://docs.knapsackpro.com/ruby/split-by-test-examples/).
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/288
10
+
11
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v7.14.1...v8.0.0
12
+
13
+ ### 7.14.1
14
+
15
+ * Improve execution time tracking for RSpec individual test examples
16
+
17
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/289
18
+
19
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v7.14.0...v7.14.1
20
+
3
21
  ### 7.14.0
4
22
 
5
23
  * Improve debugging for hanging CI nodes: show hanging spec files in the RSpec output and a command to reproduce the current batch of tests.
data/knapsack_pro.gemspec CHANGED
@@ -29,15 +29,15 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency 'rake', '>= 0'
30
30
 
31
31
  spec.add_development_dependency 'bundler', '>= 1.6'
32
+ spec.add_development_dependency 'cucumber', '>= 0'
33
+ spec.add_development_dependency 'minitest', '>= 5.0.0'
34
+ spec.add_development_dependency 'ostruct', '>= 0.6.0'
35
+ spec.add_development_dependency 'pry', '~> 0'
32
36
  spec.add_development_dependency 'rspec', '~> 3.0'
33
37
  spec.add_development_dependency 'rspec-its', '~> 1.3'
34
- spec.add_development_dependency 'cucumber', '>= 0'
35
38
  spec.add_development_dependency 'spinach', '>= 0.8'
36
- spec.add_development_dependency 'minitest', '>= 5.0.0'
37
39
  spec.add_development_dependency 'test-unit', '>= 3.0.0'
38
- spec.add_development_dependency 'pry', '~> 0'
40
+ spec.add_development_dependency 'timecop', '>= 0.9.9'
39
41
  spec.add_development_dependency 'vcr', '>= 6.0'
40
42
  spec.add_development_dependency 'webmock', '>= 3.13'
41
- spec.add_development_dependency 'timecop', '>= 0.9.9'
42
- spec.add_development_dependency 'ostruct', '>= 0.6.0'
43
43
  end
@@ -59,13 +59,13 @@ module KnapsackPro
59
59
  KnapsackPro::Config::TempFiles.ensure_temp_directory_exists!
60
60
  File.write(self.class.adapter_bind_method_called_file, nil)
61
61
 
62
- if KnapsackPro::Config::Env.recording_enabled?
62
+ if KnapsackPro::Config::Env.regular_mode?
63
63
  KnapsackPro.logger.debug('Regular Mode enabled.')
64
64
  bind_time_tracker
65
65
  bind_save_report
66
66
  end
67
67
 
68
- if KnapsackPro::Config::Env.queue_recording_enabled?
68
+ if KnapsackPro::Config::Env.queue_mode?
69
69
  KnapsackPro.logger.debug('Queue Mode enabled.')
70
70
  bind_queue_mode
71
71
  end
@@ -6,6 +6,7 @@ module KnapsackPro
6
6
  module Adapters
7
7
  class RSpecAdapter < BaseAdapter
8
8
  TEST_DIR_PATTERN = 'spec/**{,/*/**}/*_spec.rb'
9
+ ID_PATH_REGEX = /.+_spec\.rb\[.+\]$/
9
10
 
10
11
  def self.split_by_test_cases_enabled?
11
12
  return false unless KnapsackPro::Config::Env.rspec_split_by_test_examples?
@@ -36,18 +37,6 @@ module KnapsackPro
36
37
  KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector.new.test_file_example_paths
37
38
  end
38
39
 
39
- def self.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
40
- if KnapsackPro::Config::Env.rspec_split_by_test_examples? && has_tag_option?(cli_args)
41
- error_message = "It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature. Please see: #{KnapsackPro::Urls::RSPEC__SPLIT_BY_TEST_EXAMPLES__TAG}"
42
- KnapsackPro.logger.error(error_message)
43
- raise error_message
44
- end
45
- end
46
-
47
- def self.has_tag_option?(cli_args)
48
- !!parsed_options(cli_args)&.[](:inclusion_filter)
49
- end
50
-
51
40
  def self.has_format_option?(cli_args)
52
41
  !!parsed_options(cli_args)&.[](:formatters)
53
42
  end
@@ -60,6 +49,17 @@ module KnapsackPro
60
49
  parsed_options(cli_args)&.[](:order)
61
50
  end
62
51
 
52
+ def self.remove_formatters(cli_args)
53
+ formatter_options = ['-f', '--format', '-o', '--out']
54
+ cli_args.dup.each_with_index do |arg, index|
55
+ if formatter_options.include?(arg)
56
+ cli_args[index] = nil
57
+ cli_args[index + 1] = nil
58
+ end
59
+ end
60
+ cli_args.compact
61
+ end
62
+
63
63
  def self.file_path_for(example)
64
64
  [
65
65
  -> { parse_file_path(example.id) },
@@ -80,6 +80,10 @@ module KnapsackPro
80
80
  id.match(/\A(.*?)(?:\[([\d\s:,]+)\])?\z/).captures.first
81
81
  end
82
82
 
83
+ def self.id_path?(path)
84
+ ID_PATH_REGEX.match?(path)
85
+ end
86
+
83
87
  def self.rails_helper_exists?(test_dir)
84
88
  File.exist?("#{test_dir}/rails_helper.rb")
85
89
  end
@@ -95,6 +99,7 @@ module KnapsackPro
95
99
 
96
100
  def bind_time_tracker
97
101
  ensure_no_focus!
102
+ bind_regular_mode_time_tracker
98
103
  log_tests_duration
99
104
  end
100
105
 
@@ -117,10 +122,19 @@ module KnapsackPro
117
122
  ::RSpec.configure do |config|
118
123
  config.append_after(:suite) do
119
124
  time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
120
- if time_tracker
121
- formatted = KnapsackPro::Presenter.global_time(time_tracker.duration)
122
- KnapsackPro.logger.debug(formatted)
123
- end
125
+ formatted = KnapsackPro::Presenter.global_time(time_tracker.duration)
126
+ KnapsackPro.logger.debug(formatted)
127
+ end
128
+ end
129
+ end
130
+
131
+ def bind_regular_mode_time_tracker
132
+ return unless KnapsackPro::Config::Env.regular_mode?
133
+
134
+ ::RSpec.configure do |config|
135
+ config.append_before(:suite) do
136
+ time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
137
+ time_tracker.scheduled_paths = KnapsackPro::Adapters::RSpecAdapter.scheduled_paths
124
138
  end
125
139
  end
126
140
  end
@@ -158,6 +172,10 @@ module KnapsackPro
158
172
  ::RSpec.configuration
159
173
  end
160
174
 
175
+ def self.scheduled_paths
176
+ rspec_configuration.instance_variable_get(:@files_or_directories_to_run) || []
177
+ end
178
+
161
179
  def self.parsed_options(cli_args)
162
180
  ::RSpec::Core::Parser.parse(cli_args)
163
181
  rescue SystemExit
@@ -23,15 +23,15 @@ module KnapsackPro
23
23
  KnapsackPro::Config::Env.test_dir || TestFilePattern.test_dir(adapter_class)
24
24
  end
25
25
 
26
- # in fallback mode we always want to run the whole test files
27
- # (not split by test cases) to guarantee that each test will be executed
28
- # at least once across parallel CI nodes
26
+ # In Fallback Mode, we always want to run whole test files (not split by
27
+ # test cases) to guarantee that each test will be executed at least once
28
+ # across parallel CI nodes.
29
29
  def fallback_mode_test_files
30
30
  all_test_files_to_run
31
31
  end
32
32
 
33
- # detect test files present on the disk that should be run
34
- # this may include some fast test files + slow test files split by test cases
33
+ # Detect test files present on the disk that should be run.
34
+ # This may include fast test files + slow test files split by test cases.
35
35
  def fast_and_slow_test_files_to_run
36
36
  test_files_to_run = all_test_files_to_run
37
37
 
@@ -87,24 +87,12 @@ module KnapsackPro
87
87
  ENV['KNAPSACK_PRO_REPOSITORY_ADAPTER']
88
88
  end
89
89
 
90
- def recording_enabled
91
- ENV['KNAPSACK_PRO_RECORDING_ENABLED']
92
- end
93
-
94
- def recording_enabled?
95
- recording_enabled == 'true'
96
- end
97
-
98
90
  def regular_mode?
99
- recording_enabled?
91
+ ENV['KNAPSACK_PRO_REGULAR_MODE_ENABLED'] == 'true'
100
92
  end
101
93
 
102
- def queue_recording_enabled
103
- ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED']
104
- end
105
-
106
- def queue_recording_enabled?
107
- queue_recording_enabled == 'true'
94
+ def queue_mode?
95
+ ENV['KNAPSACK_PRO_QUEUE_MODE_ENABLED'] == 'true'
108
96
  end
109
97
 
110
98
  def queue_id
@@ -191,10 +179,17 @@ module KnapsackPro
191
179
  def rspec_split_by_test_examples?
192
180
  return @rspec_split_by_test_examples if defined?(@rspec_split_by_test_examples)
193
181
 
194
- split = ENV.fetch('KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES', false).to_s == 'true'
182
+ env = ENV['KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES']
183
+
184
+ if test_files_encrypted? && env.nil?
185
+ KnapsackPro.logger.warn("Skipping split by test examples because test file names encryption is enabled:\n#{KnapsackPro::Urls::ENCRYPTION}\n#{KnapsackPro::Urls::SPLIT_BY_TEST_EXAMPLES}")
186
+ return (@rspec_split_by_test_examples = false)
187
+ end
188
+
189
+ split = (env || true).to_s == 'true'
195
190
 
196
191
  if split && ci_node_total < 2
197
- KnapsackPro.logger.debug('Skipping split of test files by test examples because you are running tests on a single CI node (no parallelism)')
192
+ KnapsackPro.logger.debug('Skipping split by test examples because tests are running on a single CI node (no parallelism)')
198
193
  @rspec_split_by_test_examples = false
199
194
  else
200
195
  @rspec_split_by_test_examples = split
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'stringio'
4
+ require 'set'
4
5
  require_relative '../utils'
5
6
 
6
7
  module KnapsackPro
@@ -22,6 +23,18 @@ module KnapsackPro
22
23
  @group = {}
23
24
  @paths = {}
24
25
  @suite_started = now
26
+ @scheduled_paths = []
27
+ @split_by_test_example_file_paths = Set.new
28
+ end
29
+
30
+ def scheduled_paths=(scheduled_paths)
31
+ @scheduled_paths = scheduled_paths
32
+ @scheduled_paths.each do |path|
33
+ if KnapsackPro::Adapters::RSpecAdapter.id_path?(path)
34
+ file_path = KnapsackPro::Adapters::RSpecAdapter.parse_file_path(path)
35
+ @split_by_test_example_file_paths << file_path
36
+ end
37
+ end
25
38
  end
26
39
 
27
40
  def example_group_started(notification)
@@ -49,12 +62,12 @@ module KnapsackPro
49
62
  @group = {}
50
63
  end
51
64
 
52
- def queue(scheduled_paths)
65
+ def queue
53
66
  recorded_paths = @paths.values.map do |example|
54
67
  KnapsackPro::Adapters::RSpecAdapter.parse_file_path(example[:path])
55
68
  end
56
69
 
57
- missing = (scheduled_paths - recorded_paths).each_with_object({}) do |path, object|
70
+ missing = (@scheduled_paths - recorded_paths).each_with_object({}) do |path, object|
58
71
  object[path] = { path: path, time_execution: 0.0 }
59
72
  end
60
73
 
@@ -73,12 +86,12 @@ module KnapsackPro
73
86
  now - @suite_started
74
87
  end
75
88
 
76
- def unexecuted_test_files(scheduled_paths)
89
+ def unexecuted_test_files
77
90
  pending_paths = @paths.values
78
91
  .filter { |example| example[:time_execution] == 0.0 }
79
92
  .map { |example| example[:path] }
80
93
 
81
- not_run_paths = scheduled_paths -
94
+ not_run_paths = @scheduled_paths -
82
95
  @paths.values
83
96
  .map { |example| example[:path] }
84
97
 
@@ -111,21 +124,22 @@ module KnapsackPro
111
124
  end
112
125
 
113
126
  def path_for(example)
114
- file = file_path_for(example)
115
- return nil if file == ""
127
+ file_path = file_path_for(example)
128
+ return nil if file_path == ""
116
129
 
117
- path = rspec_split_by_test_example?(file) ? example.id : file
118
- KnapsackPro::TestFileCleaner.clean(path)
130
+ if rspec_split_by_test_example?(file_path)
131
+ KnapsackPro::TestFileCleaner.clean(example.id)
132
+ else
133
+ file_path
134
+ end
119
135
  end
120
136
 
121
- def rspec_split_by_test_example?(file)
122
- return false unless KnapsackPro::Config::Env.rspec_split_by_test_examples?
123
- return false unless KnapsackPro::Adapters::RSpecAdapter.slow_test_file?(KnapsackPro::Adapters::RSpecAdapter, file)
124
- true
137
+ def rspec_split_by_test_example?(file_path)
138
+ @split_by_test_example_file_paths.include?(file_path)
125
139
  end
126
140
 
127
141
  def file_path_for(example)
128
- KnapsackPro::Adapters::RSpecAdapter.file_path_for(example)
142
+ KnapsackPro::TestFileCleaner.clean(KnapsackPro::Adapters::RSpecAdapter.file_path_for(example))
129
143
  end
130
144
 
131
145
  def time_execution_for(example, started_at)
@@ -10,10 +10,10 @@ module KnapsackPro
10
10
  .find { |f| f.class.to_s == "KnapsackPro::Formatters::TimeTracker" }
11
11
  end
12
12
 
13
- def self.unexecuted_test_files(scheduled_paths)
13
+ def self.unexecuted_test_files
14
14
  time_tracker = call
15
15
  return [] unless time_tracker
16
- time_tracker.unexecuted_test_files(scheduled_paths)
16
+ time_tracker.unexecuted_test_files
17
17
  end
18
18
  end
19
19
  end
@@ -5,7 +5,7 @@ module KnapsackPro
5
5
  class CucumberRunner < BaseRunner
6
6
  def self.run(args)
7
7
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_cucumber
8
- ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
8
+ ENV['KNAPSACK_PRO_REGULAR_MODE_ENABLED'] = 'true'
9
9
 
10
10
  adapter_class = KnapsackPro::Adapters::CucumberAdapter
11
11
  KnapsackPro::Config::Env.set_test_runner_adapter(adapter_class)
@@ -5,7 +5,7 @@ module KnapsackPro
5
5
  class MinitestRunner < BaseRunner
6
6
  def self.run(args)
7
7
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_minitest
8
- ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
8
+ ENV['KNAPSACK_PRO_REGULAR_MODE_ENABLED'] = 'true'
9
9
 
10
10
  adapter_class = KnapsackPro::Adapters::MinitestAdapter
11
11
  KnapsackPro::Config::Env.set_test_runner_adapter(adapter_class)
@@ -8,7 +8,7 @@ module KnapsackPro
8
8
  require 'cucumber/rake/task'
9
9
 
10
10
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_cucumber
11
- ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
11
+ ENV['KNAPSACK_PRO_QUEUE_MODE_ENABLED'] = 'true'
12
12
  ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
13
13
 
14
14
  adapter_class = KnapsackPro::Adapters::CucumberAdapter
@@ -12,7 +12,7 @@ module KnapsackPro
12
12
  ::Minitest.class_variable_set('@@installed_at_exit', true)
13
13
 
14
14
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_minitest
15
- ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
15
+ ENV['KNAPSACK_PRO_QUEUE_MODE_ENABLED'] = 'true'
16
16
  ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
17
17
 
18
18
  adapter_class = KnapsackPro::Adapters::MinitestAdapter
@@ -21,6 +21,7 @@ module KnapsackPro
21
21
  end
22
22
 
23
23
  def initialize(adapter_class, rspec_pure, args, stream_error, stream_out)
24
+ ENV['KNAPSACK_PRO_RSPEC_OPTIONS'] = args.to_s
24
25
  super(adapter_class)
25
26
  @adapter_class = adapter_class
26
27
  @rspec_pure = rspec_pure
@@ -143,13 +144,12 @@ module KnapsackPro
143
144
  end
144
145
 
145
146
  def pre_run_setup
146
- ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
147
+ ENV['KNAPSACK_PRO_QUEUE_MODE_ENABLED'] = 'true'
147
148
  ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
148
149
 
149
150
  KnapsackPro::Config::Env.set_test_runner_adapter(@adapter_class)
150
151
 
151
152
  ENV['SPEC_OPTS'] = @rspec_pure.add_knapsack_pro_formatters_to(ENV['SPEC_OPTS'])
152
- @adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(@cli_args)
153
153
 
154
154
  rspec_configuration_options = ::RSpec::Core::ConfigurationOptions.new(@cli_args)
155
155
  @rspec_runner = ::RSpec::Core::Runner.new(rspec_configuration_options)
@@ -164,7 +164,7 @@ module KnapsackPro
164
164
  log_rspec_queue_command
165
165
 
166
166
  time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
167
- KnapsackPro::Report.save_node_queue_to_api(time_tracker&.queue(@node_test_file_paths))
167
+ KnapsackPro::Report.save_node_queue_to_api(time_tracker&.queue)
168
168
 
169
169
  Kernel.exit(exit_code)
170
170
  end
@@ -183,6 +183,10 @@ module KnapsackPro
183
183
  executed_test_files: @node_test_file_paths
184
184
  )
185
185
  @node_test_file_paths += test_file_paths
186
+
187
+ time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
188
+ time_tracker.scheduled_paths = @node_test_file_paths
189
+
186
190
  test_file_paths
187
191
  end
188
192
 
@@ -222,7 +226,7 @@ module KnapsackPro
222
226
  end
223
227
 
224
228
  def unexecuted_test_files
225
- KnapsackPro::Formatters::TimeTrackerFetcher.unexecuted_test_files(@node_test_file_paths)
229
+ KnapsackPro::Formatters::TimeTrackerFetcher.unexecuted_test_files
226
230
  end
227
231
  end
228
232
  end
@@ -7,7 +7,8 @@ module KnapsackPro
7
7
  require 'rspec/core'
8
8
 
9
9
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec
10
- ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
10
+ ENV['KNAPSACK_PRO_REGULAR_MODE_ENABLED'] = 'true'
11
+ ENV['KNAPSACK_PRO_RSPEC_OPTIONS'] = args.to_s
11
12
 
12
13
  adapter_class = KnapsackPro::Adapters::RSpecAdapter
13
14
  KnapsackPro::Config::Env.set_test_runner_adapter(adapter_class)
@@ -16,9 +17,6 @@ module KnapsackPro
16
17
  if runner.test_files_to_execute_exist?
17
18
  adapter_class.verify_bind_method_called
18
19
 
19
- cli_args = (args || '').split
20
- adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
21
-
22
20
  require 'rspec/core/rake_task'
23
21
 
24
22
  task_name = 'knapsack_pro:rspec_run'
@@ -15,7 +15,7 @@ module KnapsackPro
15
15
 
16
16
  KnapsackPro.tracker.set_prerun_tests(runner.test_file_paths)
17
17
 
18
- cmd = %Q[KNAPSACK_PRO_RECORDING_ENABLED=true KNAPSACK_PRO_TEST_SUITE_TOKEN=#{ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN']} bundle exec spinach #{args} --features_path #{runner.test_dir} -- #{runner.stringify_test_file_paths}]
18
+ cmd = %Q[KNAPSACK_PRO_REGULAR_MODE_ENABLED=true KNAPSACK_PRO_TEST_SUITE_TOKEN=#{ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN']} bundle exec spinach #{args} --features_path #{runner.test_dir} -- #{runner.stringify_test_file_paths}]
19
19
 
20
20
  Kernel.system(cmd)
21
21
  Kernel.exit(child_status.exitstatus) unless child_status.exitstatus.zero?
@@ -5,7 +5,7 @@ module KnapsackPro
5
5
  class TestUnitRunner < BaseRunner
6
6
  def self.run(args)
7
7
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_test_unit
8
- ENV['KNAPSACK_PRO_RECORDING_ENABLED'] = 'true'
8
+ ENV['KNAPSACK_PRO_REGULAR_MODE_ENABLED'] = 'true'
9
9
 
10
10
  adapter_class = KnapsackPro::Adapters::TestUnitAdapter
11
11
  KnapsackPro::Config::Env.set_test_runner_adapter(adapter_class)
@@ -3,7 +3,9 @@
3
3
  module KnapsackPro
4
4
  module TestCaseDetectors
5
5
  class RSpecTestExampleDetector
6
- def generate_json_report
6
+ def generate_json_report(rspec_args)
7
+ raise "The internal KNAPSACK_PRO_RSPEC_OPTIONS environment variable is unset. Ensure it is not overridden accidentally. Otherwise, please report this as a bug: #{KnapsackPro::Urls::SUPPORT}" if rspec_args.nil?
8
+
7
9
  require 'rspec/core'
8
10
 
9
11
  cli_format =
@@ -25,7 +27,11 @@ module KnapsackPro
25
27
  return
26
28
  end
27
29
 
28
- cli_args = cli_format + [
30
+ args = (rspec_args || '').split
31
+ cli_args_without_formatters = KnapsackPro::Adapters::RSpecAdapter.remove_formatters(args)
32
+
33
+ # Apply a --format option which overrides formatters from the RSpec custom option files like `.rspec`.
34
+ cli_args = cli_args_without_formatters + cli_format + [
29
35
  '--dry-run',
30
36
  '--no-color',
31
37
  '--out', report_path,
@@ -11,7 +11,7 @@ module KnapsackPro
11
11
  path = test_file.fetch('path')
12
12
  test_file_path = extract_test_file_path(path)
13
13
 
14
- if rspec_id_path?(path)
14
+ if KnapsackPro::Adapters::RSpecAdapter.id_path?(path)
15
15
  merged_test_file_examples_hash[test_file_path] ||= 0.0
16
16
  merged_test_file_examples_hash[test_file_path] += test_file.fetch('time_execution')
17
17
  else
@@ -41,12 +41,6 @@ module KnapsackPro
41
41
  def extract_test_file_path(path)
42
42
  path.gsub(/\.rb\[.+\]$/, '.rb')
43
43
  end
44
-
45
- def rspec_id_path?(path)
46
- path_with_id_regex = /.+_spec\.rb\[.+\]$/
47
-
48
- path&.match?(path_with_id_regex)
49
- end
50
44
  end
51
45
  end
52
46
  end
@@ -113,7 +113,7 @@ module KnapsackPro
113
113
  end
114
114
 
115
115
  def read_prerun_tests_report
116
- raise "Report #{prerun_tests_report_path} doest not exist on the disk. Most likely, it was removed accidentally. Please report the bug to the Knapsack Pro support team at #{KnapsackPro::Urls::SUPPORT}" unless File.exist?(prerun_tests_report_path)
116
+ raise "Report #{prerun_tests_report_path} does not exist on the disk. Most likely, it was removed accidentally. Please report the bug to the Knapsack Pro support team at #{KnapsackPro::Urls::SUPPORT}" unless File.exist?(prerun_tests_report_path)
117
117
  JSON.parse(File.read(prerun_tests_report_path))
118
118
  end
119
119
 
@@ -32,8 +32,6 @@ module KnapsackPro
32
32
 
33
33
  RSPEC__SKIPS_TESTS = "#{HOST}/perma/ruby/rspec-skips-tests"
34
34
 
35
- RSPEC__SPLIT_BY_TEST_EXAMPLES__TAG = "#{HOST}/perma/ruby/rspec-split-by-test-examples-tag"
36
-
37
35
  SPLIT_BY_TEST_EXAMPLES = "#{HOST}/perma/ruby/split-by-test-examples"
38
36
 
39
37
  TEST_UNIT__TEST_FILE_PATH_DETECTION = "#{HOST}/perma/ruby/test-unit-test-file-path-detection"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KnapsackPro
4
- VERSION = '7.14.0'
4
+ VERSION = '8.0.0'
5
5
  end
data/lib/tasks/rspec.rake CHANGED
@@ -13,6 +13,6 @@ namespace :knapsack_pro do
13
13
  ENV.delete('SPEC_OPTS')
14
14
 
15
15
  detector = KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector.new
16
- detector.generate_json_report
16
+ detector.generate_json_report(ENV['KNAPSACK_PRO_RSPEC_OPTIONS'])
17
17
  end
18
18
  end