thinking-sphinx 1.2.12

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 (95) hide show
  1. data/LICENCE +20 -0
  2. data/README.textile +157 -0
  3. data/VERSION.yml +4 -0
  4. data/lib/thinking_sphinx.rb +211 -0
  5. data/lib/thinking_sphinx/active_record.rb +307 -0
  6. data/lib/thinking_sphinx/active_record/attribute_updates.rb +48 -0
  7. data/lib/thinking_sphinx/active_record/delta.rb +87 -0
  8. data/lib/thinking_sphinx/active_record/has_many_association.rb +28 -0
  9. data/lib/thinking_sphinx/active_record/scopes.rb +39 -0
  10. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
  11. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
  12. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +136 -0
  13. data/lib/thinking_sphinx/association.rb +164 -0
  14. data/lib/thinking_sphinx/attribute.rb +342 -0
  15. data/lib/thinking_sphinx/class_facet.rb +15 -0
  16. data/lib/thinking_sphinx/configuration.rb +282 -0
  17. data/lib/thinking_sphinx/core/array.rb +7 -0
  18. data/lib/thinking_sphinx/core/string.rb +15 -0
  19. data/lib/thinking_sphinx/deltas.rb +30 -0
  20. data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
  21. data/lib/thinking_sphinx/deltas/default_delta.rb +68 -0
  22. data/lib/thinking_sphinx/deltas/delayed_delta.rb +30 -0
  23. data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +24 -0
  24. data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +27 -0
  25. data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +26 -0
  26. data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
  27. data/lib/thinking_sphinx/excerpter.rb +22 -0
  28. data/lib/thinking_sphinx/facet.rb +125 -0
  29. data/lib/thinking_sphinx/facet_search.rb +134 -0
  30. data/lib/thinking_sphinx/field.rb +82 -0
  31. data/lib/thinking_sphinx/index.rb +99 -0
  32. data/lib/thinking_sphinx/index/builder.rb +286 -0
  33. data/lib/thinking_sphinx/index/faux_column.rb +110 -0
  34. data/lib/thinking_sphinx/property.rb +162 -0
  35. data/lib/thinking_sphinx/rails_additions.rb +150 -0
  36. data/lib/thinking_sphinx/search.rb +707 -0
  37. data/lib/thinking_sphinx/search_methods.rb +421 -0
  38. data/lib/thinking_sphinx/source.rb +150 -0
  39. data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
  40. data/lib/thinking_sphinx/source/sql.rb +128 -0
  41. data/lib/thinking_sphinx/tasks.rb +165 -0
  42. data/rails/init.rb +14 -0
  43. data/spec/lib/thinking_sphinx/active_record/delta_spec.rb +130 -0
  44. data/spec/lib/thinking_sphinx/active_record/has_many_association_spec.rb +49 -0
  45. data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +96 -0
  46. data/spec/lib/thinking_sphinx/active_record_spec.rb +364 -0
  47. data/spec/lib/thinking_sphinx/association_spec.rb +239 -0
  48. data/spec/lib/thinking_sphinx/attribute_spec.rb +500 -0
  49. data/spec/lib/thinking_sphinx/configuration_spec.rb +268 -0
  50. data/spec/lib/thinking_sphinx/core/array_spec.rb +9 -0
  51. data/spec/lib/thinking_sphinx/core/string_spec.rb +9 -0
  52. data/spec/lib/thinking_sphinx/excerpter_spec.rb +49 -0
  53. data/spec/lib/thinking_sphinx/facet_search_spec.rb +176 -0
  54. data/spec/lib/thinking_sphinx/facet_spec.rb +333 -0
  55. data/spec/lib/thinking_sphinx/field_spec.rb +154 -0
  56. data/spec/lib/thinking_sphinx/index/builder_spec.rb +455 -0
  57. data/spec/lib/thinking_sphinx/index/faux_column_spec.rb +30 -0
  58. data/spec/lib/thinking_sphinx/index_spec.rb +45 -0
  59. data/spec/lib/thinking_sphinx/rails_additions_spec.rb +203 -0
  60. data/spec/lib/thinking_sphinx/search_methods_spec.rb +152 -0
  61. data/spec/lib/thinking_sphinx/search_spec.rb +1092 -0
  62. data/spec/lib/thinking_sphinx/source_spec.rb +227 -0
  63. data/spec/lib/thinking_sphinx_spec.rb +162 -0
  64. data/tasks/distribution.rb +50 -0
  65. data/tasks/rails.rake +1 -0
  66. data/tasks/testing.rb +83 -0
  67. data/vendor/after_commit/LICENSE +20 -0
  68. data/vendor/after_commit/README +16 -0
  69. data/vendor/after_commit/Rakefile +22 -0
  70. data/vendor/after_commit/init.rb +8 -0
  71. data/vendor/after_commit/lib/after_commit.rb +45 -0
  72. data/vendor/after_commit/lib/after_commit/active_record.rb +114 -0
  73. data/vendor/after_commit/lib/after_commit/connection_adapters.rb +103 -0
  74. data/vendor/after_commit/test/after_commit_test.rb +53 -0
  75. data/vendor/delayed_job/lib/delayed/job.rb +251 -0
  76. data/vendor/delayed_job/lib/delayed/message_sending.rb +7 -0
  77. data/vendor/delayed_job/lib/delayed/performable_method.rb +55 -0
  78. data/vendor/delayed_job/lib/delayed/worker.rb +54 -0
  79. data/vendor/riddle/lib/riddle.rb +30 -0
  80. data/vendor/riddle/lib/riddle/client.rb +635 -0
  81. data/vendor/riddle/lib/riddle/client/filter.rb +53 -0
  82. data/vendor/riddle/lib/riddle/client/message.rb +66 -0
  83. data/vendor/riddle/lib/riddle/client/response.rb +84 -0
  84. data/vendor/riddle/lib/riddle/configuration.rb +33 -0
  85. data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +48 -0
  86. data/vendor/riddle/lib/riddle/configuration/index.rb +142 -0
  87. data/vendor/riddle/lib/riddle/configuration/indexer.rb +19 -0
  88. data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
  89. data/vendor/riddle/lib/riddle/configuration/searchd.rb +25 -0
  90. data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
  91. data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
  92. data/vendor/riddle/lib/riddle/configuration/sql_source.rb +34 -0
  93. data/vendor/riddle/lib/riddle/configuration/xml_source.rb +28 -0
  94. data/vendor/riddle/lib/riddle/controller.rb +53 -0
  95. metadata +172 -0
@@ -0,0 +1,49 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
4
+ describe "search method" do
5
+ before :each do
6
+ Friendship.stub!(:search => true)
7
+
8
+ @person = Person.find(:first)
9
+ @index = Friendship.sphinx_indexes.first
10
+ end
11
+
12
+ it "should raise an error if the required attribute doesn't exist" do
13
+ @index.stub!(:attributes => [])
14
+
15
+ lambda { @person.friendships.search "test" }.should raise_error(RuntimeError)
16
+ end
17
+
18
+ it "should add a filter for the attribute into a normal search call" do
19
+ Friendship.should_receive(:search) do |query, options|
20
+ options[:with][:person_id].should == @person.id
21
+ end
22
+
23
+ @person.friendships.search "test"
24
+ end
25
+ end
26
+
27
+ describe "search method for has_many :through" do
28
+ before :each do
29
+ Person.stub!(:search => true)
30
+
31
+ @person = Person.find(:first)
32
+ @index = Person.sphinx_indexes.first
33
+ end
34
+
35
+ it "should raise an error if the required attribute doesn't exist" do
36
+ @index.stub!(:attributes => [])
37
+
38
+ lambda { @person.friends.search "test" }.should raise_error(RuntimeError)
39
+ end
40
+
41
+ it "should add a filter for the attribute into a normal search call" do
42
+ Person.should_receive(:search).with do |query, options|
43
+ options[:with][:friendly_ids].should == @person.id
44
+ end
45
+
46
+ @person.friends.search "test"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::ActiveRecord::Scopes do
4
+ after :each do
5
+ Alpha.remove_sphinx_scopes
6
+ end
7
+
8
+ it "should be included into models with indexes" do
9
+ Alpha.included_modules.should include(ThinkingSphinx::ActiveRecord::Scopes)
10
+ end
11
+
12
+ it "should not be included into models without indexes" do
13
+ Gamma.included_modules.should_not include(
14
+ ThinkingSphinx::ActiveRecord::Scopes
15
+ )
16
+ end
17
+
18
+ describe '.sphinx_scope' do
19
+ before :each do
20
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
21
+ end
22
+
23
+ it "should define a method on the model" do
24
+ Alpha.should respond_to(:by_name)
25
+ end
26
+ end
27
+
28
+ describe '.sphinx_scopes' do
29
+ before :each do
30
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
31
+ end
32
+
33
+ it "should return an array of defined scope names as symbols" do
34
+ Alpha.sphinx_scopes.should == [:by_name]
35
+ end
36
+ end
37
+
38
+ describe '.remove_sphinx_scopes' do
39
+ before :each do
40
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
41
+ Alpha.remove_sphinx_scopes
42
+ end
43
+
44
+ it "should remove sphinx scope methods" do
45
+ Alpha.should_not respond_to(:by_name)
46
+ end
47
+
48
+ it "should empty the list of sphinx scopes" do
49
+ Alpha.sphinx_scopes.should be_empty
50
+ end
51
+ end
52
+
53
+ describe '.example_scope' do
54
+ before :each do
55
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
56
+ Alpha.sphinx_scope(:by_foo) { |foo| {:conditions => {:foo => foo}} }
57
+ Alpha.sphinx_scope(:with_betas) { {:classes => [Beta]} }
58
+ end
59
+
60
+ it "should return a ThinkingSphinx::Search object" do
61
+ Alpha.by_name('foo').should be_a(ThinkingSphinx::Search)
62
+ end
63
+
64
+ it "should set the classes option" do
65
+ Alpha.by_name('foo').options[:classes].should == [Alpha]
66
+ end
67
+
68
+ it "should be able to be called on a ThinkingSphinx::Search object" do
69
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
70
+ lambda {
71
+ search.by_name('foo')
72
+ }.should_not raise_error
73
+ end
74
+
75
+ it "should return the search object it gets called upon" do
76
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
77
+ search.by_name('foo').should == search
78
+ end
79
+
80
+ it "should apply the scope options to the underlying search object" do
81
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
82
+ search.by_name('foo').options[:conditions].should == {:name => 'foo'}
83
+ end
84
+
85
+ it "should combine hash option scopes such as :conditions" do
86
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
87
+ search.by_name('foo').by_foo('bar').options[:conditions].
88
+ should == {:name => 'foo', :foo => 'bar'}
89
+ end
90
+
91
+ it "should combine array option scopes such as :classes" do
92
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
93
+ search.with_betas.options[:classes].should == [Alpha, Beta]
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,364 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::ActiveRecord do
4
+ describe '.define_index' do
5
+ before :each do
6
+ module ::TestModule
7
+ class TestModel < ActiveRecord::Base; end
8
+ end
9
+
10
+ TestModule::TestModel.stub!(
11
+ :before_save => true,
12
+ :after_commit => true,
13
+ :after_destroy => true
14
+ )
15
+
16
+ @index = ThinkingSphinx::Index.new(TestModule::TestModel)
17
+ @index.stub!(:delta? => false)
18
+ ThinkingSphinx::Index::Builder.stub!(:generate => @index)
19
+ end
20
+
21
+ after :each do
22
+ # Remove the class so we can redefine it
23
+ TestModule.send(:remove_const, :TestModel)
24
+
25
+ ThinkingSphinx.indexed_models.delete "TestModule::TestModel"
26
+ end
27
+
28
+ it "should do nothing if indexes are disabled" do
29
+ ThinkingSphinx.define_indexes = false
30
+ ThinkingSphinx::Index.should_not_receive(:new)
31
+
32
+ TestModule::TestModel.define_index {}
33
+
34
+ ThinkingSphinx.define_indexes = true
35
+ end
36
+
37
+ it "should add a new index to the model" do
38
+ TestModule::TestModel.define_index {}
39
+
40
+ TestModule::TestModel.sphinx_indexes.length.should == 1
41
+ end
42
+
43
+ it "should add to ThinkingSphinx.indexed_models if the model doesn't already exist in the array" do
44
+ TestModule::TestModel.define_index do; end
45
+
46
+ ThinkingSphinx.indexed_models.should include("TestModule::TestModel")
47
+ end
48
+
49
+ it "shouldn't add to ThinkingSphinx.indexed_models if the model already exists in the array" do
50
+ TestModule::TestModel.define_index do; end
51
+
52
+ ThinkingSphinx.indexed_models.select { |model|
53
+ model == "TestModule::TestModel"
54
+ }.length.should == 1
55
+
56
+ TestModule::TestModel.define_index do; end
57
+
58
+ ThinkingSphinx.indexed_models.select { |model|
59
+ model == "TestModule::TestModel"
60
+ }.length.should == 1
61
+ end
62
+
63
+ it "should add before_save and after_commit hooks to the model if delta indexing is enabled" do
64
+ @index.stub!(:delta? => true)
65
+ TestModule::TestModel.should_receive(:before_save).with(:toggle_delta)
66
+ TestModule::TestModel.should_receive(:after_commit).with(:index_delta)
67
+
68
+ TestModule::TestModel.define_index do; end
69
+ end
70
+
71
+ it "should not add before_save and after_commit hooks to the model if delta indexing is disabled" do
72
+ TestModule::TestModel.should_not_receive(:before_save).with(:toggle_delta)
73
+ TestModule::TestModel.should_not_receive(:after_commit).with(:index_delta)
74
+
75
+ TestModule::TestModel.define_index do; end
76
+ end
77
+
78
+ it "should add an after_destroy hook with delta indexing enabled" do
79
+ @index.stub!(:delta? => true)
80
+ TestModule::TestModel.should_receive(:after_destroy).with(:toggle_deleted)
81
+
82
+ TestModule::TestModel.define_index do; end
83
+ end
84
+
85
+ it "should add an after_destroy hook with delta indexing disabled" do
86
+ TestModule::TestModel.should_receive(:after_destroy).with(:toggle_deleted)
87
+
88
+ TestModule::TestModel.define_index do; end
89
+ end
90
+
91
+ it "should return the new index" do
92
+ TestModule::TestModel.define_index.should == @index
93
+ end
94
+
95
+ it "should die quietly if there is a database error" do
96
+ ThinkingSphinx::Index::Builder.stub(:generate) { raise Mysql::Error }
97
+
98
+ lambda {
99
+ TestModule::TestModel.define_index
100
+ }.should_not raise_error
101
+ end
102
+
103
+ it "should die noisily if there is a non-database error" do
104
+ ThinkingSphinx::Index::Builder.stub(:generate) { raise StandardError }
105
+
106
+ lambda {
107
+ TestModule::TestModel.define_index
108
+ }.should raise_error
109
+ end
110
+ end
111
+
112
+ describe "index methods" do
113
+ before(:all) do
114
+ @person = Person.find(:first)
115
+ end
116
+
117
+ describe "in_both_indexes?" do
118
+ it "should return true if in core and delta indexes" do
119
+ @person.should_receive(:in_core_index?).and_return(true)
120
+ @person.should_receive(:in_delta_index?).and_return(true)
121
+ @person.in_both_indexes?.should be_true
122
+ end
123
+
124
+ it "should return false if in one index and not the other" do
125
+ @person.should_receive(:in_core_index?).and_return(true)
126
+ @person.should_receive(:in_delta_index?).and_return(false)
127
+ @person.in_both_indexes?.should be_false
128
+ end
129
+ end
130
+
131
+ describe "in_core_index?" do
132
+ it "should call in_index? with core" do
133
+ @person.should_receive(:in_index?).with('core')
134
+ @person.in_core_index?
135
+ end
136
+ end
137
+
138
+ describe "in_delta_index?" do
139
+ it "should call in_index? with delta" do
140
+ @person.should_receive(:in_index?).with('delta')
141
+ @person.in_delta_index?
142
+ end
143
+ end
144
+
145
+ describe "in_index?" do
146
+ it "should return true if in the specified index" do
147
+ @person.should_receive(:sphinx_document_id).and_return(1)
148
+ @person.should_receive(:sphinx_index_name).and_return('person_core')
149
+ Person.should_receive(:search_for_id).with(1, 'person_core').and_return(true)
150
+
151
+ @person.in_index?('core').should be_true
152
+ end
153
+ end
154
+ end
155
+
156
+ describe '.source_of_sphinx_index' do
157
+ it "should return self if model defines an index" do
158
+ Person.source_of_sphinx_index.should == Person
159
+ end
160
+
161
+ it "should return the parent if model inherits an index" do
162
+ Admin::Person.source_of_sphinx_index.should == Person
163
+ end
164
+ end
165
+
166
+ describe '.to_crc32' do
167
+ it "should return an integer" do
168
+ Person.to_crc32.should be_a_kind_of(Integer)
169
+ end
170
+ end
171
+
172
+ describe '.to_crc32s' do
173
+ it "should return an array" do
174
+ Person.to_crc32s.should be_a_kind_of(Array)
175
+ end
176
+ end
177
+
178
+ describe "toggle_deleted method" do
179
+ before :each do
180
+ ThinkingSphinx.stub!(:sphinx_running? => true)
181
+
182
+ @configuration = ThinkingSphinx::Configuration.instance
183
+ @configuration.stub!(
184
+ :address => "an address",
185
+ :port => 123
186
+ )
187
+ @client = Riddle::Client.new
188
+ @client.stub!(:update => true)
189
+ @person = Person.find(:first)
190
+
191
+ Riddle::Client.stub!(:new => @client)
192
+ Person.sphinx_indexes.each { |index| index.stub!(:delta? => false) }
193
+ @person.stub!(:in_core_index? => true)
194
+ end
195
+
196
+ it "should create a client using the Configuration's address and port" do
197
+ Riddle::Client.should_receive(:new).with(
198
+ @configuration.address, @configuration.port
199
+ )
200
+
201
+ @person.toggle_deleted
202
+ end
203
+
204
+ it "should update the core index's deleted flag if in core index" do
205
+ @client.should_receive(:update).with(
206
+ "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
207
+ )
208
+
209
+ @person.toggle_deleted
210
+ end
211
+
212
+ it "shouldn't update the core index's deleted flag if the record isn't in it" do
213
+ @person.stub!(:in_core_index? => false)
214
+ @client.should_not_receive(:update).with(
215
+ "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
216
+ )
217
+
218
+ @person.toggle_deleted
219
+ end
220
+
221
+ it "shouldn't attempt to update the deleted flag if sphinx isn't running" do
222
+ ThinkingSphinx.stub!(:sphinx_running? => false)
223
+ @client.should_not_receive(:update)
224
+ @person.should_not_receive(:in_core_index?)
225
+
226
+ @person.toggle_deleted
227
+ end
228
+
229
+ it "should update the delta index's deleted flag if delta indexes are enabled and the instance's delta is true" do
230
+ ThinkingSphinx.deltas_enabled = true
231
+ Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
232
+ @person.delta = true
233
+ @client.should_receive(:update).with(
234
+ "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
235
+ )
236
+
237
+ @person.toggle_deleted
238
+ end
239
+
240
+ it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is false" do
241
+ ThinkingSphinx.deltas_enabled = true
242
+ Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
243
+ @person.delta = false
244
+ @client.should_not_receive(:update).with(
245
+ "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
246
+ )
247
+
248
+ @person.toggle_deleted
249
+ end
250
+
251
+ it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is equivalent to false" do
252
+ ThinkingSphinx.deltas_enabled = true
253
+ Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
254
+ @person.delta = 0
255
+ @client.should_not_receive(:update).with(
256
+ "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
257
+ )
258
+
259
+ @person.toggle_deleted
260
+ end
261
+
262
+ it "shouldn't update the delta index if delta indexes are disabled" do
263
+ ThinkingSphinx.deltas_enabled = true
264
+ @client.should_not_receive(:update).with(
265
+ "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
266
+ )
267
+
268
+ @person.toggle_deleted
269
+ end
270
+
271
+ it "should not update the delta index if delta indexing is disabled" do
272
+ ThinkingSphinx.deltas_enabled = false
273
+ Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
274
+ @person.delta = true
275
+ @client.should_not_receive(:update).with(
276
+ "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
277
+ )
278
+
279
+ @person.toggle_deleted
280
+ end
281
+
282
+ it "should not update either index if updates are disabled" do
283
+ ThinkingSphinx.updates_enabled = false
284
+ ThinkingSphinx.deltas_enabled = true
285
+ Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
286
+ @person.delta = true
287
+ @client.should_not_receive(:update)
288
+
289
+ @person.toggle_deleted
290
+ end
291
+ end
292
+
293
+ describe "sphinx_indexes in the inheritance chain (STI)" do
294
+ it "should hand defined indexes on a class down to its child classes" do
295
+ Child.sphinx_indexes.should include(*Person.sphinx_indexes)
296
+ end
297
+
298
+ it "should allow associations to other STI models" do
299
+ source = Child.sphinx_indexes.last.sources.first
300
+ sql = source.to_riddle_for_core(0, 0).sql_query
301
+ sql.gsub!('$start', '0').gsub!('$end', '100')
302
+ lambda {
303
+ Child.connection.execute(sql)
304
+ }.should_not raise_error(ActiveRecord::StatementInvalid)
305
+ end
306
+ end
307
+
308
+ it "should return the sphinx document id as expected" do
309
+ person = Person.find(:first)
310
+ model_count = ThinkingSphinx.indexed_models.length
311
+ offset = ThinkingSphinx.indexed_models.index("Person")
312
+
313
+ (person.id * model_count + offset).should == person.sphinx_document_id
314
+
315
+ alpha = Alpha.find(:first)
316
+ offset = ThinkingSphinx.indexed_models.index("Alpha")
317
+
318
+ (alpha.id * model_count + offset).should == alpha.sphinx_document_id
319
+
320
+ beta = Beta.find(:first)
321
+ offset = ThinkingSphinx.indexed_models.index("Beta")
322
+
323
+ (beta.id * model_count + offset).should == beta.sphinx_document_id
324
+ end
325
+
326
+ describe '#primary_key_for_sphinx' do
327
+ before :each do
328
+ @person = Person.find(:first)
329
+ end
330
+
331
+ after :each do
332
+ Person.set_sphinx_primary_key nil
333
+ end
334
+
335
+ it "should return the id by default" do
336
+ @person.primary_key_for_sphinx.should == @person.id
337
+ end
338
+
339
+ it "should use the sphinx primary key to determine the value" do
340
+ Person.set_sphinx_primary_key :first_name
341
+ @person.primary_key_for_sphinx.should == @person.first_name
342
+ end
343
+
344
+ it "should not use accessor methods but the attributes hash" do
345
+ id = @person.id
346
+ @person.stub!(:id => 'unique_hash')
347
+ @person.primary_key_for_sphinx.should == id
348
+ end
349
+ end
350
+
351
+ describe '.sphinx_index_names' do
352
+ it "should return the core index" do
353
+ Alpha.sphinx_index_names.should == ['alpha_core']
354
+ end
355
+
356
+ it "should return the delta index if enabled" do
357
+ Beta.sphinx_index_names.should == ['beta_core', 'beta_delta']
358
+ end
359
+
360
+ it "should return the superclass with an index definition" do
361
+ Parent.sphinx_index_names.should == ['person_core', 'person_delta']
362
+ end
363
+ end
364
+ end