Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 898 lines (731 sloc) 32.495 kB
be1f234 @nertzy Use simpler require for spec_helper
nertzy authored
1 require "spec_helper"
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
2
3 describe "an ActiveRecord model which includes PgSearch" do
4
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
5 with_model :ModelWithPgSearch do
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
6 table do |t|
cf26fb2 Add support for searching multiple columns
Grant Hutchins & Peter Jaros authored
7 t.string 'title'
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
8 t.text 'content'
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
9 t.integer 'importance'
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
10 end
11
12 model do
13 include PgSearch
14 end
15 end
16
cf26fb2 Add support for searching multiple columns
Grant Hutchins & Peter Jaros authored
17 describe ".pg_search_scope" do
04a4b1d @nertzy Clean up specs
nertzy authored
18 it "builds a chainable scope" do
19 ModelWithPgSearch.pg_search_scope "matching_query", :against => []
20 scope = ModelWithPgSearch.scoped({}).matching_query("foo").scoped({})
21 scope.should be_an ActiveRecord::Relation
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
22 end
23
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
24 context "when passed a lambda" do
25 it "builds a dynamic scope" do
04a4b1d @nertzy Clean up specs
nertzy authored
26 ModelWithPgSearch.pg_search_scope :search_title_or_content,
27 lambda { |query, pick_content|
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
28 {
29 :query => query.gsub("-remove-", ""),
30 :against => pick_content ? :content : :title
31 }
32 }
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
33
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
34 included = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
35 excluded = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
36
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
37 ModelWithPgSearch.search_title_or_content('fo-remove-o', false).should == [included]
38 ModelWithPgSearch.search_title_or_content('b-remove-ar', true).should == [included]
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
39 end
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
40 end
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
41
42 context "when an unknown option is passed in" do
43 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
44 ModelWithPgSearch.pg_search_scope :with_unknown_option,
45 :against => :content,
46 :foo => :bar
47
48 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
49 ModelWithPgSearch.with_unknown_option("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
50 }.to raise_error(ArgumentError, /foo/)
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
51 end
52
53 context "dynamically" do
54 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
55 ModelWithPgSearch.pg_search_scope :with_unknown_option,
56 lambda { |*| {:against => :content, :foo => :bar} }
57
58 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
59 ModelWithPgSearch.with_unknown_option("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
60 }.to raise_error(ArgumentError, /foo/)
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
61 end
62 end
63 end
64
65 context "when an unknown :using is passed" do
66 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
67 ModelWithPgSearch.pg_search_scope :with_unknown_using,
68 :against => :content,
69 :using => :foo
70
71 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
72 ModelWithPgSearch.with_unknown_using("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
73 }.to raise_error(ArgumentError, /foo/)
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
74 end
75
76 context "dynamically" do
77 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
78 ModelWithPgSearch.pg_search_scope :with_unknown_using,
79 lambda { |*| {:against => :content, :using => :foo} }
80
81 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
82 ModelWithPgSearch.with_unknown_using("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
83 }.to raise_error(ArgumentError, /foo/)
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
84 end
85 end
86 end
87
706d81e Change the weird :normalizing => :diacritics API to :ignoring => :acc…
Grant Hutchins & Rachel Heaton authored
88 context "when an unknown :ignoring is passed" do
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
89 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
90 ModelWithPgSearch.pg_search_scope :with_unknown_ignoring,
91 :against => :content,
92 :ignoring => :foo
93
94 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
95 ModelWithPgSearch.with_unknown_ignoring("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
96 }.to raise_error(ArgumentError, /ignoring.*foo/)
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
97 end
98
99 context "dynamically" do
100 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
101 ModelWithPgSearch.pg_search_scope :with_unknown_ignoring,
102 lambda { |*| {:against => :content, :ignoring => :foo} }
103
104 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
105 ModelWithPgSearch.with_unknown_ignoring("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
106 }.to raise_error(ArgumentError, /ignoring.*foo/)
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
107 end
108 end
6ce7ce5 Add specs for testing that :against is present
Grant Hutchins & Peter Jaros authored
109
110 context "when :against is not passed in" do
111 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
112 ModelWithPgSearch.pg_search_scope :with_unknown_ignoring, {}
113
114 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
115 ModelWithPgSearch.with_unknown_ignoring("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
116 }.to raise_error(ArgumentError, /against/)
6ce7ce5 Add specs for testing that :against is present
Grant Hutchins & Peter Jaros authored
117 end
04a4b1d @nertzy Clean up specs
nertzy authored
118
6ce7ce5 Add specs for testing that :against is present
Grant Hutchins & Peter Jaros authored
119 context "dynamically" do
120 it "raises an exception when invoked" do
04a4b1d @nertzy Clean up specs
nertzy authored
121 ModelWithPgSearch.pg_search_scope :with_unknown_ignoring,
122 lambda { |*| {} }
123
124 expect {
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
125 ModelWithPgSearch.with_unknown_ignoring("foo")
04a4b1d @nertzy Clean up specs
nertzy authored
126 }.to raise_error(ArgumentError, /against/)
6ce7ce5 Add specs for testing that :against is present
Grant Hutchins & Peter Jaros authored
127 end
128 end
129 end
861b37f Validate options passed into pg_search_scope
Grant Hutchins & Peter Jaros authored
130 end
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
131 end
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
132
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
133 describe "a search scope" do
134 context "against a single column" do
135 before do
04a4b1d @nertzy Clean up specs
nertzy authored
136 ModelWithPgSearch.pg_search_scope :search_content, :against => :content
cf26fb2 Add support for searching multiple columns
Grant Hutchins & Peter Jaros authored
137 end
138
12dc34c @nertzy tsearch properly handles blank queries
nertzy authored
139 it "returns an empty array when a blank query is passed in" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
140 ModelWithPgSearch.create!(:content => 'foo')
12dc34c @nertzy tsearch properly handles blank queries
nertzy authored
141
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
142 results = ModelWithPgSearch.search_content('')
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
143 results.should == []
12dc34c @nertzy tsearch properly handles blank queries
nertzy authored
144 end
145
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
146 it "returns rows where the column contains the term in the query" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
147 included = ModelWithPgSearch.create!(:content => 'foo')
148 excluded = ModelWithPgSearch.create!(:content => 'bar')
7557f2c Support searching multiple words across multiple columns
Grant Hutchins & Peter Jaros authored
149
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
150 results = ModelWithPgSearch.search_content('foo')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
151 results.should include(included)
152 results.should_not include(excluded)
7557f2c Support searching multiple words across multiple columns
Grant Hutchins & Peter Jaros authored
153 end
fd34c1c Accept a lambda to build a dynamic pg_search_scope
Grant Hutchins & Peter Jaros authored
154
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
155 it "returns rows where the column contains all the terms in the query in any order" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
156 included = [ModelWithPgSearch.create!(:content => 'foo bar'),
157 ModelWithPgSearch.create!(:content => 'bar foo')]
158 excluded = ModelWithPgSearch.create!(:content => 'foo')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
159
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
160 results = ModelWithPgSearch.search_content('foo bar')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
161 results.should =~ included
162 results.should_not include(excluded)
cfadef7 Support NULL values when searching multiple columns
Grant Hutchins & Peter Jaros authored
163 end
164
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
165 it "returns rows that match the query but not its case" do
166 # \303\241 is a with acute accent
167 # \303\251 is e with acute accent
cfadef7 Support NULL values when searching multiple columns
Grant Hutchins & Peter Jaros authored
168
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
169 included = [ModelWithPgSearch.create!(:content => "foo"),
170 ModelWithPgSearch.create!(:content => "FOO")]
cfadef7 Support NULL values when searching multiple columns
Grant Hutchins & Peter Jaros authored
171
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
172 results = ModelWithPgSearch.search_content("Foo")
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
173 results.should =~ included
174 end
cfadef7 Support NULL values when searching multiple columns
Grant Hutchins & Peter Jaros authored
175
706d81e Change the weird :normalizing => :diacritics API to :ignoring => :acc…
Grant Hutchins & Rachel Heaton authored
176 it "returns rows that match the query only if their accents match" do
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
177 # \303\241 is a with acute accent
178 # \303\251 is e with acute accent
179
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
180 included = ModelWithPgSearch.create!(:content => "abcd\303\251f")
181 excluded = ModelWithPgSearch.create!(:content => "\303\241bcdef")
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
182
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
183 results = ModelWithPgSearch.search_content("abcd\303\251f")
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
184 results.should == [included]
185 results.should_not include(excluded)
4d09415 @nertzy Add support for searching trigrams
nertzy authored
186 end
187
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
188 it "returns rows that match the query but not rows that are prefixed by the query" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
189 included = ModelWithPgSearch.create!(:content => 'pre')
190 excluded = ModelWithPgSearch.create!(:content => 'prefix')
4d09415 @nertzy Add support for searching trigrams
nertzy authored
191
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
192 results = ModelWithPgSearch.search_content("pre")
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
193 results.should == [included]
194 results.should_not include(excluded)
195 end
4d09415 @nertzy Add support for searching trigrams
nertzy authored
196
93a3aea @nertzy Always specify dictionary. :simple is new default.
nertzy authored
197 it "returns rows that match the query exactly and not those that match the query when stemmed by the default english dictionary" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
198 included = ModelWithPgSearch.create!(:content => "jumped")
199 excluded = [ModelWithPgSearch.create!(:content => "jump"),
200 ModelWithPgSearch.create!(:content => "jumping")]
4d09415 @nertzy Add support for searching trigrams
nertzy authored
201
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
202 results = ModelWithPgSearch.search_content("jumped")
93a3aea @nertzy Always specify dictionary. :simple is new default.
nertzy authored
203 results.should == [included]
698a3c4 @nertzy Support scopes that use multiple features
nertzy authored
204 end
205
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
206 it "returns rows that match sorted by rank" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
207 loser = ModelWithPgSearch.create!(:content => 'foo')
208 winner = ModelWithPgSearch.create!(:content => 'foo foo')
698a3c4 @nertzy Support scopes that use multiple features
nertzy authored
209
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
210 results = ModelWithPgSearch.search_content("foo")
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
211 results[0].pg_search_rank.should > results[1].pg_search_rank
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
212 results.should == [winner, loser]
213 end
698a3c4 @nertzy Support scopes that use multiple features
nertzy authored
214
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
215 it "returns results that match sorted by primary key for records that rank the same" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
216 sorted_results = [ModelWithPgSearch.create!(:content => 'foo'),
217 ModelWithPgSearch.create!(:content => 'foo')].sort_by(&:id)
698a3c4 @nertzy Support scopes that use multiple features
nertzy authored
218
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
219 results = ModelWithPgSearch.search_content("foo")
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
220 results.should == sorted_results
6dabf15 @nertzy Make searches case-insensitive
nertzy authored
221 end
222
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
223 it "returns results that match a query with multiple space-separated search terms" do
224 included = [
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
225 ModelWithPgSearch.create!(:content => 'foo bar'),
226 ModelWithPgSearch.create!(:content => 'bar foo'),
227 ModelWithPgSearch.create!(:content => 'bar foo baz'),
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
228 ]
229 excluded = [
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
230 ModelWithPgSearch.create!(:content => 'foo'),
231 ModelWithPgSearch.create!(:content => 'foo baz')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
232 ]
233
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
234 results = ModelWithPgSearch.search_content('foo bar')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
235 results.should =~ included
236 results.should_not include(excluded)
237 end
6dabf15 @nertzy Make searches case-insensitive
nertzy authored
238
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
239 it "returns rows that match a query with characters that are invalid in a tsquery expression" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
240 included = ModelWithPgSearch.create!(:content => "(:Foo.) Bar?, \\")
6dabf15 @nertzy Make searches case-insensitive
nertzy authored
241
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
242 results = ModelWithPgSearch.search_content("foo :bar .,?() \\")
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
243 results.should == [included]
244 end
956296d " w " in a query no longer breaks dmetaphone
Grant Hutchins & Michael Schubert authored
245
314650a Accept non-string queries
Grant Hutchins & Peter Jaros authored
246 it "accepts non-string queries and calls #to_s on them" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
247 foo = ModelWithPgSearch.create!(:content => "foo")
314650a Accept non-string queries
Grant Hutchins & Peter Jaros authored
248 not_a_string = stub(:to_s => "foo")
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
249 ModelWithPgSearch.search_content(not_a_string).should == [foo]
314650a Accept non-string queries
Grant Hutchins & Peter Jaros authored
250 end
41615c6 @nertzy Always cast columns to text
nertzy authored
251
252 context "when the column is not text" do
253 with_model :ModelWithTimestamps do
254 table do |t|
255 t.timestamps
256 end
257
258 model do
259 include PgSearch
260
261 # WARNING: searching timestamps is not something PostgreSQL
262 # full-text search is good at. Use at your own risk.
263 pg_search_scope :search_timestamps,
264 :against => [:created_at, :updated_at]
265 end
266 end
267
268 it "casts the column to text" do
269 record = ModelWithTimestamps.create!
270
271 query = record.created_at.strftime("%Y-%m-%d")
272 results = ModelWithTimestamps.search_timestamps(query)
273 results.should == [record]
274 end
275 end
6dabf15 @nertzy Make searches case-insensitive
nertzy authored
276 end
277
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
278 context "against multiple columns" do
279 before do
04a4b1d @nertzy Clean up specs
nertzy authored
280 ModelWithPgSearch.pg_search_scope :search_title_and_content, :against => [:title, :content]
5d9fa06 @nertzy Add support for removing accent marks
nertzy authored
281 end
282
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
283 it "returns rows whose columns contain all of the terms in the query across columns" do
284 included = [
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
285 ModelWithPgSearch.create!(:title => 'foo', :content => 'bar'),
286 ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
287 ]
288 excluded = [
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
289 ModelWithPgSearch.create!(:title => 'foo', :content => 'foo'),
290 ModelWithPgSearch.create!(:title => 'bar', :content => 'bar')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
291 ]
5d9fa06 @nertzy Add support for removing accent marks
nertzy authored
292
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
293 results = ModelWithPgSearch.search_title_and_content('foo bar')
5d9fa06 @nertzy Add support for removing accent marks
nertzy authored
294
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
295 results.should =~ included
296 excluded.each do |result|
297 results.should_not include(result)
298 end
299 end
300
301 it "returns rows where at one column contains all of the terms in the query and another does not" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
302 in_title = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
303 in_content = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
3c6d386 Test both columns in the multiple columns spec
Grant Hutchins, Lee Edwards & Rachel Heaton authored
304
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
305 results = ModelWithPgSearch.search_title_and_content('foo')
3c6d386 Test both columns in the multiple columns spec
Grant Hutchins, Lee Edwards & Rachel Heaton authored
306 results.should =~ [in_title, in_content]
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
307 end
308
309 # Searching with a NULL column will prevent any matches unless we coalesce it.
310 it "returns rows where at one column contains all of the terms in the query and another is NULL" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
311 included = ModelWithPgSearch.create!(:title => 'foo', :content => nil)
312 results = ModelWithPgSearch.search_title_and_content('foo')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
313 results.should == [included]
314 end
5d9fa06 @nertzy Add support for removing accent marks
nertzy authored
315 end
316
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
317 context "using trigram" do
318 before do
04a4b1d @nertzy Clean up specs
nertzy authored
319 ModelWithPgSearch.pg_search_scope :with_trigrams, :against => [:title, :content], :using => :trigram
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
320 end
5d9fa06 @nertzy Add support for removing accent marks
nertzy authored
321
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
322 it "returns rows where one searchable column and the query share enough trigrams" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
323 included = ModelWithPgSearch.create!(:title => 'abcdefghijkl', :content => nil)
324 results = ModelWithPgSearch.with_trigrams('cdefhijkl')
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
325 results.should == [included]
326 end
5d9fa06 @nertzy Add support for removing accent marks
nertzy authored
327
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
328 it "returns rows where multiple searchable columns and the query share enough trigrams" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
329 included = ModelWithPgSearch.create!(:title => 'abcdef', :content => 'ghijkl')
330 results = ModelWithPgSearch.with_trigrams('cdefhijkl')
5d9fa06 @nertzy Add support for removing accent marks
nertzy authored
331 results.should == [included]
332 end
333 end
334
92d829e Change prefix matching from a :normalizing option to a tsearch-specif…
Grant Hutchins & Peter Jaros authored
335 context "using tsearch" do
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
336 before do
04a4b1d @nertzy Clean up specs
nertzy authored
337 ModelWithPgSearch.pg_search_scope :search_title_with_prefixes,
338 :against => :title,
339 :using => {
340 :tsearch => {:prefix => true}
341 }
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
342 end
92d829e Change prefix matching from a :normalizing option to a tsearch-specif…
Grant Hutchins & Peter Jaros authored
343
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
344 if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
345 it "is unsupported in PostgreSQL 8.3 and earlier" do
04a4b1d @nertzy Clean up specs
nertzy authored
346 expect {
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
347 ModelWithPgSearch.search_title_with_prefixes("abcd\303\251f")
04a4b1d @nertzy Clean up specs
nertzy authored
348 }.to raise_exception(PgSearch::NotSupportedForPostgresqlVersion)
92d829e Change prefix matching from a :normalizing option to a tsearch-specif…
Grant Hutchins & Peter Jaros authored
349 end
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
350 else
351 context "with :prefix => true" do
352 it "returns rows that match the query and that are prefixed by the query" do
353 included = ModelWithPgSearch.create!(:title => 'prefix')
354 excluded = ModelWithPgSearch.create!(:title => 'postfix')
355
356 results = ModelWithPgSearch.search_title_with_prefixes("pre")
357 results.should == [included]
358 results.should_not include(excluded)
359 end
62adada @nertzy Split tsearch queries on hyphen to improve quality of results
nertzy authored
360
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
361 it "returns rows that match the query when the query has a hyphen" do
07161f1 @nertzy Allow hyphens in tsquery
nertzy authored
362 included = ModelWithPgSearch.create!(:title => 'foo-bar')
363 excluded = ModelWithPgSearch.create!(:title => 'foo bar')
62adada @nertzy Split tsearch queries on hyphen to improve quality of results
nertzy authored
364
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
365 results = ModelWithPgSearch.search_title_with_prefixes("foo-bar")
07161f1 @nertzy Allow hyphens in tsquery
nertzy authored
366 results.should include(included)
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
367 results.should_not include(excluded)
368 end
62adada @nertzy Split tsearch queries on hyphen to improve quality of results
nertzy authored
369 end
92d829e Change prefix matching from a :normalizing option to a tsearch-specif…
Grant Hutchins & Peter Jaros authored
370 end
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
371
93a3aea @nertzy Always specify dictionary. :simple is new default.
nertzy authored
372 context "with the english dictionary" do
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
373 before do
04a4b1d @nertzy Clean up specs
nertzy authored
374 ModelWithPgSearch.pg_search_scope :search_content_with_english,
375 :against => :content,
376 :using => {
377 :tsearch => {:dictionary => :english}
378 }
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
379 end
380
93a3aea @nertzy Always specify dictionary. :simple is new default.
nertzy authored
381 it "returns rows that match the query when stemmed by the english dictionary" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
382 included = [ModelWithPgSearch.create!(:content => "jump"),
383 ModelWithPgSearch.create!(:content => "jumped"),
384 ModelWithPgSearch.create!(:content => "jumping")]
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
385
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
386 results = ModelWithPgSearch.search_content_with_english("jump")
93a3aea @nertzy Always specify dictionary. :simple is new default.
nertzy authored
387 results.should =~ included
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
388 end
389 end
0ade7a0 whitespace
Jeronimo Colon & Michael Schubert authored
390
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
391 describe "ranking" do
392 before do
393 ["Strip Down", "Down", "Down and Out", "Won't Let You Down"].each do |name|
394 ModelWithPgSearch.create! :content => name
395 end
396 end
0ade7a0 whitespace
Jeronimo Colon & Michael Schubert authored
397
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
398 it "adds a #pg_search_rank method to each returned model record" do
04a4b1d @nertzy Clean up specs
nertzy authored
399 ModelWithPgSearch.pg_search_scope :search_content, :against => :content
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
400
401 result = ModelWithPgSearch.search_content("Strip Down").first
402
403 result.pg_search_rank.should be_a(Float)
404 end
405
41f0390 @nertzy Rename :normalization_option to just :normalization
nertzy authored
406 context "with a normalization specified" do
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
407 before do
04a4b1d @nertzy Clean up specs
nertzy authored
408 ModelWithPgSearch.pg_search_scope :search_content_with_normalization,
409 :against => :content,
410 :using => {
411 :tsearch => {:normalization => 2}
412 }
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
413 end
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
414
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
415 it "ranks the results for documents with less text higher" do
416 results = ModelWithPgSearch.search_content_with_normalization("down")
0ade7a0 whitespace
Jeronimo Colon & Michael Schubert authored
417
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
418 results.map(&:content).should == ["Down", "Strip Down", "Down and Out", "Won't Let You Down"]
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
419 results.first.pg_search_rank.should be > results.last.pg_search_rank
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
420 end
421 end
0ade7a0 whitespace
Jeronimo Colon & Michael Schubert authored
422
41f0390 @nertzy Rename :normalization_option to just :normalization
nertzy authored
423 context "with no normalization" do
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
424 before do
04a4b1d @nertzy Clean up specs
nertzy authored
425 ModelWithPgSearch.pg_search_scope :search_content_without_normalization,
426 :against => :content,
427 :using => :tsearch
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
428 end
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
429
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
430 it "ranks the results equally" do
431 results = ModelWithPgSearch.search_content_without_normalization("down")
0ade7a0 whitespace
Jeronimo Colon & Michael Schubert authored
432
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
433 results.map(&:content).should == ["Strip Down", "Down", "Down and Out", "Won't Let You Down"]
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
434 results.first.pg_search_rank.should == results.last.pg_search_rank
1d0c501 @gunn Added support for specifying a method of rank normalisation when usin…
gunn authored
435 end
436 end
437 end
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
438
439 context "against columns ranked with arrays" do
440 before do
04a4b1d @nertzy Clean up specs
nertzy authored
441 ModelWithPgSearch.pg_search_scope :search_weighted_by_array_of_arrays,
442 :against => [[:content, 'B'], [:title, 'A']]
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
443 end
444
445 it "returns results sorted by weighted rank" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
446 loser = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
447 winner = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
448
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
449 results = ModelWithPgSearch.search_weighted_by_array_of_arrays('foo')
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
450 results[0].pg_search_rank.should > results[1].pg_search_rank
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
451 results.should == [winner, loser]
452 end
453 end
454
455 context "against columns ranked with a hash" do
456 before do
04a4b1d @nertzy Clean up specs
nertzy authored
457 ModelWithPgSearch.pg_search_scope :search_weighted_by_hash,
458 :against => {:content => 'B', :title => 'A'}
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
459 end
460
461 it "returns results sorted by weighted rank" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
462 loser = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
463 winner = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
464
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
465 results = ModelWithPgSearch.search_weighted_by_hash('foo')
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
466 results[0].pg_search_rank.should > results[1].pg_search_rank
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
467 results.should == [winner, loser]
468 end
469 end
470
471 context "against columns of which only some are ranked" do
472 before do
04a4b1d @nertzy Clean up specs
nertzy authored
473 ModelWithPgSearch.pg_search_scope :search_weighted,
474 :against => [:content, [:title, 'A']]
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
475 end
476
477 it "returns results sorted by weighted rank using an implied low rank for unranked columns" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
478 loser = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
479 winner = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
480
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
481 results = ModelWithPgSearch.search_weighted('foo')
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
482 results[0].pg_search_rank.should > results[1].pg_search_rank
de8fb62 Reorganize pg_search_spec
Grant Hutchins & Rachel Heaton authored
483 results.should == [winner, loser]
484 end
485 end
fc72793 @Ferdev Add :any_word option to :tsearch search feature
Ferdev authored
486
487 context "searching any_word option" do
488 before do
04a4b1d @nertzy Clean up specs
nertzy authored
489 ModelWithPgSearch.pg_search_scope :search_title_with_any_word,
490 :against => :title,
491 :using => {
492 :tsearch => {:any_word => true}
493 }
494
495 ModelWithPgSearch.pg_search_scope :search_title_with_all_words,
496 :against => :title
fc72793 @Ferdev Add :any_word option to :tsearch search feature
Ferdev authored
497 end
498
499 it "returns all results containing any word in their title" do
500 numbers = %w(one two three four).map{|number| ModelWithPgSearch.create!(:title => number)}
501
502 results = ModelWithPgSearch.search_title_with_any_word("one two three four")
503
504 results.map(&:title).should == %w(one two three four)
505
506 results = ModelWithPgSearch.search_title_with_all_words("one two three four")
507
508 results.map(&:title).should == []
509 end
510 end
92d829e Change prefix matching from a :normalizing option to a tsearch-specif…
Grant Hutchins & Peter Jaros authored
511 end
512
c0d9b25 Add support for :dmetaphone
Grant Hutchins & Peter Jaros authored
513 context "using dmetaphone" do
514 before do
04a4b1d @nertzy Clean up specs
nertzy authored
515 ModelWithPgSearch.pg_search_scope :with_dmetaphones,
516 :against => [:title, :content],
517 :using => :dmetaphone
c0d9b25 Add support for :dmetaphone
Grant Hutchins & Peter Jaros authored
518 end
519
520 it "returns rows where one searchable column and the query share enough dmetaphones" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
521 included = ModelWithPgSearch.create!(:title => 'Geoff', :content => nil)
522 excluded = ModelWithPgSearch.create!(:title => 'Bob', :content => nil)
523 results = ModelWithPgSearch.with_dmetaphones('Jeff')
c0d9b25 Add support for :dmetaphone
Grant Hutchins & Peter Jaros authored
524 results.should == [included]
525 end
526
527 it "returns rows where multiple searchable columns and the query share enough dmetaphones" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
528 included = ModelWithPgSearch.create!(:title => 'Geoff', :content => 'George')
529 excluded = ModelWithPgSearch.create!(:title => 'Bob', :content => 'Jones')
530 results = ModelWithPgSearch.with_dmetaphones('Jeff Jorge')
c0d9b25 Add support for :dmetaphone
Grant Hutchins & Peter Jaros authored
531 results.should == [included]
532 end
4da4e19 return results for strings whose dmetaphone maps to an English stopword
Grant Hutchins & Peter Jaros authored
533
534 it "returns rows that match dmetaphones that are English stopwords" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
535 included = ModelWithPgSearch.create!(:title => 'White', :content => nil)
536 excluded = ModelWithPgSearch.create!(:title => 'Black', :content => nil)
537 results = ModelWithPgSearch.with_dmetaphones('Wight')
4da4e19 return results for strings whose dmetaphone maps to an English stopword
Grant Hutchins & Peter Jaros authored
538 results.should == [included]
539 end
956296d " w " in a query no longer breaks dmetaphone
Grant Hutchins & Michael Schubert authored
540
541 it "can handle terms that do not have a dmetaphone equivalent" do
542 term_with_blank_metaphone = "w"
543
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
544 included = ModelWithPgSearch.create!(:title => 'White', :content => nil)
545 excluded = ModelWithPgSearch.create!(:title => 'Black', :content => nil)
956296d " w " in a query no longer breaks dmetaphone
Grant Hutchins & Michael Schubert authored
546
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
547 results = ModelWithPgSearch.with_dmetaphones('Wight W')
956296d " w " in a query no longer breaks dmetaphone
Grant Hutchins & Michael Schubert authored
548 results.should == [included]
549 end
c0d9b25 Add support for :dmetaphone
Grant Hutchins & Peter Jaros authored
550 end
551
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
552 context "using multiple features" do
553 before do
04a4b1d @nertzy Clean up specs
nertzy authored
554 ModelWithPgSearch.pg_search_scope :with_tsearch,
555 :against => :title,
556 :using => [
557 [:tsearch, {:dictionary => 'english'}]
558 ]
559
560 ModelWithPgSearch.pg_search_scope :with_trigram,
561 :against => :title,
562 :using => :trigram
563
564 ModelWithPgSearch.pg_search_scope :with_tsearch_and_trigram,
565 :against => :title,
566 :using => [
567 [:tsearch, {:dictionary => 'english'}],
568 :trigram
569 ]
6a96a8e Extract TSearch and Trigram implementations into their own classes
Grant Hutchins & Peter Jaros authored
570
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
571 end
fd34c1c Accept a lambda to build a dynamic pg_search_scope
Grant Hutchins & Peter Jaros authored
572
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
573 it "returns rows that match using any of the features" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
574 record = ModelWithPgSearch.create!(:title => "tiling is grouty")
fd34c1c Accept a lambda to build a dynamic pg_search_scope
Grant Hutchins & Peter Jaros authored
575
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
576 # matches trigram only
577 trigram_query = "ling is grouty"
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
578 ModelWithPgSearch.with_trigram(trigram_query).should include(record)
579 ModelWithPgSearch.with_tsearch(trigram_query).should_not include(record)
04a4b1d @nertzy Clean up specs
nertzy authored
580 ModelWithPgSearch.with_tsearch_and_trigram(trigram_query).should == [record]
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
581
582 # matches tsearch only
e5d721e @nertzy PostgreSQL 8.3 and earlier do not support :prefix
nertzy authored
583 tsearch_query = "tiles"
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
584 ModelWithPgSearch.with_tsearch(tsearch_query).should include(record)
585 ModelWithPgSearch.with_trigram(tsearch_query).should_not include(record)
04a4b1d @nertzy Clean up specs
nertzy authored
586 ModelWithPgSearch.with_tsearch_and_trigram(tsearch_query).should == [record]
6a96a8e Extract TSearch and Trigram implementations into their own classes
Grant Hutchins & Peter Jaros authored
587 end
588
589 context "with feature-specific configuration" do
590 before do
9b386e9 Refactor interpolations
Grant Hutchins & Peter Jaros authored
591 @tsearch_config = tsearch_config = {:dictionary => 'english'}
6a96a8e Extract TSearch and Trigram implementations into their own classes
Grant Hutchins & Peter Jaros authored
592 @trigram_config = trigram_config = {:foo => 'bar'}
593
04a4b1d @nertzy Clean up specs
nertzy authored
594 ModelWithPgSearch.pg_search_scope :with_tsearch_and_trigram_using_hash,
595 :against => :title,
596 :using => {
597 :tsearch => tsearch_config,
598 :trigram => trigram_config
599 }
6a96a8e Extract TSearch and Trigram implementations into their own classes
Grant Hutchins & Peter Jaros authored
600 end
601
602 it "should pass the custom configuration down to the specified feature" do
603 stub_feature = stub(:conditions => "1 = 1", :rank => "1.0")
9b386e9 Refactor interpolations
Grant Hutchins & Peter Jaros authored
604 PgSearch::Features::TSearch.should_receive(:new).with(anything, @tsearch_config, anything, anything, anything).at_least(:once).and_return(stub_feature)
605 PgSearch::Features::Trigram.should_receive(:new).with(anything, @trigram_config, anything, anything, anything).at_least(:once).and_return(stub_feature)
6a96a8e Extract TSearch and Trigram implementations into their own classes
Grant Hutchins & Peter Jaros authored
606
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
607 ModelWithPgSearch.with_tsearch_and_trigram_using_hash("foo")
6a96a8e Extract TSearch and Trigram implementations into their own classes
Grant Hutchins & Peter Jaros authored
608 end
e361475 @nertzy Change pg_search_scope signature to accept Hash options
nertzy authored
609 end
fd34c1c Accept a lambda to build a dynamic pg_search_scope
Grant Hutchins & Peter Jaros authored
610 end
fcf1d5f @nertzy Add support for prefix searching
nertzy authored
611
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
612 context "using a tsvector column" do
56e5406 Use table name when referring to tsvector column.
Peter Jaros & Grant Hutchins authored
613 with_model :ModelWithTsvector do
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
614 table do |t|
615 t.text 'content'
616 t.tsvector 'content_tsvector'
617 end
618
619 model { include PgSearch }
620 end
621
56e5406 Use table name when referring to tsvector column.
Peter Jaros & Grant Hutchins authored
622 let!(:expected) { ModelWithTsvector.create!(:content => 'tiling is grouty') }
623 let!(:unexpected) { ModelWithTsvector.create!(:content => 'longcat is looooooooong') }
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
624
625 before do
626 ActiveRecord::Base.connection.execute <<-SQL
56e5406 Use table name when referring to tsvector column.
Peter Jaros & Grant Hutchins authored
627 UPDATE #{ModelWithTsvector.table_name}
628 SET content_tsvector = to_tsvector('english'::regconfig, "#{ModelWithTsvector.table_name}"."content")
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
629 SQL
630
56e5406 Use table name when referring to tsvector column.
Peter Jaros & Grant Hutchins authored
631 ModelWithTsvector.pg_search_scope :search_by_content_with_tsvector,
04a4b1d @nertzy Clean up specs
nertzy authored
632 :against => :content,
633 :using => {
634 :tsearch => {
635 :tsvector_column => 'content_tsvector',
636 :dictionary => 'english'
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
637 }
04a4b1d @nertzy Clean up specs
nertzy authored
638 }
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
639 end
640
641 it "should not use to_tsvector in the query" do
56e5406 Use table name when referring to tsvector column.
Peter Jaros & Grant Hutchins authored
642 ModelWithTsvector.search_by_content_with_tsvector("tiles").to_sql.should_not =~ /to_tsvector/
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
643 end
644
645 it "should find the expected result" do
56e5406 Use table name when referring to tsvector column.
Peter Jaros & Grant Hutchins authored
646 ModelWithTsvector.search_by_content_with_tsvector("tiles").map(&:id).should == [expected.id]
647 end
648
649 context "when joining to a table with a column of the same name" do
650 with_model :AnotherModel do
651 table do |t|
652 t.string :content_tsvector # the type of the column doesn't matter
653 t.belongs_to :model_with_tsvector
654 end
655 end
656
657 before do
658 ModelWithTsvector.has_many :another_models
659 end
660
661 it "should refer to the tsvector column in the query unambiguously" do
662 expect {
663 ModelWithTsvector.joins(:another_models).search_by_content_with_tsvector("test").all
664 }.not_to raise_exception
665 end
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
666 end
667 end
668
706d81e Change the weird :normalizing => :diacritics API to :ignoring => :acc…
Grant Hutchins & Rachel Heaton authored
669 context "ignoring accents" do
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
670 before do
04a4b1d @nertzy Clean up specs
nertzy authored
671 ModelWithPgSearch.pg_search_scope :search_title_without_accents,
672 :against => :title,
673 :ignoring => :accents
fcf1d5f @nertzy Add support for prefix searching
nertzy authored
674 end
675
d5bf5ec @nertzy Disable {:ignoring => :accents} in PostgreSQL 8.x
nertzy authored
676 if ActiveRecord::Base.connection.send(:postgresql_version) < 90000
677 it "is unsupported in PostgreSQL 8.x" do
04a4b1d @nertzy Clean up specs
nertzy authored
678 expect {
d5bf5ec @nertzy Disable {:ignoring => :accents} in PostgreSQL 8.x
nertzy authored
679 ModelWithPgSearch.search_title_without_accents("abcd\303\251f")
04a4b1d @nertzy Clean up specs
nertzy authored
680 }.to raise_exception(PgSearch::NotSupportedForPostgresqlVersion)
d5bf5ec @nertzy Disable {:ignoring => :accents} in PostgreSQL 8.x
nertzy authored
681 end
682 else
683 it "returns rows that match the query but not its accents" do
684 # \303\241 is a with acute accent
685 # \303\251 is e with acute accent
fcf1d5f @nertzy Add support for prefix searching
nertzy authored
686
d5bf5ec @nertzy Disable {:ignoring => :accents} in PostgreSQL 8.x
nertzy authored
687 included = ModelWithPgSearch.create!(:title => "\303\241bcdef")
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
688
d5bf5ec @nertzy Disable {:ignoring => :accents} in PostgreSQL 8.x
nertzy authored
689 results = ModelWithPgSearch.search_title_without_accents("abcd\303\251f")
690 results.should == [included]
691 end
c040232 @nertzy Refactor tests and fix a bug where queries could get stuck on subsequ…
nertzy authored
692 end
fcf1d5f @nertzy Add support for prefix searching
nertzy authored
693 end
694
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
695 context "when passed a :ranked_by expression" do
696 before do
04a4b1d @nertzy Clean up specs
nertzy authored
697 ModelWithPgSearch.pg_search_scope :search_content_with_default_rank,
698 :against => :content
699
700 ModelWithPgSearch.pg_search_scope :search_content_with_importance_as_rank,
701 :against => :content,
702 :ranked_by => "importance"
703
704 ModelWithPgSearch.pg_search_scope :search_content_with_importance_as_rank_multiplier,
705 :against => :content,
706 :ranked_by => ":tsearch * importance"
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
707 end
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
708
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
709 it "should return records with a rank attribute equal to the :ranked_by expression" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
710 ModelWithPgSearch.create!(:content => 'foo', :importance => 10)
711 results = ModelWithPgSearch.search_content_with_importance_as_rank("foo")
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
712 results.first.pg_search_rank.should == 10
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
713 end
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
714
6a96a8e Extract TSearch and Trigram implementations into their own classes
Grant Hutchins & Peter Jaros authored
715 it "should substitute :tsearch with the tsearch rank expression in the :ranked_by expression" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
716 ModelWithPgSearch.create!(:content => 'foo', :importance => 10)
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
717
657b2a7 @nertzy Rename PgSearch#rank to PgSearch#pg_search_rank
nertzy authored
718 tsearch_rank = ModelWithPgSearch.search_content_with_default_rank("foo").first.pg_search_rank
719 multiplied_rank = ModelWithPgSearch.search_content_with_importance_as_rank_multiplier("foo").first.pg_search_rank
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
720
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
721 multiplied_rank.should be_within(0.001).of(tsearch_rank * 10)
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
722 end
723
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
724 it "should return results in descending order of the value of the rank expression" do
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
725 records = [
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
726 ModelWithPgSearch.create!(:content => 'foo', :importance => 1),
727 ModelWithPgSearch.create!(:content => 'foo', :importance => 3),
728 ModelWithPgSearch.create!(:content => 'foo', :importance => 2)
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
729 ]
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
730
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
731 results = ModelWithPgSearch.search_content_with_importance_as_rank("foo")
9118ec4 Support ranking by an arbitrary :ranked_by SQL expression.
Grant Hutchins & Peter Jaros authored
732 results.should == records.sort_by(&:importance).reverse
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
733 end
347ae6c @nertzy Add ranking by :trigram
nertzy authored
734
735 %w[tsearch trigram dmetaphone].each do |feature|
736 context "using the #{feature} ranking algorithm" do
737 before do
738 @scope_name = scope_name = :"search_content_ranked_by_#{feature}"
04a4b1d @nertzy Clean up specs
nertzy authored
739
740 ModelWithPgSearch.pg_search_scope scope_name,
741 :against => :content,
742 :ranked_by => ":#{feature}"
347ae6c @nertzy Add ranking by :trigram
nertzy authored
743 end
744
745 it "should return results with a rank" do
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
746 ModelWithPgSearch.create!(:content => 'foo')
347ae6c @nertzy Add ranking by :trigram
nertzy authored
747
5b91aa8 @nertzy Fix tests to use new with_model version.
nertzy authored
748 results = ModelWithPgSearch.send(@scope_name, 'foo')
04a4b1d @nertzy Clean up specs
nertzy authored
749 results.first.pg_search_rank.should be_a Float
347ae6c @nertzy Add ranking by :trigram
nertzy authored
750 end
751 end
752 end
69a12cc Allow overriding the default :order to work around ActiveRecord 2.3 s…
Grant Hutchins & Peter Jaros authored
753 end
50c4f8a @nertzy Add weighting to search rank
nertzy authored
754 end
7ceac78 When a multisearchable record is saved, a PgSearch::Document is created.
Grant Hutchins & Ian Zabel authored
755
756 describe ".multisearchable" do
7ba1cb7 Extract the specs for Multisearchable.
Grant Hutchins & Ian Zabel authored
757 it "should include the Multisearchable module" do
758 ModelWithPgSearch.should_receive(:include).with(PgSearch::Multisearchable)
759 ModelWithPgSearch.multisearchable
7ceac78 When a multisearchable record is saved, a PgSearch::Document is created.
Grant Hutchins & Ian Zabel authored
760 end
8a29a13 Make PgSearch.multisearch return multisearch results
Grant Hutchins & Ian Zabel authored
761
762 it "should set pg_search_multisearchable_options on the class" do
763 options = double(:options)
764 ModelWithPgSearch.multisearchable(options)
765 ModelWithPgSearch.pg_search_multisearchable_options.should == options
766 end
767 end
768
769 describe ".multisearch" do
d6ce97c PgSearch.multisearch now has options
Grant Hutchins & Joe Moore authored
770 with_table "pg_search_documents", {}, &DOCUMENTS_SCHEMA
771
772 describe "delegation to PgSearch::Document.search" do
773 subject { PgSearch.multisearch(query) }
774
775 let(:query) { double(:query) }
776 let(:relation) { double(:relation) }
777 before do
778 PgSearch::Document.should_receive(:search).with(query).and_return(relation)
779 end
780
781 it { should == relation }
8a29a13 Make PgSearch.multisearch return multisearch results
Grant Hutchins & Ian Zabel authored
782 end
783
60df161 PgSearch.multisearch_options can be a Proc.
Grant Hutchins & Joe Moore authored
784 context "with PgSearch.multisearch_options set to a Hash" do
d6ce97c PgSearch.multisearch now has options
Grant Hutchins & Joe Moore authored
785 before { PgSearch.stub(:multisearch_options).and_return({:using => :dmetaphone}) }
786 subject { PgSearch.multisearch(query).map(&:searchable) }
787
788 with_model :MultisearchableModel do
789 table do |t|
790 t.string :title
791 end
792 model do
793 include PgSearch
794 multisearchable :against => :title
795 end
796 end
797
798 let!(:soundalike_record) { MultisearchableModel.create!(:title => 'foning') }
799 let(:query) { "Phoning" }
800 it { should include(soundalike_record) }
801 end
60df161 PgSearch.multisearch_options can be a Proc.
Grant Hutchins & Joe Moore authored
802
803 context "with PgSearch.multisearch_options set to a Proc" do
804 subject { PgSearch.multisearch(query, soundalike).map(&:searchable) }
805
806 before do
807 PgSearch.stub(:multisearch_options).and_return do
808 lambda do |query, soundalike|
809 if soundalike
810 {:using => :dmetaphone, :query => query}
811 else
812 {:query => query}
813 end
814 end
815 end
816 end
817
818 with_model :MultisearchableModel do
819 table do |t|
820 t.string :title
821 end
822 model do
823 include PgSearch
824 multisearchable :against => :title
825 end
826 end
827
828 let!(:soundalike_record) { MultisearchableModel.create!(:title => 'foning') }
829 let(:query) { "Phoning" }
830
831 context "with soundalike true" do
832 let(:soundalike) { true }
833 it { should include(soundalike_record) }
834 end
835
836 context "with soundalike false" do
837 let(:soundalike) { false }
838 it { should_not include(soundalike_record) }
839 end
840 end
7ceac78 When a multisearchable record is saved, a PgSearch::Document is created.
Grant Hutchins & Ian Zabel authored
841 end
8c090e9 Multisearch can be temporarily disabled
Ian Zabel & Peter Jaros authored
842
843 describe ".disable_multisearch" do
844 it "should temporarily disable multisearch" do
845 @multisearch_enabled_before = PgSearch.multisearch_enabled?
846 PgSearch.disable_multisearch do
847 @multisearch_enabled_inside = PgSearch.multisearch_enabled?
848 end
849 @multisearch_enabled_after = PgSearch.multisearch_enabled?
850
851 @multisearch_enabled_before.should be(true)
852 @multisearch_enabled_inside.should be(false)
853 @multisearch_enabled_after.should be(true)
854 end
855
6862f80 @nertzy Re-enable multisearch even after an Exception.
nertzy authored
856 it "should reenable multisearch after an error" do
857 @multisearch_enabled_before = PgSearch.multisearch_enabled?
858 begin
859 PgSearch.disable_multisearch do
860 @multisearch_enabled_inside = PgSearch.multisearch_enabled?
861 raise
862 end
863 rescue
864 end
865
866 @multisearch_enabled_after = PgSearch.multisearch_enabled?
867
868 @multisearch_enabled_before.should be(true)
869 @multisearch_enabled_inside.should be(false)
870 @multisearch_enabled_after.should be(true)
871 end
872
8c090e9 Multisearch can be temporarily disabled
Ian Zabel & Peter Jaros authored
873 it "should not disable multisearch on other threads" do
874 values = Queue.new
875 sync = Queue.new
876 Thread.new do
877 values.push PgSearch.multisearch_enabled?
878 sync.pop # wait
879 values.push PgSearch.multisearch_enabled?
880 sync.pop # wait
881 values.push PgSearch.multisearch_enabled?
882 end
883
884 @multisearch_enabled_before = values.pop
885 PgSearch.disable_multisearch do
886 sync.push :go
887 @multisearch_enabled_inside = values.pop
888 end
889 sync.push :go
890 @multisearch_enabled_after = values.pop
891
892 @multisearch_enabled_before.should be(true)
893 @multisearch_enabled_inside.should be(true)
894 @multisearch_enabled_after.should be(true)
895 end
896 end
7ec90ef Use tsearch to do a simple search on a column
Grant Hutchins & Peter Jaros authored
897 end
Something went wrong with that request. Please try again.