knapsack_pro 2.13.0 → 2.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e1ee6f214c79d86f5ae94658f147e5f3060a77460e1e26109752e57fdd92bed
4
- data.tar.gz: 3bde2c1578bd8e3d3e3ae39880eac80b598464cb57d8c6698440088ab7c552e0
3
+ metadata.gz: b2e5ae3f380ffe2e210417898e30fc7091abcc4fbcacab97b340e9e5ea5e700b
4
+ data.tar.gz: 481dda7a93c2ba5964fa3c20cf60bf2666432311c9a7f1bf59b3be1c905939bb
5
5
  SHA512:
6
- metadata.gz: 197ea0eeff47c4ed54d3baee9f94b9f00cf2c24b61ecb9ae1aaab4c9c8bca3bb247affb26db99e5fcfc3a172be83fefb765e0d4763f48eab4e243b84e262dddf
7
- data.tar.gz: 681cfbb090e0152190fcf54266ef3b9eb70bca40c17494a7f0679846241a3612a8b9b2e2fa37e624deec7e474352cd0b39ac206add49fc48c31185f4cfe4cd30
6
+ metadata.gz: 185add13dfe335fb6b83c1d4a0121f7e097535459c10356401176e1acea5722764554e8f44a2db2ccf806e9a3f4f0a77ca3f701b5b1bc65881d1771722992e67
7
+ data.tar.gz: a267ddf7469e2affd5e472661dbd2a4fdd17c7f58543dc2c40e305d905004ff7d85808f3e7705892cb4da7ea2dd6fac447ca4a30fc15f296abfafb4668f0f001
data/.circleci/config.yml CHANGED
@@ -8,7 +8,7 @@ jobs:
8
8
  parallelism: 1
9
9
  docker:
10
10
  # specify the version you desire here
11
- - image: circleci/ruby:2.7.0
11
+ - image: circleci/ruby:3.0.1
12
12
  environment:
13
13
  CODECLIMATE_REPO_TOKEN: b6626e682a8e97e0c5978febc92c3526792a2d018b41b8e1b52689da37fb7d92
14
14
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Change Log
2
2
 
3
+ ### 2.18.0
4
+
5
+ * Do not allow to use the RSpec tag option together with the RSpec split by test examples feature in knapsack_pro gem in Regular Mode
6
+
7
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/148
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.17.0...v2.18.0
10
+
11
+ ### 2.17.0
12
+
13
+ * Use Ruby 3 in development and add small improvements
14
+
15
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/147
16
+
17
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.16.0...v2.17.0
18
+
19
+ ### 2.16.0
20
+
21
+ * Improve test time execution tracking for RSpec
22
+
23
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/145
24
+
25
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.15.0...v2.16.0
26
+
27
+ ### 2.15.0
28
+
29
+ * Do not allow to use the RSpec tag option together with the RSpec split by test examples feature
30
+
31
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/139
32
+
33
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.14.0...v2.15.0
34
+
35
+ ### 2.14.0
36
+
37
+ * Track time spend in RSpec context hook
38
+
39
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/143
40
+
41
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.13.0...v2.14.0
42
+
3
43
  ### 2.13.0
4
44
 
5
45
  * Update FAQ links in `knapsack_pro` warnings and remove FAQ from readme
data/README.md CHANGED
@@ -793,43 +793,7 @@ $ KNAPSACK_PRO_SALT=xxx bundle exec rake knapsack_pro:encrypted_branch_names[not
793
793
 
794
794
  If you are using circleci.com you can omit `KNAPSACK_PRO_CI_NODE_TOTAL` and `KNAPSACK_PRO_CI_NODE_INDEX`. Knapsack Pro will use `CIRCLE_NODE_TOTAL` and `CIRCLE_NODE_INDEX` provided by CircleCI.
795
795
 
796
- Here is an example for test configuration in your `circleci.yml` file.
797
-
798
- ```yaml
799
- # CircleCI 1.0
800
-
801
- machine:
802
- environment:
803
- # Tokens should be set in CircleCI settings to avoid expose tokens in build logs
804
- # KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC: rspec-token
805
- # KNAPSACK_PRO_TEST_SUITE_TOKEN_CUCUMBER: cucumber-token
806
- # KNAPSACK_PRO_TEST_SUITE_TOKEN_MINITEST: minitest-token
807
- # KNAPSACK_PRO_TEST_SUITE_TOKEN_TEST_UNIT: test-unit-token
808
- # KNAPSACK_PRO_TEST_SUITE_TOKEN_SPINACH: spinach-token
809
- test:
810
- override:
811
- # Step for RSpec
812
- - bundle exec rake knapsack_pro:rspec:
813
- parallel: true # Caution: there are 8 spaces indentation!
814
-
815
- # Step for Cucumber
816
- - bundle exec rake knapsack_pro:cucumber:
817
- parallel: true # Caution: there are 8 spaces indentation!
818
-
819
- # Step for Minitest
820
- - bundle exec rake knapsack_pro:minitest:
821
- parallel: true # Caution: there are 8 spaces indentation!
822
-
823
- # Step for test-unit
824
- - bundle exec rake knapsack_pro:test_unit:
825
- parallel: true # Caution: there are 8 spaces indentation!
826
-
827
- # Step for Spinach
828
- - bundle exec rake knapsack_pro:spinach:
829
- parallel: true # Caution: there are 8 spaces indentation!
830
- ```
831
-
832
- Here is another example for CircleCI 2.0 platform.
796
+ Here is an example for test configuration in your `.circleci/config.yml` file.
833
797
 
834
798
  ```yaml
835
799
  # CircleCI 2.0
@@ -866,7 +830,7 @@ Please remember to add additional containers for your project in CircleCI settin
866
830
 
867
831
  ##### CircleCI and knapsack_pro Queue Mode
868
832
 
869
- If you use knapsack_pro Queue Mode with CircleCI you may want to [collect metadata](https://circleci.com/docs/1.0/test-metadata/#metadata-collection-in-custom-test-steps) like junit xml report about your RSpec test suite.
833
+ If you use knapsack_pro Queue Mode with CircleCI you may want to [collect metadata](https://circleci.com/docs/2.0/collect-test-data/#metadata-collection-in-custom-test-steps) like junit xml report about your RSpec test suite.
870
834
 
871
835
  Here you can read how to configure [junit formatter](https://knapsackpro.com/faq/question/how-to-use-junit-formatter#how-to-use-junit-formatter-with-knapsack_pro-queue-mode). Step for CircleCI is to copy the xml report to `$CIRCLE_TEST_REPORTS` directory. Below is full config for your `spec_helper.rb`:
872
836
 
@@ -874,7 +838,7 @@ Here you can read how to configure [junit formatter](https://knapsackpro.com/faq
874
838
  # spec_helper.rb or rails_helper.rb
875
839
 
876
840
  # TODO This must be the same path as value for rspec --out argument
877
- # Note the path should not contain sign ~, for instance path ~/project/tmp/rspec.xml may not work. Please use full path instead.
841
+ # Note the path should not contain ~ char, for instance path ~/project/tmp/rspec.xml may not work. Please use full path instead.
878
842
  TMP_RSPEC_XML_REPORT = 'tmp/rspec.xml'
879
843
  # move results to FINAL_RSPEC_XML_REPORT so the results won't accumulate with duplicated xml tags in TMP_RSPEC_XML_REPORT
880
844
  FINAL_RSPEC_XML_REPORT = 'tmp/rspec_final_results.xml'
@@ -913,6 +877,8 @@ Ensure you have in CircleCI config yml
913
877
  destination: test-results
914
878
  ```
915
879
 
880
+ You can find a complete CircleCI YML config example in [the article](https://docs.knapsackpro.com/2021/rspec-testing-parallel-jobs-with-circleci-and-junit-xml-report).
881
+
916
882
  #### Info for Travis users
917
883
 
918
884
  You can parallelize your builds across virtual machines with [travis matrix feature](http://docs.travis-ci.com/user/speeding-up-the-build/#parallelizing-your-builds-across-virtual-machines). Edit `.travis.yml`
data/knapsack_pro.gemspec CHANGED
@@ -29,14 +29,13 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_development_dependency 'bundler', '>= 1.6'
31
31
  spec.add_development_dependency 'rspec', '~> 3.0', '>= 2.10.0'
32
- spec.add_development_dependency 'rspec-its', '~> 1.2'
32
+ spec.add_development_dependency 'rspec-its', '~> 1.3'
33
33
  spec.add_development_dependency 'cucumber', '>= 0'
34
34
  spec.add_development_dependency 'spinach', '>= 0.8'
35
35
  spec.add_development_dependency 'minitest', '>= 5.0.0'
36
36
  spec.add_development_dependency 'test-unit', '>= 3.0.0'
37
- spec.add_development_dependency 'codeclimate-test-reporter', '~> 0'
38
37
  spec.add_development_dependency 'pry', '~> 0'
39
- spec.add_development_dependency 'vcr', '~> 2.9'
40
- spec.add_development_dependency 'webmock', '~> 1.21'
41
- spec.add_development_dependency 'timecop', '>= 0.1.0'
38
+ spec.add_development_dependency 'vcr', '>= 6.0'
39
+ spec.add_development_dependency 'webmock', '>= 3.13'
40
+ spec.add_development_dependency 'timecop', '>= 0.9.4'
42
41
  end
@@ -3,6 +3,27 @@ module KnapsackPro
3
3
  class RSpecAdapter < BaseAdapter
4
4
  TEST_DIR_PATTERN = 'spec/**{,/*/**}/*_spec.rb'
5
5
 
6
+ def self.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
7
+ if KnapsackPro::Config::Env.rspec_split_by_test_examples? && has_tag_option?(cli_args)
8
+ error_message = 'It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature. Please see: https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it#warning-dont-use-rspec-tag-option'
9
+ KnapsackPro.logger.error(error_message)
10
+ raise error_message
11
+ end
12
+ end
13
+
14
+ def self.has_tag_option?(cli_args)
15
+ # use start_with? because user can define tag option in a few ways:
16
+ # -t mytag
17
+ # -tmytag
18
+ # --tag mytag
19
+ # --tag=mytag
20
+ cli_args.any? { |arg| arg.start_with?('-t') || arg.start_with?('--tag') }
21
+ end
22
+
23
+ def self.has_format_option?(cli_args)
24
+ cli_args.any? { |arg| arg.start_with?('-f') || arg.start_with?('--format') }
25
+ end
26
+
6
27
  def self.test_path(example_group)
7
28
  if defined?(::Turnip) && ::Turnip::VERSION.to_i < 2
8
29
  unless example_group[:turnip]
@@ -21,7 +42,15 @@ module KnapsackPro
21
42
 
22
43
  def bind_time_tracker
23
44
  ::RSpec.configure do |config|
45
+ config.prepend_before(:context) do
46
+ KnapsackPro.tracker.start_timer
47
+ end
48
+
24
49
  config.around(:each) do |example|
50
+ # stop timer to update time for a previously run test example
51
+ # this way we count time spend in runtime for the previous test example after around(:each) is already done
52
+ KnapsackPro.tracker.stop_timer
53
+
25
54
  current_example_group =
26
55
  if ::RSpec.respond_to?(:current_example)
27
56
  ::RSpec.current_example.metadata[:example_group]
@@ -38,10 +67,12 @@ module KnapsackPro
38
67
  current_test_path
39
68
  end
40
69
 
41
- KnapsackPro.tracker.start_timer
42
-
43
70
  example.run
71
+ end
44
72
 
73
+ config.append_after(:context) do
74
+ # after(:context) hook is run one time only, after all of the examples in a group
75
+ # stop timer to count time for the very last executed test example
45
76
  KnapsackPro.tracker.stop_timer
46
77
  end
47
78
 
@@ -23,8 +23,7 @@ module KnapsackPro
23
23
  end
24
24
 
25
25
  def project_dir
26
- project_repo_name = ENV['CIRCLE_PROJECT_REPONAME']
27
- "/home/ubuntu/#{project_repo_name}" if project_repo_name
26
+ ENV['CIRCLE_WORKING_DIRECTORY']
28
27
  end
29
28
  end
30
29
  end
@@ -17,7 +17,8 @@ module KnapsackPro
17
17
  private
18
18
 
19
19
  def working_dir
20
- KnapsackPro::Config::Env.project_dir
20
+ dir = KnapsackPro::Config::Env.project_dir
21
+ File.expand_path(dir)
21
22
  end
22
23
  end
23
24
  end
@@ -35,6 +35,10 @@ module KnapsackPro
35
35
 
36
36
  attr_reader :allocator_builder,
37
37
  :allocator
38
+
39
+ def self.child_status
40
+ $?
41
+ end
38
42
  end
39
43
  end
40
44
  end
@@ -29,6 +29,10 @@ module KnapsackPro
29
29
 
30
30
  attr_reader :allocator_builder,
31
31
  :allocator
32
+
33
+ def self.child_status
34
+ $?
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -95,16 +95,14 @@ module KnapsackPro
95
95
  # which is defined in lib/knapsack_pro/adapters/cucumber_adapter.rb
96
96
  ENV['KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED'] = 'true'
97
97
 
98
- process_status = $?
99
-
100
- unless process_status.exited?
98
+ unless child_status.exited?
101
99
  raise "Cucumber process execution failed. It's likely that your CI server has exceeded"\
102
100
  " its available memory. Please try changing CI config or retrying the CI build.\n"\
103
101
  "Failed command: #{cmd}\n"\
104
- "Process status: #{process_status.inspect}"
102
+ "Process status: #{child_status.inspect}"
105
103
  end
106
104
 
107
- process_status.exitstatus
105
+ child_status.exitstatus
108
106
  end
109
107
  end
110
108
  end
@@ -11,15 +11,17 @@ module KnapsackPro
11
11
  ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
12
12
  ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
13
13
 
14
- runner = new(KnapsackPro::Adapters::RSpecAdapter)
14
+ adapter_class = KnapsackPro::Adapters::RSpecAdapter
15
+ runner = new(adapter_class)
15
16
 
16
17
  cli_args = (args || '').split
17
- # if user didn't provide the format then use explicitly default progress formatter
18
- # in order to avoid KnapsackPro::Formatters::RSpecQueueSummaryFormatter being the only default formatter
19
- if !cli_args.any? { |arg| arg.start_with?('-f') || arg.start_with?('--format')}
20
- cli_args += ['--format', 'progress']
21
- end
18
+ adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
19
+
20
+ # when format option is not defined by user then use progress formatter to show tests execution progress
21
+ cli_args += ['--format', 'progress'] unless adapter_class.has_format_option?(cli_args)
22
+
22
23
  cli_args += [
24
+ # shows summary of all tests executed in Queue Mode at the very end
23
25
  '--format', KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s,
24
26
  '--default-path', runner.test_dir,
25
27
  ]
@@ -11,6 +11,9 @@ module KnapsackPro
11
11
  if runner.test_files_to_execute_exist?
12
12
  adapter_class.verify_bind_method_called
13
13
 
14
+ cli_args = (args || '').split
15
+ adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
16
+
14
17
  require 'rspec/core/rake_task'
15
18
 
16
19
  task_name = 'knapsack_pro:rspec_run'
@@ -13,7 +13,7 @@ module KnapsackPro
13
13
  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}]
14
14
 
15
15
  Kernel.system(cmd)
16
- Kernel.exit($?.exitstatus) unless $?.exitstatus.zero?
16
+ Kernel.exit(child_status.exitstatus) unless child_status.exitstatus.zero?
17
17
  end
18
18
  end
19
19
  end
@@ -11,21 +11,32 @@ module KnapsackPro
11
11
  if runner.test_files_to_execute_exist?
12
12
  adapter_class.verify_bind_method_called
13
13
 
14
- require 'test/unit'
15
-
16
14
  cli_args =
17
15
  (args || '').split +
18
16
  runner.test_file_paths.map do |f|
19
17
  File.expand_path(f)
20
18
  end
21
19
 
22
- exit ::Test::Unit::AutoRunner.run(
20
+ exit test_unit_autorunner_run(
23
21
  true,
24
22
  runner.test_dir,
25
23
  cli_args
26
24
  )
27
25
  end
28
26
  end
27
+
28
+ private
29
+
30
+ # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/AutoRunner#run-class_method
31
+ def self.test_unit_autorunner_run(force_standalone, default_dir, argv)
32
+ require 'test/unit'
33
+
34
+ ::Test::Unit::AutoRunner.run(
35
+ force_standalone,
36
+ default_dir,
37
+ argv
38
+ )
39
+ end
29
40
  end
30
41
  end
31
42
  end
@@ -19,13 +19,22 @@ module KnapsackPro
19
19
  end
20
20
 
21
21
  def start_timer
22
+ @start_time ||= now_without_mock_time.to_f
23
+ end
24
+
25
+ def reset_timer
22
26
  @start_time = now_without_mock_time.to_f
23
27
  end
24
28
 
25
29
  def stop_timer
26
30
  execution_time = @start_time ? now_without_mock_time.to_f - @start_time : 0.0
27
- update_global_time(execution_time)
28
- update_test_file_time(execution_time)
31
+
32
+ if @current_test_path
33
+ update_global_time(execution_time)
34
+ update_test_file_time(execution_time)
35
+ reset_timer
36
+ end
37
+
29
38
  execution_time
30
39
  end
31
40
 
@@ -63,7 +72,7 @@ module KnapsackPro
63
72
  def set_defaults
64
73
  @global_time = 0
65
74
  @test_files_with_time = {}
66
- @test_path = nil
75
+ @current_test_path = nil
67
76
  end
68
77
 
69
78
  def update_global_time(execution_time)
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '2.13.0'
2
+ VERSION = '2.18.0'
3
3
  end
@@ -12,6 +12,104 @@ describe KnapsackPro::Adapters::RSpecAdapter do
12
12
  it_behaves_like 'adapter'
13
13
  end
14
14
 
15
+ describe '.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!' do
16
+ let(:cli_args) { double }
17
+
18
+ subject { described_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args) }
19
+
20
+ before do
21
+ expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(rspec_split_by_test_examples_enabled)
22
+ end
23
+
24
+ context 'when RSpec split by test examples enabled' do
25
+ let(:rspec_split_by_test_examples_enabled) { true }
26
+
27
+ before do
28
+ expect(described_class).to receive(:has_tag_option?).with(cli_args).and_return(has_tag_option)
29
+ end
30
+
31
+ context 'when RSpec tag option is provided' do
32
+ let(:has_tag_option) { true }
33
+
34
+ it do
35
+ expect { subject }.to raise_error(/It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature/)
36
+ end
37
+ end
38
+
39
+ context 'when RSpec tag option is not provided' do
40
+ let(:has_tag_option) { false }
41
+
42
+ it 'does nothing' do
43
+ expect(subject).to be_nil
44
+ end
45
+ end
46
+ end
47
+
48
+ context 'when RSpec split by test examples disabled' do
49
+ let(:rspec_split_by_test_examples_enabled) { false }
50
+
51
+ it 'does nothing' do
52
+ expect(subject).to be_nil
53
+ end
54
+ end
55
+ end
56
+
57
+ describe '.has_tag_option?' do
58
+ subject { described_class.has_tag_option?(cli_args) }
59
+
60
+ context 'when tag option is provided as -t' do
61
+ let(:cli_args) { ['-t', 'mytag'] }
62
+
63
+ it { expect(subject).to be true }
64
+ end
65
+
66
+ context 'when tag option is provided as --tag' do
67
+ let(:cli_args) { ['--tag', 'mytag'] }
68
+
69
+ it { expect(subject).to be true }
70
+ end
71
+
72
+ context 'when tag option is provided without delimiter' do
73
+ let(:cli_args) { ['-tmytag'] }
74
+
75
+ it { expect(subject).to be true }
76
+ end
77
+
78
+ context 'when tag option is not provided' do
79
+ let(:cli_args) { ['--fake', 'value'] }
80
+
81
+ it { expect(subject).to be false }
82
+ end
83
+ end
84
+
85
+ describe '.has_format_option?' do
86
+ subject { described_class.has_format_option?(cli_args) }
87
+
88
+ context 'when format option is provided as -f' do
89
+ let(:cli_args) { ['-f', 'documentation'] }
90
+
91
+ it { expect(subject).to be true }
92
+ end
93
+
94
+ context 'when format option is provided as --format' do
95
+ let(:cli_args) { ['--format', 'documentation'] }
96
+
97
+ it { expect(subject).to be true }
98
+ end
99
+
100
+ context 'when format option is provided without delimiter' do
101
+ let(:cli_args) { ['-fd'] }
102
+
103
+ it { expect(subject).to be true }
104
+ end
105
+
106
+ context 'when format option is not provided' do
107
+ let(:cli_args) { ['--fake', 'value'] }
108
+
109
+ it { expect(subject).to be false }
110
+ end
111
+ end
112
+
15
113
  describe '.test_path' do
16
114
  let(:current_example_metadata) do
17
115
  {
@@ -86,20 +184,26 @@ describe KnapsackPro::Adapters::RSpecAdapter do
86
184
  end
87
185
 
88
186
  it 'records time for current test path' do
187
+ expect(config).to receive(:prepend_before).with(:context).and_yield
188
+
189
+ allow(KnapsackPro).to receive(:tracker).and_return(tracker)
190
+ expect(tracker).to receive(:start_timer).ordered
191
+
89
192
  expect(config).to receive(:around).with(:each).and_yield(example)
193
+ expect(config).to receive(:append_after).with(:context).and_yield
90
194
  expect(config).to receive(:after).with(:suite).and_yield
91
195
  expect(::RSpec).to receive(:configure).and_yield(config)
92
196
 
197
+ expect(tracker).to receive(:stop_timer).ordered
198
+
93
199
  expect(::RSpec).to receive(:current_example).twice.and_return(current_example)
94
200
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
95
201
 
96
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
97
- expect(tracker).to receive(:current_test_path=).with(test_path)
98
- expect(tracker).to receive(:start_timer)
202
+ expect(tracker).to receive(:current_test_path=).with(test_path).ordered
99
203
 
100
204
  expect(example).to receive(:run)
101
205
 
102
- expect(tracker).to receive(:stop_timer)
206
+ expect(tracker).to receive(:stop_timer).ordered
103
207
 
104
208
  expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
105
209
  expect(KnapsackPro).to receive(:logger).and_return(logger)
@@ -124,20 +228,26 @@ describe KnapsackPro::Adapters::RSpecAdapter do
124
228
  it 'records time for example.id' do
125
229
  expect(example).to receive(:id).and_return(test_example_path)
126
230
 
231
+ expect(config).to receive(:prepend_before).with(:context).and_yield
232
+
233
+ allow(KnapsackPro).to receive(:tracker).and_return(tracker)
234
+ expect(tracker).to receive(:start_timer).ordered
235
+
127
236
  expect(config).to receive(:around).with(:each).and_yield(example)
237
+ expect(config).to receive(:append_after).with(:context).and_yield
128
238
  expect(config).to receive(:after).with(:suite).and_yield
129
239
  expect(::RSpec).to receive(:configure).and_yield(config)
130
240
 
241
+ expect(tracker).to receive(:stop_timer).ordered
242
+
131
243
  expect(::RSpec).to receive(:current_example).twice.and_return(current_example)
132
244
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
133
245
 
134
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
135
- expect(tracker).to receive(:current_test_path=).with(test_example_path)
136
- expect(tracker).to receive(:start_timer)
246
+ expect(tracker).to receive(:current_test_path=).with(test_example_path).ordered
137
247
 
138
248
  expect(example).to receive(:run)
139
249
 
140
- expect(tracker).to receive(:stop_timer)
250
+ expect(tracker).to receive(:stop_timer).ordered
141
251
 
142
252
  expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
143
253
  expect(KnapsackPro).to receive(:logger).and_return(logger)
@@ -153,20 +263,26 @@ describe KnapsackPro::Adapters::RSpecAdapter do
153
263
  end
154
264
 
155
265
  it 'records time for current test path' do
266
+ expect(config).to receive(:prepend_before).with(:context).and_yield
267
+
268
+ allow(KnapsackPro).to receive(:tracker).and_return(tracker)
269
+ expect(tracker).to receive(:start_timer).ordered
270
+
156
271
  expect(config).to receive(:around).with(:each).and_yield(example)
272
+ expect(config).to receive(:append_after).with(:context).and_yield
157
273
  expect(config).to receive(:after).with(:suite).and_yield
158
274
  expect(::RSpec).to receive(:configure).and_yield(config)
159
275
 
160
276
  expect(::RSpec).to receive(:current_example).twice.and_return(current_example)
161
277
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
162
278
 
163
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
164
- expect(tracker).to receive(:current_test_path=).with(test_path)
165
- expect(tracker).to receive(:start_timer)
279
+ expect(tracker).to receive(:stop_timer).ordered
280
+
281
+ expect(tracker).to receive(:current_test_path=).with(test_path).ordered
166
282
 
167
283
  expect(example).to receive(:run)
168
284
 
169
- expect(tracker).to receive(:stop_timer)
285
+ expect(tracker).to receive(:stop_timer).ordered
170
286
 
171
287
  expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
172
288
  expect(KnapsackPro).to receive(:logger).and_return(logger)
@@ -1,4 +1,11 @@
1
- require 'test/unit/testcase'
1
+ # fake class to make tests pass and to avoid require 'test/unit/testcase' to not break RSpec
2
+ # https://www.rubydoc.info/gems/test-unit/3.4.1/Test/Unit/TestSuite
3
+ module Test
4
+ module Unit
5
+ class TestSuite
6
+ end
7
+ end
8
+ end
2
9
 
3
10
  describe KnapsackPro::Adapters::TestUnitAdapter do
4
11
  it do
@@ -75,9 +75,9 @@ describe KnapsackPro::Config::CI::Circle do
75
75
  describe '#project_dir' do
76
76
  subject { described_class.new.project_dir }
77
77
 
78
- context 'when environment exists' do
79
- let(:env) { { 'CIRCLE_PROJECT_REPONAME' => 'knapsack_pro-ruby' } }
80
- it { should eql '/home/ubuntu/knapsack_pro-ruby' }
78
+ context 'when CIRCLE_WORKING_DIRECTORY environment variable exists' do
79
+ let(:env) { { 'CIRCLE_WORKING_DIRECTORY' => '~/knapsack_pro-ruby' } }
80
+ it { should eql '~/knapsack_pro-ruby' }
81
81
  end
82
82
 
83
83
  context "when environment doesn't exist" do
@@ -15,20 +15,20 @@ describe KnapsackPro::RepositoryAdapters::GitAdapter do
15
15
 
16
16
  it { should_not be_nil }
17
17
  its(:size) { should eq 40 }
18
- it { should eq circle_sha1 } if ENV['CIRCLE_SHA1']
18
+ it { should eq circle_sha1 } if ENV['CIRCLECI']
19
19
  end
20
20
 
21
21
  describe '#branch' do
22
22
  subject { described_class.new.branch }
23
23
 
24
24
  it { should_not be_nil }
25
- it { should eq circle_branch } if ENV['CIRCLE_BRANCH']
25
+ it { should eq circle_branch } if ENV['CIRCLECI']
26
26
  end
27
27
 
28
28
  describe '#branches' do
29
29
  subject { described_class.new.branches }
30
30
 
31
31
  it { expect(subject.include?('master')).to be true }
32
- it { expect(subject.include?(circle_branch)).to be true } if ENV['CIRCLE_BRANCH']
32
+ it { expect(subject.include?(circle_branch)).to be true } if ENV['CIRCLECI']
33
33
  end
34
34
  end
@@ -100,6 +100,7 @@ describe KnapsackPro::Runners::Queue::CucumberRunner do
100
100
 
101
101
  context 'when test files exist' do
102
102
  let(:test_file_paths) { ['features/a.feature', 'features/b.feature'] }
103
+ let(:child_status) { double }
103
104
 
104
105
  before do
105
106
  subset_queue_id = 'fake-subset-queue-id'
@@ -117,8 +118,9 @@ describe KnapsackPro::Runners::Queue::CucumberRunner do
117
118
 
118
119
  expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED', 'true')
119
120
 
120
- expect($?).to receive(:exited?).and_return(process_exited)
121
- allow($?).to receive(:exitstatus).and_return(exitstatus)
121
+ allow(described_class).to receive(:child_status).and_return(child_status)
122
+ expect(child_status).to receive(:exited?).and_return(process_exited)
123
+ allow(child_status).to receive(:exitstatus).and_return(exitstatus)
122
124
  end
123
125
 
124
126
  context 'when system process finished its work (exited)' do
@@ -30,7 +30,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
30
30
  end
31
31
 
32
32
  context 'when args provided' do
33
- context 'when format param is not provided' do
33
+ context 'when format option is not provided' do
34
34
  let(:args) { '--example-arg example-value' }
35
35
 
36
36
  it 'uses default formatter progress' do
@@ -55,10 +55,10 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
55
55
  end
56
56
  end
57
57
 
58
- context 'when format param is provided as --format' do
58
+ context 'when format option is provided as --format' do
59
59
  let(:args) { '--format documentation' }
60
60
 
61
- it 'uses provided format param instead of default formatter progress' do
61
+ it 'uses provided format option instead of default formatter progress' do
62
62
  expected_exitstatus = 0
63
63
  expected_accumulator = {
64
64
  status: :completed,
@@ -80,10 +80,10 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
80
80
  end
81
81
  end
82
82
 
83
- context 'when format param is provided as -f' do
83
+ context 'when format option is provided as -f' do
84
84
  let(:args) { '-f d' }
85
85
 
86
- it 'uses provided format param instead of default formatter progress' do
86
+ it 'uses provided format option instead of default formatter progress' do
87
87
  expected_exitstatus = 0
88
88
  expected_accumulator = {
89
89
  status: :completed,
@@ -105,10 +105,10 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
105
105
  end
106
106
  end
107
107
 
108
- context 'when format param is provided without a delimiter' do
108
+ context 'when format option is provided without a delimiter' do
109
109
  let(:args) { '-fMyCustomFormatter' }
110
110
 
111
- it 'uses provided format param instead of default formatter progress' do
111
+ it 'uses provided format option instead of default formatter progress' do
112
112
  expected_exitstatus = 0
113
113
  expected_accumulator = {
114
114
  status: :completed,
@@ -129,6 +129,21 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
129
129
  subject
130
130
  end
131
131
  end
132
+
133
+ context 'when RSpec split by test examples feature is enabled' do
134
+ before do
135
+ expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(true)
136
+ expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!).and_call_original
137
+ end
138
+
139
+ context 'when tag option is provided' do
140
+ let(:args) { '--tag example-value' }
141
+
142
+ it do
143
+ expect { subject }.to raise_error(/It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature/)
144
+ end
145
+ end
146
+ end
132
147
  end
133
148
 
134
149
  context 'when args not provided' do
@@ -34,7 +34,8 @@ describe KnapsackPro::Runners::RSpecRunner do
34
34
  let(:task) { double }
35
35
 
36
36
  before do
37
- expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:verify_bind_method_called)
37
+ expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:verify_bind_method_called).ordered
38
+ expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!).with(['--profile', '--color']).ordered
38
39
 
39
40
  expect(Rake::Task).to receive(:[]).with('knapsack_pro:rspec_run').at_least(1).and_return(task)
40
41
 
@@ -44,7 +45,7 @@ describe KnapsackPro::Runners::RSpecRunner do
44
45
  expect(t).to receive(:pattern=).with([])
45
46
  end
46
47
 
47
- context 'when task already exists' do
48
+ context 'when rake task already exists' do
48
49
  before do
49
50
  expect(Rake::Task).to receive(:task_defined?).with('knapsack_pro:rspec_run').and_return(true)
50
51
  expect(task).to receive(:clear)
@@ -57,7 +58,7 @@ describe KnapsackPro::Runners::RSpecRunner do
57
58
  end
58
59
  end
59
60
 
60
- context "when task doesn't exist" do
61
+ context "when rake task doesn't exist" do
61
62
  before do
62
63
  expect(Rake::Task).to receive(:task_defined?).with('knapsack_pro:rspec_run').and_return(false)
63
64
  expect(task).not_to receive(:clear)
@@ -24,11 +24,14 @@ describe KnapsackPro::Runners::SpinachRunner do
24
24
  stringify_test_file_paths: stringify_test_file_paths,
25
25
  test_files_to_execute_exist?: true)
26
26
  end
27
+ let(:child_status) { double }
27
28
 
28
29
  before do
29
30
  expect(KnapsackPro::Adapters::SpinachAdapter).to receive(:verify_bind_method_called)
30
31
 
31
32
  expect(Kernel).to receive(:system).with('KNAPSACK_PRO_RECORDING_ENABLED=true KNAPSACK_PRO_TEST_SUITE_TOKEN=spinach-token bundle exec spinach --custom-arg --features_path fake-test-dir -- features/a.feature features/b.feature')
33
+
34
+ allow(described_class).to receive(:child_status).and_return(child_status)
32
35
  end
33
36
 
34
37
  after { subject }
@@ -37,7 +40,7 @@ describe KnapsackPro::Runners::SpinachRunner do
37
40
  let(:exitstatus) { 0 }
38
41
 
39
42
  before do
40
- expect($?).to receive(:exitstatus).and_return(exitstatus)
43
+ expect(child_status).to receive(:exitstatus).and_return(exitstatus)
41
44
  end
42
45
 
43
46
  it do
@@ -49,7 +52,7 @@ describe KnapsackPro::Runners::SpinachRunner do
49
52
  let(:exitstatus) { 1 }
50
53
 
51
54
  before do
52
- expect($?).to receive(:exitstatus).twice.and_return(exitstatus)
55
+ expect(child_status).to receive(:exitstatus).twice.and_return(exitstatus)
53
56
  end
54
57
 
55
58
  it do
@@ -1,5 +1,3 @@
1
- require 'test/unit'
2
-
3
1
  describe KnapsackPro::Runners::TestUnitRunner do
4
2
  subject { described_class.new(KnapsackPro::Adapters::TestUnitAdapter) }
5
3
 
@@ -27,7 +25,7 @@ describe KnapsackPro::Runners::TestUnitRunner do
27
25
  .with(KnapsackPro::Adapters::TestUnitAdapter).and_return(runner)
28
26
 
29
27
  auto_runner_exit_code = 0
30
- expect(Test::Unit::AutoRunner).to receive(:run) do |flag, test_dir, cli_args|
28
+ expect(described_class).to receive(:test_unit_autorunner_run) do |flag, test_dir, cli_args|
31
29
  expect(flag).to be true
32
30
  expect(test_dir).to eq 'test-unit_fake'
33
31
  expect(cli_args.size).to eq 4
@@ -95,10 +95,12 @@ describe KnapsackPro::Tracker do
95
95
  end
96
96
  end
97
97
 
98
- it { expect(tracker.global_time).to eq 0 }
98
+ it { expect(tracker.global_time).to be > 0 }
99
99
  it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
100
100
  it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to eq 0 }
101
- it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to eq 0 }
101
+ it '2nd spec (b_spec.rb) should have recorded time execution - because start_time was set during first call of stop_timer for the first spec (a_spec.rb)' do
102
+ expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be > 0
103
+ end
102
104
  it_behaves_like '#to_a'
103
105
  end
104
106
  end
data/spec/spec_helper.rb CHANGED
@@ -4,9 +4,6 @@ require 'spinach'
4
4
  require 'timecop'
5
5
  Timecop.safe_mode = true
6
6
 
7
- require 'codeclimate-test-reporter'
8
- CodeClimate::TestReporter.start
9
-
10
7
  require 'vcr'
11
8
  require 'webmock/rspec'
12
9
  VCR.configure do |config|
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: 2.13.0
4
+ version: 2.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-13 00:00:00.000000000 Z
11
+ date: 2021-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -42,36 +42,36 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 2.10.0
48
45
  - - "~>"
49
46
  - !ruby/object:Gem::Version
50
47
  version: '3.0'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 2.10.0
51
51
  type: :development
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: 2.10.0
58
55
  - - "~>"
59
56
  - !ruby/object:Gem::Version
60
57
  version: '3.0'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 2.10.0
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rspec-its
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '1.2'
67
+ version: '1.3'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '1.2'
74
+ version: '1.3'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: cucumber
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -128,20 +128,6 @@ dependencies:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
130
  version: 3.0.0
131
- - !ruby/object:Gem::Dependency
132
- name: codeclimate-test-reporter
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: '0'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: '0'
145
131
  - !ruby/object:Gem::Dependency
146
132
  name: pry
147
133
  requirement: !ruby/object:Gem::Requirement
@@ -160,44 +146,44 @@ dependencies:
160
146
  name: vcr
161
147
  requirement: !ruby/object:Gem::Requirement
162
148
  requirements:
163
- - - "~>"
149
+ - - ">="
164
150
  - !ruby/object:Gem::Version
165
- version: '2.9'
151
+ version: '6.0'
166
152
  type: :development
167
153
  prerelease: false
168
154
  version_requirements: !ruby/object:Gem::Requirement
169
155
  requirements:
170
- - - "~>"
156
+ - - ">="
171
157
  - !ruby/object:Gem::Version
172
- version: '2.9'
158
+ version: '6.0'
173
159
  - !ruby/object:Gem::Dependency
174
160
  name: webmock
175
161
  requirement: !ruby/object:Gem::Requirement
176
162
  requirements:
177
- - - "~>"
163
+ - - ">="
178
164
  - !ruby/object:Gem::Version
179
- version: '1.21'
165
+ version: '3.13'
180
166
  type: :development
181
167
  prerelease: false
182
168
  version_requirements: !ruby/object:Gem::Requirement
183
169
  requirements:
184
- - - "~>"
170
+ - - ">="
185
171
  - !ruby/object:Gem::Version
186
- version: '1.21'
172
+ version: '3.13'
187
173
  - !ruby/object:Gem::Dependency
188
174
  name: timecop
189
175
  requirement: !ruby/object:Gem::Requirement
190
176
  requirements:
191
177
  - - ">="
192
178
  - !ruby/object:Gem::Version
193
- version: 0.1.0
179
+ version: 0.9.4
194
180
  type: :development
195
181
  prerelease: false
196
182
  version_requirements: !ruby/object:Gem::Requirement
197
183
  requirements:
198
184
  - - ">="
199
185
  - !ruby/object:Gem::Version
200
- version: 0.1.0
186
+ version: 0.9.4
201
187
  description: Run tests in parallel across CI server nodes based on tests execution
202
188
  time. Split tests in a dynamic way to ensure parallel jobs are done at a similar
203
189
  time. Thanks to that your CI build time is as fast as possible. It works with many
@@ -423,7 +409,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
423
409
  - !ruby/object:Gem::Version
424
410
  version: '0'
425
411
  requirements: []
426
- rubygems_version: 3.0.6
412
+ rubygems_version: 3.2.15
427
413
  signing_key:
428
414
  specification_version: 4
429
415
  summary: Knapsack Pro splits tests across parallel CI nodes and ensures each parallel