pg_search 2.3.0 → 2.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -0
  3. data/.github/dependabot.yml +11 -0
  4. data/.jrubyrc +1 -0
  5. data/.rubocop.yml +85 -7
  6. data/.travis.yml +14 -22
  7. data/CHANGELOG.md +41 -16
  8. data/CODE_OF_CONDUCT.md +76 -0
  9. data/Gemfile +1 -1
  10. data/LICENSE +1 -1
  11. data/README.md +60 -18
  12. data/lib/pg_search.rb +4 -6
  13. data/lib/pg_search/document.rb +1 -1
  14. data/lib/pg_search/features/dmetaphone.rb +4 -6
  15. data/lib/pg_search/features/tsearch.rb +13 -12
  16. data/lib/pg_search/migration/templates/add_pg_search_dmetaphone_support_functions.rb.erb +6 -6
  17. data/lib/pg_search/migration/templates/create_pg_search_documents.rb.erb +2 -2
  18. data/lib/pg_search/multisearch.rb +10 -1
  19. data/lib/pg_search/multisearch/rebuilder.rb +7 -3
  20. data/lib/pg_search/scope_options.rb +3 -3
  21. data/lib/pg_search/tasks.rb +2 -1
  22. data/lib/pg_search/version.rb +1 -1
  23. data/pg_search.gemspec +11 -7
  24. data/spec/.rubocop.yml +2 -2
  25. data/spec/integration/.rubocop.yml +11 -0
  26. data/spec/integration/associations_spec.rb +17 -56
  27. data/spec/integration/deprecation_spec.rb +1 -1
  28. data/spec/integration/pg_search_spec.rb +62 -51
  29. data/spec/lib/pg_search/configuration/association_spec.rb +8 -6
  30. data/spec/lib/pg_search/features/dmetaphone_spec.rb +2 -2
  31. data/spec/lib/pg_search/features/trigram_spec.rb +15 -11
  32. data/spec/lib/pg_search/features/tsearch_spec.rb +16 -10
  33. data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +116 -71
  34. data/spec/lib/pg_search/multisearch_spec.rb +48 -29
  35. data/spec/lib/pg_search/multisearchable_spec.rb +150 -97
  36. data/spec/lib/pg_search/normalizer_spec.rb +12 -10
  37. data/spec/lib/pg_search_spec.rb +66 -55
  38. data/spec/spec_helper.rb +13 -4
  39. data/spec/support/database.rb +1 -1
  40. metadata +78 -17
@@ -18,7 +18,7 @@ describe PgSearch::Features::DMetaphone do
18
18
  PgSearch::Configuration::Column.new(:content, nil, Model)
19
19
  ]
20
20
  options = {}
21
- config = double(:config, ignore: [])
21
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
22
22
  normalizer = PgSearch::Normalizer.new(config)
23
23
 
24
24
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -43,7 +43,7 @@ describe PgSearch::Features::DMetaphone do
43
43
  PgSearch::Configuration::Column.new(:content, nil, Model)
44
44
  ]
45
45
  options = {}
46
- config = double(:config, ignore: [])
46
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
47
47
  normalizer = PgSearch::Normalizer.new(config)
48
48
 
49
49
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -3,8 +3,10 @@
3
3
  require 'spec_helper'
4
4
  require 'ostruct'
5
5
 
6
+ # rubocop:disable RSpec/MultipleMemoizedHelpers, RSpec/NestedGroups
6
7
  describe PgSearch::Features::Trigram do
7
8
  subject(:feature) { described_class.new(query, options, columns, Model, normalizer) }
9
+
8
10
  let(:query) { 'lolwut' }
9
11
  let(:options) { {} }
10
12
  let(:columns) {
@@ -17,8 +19,10 @@ describe PgSearch::Features::Trigram do
17
19
  let(:config) { OpenStruct.new(ignore: []) }
18
20
 
19
21
  let(:coalesced_columns) do
20
- <<-SQL.strip_heredoc.chomp
21
- coalesce(#{Model.quoted_table_name}."name"::text, '') || ' ' || coalesce(#{Model.quoted_table_name}."content"::text, '')
22
+ <<~SQL.squish
23
+ coalesce(#{Model.quoted_table_name}."name"::text, '')
24
+ || ' '
25
+ || coalesce(#{Model.quoted_table_name}."content"::text, '')
22
26
  SQL
23
27
  end
24
28
 
@@ -35,7 +39,7 @@ describe PgSearch::Features::Trigram do
35
39
  expect(feature.conditions.to_sql).to eq("('#{query}' % (#{coalesced_columns}))")
36
40
  end
37
41
 
38
- context 'searching by word_similarity' do
42
+ context 'when searching by word_similarity' do
39
43
  let(:options) do
40
44
  { word_similarity: true }
41
45
  end
@@ -46,7 +50,7 @@ describe PgSearch::Features::Trigram do
46
50
  end
47
51
  end
48
52
 
49
- context 'ignoring accents' do
53
+ context 'when ignoring accents' do
50
54
  it 'escapes the search document and query, but not the accent function' do
51
55
  config.ignore = [:accents]
52
56
  expect(feature.conditions.to_sql).to eq("(unaccent('#{query}') % (unaccent(#{coalesced_columns})))")
@@ -54,7 +58,7 @@ describe PgSearch::Features::Trigram do
54
58
  end
55
59
 
56
60
  context 'when a threshold is specified' do
57
- context 'searching by similarity' do
61
+ context 'when searching by similarity' do
58
62
  let(:options) do
59
63
  { threshold: 0.5 }
60
64
  end
@@ -66,7 +70,7 @@ describe PgSearch::Features::Trigram do
66
70
  end
67
71
  end
68
72
 
69
- context 'searching by word_similarity' do
73
+ context 'when searching by word_similarity' do
70
74
  let(:options) do
71
75
  { threshold: 0.5, word_similarity: true }
72
76
  end
@@ -79,21 +83,20 @@ describe PgSearch::Features::Trigram do
79
83
  end
80
84
  end
81
85
 
82
- context 'only certain columns are selected' do
83
- context 'one column' do
86
+ context 'when only certain columns are selected' do
87
+ context 'with one column' do
84
88
  let(:options) { { only: :name } }
85
89
 
86
90
  it 'only searches against the select column' do
87
- options = { only: :name }
88
91
  coalesced_column = "coalesce(#{Model.quoted_table_name}.\"name\"::text, '')"
89
92
  expect(feature.conditions.to_sql).to eq("('#{query}' % (#{coalesced_column}))")
90
93
  end
91
94
  end
92
- context 'multiple columns' do
95
+
96
+ context 'with multiple columns' do
93
97
  let(:options) { { only: %i[name content] } }
94
98
 
95
99
  it 'concatenates when multiples columns are selected' do
96
- options = { only: %i[name content] }
97
100
  expect(feature.conditions.to_sql).to eq("('#{query}' % (#{coalesced_columns}))")
98
101
  end
99
102
  end
@@ -106,3 +109,4 @@ describe PgSearch::Features::Trigram do
106
109
  end
107
110
  end
108
111
  end
112
+ # rubocop:enable RSpec/MultipleMemoizedHelpers, RSpec/NestedGroups
@@ -19,7 +19,7 @@ describe PgSearch::Features::TSearch do
19
19
  PgSearch::Configuration::Column.new(:content, nil, Model)
20
20
  ]
21
21
  options = {}
22
- config = double(:config, ignore: [])
22
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
23
23
  normalizer = PgSearch::Normalizer.new(config)
24
24
 
25
25
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -44,7 +44,7 @@ describe PgSearch::Features::TSearch do
44
44
  PgSearch::Configuration::Column.new(:content, nil, Model)
45
45
  ]
46
46
  options = {}
47
- config = double(:config, ignore: [])
47
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
48
48
  normalizer = PgSearch::Normalizer.new(config)
49
49
 
50
50
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -61,7 +61,7 @@ describe PgSearch::Features::TSearch do
61
61
  PgSearch::Configuration::Column.new(:content, nil, Model)
62
62
  ]
63
63
  options = { negation: true }
64
- config = double(:config, ignore: [])
64
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
65
65
  normalizer = PgSearch::Normalizer.new(config)
66
66
 
67
67
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -79,7 +79,7 @@ describe PgSearch::Features::TSearch do
79
79
  PgSearch::Configuration::Column.new(:content, nil, Model)
80
80
  ]
81
81
  options = { negation: false }
82
- config = double(:config, ignore: [])
82
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
83
83
  normalizer = PgSearch::Normalizer.new(config)
84
84
 
85
85
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -97,7 +97,7 @@ describe PgSearch::Features::TSearch do
97
97
  PgSearch::Configuration::Column.new(:content, nil, Model)
98
98
  ]
99
99
  options = { tsvector_column: "my_tsvector" }
100
- config = double(:config, ignore: [])
100
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
101
101
  normalizer = PgSearch::Normalizer.new(config)
102
102
 
103
103
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -115,7 +115,7 @@ describe PgSearch::Features::TSearch do
115
115
  PgSearch::Configuration::Column.new(:content, nil, Model)
116
116
  ]
117
117
  options = { tsvector_column: ["tsvector1", "tsvector2"] }
118
- config = double(:config, ignore: [])
118
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
119
119
  normalizer = PgSearch::Normalizer.new(config)
120
120
 
121
121
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -141,7 +141,7 @@ describe PgSearch::Features::TSearch do
141
141
  ]
142
142
  options = {}
143
143
 
144
- config = double(:config, ignore: [])
144
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
145
145
  normalizer = PgSearch::Normalizer.new(config)
146
146
 
147
147
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -151,6 +151,7 @@ describe PgSearch::Features::TSearch do
151
151
  end
152
152
 
153
153
  context "when options[:dictionary] is passed" do
154
+ # rubocop:disable RSpec/ExampleLength
154
155
  it 'uses the provided dictionary' do
155
156
  query = "query"
156
157
  columns = [
@@ -165,7 +166,7 @@ describe PgSearch::Features::TSearch do
165
166
  }
166
167
  }
167
168
 
168
- config = double(:config, ignore: [])
169
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
169
170
  normalizer = PgSearch::Normalizer.new(config)
170
171
 
171
172
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -174,9 +175,11 @@ describe PgSearch::Features::TSearch do
174
175
 
175
176
  expect(feature.highlight.to_sql).to eq(expected_sql)
176
177
  end
178
+ # rubocop:enable RSpec/ExampleLength
177
179
  end
178
180
 
179
181
  context "when options[:highlight] has options set" do
182
+ # rubocop:disable RSpec/ExampleLength
180
183
  it "passes the options to ts_headline" do
181
184
  query = "query"
182
185
  columns = [
@@ -195,7 +198,7 @@ describe PgSearch::Features::TSearch do
195
198
  }
196
199
  }
197
200
 
198
- config = double(:config, ignore: [])
201
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
199
202
  normalizer = PgSearch::Normalizer.new(config)
200
203
 
201
204
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -204,7 +207,9 @@ describe PgSearch::Features::TSearch do
204
207
 
205
208
  expect(feature.highlight.to_sql).to eq(expected_sql)
206
209
  end
210
+ # rubocop:enable RSpec/ExampleLength
207
211
 
212
+ # rubocop:disable RSpec/ExampleLength
208
213
  it "passes deprecated options to ts_headline" do
209
214
  query = "query"
210
215
  columns = [
@@ -223,7 +228,7 @@ describe PgSearch::Features::TSearch do
223
228
  }
224
229
  }
225
230
 
226
- config = double(:config, ignore: [])
231
+ config = instance_double("PgSearch::Configuration", :config, ignore: [])
227
232
  normalizer = PgSearch::Normalizer.new(config)
228
233
 
229
234
  feature = described_class.new(query, options, columns, Model, normalizer)
@@ -233,6 +238,7 @@ describe PgSearch::Features::TSearch do
233
238
 
234
239
  expect(highlight_sql).to eq(expected_sql)
235
240
  end
241
+ # rubocop:enable RSpec/ExampleLength
236
242
  end
237
243
  end
238
244
  end
@@ -2,20 +2,16 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- def has_microsecond_precision?
6
- (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 1) ||
7
- (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0 && ActiveRecord::VERSION::TINY >= 1)
8
- end
9
-
5
+ # rubocop:disable RSpec/NestedGroups
10
6
  describe PgSearch::Multisearch::Rebuilder do
11
- with_table "pg_search_documents", {}, &DOCUMENTS_SCHEMA
7
+ with_table "pg_search_documents", &DOCUMENTS_SCHEMA
12
8
 
13
9
  describe 'when initialized with a model that is not multisearchable' do
14
10
  with_model :not_multisearchable
15
11
 
16
12
  it 'raises an exception' do
17
13
  expect {
18
- PgSearch::Multisearch::Rebuilder.new(NotMultisearchable)
14
+ described_class.new(NotMultisearchable)
19
15
  }.to raise_exception(
20
16
  PgSearch::Multisearch::ModelNotMultisearchable,
21
17
  "NotMultisearchable is not multisearchable. See PgSearch::ClassMethods#multisearchable"
@@ -25,7 +21,7 @@ describe PgSearch::Multisearch::Rebuilder do
25
21
 
26
22
  describe "#rebuild" do
27
23
  context "when the model defines .rebuild_pg_search_documents" do
28
- context "and multisearchable is not conditional" do
24
+ context "when multisearchable is not conditional" do
29
25
  with_model :Model do
30
26
  model do
31
27
  include PgSearch::Model
@@ -36,14 +32,18 @@ describe PgSearch::Multisearch::Rebuilder do
36
32
  end
37
33
  end
38
34
 
39
- it "should call .rebuild_pg_search_documents" do
40
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
41
- expect(Model).to receive(:rebuild_pg_search_documents)
42
- rebuilder.rebuild
35
+ it "calls .rebuild_pg_search_documents" do
36
+ rebuilder = described_class.new(Model)
37
+
38
+ without_partial_double_verification do
39
+ allow(Model).to receive(:rebuild_pg_search_documents)
40
+ rebuilder.rebuild
41
+ expect(Model).to have_received(:rebuild_pg_search_documents)
42
+ end
43
43
  end
44
44
  end
45
45
 
46
- context "and multisearchable is conditional" do
46
+ context "when multisearchable is conditional" do
47
47
  %i[if unless].each do |conditional_key|
48
48
  context "via :#{conditional_key}" do
49
49
  with_model :Model do
@@ -60,10 +60,14 @@ describe PgSearch::Multisearch::Rebuilder do
60
60
  end
61
61
  end
62
62
 
63
- it "should call .rebuild_pg_search_documents" do
64
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
65
- expect(Model).to receive(:rebuild_pg_search_documents)
66
- rebuilder.rebuild
63
+ it "calls .rebuild_pg_search_documents" do
64
+ rebuilder = described_class.new(Model)
65
+
66
+ without_partial_double_verification do
67
+ allow(Model).to receive(:rebuild_pg_search_documents)
68
+ rebuilder.rebuild
69
+ expect(Model).to have_received(:rebuild_pg_search_documents)
70
+ end
67
71
  end
68
72
  end
69
73
  end
@@ -71,7 +75,7 @@ describe PgSearch::Multisearch::Rebuilder do
71
75
  end
72
76
 
73
77
  context "when the model does not define .rebuild_pg_search_documents" do
74
- context "and multisearchable is not conditional" do
78
+ context "when multisearchable is not conditional" do
75
79
  context "when :against only includes columns" do
76
80
  with_model :Model do
77
81
  table do |t|
@@ -84,8 +88,8 @@ describe PgSearch::Multisearch::Rebuilder do
84
88
  end
85
89
  end
86
90
 
87
- it "should not call :rebuild_pg_search_documents" do
88
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
91
+ it "does not call :rebuild_pg_search_documents" do
92
+ rebuilder = described_class.new(Model)
89
93
 
90
94
  # stub respond_to? to return false since should_not_receive defines the method
91
95
  original_respond_to = Model.method(:respond_to?)
@@ -97,28 +101,28 @@ describe PgSearch::Multisearch::Rebuilder do
97
101
  end
98
102
  end
99
103
 
100
- expect(Model).not_to receive(:rebuild_pg_search_documents)
101
- rebuilder.rebuild
104
+ without_partial_double_verification do
105
+ allow(Model).to receive(:rebuild_pg_search_documents)
106
+ rebuilder.rebuild
107
+ expect(Model).not_to have_received(:rebuild_pg_search_documents)
108
+ end
102
109
  end
103
110
 
104
- it "should execute the default SQL" do
111
+ # rubocop:disable RSpec/ExampleLength
112
+ it "executes the default SQL" do
105
113
  time = Time.utc(2001, 1, 1, 0, 0, 0)
106
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model, -> { time })
107
-
108
- # Handle change in precision of Time objects in SQL in Active Record 4.0.1
109
- # https://github.com/rails/rails/commit/17f5d8e062909f1fcae25351834d8e89967b645e
110
- expected_timestamp = has_microsecond_precision? ? "2001-01-01 00:00:00.000000" : "2001-01-01 00:00:00"
111
-
112
- expected_sql = <<-SQL.strip_heredoc
113
- INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
114
- SELECT 'Model' AS searchable_type,
115
- #{Model.quoted_table_name}.#{Model.primary_key} AS searchable_id,
116
- (
117
- coalesce(#{Model.quoted_table_name}."name"::text, '')
118
- ) AS content,
119
- '#{expected_timestamp}' AS created_at,
120
- '#{expected_timestamp}' AS updated_at
121
- FROM #{Model.quoted_table_name}
114
+ rebuilder = described_class.new(Model, -> { time })
115
+
116
+ expected_sql = <<~SQL.squish
117
+ INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
118
+ SELECT 'Model' AS searchable_type,
119
+ #{Model.quoted_table_name}.#{Model.primary_key} AS searchable_id,
120
+ (
121
+ coalesce(#{Model.quoted_table_name}."name"::text, '')
122
+ ) AS content,
123
+ '2001-01-01 00:00:00' AS created_at,
124
+ '2001-01-01 00:00:00' AS updated_at
125
+ FROM #{Model.quoted_table_name}
122
126
  SQL
123
127
 
124
128
  executed_sql = []
@@ -133,8 +137,9 @@ describe PgSearch::Multisearch::Rebuilder do
133
137
  expect(executed_sql.length).to eq(1)
134
138
  expect(executed_sql.first.strip).to eq(expected_sql.strip)
135
139
  end
140
+ # rubocop:enable RSpec/ExampleLength
136
141
 
137
- context "for a model with a camel case column" do
142
+ context "with a model with a camel case column" do
138
143
  with_model :ModelWithCamelCaseColumn do
139
144
  table do |t|
140
145
  t.string :camelName
@@ -148,12 +153,12 @@ describe PgSearch::Multisearch::Rebuilder do
148
153
 
149
154
  it "creates search document without PG error" do
150
155
  time = Time.utc(2001, 1, 1, 0, 0, 0)
151
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model, -> { time })
156
+ rebuilder = described_class.new(Model, -> { time })
152
157
  rebuilder.rebuild
153
158
  end
154
159
  end
155
160
 
156
- context "for a model with a non-standard primary key" do
161
+ context "with a model with a non-standard primary key" do
157
162
  with_model :ModelWithNonStandardPrimaryKey do
158
163
  table primary_key: :non_standard_primary_key do |t|
159
164
  t.string :name
@@ -165,24 +170,21 @@ describe PgSearch::Multisearch::Rebuilder do
165
170
  end
166
171
  end
167
172
 
173
+ # rubocop:disable RSpec/ExampleLength
168
174
  it "generates SQL with the correct primary key" do
169
175
  time = Time.utc(2001, 1, 1, 0, 0, 0)
170
- rebuilder = PgSearch::Multisearch::Rebuilder.new(ModelWithNonStandardPrimaryKey, -> { time })
171
-
172
- # Handle change in precision of Time objects in SQL in Active Record 4.0.1
173
- # https://github.com/rails/rails/commit/17f5d8e062909f1fcae25351834d8e89967b645e
174
- expected_timestamp = has_microsecond_precision? ? "2001-01-01 00:00:00.000000" : "2001-01-01 00:00:00"
175
-
176
- expected_sql = <<-SQL.strip_heredoc
177
- INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
178
- SELECT 'ModelWithNonStandardPrimaryKey' AS searchable_type,
179
- #{ModelWithNonStandardPrimaryKey.quoted_table_name}.non_standard_primary_key AS searchable_id,
180
- (
181
- coalesce(#{ModelWithNonStandardPrimaryKey.quoted_table_name}."name"::text, '')
182
- ) AS content,
183
- '#{expected_timestamp}' AS created_at,
184
- '#{expected_timestamp}' AS updated_at
185
- FROM #{ModelWithNonStandardPrimaryKey.quoted_table_name}
176
+ rebuilder = described_class.new(ModelWithNonStandardPrimaryKey, -> { time })
177
+
178
+ expected_sql = <<~SQL.squish
179
+ INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
180
+ SELECT 'ModelWithNonStandardPrimaryKey' AS searchable_type,
181
+ #{ModelWithNonStandardPrimaryKey.quoted_table_name}.non_standard_primary_key AS searchable_id,
182
+ (
183
+ coalesce(#{ModelWithNonStandardPrimaryKey.quoted_table_name}."name"::text, '')
184
+ ) AS content,
185
+ '2001-01-01 00:00:00' AS created_at,
186
+ '2001-01-01 00:00:00' AS updated_at
187
+ FROM #{ModelWithNonStandardPrimaryKey.quoted_table_name}
186
188
  SQL
187
189
 
188
190
  executed_sql = []
@@ -197,14 +199,12 @@ describe PgSearch::Multisearch::Rebuilder do
197
199
  expect(executed_sql.length).to eq(1)
198
200
  expect(executed_sql.first.strip).to eq(expected_sql.strip)
199
201
  end
202
+ # rubocop:enable RSpec/ExampleLength
200
203
  end
201
204
  end
202
205
 
203
206
  context "when :against includes non-column dynamic methods" do
204
207
  with_model :Model do
205
- table do
206
- end
207
-
208
208
  model do
209
209
  include PgSearch::Model
210
210
  multisearchable against: [:foo]
@@ -215,10 +215,11 @@ describe PgSearch::Multisearch::Rebuilder do
215
215
  end
216
216
  end
217
217
 
218
+ # rubocop:disable RSpec/ExampleLength
218
219
  it "calls update_pg_search_document on each record" do
219
220
  record = Model.create!
220
221
 
221
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
222
+ rebuilder = described_class.new(Model)
222
223
 
223
224
  # stub respond_to? to return false since should_not_receive defines the method
224
225
  original_respond_to = Model.method(:respond_to?)
@@ -229,16 +230,49 @@ describe PgSearch::Multisearch::Rebuilder do
229
230
  original_respond_to.call(method_name, *args)
230
231
  end
231
232
  end
232
- expect(Model).not_to receive(:rebuild_pg_search_documents)
233
233
 
234
- rebuilder.rebuild
234
+ without_partial_double_verification do
235
+ allow(Model).to receive(:rebuild_pg_search_documents)
236
+
237
+ rebuilder.rebuild
238
+
239
+ expect(Model).not_to have_received(:rebuild_pg_search_documents)
240
+ end
235
241
 
236
242
  expect(record.pg_search_document).to be_present
237
243
  end
244
+ # rubocop:enable RSpec/ExampleLength
245
+ end
246
+
247
+ context "when only additional_attributes is set" do
248
+ with_model :Model do
249
+ table do |t|
250
+ t.string :name
251
+ end
252
+
253
+ model do
254
+ include PgSearch::Model
255
+ multisearchable against: :name,
256
+ additional_attributes: ->(obj) { { additional_attribute_column: "#{obj.class}::#{obj.id}" } }
257
+ end
258
+ end
259
+
260
+ it "calls update_pg_search_document on each record" do
261
+ record_1 = Model.create!(name: "record_1", id: 1)
262
+ record_2 = Model.create!(name: "record_2", id: 2)
263
+
264
+ PgSearch::Document.delete_all
265
+
266
+ rebuilder = described_class.new(Model)
267
+ rebuilder.rebuild
268
+
269
+ expect(record_1.reload.pg_search_document.additional_attribute_column).to eq("Model::1")
270
+ expect(record_2.reload.pg_search_document.additional_attribute_column).to eq("Model::2")
271
+ end
238
272
  end
239
273
  end
240
274
 
241
- context "and multisearchable is conditional" do
275
+ context "when multisearchable is conditional" do
242
276
  context "via :if" do
243
277
  with_model :Model do
244
278
  table do |t|
@@ -251,11 +285,12 @@ describe PgSearch::Multisearch::Rebuilder do
251
285
  end
252
286
  end
253
287
 
288
+ # rubocop:disable RSpec/ExampleLength
254
289
  it "calls update_pg_search_document on each record" do
255
290
  record_1 = Model.create!(active: true)
256
291
  record_2 = Model.create!(active: false)
257
292
 
258
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
293
+ rebuilder = described_class.new(Model)
259
294
 
260
295
  # stub respond_to? to return false since should_not_receive defines the method
261
296
  original_respond_to = Model.method(:respond_to?)
@@ -266,13 +301,17 @@ describe PgSearch::Multisearch::Rebuilder do
266
301
  original_respond_to.call(method_name, *args)
267
302
  end
268
303
  end
269
- expect(Model).not_to receive(:rebuild_pg_search_documents)
270
304
 
271
- rebuilder.rebuild
305
+ without_partial_double_verification do
306
+ allow(Model).to receive(:rebuild_pg_search_documents)
307
+ rebuilder.rebuild
308
+ expect(Model).not_to have_received(:rebuild_pg_search_documents)
309
+ end
272
310
 
273
311
  expect(record_1.pg_search_document).to be_present
274
312
  expect(record_2.pg_search_document).not_to be_present
275
313
  end
314
+ # rubocop:enable RSpec/ExampleLength
276
315
  end
277
316
 
278
317
  context "via :unless" do
@@ -287,11 +326,12 @@ describe PgSearch::Multisearch::Rebuilder do
287
326
  end
288
327
  end
289
328
 
329
+ # rubocop:disable RSpec/ExampleLength
290
330
  it "calls update_pg_search_document on each record" do
291
331
  record_1 = Model.create!(inactive: true)
292
332
  record_2 = Model.create!(inactive: false)
293
333
 
294
- rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
334
+ rebuilder = described_class.new(Model)
295
335
 
296
336
  # stub respond_to? to return false since should_not_receive defines the method
297
337
  original_respond_to = Model.method(:respond_to?)
@@ -302,15 +342,20 @@ describe PgSearch::Multisearch::Rebuilder do
302
342
  original_respond_to.call(method_name, *args)
303
343
  end
304
344
  end
305
- expect(Model).not_to receive(:rebuild_pg_search_documents)
306
345
 
307
- rebuilder.rebuild
346
+ without_partial_double_verification do
347
+ allow(Model).to receive(:rebuild_pg_search_documents)
348
+ rebuilder.rebuild
349
+ expect(Model).not_to have_received(:rebuild_pg_search_documents)
350
+ end
308
351
 
309
352
  expect(record_1.pg_search_document).not_to be_present
310
353
  expect(record_2.pg_search_document).to be_present
311
354
  end
355
+ # rubocop:enable RSpec/ExampleLength
312
356
  end
313
357
  end
314
358
  end
315
359
  end
316
360
  end
361
+ # rubocop:enable RSpec/NestedGroups