pg_search 2.3.6 → 2.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +47 -35
- data/.github/workflows/codeql.yml +87 -0
- data/.standard.yml +6 -0
- data/CHANGELOG.md +23 -0
- data/Gemfile +21 -6
- data/LICENSE +1 -1
- data/README.md +133 -114
- data/Rakefile +4 -13
- data/lib/pg_search/configuration/column.rb +6 -4
- data/lib/pg_search/configuration/foreign_column.rb +1 -1
- data/lib/pg_search/configuration.rb +11 -27
- data/lib/pg_search/document.rb +8 -8
- data/lib/pg_search/features/dmetaphone.rb +1 -1
- data/lib/pg_search/features/trigram.rb +4 -4
- data/lib/pg_search/features/tsearch.rb +23 -30
- data/lib/pg_search/migration/dmetaphone_generator.rb +2 -2
- data/lib/pg_search/migration/generator.rb +5 -5
- data/lib/pg_search/migration/multisearch_generator.rb +2 -2
- data/lib/pg_search/model.rb +12 -14
- data/lib/pg_search/multisearch/rebuilder.rb +4 -3
- data/lib/pg_search/multisearch.rb +4 -2
- data/lib/pg_search/multisearchable.rb +7 -7
- data/lib/pg_search/normalizer.rb +17 -7
- data/lib/pg_search/scope_options.rb +36 -8
- data/lib/pg_search/tasks.rb +2 -2
- data/lib/pg_search/version.rb +1 -1
- data/lib/pg_search.rb +3 -3
- data/pg_search.gemspec +16 -31
- data/spec/integration/associations_spec.rb +118 -106
- data/spec/integration/deprecation_spec.rb +12 -9
- data/spec/integration/pagination_spec.rb +1 -0
- data/spec/integration/pg_search_spec.rb +343 -298
- data/spec/integration/single_table_inheritance_spec.rb +7 -5
- data/spec/lib/pg_search/configuration/association_spec.rb +17 -15
- data/spec/lib/pg_search/configuration/column_spec.rb +13 -1
- data/spec/lib/pg_search/configuration/foreign_column_spec.rb +5 -4
- data/spec/lib/pg_search/features/dmetaphone_spec.rb +4 -4
- data/spec/lib/pg_search/features/trigram_spec.rb +32 -33
- data/spec/lib/pg_search/features/tsearch_spec.rb +57 -39
- data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +70 -20
- data/spec/lib/pg_search/multisearch_spec.rb +8 -8
- data/spec/lib/pg_search/multisearchable_spec.rb +34 -26
- data/spec/lib/pg_search/normalizer_spec.rb +11 -11
- data/spec/lib/pg_search_spec.rb +22 -18
- data/spec/spec_helper.rb +3 -18
- data/spec/support/database.rb +6 -6
- metadata +11 -219
- data/.codeclimate.yml +0 -17
- data/.rubocop.yml +0 -137
- data/.travis.yml +0 -37
- data/spec/.rubocop.yml +0 -14
- data/spec/integration/.rubocop.yml +0 -11
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# standard:disable RSpec/NestedGroups
|
|
6
6
|
describe PgSearch::Multisearch::Rebuilder do
|
|
7
7
|
with_table "pg_search_documents", &DOCUMENTS_SCHEMA
|
|
8
8
|
|
|
9
|
-
describe
|
|
10
|
-
with_model :not_multisearchable
|
|
9
|
+
describe "when initialized with a model that is not multisearchable" do
|
|
10
|
+
with_model :not_multisearchable do
|
|
11
|
+
table
|
|
12
|
+
end
|
|
11
13
|
|
|
12
|
-
it
|
|
14
|
+
it "raises an exception" do
|
|
13
15
|
expect {
|
|
14
16
|
described_class.new(NotMultisearchable)
|
|
15
17
|
}.to raise_exception(
|
|
@@ -23,8 +25,11 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
23
25
|
context "when the model defines .rebuild_pg_search_documents" do
|
|
24
26
|
context "when multisearchable is not conditional" do
|
|
25
27
|
with_model :Model do
|
|
28
|
+
table
|
|
29
|
+
|
|
26
30
|
model do
|
|
27
31
|
include PgSearch::Model
|
|
32
|
+
|
|
28
33
|
multisearchable
|
|
29
34
|
|
|
30
35
|
def rebuild_pg_search_documents
|
|
@@ -53,6 +58,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
53
58
|
|
|
54
59
|
model do
|
|
55
60
|
include PgSearch::Model
|
|
61
|
+
|
|
56
62
|
multisearchable conditional_key => :active?
|
|
57
63
|
|
|
58
64
|
def rebuild_pg_search_documents
|
|
@@ -84,6 +90,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
84
90
|
|
|
85
91
|
model do
|
|
86
92
|
include PgSearch::Model
|
|
93
|
+
|
|
87
94
|
multisearchable against: :name
|
|
88
95
|
end
|
|
89
96
|
end
|
|
@@ -108,7 +115,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
108
115
|
end
|
|
109
116
|
end
|
|
110
117
|
|
|
111
|
-
#
|
|
118
|
+
# standard:disable RSpec/ExampleLength
|
|
112
119
|
it "executes the default SQL" do
|
|
113
120
|
time = Time.utc(2001, 1, 1, 0, 0, 0)
|
|
114
121
|
rebuilder = described_class.new(Model, -> { time })
|
|
@@ -116,7 +123,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
116
123
|
expected_sql = <<~SQL.squish
|
|
117
124
|
INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
|
|
118
125
|
SELECT 'Model' AS searchable_type,
|
|
119
|
-
#{Model.quoted_table_name}.#{Model.primary_key} AS searchable_id,
|
|
126
|
+
#{Model.quoted_table_name}.#{Model.connection.quote_column_name(Model.primary_key)} AS searchable_id,
|
|
120
127
|
(
|
|
121
128
|
coalesce(#{Model.quoted_table_name}."name"::text, '')
|
|
122
129
|
) AS content,
|
|
@@ -137,7 +144,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
137
144
|
expect(executed_sql.length).to eq(1)
|
|
138
145
|
expect(executed_sql.first.strip).to eq(expected_sql.strip)
|
|
139
146
|
end
|
|
140
|
-
#
|
|
147
|
+
# standard:enable RSpec/ExampleLength
|
|
141
148
|
|
|
142
149
|
context "with a model with a camel case column" do
|
|
143
150
|
with_model :ModelWithCamelCaseColumn do
|
|
@@ -147,14 +154,15 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
147
154
|
|
|
148
155
|
model do
|
|
149
156
|
include PgSearch::Model
|
|
157
|
+
|
|
150
158
|
multisearchable against: :name
|
|
151
159
|
end
|
|
152
160
|
end
|
|
153
161
|
|
|
154
|
-
it "
|
|
162
|
+
it "rebuilds without error" do
|
|
155
163
|
time = Time.utc(2001, 1, 1, 0, 0, 0)
|
|
156
164
|
rebuilder = described_class.new(Model, -> { time })
|
|
157
|
-
rebuilder.rebuild
|
|
165
|
+
expect { rebuilder.rebuild }.not_to raise_error
|
|
158
166
|
end
|
|
159
167
|
end
|
|
160
168
|
|
|
@@ -166,11 +174,12 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
166
174
|
|
|
167
175
|
model do
|
|
168
176
|
include PgSearch::Model
|
|
177
|
+
|
|
169
178
|
multisearchable against: :name
|
|
170
179
|
end
|
|
171
180
|
end
|
|
172
181
|
|
|
173
|
-
#
|
|
182
|
+
# standard:disable RSpec/ExampleLength
|
|
174
183
|
it "generates SQL with the correct primary key" do
|
|
175
184
|
time = Time.utc(2001, 1, 1, 0, 0, 0)
|
|
176
185
|
rebuilder = described_class.new(ModelWithNonStandardPrimaryKey, -> { time })
|
|
@@ -178,7 +187,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
178
187
|
expected_sql = <<~SQL.squish
|
|
179
188
|
INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
|
|
180
189
|
SELECT 'ModelWithNonStandardPrimaryKey' AS searchable_type,
|
|
181
|
-
#{ModelWithNonStandardPrimaryKey.quoted_table_name}.non_standard_primary_key AS searchable_id,
|
|
190
|
+
#{ModelWithNonStandardPrimaryKey.quoted_table_name}."non_standard_primary_key" AS searchable_id,
|
|
182
191
|
(
|
|
183
192
|
coalesce(#{ModelWithNonStandardPrimaryKey.quoted_table_name}."name"::text, '')
|
|
184
193
|
) AS content,
|
|
@@ -199,14 +208,17 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
199
208
|
expect(executed_sql.length).to eq(1)
|
|
200
209
|
expect(executed_sql.first.strip).to eq(expected_sql.strip)
|
|
201
210
|
end
|
|
202
|
-
#
|
|
211
|
+
# standard:enable RSpec/ExampleLength
|
|
203
212
|
end
|
|
204
213
|
end
|
|
205
214
|
|
|
206
215
|
context "when :against includes non-column dynamic methods" do
|
|
207
216
|
with_model :Model do
|
|
217
|
+
table
|
|
218
|
+
|
|
208
219
|
model do
|
|
209
220
|
include PgSearch::Model
|
|
221
|
+
|
|
210
222
|
multisearchable against: [:foo]
|
|
211
223
|
|
|
212
224
|
def foo
|
|
@@ -215,7 +227,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
215
227
|
end
|
|
216
228
|
end
|
|
217
229
|
|
|
218
|
-
#
|
|
230
|
+
# standard:disable RSpec/ExampleLength
|
|
219
231
|
it "calls update_pg_search_document on each record" do
|
|
220
232
|
record = Model.create!
|
|
221
233
|
|
|
@@ -241,7 +253,42 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
241
253
|
|
|
242
254
|
expect(record.pg_search_document).to be_present
|
|
243
255
|
end
|
|
244
|
-
#
|
|
256
|
+
# standard:enable RSpec/ExampleLength
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
context "with an identifier that requires quoting" do
|
|
260
|
+
with_model :Model do
|
|
261
|
+
table do |t|
|
|
262
|
+
t.string :name
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
model do
|
|
266
|
+
include PgSearch::Model
|
|
267
|
+
|
|
268
|
+
multisearchable against: :name
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "quotes the primary key in the generated SQL" do
|
|
273
|
+
malicious_pk = %(id"; DROP TABLE pg_search_documents; --)
|
|
274
|
+
allow(Model).to receive(:primary_key).and_return(malicious_pk)
|
|
275
|
+
|
|
276
|
+
rebuilder = described_class.new(Model)
|
|
277
|
+
sql = rebuilder.send(:rebuild_sql)
|
|
278
|
+
|
|
279
|
+
expect(sql).to include(Model.connection.quote_column_name(malicious_pk))
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "quotes the inheritance column in the STI clause" do
|
|
283
|
+
malicious_column = %(type"; DROP TABLE pg_search_documents; --)
|
|
284
|
+
allow(Model).to receive(:inheritance_column).and_return(malicious_column)
|
|
285
|
+
allow(Model).to receive(:column_names).and_return(Model.column_names + [malicious_column])
|
|
286
|
+
|
|
287
|
+
rebuilder = described_class.new(Model)
|
|
288
|
+
sql = rebuilder.send(:rebuild_sql)
|
|
289
|
+
|
|
290
|
+
expect(sql).to include(Model.connection.quote_column_name(malicious_column))
|
|
291
|
+
end
|
|
245
292
|
end
|
|
246
293
|
|
|
247
294
|
context "when only additional_attributes is set" do
|
|
@@ -252,8 +299,9 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
252
299
|
|
|
253
300
|
model do
|
|
254
301
|
include PgSearch::Model
|
|
302
|
+
|
|
255
303
|
multisearchable against: :name,
|
|
256
|
-
|
|
304
|
+
additional_attributes: ->(obj) { {additional_attribute_column: "#{obj.class}::#{obj.id}"} }
|
|
257
305
|
end
|
|
258
306
|
end
|
|
259
307
|
|
|
@@ -281,11 +329,12 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
281
329
|
|
|
282
330
|
model do
|
|
283
331
|
include PgSearch::Model
|
|
332
|
+
|
|
284
333
|
multisearchable if: :active?
|
|
285
334
|
end
|
|
286
335
|
end
|
|
287
336
|
|
|
288
|
-
#
|
|
337
|
+
# standard:disable RSpec/ExampleLength
|
|
289
338
|
it "calls update_pg_search_document on each record" do
|
|
290
339
|
record_1 = Model.create!(active: true)
|
|
291
340
|
record_2 = Model.create!(active: false)
|
|
@@ -311,7 +360,7 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
311
360
|
expect(record_1.pg_search_document).to be_present
|
|
312
361
|
expect(record_2.pg_search_document).not_to be_present
|
|
313
362
|
end
|
|
314
|
-
#
|
|
363
|
+
# standard:enable RSpec/ExampleLength
|
|
315
364
|
end
|
|
316
365
|
|
|
317
366
|
context "via :unless" do
|
|
@@ -322,11 +371,12 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
322
371
|
|
|
323
372
|
model do
|
|
324
373
|
include PgSearch::Model
|
|
374
|
+
|
|
325
375
|
multisearchable unless: :inactive?
|
|
326
376
|
end
|
|
327
377
|
end
|
|
328
378
|
|
|
329
|
-
#
|
|
379
|
+
# standard:disable RSpec/ExampleLength
|
|
330
380
|
it "calls update_pg_search_document on each record" do
|
|
331
381
|
record_1 = Model.create!(inactive: true)
|
|
332
382
|
record_2 = Model.create!(inactive: false)
|
|
@@ -352,10 +402,10 @@ describe PgSearch::Multisearch::Rebuilder do
|
|
|
352
402
|
expect(record_1.pg_search_document).not_to be_present
|
|
353
403
|
expect(record_2.pg_search_document).to be_present
|
|
354
404
|
end
|
|
355
|
-
#
|
|
405
|
+
# standard:enable RSpec/ExampleLength
|
|
356
406
|
end
|
|
357
407
|
end
|
|
358
408
|
end
|
|
359
409
|
end
|
|
360
410
|
end
|
|
361
|
-
#
|
|
411
|
+
# standard:enable RSpec/NestedGroups
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
|
-
require "active_support/
|
|
4
|
+
require "active_support/core_ext/kernel/reporting"
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# standard:disable RSpec/NestedGroups
|
|
7
7
|
describe PgSearch::Multisearch do
|
|
8
8
|
with_table "pg_search_documents", &DOCUMENTS_SCHEMA
|
|
9
9
|
|
|
@@ -82,7 +82,7 @@ describe PgSearch::Multisearch do
|
|
|
82
82
|
|
|
83
83
|
context "when deprecated_clean_up is true" do
|
|
84
84
|
it "deletes the document for the model" do
|
|
85
|
-
|
|
85
|
+
silence_warnings { described_class.rebuild(model, true) }
|
|
86
86
|
expect(PgSearch::Document.count).to eq(1)
|
|
87
87
|
expect(PgSearch::Document.first.searchable_type).to eq("Bar")
|
|
88
88
|
end
|
|
@@ -90,7 +90,7 @@ describe PgSearch::Multisearch do
|
|
|
90
90
|
|
|
91
91
|
context "when deprecated_clean_up is false" do
|
|
92
92
|
it "does not delete the document for the model" do
|
|
93
|
-
|
|
93
|
+
silence_warnings { described_class.rebuild(model, false) }
|
|
94
94
|
expect(PgSearch::Document.count).to eq(2)
|
|
95
95
|
end
|
|
96
96
|
end
|
|
@@ -135,7 +135,7 @@ describe PgSearch::Multisearch do
|
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
describe "the generated SQL" do
|
|
138
|
-
let(:now) { Time.now }
|
|
138
|
+
let(:now) { Time.now } # standard:disable Rails/TimeZone
|
|
139
139
|
|
|
140
140
|
before { allow(Time).to receive(:now).and_return(now) }
|
|
141
141
|
|
|
@@ -148,7 +148,7 @@ describe PgSearch::Multisearch do
|
|
|
148
148
|
expected_sql = <<~SQL.squish
|
|
149
149
|
INSERT INTO #{PgSearch::Document.quoted_table_name} (searchable_type, searchable_id, content, created_at, updated_at)
|
|
150
150
|
SELECT #{connection.quote(model.name)} AS searchable_type,
|
|
151
|
-
#{model.quoted_table_name}.
|
|
151
|
+
#{model.quoted_table_name}.#{connection.quote_column_name(model.primary_key)} AS searchable_id,
|
|
152
152
|
(
|
|
153
153
|
coalesce(#{model.quoted_table_name}."title"::text, '')
|
|
154
154
|
) AS content,
|
|
@@ -175,7 +175,7 @@ describe PgSearch::Multisearch do
|
|
|
175
175
|
expected_sql = <<~SQL.squish
|
|
176
176
|
INSERT INTO #{PgSearch::Document.quoted_table_name} (searchable_type, searchable_id, content, created_at, updated_at)
|
|
177
177
|
SELECT #{connection.quote(model.name)} AS searchable_type,
|
|
178
|
-
#{model.quoted_table_name}.
|
|
178
|
+
#{model.quoted_table_name}.#{connection.quote_column_name(model.primary_key)} AS searchable_id,
|
|
179
179
|
(
|
|
180
180
|
coalesce(#{model.quoted_table_name}."title"::text, '') || ' ' || coalesce(#{model.quoted_table_name}."content"::text, '')
|
|
181
181
|
) AS content,
|
|
@@ -195,4 +195,4 @@ describe PgSearch::Multisearch do
|
|
|
195
195
|
end
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
|
-
#
|
|
198
|
+
# standard:enable RSpec/NestedGroups
|
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# standard:disable RSpec/NestedGroups
|
|
6
6
|
describe PgSearch::Multisearchable do
|
|
7
7
|
with_table "pg_search_documents", &DOCUMENTS_SCHEMA
|
|
8
8
|
|
|
9
9
|
describe "a model that is multisearchable" do
|
|
10
10
|
with_model :ModelThatIsMultisearchable do
|
|
11
|
+
table
|
|
12
|
+
|
|
11
13
|
model do
|
|
12
14
|
include PgSearch::Model
|
|
15
|
+
|
|
13
16
|
multisearchable
|
|
14
17
|
end
|
|
15
18
|
end
|
|
@@ -21,6 +24,7 @@ describe PgSearch::Multisearchable do
|
|
|
21
24
|
|
|
22
25
|
model do
|
|
23
26
|
include PgSearch::Model
|
|
27
|
+
|
|
24
28
|
multisearchable
|
|
25
29
|
|
|
26
30
|
has_many :multisearchable_children, dependent: :destroy
|
|
@@ -36,7 +40,7 @@ describe PgSearch::Multisearchable do
|
|
|
36
40
|
belongs_to :multisearchable_parent
|
|
37
41
|
|
|
38
42
|
after_destroy do
|
|
39
|
-
multisearchable_parent.update_attribute(:secret, rand(1000).to_s)
|
|
43
|
+
multisearchable_parent.update_attribute(:secret, rand(1000).to_s)
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
@@ -149,17 +153,17 @@ describe PgSearch::Multisearchable do
|
|
|
149
153
|
end
|
|
150
154
|
|
|
151
155
|
context "when searching against a single column" do
|
|
152
|
-
let(:multisearchable_options) { {
|
|
156
|
+
let(:multisearchable_options) { {against: :some_content} }
|
|
153
157
|
let(:text) { "foo bar" }
|
|
154
158
|
|
|
155
159
|
before do
|
|
156
160
|
without_partial_double_verification do
|
|
157
161
|
allow(record).to receive(:some_content) { text }
|
|
158
162
|
end
|
|
159
|
-
record.save
|
|
163
|
+
record.save!
|
|
160
164
|
end
|
|
161
165
|
|
|
162
|
-
describe
|
|
166
|
+
describe "#content" do
|
|
163
167
|
subject { super().pg_search_document.content }
|
|
164
168
|
|
|
165
169
|
it { is_expected.to eq(text) }
|
|
@@ -167,17 +171,17 @@ describe PgSearch::Multisearchable do
|
|
|
167
171
|
end
|
|
168
172
|
|
|
169
173
|
context "when searching against multiple columns" do
|
|
170
|
-
let(:multisearchable_options) { {
|
|
174
|
+
let(:multisearchable_options) { {against: %i[attr_1 attr_2]} }
|
|
171
175
|
|
|
172
176
|
before do
|
|
173
177
|
without_partial_double_verification do
|
|
174
|
-
allow(record).to receive(:attr_1).and_return(
|
|
175
|
-
allow(record).to receive(:attr_2).and_return(
|
|
178
|
+
allow(record).to receive(:attr_1).and_return("1")
|
|
179
|
+
allow(record).to receive(:attr_2).and_return("2")
|
|
176
180
|
end
|
|
177
|
-
record.save
|
|
181
|
+
record.save!
|
|
178
182
|
end
|
|
179
183
|
|
|
180
|
-
describe
|
|
184
|
+
describe "#content" do
|
|
181
185
|
subject { super().pg_search_document.content }
|
|
182
186
|
|
|
183
187
|
it { is_expected.to eq("1 2") }
|
|
@@ -195,17 +199,17 @@ describe PgSearch::Multisearchable do
|
|
|
195
199
|
end
|
|
196
200
|
|
|
197
201
|
context "when searching against a single column" do
|
|
198
|
-
let(:multisearchable_options) { {
|
|
202
|
+
let(:multisearchable_options) { {against: :some_content} }
|
|
199
203
|
let(:text) { "foo bar" }
|
|
200
204
|
|
|
201
205
|
before do
|
|
202
206
|
without_partial_double_verification do
|
|
203
207
|
allow(record).to receive(:some_content) { text }
|
|
204
208
|
end
|
|
205
|
-
record.save
|
|
209
|
+
record.save!
|
|
206
210
|
end
|
|
207
211
|
|
|
208
|
-
describe
|
|
212
|
+
describe "#content" do
|
|
209
213
|
subject { super().pg_search_document.content }
|
|
210
214
|
|
|
211
215
|
it { is_expected.to eq(text) }
|
|
@@ -213,17 +217,17 @@ describe PgSearch::Multisearchable do
|
|
|
213
217
|
end
|
|
214
218
|
|
|
215
219
|
context "when searching against multiple columns" do
|
|
216
|
-
let(:multisearchable_options) { {
|
|
220
|
+
let(:multisearchable_options) { {against: %i[attr_1 attr_2]} }
|
|
217
221
|
|
|
218
222
|
before do
|
|
219
223
|
without_partial_double_verification do
|
|
220
|
-
allow(record).to receive(:attr_1).and_return(
|
|
221
|
-
allow(record).to receive(:attr_2).and_return(
|
|
224
|
+
allow(record).to receive(:attr_1).and_return("1")
|
|
225
|
+
allow(record).to receive(:attr_2).and_return("2")
|
|
222
226
|
end
|
|
223
|
-
record.save
|
|
227
|
+
record.save!
|
|
224
228
|
end
|
|
225
229
|
|
|
226
|
-
describe
|
|
230
|
+
describe "#content" do
|
|
227
231
|
subject { super().pg_search_document.content }
|
|
228
232
|
|
|
229
233
|
it { is_expected.to eq("1 2") }
|
|
@@ -234,7 +238,7 @@ describe PgSearch::Multisearchable do
|
|
|
234
238
|
let(:multisearchable_options) do
|
|
235
239
|
{
|
|
236
240
|
additional_attributes: lambda do |record|
|
|
237
|
-
{
|
|
241
|
+
{foo: record.bar}
|
|
238
242
|
end
|
|
239
243
|
}
|
|
240
244
|
end
|
|
@@ -244,10 +248,10 @@ describe PgSearch::Multisearchable do
|
|
|
244
248
|
without_partial_double_verification do
|
|
245
249
|
allow(record).to receive(:bar).and_return(text)
|
|
246
250
|
allow(record).to receive(:create_pg_search_document)
|
|
247
|
-
record.save
|
|
251
|
+
record.save!
|
|
248
252
|
expect(record)
|
|
249
253
|
.to have_received(:create_pg_search_document)
|
|
250
|
-
.with(content:
|
|
254
|
+
.with(content: "", foo: text)
|
|
251
255
|
end
|
|
252
256
|
end
|
|
253
257
|
end
|
|
@@ -266,10 +270,10 @@ describe PgSearch::Multisearchable do
|
|
|
266
270
|
without_partial_double_verification do
|
|
267
271
|
allow(record).to receive(:bar?).and_return(false)
|
|
268
272
|
allow(record).to receive(:create_pg_search_document)
|
|
269
|
-
record.save
|
|
273
|
+
record.save!
|
|
270
274
|
expect(record)
|
|
271
275
|
.to have_received(:create_pg_search_document)
|
|
272
|
-
.with(content:
|
|
276
|
+
.with(content: "")
|
|
273
277
|
end
|
|
274
278
|
end
|
|
275
279
|
|
|
@@ -286,7 +290,7 @@ describe PgSearch::Multisearchable do
|
|
|
286
290
|
it "does not update the document" do
|
|
287
291
|
without_partial_double_verification do
|
|
288
292
|
allow(record.pg_search_document).to receive(:update)
|
|
289
|
-
record.save
|
|
293
|
+
record.save!
|
|
290
294
|
expect(record.pg_search_document).not_to have_received(:update)
|
|
291
295
|
end
|
|
292
296
|
end
|
|
@@ -301,7 +305,7 @@ describe PgSearch::Multisearchable do
|
|
|
301
305
|
|
|
302
306
|
it "updates the document" do
|
|
303
307
|
allow(record.pg_search_document).to receive(:update)
|
|
304
|
-
record.save
|
|
308
|
+
record.save!
|
|
305
309
|
expect(record.pg_search_document).to have_received(:update)
|
|
306
310
|
end
|
|
307
311
|
end
|
|
@@ -319,6 +323,7 @@ describe PgSearch::Multisearchable do
|
|
|
319
323
|
|
|
320
324
|
model do
|
|
321
325
|
include PgSearch::Model
|
|
326
|
+
|
|
322
327
|
multisearchable if: ->(record) { record.multisearchable? }
|
|
323
328
|
end
|
|
324
329
|
end
|
|
@@ -450,6 +455,7 @@ describe PgSearch::Multisearchable do
|
|
|
450
455
|
|
|
451
456
|
model do
|
|
452
457
|
include PgSearch::Model
|
|
458
|
+
|
|
453
459
|
multisearchable unless: ->(record) { record.not_multisearchable? }
|
|
454
460
|
end
|
|
455
461
|
end
|
|
@@ -585,6 +591,7 @@ describe PgSearch::Multisearchable do
|
|
|
585
591
|
|
|
586
592
|
model do
|
|
587
593
|
include PgSearch::Model
|
|
594
|
+
|
|
588
595
|
multisearchable if: :multisearchable?
|
|
589
596
|
end
|
|
590
597
|
end
|
|
@@ -723,6 +730,7 @@ describe PgSearch::Multisearchable do
|
|
|
723
730
|
|
|
724
731
|
model do
|
|
725
732
|
include PgSearch::Model
|
|
733
|
+
|
|
726
734
|
multisearchable unless: :not_multisearchable?
|
|
727
735
|
end
|
|
728
736
|
end
|
|
@@ -854,4 +862,4 @@ describe PgSearch::Multisearchable do
|
|
|
854
862
|
end
|
|
855
863
|
end
|
|
856
864
|
end
|
|
857
|
-
#
|
|
865
|
+
# standard:enable RSpec/NestedGroups
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# standard:disable RSpec/NestedGroups
|
|
6
6
|
describe PgSearch::Normalizer do
|
|
7
7
|
describe "#add_normalization" do
|
|
8
8
|
context "when config[:ignore] includes :accents" do
|
|
9
9
|
context "when passed an Arel node" do
|
|
10
10
|
it "wraps the expression in unaccent()" do
|
|
11
|
-
config = instance_double(
|
|
11
|
+
config = instance_double(PgSearch::Configuration, "config", ignore: [:accents])
|
|
12
12
|
node = Arel::Nodes::NamedFunction.new("foo", [Arel::Nodes.build_quoted("bar")])
|
|
13
13
|
|
|
14
14
|
normalizer = described_class.new(config)
|
|
15
|
-
expect(normalizer.add_normalization(node)).to eq("unaccent(foo('bar'))")
|
|
15
|
+
expect(normalizer.add_normalization(node)).to eq("regexp_replace(unaccent(foo('bar')), '[''?\\:]', '', 'g')")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
context "when a custom unaccent function is specified" do
|
|
@@ -20,30 +20,30 @@ describe PgSearch::Normalizer do
|
|
|
20
20
|
allow(PgSearch).to receive(:unaccent_function).and_return("my_unaccent")
|
|
21
21
|
node = Arel::Nodes::NamedFunction.new("foo", [Arel::Nodes.build_quoted("bar")])
|
|
22
22
|
|
|
23
|
-
config = instance_double(
|
|
23
|
+
config = instance_double(PgSearch::Configuration, "config", ignore: [:accents])
|
|
24
24
|
|
|
25
25
|
normalizer = described_class.new(config)
|
|
26
|
-
expect(normalizer.add_normalization(node)).to eq("my_unaccent(foo('bar'))")
|
|
26
|
+
expect(normalizer.add_normalization(node)).to eq("regexp_replace(my_unaccent(foo('bar')), '[''?\\:]', '', 'g')")
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
context "when passed a String" do
|
|
32
32
|
it "wraps the expression in unaccent()" do
|
|
33
|
-
config = instance_double(
|
|
33
|
+
config = instance_double(PgSearch::Configuration, "config", ignore: [:accents])
|
|
34
34
|
|
|
35
35
|
normalizer = described_class.new(config)
|
|
36
|
-
expect(normalizer.add_normalization("foo")).to eq("unaccent(foo)")
|
|
36
|
+
expect(normalizer.add_normalization("foo")).to eq("regexp_replace(unaccent(foo), '[''?\\:]', '', 'g')")
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
context "when a custom unaccent function is specified" do
|
|
40
40
|
it "wraps the expression in that function" do
|
|
41
41
|
allow(PgSearch).to receive(:unaccent_function).and_return("my_unaccent")
|
|
42
42
|
|
|
43
|
-
config = instance_double(
|
|
43
|
+
config = instance_double(PgSearch::Configuration, "config", ignore: [:accents])
|
|
44
44
|
|
|
45
45
|
normalizer = described_class.new(config)
|
|
46
|
-
expect(normalizer.add_normalization("foo")).to eq("my_unaccent(foo)")
|
|
46
|
+
expect(normalizer.add_normalization("foo")).to eq("regexp_replace(my_unaccent(foo), '[''?\\:]', '', 'g')")
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
end
|
|
@@ -51,7 +51,7 @@ describe PgSearch::Normalizer do
|
|
|
51
51
|
|
|
52
52
|
context "when config[:ignore] does not include :accents" do
|
|
53
53
|
it "passes the expression through" do
|
|
54
|
-
config = instance_double(
|
|
54
|
+
config = instance_double(PgSearch::Configuration, "config", ignore: [])
|
|
55
55
|
|
|
56
56
|
normalizer = described_class.new(config)
|
|
57
57
|
expect(normalizer.add_normalization("foo")).to eq("foo")
|
|
@@ -59,4 +59,4 @@ describe PgSearch::Normalizer do
|
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
|
-
#
|
|
62
|
+
# standard:enable RSpec/NestedGroups
|