adamsalter-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/adapters.rb +54 -0
  11. data/lib/sunspot/rails/configuration.rb +151 -0
  12. data/lib/sunspot/rails/request_lifecycle.rb +18 -0
  13. data/lib/sunspot/rails/searchable.rb +304 -0
  14. data/lib/sunspot/rails/tasks.rb +47 -0
  15. data/lib/sunspot/rails.rb +11 -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 +180 -0
@@ -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
@@ -0,0 +1,10 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'request lifecycle', :type => :controller do
4
+ controller_name :posts
5
+
6
+ it 'should automatically commit after each action' do
7
+ post :create, :post => { :title => 'Test 1' }
8
+ PostWithAuto.search { with :title, 'Test 1' }.results.should_not be_empty
9
+ end
10
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,14 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :posts, :force => true do |t|
3
+ t.string :title
4
+ t.text :body
5
+ t.references :blog
6
+ t.timestamps
7
+ end
8
+
9
+ create_table :blogs, :force => true do |t|
10
+ t.string :name
11
+ t.string :subdomain
12
+ t.timestamps
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+ ENV['RAILS_ROOT'] ||= File.join(File.dirname(__FILE__), 'mock_app')
3
+
4
+ require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config', 'environment.rb'))
5
+
6
+ require 'spec'
7
+ require 'spec/rails'
8
+ require 'ruby-debug' unless RUBY_VERSION =~ /1.9/
9
+
10
+ def load_schema
11
+ stdout = $stdout
12
+ $stdout = StringIO.new # suppress output while building the schema
13
+ load File.join(File.dirname(__FILE__), 'schema.rb')
14
+ $stdout = stdout
15
+ end
16
+
17
+ def silence_stderr(&block)
18
+ stderr = $stderr
19
+ $stderr = StringIO.new
20
+ yield
21
+ $stderr = stderr
22
+ end
23
+
24
+ Spec::Runner.configure do |config|
25
+ config.before(:each) do
26
+ Sunspot.remove_all
27
+ Sunspot.commit
28
+ load_schema
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,180 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adamsalter-sunspot_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.4
5
+ platform: ruby
6
+ authors:
7
+ - Mat Brown
8
+ - Peer Allan
9
+ - Michael Moen
10
+ - Benjamin Krause
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2009-07-23 00:00:00 -07:00
16
+ default_executable:
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: rails
20
+ type: :runtime
21
+ version_requirement:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: "2.1"
27
+ version:
28
+ - !ruby/object:Gem::Dependency
29
+ name: escape
30
+ type: :runtime
31
+ version_requirement:
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.0.4
37
+ version:
38
+ - !ruby/object:Gem::Dependency
39
+ name: outoftime-sunspot
40
+ type: :runtime
41
+ version_requirement:
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 0.8.2
47
+ version:
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ type: :development
51
+ version_requirement:
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: "1.2"
57
+ version:
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec-rails
60
+ type: :development
61
+ version_requirement:
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: "1.2"
67
+ version:
68
+ - !ruby/object:Gem::Dependency
69
+ name: ruby-debug
70
+ type: :development
71
+ version_requirement:
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: "0.10"
77
+ version:
78
+ - !ruby/object:Gem::Dependency
79
+ name: technicalpickles-jeweler
80
+ type: :development
81
+ version_requirement:
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: "1.0"
87
+ version:
88
+ description: Rails integration for the Sunspot Solr search library
89
+ email: mat@patch.com
90
+ executables: []
91
+
92
+ extensions: []
93
+
94
+ extra_rdoc_files:
95
+ - LICENSE
96
+ - README.rdoc
97
+ files:
98
+ - LICENSE
99
+ - MIT-LICENSE
100
+ - README.rdoc
101
+ - Rakefile
102
+ - VERSION.yml
103
+ - dev_tasks/gemspec.rake
104
+ - dev_tasks/rdoc.rake
105
+ - dev_tasks/todo.rake
106
+ - install.rb
107
+ - lib/sunspot/rails.rb
108
+ - lib/sunspot/rails/adapters.rb
109
+ - lib/sunspot/rails/configuration.rb
110
+ - lib/sunspot/rails/request_lifecycle.rb
111
+ - lib/sunspot/rails/searchable.rb
112
+ - lib/sunspot/rails/tasks.rb
113
+ - rails/init.rb
114
+ - spec/configuration_spec.rb
115
+ - spec/mock_app/app/controllers/application.rb
116
+ - spec/mock_app/app/controllers/application_controller.rb
117
+ - spec/mock_app/app/controllers/posts_controller.rb
118
+ - spec/mock_app/app/models/blog.rb
119
+ - spec/mock_app/app/models/post.rb
120
+ - spec/mock_app/app/models/post_with_auto.rb
121
+ - spec/mock_app/config/boot.rb
122
+ - spec/mock_app/config/database.yml
123
+ - spec/mock_app/config/environment.rb
124
+ - spec/mock_app/config/environments/development.rb
125
+ - spec/mock_app/config/environments/test.rb
126
+ - spec/mock_app/config/initializers/new_rails_defaults.rb
127
+ - spec/mock_app/config/initializers/session_store.rb
128
+ - spec/mock_app/config/routes.rb
129
+ - spec/mock_app/config/sunspot.yml
130
+ - spec/model_lifecycle_spec.rb
131
+ - spec/model_spec.rb
132
+ - spec/request_lifecycle_spec.rb
133
+ - spec/schema.rb
134
+ - spec/spec_helper.rb
135
+ has_rdoc: true
136
+ homepage: http://github.com/outoftime/sunspot_rails
137
+ post_install_message:
138
+ rdoc_options:
139
+ - --charset=UTF-8
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: "0"
147
+ version:
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: "0"
153
+ version:
154
+ requirements: []
155
+
156
+ rubyforge_project:
157
+ rubygems_version: 1.2.0
158
+ signing_key:
159
+ specification_version: 3
160
+ summary: Rails integration for the Sunspot Solr search library
161
+ test_files:
162
+ - spec/spec_helper.rb
163
+ - spec/configuration_spec.rb
164
+ - spec/model_lifecycle_spec.rb
165
+ - spec/schema.rb
166
+ - spec/model_spec.rb
167
+ - spec/mock_app/app/controllers/posts_controller.rb
168
+ - spec/mock_app/app/controllers/application_controller.rb
169
+ - spec/mock_app/app/controllers/application.rb
170
+ - spec/mock_app/app/models/blog.rb
171
+ - spec/mock_app/app/models/post_with_auto.rb
172
+ - spec/mock_app/app/models/post.rb
173
+ - spec/mock_app/config/environment.rb
174
+ - spec/mock_app/config/initializers/session_store.rb
175
+ - spec/mock_app/config/initializers/new_rails_defaults.rb
176
+ - spec/mock_app/config/environments/development.rb
177
+ - spec/mock_app/config/environments/test.rb
178
+ - spec/mock_app/config/routes.rb
179
+ - spec/mock_app/config/boot.rb
180
+ - spec/request_lifecycle_spec.rb