pg_search 2.3.0 → 2.3.5

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.
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