sunspot_rails 0.10.4

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 (38) hide show
  1. data/LICENSE +18 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +246 -0
  4. data/Rakefile +19 -0
  5. data/VERSION.yml +4 -0
  6. data/dev_tasks/gemspec.rake +27 -0
  7. data/dev_tasks/rdoc.rake +7 -0
  8. data/dev_tasks/todo.rake +4 -0
  9. data/install.rb +1 -0
  10. data/lib/sunspot/rails.rb +11 -0
  11. data/lib/sunspot/rails/adapters.rb +54 -0
  12. data/lib/sunspot/rails/configuration.rb +94 -0
  13. data/lib/sunspot/rails/request_lifecycle.rb +18 -0
  14. data/lib/sunspot/rails/searchable.rb +304 -0
  15. data/lib/sunspot/rails/tasks.rb +53 -0
  16. data/rails/init.rb +10 -0
  17. data/spec/configuration_spec.rb +16 -0
  18. data/spec/mock_app/app/controllers/application.rb +10 -0
  19. data/spec/mock_app/app/controllers/application_controller.rb +10 -0
  20. data/spec/mock_app/app/controllers/posts_controller.rb +6 -0
  21. data/spec/mock_app/app/models/blog.rb +2 -0
  22. data/spec/mock_app/app/models/post.rb +5 -0
  23. data/spec/mock_app/app/models/post_with_auto.rb +9 -0
  24. data/spec/mock_app/config/boot.rb +110 -0
  25. data/spec/mock_app/config/database.yml +4 -0
  26. data/spec/mock_app/config/environment.rb +41 -0
  27. data/spec/mock_app/config/environments/development.rb +27 -0
  28. data/spec/mock_app/config/environments/test.rb +27 -0
  29. data/spec/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  30. data/spec/mock_app/config/initializers/session_store.rb +15 -0
  31. data/spec/mock_app/config/routes.rb +43 -0
  32. data/spec/mock_app/config/sunspot.yml +13 -0
  33. data/spec/model_lifecycle_spec.rb +38 -0
  34. data/spec/model_spec.rb +278 -0
  35. data/spec/request_lifecycle_spec.rb +10 -0
  36. data/spec/schema.rb +14 -0
  37. data/spec/spec_helper.rb +30 -0
  38. metadata +182 -0
@@ -0,0 +1,9 @@
1
+ class PostWithAuto < ActiveRecord::Base
2
+ def self.table_name
3
+ 'posts'
4
+ end
5
+
6
+ searchable do
7
+ string :title
8
+ end
9
+ end
@@ -0,0 +1,110 @@
1
+ # Don't change this file!
2
+ # Configure your app in config/environment.rb and config/environments/*.rb
3
+
4
+ RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5
+
6
+ module Rails
7
+ class << self
8
+ def boot!
9
+ unless booted?
10
+ preinitialize
11
+ pick_boot.run
12
+ end
13
+ end
14
+
15
+ def booted?
16
+ defined? Rails::Initializer
17
+ end
18
+
19
+ def pick_boot
20
+ (vendor_rails? ? VendorBoot : GemBoot).new
21
+ end
22
+
23
+ def vendor_rails?
24
+ File.exist?("#{RAILS_ROOT}/vendor/rails")
25
+ end
26
+
27
+ def preinitialize
28
+ load(preinitializer_path) if File.exist?(preinitializer_path)
29
+ end
30
+
31
+ def preinitializer_path
32
+ "#{RAILS_ROOT}/config/preinitializer.rb"
33
+ end
34
+ end
35
+
36
+ class Boot
37
+ def run
38
+ load_initializer
39
+ Rails::Initializer.run(:set_load_path)
40
+ end
41
+ end
42
+
43
+ class VendorBoot < Boot
44
+ def load_initializer
45
+ require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46
+ Rails::Initializer.run(:install_gem_spec_stubs)
47
+ Rails::GemDependency.add_frozen_gem_path
48
+ end
49
+ end
50
+
51
+ class GemBoot < Boot
52
+ def load_initializer
53
+ self.class.load_rubygems
54
+ load_rails_gem
55
+ require 'initializer'
56
+ end
57
+
58
+ def load_rails_gem
59
+ if version = self.class.gem_version
60
+ gem 'rails', version
61
+ else
62
+ gem 'rails'
63
+ end
64
+ rescue Gem::LoadError => load_error
65
+ $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
66
+ exit 1
67
+ end
68
+
69
+ class << self
70
+ def rubygems_version
71
+ Gem::RubyGemsVersion rescue nil
72
+ end
73
+
74
+ def gem_version
75
+ if defined? RAILS_GEM_VERSION
76
+ RAILS_GEM_VERSION
77
+ elsif ENV.include?('RAILS_GEM_VERSION')
78
+ ENV['RAILS_GEM_VERSION']
79
+ else
80
+ parse_gem_version(read_environment_rb)
81
+ end
82
+ end
83
+
84
+ def load_rubygems
85
+ require 'rubygems'
86
+ min_version = '1.3.1'
87
+ unless rubygems_version >= min_version
88
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
89
+ exit 1
90
+ end
91
+
92
+ rescue LoadError
93
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
94
+ exit 1
95
+ end
96
+
97
+ def parse_gem_version(text)
98
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
99
+ end
100
+
101
+ private
102
+ def read_environment_rb
103
+ File.read("#{RAILS_ROOT}/config/environment.rb")
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ # All that for this:
110
+ Rails.boot!
@@ -0,0 +1,4 @@
1
+ test: &test
2
+ :adapter: sqlite3
3
+ :dbfile: vendor/plugins/sunspot_rails/spec/test.db
4
+ development: *test
@@ -0,0 +1,41 @@
1
+ # Be sure to restart your server when you modify this file
2
+
3
+ # Specifies gem version of Rails to use when vendor/rails is not present
4
+ RAILS_GEM_VERSION = ENV['RAILS_GEM_VERSION'] || '2.3.2' unless defined? RAILS_GEM_VERSION
5
+
6
+ # Bootstrap the Rails environment, frameworks, and default configuration
7
+ require File.join(File.dirname(__FILE__), 'boot')
8
+
9
+ Rails::Initializer.run do |config|
10
+ # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Add additional load paths for your own custom dirs
15
+ # config.load_paths += %W( #{RAILS_ROOT}/extras )
16
+
17
+ # Specify gems that this application depends on and have them installed with rake gems:install
18
+ # config.gem "bj"
19
+ # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
20
+ # config.gem "sqlite3-ruby", :lib => "sqlite3"
21
+ # config.gem "aws-s3", :lib => "aws/s3"
22
+
23
+ # Only load the plugins named here, in the order given (default is alphabetical).
24
+ # :all can be used as a placeholder for all plugins not explicitly named
25
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
26
+
27
+ # Skip frameworks you're not going to use. To use Rails without a database,
28
+ # you must remove the Active Record framework.
29
+ # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
30
+
31
+ # Activate observers that should always be running
32
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
33
+
34
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
35
+ # Run "rake -D time" for a list of tasks for finding time zone names.
36
+ config.time_zone = 'UTC'
37
+
38
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
39
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
40
+ # config.i18n.default_locale = :de
41
+ end
@@ -0,0 +1,27 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # The test environment is used exclusively to run your application's
4
+ # test suite. You never need to work with it otherwise. Remember that
5
+ # your test database is "scratch space" for the test suite and is wiped
6
+ # and recreated between test runs. Don't rely on the data there!
7
+ config.cache_classes = true
8
+
9
+ # Log error messages when you accidentally call methods on nil.
10
+ config.whiny_nils = true
11
+
12
+ # Show full error reports and disable caching
13
+ config.action_controller.consider_all_requests_local = true
14
+ config.action_controller.perform_caching = false
15
+
16
+ # Disable request forgery protection in test environment
17
+ config.action_controller.allow_forgery_protection = false
18
+
19
+ # Tell Action Mailer not to deliver emails to the real world.
20
+ # The :test delivery method accumulates sent emails in the
21
+ # ActionMailer::Base.deliveries array.
22
+ config.action_mailer.delivery_method = :test
23
+
24
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
25
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
26
+ # like if you have constraints or database-specific column types
27
+ # config.active_record.schema_format = :sql
@@ -0,0 +1,27 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # The test environment is used exclusively to run your application's
4
+ # test suite. You never need to work with it otherwise. Remember that
5
+ # your test database is "scratch space" for the test suite and is wiped
6
+ # and recreated between test runs. Don't rely on the data there!
7
+ config.cache_classes = true
8
+
9
+ # Log error messages when you accidentally call methods on nil.
10
+ config.whiny_nils = true
11
+
12
+ # Show full error reports and disable caching
13
+ config.action_controller.consider_all_requests_local = true
14
+ config.action_controller.perform_caching = false
15
+
16
+ # Disable request forgery protection in test environment
17
+ config.action_controller.allow_forgery_protection = false
18
+
19
+ # Tell Action Mailer not to deliver emails to the real world.
20
+ # The :test delivery method accumulates sent emails in the
21
+ # ActionMailer::Base.deliveries array.
22
+ config.action_mailer.delivery_method = :test
23
+
24
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
25
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
26
+ # like if you have constraints or database-specific column types
27
+ # config.active_record.schema_format = :sql
@@ -0,0 +1,19 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # These settings change the behavior of Rails 2 apps and will be defaults
4
+ # for Rails 3. You can remove this initializer when Rails 3 is released.
5
+
6
+ if defined?(ActiveRecord)
7
+ # Include Active Record class name as root for JSON serialized output.
8
+ ActiveRecord::Base.include_root_in_json = true
9
+
10
+ # Store the full class name (including module namespace) in STI type column.
11
+ ActiveRecord::Base.store_full_sti_class = true
12
+ end
13
+
14
+ # Use ISO 8601 format for JSON serialized times and dates.
15
+ ActiveSupport.use_standard_json_time_format = true
16
+
17
+ # Don't escape HTML entities in JSON, leave that for the #json_escape helper.
18
+ # if you're including raw json in an HTML page.
19
+ ActiveSupport.escape_html_entities_in_json = false
@@ -0,0 +1,15 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key for verifying cookie session data integrity.
4
+ # If you change this key, all old sessions will become invalid!
5
+ # Make sure the secret is at least 30 characters and all random,
6
+ # no regular words or you'll be exposed to dictionary attacks.
7
+ ActionController::Base.session = {
8
+ :key => '_mock_app_session',
9
+ :secret => 'a2ddf56c7d642f2075a5d466eff55556c20d13415aff5156740ac82848c3c586711fde0e52f4834727816d08b2d13f3da7b6c7587d789cebe6081ee1a7fec943'
10
+ }
11
+
12
+ # Use the database for sessions instead of the cookie-based default,
13
+ # which shouldn't be used to store highly confidential information
14
+ # (create the session table with "rake db:sessions:create")
15
+ # ActionController::Base.session_store = :active_record_store
@@ -0,0 +1,43 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ # The priority is based upon order of creation: first created -> highest priority.
3
+
4
+ # Sample of regular route:
5
+ # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6
+ # Keep in mind you can assign values other than :controller and :action
7
+
8
+ # Sample of named route:
9
+ # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
10
+ # This route can be invoked with purchase_url(:id => product.id)
11
+
12
+ # Sample resource route (maps HTTP verbs to controller actions automatically):
13
+ # map.resources :products
14
+
15
+ # Sample resource route with options:
16
+ # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
17
+
18
+ # Sample resource route with sub-resources:
19
+ # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
20
+
21
+ # Sample resource route with more complex sub-resources
22
+ # map.resources :products do |products|
23
+ # products.resources :comments
24
+ # products.resources :sales, :collection => { :recent => :get }
25
+ # end
26
+
27
+ # Sample resource route within a namespace:
28
+ # map.namespace :admin do |admin|
29
+ # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
30
+ # admin.resources :products
31
+ # end
32
+
33
+ # You can have the root of your site routed with map.root -- just remember to delete public/index.html.
34
+ # map.root :controller => "welcome"
35
+
36
+ # See how all your routes lay out with "rake routes"
37
+
38
+ # Install the default routes as the lowest priority.
39
+ # Note: These default routes make all actions in every controller accessible via GET requests. You should
40
+ # consider removing the them or commenting them out if you're using named routes and resources.
41
+
42
+ map.resources :posts, :only => :create
43
+ end
@@ -0,0 +1,13 @@
1
+ test:
2
+ solr:
3
+ hostname: localhost
4
+ port: 8980
5
+ development:
6
+ solr:
7
+ hostname: localhost
8
+ port: 8981
9
+ path_test:
10
+ solr:
11
+ hostname: localhost
12
+ port: 8981
13
+ path: /solr/path_test
@@ -0,0 +1,38 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'searchable with lifecycle' do
4
+ describe 'on create' do
5
+ before :each do
6
+ @post = PostWithAuto.create
7
+ Sunspot.commit
8
+ end
9
+
10
+ it 'should automatically index' do
11
+ PostWithAuto.search.results.should == [@post]
12
+ end
13
+ end
14
+
15
+ describe 'on update' do
16
+ before :each do
17
+ @post = PostWithAuto.create
18
+ @post.update_attributes(:title => 'Test 1')
19
+ Sunspot.commit
20
+ end
21
+
22
+ it 'should automatically update index' do
23
+ PostWithAuto.search { with :title, 'Test 1' }.results.should == [@post]
24
+ end
25
+ end
26
+
27
+ describe 'on destroy' do
28
+ before :each do
29
+ @post = PostWithAuto.create
30
+ @post.destroy
31
+ Sunspot.commit
32
+ end
33
+
34
+ it 'should automatically remove it from the index' do
35
+ PostWithAuto.search_ids.should be_empty
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,278 @@
1
+ require File.join(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
+ end
19
+
20
+ describe 'index!()' do
21
+ before :each do
22
+ @post = Post.create!
23
+ @post.index!
24
+ end
25
+
26
+ it 'should immediately index and commit' do
27
+ Post.search.results.should == [@post]
28
+ end
29
+ end
30
+
31
+ describe 'remove_from_index()' do
32
+ before :each do
33
+ @post = Post.create!
34
+ @post.index!
35
+ @post.remove_from_index
36
+ end
37
+
38
+ it 'should not commit immediately' do
39
+ Post.search.results.should == [@post]
40
+ end
41
+
42
+ it 'should remove the model from the index' do
43
+ Sunspot.commit
44
+ Post.search.results.should be_empty
45
+ end
46
+ end
47
+
48
+ describe 'remove_from_index!()' do
49
+ before :each do
50
+ @post = Post.create!
51
+ @post.index!
52
+ @post.remove_from_index!
53
+ end
54
+
55
+ it 'should immediately remove the model and commit' do
56
+ Post.search.results.should be_empty
57
+ end
58
+ end
59
+
60
+ describe 'remove_all_from_index' do
61
+ before :each do
62
+ @posts = Array.new(10) { Post.create! }.each { |post| Sunspot.index(post) }
63
+ Sunspot.commit
64
+ Post.remove_all_from_index
65
+ end
66
+
67
+ it 'should not commit immediately' do
68
+ Post.search.results.to_set.should == @posts.to_set
69
+ end
70
+
71
+ it 'should remove all instances from the index' do
72
+ Sunspot.commit
73
+ Post.search.results.should be_empty
74
+ end
75
+ end
76
+
77
+ describe 'remove_all_from_index!' do
78
+ before :each do
79
+ Array.new(10) { Post.create! }.each { |post| Sunspot.index(post) }
80
+ Sunspot.commit
81
+ Post.remove_all_from_index!
82
+ end
83
+
84
+ it 'should remove all instances from the index and commit immediately' do
85
+ Post.search.results.should be_empty
86
+ end
87
+ end
88
+
89
+ describe 'search()' do
90
+ before :each do
91
+ @post = Post.create!(:title => 'Test Post')
92
+ @post.index!
93
+ end
94
+
95
+ it 'should return results specified by search' do
96
+ Post.search do
97
+ with :title, 'Test Post'
98
+ end.results.should == [@post]
99
+ end
100
+
101
+ it 'should not return results excluded by search' do
102
+ Post.search do
103
+ with :title, 'Bogus Post'
104
+ end.results.should be_empty
105
+ end
106
+
107
+ it 'should find ActiveRecord objects with an integer, not a string' do
108
+ Post.should_receive(:find).with([@post.id.to_i]).and_return([@post])
109
+ Post.search do
110
+ with :title, 'Test Post'
111
+ end.results.should == [@post]
112
+ end
113
+ end
114
+
115
+ describe 'search_ids()' do
116
+ before :each do
117
+ @posts = Array.new(2) { Post.create! }.each { |post| post.index }
118
+ Sunspot.commit
119
+ end
120
+
121
+ it 'should return IDs' do
122
+ Post.search_ids.to_set.should == @posts.map { |post| post.id }.to_set
123
+ end
124
+ end
125
+
126
+ describe 'searchable?()' do
127
+ it 'should not be true for models that have not been configured for search' do
128
+ Blog.should_not be_searchable
129
+ end
130
+
131
+ it 'should be true for models that have been configured for search' do
132
+ Post.should be_searchable
133
+ end
134
+ end
135
+
136
+ describe 'index_orphans()' do
137
+ before :each do
138
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
139
+ Sunspot.commit
140
+ @posts.first.destroy
141
+ end
142
+
143
+ it 'should return IDs of objects that are in the index but not the database' do
144
+ Post.index_orphans.should == [@posts.first.id]
145
+ end
146
+ end
147
+
148
+ describe 'clean_index_orphans()' do
149
+ before :each do
150
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
151
+ Sunspot.commit
152
+ @posts.first.destroy
153
+ end
154
+
155
+ it 'should remove orphans from the index' do
156
+ Post.clean_index_orphans
157
+ Sunspot.commit
158
+ Post.search.results.should == [@posts.last]
159
+ end
160
+ end
161
+
162
+ describe 'reindex()' do
163
+ before :each do
164
+ @posts = Array.new(2) { Post.create }
165
+ end
166
+
167
+ it 'should index all instances' do
168
+ Post.reindex(:batch_size => nil)
169
+ Sunspot.commit
170
+ Post.search.results.to_set.should == @posts.to_set
171
+ end
172
+
173
+ it 'should remove all currently indexed instances' do
174
+ old_post = Post.create!
175
+ old_post.index!
176
+ old_post.destroy
177
+ Post.reindex
178
+ Sunspot.commit
179
+ Post.search.results.to_set.should == @posts.to_set
180
+ end
181
+
182
+ end
183
+
184
+ describe 'reindex() with real data' do
185
+ before :each do
186
+ @posts = Array.new(2) { Post.create }
187
+ end
188
+
189
+ it 'should index all instances' do
190
+ Post.reindex(:batch_size => nil)
191
+ Sunspot.commit
192
+ Post.search.results.to_set.should == @posts.to_set
193
+ end
194
+
195
+ it 'should remove all currently indexed instances' do
196
+ old_post = Post.create!
197
+ old_post.index!
198
+ old_post.destroy
199
+ Post.reindex
200
+ Sunspot.commit
201
+ Post.search.results.to_set.should == @posts.to_set
202
+ end
203
+
204
+ describe "using batch sizes" do
205
+ it 'should index with a specified batch size' do
206
+ Post.reindex(:batch_size => 1)
207
+ Sunspot.commit
208
+ Post.search.results.to_set.should == @posts.to_set
209
+ end
210
+ end
211
+
212
+ end
213
+
214
+ describe "reindex()" do
215
+
216
+ before(:each) do
217
+ @posts = Array.new(10) { Post.create }
218
+ end
219
+
220
+ describe "when not using batches" do
221
+
222
+ it "should select all if the batch_size is nil" do
223
+ Post.should_receive(:all).with(:include => []).and_return([])
224
+ Post.reindex(:batch_size => nil)
225
+ end
226
+
227
+ it "should search for models with includes" do
228
+ Post.should_receive(:all).with(:include => :author).and_return([])
229
+ Post.reindex(:batch_size => nil, :include => :author)
230
+ end
231
+
232
+ end
233
+
234
+ describe "when using batches" do
235
+
236
+ it "should use the default options" do
237
+ Post.should_receive(:all).with do |params|
238
+ params[:limit].should == 500
239
+ params[:include].should == []
240
+ end.and_return(@posts)
241
+ Post.reindex
242
+ end
243
+
244
+ it "should count the number of records to index" do
245
+ Post.should_receive(:count).and_return(10)
246
+ Post.reindex
247
+ end
248
+
249
+ it "should override the batch_size" do
250
+ Post.should_receive(:all).with do |params|
251
+ params[:limit].should == 20
252
+ @posts
253
+ end.and_return(@posts)
254
+ Post.reindex(:batch_size => 20)
255
+ end
256
+
257
+ it "should set the include option" do
258
+ Post.should_receive(:all).with do |params|
259
+ params[:include].should == [{:author => :address}]
260
+ @posts
261
+ end.and_return(@posts)
262
+ Post.reindex(:include => [{:author => :address}])
263
+ end
264
+
265
+ it "should commit after indexing each batch" do
266
+ Sunspot.should_receive(:commit).twice
267
+ Post.reindex(:batch_size => 5)
268
+ end
269
+
270
+ it "should commit after indexing everything" do
271
+ Sunspot.should_receive(:commit).once
272
+ Post.reindex(:batch_commit => false)
273
+ end
274
+
275
+ end
276
+ end
277
+
278
+ end