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,38 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "sunspot/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "pduey-sunspot"
|
|
7
|
+
s.version = Sunspot::VERSION + ".1"
|
|
8
|
+
s.platform = Gem::Platform::RUBY
|
|
9
|
+
s.authors = ['Mat Brown', 'Peer Allan', 'Dmitriy Dzema', 'Benjamin Krause', 'Marcel de Graaf', 'Brandon Keepers', 'Peter Berkenbosch',
|
|
10
|
+
'Brian Atkinson', 'Tom Coleman', 'Matt Mitchell', 'Nathan Beyer', 'Kieran Topping', 'Nicolas Braem', 'Jeremy Ashkenas',
|
|
11
|
+
'Dylan Vaughn', 'Brian Durand', 'Sam Granieri', 'Nick Zadrozny', 'Jason Ronallo']
|
|
12
|
+
s.email = ["pduey@acm.org"]
|
|
13
|
+
s.homepage = "https://github.com/pduey/sunspot"
|
|
14
|
+
s.summary = 'Library for expressive, powerful interaction with the Solr search engine'
|
|
15
|
+
s.description = <<-TEXT
|
|
16
|
+
Sunspot is a library providing a powerful, all-ruby API for the Solr search engine. Sunspot manages the configuration of persistent
|
|
17
|
+
Ruby classes for search and indexing and exposes Solr's most powerful features through a collection of DSLs. Complex search operations
|
|
18
|
+
can be performed without hand-writing any boolean queries or building Solr parameters by hand.
|
|
19
|
+
TEXT
|
|
20
|
+
|
|
21
|
+
s.rubyforge_project = "sunspot"
|
|
22
|
+
|
|
23
|
+
s.files = `git ls-files`.split("\n")
|
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
26
|
+
s.require_paths = ["lib"]
|
|
27
|
+
|
|
28
|
+
s.add_dependency 'rsolr', '1.0.2'
|
|
29
|
+
s.add_dependency 'escape', '0.0.4'
|
|
30
|
+
s.add_dependency 'pr_geohash', '~> 1.0'
|
|
31
|
+
|
|
32
|
+
s.add_development_dependency 'rspec', '~> 1.1'
|
|
33
|
+
s.add_development_dependency 'hanna'
|
|
34
|
+
|
|
35
|
+
s.rdoc_options << '--webcvs=http://github.com/outoftime/sunspot/tree/master/%s' <<
|
|
36
|
+
'--title' << 'Sunspot - Solr-powered search for Ruby objects - API Documentation' <<
|
|
37
|
+
'--main' << 'README.rdoc'
|
|
38
|
+
end
|
data/script/console
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Sunspot::Adapters::InstanceAdapter do
|
|
4
|
+
it "finds adapter by superclass" do
|
|
5
|
+
Sunspot::Adapters::InstanceAdapter::for(Model).should be(AbstractModelInstanceAdapter)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "finds adapter by mixin" do
|
|
9
|
+
Sunspot::Adapters::InstanceAdapter::for(MixModel).should be(MixInModelInstanceAdapter)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'throws NoAdapterError if anonymous module passed in' do
|
|
13
|
+
lambda do
|
|
14
|
+
Sunspot::Adapters::InstanceAdapter::for(Module.new)
|
|
15
|
+
end.should raise_error(Sunspot::NoAdapterError)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe Sunspot::Adapters::DataAccessor do
|
|
20
|
+
it "finds adapter by superclass" do
|
|
21
|
+
Sunspot::Adapters::DataAccessor::for(Model).should be(AbstractModelDataAccessor)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "finds adapter by mixin" do
|
|
25
|
+
Sunspot::Adapters::DataAccessor::for(MixModel).should be(MixInModelDataAccessor)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'throws NoAdapterError if anonymous module passed in' do
|
|
29
|
+
lambda do
|
|
30
|
+
Sunspot::Adapters::DataAccessor::for(Module.new)
|
|
31
|
+
end.should raise_error(Sunspot::NoAdapterError)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe "DSL bindings" do
|
|
4
|
+
it 'should give access to calling context\'s methods in search DSL' do
|
|
5
|
+
value = nil
|
|
6
|
+
session.search(Post) do
|
|
7
|
+
value = test_method
|
|
8
|
+
end
|
|
9
|
+
value.should == 'value'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should give access to calling context\'s id method in search DSL' do
|
|
13
|
+
value = nil
|
|
14
|
+
session.search(Post) do
|
|
15
|
+
value = id
|
|
16
|
+
end
|
|
17
|
+
value.should == 16
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should give access to calling context\'s methods in nested DSL block' do
|
|
21
|
+
value = nil
|
|
22
|
+
session.search(Post) do
|
|
23
|
+
any_of do
|
|
24
|
+
value = test_method
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
value.should == 'value'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should give access to calling context\'s methods in double-nested DSL block' do
|
|
31
|
+
value = nil
|
|
32
|
+
session.search(Post) do
|
|
33
|
+
any_of do
|
|
34
|
+
all_of do
|
|
35
|
+
value = test_method
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def test_method
|
|
44
|
+
'value'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def id
|
|
48
|
+
16
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
require 'bigdecimal'
|
|
3
|
+
|
|
4
|
+
describe 'indexing attribute fields', :type => :indexer do
|
|
5
|
+
it 'should correctly index a stored string attribute field' do
|
|
6
|
+
session.index(post(:title => 'A Title'))
|
|
7
|
+
connection.should have_add_with(:title_ss => 'A Title')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'should correctly index an integer attribute field' do
|
|
11
|
+
session.index(post(:blog_id => 4))
|
|
12
|
+
connection.should have_add_with(:blog_id_i => '4')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should correctly index a long attribute field' do
|
|
16
|
+
session.index(Namespaced::Comment.new(:hash => 2**30))
|
|
17
|
+
connection.should have_add_with(:hash_l => '1073741824')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should correctly index a float attribute field' do
|
|
21
|
+
session.index(post(:ratings_average => 2.23))
|
|
22
|
+
connection.should have_add_with(:average_rating_ft => '2.23')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should correctly index a double attribute field' do
|
|
26
|
+
session.index(Namespaced::Comment.new(:average_rating => 2.23))
|
|
27
|
+
connection.should have_add_with(:average_rating_e => '2.23')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should correctly index a trie integer attribute field' do
|
|
31
|
+
session.index(Photo.new(:size => 104856))
|
|
32
|
+
connection.should have_add_with(:size_it => '104856')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should correctly index a trie float attribute field' do
|
|
36
|
+
session.index(Photo.new(:average_rating => 2.23))
|
|
37
|
+
connection.should have_add_with(:average_rating_ft => '2.23')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'should correctly index a trie time attribute field' do
|
|
41
|
+
session.index(Photo.new(:created_at => Time.parse('2009-12-16 15:00:00 -0400')))
|
|
42
|
+
connection.should have_add_with(:created_at_dt => '2009-12-16T19:00:00Z')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'should allow indexing by a multiple-value field' do
|
|
46
|
+
session.index(post(:category_ids => [3, 14]))
|
|
47
|
+
connection.should have_add_with(:category_ids_im => ['3', '14'])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should not index a single-value field with newlines as multiple' do
|
|
51
|
+
session.index(post(:title => "Multi\nLine"))
|
|
52
|
+
connection.adds.last.first.field_by_name(:title_ss).value.should == "Multi\nLine"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'should correctly index a time field' do
|
|
56
|
+
session.index(
|
|
57
|
+
post(:published_at => Time.parse('1983-07-08 05:00:00 -0400'))
|
|
58
|
+
)
|
|
59
|
+
connection.should have_add_with(:published_at_dt => '1983-07-08T09:00:00Z')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'should correctly index a time field that\'s after 32-bit Y2K' do
|
|
63
|
+
session.index(
|
|
64
|
+
post(:published_at => DateTime.parse('2050-07-08 05:00:00 -0400'))
|
|
65
|
+
)
|
|
66
|
+
connection.should have_add_with(:published_at_dt => '2050-07-08T09:00:00Z')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'should correctly index a date field' do
|
|
70
|
+
session.index(post(:expire_date => Date.new(2009, 07, 13)))
|
|
71
|
+
connection.should have_add_with(:expire_date_d => '2009-07-13T00:00:00Z')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'should correctly index a boolean field' do
|
|
75
|
+
session.index(post(:featured => true))
|
|
76
|
+
connection.should have_add_with(:featured_bs => 'true')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'should correctly index a false boolean field' do
|
|
80
|
+
session.index(post(:featured => false))
|
|
81
|
+
connection.should have_add_with(:featured_bs => 'false')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'should not index a nil boolean field' do
|
|
85
|
+
session.index(post)
|
|
86
|
+
connection.should_not have_add_with(:featured_bs)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'should index latitude and longitude as a pair' do
|
|
90
|
+
session.index(post(:coordinates => Sunspot::Util::Coordinates.new(40.7, -73.5)))
|
|
91
|
+
connection.should have_add_with(:coordinates_s => 'dr5xx3nytvgs')
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'should index latitude and longitude passed as non-Floats' do
|
|
95
|
+
coordinates = Sunspot::Util::Coordinates.new(
|
|
96
|
+
BigDecimal.new('40.7'), BigDecimal.new('-73.5'))
|
|
97
|
+
session.index(post(:coordinates => coordinates))
|
|
98
|
+
connection.should have_add_with(:coordinates_s => 'dr5xx3nytvgs')
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'should correctly index an attribute field with block access' do
|
|
102
|
+
session.index(post(:title => 'The Blog Post'))
|
|
103
|
+
connection.should have_add_with(:sort_title_s => 'blog post')
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'should correctly index an attribute field with instance-external block access' do
|
|
107
|
+
session.index(post(:category_ids => [1, 2, 3]))
|
|
108
|
+
connection.should have_add_with(:primary_category_id_i => '1')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'should correctly index a field that is defined on a superclass' do
|
|
112
|
+
Sunspot.setup(SuperClass) { string :author_name }
|
|
113
|
+
session.index(post(:author_name => 'Mat Brown'))
|
|
114
|
+
connection.should have_add_with(:author_name_s => 'Mat Brown')
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'should throw a NoMethodError only if a nonexistent type is defined' do
|
|
118
|
+
lambda { Sunspot.setup(Post) { string :author_name }}.should_not raise_error
|
|
119
|
+
lambda { Sunspot.setup(Post) { bogus :journey }}.should raise_error(NoMethodError)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'should throw a NoMethodError if a nonexistent field argument is passed' do
|
|
123
|
+
lambda { Sunspot.setup(Post) { string :author_name, :bogus => :argument }}.should raise_error(ArgumentError)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'should throw an ArgumentError if single-value field tries to index multiple values' do
|
|
127
|
+
lambda do
|
|
128
|
+
Sunspot.setup(Post) { string :author_name }
|
|
129
|
+
session.index(post(:author_name => ['Mat Brown', 'Matthew Brown']))
|
|
130
|
+
end.should raise_error(ArgumentError)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'should throw an ArgumentError if specifying more_like_this on type that does not support it' do
|
|
134
|
+
lambda do
|
|
135
|
+
Sunspot.setup(Post) { integer :popularity, :more_like_this => true }
|
|
136
|
+
end.should raise_error(ArgumentError)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'should use a specified field name when the :as option is set' do
|
|
140
|
+
session.index(post(:title => 'A Title'))
|
|
141
|
+
connection.should have_add_with(:legacy_field_s => 'legacy A Title')
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'should use a specified field name when the :as option is set for array values' do
|
|
145
|
+
session.index(post(:title => 'Another Title'))
|
|
146
|
+
connection.should have_add_with(:legacy_array_field_sm => ['first string', 'second string'])
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'batch indexing', :type => :indexer do
|
|
4
|
+
it 'should send all batched adds in a single request' do
|
|
5
|
+
posts = Array.new(2) { Post.new }
|
|
6
|
+
session.batch do
|
|
7
|
+
for post in posts
|
|
8
|
+
session.index(post)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
connection.adds.length.should == 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should add all batched adds' do
|
|
15
|
+
posts = Array.new(2) { Post.new }
|
|
16
|
+
session.batch do
|
|
17
|
+
for post in posts
|
|
18
|
+
session.index(post)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
add = connection.adds.last
|
|
22
|
+
connection.adds.first.map { |add| add.field_by_name(:id).value }.should ==
|
|
23
|
+
posts.map { |post| "Post #{post.id}" }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should not index changes to models that happen after index call' do
|
|
27
|
+
post = Post.new
|
|
28
|
+
session.batch do
|
|
29
|
+
session.index(post)
|
|
30
|
+
post.title = 'Title'
|
|
31
|
+
end
|
|
32
|
+
connection.adds.first.first.field_by_name(:title_ss).should be_nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should batch an add and a delete' do
|
|
36
|
+
pending 'batching all operations'
|
|
37
|
+
connection.should_not_receive(:add)
|
|
38
|
+
connection.should_not_receive(:remove)
|
|
39
|
+
posts = Array.new(2) { Post.new }
|
|
40
|
+
session.batch do
|
|
41
|
+
session.index(posts[0])
|
|
42
|
+
session.remove(posts[1])
|
|
43
|
+
end
|
|
44
|
+
connection.adds
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'indexing dynamic fields' do
|
|
4
|
+
it 'indexes string data' do
|
|
5
|
+
session.index(post(:custom_string => { :test => 'string' }))
|
|
6
|
+
connection.should have_add_with(:"custom_string:test_ss" => 'string')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'indexes integer data with virtual accessor' do
|
|
10
|
+
session.index(post(:category_ids => [1, 2]))
|
|
11
|
+
connection.should have_add_with(:"custom_integer:1_i" => '1', :"custom_integer:2_i" => '1')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'indexes float data' do
|
|
15
|
+
session.index(post(:custom_fl => { :test => 1.5 }))
|
|
16
|
+
connection.should have_add_with(:"custom_float:test_fm" => '1.5')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'indexes time data' do
|
|
20
|
+
session.index(post(:custom_time => { :test => Time.parse('2009-05-18 18:05:00 -0400') }))
|
|
21
|
+
connection.should have_add_with(:"custom_time:test_d" => '2009-05-18T22:05:00Z')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'indexes boolean data' do
|
|
25
|
+
session.index(post(:custom_boolean => { :test => false }))
|
|
26
|
+
connection.should have_add_with(:"custom_boolean:test_b" => 'false')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'indexes multiple values for a field' do
|
|
30
|
+
session.index(post(:custom_fl => { :test => [1.0, 2.1, 3.2] }))
|
|
31
|
+
connection.should have_add_with(:"custom_float:test_fm" => %w(1.0 2.1 3.2))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should throw a NoMethodError if dynamic text field defined' do
|
|
35
|
+
lambda do
|
|
36
|
+
Sunspot.setup(Post) do
|
|
37
|
+
dynamic_text :custom_text
|
|
38
|
+
end
|
|
39
|
+
end.should raise_error(NoMethodError)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'indexing fixed fields', :type => :indexer do
|
|
4
|
+
it 'should index id' do
|
|
5
|
+
session.index post
|
|
6
|
+
connection.should have_add_with(:id => "Post #{post.id}")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'should index type' do
|
|
10
|
+
session.index post
|
|
11
|
+
connection.should have_add_with(:type => ['Post', 'SuperClass', 'MockRecord'])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should index class name' do
|
|
15
|
+
session.index post
|
|
16
|
+
connection.should have_add_with(:class_name => 'Post')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should index the array of objects supplied' do
|
|
20
|
+
posts = Array.new(2) { Post.new }
|
|
21
|
+
session.index posts
|
|
22
|
+
connection.should have_add_with(
|
|
23
|
+
{ :id => "Post #{posts.first.id}" },
|
|
24
|
+
{ :id => "Post #{posts.last.id}" }
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should index an array containing more than one type of object' do
|
|
29
|
+
post1, comment, post2 = objects = [Post.new, Namespaced::Comment.new, Post.new]
|
|
30
|
+
session.index objects
|
|
31
|
+
connection.should have_add_with(
|
|
32
|
+
{ :id => "Post #{post1.id}", :type => ['Post', 'SuperClass', 'MockRecord'] },
|
|
33
|
+
{ :id => "Namespaced::Comment #{comment.id}", :type => ['Namespaced::Comment', 'MockRecord'] },
|
|
34
|
+
{ :id => "Post #{post2.id}", :type => ['Post', 'SuperClass', 'MockRecord'] }
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'commits immediately after index! called' do
|
|
39
|
+
connection.should_receive(:add).ordered
|
|
40
|
+
connection.should_receive(:commit).ordered
|
|
41
|
+
session.index!(post)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'raises an ArgumentError if an attempt is made to index an object that has no configuration' do
|
|
45
|
+
lambda { session.index(Blog.new) }.should raise_error(Sunspot::NoSetupError)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'raises a NoAdapterError if class without adapter is indexed' do
|
|
49
|
+
lambda { session.index(User.new) }.should raise_error(Sunspot::NoAdapterError)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'raises an ArgumentError if a non-word character is included in the field name' do
|
|
53
|
+
lambda do
|
|
54
|
+
Sunspot.setup(Post) { string :"bad name" }
|
|
55
|
+
end.should raise_error(ArgumentError)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'indexing fulltext fields' do
|
|
4
|
+
it 'indexes text field' do
|
|
5
|
+
session.index(post(:title => 'A Title'))
|
|
6
|
+
connection.should have_add_with(:title_text => 'A Title')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'indexes stored text field' do
|
|
10
|
+
session.index(post(:body => 'Test body'))
|
|
11
|
+
connection.should have_add_with(:body_textsv => 'Test body')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'indexes text field with boost' do
|
|
15
|
+
session.index(post(:title => 'A Title'))
|
|
16
|
+
connection.adds.last.first.field_by_name(:title_text).attrs[:boost].should == 2
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'indexes multiple values for a text field' do
|
|
20
|
+
session.index(post(:body => %w(some title)))
|
|
21
|
+
connection.should have_add_with(:body_textsv => %w(some title))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'indexes text via a block accessor' do
|
|
25
|
+
session.index(post(:title => 'backwards'))
|
|
26
|
+
connection.should have_add_with(:backwards_title_text => 'sdrawkcab')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'indexes document level boost using block' do
|
|
30
|
+
session.index(post(:ratings_average => 4.0))
|
|
31
|
+
connection.adds.last.first.attrs[:boost].should == 1.25
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'indexes document level boost using attribute' do
|
|
35
|
+
session.index(Namespaced::Comment.new(:boost => 1.5))
|
|
36
|
+
connection.adds.last.first.attrs[:boost].should == 1.5
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'indexes document level boost defined statically' do
|
|
40
|
+
session.index(Photo.new)
|
|
41
|
+
connection.adds.last.first.attrs[:boost].should == 0.75
|
|
42
|
+
end
|
|
43
|
+
end
|