outoftime-sunspot 0.0.1 → 0.0.2

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 (94) hide show
  1. data/History.txt +9 -6
  2. data/README.rdoc +45 -13
  3. data/Rakefile +5 -21
  4. data/VERSION.yml +4 -0
  5. data/bin/sunspot-solr +39 -0
  6. data/lib/sunspot/builder.rb +78 -0
  7. data/lib/sunspot/dsl/fields.rb +39 -0
  8. data/lib/sunspot/dsl/query.rb +32 -0
  9. data/lib/sunspot/dsl/scope.rb +35 -0
  10. data/lib/sunspot/dsl.rb +3 -0
  11. data/lib/sunspot/query.rb +9 -20
  12. data/lib/sunspot/search.rb +8 -25
  13. data/lib/sunspot.rb +2 -3
  14. data/solr/etc/jetty.xml +10 -4
  15. data/solr/solr/conf/{admin-extra.html → elevate.xml} +18 -13
  16. data/solr/solr/conf/solrconfig.xml +369 -67
  17. data/solr/webapps/solr.war +0 -0
  18. data/spec/api/build_search_spec.rb +195 -0
  19. data/spec/api/indexer_spec.rb +112 -0
  20. data/spec/api/search_retrieval_spec.rb +59 -0
  21. data/spec/api/session_spec.rb +44 -0
  22. data/spec/api/spec_helper.rb +1 -0
  23. data/spec/api/standard_search_builder_spec.rb +76 -0
  24. data/{test → spec}/custom_expectation.rb +0 -0
  25. data/{test/integration/test_field_types.rb → spec/integration/field_types_spec.rb} +9 -9
  26. data/{test/integration/test_keyword_search.rb → spec/integration/keyword_search_spec.rb} +5 -5
  27. data/spec/integration/spec_helper.rb +1 -0
  28. data/{test → spec}/integration/test_pagination.rb +5 -5
  29. data/{test → spec}/mocks/base_class.rb +0 -0
  30. data/{test → spec}/mocks/comment.rb +0 -0
  31. data/{test → spec}/mocks/mock_adapter.rb +0 -0
  32. data/{test → spec}/mocks/post.rb +0 -0
  33. data/{test/test_helper.rb → spec/spec_helper.rb} +6 -12
  34. data/tasks/gemspec.rake +18 -0
  35. data/tasks/rcov.rake +27 -5
  36. data/tasks/spec.rake +21 -0
  37. metadata +90 -125
  38. data/Manifest.txt +0 -104
  39. data/PostInstall.txt +0 -7
  40. data/config/hoe.rb +0 -74
  41. data/config/requirements.rb +0 -15
  42. data/lib/sunspot/conditions.rb +0 -50
  43. data/lib/sunspot/conditions_builder.rb +0 -37
  44. data/lib/sunspot/field_builder.rb +0 -37
  45. data/lib/sunspot/query_builder.rb +0 -30
  46. data/lib/sunspot/scope_builder.rb +0 -33
  47. data/lib/sunspot/version.rb +0 -10
  48. data/setup.rb +0 -1585
  49. data/solr/README.txt +0 -36
  50. data/solr/exampledocs/books.csv +0 -11
  51. data/solr/exampledocs/hd.xml +0 -46
  52. data/solr/exampledocs/ipod_other.xml +0 -50
  53. data/solr/exampledocs/ipod_video.xml +0 -35
  54. data/solr/exampledocs/mem.xml +0 -58
  55. data/solr/exampledocs/monitor.xml +0 -31
  56. data/solr/exampledocs/monitor2.xml +0 -30
  57. data/solr/exampledocs/mp500.xml +0 -39
  58. data/solr/exampledocs/post.jar +0 -0
  59. data/solr/exampledocs/post.sh +0 -28
  60. data/solr/exampledocs/sd500.xml +0 -33
  61. data/solr/exampledocs/solr.xml +0 -38
  62. data/solr/exampledocs/spellchecker.xml +0 -58
  63. data/solr/exampledocs/utf8-example.xml +0 -42
  64. data/solr/exampledocs/vidcard.xml +0 -52
  65. data/solr/solr/README.txt +0 -52
  66. data/solr/solr/bin/abc +0 -176
  67. data/solr/solr/bin/abo +0 -176
  68. data/solr/solr/bin/backup +0 -108
  69. data/solr/solr/bin/backupcleaner +0 -142
  70. data/solr/solr/bin/commit +0 -128
  71. data/solr/solr/bin/optimize +0 -129
  72. data/solr/solr/bin/readercycle +0 -129
  73. data/solr/solr/bin/rsyncd-disable +0 -77
  74. data/solr/solr/bin/rsyncd-enable +0 -76
  75. data/solr/solr/bin/rsyncd-start +0 -145
  76. data/solr/solr/bin/rsyncd-stop +0 -105
  77. data/solr/solr/bin/scripts-util +0 -83
  78. data/solr/solr/bin/snapcleaner +0 -148
  79. data/solr/solr/bin/snapinstaller +0 -168
  80. data/solr/solr/bin/snappuller +0 -248
  81. data/solr/solr/bin/snappuller-disable +0 -77
  82. data/solr/solr/bin/snappuller-enable +0 -77
  83. data/solr/solr/bin/snapshooter +0 -109
  84. data/solr/solr/conf/scripts.conf +0 -24
  85. data/tasks/deployment.rake +0 -34
  86. data/tasks/environment.rake +0 -7
  87. data/tasks/solr.rake +0 -12
  88. data/tasks/website.rake +0 -17
  89. data/test/api/test_build_search.rb +0 -216
  90. data/test/api/test_helper.rb +0 -4
  91. data/test/api/test_indexer.rb +0 -110
  92. data/test/api/test_retrieve_search.rb +0 -114
  93. data/test/api/test_session.rb +0 -46
  94. data/test/integration/test_helper.rb +0 -1
@@ -1,216 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
-
3
- class TestBuildSearch < Test::Unit::TestCase
4
- CONFIG = Sunspot::Configuration.build
5
-
6
- test 'should search by keywords' do
7
- connection.expects(:query).with('(keyword search) AND (type:Post)', :filter_queries => [], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
8
- session.search Post, :keywords => 'keyword search'
9
- session.search Post do
10
- keywords 'keyword search'
11
- end
12
- end
13
-
14
- test 'should scope by exact match with a string' do
15
- connection.expects(:query).with('(type:Post)', :filter_queries => ['title_s:My\ Pet\ Post'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
16
- session.search Post, :conditions => { :title => 'My Pet Post' }
17
- session.search Post do
18
- with.title 'My Pet Post'
19
- end
20
- end
21
-
22
- test 'should ignore nonexistant fields in hash scope' do
23
- connection.expects(:query).with('(type:Post)', :filter_queries => [], :start => 0, :rows => CONFIG.pagination.default_per_page)
24
- session.search Post, :conditions => { :bogus => 'Field' }
25
- end
26
-
27
- test 'should raise an ArgumentError for nonexistant fields in block scope' do
28
- lambda do
29
- session.search Post do
30
- with.bogus 'Field'
31
- end
32
- end.should raise_error(ArgumentError)
33
- end
34
-
35
- test 'should scope by exact match with time' do
36
- connection.expects(:query).with('(type:Post)', :filter_queries => ['published_at_d:1983\-07\-08T09\:00\:00Z'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
37
- time = Time.parse('1983-07-08 05:00:00 -0400')
38
- session.search Post, :conditions => { :published_at => time }
39
- session.search Post do
40
- with.published_at time
41
- end
42
- end
43
-
44
- test 'should scope by less than match with float' do
45
- connection.expects(:query).with('(type:Post)', :filter_queries => ['average_rating_f:[* TO 3\.0]'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
46
-
47
- session.search Post, :conditions => { :average_rating => 3.0 } do
48
- conditions.interpret :average_rating, :less_than
49
- end
50
-
51
- session.search Post do
52
- with.average_rating.less_than 3.0
53
- end
54
- end
55
-
56
- test 'should scope by greater than match with float' do
57
- connection.expects(:query).with('(type:Post)', :filter_queries => ['average_rating_f:[3\.0 TO *]'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
58
- session.search Post, :conditions => { :average_rating => 3.0 } do
59
- conditions.interpret :average_rating, :greater_than
60
- end
61
- session.search Post do
62
- with.average_rating.greater_than 3.0
63
- end
64
- end
65
-
66
- test 'should scope by between match with float' do
67
- connection.expects(:query).with('(type:Post)', :filter_queries => ['average_rating_f:[2\.0 TO 4\.0]'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
68
- session.search Post, :conditions => { :average_rating => [2.0, 4.0] } do
69
- conditions.interpret :average_rating, :between
70
- end
71
- session.search Post do
72
- with.average_rating.between 2.0..4.0
73
- end
74
- end
75
-
76
- test 'should scope by any match with integer' do
77
- connection.expects(:query).with('(type:Post)', :filter_queries => ['category_ids_im:(2 OR 7 OR 12)'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
78
- session.search Post, :conditions => { :category_ids => [2, 7, 12] }
79
- session.search Post do
80
- with.category_ids.any_of [2, 7, 12]
81
- end
82
- end
83
-
84
- test 'should scope by all match with integer' do
85
- connection.expects(:query).with('(type:Post)', :filter_queries => ['category_ids_im:(2 AND 7 AND 12)'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
86
- session.search Post, :conditions => { :category_ids => [2, 7, 12] } do
87
- conditions.interpret :category_ids, :all_of
88
- end
89
- session.search Post do
90
- with.category_ids.all_of [2, 7, 12]
91
- end
92
- end
93
-
94
- test 'should allow setting of default conditions' do
95
- connection.expects(:query).with('(type:Post)', :filter_queries => ['average_rating_f:2\.0'], :start => 0, :rows => CONFIG.pagination.default_per_page)
96
- session.search Post do
97
- conditions.default :average_rating, 2.0
98
- end
99
- end
100
-
101
- test 'should not use default condition value if condition provided' do
102
- connection.expects(:query).with('(type:Post)', :filter_queries => ['average_rating_f:3\.0'], :start => 0, :rows => CONFIG.pagination.default_per_page)
103
- session.search Post, :conditions => { :average_rating => 3.0 } do
104
- conditions.default :average_rating, 2.0
105
- end
106
- end
107
-
108
- test 'should paginate using default per_page' do
109
- connection.expects(:query).with('(type:Post)', :filter_queries => [], :rows => 30, :start => 30).times(2)
110
- session.search Post, :page => 2
111
- session.search Post do
112
- paginate :page => 2
113
- end
114
- end
115
-
116
- test 'should paginate using provided per_page' do
117
- connection.expects(:query).with('(type:Post)', :filter_queries => [], :rows => 15, :start => 45).times(2)
118
- session.search Post, :page => 4, :per_page => 15
119
- session.search Post do
120
- paginate :page => 4, :per_page => 15
121
- end
122
- end
123
-
124
- test 'should order' do
125
- connection.expects(:query).with('(type:Post)', :filter_queries => [], :sort => [{ :average_rating_f => :descending }], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
126
- session.search Post, :order => 'average_rating desc'
127
- session.search Post do
128
- order_by :average_rating, :desc
129
- end
130
- end
131
-
132
- test 'should build search for multiple types' do
133
- connection.expects(:query).with('(type:(Post OR Comment))', :filter_queries => [], :start => 0, :rows => CONFIG.pagination.default_per_page)
134
- session.search(Post, Comment)
135
- end
136
-
137
- test 'should allow search on fields common to all types' do
138
- connection.expects(:query).with('(type:(Post OR Comment))', :filter_queries => ['published_at_d:1983\-07\-08T09\:00\:00Z'], :start => 0, :rows => CONFIG.pagination.default_per_page).times(2)
139
- time = Time.parse('1983-07-08 05:00:00 -0400')
140
- session.search Post, Comment, :conditions => { :published_at => time }
141
- session.search Post, Comment do
142
- with.published_at time
143
- end
144
- end
145
-
146
- test 'should raise exception if search scoped to field not common to all types' do
147
- lambda do
148
- session.search Post, Comment do
149
- with.blog_id 1
150
- end
151
- end.should raise_error(ArgumentError)
152
- end
153
-
154
- test 'should raise exception if search scoped to field configured differently between types' do
155
- lambda do
156
- session.search Post, Comment do
157
- with.average_rating 2.2 # this is a float in Post but an integer in Comment
158
- end
159
- end.should raise_error(ArgumentError)
160
- end
161
-
162
- test 'should ignore condition if field is not common to all types' do
163
- connection.expects(:query).with('(type:(Post OR Comment))', :filter_queries => [], :start => 0, :rows => CONFIG.pagination.default_per_page)
164
- session.search Post, Comment, :conditions => { :blog_id => 1 }
165
- end
166
-
167
- test 'should raise ArgumentError if bogus field scoped' do
168
- lambda do
169
- session.search Post do
170
- with.bogus.equal_to :field
171
- end
172
- end.should raise_error(ArgumentError)
173
- end
174
-
175
- test 'should raise NoMethodError if bogus operator referenced' do
176
- lambda do
177
- session.search Post do
178
- with.category_ids.resembling :bogus_condition
179
- end
180
- end.should raise_error(NoMethodError)
181
- end
182
-
183
- test 'should raise ArgumentError if no :page argument given to paginate' do
184
- lambda do
185
- session.search Post do
186
- paginate
187
- end
188
- end.should raise_error(ArgumentError)
189
- end
190
-
191
- test 'should raise ArgumentError if bogus argument given to paginate' do
192
- lambda do
193
- session.search Post do
194
- paginate :page => 4, :ugly => :puppy
195
- end
196
- end.should raise_error(ArgumentError)
197
- end
198
-
199
- test 'should raise NoMethodError if more than one argument passed to scope method' do # or should it?
200
- lambda do
201
- session.search Post do
202
- with.category_ids 4, 5
203
- end
204
- end.should raise_error(NoMethodError)
205
- end
206
-
207
- private
208
-
209
- def connection
210
- @connection ||= stub
211
- end
212
-
213
- def session
214
- @session ||= Sunspot::Session.new(CONFIG, connection)
215
- end
216
- end
@@ -1,4 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
-
3
- gem 'mocha', '~>0.9'
4
- require 'mocha'
@@ -1,110 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
-
3
- class TestIndexer < Test::Unit::TestCase
4
- CONFIG = Sunspot::Configuration.build
5
-
6
- describe 'when indexing an object' do
7
- test 'should index id and type' do
8
- connection.expects(:add).with(has_entries(:id => "Post #{post.id}", :type => ['Post', 'BaseClass']))
9
- session.index post
10
- end
11
-
12
- test 'should index text' do
13
- post :title => 'A Title', :body => 'A Post'
14
- connection.expects(:add).with(has_entries(:title_text => 'A Title', :body_text => 'A Post'))
15
- session.index post
16
- end
17
-
18
- test 'should correctly index a string attribute field' do
19
- post :title => 'A Title'
20
- connection.expects(:add).with(has_entries(:title_s => 'A Title'))
21
- session.index post
22
- end
23
-
24
- test 'should correctly index an integer attribute field' do
25
- post :blog_id => 4
26
- connection.expects(:add).with(has_entries(:blog_id_i => '4'))
27
- session.index post
28
- end
29
-
30
- test 'should correctly index a float attribute field' do
31
- post :average_rating => 2.23
32
- connection.expects(:add).with(has_entries(:average_rating_f => '2.23'))
33
- session.index post
34
- end
35
-
36
- test 'should allow indexing by a multiple-value field' do
37
- post :category_ids => [3, 14]
38
- connection.expects(:add).with(has_entries(:category_ids_im => ['3', '14']))
39
- session.index post
40
- end
41
-
42
- test 'should correctly index a time field' do
43
- post :published_at => Time.parse('1983-07-08 05:00:00 -0400')
44
- connection.expects(:add).with(has_entries(:published_at_d => '1983-07-08T09:00:00Z'))
45
- session.index post
46
- end
47
-
48
- test 'should correctly index a virtual field' do
49
- post :title => 'The Blog Post'
50
- connection.expects(:add).with(has_entries(:sort_title_s => 'blog post'))
51
- session.index post
52
- end
53
-
54
- test 'should correctly index a field that is defined on a superclass' do
55
- Sunspot.setup(BaseClass) { string :author_name }
56
- post :author_name => 'Mat Brown'
57
- connection.expects(:add).with(has_entries(:author_name_s => 'Mat Brown'))
58
- session.index post
59
- end
60
-
61
- test 'should remove an object from the index' do
62
- connection.expects(:delete).with("Post #{post.id}")
63
- session.remove(post)
64
- end
65
-
66
- test 'should be able to remove everything from the index' do
67
- connection.expects(:delete_by_query).with("type:[* TO *]")
68
- session.remove_all
69
- end
70
-
71
- test 'should be able to remove everything of a given class from the index' do
72
- connection.expects(:delete_by_query).with("type:Post")
73
- session.remove_all(Post)
74
- end
75
- end
76
-
77
- test 'should throw a NoMethodError only if a nonexistent type is defined' do
78
- lambda { Sunspot.setup(Post) { string :author_name }}.should_not raise_error
79
- lambda { Sunspot.setup(Post) { bogus :journey }}.should raise_error(NoMethodError)
80
- end
81
-
82
- test 'should throw a NoMethodError if a nonexistent field argument is passed' do
83
- lambda { Sunspot.setup(Post) { string :author_name, :bogus => :argument }}.should raise_error(ArgumentError)
84
- end
85
-
86
- test 'should throw an ArgumentError if an attempt is made to index an object that has no configuration' do
87
- lambda { session.index(Time.now) }.should raise_error(ArgumentError)
88
- end
89
-
90
- test 'should throw an ArgumentError if single-value field tries to index multiple values' do
91
- lambda do
92
- Sunspot.setup(Post) { string :author_name }
93
- session.index(post(:author_name => ['Mat Brown', 'Matthew Brown']))
94
- end.should raise_error(ArgumentError)
95
- end
96
-
97
- private
98
-
99
- def connection
100
- @connection ||= stub
101
- end
102
-
103
- def session
104
- @session ||= Sunspot::Session.new(CONFIG, connection)
105
- end
106
-
107
- def post(attrs = {})
108
- @post ||= Post.new(attrs)
109
- end
110
- end
@@ -1,114 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
-
3
- class TestRetrieveSearch < Test::Unit::TestCase
4
- CONFIG = Sunspot::Configuration.build
5
-
6
- test 'should load search result' do
7
- post = Post.new
8
- stub_results(post)
9
-
10
- session.search(Post).results.should == [post]
11
- end
12
-
13
- test 'should load multiple search results in order' do
14
- post_1, post_2 = Post.new, Post.new
15
- stub_results(post_1, post_2)
16
- session.search(Post).results.should == [post_1, post_2]
17
- stub_results(post_2, post_1)
18
- session.search(Post).results.should == [post_2, post_1]
19
- end
20
-
21
- test 'should return search total as attribute of results if pagination is provided' do
22
- stub_results(Post.new, 4)
23
- session.search(Post, :page => 1).results.total_entries.should == 4
24
- end
25
-
26
- test 'should return vanilla array if pagination is provided but WillPaginate is not available' do
27
- stub_results(Post.new)
28
- without_class(WillPaginate) do
29
- session.search(Post, :page => 1).results.should_not respond_to(:total_entries)
30
- end
31
- end
32
-
33
- test 'should return total' do
34
- stub_results(Post.new, Post.new, 4)
35
- session.search(Post, :page => 1).total.should == 4
36
- end
37
-
38
- test 'should give access to order through hash and object' do
39
- stub_results
40
- search = session.search(Post, :order => 'sort_title asc')
41
- search.attributes[:order].should == 'sort_title asc'
42
- search.order.should == 'sort_title asc'
43
- end
44
-
45
- test 'should give nil order if no order set' do
46
- stub_results
47
- search = session.search(Post)
48
- search.attributes.should have_key(:order)
49
- search.attributes[:order].should be_nil
50
- search.order.should be_nil
51
- end
52
-
53
- test 'should give access to page and per-page through hash and object' do
54
- stub_results
55
- search = session.search(Post, :page => 2, :per_page => 15)
56
- search.attributes[:page].should == 2
57
- search.attributes[:per_page].should == 15
58
- search.page.should == 2
59
- search.per_page.should == 15
60
- end
61
-
62
- test 'should give access to keywords' do
63
- stub_results
64
- search = session.search(Post, :keywords => 'some keywords')
65
- search.attributes[:keywords].should == 'some keywords'
66
- search.keywords.should == 'some keywords'
67
- end
68
-
69
- test 'should have nil keywords if no keywords given' do
70
- stub_results
71
- search = session.search(Post)
72
- search.attributes.should have_key(:keywords)
73
- search.attributes[:keywords].should be_nil
74
- search.keywords.should be_nil
75
- end
76
-
77
- test 'should give access to conditions' do
78
- stub_results
79
- search = session.search(Post, :conditions => { :blog_id => 1 })
80
- search.attributes[:conditions][:blog_id].should == 1
81
- search.conditions.blog_id.should == 1
82
- end
83
-
84
- test 'should have nil values for fields with unspecified conditions' do
85
- stub_results
86
- search = session.search(Post)
87
- %w(title blog_id category_ids average_rating published_at sort_title).each do |field_name|
88
- search.attributes[:conditions].should have_key(field_name.to_sym)
89
- search.attributes[:conditions][field_name.to_sym].should == nil
90
- search.conditions.should respond_to(field_name)
91
- search.conditions.send(field_name).should == nil
92
- end
93
- end
94
-
95
- private
96
-
97
- def stub_results(*results)
98
- total_hits = if results.last.is_a?(Integer) then results.pop
99
- else results.length
100
- end
101
- response = stub
102
- response.stubs(:hits).returns(results.map { |result| { 'id' => "#{result.class.name} #{result.id}" }})
103
- response.stubs(:total_hits).returns(total_hits)
104
- connection.stubs(:query).returns(response)
105
- end
106
-
107
- def connection
108
- @connection ||= Object.new
109
- end
110
-
111
- def session
112
- @session ||= Sunspot::Session.new(CONFIG, connection)
113
- end
114
- end
@@ -1,46 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
-
3
- class TestSession < Test::Unit::TestCase
4
- context 'using singleton session' do
5
- before do
6
- Sunspot.reset!
7
- connection.expects(:add)
8
- connection.expects(:query)
9
- end
10
-
11
- test 'should open connection with defaults if nothing specified' do
12
- Solr::Connection.stubs(:new).with('http://localhost:8983/solr', :autocommit => :on).returns(connection)
13
- Sunspot.index(Post.new)
14
- Sunspot.search(Post)
15
- end
16
-
17
- test 'should open a connection with custom host' do
18
- Solr::Connection.stubs(:new).with('http://127.0.0.1:8981/solr', :autocommit => :on).returns(connection)
19
- Sunspot.config.solr.url = 'http://127.0.0.1:8981/solr'
20
- Sunspot.index(Post.new)
21
- Sunspot.search(Post)
22
- end
23
- end
24
-
25
- context 'using custom session' do
26
- before do
27
- connection.expects(:add)
28
- connection.expects(:query)
29
- end
30
-
31
- test 'should open a connection with custom host' do
32
- Solr::Connection.stubs(:new).with('http://127.0.0.1:8982/solr', :autocommit => :on).returns(connection)
33
- session = Sunspot::Session.new do |config|
34
- config.solr.url = 'http://127.0.0.1:8982/solr'
35
- end
36
- session.index(Post.new)
37
- session.search(Post)
38
- end
39
- end
40
-
41
- private
42
-
43
- def connection
44
- @connection ||= stub_everything('Connection')
45
- end
46
- end
@@ -1 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', 'test_helper')