picky 0.0.0 → 0.0.2

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 (161) hide show
  1. data/bin/picky +14 -0
  2. data/lib/bundling.rb +10 -0
  3. data/lib/constants.rb +9 -0
  4. data/lib/deployment.rb +212 -0
  5. data/lib/picky/application.rb +40 -0
  6. data/lib/picky/cacher/convenience.rb +3 -0
  7. data/lib/picky/cacher/generator.rb +17 -0
  8. data/lib/picky/cacher/partial/default.rb +7 -0
  9. data/lib/picky/cacher/partial/none.rb +19 -0
  10. data/lib/picky/cacher/partial/strategy.rb +7 -0
  11. data/lib/picky/cacher/partial/subtoken.rb +91 -0
  12. data/lib/picky/cacher/partial_generator.rb +15 -0
  13. data/lib/picky/cacher/similarity/default.rb +7 -0
  14. data/lib/picky/cacher/similarity/double_levenshtone.rb +73 -0
  15. data/lib/picky/cacher/similarity/none.rb +25 -0
  16. data/lib/picky/cacher/similarity/strategy.rb +7 -0
  17. data/lib/picky/cacher/similarity_generator.rb +15 -0
  18. data/lib/picky/cacher/weights/default.rb +7 -0
  19. data/lib/picky/cacher/weights/logarithmic.rb +39 -0
  20. data/lib/picky/cacher/weights/strategy.rb +7 -0
  21. data/lib/picky/cacher/weights_generator.rb +15 -0
  22. data/lib/picky/configuration/configuration.rb +13 -0
  23. data/lib/picky/configuration/field.rb +68 -0
  24. data/lib/picky/configuration/indexes.rb +60 -0
  25. data/lib/picky/configuration/queries.rb +32 -0
  26. data/lib/picky/configuration/type.rb +52 -0
  27. data/lib/picky/cores.rb +101 -0
  28. data/lib/picky/db/configuration.rb +23 -0
  29. data/lib/picky/ext/ruby19/extconf.rb +7 -0
  30. data/lib/picky/ext/ruby19/performant.c +339 -0
  31. data/lib/picky/extensions/array.rb +45 -0
  32. data/lib/picky/extensions/hash.rb +11 -0
  33. data/lib/picky/extensions/module.rb +15 -0
  34. data/lib/picky/extensions/symbol.rb +18 -0
  35. data/lib/picky/generator.rb +156 -0
  36. data/lib/picky/helpers/cache.rb +23 -0
  37. data/lib/picky/helpers/gc.rb +11 -0
  38. data/lib/picky/helpers/measuring.rb +45 -0
  39. data/lib/picky/helpers/search.rb +27 -0
  40. data/lib/picky/index/bundle.rb +328 -0
  41. data/lib/picky/index/category.rb +109 -0
  42. data/lib/picky/index/combined.rb +38 -0
  43. data/lib/picky/index/type.rb +30 -0
  44. data/lib/picky/indexers/base.rb +77 -0
  45. data/lib/picky/indexers/default.rb +3 -0
  46. data/lib/picky/indexers/field.rb +13 -0
  47. data/lib/picky/indexers/no_source_specified_error.rb +5 -0
  48. data/lib/picky/indexers/solr.rb +60 -0
  49. data/lib/picky/indexes.rb +180 -0
  50. data/lib/picky/initializers/ext.rb +6 -0
  51. data/lib/picky/initializers/mysql.rb +22 -0
  52. data/lib/picky/loader.rb +287 -0
  53. data/lib/picky/loggers/search.rb +19 -0
  54. data/lib/picky/performant/array.rb +23 -0
  55. data/lib/picky/query/allocation.rb +82 -0
  56. data/lib/picky/query/allocations.rb +131 -0
  57. data/lib/picky/query/base.rb +124 -0
  58. data/lib/picky/query/combination.rb +69 -0
  59. data/lib/picky/query/combinations.rb +106 -0
  60. data/lib/picky/query/combinator.rb +92 -0
  61. data/lib/picky/query/full.rb +15 -0
  62. data/lib/picky/query/live.rb +22 -0
  63. data/lib/picky/query/qualifiers.rb +73 -0
  64. data/lib/picky/query/solr.rb +77 -0
  65. data/lib/picky/query/token.rb +215 -0
  66. data/lib/picky/query/tokens.rb +102 -0
  67. data/lib/picky/query/weigher.rb +159 -0
  68. data/lib/picky/query/weights.rb +55 -0
  69. data/lib/picky/rack/harakiri.rb +37 -0
  70. data/lib/picky/results/base.rb +103 -0
  71. data/lib/picky/results/full.rb +19 -0
  72. data/lib/picky/results/live.rb +19 -0
  73. data/lib/picky/routing.rb +165 -0
  74. data/lib/picky/signals.rb +11 -0
  75. data/lib/picky/solr/schema_generator.rb +73 -0
  76. data/lib/picky/sources/base.rb +19 -0
  77. data/lib/picky/sources/csv.rb +30 -0
  78. data/lib/picky/sources/db.rb +77 -0
  79. data/lib/picky/tokenizers/base.rb +130 -0
  80. data/lib/picky/tokenizers/default.rb +3 -0
  81. data/lib/picky/tokenizers/index.rb +73 -0
  82. data/lib/picky/tokenizers/query.rb +70 -0
  83. data/lib/picky/umlaut_substituter.rb +21 -0
  84. data/lib/picky-tasks.rb +6 -0
  85. data/lib/picky.rb +18 -0
  86. data/lib/tasks/application.rake +5 -0
  87. data/lib/tasks/cache.rake +53 -0
  88. data/lib/tasks/framework.rake +4 -0
  89. data/lib/tasks/index.rake +29 -0
  90. data/lib/tasks/server.rake +48 -0
  91. data/lib/tasks/shortcuts.rake +13 -0
  92. data/lib/tasks/solr.rake +36 -0
  93. data/lib/tasks/spec.rake +11 -0
  94. data/lib/tasks/statistics.rake +13 -0
  95. data/lib/tasks/try.rake +29 -0
  96. data/prototype_project/Gemfile +23 -0
  97. data/prototype_project/Rakefile +1 -0
  98. data/prototype_project/app/README +6 -0
  99. data/prototype_project/app/application.rb +50 -0
  100. data/prototype_project/app/application.ru +29 -0
  101. data/prototype_project/app/db.yml +10 -0
  102. data/prototype_project/app/logging.rb +20 -0
  103. data/prototype_project/app/unicorn.ru +10 -0
  104. data/prototype_project/log/README +1 -0
  105. data/prototype_project/script/console +34 -0
  106. data/prototype_project/tmp/README +0 -0
  107. data/prototype_project/tmp/pids/README +0 -0
  108. data/spec/ext/performant_spec.rb +64 -0
  109. data/spec/lib/application_spec.rb +61 -0
  110. data/spec/lib/cacher/partial/subtoken_spec.rb +89 -0
  111. data/spec/lib/cacher/partial_generator_spec.rb +35 -0
  112. data/spec/lib/cacher/similarity/double_levenshtone_spec.rb +60 -0
  113. data/spec/lib/cacher/similarity/none_spec.rb +23 -0
  114. data/spec/lib/cacher/similarity_generator_spec.rb +22 -0
  115. data/spec/lib/cacher/weights/logarithmic_spec.rb +30 -0
  116. data/spec/lib/cacher/weights_generator_spec.rb +21 -0
  117. data/spec/lib/configuration/configuration_spec.rb +38 -0
  118. data/spec/lib/configuration/type_spec.rb +49 -0
  119. data/spec/lib/configuration_spec.rb +8 -0
  120. data/spec/lib/cores_spec.rb +65 -0
  121. data/spec/lib/extensions/array_spec.rb +37 -0
  122. data/spec/lib/extensions/hash_spec.rb +11 -0
  123. data/spec/lib/extensions/module_spec.rb +27 -0
  124. data/spec/lib/extensions/symbol_spec.rb +85 -0
  125. data/spec/lib/generator_spec.rb +135 -0
  126. data/spec/lib/helpers/cache_spec.rb +35 -0
  127. data/spec/lib/helpers/gc_spec.rb +71 -0
  128. data/spec/lib/helpers/measuring_spec.rb +18 -0
  129. data/spec/lib/helpers/search_spec.rb +50 -0
  130. data/spec/lib/index/bundle_partial_generation_speed_spec.rb +47 -0
  131. data/spec/lib/index/bundle_spec.rb +260 -0
  132. data/spec/lib/index/category_spec.rb +203 -0
  133. data/spec/lib/indexers/base_spec.rb +73 -0
  134. data/spec/lib/indexers/field_spec.rb +20 -0
  135. data/spec/lib/loader_spec.rb +48 -0
  136. data/spec/lib/loggers/search_spec.rb +19 -0
  137. data/spec/lib/performant/array_spec.rb +13 -0
  138. data/spec/lib/query/allocation_spec.rb +194 -0
  139. data/spec/lib/query/allocations_spec.rb +336 -0
  140. data/spec/lib/query/base_spec.rb +104 -0
  141. data/spec/lib/query/combination_spec.rb +90 -0
  142. data/spec/lib/query/combinations_spec.rb +83 -0
  143. data/spec/lib/query/combinator_spec.rb +112 -0
  144. data/spec/lib/query/full_spec.rb +22 -0
  145. data/spec/lib/query/live_spec.rb +61 -0
  146. data/spec/lib/query/qualifiers_spec.rb +31 -0
  147. data/spec/lib/query/solr_spec.rb +51 -0
  148. data/spec/lib/query/token_spec.rb +297 -0
  149. data/spec/lib/query/tokens_spec.rb +189 -0
  150. data/spec/lib/query/weights_spec.rb +47 -0
  151. data/spec/lib/results/base_spec.rb +233 -0
  152. data/spec/lib/routing_spec.rb +318 -0
  153. data/spec/lib/solr/schema_generator_spec.rb +42 -0
  154. data/spec/lib/sources/db_spec.rb +91 -0
  155. data/spec/lib/tokenizers/base_spec.rb +61 -0
  156. data/spec/lib/tokenizers/index_spec.rb +51 -0
  157. data/spec/lib/tokenizers/query_spec.rb +105 -0
  158. data/spec/lib/umlaut_substituter_spec.rb +84 -0
  159. data/spec/specific/speed_spec.rb +55 -0
  160. metadata +371 -15
  161. data/README.textile +0 -9
@@ -0,0 +1,297 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Query::Token do
5
+
6
+ before(:all) do
7
+ Query::Qualifiers.instance << Query::Qualifier.new(:specific, [:sp, :spec])
8
+ Query::Qualifiers.instance.prepare
9
+ end
10
+
11
+ describe 'to_solr' do
12
+ def self.it_should_solr text, expected_result
13
+ it "should solrify into #{expected_result} from #{text}" do
14
+ Query::Token.processed(text).to_solr.should == expected_result
15
+ end
16
+ end
17
+ it_should_solr 's', 's'
18
+ it_should_solr 'se', 'se'
19
+ it_should_solr 'sea', 'sea'
20
+ it_should_solr 'sear', 'sear~0.74'
21
+ it_should_solr 'searc', 'searc~0.78'
22
+ it_should_solr 'search', 'search~0.81'
23
+ it_should_solr 'searche', 'searche~0.83'
24
+ it_should_solr 'searchen', 'searchen~0.85'
25
+ it_should_solr 'searcheng', 'searcheng~0.87'
26
+ it_should_solr 'searchengi', 'searchengi~0.89'
27
+ it_should_solr 'searchengin', 'searchengin~0.9'
28
+ it_should_solr 'searchengine', 'searchengine~0.9'
29
+
30
+ it_should_solr 'spec:tex', 'specific:tex'
31
+ it_should_solr 'with:text', 'text~0.74'
32
+ it_should_solr 'name:', 'name~0.74'
33
+ it_should_solr '', ''
34
+ it_should_solr 'sp:tex', 'specific:tex'
35
+ it_should_solr 'sp:tex~', 'specific:tex'
36
+ it_should_solr 'sp:tex"', 'specific:tex'
37
+ end
38
+
39
+ describe 'qualify' do
40
+ def self.it_should_qualify text, expected_result
41
+ it "should extract the qualifier #{expected_result} from #{text}" do
42
+ Query::Token.new(text).qualify.should == expected_result
43
+ end
44
+ end
45
+ it_should_qualify 'spec:qualifier', :specific
46
+ it_should_qualify 'with:qualifier', nil
47
+ it_should_qualify 'without qualifier', nil
48
+ it_should_qualify 'name:', nil
49
+ it_should_qualify ':broken qualifier', nil
50
+ it_should_qualify '', nil
51
+ it_should_qualify 'sp:text', :specific
52
+ end
53
+
54
+ describe 'processed' do
55
+ it 'should have an order' do
56
+ token = stub :token
57
+ Query::Token.should_receive(:new).once.and_return token
58
+
59
+ token.should_receive(:qualify).once.ordered
60
+ token.should_receive(:extract_original).once.ordered
61
+ token.should_receive(:partialize).once.ordered
62
+ token.should_receive(:similarize).once.ordered
63
+ token.should_receive(:remove_illegals).once.ordered
64
+
65
+ Query::Token.processed :any_text
66
+ end
67
+ it 'should return a new token' do
68
+ Query::Token.processed('some text').should be_kind_of(Query::Token)
69
+ end
70
+ end
71
+
72
+ describe 'partial?' do
73
+ context 'similar, partial' do
74
+ before(:each) do
75
+ @token = Query::Token.processed 'similar~'
76
+ @token.partial = true
77
+ end
78
+ it 'should be false' do
79
+ @token.partial?.should == false
80
+ end
81
+ end
82
+ context 'similar, not partial' do
83
+ before(:each) do
84
+ @token = Query::Token.processed 'similar~'
85
+ end
86
+ it 'should be false' do
87
+ @token.partial?.should == false
88
+ end
89
+ end
90
+ context 'not similar, partial' do
91
+ before(:each) do
92
+ @token = Query::Token.processed 'not similar'
93
+ @token.partial = true
94
+ end
95
+ it 'should be true' do
96
+ @token.partial?.should == true
97
+ end
98
+ end
99
+ context 'not similar, not partial' do
100
+ before(:each) do
101
+ @token = Query::Token.processed 'not similar'
102
+ end
103
+ it 'should be nil' do
104
+ @token.partial?.should == nil
105
+ end
106
+ end
107
+ end
108
+
109
+ describe 'similar' do
110
+ it 'should not change the original with the text' do
111
+ token = Query::Token.processed "bla~"
112
+ token.text.should_not == token.original
113
+ end
114
+ def self.it_should_have_similarity text, expected_similarity_value
115
+ it "should have #{ "no" unless expected_similarity_value } similarity for '#{text}'" do
116
+ Query::Token.processed(text).similar?.should == expected_similarity_value
117
+ end
118
+ end
119
+ it_should_have_similarity 'name:', nil
120
+ it_should_have_similarity 'name:hanke', nil
121
+ it_should_have_similarity 'g:gaga', nil
122
+ it_should_have_similarity ':nothing', nil
123
+ it_should_have_similarity 'hello', nil
124
+ it_should_have_similarity 'a:b:c', nil
125
+
126
+ it_should_have_similarity '""', false
127
+ it_should_have_similarity '"exact~"', false # The tilde will just be removed
128
+
129
+ it_should_have_similarity '~', true
130
+ it_should_have_similarity '"hello"~', true # overrides the ""
131
+ it_should_have_similarity 'philippe~', true
132
+ end
133
+
134
+ describe 'special cases' do
135
+ it 'should be blank on ""' do
136
+ token = Query::Token.processed '""'
137
+
138
+ token.should be_blank
139
+ end
140
+ end
141
+
142
+ describe 'split' do
143
+ def self.it_should_split text, expected_qualifier
144
+ it "should extract #{expected_qualifier} from #{text}" do
145
+ Query::Token.new('any').send(:split, text).should == expected_qualifier
146
+ end
147
+ end
148
+ it_should_split '""', [nil, '""']
149
+ it_should_split 'name:', [nil, 'name']
150
+ it_should_split 'name:hanke', ['name', 'hanke']
151
+ it_should_split 'g:gaga', ['g', 'gaga']
152
+ it_should_split ':nothing', ['', 'nothing']
153
+ it_should_split 'hello', [nil, 'hello']
154
+ it_should_split 'a:b:c', ['a', 'b:c']
155
+ end
156
+
157
+ describe "original" do
158
+ it "should keep the original text even when processed" do
159
+ token = Query::Token.processed "I'm the original token text."
160
+
161
+ token.original.should == "I'm the original token text."
162
+ end
163
+ end
164
+
165
+ describe "blank?" do
166
+ it "should be blank if the token text itself is blank" do
167
+ token = Query::Token.processed ''
168
+
169
+ token.blank?.should be_true
170
+ end
171
+ it "should be non-blank if the token text itself is non-blank" do
172
+ token = Query::Token.processed 'not empty'
173
+
174
+ token.blank?.should be_false
175
+ end
176
+ end
177
+
178
+ describe "to_s" do
179
+ describe "with qualifier" do
180
+ it "should display qualifier and text combined with a ':'" do
181
+ token = Query::Token.processed('sp:qualifier')
182
+
183
+ token.to_s.should == 'specific:qualifier'
184
+ end
185
+ end
186
+ describe "without qualifier" do
187
+ it "should display just the text" do
188
+ token = Query::Token.processed('text')
189
+
190
+ token.to_s.should == 'text'
191
+ end
192
+ end
193
+ end
194
+
195
+ describe 'user_defined_category_name' do
196
+ context 'with qualifier' do
197
+ before(:each) do
198
+ @token = Query::Token.processed('sp:qualifier')
199
+ end
200
+ it 'should return the qualifier' do
201
+ @token.user_defined_category_name.should == :specific
202
+ end
203
+ end
204
+ context 'without qualifier' do
205
+ before(:each) do
206
+ @token = Query::Token.processed('noqualifier')
207
+ end
208
+ it 'should return nil' do
209
+ @token.user_defined_category_name.should == nil
210
+ end
211
+ end
212
+ end
213
+
214
+ describe "split" do
215
+ def self.it_should_split text, expected_result
216
+ it "should split #{expected_result} from #{text}" do
217
+ Query::Token.new('any').send(:split, text).should == expected_result
218
+ end
219
+ end
220
+ it_should_split ':', [nil, '']
221
+ it_should_split 'vorname:qualifier', ['vorname', 'qualifier']
222
+ it_should_split 'with:qualifier', ['with', 'qualifier']
223
+ it_should_split 'without qualifier', [nil, 'without qualifier']
224
+ it_should_split 'name:', [nil, 'name']
225
+ it_should_split ':broken qualifier', ['', 'broken qualifier']
226
+ it_should_split '', [nil, '']
227
+ it_should_split 'fn:text', ['fn', 'text']
228
+ end
229
+
230
+ describe 'partial=' do
231
+ context 'partial nil' do
232
+ before(:each) do
233
+ @token = Query::Token.new 'text'
234
+ end
235
+ it 'should set partial' do
236
+ @token.partial = true
237
+
238
+ @token.instance_variable_get(:@partial).should be_true
239
+ end
240
+ it 'should set partial' do
241
+ @token.partial = false
242
+
243
+ @token.instance_variable_get(:@partial).should be_false
244
+ end
245
+ end
246
+ context 'partial not nil' do
247
+ before(:each) do
248
+ @token = Query::Token.processed 'text*'
249
+ end
250
+ it 'should not set partial' do
251
+ @token.partial = false
252
+
253
+ @token.instance_variable_get(:@partial).should be_true
254
+ end
255
+ end
256
+ end
257
+
258
+ describe 'partialize!' do
259
+ it 'should not partialize a token if the text ends with "' do
260
+ token = Query::Token.processed 'text"'
261
+
262
+ token.instance_variable_get(:@partial).should be_false
263
+ end
264
+ it 'should partialize a token if the text ends with *' do
265
+ token = Query::Token.processed 'text*'
266
+
267
+ token.instance_variable_get(:@partial).should be_true
268
+ end
269
+ it 'should not partialize a token if the text ends with ~' do
270
+ token = Query::Token.processed 'text~'
271
+
272
+ token.instance_variable_get(:@partial).should be_nil
273
+ end
274
+ end
275
+
276
+ describe "processed" do
277
+ it 'should remove *' do
278
+ token = Query::Token.processed 'text*'
279
+
280
+ token.text.should == 'text'
281
+ end
282
+ it 'should remove ~' do
283
+ token = Query::Token.processed 'text~'
284
+
285
+ token.text.should == 'text'
286
+ end
287
+ it 'should remove "' do
288
+ token = Query::Token.processed 'text"'
289
+
290
+ token.text.should == 'text'
291
+ end
292
+ it "should pass on a processed text" do
293
+ Query::Token.processed('text').text.should == 'text'
294
+ end
295
+ end
296
+
297
+ end
@@ -0,0 +1,189 @@
1
+ require 'spec_helper'
2
+
3
+ describe Query::Tokens do
4
+
5
+ before(:all) do
6
+ Query::Qualifiers.instance << Query::Qualifier.new(:specific, [:sp, :spec])
7
+ Query::Qualifiers.instance.prepare
8
+ end
9
+
10
+ describe 'to_solr_query' do
11
+ context 'many tokens' do
12
+ before(:each) do
13
+ @tokens = Query::Tokens.new [
14
+ Query::Token.processed('this~'),
15
+ Query::Token.processed('is'),
16
+ Query::Token.processed('a'),
17
+ Query::Token.processed('sp:solr'),
18
+ Query::Token.processed('query"')
19
+ ]
20
+ end
21
+ it 'should output a correct solr query' do
22
+ @tokens.to_solr_query.should == 'this~0.74 is a specific:solr~0.74 query~0.78'
23
+ end
24
+ end
25
+ end
26
+
27
+ describe 'reject' do
28
+ before(:each) do
29
+ @blank = stub :blank, :blank? => true
30
+ @nonblank = stub :nonblank, :blank? => false
31
+ @tokens = Query::Tokens.new [@blank, @nonblank, @blank, @blank, @nonblank]
32
+ end
33
+ it 'should not cut it down' do
34
+ @tokens.reject
35
+
36
+ @tokens.instance_variable_get(:@tokens).should == [@nonblank, @nonblank]
37
+ end
38
+ end
39
+
40
+ describe "class variables" do
41
+ describe "maximal query words" do
42
+ it "should answer" do
43
+ lambda { Query::Tokens.maximum }.should_not raise_error
44
+ end
45
+ end
46
+ end
47
+
48
+ describe 'cap' do
49
+ context 'one token' do
50
+ before(:each) do
51
+ @token = Query::Token.processed 'Token'
52
+ @tokens = Query::Tokens.new [@token]
53
+ end
54
+ it 'should not cut it down' do
55
+ @tokens.cap
56
+
57
+ @tokens.instance_variable_get(:@tokens).should == [@token]
58
+ end
59
+ end
60
+ context 'many tokens' do
61
+ before(:each) do
62
+ @old_maximum = Query::Tokens.maximum
63
+ Query::Tokens.maximum = 3
64
+ @first = Query::Token.processed 'Hello'
65
+ @second = Query::Token.processed 'I'
66
+ @third = Query::Token.processed 'Am'
67
+ @tokens = Query::Tokens.new [
68
+ @first,
69
+ @second,
70
+ @third,
71
+ Query::Token.processed('A'),
72
+ Query::Token.processed('Token')
73
+ ]
74
+ end
75
+ after(:each) do
76
+ Query::Tokens.maximum = @old_maximum
77
+ end
78
+ it 'should cap the number of tokens' do
79
+ @tokens.cap
80
+
81
+ @tokens.instance_variable_get(:@tokens).should == [@first, @second, @third]
82
+ end
83
+ end
84
+ end
85
+
86
+ describe 'partialize_last' do
87
+ context 'special case' do
88
+ before(:each) do
89
+ @token = Query::Token.processed 'a*'
90
+ @tokens = Query::Tokens.new [@token]
91
+ end
92
+ it 'should have a last partialized token' do
93
+ @token.should be_partial
94
+ end
95
+ it 'should still partialize the last token' do
96
+ @tokens.partialize_last
97
+
98
+ @token.should be_partial
99
+ end
100
+ end
101
+ context 'one token' do
102
+ before(:each) do
103
+ @token = Query::Token.processed 'Token'
104
+ @tokens = Query::Tokens.new [@token]
105
+ end
106
+ it 'should not have a last partialized token' do
107
+ @token.should_not be_partial
108
+ end
109
+ it 'should partialize the last token' do
110
+ @tokens.partialize_last
111
+
112
+ @token.should be_partial
113
+ end
114
+ end
115
+ context 'many tokens' do
116
+ before(:each) do
117
+ @first = Query::Token.processed 'Hello'
118
+ @last = Query::Token.processed 'Token'
119
+ @tokens = Query::Tokens.new [
120
+ @first,
121
+ Query::Token.processed('I'),
122
+ Query::Token.processed('Am'),
123
+ Query::Token.processed('A'),
124
+ @last
125
+ ]
126
+ end
127
+ it 'should not have a last partialized token' do
128
+ @last.should_not be_partial
129
+ end
130
+ it 'should partialize the last token' do
131
+ @tokens.partialize_last
132
+
133
+ @last.should be_partial
134
+ end
135
+ it 'should not partialize any other token' do
136
+ @tokens.partialize_last
137
+
138
+ @first.should_not be_partial
139
+ end
140
+ end
141
+ end
142
+
143
+ describe 'to_s' do
144
+ before(:each) do
145
+ @tokens = Query::Tokens.new [
146
+ Query::Token.processed('Hello~'),
147
+ Query::Token.processed('I~'),
148
+ Query::Token.processed('Am'),
149
+ Query::Token.processed('A*'),
150
+ Query::Token.processed('Token~')
151
+ ]
152
+ end
153
+ it 'should work correctly' do
154
+ @tokens.to_s.should == 'Hello~ I~ Am A* Token~'
155
+ end
156
+ end
157
+
158
+ def self.it_should_delegate name
159
+ describe name do
160
+ before(:each) do
161
+ @internal_tokens = mock :internal_tokens
162
+ @tokens = Query::Tokens.new @internal_tokens
163
+ end
164
+ it "should delegate #{name} to the internal tokens" do
165
+ proc_stub = lambda {}
166
+
167
+ @internal_tokens.should_receive(name).once.with &proc_stub
168
+
169
+ @tokens.send name, &proc_stub
170
+ end
171
+ end
172
+ end
173
+ # Reject is tested separately.
174
+ #
175
+ (Enumerable.instance_methods - [:reject]).each do |name|
176
+ it_should_delegate name
177
+ end
178
+ it_should_delegate :slice!
179
+ it_should_delegate :[]
180
+ it_should_delegate :uniq!
181
+ it_should_delegate :last
182
+ it_should_delegate :length
183
+ it_should_delegate :reject!
184
+ it_should_delegate :size
185
+ it_should_delegate :empty?
186
+ it_should_delegate :each
187
+ it_should_delegate :exit
188
+
189
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Query::Weights do
4
+
5
+ before(:each) do
6
+ @weights = Query::Weights.new [:test1, :test2] => 6,
7
+ [:test1] => 5,
8
+ [:test3] => 3,
9
+ [:test3, :test2] => 4,
10
+ [:test1, :test4] => 5,
11
+ [:test4, :test1] => 5,
12
+ [:test4, :test1, :test2] => 4,
13
+ [:test1, :test4, :test2] => 4,
14
+ [:test4, :test5] => 3,
15
+ [:test5, :test1] => 2,
16
+ [:test1, :test5] => 2,
17
+ [:test3, :test1] => 2,
18
+ [:test1, :test3] => 2
19
+ end
20
+
21
+ describe "weight_for" do
22
+ it "should return zero if there is no specific weight" do
23
+ @weights.weight_for([:not_a_specific_allocation]).should be_zero
24
+ end
25
+ end
26
+
27
+ def self.it_should_return_a_specific_weight_for(allocation, weight)
28
+ it "should return weight #{weight} for #{allocation.inspect}" do
29
+ @weights.weight_for(allocation).should == weight
30
+ end
31
+ end
32
+
33
+ it_should_return_a_specific_weight_for [:test1, :test2], 6
34
+ it_should_return_a_specific_weight_for [:test1], 5
35
+ it_should_return_a_specific_weight_for [:test1, :test3], 2
36
+ it_should_return_a_specific_weight_for [:test3], 3
37
+ it_should_return_a_specific_weight_for [:test3, :test2], 4
38
+ it_should_return_a_specific_weight_for [:test1, :test4], 5
39
+ it_should_return_a_specific_weight_for [:test4, :test1], 5
40
+ it_should_return_a_specific_weight_for [:test4, :test1, :test2], 4
41
+ it_should_return_a_specific_weight_for [:test1, :test4, :test2], 4
42
+ it_should_return_a_specific_weight_for [:test4, :test5], 3
43
+ it_should_return_a_specific_weight_for [:test5, :test1], 2
44
+ it_should_return_a_specific_weight_for [:test1, :test5], 2
45
+ it_should_return_a_specific_weight_for [:test3, :test1], 2
46
+
47
+ end