picky 4.0.0pre1 → 4.0.0pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/aux/picky/cli.rb +6 -2
  2. data/lib/picky.rb +10 -8
  3. data/lib/picky/backends/backend.rb +37 -0
  4. data/lib/picky/backends/file.rb +0 -20
  5. data/lib/picky/backends/memory.rb +0 -29
  6. data/lib/picky/backends/redis.rb +74 -15
  7. data/lib/picky/backends/redis/list.rb +1 -1
  8. data/lib/picky/backends/sqlite.rb +0 -27
  9. data/lib/picky/bundle.rb +2 -2
  10. data/lib/picky/bundle_indexed.rb +1 -1
  11. data/lib/picky/bundle_indexing.rb +1 -1
  12. data/lib/picky/categories_indexed.rb +1 -11
  13. data/lib/picky/category.rb +4 -4
  14. data/lib/picky/category/location.rb +25 -0
  15. data/lib/picky/category_realtime.rb +4 -3
  16. data/lib/picky/console.rb +1 -1
  17. data/lib/picky/constants.rb +1 -1
  18. data/lib/picky/ext/maybe_compile.rb +2 -2
  19. data/lib/picky/extensions/object.rb +3 -2
  20. data/lib/picky/generators/aliases.rb +7 -2
  21. data/lib/picky/generators/partial/default.rb +1 -0
  22. data/lib/picky/generators/similarity/default.rb +1 -0
  23. data/lib/picky/generators/similarity/phonetic.rb +13 -2
  24. data/lib/picky/generators/strategy.rb +0 -2
  25. data/lib/picky/generators/weights/constant.rb +1 -2
  26. data/lib/picky/generators/weights/default.rb +1 -0
  27. data/lib/picky/generators/weights/dynamic.rb +1 -1
  28. data/lib/picky/generators/weights/logarithmic.rb +1 -1
  29. data/lib/picky/generators/weights/{runtime.rb → stub.rb} +1 -3
  30. data/lib/picky/index.rb +3 -3
  31. data/lib/picky/index_indexing.rb +0 -2
  32. data/lib/picky/index_realtime.rb +1 -1
  33. data/lib/picky/indexers/base.rb +7 -0
  34. data/lib/picky/indexers/parallel.rb +2 -4
  35. data/lib/picky/indexers/serial.rb +2 -0
  36. data/lib/picky/indexes_indexing.rb +1 -1
  37. data/lib/picky/interfaces/live_parameters/master_child.rb +175 -0
  38. data/lib/picky/interfaces/live_parameters/unicorn.rb +37 -0
  39. data/lib/picky/loader.rb +238 -259
  40. data/lib/picky/query/allocation.rb +19 -10
  41. data/lib/picky/query/combination.rb +7 -1
  42. data/lib/picky/query/combinations.rb +1 -6
  43. data/lib/picky/query/token.rb +26 -36
  44. data/lib/picky/results.rb +18 -17
  45. data/lib/picky/scheduler.rb +2 -1
  46. data/lib/picky/search.rb +1 -1
  47. data/lib/picky/sinatra.rb +6 -6
  48. data/lib/picky/statistics.rb +2 -0
  49. data/lib/picky/tokenizer.rb +8 -8
  50. data/lib/picky/wrappers/bundle/calculation.rb +4 -4
  51. data/lib/picky/wrappers/bundle/location.rb +1 -2
  52. data/lib/tasks/framework.rake +1 -1
  53. data/lib/tasks/statistics.rake +1 -1
  54. data/lib/tasks/try.rake +1 -1
  55. data/lib/tasks/try.rb +1 -1
  56. data/spec/aux/picky/cli_spec.rb +12 -12
  57. data/spec/ext/performant_spec.rb +16 -16
  58. data/spec/functional/backends/file_spec.rb +78 -7
  59. data/spec/functional/backends/memory_spec.rb +78 -7
  60. data/spec/functional/backends/redis_spec.rb +73 -13
  61. data/spec/functional/dynamic_weights_spec.rb +3 -4
  62. data/spec/functional/realtime_spec.rb +2 -2
  63. data/spec/functional/speed_spec.rb +2 -2
  64. data/spec/functional/terminate_early_spec.rb +3 -3
  65. data/spec/lib/analytics_spec.rb +1 -1
  66. data/spec/lib/analyzer_spec.rb +5 -3
  67. data/spec/lib/categories_indexed_spec.rb +38 -20
  68. data/spec/lib/category/location_spec.rb +30 -0
  69. data/spec/lib/character_substituters/west_european_spec.rb +1 -0
  70. data/spec/lib/extensions/hash_spec.rb +6 -5
  71. data/spec/lib/extensions/module_spec.rb +6 -6
  72. data/spec/lib/extensions/object_spec.rb +9 -8
  73. data/spec/lib/extensions/string_spec.rb +1 -1
  74. data/spec/lib/generators/similarity/phonetic_spec.rb +11 -0
  75. data/spec/lib/index_realtime_spec.rb +5 -5
  76. data/spec/lib/interfaces/{live_parameters_spec.rb → live_parameters/master_child_spec.rb} +26 -26
  77. data/spec/lib/interfaces/live_parameters/unicorn_spec.rb +160 -0
  78. data/spec/lib/loader_spec.rb +65 -25
  79. data/spec/lib/query/allocation_spec.rb +25 -22
  80. data/spec/lib/query/combinations_spec.rb +13 -36
  81. data/spec/lib/query/token_spec.rb +144 -131
  82. data/spec/lib/query/tokens_spec.rb +14 -0
  83. data/spec/lib/results_spec.rb +14 -8
  84. data/spec/lib/search_spec.rb +1 -1
  85. data/spec/lib/sinatra_spec.rb +8 -8
  86. metadata +28 -91
  87. data/lib/picky/adapters/rack.rb +0 -34
  88. data/lib/picky/adapters/rack/base.rb +0 -27
  89. data/lib/picky/adapters/rack/live_parameters.rb +0 -37
  90. data/lib/picky/adapters/rack/search.rb +0 -67
  91. data/lib/picky/application.rb +0 -268
  92. data/lib/picky/frontend_adapters/rack.rb +0 -161
  93. data/lib/picky/interfaces/live_parameters.rb +0 -187
  94. data/lib/picky/sources/base.rb +0 -92
  95. data/lib/picky/sources/couch.rb +0 -76
  96. data/lib/picky/sources/csv.rb +0 -83
  97. data/lib/picky/sources/db.rb +0 -189
  98. data/lib/picky/sources/delicious.rb +0 -63
  99. data/lib/picky/sources/mongo.rb +0 -80
  100. data/lib/picky/wrappers/category/location.rb +0 -38
  101. data/lib/tasks/routes.rake +0 -8
  102. data/spec/lib/adapters/rack/base_spec.rb +0 -24
  103. data/spec/lib/adapters/rack/live_parameters_spec.rb +0 -26
  104. data/spec/lib/adapters/rack/query_spec.rb +0 -39
  105. data/spec/lib/application_spec.rb +0 -155
  106. data/spec/lib/frontend_adapters/rack_spec.rb +0 -294
  107. data/spec/lib/sources/base_spec.rb +0 -53
  108. data/spec/lib/sources/couch_spec.rb +0 -114
  109. data/spec/lib/sources/csv_spec.rb +0 -89
  110. data/spec/lib/sources/db_spec.rb +0 -125
  111. data/spec/lib/sources/delicious_spec.rb +0 -94
  112. data/spec/lib/sources/mongo_spec.rb +0 -50
@@ -12,105 +12,40 @@ describe Picky::Query::Token do
12
12
  end
13
13
  end
14
14
 
15
- describe 'next_similar_token' do
16
- before(:each) do
17
- @bundle = stub :bundle, :similar => [:array, :of, :similar]
18
- @category = stub :category, :bundle_for => @bundle
19
-
20
- @token = described_class.processed 'similar~', 'Similar~'
21
- end
22
- it 'returns the right next tokens' do
23
- next_token = @token.next_similar_token @category
24
- next_token.text.should == :array
25
- next_token = next_token.next_similar_token @category
26
- next_token.text.should == :of
27
- next_token = next_token.next_similar_token @category
28
- next_token.text.should == :similar
29
- next_token = next_token.next_similar_token @category
30
- next_token.should == nil
31
- end
32
- end
33
-
34
- describe 'next_similar' do
35
- before(:each) do
36
- @bundle = stub :bundle
37
- end
38
- describe 'original' do
39
- context 'with stub' do
40
- before(:each) do
41
- @bundle.stub! :similar => [:array, :of, :similar]
42
-
43
- @token = described_class.processed 'similar~', 'Similar'
44
- end
45
- it 'should have a certain original text' do
46
- @token.next_similar @bundle
47
-
48
- @token.original.should == :array
49
- end
15
+ describe 'similar_tokens_for' do
16
+ let(:token) { described_class.processed 'similar~', 'Similar~' }
17
+ context 'with similar' do
18
+ before(:each) do
19
+ @bundle = stub :bundle, :similar => ['array', 'of', 'similar']
20
+ @category = stub :category, :bundle_for => @bundle
50
21
  end
51
- end
52
- context 'similar' do
53
- context 'with stub' do
54
- before(:each) do
55
- @bundle.stub! :similar => [:array, :of, :similar]
56
-
57
- @token = described_class.processed 'similar~', 'Similar'
58
- end
59
- it 'generates all similar' do
60
- @token.next_similar(@bundle).should == :array
61
- @token.next_similar(@bundle).should == :of
62
- @token.next_similar(@bundle).should == :similar
63
- @token.next_similar(@bundle).should == nil
64
- end
65
- it 'should have a certain text' do
66
- @token.next_similar @bundle
67
- @token.next_similar @bundle
68
- @token.next_similar @bundle
69
- @token.next_similar @bundle
70
-
71
- @token.text.should == :similar
22
+ it 'returns a list of tokens' do
23
+ token.similar_tokens_for(@category).each do |token|
24
+ token.should be_kind_of(described_class)
72
25
  end
73
26
  end
74
- end
75
- context 'non-similar' do
76
- context 'with stub' do
77
- before(:each) do
78
- @bundle.stub! :similar => [:array, :of, :similar]
79
-
80
- @token = described_class.processed 'nonsimilar', 'Nonsimilar'
81
- end
82
- it 'generates all similar' do
83
- @token.next_similar(@bundle).should == nil
84
- end
85
- it 'should have a certain text' do
86
- @token.next_similar @bundle
87
-
88
- @token.text.should == 'nonsimilar'
27
+ it 'returns all non-similar tokens' do
28
+ token.similar_tokens_for(@category).each do |token|
29
+ token.should_not be_similar
89
30
  end
90
31
  end
91
- end
92
- end
93
-
94
- describe "generate_similarity_for" do
95
- before(:each) do
96
- @bundle = stub :bundle
97
-
98
- @token = described_class.processed 'flarb~', 'FLARB~'
99
- end
100
- context "with similar" do
101
- before(:each) do
102
- @bundle.stub! :similar => [:array, :of, :similar]
32
+ it 'returns a list of tokens with the right text' do
33
+ token.similar_tokens_for(@category).map(&:text).should == ['array', 'of', 'similar']
34
+ end
35
+ it 'returns a list of tokens with the right original' do
36
+ token.similar_tokens_for(@category).map(&:original).should == ['array', 'of', 'similar']
103
37
  end
104
- it "returns an array of the right size" do
105
- @token.generate_similarity_for(@bundle).size.should == 3
38
+ it 'returns a list of tokens with the right categorization' do
39
+ token.similar_tokens_for(@category).map(&:user_defined_categories).should == [[@category], [@category], [@category]]
106
40
  end
107
41
  end
108
- context "without similar" do
42
+ context 'without similar' do
109
43
  before(:each) do
110
- @bundle.stub! :similar => []
44
+ @bundle = stub :bundle, :similar => []
45
+ @category = stub :category, :bundle_for => @bundle
111
46
  end
112
- it "returns an array of the right size" do
113
- @token.generate_similarity_for(@bundle).size.should == 0
47
+ it 'returns an empty list' do
48
+ token.similar_tokens_for(@category).should == []
114
49
  end
115
50
  end
116
51
  end
@@ -167,12 +102,24 @@ describe Picky::Query::Token do
167
102
  it_should_qualify 'a,b,c:d', [['a','b','c'], 'd']
168
103
  it_should_qualify ':', [nil, '']
169
104
  it_should_qualify 'vorname:qualifier', [['vorname'], 'qualifier']
170
- it_should_qualify 'with:qualifier', [['with'], 'qualifier']
171
- it_should_qualify 'without qualifier', [nil, 'without qualifier']
172
- it_should_qualify 'name:', [nil, 'name']
173
- it_should_qualify ':broken qualifier', [[], 'broken qualifier']
174
- it_should_qualify '', [nil, '']
175
- it_should_qualify 'fn:text', [['fn'], 'text']
105
+ end
106
+
107
+ describe 'qualifier' do
108
+ it 'returns the right thing' do
109
+ token = described_class.processed 'b'
110
+
111
+ token.qualifiers.should == []
112
+ end
113
+ it 'returns the right thing' do
114
+ token = described_class.processed 'a:b'
115
+
116
+ token.qualifiers.should == ['a']
117
+ end
118
+ it 'returns the right thing' do
119
+ token = described_class.processed 'a,b:c'
120
+
121
+ token.qualifiers.should == ['a', 'b']
122
+ end
176
123
  end
177
124
 
178
125
  describe 'processed' do
@@ -199,6 +146,76 @@ describe Picky::Query::Token do
199
146
  end
200
147
  end
201
148
 
149
+ describe 'partialize' do
150
+ context 'token explicitly partial' do
151
+ let(:token) { described_class.new 'a*' }
152
+ it 'is afterwards partial' do
153
+ token.partialize
154
+
155
+ token.should be_partial
156
+ end
157
+ end
158
+ context 'token explicitly nonpartial' do
159
+ let(:token) { described_class.new 'a"' }
160
+ it 'is afterwards not partial' do
161
+ token.partialize
162
+
163
+ token.should_not be_partial
164
+ end
165
+ end
166
+ context 'token nonpartial' do
167
+ let(:token) { described_class.new 'a' }
168
+ it 'is afterwards not partial' do
169
+ token.partialize
170
+
171
+ token.should_not be_partial
172
+ end
173
+ end
174
+ context 'special case' do
175
+ let(:token) { described_class.new 'a*"' }
176
+ it 'is afterwards not partial - last one wins' do
177
+ token.partialize
178
+
179
+ token.should_not be_partial
180
+ end
181
+ end
182
+ context 'special case' do
183
+ let(:token) { described_class.new 'a"*' }
184
+ it 'is afterwards partial - last one wins' do
185
+ token.partialize
186
+
187
+ token.should be_partial
188
+ end
189
+ end
190
+ end
191
+
192
+ describe 'similarize' do
193
+ context 'token explicitly similar' do
194
+ let(:token) { described_class.new 'a~' }
195
+ it 'is afterwards similar' do
196
+ token.similarize
197
+
198
+ token.should be_similar
199
+ end
200
+ end
201
+ context 'token explicitly nonsimilar' do
202
+ let(:token) { described_class.new 'a"' }
203
+ it 'is afterwards not similar' do
204
+ token.similarize
205
+
206
+ token.should_not be_similar
207
+ end
208
+ end
209
+ context 'token nonsimilar' do
210
+ let(:token) { described_class.new 'a' }
211
+ it 'is afterwards not similar' do
212
+ token.similarize
213
+
214
+ token.should_not be_similar
215
+ end
216
+ end
217
+ end
218
+
202
219
  describe 'symbolize!' do
203
220
  before(:each) do
204
221
  @token = described_class.processed 'string', 'String'
@@ -323,70 +340,66 @@ describe Picky::Query::Token do
323
340
 
324
341
  describe 'qualifiers' do
325
342
  context 'with qualifier' do
326
- before(:each) do
327
- @token = described_class.processed('sp:qualifier')
328
- end
343
+ let(:token) { described_class.processed 'sp:qualifier' }
329
344
  it 'should return the qualifier' do
330
- @token.qualifiers.should == ['sp']
345
+ token.qualifiers.should == ['sp']
331
346
  end
332
347
  end
333
348
  context 'with incorrect qualifier' do
334
- before(:each) do
335
- @token = described_class.processed('specific:qualifier')
336
- end
349
+ let(:token) { described_class.processed 'specific:qualifier' }
337
350
  it 'should return the qualifier' do
338
- @token.qualifiers.should == ['specific']
351
+ token.qualifiers.should == ['specific']
339
352
  end
340
353
  end
341
354
  context 'with multiple qualifiers' do
342
- before(:each) do
343
- @token = described_class.processed('sp,spec:qualifier')
344
- end
355
+ let(:token) { described_class.processed 'sp,spec:qualifier' }
345
356
  it 'should return the qualifier' do
346
- @token.qualifiers.should == ['sp', 'spec']
357
+ token.qualifiers.should == ['sp', 'spec']
347
358
  end
348
359
  end
349
360
  context 'without qualifier' do
350
- before(:each) do
351
- @token = described_class.processed('noqualifier')
352
- end
353
- it 'should return nil' do
354
- @token.qualifiers.should == nil
361
+ let(:token) { described_class.processed 'noqualifier' }
362
+ it 'is correct' do
363
+ token.qualifiers.should == []
355
364
  end
356
365
  end
357
366
  end
358
367
 
359
368
  describe 'partial=' do
360
369
  context 'partial nil' do
361
- before(:each) do
362
- @token = described_class.new 'text'
363
- end
370
+ let(:token) { described_class.new 'text' }
364
371
  it 'should set partial' do
365
- @token.partial = true
372
+ token.partial = true
366
373
 
367
- @token.instance_variable_get(:@partial).should be_true
374
+ token.should be_partial
368
375
  end
369
376
  it 'should set partial' do
370
- @token.partial = false
377
+ token.partial = false
371
378
 
372
- @token.instance_variable_get(:@partial).should be_false
379
+ token.should_not be_partial
373
380
  end
374
381
  end
375
382
  context 'partial not nil' do
376
- before(:each) do
377
- @token = described_class.processed 'text*'
383
+ let(:token) { described_class.processed 'text"' }
384
+ it 'should not set partial' do
385
+ token.partial = true
386
+
387
+ token.should_not be_partial
378
388
  end
389
+ end
390
+ context 'partial not nil' do
391
+ let(:token) { described_class.processed 'text*' }
379
392
  it 'should not set partial' do
380
- @token.instance_variable_set :@partial, false
393
+ token.instance_variable_set :@partial, false
381
394
 
382
- @token.partial = true
395
+ token.partial = true
383
396
 
384
- @token.instance_variable_get(:@partial).should be_false
397
+ token.should_not be_partial
385
398
  end
386
399
  it 'should not set partial' do
387
- @token.partial = false
400
+ token.partial = false
388
401
 
389
- @token.instance_variable_get(:@partial).should be_true
402
+ token.should be_partial
390
403
  end
391
404
  end
392
405
  end
@@ -395,27 +408,27 @@ describe Picky::Query::Token do
395
408
  it 'should not partialize a token if the text ends with "' do
396
409
  token = described_class.processed 'text"'
397
410
 
398
- token.instance_variable_get(:@partial).should be_false
411
+ token.should_not be_partial
399
412
  end
400
413
  it 'should partialize a token if the text ends with *' do
401
414
  token = described_class.processed 'text*'
402
415
 
403
- token.instance_variable_get(:@partial).should be_true
416
+ token.should be_partial
404
417
  end
405
418
  it 'should not partialize a token if the text ends with ~' do
406
419
  token = described_class.processed 'text~'
407
420
 
408
- token.instance_variable_get(:@partial).should be_nil
421
+ token.should_not be_partial
409
422
  end
410
423
  it 'lets the last one win' do
411
424
  token = described_class.processed 'text"*'
412
425
 
413
- token.partial?.should == true
426
+ token.should be_partial
414
427
  end
415
428
  it 'lets the last one win' do
416
429
  token = described_class.processed 'text*"'
417
430
 
418
- token.partial?.should == false
431
+ token.should_not be_partial
419
432
  end
420
433
  end
421
434
 
@@ -106,6 +106,20 @@ describe Picky::Query::Tokens do
106
106
  @token.should be_partial
107
107
  end
108
108
  end
109
+ context 'special case' do
110
+ before(:each) do
111
+ @token = Picky::Query::Token.processed 'a"'
112
+ @tokens = described_class.new [@token]
113
+ end
114
+ it 'should not have a last partialized token' do
115
+ @token.should_not be_partial
116
+ end
117
+ it 'should not partialize the last token' do
118
+ @tokens.partialize_last
119
+
120
+ @token.should_not be_partial
121
+ end
122
+ end
109
123
  context 'one token' do
110
124
  before(:each) do
111
125
  @token = Picky::Query::Token.processed 'Token'
@@ -1,19 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Picky::Results do
4
-
4
+
5
5
  describe "from" do
6
6
  before(:each) do
7
7
  @results = stub :results
8
8
  described_class.stub! :new => @results
9
-
9
+
10
10
  @results.stub! :prepare!
11
11
  end
12
12
  it "should generate a result" do
13
13
  described_class.from("some query", 20, 0, @allocations).should == @results
14
14
  end
15
15
  end
16
-
16
+
17
17
  describe "ids" do
18
18
  before(:each) do
19
19
  @allocations = stub :allocations
@@ -21,14 +21,20 @@ describe Picky::Results do
21
21
  end
22
22
  it "delegates" do
23
23
  @allocations.should_receive(:ids).once.with :anything
24
-
24
+
25
25
  @results.ids :anything
26
26
  end
27
27
  end
28
-
28
+
29
+ describe 'to_s time format' do
30
+ it 'is in the right format' do
31
+ described_class.new("some_query").to_s.should match(/\d{2}\-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/)
32
+ end
33
+ end
34
+
29
35
  describe 'to_s' do
30
36
  before(:each) do
31
- time = stub :time, :to_s => '0-08-16 10:07:33'
37
+ time = stub :time, :strftime => '2011-08-16 10:07:33'
32
38
  Time.stub! :now => time
33
39
  end
34
40
  context 'without results' do
@@ -36,7 +42,7 @@ describe Picky::Results do
36
42
  @results = described_class.new "some_query"
37
43
  end
38
44
  it 'should output a default log' do
39
- @results.to_s.should == '.|0-08-16 10:07:33|0.000000|some_query | 0| 0| 0|'
45
+ @results.to_s.should == '.|2011-08-16 10:07:33|0.000000|some_query | 0| 0| 0|'
40
46
  end
41
47
  end
42
48
  context 'with results' do
@@ -50,7 +56,7 @@ describe Picky::Results do
50
56
  :total => 12345678
51
57
  end
52
58
  it 'should output a specific log' do
53
- @results.to_s.should == '>|0-08-16 10:07:33|0.123457|some_query |12345678|1234|12|'
59
+ @results.to_s.should == '>|2011-08-16 10:07:33|0.123457|some_query |12345678|1234|12|'
54
60
  end
55
61
  end
56
62
  end