pallan-sunspot_rails 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/LICENSE +18 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +244 -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 +283 -0
  15. data/lib/sunspot/rails/tasks.rb +31 -0
  16. data/rails/init.rb +10 -0
  17. data/spec/mock_app/app/controllers/application.rb +10 -0
  18. data/spec/mock_app/app/controllers/application_controller.rb +10 -0
  19. data/spec/mock_app/app/controllers/posts_controller.rb +6 -0
  20. data/spec/mock_app/app/models/blog.rb +2 -0
  21. data/spec/mock_app/app/models/post.rb +5 -0
  22. data/spec/mock_app/app/models/post_with_auto.rb +9 -0
  23. data/spec/mock_app/config/boot.rb +110 -0
  24. data/spec/mock_app/config/database.yml +4 -0
  25. data/spec/mock_app/config/environment.rb +41 -0
  26. data/spec/mock_app/config/environments/development.rb +27 -0
  27. data/spec/mock_app/config/environments/test.rb +27 -0
  28. data/spec/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  29. data/spec/mock_app/config/initializers/session_store.rb +15 -0
  30. data/spec/mock_app/config/routes.rb +43 -0
  31. data/spec/mock_app/config/sunspot.yml +13 -0
  32. data/spec/model_lifecycle_spec.rb +38 -0
  33. data/spec/model_spec.rb +205 -0
  34. data/spec/request_lifecycle_spec.rb +10 -0
  35. data/spec/schema.rb +14 -0
  36. data/spec/spec_helper.rb +30 -0
  37. metadata +175 -0
@@ -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,205 @@
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
+ end
107
+
108
+ describe 'search_ids()' do
109
+ before :each do
110
+ @posts = Array.new(2) { Post.create! }.each { |post| post.index }
111
+ Sunspot.commit
112
+ end
113
+
114
+ it 'should return IDs' do
115
+ Post.search_ids.to_set.should == @posts.map { |post| post.id }.to_set
116
+ end
117
+ end
118
+
119
+ describe 'searchable?()' do
120
+ it 'should not be true for models that have not been configured for search' do
121
+ Blog.should_not be_searchable
122
+ end
123
+
124
+ it 'should be true for models that have been configured for search' do
125
+ Post.should be_searchable
126
+ end
127
+ end
128
+
129
+ describe 'index_orphans()' do
130
+ before :each do
131
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
132
+ Sunspot.commit
133
+ @posts.first.destroy
134
+ end
135
+
136
+ it 'should return IDs of objects that are in the index but not the database' do
137
+ Post.index_orphans.should == [@posts.first.id]
138
+ end
139
+ end
140
+
141
+ describe 'clean_index_orphans()' do
142
+ before :each do
143
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
144
+ Sunspot.commit
145
+ @posts.first.destroy
146
+ end
147
+
148
+ it 'should remove orphans from the index' do
149
+ Post.clean_index_orphans
150
+ Sunspot.commit
151
+ Post.search.results.should == [@posts.last]
152
+ end
153
+ end
154
+
155
+ describe 'reindex()' do
156
+ before :each do
157
+ @posts = Array.new(2) { Post.create }
158
+ end
159
+
160
+ it 'should index all instances' do
161
+ Post.reindex
162
+ Sunspot.commit
163
+ Post.search.results.to_set.should == @posts.to_set
164
+ end
165
+
166
+ it 'should remove all currently indexed instances' do
167
+ old_post = Post.create!
168
+ old_post.index!
169
+ old_post.destroy
170
+ Post.reindex
171
+ Sunspot.commit
172
+ Post.search.results.to_set.should == @posts.to_set
173
+ end
174
+
175
+ describe "using batch sizes" do
176
+
177
+ it 'should index with a batch size' do
178
+ Post.reindex(1)
179
+ Sunspot.commit
180
+ Post.search.results.to_set.should == @posts.to_set
181
+ end
182
+
183
+ it "should look for find_in_batches" do
184
+ pending "Have to figure out how to remove stubs for Class Methods so this will work"
185
+ Post.stub!(:respond_to?).with(:to_ary).and_return(false)
186
+ Post.should_receive(:respond_to?).with(:find_in_batches).and_return(true)
187
+ Post.reindex(100)
188
+ end
189
+
190
+ it "should use find_in_batches" do
191
+ pending "Have to figure out how to remove stubs for Class Methods so this will work"
192
+ Post.should_receive(:find_in_batches).with(:batch_size => 100).and_return([])
193
+ Post.reindex(100)
194
+ end
195
+
196
+ it "should find all with the batch size and offset if it can't use find_by_batches" do
197
+ pending "Have to figure out how to remove stubs for Class Methods so this will work"
198
+ Post.stub!(:respond_to?).with(:to_ary).and_return(false)
199
+ Post.stub!(:respond_to?).with(:find_in_batches).and_return(false)
200
+ Post.should_receive(:all).with(:offset => 0, :limit => 100).and_return([])
201
+ Post.reindex(100)
202
+ end
203
+ end
204
+ end
205
+ 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