initforthe-thinking-sphinx 1.1.21
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/LICENCE +20 -0
- data/README.textile +141 -0
- data/lib/thinking_sphinx.rb +215 -0
- data/lib/thinking_sphinx/active_record.rb +278 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +48 -0
- data/lib/thinking_sphinx/active_record/delta.rb +87 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
- data/lib/thinking_sphinx/active_record/search.rb +57 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +135 -0
- data/lib/thinking_sphinx/association.rb +164 -0
- data/lib/thinking_sphinx/attribute.rb +268 -0
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/collection.rb +148 -0
- data/lib/thinking_sphinx/configuration.rb +262 -0
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas.rb +30 -0
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +68 -0
- data/lib/thinking_sphinx/deltas/delayed_delta.rb +27 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +24 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +27 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +26 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +82 -0
- data/lib/thinking_sphinx/facet.rb +108 -0
- data/lib/thinking_sphinx/facet_collection.rb +59 -0
- data/lib/thinking_sphinx/field.rb +82 -0
- data/lib/thinking_sphinx/index.rb +99 -0
- data/lib/thinking_sphinx/index/builder.rb +287 -0
- data/lib/thinking_sphinx/index/faux_column.rb +110 -0
- data/lib/thinking_sphinx/property.rb +160 -0
- data/lib/thinking_sphinx/rails_additions.rb +136 -0
- data/lib/thinking_sphinx/search.rb +727 -0
- data/lib/thinking_sphinx/search/facets.rb +104 -0
- data/lib/thinking_sphinx/source.rb +150 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +126 -0
- data/lib/thinking_sphinx/tasks.rb +162 -0
- data/rails/init.rb +14 -0
- data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +136 -0
- data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +53 -0
- data/spec/unit/thinking_sphinx/active_record/search_spec.rb +107 -0
- data/spec/unit/thinking_sphinx/active_record_spec.rb +329 -0
- data/spec/unit/thinking_sphinx/association_spec.rb +246 -0
- data/spec/unit/thinking_sphinx/attribute_spec.rb +338 -0
- data/spec/unit/thinking_sphinx/collection_spec.rb +15 -0
- data/spec/unit/thinking_sphinx/configuration_spec.rb +222 -0
- data/spec/unit/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/unit/thinking_sphinx/facet_collection_spec.rb +64 -0
- data/spec/unit/thinking_sphinx/facet_spec.rb +302 -0
- data/spec/unit/thinking_sphinx/field_spec.rb +154 -0
- data/spec/unit/thinking_sphinx/index/builder_spec.rb +355 -0
- data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +30 -0
- data/spec/unit/thinking_sphinx/index_spec.rb +45 -0
- data/spec/unit/thinking_sphinx/rails_additions_spec.rb +191 -0
- data/spec/unit/thinking_sphinx/search_spec.rb +228 -0
- data/spec/unit/thinking_sphinx/source_spec.rb +217 -0
- data/spec/unit/thinking_sphinx_spec.rb +151 -0
- data/tasks/distribution.rb +67 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +78 -0
- data/vendor/after_commit/LICENSE +20 -0
- data/vendor/after_commit/README +16 -0
- data/vendor/after_commit/Rakefile +22 -0
- data/vendor/after_commit/init.rb +8 -0
- data/vendor/after_commit/lib/after_commit.rb +45 -0
- data/vendor/after_commit/lib/after_commit/active_record.rb +114 -0
- data/vendor/after_commit/lib/after_commit/connection_adapters.rb +103 -0
- data/vendor/after_commit/test/after_commit_test.rb +53 -0
- data/vendor/delayed_job/lib/delayed/job.rb +251 -0
- data/vendor/delayed_job/lib/delayed/message_sending.rb +7 -0
- data/vendor/delayed_job/lib/delayed/performable_method.rb +55 -0
- data/vendor/delayed_job/lib/delayed/worker.rb +54 -0
- data/vendor/riddle/lib/riddle.rb +30 -0
- data/vendor/riddle/lib/riddle/client.rb +619 -0
- data/vendor/riddle/lib/riddle/client/filter.rb +53 -0
- data/vendor/riddle/lib/riddle/client/message.rb +65 -0
- data/vendor/riddle/lib/riddle/client/response.rb +84 -0
- data/vendor/riddle/lib/riddle/configuration.rb +33 -0
- data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +48 -0
- data/vendor/riddle/lib/riddle/configuration/index.rb +142 -0
- data/vendor/riddle/lib/riddle/configuration/indexer.rb +19 -0
- data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
- data/vendor/riddle/lib/riddle/configuration/searchd.rb +25 -0
- data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
- data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
- data/vendor/riddle/lib/riddle/configuration/sql_source.rb +34 -0
- data/vendor/riddle/lib/riddle/configuration/xml_source.rb +28 -0
- data/vendor/riddle/lib/riddle/controller.rb +44 -0
- metadata +190 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::Index::FauxColumn do
|
|
4
|
+
describe "coerce class method" do
|
|
5
|
+
before :each do
|
|
6
|
+
@column = ThinkingSphinx::Index::FauxColumn.stub_instance
|
|
7
|
+
ThinkingSphinx::Index::FauxColumn.stub_method(:new => @column)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should return a single faux column if passed a string" do
|
|
11
|
+
ThinkingSphinx::Index::FauxColumn.coerce("string").should == @column
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should return a single faux column if passed a symbol" do
|
|
15
|
+
ThinkingSphinx::Index::FauxColumn.coerce(:string).should == @column
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should return an array of faux columns if passed an array of strings" do
|
|
19
|
+
ThinkingSphinx::Index::FauxColumn.coerce(["one", "two"]).should == [
|
|
20
|
+
@column, @column
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should return an array of faux columns if passed an array of symbols" do
|
|
25
|
+
ThinkingSphinx::Index::FauxColumn.coerce([:one, :two]).should == [
|
|
26
|
+
@column, @column
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::Index do
|
|
4
|
+
describe "prefix_fields method" do
|
|
5
|
+
before :each do
|
|
6
|
+
@index = ThinkingSphinx::Index.new(Person)
|
|
7
|
+
|
|
8
|
+
@field_a = ThinkingSphinx::Field.stub_instance(:prefixes => true)
|
|
9
|
+
@field_b = ThinkingSphinx::Field.stub_instance(:prefixes => false)
|
|
10
|
+
@field_c = ThinkingSphinx::Field.stub_instance(:prefixes => true)
|
|
11
|
+
|
|
12
|
+
@index.stub_method(:fields => [@field_a, @field_b, @field_c])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should return fields that are flagged as prefixed" do
|
|
16
|
+
@index.prefix_fields.should include(@field_a)
|
|
17
|
+
@index.prefix_fields.should include(@field_c)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should not return fields that aren't flagged as prefixed" do
|
|
21
|
+
@index.prefix_fields.should_not include(@field_b)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "infix_fields method" do
|
|
26
|
+
before :each do
|
|
27
|
+
@index = ThinkingSphinx::Index.new(Person)
|
|
28
|
+
|
|
29
|
+
@field_a = ThinkingSphinx::Field.stub_instance(:infixes => true)
|
|
30
|
+
@field_b = ThinkingSphinx::Field.stub_instance(:infixes => false)
|
|
31
|
+
@field_c = ThinkingSphinx::Field.stub_instance(:infixes => true)
|
|
32
|
+
|
|
33
|
+
@index.stub_method(:fields => [@field_a, @field_b, @field_c])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should return fields that are flagged as infixed" do
|
|
37
|
+
@index.infix_fields.should include(@field_a)
|
|
38
|
+
@index.infix_fields.should include(@field_c)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should not return fields that aren't flagged as infixed" do
|
|
42
|
+
@index.infix_fields.should_not include(@field_b)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::HashExcept do
|
|
4
|
+
before(:each) do
|
|
5
|
+
@hash = { :number => 20, :letter => 'b', :shape => 'rectangle' }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe "except method" do
|
|
9
|
+
it "returns a hash without the specified keys" do
|
|
10
|
+
new_hash = @hash.except(:number)
|
|
11
|
+
new_hash.should_not have_key(:number)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "except! method" do
|
|
16
|
+
it "modifies hash removing specified keys" do
|
|
17
|
+
@hash.except!(:number)
|
|
18
|
+
@hash.should_not have_key(:number)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "extends Hash" do
|
|
23
|
+
before :each do
|
|
24
|
+
@instance_methods = Hash.instance_methods.collect { |m| m.to_s }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'with except' do
|
|
28
|
+
@instance_methods.include?('except').should be_true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'with except!' do
|
|
32
|
+
@instance_methods.include?('except!').should be_true
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe ThinkingSphinx::ArrayExtractOptions do
|
|
38
|
+
describe 'extract_options! method' do
|
|
39
|
+
it 'returns a hash' do
|
|
40
|
+
array = []
|
|
41
|
+
array.extract_options!.should be_kind_of(Hash)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'returns the last option if it is a hash' do
|
|
45
|
+
array = ['a', 'b', {:c => 'd'}]
|
|
46
|
+
array.extract_options!.should == {:c => 'd'}
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "extends Array" do
|
|
51
|
+
it 'with extract_options!' do
|
|
52
|
+
Array.instance_methods.collect { |m| m.to_s }.include?('extract_options!').should be_true
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe ThinkingSphinx::AbstractQuotedTableName do
|
|
58
|
+
describe 'quote_table_name method' do
|
|
59
|
+
it 'calls quote_column_name' do
|
|
60
|
+
adapter = ActiveRecord::ConnectionAdapters::AbstractAdapter.new(defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql')
|
|
61
|
+
adapter.should_receive(:quote_column_name).with('messages')
|
|
62
|
+
adapter.quote_table_name('messages')
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe "extends ActiveRecord::ConnectionAdapters::AbstractAdapter" do
|
|
67
|
+
it 'with quote_table_name' do
|
|
68
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.instance_methods.collect { |m|
|
|
69
|
+
m.to_s
|
|
70
|
+
}.include?('quote_table_name').should be_true
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe ThinkingSphinx::MysqlQuotedTableName do
|
|
76
|
+
describe "quote_table_name method" do
|
|
77
|
+
it 'correctly quotes' do
|
|
78
|
+
adapter = ActiveRecord::Base.connection
|
|
79
|
+
adapter.quote_table_name('thinking_sphinx.messages').should == "`thinking_sphinx`.`messages`"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe "extends ActiveRecord::ConnectionAdapters::MysqlAdapter" do
|
|
84
|
+
it 'with quote_table_name' do
|
|
85
|
+
adapter = defined?(JRUBY_VERSION) ? :JdbcAdapter : :MysqlAdapter
|
|
86
|
+
ActiveRecord::ConnectionAdapters.const_get(adapter).instance_methods.collect { |m|
|
|
87
|
+
m.to_s
|
|
88
|
+
}.include?("quote_table_name").should be_true
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe ThinkingSphinx::ActiveRecordQuotedName do
|
|
94
|
+
describe "quoted_table_name method" do
|
|
95
|
+
it 'returns table name wrappd in quotes' do
|
|
96
|
+
Person.quoted_table_name.should == '`people`'
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "extends ActiveRecord::Base" do
|
|
101
|
+
it 'with quoted_table_name' do
|
|
102
|
+
ActiveRecord::Base.respond_to?("quoted_table_name").should be_true
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe ThinkingSphinx::ActiveRecordStoreFullSTIClass do
|
|
108
|
+
describe "store_full_sti_class method" do
|
|
109
|
+
it 'returns false' do
|
|
110
|
+
Person.store_full_sti_class.should be_false
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "extends ActiveRecord::Base" do
|
|
115
|
+
it 'with store_full_sti_class' do
|
|
116
|
+
ActiveRecord::Base.respond_to?(:store_full_sti_class).should be_true
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
class TestModel
|
|
122
|
+
@@squares = 89
|
|
123
|
+
@@circles = 43
|
|
124
|
+
|
|
125
|
+
def number_of_polygons
|
|
126
|
+
@@polygons
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
describe ThinkingSphinx::ClassAttributeMethods do
|
|
131
|
+
describe "cattr_reader method" do
|
|
132
|
+
it 'creates getters' do
|
|
133
|
+
TestModel.cattr_reader :herbivores
|
|
134
|
+
test_model = TestModel.new
|
|
135
|
+
test_model.respond_to?(:herbivores).should be_true
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'sets the initial value to nil' do
|
|
139
|
+
TestModel.cattr_reader :carnivores
|
|
140
|
+
test_model = TestModel.new
|
|
141
|
+
test_model.carnivores.should be_nil
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'does not override an existing definition' do
|
|
145
|
+
TestModel.cattr_reader :squares
|
|
146
|
+
test_model = TestModel.new
|
|
147
|
+
test_model.squares.should == 89
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
describe "cattr_writer method" do
|
|
152
|
+
it 'creates setters' do
|
|
153
|
+
TestModel.cattr_writer :herbivores
|
|
154
|
+
test_model = TestModel.new
|
|
155
|
+
test_model.respond_to?(:herbivores=).should be_true
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it 'does not override an existing definition' do
|
|
159
|
+
TestModel.cattr_writer :polygons
|
|
160
|
+
test_model = TestModel.new
|
|
161
|
+
test_model.polygons = 100
|
|
162
|
+
test_model.number_of_polygons.should == 100
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe "cattr_accessor method" do
|
|
167
|
+
it 'calls cattr_reader' do
|
|
168
|
+
Class.should_receive(:cattr_reader).with('polygons')
|
|
169
|
+
Class.cattr_accessor('polygons')
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it 'calls cattr_writer' do
|
|
173
|
+
Class.should_receive(:cattr_writer).with('polygons')
|
|
174
|
+
Class.cattr_accessor('polygons')
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
describe "extends Class" do
|
|
179
|
+
it 'with cattr_reader' do
|
|
180
|
+
Class.respond_to?('cattr_reader').should be_true
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'with cattr_writer' do
|
|
184
|
+
Class.respond_to?('cattr_writer').should be_true
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'with cattr_accessor' do
|
|
188
|
+
Class.respond_to?('cattr_accessor').should be_true
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
require 'will_paginate/collection'
|
|
3
|
+
|
|
4
|
+
describe ThinkingSphinx::Search do
|
|
5
|
+
describe "search method" do
|
|
6
|
+
describe ":star option" do
|
|
7
|
+
before :each do
|
|
8
|
+
@client = Riddle::Client.new
|
|
9
|
+
@client.stub!(
|
|
10
|
+
:filters => [],
|
|
11
|
+
:filters= => true,
|
|
12
|
+
:id_range= => true,
|
|
13
|
+
:sort_mode => :asc,
|
|
14
|
+
:limit => 5,
|
|
15
|
+
:offset= => 0,
|
|
16
|
+
:sort_mode= => true,
|
|
17
|
+
:query => {
|
|
18
|
+
:matches => [],
|
|
19
|
+
:total => 50
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
ThinkingSphinx::Search.stub_methods(
|
|
24
|
+
:client_from_options => @client,
|
|
25
|
+
:search_conditions => ["", []]
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should not apply by default" do
|
|
30
|
+
@client.should_receive(:query).with("foo bar",'*','')
|
|
31
|
+
|
|
32
|
+
ThinkingSphinx::Search.search "foo bar"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should apply when passed, and handle full extended syntax" do
|
|
36
|
+
input = %{a b* c (d | e) 123 5&6 (f_f g) !h "i j" "k l"~10 "m n"/3 @o p -(q|r)}
|
|
37
|
+
expected = %{*a* b* *c* (*d* | *e*) *123* *5*&*6* (*f_f* *g*) !*h* "i j" "k l"~10 "m n"/3 @o *p* -(*q*|*r*)}
|
|
38
|
+
@client.should_receive(:query).with(expected,'*','')
|
|
39
|
+
|
|
40
|
+
ThinkingSphinx::Search.search input, :star => true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should default to /\w+/ as token" do
|
|
44
|
+
@client.should_receive(:query).with("*foo*@*bar*.*com*",'*','')
|
|
45
|
+
|
|
46
|
+
ThinkingSphinx::Search.search "foo@bar.com", :star => true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should honour custom token" do
|
|
50
|
+
@client.should_receive(:query).with("*foo@bar.com* -*foo-bar*",'*','')
|
|
51
|
+
|
|
52
|
+
ThinkingSphinx::Search.search "foo@bar.com -foo-bar", :star => /[\w@.-]+/u
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "sort modes" do
|
|
57
|
+
before :each do
|
|
58
|
+
@client = Riddle::Client.new
|
|
59
|
+
@client.stub_method(:query => {:matches => []})
|
|
60
|
+
Riddle::Client.stub_method(:new => @client)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should use :relevance as a default" do
|
|
64
|
+
ThinkingSphinx::Search.search "foo"
|
|
65
|
+
@client.sort_mode.should == :relevance
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should use :attr_asc if a symbol is supplied to :order" do
|
|
69
|
+
ThinkingSphinx::Search.search "foo", :order => :created_at
|
|
70
|
+
@client.sort_mode.should == :attr_asc
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should use :attr_desc if a symbol is supplied and :desc is the mode" do
|
|
74
|
+
ThinkingSphinx::Search.search "foo", :order => :created_at, :sort_mode => :desc
|
|
75
|
+
@client.sort_mode.should == :attr_desc
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "should use :extended if a string is supplied to :order" do
|
|
79
|
+
ThinkingSphinx::Search.search "foo", :order => "created_at ASC"
|
|
80
|
+
@client.sort_mode.should == :extended
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "should use :expr if explicitly requested with a string supplied to :order" do
|
|
84
|
+
ThinkingSphinx::Search.search "foo", :order => "created_at ASC", :sort_mode => :expr
|
|
85
|
+
@client.sort_mode.should == :expr
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should use :attr_desc if explicitly requested with a string supplied to :order" do
|
|
89
|
+
ThinkingSphinx::Search.search "foo", :order => "created_at", :sort_mode => :desc
|
|
90
|
+
@client.sort_mode.should == :attr_desc
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe "grouping" do
|
|
95
|
+
before :each do
|
|
96
|
+
@client = Riddle::Client.new
|
|
97
|
+
@client.stub_method(:query => {:matches => []})
|
|
98
|
+
Riddle::Client.stub_method(:new => @client)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "should convert group into group_by and group_function" do
|
|
102
|
+
ThinkingSphinx::Search.search "foo", :group => :edition
|
|
103
|
+
@client.group_function.should == :attr
|
|
104
|
+
@client.group_by.should == "edition"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
describe ":comment option" do
|
|
109
|
+
before :each do
|
|
110
|
+
@client = Riddle::Client.new
|
|
111
|
+
@client.stub_method(:query => {:matches => []})
|
|
112
|
+
Riddle::Client.stub_method(:new => @client)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should add comment to log" do
|
|
116
|
+
ThinkingSphinx::Search.search 'foo bar', :comment => 'custom log'
|
|
117
|
+
@client.should have_received(:query).with('foo bar', '*', 'custom log')
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should use a blank string when no comment is specified" do
|
|
121
|
+
ThinkingSphinx::Search.search 'foo bar'
|
|
122
|
+
@client.should have_received(:query).with('foo bar', '*', '')
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "facets method" do
|
|
128
|
+
before :each do
|
|
129
|
+
@person = Person.find(:first)
|
|
130
|
+
|
|
131
|
+
@city_results = [@person]
|
|
132
|
+
@city_results.stub!(:each_with_groupby_and_count).
|
|
133
|
+
and_yield(@person, @person.city.to_crc32, 1)
|
|
134
|
+
|
|
135
|
+
@birthday_results = [@person]
|
|
136
|
+
@birthday_results.stub!(:each_with_groupby_and_count).
|
|
137
|
+
and_yield(@person, @person.birthday.to_i, 1)
|
|
138
|
+
|
|
139
|
+
@config = ThinkingSphinx::Configuration.instance
|
|
140
|
+
@config.configuration.searchd.max_matches = 10_000
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "should use the system-set max_matches for limit on facet calls" do
|
|
144
|
+
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
|
145
|
+
|
|
146
|
+
ThinkingSphinx::Search.should_receive(:search) do |options|
|
|
147
|
+
options[:max_matches].should == 10_000
|
|
148
|
+
options[:limit].should == 10_000
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
ThinkingSphinx::Search.facets :all_attributes => true
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "should use the default max-matches if there is no explicit setting" do
|
|
155
|
+
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
|
156
|
+
|
|
157
|
+
@config.configuration.searchd.max_matches = nil
|
|
158
|
+
ThinkingSphinx::Search.should_receive(:search) do |options|
|
|
159
|
+
options[:max_matches].should == 1000
|
|
160
|
+
options[:limit].should == 1000
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
ThinkingSphinx::Search.facets :all_attributes => true
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "should ignore user-provided max_matches and limit on facet calls" do
|
|
167
|
+
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
|
168
|
+
|
|
169
|
+
ThinkingSphinx::Search.should_receive(:search) do |options|
|
|
170
|
+
options[:max_matches].should == 10_000
|
|
171
|
+
options[:limit].should == 10_000
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
ThinkingSphinx::Search.facets(
|
|
175
|
+
:all_attributes => true,
|
|
176
|
+
:max_matches => 500,
|
|
177
|
+
:limit => 200
|
|
178
|
+
)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should use explicit facet list if one is provided" do
|
|
182
|
+
ThinkingSphinx::Search.should_receive(:search).once.and_return(@city_results)
|
|
183
|
+
|
|
184
|
+
ThinkingSphinx::Search.facets(
|
|
185
|
+
:facets => ['city'],
|
|
186
|
+
:class => Person
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "should not use an explicit :page" do
|
|
191
|
+
ThinkingSphinx::Search.stub!(:search).and_return(@city_results, @birthday_results)
|
|
192
|
+
ThinkingSphinx::Search.should_receive(:search) do |options|
|
|
193
|
+
options[:page].should == 1
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
ThinkingSphinx::Search.facets(
|
|
197
|
+
:all_attributes => true,
|
|
198
|
+
:page => 3
|
|
199
|
+
)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe "conflicting facets" do
|
|
203
|
+
before :each do
|
|
204
|
+
@index = ThinkingSphinx::Index::Builder.generate(Alpha) do
|
|
205
|
+
indexes :name
|
|
206
|
+
has :value, :as => :city, :facet => true
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
after :each do
|
|
211
|
+
Alpha.sphinx_facets.delete_at(-1)
|
|
212
|
+
Alpha.sphinx_indexes.delete_at(-1)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it "should raise an error if searching with facets of same name but different type" do
|
|
216
|
+
lambda {
|
|
217
|
+
ThinkingSphinx::Search.facets :all_attributes => true
|
|
218
|
+
}.should raise_error
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
describe ThinkingSphinx::Search, "playing nice with Search model" do
|
|
225
|
+
it "should not conflict with models called Search" do
|
|
226
|
+
lambda { Search.find(:all) }.should_not raise_error
|
|
227
|
+
end
|
|
228
|
+
end
|