rlibsphinxclient 0.2.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 (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