knapsack_pro 2.15.0 → 2.18.1

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/CHANGELOG.md +32 -0
  4. data/README.md +5 -39
  5. data/knapsack_pro.gemspec +4 -5
  6. data/lib/knapsack_pro/adapters/rspec_adapter.rb +27 -0
  7. data/lib/knapsack_pro/base_allocator_builder.rb +1 -0
  8. data/lib/knapsack_pro/config/ci/circle.rb +1 -2
  9. data/lib/knapsack_pro/repository_adapters/git_adapter.rb +2 -1
  10. data/lib/knapsack_pro/runners/base_runner.rb +4 -0
  11. data/lib/knapsack_pro/runners/queue/base_runner.rb +4 -0
  12. data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +3 -5
  13. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +4 -21
  14. data/lib/knapsack_pro/runners/rspec_runner.rb +3 -0
  15. data/lib/knapsack_pro/runners/spinach_runner.rb +1 -1
  16. data/lib/knapsack_pro/runners/test_unit_runner.rb +14 -3
  17. data/lib/knapsack_pro/tracker.rb +8 -3
  18. data/lib/knapsack_pro/version.rb +1 -1
  19. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +116 -6
  20. data/spec/knapsack_pro/adapters/test_unit_adapter_spec.rb +8 -1
  21. data/spec/knapsack_pro/config/ci/circle_spec.rb +3 -3
  22. data/spec/knapsack_pro/repository_adapters/git_adapter_spec.rb +3 -3
  23. data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +4 -2
  24. data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +2 -17
  25. data/spec/knapsack_pro/runners/rspec_runner_spec.rb +4 -3
  26. data/spec/knapsack_pro/runners/spinach_runner_spec.rb +5 -2
  27. data/spec/knapsack_pro/runners/test_unit_runner_spec.rb +1 -3
  28. data/spec/knapsack_pro/tracker_spec.rb +7 -9
  29. data/spec/spec_helper.rb +0 -3
  30. metadata +21 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a97f9fbc29f0a109fbbf35b6a544f2ad86208feb697b7ff81f8458b679843c91
4
- data.tar.gz: 434871e67293512331dfe99ed7915eb0f96ae27d2a7b3a1023e8752c752455ac
3
+ metadata.gz: dfa70d9f5566c820f5ca45bc6c0dc52302ee7de056f4b50ad86739b3ca34960d
4
+ data.tar.gz: a5c877f7c89a4c94bbcd247a6fe75b8ff01a9e2be7f82b82fe4ac42dcdac489c
5
5
  SHA512:
6
- metadata.gz: 3d5be26f0d227707d789b5d7243f3617ea6f839154725b555f0ada89b6600aef0b18aaa2532d018344c797a1f79465e27d3caadebb955d1ca00684b08f1be4ea
7
- data.tar.gz: ddb85043aad801bbb9f47f51c36bace0c34b73f958968e821c7b2e8845cc0a302ef05d9e55033d260a86817d4a99d924084f8c29c86b87ce2c2a75fd96fef4af
6
+ metadata.gz: 390be4aa9a3bfa79da3149bbc7acdec09905aed17ddbac32998e7324cc23571bcb321e3ba541d3890df1993ab5a125c10edf5cfcf28f8568347ff96af8b18a94
7
+ data.tar.gz: 431ec87a1b9c17fb9e2c5dfde14d93118e0378731f6c70ff7fcb1ed4f74dcef773bd861be33d0d4327689d4d8fb9df333df59630f44c9be3212b3915f2ab5cd4
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,37 @@
1
1
  # Change Log
2
2
 
3
+ ### 2.18.1
4
+
5
+ * Ensure RSpec is loaded to check its version for RSpec split by test examples feature
6
+
7
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/151
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.18.0...v2.18.1
10
+
11
+ ### 2.18.0
12
+
13
+ * 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
14
+
15
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/148
16
+
17
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.17.0...v2.18.0
18
+
19
+ ### 2.17.0
20
+
21
+ * Use Ruby 3 in development and add small improvements
22
+
23
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/147
24
+
25
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.16.0...v2.17.0
26
+
27
+ ### 2.16.0
28
+
29
+ * Improve test time execution tracking for RSpec
30
+
31
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/145
32
+
33
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.15.0...v2.16.0
34
+
3
35
  ### 2.15.0
4
36
 
5
37
  * Do not allow to use the RSpec tag option together with the RSpec split by test examples feature
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]
@@ -26,6 +47,10 @@ module KnapsackPro
26
47
  end
27
48
 
28
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
+
29
54
  current_example_group =
30
55
  if ::RSpec.respond_to?(:current_example)
31
56
  ::RSpec.current_example.metadata[:example_group]
@@ -46,6 +71,8 @@ module KnapsackPro
46
71
  end
47
72
 
48
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
49
76
  KnapsackPro.tracker.stop_timer
50
77
  end
51
78
 
@@ -34,6 +34,7 @@ module KnapsackPro
34
34
  test_files_to_run = all_test_files_to_run
35
35
 
36
36
  if adapter_class == KnapsackPro::Adapters::RSpecAdapter && KnapsackPro::Config::Env.rspec_split_by_test_examples?
37
+ require 'rspec/core/version'
37
38
  unless Gem::Version.new(::RSpec::Core::Version::STRING) >= Gem::Version.new('3.3.0')
38
39
  raise 'RSpec >= 3.3.0 is required to split test files by test examples. Learn more: https://github.com/KnapsackPro/knapsack_pro-ruby#split-test-files-by-test-cases'
39
40
  end
@@ -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,18 +11,14 @@ 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
-
18
- if KnapsackPro::Config::Env.rspec_split_by_test_examples? && has_tag_option?(cli_args)
19
- 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'
20
- KnapsackPro.logger.error(error_message)
21
- raise error_message
22
- end
18
+ adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
23
19
 
24
20
  # when format option is not defined by user then use progress formatter to show tests execution progress
25
- cli_args += ['--format', 'progress'] unless has_format_option?(cli_args)
21
+ cli_args += ['--format', 'progress'] unless adapter_class.has_format_option?(cli_args)
26
22
 
27
23
  cli_args += [
28
24
  # shows summary of all tests executed in Queue Mode at the very end
@@ -154,19 +150,6 @@ module KnapsackPro
154
150
  ::RSpec.configuration.reset_filters
155
151
  end
156
152
  end
157
-
158
- def self.has_tag_option?(cli_args)
159
- # use start_with? because user can define tag option in a few ways:
160
- # -t mytag
161
- # -tmytag
162
- # --tag mytag
163
- # --tag=mytag
164
- cli_args.any? { |arg| arg.start_with?('-t') || arg.start_with?('--tag') }
165
- end
166
-
167
- def self.has_format_option?(cli_args)
168
- cli_args.any? { |arg| arg.start_with?('-f') || arg.start_with?('--format') }
169
- end
170
153
  end
171
154
  end
172
155
  end
@@ -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,23 +19,28 @@ 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
31
 
28
- if current_test_path
32
+ if @current_test_path
29
33
  update_global_time(execution_time)
30
34
  update_test_file_time(execution_time)
31
- @current_test_path = nil
35
+ reset_timer
32
36
  end
33
37
 
34
38
  execution_time
35
39
  end
36
40
 
37
41
  def current_test_path
38
- KnapsackPro::TestFileCleaner.clean(@current_test_path) if @current_test_path
42
+ raise("current_test_path needs to be set by Knapsack Pro Adapter's bind method") unless @current_test_path
43
+ KnapsackPro::TestFileCleaner.clean(@current_test_path)
39
44
  end
40
45
 
41
46
  def set_prerun_tests(test_file_paths)
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '2.15.0'
2
+ VERSION = '2.18.1'
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
  {
@@ -87,16 +185,20 @@ describe KnapsackPro::Adapters::RSpecAdapter do
87
185
 
88
186
  it 'records time for current test path' do
89
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
+
90
192
  expect(config).to receive(:around).with(:each).and_yield(example)
91
193
  expect(config).to receive(:append_after).with(:context).and_yield
92
194
  expect(config).to receive(:after).with(:suite).and_yield
93
195
  expect(::RSpec).to receive(:configure).and_yield(config)
94
196
 
197
+ expect(tracker).to receive(:stop_timer).ordered
198
+
95
199
  expect(::RSpec).to receive(:current_example).twice.and_return(current_example)
96
200
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
97
201
 
98
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
99
- expect(tracker).to receive(:start_timer).ordered
100
202
  expect(tracker).to receive(:current_test_path=).with(test_path).ordered
101
203
 
102
204
  expect(example).to receive(:run)
@@ -127,16 +229,20 @@ describe KnapsackPro::Adapters::RSpecAdapter do
127
229
  expect(example).to receive(:id).and_return(test_example_path)
128
230
 
129
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
+
130
236
  expect(config).to receive(:around).with(:each).and_yield(example)
131
237
  expect(config).to receive(:append_after).with(:context).and_yield
132
238
  expect(config).to receive(:after).with(:suite).and_yield
133
239
  expect(::RSpec).to receive(:configure).and_yield(config)
134
240
 
241
+ expect(tracker).to receive(:stop_timer).ordered
242
+
135
243
  expect(::RSpec).to receive(:current_example).twice.and_return(current_example)
136
244
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
137
245
 
138
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
139
- expect(tracker).to receive(:start_timer).ordered
140
246
  expect(tracker).to receive(:current_test_path=).with(test_example_path).ordered
141
247
 
142
248
  expect(example).to receive(:run)
@@ -158,6 +264,10 @@ describe KnapsackPro::Adapters::RSpecAdapter do
158
264
 
159
265
  it 'records time for current test path' do
160
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
+
161
271
  expect(config).to receive(:around).with(:each).and_yield(example)
162
272
  expect(config).to receive(:append_after).with(:context).and_yield
163
273
  expect(config).to receive(:after).with(:suite).and_yield
@@ -166,8 +276,8 @@ describe KnapsackPro::Adapters::RSpecAdapter do
166
276
  expect(::RSpec).to receive(:current_example).twice.and_return(current_example)
167
277
  expect(described_class).to receive(:test_path).with(example_group).and_return(test_path)
168
278
 
169
- allow(KnapsackPro).to receive(:tracker).and_return(tracker)
170
- expect(tracker).to receive(:start_timer).ordered
279
+ expect(tracker).to receive(:stop_timer).ordered
280
+
171
281
  expect(tracker).to receive(:current_test_path=).with(test_path).ordered
172
282
 
173
283
  expect(example).to receive(:run)
@@ -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
@@ -133,31 +133,16 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
133
133
  context 'when RSpec split by test examples feature is enabled' do
134
134
  before do
135
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
136
137
  end
137
138
 
138
- context 'when tag option is provided as --tag' do
139
+ context 'when tag option is provided' do
139
140
  let(:args) { '--tag example-value' }
140
141
 
141
142
  it do
142
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/)
143
144
  end
144
145
  end
145
-
146
- context 'when tag option is provided as -t' do
147
- let(:args) { '-t example-value' }
148
-
149
- it do
150
- expect { subject }.to raise_error(/It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature/)
151
- end
152
- end
153
-
154
- context 'when tag option is provided without delimiter' do
155
- let(:args) { '-texample-value' }
156
-
157
- it do
158
- expect { subject }.to raise_error(/It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature/)
159
- end
160
- end
161
146
  end
162
147
  end
163
148
 
@@ -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
@@ -12,7 +12,9 @@ describe KnapsackPro::Tracker do
12
12
  subject { tracker.current_test_path }
13
13
 
14
14
  context 'when current_test_path not set' do
15
- it { expect(subject).to be_nil }
15
+ it do
16
+ expect { subject }.to raise_error("current_test_path needs to be set by Knapsack Pro Adapter's bind method")
17
+ end
16
18
  end
17
19
 
18
20
  context 'when current_test_path set' do
@@ -56,9 +58,6 @@ describe KnapsackPro::Tracker do
56
58
  it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
57
59
  it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0.1) }
58
60
  it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0.2) }
59
- it 'resets current_test_path after time is measured' do
60
- expect(tracker.current_test_path).to be_nil
61
- end
62
61
  it_behaves_like '#to_a'
63
62
  end
64
63
 
@@ -84,9 +83,6 @@ describe KnapsackPro::Tracker do
84
83
  it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
85
84
  it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0) }
86
85
  it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0) }
87
- it 'resets current_test_path after time is measured' do
88
- expect(tracker.current_test_path).to be_nil
89
- end
90
86
  it_behaves_like '#to_a'
91
87
  end
92
88
 
@@ -99,10 +95,12 @@ describe KnapsackPro::Tracker do
99
95
  end
100
96
  end
101
97
 
102
- it { expect(tracker.global_time).to eq 0 }
98
+ it { expect(tracker.global_time).to be > 0 }
103
99
  it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
104
100
  it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to eq 0 }
105
- 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
106
104
  it_behaves_like '#to_a'
107
105
  end
108
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.15.0
4
+ version: 2.18.1
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-20 00:00:00.000000000 Z
11
+ date: 2021-07-22 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