erichummel-sunspot_rails 1.2.1a

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/History.txt +51 -0
  2. data/LICENSE +18 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +258 -0
  5. data/Rakefile +18 -0
  6. data/TESTING.md +35 -0
  7. data/TODO +8 -0
  8. data/VERSION.yml +4 -0
  9. data/dev_tasks/rdoc.rake +24 -0
  10. data/dev_tasks/release.rake +4 -0
  11. data/dev_tasks/spec.rake +22 -0
  12. data/dev_tasks/todo.rake +4 -0
  13. data/generators/sunspot/sunspot_generator.rb +9 -0
  14. data/generators/sunspot/templates/sunspot.yml +18 -0
  15. data/install.rb +1 -0
  16. data/lib/generators/sunspot_rails/install/install_generator.rb +13 -0
  17. data/lib/generators/sunspot_rails/install/templates/config/sunspot.yml +17 -0
  18. data/lib/generators/sunspot_rails.rb +9 -0
  19. data/lib/sunspot/rails/adapters.rb +83 -0
  20. data/lib/sunspot/rails/configuration.rb +323 -0
  21. data/lib/sunspot/rails/init.rb +5 -0
  22. data/lib/sunspot/rails/log_subscriber.rb +33 -0
  23. data/lib/sunspot/rails/railtie.rb +36 -0
  24. data/lib/sunspot/rails/railties/controller_runtime.rb +36 -0
  25. data/lib/sunspot/rails/request_lifecycle.rb +36 -0
  26. data/lib/sunspot/rails/searchable.rb +412 -0
  27. data/lib/sunspot/rails/server.rb +173 -0
  28. data/lib/sunspot/rails/solr_instrumentation.rb +21 -0
  29. data/lib/sunspot/rails/solr_logging.rb +63 -0
  30. data/lib/sunspot/rails/spec_helper.rb +26 -0
  31. data/lib/sunspot/rails/stub_session_proxy.rb +88 -0
  32. data/lib/sunspot/rails/tasks.rb +62 -0
  33. data/lib/sunspot/rails/version.rb +5 -0
  34. data/lib/sunspot/rails.rb +59 -0
  35. data/lib/sunspot_rails.rb +12 -0
  36. data/spec/configuration_spec.rb +173 -0
  37. data/spec/model_lifecycle_spec.rb +63 -0
  38. data/spec/model_spec.rb +356 -0
  39. data/spec/request_lifecycle_spec.rb +61 -0
  40. data/spec/schema.rb +27 -0
  41. data/spec/server_spec.rb +37 -0
  42. data/spec/session_spec.rb +24 -0
  43. data/spec/spec_helper.rb +46 -0
  44. data/spec/stub_session_proxy_spec.rb +122 -0
  45. metadata +155 -0
@@ -0,0 +1,356 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'ActiveRecord mixin' do
4
+ describe 'index()' do
5
+ before :each do
6
+ @post = Post.create!
7
+ @post.index
8
+ end
9
+
10
+ it 'should not commit the model' do
11
+ Post.search.results.should be_empty
12
+ end
13
+
14
+ it 'should index the model' do
15
+ Sunspot.commit
16
+ Post.search.results.should == [@post]
17
+ end
18
+
19
+ it "should not blow up if there's a default scope specifying order" do
20
+ posts = Array.new(2) { |j| PostWithDefaultScope.create! :title => (10-j).to_s }
21
+ lambda { PostWithDefaultScope.index(:batch_size => 1) }.should_not raise_error
22
+ end
23
+ end
24
+
25
+ describe 'single table inheritence' do
26
+ before :each do
27
+ @post = PhotoPost.create!
28
+ end
29
+
30
+ it 'should not break auto-indexing' do
31
+ @post.title = 'Title'
32
+ lambda { @post.save! }.should_not raise_error
33
+ end
34
+ end
35
+
36
+ describe 'index!()' do
37
+ before :each do
38
+ @post = Post.create!
39
+ @post.index!
40
+ end
41
+
42
+ it 'should immediately index and commit' do
43
+ Post.search.results.should == [@post]
44
+ end
45
+ end
46
+
47
+ describe 'remove_from_index()' do
48
+ before :each do
49
+ @post = Post.create!
50
+ @post.index!
51
+ @post.remove_from_index
52
+ end
53
+
54
+ it 'should not commit immediately' do
55
+ Post.search.results.should == [@post]
56
+ end
57
+
58
+ it 'should remove the model from the index' do
59
+ Sunspot.commit
60
+ Post.search.results.should be_empty
61
+ end
62
+ end
63
+
64
+ describe 'remove_from_index!()' do
65
+ before :each do
66
+ @post = Post.create!
67
+ @post.index!
68
+ @post.remove_from_index!
69
+ end
70
+
71
+ it 'should immediately remove the model and commit' do
72
+ Post.search.results.should be_empty
73
+ end
74
+ end
75
+
76
+ describe 'remove_all_from_index' do
77
+ before :each do
78
+ @posts = Array.new(2) { Post.create! }.each { |post| Sunspot.index(post) }
79
+ Sunspot.commit
80
+ Post.remove_all_from_index
81
+ end
82
+
83
+ it 'should not commit immediately' do
84
+ Post.search.results.to_set.should == @posts.to_set
85
+ end
86
+
87
+ it 'should remove all instances from the index' do
88
+ Sunspot.commit
89
+ Post.search.results.should be_empty
90
+ end
91
+ end
92
+
93
+ describe 'remove_all_from_index!' do
94
+ before :each do
95
+ Array.new(2) { Post.create! }.each { |post| Sunspot.index(post) }
96
+ Sunspot.commit
97
+ Post.remove_all_from_index!
98
+ end
99
+
100
+ it 'should remove all instances from the index and commit immediately' do
101
+ Post.search.results.should be_empty
102
+ end
103
+ end
104
+
105
+ describe 'search()' do
106
+ before :each do
107
+ @post = Post.create!(:title => 'Test Post')
108
+ @post.index!
109
+ end
110
+
111
+ it 'should return results specified by search' do
112
+ Post.search do
113
+ with :title, 'Test Post'
114
+ end.results.should == [@post]
115
+ end
116
+
117
+ it 'should not return results excluded by search' do
118
+ Post.search do
119
+ with :title, 'Bogus Post'
120
+ end.results.should be_empty
121
+ end
122
+
123
+ it 'should use the include option on the data accessor when specified' do
124
+ Post.should_receive(:all).with(hash_including(:include => [:blog])).and_return([@post])
125
+ Post.search do
126
+ with :title, 'Test Post'
127
+ data_accessor_for(Post).include = [:blog]
128
+ end.results.should == [@post]
129
+ end
130
+
131
+ it 'should pass :include option from search call to data accessor' do
132
+ Post.should_receive(:all).with(hash_including(:include => [:blog])).and_return([@post])
133
+ Post.search(:include => [:blog]) do
134
+ with :title, 'Test Post'
135
+ end.results.should == [@post]
136
+ end
137
+
138
+ it 'should use the select option from search call to data accessor' do
139
+ Post.should_receive(:all).with(hash_including(:select => 'title, published_at')).and_return([@post])
140
+ Post.search(:select => 'title, published_at') do
141
+ with :title, 'Test Post'
142
+ end.results.should == [@post]
143
+ end
144
+
145
+ it 'should not allow bogus options to search' do
146
+ lambda { Post.search(:bogus => :option) }.should raise_error(ArgumentError)
147
+ end
148
+
149
+ it 'should use the select option on the data accessor when specified' do
150
+ Post.should_receive(:all).with(hash_including(:select => 'title, published_at')).and_return([@post])
151
+ Post.search do
152
+ with :title, 'Test Post'
153
+ data_accessor_for(Post).select = [:title, :published_at]
154
+ end.results.should == [@post]
155
+ end
156
+
157
+ it 'should not use the select option on the data accessor when not specified' do
158
+ Post.should_receive(:all).with(hash_not_including(:select)).and_return([@post])
159
+ Post.search do
160
+ with :title, 'Test Post'
161
+ end.results.should == [@post]
162
+ end
163
+
164
+ it 'should gracefully handle nonexistent records' do
165
+ post2 = Post.create!(:title => 'Test Post')
166
+ post2.index!
167
+ post2.destroy
168
+ Post.search do
169
+ with :title, 'Test Post'
170
+ end.results.should == [@post]
171
+ end
172
+
173
+ it 'should use an ActiveRecord object for coordinates' do
174
+ post = Post.new(:title => 'Test Post')
175
+ post.location = Location.create!(:lat => 40.0, :lng => -70.0)
176
+ post.save
177
+ post.index!
178
+ Post.search { with(:location).near(40.0, -70.0) }.results.should == [post]
179
+ end
180
+
181
+ end
182
+
183
+ describe 'search_ids()' do
184
+ before :each do
185
+ @posts = Array.new(2) { Post.create! }.each { |post| post.index }
186
+ Sunspot.commit
187
+ end
188
+
189
+ it 'should return IDs' do
190
+ Post.search_ids.to_set.should == @posts.map { |post| post.id }.to_set
191
+ end
192
+ end
193
+
194
+ describe 'searchable?()' do
195
+ it 'should not be true for models that have not been configured for search' do
196
+ Location.should_not be_searchable
197
+ end
198
+
199
+ it 'should be true for models that have been configured for search' do
200
+ Post.should be_searchable
201
+ end
202
+ end
203
+
204
+ describe 'index_orphans()' do
205
+ before :each do
206
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
207
+ Sunspot.commit
208
+ @posts.first.destroy
209
+ end
210
+
211
+ it 'should return IDs of objects that are in the index but not the database' do
212
+ Post.index_orphans.should == [@posts.first.id]
213
+ end
214
+ end
215
+
216
+ describe 'clean_index_orphans()' do
217
+ before :each do
218
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
219
+ Sunspot.commit
220
+ @posts.first.destroy
221
+ end
222
+
223
+ it 'should remove orphans from the index' do
224
+ Post.clean_index_orphans
225
+ Sunspot.commit
226
+ Post.search.results.should == [@posts.last]
227
+ end
228
+ end
229
+
230
+ describe 'reindex()' do
231
+ before :each do
232
+ @posts = Array.new(2) { Post.create }
233
+ end
234
+
235
+ it 'should index all instances' do
236
+ Post.reindex(:batch_size => nil)
237
+ Sunspot.commit
238
+ Post.search.results.to_set.should == @posts.to_set
239
+ end
240
+
241
+ it 'should remove all currently indexed instances' do
242
+ old_post = Post.create!
243
+ old_post.index!
244
+ old_post.destroy
245
+ Post.reindex
246
+ Sunspot.commit
247
+ Post.search.results.to_set.should == @posts.to_set
248
+ end
249
+
250
+ end
251
+
252
+ describe 'reindex() with real data' do
253
+ before :each do
254
+ @posts = Array.new(2) { Post.create }
255
+ end
256
+
257
+ it 'should index all instances' do
258
+ Post.reindex(:batch_size => nil)
259
+ Sunspot.commit
260
+ Post.search.results.to_set.should == @posts.to_set
261
+ end
262
+
263
+ it 'should remove all currently indexed instances' do
264
+ old_post = Post.create!
265
+ old_post.index!
266
+ old_post.destroy
267
+ Post.reindex
268
+ Sunspot.commit
269
+ Post.search.results.to_set.should == @posts.to_set
270
+ end
271
+
272
+ describe "using batch sizes" do
273
+ it 'should index with a specified batch size' do
274
+ Post.reindex(:batch_size => 1)
275
+ Sunspot.commit
276
+ Post.search.results.to_set.should == @posts.to_set
277
+ end
278
+ end
279
+ end
280
+
281
+
282
+
283
+ describe "reindex()" do
284
+
285
+ before(:each) do
286
+ @posts = Array.new(2) { Post.create }
287
+ end
288
+
289
+ describe "when not using batches" do
290
+
291
+ it "should select all if the batch_size is nil" do
292
+ Post.should_receive(:all).with(:include => []).and_return([])
293
+ Post.reindex(:batch_size => nil)
294
+ end
295
+
296
+ it "should search for models with includes" do
297
+ Post.should_receive(:all).with(:include => :author).and_return([])
298
+ Post.reindex(:batch_size => nil, :include => :author)
299
+ end
300
+
301
+ end
302
+
303
+ describe "when using batches" do
304
+ it "should commit after indexing each batch" do
305
+ Sunspot.should_receive(:commit).twice
306
+ Post.reindex(:batch_size => 1)
307
+ end
308
+
309
+ it "should commit after indexing everything" do
310
+ Sunspot.should_receive(:commit).once
311
+ Post.reindex(:batch_commit => false)
312
+ end
313
+ end
314
+ end
315
+
316
+ describe "more_like_this()" do
317
+ before(:each) do
318
+ @posts = [
319
+ Post.create!(:title => 'Post123', :body => "one two three"),
320
+ Post.create!(:title => 'Post345', :body => "three four five"),
321
+ Post.create!(:title => 'Post456', :body => "four five six"),
322
+ Post.create!(:title => 'Post234', :body => "two three four"),
323
+ ]
324
+ @posts_with_auto = [
325
+ PostWithAuto.create!(:body => "one two three"),
326
+ PostWithAuto.create!(:body => "four five six")
327
+ ]
328
+ @posts.each { |p| p.index! }
329
+ end
330
+
331
+ it "should return results" do
332
+ @posts.first.more_like_this.results.should == [@posts[3], @posts[1]]
333
+ end
334
+
335
+ it "should return results for specified classes" do
336
+ @posts.first.more_like_this(Post, PostWithAuto).results.to_set.should ==
337
+ Set[@posts_with_auto[0], @posts[1], @posts[3]]
338
+ end
339
+ end
340
+
341
+ describe 'more_like_this_ids()' do
342
+ before :each do
343
+ @posts = [
344
+ Post.create!(:title => 'Post123', :body => "one two three"),
345
+ Post.create!(:title => 'Post345', :body => "three four five"),
346
+ Post.create!(:title => 'Post456', :body => "four five six"),
347
+ Post.create!(:title => 'Post234', :body => "two three four"),
348
+ ]
349
+ @posts.each { |p| p.index! }
350
+ end
351
+
352
+ it 'should return IDs' do
353
+ @posts.first.more_like_this_ids.to_set.should == [@posts[3], @posts[1]].map { |post| post.id }.to_set
354
+ end
355
+ end
356
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe PostsController, :type => :controller do
4
+ begin
5
+ include ::RSpec::Rails::ControllerExampleGroup
6
+ rescue NameError
7
+ # Silent -- rspec-rails 1.x catches the :type => :controller
8
+ end
9
+
10
+ before(:each) do
11
+ Sunspot::Rails.configuration = @configuration = Sunspot::Rails::Configuration.new
12
+ end
13
+
14
+ after(:each) do
15
+ Sunspot::Rails.configuration = nil
16
+ end
17
+
18
+ unless respond_to?(:describes)
19
+ controller_name :posts # RSpec 1
20
+ end
21
+
22
+ it 'should automatically commit after each action if specified' do
23
+ @configuration.user_configuration = { 'auto_commit_after_request' => true }
24
+ Sunspot.should_receive(:commit_if_dirty)
25
+ post :create, :post => { :title => 'Test 1' }
26
+ end
27
+
28
+ it 'should not commit, if configuration is set to false' do
29
+ @configuration.user_configuration = { 'auto_commit_after_request' => false }
30
+ Sunspot.should_not_receive(:commit_if_dirty)
31
+ post :create, :post => { :title => 'Test 1' }
32
+ end
33
+
34
+ it 'should commit if configuration is not specified' do
35
+ @configuration.user_configuration = {}
36
+ Sunspot.should_receive(:commit_if_dirty)
37
+ post :create, :post => { :title => 'Test 1' }
38
+ end
39
+
40
+ ### auto_commit_if_delete_dirty
41
+
42
+ it 'should automatically commit after each delete if specified' do
43
+ @configuration.user_configuration = { 'auto_commit_after_request' => false,
44
+ 'auto_commit_after_delete_request' => true }
45
+ Sunspot.should_receive(:commit_if_delete_dirty)
46
+ post :create, :post => { :title => 'Test 1' }
47
+ end
48
+
49
+ it 'should not automatically commit on delete if configuration is set to false' do
50
+ @configuration.user_configuration = { 'auto_commit_after_request' => false,
51
+ 'auto_commit_after_delete_request' => false }
52
+ Sunspot.should_not_receive(:commit_if_delete_dirty)
53
+ post :create, :post => { :title => 'Test 1' }
54
+ end
55
+
56
+ it 'should not automatically commit on delete if configuration is not specified' do
57
+ @configuration.user_configuration = { 'auto_commit_after_request' => false }
58
+ Sunspot.should_not_receive(:commit_if_delete_dirty)
59
+ post :create, :post => { :title => 'Test 1' }
60
+ end
61
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,27 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :posts, :force => true do |t|
3
+ t.string :title
4
+ t.string :type
5
+ t.integer :location_id
6
+ t.text :body
7
+ t.references :blog
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :locations, :force => true do |t|
12
+ t.float :lat
13
+ t.float :lng
14
+ end
15
+
16
+ create_table :blogs, :force => true do |t|
17
+ t.string :name
18
+ t.string :subdomain
19
+ t.timestamps
20
+ end
21
+
22
+ create_table :writers, :force => true, :primary_key => :writer_id do |t|
23
+ t.string :name
24
+ t.timestamps
25
+ end
26
+
27
+ end
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe Sunspot::Rails::Server do
4
+ before :each do
5
+ @server = Sunspot::Rails::Server.new
6
+ @config = Sunspot::Rails::Configuration.new
7
+ @solr_home = File.join(@config.solr_home)
8
+ end
9
+
10
+ it "sets the correct Solr home" do
11
+ @server.solr_home.should == @solr_home
12
+ end
13
+
14
+ it "sets the correct Solr library path" do
15
+ @server.lib_path.should == File.join(@solr_home, 'lib')
16
+ end
17
+
18
+ it "sets the correct Solr PID path" do
19
+ @server.pid_path.should == File.join(@server.pid_dir, 'sunspot-solr-test.pid')
20
+ end
21
+
22
+ it "sets the correct Solr data dir" do
23
+ @server.solr_data_dir.should == File.join(@solr_home, 'data', 'test')
24
+ end
25
+
26
+ it "sets the correct port" do
27
+ @server.port.should == 8980
28
+ end
29
+
30
+ it "sets the correct log level" do
31
+ @server.log_level.should == "FINE"
32
+ end
33
+
34
+ it "sets the correct log file" do
35
+ @server.log_file.should == File.join(Rails.root, 'log', 'sunspot-solr-test.log')
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'Sunspot::Rails session' do
4
+ it 'should be a different object for each thread' do
5
+ end
6
+
7
+ it 'should create a separate master/slave session if configured' do
8
+ end
9
+
10
+ it 'should not create a separate master/slave session if no master configured' do
11
+ end
12
+
13
+ private
14
+
15
+ def with_configuration(options)
16
+ original_configuration = Sunspot::Rails.configuration
17
+ Sunspot::Rails.reset
18
+ Sunspot::Rails.configuration = Sunspot::Rails::Configuration.new
19
+ Sunspot::Rails.configuration.user_configuration = options
20
+ yield
21
+ Sunspot::Rails.reset
22
+ Sunspot::Rails.configuration = original_configuration
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+ ENV['RAILS_ROOT'] ||= File.join(File.dirname(__FILE__), 'rails3')
3
+ if rsolr_version = ENV['RSOLR_GEM_VERSION']
4
+ STDERR.puts("Forcing RSolr version #{rsolr_version}")
5
+ gem "rsolr", rsolr_version
6
+ end
7
+
8
+ require File.expand_path('config/environment', ENV['RAILS_ROOT'])
9
+
10
+ begin
11
+ require 'rspec'
12
+ require 'rspec/rails'
13
+ rescue LoadError => e
14
+ require 'spec'
15
+ require 'spec/rails'
16
+ end
17
+ require 'rake'
18
+ require File.join('sunspot', 'rails', 'solr_logging')
19
+
20
+ def load_schema
21
+ stdout = $stdout
22
+ $stdout = StringIO.new # suppress output while building the schema
23
+ load File.join(ENV['RAILS_ROOT'], 'db', 'schema.rb')
24
+ $stdout = stdout
25
+ end
26
+
27
+ def silence_stderr(&block)
28
+ stderr = $stderr
29
+ $stderr = StringIO.new
30
+ yield
31
+ $stderr = stderr
32
+ end
33
+
34
+ rspec =
35
+ begin
36
+ RSpec
37
+ rescue NameError, ArgumentError
38
+ Spec::Runner
39
+ end
40
+
41
+ rspec.configure do |config|
42
+ config.before(:each) do
43
+ load_schema
44
+ Sunspot.remove_all!
45
+ end
46
+ end
@@ -0,0 +1,122 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'sunspot', 'rails', 'spec_helper')
3
+
4
+ describe 'specs with Sunspot stubbed' do
5
+ disconnect_sunspot
6
+
7
+ before :each do
8
+ @session = Sunspot.session.original_session
9
+ @post = Post.create!
10
+ end
11
+
12
+ it 'should not send index to session' do
13
+ @session.should_not_receive(:index)
14
+ @post.index
15
+ end
16
+
17
+ it 'should not send index! to session' do
18
+ @session.should_not_receive(:index!)
19
+ @post.index!
20
+ end
21
+
22
+ it 'should not send commit to session' do
23
+ @session.should_not_receive(:commit)
24
+ Sunspot.commit
25
+ end
26
+
27
+ it 'should not send remove to session' do
28
+ @session.should_not_receive(:remove)
29
+ @post.remove_from_index
30
+ end
31
+
32
+ it 'should not send remove! to session' do
33
+ @session.should_not_receive(:remove)
34
+ @post.remove_from_index!
35
+ end
36
+
37
+ it 'should not send remove_by_id to session' do
38
+ @session.should_not_receive(:remove_by_id)
39
+ Sunspot.remove_by_id(Post, 1)
40
+ end
41
+
42
+ it 'should not send remove_by_id! to session' do
43
+ @session.should_not_receive(:remove_by_id!)
44
+ Sunspot.remove_by_id!(Post, 1)
45
+ end
46
+
47
+ it 'should not send remove_all to session' do
48
+ @session.should_not_receive(:remove_all)
49
+ Post.remove_all_from_index
50
+ end
51
+
52
+ it 'should not send remove_all! to session' do
53
+ @session.should_not_receive(:remove_all!)
54
+ Post.remove_all_from_index!
55
+ end
56
+
57
+ it 'should return false for dirty?' do
58
+ @session.should_not_receive(:dirty?)
59
+ Sunspot.dirty?.should == false
60
+ end
61
+
62
+ it 'should not send commit_if_dirty to session' do
63
+ @session.should_not_receive(:commit_if_dirty)
64
+ Sunspot.commit_if_dirty
65
+ end
66
+
67
+ it 'should return false for delete_dirty?' do
68
+ @session.should_not_receive(:delete_dirty?)
69
+ Sunspot.delete_dirty?.should == false
70
+ end
71
+
72
+ it 'should not send commit_if_delete_dirty to session' do
73
+ @session.should_not_receive(:commit_if_delete_dirty)
74
+ Sunspot.commit_if_delete_dirty
75
+ end
76
+
77
+ it 'should not execute a search when #search called' do
78
+ @session.should_not_receive(:search)
79
+ Post.search
80
+ end
81
+
82
+ it 'should not execute a search when #search called' do
83
+ @session.should_not_receive(:search)
84
+ Post.search
85
+ end
86
+
87
+ it 'should not execute a search when #search called with parameters' do
88
+ @session.should_not_receive(:search)
89
+ Post.search(:include => :blog, :select => 'id, title')
90
+ end
91
+
92
+ it 'should return a new search' do
93
+ @session.should_not_receive(:new_search)
94
+ Sunspot.new_search(Post).should respond_to(:execute)
95
+ end
96
+
97
+ describe 'stub search' do
98
+ before :each do
99
+ @search = Post.search
100
+ end
101
+
102
+ it 'should return empty results' do
103
+ @search.results.should == []
104
+ end
105
+
106
+ it 'should return empty hits' do
107
+ @search.hits.should == []
108
+ end
109
+
110
+ it 'should return zero total' do
111
+ @search.total.should == 0
112
+ end
113
+
114
+ it 'should return nil for a given facet' do
115
+ @search.facet(:category_id).should be_nil
116
+ end
117
+
118
+ it 'should return nil for a given dynamic facet' do
119
+ @search.dynamic_facet(:custom).should be_nil
120
+ end
121
+ end
122
+ end