jaikoo-thinking-sphinx 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/LICENCE +20 -0
  2. data/README +76 -0
  3. data/lib/thinking_sphinx.rb +112 -0
  4. data/lib/thinking_sphinx/active_record.rb +153 -0
  5. data/lib/thinking_sphinx/active_record/delta.rb +80 -0
  6. data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
  7. data/lib/thinking_sphinx/active_record/search.rb +50 -0
  8. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +27 -0
  9. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +9 -0
  10. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +84 -0
  11. data/lib/thinking_sphinx/association.rb +144 -0
  12. data/lib/thinking_sphinx/attribute.rb +284 -0
  13. data/lib/thinking_sphinx/collection.rb +105 -0
  14. data/lib/thinking_sphinx/configuration.rb +314 -0
  15. data/lib/thinking_sphinx/field.rb +206 -0
  16. data/lib/thinking_sphinx/index.rb +432 -0
  17. data/lib/thinking_sphinx/index/builder.rb +220 -0
  18. data/lib/thinking_sphinx/index/faux_column.rb +110 -0
  19. data/lib/thinking_sphinx/rails_additions.rb +68 -0
  20. data/lib/thinking_sphinx/search.rb +436 -0
  21. data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +132 -0
  22. data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +53 -0
  23. data/spec/unit/thinking_sphinx/active_record/search_spec.rb +107 -0
  24. data/spec/unit/thinking_sphinx/active_record_spec.rb +295 -0
  25. data/spec/unit/thinking_sphinx/association_spec.rb +247 -0
  26. data/spec/unit/thinking_sphinx/attribute_spec.rb +360 -0
  27. data/spec/unit/thinking_sphinx/collection_spec.rb +71 -0
  28. data/spec/unit/thinking_sphinx/configuration_spec.rb +512 -0
  29. data/spec/unit/thinking_sphinx/field_spec.rb +224 -0
  30. data/spec/unit/thinking_sphinx/index/builder_spec.rb +34 -0
  31. data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +68 -0
  32. data/spec/unit/thinking_sphinx/index_spec.rb +317 -0
  33. data/spec/unit/thinking_sphinx/search_spec.rb +203 -0
  34. data/spec/unit/thinking_sphinx_spec.rb +129 -0
  35. data/tasks/thinking_sphinx_tasks.rake +1 -0
  36. data/tasks/thinking_sphinx_tasks.rb +100 -0
  37. metadata +103 -0
@@ -0,0 +1,224 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Field 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::Field.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::Field.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.sphinx_indexes.first
21
+ @index.link!
22
+ end
23
+
24
+ it "should concat with spaces if there are multiple columns" do
25
+ @index.fields.first.to_select_sql.should match(/CONCAT_WS\(' ', /)
26
+ end
27
+
28
+ it "should concat with spaces if a column has more than one association" do
29
+ @index.fields[1].to_select_sql.should match(/CONCAT_WS\(' ', /)
30
+ end
31
+
32
+ it "should group if any association for any column is a has_many or has_and_belongs_to_many" do
33
+ @index.fields[2].to_select_sql.should match(/GROUP_CONCAT/)
34
+ end
35
+ end
36
+
37
+ describe "to_select_sql method with PostgreSQL" do
38
+ before :each do
39
+ @index = Person.sphinx_indexes.first
40
+ Person.connection.class.stub_method(
41
+ :name => "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
42
+ )
43
+ @index.link!
44
+ end
45
+
46
+ it "should concat with spaces if there are multiple columns" do
47
+ @index.fields.first.to_select_sql.should match(/|| ' ' ||/)
48
+ end
49
+
50
+ it "should concat with spaces if a column has more than one association" do
51
+ @index.fields[1].to_select_sql.should match(/|| ' ' ||/)
52
+ end
53
+
54
+ it "should group if any association for any column is a has_many or has_and_belongs_to_many" do
55
+ @index.fields[2].to_select_sql.should match(/array_to_string\(array_accum\(/)
56
+ end
57
+ end
58
+
59
+ describe "to_group_sql method" do
60
+ before :each do
61
+ @field = ThinkingSphinx::Field.new([Object.stub_instance(:__stack => [])])
62
+ @field.stub_methods(:is_many? => false)
63
+
64
+ ThinkingSphinx.stub_method(:use_group_by_shortcut? => false)
65
+ end
66
+
67
+ it "should return nil if is_many?" do
68
+ @field.stub_method(:is_many? => true)
69
+
70
+ @field.to_group_sql.should be_nil
71
+ end
72
+
73
+ it "should return nil if group_by shortcut is allowed" do
74
+ ThinkingSphinx.stub_method(:use_group_by_shortcut? => true)
75
+
76
+ @field.to_group_sql.should be_nil
77
+ end
78
+
79
+ it "should return an array if neither is_many? or shortcut allowed" do
80
+ @field.stub_method(:column_with_prefix => 'hello')
81
+ @field.to_group_sql.should be_a_kind_of(Array)
82
+ end
83
+ end
84
+
85
+ describe "unique_name method" do
86
+ before :each do
87
+ @field = ThinkingSphinx::Field.new [
88
+ Object.stub_instance(:__stack => [], :__name => "col_name")
89
+ ]
90
+ end
91
+
92
+ it "should use the alias if there is one" do
93
+ @field.alias = "alias"
94
+ @field.unique_name.should == "alias"
95
+ end
96
+
97
+ it "should use the alias if there's multiple columns" do
98
+ @field.columns << Object.stub_instance(:__stack => [], :__name => "col_name")
99
+ @field.unique_name.should be_nil
100
+
101
+ @field.alias = "alias"
102
+ @field.unique_name.should == "alias"
103
+ end
104
+
105
+ it "should use the column name if there's no alias and just one column" do
106
+ @field.unique_name.should == "col_name"
107
+ end
108
+ end
109
+
110
+ describe "prefixes method" do
111
+ it "should default to false" do
112
+ @field = ThinkingSphinx::Field.new([Object.stub_instance(:__stack => [])])
113
+ @field.prefixes.should be_false
114
+ end
115
+
116
+ it "should be true if the corresponding option is set" do
117
+ @field = ThinkingSphinx::Field.new(
118
+ [Object.stub_instance(:__stack => [])], :prefixes => true
119
+ )
120
+ @field.prefixes.should be_true
121
+ end
122
+ end
123
+
124
+ describe "infixes method" do
125
+ it "should default to false" do
126
+ @field = ThinkingSphinx::Field.new([Object.stub_instance(:__stack => [])])
127
+ @field.infixes.should be_false
128
+ end
129
+
130
+ it "should be true if the corresponding option is set" do
131
+ @field = ThinkingSphinx::Field.new(
132
+ [Object.stub_instance(:__stack => [])], :infixes => true
133
+ )
134
+ @field.infixes.should be_true
135
+ end
136
+ end
137
+
138
+ describe "quote_column_name method" do
139
+ it "should delegate the call to the model's connection" do
140
+ @field = ThinkingSphinx::Field.new [
141
+ ThinkingSphinx::Index::FauxColumn.new(:col_name)
142
+ ]
143
+ @field.model = Person
144
+ Person.connection.stub_method(:quote_column_name => "quoted!")
145
+
146
+ @field.send(:quote_column, "blah").should == "quoted!"
147
+ end
148
+ end
149
+
150
+ describe "column_with_prefix method" do
151
+ before :each do
152
+ @field = ThinkingSphinx::Field.new [
153
+ ThinkingSphinx::Index::FauxColumn.new(:col_name)
154
+ ]
155
+ @field.columns.each { |col| @field.associations[col] = [] }
156
+ @field.model = Person
157
+
158
+ @first_join = Object.stub_instance(:aliased_table_name => "tabular")
159
+ @second_join = Object.stub_instance(:aliased_table_name => "data")
160
+
161
+ @first_assoc = ThinkingSphinx::Association.stub_instance(
162
+ :join => @first_join, :has_column? => true
163
+ )
164
+ @second_assoc = ThinkingSphinx::Association.stub_instance(
165
+ :join => @second_join, :has_column? => true
166
+ )
167
+ end
168
+
169
+ it "should return the column name if the column is a string" do
170
+ @field.columns = [ThinkingSphinx::Index::FauxColumn.new("string")]
171
+ @field.send(:column_with_prefix, @field.columns.first).should == "string"
172
+ end
173
+
174
+ it "should return the column with model's table prefix if there's no associations for the column" do
175
+ @field.send(:column_with_prefix, @field.columns.first).should == "`people`.`col_name`"
176
+ end
177
+
178
+ it "should return the column with its join table prefix if an association exists" do
179
+ column = @field.columns.first
180
+ @field.associations[column] = [@first_assoc]
181
+ @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`"
182
+ end
183
+
184
+ it "should return multiple columns concatenated if more than one association exists" do
185
+ column = @field.columns.first
186
+ @field.associations[column] = [@first_assoc, @second_assoc]
187
+ @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`, `data`.`col_name`"
188
+ end
189
+ end
190
+
191
+ describe "is_many? method" do
192
+ before :each do
193
+ @assoc_a = Object.stub_instance(:is_many? => true)
194
+ @assoc_b = Object.stub_instance(:is_many? => true)
195
+ @assoc_c = Object.stub_instance(:is_many? => true)
196
+
197
+ @field = ThinkingSphinx::Field.new(
198
+ [ThinkingSphinx::Index::FauxColumn.new(:col_name)]
199
+ )
200
+ @field.associations = {
201
+ :a => @assoc_a, :b => @assoc_b, :c => @assoc_c
202
+ }
203
+ end
204
+
205
+ it "should return true if all associations return true to is_many?" do
206
+ @field.send(:is_many?).should be_true
207
+ end
208
+
209
+ it "should return true if one association returns true to is_many?" do
210
+ @assoc_b.stub_method(:is_many? => false)
211
+ @assoc_c.stub_method(:is_many? => false)
212
+
213
+ @field.send(:is_many?).should be_true
214
+ end
215
+
216
+ it "should return false if all associations return false to is_many?" do
217
+ @assoc_a.stub_method(:is_many? => false)
218
+ @assoc_b.stub_method(:is_many? => false)
219
+ @assoc_c.stub_method(:is_many? => false)
220
+
221
+ @field.send(:is_many?).should be_false
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Index::Builder do
4
+ before :each do
5
+ @builder = Class.new(ThinkingSphinx::Index::Builder)
6
+ @builder.setup
7
+ end
8
+
9
+ describe "setup method" do
10
+ it "should set up the information arrays and properties hash" do
11
+ @builder.fields.should == []
12
+ @builder.attributes.should == []
13
+ @builder.conditions.should == []
14
+ @builder.groupings.should == []
15
+ @builder.properties.should == {}
16
+ end
17
+ end
18
+
19
+ describe "indexes method" do
20
+
21
+ end
22
+
23
+ describe "has method" do
24
+
25
+ end
26
+
27
+ describe "where method" do
28
+
29
+ end
30
+
31
+ describe "set_property method" do
32
+
33
+ end
34
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Index::FauxColumn do
4
+ it "should use the last argument as the name, with preceeding ones going into the stack" do
5
+ #
6
+ end
7
+
8
+ it "should access the name through __name" do
9
+ #
10
+ end
11
+
12
+ it "should access the stack through __stack" do
13
+ #
14
+ end
15
+
16
+ it "should return true from is_string? if the name is a string and the stack is empty" do
17
+ #
18
+ end
19
+
20
+ describe "coerce class method" do
21
+ before :each do
22
+ @column = ThinkingSphinx::Index::FauxColumn.stub_instance
23
+ ThinkingSphinx::Index::FauxColumn.stub_method(:new => @column)
24
+ end
25
+
26
+ it "should return a single faux column if passed a string" do
27
+ ThinkingSphinx::Index::FauxColumn.coerce("string").should == @column
28
+ end
29
+
30
+ it "should return a single faux column if passed a symbol" do
31
+ ThinkingSphinx::Index::FauxColumn.coerce(:string).should == @column
32
+ end
33
+
34
+ it "should return an array of faux columns if passed an array of strings" do
35
+ ThinkingSphinx::Index::FauxColumn.coerce(["one", "two"]).should == [
36
+ @column, @column
37
+ ]
38
+ end
39
+
40
+ it "should return an array of faux columns if passed an array of symbols" do
41
+ ThinkingSphinx::Index::FauxColumn.coerce([:one, :two]).should == [
42
+ @column, @column
43
+ ]
44
+ end
45
+ end
46
+
47
+ describe "method_missing calls with no arguments" do
48
+ it "should push any further method calls into name, and the old name goes into the stack" do
49
+ #
50
+ end
51
+
52
+ it "should return itself" do
53
+ #
54
+ end
55
+ end
56
+
57
+ describe "method_missing calls with one argument" do
58
+ it "should act as if calling method missing with method, then argument" do
59
+ #
60
+ end
61
+ end
62
+
63
+ describe "method_missing calls with more than one argument" do
64
+ it "should return a collection of Faux Columns sharing the same stack, but with each argument as the name" do
65
+ #
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,317 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Index do
4
+ describe "to_config method" do
5
+ before :each do
6
+ @index = ThinkingSphinx::Index.new(Person)
7
+
8
+ @index.stub_methods(
9
+ :attributes => [
10
+ ThinkingSphinx::Attribute.stub_instance(:to_sphinx_clause => "attr a"),
11
+ ThinkingSphinx::Attribute.stub_instance(:to_sphinx_clause => "attr b")
12
+ ],
13
+ :link! => true,
14
+ :adapter => :mysql,
15
+ :to_sql_query_pre => "sql_query_pre",
16
+ :to_sql => "SQL",
17
+ :to_sql_query_range => "sql_query_range",
18
+ :to_sql_query_info => "sql_query_info",
19
+ :delta? => false
20
+ )
21
+
22
+ @database = {
23
+ :host => "localhost",
24
+ :username => "username",
25
+ :password => "blank",
26
+ :database => "db"
27
+ }
28
+ end
29
+
30
+ it "should call link!" do
31
+ @index.to_config(Person, 0, @database, 0)
32
+
33
+ @index.should have_received(:link!)
34
+ end
35
+
36
+ it "should raise an exception if the adapter isn't mysql or postgres" do
37
+ @index.stub_method(:adapter => :sqlite)
38
+
39
+ lambda { @index.to_config(Person, 0, @database, 0) }.should raise_error
40
+ end
41
+
42
+ it "should set the core source name to {model}_{index}_core" do
43
+ @index.to_config(Person, 0, @database, 0).should match(
44
+ /source person_0_core/
45
+ )
46
+ end
47
+
48
+ it "should include the database config supplied" do
49
+ conf = @index.to_config(Person, 0, @database, 0)
50
+ conf.should match(/type\s+= mysql/)
51
+ conf.should match(/sql_host\s+= localhost/)
52
+ conf.should match(/sql_user\s+= username/)
53
+ conf.should match(/sql_pass\s+= blank/)
54
+ conf.should match(/sql_db\s+= db/)
55
+ end
56
+
57
+ it "should use 'user' if 'username' doesn't exist in database configuration" do
58
+ conf = @index.to_config(Person, 0,
59
+ @database.except(:username).merge(:user => "username"),
60
+ 0
61
+ )
62
+ conf.should match(/sql_user\s+= username/)
63
+ end
64
+
65
+ it "should include the database socket if set" do
66
+ conf = @index.to_config(Person, 0, @database.merge(:socket => "dbsocket"), 0)
67
+ conf.should match(/sql_sock\s+= dbsocket/)
68
+ end
69
+
70
+ it "should not include the database socket if not set" do
71
+ conf = @index.to_config(Person, 0, @database, 0)
72
+ conf.should_not match(/sql_sock/)
73
+ end
74
+
75
+ it "should include the database port if set" do
76
+ conf = @index.to_config(Person, 0, @database.merge(:port => "dbport"), 0)
77
+ conf.should match(/sql_port\s+= dbport/)
78
+ end
79
+
80
+ it "should not include the database socket if not set" do
81
+ conf = @index.to_config(Person, 0, @database, 0)
82
+ conf.should_not match(/sql_port/)
83
+ end
84
+
85
+ it "should have a pre query 'SET NAMES utf8' if using mysql and utf8 charset" do
86
+ @index.options[:charset_type] = "utf-8"
87
+ @index.to_config(Person, 0, @database, 0).should match(
88
+ /sql_query_pre\s+= SET NAMES utf8/
89
+ )
90
+
91
+ @index.stub_method(:delta? => true)
92
+ @index.to_config(Person, 0, @database, 0).should match(
93
+ /source person_0_delta.+sql_query_pre\s+= SET NAMES utf8/m
94
+ )
95
+
96
+ @index.options[:charset_type] = "non-utf-8"
97
+ @index.stub_method(:delta? => false)
98
+ @index.to_config(Person, 0, @database, 0).should_not match(
99
+ /SET NAMES utf8/
100
+ )
101
+
102
+ @index.options[:charset_type] = "utf-8"
103
+ @index.stub_method(:adapter => :postgres)
104
+ @index.to_config(Person, 0, @database, 0).should_not match(
105
+ /SET NAMES utf8/
106
+ )
107
+ end
108
+
109
+ it "should use the pre query from the index" do
110
+ @index.to_config(Person, 0, @database, 0).should match(
111
+ /sql_query_pre\s+= sql_query_pre/
112
+ )
113
+ end
114
+
115
+ it "should not set group_concat_max_len if not specified" do
116
+ @index.to_config(Person, 0, @database, 0).should_not match(
117
+ /group_concat_max_len/
118
+ )
119
+ end
120
+
121
+ it "should set group_concat_max_len if specified" do
122
+ @index.options.merge! :group_concat_max_len => 2056
123
+ @index.to_config(Person, 0, @database, 0).should match(
124
+ /sql_query_pre\s+= SET SESSION group_concat_max_len = 2056/
125
+ )
126
+
127
+ @index.stub_method(:delta? => true)
128
+ @index.to_config(Person, 0, @database, 0).should match(
129
+ /source person_0_delta.+sql_query_pre\s+= SET SESSION group_concat_max_len = 2056/m
130
+ )
131
+ end
132
+
133
+ it "should use the main query from the index" do
134
+ @index.to_config(Person, 0, @database, 0).should match(
135
+ /sql_query\s+= SQL/
136
+ )
137
+ end
138
+
139
+ it "should use the range query from the index" do
140
+ @index.to_config(Person, 0, @database, 0).should match(
141
+ /sql_query_range\s+= sql_query_range/
142
+ )
143
+ end
144
+
145
+ it "should use the info query from the index" do
146
+ @index.to_config(Person, 0, @database, 0).should match(
147
+ /sql_query_info\s+= sql_query_info/
148
+ )
149
+ end
150
+
151
+ it "should include the attribute sources" do
152
+ @index.to_config(Person, 0, @database, 0).should match(
153
+ /attr a\n\s+attr b/
154
+ )
155
+ end
156
+
157
+ it "should add a delta index with name {model}_{index}_delta if requested" do
158
+ @index.stub_method(:delta? => true)
159
+
160
+ @index.to_config(Person, 0, @database, 0).should match(
161
+ /source person_0_delta/
162
+ )
163
+ end
164
+
165
+ it "should not add a delta index unless requested" do
166
+ @index.to_config(Person, 0, @database, 0).should_not match(
167
+ /source person_0_delta/
168
+ )
169
+ end
170
+
171
+ it "should have the delta index inherit from the core index" do
172
+ @index.stub_method(:delta? => true)
173
+
174
+ @index.to_config(Person, 0, @database, 0).should match(
175
+ /source person_0_delta : person_0_core/
176
+ )
177
+ end
178
+
179
+ it "should redefine the main query for the delta index" do
180
+ @index.stub_method(:delta? => true)
181
+
182
+ @index.to_config(Person, 0, @database, 0).should match(
183
+ /source person_0_delta.+sql_query\s+= SQL/m
184
+ )
185
+ end
186
+
187
+ it "should redefine the range query for the delta index" do
188
+ @index.stub_method(:delta? => true)
189
+
190
+ @index.to_config(Person, 0, @database, 0).should match(
191
+ /source person_0_delta.+sql_query_range\s+= sql_query_range/m
192
+ )
193
+ end
194
+
195
+ it "should redefine the pre query for the delta index" do
196
+ @index.stub_method(:delta? => true)
197
+
198
+ @index.to_config(Person, 0, @database, 0).should match(
199
+ /source person_0_delta.+sql_query_pre\s+=\s*\n/m
200
+ )
201
+ end
202
+ end
203
+
204
+ describe "to_sql method" do
205
+ it "should include explicit groupings if requested" do
206
+ @index = ThinkingSphinx::Index.new(Person)
207
+
208
+ @index.groupings << "custom_sql"
209
+ @index.to_sql.should match(/GROUP BY.+custom_sql/)
210
+ end
211
+ end
212
+
213
+ describe "to_sql_query_range method" do
214
+ before :each do
215
+ @index = ThinkingSphinx::Index.new(Person)
216
+ end
217
+
218
+ it "should add COALESCE around MIN and MAX calls if using PostgreSQL" do
219
+ @index.stub_method(:adapter => :postgres)
220
+
221
+ @index.to_sql_query_range.should match(/COALESCE\(MIN.+COALESCE\(MAX/)
222
+ end
223
+
224
+ it "shouldn't add COALESCE if using MySQL" do
225
+ @index.to_sql_query_range.should_not match(/COALESCE/)
226
+ end
227
+ end
228
+
229
+ describe "prefix_fields method" do
230
+ before :each do
231
+ @index = ThinkingSphinx::Index.new(Person)
232
+
233
+ @field_a = ThinkingSphinx::Field.stub_instance(:prefixes => true)
234
+ @field_b = ThinkingSphinx::Field.stub_instance(:prefixes => false)
235
+ @field_c = ThinkingSphinx::Field.stub_instance(:prefixes => true)
236
+
237
+ @index.fields = [@field_a, @field_b, @field_c]
238
+ end
239
+
240
+ it "should return fields that are flagged as prefixed" do
241
+ @index.prefix_fields.should include(@field_a)
242
+ @index.prefix_fields.should include(@field_c)
243
+ end
244
+
245
+ it "should not return fields that aren't flagged as prefixed" do
246
+ @index.prefix_fields.should_not include(@field_b)
247
+ end
248
+ end
249
+
250
+ describe "infix_fields method" do
251
+ before :each do
252
+ @index = ThinkingSphinx::Index.new(Person)
253
+
254
+ @field_a = ThinkingSphinx::Field.stub_instance(:infixes => true)
255
+ @field_b = ThinkingSphinx::Field.stub_instance(:infixes => false)
256
+ @field_c = ThinkingSphinx::Field.stub_instance(:infixes => true)
257
+
258
+ @index.fields = [@field_a, @field_b, @field_c]
259
+ end
260
+
261
+ it "should return fields that are flagged as infixed" do
262
+ @index.infix_fields.should include(@field_a)
263
+ @index.infix_fields.should include(@field_c)
264
+ end
265
+
266
+ it "should not return fields that aren't flagged as infixed" do
267
+ @index.infix_fields.should_not include(@field_b)
268
+ end
269
+ end
270
+
271
+ describe "empty? method" do
272
+ before :each do
273
+ @index = ThinkingSphinx::Index.new(Contact)
274
+ config = ThinkingSphinx::Configuration.instance
275
+
276
+ `mkdir -p #{config.searchd_file_path}`
277
+ @file_path = "#{config.searchd_file_path}/#{@index.name}_core.spa"
278
+ end
279
+
280
+ after :each do
281
+ FileUtils.rm(@file_path, :force => true)
282
+ end
283
+
284
+ it "should return true if the core index files are empty" do
285
+ `touch #{@file_path}`
286
+ @index.should be_empty
287
+ end
288
+
289
+ it "should return true if the core index files don't exist" do
290
+ @index.should be_empty
291
+ end
292
+
293
+ it "should return false if the core index files aren't empty" do
294
+ `echo 'a' > #{@file_path}`
295
+ @index.should_not be_empty
296
+ end
297
+
298
+ it "should check the delta files if specified" do
299
+ delta_path = @file_path.gsub(/_core.spa$/, '_delta.spa')
300
+
301
+ @index.should be_empty(:delta)
302
+ `echo 'a' > #{delta_path}`
303
+ @index.should_not be_empty(:delta)
304
+
305
+ FileUtils.rm(delta_path)
306
+ end
307
+ end
308
+
309
+ describe "initialize_from_builder method" do
310
+ it "should copy groupings across from the builder to the index" do
311
+ @index = ThinkingSphinx::Index.new(Person) do
312
+ group_by "custom_grouping"
313
+ end
314
+ @index.groupings.should include("custom_grouping")
315
+ end
316
+ end
317
+ end