knapsack_pro 7.14.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74a234f9f6948aef8fb2f4c5aff8b2f56077c4cf227b78e76957c470681dc8e7
4
- data.tar.gz: 980e6ebff8f7d49dfa4b1e7296f8d507600a052e49845e0ffde27ffa68d57272
3
+ metadata.gz: c531fc28ddde021a2417447b60d2feaec8924994bb5575cf1f3cd63484d2fa2b
4
+ data.tar.gz: 28eb5e92aff6522f1dfb31b2c2c076bb54f6e50daec25985a09286fb337fec90
5
5
  SHA512:
6
- metadata.gz: '09abbaa277b6593990984ab0a0052b8ca7955366e3460971adb52656e5fb8298e5040af857cd14d87eb3d514127f8dbf388c7470880c86d129a409f30d55f2eb'
7
- data.tar.gz: eef211470c7a006428b346eff52063e491461134ee7c82d02b9ebe6cd829ae2b1091e0432d8c0037f0aaafdc624f7b7707fc8e3b88dd5720721ceb6840514730
6
+ metadata.gz: 5b66568ea07f6ab6ef881e61d3f3affa5d9ba0c0201c64c2292573fc11afc8e212e4d848e63c22b2596b9e4ea36780ad4f5b72a25f729370e463f865aed324c4
7
+ data.tar.gz: '0021619b437b7815807667549ee8a49ffcfca23358b3456e3cbbc5331f2a03a535f271c9cdbf5c83db632709c47ec82e50f3806aab30a0660763011efe9e7800'
data/.circleci/config.yml CHANGED
@@ -194,6 +194,15 @@ jobs:
194
194
  export KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
195
195
  export KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="spec/features/calculator_spec.rb"
196
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]"
197
206
 
198
207
  e2e-queue-rspec:
199
208
  parameters:
@@ -289,24 +298,47 @@ jobs:
289
298
  export KNAPSACK_PRO_CI_NODE_TOTAL=1
290
299
  export KNAPSACK_PRO_CI_NODE_INDEX=0
291
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]"
292
310
  - run:
293
311
  working_directory: ~/rails-app-with-knapsack_pro
294
312
  command: |
295
313
  # turnip ||
314
+ mv .rspec .rspec.off
315
+ cp .rspec.turnip .rspec
296
316
  export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--queue--turnip"
297
317
  export KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true
298
318
  export KNAPSACK_PRO_TEST_DIR=turnip
299
319
  export KNAPSACK_PRO_TEST_FILE_PATTERN="turnip/**/*.feature"
300
- 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
301
326
  - run:
302
327
  working_directory: ~/rails-app-with-knapsack_pro
303
328
  command: |
304
329
  # turnip retry ||
330
+ mv .rspec .rspec.off
331
+ cp .rspec.turnip .rspec
305
332
  export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--queue--turnip"
306
333
  export KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true
307
334
  export KNAPSACK_PRO_TEST_DIR=turnip
308
335
  export KNAPSACK_PRO_TEST_FILE_PATTERN="turnip/**/*.feature"
309
- 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
310
342
 
311
343
  e2e-regular-minitest:
312
344
  parallelism: 2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
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
+
3
13
  ### 7.14.1
4
14
 
5
15
  * Improve execution time tracking for RSpec individual test examples
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
@@ -37,18 +37,6 @@ module KnapsackPro
37
37
  KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector.new.test_file_example_paths
38
38
  end
39
39
 
40
- def self.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
41
- if KnapsackPro::Config::Env.rspec_split_by_test_examples? && has_tag_option?(cli_args)
42
- 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}"
43
- KnapsackPro.logger.error(error_message)
44
- raise error_message
45
- end
46
- end
47
-
48
- def self.has_tag_option?(cli_args)
49
- !!parsed_options(cli_args)&.[](:inclusion_filter)
50
- end
51
-
52
40
  def self.has_format_option?(cli_args)
53
41
  !!parsed_options(cli_args)&.[](:formatters)
54
42
  end
@@ -61,6 +49,17 @@ module KnapsackPro
61
49
  parsed_options(cli_args)&.[](:order)
62
50
  end
63
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
+
64
63
  def self.file_path_for(example)
65
64
  [
66
65
  -> { parse_file_path(example.id) },
@@ -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
 
@@ -179,10 +179,17 @@ module KnapsackPro
179
179
  def rspec_split_by_test_examples?
180
180
  return @rspec_split_by_test_examples if defined?(@rspec_split_by_test_examples)
181
181
 
182
- 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'
183
190
 
184
191
  if split && ci_node_total < 2
185
- 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)')
186
193
  @rspec_split_by_test_examples = false
187
194
  else
188
195
  @rspec_split_by_test_examples = split
@@ -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
@@ -149,7 +150,6 @@ module KnapsackPro
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)
@@ -8,6 +8,7 @@ module KnapsackPro
8
8
 
9
9
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec
10
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'
@@ -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,
@@ -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.1'
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
@@ -1961,16 +1961,13 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1961
1961
 
1962
1962
  context 'when the RSpec split by test examples is enabled' do
1963
1963
  before do
1964
- ENV['KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES'] = 'true'
1965
-
1966
- # remember to stub Queue API batches to include test examples (example: a_spec.rb[1:1])
1967
- # for the following slow test files
1964
+ # Remember to stub the Queue API batches to include test examples (example: a_spec.rb[1:1])
1965
+ # for the following slow test files.
1968
1966
  ENV['KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN'] = "#{SPEC_DIRECTORY}/a_spec.rb"
1969
1967
 
1970
1968
  ENV['KNAPSACK_PRO_CI_NODE_TOTAL'] = '2'
1971
1969
  end
1972
1970
  after do
1973
- ENV.delete('KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES')
1974
1971
  ENV.delete('KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN')
1975
1972
  ENV.delete('KNAPSACK_PRO_CI_NODE_TOTAL')
1976
1973
  end
@@ -2060,21 +2057,18 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
2060
2057
 
2061
2058
  context 'when the RSpec split by test examples is enabled AND --tag is set' do
2062
2059
  before do
2063
- ENV['KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES'] = 'true'
2064
-
2065
- # remember to stub Queue API batches to include test examples (example: a_spec.rb[1:1])
2066
- # for the following slow test files
2060
+ # Remember to stub the Queue API batches to include test examples (example: a_spec.rb[1:2])
2061
+ # for the following slow test files.
2067
2062
  ENV['KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN'] = "#{SPEC_DIRECTORY}/a_spec.rb"
2068
2063
 
2069
2064
  ENV['KNAPSACK_PRO_CI_NODE_TOTAL'] = '2'
2070
2065
  end
2071
2066
  after do
2072
- ENV.delete('KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES')
2073
2067
  ENV.delete('KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN')
2074
2068
  ENV.delete('KNAPSACK_PRO_CI_NODE_TOTAL')
2075
2069
  end
2076
2070
 
2077
- it 'sets 1 as exit code AND raises an error (a test example path as a_spec.rb[1:1] would always be executed even when it does not have the tag that is set via the --tag option. We cannot run tests because it could lead to running unintentional tests)' do
2071
+ it 'splits slow test files by test examples AND ensures the test examples are executed only once' do
2078
2072
  rspec_options = '--format d --tag my_tag'
2079
2073
 
2080
2074
  spec_a = Spec.new('a_spec.rb', <<~SPEC)
@@ -2082,7 +2076,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
2082
2076
  it 'A1 test example' do
2083
2077
  expect(1).to eq 1
2084
2078
  end
2085
- it 'A2 test example' do
2079
+ it 'A2 test example', :my_tag do
2086
2080
  expect(1).to eq 1
2087
2081
  end
2088
2082
  end
@@ -2101,7 +2095,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
2101
2095
 
2102
2096
  spec_c = Spec.new('c_spec.rb', <<~SPEC)
2103
2097
  describe 'C_describe' do
2104
- it 'C1 test example' do
2098
+ it 'C1 test example', :my_tag do
2105
2099
  expect(1).to eq 1
2106
2100
  end
2107
2101
  it 'C2 test example' do
@@ -2114,26 +2108,25 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
2114
2108
  [spec_a, spec_b, spec_c]
2115
2109
  ])
2116
2110
  stub_test_cases_for_slow_test_files([
2117
- "#{spec_a.path}[1:1]",
2118
- "#{spec_a.path}[1:2]",
2111
+ "#{spec_a.path}[1:2]", # only this test example is tagged
2119
2112
  ])
2120
2113
  stub_spec_batches([
2121
- ["#{spec_a.path}[1:1]", spec_b.path],
2114
+ [spec_b.path],
2122
2115
  ["#{spec_a.path}[1:2]", spec_c.path],
2123
2116
  ])
2124
2117
 
2125
2118
  actual = subject
2126
2119
 
2127
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature. Please see: https://knapsackpro.com/perma/ruby/rspec-split-by-test-examples-tag')
2128
-
2129
2120
  expect(actual.stdout).to_not include('A1 test example')
2130
- expect(actual.stdout).to_not include('A2 test example')
2131
- expect(actual.stdout).to_not include('B1 test example')
2132
- expect(actual.stdout).to_not include('B2 test example')
2133
- expect(actual.stdout).to_not include('C1 test example')
2121
+ expect(actual.stdout).to include('A2 test example')
2122
+ expect(actual.stdout).to include('B1 test example')
2123
+ expect(actual.stdout).to include('B2 test example')
2124
+ expect(actual.stdout).to include('C1 test example')
2134
2125
  expect(actual.stdout).to_not include('C2 test example')
2135
2126
 
2136
- expect(actual.exit_code).to eq 1
2127
+ expect(actual.stdout).to include('4 examples, 0 failures')
2128
+
2129
+ expect(actual.exit_code).to eq 0
2137
2130
  end
2138
2131
  end
2139
2132
 
@@ -2141,16 +2134,13 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
2141
2134
  let(:json_file) { "#{SPEC_DIRECTORY}/rspec.json" }
2142
2135
 
2143
2136
  before do
2144
- ENV['KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES'] = 'true'
2145
-
2146
- # remember to stub Queue API batches to include test examples (example: a_spec.rb[1:1])
2147
- # for the following slow test files
2137
+ # Remember to stub the Queue API batches to include test examples (example: a_spec.rb[1:1])
2138
+ # for the following slow test files.
2148
2139
  ENV['KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN'] = "#{SPEC_DIRECTORY}/a_spec.rb"
2149
2140
 
2150
2141
  ENV['KNAPSACK_PRO_CI_NODE_TOTAL'] = '2'
2151
2142
  end
2152
2143
  after do
2153
- ENV.delete('KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES')
2154
2144
  ENV.delete('KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN')
2155
2145
  ENV.delete('KNAPSACK_PRO_CI_NODE_TOTAL')
2156
2146
  end
@@ -2243,16 +2233,13 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
2243
2233
  let(:xml_file) { "#{SPEC_DIRECTORY}/rspec.xml" }
2244
2234
 
2245
2235
  before do
2246
- ENV['KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES'] = 'true'
2247
-
2248
- # remember to stub Queue API batches to include test examples (example: a_spec.rb[1:1])
2249
- # for the following slow test files
2236
+ # Remember to stub the Queue API batches to include test examples (example: a_spec.rb[1:1])
2237
+ # for the following slow test files.
2250
2238
  ENV['KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN'] = "#{SPEC_DIRECTORY}/a_spec.rb"
2251
2239
 
2252
2240
  ENV['KNAPSACK_PRO_CI_NODE_TOTAL'] = '2'
2253
2241
  end
2254
2242
  after do
2255
- ENV.delete('KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES')
2256
2243
  ENV.delete('KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN')
2257
2244
  ENV.delete('KNAPSACK_PRO_CI_NODE_TOTAL')
2258
2245
  end
@@ -2343,16 +2330,13 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
2343
2330
  let(:coverage_file) { "#{coverage_dir}/index.html" }
2344
2331
 
2345
2332
  before do
2346
- ENV['KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES'] = 'true'
2347
-
2348
- # remember to stub Queue API batches to include test examples (example: a_spec.rb[1:1])
2349
- # for the following slow test files
2333
+ # Remember to stub the Queue API batches to include test examples (example: a_spec.rb[1:1])
2334
+ # for the following slow test files.
2350
2335
  ENV['KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN'] = "#{SPEC_DIRECTORY}/a_spec.rb"
2351
2336
 
2352
2337
  ENV['KNAPSACK_PRO_CI_NODE_TOTAL'] = '2'
2353
2338
  end
2354
2339
  after do
2355
- ENV.delete('KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES')
2356
2340
  ENV.delete('KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN')
2357
2341
  ENV.delete('KNAPSACK_PRO_CI_NODE_TOTAL')
2358
2342
  end
@@ -89,76 +89,6 @@ describe KnapsackPro::Adapters::RSpecAdapter do
89
89
  end
90
90
  end
91
91
 
92
- describe '.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!' do
93
- let(:cli_args) { double }
94
-
95
- subject { described_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args) }
96
-
97
- before do
98
- expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(rspec_split_by_test_examples_enabled)
99
- end
100
-
101
- context 'when RSpec split by test examples enabled' do
102
- let(:rspec_split_by_test_examples_enabled) { true }
103
-
104
- before do
105
- expect(described_class).to receive(:has_tag_option?).with(cli_args).and_return(has_tag_option)
106
- end
107
-
108
- context 'when RSpec tag option is provided' do
109
- let(:has_tag_option) { true }
110
-
111
- it do
112
- expect { subject }.to raise_error(/It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature/)
113
- end
114
- end
115
-
116
- context 'when RSpec tag option is not provided' do
117
- let(:has_tag_option) { false }
118
-
119
- it 'does nothing' do
120
- expect(subject).to be_nil
121
- end
122
- end
123
- end
124
-
125
- context 'when RSpec split by test examples disabled' do
126
- let(:rspec_split_by_test_examples_enabled) { false }
127
-
128
- it 'does nothing' do
129
- expect(subject).to be_nil
130
- end
131
- end
132
- end
133
-
134
- describe '.has_tag_option?' do
135
- subject { described_class.has_tag_option?(cli_args) }
136
-
137
- context 'when tag option is provided as -t' do
138
- let(:cli_args) { ['-t', 'mytag'] }
139
-
140
- it { expect(subject).to be true }
141
- end
142
-
143
- context 'when tag option is provided as --tag' do
144
- let(:cli_args) { ['--tag', 'mytag'] }
145
-
146
- it { expect(subject).to be true }
147
- end
148
-
149
- context 'when tag option is provided without delimiter' do
150
- let(:cli_args) { ['-tmytag'] }
151
-
152
- it { expect(subject).to be true }
153
- end
154
-
155
- context 'when tag option is not provided' do
156
- let(:cli_args) { ['--fake', 'value'] }
157
-
158
- it { expect(subject).to be false }
159
- end
160
- end
161
-
162
92
  describe '.has_format_option?' do
163
93
  subject { described_class.has_format_option?(cli_args) }
164
94
 
@@ -315,6 +245,18 @@ describe KnapsackPro::Adapters::RSpecAdapter do
315
245
  end
316
246
  end
317
247
 
248
+ describe '.remove_formatters' do
249
+ subject { described_class.remove_formatters(cli_args) }
250
+
251
+ context "when CLI args include formatters" do
252
+ let(:cli_args) { ['-t', 'awesome_tag', '-f', 'documentation', '-o', '/tmp/documentation.txt', '--tag', 'mytag', '--format', 'json', '--out', '/tmp/file.json', '--no-color'] }
253
+
254
+ it 'removes formatters and the related output file options' do
255
+ expect(subject).to eq ['-t', 'awesome_tag', '--tag', 'mytag', '--no-color']
256
+ end
257
+ end
258
+ end
259
+
318
260
  describe '.file_path_for' do
319
261
  let(:current_example) { ::RSpec.describe.example }
320
262
 
@@ -977,47 +977,36 @@ describe KnapsackPro::Config::Env do
977
977
  described_class.remove_instance_variable(:@rspec_split_by_test_examples)
978
978
  end
979
979
 
980
- context 'when KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true AND KNAPSACK_PRO_CI_NODE_TOTAL >= 2' do
981
- before do
982
- stub_const("ENV", { 'KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES' => 'true', 'KNAPSACK_PRO_CI_NODE_TOTAL' => '2' })
983
- expect(KnapsackPro).not_to receive(:logger)
984
- end
985
-
986
- it { should be true }
987
- end
988
-
989
- context 'when KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=false AND KNAPSACK_PRO_CI_NODE_TOTAL >= 2' do
990
- before do
991
- stub_const("ENV", { 'KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES' => 'false', 'KNAPSACK_PRO_CI_NODE_TOTAL' => '2' })
992
- expect(KnapsackPro).not_to receive(:logger)
993
- end
994
-
995
- it { should be false }
996
- end
997
-
998
- context 'when KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true AND KNAPSACK_PRO_CI_NODE_TOTAL < 2' do
999
- before { stub_const("ENV", { 'KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES' => 'true', 'KNAPSACK_PRO_CI_NODE_TOTAL' => '1' }) }
1000
-
1001
- it { should be false }
1002
-
1003
- context 'when called twice' do
1004
- it 'logs a debug message only once' do
1005
- logger = instance_double(Logger)
1006
- expect(KnapsackPro).to receive(:logger).and_return(logger)
1007
- expect(logger).to receive(:debug).with('Skipping split of test files by test examples because you are running tests on a single CI node (no parallelism)')
980
+ [
981
+ ['false', '2', nil, false],
982
+ ['true', '2', nil, true],
983
+ [nil, '2', nil, true],
984
+ ['false', '1', nil, false],
985
+ ['true', '1', nil, false, :debug, 'Skipping split by test examples because tests are running on a single CI node (no parallelism)'],
986
+ [nil, '1', nil, false, :debug, 'Skipping split by test examples because tests are running on a single CI node (no parallelism)'],
987
+ ['false', '2', 'true', false],
988
+ ['true', '2', 'true', true],
989
+ [nil, '2', 'true', false, :warn, "Skipping split by test examples because test file names encryption is enabled:\nhttps://knapsackpro.com/perma/ruby/encryption\nhttps://knapsackpro.com/perma/ruby/split-by-test-examples"],
990
+ ['false', '1', 'true', false],
991
+ ['true', '1', 'true', false, :debug, 'Skipping split by test examples because tests are running on a single CI node (no parallelism)'],
992
+ [nil, '1', 'true', false, :warn, "Skipping split by test examples because test file names encryption is enabled:\nhttps://knapsackpro.com/perma/ruby/encryption\nhttps://knapsackpro.com/perma/ruby/split-by-test-examples"],
993
+ ].each do |sbte, node_total, encrypted, expected, log_level, log_message|
994
+ context "KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=#{sbte.inspect} AND KNAPSACK_PRO_CI_NODE_TOTAL=#{node_total.inspect} AND KNAPSACK_PRO_TEST_FILES_ENCRYPTED=#{encrypted.inspect}" do
995
+ before do
996
+ stub_const("ENV", { 'KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES' => sbte, 'KNAPSACK_PRO_CI_NODE_TOTAL' => node_total, 'KNAPSACK_PRO_TEST_FILES_ENCRYPTED' => encrypted }.compact)
1008
997
 
1009
- 2.times { described_class.rspec_split_by_test_examples? }
998
+ if log_level && log_message
999
+ logger = instance_double(Logger)
1000
+ expect(KnapsackPro).to receive(:logger).and_return(logger)
1001
+ expect(logger).to receive(log_level).once.with(log_message)
1002
+ end
1010
1003
  end
1011
- end
1012
- end
1013
1004
 
1014
- context "when ENV doesn't exist" do
1015
- before do
1016
- stub_const("ENV", {})
1017
- expect(KnapsackPro).not_to receive(:logger)
1005
+ it do
1006
+ expect(described_class.rspec_split_by_test_examples?).to eq(expected)
1007
+ expect(described_class.rspec_split_by_test_examples?).to eq(expected)
1008
+ end
1018
1009
  end
1019
-
1020
- it { should be false }
1021
1010
  end
1022
1011
  end
1023
1012
 
@@ -17,6 +17,7 @@ describe KnapsackPro::Runners::RSpecRunner do
17
17
 
18
18
  expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_TEST_SUITE_TOKEN', test_suite_token_rspec)
19
19
  expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_REGULAR_MODE_ENABLED', 'true')
20
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_RSPEC_OPTIONS', args)
20
21
 
21
22
  expect(KnapsackPro::Config::Env).to receive(:set_test_runner_adapter).with(KnapsackPro::Adapters::RSpecAdapter)
22
23
 
@@ -40,7 +41,6 @@ describe KnapsackPro::Runners::RSpecRunner do
40
41
 
41
42
  before do
42
43
  expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:verify_bind_method_called).ordered
43
- expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!).with(['--profile', '--color']).ordered
44
44
 
45
45
  expect(Rake::Task).to receive(:[]).with('knapsack_pro:rspec_run').at_least(1).and_return(task)
46
46
 
@@ -4,21 +4,21 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
4
4
  let(:rspec_test_example_detector) { described_class.new }
5
5
 
6
6
  describe '#generate_json_report' do
7
- subject { rspec_test_example_detector.generate_json_report }
7
+ subject { rspec_test_example_detector.generate_json_report(rspec_args) }
8
8
 
9
- before do
10
- expect(KnapsackPro::Config::TempFiles).to receive(:ensure_temp_directory_exists!)
9
+ shared_examples 'generate_json_report runs RSpec::Core::Runner' do
10
+ before do
11
+ expect(KnapsackPro::Config::TempFiles).to receive(:ensure_temp_directory_exists!)
11
12
 
12
- expect(FileUtils).to receive(:mkdir_p).with(report_dir)
13
+ expect(FileUtils).to receive(:mkdir_p).with(report_dir)
13
14
 
14
- allow(File).to receive(:exist?)
15
- expect(File).to receive(:exist?).at_least(:once).with(report_path).and_return(true)
16
- expect(File).to receive(:delete).with(report_path)
15
+ allow(File).to receive(:exist?)
16
+ expect(File).to receive(:exist?).at_least(:once).with(report_path).and_return(true)
17
+ expect(File).to receive(:delete).with(report_path)
17
18
 
18
- expect(rspec_test_example_detector).to receive(:slow_test_files).and_return(test_file_entities)
19
- end
19
+ expect(rspec_test_example_detector).to receive(:slow_test_files).and_return(test_file_entities)
20
+ end
20
21
 
21
- shared_examples 'generate_json_report runs RSpec::Core::Runner' do
22
22
  context 'when there are no slow test files' do
23
23
  let(:test_file_entities) { [] }
24
24
 
@@ -45,7 +45,7 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
45
45
  expect(KnapsackPro::TestFilePattern).to receive(:test_dir).with(KnapsackPro::Adapters::RSpecAdapter).and_return(test_dir)
46
46
 
47
47
  options = double
48
- expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
48
+ expect(RSpec::Core::ConfigurationOptions).to receive(:new).with(expected_args + [
49
49
  '--format', expected_format,
50
50
  '--dry-run',
51
51
  '--no-color',
@@ -85,12 +85,16 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
85
85
  end
86
86
 
87
87
  context 'when RSpec >= 3.6.0' do
88
+ let(:rspec_args) { '' }
89
+ let(:expected_args) { [] }
88
90
  let(:expected_format) { 'json' }
89
91
 
90
92
  it_behaves_like 'generate_json_report runs RSpec::Core::Runner'
91
93
  end
92
94
 
93
95
  context 'when RSpec < 3.6.0' do
96
+ let(:rspec_args) { '' }
97
+ let(:expected_args) { [] }
94
98
  let(:expected_format) { 'KnapsackPro::Formatters::RSpecJsonFormatter' }
95
99
 
96
100
  before do
@@ -99,6 +103,26 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
99
103
 
100
104
  it_behaves_like 'generate_json_report runs RSpec::Core::Runner'
101
105
  end
106
+
107
+ context 'when RSpec CLI args are present including format option' do
108
+ let(:rspec_args) { '-t mytag --format documentation --out /tmp/documentation.txt --tag ~@skip --example-matches regexp --example string' }
109
+ let(:expected_args) { ['-t', 'mytag', '--tag', '~@skip', '--example-matches', 'regexp', '--example', 'string'] }
110
+ let(:expected_format) { 'json' }
111
+
112
+ describe 'removes formatters from RSpec CLI args' do
113
+ it_behaves_like 'generate_json_report runs RSpec::Core::Runner'
114
+ end
115
+ end
116
+
117
+ context 'when RSpec CLI args are not set' do
118
+ let(:rspec_args) { nil }
119
+ let(:expected_args) { [] }
120
+ let(:expected_format) { 'json' }
121
+
122
+ it do
123
+ expect { subject }.to raise_error("The internal KNAPSACK_PRO_RSPEC_OPTIONS environment variable is unset. Ensure it is not overridden accidentally. Otherwise, please report this as a bug: https://knapsackpro.com/perma/ruby/support")
124
+ end
125
+ end
102
126
  end
103
127
 
104
128
  describe '#test_file_example_paths' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knapsack_pro
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.14.1
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-21 00:00:00.000000000 Z
11
+ date: 2025-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -39,159 +39,159 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.6'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: cucumber
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rspec-its
56
+ name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '1.3'
61
+ version: 5.0.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '1.3'
68
+ version: 5.0.0
69
69
  - !ruby/object:Gem::Dependency
70
- name: cucumber
70
+ name: ostruct
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 0.6.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: 0.6.0
83
83
  - !ruby/object:Gem::Dependency
84
- name: spinach
84
+ name: pry
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.8'
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.8'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: minitest
98
+ name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 5.0.0
103
+ version: '3.0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 5.0.0
110
+ version: '3.0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: test-unit
112
+ name: rspec-its
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 3.0.0
117
+ version: '1.3'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 3.0.0
124
+ version: '1.3'
125
125
  - !ruby/object:Gem::Dependency
126
- name: pry
126
+ name: spinach
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: '0.8'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: '0'
138
+ version: '0.8'
139
139
  - !ruby/object:Gem::Dependency
140
- name: vcr
140
+ name: test-unit
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
144
144
  - !ruby/object:Gem::Version
145
- version: '6.0'
145
+ version: 3.0.0
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
- version: '6.0'
152
+ version: 3.0.0
153
153
  - !ruby/object:Gem::Dependency
154
- name: webmock
154
+ name: timecop
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: '3.13'
159
+ version: 0.9.9
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
- version: '3.13'
166
+ version: 0.9.9
167
167
  - !ruby/object:Gem::Dependency
168
- name: timecop
168
+ name: vcr
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
172
172
  - !ruby/object:Gem::Version
173
- version: 0.9.9
173
+ version: '6.0'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
- version: 0.9.9
180
+ version: '6.0'
181
181
  - !ruby/object:Gem::Dependency
182
- name: ostruct
182
+ name: webmock
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - ">="
186
186
  - !ruby/object:Gem::Version
187
- version: 0.6.0
187
+ version: '3.13'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
- version: 0.6.0
194
+ version: '3.13'
195
195
  description: Knapsack Pro wraps your current test runner(s) and works with your existing
196
196
  CI infrastructure to parallelize tests optimally. It dynamically splits your tests
197
197
  based on up-to-date test execution data. It's designed from the ground up for CI