rlibsphinxclient 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG.rdoc +18 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +151 -0
  5. data/Rakefile +39 -0
  6. data/VERSION +1 -0
  7. data/ext/extconf.rb +20 -0
  8. data/ext/rlibsphinxclient.i +314 -0
  9. data/ext/rlibsphinxclient_wrap.c +5931 -0
  10. data/init.rb +1 -0
  11. data/lib/sphinx.rb +22 -0
  12. data/lib/sphinx/client.rb +1070 -0
  13. data/lib/sphinx/fast_client.rb +184 -0
  14. data/lib/sphinx/request.rb +49 -0
  15. data/lib/sphinx/response.rb +69 -0
  16. data/lib/sphinx/safe_executor.rb +11 -0
  17. data/lib/sphinx/timeout.rb +9 -0
  18. data/rlibsphinxclient.gemspec +117 -0
  19. data/spec/client_response_spec.rb +135 -0
  20. data/spec/client_spec.rb +548 -0
  21. data/spec/fixtures/default_search.php +8 -0
  22. data/spec/fixtures/default_search_index.php +8 -0
  23. data/spec/fixtures/excerpt_custom.php +11 -0
  24. data/spec/fixtures/excerpt_default.php +8 -0
  25. data/spec/fixtures/excerpt_flags.php +11 -0
  26. data/spec/fixtures/field_weights.php +9 -0
  27. data/spec/fixtures/filter.php +9 -0
  28. data/spec/fixtures/filter_exclude.php +9 -0
  29. data/spec/fixtures/filter_float_range.php +9 -0
  30. data/spec/fixtures/filter_float_range_exclude.php +9 -0
  31. data/spec/fixtures/filter_range.php +9 -0
  32. data/spec/fixtures/filter_range_exclude.php +9 -0
  33. data/spec/fixtures/filter_ranges.php +10 -0
  34. data/spec/fixtures/filters.php +10 -0
  35. data/spec/fixtures/filters_different.php +13 -0
  36. data/spec/fixtures/geo_anchor.php +9 -0
  37. data/spec/fixtures/group_by_attr.php +9 -0
  38. data/spec/fixtures/group_by_attrpair.php +9 -0
  39. data/spec/fixtures/group_by_day.php +9 -0
  40. data/spec/fixtures/group_by_day_sort.php +9 -0
  41. data/spec/fixtures/group_by_month.php +9 -0
  42. data/spec/fixtures/group_by_week.php +9 -0
  43. data/spec/fixtures/group_by_year.php +9 -0
  44. data/spec/fixtures/group_distinct.php +10 -0
  45. data/spec/fixtures/id_range.php +9 -0
  46. data/spec/fixtures/id_range64.php +9 -0
  47. data/spec/fixtures/index_weights.php +9 -0
  48. data/spec/fixtures/keywords.php +8 -0
  49. data/spec/fixtures/limits.php +9 -0
  50. data/spec/fixtures/limits_cutoff.php +9 -0
  51. data/spec/fixtures/limits_max.php +9 -0
  52. data/spec/fixtures/limits_max_cutoff.php +9 -0
  53. data/spec/fixtures/match_all.php +9 -0
  54. data/spec/fixtures/match_any.php +9 -0
  55. data/spec/fixtures/match_boolean.php +9 -0
  56. data/spec/fixtures/match_extended.php +9 -0
  57. data/spec/fixtures/match_extended2.php +9 -0
  58. data/spec/fixtures/match_fullscan.php +9 -0
  59. data/spec/fixtures/match_phrase.php +9 -0
  60. data/spec/fixtures/max_query_time.php +9 -0
  61. data/spec/fixtures/miltiple_queries.php +12 -0
  62. data/spec/fixtures/ranking_bm25.php +9 -0
  63. data/spec/fixtures/ranking_none.php +9 -0
  64. data/spec/fixtures/ranking_proximity_bm25.php +9 -0
  65. data/spec/fixtures/ranking_wordcount.php +9 -0
  66. data/spec/fixtures/retries.php +9 -0
  67. data/spec/fixtures/retries_delay.php +9 -0
  68. data/spec/fixtures/sort_attr_asc.php +9 -0
  69. data/spec/fixtures/sort_attr_desc.php +9 -0
  70. data/spec/fixtures/sort_expr.php +9 -0
  71. data/spec/fixtures/sort_extended.php +9 -0
  72. data/spec/fixtures/sort_relevance.php +9 -0
  73. data/spec/fixtures/sort_time_segments.php +9 -0
  74. data/spec/fixtures/sphinxapi.php +1181 -0
  75. data/spec/fixtures/update_attributes.php +8 -0
  76. data/spec/fixtures/weights.php +9 -0
  77. data/spec/sphinx/sphinx.conf +67 -0
  78. data/spec/sphinx/sphinx_test.sql +86 -0
  79. metadata +133 -0
@@ -0,0 +1,548 @@
1
+ require File.dirname(__FILE__) + '/../init'
2
+
3
+ module SphinxFixtureHelper
4
+ def sphinx_fixture(name)
5
+ `php #{File.dirname(__FILE__)}/fixtures/#{name}.php`
6
+ end
7
+ end
8
+
9
+ describe 'The Connect method of SphinxApi' do
10
+ before(:each) do
11
+ @sphinx = Sphinx::Client.new
12
+ @sock = mock('TCPSocket')
13
+ end
14
+
15
+ it 'should establish TCP connection to the server and initialize session' do
16
+ TCPSocket.should_receive(:new).with('localhost', 3312).and_return(@sock)
17
+ @sock.should_receive(:recv).with(4).and_return([1].pack('N'))
18
+ @sock.should_receive(:send).with([1].pack('N'), 0)
19
+ @sphinx.send(:Connect) do |sock|
20
+ sock.should be(@sock)
21
+ end
22
+ end
23
+
24
+ it 'should raise exception when searchd protocol is not 1+' do
25
+ TCPSocket.should_receive(:new).with('localhost', 3312).and_return(@sock)
26
+ @sock.should_receive(:recv).with(4).and_return([0].pack('N'))
27
+ @sock.should_receive(:close)
28
+ lambda { @sphinx.send(:Connect) }.should raise_error(Sphinx::SphinxConnectError)
29
+ @sphinx.GetLastError.should == 'expected searchd protocol version 1+, got version \'0\''
30
+ end
31
+
32
+ it 'should raise exception on connection error' do
33
+ TCPSocket.should_receive(:new).with('localhost', 3312).and_raise(Errno::EBADF)
34
+ lambda { @sphinx.send(:Connect) }.should raise_error(Sphinx::SphinxConnectError)
35
+ @sphinx.GetLastError.should == 'connection to localhost:3312 failed'
36
+ end
37
+
38
+ it 'should use custom host and port' do
39
+ @sphinx.SetServer('anotherhost', 55555)
40
+ TCPSocket.should_receive(:new).with('anotherhost', 55555).and_raise(Errno::EBADF)
41
+ lambda { @sphinx.send(:Connect) }.should raise_error(Sphinx::SphinxConnectError)
42
+ end
43
+ end
44
+
45
+ describe 'The GetResponse method of SphinxApi' do
46
+ before(:each) do
47
+ @sphinx = Sphinx::Client.new
48
+ @sock = mock('TCPSocket')
49
+ @sock.should_receive(:close)
50
+ end
51
+
52
+ it 'should receive response' do
53
+ @sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 4].pack('n2N'))
54
+ @sock.should_receive(:recv).with(4).and_return([0].pack('N'))
55
+ @sphinx.send(:GetResponse, @sock, 1)
56
+ end
57
+
58
+ it 'should raise exception on zero-sized response' do
59
+ @sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 0].pack('n2N'))
60
+ lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxResponseError)
61
+ end
62
+
63
+ it 'should raise exception when response is incomplete' do
64
+ @sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 4].pack('n2N'))
65
+ @sock.should_receive(:recv).with(4).and_raise(EOFError)
66
+ lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxResponseError)
67
+ end
68
+
69
+ it 'should set warning message when SEARCHD_WARNING received' do
70
+ @sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_WARNING, 1, 14].pack('n2N'))
71
+ @sock.should_receive(:recv).with(14).and_return([5].pack('N') + 'helloworld')
72
+ @sphinx.send(:GetResponse, @sock, 1).should == 'world'
73
+ @sphinx.GetLastWarning.should == 'hello'
74
+ end
75
+
76
+ it 'should raise exception when SEARCHD_ERROR received' do
77
+ @sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_ERROR, 1, 9].pack('n2N'))
78
+ @sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
79
+ lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxInternalError)
80
+ @sphinx.GetLastError.should == 'searchd error: hello'
81
+ end
82
+
83
+ it 'should raise exception when SEARCHD_RETRY received' do
84
+ @sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_RETRY, 1, 9].pack('n2N'))
85
+ @sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
86
+ lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxTemporaryError)
87
+ @sphinx.GetLastError.should == 'temporary searchd error: hello'
88
+ end
89
+
90
+ it 'should raise exception when unknown status received' do
91
+ @sock.should_receive(:recv).with(8).and_return([65535, 1, 9].pack('n2N'))
92
+ @sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
93
+ lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxUnknownError)
94
+ @sphinx.GetLastError.should == 'unknown status code: \'65535\''
95
+ end
96
+
97
+ it 'should set warning when server is older than client' do
98
+ @sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 9].pack('n2N'))
99
+ @sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
100
+ @sphinx.send(:GetResponse, @sock, 5)
101
+ @sphinx.GetLastWarning.should == 'searchd command v.0.1 older than client\'s v.0.5, some options might not work'
102
+ end
103
+ end
104
+
105
+ describe 'The Query method of SphinxApi' do
106
+ include SphinxFixtureHelper
107
+
108
+ before(:each) do
109
+ @sphinx = Sphinx::Client.new
110
+ @sock = mock('TCPSocket')
111
+ @sphinx.stub!(:Connect).and_yield(@sock)
112
+ @sphinx.stub!(:GetResponse).and_raise(Sphinx::SphinxError)
113
+ end
114
+
115
+ it 'should generate valid request with default parameters' do
116
+ expected = sphinx_fixture('default_search')
117
+ @sock.should_receive(:send).with(expected, 0)
118
+ @sphinx.Query('query') rescue nil?
119
+ end
120
+
121
+ it 'should generate valid request with default parameters and index' do
122
+ expected = sphinx_fixture('default_search_index')
123
+ @sock.should_receive(:send).with(expected, 0)
124
+ @sphinx.Query('query', 'index') rescue nil?
125
+ end
126
+
127
+ it 'should generate valid request with limits' do
128
+ expected = sphinx_fixture('limits')
129
+ @sock.should_receive(:send).with(expected, 0)
130
+ @sphinx.SetLimits(10, 20)
131
+ @sphinx.Query('query') rescue nil?
132
+ end
133
+
134
+ it 'should generate valid request with limits and max number to retrieve' do
135
+ expected = sphinx_fixture('limits_max')
136
+ @sock.should_receive(:send).with(expected, 0)
137
+ @sphinx.SetLimits(10, 20, 30)
138
+ @sphinx.Query('query') rescue nil?
139
+ end
140
+
141
+ it 'should generate valid request with limits and cutoff to retrieve' do
142
+ expected = sphinx_fixture('limits_cutoff')
143
+ @sock.should_receive(:send).with(expected, 0)
144
+ @sphinx.SetLimits(10, 20, 30, 40)
145
+ @sphinx.Query('query') rescue nil?
146
+ end
147
+
148
+ it 'should generate valid request with max query time specified' do
149
+ expected = sphinx_fixture('max_query_time')
150
+ @sock.should_receive(:send).with(expected, 0)
151
+ @sphinx.SetMaxQueryTime(1000)
152
+ @sphinx.Query('query') rescue nil?
153
+ end
154
+
155
+ it 'should generate valid request with match SPH_MATCH_ALL' do
156
+ expected = sphinx_fixture('match_all')
157
+ @sock.should_receive(:send).with(expected, 0)
158
+ @sphinx.SetMatchMode(Sphinx::Client::SPH_MATCH_ALL)
159
+ @sphinx.Query('query') rescue nil?
160
+ end
161
+
162
+ it 'should generate valid request with match SPH_MATCH_ANY' do
163
+ expected = sphinx_fixture('match_any')
164
+ @sock.should_receive(:send).with(expected, 0)
165
+ @sphinx.SetMatchMode(Sphinx::Client::SPH_MATCH_ANY)
166
+ @sphinx.Query('query') rescue nil?
167
+ end
168
+
169
+ it 'should generate valid request with match SPH_MATCH_PHRASE' do
170
+ expected = sphinx_fixture('match_phrase')
171
+ @sock.should_receive(:send).with(expected, 0)
172
+ @sphinx.SetMatchMode(Sphinx::Client::SPH_MATCH_PHRASE)
173
+ @sphinx.Query('query') rescue nil?
174
+ end
175
+
176
+ it 'should generate valid request with match SPH_MATCH_BOOLEAN' do
177
+ expected = sphinx_fixture('match_boolean')
178
+ @sock.should_receive(:send).with(expected, 0)
179
+ @sphinx.SetMatchMode(Sphinx::Client::SPH_MATCH_BOOLEAN)
180
+ @sphinx.Query('query') rescue nil?
181
+ end
182
+
183
+ it 'should generate valid request with match SPH_MATCH_EXTENDED' do
184
+ expected = sphinx_fixture('match_extended')
185
+ @sock.should_receive(:send).with(expected, 0)
186
+ @sphinx.SetMatchMode(Sphinx::Client::SPH_MATCH_EXTENDED)
187
+ @sphinx.Query('query') rescue nil?
188
+ end
189
+
190
+ it 'should generate valid request with match SPH_MATCH_FULLSCAN' do
191
+ expected = sphinx_fixture('match_fullscan')
192
+ @sock.should_receive(:send).with(expected, 0)
193
+ @sphinx.SetMatchMode(Sphinx::Client::SPH_MATCH_FULLSCAN)
194
+ @sphinx.Query('query') rescue nil?
195
+ end
196
+
197
+ it 'should generate valid request with match SPH_MATCH_EXTENDED2' do
198
+ expected = sphinx_fixture('match_extended2')
199
+ @sock.should_receive(:send).with(expected, 0)
200
+ @sphinx.SetMatchMode(Sphinx::Client::SPH_MATCH_EXTENDED2)
201
+ @sphinx.Query('query') rescue nil?
202
+ end
203
+
204
+ it 'should generate valid request with ranking mode SPH_RANK_PROXIMITY_BM25' do
205
+ expected = sphinx_fixture('ranking_proximity_bm25')
206
+ @sock.should_receive(:send).with(expected, 0)
207
+ @sphinx.SetRankingMode(Sphinx::Client::SPH_RANK_PROXIMITY_BM25)
208
+ @sphinx.Query('query') rescue nil?
209
+ end
210
+
211
+ it 'should generate valid request with ranking mode SPH_RANK_BM25' do
212
+ expected = sphinx_fixture('ranking_bm25')
213
+ @sock.should_receive(:send).with(expected, 0)
214
+ @sphinx.SetRankingMode(Sphinx::Client::SPH_RANK_BM25)
215
+ @sphinx.Query('query') rescue nil?
216
+ end
217
+
218
+ it 'should generate valid request with ranking mode SPH_RANK_NONE' do
219
+ expected = sphinx_fixture('ranking_none')
220
+ @sock.should_receive(:send).with(expected, 0)
221
+ @sphinx.SetRankingMode(Sphinx::Client::SPH_RANK_NONE)
222
+ @sphinx.Query('query') rescue nil?
223
+ end
224
+
225
+ it 'should generate valid request with ranking mode SPH_RANK_WORDCOUNT' do
226
+ expected = sphinx_fixture('ranking_wordcount')
227
+ @sock.should_receive(:send).with(expected, 0)
228
+ @sphinx.SetRankingMode(Sphinx::Client::SPH_RANK_WORDCOUNT)
229
+ @sphinx.Query('query') rescue nil?
230
+ end
231
+
232
+ it 'should generate valid request with sort mode SPH_SORT_RELEVANCE' do
233
+ expected = sphinx_fixture('sort_relevance')
234
+ @sock.should_receive(:send).with(expected, 0)
235
+ @sphinx.SetSortMode(Sphinx::Client::SPH_SORT_RELEVANCE)
236
+ @sphinx.Query('query') rescue nil?
237
+ end
238
+
239
+ it 'should generate valid request with sort mode SPH_SORT_ATTR_DESC' do
240
+ expected = sphinx_fixture('sort_attr_desc')
241
+ @sock.should_receive(:send).with(expected, 0)
242
+ @sphinx.SetSortMode(Sphinx::Client::SPH_SORT_ATTR_DESC, 'sortby')
243
+ @sphinx.Query('query') rescue nil?
244
+ end
245
+
246
+ it 'should generate valid request with sort mode SPH_SORT_ATTR_ASC' do
247
+ expected = sphinx_fixture('sort_attr_asc')
248
+ @sock.should_receive(:send).with(expected, 0)
249
+ @sphinx.SetSortMode(Sphinx::Client::SPH_SORT_ATTR_ASC, 'sortby')
250
+ @sphinx.Query('query') rescue nil?
251
+ end
252
+
253
+ it 'should generate valid request with sort mode SPH_SORT_TIME_SEGMENTS' do
254
+ expected = sphinx_fixture('sort_time_segments')
255
+ @sock.should_receive(:send).with(expected, 0)
256
+ @sphinx.SetSortMode(Sphinx::Client::SPH_SORT_TIME_SEGMENTS, 'sortby')
257
+ @sphinx.Query('query') rescue nil?
258
+ end
259
+
260
+ it 'should generate valid request with sort mode SPH_SORT_EXTENDED' do
261
+ expected = sphinx_fixture('sort_extended')
262
+ @sock.should_receive(:send).with(expected, 0)
263
+ @sphinx.SetSortMode(Sphinx::Client::SPH_SORT_EXTENDED, 'sortby')
264
+ @sphinx.Query('query') rescue nil?
265
+ end
266
+
267
+
268
+ it 'should generate valid request with sort mode SPH_SORT_EXPR' do
269
+ expected = sphinx_fixture('sort_EXPR')
270
+ @sock.should_receive(:send).with(expected, 0)
271
+ @sphinx.SetSortMode(Sphinx::Client::SPH_SORT_EXPR, 'sortby')
272
+ @sphinx.Query('query') rescue nil?
273
+ end
274
+
275
+ it 'should generate valid request with weights' do
276
+ expected = sphinx_fixture('weights')
277
+ @sock.should_receive(:send).with(expected, 0)
278
+ @sphinx.SetWeights([10, 20, 30, 40])
279
+ @sphinx.Query('query') rescue nil?
280
+ end
281
+
282
+ it 'should generate valid request with field weights' do
283
+ expected = sphinx_fixture('field_weights')
284
+ @sock.should_receive(:send).with(expected, 0)
285
+ @sphinx.SetFieldWeights({'field1' => 10, 'field2' => 20})
286
+ @sphinx.Query('query') rescue nil?
287
+ end
288
+
289
+ it 'should generate valid request with index weights' do
290
+ expected = sphinx_fixture('index_weights')
291
+ @sock.should_receive(:send).with(expected, 0)
292
+ @sphinx.SetIndexWeights({'index1' => 10, 'index2' => 20})
293
+ @sphinx.Query('query') rescue nil?
294
+ end
295
+
296
+ it 'should generate valid request with ID range' do
297
+ expected = sphinx_fixture('id_range')
298
+ @sock.should_receive(:send).with(expected, 0)
299
+ @sphinx.SetIDRange(10, 20)
300
+ @sphinx.Query('query') rescue nil?
301
+ end
302
+
303
+ it 'should generate valid request with ID range and 64-bit ints' do
304
+ expected = sphinx_fixture('id_range64')
305
+ @sock.should_receive(:send).with(expected, 0)
306
+ @sphinx.SetIDRange(8589934591, 17179869183)
307
+ @sphinx.Query('query') rescue nil?
308
+ end
309
+
310
+ it 'should generate valid request with values filter' do
311
+ expected = sphinx_fixture('filter')
312
+ @sock.should_receive(:send).with(expected, 0)
313
+ @sphinx.SetFilter('attr', [10, 20, 30])
314
+ @sphinx.Query('query') rescue nil?
315
+ end
316
+
317
+ it 'should generate valid request with two values filters' do
318
+ expected = sphinx_fixture('filters')
319
+ @sock.should_receive(:send).with(expected, 0)
320
+ @sphinx.SetFilter('attr2', [40, 50])
321
+ @sphinx.SetFilter('attr1', [10, 20, 30])
322
+ @sphinx.Query('query') rescue nil?
323
+ end
324
+
325
+ it 'should generate valid request with values filter excluded' do
326
+ expected = sphinx_fixture('filter_exclude')
327
+ @sock.should_receive(:send).with(expected, 0)
328
+ @sphinx.SetFilter('attr', [10, 20, 30], true)
329
+ @sphinx.Query('query') rescue nil?
330
+ end
331
+
332
+ it 'should generate valid request with values filter range' do
333
+ expected = sphinx_fixture('filter_range')
334
+ @sock.should_receive(:send).with(expected, 0)
335
+ @sphinx.SetFilterRange('attr', 10, 20)
336
+ @sphinx.Query('query') rescue nil?
337
+ end
338
+
339
+ it 'should generate valid request with two filter ranges' do
340
+ expected = sphinx_fixture('filter_ranges')
341
+ @sock.should_receive(:send).with(expected, 0)
342
+ @sphinx.SetFilterRange('attr2', 30, 40)
343
+ @sphinx.SetFilterRange('attr1', 10, 20)
344
+ @sphinx.Query('query') rescue nil?
345
+ end
346
+
347
+ it 'should generate valid request with filter range excluded' do
348
+ expected = sphinx_fixture('filter_range_exclude')
349
+ @sock.should_receive(:send).with(expected, 0)
350
+ @sphinx.SetFilterRange('attr', 10, 20, true)
351
+ @sphinx.Query('query') rescue nil?
352
+ end
353
+
354
+ it 'should generate valid request with float filter range' do
355
+ expected = sphinx_fixture('filter_float_range')
356
+ @sock.should_receive(:send).with(expected, 0)
357
+ @sphinx.SetFilterFloatRange('attr', 10.5, 20.3)
358
+ @sphinx.Query('query') rescue nil?
359
+ end
360
+
361
+ it 'should generate valid request with float filter excluded' do
362
+ expected = sphinx_fixture('filter_float_range_exclude')
363
+ @sock.should_receive(:send).with(expected, 0)
364
+ @sphinx.SetFilterFloatRange('attr', 10.5, 20.3, true)
365
+ @sphinx.Query('query') rescue nil?
366
+ end
367
+
368
+ it 'should generate valid request with different filters' do
369
+ expected = sphinx_fixture('filters_different')
370
+ @sock.should_receive(:send).with(expected, 0)
371
+ @sphinx.SetFilterRange('attr1', 10, 20, true)
372
+ @sphinx.SetFilter('attr3', [30, 40, 50])
373
+ @sphinx.SetFilterRange('attr1', 60, 70)
374
+ @sphinx.SetFilter('attr2', [80, 90, 100], true)
375
+ @sphinx.SetFilterFloatRange('attr1', 60.8, 70.5)
376
+ @sphinx.Query('query') rescue nil?
377
+ end
378
+
379
+ it 'should generate valid request with geographical anchor point' do
380
+ expected = sphinx_fixture('geo_anchor')
381
+ @sock.should_receive(:send).with(expected, 0)
382
+ @sphinx.SetGeoAnchor('attrlat', 'attrlong', 20.3, 40.7)
383
+ @sphinx.Query('query') rescue nil?
384
+ end
385
+
386
+ it 'should generate valid request with group by SPH_GROUPBY_DAY' do
387
+ expected = sphinx_fixture('group_by_day')
388
+ @sock.should_receive(:send).with(expected, 0)
389
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_DAY)
390
+ @sphinx.Query('query') rescue nil?
391
+ end
392
+
393
+ it 'should generate valid request with group by SPH_GROUPBY_WEEK' do
394
+ expected = sphinx_fixture('group_by_week')
395
+ @sock.should_receive(:send).with(expected, 0)
396
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_WEEK)
397
+ @sphinx.Query('query') rescue nil?
398
+ end
399
+
400
+ it 'should generate valid request with group by SPH_GROUPBY_MONTH' do
401
+ expected = sphinx_fixture('group_by_month')
402
+ @sock.should_receive(:send).with(expected, 0)
403
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_MONTH)
404
+ @sphinx.Query('query') rescue nil?
405
+ end
406
+
407
+ it 'should generate valid request with group by SPH_GROUPBY_YEAR' do
408
+ expected = sphinx_fixture('group_by_year')
409
+ @sock.should_receive(:send).with(expected, 0)
410
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_YEAR)
411
+ @sphinx.Query('query') rescue nil?
412
+ end
413
+
414
+ it 'should generate valid request with group by SPH_GROUPBY_ATTR' do
415
+ expected = sphinx_fixture('group_by_attr')
416
+ @sock.should_receive(:send).with(expected, 0)
417
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_ATTR)
418
+ @sphinx.Query('query') rescue nil?
419
+ end
420
+
421
+ it 'should generate valid request with group by SPH_GROUPBY_ATTRPAIR' do
422
+ expected = sphinx_fixture('group_by_attrpair')
423
+ @sock.should_receive(:send).with(expected, 0)
424
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_ATTRPAIR)
425
+ @sphinx.Query('query') rescue nil?
426
+ end
427
+
428
+ it 'should generate valid request with group by SPH_GROUPBY_DAY with sort' do
429
+ expected = sphinx_fixture('group_by_day_sort')
430
+ @sock.should_receive(:send).with(expected, 0)
431
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_DAY, 'somesort')
432
+ @sphinx.Query('query') rescue nil?
433
+ end
434
+
435
+ it 'should generate valid request with count-distinct attribute' do
436
+ expected = sphinx_fixture('group_distinct')
437
+ @sock.should_receive(:send).with(expected, 0)
438
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_DAY)
439
+ @sphinx.SetGroupDistinct('attr')
440
+ @sphinx.Query('query') rescue nil?
441
+ end
442
+
443
+ it 'should generate valid request with retries count specified' do
444
+ expected = sphinx_fixture('retries')
445
+ @sock.should_receive(:send).with(expected, 0)
446
+ @sphinx.SetRetries(10)
447
+ @sphinx.Query('query') rescue nil?
448
+ end
449
+
450
+ it 'should generate valid request with retries count and delay specified' do
451
+ expected = sphinx_fixture('retries_delay')
452
+ @sock.should_receive(:send).with(expected, 0)
453
+ @sphinx.SetRetries(10, 20)
454
+ @sphinx.Query('query') rescue nil?
455
+ end
456
+ end
457
+
458
+ describe 'The RunQueries method of SphinxApi' do
459
+ include SphinxFixtureHelper
460
+
461
+ before(:each) do
462
+ @sphinx = Sphinx::Client.new
463
+ @sock = mock('TCPSocket')
464
+ @sphinx.stub!(:Connect).and_yield(@sock)
465
+ @sphinx.stub!(:GetResponse).and_raise(Sphinx::SphinxError)
466
+ end
467
+
468
+ it 'should generate valid request for multiple queries' do
469
+ expected = sphinx_fixture('miltiple_queries')
470
+ @sock.should_receive(:send).with(expected, 0)
471
+
472
+ @sphinx.SetRetries(10, 20)
473
+ @sphinx.AddQuery('test1')
474
+ @sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_DAY)
475
+ @sphinx.AddQuery('test2') rescue nil?
476
+
477
+ @sphinx.RunQueries rescue nil?
478
+ end
479
+ end
480
+
481
+ describe 'The BuildExcerpts method of SphinxApi' do
482
+ include SphinxFixtureHelper
483
+
484
+ before(:each) do
485
+ @sphinx = Sphinx::Client.new
486
+ @sock = mock('TCPSocket')
487
+ @sphinx.stub!(:Connect).and_yield(@sock)
488
+ @sphinx.stub!(:GetResponse).and_raise(Sphinx::SphinxError)
489
+ end
490
+
491
+ it 'should generate valid request with default parameters' do
492
+ expected = sphinx_fixture('excerpt_default')
493
+ @sock.should_receive(:send).with(expected, 0)
494
+ @sphinx.BuildExcerpts(['10', '20'], 'index', 'word1 word2') rescue nil?
495
+ end
496
+
497
+ it 'should generate valid request with custom parameters' do
498
+ expected = sphinx_fixture('excerpt_custom')
499
+ @sock.should_receive(:send).with(expected, 0)
500
+ @sphinx.BuildExcerpts(['10', '20'], 'index', 'word1 word2', { 'before_match' => 'before',
501
+ 'after_match' => 'after',
502
+ 'chunk_separator' => 'separator',
503
+ 'limit' => 10 }) rescue nil?
504
+ end
505
+
506
+ it 'should generate valid request with flags' do
507
+ expected = sphinx_fixture('excerpt_flags')
508
+ @sock.should_receive(:send).with(expected, 0)
509
+ @sphinx.BuildExcerpts(['10', '20'], 'index', 'word1 word2', { 'exact_phrase' => true,
510
+ 'single_passage' => true,
511
+ 'use_boundaries' => true,
512
+ 'weight_order' => true }) rescue nil?
513
+ end
514
+ end
515
+
516
+ describe 'The BuildKeywords method of SphinxApi' do
517
+ include SphinxFixtureHelper
518
+
519
+ before(:each) do
520
+ @sphinx = Sphinx::Client.new
521
+ @sock = mock('TCPSocket')
522
+ @sphinx.stub!(:Connect).and_yield(@sock)
523
+ @sphinx.stub!(:GetResponse).and_raise(Sphinx::SphinxError)
524
+ end
525
+
526
+ it 'should generate valid request' do
527
+ expected = sphinx_fixture('keywords')
528
+ @sock.should_receive(:send).with(expected, 0)
529
+ @sphinx.BuildKeywords('test', 'index', true) rescue nil?
530
+ end
531
+ end
532
+
533
+ describe 'The UpdateAttributes method of SphinxApi' do
534
+ include SphinxFixtureHelper
535
+
536
+ before(:each) do
537
+ @sphinx = Sphinx::Client.new
538
+ @sock = mock('TCPSocket')
539
+ @sphinx.stub!(:Connect).and_yield(@sock)
540
+ @sphinx.stub!(:GetResponse).and_raise(Sphinx::SphinxError)
541
+ end
542
+
543
+ it 'should generate valid request' do
544
+ expected = sphinx_fixture('update_attributes')
545
+ @sock.should_receive(:send).with(expected, 0)
546
+ @sphinx.UpdateAttributes('index', ['group'], { 123 => [456] }) rescue nil?
547
+ end
548
+ end