nixme-thinking-sphinx 0.9.7

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 (38) hide show
  1. data/LICENCE +20 -0
  2. data/README +52 -0
  3. data/lib/riddle.rb +22 -0
  4. data/lib/riddle/client.rb +593 -0
  5. data/lib/riddle/client/filter.rb +44 -0
  6. data/lib/riddle/client/message.rb +65 -0
  7. data/lib/riddle/client/response.rb +84 -0
  8. data/lib/test.rb +46 -0
  9. data/lib/thinking_sphinx.rb +82 -0
  10. data/lib/thinking_sphinx/active_record.rb +138 -0
  11. data/lib/thinking_sphinx/active_record/delta.rb +90 -0
  12. data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
  13. data/lib/thinking_sphinx/active_record/search.rb +43 -0
  14. data/lib/thinking_sphinx/association.rb +140 -0
  15. data/lib/thinking_sphinx/attribute.rb +282 -0
  16. data/lib/thinking_sphinx/configuration.rb +277 -0
  17. data/lib/thinking_sphinx/field.rb +198 -0
  18. data/lib/thinking_sphinx/index.rb +334 -0
  19. data/lib/thinking_sphinx/index/builder.rb +212 -0
  20. data/lib/thinking_sphinx/index/faux_column.rb +97 -0
  21. data/lib/thinking_sphinx/rails_additions.rb +56 -0
  22. data/lib/thinking_sphinx/search.rb +455 -0
  23. data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +185 -0
  24. data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +53 -0
  25. data/spec/unit/thinking_sphinx/active_record/search_spec.rb +81 -0
  26. data/spec/unit/thinking_sphinx/active_record_spec.rb +201 -0
  27. data/spec/unit/thinking_sphinx/association_spec.rb +247 -0
  28. data/spec/unit/thinking_sphinx/attribute_spec.rb +356 -0
  29. data/spec/unit/thinking_sphinx/configuration_spec.rb +476 -0
  30. data/spec/unit/thinking_sphinx/field_spec.rb +215 -0
  31. data/spec/unit/thinking_sphinx/index/builder_spec.rb +33 -0
  32. data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +41 -0
  33. data/spec/unit/thinking_sphinx/index_spec.rb +230 -0
  34. data/spec/unit/thinking_sphinx/search_spec.rb +163 -0
  35. data/spec/unit/thinking_sphinx_spec.rb +107 -0
  36. data/tasks/thinking_sphinx_tasks.rake +1 -0
  37. data/tasks/thinking_sphinx_tasks.rb +86 -0
  38. metadata +90 -0
@@ -0,0 +1,247 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Association do
4
+ describe "class-level children method" do
5
+ before :each do
6
+ @normal_reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance(
7
+ :options => {:polymorphic => false}
8
+ )
9
+ @normal_association = ThinkingSphinx::Association.stub_instance
10
+ @poly_reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance(
11
+ :options => {:polymorphic => true},
12
+ :macro => :has_many,
13
+ :name => "polly",
14
+ :active_record => "AR"
15
+ )
16
+ @non_poly_reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance
17
+
18
+ Person.stub_method(:reflect_on_association => @normal_reflection)
19
+ ThinkingSphinx::Association.stub_methods(
20
+ :new => @normal_association,
21
+ :polymorphic_classes => [Person, Person],
22
+ :casted_options => {:casted => :options}
23
+ )
24
+ ::ActiveRecord::Reflection::AssociationReflection.stub_method(
25
+ :new => @non_poly_reflection
26
+ )
27
+ end
28
+
29
+ it "should return an empty array if no association exists" do
30
+ Person.stub_method(:reflect_on_association => nil)
31
+
32
+ ThinkingSphinx::Association.children(Person, :assoc).should == []
33
+ end
34
+
35
+ it "should return a single association instance in an array if assocation isn't polymorphic" do
36
+ ThinkingSphinx::Association.children(Person, :assoc).should == [@normal_association]
37
+ end
38
+
39
+ it "should return multiple association instances for polymorphic associations" do
40
+ Person.stub_method(:reflect_on_association => @poly_reflection)
41
+
42
+ ThinkingSphinx::Association.children(Person, :assoc).should ==
43
+ [@normal_association, @normal_association]
44
+ end
45
+
46
+ it "should generate non-polymorphic 'casted' associations for each polymorphic possibility" do
47
+ Person.stub_method(:reflect_on_association => @poly_reflection)
48
+
49
+ ThinkingSphinx::Association.children(Person, :assoc)
50
+
51
+ ThinkingSphinx::Association.should have_received(:casted_options).with(
52
+ Person, @poly_reflection
53
+ ).twice
54
+
55
+ ::ActiveRecord::Reflection::AssociationReflection.should have_received(:new).with(
56
+ :has_many, :polly_Person, {:casted => :options}, "AR"
57
+ ).twice
58
+
59
+ ThinkingSphinx::Association.should have_received(:new).with(
60
+ nil, @non_poly_reflection
61
+ ).twice
62
+ end
63
+ end
64
+
65
+ describe "instance-level children method" do
66
+ it "should return the children associations for the given association" do
67
+ @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance(
68
+ :klass => :klass
69
+ )
70
+ @association = ThinkingSphinx::Association.new(nil, @reflection)
71
+ ThinkingSphinx::Association.stub_method(:children => :result)
72
+
73
+ @association.children(:assoc).should == :result
74
+ ThinkingSphinx::Association.should have_received(:children).with(:klass, :assoc, @association)
75
+ end
76
+ end
77
+
78
+ describe "join_to method" do
79
+ before :each do
80
+ @parent_join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance
81
+ @join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance
82
+ @parent = ThinkingSphinx::Association.stub_instance(:join_to => true, :join => nil)
83
+ @base_join = Object.stub_instance(:joins => [:a, :b, :c])
84
+
85
+ ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_method(:new => @join)
86
+ end
87
+
88
+ it "should call the parent's join_to if parent has no join" do
89
+ @assoc = ThinkingSphinx::Association.new(@parent, :ref)
90
+
91
+ @assoc.join_to(@base_join)
92
+
93
+ @parent.should have_received(:join_to).with(@base_join)
94
+ end
95
+
96
+ it "should not call the parent's join_to if it already has a join" do
97
+ @assoc = ThinkingSphinx::Association.new(@parent, :ref)
98
+ @parent.stub_method(:join => @parent_join)
99
+
100
+ @assoc.join_to(@base_join)
101
+
102
+ @parent.should_not have_received(:join_to)
103
+ end
104
+
105
+ it "should define the join association with a JoinAssociation instance" do
106
+ @assoc = ThinkingSphinx::Association.new(@parent, :ref)
107
+
108
+ @assoc.join_to(@base_join).should == @join
109
+ @assoc.join.should == @join
110
+ end
111
+ end
112
+
113
+ describe "to_sql method" do
114
+ before :each do
115
+ @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance(
116
+ :klass => Person
117
+ )
118
+ @association = ThinkingSphinx::Association.new(nil, @reflection)
119
+ @parent = Object.stub_instance(:aliased_table_name => "ALIAS TABLE NAME")
120
+ @join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance(
121
+ :association_join => "full association join SQL",
122
+ :parent => @parent
123
+ )
124
+ @association.join = @join
125
+ end
126
+
127
+ it "should return the join's association join value" do
128
+ @association.to_sql.should == "full association join SQL"
129
+ end
130
+
131
+ it "should replace ::ts_join_alias:: with the aliased table name" do
132
+ @join.stub_method(:association_join => "text with ::ts_join_alias:: gone")
133
+
134
+ @association.to_sql.should == "text with `ALIAS TABLE NAME` gone"
135
+ end
136
+ end
137
+
138
+ describe "is_many? method" do
139
+ before :each do
140
+ @parent = ThinkingSphinx::Association.stub_instance(
141
+ :is_many? => :parent_is_many
142
+ )
143
+ @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance(
144
+ :macro => :has_many
145
+ )
146
+ end
147
+
148
+ it "should return true if association is either a has_many or a habtm" do
149
+ association = ThinkingSphinx::Association.new(@parent, @reflection)
150
+ association.is_many?.should be_true
151
+
152
+ @reflection.stub_method(:macro => :has_and_belongs_to_many)
153
+ association.is_many?.should be_true
154
+ end
155
+
156
+ it "should return the parent value if not a has many or habtm and there is a parent" do
157
+ association = ThinkingSphinx::Association.new(@parent, @reflection)
158
+ @reflection.stub_method(:macro => :belongs_to)
159
+ association.is_many?.should == :parent_is_many
160
+ end
161
+
162
+ it "should return false if no parent and not a has many or habtm" do
163
+ association = ThinkingSphinx::Association.new(nil, @reflection)
164
+ @reflection.stub_method(:macro => :belongs_to)
165
+ association.is_many?.should be_false
166
+ end
167
+ end
168
+
169
+ describe "ancestors method" do
170
+ it "should return an array of associations - including all parents" do
171
+ parent = ThinkingSphinx::Association.stub_instance(:ancestors => [:all, :ancestors])
172
+ association = ThinkingSphinx::Association.new(parent, @reflection)
173
+ association.ancestors.should == [:all, :ancestors, association]
174
+ end
175
+ end
176
+
177
+ describe "polymorphic_classes method" do
178
+ it "should return all the polymorphic result types as classes" do
179
+ Person.connection.stub_method(:select_all => [
180
+ {"person_type" => "Person"},
181
+ {"person_type" => "Friendship"}
182
+ ])
183
+ ref = Object.stub_instance(
184
+ :active_record => Person,
185
+ :options => {:foreign_type => "person_type"}
186
+ )
187
+
188
+ ThinkingSphinx::Association.send(:polymorphic_classes, ref).should == [Person, Friendship]
189
+ end
190
+ end
191
+
192
+ describe "casted_options method" do
193
+ before :each do
194
+ @options = {
195
+ :foreign_key => "thing_id",
196
+ :foreign_type => "thing_type",
197
+ :polymorphic => true
198
+ }
199
+ @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance(
200
+ :options => @options
201
+ )
202
+ end
203
+
204
+ it "should return a new options set for a specific class" do
205
+ ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
206
+ :polymorphic => nil,
207
+ :class_name => "Person",
208
+ :foreign_key => "thing_id",
209
+ :foreign_type => "thing_type",
210
+ :conditions => "::ts_join_alias::.`thing_type` = 'Person'"
211
+ }
212
+ end
213
+
214
+ it "should append to existing Array of conditions" do
215
+ @options[:conditions] = ["first condition"]
216
+ ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
217
+ :polymorphic => nil,
218
+ :class_name => "Person",
219
+ :foreign_key => "thing_id",
220
+ :foreign_type => "thing_type",
221
+ :conditions => ["first condition", "::ts_join_alias::.`thing_type` = 'Person'"]
222
+ }
223
+ end
224
+
225
+ it "should merge to an existing Hash of conditions" do
226
+ @options[:conditions] = {"field" => "value"}
227
+ ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
228
+ :polymorphic => nil,
229
+ :class_name => "Person",
230
+ :foreign_key => "thing_id",
231
+ :foreign_type => "thing_type",
232
+ :conditions => {"field" => "value", "thing_type" => "Person"}
233
+ }
234
+ end
235
+
236
+ it "should append to an existing String of conditions" do
237
+ @options[:conditions] = "first condition"
238
+ ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
239
+ :polymorphic => nil,
240
+ :class_name => "Person",
241
+ :foreign_key => "thing_id",
242
+ :foreign_type => "thing_type",
243
+ :conditions => "first condition AND ::ts_join_alias::.`thing_type` = 'Person'"
244
+ }
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,356 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Attribute do
4
+ describe '#initialize' do
5
+ it 'raises if no columns are provided so that configuration errors are easier to track down' do
6
+ lambda {
7
+ ThinkingSphinx::Attribute.new([])
8
+ }.should raise_error(RuntimeError)
9
+ end
10
+
11
+ 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
12
+ lambda {
13
+ ThinkingSphinx::Attribute.new([1234])
14
+ }.should raise_error(RuntimeError)
15
+ end
16
+ end
17
+
18
+ describe "to_select_sql method with MySQL" do
19
+ before :each do
20
+ @index = Person.indexes.first
21
+ @index.link!
22
+ end
23
+
24
+ it "should concat with spaces if there's more than one non-integer column" do
25
+ @index.attributes[0].to_select_sql.should match(/CONCAT_WS\(' ', /)
26
+ end
27
+
28
+ it "should concat with spaces if there's more than one association for a non-integer column" do
29
+ @index.attributes[1].to_select_sql.should match(/CONCAT_WS\(' ', /)
30
+ end
31
+
32
+ it "should concat with commas if there's multiple integer columns" do
33
+ @index.attributes[2].to_select_sql.should match(/CONCAT_WS\(',', /)
34
+ end
35
+
36
+ it "should concat with commas if there's more than one association for an integer column" do
37
+ @index.attributes[3].to_select_sql.should match(/CONCAT_WS\(',', /)
38
+ end
39
+
40
+ it "should group with spaces if there's string columns from a has_many or has_and_belongs_to_many association" do
41
+ @index.attributes[4].to_select_sql.should match(/GROUP_CONCAT\(.+ SEPARATOR ' '\)/)
42
+ end
43
+
44
+ it "should group with commas if there's integer columns from a has_many or has_and_belongs_to_many association" do
45
+ @index.attributes[5].to_select_sql.should match(/GROUP_CONCAT\(.+ SEPARATOR ','\)/)
46
+ end
47
+
48
+ it "should convert datetime values to timestamps" do
49
+ @index.attributes[6].to_select_sql.should match(/UNIX_TIMESTAMP/)
50
+ end
51
+ end
52
+
53
+ describe "to_select_sql method with PostgreSQL" do
54
+ before :each do
55
+ @index = Person.indexes.first
56
+ Person.connection.class.stub_method(
57
+ :name => "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
58
+ )
59
+ @index.link!
60
+ end
61
+
62
+ it "should concat with spaces if there's more than one non-integer column" do
63
+ @index.attributes[0].to_select_sql.should match(/|| ' ' ||/)
64
+ end
65
+
66
+ it "should concat with spaces if there's more than one association for a non-integer column" do
67
+ @index.attributes[1].to_select_sql.should match(/|| ' ' ||/)
68
+ end
69
+
70
+ it "should concat with commas if there's multiple integer columns" do
71
+ @index.attributes[2].to_select_sql.should match(/|| ',' ||/)
72
+ end
73
+
74
+ it "should concat with commas if there's more than one association for an integer column" do
75
+ @index.attributes[3].to_select_sql.should match(/|| ',' ||/)
76
+ end
77
+
78
+ it "should group with spaces if there's string columns from a has_many or has_and_belongs_to_many association" do
79
+ @index.attributes[4].to_select_sql.should match(/array_to_string\(array_accum\(.+, ' '\)/)
80
+ end
81
+
82
+ it "should group with commas if there's integer columns from a has_many or has_and_belongs_to_many association" do
83
+ @index.attributes[5].to_select_sql.should match(/array_to_string\(array_accum\(.+, ','\)/)
84
+ end
85
+ end
86
+
87
+ describe "to_group_sql method" do
88
+ before :each do
89
+ @attribute = ThinkingSphinx::Attribute.new([Object.stub_instance(:__stack => [])])
90
+ @attribute.stub_method(:is_many? => false, :is_string? => false)
91
+
92
+ ThinkingSphinx.stub_method(:use_group_by_shortcut? => false)
93
+ end
94
+
95
+ it "should return nil if is_many?" do
96
+ @attribute.stub_method(:is_many? => true)
97
+
98
+ @attribute.to_group_sql.should be_nil
99
+ end
100
+
101
+ it "should return nil if is_string?" do
102
+ @attribute.stub_method(:is_string? => true)
103
+
104
+ @attribute.to_group_sql.should be_nil
105
+ end
106
+
107
+ it "should return nil if group_by shortcut is allowed" do
108
+ ThinkingSphinx.stub_method(:use_group_by_shortcut? => true)
109
+
110
+ @attribute.to_group_sql.should be_nil
111
+ end
112
+
113
+ it "should return an array if neither is_many? or shortcut allowed" do
114
+ @attribute.stub_method(:column_with_prefix => 'hello')
115
+ @attribute.to_group_sql.should be_a_kind_of(Array)
116
+ end
117
+
118
+ after :each do
119
+ ThinkingSphinx.unstub_method(:use_group_by_shortcut?)
120
+ end
121
+ end
122
+
123
+ describe "to_sphinx_clause method" do
124
+ before :each do
125
+ @attribute = ThinkingSphinx::Attribute.new [Object.stub_instance(:__stack => [])]
126
+ @attribute.stub_method(:unique_name => "unique name")
127
+ end
128
+
129
+ it "should use sql_attr_multi syntax for MVA attributes" do
130
+ @attribute.stub_method(:type => :multi)
131
+ @attribute.to_sphinx_clause.should match(/^sql_attr_multi\s+= uint unique name from field$/)
132
+ end
133
+
134
+ it "should use sql_attr_timestamp syntax for datetime values" do
135
+ @attribute.stub_method(:type => :datetime)
136
+ @attribute.to_sphinx_clause.should match(/^sql_attr_timestamp\s+= unique name$/)
137
+ end
138
+
139
+ it "should use sql_attr_str2ordinal for string values" do
140
+ @attribute.stub_method(:type => :string)
141
+ @attribute.to_sphinx_clause.should match(/^sql_attr_str2ordinal\s+= unique name$/)
142
+ end
143
+
144
+ it "should use sql_attr_float for float values" do
145
+ @attribute.stub_method(:type => :float)
146
+ @attribute.to_sphinx_clause.should match(/^sql_attr_float\s+= unique name$/)
147
+ end
148
+
149
+ it "should use sql_attr_bool for boolean values" do
150
+ @attribute.stub_method(:type => :boolean)
151
+ @attribute.to_sphinx_clause.should match(/^sql_attr_bool\s+= unique name$/)
152
+ end
153
+
154
+ it "should use sql_attr_uint for integer values" do
155
+ @attribute.stub_method(:type => :integer)
156
+ @attribute.to_sphinx_clause.should match(/^sql_attr_uint\s+= unique name$/)
157
+ end
158
+
159
+ it "should assume integer for any other types" do
160
+ @attribute.stub_method(:type => :unknown)
161
+ @attribute.to_sphinx_clause.should match(/^sql_attr_uint\s+= unique name$/)
162
+ end
163
+
164
+ end
165
+
166
+ describe "unique_name method" do
167
+ before :each do
168
+ @attribute = ThinkingSphinx::Attribute.new [
169
+ Object.stub_instance(:__stack => [], :__name => "col_name")
170
+ ]
171
+ end
172
+
173
+ it "should use the alias if there is one" do
174
+ @attribute.alias = "alias"
175
+ @attribute.unique_name.should == "alias"
176
+ end
177
+
178
+ it "should use the alias if there's multiple columns" do
179
+ @attribute.columns << Object.stub_instance(:__stack => [], :__name => "col_name")
180
+ @attribute.unique_name.should be_nil
181
+
182
+ @attribute.alias = "alias"
183
+ @attribute.unique_name.should == "alias"
184
+ end
185
+
186
+ it "should use the column name if there's no alias and just one column" do
187
+ @attribute.unique_name.should == "col_name"
188
+ end
189
+ end
190
+
191
+ describe "column_with_prefix method" do
192
+ before :each do
193
+ @attribute = ThinkingSphinx::Attribute.new [
194
+ ThinkingSphinx::Index::FauxColumn.new(:col_name)
195
+ ]
196
+ @attribute.columns.each { |col| @attribute.associations[col] = [] }
197
+ @attribute.model = Person
198
+
199
+ @first_join = Object.stub_instance(:aliased_table_name => "tabular")
200
+ @second_join = Object.stub_instance(:aliased_table_name => "data")
201
+
202
+ @first_assoc = ThinkingSphinx::Association.stub_instance(:join => @first_join)
203
+ @second_assoc = ThinkingSphinx::Association.stub_instance(:join => @second_join)
204
+ end
205
+
206
+ it "should return the column name if the column is a string" do
207
+ @attribute.columns = [ThinkingSphinx::Index::FauxColumn.new("string")]
208
+ @attribute.send(:column_with_prefix, @attribute.columns.first).should == "string"
209
+ end
210
+
211
+ it "should return the column with model's table prefix if there's no associations for the column" do
212
+ @attribute.send(:column_with_prefix, @attribute.columns.first).should == "`people`.`col_name`"
213
+ end
214
+
215
+ it "should return the column with its join table prefix if an association exists" do
216
+ column = @attribute.columns.first
217
+ @attribute.associations[column] = [@first_assoc]
218
+ @attribute.send(:column_with_prefix, column).should == "`tabular`.`col_name`"
219
+ end
220
+
221
+ it "should return multiple columns concatenated if more than one association exists" do
222
+ column = @attribute.columns.first
223
+ @attribute.associations[column] = [@first_assoc, @second_assoc]
224
+ @attribute.send(:column_with_prefix, column).should == "`tabular`.`col_name`, `data`.`col_name`"
225
+ end
226
+ end
227
+
228
+ describe "is_many? method" do
229
+ before :each do
230
+ @assoc_a = Object.stub_instance(:is_many? => true)
231
+ @assoc_b = Object.stub_instance(:is_many? => true)
232
+ @assoc_c = Object.stub_instance(:is_many? => true)
233
+
234
+ @attribute = ThinkingSphinx::Attribute.new(
235
+ [ThinkingSphinx::Index::FauxColumn.new(:col_name)]
236
+ )
237
+ @attribute.associations = {
238
+ :a => @assoc_a, :b => @assoc_b, :c => @assoc_c
239
+ }
240
+ end
241
+
242
+ it "should return true if all associations return true to is_many?" do
243
+ @attribute.send(:is_many?).should be_true
244
+ end
245
+
246
+ it "should return true if one association returns true to is_many?" do
247
+ @assoc_b.stub_method(:is_many? => false)
248
+ @assoc_c.stub_method(:is_many? => false)
249
+
250
+ @attribute.send(:is_many?).should be_true
251
+ end
252
+
253
+ it "should return false if all associations return false to is_many?" do
254
+ @assoc_a.stub_method(:is_many? => false)
255
+ @assoc_b.stub_method(:is_many? => false)
256
+ @assoc_c.stub_method(:is_many? => false)
257
+
258
+ @attribute.send(:is_many?).should be_false
259
+ end
260
+ end
261
+
262
+ describe "is_string? method" do
263
+ before :each do
264
+ @col_a = ThinkingSphinx::Index::FauxColumn.new("a")
265
+ @col_b = ThinkingSphinx::Index::FauxColumn.new("b")
266
+ @col_c = ThinkingSphinx::Index::FauxColumn.new("c")
267
+
268
+ @attribute = ThinkingSphinx::Attribute.new(
269
+ [@col_a, @col_b, @col_c]
270
+ )
271
+ end
272
+
273
+ it "should return true if all columns return true to is_string?" do
274
+ @attribute.send(:is_string?).should be_true
275
+ end
276
+
277
+ it "should return false if one column returns true to is_string?" do
278
+ @col_a.send(:instance_variable_set, :@name, :a)
279
+ @attribute.send(:is_string?).should be_false
280
+ end
281
+
282
+ it "should return false if all columns return false to is_string?" do
283
+ @col_a.send(:instance_variable_set, :@name, :a)
284
+ @col_b.send(:instance_variable_set, :@name, :b)
285
+ @col_c.send(:instance_variable_set, :@name, :c)
286
+ @attribute.send(:is_string?).should be_false
287
+ end
288
+ end
289
+
290
+ describe "type method" do
291
+ before :each do
292
+ @column = ThinkingSphinx::Index::FauxColumn.new(:col_name)
293
+ @attribute = ThinkingSphinx::Attribute.new([@column])
294
+ @attribute.model = Person
295
+ @attribute.stub_method(:is_many? => false)
296
+ end
297
+
298
+ it "should return :multi if is_many? is true" do
299
+ @attribute.stub_method(:is_many? => true)
300
+ @attribute.send(:type).should == :multi
301
+ end
302
+
303
+ it "should return :string if there's more than one association" do
304
+ @attribute.associations = {:a => :assoc, :b => :assoc}
305
+ @attribute.send(:type).should == :string
306
+ end
307
+
308
+ it "should return the column type from the database if not :multi or more than one association" do
309
+ @column.send(:instance_variable_set, :@name, "birthday")
310
+ @attribute.send(:type).should == :datetime
311
+
312
+ @attribute.send(:instance_variable_set, :@type, nil)
313
+ @column.send(:instance_variable_set, :@name, "first_name")
314
+ @attribute.send(:type).should == :string
315
+
316
+ @attribute.send(:instance_variable_set, :@type, nil)
317
+ @column.send(:instance_variable_set, :@name, "id")
318
+ @attribute.send(:type).should == :integer
319
+ end
320
+ end
321
+
322
+ describe "all_ints? method" do
323
+ it "should return true if all columns are integers" do
324
+ attribute = ThinkingSphinx::Attribute.new(
325
+ [ ThinkingSphinx::Index::FauxColumn.new(:id),
326
+ ThinkingSphinx::Index::FauxColumn.new(:team_id) ]
327
+ )
328
+ attribute.model = Person
329
+ attribute.columns.each { |col| attribute.associations[col] = [] }
330
+
331
+ attribute.send(:all_ints?).should be_true
332
+ end
333
+
334
+ it "should return false if only some columns are integers" do
335
+ attribute = ThinkingSphinx::Attribute.new(
336
+ [ ThinkingSphinx::Index::FauxColumn.new(:id),
337
+ ThinkingSphinx::Index::FauxColumn.new(:first_name) ]
338
+ )
339
+ attribute.model = Person
340
+ attribute.columns.each { |col| attribute.associations[col] = [] }
341
+
342
+ attribute.send(:all_ints?).should be_false
343
+ end
344
+
345
+ it "should return false if no columns are integers" do
346
+ attribute = ThinkingSphinx::Attribute.new(
347
+ [ ThinkingSphinx::Index::FauxColumn.new(:first_name),
348
+ ThinkingSphinx::Index::FauxColumn.new(:last_name) ]
349
+ )
350
+ attribute.model = Person
351
+ attribute.columns.each { |col| attribute.associations[col] = [] }
352
+
353
+ attribute.send(:all_ints?).should be_false
354
+ end
355
+ end
356
+ end