knapsack 0.0.3 → 0.1.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -1
  3. data/CHANGELOG.md +11 -0
  4. data/LICENSE.txt +1 -1
  5. data/README.md +71 -24
  6. data/Rakefile +3 -1
  7. data/TODO.md +5 -0
  8. data/knapsack_report.json +9 -12
  9. data/lib/knapsack.rb +25 -6
  10. data/lib/knapsack/adapters/{base.rb → base_adapter.rb} +18 -8
  11. data/lib/knapsack/adapters/{rspec.rb → rspec_adapter.rb} +13 -6
  12. data/lib/knapsack/allocator.rb +65 -0
  13. data/lib/knapsack/distributors/base_distributor.rb +67 -0
  14. data/lib/knapsack/distributors/leftover_distributor.rb +49 -0
  15. data/lib/knapsack/distributors/report_distributor.rb +76 -0
  16. data/lib/knapsack/presenter.rb +38 -5
  17. data/lib/knapsack/report.rb +27 -12
  18. data/lib/knapsack/task_loader.rb +11 -0
  19. data/lib/knapsack/tracker.rb +30 -13
  20. data/lib/knapsack/version.rb +1 -1
  21. data/lib/tasks/knapsack.rake +21 -0
  22. data/spec/knapsack/adapters/base_adapter_spec.rb +91 -0
  23. data/spec/knapsack/adapters/rspec_adapter_spec.rb +29 -0
  24. data/spec/knapsack/allocator_spec.rb +57 -0
  25. data/spec/knapsack/distributors/base_distributor_spec.rb +85 -0
  26. data/spec/knapsack/distributors/leftover_distributor_spec.rb +110 -0
  27. data/spec/knapsack/distributors/report_distributor_spec.rb +152 -0
  28. data/spec/knapsack/presenter_spec.rb +83 -0
  29. data/spec/knapsack/report_spec.rb +73 -0
  30. data/spec/knapsack/task_loader_spec.rb +10 -0
  31. data/spec/knapsack/tracker_spec.rb +84 -20
  32. data/spec/knapsack_spec.rb +23 -2
  33. data/spec/spec_helper.rb +16 -0
  34. data/spec_examples/fast/1_spec.rb +1 -4
  35. data/spec_examples/fast/2_spec.rb +1 -4
  36. data/spec_examples/fast/3_spec.rb +1 -4
  37. data/spec_examples/fast/4_spec.rb +1 -4
  38. data/spec_examples/fast/5_spec.rb +1 -4
  39. data/spec_examples/fast/6_spec.rb +1 -4
  40. data/spec_examples/leftover/1_spec.rb +4 -0
  41. data/spec_examples/leftover/a_spec.rb +8 -0
  42. data/spec_examples/slow/a_spec.rb +1 -3
  43. data/spec_examples/slow/b_spec.rb +3 -5
  44. data/spec_examples/slow/c_spec.rb +1 -3
  45. data/spec_examples/spec_helper.rb +5 -2
  46. metadata +32 -7
  47. data/spec_examples/slow/d_spec.rb +0 -7
  48. data/spec_examples/slow/e_spec.rb +0 -7
  49. data/spec_examples/slow/f_spec.rb +0 -7
@@ -0,0 +1,73 @@
1
+ describe Knapsack::Report do
2
+ let(:report) { described_class.send(:new) }
3
+ let(:report_path) { 'tmp/fake_report.json' }
4
+ let(:report_json) do
5
+ %Q[{"a_spec.rb": #{rand(Math::E..Math::PI)}}]
6
+ end
7
+
8
+ describe '#config' do
9
+ context 'when passed options' do
10
+ let(:opts) do
11
+ {
12
+ report_path: 'new_knapsack_report.json',
13
+ fake: true
14
+ }
15
+ end
16
+
17
+ it do
18
+ expect(report.config(opts)).to eql({
19
+ report_path: 'new_knapsack_report.json',
20
+ fake: true
21
+ })
22
+ end
23
+ end
24
+
25
+ context "when didn't pass options" do
26
+ it do
27
+ expect(report.config).to eql({
28
+ report_path: 'knapsack_report.json'
29
+ })
30
+ end
31
+ end
32
+ end
33
+
34
+ describe '#save', :clear_tmp do
35
+ before do
36
+ expect(report).to receive(:report_json).and_return(report_json)
37
+ report.config({
38
+ report_path: report_path
39
+ })
40
+ report.save
41
+ end
42
+
43
+ it { expect(File.read(report_path)).to eql report_json }
44
+ end
45
+
46
+ describe '.open' do
47
+ let(:subject) { report.open }
48
+
49
+ before do
50
+ report.config({
51
+ report_path: report_path
52
+ })
53
+ end
54
+
55
+ context 'when report file exists' do
56
+ before do
57
+ expect(File).to receive(:read).with(report_path).and_return(report_json)
58
+ end
59
+
60
+ it { should eql(JSON.parse(report_json)) }
61
+ end
62
+
63
+ context "when report file doesn't exist" do
64
+ let(:report_path) { 'tmp/non_existing_report.json' }
65
+
66
+ it do
67
+ expect {
68
+ subject
69
+ }.to raise_error("Knapsack report file doesn't exist. Please generate report first!")
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,10 @@
1
+ describe Knapsack::TaskLoader do
2
+ describe '#load_tasks' do
3
+ let(:rake_task_path) { "#{Knapsack.root}/lib/tasks/knapsack.rake" }
4
+
5
+ it do
6
+ expect(subject).to receive(:import).with(rake_task_path)
7
+ subject.load_tasks
8
+ end
9
+ end
10
+ end
@@ -1,8 +1,6 @@
1
- require 'spec_helper'
2
-
3
1
  shared_examples 'default trakcer attributes' do
4
2
  it { expect(tracker.global_time).to eql 0 }
5
- it { expect(tracker.files).to eql({}) }
3
+ it { expect(tracker.spec_files_with_time).to eql({}) }
6
4
  end
7
5
 
8
6
  describe Knapsack::Tracker do
@@ -10,23 +8,13 @@ describe Knapsack::Tracker do
10
8
 
11
9
  it_behaves_like 'default trakcer attributes'
12
10
 
13
- describe '#generate_report?' do
14
- subject { tracker.generate_report? }
15
-
16
- context 'when ENV variable is defined' do
17
- before do
18
- stub_const("ENV", { 'KNAPSACK_GENERATE_REPORT' => true })
19
- end
20
- it { should be true }
21
- end
22
-
23
- context 'when ENV variable is not defined' do
24
- it { should be false }
11
+ describe '#config' do
12
+ before do
13
+ stub_const("ENV", { 'KNAPSACK_GENERATE_REPORT' => generate_report })
25
14
  end
26
- end
27
15
 
28
- describe '#config' do
29
16
  context 'when passed options' do
17
+ let(:generate_report) { true }
30
18
  let(:opts) do
31
19
  {
32
20
  enable_time_offset_warning: false,
@@ -37,22 +25,98 @@ describe Knapsack::Tracker do
37
25
  it do
38
26
  expect(tracker.config(opts)).to eql({
39
27
  enable_time_offset_warning: false,
40
- time_offset_warning: 30,
28
+ time_offset_in_seconds: 30,
29
+ generate_report: true,
41
30
  fake: true
42
31
  })
43
32
  end
44
33
  end
45
34
 
46
35
  context "when didn't pass options" do
36
+ let(:generate_report) { nil }
37
+
47
38
  it do
48
39
  expect(tracker.config).to eql({
49
40
  enable_time_offset_warning: true,
50
- time_offset_warning: 30,
41
+ time_offset_in_seconds: 30,
42
+ generate_report: false
51
43
  })
52
44
  end
53
45
  end
54
46
  end
55
47
 
48
+ describe '#spec_path' do
49
+ subject { tracker.spec_path }
50
+
51
+ context 'when spec_path not set' do
52
+ it do
53
+ expect { subject }.to raise_error("spec_path needs to be set by Knapsack Adapter's bind method")
54
+ end
55
+ end
56
+
57
+ context 'when spec_path set' do
58
+ context 'when spec path has prefix ./' do
59
+ before { tracker.spec_path = './spec/models/user_spec.rb' }
60
+ it { should eql 'spec/models/user_spec.rb' }
61
+ end
62
+
63
+ context 'when spec path has not prefix ./' do
64
+ before { tracker.spec_path = 'spec/models/user_spec.rb' }
65
+ it { should eql 'spec/models/user_spec.rb' }
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '#time_exceeded?' do
71
+ subject { tracker.time_exceeded? }
72
+
73
+ before do
74
+ expect(tracker).to receive(:global_time).and_return(global_time)
75
+ expect(tracker).to receive(:max_node_time_execution).and_return(max_node_time_execution)
76
+ end
77
+
78
+ context 'when true' do
79
+ let(:global_time) { 2 }
80
+ let(:max_node_time_execution) { 1 }
81
+ it { should be true }
82
+ end
83
+
84
+ context 'when false' do
85
+ let(:global_time) { 1 }
86
+ let(:max_node_time_execution) { 1 }
87
+ it { should be false }
88
+ end
89
+ end
90
+
91
+ describe '#max_node_time_execution' do
92
+ let(:report_distributor) { instance_double(Knapsack::Distributors::ReportDistributor) }
93
+ let(:node_time_execution) { 3.5 }
94
+ let(:max_node_time_execution) { node_time_execution + tracker.config[:time_offset_in_seconds] }
95
+
96
+ subject { tracker.max_node_time_execution }
97
+
98
+ before do
99
+ expect(tracker).to receive(:report_distributor).and_return(report_distributor)
100
+ expect(report_distributor).to receive(:node_time_execution).and_return(node_time_execution)
101
+ end
102
+
103
+ it { should eql max_node_time_execution }
104
+ end
105
+
106
+ describe '#exceeded_time' do
107
+ let(:global_time) { 5 }
108
+ let(:max_node_time_execution) { 2 }
109
+
110
+ subject { tracker.exceeded_time }
111
+
112
+ before do
113
+ expect(tracker).to receive(:global_time).and_return(global_time)
114
+ expect(tracker).to receive(:max_node_time_execution).and_return(max_node_time_execution)
115
+ end
116
+
117
+ it { should eql 3 }
118
+ end
119
+
56
120
  describe 'track time execution' do
57
121
  let(:now) { Time.now }
58
122
  let(:spec_paths) { ['a_spec.rb', 'b_spec.rb'] }
@@ -73,7 +137,7 @@ describe Knapsack::Tracker do
73
137
 
74
138
  it { expect(tracker.global_time).to eql 3.0 }
75
139
  it do
76
- expect(tracker.files).to eql({
140
+ expect(tracker.spec_files_with_time).to eql({
77
141
  'a_spec.rb' => 1.0,
78
142
  'b_spec.rb' => 2.0,
79
143
  })
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe Knapsack do
4
2
  describe '.tracker' do
5
3
  subject { described_class.tracker }
@@ -7,4 +5,27 @@ describe Knapsack do
7
5
  it { should be_a Knapsack::Tracker }
8
6
  it { expect(subject.object_id).to eql described_class.tracker.object_id }
9
7
  end
8
+
9
+ describe '.report' do
10
+ subject { described_class.report }
11
+
12
+ it { should be_a Knapsack::Report }
13
+ it { expect(subject.object_id).to eql described_class.report.object_id }
14
+ end
15
+
16
+ describe '.root' do
17
+ subject { described_class.root }
18
+
19
+ it { expect(subject).to match 'knapsack' }
20
+ end
21
+
22
+ describe '.load_tasks' do
23
+ let(:task_loader) { instance_double(Knapsack::TaskLoader) }
24
+
25
+ it do
26
+ expect(Knapsack::TaskLoader).to receive(:new).and_return(task_loader)
27
+ expect(task_loader).to receive(:load_tasks)
28
+ described_class.load_tasks
29
+ end
30
+ end
10
31
  end
data/spec/spec_helper.rb CHANGED
@@ -12,4 +12,20 @@ RSpec.configure do |config|
12
12
  mocks.syntax = :expect
13
13
  mocks.verify_partial_doubles = true
14
14
  end
15
+
16
+ config.expect_with :rspec do |c|
17
+ c.syntax = :expect
18
+ end
19
+
20
+ config.before(:each) do
21
+ if RSpec.current_example.metadata[:clear_tmp]
22
+ FileUtils.mkdir_p(File.join(Knapsack.root, 'tmp'))
23
+ end
24
+ end
25
+
26
+ config.after(:each) do
27
+ if RSpec.current_example.metadata[:clear_tmp]
28
+ FileUtils.rm_r(File.join(Knapsack.root, 'tmp'))
29
+ end
30
+ end
15
31
  end
@@ -1,6 +1,3 @@
1
- require 'spec_helper'
2
-
3
- describe 'Fast 1' do
1
+ describe 'Fast 1', :focus do
4
2
  it {}
5
3
  end
6
-
@@ -1,7 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe 'Fast 2' do
1
+ describe 'Fast 2', :focus do
4
2
  it {}
5
3
  it {}
6
4
  end
7
-
@@ -1,8 +1,5 @@
1
- require 'spec_helper'
2
-
3
- describe 'Fast 3' do
1
+ describe 'Fast 3', :focus do
4
2
  it {}
5
3
  it {}
6
4
  it {}
7
5
  end
8
-
@@ -1,9 +1,6 @@
1
- require 'spec_helper'
2
-
3
- describe 'Fast 4' do
1
+ describe 'Fast 4', :focus do
4
2
  it {}
5
3
  it {}
6
4
  it {}
7
5
  it {}
8
6
  end
9
-
@@ -1,10 +1,7 @@
1
- require 'spec_helper'
2
-
3
- describe 'Fast 5' do
1
+ describe 'Fast 5', :focus do
4
2
  it {}
5
3
  it {}
6
4
  it {}
7
5
  it {}
8
6
  it {}
9
7
  end
10
-
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe 'Fast 6' do
1
+ describe 'Fast 6', :focus do
4
2
  it {}
5
3
  it {}
6
4
  it {}
@@ -8,4 +6,3 @@ describe 'Fast 6' do
8
6
  it {}
9
7
  it {}
10
8
  end
11
-
@@ -0,0 +1,4 @@
1
+ # this file should not be included in knapsack_report.json
2
+ describe 'Leftover Fast 1' do
3
+ it {}
4
+ end
@@ -0,0 +1,8 @@
1
+ # this file should not be included in knapsack_report.json
2
+ describe 'Leftover Slow A' do
3
+ it { sleep 1 }
4
+ it { sleep 0.1 }
5
+ it { sleep 0.5 }
6
+ it { sleep 3 }
7
+ it { sleep 1 }
8
+ end
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe 'Slow A' do
1
+ describe 'Slow A', :focus do
4
2
  it { sleep 1 }
5
3
  it { sleep 0.1 }
6
4
  it { sleep 0.5 }
@@ -1,7 +1,5 @@
1
- require 'spec_helper'
2
-
3
- describe 'Slow B' do
4
- it { sleep 2 }
1
+ describe 'Slow B', :focus do
2
+ it { sleep 0.3 }
5
3
  it { sleep 0.2 }
6
- it { sleep 1 }
4
+ it { sleep 0.4 }
7
5
  end
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe 'Slow C' do
1
+ describe 'Slow C', :focus do
4
2
  it { sleep 0.8 }
5
3
  it { sleep 0.1 }
6
4
  it { sleep 0.1 }
@@ -1,9 +1,12 @@
1
1
  require 'knapsack'
2
2
  Knapsack.tracker.config({
3
3
  enable_time_offset_warning: true,
4
- time_offset_warning: 5
4
+ time_offset_in_seconds: 3
5
5
  })
6
- Knapsack::Adapters::Rspec.bind
6
+ Knapsack.report.config({
7
+ report_path: 'knapsack_report.json'
8
+ })
9
+ Knapsack::Adapters::RspecAdapter.bind
7
10
 
8
11
  RSpec.configure do |config|
9
12
  config.order = :random
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knapsack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-04 00:00:00.000000000 Z
11
+ date: 2014-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -98,19 +98,36 @@ files:
98
98
  - ".gitignore"
99
99
  - ".rspec"
100
100
  - ".travis.yml"
101
+ - CHANGELOG.md
101
102
  - Gemfile
102
103
  - LICENSE.txt
103
104
  - README.md
104
105
  - Rakefile
106
+ - TODO.md
105
107
  - knapsack.gemspec
106
108
  - knapsack_report.json
107
109
  - lib/knapsack.rb
108
- - lib/knapsack/adapters/base.rb
109
- - lib/knapsack/adapters/rspec.rb
110
+ - lib/knapsack/adapters/base_adapter.rb
111
+ - lib/knapsack/adapters/rspec_adapter.rb
112
+ - lib/knapsack/allocator.rb
113
+ - lib/knapsack/distributors/base_distributor.rb
114
+ - lib/knapsack/distributors/leftover_distributor.rb
115
+ - lib/knapsack/distributors/report_distributor.rb
110
116
  - lib/knapsack/presenter.rb
111
117
  - lib/knapsack/report.rb
118
+ - lib/knapsack/task_loader.rb
112
119
  - lib/knapsack/tracker.rb
113
120
  - lib/knapsack/version.rb
121
+ - lib/tasks/knapsack.rake
122
+ - spec/knapsack/adapters/base_adapter_spec.rb
123
+ - spec/knapsack/adapters/rspec_adapter_spec.rb
124
+ - spec/knapsack/allocator_spec.rb
125
+ - spec/knapsack/distributors/base_distributor_spec.rb
126
+ - spec/knapsack/distributors/leftover_distributor_spec.rb
127
+ - spec/knapsack/distributors/report_distributor_spec.rb
128
+ - spec/knapsack/presenter_spec.rb
129
+ - spec/knapsack/report_spec.rb
130
+ - spec/knapsack/task_loader_spec.rb
114
131
  - spec/knapsack/tracker_spec.rb
115
132
  - spec/knapsack_spec.rb
116
133
  - spec/spec_helper.rb
@@ -120,12 +137,11 @@ files:
120
137
  - spec_examples/fast/4_spec.rb
121
138
  - spec_examples/fast/5_spec.rb
122
139
  - spec_examples/fast/6_spec.rb
140
+ - spec_examples/leftover/1_spec.rb
141
+ - spec_examples/leftover/a_spec.rb
123
142
  - spec_examples/slow/a_spec.rb
124
143
  - spec_examples/slow/b_spec.rb
125
144
  - spec_examples/slow/c_spec.rb
126
- - spec_examples/slow/d_spec.rb
127
- - spec_examples/slow/e_spec.rb
128
- - spec_examples/slow/f_spec.rb
129
145
  - spec_examples/spec_helper.rb
130
146
  homepage: https://github.com/ArturT/knapsack
131
147
  licenses:
@@ -152,6 +168,15 @@ signing_key:
152
168
  specification_version: 4
153
169
  summary: Parallel specs across CI server nodes based on each spec file's time execution.
154
170
  test_files:
171
+ - spec/knapsack/adapters/base_adapter_spec.rb
172
+ - spec/knapsack/adapters/rspec_adapter_spec.rb
173
+ - spec/knapsack/allocator_spec.rb
174
+ - spec/knapsack/distributors/base_distributor_spec.rb
175
+ - spec/knapsack/distributors/leftover_distributor_spec.rb
176
+ - spec/knapsack/distributors/report_distributor_spec.rb
177
+ - spec/knapsack/presenter_spec.rb
178
+ - spec/knapsack/report_spec.rb
179
+ - spec/knapsack/task_loader_spec.rb
155
180
  - spec/knapsack/tracker_spec.rb
156
181
  - spec/knapsack_spec.rb
157
182
  - spec/spec_helper.rb