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,333 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Facet do
4
+ describe ".name_for" do
5
+ it "should remove '_facet' from provided string and return a symbol" do
6
+ ThinkingSphinx::Facet.name_for('attribute_facet').should == :attribute
7
+ end
8
+
9
+ it "should remove '_facet' from provided symbol" do
10
+ ThinkingSphinx::Facet.name_for(:attribute_facet).should == :attribute
11
+ end
12
+
13
+ it "should return the name of the facet if a Facet is passed" do
14
+ facet = ThinkingSphinx::Facet.new(
15
+ stub('attribute', :unique_name => :attribute, :columns => ['attribute'])
16
+ )
17
+ ThinkingSphinx::Facet.name_for(facet).should == :attribute
18
+ end
19
+
20
+ it "should return 'class' for special case name 'class_crc'" do
21
+ ThinkingSphinx::Facet.name_for(:class_crc).should == :class
22
+ end
23
+
24
+ it "should cycle" do
25
+ ThinkingSphinx::Facet.name_for(ThinkingSphinx::Facet.attribute_name_for(:attribute)).should == :attribute
26
+ end
27
+ end
28
+
29
+ describe ".attribute_name_for" do
30
+ it "should append '_facet' to provided string" do
31
+ ThinkingSphinx::Facet.attribute_name_for('attribute').should == 'attribute_facet'
32
+ end
33
+
34
+ it "should append '_facet' to provided symbol and return a string" do
35
+ ThinkingSphinx::Facet.attribute_name_for(:attribute).should == 'attribute_facet'
36
+ end
37
+
38
+ it "should return 'class_crc' for special case attribute 'class'" do
39
+ ThinkingSphinx::Facet.attribute_name_for(:class).should == 'class_crc'
40
+ end
41
+
42
+ it "should cycle" do
43
+ ThinkingSphinx::Facet.attribute_name_for(ThinkingSphinx::Facet.name_for('attribute_facet')).should == 'attribute_facet'
44
+ end
45
+ end
46
+
47
+ describe ".attribute_name_from_value" do
48
+ it "should append _facet if the value is a string" do
49
+ ThinkingSphinx::Facet.attribute_name_from_value('attribute', 'string').
50
+ should == 'attribute_facet'
51
+ end
52
+
53
+ it "should not append _facet if the value isn't a string" do
54
+ ThinkingSphinx::Facet.attribute_name_from_value('attribute', 1).
55
+ should == 'attribute'
56
+ ThinkingSphinx::Facet.attribute_name_from_value('attribute', Time.now).
57
+ should == 'attribute'
58
+ ThinkingSphinx::Facet.attribute_name_from_value('attribute', true).
59
+ should == 'attribute'
60
+ ThinkingSphinx::Facet.attribute_name_from_value('attribute', 1.23).
61
+ should == 'attribute'
62
+ end
63
+
64
+ it "should append _facet is the value is an array of strings" do
65
+ ThinkingSphinx::Facet.attribute_name_from_value('attribute', ['a', 'b']).
66
+ should == 'attribute_facet'
67
+ end
68
+
69
+ it "should not append _facet if the value is an array of integers" do
70
+ ThinkingSphinx::Facet.attribute_name_from_value('attribute', [1, 2]).
71
+ should == 'attribute'
72
+ end
73
+ end
74
+
75
+ describe ".translate?" do
76
+ before :each do
77
+ @index = ThinkingSphinx::Index.new(Alpha)
78
+ @source = ThinkingSphinx::Source.new(@index)
79
+ @attribute = ThinkingSphinx::Attribute.new(
80
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
81
+ )
82
+ end
83
+
84
+ it "should return true if the property is a field" do
85
+ field = ThinkingSphinx::Field.new(
86
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
87
+ )
88
+
89
+ ThinkingSphinx::Facet.translate?(field).should be_true
90
+ end
91
+
92
+ it "should return true if the property is a string attribute" do
93
+ @attribute.stub!(:type => :string)
94
+
95
+ ThinkingSphinx::Facet.translate?(@attribute).should be_true
96
+ end
97
+
98
+ it "should return false if the property is an integer attribute" do
99
+ @attribute.stub!(:type => :integer)
100
+
101
+ ThinkingSphinx::Facet.translate?(@attribute).should be_false
102
+ end
103
+
104
+ it "should return false if the property is a boolean attribute" do
105
+ @attribute.stub!(:type => :boolean)
106
+
107
+ ThinkingSphinx::Facet.translate?(@attribute).should be_false
108
+ end
109
+
110
+ it "should return false if the property is a timestamp attribute" do
111
+ @attribute.stub!(:type => :datetime)
112
+
113
+ ThinkingSphinx::Facet.translate?(@attribute).should be_false
114
+ end
115
+
116
+ it "should return false if the property is a float attribute" do
117
+ @attribute.stub!(:type => :float)
118
+
119
+ ThinkingSphinx::Facet.translate?(@attribute).should be_false
120
+ end
121
+
122
+ it "should return false if the property is an MVA of integer values" do
123
+ @attribute.stub!(:type => :multi, :all_ints? => true)
124
+
125
+ ThinkingSphinx::Facet.translate?(@attribute).should be_false
126
+ end
127
+
128
+ it "should return true if the property is an MVA of string values" do
129
+ @attribute.stub!(:type => :multi, :all_ints? => false)
130
+
131
+ ThinkingSphinx::Facet.translate?(@attribute).should be_true
132
+ end
133
+ end
134
+
135
+ describe "#translate?" do
136
+ before :each do
137
+ @index = ThinkingSphinx::Index.new(Alpha)
138
+ @source = ThinkingSphinx::Source.new(@index)
139
+ @attribute = ThinkingSphinx::Attribute.new(
140
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
141
+ )
142
+ end
143
+
144
+ it "should return true if the property is a field" do
145
+ field = ThinkingSphinx::Field.new(
146
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
147
+ )
148
+
149
+ ThinkingSphinx::Facet.new(field).translate?.should be_true
150
+ end
151
+
152
+ it "should return true if the property is a string attribute" do
153
+ @attribute.stub!(:type => :string)
154
+
155
+ ThinkingSphinx::Facet.new(@attribute).translate?.should be_true
156
+ end
157
+
158
+ it "should return false if the property is an integer attribute" do
159
+ @attribute.stub!(:type => :integer)
160
+
161
+ ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
162
+ end
163
+
164
+ it "should return false if the property is a boolean attribute" do
165
+ @attribute.stub!(:type => :boolean)
166
+
167
+ ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
168
+ end
169
+
170
+ it "should return false if the property is a timestamp attribute" do
171
+ @attribute.stub!(:type => :datetime)
172
+
173
+ ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
174
+ end
175
+
176
+ it "should return false if the property is a float attribute" do
177
+ @attribute.stub!(:type => :float)
178
+
179
+ ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
180
+ end
181
+
182
+ it "should return false if the property is an MVA of integer values" do
183
+ @attribute.stub!(:type => :multi, :all_ints? => true)
184
+
185
+ ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
186
+ end
187
+
188
+ it "should return true if the property is an MVA of string values" do
189
+ @attribute.stub!(:type => :multi, :all_ints? => false)
190
+
191
+ ThinkingSphinx::Facet.new(@attribute).translate?.should be_true
192
+ end
193
+ end
194
+
195
+ describe "#attribute_name" do
196
+ before :each do
197
+ @index = ThinkingSphinx::Index.new(Alpha)
198
+ @source = ThinkingSphinx::Source.new(@index)
199
+ @attribute = ThinkingSphinx::Attribute.new(
200
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
201
+ )
202
+ end
203
+
204
+ it "should return the attribute name if built off an integer attribute" do
205
+ @attribute.stub!(:type => :integer)
206
+
207
+ ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
208
+ end
209
+
210
+ it "should return the attribute name if built off a boolean attribute" do
211
+ @attribute.stub!(:type => :boolean)
212
+
213
+ ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
214
+ end
215
+
216
+ it "should return the attribute name if built off a float attribute" do
217
+ @attribute.stub!(:type => :float)
218
+
219
+ ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
220
+ end
221
+
222
+ it "should return the attribute name if built off a timestamp attribute" do
223
+ @attribute.stub!(:type => :datetime)
224
+
225
+ ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
226
+ end
227
+
228
+ it "should return the attribute name with _facet suffix if built off a string attribute" do
229
+ @attribute.stub!(:type => :string)
230
+
231
+ ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name_facet"
232
+ end
233
+
234
+ it "should return the attribute name with _facet suffix if built off a field" do
235
+ field = ThinkingSphinx::Field.new(
236
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
237
+ )
238
+
239
+ ThinkingSphinx::Facet.new(field).attribute_name.should == "name_facet"
240
+ end
241
+
242
+ it "should return the attribute name if build off an integer MVA" do
243
+ @attribute.stub!(:type => :multi, :all_ints? => true)
244
+
245
+ ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
246
+ end
247
+
248
+ it "should return the attribute name with the _facet suffix if build off an non-integer MVA" do
249
+ @attribute.stub!(:type => :multi, :all_ints? => false)
250
+
251
+ ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name_facet"
252
+ end
253
+ end
254
+
255
+ describe "#type" do
256
+ before :each do
257
+ @index = ThinkingSphinx::Index.new(Alpha)
258
+ @source = ThinkingSphinx::Source.new(@index)
259
+ end
260
+
261
+ it "should return :string if the property is a field" do
262
+ field = ThinkingSphinx::Field.new(
263
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
264
+ )
265
+
266
+ ThinkingSphinx::Facet.new(field).type.should == :string
267
+ end
268
+
269
+ it "should return the attribute type if the property is an attribute" do
270
+ attribute = ThinkingSphinx::Attribute.new(
271
+ @source, ThinkingSphinx::Index::FauxColumn.new(:name)
272
+ )
273
+ attribute.stub!(:type => :anything)
274
+
275
+ ThinkingSphinx::Facet.new(attribute).type.should == :anything
276
+ end
277
+ end
278
+
279
+ describe "#value" do
280
+ describe 'for fields from associations' do
281
+ before :each do
282
+ @index = ThinkingSphinx::Index.new(Friendship)
283
+ @source = ThinkingSphinx::Source.new(@index)
284
+ @field = ThinkingSphinx::Field.new(
285
+ @source, ThinkingSphinx::Index::FauxColumn.new(:person, :first_name)
286
+ )
287
+ @facet = ThinkingSphinx::Facet.new(@field)
288
+ end
289
+
290
+ it "should return association values" do
291
+ person = Person.find(:first)
292
+ friendship = Friendship.new(:person => person)
293
+
294
+ @facet.value(friendship, 1).should == person.first_name
295
+ end
296
+
297
+ it "should return nil if the association is nil" do
298
+ friendship = Friendship.new(:person => nil)
299
+
300
+ @facet.value(friendship, 1).should be_nil
301
+ end
302
+
303
+ it "should return multi-level association values" do
304
+ person = Person.find(:first)
305
+ tag = person.tags.build(:name => 'buried')
306
+ friendship = Friendship.new(:person => person)
307
+
308
+ field = ThinkingSphinx::Field.new(
309
+ @source, ThinkingSphinx::Index::FauxColumn.new(:person, :tags, :name)
310
+ )
311
+ ThinkingSphinx::Facet.new(field).value(friendship, 'buried'.to_crc32).
312
+ should == 'buried'
313
+ end
314
+ end
315
+
316
+ describe 'for float attributes' do
317
+ before :each do
318
+ @index = ThinkingSphinx::Index.new(Alpha)
319
+ @source = ThinkingSphinx::Source.new(@index)
320
+ @attribute = ThinkingSphinx::Attribute.new(
321
+ @source, ThinkingSphinx::Index::FauxColumn.new(:cost)
322
+ )
323
+ @facet = ThinkingSphinx::Facet.new(@attribute)
324
+ end
325
+
326
+ it "should translate using the given model" do
327
+ alpha = Alpha.new(:cost => 10.5)
328
+
329
+ @facet.value(alpha, 1093140480).should == 10.5
330
+ end
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,154 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Field do
4
+ before :each do
5
+ @index = ThinkingSphinx::Index.new(Alpha)
6
+ @source = ThinkingSphinx::Source.new(@index)
7
+ end
8
+
9
+ describe '#initialize' do
10
+ it 'raises if no columns are provided so that configuration errors are easier to track down' do
11
+ lambda {
12
+ ThinkingSphinx::Field.new(@source, [])
13
+ }.should raise_error(RuntimeError)
14
+ end
15
+
16
+ it 'raises if an element of the columns param is an integer - as happens when you use id instead of :id - so that configuration errors are easier to track down' do
17
+ lambda {
18
+ ThinkingSphinx::Field.new(@source, [1234])
19
+ }.should raise_error(RuntimeError)
20
+ end
21
+ end
22
+
23
+ describe "unique_name method" do
24
+ before :each do
25
+ @field = ThinkingSphinx::Field.new @source, [
26
+ stub('column', :__stack => [], :__name => "col_name")
27
+ ]
28
+ end
29
+
30
+ it "should use the alias if there is one" do
31
+ @field.alias = "alias"
32
+ @field.unique_name.should == "alias"
33
+ end
34
+
35
+ it "should use the alias if there's multiple columns" do
36
+ @field.columns << stub('column', :__stack => [], :__name => "col_name")
37
+ @field.unique_name.should be_nil
38
+
39
+ @field.alias = "alias"
40
+ @field.unique_name.should == "alias"
41
+ end
42
+
43
+ it "should use the column name if there's no alias and just one column" do
44
+ @field.unique_name.should == "col_name"
45
+ end
46
+ end
47
+
48
+ describe "prefixes method" do
49
+ it "should default to false" do
50
+ @field = ThinkingSphinx::Field.new(
51
+ @source, [stub('column', :__stack => [])]
52
+ )
53
+ @field.prefixes.should be_false
54
+ end
55
+
56
+ it "should be true if the corresponding option is set" do
57
+ @field = ThinkingSphinx::Field.new(
58
+ @source, [stub('column', :__stack => [])], :prefixes => true
59
+ )
60
+ @field.prefixes.should be_true
61
+ end
62
+ end
63
+
64
+ describe "infixes method" do
65
+ it "should default to false" do
66
+ @field = ThinkingSphinx::Field.new(
67
+ @source, [stub('column', :__stack => [])]
68
+ )
69
+ @field.infixes.should be_false
70
+ end
71
+
72
+ it "should be true if the corresponding option is set" do
73
+ @field = ThinkingSphinx::Field.new(
74
+ @source, [stub('column', :__stack => [])], :infixes => true
75
+ )
76
+ @field.infixes.should be_true
77
+ end
78
+ end
79
+
80
+ describe "column_with_prefix method" do
81
+ before :each do
82
+ @field = ThinkingSphinx::Field.new @source, [
83
+ ThinkingSphinx::Index::FauxColumn.new(:col_name)
84
+ ]
85
+ @field.columns.each { |col| @field.associations[col] = [] }
86
+ @field.model = Person
87
+
88
+ @first_join = Object.new
89
+ @first_join.stub!(:aliased_table_name => "tabular")
90
+ @second_join = Object.new
91
+ @second_join.stub!(:aliased_table_name => "data")
92
+
93
+ @first_assoc = ThinkingSphinx::Association.new nil, nil
94
+ @first_assoc.stub!(:join => @first_join, :has_column? => true)
95
+ @second_assoc = ThinkingSphinx::Association.new nil, nil
96
+ @second_assoc.stub!(:join => @second_join, :has_column? => true)
97
+ end
98
+
99
+ it "should return the column name if the column is a string" do
100
+ @field.columns = [ThinkingSphinx::Index::FauxColumn.new("string")]
101
+ @field.send(:column_with_prefix, @field.columns.first).should == "string"
102
+ end
103
+
104
+ it "should return the column with model's table prefix if there's no associations for the column" do
105
+ @field.send(:column_with_prefix, @field.columns.first).should == "`people`.`col_name`"
106
+ end
107
+
108
+ it "should return the column with its join table prefix if an association exists" do
109
+ column = @field.columns.first
110
+ @field.associations[column] = [@first_assoc]
111
+ @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`"
112
+ end
113
+
114
+ it "should return multiple columns concatenated if more than one association exists" do
115
+ column = @field.columns.first
116
+ @field.associations[column] = [@first_assoc, @second_assoc]
117
+ @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`, `data`.`col_name`"
118
+ end
119
+ end
120
+
121
+ describe "is_many? method" do
122
+ before :each do
123
+ @assoc_a = stub('assoc', :is_many? => true)
124
+ @assoc_b = stub('assoc', :is_many? => true)
125
+ @assoc_c = stub('assoc', :is_many? => true)
126
+
127
+ @field = ThinkingSphinx::Field.new(
128
+ @source, [ThinkingSphinx::Index::FauxColumn.new(:col_name)]
129
+ )
130
+ @field.associations = {
131
+ :a => @assoc_a, :b => @assoc_b, :c => @assoc_c
132
+ }
133
+ end
134
+
135
+ it "should return true if all associations return true to is_many?" do
136
+ @field.send(:is_many?).should be_true
137
+ end
138
+
139
+ it "should return true if one association returns true to is_many?" do
140
+ @assoc_b.stub!(:is_many? => false)
141
+ @assoc_c.stub!(:is_many? => false)
142
+
143
+ @field.send(:is_many?).should be_true
144
+ end
145
+
146
+ it "should return false if all associations return false to is_many?" do
147
+ @assoc_a.stub!(:is_many? => false)
148
+ @assoc_b.stub!(:is_many? => false)
149
+ @assoc_c.stub!(:is_many? => false)
150
+
151
+ @field.send(:is_many?).should be_false
152
+ end
153
+ end
154
+ end