knapsack_pro 1.20.0 → 1.22.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/README.md +42 -17
  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 +33 -15
  13. data/lib/knapsack_pro/config/env.rb +4 -0
  14. data/lib/knapsack_pro/formatters/rspec_json_formatter.rb +1 -1
  15. data/lib/knapsack_pro/queue_allocator.rb +7 -5
  16. data/lib/knapsack_pro/queue_allocator_builder.rb +2 -1
  17. data/lib/knapsack_pro/report.rb +1 -1
  18. data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +10 -1
  19. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +7 -0
  20. data/lib/knapsack_pro/runners/rspec_runner.rb +5 -2
  21. data/lib/knapsack_pro/slow_test_file_determiner.rb +33 -0
  22. data/lib/knapsack_pro/slow_test_file_finder.rb +27 -0
  23. data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +26 -7
  24. data/lib/knapsack_pro/test_case_mergers/base_merger.rb +29 -0
  25. data/lib/knapsack_pro/test_case_mergers/rspec_merger.rb +34 -0
  26. data/lib/knapsack_pro/test_file_finder.rb +43 -5
  27. data/lib/knapsack_pro/test_files_with_test_cases_composer.rb +22 -0
  28. data/lib/knapsack_pro/version.rb +1 -1
  29. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +55 -0
  30. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +61 -25
  31. data/spec/knapsack_pro/allocator_builder_spec.rb +7 -3
  32. data/spec/knapsack_pro/allocator_spec.rb +7 -5
  33. data/spec/knapsack_pro/base_allocator_builder_spec.rb +79 -27
  34. data/spec/knapsack_pro/build_distribution_fetcher_spec.rb +89 -0
  35. data/spec/knapsack_pro/client/api/v1/build_distributions_spec.rb +31 -0
  36. data/spec/knapsack_pro/client/connection_spec.rb +202 -104
  37. data/spec/knapsack_pro/config/env_spec.rb +14 -0
  38. data/spec/knapsack_pro/queue_allocator_builder_spec.rb +7 -3
  39. data/spec/knapsack_pro/queue_allocator_spec.rb +7 -5
  40. data/spec/knapsack_pro/report_spec.rb +1 -1
  41. data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +38 -25
  42. data/spec/knapsack_pro/runners/rspec_runner_spec.rb +4 -4
  43. data/spec/knapsack_pro/slow_test_file_determiner_spec.rb +74 -0
  44. data/spec/knapsack_pro/slow_test_file_finder_spec.rb +43 -0
  45. data/spec/knapsack_pro/test_case_detectors/rspec_test_example_detector_spec.rb +83 -37
  46. data/spec/knapsack_pro/test_case_mergers/base_merger_spec.rb +27 -0
  47. data/spec/knapsack_pro/test_case_mergers/rspec_merger_spec.rb +59 -0
  48. data/spec/knapsack_pro/test_file_finder_spec.rb +105 -29
  49. data/spec/knapsack_pro/test_files_with_test_cases_composer_spec.rb +41 -0
  50. metadata +20 -2
@@ -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' },
@@ -129,7 +129,7 @@ describe KnapsackPro::Report do
129
129
  expect(KnapsackPro).to receive(:logger).exactly(3).and_return(logger)
130
130
  expect(logger).to receive(:warn).with('No test files were executed on this CI node.')
131
131
  expect(logger).to receive(:debug).with('When you use knapsack_pro queue mode then probably reason might be that CI node was started after the test files from the queue were already executed by other CI nodes. That is why this CI node has no test files to execute.')
132
- expect(logger).to receive(:debug).with("Another reason might be when your CI node failed in a way that prevented knapsack_pro to save time execution data to Knapsack Pro API and you have just tried to retry failed CI node but instead you got no test files to execute. In that case knapsack_pro don't know what testes should be executed here.")
132
+ expect(logger).to receive(:debug).with("Another reason might be when your CI node failed in a way that prevented knapsack_pro to save time execution data to Knapsack Pro API and you have just tried to retry failed CI node but instead you got no test files to execute. In that case knapsack_pro don't know what tests should be executed here.")
133
133
 
134
134
  expect(described_class).to receive(:create_build_subset).with([])
135
135
 
@@ -117,36 +117,49 @@ describe KnapsackPro::Runners::Queue::CucumberRunner do
117
117
 
118
118
  expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED', 'true')
119
119
 
120
- expect($?).to receive(:exitstatus).and_return(exitstatus)
120
+ expect($?).to receive(:exited?).and_return(process_exited)
121
+ allow($?).to receive(:exitstatus).and_return(exitstatus)
121
122
  end
122
123
 
123
- context 'when tests are passing' do
124
- let(:exitstatus) { 0 }
125
-
126
- it 'returns exit code 0' do
127
- expect(subject).to eq({
128
- status: :next,
129
- runner: runner,
130
- can_initialize_queue: false,
131
- args: args,
132
- exitstatus: exitstatus,
133
- all_test_file_paths: test_file_paths,
134
- })
124
+ context 'when system process finished its work (exited)' do
125
+ let(:process_exited) { true }
126
+
127
+ context 'when tests are passing' do
128
+ let(:exitstatus) { 0 }
129
+
130
+ it 'returns exit code 0' do
131
+ expect(subject).to eq({
132
+ status: :next,
133
+ runner: runner,
134
+ can_initialize_queue: false,
135
+ args: args,
136
+ exitstatus: exitstatus,
137
+ all_test_file_paths: test_file_paths,
138
+ })
139
+ end
140
+ end
141
+
142
+ context 'when tests are failing' do
143
+ let(:exitstatus) { 1 }
144
+
145
+ it 'returns exit code 1' do
146
+ expect(subject).to eq({
147
+ status: :next,
148
+ runner: runner,
149
+ can_initialize_queue: false,
150
+ args: args,
151
+ exitstatus: 1, # tests failed
152
+ all_test_file_paths: test_file_paths,
153
+ })
154
+ end
135
155
  end
136
156
  end
137
157
 
138
- context 'when tests are failing' do
139
- let(:exitstatus) { 1 }
140
-
141
- it 'returns exit code 1' do
142
- expect(subject).to eq({
143
- status: :next,
144
- runner: runner,
145
- can_initialize_queue: false,
146
- args: args,
147
- exitstatus: 1, # tests failed
148
- all_test_file_paths: test_file_paths,
149
- })
158
+ context "when system process didn't finish its work (hasn't exited)" do
159
+ let(:process_exited) { false }
160
+
161
+ it 'raises an error' do
162
+ expect { subject }.to raise_error(RuntimeError, /^Cucumber process execution failed/)
150
163
  end
151
164
  end
152
165
  end
@@ -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