qfill 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/style.yml +37 -0
- data/.github/workflows/test.yml +55 -0
- data/.rspec +3 -2
- data/.rubocop.yml +26 -0
- data/.rubocop_todo.yml +163 -0
- data/.simplecov +6 -0
- data/CODE_OF_CONDUCT.md +133 -0
- data/Gemfile +33 -0
- data/Guardfile +12 -0
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +2 -2
- data/Rakefile +24 -1
- data/lib/qfill.rb +13 -10
- data/lib/qfill/errors/invalid_index.rb +8 -0
- data/lib/qfill/filter.rb +5 -3
- data/lib/qfill/list.rb +4 -2
- data/lib/qfill/list_set.rb +13 -9
- data/lib/qfill/manager.rb +78 -124
- data/lib/qfill/origin.rb +4 -3
- data/lib/qfill/popper.rb +30 -25
- data/lib/qfill/pusher.rb +33 -22
- data/lib/qfill/result.rb +63 -42
- data/lib/qfill/strategy.rb +13 -0
- data/lib/qfill/strategy/base.rb +65 -0
- data/lib/qfill/strategy/drain_to_empty.rb +73 -0
- data/lib/qfill/strategy/drain_to_limit.rb +46 -0
- data/lib/qfill/strategy/sample.rb +42 -0
- data/lib/qfill/strategy/time_slice.rb +106 -0
- data/lib/qfill/version.rb +3 -1
- data/maintenance-branch +1 -0
- data/qfill.gemspec +15 -13
- data/spec/qfill/filter_spec.rb +35 -26
- data/spec/qfill/list_set_spec.rb +28 -23
- data/spec/qfill/list_spec.rb +35 -27
- data/spec/qfill/manager_spec.rb +670 -434
- data/spec/qfill/origin_spec.rb +45 -35
- data/spec/qfill/popper_spec.rb +36 -30
- data/spec/qfill/pusher_spec.rb +32 -26
- data/spec/qfill/result_spec.rb +49 -38
- data/spec/qfill_spec.rb +6 -5
- data/spec/spec_helper.rb +11 -38
- data/spec/support/helper.rb +13 -0
- data/spec/support/random_object.rb +30 -0
- metadata +52 -23
data/spec/qfill/origin_spec.rb
CHANGED
@@ -1,55 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
describe Qfill::Origin do
|
3
|
-
|
4
|
-
context
|
5
|
-
it
|
6
|
-
|
5
|
+
describe '#new' do
|
6
|
+
context 'with no arguments' do
|
7
|
+
it 'raises ArgumentError' do
|
8
|
+
expect { described_class.new }.to raise_error(ArgumentError)
|
7
9
|
end
|
8
10
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
|
12
|
+
context 'with name' do
|
13
|
+
before do
|
14
|
+
@arguments = { name: 'High List' }
|
12
15
|
end
|
13
|
-
|
14
|
-
|
16
|
+
|
17
|
+
it 'does not raise any errors' do
|
18
|
+
expect { described_class.new(@arguments) }.not_to raise_error
|
15
19
|
end
|
16
|
-
|
17
|
-
|
20
|
+
|
21
|
+
it 'instantiates with name' do
|
22
|
+
expect(described_class.new(@arguments).name).to eq('High List')
|
18
23
|
end
|
19
24
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
|
26
|
+
context 'with elements' do
|
27
|
+
before do
|
28
|
+
@arguments = { name: 'High List',
|
29
|
+
elements: [1, 2] }
|
24
30
|
end
|
25
|
-
|
26
|
-
|
31
|
+
|
32
|
+
it 'instantiates with elements' do
|
33
|
+
expect(described_class.new(@arguments).elements).to eq([1, 2])
|
27
34
|
end
|
28
35
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
:
|
36
|
+
|
37
|
+
context 'with backfill' do
|
38
|
+
before do
|
39
|
+
@arguments = { name: 'High List',
|
40
|
+
elements: [1, 2],
|
41
|
+
backfill: 'Medium List' }
|
34
42
|
end
|
35
|
-
|
36
|
-
|
43
|
+
|
44
|
+
it 'instantiates with elements' do
|
45
|
+
expect(described_class.new(@arguments).backfill).to eq('Medium List')
|
37
46
|
end
|
38
47
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
48
|
+
|
49
|
+
context 'with filter' do
|
50
|
+
before do
|
51
|
+
lambda = ->(object) { !object.nil? }
|
42
52
|
@filter = Qfill::Filter.new(lambda)
|
43
|
-
@arguments = { :
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
53
|
+
@arguments = { name: 'High List',
|
54
|
+
elements: [1, 2],
|
55
|
+
backfill: 'Medium List',
|
56
|
+
filter: @filter }
|
47
57
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
58
|
+
|
59
|
+
it 'instantiates with processor' do
|
60
|
+
expect(described_class.new(@arguments).filter).to be_a(Qfill::Filter)
|
61
|
+
expect(described_class.new(@arguments).filter).to eq(@filter)
|
51
62
|
end
|
52
63
|
end
|
53
64
|
end
|
54
|
-
|
55
65
|
end
|
data/spec/qfill/popper_spec.rb
CHANGED
@@ -1,44 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
describe Qfill::Popper do
|
3
|
-
|
4
|
-
context
|
5
|
-
it
|
6
|
-
expect {
|
5
|
+
describe '#new' do
|
6
|
+
context 'with no arguments' do
|
7
|
+
it 'raises ArgumentError' do
|
8
|
+
expect { described_class.new }.to raise_error(ArgumentError)
|
7
9
|
end
|
8
10
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
|
12
|
+
context 'with arguments' do
|
13
|
+
before do
|
14
|
+
@filter = Qfill::Filter.new(->(object) { object.is_a?(Numeric) })
|
12
15
|
@origin_queues = [
|
13
16
|
Qfill::Origin.new(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
name: 'High List',
|
18
|
+
elements: [1, 2, 3, 'c'],
|
19
|
+
backfill: 'Medium List',
|
20
|
+
filter: @filter
|
21
|
+
),
|
22
|
+
Qfill::Origin.new(name: 'Medium List',
|
23
|
+
elements: ['e', 'f', 4, 5],
|
24
|
+
backfill: 'Low List',
|
25
|
+
filter: @filter),
|
26
|
+
Qfill::Origin.new(name: 'Low List',
|
27
|
+
elements: [7, 8, 'd'],
|
28
|
+
backfill: nil,
|
29
|
+
filter: @filter)
|
26
30
|
]
|
27
31
|
end
|
28
|
-
|
29
|
-
|
32
|
+
|
33
|
+
it 'does not raise any errors' do
|
34
|
+
expect { described_class.new(*@origin_queues) }.not_to raise_error
|
30
35
|
end
|
31
|
-
|
32
|
-
|
33
|
-
popper
|
34
|
-
popper.queues.
|
36
|
+
|
37
|
+
it 'instantiates with name' do
|
38
|
+
popper = described_class.new(*@origin_queues)
|
39
|
+
expect(popper.queues.first.name).to eq('High List')
|
40
|
+
expect(popper.queues.last.name).to eq('Low List')
|
35
41
|
end
|
36
|
-
|
37
|
-
|
38
|
-
popper
|
39
|
-
popper.queues.
|
42
|
+
|
43
|
+
it 'instantiates with elements' do
|
44
|
+
popper = described_class.new(*@origin_queues)
|
45
|
+
expect(popper.queues.first.elements).to eq([1, 2, 3, 'c'])
|
46
|
+
expect(popper.queues.last.elements).to eq([7, 8, 'd'])
|
40
47
|
end
|
41
48
|
end
|
42
49
|
end
|
43
|
-
|
44
50
|
end
|
data/spec/qfill/pusher_spec.rb
CHANGED
@@ -1,38 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
describe Qfill::Pusher do
|
3
|
-
|
4
|
-
context
|
5
|
-
it
|
6
|
-
expect {
|
5
|
+
describe '#new' do
|
6
|
+
context 'with no arguments' do
|
7
|
+
it 'raises ArgumentError' do
|
8
|
+
expect { described_class.new }.to raise_error(ArgumentError)
|
7
9
|
end
|
8
10
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
|
12
|
+
context 'with arguments' do
|
13
|
+
before do
|
14
|
+
@filter = Qfill::Filter.new(->(object) { object.is_a?(Numeric) })
|
12
15
|
@origin_queues = [
|
13
|
-
Qfill::Result.new({
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
Qfill::Result.new({ name: 'Top Results',
|
17
|
+
ratio: 0.4,
|
18
|
+
list_ratios: {
|
19
|
+
'High Price' => 0.2,
|
20
|
+
'Medium Price' => 0.3,
|
21
|
+
'Low Price' => 0.5
|
22
|
+
} }),
|
23
|
+
Qfill::Result.new({ name: 'Page Results',
|
24
|
+
ratio: 0.6,
|
25
|
+
list_ratios: {
|
26
|
+
'High Price' => 0.5,
|
27
|
+
'Medium Price' => 0.3,
|
28
|
+
'Low Price' => 0.2
|
29
|
+
} })
|
25
30
|
]
|
26
31
|
end
|
27
|
-
|
28
|
-
|
32
|
+
|
33
|
+
it 'does not raise any errors' do
|
34
|
+
expect { described_class.new(*@origin_queues) }.not_to raise_error
|
29
35
|
end
|
30
|
-
|
31
|
-
|
32
|
-
popper
|
33
|
-
popper.queues.
|
36
|
+
|
37
|
+
it 'instantiates with name' do
|
38
|
+
popper = described_class.new(*@origin_queues)
|
39
|
+
expect(popper.queues.first.name).to eq('Top Results')
|
40
|
+
expect(popper.queues.last.name).to eq('Page Results')
|
34
41
|
end
|
35
42
|
end
|
36
43
|
end
|
37
|
-
|
38
44
|
end
|
data/spec/qfill/result_spec.rb
CHANGED
@@ -1,57 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
describe Qfill::Result do
|
3
|
-
|
4
|
-
context
|
5
|
-
it
|
6
|
-
expect {
|
5
|
+
describe '#new' do
|
6
|
+
context 'with no arguments' do
|
7
|
+
it 'raises ArgumentError' do
|
8
|
+
expect { described_class.new }.to raise_error(ArgumentError)
|
7
9
|
end
|
8
10
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
|
12
|
+
context 'with name' do
|
13
|
+
before do
|
14
|
+
@arguments = { name: 'Best Results' }
|
12
15
|
end
|
13
|
-
|
14
|
-
|
16
|
+
|
17
|
+
it 'does not raise any errors' do
|
18
|
+
expect { described_class.new(@arguments) }.not_to raise_error
|
15
19
|
end
|
16
|
-
|
17
|
-
|
20
|
+
|
21
|
+
it 'instantiates with name' do
|
22
|
+
expect(described_class.new(@arguments).name).to eq('Best Results')
|
18
23
|
end
|
19
24
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
|
26
|
+
context 'with ratio' do
|
27
|
+
before do
|
28
|
+
@arguments = { name: 'Best Results',
|
29
|
+
ratio: 0.5 }
|
24
30
|
end
|
25
|
-
|
26
|
-
|
31
|
+
|
32
|
+
it 'instantiates with elements' do
|
33
|
+
expect(described_class.new(@arguments).ratio).to eq(0.5)
|
27
34
|
end
|
28
35
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
36
|
+
|
37
|
+
context 'with filter' do
|
38
|
+
before do
|
39
|
+
lambda = ->(object) { !object.nil? }
|
32
40
|
@filter = Qfill::Filter.new(lambda)
|
33
|
-
@arguments = { :
|
34
|
-
:
|
35
|
-
:
|
41
|
+
@arguments = { name: 'Best Results',
|
42
|
+
ratio: 0.5,
|
43
|
+
filter: @filter }
|
36
44
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
45
|
+
|
46
|
+
it 'instantiates with filter' do
|
47
|
+
expect(described_class.new(@arguments).filter).to be_a(Qfill::Filter)
|
48
|
+
expect(described_class.new(@arguments).filter).to eq(@filter)
|
40
49
|
end
|
41
50
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
:
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
|
52
|
+
context 'with list_ratios' do
|
53
|
+
before do
|
54
|
+
@arguments = { name: 'Best Results',
|
55
|
+
ratio: 0.5,
|
56
|
+
list_ratios: {
|
57
|
+
'High Price' => 0.4,
|
58
|
+
'Medium Price' => 0.3,
|
59
|
+
'Low Price' => 0.3
|
60
|
+
} }
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'instantiates with elements' do
|
64
|
+
expect(described_class.new(@arguments).list_ratios['High Price']).to eq(0.4)
|
53
65
|
end
|
54
66
|
end
|
55
67
|
end
|
56
|
-
|
57
68
|
end
|
data/spec/qfill_spec.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
describe Qfill do
|
3
|
-
it
|
4
|
-
Qfill::VERSION.
|
5
|
+
it 'has string version' do
|
6
|
+
expect(Qfill::VERSION).to be_a(String)
|
5
7
|
end
|
6
8
|
|
7
|
-
it
|
8
|
-
Qfill::VERSION.
|
9
|
+
it 'has major, minor & patch version levels' do
|
10
|
+
expect(Qfill::VERSION).to match(/\d+\.\d+\.\d+/)
|
9
11
|
end
|
10
|
-
|
11
12
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,49 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'qfill'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
4
|
+
|
5
|
+
require 'byebug' if RUBY_ENGINE == 'ruby'
|
6
|
+
require 'support/helper'
|
7
|
+
require 'support/random_object'
|
8
|
+
|
9
9
|
RSpec.configure do |config|
|
10
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
10
|
config.run_all_when_everything_filtered = true
|
12
11
|
config.filter_run :focus
|
12
|
+
config.include Support::Helper
|
13
13
|
|
14
14
|
# Run specs in random order to surface order dependencies. If you find an
|
15
15
|
# order dependency and want to debug it, you can fix the order by providing
|
16
16
|
# the seed, which is printed after each run.
|
17
17
|
# --seed 1234
|
18
18
|
config.order = 'random'
|
19
|
+
config.before do
|
20
|
+
stub_const('Qfill::VERBOSE', false)
|
21
|
+
end
|
19
22
|
end
|
20
|
-
|
21
|
-
# TODO: Write some specs with this dude:
|
22
|
-
#class RandomObject
|
23
|
-
#
|
24
|
-
# attr_accessor :rating, :queue
|
25
|
-
# def initialize(options = {})
|
26
|
-
# @rating = options[:rating] || RandomObject.random_rating
|
27
|
-
# @queue = RandomObject.list_designation(self.rating)
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# def self.random_rating
|
31
|
-
# rand(101) # 0 - 100
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# def self.list_designation(rating)
|
35
|
-
# if rating == 0
|
36
|
-
# 'none'
|
37
|
-
# elsif rating < 34
|
38
|
-
# 'low'
|
39
|
-
# elsif rating < 67
|
40
|
-
# 'medium'
|
41
|
-
# else
|
42
|
-
# 'high'
|
43
|
-
# end
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# def to_s
|
47
|
-
# "RO:#{rating}:#{queue}"
|
48
|
-
# end
|
49
|
-
#end
|