knapsack_pro 1.20.2 → 1.22.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/README.md +43 -18
  4. data/lib/knapsack_pro.rb +6 -0
  5. data/lib/knapsack_pro/adapters/base_adapter.rb +16 -0
  6. data/lib/knapsack_pro/adapters/rspec_adapter.rb +11 -9
  7. data/lib/knapsack_pro/allocator.rb +7 -5
  8. data/lib/knapsack_pro/allocator_builder.rb +2 -1
  9. data/lib/knapsack_pro/base_allocator_builder.rb +41 -10
  10. data/lib/knapsack_pro/build_distribution_fetcher.rb +57 -0
  11. data/lib/knapsack_pro/client/api/v1/build_distributions.rb +13 -0
  12. data/lib/knapsack_pro/client/connection.rb +38 -16
  13. data/lib/knapsack_pro/config/env.rb +4 -0
  14. data/lib/knapsack_pro/queue_allocator.rb +7 -5
  15. data/lib/knapsack_pro/queue_allocator_builder.rb +2 -1
  16. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +8 -1
  17. data/lib/knapsack_pro/runners/rspec_runner.rb +5 -2
  18. data/lib/knapsack_pro/slow_test_file_determiner.rb +33 -0
  19. data/lib/knapsack_pro/slow_test_file_finder.rb +27 -0
  20. data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +26 -7
  21. data/lib/knapsack_pro/test_case_mergers/base_merger.rb +29 -0
  22. data/lib/knapsack_pro/test_case_mergers/rspec_merger.rb +34 -0
  23. data/lib/knapsack_pro/test_file_finder.rb +43 -5
  24. data/lib/knapsack_pro/test_files_with_test_cases_composer.rb +22 -0
  25. data/lib/knapsack_pro/version.rb +1 -1
  26. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +55 -0
  27. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +61 -25
  28. data/spec/knapsack_pro/allocator_builder_spec.rb +7 -3
  29. data/spec/knapsack_pro/allocator_spec.rb +7 -5
  30. data/spec/knapsack_pro/base_allocator_builder_spec.rb +79 -27
  31. data/spec/knapsack_pro/build_distribution_fetcher_spec.rb +89 -0
  32. data/spec/knapsack_pro/client/api/v1/build_distributions_spec.rb +31 -0
  33. data/spec/knapsack_pro/client/connection_spec.rb +235 -104
  34. data/spec/knapsack_pro/config/env_spec.rb +14 -0
  35. data/spec/knapsack_pro/queue_allocator_builder_spec.rb +7 -3
  36. data/spec/knapsack_pro/queue_allocator_spec.rb +7 -5
  37. data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +25 -0
  38. data/spec/knapsack_pro/runners/rspec_runner_spec.rb +4 -4
  39. data/spec/knapsack_pro/slow_test_file_determiner_spec.rb +74 -0
  40. data/spec/knapsack_pro/slow_test_file_finder_spec.rb +43 -0
  41. data/spec/knapsack_pro/test_case_detectors/rspec_test_example_detector_spec.rb +83 -37
  42. data/spec/knapsack_pro/test_case_mergers/base_merger_spec.rb +27 -0
  43. data/spec/knapsack_pro/test_case_mergers/rspec_merger_spec.rb +59 -0
  44. data/spec/knapsack_pro/test_file_finder_spec.rb +105 -29
  45. data/spec/knapsack_pro/test_files_with_test_cases_composer_spec.rb +41 -0
  46. metadata +27 -10
@@ -8,8 +8,11 @@ describe KnapsackPro::QueueAllocatorBuilder do
8
8
  subject { allocator_builder.allocator }
9
9
 
10
10
  before do
11
- test_files = double
12
- expect(allocator_builder).to receive(:test_files).and_return(test_files)
11
+ fast_and_slow_test_files_to_run = double
12
+ expect(allocator_builder).to receive(:fast_and_slow_test_files_to_run).and_return(fast_and_slow_test_files_to_run)
13
+
14
+ fallback_mode_test_files = double
15
+ expect(allocator_builder).to receive(:fallback_mode_test_files).and_return(fallback_mode_test_files)
13
16
 
14
17
  repository_adapter = double
15
18
  expect(KnapsackPro::RepositoryAdapterInitiator).to receive(:call).and_return(repository_adapter)
@@ -22,7 +25,8 @@ describe KnapsackPro::QueueAllocatorBuilder do
22
25
  expect(KnapsackPro::Config::Env).to receive(:ci_node_build_id).and_return(ci_node_build_id)
23
26
 
24
27
  expect(KnapsackPro::QueueAllocator).to receive(:new).with(
25
- test_files: test_files,
28
+ fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
29
+ fallback_mode_test_files: fallback_mode_test_files,
26
30
  ci_node_total: ci_node_total,
27
31
  ci_node_index: ci_node_index,
28
32
  ci_node_build_id: ci_node_build_id,
@@ -1,5 +1,6 @@
1
1
  describe KnapsackPro::QueueAllocator do
2
- let(:test_files) { double }
2
+ let(:fast_and_slow_test_files_to_run) { double }
3
+ let(:fallback_mode_test_files) { double }
3
4
  let(:ci_node_total) { double }
4
5
  let(:ci_node_index) { double }
5
6
  let(:ci_node_build_id) { double }
@@ -7,7 +8,8 @@ describe KnapsackPro::QueueAllocator do
7
8
 
8
9
  let(:queue_allocator) do
9
10
  described_class.new(
10
- test_files: test_files,
11
+ fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
12
+ fallback_mode_test_files: fallback_mode_test_files,
11
13
  ci_node_total: ci_node_total,
12
14
  ci_node_index: ci_node_index,
13
15
  ci_node_build_id: ci_node_build_id,
@@ -24,7 +26,7 @@ describe KnapsackPro::QueueAllocator do
24
26
 
25
27
  before do
26
28
  encrypted_test_files = double
27
- expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(test_files).and_return(encrypted_test_files)
29
+ expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(fast_and_slow_test_files_to_run).and_return(encrypted_test_files)
28
30
 
29
31
  encrypted_branch = double
30
32
  expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
@@ -70,7 +72,7 @@ describe KnapsackPro::QueueAllocator do
70
72
  end
71
73
 
72
74
  before do
73
- expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(test_files, response['test_files']).and_call_original
75
+ expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
74
76
  end
75
77
 
76
78
  it { should eq ['a_spec.rb', 'b_spec.rb'] }
@@ -120,7 +122,7 @@ describe KnapsackPro::QueueAllocator do
120
122
  context 'when fallback mode started' do
121
123
  before do
122
124
  test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
123
- expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(test_files, ci_node_total).and_return(test_flat_distributor)
125
+ expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(fallback_mode_test_files, ci_node_total).and_return(test_flat_distributor)
124
126
  expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
125
127
  { 'path' => 'c_spec.rb' },
126
128
  { 'path' => 'd_spec.rb' },
@@ -104,6 +104,31 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
104
104
  subject
105
105
  end
106
106
  end
107
+
108
+ context 'when format param is provided without a delimiter' do
109
+ let(:args) { '-fMyCustomFormatter' }
110
+
111
+ it 'uses provided format param instead of default formatter progress' do
112
+ expected_exitstatus = 0
113
+ expected_accumulator = {
114
+ status: :completed,
115
+ exitstatus: expected_exitstatus
116
+ }
117
+ accumulator = {
118
+ status: :next,
119
+ runner: runner,
120
+ can_initialize_queue: true,
121
+ args: ['-fMyCustomFormatter', '--format', 'KnapsackPro::Formatters::RSpecQueueSummaryFormatter', '--default-path', 'fake-test-dir'],
122
+ exitstatus: 0,
123
+ all_test_file_paths: [],
124
+ }
125
+ expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
126
+
127
+ expect(Kernel).to receive(:exit).with(expected_exitstatus)
128
+
129
+ subject
130
+ end
131
+ end
107
132
  end
108
133
 
109
134
  context 'when args not provided' do
@@ -24,11 +24,11 @@ describe KnapsackPro::Runners::RSpecRunner do
24
24
 
25
25
  context 'when test files were returned by Knapsack Pro API' do
26
26
  let(:test_dir) { 'fake-test-dir' }
27
- let(:test_file_paths) { double(:test_file_paths) }
27
+ let(:stringify_test_file_paths) { "spec/a_spec.rb spec/b_spec.rb[1:1]" }
28
28
  let(:runner) do
29
29
  instance_double(described_class,
30
30
  test_dir: test_dir,
31
- test_file_paths: test_file_paths,
31
+ stringify_test_file_paths: stringify_test_file_paths,
32
32
  test_files_to_execute_exist?: true)
33
33
  end
34
34
  let(:task) { double }
@@ -38,8 +38,8 @@ describe KnapsackPro::Runners::RSpecRunner do
38
38
 
39
39
  t = double
40
40
  expect(RSpec::Core::RakeTask).to receive(:new).with('knapsack_pro:rspec_run').and_yield(t)
41
- expect(t).to receive(:rspec_opts=).with('--profile --color --default-path fake-test-dir')
42
- expect(t).to receive(:pattern=).with(test_file_paths)
41
+ expect(t).to receive(:rspec_opts=).with('--profile --color --default-path fake-test-dir spec/a_spec.rb spec/b_spec.rb[1:1]')
42
+ expect(t).to receive(:pattern=).with([])
43
43
  end
44
44
 
45
45
  context 'when task already exists' do
@@ -0,0 +1,74 @@
1
+ describe KnapsackPro::SlowTestFileDeterminer do
2
+ describe '.call' do
3
+ let(:node_total) { 4 }
4
+ let(:time_execution) { 20.0 }
5
+ let(:test_files) do
6
+ [
7
+ { 'path' => 'a_spec.rb', 'time_execution' => 1.0 },
8
+ { 'path' => 'b_spec.rb', 'time_execution' => 3.4 },
9
+ # slow tests are above 3.5s threshold (20.0 / 4 * 0.7 = 3.5)
10
+ { 'path' => 'c_spec.rb', 'time_execution' => 3.5 },
11
+ { 'path' => 'd_spec.rb', 'time_execution' => 5.9 },
12
+ ]
13
+ end
14
+
15
+ before do
16
+ expect(KnapsackPro::Config::Env).to receive(:ci_node_total).and_return(node_total)
17
+ end
18
+
19
+ subject { described_class.call(test_files, time_execution) }
20
+
21
+ it do
22
+ expect(subject).to eq([
23
+ { 'path' => 'c_spec.rb', 'time_execution' => 3.5 },
24
+ { 'path' => 'd_spec.rb', 'time_execution' => 5.9 },
25
+ ])
26
+ end
27
+ end
28
+
29
+ describe '.save_to_json_report', :clear_tmp do
30
+ let(:json_report_path) { 'tmp/knapsack_pro/slow_test_file_determiner/slow_test_files_node_0.json' }
31
+ let(:test_files) do
32
+ [
33
+ { 'path' => 'a_spec.rb', 'time_execution' => 1.0 },
34
+ # unique path to ensure we saved on disk a completely new report
35
+ { 'path' => "#{SecureRandom.hex}_spec.rb", 'time_execution' => 3.4 },
36
+ ]
37
+ end
38
+
39
+ subject { described_class.save_to_json_report(test_files) }
40
+
41
+ it do
42
+ subject
43
+ expect(File.read(json_report_path)).to eq(test_files.to_json)
44
+ end
45
+ end
46
+
47
+ describe '.read_from_json_report', :clear_tmp do
48
+ let(:test_files) do
49
+ [
50
+ { 'path' => 'a_spec.rb', 'time_execution' => 1.0 },
51
+ # unique path to ensure we saved on disk a completely new report
52
+ { 'path' => "#{SecureRandom.hex}_spec.rb", 'time_execution' => 3.4 },
53
+ ]
54
+ end
55
+
56
+ subject { described_class.read_from_json_report }
57
+
58
+ context 'when json report exists' do
59
+ before do
60
+ described_class.save_to_json_report(test_files)
61
+ end
62
+
63
+ it do
64
+ expect(subject).to eq test_files
65
+ end
66
+ end
67
+
68
+ context 'when json report does not exist' do
69
+ it do
70
+ expect { subject }.to raise_error(RuntimeError, 'Report with slow test files was not generated yet. If you have enabled split by test cases https://github.com/KnapsackPro/knapsack_pro-ruby#split-test-files-by-test-cases and you see this error it means that your tests accidentally cleaned up tmp/knapsack_pro directory. Please do not remove this directory during tests runtime!')
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,43 @@
1
+ describe KnapsackPro::SlowTestFileFinder do
2
+ describe '.call' do
3
+ let(:adapter_class) { double }
4
+
5
+ subject { described_class.call(adapter_class) }
6
+
7
+ before do
8
+ expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(test_files_encrypted?)
9
+ end
10
+
11
+ context 'when test files are not encrypted' do
12
+ let(:test_files_encrypted?) { false }
13
+
14
+ it do
15
+ test_files_from_api = double
16
+ time_execution = double
17
+ build_distribution_entity = instance_double(KnapsackPro::BuildDistributionFetcher::BuildDistributionEntity, test_files: test_files_from_api, time_execution: time_execution)
18
+ expect(KnapsackPro::BuildDistributionFetcher).to receive(:call).and_return(build_distribution_entity)
19
+
20
+ merged_test_files_from_api = double
21
+ expect(KnapsackPro::TestCaseMergers::BaseMerger).to receive(:call).with(adapter_class, test_files_from_api).and_return(merged_test_files_from_api)
22
+
23
+ test_files_existing_on_disk = double
24
+ expect(KnapsackPro::TestFileFinder).to receive(:select_test_files_that_can_be_run).with(adapter_class, merged_test_files_from_api).and_return(test_files_existing_on_disk)
25
+
26
+ slow_test_files = double
27
+ expect(KnapsackPro::SlowTestFileDeterminer).to receive(:call).with(test_files_existing_on_disk, time_execution).and_return(slow_test_files)
28
+
29
+ expect(KnapsackPro::SlowTestFileDeterminer).to receive(:save_to_json_report).with(slow_test_files)
30
+
31
+ expect(subject).to eq slow_test_files
32
+ end
33
+ end
34
+
35
+ context 'when test files are encrypted' do
36
+ let(:test_files_encrypted?) { true }
37
+
38
+ it do
39
+ expect { subject }.to raise_error RuntimeError, 'Split by test cases is not possible when you have enabled test file names encryption ( https://github.com/KnapsackPro/knapsack_pro-ruby#test-file-names-encryption ). You need to disable encryption with KNAPSACK_PRO_TEST_FILES_ENCRYPTED=false in order to use split by test cases https://github.com/KnapsackPro/knapsack_pro-ruby#split-test-files-by-test-cases'
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,9 +1,10 @@
1
1
  describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
2
2
  let(:report_dir) { 'tmp/knapsack_pro/test_case_detectors/rspec' }
3
- let(:report_path) { 'tmp/knapsack_pro/test_case_detectors/rspec/rspec_dry_run_json_report.json' }
3
+ let(:report_path) { 'tmp/knapsack_pro/test_case_detectors/rspec/rspec_dry_run_json_report_node_0.json' }
4
+ let(:rspec_test_example_detector) { described_class.new }
4
5
 
5
6
  describe '#generate_json_report' do
6
- subject { described_class.new.generate_json_report }
7
+ subject { rspec_test_example_detector.generate_json_report }
7
8
 
8
9
  before do
9
10
  expect(FileUtils).to receive(:mkdir_p).with(report_dir)
@@ -11,48 +12,63 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
11
12
  expect(File).to receive(:exists?).with(report_path).and_return(true)
12
13
  expect(File).to receive(:delete).with(report_path)
13
14
 
14
- test_file_pattern = double
15
- adapter_class = KnapsackPro::Adapters::RSpecAdapter
16
- expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
17
-
18
- test_file_paths = [
19
- { 'path' => 'spec/a_spec.rb' },
20
- { 'path' => 'spec/b_spec.rb' },
21
- ]
22
- expect(KnapsackPro::TestFileFinder).to receive(:call).with(test_file_pattern).and_return(test_file_paths)
23
-
24
- test_dir = 'spec'
25
- expect(KnapsackPro::Config::Env).to receive(:test_dir).and_return(nil)
26
- expect(KnapsackPro::TestFilePattern).to receive(:test_dir).with(adapter_class).and_return(test_dir)
27
-
28
- options = double
29
- expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
30
- '--format', expected_format,
31
- '--dry-run',
32
- '--out', report_path,
33
- '--default-path', test_dir,
34
- 'spec/a_spec.rb', 'spec/b_spec.rb',
35
- ]).and_return(options)
36
-
37
- rspec_core_runner = double
38
- expect(RSpec::Core::Runner).to receive(:new).with(options).and_return(rspec_core_runner)
39
- expect(rspec_core_runner).to receive(:run).with($stderr, $stdout).and_return(exit_code)
15
+ expect(rspec_test_example_detector).to receive(:slow_test_files).and_return(test_file_entities)
40
16
  end
41
17
 
42
18
  shared_examples 'generate_json_report runs RSpec::Core::Runner' do
43
- context 'when exit code from RSpec::Core::Runner is 0' do
44
- let(:exit_code) { 0 }
19
+ context 'when there are no slow test files' do
20
+ let(:test_file_entities) { [] }
21
+
22
+ before do
23
+ expect(File).to receive(:write).with(report_path, { examples: [] }.to_json)
24
+ end
45
25
 
46
26
  it do
47
27
  expect(subject).to be_nil
48
28
  end
49
29
  end
50
30
 
51
- context 'when exit code from RSpec::Core::Runner is 1' do
52
- let(:exit_code) { 1 }
31
+ context 'when slow test files exist' do
32
+ let(:test_file_entities) do
33
+ [
34
+ { 'path' => 'spec/a_spec.rb' },
35
+ { 'path' => 'spec/b_spec.rb' },
36
+ ]
37
+ end
53
38
 
54
- it do
55
- expect { subject }.to raise_error(RuntimeError, 'There was problem to generate test examples for test suite')
39
+ before do
40
+ test_dir = 'spec'
41
+ expect(KnapsackPro::Config::Env).to receive(:test_dir).and_return(nil)
42
+ expect(KnapsackPro::TestFilePattern).to receive(:test_dir).with(KnapsackPro::Adapters::RSpecAdapter).and_return(test_dir)
43
+
44
+ options = double
45
+ expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
46
+ '--format', expected_format,
47
+ '--dry-run',
48
+ '--out', report_path,
49
+ '--default-path', test_dir,
50
+ 'spec/a_spec.rb', 'spec/b_spec.rb',
51
+ ]).and_return(options)
52
+
53
+ rspec_core_runner = double
54
+ expect(RSpec::Core::Runner).to receive(:new).with(options).and_return(rspec_core_runner)
55
+ expect(rspec_core_runner).to receive(:run).with($stderr, $stdout).and_return(exit_code)
56
+ end
57
+
58
+ context 'when exit code from RSpec::Core::Runner is 0' do
59
+ let(:exit_code) { 0 }
60
+
61
+ it do
62
+ expect(subject).to be_nil
63
+ end
64
+ end
65
+
66
+ context 'when exit code from RSpec::Core::Runner is 1' do
67
+ let(:exit_code) { 1 }
68
+
69
+ it do
70
+ expect { subject }.to raise_error(RuntimeError, 'There was problem to generate test examples for test suite')
71
+ end
56
72
  end
57
73
  end
58
74
  end
@@ -77,7 +93,7 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
77
93
  describe '#test_file_example_paths' do
78
94
  subject { described_class.new.test_file_example_paths }
79
95
 
80
- context 'when json report exists' do
96
+ context 'when JSON report exists' do
81
97
  it do
82
98
  expect(File).to receive(:exists?).with(report_path).and_return(true)
83
99
 
@@ -96,11 +112,41 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
96
112
  end
97
113
  end
98
114
 
99
- context 'when json report does not exist' do
115
+ context 'when JSON report does not exist' do
100
116
  it do
101
117
  expect(File).to receive(:exists?).with(report_path).and_return(false)
102
118
 
103
- expect { subject }.to raise_error(RuntimeError, 'No report found at tmp/knapsack_pro/test_case_detectors/rspec/rspec_dry_run_json_report.json')
119
+ expect { subject }.to raise_error(RuntimeError, 'No report found at tmp/knapsack_pro/test_case_detectors/rspec/rspec_dry_run_json_report_node_0.json')
120
+ end
121
+ end
122
+ end
123
+
124
+ describe '#slow_test_files' do
125
+ subject { described_class.new.slow_test_files }
126
+
127
+ before do
128
+ expect(KnapsackPro::Config::Env).to receive(:slow_test_file_pattern).and_return(slow_test_file_pattern)
129
+ end
130
+
131
+ context 'when slow test file pattern is present' do
132
+ let(:slow_test_file_pattern) { double }
133
+
134
+ it do
135
+ expected_slow_test_files = double
136
+ expect(KnapsackPro::TestFileFinder).to receive(:slow_test_files_by_pattern).with(KnapsackPro::Adapters::RSpecAdapter).and_return(expected_slow_test_files)
137
+
138
+ expect(subject).to eq expected_slow_test_files
139
+ end
140
+ end
141
+
142
+ context 'when slow test file pattern is not present' do
143
+ let(:slow_test_file_pattern) { nil }
144
+
145
+ it do
146
+ expected_slow_test_files = double
147
+ expect(KnapsackPro::SlowTestFileDeterminer).to receive(:read_from_json_report).and_return(expected_slow_test_files)
148
+
149
+ expect(subject).to eq expected_slow_test_files
104
150
  end
105
151
  end
106
152
  end
@@ -0,0 +1,27 @@
1
+ describe KnapsackPro::TestCaseMergers::BaseMerger do
2
+ describe '.call' do
3
+ let(:test_files) { double }
4
+
5
+ subject { described_class.call(adapter_class, test_files) }
6
+
7
+ context 'when adapter_class is KnapsackPro::Adapters::RSpecAdapter' do
8
+ let(:adapter_class) { KnapsackPro::Adapters::RSpecAdapter }
9
+
10
+ it do
11
+ result = double
12
+ rspec_merger = instance_double(KnapsackPro::TestCaseMergers::RSpecMerger, call: result)
13
+ expect(KnapsackPro::TestCaseMergers::RSpecMerger).to receive(:new).with(test_files).and_return(rspec_merger)
14
+
15
+ expect(subject).to eq result
16
+ end
17
+ end
18
+
19
+ context 'when adapter_class is unknown' do
20
+ let(:adapter_class) { 'fake-adapter' }
21
+
22
+ it do
23
+ expect { subject }.to raise_error 'Test case merger does not exist for adapter_class: fake-adapter'
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,59 @@
1
+ describe KnapsackPro::TestCaseMergers::RSpecMerger do
2
+ describe '#call' do
3
+ subject { described_class.new(test_files).call }
4
+
5
+ context 'when all test files are not test example paths' do
6
+ let(:test_files) do
7
+ [
8
+ { 'path' => 'spec/a_spec.rb', 'time_execution' => 1.1 },
9
+ { 'path' => 'spec/b_spec.rb', 'time_execution' => 2.2 },
10
+ ]
11
+ end
12
+
13
+ it do
14
+ expect(subject).to eq([
15
+ { 'path' => 'spec/a_spec.rb', 'time_execution' => 1.1 },
16
+ { 'path' => 'spec/b_spec.rb', 'time_execution' => 2.2 },
17
+ ])
18
+ end
19
+ end
20
+
21
+ context 'when test files have test example paths' do
22
+ let(:test_files) do
23
+ [
24
+ { 'path' => 'spec/a_spec.rb', 'time_execution' => 1.1 },
25
+ # test example paths
26
+ { 'path' => 'spec/test_case_spec.rb[1:1]', 'time_execution' => 2.2 },
27
+ { 'path' => 'spec/test_case_spec.rb[1:2]', 'time_execution' => 0.8 },
28
+ ]
29
+ end
30
+
31
+ it 'returns merged paths for test examples and sum of their time_execution' do
32
+ expect(subject).to eq([
33
+ { 'path' => 'spec/a_spec.rb', 'time_execution' => 1.1 },
34
+ { 'path' => 'spec/test_case_spec.rb', 'time_execution' => 3.0 },
35
+ ])
36
+ end
37
+ end
38
+
39
+ context 'when test files have test example paths and at the same time test file path for test example path is present as full test file path' do
40
+ let(:test_files) do
41
+ [
42
+ { 'path' => 'spec/a_spec.rb', 'time_execution' => 1.1 },
43
+ # full test file path is present despite existing test example paths
44
+ { 'path' => 'spec/test_case_spec.rb', 'time_execution' => 1.0 },
45
+ # test example paths
46
+ { 'path' => 'spec/test_case_spec.rb[1:1]', 'time_execution' => 2.2 },
47
+ { 'path' => 'spec/test_case_spec.rb[1:2]', 'time_execution' => 0.8 },
48
+ ]
49
+ end
50
+
51
+ it 'returns merged paths for test examples and sum of their time_execution' do
52
+ expect(subject).to eq([
53
+ { 'path' => 'spec/a_spec.rb', 'time_execution' => 1.1 },
54
+ { 'path' => 'spec/test_case_spec.rb', 'time_execution' => 4.0 },
55
+ ])
56
+ end
57
+ end
58
+ end
59
+ end