DrMark-thinking-sphinx 1.1.15 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/README.textile +22 -0
  2. data/VERSION.yml +4 -0
  3. data/lib/thinking_sphinx/active_record/scopes.rb +39 -0
  4. data/lib/thinking_sphinx/active_record.rb +27 -7
  5. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +9 -3
  6. data/lib/thinking_sphinx/association.rb +4 -1
  7. data/lib/thinking_sphinx/attribute.rb +91 -30
  8. data/lib/thinking_sphinx/configuration.rb +51 -12
  9. data/lib/thinking_sphinx/deltas/datetime_delta.rb +2 -2
  10. data/lib/thinking_sphinx/deltas/default_delta.rb +1 -1
  11. data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +1 -1
  12. data/lib/thinking_sphinx/deltas/delayed_delta.rb +3 -0
  13. data/lib/thinking_sphinx/deploy/capistrano.rb +25 -8
  14. data/lib/thinking_sphinx/excerpter.rb +22 -0
  15. data/lib/thinking_sphinx/facet.rb +1 -1
  16. data/lib/thinking_sphinx/facet_search.rb +134 -0
  17. data/lib/thinking_sphinx/index.rb +2 -1
  18. data/lib/thinking_sphinx/rails_additions.rb +14 -0
  19. data/lib/thinking_sphinx/search.rb +599 -658
  20. data/lib/thinking_sphinx/search_methods.rb +421 -0
  21. data/lib/thinking_sphinx/source/internal_properties.rb +1 -1
  22. data/lib/thinking_sphinx/source/sql.rb +17 -13
  23. data/lib/thinking_sphinx/source.rb +6 -6
  24. data/lib/thinking_sphinx/tasks.rb +42 -8
  25. data/lib/thinking_sphinx.rb +82 -54
  26. data/rails/init.rb +14 -0
  27. data/spec/{unit → lib}/thinking_sphinx/active_record/delta_spec.rb +5 -5
  28. data/spec/{unit → lib}/thinking_sphinx/active_record/has_many_association_spec.rb +0 -0
  29. data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +96 -0
  30. data/spec/{unit → lib}/thinking_sphinx/active_record_spec.rb +51 -31
  31. data/spec/{unit → lib}/thinking_sphinx/association_spec.rb +4 -5
  32. data/spec/lib/thinking_sphinx/attribute_spec.rb +465 -0
  33. data/spec/{unit → lib}/thinking_sphinx/configuration_spec.rb +161 -29
  34. data/spec/{unit → lib}/thinking_sphinx/core/string_spec.rb +0 -0
  35. data/spec/lib/thinking_sphinx/excerpter_spec.rb +49 -0
  36. data/spec/lib/thinking_sphinx/facet_search_spec.rb +176 -0
  37. data/spec/{unit → lib}/thinking_sphinx/facet_spec.rb +24 -0
  38. data/spec/{unit → lib}/thinking_sphinx/field_spec.rb +8 -8
  39. data/spec/{unit → lib}/thinking_sphinx/index/builder_spec.rb +6 -2
  40. data/spec/{unit → lib}/thinking_sphinx/index/faux_column_spec.rb +0 -0
  41. data/spec/lib/thinking_sphinx/index_spec.rb +45 -0
  42. data/spec/{unit → lib}/thinking_sphinx/rails_additions_spec.rb +25 -5
  43. data/spec/lib/thinking_sphinx/search_methods_spec.rb +152 -0
  44. data/spec/lib/thinking_sphinx/search_spec.rb +960 -0
  45. data/spec/{unit → lib}/thinking_sphinx/source_spec.rb +63 -2
  46. data/spec/{unit → lib}/thinking_sphinx_spec.rb +32 -4
  47. data/tasks/distribution.rb +36 -35
  48. data/vendor/riddle/lib/riddle/client/message.rb +4 -3
  49. data/vendor/riddle/lib/riddle/client.rb +3 -0
  50. data/vendor/riddle/lib/riddle/configuration/section.rb +8 -2
  51. data/vendor/riddle/lib/riddle/controller.rb +17 -7
  52. data/vendor/riddle/lib/riddle.rb +1 -1
  53. metadata +79 -83
  54. data/lib/thinking_sphinx/active_record/search.rb +0 -57
  55. data/lib/thinking_sphinx/collection.rb +0 -148
  56. data/lib/thinking_sphinx/facet_collection.rb +0 -59
  57. data/lib/thinking_sphinx/search/facets.rb +0 -98
  58. data/spec/unit/thinking_sphinx/active_record/search_spec.rb +0 -107
  59. data/spec/unit/thinking_sphinx/attribute_spec.rb +0 -232
  60. data/spec/unit/thinking_sphinx/collection_spec.rb +0 -14
  61. data/spec/unit/thinking_sphinx/facet_collection_spec.rb +0 -64
  62. data/spec/unit/thinking_sphinx/index_spec.rb +0 -139
  63. data/spec/unit/thinking_sphinx/search_spec.rb +0 -130
@@ -4,32 +4,32 @@ describe ThinkingSphinx::Configuration do
4
4
  describe "environment class method" do
5
5
  before :each do
6
6
  ThinkingSphinx::Configuration.send(:class_variable_set, :@@environment, nil)
7
-
7
+
8
8
  ENV["RAILS_ENV"] = nil
9
9
  end
10
-
10
+
11
11
  it "should use the Merb environment value if set" do
12
12
  unless defined?(Merb)
13
- module Merb; end
13
+ module ::Merb; end
14
14
  end
15
-
15
+
16
16
  ThinkingSphinx::Configuration.stub_method(:defined? => true)
17
- Merb.stub_method(:environment => "merb_production")
17
+ Merb.stub!(:environment => "merb_production")
18
18
  ThinkingSphinx::Configuration.environment.should == "merb_production"
19
-
19
+
20
20
  Object.send(:remove_const, :Merb)
21
21
  end
22
-
22
+
23
23
  it "should use the Rails environment value if set" do
24
24
  ENV["RAILS_ENV"] = "rails_production"
25
25
  ThinkingSphinx::Configuration.environment.should == "rails_production"
26
26
  end
27
-
27
+
28
28
  it "should default to development" do
29
29
  ThinkingSphinx::Configuration.environment.should == "development"
30
30
  end
31
31
  end
32
-
32
+
33
33
  describe "parse_config method" do
34
34
  before :each do
35
35
  @settings = {
@@ -48,89 +48,221 @@ describe ThinkingSphinx::Configuration do
48
48
  "morphology" => "stem_ru",
49
49
  "charset_type" => "latin1",
50
50
  "charset_table" => "table",
51
- "ignore_chars" => "e"
51
+ "ignore_chars" => "e",
52
+ "searchd_binary_name" => "sphinx-searchd",
53
+ "indexer_binary_name" => "sphinx-indexer"
52
54
  }
53
55
  }
54
-
56
+
55
57
  open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
56
58
  f.write YAML.dump(@settings)
57
59
  end
58
60
  end
59
-
61
+
60
62
  it "should use the accessors to set the configuration values" do
61
63
  config = ThinkingSphinx::Configuration.instance
62
64
  config.send(:parse_config)
63
-
65
+
64
66
  %w(config_file searchd_log_file query_log_file pid_file searchd_file_path
65
- address port).each do |key|
67
+ address port searchd_binary_name indexer_binary_name).each do |key|
66
68
  config.send(key).should == @settings["development"][key]
67
69
  end
68
70
  end
69
-
71
+
70
72
  after :each do
71
73
  FileUtils.rm "#{RAILS_ROOT}/config/sphinx.yml"
72
74
  end
73
75
  end
74
-
76
+
77
+ describe "block configuration" do
78
+ it "should let the user set-up a custom app_root" do
79
+ ThinkingSphinx::Configuration.configure do |config|
80
+ config.app_root = "/here/somewhere"
81
+ end
82
+ ThinkingSphinx::Configuration.instance.app_root.should == "/here/somewhere"
83
+ end
84
+ end
85
+
75
86
  describe "initialisation" do
76
87
  it "should have a default bin_path of nothing" do
77
88
  ThinkingSphinx::Configuration.instance.bin_path.should == ""
78
89
  end
79
-
90
+
80
91
  it "should append a / to bin_path if one is supplied" do
81
92
  @settings = {
82
93
  "development" => {
83
94
  "bin_path" => "path/to/somewhere"
84
95
  }
85
96
  }
86
-
97
+
87
98
  open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
88
99
  f.write YAML.dump(@settings)
89
100
  end
90
-
101
+
91
102
  ThinkingSphinx::Configuration.instance.send(:parse_config)
92
103
  ThinkingSphinx::Configuration.instance.bin_path.should match(/\/$/)
104
+
105
+ FileUtils.rm "#{RAILS_ROOT}/config/sphinx.yml"
93
106
  end
94
107
  end
95
-
108
+
109
+ describe "index options" do
110
+ before :each do
111
+ @settings = {
112
+ "development" => {"disable_range" => true}
113
+ }
114
+
115
+ open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
116
+ f.write YAML.dump(@settings)
117
+ end
118
+
119
+ @config = ThinkingSphinx::Configuration.instance
120
+ @config.send(:parse_config)
121
+ end
122
+
123
+ it "should collect disable_range" do
124
+ @config.index_options[:disable_range].should be_true
125
+ end
126
+
127
+ after :each do
128
+ FileUtils.rm "#{RAILS_ROOT}/config/sphinx.yml"
129
+ end
130
+ end
131
+
132
+ describe "#load_models" do
133
+ before :each do
134
+ @config = ThinkingSphinx::Configuration.instance
135
+ @config.model_directories = ['']
136
+
137
+ @file_name = 'a.rb'
138
+ @model_name_lower = 'a'
139
+ @class_name = 'A'
140
+
141
+ @file_name.stub!(:gsub).and_return(@model_name_lower)
142
+ @model_name_lower.stub!(:camelize).and_return(@class_name)
143
+ Dir.stub(:[]).and_return([@file_name])
144
+ end
145
+
146
+ it "should load the files by guessing the file name" do
147
+ @class_name.should_receive(:constantize).and_return(true)
148
+
149
+ @config.load_models
150
+ end
151
+
152
+ it "should not raise errors if the model name is nil" do
153
+ @file_name.stub!(:gsub).and_return(nil)
154
+
155
+ lambda {
156
+ @config.load_models
157
+ }.should_not raise_error
158
+ end
159
+
160
+ it "should not raise errors if the file name does not represent a class name" do
161
+ @class_name.should_receive(:constantize).and_raise(NameError)
162
+
163
+ lambda {
164
+ @config.load_models
165
+ }.should_not raise_error
166
+ end
167
+
168
+ it "should retry if the first pass fails and contains a directory" do
169
+ @model_name_lower.stub!(:gsub!).and_return(true, nil)
170
+ @class_name.stub(:constantize).and_raise(LoadError)
171
+ @model_name_lower.should_receive(:camelize).twice
172
+
173
+ lambda {
174
+ @config.load_models
175
+ }.should_not raise_error
176
+ end
177
+
178
+ it "should catch database errors with a warning" do
179
+ @class_name.should_receive(:constantize).and_raise(Mysql::Error)
180
+ @config.should_receive(:puts).with('Warning: Error loading a.rb')
181
+
182
+ lambda {
183
+ @config.load_models
184
+ }.should_not raise_error
185
+ end
186
+ end
187
+
96
188
  it "should insert set index options into the configuration file" do
97
189
  config = ThinkingSphinx::Configuration.instance
98
190
  ThinkingSphinx::Configuration::IndexOptions.each do |option|
99
191
  config.index_options[option.to_sym] = "something"
100
192
  config.build
101
-
193
+
102
194
  file = open(config.config_file) { |f| f.read }
103
195
  file.should match(/#{option}\s+= something/)
104
-
196
+
105
197
  config.index_options[option.to_sym] = nil
106
198
  end
107
199
  end
108
-
200
+
109
201
  it "should insert set source options into the configuration file" do
110
202
  config = ThinkingSphinx::Configuration.instance
111
203
  ThinkingSphinx::Configuration::SourceOptions.each do |option|
112
204
  config.source_options[option.to_sym] = "something"
113
205
  config.build
114
-
206
+
115
207
  file = open(config.config_file) { |f| f.read }
116
208
  file.should match(/#{option}\s+= something/)
117
-
209
+
118
210
  config.source_options[option.to_sym] = nil
119
211
  end
120
212
  end
121
-
213
+
122
214
  it "should set any explicit prefixed or infixed fields" do
123
215
  file = open(ThinkingSphinx::Configuration.instance.config_file) { |f|
124
216
  f.read
125
217
  }
126
218
  file.should match(/prefix_fields\s+= city/)
127
- file.should match(/infix_fields\s+= state/)
219
+ file.should match(/infix_fields\s+= state/)
128
220
  end
129
-
221
+
130
222
  it "should not have prefix fields in indexes where nothing is set" do
131
223
  file = open(ThinkingSphinx::Configuration.instance.config_file) { |f|
132
224
  f.read
133
225
  }
134
226
  file.should_not match(/index alpha_core\s+\{\s+[^\}]*prefix_fields\s+=[^\}]*\}/m)
135
227
  end
136
- end
228
+
229
+ describe '#client' do
230
+ before :each do
231
+ @config = ThinkingSphinx::Configuration.instance
232
+ @config.address = 'domain.url'
233
+ @config.port = 3333
234
+ @config.configuration.searchd.max_matches = 100
235
+ end
236
+
237
+ it "should return an instance of Riddle::Client" do
238
+ @config.client.should be_a(Riddle::Client)
239
+ end
240
+
241
+ it "should use the configuration address" do
242
+ @config.client.server.should == 'domain.url'
243
+ end
244
+
245
+ it "should use the configuration port" do
246
+ @config.client.port.should == 3333
247
+ end
248
+
249
+ it "should use the configuration max matches" do
250
+ @config.client.max_matches.should == 100
251
+ end
252
+ end
253
+
254
+ describe '#models_by_crc' do
255
+ before :each do
256
+ @config = ThinkingSphinx::Configuration.instance
257
+ end
258
+
259
+ it "should return a hash" do
260
+ @config.models_by_crc.should be_a(Hash)
261
+ end
262
+
263
+ it "should pair class names to their crc codes" do
264
+ @config.models_by_crc[Person.to_crc32].should == 'Person'
265
+ @config.models_by_crc[Alpha.to_crc32].should == 'Alpha'
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Excerpter do
4
+ before :each do
5
+ @alpha = Alpha.find(:first)
6
+ @search = mock 'search', :excerpt_for => 'excerpted value'
7
+ @excerpter = ThinkingSphinx::Excerpter.new(@search, @alpha)
8
+ end
9
+
10
+ it "should not respond to id" do
11
+ @excerpter.should_not respond_to(:id)
12
+ end
13
+
14
+ describe '#method_missing' do
15
+ it "should return the excerpt from Sphinx" do
16
+ @excerpter.name.should == 'excerpted value'
17
+ end
18
+
19
+ it "should send through the instance class to excerpt_for" do
20
+ @search.should_receive(:excerpt_for) do |string, model|
21
+ model.should == Alpha
22
+ end
23
+
24
+ @excerpter.name
25
+ end
26
+
27
+ it "should use attribute methods for excerpts calls" do
28
+ @search.should_receive(:excerpt_for) do |string, model|
29
+ string.should == 'one'
30
+ end
31
+
32
+ @excerpter.name
33
+ end
34
+
35
+ it "should use instance methods for excerpts calls" do
36
+ @search.should_receive(:excerpt_for) do |string, model|
37
+ string.should == 'ONE'
38
+ end
39
+
40
+ @excerpter.big_name
41
+ end
42
+
43
+ it "should still raise an exception if no column or method exists" do
44
+ lambda {
45
+ @excerpter.foo
46
+ }.should raise_error(NoMethodError)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,176 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::FacetSearch do
4
+ describe 'populate' do
5
+ it "should make separate Sphinx queries for each facet" do
6
+ ThinkingSphinx.should_receive(:search).with(
7
+ hash_including(:group_by => 'city_facet')
8
+ ).and_return([])
9
+ ThinkingSphinx.should_receive(:search).with(
10
+ hash_including(:group_by => 'state_facet')
11
+ ).and_return([])
12
+ ThinkingSphinx.should_receive(:search).with(
13
+ hash_including(:group_by => 'birthday')
14
+ ).and_return([])
15
+
16
+ ThinkingSphinx::FacetSearch.new(:classes => [Person])
17
+ end
18
+
19
+ it "should request all shared facets in a multi-model request by default" do
20
+ ThinkingSphinx.stub!(:search => [])
21
+ ThinkingSphinx::FacetSearch.new.facet_names.should == ['class_crc']
22
+ end
23
+
24
+ it "should request all facets in a multi-model request if specified" do
25
+ ThinkingSphinx.stub!(:search => [])
26
+ ThinkingSphinx::FacetSearch.new(
27
+ :all_facets => true
28
+ ).facet_names.should == [
29
+ 'class_crc', 'city_facet', 'state_facet', 'birthday'
30
+ ]
31
+ end
32
+
33
+ describe ':facets option' do
34
+ it "should limit facets to the requested set" do
35
+ ThinkingSphinx.should_receive(:search).once.and_return([])
36
+
37
+ ThinkingSphinx::FacetSearch.new(
38
+ :classes => [Person], :facets => :state
39
+ )
40
+ end
41
+ end
42
+
43
+ describe "empty result set for attributes" do
44
+ before :each do
45
+ ThinkingSphinx.stub!(:search => [])
46
+ @facets = ThinkingSphinx::FacetSearch.new(
47
+ :classes => [Person], :facets => :state
48
+ )
49
+ end
50
+
51
+ it "should add key as attribute" do
52
+ @facets.should have_key(:state)
53
+ end
54
+
55
+ it "should return an empty hash for the facet results" do
56
+ @facets[:state].should be_empty
57
+ end
58
+ end
59
+
60
+ describe "non-empty result set" do
61
+ before :each do
62
+ @person = Person.find(:first)
63
+ @people = [@person]
64
+ @people.stub!(:each_with_groupby_and_count).
65
+ and_yield(@person, @person.city.to_crc32, 1)
66
+ ThinkingSphinx.stub!(:search => @people)
67
+
68
+ @facets = ThinkingSphinx::FacetSearch.new(
69
+ :classes => [Person], :facets => :city
70
+ )
71
+ end
72
+
73
+ it "should return a hash" do
74
+ @facets.should be_a_kind_of(Hash)
75
+ end
76
+
77
+ it "should add key as attribute" do
78
+ @facets.keys.should include(:city)
79
+ end
80
+
81
+ it "should return a hash" do
82
+ @facets[:city].should == {@person.city => 1}
83
+ end
84
+ end
85
+
86
+ before :each do
87
+ @config = ThinkingSphinx::Configuration.instance
88
+ @config.configuration.searchd.max_matches = 10_000
89
+ end
90
+
91
+ it "should use the system-set max_matches for limit on facet calls" do
92
+ ThinkingSphinx.should_receive(:search) do |options|
93
+ options[:max_matches].should == 10_000
94
+ options[:limit].should == 10_000
95
+ []
96
+ end
97
+
98
+ ThinkingSphinx::FacetSearch.new
99
+ end
100
+
101
+ it "should use the default max-matches if there is no explicit setting" do
102
+ @config.configuration.searchd.max_matches = nil
103
+ ThinkingSphinx.should_receive(:search) do |options|
104
+ options[:max_matches].should == 1000
105
+ options[:limit].should == 1000
106
+ []
107
+ end
108
+
109
+ ThinkingSphinx::FacetSearch.new
110
+ end
111
+
112
+ it "should ignore user-provided max_matches and limit on facet calls" do
113
+ ThinkingSphinx.should_receive(:search) do |options|
114
+ options[:max_matches].should == 10_000
115
+ options[:limit].should == 10_000
116
+ []
117
+ end
118
+
119
+ ThinkingSphinx::FacetSearch.new(
120
+ :max_matches => 500,
121
+ :limit => 200
122
+ )
123
+ end
124
+
125
+ it "should not use an explicit :page" do
126
+ ThinkingSphinx.should_receive(:search) do |options|
127
+ options[:page].should == 1
128
+ []
129
+ end
130
+
131
+ ThinkingSphinx::FacetSearch.new(:page => 3)
132
+ end
133
+
134
+ describe "conflicting facets" do
135
+ before :each do
136
+ @index = ThinkingSphinx::Index::Builder.generate(Alpha) do
137
+ indexes :name
138
+ has :value, :as => :city, :facet => true
139
+ end
140
+ end
141
+
142
+ after :each do
143
+ Alpha.sphinx_facets.delete_at(-1)
144
+ end
145
+
146
+ it "should raise an error if searching with facets of same name but different type" do
147
+ lambda {
148
+ facets = ThinkingSphinx.facets :all_facets => true
149
+ }.should raise_error
150
+ end
151
+ end
152
+ end
153
+
154
+ describe "#for" do
155
+ before do
156
+ @person = Person.find(:first)
157
+ @people = [@person]
158
+ @people.stub!(:each_with_groupby_and_count).
159
+ and_yield(@person, @person.city.to_crc32, 1)
160
+ ThinkingSphinx.stub!(:search => @people)
161
+
162
+ @facets = ThinkingSphinx::FacetSearch.new(
163
+ :classes => [Person], :facets => :city
164
+ )
165
+ end
166
+
167
+ it "should return the search results for the attribute and key pair" do
168
+ ThinkingSphinx.should_receive(:search) do |options|
169
+ options[:with].should have_key('city_facet')
170
+ options[:with]['city_facet'].should == @person.city.to_crc32
171
+ end
172
+
173
+ @facets.for(:city => @person.city)
174
+ end
175
+ end
176
+ end
@@ -275,4 +275,28 @@ describe ThinkingSphinx::Facet do
275
275
  ThinkingSphinx::Facet.new(attribute).type.should == :anything
276
276
  end
277
277
  end
278
+
279
+ describe "#value" do
280
+ before :each do
281
+ @index = ThinkingSphinx::Index.new(Friendship)
282
+ @source = ThinkingSphinx::Source.new(@index)
283
+ @field = ThinkingSphinx::Field.new(
284
+ @source, ThinkingSphinx::Index::FauxColumn.new(:person, :first_name)
285
+ )
286
+ @facet = ThinkingSphinx::Facet.new(@field)
287
+ end
288
+
289
+ it "should return association values" do
290
+ person = Person.find(:first)
291
+ friendship = Friendship.new(:person => person)
292
+
293
+ @facet.value(friendship, 1).should == person.first_name
294
+ end
295
+
296
+ it "should return nil if the association is nil" do
297
+ friendship = Friendship.new(:person => nil)
298
+
299
+ @facet.value(friendship, 1).should be_nil
300
+ end
301
+ end
278
302
  end
@@ -85,15 +85,15 @@ describe ThinkingSphinx::Field do
85
85
  @field.columns.each { |col| @field.associations[col] = [] }
86
86
  @field.model = Person
87
87
 
88
- @first_join = Object.stub_instance(:aliased_table_name => "tabular")
89
- @second_join = Object.stub_instance(:aliased_table_name => "data")
88
+ @first_join = Object.new
89
+ @first_join.stub!(:aliased_table_name => "tabular")
90
+ @second_join = Object.new
91
+ @second_join.stub!(:aliased_table_name => "data")
90
92
 
91
- @first_assoc = ThinkingSphinx::Association.stub_instance(
92
- :join => @first_join, :has_column? => true
93
- )
94
- @second_assoc = ThinkingSphinx::Association.stub_instance(
95
- :join => @second_join, :has_column? => true
96
- )
93
+ @first_assoc = ThinkingSphinx::Association.new nil, nil
94
+ @first_assoc.stub!(:join => @first_join, :has_column? => true)
95
+ @second_assoc = ThinkingSphinx::Association.new nil, nil
96
+ @second_assoc.stub!(:join => @second_join, :has_column? => true)
97
97
  end
98
98
 
99
99
  it "should return the column name if the column is a string" do
@@ -318,13 +318,17 @@ describe ThinkingSphinx::Index::Builder do
318
318
  indexes first_name
319
319
 
320
320
  set_property :charset_type => "utf16"
321
+ set_property :group_concat_max_len => 1024
321
322
  end
322
323
  end
323
324
 
324
- it "should store the setting for the index" do
325
- @index.local_options.length.should == 1
325
+ it "should store the index setting for the index" do
326
326
  @index.local_options[:charset_type].should == "utf16"
327
327
  end
328
+
329
+ it "should store non-Sphinx settings for the index" do
330
+ @index.local_options[:group_concat_max_len].should == 1024
331
+ end
328
332
  end
329
333
 
330
334
  describe "delta options" do
@@ -0,0 +1,45 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Index do
4
+ describe "prefix_fields method" do
5
+ before :each do
6
+ @index = ThinkingSphinx::Index.new(Person)
7
+
8
+ @field_a = ThinkingSphinx::Field.stub_instance(:prefixes => true)
9
+ @field_b = ThinkingSphinx::Field.stub_instance(:prefixes => false)
10
+ @field_c = ThinkingSphinx::Field.stub_instance(:prefixes => true)
11
+
12
+ @index.stub_method(:fields => [@field_a, @field_b, @field_c])
13
+ end
14
+
15
+ it "should return fields that are flagged as prefixed" do
16
+ @index.prefix_fields.should include(@field_a)
17
+ @index.prefix_fields.should include(@field_c)
18
+ end
19
+
20
+ it "should not return fields that aren't flagged as prefixed" do
21
+ @index.prefix_fields.should_not include(@field_b)
22
+ end
23
+ end
24
+
25
+ describe "infix_fields method" do
26
+ before :each do
27
+ @index = ThinkingSphinx::Index.new(Person)
28
+
29
+ @field_a = ThinkingSphinx::Field.stub_instance(:infixes => true)
30
+ @field_b = ThinkingSphinx::Field.stub_instance(:infixes => false)
31
+ @field_c = ThinkingSphinx::Field.stub_instance(:infixes => true)
32
+
33
+ @index.stub_method(:fields => [@field_a, @field_b, @field_c])
34
+ end
35
+
36
+ it "should return fields that are flagged as infixed" do
37
+ @index.infix_fields.should include(@field_a)
38
+ @index.infix_fields.should include(@field_c)
39
+ end
40
+
41
+ it "should not return fields that aren't flagged as infixed" do
42
+ @index.infix_fields.should_not include(@field_b)
43
+ end
44
+ end
45
+ end