DrMark-thinking-sphinx 1.1.6 → 1.1.14
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/{README → README.textile} +84 -84
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +48 -0
- data/lib/thinking_sphinx/active_record/delta.rb +10 -1
- data/lib/thinking_sphinx/active_record.rb +10 -3
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +1 -1
- data/lib/thinking_sphinx/attribute.rb +44 -134
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/collection.rb +1 -0
- data/lib/thinking_sphinx/configuration.rb +7 -3
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +1 -1
- data/lib/thinking_sphinx/deltas/default_delta.rb +3 -2
- data/lib/thinking_sphinx/deltas/delayed_delta.rb +4 -2
- data/lib/thinking_sphinx/deltas.rb +9 -6
- data/lib/thinking_sphinx/deploy/capistrano.rb +82 -0
- data/lib/thinking_sphinx/facet.rb +68 -18
- data/lib/thinking_sphinx/facet_collection.rb +16 -17
- data/lib/thinking_sphinx/field.rb +7 -97
- data/lib/thinking_sphinx/index/builder.rb +255 -232
- data/lib/thinking_sphinx/index.rb +37 -349
- data/lib/thinking_sphinx/property.rb +160 -0
- data/lib/thinking_sphinx/search/facets.rb +98 -0
- data/lib/thinking_sphinx/search.rb +4 -73
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +124 -0
- data/lib/thinking_sphinx/source.rb +150 -0
- data/lib/thinking_sphinx/tasks.rb +1 -1
- data/lib/thinking_sphinx.rb +3 -1
- data/spec/unit/thinking_sphinx/active_record_spec.rb +14 -12
- data/spec/unit/thinking_sphinx/attribute_spec.rb +16 -11
- data/spec/unit/thinking_sphinx/facet_collection_spec.rb +64 -0
- data/spec/unit/thinking_sphinx/facet_spec.rb +278 -0
- data/spec/unit/thinking_sphinx/field_spec.rb +18 -9
- data/spec/unit/thinking_sphinx/index/builder_spec.rb +347 -1
- data/spec/unit/thinking_sphinx/index_spec.rb +22 -27
- data/spec/unit/thinking_sphinx/rails_additions_spec.rb +183 -0
- data/spec/unit/thinking_sphinx/search_spec.rb +71 -0
- data/spec/unit/thinking_sphinx/source_spec.rb +156 -0
- data/tasks/distribution.rb +1 -1
- data/tasks/testing.rb +7 -15
- metadata +19 -3
@@ -0,0 +1,278 @@
|
|
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
|
+
ThinkingSphinx::Attribute.stub_instance(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(: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_method(:type => :anything)
|
274
|
+
|
275
|
+
ThinkingSphinx::Facet.new(attribute).type.should == :anything
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
@@ -1,23 +1,28 @@
|
|
1
1
|
require 'spec/spec_helper'
|
2
2
|
|
3
3
|
describe ThinkingSphinx::Field do
|
4
|
+
before :each do
|
5
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
6
|
+
@source = ThinkingSphinx::Source.new(@index)
|
7
|
+
end
|
8
|
+
|
4
9
|
describe '#initialize' do
|
5
10
|
it 'raises if no columns are provided so that configuration errors are easier to track down' do
|
6
11
|
lambda {
|
7
|
-
ThinkingSphinx::Field.new([])
|
12
|
+
ThinkingSphinx::Field.new(@source, [])
|
8
13
|
}.should raise_error(RuntimeError)
|
9
14
|
end
|
10
15
|
|
11
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
|
12
17
|
lambda {
|
13
|
-
ThinkingSphinx::Field.new([1234])
|
18
|
+
ThinkingSphinx::Field.new(@source, [1234])
|
14
19
|
}.should raise_error(RuntimeError)
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
18
23
|
describe "unique_name method" do
|
19
24
|
before :each do
|
20
|
-
@field = ThinkingSphinx::Field.new [
|
25
|
+
@field = ThinkingSphinx::Field.new @source, [
|
21
26
|
Object.stub_instance(:__stack => [], :__name => "col_name")
|
22
27
|
]
|
23
28
|
end
|
@@ -42,13 +47,15 @@ describe ThinkingSphinx::Field do
|
|
42
47
|
|
43
48
|
describe "prefixes method" do
|
44
49
|
it "should default to false" do
|
45
|
-
@field = ThinkingSphinx::Field.new(
|
50
|
+
@field = ThinkingSphinx::Field.new(
|
51
|
+
@source, [Object.stub_instance(:__stack => [])]
|
52
|
+
)
|
46
53
|
@field.prefixes.should be_false
|
47
54
|
end
|
48
55
|
|
49
56
|
it "should be true if the corresponding option is set" do
|
50
57
|
@field = ThinkingSphinx::Field.new(
|
51
|
-
[Object.stub_instance(:__stack => [])], :prefixes => true
|
58
|
+
@source, [Object.stub_instance(:__stack => [])], :prefixes => true
|
52
59
|
)
|
53
60
|
@field.prefixes.should be_true
|
54
61
|
end
|
@@ -56,13 +63,15 @@ describe ThinkingSphinx::Field do
|
|
56
63
|
|
57
64
|
describe "infixes method" do
|
58
65
|
it "should default to false" do
|
59
|
-
@field = ThinkingSphinx::Field.new(
|
66
|
+
@field = ThinkingSphinx::Field.new(
|
67
|
+
@source, [Object.stub_instance(:__stack => [])]
|
68
|
+
)
|
60
69
|
@field.infixes.should be_false
|
61
70
|
end
|
62
71
|
|
63
72
|
it "should be true if the corresponding option is set" do
|
64
73
|
@field = ThinkingSphinx::Field.new(
|
65
|
-
[Object.stub_instance(:__stack => [])], :infixes => true
|
74
|
+
@source, [Object.stub_instance(:__stack => [])], :infixes => true
|
66
75
|
)
|
67
76
|
@field.infixes.should be_true
|
68
77
|
end
|
@@ -70,7 +79,7 @@ describe ThinkingSphinx::Field do
|
|
70
79
|
|
71
80
|
describe "column_with_prefix method" do
|
72
81
|
before :each do
|
73
|
-
@field = ThinkingSphinx::Field.new [
|
82
|
+
@field = ThinkingSphinx::Field.new @source, [
|
74
83
|
ThinkingSphinx::Index::FauxColumn.new(:col_name)
|
75
84
|
]
|
76
85
|
@field.columns.each { |col| @field.associations[col] = [] }
|
@@ -116,7 +125,7 @@ describe ThinkingSphinx::Field do
|
|
116
125
|
@assoc_c = Object.stub_instance(:is_many? => true)
|
117
126
|
|
118
127
|
@field = ThinkingSphinx::Field.new(
|
119
|
-
[ThinkingSphinx::Index::FauxColumn.new(:col_name)]
|
128
|
+
@source, [ThinkingSphinx::Index::FauxColumn.new(:col_name)]
|
120
129
|
)
|
121
130
|
@field.associations = {
|
122
131
|
:a => @assoc_a, :b => @assoc_b, :c => @assoc_c
|
@@ -1,5 +1,351 @@
|
|
1
1
|
require 'spec/spec_helper'
|
2
2
|
|
3
3
|
describe ThinkingSphinx::Index::Builder do
|
4
|
-
|
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 "sortable field" do
|
57
|
+
before :each do
|
58
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
59
|
+
indexes first_name, :sortable => true
|
60
|
+
end
|
61
|
+
|
62
|
+
@source = @index.sources.first
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should have one field" do
|
66
|
+
@source.fields.length.should == 1
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have one attribute alongside the four internal ones" do
|
70
|
+
@source.attributes.length.should == 5
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should set the attribute name to have the _sort suffix" do
|
74
|
+
@source.attributes.last.unique_name.should == :first_name_sort
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should set the attribute column to be the same as the field" do
|
78
|
+
@source.attributes.last.columns.length.should == 1
|
79
|
+
@source.attributes.last.columns.first.__name.should == :first_name
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "faceted field" do
|
84
|
+
before :each do
|
85
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
86
|
+
indexes first_name, :facet => true
|
87
|
+
end
|
88
|
+
|
89
|
+
@source = @index.sources.first
|
90
|
+
end
|
91
|
+
|
92
|
+
after :each do
|
93
|
+
Person.sphinx_facets.delete_at(-1)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have one field" do
|
97
|
+
@source.fields.length.should == 1
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should have one attribute alongside the four internal ones" do
|
101
|
+
@source.attributes.length.should == 5
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should set the attribute name to have the _facet suffix" do
|
105
|
+
@source.attributes.last.unique_name.should == :first_name_facet
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should set the attribute type to integer" do
|
109
|
+
@source.attributes.last.type.should == :integer
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should set the attribute column to be the same as the field" do
|
113
|
+
@source.attributes.last.columns.length.should == 1
|
114
|
+
@source.attributes.last.columns.first.__name.should == :first_name
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "faceted integer attribute" do
|
119
|
+
before :each do
|
120
|
+
@index = ThinkingSphinx::Index::Builder.generate(Alpha) do
|
121
|
+
indexes :name
|
122
|
+
has value, :facet => true
|
123
|
+
end
|
124
|
+
|
125
|
+
@source = @index.sources.first
|
126
|
+
end
|
127
|
+
|
128
|
+
after :each do
|
129
|
+
Alpha.sphinx_facets.delete_at(-1)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should have just one attribute alongside the four internal ones" do
|
133
|
+
@source.attributes.length.should == 5
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "faceted timestamp attribute" do
|
138
|
+
before :each do
|
139
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
140
|
+
indexes first_name
|
141
|
+
has birthday, :facet => true
|
142
|
+
end
|
143
|
+
|
144
|
+
@source = @index.sources.first
|
145
|
+
end
|
146
|
+
|
147
|
+
after :each do
|
148
|
+
Person.sphinx_facets.delete_at(-1)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should have just one attribute alongside the four internal ones" do
|
152
|
+
@source.attributes.length.should == 5
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "faceted boolean attribute" do
|
157
|
+
before :each do
|
158
|
+
@index = ThinkingSphinx::Index::Builder.generate(Beta) do
|
159
|
+
indexes :name
|
160
|
+
has delta, :facet => true
|
161
|
+
end
|
162
|
+
|
163
|
+
@source = @index.sources.first
|
164
|
+
end
|
165
|
+
|
166
|
+
after :each do
|
167
|
+
Beta.sphinx_facets.delete_at(-1)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should have just one attribute alongside the four internal ones" do
|
171
|
+
@source.attributes.length.should == 5
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "faceted float attribute" do
|
176
|
+
before :each do
|
177
|
+
@index = ThinkingSphinx::Index::Builder.generate(Alpha) do
|
178
|
+
indexes :name
|
179
|
+
has cost, :facet => true
|
180
|
+
end
|
181
|
+
|
182
|
+
@source = @index.sources.first
|
183
|
+
end
|
184
|
+
|
185
|
+
after :each do
|
186
|
+
Alpha.sphinx_facets.delete_at(-1)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should have just one attribute alongside the four internal ones" do
|
190
|
+
@source.attributes.length.should == 5
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "faceted string attribute" do
|
195
|
+
before :each do
|
196
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
197
|
+
indexes first_name
|
198
|
+
has last_name, :facet => true
|
199
|
+
end
|
200
|
+
|
201
|
+
@source = @index.sources.first
|
202
|
+
end
|
203
|
+
|
204
|
+
after :each do
|
205
|
+
Person.sphinx_facets.delete_at(-1)
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should have two attributes alongside the four internal ones" do
|
209
|
+
@source.attributes.length.should == 6
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should set the facet attribute name to have the _facet suffix" do
|
213
|
+
@source.attributes.last.unique_name.should == :last_name_facet
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should set the attribute type to integer" do
|
217
|
+
@source.attributes.last.type.should == :integer
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should set the attribute column to be the same as the field" do
|
221
|
+
@source.attributes.last.columns.length.should == 1
|
222
|
+
@source.attributes.last.columns.first.__name.should == :last_name
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe "no fields" do
|
227
|
+
it "should raise an exception" do
|
228
|
+
lambda {
|
229
|
+
ThinkingSphinx::Index::Builder.generate(Person) do
|
230
|
+
#
|
231
|
+
end
|
232
|
+
}.should raise_error
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "explicit source" do
|
237
|
+
before :each do
|
238
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
239
|
+
define_source do
|
240
|
+
indexes first_name, last_name
|
241
|
+
has birthday
|
242
|
+
has id, :as => :internal_id
|
243
|
+
|
244
|
+
set_property :delta => true
|
245
|
+
|
246
|
+
where "birthday <= NOW()"
|
247
|
+
group_by "first_name"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
@source = @index.sources.first
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should return an index" do
|
255
|
+
@index.should be_a_kind_of(ThinkingSphinx::Index)
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should have one source for the index" do
|
259
|
+
@index.sources.length.should == 1
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should have two fields" do
|
263
|
+
@source.fields.length.should == 2
|
264
|
+
@source.fields[0].unique_name.should == :first_name
|
265
|
+
@source.fields[1].unique_name.should == :last_name
|
266
|
+
end
|
267
|
+
|
268
|
+
it "should have two attributes alongside the four internal ones" do
|
269
|
+
@source.attributes.length.should == 6
|
270
|
+
@source.attributes[4].unique_name.should == :birthday
|
271
|
+
@source.attributes[5].unique_name.should == :internal_id
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "multiple sources" do
|
276
|
+
before :each do
|
277
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
278
|
+
define_source do
|
279
|
+
indexes first_name
|
280
|
+
has birthday
|
281
|
+
end
|
282
|
+
|
283
|
+
define_source do
|
284
|
+
indexes last_name
|
285
|
+
has :id, :as => :internal_id
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should have two sources" do
|
291
|
+
@index.sources.length.should == 2
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should have two fields" do
|
295
|
+
@index.fields.length.should == 2
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should have one field in each source" do
|
299
|
+
@index.sources.each do |source|
|
300
|
+
source.fields.length.should == 1
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should have two attributes alongside the eight internal ones" do
|
305
|
+
@index.attributes.length.should == 10
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should have one attribute in each source alongside the four internal ones" do
|
309
|
+
@index.sources.each do |source|
|
310
|
+
source.attributes.length.should == 5
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
describe "index options" do
|
316
|
+
before :each do
|
317
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
318
|
+
indexes first_name
|
319
|
+
|
320
|
+
set_property :charset_type => "utf16"
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should store the setting for the index" do
|
325
|
+
@index.local_options.length.should == 1
|
326
|
+
@index.local_options[:charset_type].should == "utf16"
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe "delta options" do
|
331
|
+
before :each do
|
332
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
333
|
+
indexes first_name
|
334
|
+
|
335
|
+
set_property :delta => true
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
it "should not keep the delta setting in source options" do
|
340
|
+
@index.sources.first.options.should be_empty
|
341
|
+
end
|
342
|
+
|
343
|
+
it "should not keep the delta setting in index options" do
|
344
|
+
@index.local_options.should be_empty
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should set the index delta object set" do
|
348
|
+
@index.delta_object.should be_a_kind_of(ThinkingSphinx::Deltas::DefaultDelta)
|
349
|
+
end
|
350
|
+
end
|
5
351
|
end
|