pduey-sunspot 1.2.1.1
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.
- data/.gitignore +12 -0
- data/Gemfile +5 -0
- data/History.txt +225 -0
- data/LICENSE +18 -0
- data/Rakefile +15 -0
- data/TODO +13 -0
- data/VERSION.yml +4 -0
- data/bin/sunspot-installer +19 -0
- data/installer/config/schema.yml +95 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot.rb +568 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/composite_setup.rb +202 -0
- data/lib/sunspot/configuration.rb +46 -0
- data/lib/sunspot/data_extractor.rb +50 -0
- data/lib/sunspot/dsl.rb +5 -0
- data/lib/sunspot/dsl/adjustable.rb +47 -0
- data/lib/sunspot/dsl/field_query.rb +279 -0
- data/lib/sunspot/dsl/fields.rb +103 -0
- data/lib/sunspot/dsl/fulltext.rb +243 -0
- data/lib/sunspot/dsl/function.rb +14 -0
- data/lib/sunspot/dsl/functional.rb +44 -0
- data/lib/sunspot/dsl/more_like_this_query.rb +56 -0
- data/lib/sunspot/dsl/paginatable.rb +28 -0
- data/lib/sunspot/dsl/query_facet.rb +36 -0
- data/lib/sunspot/dsl/restriction.rb +25 -0
- data/lib/sunspot/dsl/restriction_with_near.rb +121 -0
- data/lib/sunspot/dsl/scope.rb +217 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/dsl/standard_query.rb +121 -0
- data/lib/sunspot/field.rb +193 -0
- data/lib/sunspot/field_factory.rb +129 -0
- data/lib/sunspot/indexer.rb +131 -0
- data/lib/sunspot/installer.rb +31 -0
- data/lib/sunspot/installer/library_installer.rb +45 -0
- data/lib/sunspot/installer/schema_builder.rb +219 -0
- data/lib/sunspot/installer/solrconfig_updater.rb +76 -0
- data/lib/sunspot/installer/task_helper.rb +18 -0
- data/lib/sunspot/java.rb +8 -0
- data/lib/sunspot/query.rb +11 -0
- data/lib/sunspot/query/abstract_field_facet.rb +52 -0
- data/lib/sunspot/query/boost_query.rb +24 -0
- data/lib/sunspot/query/common_query.rb +85 -0
- data/lib/sunspot/query/composite_fulltext.rb +36 -0
- data/lib/sunspot/query/connective.rb +206 -0
- data/lib/sunspot/query/date_field_facet.rb +14 -0
- data/lib/sunspot/query/dismax.rb +128 -0
- data/lib/sunspot/query/field_facet.rb +41 -0
- data/lib/sunspot/query/filter.rb +38 -0
- data/lib/sunspot/query/function_query.rb +52 -0
- data/lib/sunspot/query/geo.rb +53 -0
- data/lib/sunspot/query/highlighting.rb +55 -0
- data/lib/sunspot/query/more_like_this.rb +61 -0
- data/lib/sunspot/query/more_like_this_query.rb +12 -0
- data/lib/sunspot/query/pagination.rb +38 -0
- data/lib/sunspot/query/query_facet.rb +16 -0
- data/lib/sunspot/query/restriction.rb +262 -0
- data/lib/sunspot/query/scope.rb +9 -0
- data/lib/sunspot/query/sort.rb +95 -0
- data/lib/sunspot/query/sort_composite.rb +33 -0
- data/lib/sunspot/query/standard_query.rb +16 -0
- data/lib/sunspot/query/text_field_boost.rb +17 -0
- data/lib/sunspot/schema.rb +151 -0
- data/lib/sunspot/search.rb +9 -0
- data/lib/sunspot/search/abstract_search.rb +335 -0
- data/lib/sunspot/search/date_facet.rb +35 -0
- data/lib/sunspot/search/facet_row.rb +27 -0
- data/lib/sunspot/search/field_facet.rb +88 -0
- data/lib/sunspot/search/highlight.rb +38 -0
- data/lib/sunspot/search/hit.rb +150 -0
- data/lib/sunspot/search/more_like_this_search.rb +31 -0
- data/lib/sunspot/search/paginated_collection.rb +55 -0
- data/lib/sunspot/search/query_facet.rb +67 -0
- data/lib/sunspot/search/standard_search.rb +21 -0
- data/lib/sunspot/session.rb +260 -0
- data/lib/sunspot/session_proxy.rb +87 -0
- data/lib/sunspot/session_proxy/abstract_session_proxy.rb +29 -0
- data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +66 -0
- data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +89 -0
- data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +43 -0
- data/lib/sunspot/session_proxy/sharding_session_proxy.rb +222 -0
- data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
- data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +37 -0
- data/lib/sunspot/setup.rb +350 -0
- data/lib/sunspot/text_field_setup.rb +29 -0
- data/lib/sunspot/type.rb +372 -0
- data/lib/sunspot/util.rb +243 -0
- data/lib/sunspot/version.rb +3 -0
- data/pduey-sunspot.gemspec +38 -0
- data/script/console +10 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/binding_spec.rb +50 -0
- data/spec/api/indexer/attributes_spec.rb +149 -0
- data/spec/api/indexer/batch_spec.rb +46 -0
- data/spec/api/indexer/dynamic_fields_spec.rb +42 -0
- data/spec/api/indexer/fixed_fields_spec.rb +57 -0
- data/spec/api/indexer/fulltext_spec.rb +43 -0
- data/spec/api/indexer/removal_spec.rb +53 -0
- data/spec/api/indexer/spec_helper.rb +1 -0
- data/spec/api/indexer_spec.rb +14 -0
- data/spec/api/query/advanced_manipulation_examples.rb +35 -0
- data/spec/api/query/connectives_examples.rb +189 -0
- data/spec/api/query/dsl_spec.rb +18 -0
- data/spec/api/query/dynamic_fields_examples.rb +165 -0
- data/spec/api/query/faceting_examples.rb +397 -0
- data/spec/api/query/fulltext_examples.rb +313 -0
- data/spec/api/query/function_spec.rb +70 -0
- data/spec/api/query/geo_examples.rb +68 -0
- data/spec/api/query/highlighting_examples.rb +223 -0
- data/spec/api/query/more_like_this_spec.rb +140 -0
- data/spec/api/query/ordering_pagination_examples.rb +95 -0
- data/spec/api/query/scope_examples.rb +275 -0
- data/spec/api/query/spec_helper.rb +1 -0
- data/spec/api/query/standard_spec.rb +28 -0
- data/spec/api/query/text_field_scoping_examples.rb +30 -0
- data/spec/api/query/types_spec.rb +20 -0
- data/spec/api/search/dynamic_fields_spec.rb +33 -0
- data/spec/api/search/faceting_spec.rb +360 -0
- data/spec/api/search/highlighting_spec.rb +69 -0
- data/spec/api/search/hits_spec.rb +131 -0
- data/spec/api/search/paginated_collection_spec.rb +26 -0
- data/spec/api/search/results_spec.rb +66 -0
- data/spec/api/search/search_spec.rb +23 -0
- data/spec/api/search/spec_helper.rb +1 -0
- data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +85 -0
- data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +30 -0
- data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +41 -0
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +77 -0
- data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
- data/spec/api/session_proxy/spec_helper.rb +9 -0
- data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +39 -0
- data/spec/api/session_spec.rb +220 -0
- data/spec/api/spec_helper.rb +3 -0
- data/spec/api/sunspot_spec.rb +18 -0
- data/spec/ext.rb +11 -0
- data/spec/helpers/indexer_helper.rb +29 -0
- data/spec/helpers/query_helper.rb +38 -0
- data/spec/helpers/search_helper.rb +80 -0
- data/spec/integration/dynamic_fields_spec.rb +57 -0
- data/spec/integration/faceting_spec.rb +238 -0
- data/spec/integration/highlighting_spec.rb +24 -0
- data/spec/integration/indexing_spec.rb +33 -0
- data/spec/integration/keyword_search_spec.rb +317 -0
- data/spec/integration/local_search_spec.rb +64 -0
- data/spec/integration/more_like_this_spec.rb +43 -0
- data/spec/integration/scoped_search_spec.rb +354 -0
- data/spec/integration/spec_helper.rb +7 -0
- data/spec/integration/stored_fields_spec.rb +12 -0
- data/spec/integration/test_pagination.rb +32 -0
- data/spec/mocks/adapters.rb +32 -0
- data/spec/mocks/blog.rb +3 -0
- data/spec/mocks/comment.rb +21 -0
- data/spec/mocks/connection.rb +126 -0
- data/spec/mocks/mock_adapter.rb +30 -0
- data/spec/mocks/mock_class_sharding_session_proxy.rb +24 -0
- data/spec/mocks/mock_record.rb +52 -0
- data/spec/mocks/mock_sharding_session_proxy.rb +15 -0
- data/spec/mocks/photo.rb +11 -0
- data/spec/mocks/post.rb +85 -0
- data/spec/mocks/super_class.rb +2 -0
- data/spec/mocks/user.rb +13 -0
- data/spec/spec_helper.rb +28 -0
- data/tasks/rdoc.rake +27 -0
- data/tasks/schema.rake +19 -0
- data/tasks/todo.rake +4 -0
- metadata +369 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'hits', :type => :search do
|
|
4
|
+
it 'should return hits without loading instances' do
|
|
5
|
+
post_1, post_2 = Array.new(2) { Post.new }
|
|
6
|
+
stub_results(post_1, post_2)
|
|
7
|
+
%w(load load_all).each do |message|
|
|
8
|
+
MockAdapter::DataAccessor.should_not_receive(message)
|
|
9
|
+
end
|
|
10
|
+
session.search(Post).hits.map do |hit|
|
|
11
|
+
[hit.class_name, hit.primary_key]
|
|
12
|
+
end.should == [['Post', post_1.id.to_s], ['Post', post_2.id.to_s]]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'returns search total as attribute of hits' do
|
|
16
|
+
stub_results(Post.new, 4)
|
|
17
|
+
session.search(Post) do
|
|
18
|
+
paginate(:page => 1)
|
|
19
|
+
end.hits.total_entries.should == 4
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'returns search total as attribute of verified hits' do
|
|
23
|
+
stub_results(Post.new, 4)
|
|
24
|
+
session.search(Post) do
|
|
25
|
+
paginate(:page => 1)
|
|
26
|
+
end.hits(:verify => true).total_entries.should == 4
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should return instance from hit' do
|
|
30
|
+
posts = Array.new(2) { Post.new }
|
|
31
|
+
stub_results(*posts)
|
|
32
|
+
session.search(Post).hits.first.instance.should == posts.first
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should return the instance primary key when you use it as a param' do
|
|
36
|
+
posts = Array.new(2) { Post.new }
|
|
37
|
+
stub_results(*posts)
|
|
38
|
+
session.search(Post).hits.first.to_param.should == posts.first.id.to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'should provide iterator over hits with instances' do
|
|
42
|
+
posts = Array.new(2) { Post.new }
|
|
43
|
+
stub_results(*posts)
|
|
44
|
+
search = session.search(Post)
|
|
45
|
+
hits, results = [], []
|
|
46
|
+
search.each_hit_with_result do |hit, result|
|
|
47
|
+
hits << hit
|
|
48
|
+
results << result
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'should hydrate all hits when an instance is requested from a hit' do
|
|
53
|
+
posts = Array.new(2) { Post.new }
|
|
54
|
+
stub_results(*posts)
|
|
55
|
+
search = session.search(Post)
|
|
56
|
+
search.hits.first.instance
|
|
57
|
+
%w(load load_all).each do |message|
|
|
58
|
+
MockAdapter::DataAccessor.should_not_receive(message)
|
|
59
|
+
end
|
|
60
|
+
search.hits.last.instance.should == posts.last
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'should return only hits whose referenced object exists in the data store if :verify option passed' do
|
|
64
|
+
posts = Array.new(2) { Post.new }
|
|
65
|
+
posts.last.destroy
|
|
66
|
+
stub_results(*posts)
|
|
67
|
+
search = session.search(Post)
|
|
68
|
+
search.hits(:verify => true).map { |hit| hit.instance }.should == posts[0..0]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'should return verified and unverified hits from the same search' do
|
|
72
|
+
posts = Array.new(2) { Post.new }
|
|
73
|
+
posts.last.destroy
|
|
74
|
+
stub_results(*posts)
|
|
75
|
+
search = session.search(Post)
|
|
76
|
+
search.hits(:verify => true).map { |hit| hit.instance }.should == posts[0..0]
|
|
77
|
+
search.hits.map { |hit| hit.instance }.should == [posts.first, nil]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'should attach score to hits' do
|
|
81
|
+
stub_full_results('instance' => Post.new, 'score' => 1.23)
|
|
82
|
+
session.search(Post).hits.first.score.should == 1.23
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'should return stored field values in hits' do
|
|
86
|
+
stub_full_results('instance' => Post.new, 'title_ss' => 'Title')
|
|
87
|
+
session.search(Post).hits.first.stored(:title).should == 'Title'
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'should return stored field values for searches against multiple types' do
|
|
91
|
+
stub_full_results('instance' => Post.new, 'title_ss' => 'Title')
|
|
92
|
+
session.search(Post, Namespaced::Comment).hits.first.stored(:title).should == 'Title'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'should return stored field values for searches against base type when subtype matches' do
|
|
96
|
+
class SubclassedPost < Post; end;
|
|
97
|
+
stub_full_results('instance' => SubclassedPost.new, 'title_ss' => 'Title')
|
|
98
|
+
session.search(Post).hits.first.stored(:title).should == 'Title'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'should return stored text fields' do
|
|
102
|
+
stub_full_results('instance' => Post.new, 'body_textsv' => 'Body')
|
|
103
|
+
session.search(Post, Namespaced::Comment).hits.first.stored(:body).should == 'Body'
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'should return stored boolean fields' do
|
|
107
|
+
stub_full_results('instance' => Post.new, 'featured_bs' => true)
|
|
108
|
+
session.search(Post, Namespaced::Comment).hits.first.stored(:featured).should be_true
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'should return stored boolean fields that evaluate to false' do
|
|
112
|
+
stub_full_results('instance' => Post.new, 'featured_bs' => false)
|
|
113
|
+
session.search(Post, Namespaced::Comment).hits.first.stored(:featured).should == false
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'should return stored dynamic fields' do
|
|
117
|
+
stub_full_results('instance' => Post.new, 'custom_string:test_ss' => 'Custom')
|
|
118
|
+
session.search(Post, Namespaced::Comment).hits.first.stored(:custom_string, :test).should == 'Custom'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'should typecast stored field values in hits' do
|
|
122
|
+
time = Time.utc(2008, 7, 8, 2, 45)
|
|
123
|
+
stub_full_results('instance' => Post.new, 'last_indexed_at_ds' => time.xmlschema)
|
|
124
|
+
session.search(Post).hits.first.stored(:last_indexed_at).should == time
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'should return stored values for multi-valued fields' do
|
|
128
|
+
stub_full_results('instance' => User.new, 'role_ids_ims' => %w(1 4 5))
|
|
129
|
+
session.search(User).hits.first.stored(:role_ids).should == [1, 4, 5]
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe "PaginatedCollection" do
|
|
4
|
+
subject { Sunspot::Search::PaginatedCollection.new [], 1, 10, 20 }
|
|
5
|
+
|
|
6
|
+
it { subject.should be_an(Array) }
|
|
7
|
+
|
|
8
|
+
context "behaves like a WillPaginate::Collection" do
|
|
9
|
+
it { subject.total_entries.should eql(20) }
|
|
10
|
+
it { subject.total_pages.should eql(2) }
|
|
11
|
+
it { subject.current_page.should eql(1) }
|
|
12
|
+
it { subject.per_page.should eql(10) }
|
|
13
|
+
it { subject.previous_page.should be_nil }
|
|
14
|
+
it { subject.next_page.should eql(2) }
|
|
15
|
+
it { subject.out_of_bounds?.should_not be_true }
|
|
16
|
+
it { subject.offset.should eql(0) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "behaves like Kaminari" do
|
|
20
|
+
it { subject.total_count.should eql(20) }
|
|
21
|
+
it { subject.num_pages.should eql(2) }
|
|
22
|
+
it { subject.limit_value.should eql(10) }
|
|
23
|
+
it { subject.first_page?.should be_true }
|
|
24
|
+
it { subject.last_page?.should_not be_true }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'search results', :type => :search do
|
|
4
|
+
it 'loads single result' do
|
|
5
|
+
post = Post.new
|
|
6
|
+
stub_results(post)
|
|
7
|
+
session.search(Post).results.should == [post]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'loads multiple results in order' do
|
|
11
|
+
post_1, post_2 = Post.new, Post.new
|
|
12
|
+
stub_results(post_1, post_2)
|
|
13
|
+
session.search(Post).results.should == [post_1, post_2]
|
|
14
|
+
stub_results(post_2, post_1)
|
|
15
|
+
session.search(Post).results.should == [post_2, post_1]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# This is a reduction of a crazy bug I found in production where some hits
|
|
19
|
+
# were inexplicably not being populated.
|
|
20
|
+
it 'properly loads results of multiple classes that have the same primary key' do
|
|
21
|
+
Post.reset!
|
|
22
|
+
Namespaced::Comment.reset!
|
|
23
|
+
results = [Post.new, Namespaced::Comment.new]
|
|
24
|
+
stub_results(*results)
|
|
25
|
+
session.search(Post, Namespaced::Comment).results.should == results
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'gracefully returns empty results when response is nil' do
|
|
29
|
+
stub_nil_results
|
|
30
|
+
session.search(Post).results.should == []
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'returns search total as attribute of results' do
|
|
34
|
+
stub_results(Post.new, 4)
|
|
35
|
+
session.search(Post) do
|
|
36
|
+
paginate(:page => 1)
|
|
37
|
+
end.results.total_entries.should == 4
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'returns total' do
|
|
41
|
+
stub_results(Post.new, Post.new, 4)
|
|
42
|
+
session.search(Post) { paginate(:page => 1) }.total.should == 4
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'returns total for nil search' do
|
|
46
|
+
stub_nil_results
|
|
47
|
+
session.search(Post).total.should == 0
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'returns available results if some results are not available from data store' do
|
|
51
|
+
posts = [Post.new, Post.new]
|
|
52
|
+
posts.last.destroy
|
|
53
|
+
stub_results(*posts)
|
|
54
|
+
session.search(Post).results.should == posts[0..0]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'does not attempt to query the data store more than once when results are unavailable' do
|
|
58
|
+
posts = [Post.new, Post.new]
|
|
59
|
+
posts.each { |post| post.destroy }
|
|
60
|
+
stub_results(*posts)
|
|
61
|
+
search = session.search(Post) do
|
|
62
|
+
data_accessor_for(Post).should_receive(:load_all).once.and_return([])
|
|
63
|
+
end
|
|
64
|
+
search.results.should == []
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Sunspot::Search do
|
|
4
|
+
it 'should allow access to the data accessor' do
|
|
5
|
+
stub_results(posts = Post.new)
|
|
6
|
+
search = session.search Post do
|
|
7
|
+
data_accessor_for(Post).custom_title = 'custom title'
|
|
8
|
+
end
|
|
9
|
+
search.results.first.title.should == 'custom title'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should re-execute search' do
|
|
13
|
+
post_1, post_2 = Post.new, Post.new
|
|
14
|
+
|
|
15
|
+
stub_results(post_1)
|
|
16
|
+
search = session.search Post
|
|
17
|
+
search.results.should == [post_1]
|
|
18
|
+
|
|
19
|
+
stub_results(post_2)
|
|
20
|
+
search.execute!
|
|
21
|
+
search.results.should == [post_2]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.join(File.dirname(__FILE__), '..'))
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Sunspot::SessionProxy::ClassShardingSessionProxy do
|
|
4
|
+
before do
|
|
5
|
+
@proxy = MockClassShardingSessionProxy.new(session)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
[:index, :index!, :remove, :remove!].each do |method|
|
|
9
|
+
it "should delegate #{method} to appropriate shard" do
|
|
10
|
+
post = Post.new
|
|
11
|
+
photo = Photo.new
|
|
12
|
+
@proxy.post_session.should_receive(method).with([post])
|
|
13
|
+
@proxy.photo_session.should_receive(method).with([photo])
|
|
14
|
+
@proxy.send(method, post)
|
|
15
|
+
@proxy.send(method, photo)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
[:remove_by_id, :remove_by_id!].each do |method|
|
|
20
|
+
it "should delegate #{method} to appropriate shard" do
|
|
21
|
+
@proxy.post_session.should_receive(method).with(Post, 1)
|
|
22
|
+
@proxy.photo_session.should_receive(method).with(Photo, 1)
|
|
23
|
+
@proxy.send(method, Post, 1)
|
|
24
|
+
@proxy.send(method, Photo, 1)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
[:remove_all, :remove_all!].each do |method|
|
|
29
|
+
it "should delegate #{method} with argument to appropriate shard" do
|
|
30
|
+
@proxy.post_session.should_receive(method).with(Post)
|
|
31
|
+
@proxy.photo_session.should_receive(method).with(Photo)
|
|
32
|
+
@proxy.send(method, Post)
|
|
33
|
+
@proxy.send(method, Photo)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should delegate #{method} without argument to all shards" do
|
|
37
|
+
@proxy.post_session.should_receive(method)
|
|
38
|
+
@proxy.photo_session.should_receive(method)
|
|
39
|
+
@proxy.send(method)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
[:commit, :commit_if_dirty, :commit_if_delete_dirty, :optimize].each do |method|
|
|
44
|
+
it "should delegate #{method} to all sessions" do
|
|
45
|
+
[@proxy.post_session, @proxy.photo_session].each do |session|
|
|
46
|
+
session.should_receive(method)
|
|
47
|
+
end
|
|
48
|
+
@proxy.send(method)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should not support the :batch method" do
|
|
53
|
+
lambda { @proxy.batch }.should raise_error(Sunspot::SessionProxy::NotSupportedError)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should delegate new_search to search session, adding in shards parameter" do
|
|
57
|
+
search = @proxy.new_search(Post)
|
|
58
|
+
search.query[:shards].should ==
|
|
59
|
+
'http://photos.solr.local/solr,http://posts.solr.local/solr'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should delegate search to search session, adding in shards parameter" do
|
|
63
|
+
@proxy.search(Post)
|
|
64
|
+
connection.should have_last_search_with(
|
|
65
|
+
:shards => 'http://photos.solr.local/solr,http://posts.solr.local/solr'
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
[:dirty, :delete_dirty].each do |method|
|
|
70
|
+
it "should be dirty if any of the sessions are dirty" do
|
|
71
|
+
@proxy.post_session.stub!(:"#{method}?").and_return(true)
|
|
72
|
+
@proxy.should send("be_#{method}")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should not be dirty if none of the sessions are dirty" do
|
|
76
|
+
@proxy.should_not send("be_#{method}")
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should raise a NotSupportedError when :config is called" do
|
|
81
|
+
lambda { @proxy.config }.should raise_error(Sunspot::SessionProxy::NotSupportedError)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it_should_behave_like 'session proxy'
|
|
85
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Sunspot::SessionProxy::ShardingSessionProxy do
|
|
4
|
+
before do
|
|
5
|
+
search_session = Sunspot::Session.new
|
|
6
|
+
@sessions = Array.new(2) { Sunspot::Session.new }
|
|
7
|
+
@proxy = Sunspot::SessionProxy::IdShardingSessionProxy.new(search_session, @sessions)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
[:index, :index!, :remove, :remove!].each do |method|
|
|
11
|
+
it "should delegate #{method} to appropriate shard" do
|
|
12
|
+
posts = [Post.new(:id => 2), Post.new(:id => 1)]
|
|
13
|
+
@proxy.sessions[0].should_receive(method).with([posts[0]])
|
|
14
|
+
@proxy.sessions[1].should_receive(method).with([posts[1]])
|
|
15
|
+
@proxy.send(method, posts[0])
|
|
16
|
+
@proxy.send(method, posts[1])
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
[:remove_by_id, :remove_by_id!].each do |method|
|
|
21
|
+
it "should delegate #{method} to appropriate session" do
|
|
22
|
+
@proxy.sessions[0].should_receive(method).with(Post, 2)
|
|
23
|
+
@proxy.sessions[1].should_receive(method).with(Post, 1)
|
|
24
|
+
@proxy.send(method, Post, 1)
|
|
25
|
+
@proxy.send(method, Post, 2)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it_should_behave_like 'session proxy'
|
|
30
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Sunspot::SessionProxy::MasterSlaveSessionProxy do
|
|
4
|
+
before :each do
|
|
5
|
+
@master_session, @slave_session = Sunspot::Session.new, Sunspot::Session.new
|
|
6
|
+
@proxy = Sunspot::SessionProxy::MasterSlaveSessionProxy.new(@master_session, @slave_session)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
{
|
|
10
|
+
:master_session => Sunspot::Session.public_instance_methods(false) - [:search, 'search', :new_search, 'new_search', :more_like_this, 'more_like_this', :new_more_like_this, 'new_more_like_this', :config, 'config'],
|
|
11
|
+
:slave_session => [:search, :new_search, :more_like_this, :new_more_like_this]
|
|
12
|
+
}.each_pair do |delegate, methods|
|
|
13
|
+
methods.each do |method|
|
|
14
|
+
it "should delegate #{method} to #{delegate}" do
|
|
15
|
+
args = Array.new(Sunspot::Session.instance_method(method).arity.abs) do
|
|
16
|
+
stub('arg')
|
|
17
|
+
end
|
|
18
|
+
instance_variable_get(:"@#{delegate}").should_receive(method).with(*args)
|
|
19
|
+
@proxy.send(method, *args)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should return master session config by default' do
|
|
25
|
+
@proxy.config.should eql(@master_session.config)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should return master session config when specified' do
|
|
29
|
+
@proxy.config(:master).should eql(@master_session.config)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should return slave session config when specified' do
|
|
33
|
+
@proxy.config(:slave).should eql(@slave_session.config)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should raise ArgumentError when bogus config specified' do
|
|
37
|
+
lambda { @proxy.config(:bogus) }.should raise_error
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it_should_behave_like 'session proxy'
|
|
41
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Sunspot::SessionProxy::ShardingSessionProxy do
|
|
4
|
+
before do
|
|
5
|
+
@proxy = MockShardingSessionProxy.new(session)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
[:index, :index!, :remove, :remove!].each do |method|
|
|
9
|
+
it "should delegate #{method} to appropriate shard" do
|
|
10
|
+
posts = [Post.new(:blog_id => 2), Post.new(:blog_id => 3)]
|
|
11
|
+
@proxy.sessions[0].should_receive(method).with([posts[0]])
|
|
12
|
+
@proxy.sessions[1].should_receive(method).with([posts[1]])
|
|
13
|
+
@proxy.send(method, posts[0])
|
|
14
|
+
@proxy.send(method, posts[1])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
[:remove_by_id, :remove_by_id!].each do |method|
|
|
19
|
+
it "should raise NotSupportedError when #{method} called" do
|
|
20
|
+
lambda { @proxy.send(method, Post, 1) }.should raise_error(Sunspot::SessionProxy::NotSupportedError)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
[:remove_all, :remove_all!].each do |method|
|
|
25
|
+
it "should raise NotSupportedError when #{method} called with argument" do
|
|
26
|
+
lambda { @proxy.send(method, Post) }.should raise_error(Sunspot::SessionProxy::NotSupportedError)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should delegate #{method} without argument to all shards" do
|
|
30
|
+
@proxy.sessions.each { |session| session.should_receive(method) }
|
|
31
|
+
@proxy.send(method)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
[:commit, :commit_if_dirty, :commit_if_delete_dirty, :optimize].each do |method|
|
|
36
|
+
it "should delegate #{method} to all sessions" do
|
|
37
|
+
@proxy.sessions.each do |session|
|
|
38
|
+
session.should_receive(method)
|
|
39
|
+
end
|
|
40
|
+
@proxy.send(method)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should not support the :batch method" do
|
|
45
|
+
lambda { @proxy.batch }.should raise_error(Sunspot::SessionProxy::NotSupportedError)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should delegate new_search to search session, adding in shards parameter" do
|
|
49
|
+
search = @proxy.new_search(Post)
|
|
50
|
+
search.query[:shards].should ==
|
|
51
|
+
'http://localhost:8980/solr,http://localhost:8981/solr'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should delegate search to search session, adding in shards parameter" do
|
|
55
|
+
@proxy.search(Post)
|
|
56
|
+
connection.should have_last_search_with(
|
|
57
|
+
:shards => 'http://localhost:8980/solr,http://localhost:8981/solr'
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
[:dirty, :delete_dirty].each do |method|
|
|
62
|
+
it "should be dirty if any of the sessions are dirty" do
|
|
63
|
+
@proxy.sessions[0].stub!(:"#{method}?").and_return(true)
|
|
64
|
+
@proxy.should send("be_#{method}")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should not be dirty if none of the sessions are dirty" do
|
|
68
|
+
@proxy.should_not send("be_#{method}")
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should raise a NotSupportedError when :config is called" do
|
|
73
|
+
lambda { @proxy.config }.should raise_error(Sunspot::SessionProxy::NotSupportedError)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it_should_behave_like 'session proxy'
|
|
77
|
+
end
|