UnderpantsGnome-sunspot 0.9.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/History.txt +39 -0
- data/LICENSE +18 -0
- data/README.rdoc +154 -0
- data/Rakefile +9 -0
- data/TODO +4 -0
- data/VERSION.yml +4 -0
- data/bin/sunspot-configure-solr +46 -0
- data/bin/sunspot-solr +62 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot.rb +470 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/composite_setup.rb +186 -0
- data/lib/sunspot/configuration.rb +38 -0
- data/lib/sunspot/data_extractor.rb +47 -0
- data/lib/sunspot/date_facet.rb +36 -0
- data/lib/sunspot/date_facet_row.rb +17 -0
- data/lib/sunspot/dsl.rb +3 -0
- data/lib/sunspot/dsl/field_query.rb +72 -0
- data/lib/sunspot/dsl/fields.rb +86 -0
- data/lib/sunspot/dsl/query.rb +59 -0
- data/lib/sunspot/dsl/query_facet.rb +31 -0
- data/lib/sunspot/dsl/restriction.rb +25 -0
- data/lib/sunspot/dsl/scope.rb +193 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/facet.rb +51 -0
- data/lib/sunspot/facet_row.rb +34 -0
- data/lib/sunspot/field.rb +157 -0
- data/lib/sunspot/field_factory.rb +126 -0
- data/lib/sunspot/indexer.rb +127 -0
- data/lib/sunspot/instantiated_facet.rb +38 -0
- data/lib/sunspot/instantiated_facet_row.rb +12 -0
- data/lib/sunspot/query.rb +190 -0
- data/lib/sunspot/query/base_query.rb +90 -0
- data/lib/sunspot/query/connective.rb +77 -0
- data/lib/sunspot/query/dynamic_query.rb +69 -0
- data/lib/sunspot/query/field_facet.rb +149 -0
- data/lib/sunspot/query/field_query.rb +57 -0
- data/lib/sunspot/query/pagination.rb +39 -0
- data/lib/sunspot/query/query_facet.rb +72 -0
- data/lib/sunspot/query/query_facet_row.rb +19 -0
- data/lib/sunspot/query/restriction.rb +225 -0
- data/lib/sunspot/query/scope.rb +165 -0
- data/lib/sunspot/query/sort.rb +36 -0
- data/lib/sunspot/query/sort_composite.rb +33 -0
- data/lib/sunspot/query_facet.rb +33 -0
- data/lib/sunspot/query_facet_row.rb +21 -0
- data/lib/sunspot/schema.rb +165 -0
- data/lib/sunspot/search.rb +222 -0
- data/lib/sunspot/search/hit.rb +62 -0
- data/lib/sunspot/session.rb +201 -0
- data/lib/sunspot/setup.rb +271 -0
- data/lib/sunspot/type.rb +200 -0
- data/lib/sunspot/util.rb +164 -0
- data/solr/etc/jetty.xml +212 -0
- data/solr/etc/webdefault.xml +379 -0
- data/solr/lib/jetty-6.1.3.jar +0 -0
- data/solr/lib/jetty-util-6.1.3.jar +0 -0
- data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr/solr/conf/elevate.xml +36 -0
- data/solr/solr/conf/protwords.txt +21 -0
- data/solr/solr/conf/schema.xml +50 -0
- data/solr/solr/conf/solrconfig.xml +696 -0
- data/solr/solr/conf/stopwords.txt +57 -0
- data/solr/solr/conf/synonyms.txt +31 -0
- data/solr/start.jar +0 -0
- data/solr/webapps/solr.war +0 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/build_search_spec.rb +918 -0
- data/spec/api/indexer_spec.rb +311 -0
- data/spec/api/query_spec.rb +153 -0
- data/spec/api/search_retrieval_spec.rb +325 -0
- data/spec/api/session_spec.rb +157 -0
- data/spec/api/spec_helper.rb +1 -0
- data/spec/api/sunspot_spec.rb +18 -0
- data/spec/integration/dynamic_fields_spec.rb +55 -0
- data/spec/integration/faceting_spec.rb +169 -0
- data/spec/integration/keyword_search_spec.rb +83 -0
- data/spec/integration/scoped_search_spec.rb +188 -0
- data/spec/integration/spec_helper.rb +1 -0
- data/spec/integration/stored_fields_spec.rb +10 -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 +19 -0
- data/spec/mocks/connection.rb +84 -0
- data/spec/mocks/mock_adapter.rb +30 -0
- data/spec/mocks/mock_record.rb +41 -0
- data/spec/mocks/photo.rb +8 -0
- data/spec/mocks/post.rb +70 -0
- data/spec/mocks/user.rb +8 -0
- data/spec/spec_helper.rb +47 -0
- data/tasks/gemspec.rake +25 -0
- data/tasks/rcov.rake +28 -0
- data/tasks/rdoc.rake +21 -0
- data/tasks/schema.rake +19 -0
- data/tasks/spec.rake +24 -0
- data/tasks/todo.rake +4 -0
- data/templates/schema.xml.haml +24 -0
- metadata +245 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership.
|
4
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
5
|
+
# (the "License"); you may not use this file except in compliance with
|
6
|
+
# the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
#-----------------------------------------------------------------------
|
17
|
+
# a couple of test stopwords to test that the words are really being
|
18
|
+
# configured from this file:
|
19
|
+
stopworda
|
20
|
+
stopwordb
|
21
|
+
|
22
|
+
#Standard english stop words taken from Lucene's StopAnalyzer
|
23
|
+
an
|
24
|
+
and
|
25
|
+
are
|
26
|
+
as
|
27
|
+
at
|
28
|
+
be
|
29
|
+
but
|
30
|
+
by
|
31
|
+
for
|
32
|
+
if
|
33
|
+
in
|
34
|
+
into
|
35
|
+
is
|
36
|
+
it
|
37
|
+
no
|
38
|
+
not
|
39
|
+
of
|
40
|
+
on
|
41
|
+
or
|
42
|
+
s
|
43
|
+
such
|
44
|
+
t
|
45
|
+
that
|
46
|
+
the
|
47
|
+
their
|
48
|
+
then
|
49
|
+
there
|
50
|
+
these
|
51
|
+
they
|
52
|
+
this
|
53
|
+
to
|
54
|
+
was
|
55
|
+
will
|
56
|
+
with
|
57
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
3
|
+
# the License. You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
|
13
|
+
#-----------------------------------------------------------------------
|
14
|
+
#some test synonym mappings unlikely to appear in real input text
|
15
|
+
aaa => aaaa
|
16
|
+
bbb => bbbb1 bbbb2
|
17
|
+
ccc => cccc1,cccc2
|
18
|
+
a\=>a => b\=>b
|
19
|
+
a\,a => b\,b
|
20
|
+
fooaaa,baraaa,bazaaa
|
21
|
+
|
22
|
+
# Some synonym groups specific to this example
|
23
|
+
GB,gib,gigabyte,gigabytes
|
24
|
+
MB,mib,megabyte,megabytes
|
25
|
+
Television, Televisions, TV, TVs
|
26
|
+
#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming
|
27
|
+
#after us won't split it into two words.
|
28
|
+
|
29
|
+
# Synonym mappings can be used for spelling correction too
|
30
|
+
pixima => pixma
|
31
|
+
|
data/solr/start.jar
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
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,918 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Search' do
|
4
|
+
it 'should search by keywords from DSL' do
|
5
|
+
session.search Post do
|
6
|
+
keywords 'keyword search'
|
7
|
+
end
|
8
|
+
connection.should have_last_search_with(:q => 'keyword search')
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should search by keywords from options' do
|
12
|
+
session.search Post, :keywords => 'keyword search'
|
13
|
+
connection.should have_last_search_with(:q => 'keyword search')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should set default query parser to dismax when keywords used' do
|
17
|
+
session.search Post do
|
18
|
+
keywords 'keyword search'
|
19
|
+
end
|
20
|
+
connection.should have_last_search_with(:defType => 'dismax')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should search types in filter query if keywords used' do
|
24
|
+
session.search Post do
|
25
|
+
keywords 'keyword search'
|
26
|
+
end
|
27
|
+
connection.should have_last_search_with(:fq => 'type:Post')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should search all text fields for searched class' do
|
31
|
+
session.search Post do
|
32
|
+
keywords 'keyword search'
|
33
|
+
end
|
34
|
+
connection.searches.last[:qf].split(' ').sort.should == %w(backwards_title_text body_text title_text)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should search only specified text fields when specified' do
|
38
|
+
session.search Post do
|
39
|
+
keywords 'keyword search', :fields => [:title, :body]
|
40
|
+
end
|
41
|
+
connection.searches.last[:qf].split(' ').sort.should == %w(body_text title_text)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should request score when keywords used' do
|
45
|
+
session.search Post, :keywords => 'keyword search'
|
46
|
+
connection.should have_last_search_with(:fl => '* score')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should not request score when keywords not used' do
|
50
|
+
session.search Post
|
51
|
+
connection.should_not have_last_search_with(:fl)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should scope by exact match with a string from DSL' do
|
55
|
+
session.search Post do
|
56
|
+
with :title, 'My Pet Post'
|
57
|
+
end
|
58
|
+
connection.should have_last_search_with(:fq => ['title_ss:My\ Pet\ Post'])
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should scope by exact match with a string from options' do
|
62
|
+
session.search Post, :conditions => { :title => 'My Pet Post' }
|
63
|
+
connection.should have_last_search_with(:fq => ['title_ss:My\ Pet\ Post'])
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should ignore nonexistant fields in hash scope' do
|
67
|
+
session.search Post, :conditions => { :bogus => 'Field' }
|
68
|
+
connection.should_not have_last_search_with(:fq)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should scope by exact match with time' do
|
72
|
+
time = Time.parse('1983-07-08 05:00:00 -0400')
|
73
|
+
session.search Post do
|
74
|
+
with :published_at, time
|
75
|
+
end
|
76
|
+
connection.should have_last_search_with(
|
77
|
+
:fq => ['published_at_d:1983\-07\-08T09\:00\:00Z']
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should scope by exact match with date' do
|
82
|
+
date = Date.new(1983, 7, 8)
|
83
|
+
session.search Post do
|
84
|
+
with :expire_date, date
|
85
|
+
end
|
86
|
+
connection.should have_last_search_with(
|
87
|
+
:fq => ['expire_date_d:1983\-07\-08T00\:00\:00Z']
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should scope by exact match with boolean' do
|
92
|
+
session.search Post do
|
93
|
+
with :featured, false
|
94
|
+
end
|
95
|
+
connection.should have_last_search_with(:fq => ['featured_b:false'])
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should scope by less than match with float' do
|
99
|
+
session.search Post do
|
100
|
+
with(:average_rating).less_than 3.0
|
101
|
+
end
|
102
|
+
connection.should have_last_search_with(:fq => ['average_rating_f:[* TO 3\.0]'])
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should scope by greater than match with float' do
|
106
|
+
session.search Post do
|
107
|
+
with(:average_rating).greater_than 3.0
|
108
|
+
end
|
109
|
+
connection.should have_last_search_with(:fq => ['average_rating_f:[3\.0 TO *]'])
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should scope by short-form between match with integers' do
|
113
|
+
session.search Post do
|
114
|
+
with :blog_id, 2..4
|
115
|
+
end
|
116
|
+
connection.should have_last_search_with(:fq => ['blog_id_i:[2 TO 4]'])
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should scope by between match with float' do
|
120
|
+
session.search Post do
|
121
|
+
with(:average_rating).between 2.0..4.0
|
122
|
+
end
|
123
|
+
connection.should have_last_search_with(:fq => ['average_rating_f:[2\.0 TO 4\.0]'])
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should scope by any match with integer using DSL' do
|
127
|
+
session.search Post do
|
128
|
+
with(:category_ids).any_of [2, 7, 12]
|
129
|
+
end
|
130
|
+
connection.should have_last_search_with(:fq => ['category_ids_im:(2 OR 7 OR 12)'])
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should scope by any match with integer using options' do
|
134
|
+
session.search Post, :conditions => { :category_ids => [2, 7, 12] }
|
135
|
+
connection.should have_last_search_with(:fq => ['category_ids_im:(2 OR 7 OR 12)'])
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should scope by short-form any-of match with integers' do
|
139
|
+
session.search Post do
|
140
|
+
with :category_ids, [2, 7, 12]
|
141
|
+
end
|
142
|
+
connection.should have_last_search_with(:fq => ['category_ids_im:(2 OR 7 OR 12)'])
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should scope by all match with integer' do
|
146
|
+
session.search Post do
|
147
|
+
with(:category_ids).all_of [2, 7, 12]
|
148
|
+
end
|
149
|
+
connection.should have_last_search_with(:fq => ['category_ids_im:(2 AND 7 AND 12)'])
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should scope by not equal match with string' do
|
153
|
+
session.search Post do
|
154
|
+
without :title, 'Bad Post'
|
155
|
+
end
|
156
|
+
connection.should have_last_search_with(:fq => ['-title_ss:Bad\ Post'])
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should scope by not less than match with float' do
|
160
|
+
session.search Post do
|
161
|
+
without(:average_rating).less_than 3.0
|
162
|
+
end
|
163
|
+
connection.should have_last_search_with(:fq => ['-average_rating_f:[* TO 3\.0]'])
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should scope by not greater than match with float' do
|
167
|
+
session.search Post do
|
168
|
+
without(:average_rating).greater_than 3.0
|
169
|
+
end
|
170
|
+
connection.should have_last_search_with(:fq => ['-average_rating_f:[3\.0 TO *]'])
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should scope by not between match with shorthand' do
|
174
|
+
session.search Post do
|
175
|
+
without(:blog_id, 2..4)
|
176
|
+
end
|
177
|
+
connection.should have_last_search_with(:fq => ['-blog_id_i:[2 TO 4]'])
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should scope by not between match with float' do
|
181
|
+
session.search Post do
|
182
|
+
without(:average_rating).between 2.0..4.0
|
183
|
+
end
|
184
|
+
connection.should have_last_search_with(:fq => ['-average_rating_f:[2\.0 TO 4\.0]'])
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should scope by not any match with integer' do
|
188
|
+
session.search Post do
|
189
|
+
without(:category_ids).any_of [2, 7, 12]
|
190
|
+
end
|
191
|
+
connection.should have_last_search_with(:fq => ['-category_ids_im:(2 OR 7 OR 12)'])
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
it 'should scope by not all match with integer' do
|
196
|
+
session.search Post do
|
197
|
+
without(:category_ids).all_of [2, 7, 12]
|
198
|
+
end
|
199
|
+
connection.should have_last_search_with(:fq => ['-category_ids_im:(2 AND 7 AND 12)'])
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'should scope by empty field' do
|
203
|
+
session.search Post do
|
204
|
+
with :average_rating, nil
|
205
|
+
end
|
206
|
+
connection.should have_last_search_with(:fq => ['-average_rating_f:[* TO *]'])
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should scope by non-empty field' do
|
210
|
+
session.search Post do
|
211
|
+
without :average_rating, nil
|
212
|
+
end
|
213
|
+
connection.should have_last_search_with(:fq => ['average_rating_f:[* TO *]'])
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should exclude by object identity' do
|
217
|
+
post = Post.new
|
218
|
+
session.search Post do
|
219
|
+
without post
|
220
|
+
end
|
221
|
+
connection.should have_last_search_with(:fq => ["-id:Post\\ #{post.id}"])
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'should exclude multiple objects passed as varargs by object identity' do
|
225
|
+
post1, post2 = Post.new, Post.new
|
226
|
+
session.search Post do
|
227
|
+
without post1, post2
|
228
|
+
end
|
229
|
+
connection.should have_last_search_with(
|
230
|
+
:fq => ["-id:Post\\ #{post1.id}", "-id:Post\\ #{post2.id}"]
|
231
|
+
)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should exclude multiple objects passed as array by object identity' do
|
235
|
+
posts = [Post.new, Post.new]
|
236
|
+
session.search Post do
|
237
|
+
without posts
|
238
|
+
end
|
239
|
+
connection.should have_last_search_with(
|
240
|
+
:fq => ["-id:Post\\ #{posts.first.id}", "-id:Post\\ #{posts.last.id}"]
|
241
|
+
)
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should create a disjunction between two restrictions' do
|
245
|
+
session.search Post do
|
246
|
+
any_of do
|
247
|
+
with :category_ids, 1
|
248
|
+
with :blog_id, 2
|
249
|
+
end
|
250
|
+
end
|
251
|
+
connection.should have_last_search_with(
|
252
|
+
:fq => '(category_ids_im:1 OR blog_id_i:2)'
|
253
|
+
)
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should create a conjunction inside of a disjunction' do
|
257
|
+
session.search Post do
|
258
|
+
any_of do
|
259
|
+
with :blog_id, 2
|
260
|
+
all_of do
|
261
|
+
with :category_ids, 1
|
262
|
+
with(:average_rating).greater_than(3.0)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
connection.should have_last_search_with(
|
267
|
+
:fq => '(blog_id_i:2 OR (category_ids_im:1 AND average_rating_f:[3\.0 TO *]))'
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'should do nothing special if #all_of called from the top level' do
|
272
|
+
session.search Post do
|
273
|
+
all_of do
|
274
|
+
with :blog_id, 2
|
275
|
+
with :category_ids, 1
|
276
|
+
end
|
277
|
+
end
|
278
|
+
connection.should have_last_search_with(
|
279
|
+
:fq => ['blog_id_i:2', 'category_ids_im:1']
|
280
|
+
)
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'should create a disjunction with negated restrictions' do
|
284
|
+
session.search Post do
|
285
|
+
any_of do
|
286
|
+
with :category_ids, 1
|
287
|
+
without(:average_rating).greater_than(3.0)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
connection.should have_last_search_with(
|
291
|
+
:fq => '(category_ids_im:1 OR -average_rating_f:[3\.0 TO *])'
|
292
|
+
)
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should create a disjunction with instance exclusion' do
|
296
|
+
post = Post.new
|
297
|
+
session.search Post do
|
298
|
+
any_of do
|
299
|
+
without(post)
|
300
|
+
with(:category_ids, 1)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
connection.should have_last_search_with(
|
304
|
+
:fq => "(-id:Post\\ #{post.id} OR category_ids_im:1)"
|
305
|
+
)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'should restrict by dynamic string field with equality restriction' do
|
309
|
+
session.search Post do
|
310
|
+
dynamic :custom_string do
|
311
|
+
with :test, 'string'
|
312
|
+
end
|
313
|
+
end
|
314
|
+
connection.should have_last_search_with(:fq => ['custom_string\:test_s:string'])
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'should restrict by dynamic integer field with less than restriction' do
|
318
|
+
session.search Post do
|
319
|
+
dynamic :custom_integer do
|
320
|
+
with(:test).less_than(1)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
connection.should have_last_search_with(:fq => ['custom_integer\:test_i:[* TO 1]'])
|
324
|
+
end
|
325
|
+
|
326
|
+
it 'should restrict by dynamic float field with between restriction' do
|
327
|
+
session.search Post do
|
328
|
+
dynamic :custom_float do
|
329
|
+
with(:test).between(2.2..3.3)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
connection.should have_last_search_with(:fq => ['custom_float\:test_fm:[2\.2 TO 3\.3]'])
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'should restrict by dynamic time field with any of restriction' do
|
336
|
+
session.search Post do
|
337
|
+
dynamic :custom_time do
|
338
|
+
with(:test).any_of([Time.parse('2009-02-10 14:00:00 UTC'),
|
339
|
+
Time.parse('2009-02-13 18:00:00 UTC')])
|
340
|
+
end
|
341
|
+
end
|
342
|
+
connection.should have_last_search_with(:fq => ['custom_time\:test_d:(2009\-02\-10T14\:00\:00Z OR 2009\-02\-13T18\:00\:00Z)'])
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'should restrict by dynamic boolean field with equality restriction' do
|
346
|
+
session.search Post do
|
347
|
+
dynamic :custom_boolean do
|
348
|
+
with :test, false
|
349
|
+
end
|
350
|
+
end
|
351
|
+
connection.should have_last_search_with(:fq => ['custom_boolean\:test_b:false'])
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should negate a dynamic field restriction' do
|
355
|
+
session.search Post do
|
356
|
+
dynamic :custom_string do
|
357
|
+
without :test, 'foo'
|
358
|
+
end
|
359
|
+
end
|
360
|
+
connection.should have_last_search_with(:fq => ['-custom_string\:test_s:foo'])
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'should search by a dynamic field inside a disjunction' do
|
364
|
+
session.search Post do
|
365
|
+
any_of do
|
366
|
+
dynamic :custom_string do
|
367
|
+
with :test, 'foo'
|
368
|
+
end
|
369
|
+
with :title, 'bar'
|
370
|
+
end
|
371
|
+
end
|
372
|
+
connection.should have_last_search_with(
|
373
|
+
:fq => '(custom_string\:test_s:foo OR title_ss:bar)'
|
374
|
+
)
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'should throw an UnrecognizedFieldError if an unknown dynamic field is searched by' do
|
378
|
+
lambda do
|
379
|
+
session.search Post do
|
380
|
+
dynamic(:bogus) { with :some, 'value' }
|
381
|
+
end
|
382
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
383
|
+
end
|
384
|
+
|
385
|
+
it 'should throw a NoMethodError if pagination is attempted in a dynamic query' do
|
386
|
+
lambda do
|
387
|
+
session.search Post do
|
388
|
+
dynamic :custom_string do
|
389
|
+
paginate 3, 10
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end.should raise_error(NoMethodError)
|
393
|
+
end
|
394
|
+
|
395
|
+
it 'should paginate using default per_page when page not provided' do
|
396
|
+
session.search Post
|
397
|
+
connection.should have_last_search_with(:rows => 30)
|
398
|
+
end
|
399
|
+
|
400
|
+
it 'should paginate using default per_page when page provided in DSL' do
|
401
|
+
session.search Post do
|
402
|
+
paginate :page => 2
|
403
|
+
end
|
404
|
+
connection.should have_last_search_with(:rows => 30, :start => 30)
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'should paginate using default per_page when page provided in options' do
|
408
|
+
session.search Post, :page => 2
|
409
|
+
connection.should have_last_search_with(:rows => 30, :start => 30)
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'should paginate using provided per_page in DSL' do
|
413
|
+
session.search Post do
|
414
|
+
paginate :page => 4, :per_page => 15
|
415
|
+
end
|
416
|
+
connection.should have_last_search_with(:rows => 15, :start => 45)
|
417
|
+
end
|
418
|
+
|
419
|
+
it 'should paginate using provided per_page in options' do
|
420
|
+
session.search Post, :page => 4, :per_page => 15
|
421
|
+
connection.should have_last_search_with(:rows => 15, :start => 45)
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'should order in DSL' do
|
425
|
+
session.search Post do
|
426
|
+
order_by :average_rating, :desc
|
427
|
+
end
|
428
|
+
connection.should have_last_search_with(:sort => 'average_rating_f desc')
|
429
|
+
end
|
430
|
+
|
431
|
+
it 'should order in keywords' do
|
432
|
+
session.search Post, :order => 'average_rating desc'
|
433
|
+
connection.should have_last_search_with(:sort => 'average_rating_f desc')
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'should order by multiple fields in DSL' do
|
437
|
+
session.search Post do
|
438
|
+
order_by :average_rating, :desc
|
439
|
+
order_by :sort_title, :asc
|
440
|
+
end
|
441
|
+
connection.should have_last_search_with(:sort => 'average_rating_f desc, sort_title_s asc')
|
442
|
+
end
|
443
|
+
|
444
|
+
it 'should order by multiple fields in options' do
|
445
|
+
session.search Post, :order => ['average_rating desc', 'sort_title asc']
|
446
|
+
connection.should have_last_search_with(:sort => 'average_rating_f desc, sort_title_s asc')
|
447
|
+
end
|
448
|
+
|
449
|
+
it 'should order by a dynamic field' do
|
450
|
+
session.search Post do
|
451
|
+
dynamic :custom_integer do
|
452
|
+
order_by :test, :desc
|
453
|
+
end
|
454
|
+
end
|
455
|
+
connection.should have_last_search_with(:sort => 'custom_integer:test_i desc')
|
456
|
+
end
|
457
|
+
|
458
|
+
it 'should order by a dynamic field and static field, with given precedence' do
|
459
|
+
session.search Post do
|
460
|
+
dynamic :custom_integer do
|
461
|
+
order_by :test, :desc
|
462
|
+
end
|
463
|
+
order_by :sort_title, :asc
|
464
|
+
end
|
465
|
+
connection.should have_last_search_with(:sort => 'custom_integer:test_i desc, sort_title_s asc')
|
466
|
+
end
|
467
|
+
|
468
|
+
it 'should order by random' do
|
469
|
+
session.search Post do
|
470
|
+
order_by_random
|
471
|
+
end
|
472
|
+
connection.searches.last[:sort].should =~ /^random_\d+ asc$/
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'should throw an ArgumentError if a bogus order direction is given' do
|
476
|
+
lambda do
|
477
|
+
session.search Post do
|
478
|
+
order_by :sort_title, :sideways
|
479
|
+
end
|
480
|
+
end.should raise_error(ArgumentError)
|
481
|
+
end
|
482
|
+
|
483
|
+
it 'should not allow ordering by multiple-value fields' do
|
484
|
+
lambda do
|
485
|
+
session.search Post do
|
486
|
+
order_by :category_ids
|
487
|
+
end
|
488
|
+
end.should raise_error(ArgumentError)
|
489
|
+
end
|
490
|
+
|
491
|
+
it 'should not turn faceting on if no facet requested' do
|
492
|
+
session.search(Post)
|
493
|
+
connection.should_not have_last_search_with('facet')
|
494
|
+
end
|
495
|
+
|
496
|
+
it 'should turn faceting on if facet is requested' do
|
497
|
+
session.search Post do
|
498
|
+
facet :category_ids
|
499
|
+
end
|
500
|
+
connection.should have_last_search_with(:facet => 'true')
|
501
|
+
end
|
502
|
+
|
503
|
+
it 'should request single field facet' do
|
504
|
+
session.search Post do
|
505
|
+
facet :category_ids
|
506
|
+
end
|
507
|
+
connection.should have_last_search_with(:"facet.field" => %w(category_ids_im))
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'should request multiple field facets' do
|
511
|
+
session.search Post do
|
512
|
+
facet :category_ids, :blog_id
|
513
|
+
end
|
514
|
+
connection.should have_last_search_with(:"facet.field" => %w(category_ids_im blog_id_i))
|
515
|
+
end
|
516
|
+
|
517
|
+
it 'should set facet sort by count' do
|
518
|
+
session.search Post do
|
519
|
+
facet :category_ids, :sort => :count
|
520
|
+
end
|
521
|
+
connection.should have_last_search_with(:"f.category_ids_im.facet.sort" => 'true')
|
522
|
+
end
|
523
|
+
|
524
|
+
it 'should set facet sort by index' do
|
525
|
+
session.search Post do
|
526
|
+
facet :category_ids, :sort => :index
|
527
|
+
end
|
528
|
+
connection.should have_last_search_with(:"f.category_ids_im.facet.sort" => 'false')
|
529
|
+
end
|
530
|
+
|
531
|
+
it 'should throw ArgumentError if bogus facet sort provided' do
|
532
|
+
lambda do
|
533
|
+
session.search Post do
|
534
|
+
facet :category_ids, :sort => :sideways
|
535
|
+
end
|
536
|
+
end.should raise_error(ArgumentError)
|
537
|
+
end
|
538
|
+
|
539
|
+
it 'should set the facet limit' do
|
540
|
+
session.search Post do
|
541
|
+
facet :category_ids, :limit => 10
|
542
|
+
end
|
543
|
+
connection.should have_last_search_with(:"f.category_ids_im.facet.limit" => 10)
|
544
|
+
end
|
545
|
+
|
546
|
+
it 'should set the facet minimum count' do
|
547
|
+
session.search Post do
|
548
|
+
facet :category_ids, :minimum_count => 5
|
549
|
+
end
|
550
|
+
connection.should have_last_search_with(:"f.category_ids_im.facet.mincount" => 5)
|
551
|
+
end
|
552
|
+
|
553
|
+
it 'should set the facet minimum count to zero if zeros are allowed' do
|
554
|
+
session.search Post do
|
555
|
+
facet :category_ids, :zeros => true
|
556
|
+
end
|
557
|
+
connection.should have_last_search_with(:"f.category_ids_im.facet.mincount" => 0)
|
558
|
+
end
|
559
|
+
|
560
|
+
it 'should set the facet minimum count to one by default' do
|
561
|
+
session.search Post do
|
562
|
+
facet :category_ids
|
563
|
+
end
|
564
|
+
connection.should have_last_search_with(:"f.category_ids_im.facet.mincount" => 1)
|
565
|
+
end
|
566
|
+
|
567
|
+
describe 'with date faceting' do
|
568
|
+
before :each do
|
569
|
+
@time_range = (Time.parse('2009-06-01 00:00:00 -0400')..
|
570
|
+
Time.parse('2009-07-01 00:00:00 -0400'))
|
571
|
+
end
|
572
|
+
|
573
|
+
it 'should not send date facet parameters if time range is not specified' do
|
574
|
+
session.search Post do |query|
|
575
|
+
query.facet :published_at
|
576
|
+
end
|
577
|
+
connection.should_not have_last_search_with(:"facet.date")
|
578
|
+
end
|
579
|
+
|
580
|
+
it 'should set the facet to a date facet' do
|
581
|
+
session.search Post do |query|
|
582
|
+
query.facet :published_at, :time_range => @time_range
|
583
|
+
end
|
584
|
+
connection.should have_last_search_with(:"facet.date" => ['published_at_d'])
|
585
|
+
end
|
586
|
+
|
587
|
+
it 'should set the facet start and end' do
|
588
|
+
session.search Post do |query|
|
589
|
+
query.facet :published_at, :time_range => @time_range
|
590
|
+
end
|
591
|
+
connection.should have_last_search_with(
|
592
|
+
:"f.published_at_d.facet.date.start" => '2009-06-01T04:00:00Z',
|
593
|
+
:"f.published_at_d.facet.date.end" => '2009-07-01T04:00:00Z'
|
594
|
+
)
|
595
|
+
end
|
596
|
+
|
597
|
+
it 'should default the time interval to 1 day' do
|
598
|
+
session.search Post do |query|
|
599
|
+
query.facet :published_at, :time_range => @time_range
|
600
|
+
end
|
601
|
+
connection.should have_last_search_with(:"f.published_at_d.facet.date.gap" => "+86400SECONDS")
|
602
|
+
end
|
603
|
+
|
604
|
+
it 'should use custom time interval' do
|
605
|
+
session.search Post do |query|
|
606
|
+
query.facet :published_at, :time_range => @time_range, :time_interval => 3600
|
607
|
+
end
|
608
|
+
connection.should have_last_search_with(:"f.published_at_d.facet.date.gap" => "+3600SECONDS")
|
609
|
+
end
|
610
|
+
|
611
|
+
it 'should allow computation of one other time' do
|
612
|
+
session.search Post do |query|
|
613
|
+
query.facet :published_at, :time_range => @time_range, :time_other => :before
|
614
|
+
end
|
615
|
+
connection.should have_last_search_with(:"f.published_at_d.facet.date.other" => %w(before))
|
616
|
+
end
|
617
|
+
|
618
|
+
it 'should allow computation of two other times' do
|
619
|
+
session.search Post do |query|
|
620
|
+
query.facet :published_at, :time_range => @time_range, :time_other => [:before, :after]
|
621
|
+
end
|
622
|
+
connection.should have_last_search_with(:"f.published_at_d.facet.date.other" => %w(before after))
|
623
|
+
end
|
624
|
+
|
625
|
+
it 'should not allow computation of bogus other time' do
|
626
|
+
lambda do
|
627
|
+
session.search Post do |query|
|
628
|
+
query.facet :published_at, :time_range => @time_range, :time_other => :bogus
|
629
|
+
end
|
630
|
+
end.should raise_error(ArgumentError)
|
631
|
+
end
|
632
|
+
|
633
|
+
it 'should not allow date faceting on a non-date field' do
|
634
|
+
lambda do
|
635
|
+
session.search Post do |query|
|
636
|
+
query.facet :blog_id, :time_range => @time_range
|
637
|
+
end
|
638
|
+
end.should raise_error(ArgumentError)
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
describe 'with query faceting' do
|
643
|
+
it 'should turn faceting on' do
|
644
|
+
session.search Post do
|
645
|
+
facet :foo do
|
646
|
+
row :bar do
|
647
|
+
with(:average_rating).between(4.0..5.0)
|
648
|
+
end
|
649
|
+
end
|
650
|
+
end
|
651
|
+
connection.should have_last_search_with(:facet => 'true')
|
652
|
+
end
|
653
|
+
|
654
|
+
it 'should facet by query' do
|
655
|
+
session.search Post do
|
656
|
+
facet :foo do
|
657
|
+
row :bar do
|
658
|
+
with(:average_rating).between(4.0..5.0)
|
659
|
+
end
|
660
|
+
end
|
661
|
+
end
|
662
|
+
connection.should have_last_search_with(:"facet.query" => 'average_rating_f:[4\.0 TO 5\.0]')
|
663
|
+
end
|
664
|
+
|
665
|
+
it 'should request multiple query facets' do
|
666
|
+
session.search Post do
|
667
|
+
facet :foo do
|
668
|
+
row :bar do
|
669
|
+
with(:average_rating).between(3.0..4.0)
|
670
|
+
end
|
671
|
+
row :baz do
|
672
|
+
with(:average_rating).between(4.0..5.0)
|
673
|
+
end
|
674
|
+
end
|
675
|
+
end
|
676
|
+
connection.should have_last_search_with(
|
677
|
+
:"facet.query" => [
|
678
|
+
'average_rating_f:[3\.0 TO 4\.0]',
|
679
|
+
'average_rating_f:[4\.0 TO 5\.0]'
|
680
|
+
]
|
681
|
+
)
|
682
|
+
end
|
683
|
+
|
684
|
+
it 'should request query facet with multiple conditions' do
|
685
|
+
session.search Post do
|
686
|
+
facet :foo do
|
687
|
+
row :bar do
|
688
|
+
with(:category_ids, 1)
|
689
|
+
with(:blog_id, 2)
|
690
|
+
end
|
691
|
+
end
|
692
|
+
end
|
693
|
+
connection.should have_last_search_with(
|
694
|
+
:"facet.query" => '(category_ids_im:1 AND blog_id_i:2)'
|
695
|
+
)
|
696
|
+
end
|
697
|
+
|
698
|
+
it 'should request query facet with disjunction' do
|
699
|
+
session.search Post do
|
700
|
+
facet :foo do
|
701
|
+
row :bar do
|
702
|
+
any_of do
|
703
|
+
with(:category_ids, 1)
|
704
|
+
with(:blog_id, 2)
|
705
|
+
end
|
706
|
+
end
|
707
|
+
end
|
708
|
+
end
|
709
|
+
connection.should have_last_search_with(
|
710
|
+
:"facet.query" => '(category_ids_im:1 OR blog_id_i:2)'
|
711
|
+
)
|
712
|
+
end
|
713
|
+
|
714
|
+
it 'should request query facet with internal dynamic field' do
|
715
|
+
session.search Post do
|
716
|
+
facet :test do
|
717
|
+
row 'foo' do
|
718
|
+
dynamic :custom_string do
|
719
|
+
with :test, 'foo'
|
720
|
+
end
|
721
|
+
end
|
722
|
+
end
|
723
|
+
end
|
724
|
+
connection.should have_last_search_with(
|
725
|
+
:"facet.query" => 'custom_string\:test_s:foo'
|
726
|
+
)
|
727
|
+
end
|
728
|
+
|
729
|
+
it 'should request query facet with external dynamic field' do
|
730
|
+
session.search Post do
|
731
|
+
dynamic :custom_string do
|
732
|
+
facet :test do
|
733
|
+
row 'foo' do
|
734
|
+
with :test, 'foo'
|
735
|
+
end
|
736
|
+
end
|
737
|
+
end
|
738
|
+
end
|
739
|
+
connection.should have_last_search_with(
|
740
|
+
:"facet.query" => 'custom_string\:test_s:foo'
|
741
|
+
)
|
742
|
+
end
|
743
|
+
|
744
|
+
it 'should not allow 0 arguments to facet method with block' do
|
745
|
+
lambda do
|
746
|
+
session.search Post do
|
747
|
+
facet do
|
748
|
+
end
|
749
|
+
end
|
750
|
+
end.should raise_error(ArgumentError)
|
751
|
+
end
|
752
|
+
|
753
|
+
it 'should not allow more than 1 argument to facet method with block' do
|
754
|
+
lambda do
|
755
|
+
session.search Post do
|
756
|
+
facet :foo, :bar do
|
757
|
+
end
|
758
|
+
end
|
759
|
+
end.should raise_error(ArgumentError)
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
it 'should allow faceting by dynamic string field' do
|
764
|
+
session.search Post do
|
765
|
+
dynamic :custom_string do
|
766
|
+
facet :test
|
767
|
+
end
|
768
|
+
end
|
769
|
+
connection.should have_last_search_with(:"facet.field" => %w(custom_string:test_s))
|
770
|
+
end
|
771
|
+
|
772
|
+
it 'should properly escape namespaced type names' do
|
773
|
+
session.search(Namespaced::Comment)
|
774
|
+
connection.should have_last_search_with(:q => 'type:Namespaced\:\:Comment')
|
775
|
+
end
|
776
|
+
|
777
|
+
it 'should build search for multiple types' do
|
778
|
+
session.search(Post, Namespaced::Comment)
|
779
|
+
connection.should have_last_search_with(:q => 'type:(Post OR Namespaced\:\:Comment)')
|
780
|
+
end
|
781
|
+
|
782
|
+
it 'should allow search on fields common to all types with DSL' do
|
783
|
+
time = Time.parse('1983-07-08 05:00:00 -0400')
|
784
|
+
session.search Post, Namespaced::Comment do
|
785
|
+
with :published_at, time
|
786
|
+
end
|
787
|
+
connection.should have_last_search_with(:fq => ['published_at_d:1983\-07\-08T09\:00\:00Z'])
|
788
|
+
end
|
789
|
+
|
790
|
+
it 'should allow search on fields common to all types with conditions' do
|
791
|
+
time = Time.parse('1983-07-08 05:00:00 -0400')
|
792
|
+
session.search Post, Namespaced::Comment, :conditions => { :published_at => time }
|
793
|
+
connection.should have_last_search_with(:fq => ['published_at_d:1983\-07\-08T09\:00\:00Z'])
|
794
|
+
end
|
795
|
+
|
796
|
+
it 'should allow search on dynamic fields common to all types' do
|
797
|
+
session.search Post, Namespaced::Comment do
|
798
|
+
dynamic :custom_string do
|
799
|
+
with(:test, 'test')
|
800
|
+
end
|
801
|
+
end
|
802
|
+
connection.should have_last_search_with(:fq => ['custom_string\\:test_s:test'])
|
803
|
+
end
|
804
|
+
|
805
|
+
it 'should combine all text fields' do
|
806
|
+
session.search Post, Namespaced::Comment do
|
807
|
+
keywords 'keywords'
|
808
|
+
end
|
809
|
+
connection.searches.last[:qf].split(' ').sort.should ==
|
810
|
+
%w(author_name_text backwards_title_text body_text title_text)
|
811
|
+
end
|
812
|
+
|
813
|
+
it 'should allow specification of a text field that only exists in one type' do
|
814
|
+
session.search Post, Namespaced::Comment do
|
815
|
+
keywords 'keywords', :fields => :author_name
|
816
|
+
end
|
817
|
+
connection.searches.last[:qf].should == 'author_name_text'
|
818
|
+
end
|
819
|
+
|
820
|
+
it 'should raise Sunspot::UnrecognizedFieldError if search scoped to field not common to all types' do
|
821
|
+
lambda do
|
822
|
+
session.search Post, Namespaced::Comment do
|
823
|
+
with :blog_id, 1
|
824
|
+
end
|
825
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
826
|
+
end
|
827
|
+
|
828
|
+
it 'should raise Sunspot::UnrecognizedFieldError if search scoped to field configured differently between types' do
|
829
|
+
lambda do
|
830
|
+
session.search Post, Namespaced::Comment do
|
831
|
+
with :average_rating, 2.2 # this is a float in Post but an integer in Comment
|
832
|
+
end
|
833
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
834
|
+
end
|
835
|
+
|
836
|
+
it 'should raise Sunspot::UnrecognizedFieldError if a text field that does not exist for any type is specified' do
|
837
|
+
lambda do
|
838
|
+
session.search Post, Namespaced::Comment do
|
839
|
+
keywords 'fulltext', :fields => :bogus
|
840
|
+
end
|
841
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
842
|
+
end
|
843
|
+
|
844
|
+
it 'should ignore condition if field is not common to all types' do
|
845
|
+
session.search Post, Namespaced::Comment, :conditions => { :blog_id => 1 }
|
846
|
+
connection.should_not have_last_search_with(:fq)
|
847
|
+
end
|
848
|
+
|
849
|
+
it 'should allow building search using block argument rather than instance_eval' do
|
850
|
+
@blog_id = 1
|
851
|
+
session.search Post do |query|
|
852
|
+
query.with(:blog_id, @blog_id)
|
853
|
+
end
|
854
|
+
connection.should have_last_search_with(:fq => ['blog_id_i:1'])
|
855
|
+
end
|
856
|
+
|
857
|
+
it 'should raise Sunspot::UnrecognizedFieldError for nonexistant fields in block scope' do
|
858
|
+
lambda do
|
859
|
+
session.search Post do
|
860
|
+
with :bogus, 'Field'
|
861
|
+
end
|
862
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
863
|
+
end
|
864
|
+
|
865
|
+
it 'should raise Sunspot::UnrecognizedFieldError for nonexistant fields in keywords' do
|
866
|
+
lambda do
|
867
|
+
session.search Post do
|
868
|
+
keywords 'text', :fields => :bogus
|
869
|
+
end
|
870
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
871
|
+
end
|
872
|
+
|
873
|
+
it 'should raise NoMethodError if bogus operator referenced' do
|
874
|
+
lambda do
|
875
|
+
session.search Post do
|
876
|
+
with(:category_ids).resembling :bogus_condition
|
877
|
+
end
|
878
|
+
end.should raise_error(NoMethodError)
|
879
|
+
end
|
880
|
+
|
881
|
+
it 'should raise ArgumentError if no :page argument given to paginate' do
|
882
|
+
lambda do
|
883
|
+
session.search Post do
|
884
|
+
paginate
|
885
|
+
end
|
886
|
+
end.should raise_error(ArgumentError)
|
887
|
+
end
|
888
|
+
|
889
|
+
it 'should raise ArgumentError if bogus argument given to paginate' do
|
890
|
+
lambda do
|
891
|
+
session.search Post do
|
892
|
+
paginate :page => 4, :ugly => :puppy
|
893
|
+
end
|
894
|
+
end.should raise_error(ArgumentError)
|
895
|
+
end
|
896
|
+
|
897
|
+
it 'should raise ArgumentError if more than two arguments passed to scope method' do
|
898
|
+
lambda do
|
899
|
+
session.search Post do
|
900
|
+
with(:category_ids, 4, 5)
|
901
|
+
end
|
902
|
+
end.should raise_error(ArgumentError)
|
903
|
+
end
|
904
|
+
|
905
|
+
private
|
906
|
+
|
907
|
+
def config
|
908
|
+
@config ||= Sunspot::Configuration.build
|
909
|
+
end
|
910
|
+
|
911
|
+
def connection
|
912
|
+
@connection ||= Mock::Connection.new
|
913
|
+
end
|
914
|
+
|
915
|
+
def session
|
916
|
+
@session ||= Sunspot::Session.new(config, connection)
|
917
|
+
end
|
918
|
+
end
|