ninjudd-model_set 0.9.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.
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/VERSION.yml +4 -0
- data/lib/model_set.rb +712 -0
- data/lib/model_set/conditioned.rb +33 -0
- data/lib/model_set/conditions.rb +103 -0
- data/lib/model_set/query.rb +128 -0
- data/lib/model_set/raw_query.rb +41 -0
- data/lib/model_set/raw_sql_query.rb +19 -0
- data/lib/model_set/set_query.rb +34 -0
- data/lib/model_set/solr_query.rb +70 -0
- data/lib/model_set/sphinx_query.rb +148 -0
- data/lib/model_set/sql_base_query.rb +52 -0
- data/lib/model_set/sql_query.rb +75 -0
- data/lib/multi_set.rb +67 -0
- data/test/model_set_test.rb +283 -0
- data/test/multi_set_test.rb +65 -0
- data/test/test_helper.rb +23 -0
- data/vendor/sphinx_client/README.rdoc +41 -0
- data/vendor/sphinx_client/Rakefile +21 -0
- data/vendor/sphinx_client/init.rb +1 -0
- data/vendor/sphinx_client/install.rb +5 -0
- data/vendor/sphinx_client/lib/sphinx.rb +6 -0
- data/vendor/sphinx_client/lib/sphinx/client.rb +1093 -0
- data/vendor/sphinx_client/lib/sphinx/request.rb +50 -0
- data/vendor/sphinx_client/lib/sphinx/response.rb +69 -0
- data/vendor/sphinx_client/spec/client_response_spec.rb +112 -0
- data/vendor/sphinx_client/spec/client_spec.rb +469 -0
- data/vendor/sphinx_client/spec/fixtures/default_search.php +8 -0
- data/vendor/sphinx_client/spec/fixtures/default_search_index.php +8 -0
- data/vendor/sphinx_client/spec/fixtures/excerpt_custom.php +11 -0
- data/vendor/sphinx_client/spec/fixtures/excerpt_default.php +8 -0
- data/vendor/sphinx_client/spec/fixtures/excerpt_flags.php +11 -0
- data/vendor/sphinx_client/spec/fixtures/field_weights.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/filter.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/filter_exclude.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/filter_float_range.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/filter_float_range_exclude.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/filter_range.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/filter_range_exclude.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/filter_range_int64.php +10 -0
- data/vendor/sphinx_client/spec/fixtures/filter_ranges.php +10 -0
- data/vendor/sphinx_client/spec/fixtures/filters.php +10 -0
- data/vendor/sphinx_client/spec/fixtures/filters_different.php +13 -0
- data/vendor/sphinx_client/spec/fixtures/geo_anchor.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_by_attr.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_by_attrpair.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_by_day.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_by_day_sort.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_by_month.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_by_week.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_by_year.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/group_distinct.php +10 -0
- data/vendor/sphinx_client/spec/fixtures/id_range.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/id_range64.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/index_weights.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/keywords.php +8 -0
- data/vendor/sphinx_client/spec/fixtures/limits.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/limits_cutoff.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/limits_max.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/limits_max_cutoff.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/match_all.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/match_any.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/match_boolean.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/match_extended.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/match_extended2.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/match_fullscan.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/match_phrase.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/max_query_time.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/miltiple_queries.php +12 -0
- data/vendor/sphinx_client/spec/fixtures/ranking_bm25.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/ranking_none.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/ranking_proximity.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/ranking_proximity_bm25.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/ranking_wordcount.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/retries.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/retries_delay.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/select.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/set_override.php +11 -0
- data/vendor/sphinx_client/spec/fixtures/sort_attr_asc.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/sort_attr_desc.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/sort_expr.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/sort_extended.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/sort_relevance.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/sort_time_segments.php +9 -0
- data/vendor/sphinx_client/spec/fixtures/sphinxapi.php +1269 -0
- data/vendor/sphinx_client/spec/fixtures/update_attributes.php +8 -0
- data/vendor/sphinx_client/spec/fixtures/update_attributes_mva.php +8 -0
- data/vendor/sphinx_client/spec/fixtures/weights.php +9 -0
- data/vendor/sphinx_client/spec/sphinx/sphinx-id64.conf +67 -0
- data/vendor/sphinx_client/spec/sphinx/sphinx.conf +67 -0
- data/vendor/sphinx_client/spec/sphinx/sphinx_test.sql +86 -0
- data/vendor/sphinx_client/sphinx.yml.tpl +3 -0
- data/vendor/sphinx_client/tasks/sphinx.rake +75 -0
- metadata +154 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Sphinx
|
|
2
|
+
# Pack ints, floats, strings, and arrays to internal representation
|
|
3
|
+
# needed by Sphinx search engine.
|
|
4
|
+
class Request
|
|
5
|
+
# Initialize new request.
|
|
6
|
+
def initialize
|
|
7
|
+
@request = ''
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Put int(s) to request.
|
|
11
|
+
def put_int(*ints)
|
|
12
|
+
ints.each { |i| @request << [i].pack('N') }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Put 64-bit int(s) to request.
|
|
16
|
+
def put_int64(*ints)
|
|
17
|
+
ints.each { |i| @request << [i].pack('q').reverse }#[i >> 32, i & ((1 << 32) - 1)].pack('NN') }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Put string(s) to request (first length, then the string itself).
|
|
21
|
+
def put_string(*strings)
|
|
22
|
+
strings.each { |s| @request << [s.length].pack('N') + s }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Put float(s) to request.
|
|
26
|
+
def put_float(*floats)
|
|
27
|
+
floats.each do |f|
|
|
28
|
+
t1 = [f].pack('f') # machine order
|
|
29
|
+
t2 = t1.unpack('L*').first # int in machine order
|
|
30
|
+
@request << [t2].pack('N')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Put array of ints to request (first length, then the array itself)
|
|
35
|
+
def put_int_array(arr)
|
|
36
|
+
put_int arr.length, *arr
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Put array of 64-bit ints to request (first length, then the array itself)
|
|
40
|
+
def put_int64_array(arr)
|
|
41
|
+
put_int arr.length
|
|
42
|
+
put_int64(*arr)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns the entire message
|
|
46
|
+
def to_s
|
|
47
|
+
@request
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Sphinx
|
|
2
|
+
# Unpack internal Sphinx representation of ints, floats, strings, and arrays.
|
|
3
|
+
# needed by Sphinx search engine.
|
|
4
|
+
class Response
|
|
5
|
+
# Initialize new request.
|
|
6
|
+
def initialize(response)
|
|
7
|
+
@response = response
|
|
8
|
+
@position = 0
|
|
9
|
+
@size = response.length
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Gets current stream position.
|
|
13
|
+
def position
|
|
14
|
+
@position
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Gets response size.
|
|
18
|
+
def size
|
|
19
|
+
@size
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Returns <tt>true</tt> when response stream is out.
|
|
23
|
+
def eof?
|
|
24
|
+
@position >= @size
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Get int from stream.
|
|
28
|
+
def get_int
|
|
29
|
+
raise EOFError if @position + 4 > @size
|
|
30
|
+
value = @response[@position, 4].unpack('N*').first
|
|
31
|
+
@position += 4
|
|
32
|
+
return value
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Get 64-bit int from stream.
|
|
36
|
+
def get_int64
|
|
37
|
+
raise EOFError if @position + 8 > @size
|
|
38
|
+
hi, lo = @response[@position, 8].unpack('N*N*')
|
|
39
|
+
@position += 8
|
|
40
|
+
return (hi << 32) + lo
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Get array of <tt>count</tt> ints from stream.
|
|
44
|
+
def get_ints(count)
|
|
45
|
+
length = 4 * count
|
|
46
|
+
raise EOFError if @position + length > @size
|
|
47
|
+
values = @response[@position, length].unpack('N*' * count)
|
|
48
|
+
@position += length
|
|
49
|
+
return values
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Get string from stream.
|
|
53
|
+
def get_string
|
|
54
|
+
length = get_int
|
|
55
|
+
raise EOFError if @position + length > @size
|
|
56
|
+
value = length > 0 ? @response[@position, length] : ''
|
|
57
|
+
@position += length
|
|
58
|
+
return value
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Get float from stream.
|
|
62
|
+
def get_float
|
|
63
|
+
raise EOFError if @position + 4 > @size
|
|
64
|
+
uval = @response[@position, 4].unpack('N*').first;
|
|
65
|
+
@position += 4
|
|
66
|
+
return ([uval].pack('L')).unpack('f*').first
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../init'
|
|
2
|
+
|
|
3
|
+
# To execute these tests you need to execute sphinx_test.sql and configure sphinx using sphinx.conf
|
|
4
|
+
# (both files are placed under sphinx directory)
|
|
5
|
+
context 'The SphinxApi connected to Sphinx' do
|
|
6
|
+
setup do
|
|
7
|
+
@sphinx = Sphinx::Client.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
specify 'should parse response in Query method' do
|
|
11
|
+
result = @sphinx.Query('wifi', 'test1')
|
|
12
|
+
validate_results_wifi(result)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
specify 'should process 64-bit keys in Query method' do
|
|
16
|
+
result = @sphinx.Query('wifi', 'test2')
|
|
17
|
+
result['total_found'].should == 3
|
|
18
|
+
result['matches'].length.should == 3
|
|
19
|
+
result['matches'][0]['id'].should == 4294967298
|
|
20
|
+
result['matches'][1]['id'].should == 4294967299
|
|
21
|
+
result['matches'][2]['id'].should == 4294967297
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
specify 'should parse batch-query responce in RunQueries method' do
|
|
25
|
+
@sphinx.AddQuery('wifi', 'test1')
|
|
26
|
+
@sphinx.AddQuery('gprs', 'test1')
|
|
27
|
+
results = @sphinx.RunQueries
|
|
28
|
+
results.should be_an_instance_of(Array)
|
|
29
|
+
results.length.should == 2
|
|
30
|
+
validate_results_wifi(results[0])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
specify 'should parse response in BuildExcerpts method' do
|
|
34
|
+
result = @sphinx.BuildExcerpts(['what the world', 'London is the capital of Great Britain'], 'test1', 'the')
|
|
35
|
+
result.should == ['what <b>the</b> world', 'London is <b>the</b> capital of Great Britain']
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
specify 'should parse response in BuildKeywords method' do
|
|
39
|
+
result = @sphinx.BuildKeywords('wifi gprs', 'test1', true)
|
|
40
|
+
result.should == [
|
|
41
|
+
{ 'normalized' => 'wifi', 'tokenized' => 'wifi', 'hits' => 6, 'docs' => 3 },
|
|
42
|
+
{ 'normalized' => 'gprs', 'tokenized' => 'gprs', 'hits' => 1, 'docs' => 1 }
|
|
43
|
+
]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
specify 'should parse response in UpdateAttributes method' do
|
|
47
|
+
@sphinx.UpdateAttributes('test1', ['group_id'], { 2 => [1] }).should == 1
|
|
48
|
+
result = @sphinx.Query('wifi', 'test1')
|
|
49
|
+
result['matches'][0]['attrs']['group_id'].should == 1
|
|
50
|
+
@sphinx.UpdateAttributes('test1', ['group_id'], { 2 => [2] }).should == 1
|
|
51
|
+
result = @sphinx.Query('wifi', 'test1')
|
|
52
|
+
result['matches'][0]['attrs']['group_id'].should == 2
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
specify 'should parse response in UpdateAttributes method with MVA' do
|
|
56
|
+
@sphinx.UpdateAttributes('test1', ['tags'], { 2 => [[1, 2, 3, 4, 5, 6, 7, 8, 9]] }, true).should == 1
|
|
57
|
+
result = @sphinx.Query('wifi', 'test1')
|
|
58
|
+
result['matches'][0]['attrs']['tags'].should == [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
59
|
+
@sphinx.UpdateAttributes('test1', ['tags'], { 2 => [[5, 6, 7, 8]] }, true).should == 1
|
|
60
|
+
result = @sphinx.Query('wifi', 'test1')
|
|
61
|
+
result['matches'][0]['attrs']['tags'].should == [5, 6, 7, 8]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
specify 'should process errors in Query method' do
|
|
65
|
+
@sphinx.Query('wifi', 'fakeindex').should be_false
|
|
66
|
+
@sphinx.GetLastError.length.should_not == 0
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
specify 'should process errors in RunQueries method' do
|
|
70
|
+
@sphinx.AddQuery('wifi', 'fakeindex')
|
|
71
|
+
r = @sphinx.RunQueries
|
|
72
|
+
r[0]['error'].length.should_not == 0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def validate_results_wifi(result)
|
|
76
|
+
result['total_found'].should == 3
|
|
77
|
+
result['matches'].length.should == 3
|
|
78
|
+
result['time'].should_not be_nil
|
|
79
|
+
result['attrs'].should == {
|
|
80
|
+
'group_id' => Sphinx::Client::SPH_ATTR_INTEGER,
|
|
81
|
+
'created_at' => Sphinx::Client::SPH_ATTR_TIMESTAMP,
|
|
82
|
+
'rating' => Sphinx::Client::SPH_ATTR_FLOAT,
|
|
83
|
+
'tags' => Sphinx::Client::SPH_ATTR_MULTI | Sphinx::Client::SPH_ATTR_INTEGER
|
|
84
|
+
}
|
|
85
|
+
result['fields'].should == [ 'name', 'description' ]
|
|
86
|
+
result['total'].should == 3
|
|
87
|
+
result['matches'].should be_an_instance_of(Array)
|
|
88
|
+
|
|
89
|
+
result['matches'][0]['id'].should == 2
|
|
90
|
+
result['matches'][0]['weight'].should == 2
|
|
91
|
+
result['matches'][0]['attrs']['group_id'].should == 2
|
|
92
|
+
result['matches'][0]['attrs']['created_at'].should == 1175658555
|
|
93
|
+
result['matches'][0]['attrs']['tags'].should == [5, 6, 7, 8]
|
|
94
|
+
('%0.2f' % result['matches'][0]['attrs']['rating']).should == '54.85'
|
|
95
|
+
|
|
96
|
+
result['matches'][1]['id'].should == 3
|
|
97
|
+
result['matches'][1]['weight'].should == 2
|
|
98
|
+
result['matches'][1]['attrs']['group_id'].should == 1
|
|
99
|
+
result['matches'][1]['attrs']['created_at'].should == 1175658647
|
|
100
|
+
result['matches'][1]['attrs']['tags'].should == [1, 7, 9, 10]
|
|
101
|
+
('%0.2f' % result['matches'][1]['attrs']['rating']).should == '16.25'
|
|
102
|
+
|
|
103
|
+
result['matches'][2]['id'].should == 1
|
|
104
|
+
result['matches'][2]['weight'].should == 1
|
|
105
|
+
result['matches'][2]['attrs']['group_id'].should == 1
|
|
106
|
+
result['matches'][2]['attrs']['created_at'].should == 1175658490
|
|
107
|
+
result['matches'][2]['attrs']['tags'].should == [1, 2, 3, 4]
|
|
108
|
+
('%0.2f' % result['matches'][2]['attrs']['rating']).should == '13.32'
|
|
109
|
+
|
|
110
|
+
result['words'].should == { 'wifi' => { 'hits' => 6, 'docs' => 3 } }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../init'
|
|
2
|
+
|
|
3
|
+
class SphinxSpecError < StandardError; end
|
|
4
|
+
|
|
5
|
+
module SphinxFixtureHelper
|
|
6
|
+
def sphinx_fixture(name)
|
|
7
|
+
`php #{File.dirname(__FILE__)}/fixtures/#{name}.php`
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module SphinxApiCall
|
|
12
|
+
def create_sphinx
|
|
13
|
+
@sphinx = Sphinx::Client.new
|
|
14
|
+
@sock = mock('TCPSocket')
|
|
15
|
+
@sphinx.stub!(:Connect).and_return(@sock)
|
|
16
|
+
@sphinx.stub!(:GetResponse).and_raise(SphinxSpecError)
|
|
17
|
+
return @sphinx
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def safe_call
|
|
21
|
+
yield
|
|
22
|
+
rescue SphinxSpecError
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'The Connect method of Sphinx::Client' do
|
|
27
|
+
before(:each) do
|
|
28
|
+
@sphinx = Sphinx::Client.new
|
|
29
|
+
@sock = mock('TCPSocket')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should establish TCP connection to the server and initialize session' do
|
|
33
|
+
TCPSocket.should_receive(:new).with('localhost', 3312).and_return(@sock)
|
|
34
|
+
@sock.should_receive(:recv).with(4).and_return([1].pack('N'))
|
|
35
|
+
@sock.should_receive(:send).with([1].pack('N'), 0)
|
|
36
|
+
@sphinx.send(:Connect).should be(@sock)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'should raise exception when searchd protocol is not 1+' do
|
|
40
|
+
TCPSocket.should_receive(:new).with('localhost', 3312).and_return(@sock)
|
|
41
|
+
@sock.should_receive(:recv).with(4).and_return([0].pack('N'))
|
|
42
|
+
@sock.should_receive(:close)
|
|
43
|
+
lambda { @sphinx.send(:Connect) }.should raise_error(Sphinx::SphinxConnectError)
|
|
44
|
+
@sphinx.GetLastError.should == 'expected searchd protocol version 1+, got version \'0\''
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'should raise exception on connection error' do
|
|
48
|
+
TCPSocket.should_receive(:new).with('localhost', 3312).and_raise(Errno::EBADF)
|
|
49
|
+
lambda { @sphinx.send(:Connect) }.should raise_error(Sphinx::SphinxConnectError)
|
|
50
|
+
@sphinx.GetLastError.should == 'connection to localhost:3312 failed'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'should use custom host and port' do
|
|
54
|
+
@sphinx.SetServer('anotherhost', 55555)
|
|
55
|
+
TCPSocket.should_receive(:new).with('anotherhost', 55555).and_raise(Errno::EBADF)
|
|
56
|
+
lambda { @sphinx.send(:Connect) }.should raise_error(Sphinx::SphinxConnectError)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe 'The GetResponse method of Sphinx::Client' do
|
|
61
|
+
before(:each) do
|
|
62
|
+
@sphinx = Sphinx::Client.new
|
|
63
|
+
@sock = mock('TCPSocket')
|
|
64
|
+
@sock.should_receive(:close)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'should receive response' do
|
|
68
|
+
@sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 4].pack('n2N'))
|
|
69
|
+
@sock.should_receive(:recv).with(4).and_return([0].pack('N'))
|
|
70
|
+
@sphinx.send(:GetResponse, @sock, 1)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'should raise exception on zero-sized response' do
|
|
74
|
+
@sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 0].pack('n2N'))
|
|
75
|
+
lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxResponseError)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'should raise exception when response is incomplete' do
|
|
79
|
+
@sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 4].pack('n2N'))
|
|
80
|
+
@sock.should_receive(:recv).with(4).and_raise(EOFError)
|
|
81
|
+
lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxResponseError)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'should set warning message when SEARCHD_WARNING received' do
|
|
85
|
+
@sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_WARNING, 1, 14].pack('n2N'))
|
|
86
|
+
@sock.should_receive(:recv).with(14).and_return([5].pack('N') + 'helloworld')
|
|
87
|
+
@sphinx.send(:GetResponse, @sock, 1).should == 'world'
|
|
88
|
+
@sphinx.GetLastWarning.should == 'hello'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'should raise exception when SEARCHD_ERROR received' do
|
|
92
|
+
@sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_ERROR, 1, 9].pack('n2N'))
|
|
93
|
+
@sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
|
|
94
|
+
lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxInternalError)
|
|
95
|
+
@sphinx.GetLastError.should == 'searchd error: hello'
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'should raise exception when SEARCHD_RETRY received' do
|
|
99
|
+
@sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_RETRY, 1, 9].pack('n2N'))
|
|
100
|
+
@sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
|
|
101
|
+
lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxTemporaryError)
|
|
102
|
+
@sphinx.GetLastError.should == 'temporary searchd error: hello'
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'should raise exception when unknown status received' do
|
|
106
|
+
@sock.should_receive(:recv).with(8).and_return([65535, 1, 9].pack('n2N'))
|
|
107
|
+
@sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
|
|
108
|
+
lambda { @sphinx.send(:GetResponse, @sock, 1) }.should raise_error(Sphinx::SphinxUnknownError)
|
|
109
|
+
@sphinx.GetLastError.should == 'unknown status code: \'65535\''
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'should set warning when server is older than client' do
|
|
113
|
+
@sock.should_receive(:recv).with(8).and_return([Sphinx::Client::SEARCHD_OK, 1, 9].pack('n2N'))
|
|
114
|
+
@sock.should_receive(:recv).with(9).and_return([1].pack('N') + 'hello')
|
|
115
|
+
@sphinx.send(:GetResponse, @sock, 5)
|
|
116
|
+
@sphinx.GetLastWarning.should == 'searchd command v.0.1 older than client\'s v.0.5, some options might not work'
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
describe 'The Query method of Sphinx::Client' do
|
|
121
|
+
include SphinxFixtureHelper
|
|
122
|
+
include SphinxApiCall
|
|
123
|
+
|
|
124
|
+
before(:each) do
|
|
125
|
+
@sphinx = create_sphinx
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'should generate valid request with default parameters' do
|
|
129
|
+
expected = sphinx_fixture('default_search')
|
|
130
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
131
|
+
@sphinx.Query('query') rescue nil?
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'should generate valid request with default parameters and index' do
|
|
135
|
+
expected = sphinx_fixture('default_search_index')
|
|
136
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
137
|
+
@sphinx.Query('query', 'index') rescue nil?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'should generate valid request with limits' do
|
|
141
|
+
expected = sphinx_fixture('limits')
|
|
142
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
143
|
+
@sphinx.SetLimits(10, 20)
|
|
144
|
+
@sphinx.Query('query') rescue nil?
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it 'should generate valid request with limits and max number to retrieve' do
|
|
148
|
+
expected = sphinx_fixture('limits_max')
|
|
149
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
150
|
+
@sphinx.SetLimits(10, 20, 30)
|
|
151
|
+
@sphinx.Query('query') rescue nil?
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'should generate valid request with limits and cutoff to retrieve' do
|
|
155
|
+
expected = sphinx_fixture('limits_cutoff')
|
|
156
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
157
|
+
@sphinx.SetLimits(10, 20, 30, 40)
|
|
158
|
+
@sphinx.Query('query') rescue nil?
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'should generate valid request with max query time specified' do
|
|
162
|
+
expected = sphinx_fixture('max_query_time')
|
|
163
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
164
|
+
@sphinx.SetMaxQueryTime(1000)
|
|
165
|
+
@sphinx.Query('query') rescue nil?
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
describe 'with match' do
|
|
169
|
+
[ :all, :any, :phrase, :boolean, :extended, :fullscan, :extended2 ].each do |match|
|
|
170
|
+
it "should generate valid request for SPH_MATCH_#{match.to_s.upcase}" do
|
|
171
|
+
expected = sphinx_fixture("match_#{match}")
|
|
172
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
173
|
+
@sphinx.SetMatchMode(Sphinx::Client::const_get("SPH_MATCH_#{match.to_s.upcase}"))
|
|
174
|
+
@sphinx.Query('query') rescue nil?
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
describe 'with rank' do
|
|
180
|
+
[ :proximity_bm25, :bm25, :none, :wordcount, :proximity ].each do |rank|
|
|
181
|
+
it "should generate valid request for SPH_RANK_#{rank.to_s.upcase}" do
|
|
182
|
+
expected = sphinx_fixture("ranking_#{rank}")
|
|
183
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
184
|
+
@sphinx.SetRankingMode(Sphinx::Client.const_get("SPH_RANK_#{rank.to_s.upcase}"))
|
|
185
|
+
@sphinx.Query('query') rescue nil?
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
describe 'with sorting' do
|
|
191
|
+
[ :attr_desc, :relevance, :attr_asc, :time_segments, :extended, :expr ].each do |mode|
|
|
192
|
+
it "should generate valid request for SPH_SORT_#{mode.to_s.upcase}" do
|
|
193
|
+
expected = sphinx_fixture("sort_#{mode}")
|
|
194
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
195
|
+
@sphinx.SetSortMode(Sphinx::Client.const_get("SPH_SORT_#{mode.to_s.upcase}"), mode == :relevance ? '' : 'sortby')
|
|
196
|
+
@sphinx.Query('query') rescue nil?
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'should generate valid request with weights' do
|
|
202
|
+
expected = sphinx_fixture('weights')
|
|
203
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
204
|
+
@sphinx.SetWeights([10, 20, 30, 40])
|
|
205
|
+
@sphinx.Query('query') rescue nil?
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it 'should generate valid request with field weights' do
|
|
209
|
+
expected = sphinx_fixture('field_weights')
|
|
210
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
211
|
+
@sphinx.SetFieldWeights({'field1' => 10, 'field2' => 20})
|
|
212
|
+
@sphinx.Query('query') rescue nil?
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it 'should generate valid request with index weights' do
|
|
216
|
+
expected = sphinx_fixture('index_weights')
|
|
217
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
218
|
+
@sphinx.SetIndexWeights({'index1' => 10, 'index2' => 20})
|
|
219
|
+
@sphinx.Query('query') rescue nil?
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it 'should generate valid request with ID range' do
|
|
223
|
+
expected = sphinx_fixture('id_range')
|
|
224
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
225
|
+
@sphinx.SetIDRange(10, 20)
|
|
226
|
+
@sphinx.Query('query') rescue nil?
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it 'should generate valid request with ID range and 64-bit ints' do
|
|
230
|
+
expected = sphinx_fixture('id_range64')
|
|
231
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
232
|
+
@sphinx.SetIDRange(8589934591, 17179869183)
|
|
233
|
+
@sphinx.Query('query') rescue nil?
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it 'should generate valid request with values filter' do
|
|
237
|
+
expected = sphinx_fixture('filter')
|
|
238
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
239
|
+
@sphinx.SetFilter('attr', [10, 20, 30])
|
|
240
|
+
@sphinx.Query('query') rescue nil?
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
it 'should generate valid request with two values filters' do
|
|
244
|
+
expected = sphinx_fixture('filters')
|
|
245
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
246
|
+
@sphinx.SetFilter('attr2', [40, 50])
|
|
247
|
+
@sphinx.SetFilter('attr1', [10, 20, 30])
|
|
248
|
+
@sphinx.Query('query') rescue nil?
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it 'should generate valid request with values filter excluded' do
|
|
252
|
+
expected = sphinx_fixture('filter_exclude')
|
|
253
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
254
|
+
@sphinx.SetFilter('attr', [10, 20, 30], true)
|
|
255
|
+
@sphinx.Query('query') rescue nil?
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'should generate valid request with values filter range' do
|
|
259
|
+
expected = sphinx_fixture('filter_range')
|
|
260
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
261
|
+
@sphinx.SetFilterRange('attr', 10, 20)
|
|
262
|
+
@sphinx.Query('query') rescue nil?
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it 'should generate valid request with two filter ranges' do
|
|
266
|
+
expected = sphinx_fixture('filter_ranges')
|
|
267
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
268
|
+
@sphinx.SetFilterRange('attr2', 30, 40)
|
|
269
|
+
@sphinx.SetFilterRange('attr1', 10, 20)
|
|
270
|
+
@sphinx.Query('query') rescue nil?
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it 'should generate valid request with filter range excluded' do
|
|
274
|
+
expected = sphinx_fixture('filter_range_exclude')
|
|
275
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
276
|
+
@sphinx.SetFilterRange('attr', 10, 20, true)
|
|
277
|
+
@sphinx.Query('query') rescue nil?
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it 'should generate valid request with signed int64-based filter range' do
|
|
281
|
+
expected = sphinx_fixture('filter_range_int64')
|
|
282
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
283
|
+
@sphinx.SetFilterRange('attr1', -10, 20)
|
|
284
|
+
@sphinx.SetFilterRange('attr2', -1099511627770, 1099511627780)
|
|
285
|
+
safe_call { @sphinx.Query('query') }
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it 'should generate valid request with float filter range' do
|
|
289
|
+
expected = sphinx_fixture('filter_float_range')
|
|
290
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
291
|
+
@sphinx.SetFilterFloatRange('attr', 10.5, 20.3)
|
|
292
|
+
@sphinx.Query('query') rescue nil?
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it 'should generate valid request with float filter excluded' do
|
|
296
|
+
expected = sphinx_fixture('filter_float_range_exclude')
|
|
297
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
298
|
+
@sphinx.SetFilterFloatRange('attr', 10.5, 20.3, true)
|
|
299
|
+
@sphinx.Query('query') rescue nil?
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it 'should generate valid request with different filters' do
|
|
303
|
+
expected = sphinx_fixture('filters_different')
|
|
304
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
305
|
+
@sphinx.SetFilterRange('attr1', 10, 20, true)
|
|
306
|
+
@sphinx.SetFilter('attr3', [30, 40, 50])
|
|
307
|
+
@sphinx.SetFilterRange('attr1', 60, 70)
|
|
308
|
+
@sphinx.SetFilter('attr2', [80, 90, 100], true)
|
|
309
|
+
@sphinx.SetFilterFloatRange('attr1', 60.8, 70.5)
|
|
310
|
+
@sphinx.Query('query') rescue nil?
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it 'should generate valid request with geographical anchor point' do
|
|
314
|
+
expected = sphinx_fixture('geo_anchor')
|
|
315
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
316
|
+
@sphinx.SetGeoAnchor('attrlat', 'attrlong', 20.3, 40.7)
|
|
317
|
+
@sphinx.Query('query') rescue nil?
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
describe 'with group by' do
|
|
321
|
+
[ :day, :week, :month, :year, :attr, :attrpair ].each do |groupby|
|
|
322
|
+
it "should generate valid request for SPH_GROUPBY_#{groupby.to_s.upcase}" do
|
|
323
|
+
expected = sphinx_fixture("group_by_#{groupby}")
|
|
324
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
325
|
+
@sphinx.SetGroupBy('attr', Sphinx::Client::const_get("SPH_GROUPBY_#{groupby.to_s.upcase}"))
|
|
326
|
+
@sphinx.Query('query') rescue nil?
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it 'should generate valid request for SPH_GROUPBY_DAY with sort' do
|
|
331
|
+
expected = sphinx_fixture('group_by_day_sort')
|
|
332
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
333
|
+
@sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_DAY, 'somesort')
|
|
334
|
+
@sphinx.Query('query') rescue nil?
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
it 'should generate valid request with count-distinct attribute' do
|
|
338
|
+
expected = sphinx_fixture('group_distinct')
|
|
339
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
340
|
+
@sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_DAY)
|
|
341
|
+
@sphinx.SetGroupDistinct('attr')
|
|
342
|
+
@sphinx.Query('query') rescue nil?
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it 'should generate valid request with retries count specified' do
|
|
347
|
+
expected = sphinx_fixture('retries')
|
|
348
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
349
|
+
@sphinx.SetRetries(10)
|
|
350
|
+
@sphinx.Query('query') rescue nil?
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it 'should generate valid request with retries count and delay specified' do
|
|
354
|
+
expected = sphinx_fixture('retries_delay')
|
|
355
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
356
|
+
@sphinx.SetRetries(10, 20)
|
|
357
|
+
@sphinx.Query('query') rescue nil?
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it 'should generate valid request for SetOverride' do
|
|
361
|
+
expected = sphinx_fixture('set_override')
|
|
362
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
363
|
+
@sphinx.SetOverride('attr1', Sphinx::Client::SPH_ATTR_INTEGER, { 10 => 20 })
|
|
364
|
+
@sphinx.SetOverride('attr2', Sphinx::Client::SPH_ATTR_FLOAT, { 11 => 30.3 })
|
|
365
|
+
@sphinx.SetOverride('attr3', Sphinx::Client::SPH_ATTR_BIGINT, { 12 => 1099511627780 })
|
|
366
|
+
@sphinx.Query('query') rescue nil?
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it 'should generate valid request for SetSelect' do
|
|
370
|
+
expected = sphinx_fixture('select')
|
|
371
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
372
|
+
@sphinx.SetSelect('attr1, attr2')
|
|
373
|
+
@sphinx.Query('query') rescue nil?
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
describe 'The RunQueries method of Sphinx::Client' do
|
|
378
|
+
include SphinxFixtureHelper
|
|
379
|
+
|
|
380
|
+
before(:each) do
|
|
381
|
+
@sphinx = Sphinx::Client.new
|
|
382
|
+
@sock = mock('TCPSocket')
|
|
383
|
+
@sphinx.stub!(:Connect).and_return(@sock)
|
|
384
|
+
@sphinx.stub!(:GetResponse).and_raise(Sphinx::SphinxError)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it 'should generate valid request for multiple queries' do
|
|
388
|
+
expected = sphinx_fixture('miltiple_queries')
|
|
389
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
390
|
+
|
|
391
|
+
@sphinx.SetRetries(10, 20)
|
|
392
|
+
@sphinx.AddQuery('test1')
|
|
393
|
+
@sphinx.SetGroupBy('attr', Sphinx::Client::SPH_GROUPBY_DAY)
|
|
394
|
+
@sphinx.AddQuery('test2') rescue nil?
|
|
395
|
+
|
|
396
|
+
@sphinx.RunQueries rescue nil?
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
describe 'The BuildExcerpts method of Sphinx::Client' do
|
|
401
|
+
include SphinxFixtureHelper
|
|
402
|
+
|
|
403
|
+
before(:each) do
|
|
404
|
+
@sphinx = Sphinx::Client.new
|
|
405
|
+
@sock = mock('TCPSocket')
|
|
406
|
+
@sphinx.stub!(:Connect).and_return(@sock)
|
|
407
|
+
@sphinx.stub!(:GetResponse).and_raise(Sphinx::SphinxError)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it 'should generate valid request with default parameters' do
|
|
411
|
+
expected = sphinx_fixture('excerpt_default')
|
|
412
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
413
|
+
@sphinx.BuildExcerpts(['10', '20'], 'index', 'word1 word2') rescue nil?
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
it 'should generate valid request with custom parameters' do
|
|
417
|
+
expected = sphinx_fixture('excerpt_custom')
|
|
418
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
419
|
+
@sphinx.BuildExcerpts(['10', '20'], 'index', 'word1 word2', { 'before_match' => 'before',
|
|
420
|
+
'after_match' => 'after',
|
|
421
|
+
'chunk_separator' => 'separator',
|
|
422
|
+
'limit' => 10 }) rescue nil?
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
it 'should generate valid request with flags' do
|
|
426
|
+
expected = sphinx_fixture('excerpt_flags')
|
|
427
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
428
|
+
@sphinx.BuildExcerpts(['10', '20'], 'index', 'word1 word2', { 'exact_phrase' => true,
|
|
429
|
+
'single_passage' => true,
|
|
430
|
+
'use_boundaries' => true,
|
|
431
|
+
'weight_order' => true }) rescue nil?
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
describe 'The BuildKeywords method of Sphinx::Client' do
|
|
436
|
+
include SphinxFixtureHelper
|
|
437
|
+
include SphinxApiCall
|
|
438
|
+
|
|
439
|
+
before(:each) do
|
|
440
|
+
@sphinx = create_sphinx
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
it 'should generate valid request' do
|
|
444
|
+
expected = sphinx_fixture('keywords')
|
|
445
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
446
|
+
safe_call { @sphinx.BuildKeywords('test', 'index', true) }
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
describe 'The UpdateAttributes method of Sphinx::Client' do
|
|
451
|
+
include SphinxFixtureHelper
|
|
452
|
+
include SphinxApiCall
|
|
453
|
+
|
|
454
|
+
before(:each) do
|
|
455
|
+
@sphinx = create_sphinx
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
it 'should generate valid request' do
|
|
459
|
+
expected = sphinx_fixture('update_attributes')
|
|
460
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
461
|
+
safe_call { @sphinx.UpdateAttributes('index', ['group'], { 123 => [456] }) }
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it 'should generate valid request for MVA' do
|
|
465
|
+
expected = sphinx_fixture('update_attributes_mva')
|
|
466
|
+
@sock.should_receive(:send).with(expected, 0)
|
|
467
|
+
safe_call { @sphinx.UpdateAttributes('index', ['group', 'category'], { 123 => [ [456, 789], [1, 2, 3] ] }, true) }
|
|
468
|
+
end
|
|
469
|
+
end
|