picky 4.0.0pre1 → 4.0.0pre2
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.
- data/aux/picky/cli.rb +6 -2
- data/lib/picky.rb +10 -8
- data/lib/picky/backends/backend.rb +37 -0
- data/lib/picky/backends/file.rb +0 -20
- data/lib/picky/backends/memory.rb +0 -29
- data/lib/picky/backends/redis.rb +74 -15
- data/lib/picky/backends/redis/list.rb +1 -1
- data/lib/picky/backends/sqlite.rb +0 -27
- data/lib/picky/bundle.rb +2 -2
- data/lib/picky/bundle_indexed.rb +1 -1
- data/lib/picky/bundle_indexing.rb +1 -1
- data/lib/picky/categories_indexed.rb +1 -11
- data/lib/picky/category.rb +4 -4
- data/lib/picky/category/location.rb +25 -0
- data/lib/picky/category_realtime.rb +4 -3
- data/lib/picky/console.rb +1 -1
- data/lib/picky/constants.rb +1 -1
- data/lib/picky/ext/maybe_compile.rb +2 -2
- data/lib/picky/extensions/object.rb +3 -2
- data/lib/picky/generators/aliases.rb +7 -2
- data/lib/picky/generators/partial/default.rb +1 -0
- data/lib/picky/generators/similarity/default.rb +1 -0
- data/lib/picky/generators/similarity/phonetic.rb +13 -2
- data/lib/picky/generators/strategy.rb +0 -2
- data/lib/picky/generators/weights/constant.rb +1 -2
- data/lib/picky/generators/weights/default.rb +1 -0
- data/lib/picky/generators/weights/dynamic.rb +1 -1
- data/lib/picky/generators/weights/logarithmic.rb +1 -1
- data/lib/picky/generators/weights/{runtime.rb → stub.rb} +1 -3
- data/lib/picky/index.rb +3 -3
- data/lib/picky/index_indexing.rb +0 -2
- data/lib/picky/index_realtime.rb +1 -1
- data/lib/picky/indexers/base.rb +7 -0
- data/lib/picky/indexers/parallel.rb +2 -4
- data/lib/picky/indexers/serial.rb +2 -0
- data/lib/picky/indexes_indexing.rb +1 -1
- data/lib/picky/interfaces/live_parameters/master_child.rb +175 -0
- data/lib/picky/interfaces/live_parameters/unicorn.rb +37 -0
- data/lib/picky/loader.rb +238 -259
- data/lib/picky/query/allocation.rb +19 -10
- data/lib/picky/query/combination.rb +7 -1
- data/lib/picky/query/combinations.rb +1 -6
- data/lib/picky/query/token.rb +26 -36
- data/lib/picky/results.rb +18 -17
- data/lib/picky/scheduler.rb +2 -1
- data/lib/picky/search.rb +1 -1
- data/lib/picky/sinatra.rb +6 -6
- data/lib/picky/statistics.rb +2 -0
- data/lib/picky/tokenizer.rb +8 -8
- data/lib/picky/wrappers/bundle/calculation.rb +4 -4
- data/lib/picky/wrappers/bundle/location.rb +1 -2
- data/lib/tasks/framework.rake +1 -1
- data/lib/tasks/statistics.rake +1 -1
- data/lib/tasks/try.rake +1 -1
- data/lib/tasks/try.rb +1 -1
- data/spec/aux/picky/cli_spec.rb +12 -12
- data/spec/ext/performant_spec.rb +16 -16
- data/spec/functional/backends/file_spec.rb +78 -7
- data/spec/functional/backends/memory_spec.rb +78 -7
- data/spec/functional/backends/redis_spec.rb +73 -13
- data/spec/functional/dynamic_weights_spec.rb +3 -4
- data/spec/functional/realtime_spec.rb +2 -2
- data/spec/functional/speed_spec.rb +2 -2
- data/spec/functional/terminate_early_spec.rb +3 -3
- data/spec/lib/analytics_spec.rb +1 -1
- data/spec/lib/analyzer_spec.rb +5 -3
- data/spec/lib/categories_indexed_spec.rb +38 -20
- data/spec/lib/category/location_spec.rb +30 -0
- data/spec/lib/character_substituters/west_european_spec.rb +1 -0
- data/spec/lib/extensions/hash_spec.rb +6 -5
- data/spec/lib/extensions/module_spec.rb +6 -6
- data/spec/lib/extensions/object_spec.rb +9 -8
- data/spec/lib/extensions/string_spec.rb +1 -1
- data/spec/lib/generators/similarity/phonetic_spec.rb +11 -0
- data/spec/lib/index_realtime_spec.rb +5 -5
- data/spec/lib/interfaces/{live_parameters_spec.rb → live_parameters/master_child_spec.rb} +26 -26
- data/spec/lib/interfaces/live_parameters/unicorn_spec.rb +160 -0
- data/spec/lib/loader_spec.rb +65 -25
- data/spec/lib/query/allocation_spec.rb +25 -22
- data/spec/lib/query/combinations_spec.rb +13 -36
- data/spec/lib/query/token_spec.rb +144 -131
- data/spec/lib/query/tokens_spec.rb +14 -0
- data/spec/lib/results_spec.rb +14 -8
- data/spec/lib/search_spec.rb +1 -1
- data/spec/lib/sinatra_spec.rb +8 -8
- metadata +28 -91
- data/lib/picky/adapters/rack.rb +0 -34
- data/lib/picky/adapters/rack/base.rb +0 -27
- data/lib/picky/adapters/rack/live_parameters.rb +0 -37
- data/lib/picky/adapters/rack/search.rb +0 -67
- data/lib/picky/application.rb +0 -268
- data/lib/picky/frontend_adapters/rack.rb +0 -161
- data/lib/picky/interfaces/live_parameters.rb +0 -187
- data/lib/picky/sources/base.rb +0 -92
- data/lib/picky/sources/couch.rb +0 -76
- data/lib/picky/sources/csv.rb +0 -83
- data/lib/picky/sources/db.rb +0 -189
- data/lib/picky/sources/delicious.rb +0 -63
- data/lib/picky/sources/mongo.rb +0 -80
- data/lib/picky/wrappers/category/location.rb +0 -38
- data/lib/tasks/routes.rake +0 -8
- data/spec/lib/adapters/rack/base_spec.rb +0 -24
- data/spec/lib/adapters/rack/live_parameters_spec.rb +0 -26
- data/spec/lib/adapters/rack/query_spec.rb +0 -39
- data/spec/lib/application_spec.rb +0 -155
- data/spec/lib/frontend_adapters/rack_spec.rb +0 -294
- data/spec/lib/sources/base_spec.rb +0 -53
- data/spec/lib/sources/couch_spec.rb +0 -114
- data/spec/lib/sources/csv_spec.rb +0 -89
- data/spec/lib/sources/db_spec.rb +0 -125
- data/spec/lib/sources/delicious_spec.rb +0 -94
- data/spec/lib/sources/mongo_spec.rb +0 -50
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Picky::Interfaces::LiveParameters::Unicorn do
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
@parent = stub :parent
|
|
9
|
+
@child = stub :child
|
|
10
|
+
IO.stub! :pipe => [@child, @parent]
|
|
11
|
+
@parameters = described_class.new
|
|
12
|
+
@parameters.stub! :exclaim
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe Picky::Interfaces::LiveParameters::Unicorn::CouldNotUpdateConfigurationError do
|
|
16
|
+
before(:each) do
|
|
17
|
+
@error = Picky::Interfaces::LiveParameters::Unicorn::CouldNotUpdateConfigurationError.new :some_key, 'some message'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe 'querying_removes_characters' do
|
|
22
|
+
it 'works' do
|
|
23
|
+
expect do
|
|
24
|
+
@parameters.querying_removes_characters
|
|
25
|
+
end.to_not raise_error
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
describe 'querying_stopwords' do
|
|
29
|
+
it 'works' do
|
|
30
|
+
expect do
|
|
31
|
+
@parameters.querying_stopwords
|
|
32
|
+
end.to_not raise_error
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
describe 'querying_splits_text_on' do
|
|
36
|
+
it 'works' do
|
|
37
|
+
expect do
|
|
38
|
+
@parameters.querying_splits_text_on
|
|
39
|
+
end.to_not raise_error
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe 'parameters' do
|
|
44
|
+
context 'all goes well' do
|
|
45
|
+
it 'does a few things in order' do
|
|
46
|
+
@parameters.should_receive(:close_child).once.with().ordered
|
|
47
|
+
@parameters.should_receive(:try_updating_configuration_with).once.with(:a => :b).ordered
|
|
48
|
+
@parameters.should_receive(:write_parent).once.with(:a => :b).ordered
|
|
49
|
+
@parameters.should_receive(:extract_configuration).once.with().ordered
|
|
50
|
+
|
|
51
|
+
@parameters.parameters :a => :b
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
context 'updating failed' do
|
|
55
|
+
before(:each) do
|
|
56
|
+
@parameters.should_receive(:try_updating_configuration_with).and_raise Picky::Interfaces::LiveParameters::Unicorn::CouldNotUpdateConfigurationError.new(:a, 'hello')
|
|
57
|
+
end
|
|
58
|
+
it 'kills itself and returns' do
|
|
59
|
+
@parameters.should_receive(:close_child).once.ordered
|
|
60
|
+
@parameters.should_receive(:harakiri).once.ordered
|
|
61
|
+
|
|
62
|
+
@parameters.parameters( :a => :b ).should == { :a => :ERROR }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe 'harakiri' do
|
|
68
|
+
before(:each) do
|
|
69
|
+
Process.stub! :pid => :some_pid
|
|
70
|
+
end
|
|
71
|
+
it 'kills itself' do
|
|
72
|
+
Process.should_receive(:kill).once.with :QUIT, :some_pid
|
|
73
|
+
|
|
74
|
+
@parameters.harakiri
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe 'write_parent' do
|
|
79
|
+
before(:each) do
|
|
80
|
+
Process.stub! :pid => :some_pid
|
|
81
|
+
end
|
|
82
|
+
it 'calls the parent' do
|
|
83
|
+
@parent.should_receive(:write).once.with "[:some_pid, {:a=>:b}];;;"
|
|
84
|
+
|
|
85
|
+
@parameters.write_parent :a => :b
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe 'close_child' do
|
|
90
|
+
context 'child is closed' do
|
|
91
|
+
before(:each) do
|
|
92
|
+
@child.stub! :closed? => true
|
|
93
|
+
end
|
|
94
|
+
it 'does not receive close' do
|
|
95
|
+
@child.should_receive(:close).never
|
|
96
|
+
|
|
97
|
+
@parameters.close_child
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
context 'child not yet closed' do
|
|
101
|
+
before(:each) do
|
|
102
|
+
@child.stub! :closed? => false
|
|
103
|
+
end
|
|
104
|
+
it 'does receives close' do
|
|
105
|
+
@child.should_receive(:close).once.with()
|
|
106
|
+
|
|
107
|
+
@parameters.close_child
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe 'kill_worker' do
|
|
113
|
+
context 'all goes well' do
|
|
114
|
+
it 'uses Process.kill' do
|
|
115
|
+
Process.should_receive(:kill).once.with :some_signal, :some_pid
|
|
116
|
+
|
|
117
|
+
@parameters.kill_worker :some_signal, :some_pid
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
context 'there is no such process' do
|
|
121
|
+
it 'uses Process.kill' do
|
|
122
|
+
Process.should_receive(:kill).and_raise Errno::ESRCH.new
|
|
123
|
+
|
|
124
|
+
@parameters.should_receive(:remove_worker).once.with :some_pid
|
|
125
|
+
|
|
126
|
+
@parameters.kill_worker :some_signal, :some_pid
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe 'kill_each_worker_except' do
|
|
132
|
+
context 'worker pid in the worker pids' do
|
|
133
|
+
before(:each) do
|
|
134
|
+
@parameters.stub! :worker_pids => [1,2,3,4]
|
|
135
|
+
end
|
|
136
|
+
it 'kills each except the one' do
|
|
137
|
+
@parameters.should_receive(:kill_worker).once.with(:KILL, 1)
|
|
138
|
+
@parameters.should_receive(:kill_worker).once.with(:KILL, 2)
|
|
139
|
+
|
|
140
|
+
@parameters.should_receive(:kill_worker).once.with(:KILL, 4)
|
|
141
|
+
|
|
142
|
+
@parameters.kill_each_worker_except 3
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
context 'worker pid not in the worker pids (unrealistic, but...)' do
|
|
146
|
+
before(:each) do
|
|
147
|
+
@parameters.stub! :worker_pids => [1,2,3,4]
|
|
148
|
+
end
|
|
149
|
+
it 'kills each except the one' do
|
|
150
|
+
@parameters.should_receive(:kill_worker).once.with(:KILL, 1)
|
|
151
|
+
@parameters.should_receive(:kill_worker).once.with(:KILL, 2)
|
|
152
|
+
@parameters.should_receive(:kill_worker).once.with(:KILL, 3)
|
|
153
|
+
@parameters.should_receive(:kill_worker).once.with(:KILL, 4)
|
|
154
|
+
|
|
155
|
+
@parameters.kill_each_worker_except 5
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end
|
data/spec/lib/loader_spec.rb
CHANGED
|
@@ -3,62 +3,102 @@ require 'spec_helper'
|
|
|
3
3
|
describe Picky::Loader do
|
|
4
4
|
|
|
5
5
|
before(:each) do
|
|
6
|
+
described_class.stub! :exclaim
|
|
6
7
|
@loader_path = File.absolute_path("#{File.dirname(__FILE__)}/../../lib/picky/loader.rb")
|
|
7
8
|
end
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
describe 'load self and framework' do
|
|
11
|
+
it 'it is quick' do
|
|
12
|
+
performance_of do
|
|
13
|
+
described_class.load_self
|
|
14
|
+
described_class.load_framework
|
|
15
|
+
end.should < 0.025
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
9
19
|
describe 'load_application' do
|
|
10
|
-
|
|
11
|
-
|
|
20
|
+
it 'does ok' do
|
|
21
|
+
Kernel.should_receive(:load).once.with 'spec/test_directory/app.rb'
|
|
22
|
+
|
|
23
|
+
lambda { described_class.load_application }.should_not raise_error
|
|
12
24
|
end
|
|
13
|
-
it
|
|
14
|
-
|
|
25
|
+
it 'loads correctly' do
|
|
26
|
+
described_class.should_receive(:load_user).once.with 'app'
|
|
27
|
+
|
|
28
|
+
described_class.load_application
|
|
29
|
+
end
|
|
30
|
+
it 'loads correctly' do
|
|
31
|
+
described_class.should_receive(:load_user).once.with 'special_app'
|
|
32
|
+
|
|
33
|
+
described_class.load_application 'special_app'
|
|
15
34
|
end
|
|
16
35
|
end
|
|
17
|
-
|
|
36
|
+
|
|
18
37
|
describe 'load_framework' do
|
|
19
38
|
before(:each) do
|
|
20
|
-
|
|
39
|
+
described_class.stub! :load_relative
|
|
21
40
|
end
|
|
22
|
-
it
|
|
23
|
-
lambda {
|
|
41
|
+
it 'does ok' do
|
|
42
|
+
lambda { described_class.load_framework }.should_not raise_error
|
|
24
43
|
end
|
|
25
44
|
end
|
|
26
|
-
|
|
45
|
+
|
|
27
46
|
describe 'load_self' do
|
|
28
47
|
before(:each) do
|
|
29
|
-
|
|
30
|
-
Picky::Loader.stub! :exclaim
|
|
48
|
+
described_class.stub! :load
|
|
31
49
|
end
|
|
32
50
|
after(:each) do
|
|
33
|
-
|
|
51
|
+
described_class.load_self
|
|
34
52
|
end
|
|
35
53
|
it 'should load __SELF__' do
|
|
36
|
-
|
|
54
|
+
Kernel.should_receive(:load).once.with @loader_path
|
|
37
55
|
end
|
|
38
56
|
end
|
|
39
57
|
|
|
40
58
|
describe 'reload' do
|
|
41
59
|
before(:each) do
|
|
42
60
|
load @loader_path
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
61
|
+
described_class.stub! :load_framework
|
|
62
|
+
described_class.stub! :load_application
|
|
63
|
+
Dir.stub! :chdir
|
|
64
|
+
end
|
|
65
|
+
it 'should call the right methods in order' do
|
|
66
|
+
described_class.should_receive(:load_self).ordered
|
|
67
|
+
described_class.should_receive(:load_framework).ordered
|
|
68
|
+
described_class.should_receive(:load_application).ordered
|
|
69
|
+
|
|
70
|
+
described_class.reload
|
|
71
|
+
end
|
|
72
|
+
it 'should load itself only once' do
|
|
73
|
+
described_class.should_receive(:load_self).once
|
|
74
|
+
|
|
75
|
+
described_class.reload
|
|
76
|
+
end
|
|
77
|
+
# it 'can load a specific app' do
|
|
78
|
+
# described_class.should_receive(:load_application).once.with 'special_app'
|
|
79
|
+
#
|
|
80
|
+
# described_class.reload 'special_app'
|
|
81
|
+
# end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe 'load' do
|
|
85
|
+
before(:each) do
|
|
86
|
+
load @loader_path
|
|
87
|
+
described_class.stub! :load_framework
|
|
88
|
+
described_class.stub! :load_application
|
|
46
89
|
Dir.stub! :chdir
|
|
47
90
|
end
|
|
48
91
|
after(:each) do
|
|
49
|
-
|
|
92
|
+
described_class.load
|
|
50
93
|
end
|
|
51
94
|
it 'should call the right methods in order' do
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
95
|
+
described_class.should_receive(:load_self).ordered
|
|
96
|
+
described_class.should_receive(:load_framework).ordered
|
|
97
|
+
described_class.should_receive(:load_application).ordered
|
|
55
98
|
end
|
|
56
99
|
it 'should load itself only once' do
|
|
57
|
-
|
|
100
|
+
described_class.should_receive(:load_self).once
|
|
58
101
|
end
|
|
59
|
-
# it 'should load the app only once' do
|
|
60
|
-
# Loader.should_receive(:load_framework).once
|
|
61
|
-
# end
|
|
62
102
|
end
|
|
63
103
|
|
|
64
104
|
end
|
|
@@ -1,30 +1,22 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Picky::Query::Allocation do
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
before(:each) do
|
|
6
6
|
@backend = stub :backend
|
|
7
7
|
@index = stub :index, :result_identifier => :some_result_identifier, :backend => @backend
|
|
8
8
|
@combinations = stub :combinations, :empty? => false
|
|
9
9
|
@allocation = described_class.new @index, @combinations
|
|
10
10
|
end
|
|
11
|
-
|
|
12
|
-
describe "eql?" do
|
|
13
|
-
# TODO This works, but is not acceptable.
|
|
14
|
-
#
|
|
15
|
-
it "returns true" do
|
|
16
|
-
@allocation.eql?(:anything).should == true
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
11
|
+
|
|
20
12
|
describe "hash" do
|
|
21
13
|
it "delegates to the combinations" do
|
|
22
14
|
@combinations.should_receive(:hash).once.with
|
|
23
|
-
|
|
15
|
+
|
|
24
16
|
@allocation.hash
|
|
25
17
|
end
|
|
26
18
|
end
|
|
27
|
-
|
|
19
|
+
|
|
28
20
|
describe "to_s" do
|
|
29
21
|
before(:each) do
|
|
30
22
|
@combinations.stub! :to_result => 'combinations_result'
|
|
@@ -40,15 +32,15 @@ describe Picky::Query::Allocation do
|
|
|
40
32
|
end
|
|
41
33
|
end
|
|
42
34
|
end
|
|
43
|
-
|
|
35
|
+
|
|
44
36
|
describe 'remove' do
|
|
45
37
|
it 'should delegate to the combinations' do
|
|
46
38
|
@combinations.should_receive(:remove).once.with [:some_categories]
|
|
47
|
-
|
|
39
|
+
|
|
48
40
|
@allocation.remove [:some_categories]
|
|
49
41
|
end
|
|
50
42
|
end
|
|
51
|
-
|
|
43
|
+
|
|
52
44
|
describe 'process!' do
|
|
53
45
|
context 'no ids' do
|
|
54
46
|
before(:each) do
|
|
@@ -130,7 +122,7 @@ describe Picky::Query::Allocation do
|
|
|
130
122
|
context 'with ids' do
|
|
131
123
|
it 'should output an array of information' do
|
|
132
124
|
@backend.stub! :ids => [1,2,3]
|
|
133
|
-
|
|
125
|
+
|
|
134
126
|
@allocation.process! 20, 0
|
|
135
127
|
|
|
136
128
|
@allocation.to_result.should == [:some_result_identifier, :some_score, 3, [:some_result], [1, 2, 3]]
|
|
@@ -148,7 +140,7 @@ describe Picky::Query::Allocation do
|
|
|
148
140
|
context 'with ids' do
|
|
149
141
|
it 'should output an array of information' do
|
|
150
142
|
@backend.stub! :ids => [1,2,3]
|
|
151
|
-
|
|
143
|
+
|
|
152
144
|
@allocation.process! 20, 0
|
|
153
145
|
|
|
154
146
|
@allocation.to_result.should == [:some_result_identifier, :some_score, 3, [:some_result1, :some_result2], [1, 2, 3]]
|
|
@@ -162,7 +154,7 @@ describe Picky::Query::Allocation do
|
|
|
162
154
|
end
|
|
163
155
|
it 'should return nil' do
|
|
164
156
|
@backend.stub! :ids => []
|
|
165
|
-
|
|
157
|
+
|
|
166
158
|
@allocation.process! 20, 0
|
|
167
159
|
|
|
168
160
|
@allocation.to_result.should == nil
|
|
@@ -177,7 +169,7 @@ describe Picky::Query::Allocation do
|
|
|
177
169
|
end
|
|
178
170
|
it 'should output the correct json string' do
|
|
179
171
|
@backend.stub! :ids => [1,2,3,4,5,6,7]
|
|
180
|
-
|
|
172
|
+
|
|
181
173
|
@allocation.process! 20, 0
|
|
182
174
|
|
|
183
175
|
@allocation.to_json.should == '["some_result_identifier","some_score",7,["some_result1","some_result2"],[1,2,3,4,5,6,7]]'
|
|
@@ -185,10 +177,21 @@ describe Picky::Query::Allocation do
|
|
|
185
177
|
end
|
|
186
178
|
|
|
187
179
|
describe "calculate_score" do
|
|
188
|
-
|
|
189
|
-
|
|
180
|
+
context 'non-empty combinations' do
|
|
181
|
+
it 'should delegate to backend and combinations' do
|
|
182
|
+
@backend.should_receive(:weight).once.with(@combinations).and_return 1
|
|
183
|
+
@combinations.should_receive(:weighted_score).once.with(:some_weights).and_return 2
|
|
190
184
|
|
|
191
|
-
|
|
185
|
+
@allocation.calculate_score(:some_weights).should == 3
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
context 'empty combinations' do
|
|
189
|
+
before(:each) do
|
|
190
|
+
@combinations.stub! :empty? => true
|
|
191
|
+
end
|
|
192
|
+
it 'should just be zero' do
|
|
193
|
+
@allocation.calculate_score(:some_weights).should == 0
|
|
194
|
+
end
|
|
192
195
|
end
|
|
193
196
|
end
|
|
194
197
|
|
|
@@ -6,78 +6,55 @@ describe Picky::Query::Combinations do
|
|
|
6
6
|
|
|
7
7
|
before(:each) do
|
|
8
8
|
@combinations_ary = stub :combinations_ary
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
@combinations = described_class.new @combinations_ary
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
describe "to_result" do
|
|
14
14
|
before(:each) do
|
|
15
15
|
@combination1 = stub :combination1, :to_result => :result1
|
|
16
16
|
@combination2 = stub :combination2, :to_result => :result2
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
@combinations_ary = [@combination1, @combination2]
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
@combinations = described_class.new @combinations_ary
|
|
21
21
|
end
|
|
22
22
|
it "resultifies the combinations" do
|
|
23
23
|
@combinations.to_result.should == [:result1, :result2]
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
describe "weighted_score" do
|
|
28
28
|
it "uses the weights' score method" do
|
|
29
29
|
weights = stub :weights
|
|
30
30
|
weights.should_receive(:score_for).once.with @combinations_ary
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
@combinations.weighted_score weights
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
describe "total_score" do
|
|
37
37
|
before(:each) do
|
|
38
38
|
@combination1 = stub :combination1, :weight => 3.14
|
|
39
39
|
@combination2 = stub :combination2, :weight => 2.76
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
@combinations_ary = [@combination1, @combination2]
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
@combinations = described_class.new @combinations_ary
|
|
44
44
|
end
|
|
45
45
|
it "sums the scores" do
|
|
46
|
-
@combinations.
|
|
46
|
+
@combinations.score.should == 5.90
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
|
|
50
|
-
describe "calculate_score" do
|
|
51
|
-
before(:each) do
|
|
52
|
-
@combinations.stub! :total_score => 0
|
|
53
|
-
@combinations.stub! :weighted_score => 0
|
|
54
|
-
end
|
|
55
|
-
it "first sums, then weighs" do
|
|
56
|
-
@combinations.should_receive(:total_score).once.ordered.and_return 0
|
|
57
|
-
@combinations.should_receive(:weighted_score).once.ordered.and_return 0
|
|
58
|
-
|
|
59
|
-
@combinations.calculate_score :anything
|
|
60
|
-
end
|
|
61
|
-
it "calls sum_score" do
|
|
62
|
-
@combinations.should_receive(:total_score).once.with.and_return 0
|
|
63
|
-
|
|
64
|
-
@combinations.calculate_score :anything
|
|
65
|
-
end
|
|
66
|
-
it "calls sum_score" do
|
|
67
|
-
@combinations.should_receive(:weighted_score).once.with(:weights).and_return 0
|
|
68
|
-
|
|
69
|
-
@combinations.calculate_score :weights
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
49
|
+
|
|
73
50
|
describe 'hash' do
|
|
74
51
|
it "delegates to the combinations array" do
|
|
75
52
|
@combinations_ary.should_receive(:hash).once.with
|
|
76
|
-
|
|
53
|
+
|
|
77
54
|
@combinations.hash
|
|
78
55
|
end
|
|
79
56
|
end
|
|
80
|
-
|
|
57
|
+
|
|
81
58
|
describe 'remove' do
|
|
82
59
|
before(:each) do
|
|
83
60
|
@combination1 = stub :combination1, :category => :other
|