knapsack_pro 2.15.0 → 2.18.1

Sign up to get free protection for your applications and to get access to all the features.
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