erichummel-sunspot_rails 1.2.1a

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.
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