picky 4.0.0pre6 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/picky/api/category/partial.rb +26 -0
- data/lib/picky/api/category/similarity.rb +26 -0
- data/lib/picky/api/category/weight.rb +26 -0
- data/lib/picky/api/search/boost.rb +28 -0
- data/lib/picky/api/source.rb +35 -0
- data/lib/picky/api/tokenizer/character_substituter.rb +22 -0
- data/lib/picky/api/tokenizer.rb +37 -0
- data/lib/picky/bundle.rb +1 -1
- data/lib/picky/bundle_realtime.rb +2 -2
- data/lib/picky/category.rb +12 -6
- data/lib/picky/category_indexing.rb +2 -8
- data/lib/picky/generators/similarity/double_metaphone.rb +1 -1
- data/lib/picky/generators/similarity/metaphone.rb +1 -1
- data/lib/picky/generators/similarity/none.rb +1 -1
- data/lib/picky/generators/similarity/soundex.rb +1 -1
- data/lib/picky/index_indexing.rb +5 -25
- data/lib/picky/loader.rb +15 -5
- data/lib/picky/query/allocation.rb +1 -1
- data/lib/picky/query/{weights.rb → boosts.rb} +17 -17
- data/lib/picky/query/combinations.rb +2 -2
- data/lib/picky/search.rb +17 -19
- data/lib/picky/tokenizer.rb +7 -4
- data/spec/lib/api/category/partial_spec.rb +49 -0
- data/spec/lib/api/category/similarity_spec.rb +50 -0
- data/spec/lib/api/category/weight_spec.rb +47 -0
- data/spec/lib/api/search/boost_spec.rb +44 -0
- data/spec/lib/api/source_spec.rb +68 -0
- data/spec/lib/api/tokenizer/character_substituter_spec.rb +34 -0
- data/spec/lib/api/tokenizer_spec.rb +42 -0
- data/spec/lib/category_indexed_spec.rb +2 -2
- data/spec/lib/category_indexing_spec.rb +11 -24
- data/spec/lib/category_spec.rb +48 -11
- data/spec/lib/generators/similarity/double_metaphone_spec.rb +1 -1
- data/spec/lib/generators/similarity/metaphone_spec.rb +1 -1
- data/spec/lib/generators/similarity/none_spec.rb +1 -1
- data/spec/lib/generators/similarity/soundex_spec.rb +1 -1
- data/spec/lib/index_indexing_spec.rb +10 -14
- data/spec/lib/index_spec.rb +1 -1
- data/spec/lib/query/allocation_spec.rb +2 -2
- data/spec/lib/query/boosts_spec.rb +79 -0
- data/spec/lib/query/combinations_spec.rb +3 -3
- data/spec/lib/search_spec.rb +13 -13
- data/spec/lib/tokenizer_spec.rb +12 -8
- metadata +44 -23
- data/spec/lib/query/weights_spec.rb +0 -81
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::API::Category::Partial do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Picky::API::Category::Partial
|
7
|
+
|
8
|
+
def index_name
|
9
|
+
:some_index
|
10
|
+
end
|
11
|
+
def name
|
12
|
+
:some_category
|
13
|
+
end
|
14
|
+
end.new
|
15
|
+
end
|
16
|
+
context 'extract_partial' do
|
17
|
+
context 'with nil' do
|
18
|
+
it 'returns the default' do
|
19
|
+
object.extract_partial(nil).should == Picky::Partial::Default
|
20
|
+
end
|
21
|
+
end
|
22
|
+
context 'with a partial object' do
|
23
|
+
let(:partializer) do
|
24
|
+
Class.new do
|
25
|
+
def each_partial text
|
26
|
+
'tex'
|
27
|
+
end
|
28
|
+
end.new
|
29
|
+
end
|
30
|
+
it 'yields the partial' do
|
31
|
+
object.extract_partial(partializer).each_partial('whatevs') do |text|
|
32
|
+
text.should == 'tex'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context 'invalid weight' do
|
37
|
+
it 'raises with a nice error message' do
|
38
|
+
expect {
|
39
|
+
object.extract_partial Object.new
|
40
|
+
}.to raise_error(<<-ERROR)
|
41
|
+
partial options for some_index:some_category should be either
|
42
|
+
* for example a Partial::Substring.new(from: m, to: n), Partial::Postfix.new(from: n), Partial::Infix.new(min: m, max: n) etc.
|
43
|
+
or
|
44
|
+
* an object that responds to #each_partial(str_or_sym) and yields each partial
|
45
|
+
ERROR
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::API::Category::Similarity do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Picky::API::Category::Similarity
|
7
|
+
|
8
|
+
def index_name
|
9
|
+
:some_index
|
10
|
+
end
|
11
|
+
def name
|
12
|
+
:some_category
|
13
|
+
end
|
14
|
+
end.new
|
15
|
+
end
|
16
|
+
context 'encode' do
|
17
|
+
context 'with nil' do
|
18
|
+
it 'returns the default' do
|
19
|
+
object.extract_similarity(nil).should == Picky::Similarity::Default
|
20
|
+
end
|
21
|
+
end
|
22
|
+
context 'with a similarity object' do
|
23
|
+
let(:similarizer) do
|
24
|
+
Class.new do
|
25
|
+
def encode text
|
26
|
+
:encoded
|
27
|
+
end
|
28
|
+
def prioritize ary, encoded
|
29
|
+
|
30
|
+
end
|
31
|
+
end.new
|
32
|
+
end
|
33
|
+
it 'returns the encoded string' do
|
34
|
+
object.extract_similarity(similarizer).encode('whatevs').should == :encoded
|
35
|
+
end
|
36
|
+
end
|
37
|
+
context 'invalid weight' do
|
38
|
+
it 'raises with a nice error message' do
|
39
|
+
expect {
|
40
|
+
object.extract_similarity Object.new
|
41
|
+
}.to raise_error(<<-ERROR)
|
42
|
+
similarity options for some_index:some_category should be either
|
43
|
+
* for example a Similarity::Phonetic.new(n), Similarity::Metaphone.new(n), Similarity::DoubleMetaphone.new(n) etc.
|
44
|
+
or
|
45
|
+
* an object that responds to #encode(text) => encoded_text and #prioritize(array_of_encoded, encoded)
|
46
|
+
ERROR
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::API::Category::Weight do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Picky::API::Category::Weight
|
7
|
+
|
8
|
+
def index_name
|
9
|
+
:some_index
|
10
|
+
end
|
11
|
+
def name
|
12
|
+
:some_category
|
13
|
+
end
|
14
|
+
end.new
|
15
|
+
end
|
16
|
+
context 'extract_weight' do
|
17
|
+
context 'with nil' do
|
18
|
+
it 'returns the default' do
|
19
|
+
object.extract_weight(nil).should == Picky::Weights::Default
|
20
|
+
end
|
21
|
+
end
|
22
|
+
context 'with a weight object' do
|
23
|
+
let(:weighter) do
|
24
|
+
Class.new do
|
25
|
+
def weight_for amount
|
26
|
+
7.0
|
27
|
+
end
|
28
|
+
end.new
|
29
|
+
end
|
30
|
+
it 'creates a tokenizer' do
|
31
|
+
object.extract_weight(weighter).weight_for(21).should == 7.0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
context 'invalid weight' do
|
35
|
+
it 'raises with a nice error message' do
|
36
|
+
expect {
|
37
|
+
object.extract_weight Object.new
|
38
|
+
}.to raise_error(<<-ERROR)
|
39
|
+
weight options for some_index:some_category should be either
|
40
|
+
* for example a Weights::Logarithmic.new, Weights::Constant.new(int = 0), Weights::Dynamic.new(&block) etc.
|
41
|
+
or
|
42
|
+
* an object that responds to #weight_for(amount_of_ids_for_token) => float
|
43
|
+
ERROR
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::API::Search::Boost do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Picky::API::Search::Boost
|
7
|
+
end.new
|
8
|
+
end
|
9
|
+
context 'extract_weight' do
|
10
|
+
context 'with a Hash' do
|
11
|
+
it 'returns a boosts object' do
|
12
|
+
combinations = [
|
13
|
+
stub(:combination, :category_name => :bla)
|
14
|
+
]
|
15
|
+
|
16
|
+
object.extract_boosts([:bla] => +7.77).boost_for(combinations).should == 7.77
|
17
|
+
end
|
18
|
+
end
|
19
|
+
context 'with a boosts object' do
|
20
|
+
let(:booster) do
|
21
|
+
Class.new do
|
22
|
+
def boost_for whatever
|
23
|
+
7.0
|
24
|
+
end
|
25
|
+
end.new
|
26
|
+
end
|
27
|
+
it 'returns a boosts object' do
|
28
|
+
object.extract_boosts(booster).boost_for(:anything).should == 7.0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
context 'invalid weight' do
|
32
|
+
it 'raises with a nice error message' do
|
33
|
+
expect {
|
34
|
+
object.extract_boosts Object.new
|
35
|
+
}.to raise_error(<<-ERROR)
|
36
|
+
boost options for a Search should be either
|
37
|
+
* for example a Hash { [:name, :surname] => +3 }
|
38
|
+
or
|
39
|
+
* an object that responds to #boost_for(combinations) and returns a boost float
|
40
|
+
ERROR
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::API::Source do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Picky::API::Source
|
7
|
+
end.new
|
8
|
+
end
|
9
|
+
context 'unblock_source' do
|
10
|
+
before(:each) do
|
11
|
+
class << object
|
12
|
+
def source_with source = nil, &block
|
13
|
+
@source = source || block
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
context 'with block' do
|
18
|
+
it 'unblocks' do
|
19
|
+
object.source_with do
|
20
|
+
:some_source
|
21
|
+
end
|
22
|
+
|
23
|
+
object.unblock_source == :some_source
|
24
|
+
end
|
25
|
+
end
|
26
|
+
context 'with #each' do
|
27
|
+
it 'takes the source directly' do
|
28
|
+
object.source_with :some_source
|
29
|
+
|
30
|
+
object.unblock_source == :some_source
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
context 'extract_source' do
|
35
|
+
context 'block with source hash' do
|
36
|
+
it 'extracts a source' do
|
37
|
+
object.extract_source(Proc.new {}).should be_kind_of(Proc)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
context 'each source' do
|
41
|
+
let(:source) do
|
42
|
+
Class.new do
|
43
|
+
def each
|
44
|
+
|
45
|
+
end
|
46
|
+
end.new
|
47
|
+
end
|
48
|
+
it 'extracts a source' do
|
49
|
+
object.extract_source(source).should == source
|
50
|
+
end
|
51
|
+
end
|
52
|
+
context 'invalid tokenizer' do
|
53
|
+
it 'raises with a nice error message' do
|
54
|
+
expect {
|
55
|
+
object.extract_source Object.new
|
56
|
+
}.to raise_error(<<-ERROR)
|
57
|
+
The source should respond to either the method #each or
|
58
|
+
it can be a lambda/block, returning such a source.
|
59
|
+
ERROR
|
60
|
+
end
|
61
|
+
end
|
62
|
+
context 'with nil_ok option' do
|
63
|
+
it 'simply returns nil back' do
|
64
|
+
object.extract_source(nil, nil_ok: true).should == nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::API::Tokenizer do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Picky::API::Tokenizer::CharacterSubstituter
|
7
|
+
end.new
|
8
|
+
end
|
9
|
+
context 'extract_character_substituter' do
|
10
|
+
context 'with a substituter' do
|
11
|
+
let(:substituter) do
|
12
|
+
Class.new do
|
13
|
+
def substitute text
|
14
|
+
text.tr('a-z', '1-9')
|
15
|
+
end
|
16
|
+
end.new
|
17
|
+
end
|
18
|
+
it 'creates a tokenizer' do
|
19
|
+
object.extract_character_substituter(substituter).
|
20
|
+
substitute("picky").should == '99399'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context 'invalid tokenizer' do
|
24
|
+
it 'raises with a nice error message' do
|
25
|
+
expect {
|
26
|
+
object.extract_character_substituter Object.new
|
27
|
+
}.to raise_error(<<-ERROR)
|
28
|
+
The substitutes_characters_with option needs a character substituter,
|
29
|
+
which responds to #substitute(text) and returns substituted_text."
|
30
|
+
ERROR
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::API::Tokenizer do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Picky::API::Tokenizer
|
7
|
+
end.new
|
8
|
+
end
|
9
|
+
context 'extract_tokenizer' do
|
10
|
+
context 'options hash' do
|
11
|
+
it 'creates a tokenizer' do
|
12
|
+
object.extract_tokenizer(indexing: { splits_text_on: /\t/ }).
|
13
|
+
tokenize("hello\tworld").should == [['hello', 'world'], ['hello', 'world']]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context 'tokenizer' do
|
17
|
+
let(:tokenizer) do
|
18
|
+
Class.new do
|
19
|
+
def tokenize text
|
20
|
+
['unmoved', 'by', 'your', 'texts']
|
21
|
+
end
|
22
|
+
end.new
|
23
|
+
end
|
24
|
+
it 'creates a tokenizer' do
|
25
|
+
object.extract_tokenizer(tokenizer).
|
26
|
+
tokenize("hello\tworld").should == ['unmoved', 'by', 'your', 'texts']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
context 'invalid tokenizer' do
|
30
|
+
it 'raises with a nice error message' do
|
31
|
+
expect {
|
32
|
+
object.extract_tokenizer Object.new
|
33
|
+
}.to raise_error(<<-ERROR)
|
34
|
+
indexing options should be either
|
35
|
+
* a Hash
|
36
|
+
or
|
37
|
+
* an object that responds to #tokenize(text) => [[token1, ...], [original1, ...]]
|
38
|
+
ERROR
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -6,9 +6,9 @@ describe Picky::Category do
|
|
6
6
|
@index = Picky::Index.new :some_index do
|
7
7
|
source []
|
8
8
|
end
|
9
|
-
@partial_strategy = stub :partial, :use_exact_for_partial? => false
|
9
|
+
@partial_strategy = stub :partial, :each_partial => nil, :use_exact_for_partial? => false
|
10
10
|
@weight_strategy = stub :weights, :saved? => true
|
11
|
-
@similarity_strategy = stub :similarity
|
11
|
+
@similarity_strategy = stub :similarity, :encode => nil, :prioritize => nil
|
12
12
|
|
13
13
|
@exact = stub :exact, :dump => nil
|
14
14
|
@partial = stub :partial, :dump => nil
|
@@ -4,7 +4,7 @@ describe Picky::Category do
|
|
4
4
|
|
5
5
|
before(:each) do
|
6
6
|
@index = Picky::Index.new :some_index
|
7
|
-
@source = stub :some_given_source, :
|
7
|
+
@source = stub :some_given_source, :each => nil
|
8
8
|
end
|
9
9
|
let(:category) { described_class.new(:some_category, @index, :source => @source).tap { |c| c.stub! :timed_exclaim } }
|
10
10
|
|
@@ -70,37 +70,24 @@ describe Picky::Category do
|
|
70
70
|
end
|
71
71
|
|
72
72
|
describe 'key_format' do
|
73
|
-
context '
|
73
|
+
context 'category has its own key_format' do
|
74
74
|
before(:each) do
|
75
|
-
category.
|
75
|
+
category.instance_variable_set :@key_format, :other_key_format
|
76
76
|
end
|
77
77
|
it 'returns that key_format' do
|
78
|
-
category.key_format.should == :
|
78
|
+
category.key_format.should == :other_key_format
|
79
79
|
end
|
80
80
|
end
|
81
|
-
context '
|
81
|
+
context 'category does not have its own key format' do
|
82
82
|
before(:each) do
|
83
|
-
category.
|
83
|
+
category.instance_variable_set :@key_format, nil
|
84
84
|
end
|
85
|
-
context '
|
85
|
+
context 'it has an index' do
|
86
86
|
before(:each) do
|
87
|
-
category.instance_variable_set :@
|
87
|
+
category.instance_variable_set :@index, stub(:index, :key_format => :yet_another_key_format)
|
88
88
|
end
|
89
89
|
it 'returns that key_format' do
|
90
|
-
category.key_format.should == :
|
91
|
-
end
|
92
|
-
end
|
93
|
-
context 'category does not have its own key format' do
|
94
|
-
before(:each) do
|
95
|
-
category.instance_variable_set :@key_format, nil
|
96
|
-
end
|
97
|
-
context 'it has an index' do
|
98
|
-
before(:each) do
|
99
|
-
category.instance_variable_set :@index, stub(:index, :key_format => :yet_another_key_format)
|
100
|
-
end
|
101
|
-
it 'returns that key_format' do
|
102
|
-
category.key_format.should == :yet_another_key_format
|
103
|
-
end
|
90
|
+
category.key_format.should == :yet_another_key_format
|
104
91
|
end
|
105
92
|
end
|
106
93
|
end
|
@@ -108,9 +95,9 @@ describe Picky::Category do
|
|
108
95
|
|
109
96
|
describe 'source' do
|
110
97
|
context 'with explicit source' do
|
111
|
-
let(:category) { described_class.new(:some_category, @index, :source =>
|
98
|
+
let(:category) { described_class.new(:some_category, @index, :source => [1]) }
|
112
99
|
it 'returns the right source' do
|
113
|
-
category.source.should ==
|
100
|
+
category.source.should == [1]
|
114
101
|
end
|
115
102
|
end
|
116
103
|
context 'without explicit source' do
|
data/spec/lib/category_spec.rb
CHANGED
@@ -3,22 +3,59 @@ require 'spec_helper'
|
|
3
3
|
describe Picky::Category do
|
4
4
|
|
5
5
|
let(:index) { Picky::Index.new :some_index }
|
6
|
-
let(:category) { described_class.new :some_category, index }
|
7
6
|
|
8
|
-
|
9
|
-
category.
|
10
|
-
category.exact.partial_strategy.should be_kind_of(Picky::Generators::Partial::None)
|
11
|
-
category.exact.similarity_strategy.should == Picky::Generators::Similarity::Default
|
7
|
+
context 'default parameters' do
|
8
|
+
let(:category) { described_class.new :some_category, index }
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
it 'should set defaults correctly' do
|
11
|
+
category.exact.weight_strategy.should == Picky::Generators::Weights::Default
|
12
|
+
category.exact.partial_strategy.should be_kind_of(Picky::Generators::Partial::None)
|
13
|
+
category.exact.similarity_strategy.should == Picky::Generators::Similarity::Default
|
16
14
|
|
17
|
-
|
15
|
+
category.partial.weight_strategy.should be_kind_of(Picky::Generators::Weights::Logarithmic)
|
16
|
+
category.partial.partial_strategy.should == Picky::Generators::Partial::Default
|
17
|
+
category.partial.similarity_strategy.should be_kind_of(Picky::Generators::Similarity::None)
|
18
18
|
|
19
|
-
|
19
|
+
category.exact.similarity_strategy.should == Picky::Generators::Similarity::Default
|
20
20
|
|
21
|
-
|
21
|
+
category.partial.similarity_strategy.should be_kind_of(Picky::Generators::Similarity::None)
|
22
|
+
|
23
|
+
category.instance_variable_get(:@symbols).should == nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'tokenizer' do
|
28
|
+
context 'options hash' do
|
29
|
+
let(:category) { described_class.new :some_category, index, indexing: { splits_text_on: /\t/ } }
|
30
|
+
it 'creates a tokenizer' do
|
31
|
+
category.tokenizer.tokenize("hello\tworld").should == [['hello', 'world'], ['hello', 'world']]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
context 'tokenizer' do
|
35
|
+
let(:tokenizer) do
|
36
|
+
Class.new do
|
37
|
+
def tokenize text
|
38
|
+
['unmoved', 'by', 'your', 'texts']
|
39
|
+
end
|
40
|
+
end.new
|
41
|
+
end
|
42
|
+
let(:category) { described_class.new :some_category, index, indexing: tokenizer }
|
43
|
+
it 'creates a tokenizer' do
|
44
|
+
category.tokenizer.tokenize("hello\tworld").should == ['unmoved', 'by', 'your', 'texts']
|
45
|
+
end
|
46
|
+
end
|
47
|
+
context 'invalid tokenizer' do
|
48
|
+
it 'raises with a nice error message' do
|
49
|
+
expect {
|
50
|
+
described_class.new :some_category, index, indexing: Object.new
|
51
|
+
}.to raise_error(<<-ERROR)
|
52
|
+
indexing options for some_index:some_category should be either
|
53
|
+
* a Hash
|
54
|
+
or
|
55
|
+
* an object that responds to #tokenize(text) => [[token1, ...], [original1, ...]]
|
56
|
+
ERROR
|
57
|
+
end
|
58
|
+
end
|
22
59
|
end
|
23
60
|
|
24
61
|
end
|
@@ -10,7 +10,7 @@ describe Picky::Generators::Similarity::DoubleMetaphone do
|
|
10
10
|
|
11
11
|
def self.it_should_encode text, expected
|
12
12
|
it "should encode #{text.inspect} correctly" do
|
13
|
-
@similarity.
|
13
|
+
@similarity.encode(text).should == expected
|
14
14
|
end
|
15
15
|
end
|
16
16
|
# def self.it_should_generate_from index, expected
|
@@ -10,7 +10,7 @@ describe Picky::Generators::Similarity::Metaphone do
|
|
10
10
|
|
11
11
|
def self.it_should_encode text, expected
|
12
12
|
it "should encode #{text.inspect} correctly" do
|
13
|
-
@similarity.
|
13
|
+
@similarity.encode(text).should == expected
|
14
14
|
end
|
15
15
|
end
|
16
16
|
# def self.it_should_generate_from index, expected
|
@@ -10,7 +10,7 @@ describe Picky::Generators::Similarity::Soundex do
|
|
10
10
|
|
11
11
|
def self.it_should_encode text, expected
|
12
12
|
it "should encode #{text.inspect} correctly" do
|
13
|
-
@similarity.
|
13
|
+
@similarity.encode(text).should == expected
|
14
14
|
end
|
15
15
|
end
|
16
16
|
# def self.it_should_generate_from index, expected
|
@@ -69,21 +69,17 @@ describe Picky::Index do
|
|
69
69
|
end
|
70
70
|
context 'with non#each source' do
|
71
71
|
let(:source) { stub :source, :harvest => nil }
|
72
|
-
let(:index) do
|
73
|
-
the_source = source
|
74
|
-
described_class.new :some_name do
|
75
|
-
source the_source
|
76
|
-
end
|
77
|
-
end
|
78
72
|
|
79
|
-
it '
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
73
|
+
it 'raises' do
|
74
|
+
the_source = source
|
75
|
+
expect {
|
76
|
+
described_class.new :some_name do
|
77
|
+
source the_source
|
78
|
+
end
|
79
|
+
}.to raise_error(<<-ERROR)
|
80
|
+
The some_name source should respond to either the method #each or
|
81
|
+
it can be a lambda/block, returning such a source.
|
82
|
+
ERROR
|
87
83
|
end
|
88
84
|
end
|
89
85
|
end
|
data/spec/lib/index_spec.rb
CHANGED
@@ -180,9 +180,9 @@ describe Picky::Query::Allocation do
|
|
180
180
|
context 'non-empty combinations' do
|
181
181
|
it 'should delegate to backend and combinations' do
|
182
182
|
@backend.should_receive(:weight).once.with(@combinations).and_return 1
|
183
|
-
@combinations.should_receive(:
|
183
|
+
@combinations.should_receive(:boost_for).once.with(:some_boosts).and_return 2
|
184
184
|
|
185
|
-
@allocation.calculate_score(:
|
185
|
+
@allocation.calculate_score(:some_boosts).should == 3
|
186
186
|
end
|
187
187
|
end
|
188
188
|
context 'empty combinations' do
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Picky::Query::Boosts do
|
4
|
+
|
5
|
+
context 'with boosts' do
|
6
|
+
let(:boosts) do
|
7
|
+
described_class.new [:test1, :test2] => 6,
|
8
|
+
[:test1] => 5,
|
9
|
+
[:test3] => 3,
|
10
|
+
[:test3, :test2] => 4,
|
11
|
+
[:test1, :test4] => 5,
|
12
|
+
[:test4, :test1] => 5,
|
13
|
+
[:test4, :test1, :test2] => 4,
|
14
|
+
[:test1, :test4, :test2] => 4,
|
15
|
+
[:test4, :test5] => 3,
|
16
|
+
[:test5, :test1] => 2,
|
17
|
+
[:test1, :test5] => 2,
|
18
|
+
[:test3, :test1] => 2,
|
19
|
+
[:test1, :test3] => 2
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'boost_for' do
|
23
|
+
it 'gets the category names from the combinations' do
|
24
|
+
combinations = [
|
25
|
+
stub(:combination1, :category_name => :test1),
|
26
|
+
stub(:combination1, :category_name => :test2)
|
27
|
+
]
|
28
|
+
|
29
|
+
boosts.boost_for(combinations).should == +6
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "weight_for" do
|
34
|
+
it "should return zero if there is no specific weight" do
|
35
|
+
boosts.boost_for_categories([:not_a_specific_allocation]).should be_zero
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.it_should_return_a_specific_boost_for(allocation, boost)
|
40
|
+
it "should return boost #{boost} for #{allocation.inspect}" do
|
41
|
+
boosts.boost_for_categories(allocation).should == boost
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it_should_return_a_specific_boost_for [:test1, :test2], 6
|
46
|
+
it_should_return_a_specific_boost_for [:test1], 5
|
47
|
+
it_should_return_a_specific_boost_for [:test1, :test3], 2
|
48
|
+
it_should_return_a_specific_boost_for [:test3], 3
|
49
|
+
it_should_return_a_specific_boost_for [:test3, :test2], 4
|
50
|
+
it_should_return_a_specific_boost_for [:test1, :test4], 5
|
51
|
+
it_should_return_a_specific_boost_for [:test4, :test1], 5
|
52
|
+
it_should_return_a_specific_boost_for [:test4, :test1, :test2], 4
|
53
|
+
it_should_return_a_specific_boost_for [:test1, :test4, :test2], 4
|
54
|
+
it_should_return_a_specific_boost_for [:test4, :test5], 3
|
55
|
+
it_should_return_a_specific_boost_for [:test5, :test1], 2
|
56
|
+
it_should_return_a_specific_boost_for [:test1, :test5], 2
|
57
|
+
it_should_return_a_specific_boost_for [:test3, :test1], 2
|
58
|
+
|
59
|
+
describe 'to_s' do
|
60
|
+
it 'is correct' do
|
61
|
+
boosts.to_s.should == "Picky::Query::Boosts({[:test1, :test2]=>6, [:test1]=>5, [:test3]=>3, [:test3, :test2]=>4, [:test1, :test4]=>5, [:test4, :test1]=>5, [:test4, :test1, :test2]=>4, [:test1, :test4, :test2]=>4, [:test4, :test5]=>3, [:test5, :test1]=>2, [:test1, :test5]=>2, [:test3, :test1]=>2, [:test1, :test3]=>2})"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
describe 'empty?' do
|
65
|
+
it 'is correct' do
|
66
|
+
boosts.empty?.should == false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
context 'without boosts' do
|
71
|
+
let(:boosts) { described_class.new }
|
72
|
+
describe 'empty?' do
|
73
|
+
it 'is correct' do
|
74
|
+
boosts.empty?.should == true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|