skalee-thinking-sphinx 1.3.14.1

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 (199) hide show
  1. data/LICENCE +20 -0
  2. data/README.textile +201 -0
  3. data/Rakefile +3 -0
  4. data/VERSION +1 -0
  5. data/contribute.rb +385 -0
  6. data/cucumber.yml +1 -0
  7. data/features/abstract_inheritance.feature +10 -0
  8. data/features/alternate_primary_key.feature +27 -0
  9. data/features/attribute_transformation.feature +22 -0
  10. data/features/attribute_updates.feature +51 -0
  11. data/features/deleting_instances.feature +67 -0
  12. data/features/direct_attributes.feature +11 -0
  13. data/features/excerpts.feature +13 -0
  14. data/features/extensible_delta_indexing.feature +9 -0
  15. data/features/facets.feature +82 -0
  16. data/features/facets_across_model.feature +29 -0
  17. data/features/handling_edits.feature +92 -0
  18. data/features/retry_stale_indexes.feature +24 -0
  19. data/features/searching_across_models.feature +20 -0
  20. data/features/searching_by_index.feature +40 -0
  21. data/features/searching_by_model.feature +175 -0
  22. data/features/searching_with_find_arguments.feature +56 -0
  23. data/features/sphinx_detection.feature +25 -0
  24. data/features/sphinx_scopes.feature +42 -0
  25. data/features/step_definitions/alpha_steps.rb +16 -0
  26. data/features/step_definitions/beta_steps.rb +7 -0
  27. data/features/step_definitions/common_steps.rb +188 -0
  28. data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
  29. data/features/step_definitions/facet_steps.rb +96 -0
  30. data/features/step_definitions/find_arguments_steps.rb +36 -0
  31. data/features/step_definitions/gamma_steps.rb +15 -0
  32. data/features/step_definitions/scope_steps.rb +15 -0
  33. data/features/step_definitions/search_steps.rb +89 -0
  34. data/features/step_definitions/sphinx_steps.rb +35 -0
  35. data/features/sti_searching.feature +19 -0
  36. data/features/support/database.example.yml +3 -0
  37. data/features/support/db/.gitignore +1 -0
  38. data/features/support/db/fixtures/alphas.rb +10 -0
  39. data/features/support/db/fixtures/authors.rb +1 -0
  40. data/features/support/db/fixtures/betas.rb +10 -0
  41. data/features/support/db/fixtures/boxes.rb +9 -0
  42. data/features/support/db/fixtures/categories.rb +1 -0
  43. data/features/support/db/fixtures/cats.rb +3 -0
  44. data/features/support/db/fixtures/comments.rb +24 -0
  45. data/features/support/db/fixtures/developers.rb +29 -0
  46. data/features/support/db/fixtures/dogs.rb +3 -0
  47. data/features/support/db/fixtures/extensible_betas.rb +10 -0
  48. data/features/support/db/fixtures/foxes.rb +3 -0
  49. data/features/support/db/fixtures/gammas.rb +10 -0
  50. data/features/support/db/fixtures/music.rb +4 -0
  51. data/features/support/db/fixtures/people.rb +1001 -0
  52. data/features/support/db/fixtures/posts.rb +6 -0
  53. data/features/support/db/fixtures/robots.rb +14 -0
  54. data/features/support/db/fixtures/tags.rb +27 -0
  55. data/features/support/db/migrations/create_alphas.rb +8 -0
  56. data/features/support/db/migrations/create_animals.rb +5 -0
  57. data/features/support/db/migrations/create_authors.rb +3 -0
  58. data/features/support/db/migrations/create_authors_posts.rb +6 -0
  59. data/features/support/db/migrations/create_betas.rb +5 -0
  60. data/features/support/db/migrations/create_boxes.rb +5 -0
  61. data/features/support/db/migrations/create_categories.rb +3 -0
  62. data/features/support/db/migrations/create_comments.rb +10 -0
  63. data/features/support/db/migrations/create_developers.rb +9 -0
  64. data/features/support/db/migrations/create_extensible_betas.rb +5 -0
  65. data/features/support/db/migrations/create_gammas.rb +3 -0
  66. data/features/support/db/migrations/create_genres.rb +3 -0
  67. data/features/support/db/migrations/create_music.rb +6 -0
  68. data/features/support/db/migrations/create_people.rb +13 -0
  69. data/features/support/db/migrations/create_posts.rb +5 -0
  70. data/features/support/db/migrations/create_robots.rb +4 -0
  71. data/features/support/db/migrations/create_taggings.rb +5 -0
  72. data/features/support/db/migrations/create_tags.rb +4 -0
  73. data/features/support/env.rb +21 -0
  74. data/features/support/lib/generic_delta_handler.rb +8 -0
  75. data/features/support/models/alpha.rb +22 -0
  76. data/features/support/models/animal.rb +5 -0
  77. data/features/support/models/author.rb +3 -0
  78. data/features/support/models/beta.rb +8 -0
  79. data/features/support/models/box.rb +8 -0
  80. data/features/support/models/cat.rb +3 -0
  81. data/features/support/models/category.rb +4 -0
  82. data/features/support/models/comment.rb +10 -0
  83. data/features/support/models/developer.rb +16 -0
  84. data/features/support/models/dog.rb +3 -0
  85. data/features/support/models/extensible_beta.rb +9 -0
  86. data/features/support/models/fox.rb +5 -0
  87. data/features/support/models/gamma.rb +5 -0
  88. data/features/support/models/genre.rb +3 -0
  89. data/features/support/models/medium.rb +5 -0
  90. data/features/support/models/music.rb +8 -0
  91. data/features/support/models/person.rb +23 -0
  92. data/features/support/models/post.rb +21 -0
  93. data/features/support/models/robot.rb +12 -0
  94. data/features/support/models/tag.rb +3 -0
  95. data/features/support/models/tagging.rb +4 -0
  96. data/ginger_scenarios.rb +28 -0
  97. data/init.rb +5 -0
  98. data/install.rb +5 -0
  99. data/lib/cucumber/thinking_sphinx/external_world.rb +8 -0
  100. data/lib/cucumber/thinking_sphinx/internal_world.rb +126 -0
  101. data/lib/cucumber/thinking_sphinx/sql_logger.rb +20 -0
  102. data/lib/thinking_sphinx/active_record/attribute_updates.rb +19 -0
  103. data/lib/thinking_sphinx/active_record/delta.rb +47 -0
  104. data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
  105. data/lib/thinking_sphinx/active_record/scopes.rb +75 -0
  106. data/lib/thinking_sphinx/active_record.rb +348 -0
  107. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
  108. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
  109. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +143 -0
  110. data/lib/thinking_sphinx/association.rb +164 -0
  111. data/lib/thinking_sphinx/attribute.rb +362 -0
  112. data/lib/thinking_sphinx/auto_version.rb +22 -0
  113. data/lib/thinking_sphinx/class_facet.rb +15 -0
  114. data/lib/thinking_sphinx/configuration.rb +300 -0
  115. data/lib/thinking_sphinx/context.rb +68 -0
  116. data/lib/thinking_sphinx/core/array.rb +7 -0
  117. data/lib/thinking_sphinx/core/string.rb +15 -0
  118. data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
  119. data/lib/thinking_sphinx/deltas.rb +28 -0
  120. data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
  121. data/lib/thinking_sphinx/excerpter.rb +22 -0
  122. data/lib/thinking_sphinx/facet.rb +125 -0
  123. data/lib/thinking_sphinx/facet_search.rb +136 -0
  124. data/lib/thinking_sphinx/field.rb +82 -0
  125. data/lib/thinking_sphinx/index/builder.rb +296 -0
  126. data/lib/thinking_sphinx/index/faux_column.rb +110 -0
  127. data/lib/thinking_sphinx/index.rb +157 -0
  128. data/lib/thinking_sphinx/property.rb +162 -0
  129. data/lib/thinking_sphinx/rails_additions.rb +150 -0
  130. data/lib/thinking_sphinx/search.rb +769 -0
  131. data/lib/thinking_sphinx/search_methods.rb +439 -0
  132. data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
  133. data/lib/thinking_sphinx/source/sql.rb +130 -0
  134. data/lib/thinking_sphinx/source.rb +153 -0
  135. data/lib/thinking_sphinx/tasks.rb +131 -0
  136. data/lib/thinking_sphinx/test.rb +52 -0
  137. data/lib/thinking_sphinx.rb +225 -0
  138. data/rails/init.rb +16 -0
  139. data/recipes/thinking_sphinx.rb +3 -0
  140. data/spec/fixtures/data.sql +32 -0
  141. data/spec/fixtures/database.yml.default +3 -0
  142. data/spec/fixtures/models.rb +145 -0
  143. data/spec/fixtures/structure.sql +125 -0
  144. data/spec/spec_helper.rb +60 -0
  145. data/spec/sphinx_helper.rb +81 -0
  146. data/spec/thinking_sphinx/active_record/delta_spec.rb +128 -0
  147. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +55 -0
  148. data/spec/thinking_sphinx/active_record/scopes_spec.rb +177 -0
  149. data/spec/thinking_sphinx/active_record_spec.rb +622 -0
  150. data/spec/thinking_sphinx/association_spec.rb +239 -0
  151. data/spec/thinking_sphinx/attribute_spec.rb +570 -0
  152. data/spec/thinking_sphinx/auto_version_spec.rb +39 -0
  153. data/spec/thinking_sphinx/configuration_spec.rb +234 -0
  154. data/spec/thinking_sphinx/context_spec.rb +119 -0
  155. data/spec/thinking_sphinx/core/array_spec.rb +9 -0
  156. data/spec/thinking_sphinx/core/string_spec.rb +9 -0
  157. data/spec/thinking_sphinx/excerpter_spec.rb +57 -0
  158. data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
  159. data/spec/thinking_sphinx/facet_spec.rb +333 -0
  160. data/spec/thinking_sphinx/field_spec.rb +154 -0
  161. data/spec/thinking_sphinx/index/builder_spec.rb +479 -0
  162. data/spec/thinking_sphinx/index/faux_column_spec.rb +30 -0
  163. data/spec/thinking_sphinx/index_spec.rb +183 -0
  164. data/spec/thinking_sphinx/rails_additions_spec.rb +203 -0
  165. data/spec/thinking_sphinx/search_methods_spec.rb +152 -0
  166. data/spec/thinking_sphinx/search_spec.rb +1181 -0
  167. data/spec/thinking_sphinx/source_spec.rb +235 -0
  168. data/spec/thinking_sphinx_spec.rb +204 -0
  169. data/tasks/distribution.rb +41 -0
  170. data/tasks/rails.rake +1 -0
  171. data/tasks/testing.rb +72 -0
  172. data/vendor/after_commit/.gitignore +1 -0
  173. data/vendor/after_commit/lib/after_commit/active_record.rb +122 -0
  174. data/vendor/after_commit/lib/after_commit/connection_adapters.rb +168 -0
  175. data/vendor/after_commit/lib/after_commit/test_bypass.rb +30 -0
  176. data/vendor/after_commit/lib/after_commit.rb +70 -0
  177. data/vendor/riddle/lib/riddle/0.9.8.rb +1 -0
  178. data/vendor/riddle/lib/riddle/0.9.9/client/filter.rb +22 -0
  179. data/vendor/riddle/lib/riddle/0.9.9/client.rb +49 -0
  180. data/vendor/riddle/lib/riddle/0.9.9/configuration/searchd.rb +28 -0
  181. data/vendor/riddle/lib/riddle/0.9.9.rb +7 -0
  182. data/vendor/riddle/lib/riddle/auto_version.rb +11 -0
  183. data/vendor/riddle/lib/riddle/client/filter.rb +62 -0
  184. data/vendor/riddle/lib/riddle/client/message.rb +70 -0
  185. data/vendor/riddle/lib/riddle/client/response.rb +94 -0
  186. data/vendor/riddle/lib/riddle/client.rb +745 -0
  187. data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +49 -0
  188. data/vendor/riddle/lib/riddle/configuration/index.rb +149 -0
  189. data/vendor/riddle/lib/riddle/configuration/indexer.rb +20 -0
  190. data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
  191. data/vendor/riddle/lib/riddle/configuration/searchd.rb +28 -0
  192. data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
  193. data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
  194. data/vendor/riddle/lib/riddle/configuration/sql_source.rb +53 -0
  195. data/vendor/riddle/lib/riddle/configuration/xml_source.rb +29 -0
  196. data/vendor/riddle/lib/riddle/configuration.rb +33 -0
  197. data/vendor/riddle/lib/riddle/controller.rb +78 -0
  198. data/vendor/riddle/lib/riddle.rb +51 -0
  199. metadata +312 -0
@@ -0,0 +1,479 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Index::Builder do
4
+ describe ".generate without source scope" do
5
+ before :each do
6
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
7
+ indexes first_name, last_name
8
+ has birthday
9
+ has id, :as => :internal_id
10
+
11
+ set_property :sql_range_step => 1000
12
+
13
+ where "birthday <= NOW()"
14
+ group_by "first_name"
15
+ end
16
+
17
+ @source = @index.sources.first
18
+ end
19
+
20
+ it "should return an index" do
21
+ @index.should be_a_kind_of(ThinkingSphinx::Index)
22
+ end
23
+
24
+ it "should have one source for the index" do
25
+ @index.sources.length.should == 1
26
+ end
27
+
28
+ it "should have two fields" do
29
+ @source.fields.length.should == 2
30
+ @source.fields[0].unique_name.should == :first_name
31
+ @source.fields[1].unique_name.should == :last_name
32
+ end
33
+
34
+ it "should have two attributes alongside the four internal ones" do
35
+ @source.attributes.length.should == 6
36
+ @source.attributes[4].unique_name.should == :birthday
37
+ @source.attributes[5].unique_name.should == :internal_id
38
+ end
39
+
40
+ it "should have one condition" do
41
+ @source.conditions.length.should == 1
42
+ @source.conditions.first.should == "birthday <= NOW()"
43
+ end
44
+
45
+ it "should have one grouping" do
46
+ @source.groupings.length.should == 1
47
+ @source.groupings.first.should == "first_name"
48
+ end
49
+
50
+ it "should have one option" do
51
+ @source.options.length.should == 1
52
+ @source.options[:sql_range_step].should == 1000
53
+ end
54
+ end
55
+
56
+ describe 'aliased field' do
57
+ before :each do
58
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
59
+ indexes first_name, :as => 'name'
60
+ end
61
+
62
+ @source = @index.sources.first
63
+ end
64
+
65
+ it "should store the alias as a symbol for consistency" do
66
+ @source.fields.last.unique_name.should == :name
67
+ end
68
+ end
69
+
70
+ describe 'aliased attribute' do
71
+ before :each do
72
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
73
+ indexes first_name
74
+ has :id, :as => 'real_id'
75
+ end
76
+
77
+ @source = @index.sources.first
78
+ end
79
+
80
+ it "should store the alias as a symbol for consistency" do
81
+ @source.attributes.last.unique_name.should == :real_id
82
+ end
83
+ end
84
+
85
+ describe "sortable field" do
86
+ before :each do
87
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
88
+ indexes first_name, :sortable => true
89
+ end
90
+
91
+ @source = @index.sources.first
92
+ end
93
+
94
+ it "should have one field" do
95
+ @source.fields.length.should == 1
96
+ end
97
+
98
+ it "should have one attribute alongside the four internal ones" do
99
+ @source.attributes.length.should == 5
100
+ end
101
+
102
+ it "should set the attribute name to have the _sort suffix" do
103
+ @source.attributes.last.unique_name.should == :first_name_sort
104
+ end
105
+
106
+ it "should set the attribute column to be the same as the field" do
107
+ @source.attributes.last.columns.length.should == 1
108
+ @source.attributes.last.columns.first.__name.should == :first_name
109
+ end
110
+ end
111
+
112
+ describe "faceted field" do
113
+ before :each do
114
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
115
+ indexes first_name, :facet => true
116
+ end
117
+
118
+ @source = @index.sources.first
119
+ end
120
+
121
+ after :each do
122
+ Person.sphinx_facets.delete_at(-1)
123
+ end
124
+
125
+ it "should have one field" do
126
+ @source.fields.length.should == 1
127
+ end
128
+
129
+ it "should have one attribute alongside the four internal ones" do
130
+ @source.attributes.length.should == 5
131
+ end
132
+
133
+ it "should set the attribute name to have the _facet suffix" do
134
+ @source.attributes.last.unique_name.should == :first_name_facet
135
+ end
136
+
137
+ it "should set the attribute type to integer" do
138
+ @source.attributes.last.type.should == :integer
139
+ end
140
+
141
+ it "should set the attribute column to be the same as the field" do
142
+ @source.attributes.last.columns.length.should == 1
143
+ @source.attributes.last.columns.first.__name.should == :first_name
144
+ end
145
+ end
146
+
147
+ describe "faceted integer attribute" do
148
+ before :each do
149
+ @index = ThinkingSphinx::Index::Builder.generate(Alpha) do
150
+ indexes :name
151
+ has value, :facet => true
152
+ end
153
+
154
+ @source = @index.sources.first
155
+ end
156
+
157
+ after :each do
158
+ Alpha.sphinx_facets.delete_at(-1)
159
+ end
160
+
161
+ it "should have just one attribute alongside the four internal ones" do
162
+ @source.attributes.length.should == 5
163
+ end
164
+ end
165
+
166
+ describe "faceted timestamp attribute" do
167
+ before :each do
168
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
169
+ indexes first_name
170
+ has birthday, :facet => true
171
+ end
172
+
173
+ @source = @index.sources.first
174
+ end
175
+
176
+ after :each do
177
+ Person.sphinx_facets.delete_at(-1)
178
+ end
179
+
180
+ it "should have just one attribute alongside the four internal ones" do
181
+ @source.attributes.length.should == 5
182
+ end
183
+ end
184
+
185
+ describe "faceted boolean attribute" do
186
+ before :each do
187
+ @index = ThinkingSphinx::Index::Builder.generate(Beta) do
188
+ indexes :name
189
+ has delta, :facet => true
190
+ end
191
+
192
+ @source = @index.sources.first
193
+ end
194
+
195
+ after :each do
196
+ Beta.sphinx_facets.delete_at(-1)
197
+ end
198
+
199
+ it "should have just one attribute alongside the four internal ones" do
200
+ @source.attributes.length.should == 5
201
+ end
202
+ end
203
+
204
+ describe "faceted float attribute" do
205
+ before :each do
206
+ @index = ThinkingSphinx::Index::Builder.generate(Alpha) do
207
+ indexes :name
208
+ has cost, :facet => true
209
+ end
210
+
211
+ @source = @index.sources.first
212
+ end
213
+
214
+ after :each do
215
+ Alpha.sphinx_facets.delete_at(-1)
216
+ end
217
+
218
+ it "should have just one attribute alongside the four internal ones" do
219
+ @source.attributes.length.should == 5
220
+ end
221
+ end
222
+
223
+ describe "faceted string attribute" do
224
+ before :each do
225
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
226
+ indexes first_name
227
+ has last_name, :facet => true
228
+ end
229
+
230
+ @source = @index.sources.first
231
+ end
232
+
233
+ after :each do
234
+ Person.sphinx_facets.delete_at(-1)
235
+ end
236
+
237
+ it "should have two attributes alongside the four internal ones" do
238
+ @source.attributes.length.should == 6
239
+ end
240
+
241
+ it "should set the facet attribute name to have the _facet suffix" do
242
+ @source.attributes.last.unique_name.should == :last_name_facet
243
+ end
244
+
245
+ it "should set the attribute type to integer" do
246
+ @source.attributes.last.type.should == :integer
247
+ end
248
+
249
+ it "should set the attribute column to be the same as the field" do
250
+ @source.attributes.last.columns.length.should == 1
251
+ @source.attributes.last.columns.first.__name.should == :last_name
252
+ end
253
+ end
254
+
255
+ describe 'faceted manual MVA' do
256
+ before :each do
257
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
258
+ indexes first_name
259
+ has 'SQL STATEMENT', :type => :multi, :as => :sql, :facet => true
260
+ end
261
+
262
+ @source = @index.sources.first
263
+ end
264
+
265
+ after :each do
266
+ Person.sphinx_facets.delete_at(-1)
267
+ end
268
+
269
+ it "should have two attributes alongside the four internal ones" do
270
+ @source.attributes.length.should == 6
271
+ end
272
+
273
+ it "should set the facet attribute name to have the _facet suffix" do
274
+ @source.attributes.last.unique_name.should == :sql_facet
275
+ end
276
+
277
+ it "should keep the original attribute's name set as requested" do
278
+ @source.attributes[-2].unique_name.should == :sql
279
+ end
280
+
281
+ it "should set the attribute type to multi" do
282
+ @source.attributes.last.type.should == :multi
283
+ end
284
+
285
+ it "should set the attribute column to be the same as the field" do
286
+ @source.attributes.last.columns.length.should == 1
287
+ @source.attributes.last.columns.first.__name.should == 'SQL STATEMENT'
288
+ end
289
+ end
290
+
291
+ describe 'faceted MVA field' do
292
+ before :each do
293
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
294
+ indexes tags(:name), :as => :tags, :facet => true
295
+ end
296
+
297
+ @source = @index.sources.first
298
+ end
299
+
300
+ after :each do
301
+ Person.sphinx_facets.delete_at(-1)
302
+ end
303
+
304
+ it "should have one field" do
305
+ @source.fields.length.should == 1
306
+ end
307
+
308
+ it "should have one attribute alongside the four internal ones" do
309
+ @source.attributes.length.should == 5
310
+ end
311
+
312
+ it "should set the attribute name to have the _facet suffix" do
313
+ @source.attributes.last.unique_name.should == :tags_facet
314
+ end
315
+
316
+ it "should set the attribute type to multi" do
317
+ @source.attributes.last.type.should == :multi
318
+ end
319
+
320
+ it "should set the attribute column to be the same as the field" do
321
+ @source.attributes.last.columns.length.should == 1
322
+ @source.attributes.last.columns.first.__name.should == :name
323
+ end
324
+ end
325
+
326
+ describe "no fields" do
327
+ it "should raise an exception" do
328
+ lambda {
329
+ ThinkingSphinx::Index::Builder.generate(Person) do
330
+ #
331
+ end
332
+ }.should raise_error
333
+ end
334
+ end
335
+
336
+ describe "explicit source" do
337
+ before :each do
338
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
339
+ define_source do
340
+ indexes first_name, last_name
341
+ has birthday
342
+ has id, :as => :internal_id
343
+
344
+ set_property :delta => true
345
+
346
+ where "birthday <= NOW()"
347
+ group_by "first_name"
348
+ end
349
+ end
350
+
351
+ @source = @index.sources.first
352
+ end
353
+
354
+ it "should return an index" do
355
+ @index.should be_a_kind_of(ThinkingSphinx::Index)
356
+ end
357
+
358
+ it "should have one source for the index" do
359
+ @index.sources.length.should == 1
360
+ end
361
+
362
+ it "should have two fields" do
363
+ @source.fields.length.should == 2
364
+ @source.fields[0].unique_name.should == :first_name
365
+ @source.fields[1].unique_name.should == :last_name
366
+ end
367
+
368
+ it "should have two attributes alongside the four internal ones" do
369
+ @source.attributes.length.should == 6
370
+ @source.attributes[4].unique_name.should == :birthday
371
+ @source.attributes[5].unique_name.should == :internal_id
372
+ end
373
+ end
374
+
375
+ describe "multiple sources" do
376
+ before :each do
377
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
378
+ define_source do
379
+ indexes first_name
380
+ has birthday
381
+ end
382
+
383
+ define_source do
384
+ indexes last_name
385
+ has :id, :as => :internal_id
386
+ end
387
+ end
388
+ end
389
+
390
+ it "should have two sources" do
391
+ @index.sources.length.should == 2
392
+ end
393
+
394
+ it "should have two fields" do
395
+ @index.fields.length.should == 2
396
+ end
397
+
398
+ it "should have one field in each source" do
399
+ @index.sources.each do |source|
400
+ source.fields.length.should == 1
401
+ end
402
+ end
403
+
404
+ it "should have two attributes alongside the eight internal ones" do
405
+ @index.attributes.length.should == 10
406
+ end
407
+
408
+ it "should have one attribute in each source alongside the four internal ones" do
409
+ @index.sources.each do |source|
410
+ source.attributes.length.should == 5
411
+ end
412
+ end
413
+ end
414
+
415
+ describe "index options" do
416
+ before :each do
417
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
418
+ indexes first_name
419
+
420
+ set_property :charset_type => "utf16"
421
+ set_property :group_concat_max_len => 1024
422
+ end
423
+ end
424
+
425
+ it "should store the index setting for the index" do
426
+ @index.local_options[:charset_type].should == "utf16"
427
+ end
428
+
429
+ it "should store non-Sphinx settings for the index" do
430
+ @index.local_options[:group_concat_max_len].should == 1024
431
+ end
432
+ end
433
+
434
+ describe "delta options" do
435
+ before :each do
436
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
437
+ indexes first_name
438
+
439
+ set_property :delta => true
440
+ end
441
+ end
442
+
443
+ it "should not keep the delta setting in source options" do
444
+ @index.sources.first.options.should be_empty
445
+ end
446
+
447
+ it "should not keep the delta setting in index options" do
448
+ @index.local_options.should be_empty
449
+ end
450
+
451
+ it "should set the index delta object set" do
452
+ @index.delta_object.should be_a_kind_of(ThinkingSphinx::Deltas::DefaultDelta)
453
+ end
454
+ end
455
+
456
+ context 'index options' do
457
+ before :each do
458
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
459
+ indexes first_name
460
+
461
+ set_property :index_exact_words => true
462
+ end
463
+ end
464
+
465
+ it "should track the index_exact_words option to the index" do
466
+ @index.local_options[:index_exact_words].should be_true
467
+ end
468
+ end
469
+
470
+ context 'with an explicit name' do
471
+ it "should set the index's name using the provided value" do
472
+ index = ThinkingSphinx::Index::Builder.generate(Person, 'custom') do
473
+ indexes first_name
474
+ end
475
+
476
+ index.name.should == 'custom'
477
+ end
478
+ end
479
+ end
@@ -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 = stub('column')
7
+ ThinkingSphinx::Index::FauxColumn.stub!(: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,183 @@
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 = stub('field', :prefixes => true)
9
+ @field_b = stub('field', :prefixes => false)
10
+ @field_c = stub('field', :prefixes => true)
11
+
12
+ @index.stub!(: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 = stub('field', :infixes => true)
30
+ @field_b = stub('field', :infixes => false)
31
+ @field_c = stub('field', :infixes => true)
32
+
33
+ @index.stub!(: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
+
46
+ describe '.name_for' do
47
+ it "should return the model's name downcased" do
48
+ ThinkingSphinx::Index.name_for(Alpha).should == 'alpha'
49
+ end
50
+
51
+ it "should separate words by underscores" do
52
+ ThinkingSphinx::Index.name_for(ActiveRecord).should == 'active_record'
53
+ end
54
+
55
+ it "should separate namespaces by underscores" do
56
+ ThinkingSphinx::Index.name_for(ActiveRecord::Base).
57
+ should == 'active_record_base'
58
+ end
59
+ end
60
+
61
+ describe '#name' do
62
+ it "should return the downcased name of the index's model" do
63
+ ThinkingSphinx::Index.new(Alpha).name.should == 'alpha'
64
+ end
65
+
66
+ it "should return a custom name if one is set" do
67
+ index = ThinkingSphinx::Index.new(Alpha)
68
+ index.name = 'custom'
69
+ index.name.should == 'custom'
70
+ end
71
+ end
72
+
73
+ describe '#core_name' do
74
+ it "should take the index's name and append _core" do
75
+ ThinkingSphinx::Index.new(Alpha).core_name.should == 'alpha_core'
76
+ end
77
+ end
78
+
79
+ describe '#delta_name' do
80
+ it "should take the index's name and append _delta" do
81
+ ThinkingSphinx::Index.new(Alpha).delta_name.should == 'alpha_delta'
82
+ end
83
+ end
84
+
85
+ describe '#all_names' do
86
+ it "should return the core index name by default" do
87
+ ThinkingSphinx::Index.new(Alpha).all_names.should == ['alpha_core']
88
+ end
89
+
90
+ it "should return both core and delta names if deltas are enabled" do
91
+ index = ThinkingSphinx::Index.new(Alpha)
92
+ index.delta_object = stub('delta')
93
+
94
+ index.all_names.should == ['alpha_core', 'alpha_delta']
95
+ end
96
+
97
+ it "should respect custom names" do
98
+ index = ThinkingSphinx::Index.new(Alpha)
99
+ index.name = 'custom'
100
+
101
+ index.all_names.should == ['custom_core']
102
+ end
103
+
104
+ it "should respect custom names when deltas are enabled" do
105
+ index = ThinkingSphinx::Index.new(Alpha)
106
+ index.name = 'custom'
107
+ index.delta_object = stub('delta')
108
+
109
+ index.all_names.should == ['custom_core', 'custom_delta']
110
+ end
111
+ end
112
+
113
+ describe '#to_riddle' do
114
+ it "should return two Riddle indexes if deltas are disabled" do
115
+ index = ThinkingSphinx::Index.new(Alpha)
116
+
117
+ index.to_riddle(0).length.should == 2
118
+ end
119
+
120
+ it "should return three Riddle indexes if deltas are enabled" do
121
+ index = ThinkingSphinx::Index.new(Beta)
122
+ index.delta_object = stub('delta')
123
+
124
+ index.to_riddle(0).length.should == 3
125
+ end
126
+
127
+ it "should include a distributed index" do
128
+ index = ThinkingSphinx::Index.new(Alpha)
129
+
130
+ index.to_riddle(0).last.
131
+ should be_a(Riddle::Configuration::DistributedIndex)
132
+ end
133
+
134
+ context 'core index' do
135
+ it "should use the core name" do
136
+ @index = ThinkingSphinx::Index.new(Alpha).to_riddle(0).first
137
+ @index.name.should == 'alpha_core'
138
+ end
139
+
140
+ it "should not try to set disable_range on the index" do
141
+ ThinkingSphinx::Configuration.instance.
142
+ index_options[:disable_range] = true
143
+
144
+ lambda {
145
+ @index = ThinkingSphinx::Index.new(Alpha).to_riddle(0).first
146
+ }.should_not raise_error(NoMethodError)
147
+ end
148
+ end
149
+
150
+ context 'delta index' do
151
+ before :each do
152
+ index = ThinkingSphinx::Index.new(Beta)
153
+ index.delta_object = stub('delta')
154
+ @index = index.to_riddle(0)[1]
155
+ end
156
+
157
+ it "should use the delta name" do
158
+ @index.name.should == 'beta_delta'
159
+ end
160
+ end
161
+
162
+ context 'distributed index' do
163
+ it "should use the index's name" do
164
+ index = ThinkingSphinx::Index.new(Alpha)
165
+
166
+ index.to_riddle(0).last.name.should == 'alpha'
167
+ end
168
+
169
+ it "should add the core index" do
170
+ index = ThinkingSphinx::Index.new(Alpha)
171
+
172
+ index.to_riddle(0).last.local_indexes.should include('alpha_core')
173
+ end
174
+
175
+ it "should add the delta index if there is one" do
176
+ index = ThinkingSphinx::Index.new(Beta)
177
+ index.delta_object = stub('delta')
178
+
179
+ index.to_riddle(0).last.local_indexes.should include('beta_delta')
180
+ end
181
+ end
182
+ end
183
+ end