outoftime-sunspot 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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')