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.
- data/LICENCE +20 -0
- data/README +52 -0
- data/lib/riddle.rb +22 -0
- data/lib/riddle/client.rb +593 -0
- data/lib/riddle/client/filter.rb +44 -0
- data/lib/riddle/client/message.rb +65 -0
- data/lib/riddle/client/response.rb +84 -0
- data/lib/test.rb +46 -0
- data/lib/thinking_sphinx.rb +82 -0
- data/lib/thinking_sphinx/active_record.rb +138 -0
- data/lib/thinking_sphinx/active_record/delta.rb +90 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
- data/lib/thinking_sphinx/active_record/search.rb +43 -0
- data/lib/thinking_sphinx/association.rb +140 -0
- data/lib/thinking_sphinx/attribute.rb +282 -0
- data/lib/thinking_sphinx/configuration.rb +277 -0
- data/lib/thinking_sphinx/field.rb +198 -0
- data/lib/thinking_sphinx/index.rb +334 -0
- data/lib/thinking_sphinx/index/builder.rb +212 -0
- data/lib/thinking_sphinx/index/faux_column.rb +97 -0
- data/lib/thinking_sphinx/rails_additions.rb +56 -0
- data/lib/thinking_sphinx/search.rb +455 -0
- data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +185 -0
- data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +53 -0
- data/spec/unit/thinking_sphinx/active_record/search_spec.rb +81 -0
- data/spec/unit/thinking_sphinx/active_record_spec.rb +201 -0
- data/spec/unit/thinking_sphinx/association_spec.rb +247 -0
- data/spec/unit/thinking_sphinx/attribute_spec.rb +356 -0
- data/spec/unit/thinking_sphinx/configuration_spec.rb +476 -0
- data/spec/unit/thinking_sphinx/field_spec.rb +215 -0
- data/spec/unit/thinking_sphinx/index/builder_spec.rb +33 -0
- data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +41 -0
- data/spec/unit/thinking_sphinx/index_spec.rb +230 -0
- data/spec/unit/thinking_sphinx/search_spec.rb +163 -0
- data/spec/unit/thinking_sphinx_spec.rb +107 -0
- data/tasks/thinking_sphinx_tasks.rake +1 -0
- data/tasks/thinking_sphinx_tasks.rb +86 -0
- 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
|