pg_search 0.7.4 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +30 -13
- data/lib/pg_search/document.rb +4 -2
- data/lib/pg_search/features/tsearch.rb +23 -19
- data/lib/pg_search/migration/associated_against_generator.rb +4 -16
- data/lib/pg_search/migration/dmetaphone_generator.rb +4 -16
- data/lib/pg_search/migration/generator.rb +28 -0
- data/lib/pg_search/migration/multisearch_generator.rb +4 -8
- data/lib/pg_search/migration/templates/add_pg_search_associated_against_support_functions.rb.erb +2 -2
- data/lib/pg_search/migration/templates/{create_pg_search_documents.rb → create_pg_search_documents.rb.erb} +0 -0
- data/lib/pg_search/scope_options.rb +3 -1
- data/lib/pg_search/version.rb +1 -1
- data/pg_search.gemspec +1 -1
- data/spec/integration/associations_spec.rb +25 -25
- data/spec/integration/pagination_spec.rb +4 -4
- data/spec/integration/pg_search_spec.rb +123 -103
- data/spec/lib/pg_search/configuration/column_spec.rb +2 -2
- data/spec/lib/pg_search/document_spec.rb +11 -4
- data/spec/lib/pg_search/features/dmetaphone_spec.rb +4 -2
- data/spec/lib/pg_search/features/tsearch_spec.rb +4 -2
- data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +16 -16
- data/spec/lib/pg_search/multisearch_spec.rb +15 -18
- data/spec/lib/pg_search/multisearchable_spec.rb +39 -38
- data/spec/lib/pg_search/normalizer_spec.rb +8 -8
- data/spec/spec_helper.rb +8 -94
- data/spec/support/coveralls.rb +7 -0
- data/spec/support/database.rb +83 -0
- data/spec/support/with_model.rb +5 -0
- metadata +14 -7
@@ -17,7 +17,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
17
17
|
it "builds a chainable scope" do
|
18
18
|
ModelWithPgSearch.pg_search_scope "matching_query", :against => []
|
19
19
|
scope = ModelWithPgSearch.where("1 = 1").matching_query("foo").where("1 = 1")
|
20
|
-
scope.
|
20
|
+
expect(scope).to be_an ActiveRecord::Relation
|
21
21
|
end
|
22
22
|
|
23
23
|
context "when passed a lambda" do
|
@@ -33,8 +33,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
33
33
|
included = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
|
34
34
|
excluded = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
|
35
35
|
|
36
|
-
ModelWithPgSearch.search_title_or_content('fo-remove-o', false).
|
37
|
-
ModelWithPgSearch.search_title_or_content('b-remove-ar', true).
|
36
|
+
expect(ModelWithPgSearch.search_title_or_content('fo-remove-o', false)).to eq([included])
|
37
|
+
expect(ModelWithPgSearch.search_title_or_content('b-remove-ar', true)).to eq([included])
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -139,7 +139,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
139
139
|
ModelWithPgSearch.create!(:content => 'foo')
|
140
140
|
|
141
141
|
results = ModelWithPgSearch.search_content('')
|
142
|
-
results.
|
142
|
+
expect(results).to eq([])
|
143
143
|
end
|
144
144
|
|
145
145
|
it "returns rows where the column contains the term in the query" do
|
@@ -147,8 +147,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
147
147
|
excluded = ModelWithPgSearch.create!(:content => 'bar')
|
148
148
|
|
149
149
|
results = ModelWithPgSearch.search_content('foo')
|
150
|
-
results.
|
151
|
-
results.
|
150
|
+
expect(results).to include(included)
|
151
|
+
expect(results).not_to include(excluded)
|
152
152
|
end
|
153
153
|
|
154
154
|
it "returns the correct count" do
|
@@ -165,8 +165,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
165
165
|
excluded = ModelWithPgSearch.create!(:content => 'foo')
|
166
166
|
|
167
167
|
results = ModelWithPgSearch.search_content('foo bar')
|
168
|
-
results.
|
169
|
-
results.
|
168
|
+
expect(results).to match_array(included)
|
169
|
+
expect(results).not_to include(excluded)
|
170
170
|
end
|
171
171
|
|
172
172
|
it "returns rows that match the query but not its case" do
|
@@ -174,7 +174,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
174
174
|
ModelWithPgSearch.create!(:content => "FOO")]
|
175
175
|
|
176
176
|
results = ModelWithPgSearch.search_content("Foo")
|
177
|
-
results.
|
177
|
+
expect(results).to match_array(included)
|
178
178
|
end
|
179
179
|
|
180
180
|
it "returns rows that match the query only if their accents match" do
|
@@ -185,8 +185,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
185
185
|
excluded = ModelWithPgSearch.create!(:content => "\303\241bcdef")
|
186
186
|
|
187
187
|
results = ModelWithPgSearch.search_content("abcd\303\251f")
|
188
|
-
results.
|
189
|
-
results.
|
188
|
+
expect(results).to eq([included])
|
189
|
+
expect(results).not_to include(excluded)
|
190
190
|
end
|
191
191
|
|
192
192
|
it "returns rows that match the query but not rows that are prefixed by the query" do
|
@@ -194,8 +194,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
194
194
|
excluded = ModelWithPgSearch.create!(:content => 'prefix')
|
195
195
|
|
196
196
|
results = ModelWithPgSearch.search_content("pre")
|
197
|
-
results.
|
198
|
-
results.
|
197
|
+
expect(results).to eq([included])
|
198
|
+
expect(results).not_to include(excluded)
|
199
199
|
end
|
200
200
|
|
201
201
|
it "returns rows that match the query exactly and not those that match the query when stemmed by the default english dictionary" do
|
@@ -204,7 +204,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
204
204
|
ModelWithPgSearch.create!(:content => "jumping")]
|
205
205
|
|
206
206
|
results = ModelWithPgSearch.search_content("jumped")
|
207
|
-
results.
|
207
|
+
expect(results).to eq([included])
|
208
208
|
end
|
209
209
|
|
210
210
|
it "returns rows that match sorted by rank" do
|
@@ -212,8 +212,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
212
212
|
winner = ModelWithPgSearch.create!(:content => 'foo foo')
|
213
213
|
|
214
214
|
results = ModelWithPgSearch.search_content("foo")
|
215
|
-
results[0].pg_search_rank.
|
216
|
-
results.
|
215
|
+
expect(results[0].pg_search_rank).to be > results[1].pg_search_rank
|
216
|
+
expect(results).to eq([winner, loser])
|
217
217
|
end
|
218
218
|
|
219
219
|
it "returns results that match sorted by primary key for records that rank the same" do
|
@@ -221,7 +221,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
221
221
|
ModelWithPgSearch.create!(:content => 'foo')].sort_by(&:id)
|
222
222
|
|
223
223
|
results = ModelWithPgSearch.search_content("foo")
|
224
|
-
results.
|
224
|
+
expect(results).to eq(sorted_results)
|
225
225
|
end
|
226
226
|
|
227
227
|
it "returns results that match a query with multiple space-separated search terms" do
|
@@ -236,21 +236,21 @@ describe "an Active Record model which includes PgSearch" do
|
|
236
236
|
]
|
237
237
|
|
238
238
|
results = ModelWithPgSearch.search_content('foo bar')
|
239
|
-
results.
|
240
|
-
results.
|
239
|
+
expect(results).to match_array(included)
|
240
|
+
expect(results).not_to include(excluded)
|
241
241
|
end
|
242
242
|
|
243
243
|
it "returns rows that match a query with characters that are invalid in a tsquery expression" do
|
244
244
|
included = ModelWithPgSearch.create!(:content => "(:Foo.) Bar?, \\")
|
245
245
|
|
246
246
|
results = ModelWithPgSearch.search_content("foo :bar .,?() \\")
|
247
|
-
results.
|
247
|
+
expect(results).to eq([included])
|
248
248
|
end
|
249
249
|
|
250
250
|
it "accepts non-string queries and calls #to_s on them" do
|
251
251
|
foo = ModelWithPgSearch.create!(:content => "foo")
|
252
252
|
not_a_string = double(:to_s => "foo")
|
253
|
-
ModelWithPgSearch.search_content(not_a_string).
|
253
|
+
expect(ModelWithPgSearch.search_content(not_a_string)).to eq([foo])
|
254
254
|
end
|
255
255
|
|
256
256
|
context "when the column is not text" do
|
@@ -274,7 +274,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
274
274
|
|
275
275
|
query = record.created_at.strftime("%Y-%m-%d")
|
276
276
|
results = ModelWithTimestamps.search_timestamps(query)
|
277
|
-
results.
|
277
|
+
expect(results).to eq([record])
|
278
278
|
end
|
279
279
|
end
|
280
280
|
end
|
@@ -296,9 +296,9 @@ describe "an Active Record model which includes PgSearch" do
|
|
296
296
|
|
297
297
|
results = ModelWithPgSearch.search_title_and_content('foo bar')
|
298
298
|
|
299
|
-
results.
|
299
|
+
expect(results).to match_array(included)
|
300
300
|
excluded.each do |result|
|
301
|
-
results.
|
301
|
+
expect(results).not_to include(result)
|
302
302
|
end
|
303
303
|
end
|
304
304
|
|
@@ -307,14 +307,14 @@ describe "an Active Record model which includes PgSearch" do
|
|
307
307
|
in_content = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
|
308
308
|
|
309
309
|
results = ModelWithPgSearch.search_title_and_content('foo')
|
310
|
-
results.
|
310
|
+
expect(results).to match_array([in_title, in_content])
|
311
311
|
end
|
312
312
|
|
313
313
|
# Searching with a NULL column will prevent any matches unless we coalesce it.
|
314
314
|
it "returns rows where at one column contains all of the terms in the query and another is NULL" do
|
315
315
|
included = ModelWithPgSearch.create!(:title => 'foo', :content => nil)
|
316
316
|
results = ModelWithPgSearch.search_title_and_content('foo')
|
317
|
-
results.
|
317
|
+
expect(results).to eq([included])
|
318
318
|
end
|
319
319
|
end
|
320
320
|
|
@@ -326,13 +326,13 @@ describe "an Active Record model which includes PgSearch" do
|
|
326
326
|
it "returns rows where one searchable column and the query share enough trigrams" do
|
327
327
|
included = ModelWithPgSearch.create!(:title => 'abcdefghijkl', :content => nil)
|
328
328
|
results = ModelWithPgSearch.with_trigrams('cdefhijkl')
|
329
|
-
results.
|
329
|
+
expect(results).to eq([included])
|
330
330
|
end
|
331
331
|
|
332
332
|
it "returns rows where multiple searchable columns and the query share enough trigrams" do
|
333
333
|
included = ModelWithPgSearch.create!(:title => 'abcdef', :content => 'ghijkl')
|
334
334
|
results = ModelWithPgSearch.with_trigrams('cdefhijkl')
|
335
|
-
results.
|
335
|
+
expect(results).to eq([included])
|
336
336
|
end
|
337
337
|
|
338
338
|
context "when a threshold is specified" do
|
@@ -382,8 +382,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
382
382
|
excluded = ModelWithPgSearch.create!(:title => 'postfix')
|
383
383
|
|
384
384
|
results = ModelWithPgSearch.search_title_with_prefixes("pre")
|
385
|
-
results.
|
386
|
-
results.
|
385
|
+
expect(results).to eq([included])
|
386
|
+
expect(results).not_to include(excluded)
|
387
387
|
end
|
388
388
|
|
389
389
|
it "returns rows that match the query when the query has a hyphen" do
|
@@ -391,8 +391,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
391
391
|
excluded = ModelWithPgSearch.create!(:title => 'foo bar')
|
392
392
|
|
393
393
|
results = ModelWithPgSearch.search_title_with_prefixes("foo-bar")
|
394
|
-
results.
|
395
|
-
results.
|
394
|
+
expect(results).to include(included)
|
395
|
+
expect(results).not_to include(excluded)
|
396
396
|
end
|
397
397
|
end
|
398
398
|
end
|
@@ -412,7 +412,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
412
412
|
ModelWithPgSearch.create!(:content => "jumping")]
|
413
413
|
|
414
414
|
results = ModelWithPgSearch.search_content_with_english("jump")
|
415
|
-
results.
|
415
|
+
expect(results).to match_array(included)
|
416
416
|
end
|
417
417
|
end
|
418
418
|
|
@@ -428,7 +428,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
428
428
|
|
429
429
|
result = ModelWithPgSearch.search_content("Strip Down").first
|
430
430
|
|
431
|
-
result.pg_search_rank.
|
431
|
+
expect(result.pg_search_rank).to be_a(Float)
|
432
432
|
end
|
433
433
|
|
434
434
|
context "with a normalization specified" do
|
@@ -443,8 +443,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
443
443
|
it "ranks the results for documents with less text higher" do
|
444
444
|
results = ModelWithPgSearch.search_content_with_normalization("down")
|
445
445
|
|
446
|
-
results.map(&:content).
|
447
|
-
results.first.pg_search_rank.
|
446
|
+
expect(results.map(&:content)).to eq(["Down", "Strip Down", "Down and Out", "Won't Let You Down"])
|
447
|
+
expect(results.first.pg_search_rank).to be > results.last.pg_search_rank
|
448
448
|
end
|
449
449
|
end
|
450
450
|
|
@@ -458,8 +458,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
458
458
|
it "ranks the results equally" do
|
459
459
|
results = ModelWithPgSearch.search_content_without_normalization("down")
|
460
460
|
|
461
|
-
results.map(&:content).
|
462
|
-
results.first.pg_search_rank.
|
461
|
+
expect(results.map(&:content)).to eq(["Strip Down", "Down", "Down and Out", "Won't Let You Down"])
|
462
|
+
expect(results.first.pg_search_rank).to eq(results.last.pg_search_rank)
|
463
463
|
end
|
464
464
|
end
|
465
465
|
end
|
@@ -475,8 +475,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
475
475
|
winner = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
|
476
476
|
|
477
477
|
results = ModelWithPgSearch.search_weighted_by_array_of_arrays('foo')
|
478
|
-
results[0].pg_search_rank.
|
479
|
-
results.
|
478
|
+
expect(results[0].pg_search_rank).to be > results[1].pg_search_rank
|
479
|
+
expect(results).to eq([winner, loser])
|
480
480
|
end
|
481
481
|
end
|
482
482
|
|
@@ -491,8 +491,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
491
491
|
winner = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
|
492
492
|
|
493
493
|
results = ModelWithPgSearch.search_weighted_by_hash('foo')
|
494
|
-
results[0].pg_search_rank.
|
495
|
-
results.
|
494
|
+
expect(results[0].pg_search_rank).to be > results[1].pg_search_rank
|
495
|
+
expect(results).to eq([winner, loser])
|
496
496
|
end
|
497
497
|
end
|
498
498
|
|
@@ -507,8 +507,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
507
507
|
winner = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
|
508
508
|
|
509
509
|
results = ModelWithPgSearch.search_weighted('foo')
|
510
|
-
results[0].pg_search_rank.
|
511
|
-
results.
|
510
|
+
expect(results[0].pg_search_rank).to be > results[1].pg_search_rank
|
511
|
+
expect(results).to eq([winner, loser])
|
512
512
|
end
|
513
513
|
end
|
514
514
|
|
@@ -529,11 +529,11 @@ describe "an Active Record model which includes PgSearch" do
|
|
529
529
|
|
530
530
|
results = ModelWithPgSearch.search_title_with_any_word("one two three four")
|
531
531
|
|
532
|
-
results.map(&:title).
|
532
|
+
expect(results.map(&:title)).to eq(%w(one two three four))
|
533
533
|
|
534
534
|
results = ModelWithPgSearch.search_title_with_all_words("one two three four")
|
535
535
|
|
536
|
-
results.map(&:title).
|
536
|
+
expect(results.map(&:title)).to eq([])
|
537
537
|
end
|
538
538
|
end
|
539
539
|
end
|
@@ -549,21 +549,21 @@ describe "an Active Record model which includes PgSearch" do
|
|
549
549
|
included = ModelWithPgSearch.create!(:title => 'Geoff', :content => nil)
|
550
550
|
excluded = ModelWithPgSearch.create!(:title => 'Bob', :content => nil)
|
551
551
|
results = ModelWithPgSearch.with_dmetaphones('Jeff')
|
552
|
-
results.
|
552
|
+
expect(results).to eq([included])
|
553
553
|
end
|
554
554
|
|
555
555
|
it "returns rows where multiple searchable columns and the query share enough dmetaphones" do
|
556
556
|
included = ModelWithPgSearch.create!(:title => 'Geoff', :content => 'George')
|
557
557
|
excluded = ModelWithPgSearch.create!(:title => 'Bob', :content => 'Jones')
|
558
558
|
results = ModelWithPgSearch.with_dmetaphones('Jeff Jorge')
|
559
|
-
results.
|
559
|
+
expect(results).to eq([included])
|
560
560
|
end
|
561
561
|
|
562
562
|
it "returns rows that match dmetaphones that are English stopwords" do
|
563
563
|
included = ModelWithPgSearch.create!(:title => 'White', :content => nil)
|
564
564
|
excluded = ModelWithPgSearch.create!(:title => 'Black', :content => nil)
|
565
565
|
results = ModelWithPgSearch.with_dmetaphones('Wight')
|
566
|
-
results.
|
566
|
+
expect(results).to eq([included])
|
567
567
|
end
|
568
568
|
|
569
569
|
it "can handle terms that do not have a dmetaphone equivalent" do
|
@@ -573,7 +573,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
573
573
|
excluded = ModelWithPgSearch.create!(:title => 'Black', :content => nil)
|
574
574
|
|
575
575
|
results = ModelWithPgSearch.with_dmetaphones('Wight W')
|
576
|
-
results.
|
576
|
+
expect(results).to eq([included])
|
577
577
|
end
|
578
578
|
end
|
579
579
|
|
@@ -616,37 +616,37 @@ describe "an Active Record model which includes PgSearch" do
|
|
616
616
|
|
617
617
|
# matches trigram only
|
618
618
|
trigram_query = "ling is grouty"
|
619
|
-
ModelWithPgSearch.with_trigram(trigram_query).
|
620
|
-
ModelWithPgSearch.with_trigram_and_ignoring_accents(trigram_query).
|
621
|
-
ModelWithPgSearch.with_tsearch(trigram_query).
|
622
|
-
ModelWithPgSearch.with_tsearch_and_trigram(trigram_query).
|
623
|
-
ModelWithPgSearch.complex_search(trigram_query).
|
619
|
+
expect(ModelWithPgSearch.with_trigram(trigram_query)).to include(record)
|
620
|
+
expect(ModelWithPgSearch.with_trigram_and_ignoring_accents(trigram_query)).to include(record)
|
621
|
+
expect(ModelWithPgSearch.with_tsearch(trigram_query)).not_to include(record)
|
622
|
+
expect(ModelWithPgSearch.with_tsearch_and_trigram(trigram_query)).to eq([record])
|
623
|
+
expect(ModelWithPgSearch.complex_search(trigram_query)).to include(record)
|
624
624
|
|
625
625
|
# matches accent
|
626
626
|
# \303\266 is o with diaeresis
|
627
627
|
# \303\272 is u with acute accent
|
628
628
|
accent_query = "gr\303\266\303\272ty"
|
629
|
-
ModelWithPgSearch.with_trigram(accent_query).
|
630
|
-
ModelWithPgSearch.with_trigram_and_ignoring_accents(accent_query).
|
631
|
-
ModelWithPgSearch.with_tsearch(accent_query).
|
632
|
-
ModelWithPgSearch.with_tsearch_and_trigram(accent_query).count(:all).
|
633
|
-
ModelWithPgSearch.complex_search(accent_query).
|
629
|
+
expect(ModelWithPgSearch.with_trigram(accent_query)).not_to include(record)
|
630
|
+
expect(ModelWithPgSearch.with_trigram_and_ignoring_accents(accent_query)).to include(record)
|
631
|
+
expect(ModelWithPgSearch.with_tsearch(accent_query)).not_to include(record)
|
632
|
+
expect(ModelWithPgSearch.with_tsearch_and_trigram(accent_query).count(:all)).to eq(0)
|
633
|
+
expect(ModelWithPgSearch.complex_search(accent_query)).to include(record)
|
634
634
|
|
635
635
|
# matches tsearch only
|
636
636
|
tsearch_query = "tiles"
|
637
|
-
ModelWithPgSearch.with_tsearch(tsearch_query).
|
638
|
-
ModelWithPgSearch.with_trigram(tsearch_query).
|
639
|
-
ModelWithPgSearch.with_trigram_and_ignoring_accents(tsearch_query).
|
640
|
-
ModelWithPgSearch.with_tsearch_and_trigram(tsearch_query).
|
641
|
-
ModelWithPgSearch.complex_search(tsearch_query).
|
637
|
+
expect(ModelWithPgSearch.with_tsearch(tsearch_query)).to include(record)
|
638
|
+
expect(ModelWithPgSearch.with_trigram(tsearch_query)).not_to include(record)
|
639
|
+
expect(ModelWithPgSearch.with_trigram_and_ignoring_accents(tsearch_query)).not_to include(record)
|
640
|
+
expect(ModelWithPgSearch.with_tsearch_and_trigram(tsearch_query)).to eq([record])
|
641
|
+
expect(ModelWithPgSearch.complex_search(tsearch_query)).to include(record)
|
642
642
|
|
643
643
|
# matches dmetaphone only
|
644
644
|
dmetaphone_query = "tyling"
|
645
|
-
ModelWithPgSearch.with_tsearch(dmetaphone_query).
|
646
|
-
ModelWithPgSearch.with_trigram(dmetaphone_query).
|
647
|
-
ModelWithPgSearch.with_trigram_and_ignoring_accents(dmetaphone_query).
|
648
|
-
ModelWithPgSearch.with_tsearch_and_trigram(dmetaphone_query).
|
649
|
-
ModelWithPgSearch.complex_search(dmetaphone_query).
|
645
|
+
expect(ModelWithPgSearch.with_tsearch(dmetaphone_query)).not_to include(record)
|
646
|
+
expect(ModelWithPgSearch.with_trigram(dmetaphone_query)).not_to include(record)
|
647
|
+
expect(ModelWithPgSearch.with_trigram_and_ignoring_accents(dmetaphone_query)).not_to include(record)
|
648
|
+
expect(ModelWithPgSearch.with_tsearch_and_trigram(dmetaphone_query)).not_to include(record)
|
649
|
+
expect(ModelWithPgSearch.complex_search(dmetaphone_query)).to include(record)
|
650
650
|
end
|
651
651
|
|
652
652
|
context "with feature-specific configuration" do
|
@@ -668,8 +668,8 @@ describe "an Active Record model which includes PgSearch" do
|
|
668
668
|
:rank => Arel::Nodes::Grouping.new(Arel.sql("1.0"))
|
669
669
|
)
|
670
670
|
|
671
|
-
PgSearch::Features::TSearch.
|
672
|
-
PgSearch::Features::Trigram.
|
671
|
+
expect(PgSearch::Features::TSearch).to receive(:new).with(anything, @tsearch_config, anything, anything, anything).at_least(:once).and_return(stub_feature)
|
672
|
+
expect(PgSearch::Features::Trigram).to receive(:new).with(anything, @trigram_config, anything, anything, anything).at_least(:once).and_return(stub_feature)
|
673
673
|
|
674
674
|
ModelWithPgSearch.with_tsearch_and_trigram_using_hash("foo")
|
675
675
|
end
|
@@ -723,15 +723,15 @@ describe "an Active Record model which includes PgSearch" do
|
|
723
723
|
end
|
724
724
|
|
725
725
|
it "should find by the tsvector column" do
|
726
|
-
Post.search_by_content_with_tsvector("phooey").map(&:id).
|
726
|
+
expect(Post.search_by_content_with_tsvector("phooey").map(&:id)).to eq([expected.id])
|
727
727
|
end
|
728
728
|
|
729
729
|
it "should find by the associated record" do
|
730
|
-
Post.search_by_content_with_tsvector("commentone").map(&:id).
|
730
|
+
expect(Post.search_by_content_with_tsvector("commentone").map(&:id)).to eq([expected.id])
|
731
731
|
end
|
732
732
|
|
733
733
|
it 'should find by a combination of the two' do
|
734
|
-
Post.search_by_content_with_tsvector("phooey commentone").map(&:id).
|
734
|
+
expect(Post.search_by_content_with_tsvector("phooey commentone").map(&:id)).to eq([expected.id])
|
735
735
|
end
|
736
736
|
end
|
737
737
|
|
@@ -765,11 +765,11 @@ describe "an Active Record model which includes PgSearch" do
|
|
765
765
|
end
|
766
766
|
|
767
767
|
it "should not use to_tsvector in the query" do
|
768
|
-
ModelWithTsvector.search_by_content_with_tsvector("tiles").to_sql.
|
768
|
+
expect(ModelWithTsvector.search_by_content_with_tsvector("tiles").to_sql).not_to match(/to_tsvector/)
|
769
769
|
end
|
770
770
|
|
771
771
|
it "should find the expected result" do
|
772
|
-
ModelWithTsvector.search_by_content_with_tsvector("tiles").map(&:id).
|
772
|
+
expect(ModelWithTsvector.search_by_content_with_tsvector("tiles").map(&:id)).to eq([expected.id])
|
773
773
|
end
|
774
774
|
|
775
775
|
context "when joining to a table with a column of the same name" do
|
@@ -813,7 +813,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
813
813
|
included = ModelWithPgSearch.create!(:title => "\303\241bcdef")
|
814
814
|
|
815
815
|
results = ModelWithPgSearch.search_title_without_accents("abcd\303\251f")
|
816
|
-
results.
|
816
|
+
expect(results).to eq([included])
|
817
817
|
end
|
818
818
|
end
|
819
819
|
end
|
@@ -835,7 +835,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
835
835
|
it "should return records with a rank attribute equal to the :ranked_by expression" do
|
836
836
|
ModelWithPgSearch.create!(:content => 'foo', :importance => 10)
|
837
837
|
results = ModelWithPgSearch.search_content_with_importance_as_rank("foo")
|
838
|
-
results.first.pg_search_rank.
|
838
|
+
expect(results.first.pg_search_rank).to eq(10)
|
839
839
|
end
|
840
840
|
|
841
841
|
it "should substitute :tsearch with the tsearch rank expression in the :ranked_by expression" do
|
@@ -844,7 +844,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
844
844
|
tsearch_rank = ModelWithPgSearch.search_content_with_default_rank("foo").first.pg_search_rank
|
845
845
|
multiplied_rank = ModelWithPgSearch.search_content_with_importance_as_rank_multiplier("foo").first.pg_search_rank
|
846
846
|
|
847
|
-
multiplied_rank.
|
847
|
+
expect(multiplied_rank).to be_within(0.001).of(tsearch_rank * 10)
|
848
848
|
end
|
849
849
|
|
850
850
|
it "should return results in descending order of the value of the rank expression" do
|
@@ -855,7 +855,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
855
855
|
]
|
856
856
|
|
857
857
|
results = ModelWithPgSearch.search_content_with_importance_as_rank("foo")
|
858
|
-
results.
|
858
|
+
expect(results).to eq(records.sort_by(&:importance).reverse)
|
859
859
|
end
|
860
860
|
|
861
861
|
%w[tsearch trigram dmetaphone].each do |feature|
|
@@ -870,7 +870,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
870
870
|
ModelWithPgSearch.create!(:content => 'foo')
|
871
871
|
|
872
872
|
results = ModelWithPgSearch.send(scope_name, 'foo')
|
873
|
-
results.first.pg_search_rank.
|
873
|
+
expect(results.first.pg_search_rank).to be_a Float
|
874
874
|
end
|
875
875
|
end
|
876
876
|
end
|
@@ -887,7 +887,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
887
887
|
twice = ModelWithPgSearch.create!(:content => 'foo foo')
|
888
888
|
|
889
889
|
results = ModelWithPgSearch.search_content_ranked_by_tsearch('foo')
|
890
|
-
results.index(twice).
|
890
|
+
expect(results.index(twice)).to be < results.index(once)
|
891
891
|
end
|
892
892
|
end
|
893
893
|
|
@@ -902,7 +902,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
902
902
|
exact = ModelWithPgSearch.create!(:content => 'abc')
|
903
903
|
|
904
904
|
results = ModelWithPgSearch.search_content_ranked_by_trigram('abc')
|
905
|
-
results.index(exact).
|
905
|
+
expect(results.index(exact)).to be < results.index(close)
|
906
906
|
end
|
907
907
|
end
|
908
908
|
|
@@ -917,7 +917,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
917
917
|
twice = ModelWithPgSearch.create!(:content => 'Phoo Fu')
|
918
918
|
|
919
919
|
results = ModelWithPgSearch.search_content_ranked_by_dmetaphone('foo')
|
920
|
-
results.index(twice).
|
920
|
+
expect(results.index(twice)).to be < results.index(once)
|
921
921
|
end
|
922
922
|
end
|
923
923
|
end
|
@@ -956,27 +956,47 @@ describe "an Active Record model which includes PgSearch" do
|
|
956
956
|
AnotherSubclassModel.create!(:content => "baz")
|
957
957
|
]
|
958
958
|
|
959
|
-
SuperclassModel.count.
|
960
|
-
SubclassModel.count.
|
959
|
+
expect(SuperclassModel.count).to eq(6)
|
960
|
+
expect(SubclassModel.count).to eq(2)
|
961
961
|
|
962
962
|
results = SubclassModel.search_content("foo bar")
|
963
963
|
|
964
|
-
results.
|
965
|
-
results.
|
964
|
+
expect(results).to include(*included)
|
965
|
+
expect(results).not_to include(*excluded)
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
969
|
+
context "when there is a sort only feature" do
|
970
|
+
it "excludes that feature from the conditions, but uses it in the sorting" do
|
971
|
+
ModelWithPgSearch.pg_search_scope :search_content_ranked_by_dmetaphone,
|
972
|
+
:against => :content,
|
973
|
+
:using => {
|
974
|
+
:tsearch => { :any_word => true, :prefix => true },
|
975
|
+
:dmetaphone => { :any_word => true, :prefix => true, :sort_only => true }
|
976
|
+
},
|
977
|
+
:ranked_by => ":tsearch + (0.5 * :dmetaphone)"
|
978
|
+
|
979
|
+
exact = ModelWithPgSearch.create!(:content => "ash hines")
|
980
|
+
one_exact_one_close = ModelWithPgSearch.create!(:content => "ash heinz")
|
981
|
+
one_exact = ModelWithPgSearch.create!(:content => "ash smith")
|
982
|
+
one_close = ModelWithPgSearch.create!(:content => "leigh heinz")
|
983
|
+
|
984
|
+
results = ModelWithPgSearch.search_content_ranked_by_dmetaphone("ash hines")
|
985
|
+
expect(results).to eq [exact, one_exact_one_close, one_exact]
|
966
986
|
end
|
967
987
|
end
|
968
988
|
end
|
969
989
|
|
970
990
|
describe ".multisearchable" do
|
971
991
|
it "should include the Multisearchable module" do
|
972
|
-
ModelWithPgSearch.
|
992
|
+
expect(ModelWithPgSearch).to receive(:include).with(PgSearch::Multisearchable)
|
973
993
|
ModelWithPgSearch.multisearchable
|
974
994
|
end
|
975
995
|
|
976
996
|
it "should set pg_search_multisearchable_options on the class" do
|
977
997
|
options = double(:options)
|
978
998
|
ModelWithPgSearch.multisearchable(options)
|
979
|
-
ModelWithPgSearch.pg_search_multisearchable_options.
|
999
|
+
expect(ModelWithPgSearch.pg_search_multisearchable_options).to eq(options)
|
980
1000
|
end
|
981
1001
|
end
|
982
1002
|
|
@@ -989,14 +1009,14 @@ describe "an Active Record model which includes PgSearch" do
|
|
989
1009
|
let(:query) { double(:query) }
|
990
1010
|
let(:relation) { double(:relation) }
|
991
1011
|
before do
|
992
|
-
PgSearch::Document.
|
1012
|
+
expect(PgSearch::Document).to receive(:search).with(query).and_return(relation)
|
993
1013
|
end
|
994
1014
|
|
995
1015
|
it { should == relation }
|
996
1016
|
end
|
997
1017
|
|
998
1018
|
context "with PgSearch.multisearch_options set to a Hash" do
|
999
|
-
before { PgSearch.
|
1019
|
+
before { allow(PgSearch).to receive(:multisearch_options).and_return({:using => :dmetaphone}) }
|
1000
1020
|
subject { PgSearch.multisearch(query).map(&:searchable) }
|
1001
1021
|
|
1002
1022
|
with_model :MultisearchableModel do
|
@@ -1018,7 +1038,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
1018
1038
|
subject { PgSearch.multisearch(query, soundalike).map(&:searchable) }
|
1019
1039
|
|
1020
1040
|
before do
|
1021
|
-
PgSearch.
|
1041
|
+
allow(PgSearch).to receive(:multisearch_options) do
|
1022
1042
|
lambda do |query, soundalike|
|
1023
1043
|
if soundalike
|
1024
1044
|
{:using => :dmetaphone, :query => query}
|
@@ -1105,9 +1125,9 @@ describe "an Active Record model which includes PgSearch" do
|
|
1105
1125
|
end
|
1106
1126
|
@multisearch_enabled_after = PgSearch.multisearch_enabled?
|
1107
1127
|
|
1108
|
-
@multisearch_enabled_before.
|
1109
|
-
@multisearch_enabled_inside.
|
1110
|
-
@multisearch_enabled_after.
|
1128
|
+
expect(@multisearch_enabled_before).to be(true)
|
1129
|
+
expect(@multisearch_enabled_inside).to be(false)
|
1130
|
+
expect(@multisearch_enabled_after).to be(true)
|
1111
1131
|
end
|
1112
1132
|
|
1113
1133
|
it "should reenable multisearch after an error" do
|
@@ -1122,9 +1142,9 @@ describe "an Active Record model which includes PgSearch" do
|
|
1122
1142
|
|
1123
1143
|
@multisearch_enabled_after = PgSearch.multisearch_enabled?
|
1124
1144
|
|
1125
|
-
@multisearch_enabled_before.
|
1126
|
-
@multisearch_enabled_inside.
|
1127
|
-
@multisearch_enabled_after.
|
1145
|
+
expect(@multisearch_enabled_before).to be(true)
|
1146
|
+
expect(@multisearch_enabled_inside).to be(false)
|
1147
|
+
expect(@multisearch_enabled_after).to be(true)
|
1128
1148
|
end
|
1129
1149
|
|
1130
1150
|
it "should not disable multisearch on other threads" do
|
@@ -1146,9 +1166,9 @@ describe "an Active Record model which includes PgSearch" do
|
|
1146
1166
|
sync.push :go
|
1147
1167
|
@multisearch_enabled_after = values.pop
|
1148
1168
|
|
1149
|
-
@multisearch_enabled_before.
|
1150
|
-
@multisearch_enabled_inside.
|
1151
|
-
@multisearch_enabled_after.
|
1169
|
+
expect(@multisearch_enabled_before).to be(true)
|
1170
|
+
expect(@multisearch_enabled_inside).to be(true)
|
1171
|
+
expect(@multisearch_enabled_after).to be(true)
|
1152
1172
|
end
|
1153
1173
|
end
|
1154
1174
|
end
|
@@ -10,7 +10,7 @@ describe PgSearch::Configuration::Column do
|
|
10
10
|
|
11
11
|
it "returns the fully-qualified table and column name" do
|
12
12
|
column = described_class.new("name", nil, Model)
|
13
|
-
column.full_name.
|
13
|
+
expect(column.full_name).to eq(%Q{#{Model.quoted_table_name}."name"})
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -23,7 +23,7 @@ describe PgSearch::Configuration::Column do
|
|
23
23
|
|
24
24
|
it "returns an expression that casts the column to text and coalesces it with an empty string" do
|
25
25
|
column = described_class.new("name", nil, Model)
|
26
|
-
column.to_sql.
|
26
|
+
expect(column.to_sql).to eq(%Q{coalesce(#{Model.quoted_table_name}."name"::text, '')})
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|