knapsack_pro 5.5.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +5 -1
  3. data/CHANGELOG.md +20 -0
  4. data/lib/knapsack_pro/adapters/base_adapter.rb +10 -0
  5. data/lib/knapsack_pro/adapters/cucumber_adapter.rb +2 -0
  6. data/lib/knapsack_pro/adapters/minitest_adapter.rb +2 -0
  7. data/lib/knapsack_pro/adapters/rspec_adapter.rb +31 -0
  8. data/lib/knapsack_pro/adapters/spinach_adapter.rb +2 -0
  9. data/lib/knapsack_pro/adapters/test_unit_adapter.rb +2 -0
  10. data/lib/knapsack_pro/allocator.rb +2 -0
  11. data/lib/knapsack_pro/allocator_builder.rb +2 -0
  12. data/lib/knapsack_pro/base_allocator_builder.rb +8 -25
  13. data/lib/knapsack_pro/build_distribution_fetcher.rb +2 -0
  14. data/lib/knapsack_pro/client/api/action.rb +2 -0
  15. data/lib/knapsack_pro/client/api/v1/base.rb +2 -0
  16. data/lib/knapsack_pro/client/api/v1/build_distributions.rb +2 -0
  17. data/lib/knapsack_pro/client/api/v1/build_subsets.rb +2 -0
  18. data/lib/knapsack_pro/client/api/v1/queues.rb +2 -0
  19. data/lib/knapsack_pro/client/connection.rb +2 -0
  20. data/lib/knapsack_pro/config/ci/app_veyor.rb +2 -0
  21. data/lib/knapsack_pro/config/ci/base.rb +2 -0
  22. data/lib/knapsack_pro/config/ci/buildkite.rb +2 -0
  23. data/lib/knapsack_pro/config/ci/circle.rb +2 -0
  24. data/lib/knapsack_pro/config/ci/cirrus_ci.rb +2 -0
  25. data/lib/knapsack_pro/config/ci/codefresh.rb +2 -0
  26. data/lib/knapsack_pro/config/ci/codeship.rb +2 -0
  27. data/lib/knapsack_pro/config/ci/github_actions.rb +2 -0
  28. data/lib/knapsack_pro/config/ci/gitlab_ci.rb +2 -0
  29. data/lib/knapsack_pro/config/ci/heroku.rb +2 -0
  30. data/lib/knapsack_pro/config/ci/semaphore.rb +2 -0
  31. data/lib/knapsack_pro/config/ci/semaphore2.rb +2 -0
  32. data/lib/knapsack_pro/config/ci/travis.rb +2 -0
  33. data/lib/knapsack_pro/config/env.rb +2 -0
  34. data/lib/knapsack_pro/config/env_generator.rb +2 -0
  35. data/lib/knapsack_pro/config/temp_files.rb +8 -4
  36. data/lib/knapsack_pro/crypto/branch_encryptor.rb +2 -0
  37. data/lib/knapsack_pro/crypto/decryptor.rb +2 -0
  38. data/lib/knapsack_pro/crypto/digestor.rb +2 -0
  39. data/lib/knapsack_pro/crypto/encryptor.rb +2 -0
  40. data/lib/knapsack_pro/extensions/time.rb +2 -0
  41. data/lib/knapsack_pro/formatters/rspec_json_formatter.rb +2 -0
  42. data/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb +2 -0
  43. data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +2 -0
  44. data/lib/knapsack_pro/hooks/queue.rb +2 -0
  45. data/lib/knapsack_pro/logger_wrapper.rb +2 -0
  46. data/lib/knapsack_pro/mask_string.rb +2 -0
  47. data/lib/knapsack_pro/presenter.rb +2 -0
  48. data/lib/knapsack_pro/queue_allocator.rb +2 -0
  49. data/lib/knapsack_pro/queue_allocator_builder.rb +2 -0
  50. data/lib/knapsack_pro/railtie.rb +2 -0
  51. data/lib/knapsack_pro/report.rb +2 -0
  52. data/lib/knapsack_pro/repository_adapter_initiator.rb +2 -0
  53. data/lib/knapsack_pro/repository_adapters/base_adapter.rb +2 -0
  54. data/lib/knapsack_pro/repository_adapters/env_adapter.rb +2 -0
  55. data/lib/knapsack_pro/repository_adapters/git_adapter.rb +2 -0
  56. data/lib/knapsack_pro/runners/base_runner.rb +2 -0
  57. data/lib/knapsack_pro/runners/cucumber_runner.rb +2 -0
  58. data/lib/knapsack_pro/runners/minitest_runner.rb +2 -0
  59. data/lib/knapsack_pro/runners/queue/base_runner.rb +2 -0
  60. data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +2 -0
  61. data/lib/knapsack_pro/runners/queue/minitest_runner.rb +2 -0
  62. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +2 -0
  63. data/lib/knapsack_pro/runners/rspec_runner.rb +2 -0
  64. data/lib/knapsack_pro/runners/spinach_runner.rb +2 -0
  65. data/lib/knapsack_pro/runners/test_unit_runner.rb +2 -0
  66. data/lib/knapsack_pro/slow_test_file_determiner.rb +2 -0
  67. data/lib/knapsack_pro/slow_test_file_finder.rb +2 -0
  68. data/lib/knapsack_pro/task_loader.rb +2 -0
  69. data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +2 -0
  70. data/lib/knapsack_pro/test_case_mergers/base_merger.rb +2 -0
  71. data/lib/knapsack_pro/test_case_mergers/rspec_merger.rb +2 -0
  72. data/lib/knapsack_pro/test_file_cleaner.rb +2 -0
  73. data/lib/knapsack_pro/test_file_finder.rb +2 -0
  74. data/lib/knapsack_pro/test_file_pattern.rb +2 -0
  75. data/lib/knapsack_pro/test_file_presenter.rb +2 -0
  76. data/lib/knapsack_pro/test_files_with_test_cases_composer.rb +2 -0
  77. data/lib/knapsack_pro/test_flat_distributor.rb +2 -0
  78. data/lib/knapsack_pro/tracker.rb +2 -0
  79. data/lib/knapsack_pro/utils.rb +2 -0
  80. data/lib/knapsack_pro/version.rb +3 -1
  81. data/lib/knapsack_pro.rb +2 -0
  82. data/lib/tasks/cucumber.rake +2 -0
  83. data/lib/tasks/encrypted_branch_names.rake +2 -0
  84. data/lib/tasks/encrypted_test_file_names.rake +2 -0
  85. data/lib/tasks/minitest.rake +2 -0
  86. data/lib/tasks/queue/cucumber.rake +2 -0
  87. data/lib/tasks/queue/minitest.rake +2 -0
  88. data/lib/tasks/queue/rspec.rake +2 -0
  89. data/lib/tasks/rspec.rake +2 -0
  90. data/lib/tasks/salt.rake +2 -0
  91. data/lib/tasks/spinach.rake +2 -0
  92. data/lib/tasks/test_unit.rake +2 -0
  93. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +12 -0
  94. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +75 -0
  95. data/spec/knapsack_pro/base_allocator_builder_spec.rb +22 -48
  96. data/spec/knapsack_pro/client/connection_spec.rb +54 -7
  97. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 792df8662b070a5352ff707690d0ea394a938787a2656856aa5e8a4098954765
4
- data.tar.gz: 668a573e3cda8c09b99013d8c2b9ea962e13abc1febc0e88bd8613daf7341bd3
3
+ metadata.gz: 87b8a5c7eb2a78f487c9029cdeda3a1cc367b15e248eb1f3b5aaaf1959ebe333
4
+ data.tar.gz: 12fef31bb8aac248014b3d808190f7f2e7ae6217e83e4af9e40b17b6f98ed379
5
5
  SHA512:
6
- metadata.gz: 1bdd45d85651fc9528a45f9f8604accce2abc04788d0c81809617ce30319901020decb75bdb164cccda7e70fcc9de09c5d08fde4693420684100a502dc5d7bd0
7
- data.tar.gz: 8c500895bf104fdde5e0817e55a30c2d3d54f3020e19039e291fe6dde836f9ede1e5dc5371c91b1413d23fc2fec998242bae539dbade17c21d08bb05a7d87cb5
6
+ metadata.gz: 43379ac46ef1c5fa6a3fccf0d598831e009564ba37bdb264c681799aa893d5a9d8fbb569ce2bd83fe297b9c885117e95a5439731fd16ea35aa2f294acb88d936
7
+ data.tar.gz: 1be1143ac276347a0dee92bb15b7660f36b666c9cb8d025e9b1931f463803f9efc2a38ced34d4ca27bbfaa466fc1b6afc71d2960ced12b09888ca09a6572b14b
data/.circleci/config.yml CHANGED
@@ -30,10 +30,14 @@ jobs:
30
30
  command: |
31
31
  bundle install --jobs=4 --retry=3 --path vendor/bundle
32
32
 
33
+ - run: gem install rubocop
34
+
33
35
  - save_cache:
34
36
  paths:
35
37
  - ./vendor/bundle
36
38
  key: v2-dependencies-bundler-{{ checksum "knapsack_pro.gemspec" }}
37
39
 
38
- # run tests!
40
+ # enforce `frozen_string_literal: true` in the gem files
41
+ - run: rubocop -A --only Style/FrozenStringLiteralComment,Layout/EmptyLineAfterMagicComment lib/
42
+
39
43
  - run: bundle exec rspec spec
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ### 5.7.0
4
+
5
+ * Performance improvement: don't run `rake knapsack_pro:rspec_test_example_detector` when no slow test files are detected for RSpec.
6
+
7
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/225
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v5.6.0...v5.7.0
10
+
11
+ ### 5.6.0
12
+
13
+ * Use `frozen_string_literal: true` to reduce memory usage
14
+
15
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/220
16
+
17
+ * Enforce `frozen_string_literal: true` in the gem files with Rubocop
18
+
19
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/222
20
+
21
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v5.5.0...v5.6.0
22
+
3
23
  ### 5.5.0
4
24
 
5
25
  * Detect user seats for AppVeyor, Codefresh, Codeship
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Adapters
3
5
  class BaseAdapter
@@ -9,6 +11,14 @@ module KnapsackPro
9
11
  "#{KnapsackPro::Config::TempFiles::TEMP_DIRECTORY_PATH}/#{adapter_name}-bind_method_called_for_node_#{KnapsackPro::Config::Env.ci_node_index}.txt"
10
12
  end
11
13
 
14
+ def self.split_by_test_cases_enabled?
15
+ false
16
+ end
17
+
18
+ def self.test_file_cases_for(slow_test_files)
19
+ raise NotImplementedError
20
+ end
21
+
12
22
  def self.slow_test_file?(adapter_class, test_file_path)
13
23
  @slow_test_file_paths ||=
14
24
  begin
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Adapters
3
5
  class CucumberAdapter < BaseAdapter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Adapters
3
5
  class MinitestAdapter < BaseAdapter
@@ -1,8 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Adapters
3
5
  class RSpecAdapter < BaseAdapter
4
6
  TEST_DIR_PATTERN = 'spec/**{,/*/**}/*_spec.rb'
5
7
 
8
+ def self.split_by_test_cases_enabled?
9
+ return false unless KnapsackPro::Config::Env.rspec_split_by_test_examples?
10
+
11
+ require 'rspec/core/version'
12
+ unless Gem::Version.new(::RSpec::Core::Version::STRING) >= Gem::Version.new('3.3.0')
13
+ raise "RSpec >= 3.3.0 is required to split test files by test examples. Learn more: #{KnapsackPro::Urls::SPLIT_BY_TEST_EXAMPLES}"
14
+ end
15
+
16
+ true
17
+ end
18
+
19
+ def self.test_file_cases_for(slow_test_files)
20
+ KnapsackPro.logger.info("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual test cases). Thanks to that, a single slow test file can be split across parallel CI nodes. Analyzing #{slow_test_files.size} slow test files.")
21
+
22
+ # generate the RSpec JSON report in a separate process to not pollute the RSpec state
23
+ cmd = [
24
+ 'RACK_ENV=test',
25
+ 'RAILS_ENV=test',
26
+ KnapsackPro::Config::Env.rspec_test_example_detector_prefix,
27
+ 'rake knapsack_pro:rspec_test_example_detector',
28
+ ].join(' ')
29
+ unless Kernel.system(cmd)
30
+ raise "Could not generate JSON report for RSpec. Rake task failed when running #{cmd}"
31
+ end
32
+
33
+ # read the JSON report
34
+ KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector.new.test_file_example_paths
35
+ end
36
+
6
37
  def self.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
7
38
  if KnapsackPro::Config::Env.rspec_split_by_test_examples? && has_tag_option?(cli_args)
8
39
  error_message = "It is not allowed to use the RSpec tag option together with the RSpec split by test examples feature. Please see: #{KnapsackPro::Urls::RSPEC__SPLIT_BY_TEST_EXAMPLES__TAG}"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Adapters
3
5
  class SpinachAdapter < BaseAdapter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Adapters
3
5
  class TestUnitAdapter < BaseAdapter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class Allocator
3
5
  def initialize(args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class AllocatorBuilder < BaseAllocatorBuilder
3
5
  def allocator
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class BaseAllocatorBuilder
3
5
  TEST_RUNNER_MAP = {
@@ -33,35 +35,16 @@ module KnapsackPro
33
35
  def fast_and_slow_test_files_to_run
34
36
  test_files_to_run = all_test_files_to_run
35
37
 
36
- if adapter_class == KnapsackPro::Adapters::RSpecAdapter && KnapsackPro::Config::Env.rspec_split_by_test_examples?
37
- require 'rspec/core/version'
38
- unless Gem::Version.new(::RSpec::Core::Version::STRING) >= Gem::Version.new('3.3.0')
39
- raise "RSpec >= 3.3.0 is required to split test files by test examples. Learn more: #{KnapsackPro::Urls::SPLIT_BY_TEST_EXAMPLES}"
40
- end
41
-
38
+ if adapter_class.split_by_test_cases_enabled?
42
39
  slow_test_files = get_slow_test_files
40
+ return test_files_to_run if slow_test_files.empty?
43
41
 
44
- KnapsackPro.logger.info("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual 'it's. Thanks to that a single slow test file can be split across parallel CI nodes). Analyzing #{slow_test_files.size} slow test files.")
45
-
46
- # generate RSpec JSON report in separate process to not pollute RSpec state
47
- cmd = [
48
- 'RACK_ENV=test',
49
- 'RAILS_ENV=test',
50
- KnapsackPro::Config::Env.rspec_test_example_detector_prefix,
51
- 'rake knapsack_pro:rspec_test_example_detector',
52
- ].join(' ')
53
- unless Kernel.system(cmd)
54
- raise "Could not generate JSON report for RSpec. Rake task failed when running #{cmd}"
55
- end
56
-
57
- # read JSON report
58
- detector = KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector.new
59
- test_file_example_paths = detector.test_file_example_paths
42
+ test_file_cases = adapter_class.test_file_cases_for(slow_test_files)
60
43
 
61
- KnapsackPro::TestFilesWithTestCasesComposer.call(test_files_to_run, slow_test_files, test_file_example_paths)
62
- else
63
- test_files_to_run
44
+ return KnapsackPro::TestFilesWithTestCasesComposer.call(test_files_to_run, slow_test_files, test_file_cases)
64
45
  end
46
+
47
+ test_files_to_run
65
48
  end
66
49
 
67
50
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class BuildDistributionFetcher
3
5
  class BuildDistributionEntity
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Client
3
5
  module API
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Client
3
5
  module API
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Client
3
5
  module API
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Client
3
5
  module API
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Client
3
5
  module API
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Client
3
5
  class Connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # https://www.appveyor.com/docs/environment-variables/
2
4
  module KnapsackPro
3
5
  module Config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # https://codefresh.io/docs/docs/codefresh-yaml/variables/#system-provided-variables
2
4
  module KnapsackPro
3
5
  module Config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
2
4
  module KnapsackPro
3
5
  module Config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # https://docs.gitlab.com/ce/ci/variables/
2
4
  module KnapsackPro
3
5
  module Config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # https://docs.semaphoreci.com/article/12-environment-variables
2
4
  module KnapsackPro
3
5
  module Config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  module CI
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  class Env
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  class EnvGenerator
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Config
3
5
  class TempFiles
@@ -22,10 +24,12 @@ module KnapsackPro
22
24
  end
23
25
 
24
26
  def self.gitignore_file_content
25
- "# This directory is used by knapsack_pro gem for storing temporary files during tests runtime.\n" <<
26
- "# Ignore all files, and do not commit this directory into your repository.\n" <<
27
- "# Learn more at https://knapsackpro.com\n" <<
28
- "*"
27
+ <<~GITIGNORE
28
+ # This directory is used by knapsack_pro gem for storing temporary files during tests runtime.
29
+ # Ignore all files, and do not commit this directory into your repository.
30
+ # Learn more at https://knapsackpro.com
31
+ *
32
+ GITIGNORE
29
33
  end
30
34
 
31
35
  def self.create_gitignore_file!
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Crypto
3
5
  class BranchEncryptor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Crypto
3
5
  class Decryptor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Crypto
3
5
  class Digestor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Crypto
3
5
  class Encryptor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'time'
2
4
 
3
5
  class Time
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec::Support.require_rspec_core('formatters/json_formatter')
2
4
 
3
5
  # based on https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/formatters/json_formatter.rb
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec::Support.require_rspec_core('formatters/profile_formatter')
2
4
 
3
5
  module KnapsackPro
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec::Support.require_rspec_core('formatters/base_formatter')
2
4
  RSpec::Support.require_rspec_core('formatters/base_text_formatter')
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Hooks
3
5
  class Queue
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class LoggerWrapper
3
5
  def initialize(logger)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class MaskString
3
5
  def self.call(string)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class Presenter
3
5
  class << self
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class QueueAllocator
3
5
  def initialize(args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class QueueAllocatorBuilder < BaseAllocatorBuilder
3
5
  def allocator
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails'
2
4
  require 'knapsack_pro'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class Report
3
5
  def self.save
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class RepositoryAdapterInitiator
3
5
  def self.call
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module RepositoryAdapters
3
5
  class BaseAdapter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module RepositoryAdapters
3
5
  class EnvAdapter < BaseAdapter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module RepositoryAdapters
3
5
  class GitAdapter < BaseAdapter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  class BaseRunner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  class CucumberRunner < BaseRunner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  class MinitestRunner < BaseRunner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  module Queue
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  module Queue
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  module Queue
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  module Queue
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  class RSpecRunner < BaseRunner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  class SpinachRunner < BaseRunner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module Runners
3
5
  class TestUnitRunner < BaseRunner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class SlowTestFileDeterminer
3
5
  TIME_THRESHOLD_PER_CI_NODE = 0.7 # 70%
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class SlowTestFileFinder
3
5
  # Get recorded test files from API.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake'
2
4
 
3
5
  module KnapsackPro
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module TestCaseDetectors
3
5
  class RSpecTestExampleDetector
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module TestCaseMergers
3
5
  class BaseMerger
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  module TestCaseMergers
3
5
  class RSpecMerger < BaseMerger
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class TestFileCleaner
3
5
  def self.clean(test_file_path)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class TestFileFinder
3
5
  def self.call(test_file_pattern, test_file_list_enabled: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class TestFilePattern
3
5
  def self.call(adapter_class)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class TestFilePresenter
3
5
  def self.stringify_paths(test_file_paths)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class TestFilesWithTestCasesComposer
3
5
  # Args:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class TestFlatDistributor
3
5
  DIR_TYPES = [
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class Tracker
3
5
  include Singleton
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
4
  class Utils
3
5
  def self.unsymbolize(obj)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KnapsackPro
2
- VERSION = '5.5.0'
4
+ VERSION = '5.7.0'
3
5
  end
data/lib/knapsack_pro.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'logger'
2
4
  require 'singleton'
3
5
  require 'net/http'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
data/lib/tasks/rspec.rake CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
data/lib/tasks/salt.rake CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  namespace :knapsack_pro do
2
4
  task :salt, [:size] do |_, args|
3
5
  default_size = 32
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'knapsack_pro'
2
4
 
3
5
  namespace :knapsack_pro do
@@ -42,6 +42,18 @@ describe KnapsackPro::Adapters::BaseAdapter do
42
42
  end
43
43
  end
44
44
 
45
+ describe '.split_by_test_cases_enabled?' do
46
+ subject { described_class.split_by_test_cases_enabled? }
47
+
48
+ it { expect(subject).to be false }
49
+ end
50
+
51
+ describe '.test_file_cases_for' do
52
+ subject { described_class.test_file_cases_for([]) }
53
+
54
+ it { expect { subject }.to raise_error NotImplementedError }
55
+ end
56
+
45
57
  describe '.slow_test_file?' do
46
58
  let(:adapter_class) { double }
47
59
  let(:slow_test_files) do
@@ -12,6 +12,81 @@ describe KnapsackPro::Adapters::RSpecAdapter do
12
12
  it_behaves_like 'adapter'
13
13
  end
14
14
 
15
+ describe '.split_by_test_cases_enabled?' do
16
+ subject { described_class.split_by_test_cases_enabled? }
17
+
18
+ before do
19
+ expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(rspec_split_by_test_examples_enabled)
20
+ end
21
+
22
+ context 'when the RSpec split by test examples is enabled' do
23
+ let(:rspec_split_by_test_examples_enabled) { true }
24
+
25
+ it { expect(subject).to be true }
26
+
27
+ context 'when the RSpec version is < 3.3.0' do
28
+ before do
29
+ stub_const('RSpec::Core::Version::STRING', '3.2.0')
30
+ end
31
+
32
+ it do
33
+ expect { subject }.to raise_error RuntimeError, 'RSpec >= 3.3.0 is required to split test files by test examples. Learn more: https://knapsackpro.com/perma/ruby/split-by-test-examples'
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'when the RSpec split by test examples is disabled' do
39
+ let(:rspec_split_by_test_examples_enabled) { false }
40
+
41
+ it { expect(subject).to be false }
42
+ end
43
+ end
44
+
45
+ describe '.test_file_cases_for' do
46
+ let(:slow_test_files) do
47
+ [
48
+ '1_spec.rb',
49
+ '2_spec.rb',
50
+ '3_spec.rb',
51
+ '4_spec.rb',
52
+ '5_spec.rb',
53
+ ]
54
+ end
55
+
56
+ subject { described_class.test_file_cases_for(slow_test_files) }
57
+
58
+ before do
59
+ logger = instance_double(Logger)
60
+ expect(KnapsackPro).to receive(:logger).and_return(logger)
61
+ expect(logger).to receive(:info).with("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual test cases). Thanks to that, a single slow test file can be split across parallel CI nodes. Analyzing 5 slow test files.")
62
+
63
+ cmd = 'RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector'
64
+ expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
65
+ end
66
+
67
+ context 'when the rake task to detect RSpec test examples succeeded' do
68
+ let(:cmd_result) { true }
69
+
70
+ it 'returns test example paths for slow test files' do
71
+ rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
72
+ expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
73
+
74
+ test_file_example_paths = double
75
+ expect(rspec_test_example_detector).to receive(:test_file_example_paths).and_return(test_file_example_paths)
76
+
77
+ expect(subject).to eq test_file_example_paths
78
+ end
79
+ end
80
+
81
+ context 'when the rake task to detect RSpec test examples failed' do
82
+ let(:cmd_result) { false }
83
+
84
+ it do
85
+ expect { subject }.to raise_error(RuntimeError, 'Could not generate JSON report for RSpec. Rake task failed when running RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector')
86
+ end
87
+ end
88
+ end
89
+
15
90
  describe '.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!' do
16
91
  let(:cli_args) { double }
17
92
 
@@ -117,8 +117,8 @@ describe KnapsackPro::BaseAllocatorBuilder do
117
117
  describe '#fast_and_slow_test_files_to_run' do
118
118
  subject { allocator_builder.fast_and_slow_test_files_to_run }
119
119
 
120
- context 'when looking for test files on disk by default' do
121
- it do
120
+ context 'when split by test cases disabled' do
121
+ it 'returns test files to run based on test files on the disk' do
122
122
  test_file_pattern = double
123
123
  expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
124
124
 
@@ -129,70 +129,44 @@ describe KnapsackPro::BaseAllocatorBuilder do
129
129
  end
130
130
  end
131
131
 
132
- context 'when RSpec adapter AND rspec split by test examples is enabled' do
133
- let(:adapter_class) { KnapsackPro::Adapters::RSpecAdapter }
132
+ context 'when split by test cases enabled' do
134
133
  let(:test_files_to_run) { double }
135
- let(:cmd) { 'RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector' }
136
134
 
137
- before do
138
- expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(true)
135
+ before do
136
+ expect(adapter_class).to receive(:split_by_test_cases_enabled?).and_return(true)
139
137
 
140
138
  test_file_pattern = double
141
139
  expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
142
140
 
143
141
  expect(KnapsackPro::TestFileFinder).to receive(:call).with(test_file_pattern).and_return(test_files_to_run)
144
- end
145
142
 
146
- context 'when RSpec version < 3.3.0' do
147
- before do
148
- stub_const('RSpec::Core::Version::STRING', '3.2.0')
149
- end
150
-
151
- it do
152
- expect { subject }.to raise_error RuntimeError, 'RSpec >= 3.3.0 is required to split test files by test examples. Learn more: https://knapsackpro.com/perma/ruby/split-by-test-examples'
153
- end
143
+ expect(allocator_builder).to receive(:get_slow_test_files).and_return(slow_test_files)
154
144
  end
155
145
 
156
- context 'when rake task to detect RSpec test examples works' do
157
- let(:slow_test_files) { double(size: 5) }
158
- let(:cmd_result) { true }
159
- let(:test_file_example_paths) { double }
160
- let(:logger) { instance_double(Logger) }
161
- let(:test_files_with_test_cases) { double }
162
-
163
- before do
164
- expect(allocator_builder).to receive(:get_slow_test_files).and_return(slow_test_files)
165
-
166
- expect(KnapsackPro).to receive(:logger).and_return(logger)
167
-
168
- expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
169
-
170
- rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
171
- expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
172
- expect(rspec_test_example_detector).to receive(:test_file_example_paths).and_return(test_file_example_paths)
173
-
174
- expect(KnapsackPro::TestFilesWithTestCasesComposer).to receive(:call).with(test_files_to_run, slow_test_files, test_file_example_paths).and_return(test_files_with_test_cases)
146
+ context 'when slow test files are detected' do
147
+ let(:slow_test_files) do
148
+ [
149
+ '1_spec.rb',
150
+ '2_spec.rb',
151
+ ]
175
152
  end
176
153
 
177
- it do
178
- expect(logger).to receive(:info).with("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual 'it's. Thanks to that a single slow test file can be split across parallel CI nodes). Analyzing 5 slow test files.")
154
+ it 'returns test files with test cases' do
155
+ test_file_cases = double
156
+ expect(adapter_class).to receive(:test_file_cases_for).with(slow_test_files).and_return(test_file_cases)
157
+
158
+ test_files_with_test_cases = double
159
+ expect(KnapsackPro::TestFilesWithTestCasesComposer).to receive(:call).with(test_files_to_run, slow_test_files, test_file_cases).and_return(test_files_with_test_cases)
179
160
 
180
161
  expect(subject).to eq test_files_with_test_cases
181
162
  end
182
163
  end
183
164
 
184
- context 'when rake task to detect RSpec test examples failed' do
185
- let(:slow_test_files) { double(size: 5) }
186
- let(:cmd_result) { false }
187
-
188
- before do
189
- expect(allocator_builder).to receive(:get_slow_test_files).and_return(slow_test_files)
190
-
191
- expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
192
- end
165
+ context 'when slow test files are not detected' do
166
+ let(:slow_test_files) { [] }
193
167
 
194
- it do
195
- expect { subject }.to raise_error(RuntimeError, 'Could not generate JSON report for RSpec. Rake task failed when running RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector')
168
+ it 'returns test files without test cases' do
169
+ expect(subject).to eq test_files_to_run
196
170
  end
197
171
  end
198
172
  end
@@ -282,15 +282,17 @@ describe KnapsackPro::Client::Connection do
282
282
  request_hash: request_hash)
283
283
  end
284
284
  let(:test_suite_token) { '3fa64859337f6e56409d49f865d13fd7' }
285
-
286
285
  let(:connection) { described_class.new(action) }
287
-
288
- before do
289
- stub_const('ENV', {
286
+ let(:headers) do
287
+ {
290
288
  'KNAPSACK_PRO_ENDPOINT' => 'http://api.knapsackpro.test:3000',
291
289
  'KNAPSACK_PRO_TEST_SUITE_TOKEN' => test_suite_token,
292
290
  'GITHUB_ACTIONS' => 'true',
293
- })
291
+ }
292
+ end
293
+
294
+ before do
295
+ stub_const('ENV', headers)
294
296
  end
295
297
 
296
298
  describe '#call' do
@@ -311,7 +313,7 @@ describe KnapsackPro::Client::Connection do
311
313
  expect(http).to receive(:read_timeout=).with(15)
312
314
  end
313
315
 
314
- context 'when http method is POST' do
316
+ context 'when http method is POST on GitHub Actions' do
315
317
  let(:http_method) { :post }
316
318
 
317
319
  before do
@@ -334,7 +336,30 @@ describe KnapsackPro::Client::Connection do
334
336
  end
335
337
  end
336
338
 
337
- context 'when http method is GET' do
339
+ context 'when http method is POST and CI is undetected' do
340
+ let(:http_method) { :post }
341
+
342
+ let(:headers) do
343
+ {
344
+ 'KNAPSACK_PRO_ENDPOINT' => 'http://api.knapsackpro.test:3000',
345
+ 'KNAPSACK_PRO_TEST_SUITE_TOKEN' => test_suite_token,
346
+ }
347
+ end
348
+
349
+ before do
350
+ expect(http).to receive(:post).with(
351
+ anything,
352
+ anything,
353
+ hash_not_including('KNAPSACK-PRO-CI-PROVIDER')
354
+ ).and_return(http_response)
355
+ end
356
+
357
+ it_behaves_like 'when request got response from API' do
358
+ let(:expected_http_method) { 'POST' }
359
+ end
360
+ end
361
+
362
+ context 'when http method is GET on GitHub Actions' do
338
363
  let(:http_method) { :get }
339
364
 
340
365
  before do
@@ -358,6 +383,28 @@ describe KnapsackPro::Client::Connection do
358
383
  end
359
384
  end
360
385
 
386
+ context 'when http method is GET and CI is undetected' do
387
+ let(:http_method) { :get }
388
+
389
+ let(:headers) do
390
+ {
391
+ 'KNAPSACK_PRO_ENDPOINT' => 'http://api.knapsackpro.test:3000',
392
+ 'KNAPSACK_PRO_TEST_SUITE_TOKEN' => test_suite_token,
393
+ }
394
+ end
395
+
396
+ before do
397
+ expect(http).to receive(:get).with(
398
+ anything,
399
+ hash_not_including('KNAPSACK-PRO-CI-PROVIDER')
400
+ ).and_return(http_response)
401
+ end
402
+
403
+ it_behaves_like 'when request got response from API' do
404
+ let(:expected_http_method) { 'GET' }
405
+ end
406
+ end
407
+
361
408
  context 'when retry request for http method POST' do
362
409
  let(:http_method) { :post }
363
410
 
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: 5.5.0
4
+ version: 5.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-23 00:00:00.000000000 Z
11
+ date: 2023-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake