pg_search 2.1.2 → 2.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +1 -0
  3. data/.editorconfig +10 -0
  4. data/.github/dependabot.yml +11 -0
  5. data/.github/workflows/ci.yml +75 -0
  6. data/.jrubyrc +1 -0
  7. data/.rubocop.yml +95 -10
  8. data/.travis.yml +26 -48
  9. data/CHANGELOG.md +179 -112
  10. data/CODE_OF_CONDUCT.md +76 -0
  11. data/CONTRIBUTING.md +5 -3
  12. data/Gemfile +6 -4
  13. data/LICENSE +1 -1
  14. data/README.md +307 -198
  15. data/Rakefile +7 -3
  16. data/lib/pg_search/configuration/association.rb +2 -0
  17. data/lib/pg_search/configuration/column.rb +2 -0
  18. data/lib/pg_search/configuration/foreign_column.rb +2 -0
  19. data/lib/pg_search/configuration.rb +20 -6
  20. data/lib/pg_search/document.rb +7 -5
  21. data/lib/pg_search/features/dmetaphone.rb +7 -7
  22. data/lib/pg_search/features/feature.rb +4 -2
  23. data/lib/pg_search/features/trigram.rb +31 -5
  24. data/lib/pg_search/features/tsearch.rb +18 -14
  25. data/lib/pg_search/features.rb +2 -0
  26. data/lib/pg_search/migration/dmetaphone_generator.rb +3 -1
  27. data/lib/pg_search/migration/generator.rb +4 -2
  28. data/lib/pg_search/migration/multisearch_generator.rb +2 -1
  29. data/lib/pg_search/migration/templates/add_pg_search_dmetaphone_support_functions.rb.erb +6 -6
  30. data/lib/pg_search/migration/templates/create_pg_search_documents.rb.erb +3 -3
  31. data/lib/pg_search/model.rb +57 -0
  32. data/lib/pg_search/multisearch/rebuilder.rb +14 -6
  33. data/lib/pg_search/multisearch.rb +23 -6
  34. data/lib/pg_search/multisearchable.rb +10 -6
  35. data/lib/pg_search/normalizer.rb +2 -0
  36. data/lib/pg_search/railtie.rb +2 -0
  37. data/lib/pg_search/scope_options.rb +26 -49
  38. data/lib/pg_search/tasks.rb +5 -1
  39. data/lib/pg_search/version.rb +3 -1
  40. data/lib/pg_search.rb +17 -55
  41. data/pg_search.gemspec +19 -11
  42. data/spec/.rubocop.yml +2 -2
  43. data/spec/integration/.rubocop.yml +11 -0
  44. data/spec/integration/associations_spec.rb +125 -162
  45. data/spec/integration/deprecation_spec.rb +33 -0
  46. data/spec/integration/pagination_spec.rb +10 -8
  47. data/spec/integration/pg_search_spec.rb +359 -306
  48. data/spec/integration/single_table_inheritance_spec.rb +18 -17
  49. data/spec/lib/pg_search/configuration/association_spec.rb +17 -13
  50. data/spec/lib/pg_search/configuration/column_spec.rb +2 -0
  51. data/spec/lib/pg_search/configuration/foreign_column_spec.rb +6 -4
  52. data/spec/lib/pg_search/features/dmetaphone_spec.rb +6 -4
  53. data/spec/lib/pg_search/features/trigram_spec.rb +51 -20
  54. data/spec/lib/pg_search/features/tsearch_spec.rb +29 -21
  55. data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +151 -85
  56. data/spec/lib/pg_search/multisearch_spec.rb +67 -37
  57. data/spec/lib/pg_search/multisearchable_spec.rb +217 -123
  58. data/spec/lib/pg_search/normalizer_spec.rb +14 -10
  59. data/spec/lib/pg_search_spec.rb +102 -89
  60. data/spec/spec_helper.rb +25 -6
  61. data/spec/support/database.rb +19 -21
  62. data/spec/support/with_model.rb +2 -0
  63. metadata +106 -29
  64. data/.autotest +0 -5
  65. data/.rubocop_todo.yml +0 -163
  66. data/Guardfile +0 -6
@@ -1,14 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
5
+ # rubocop:disable RSpec/NestedGroups
3
6
  describe PgSearch::Normalizer do
4
7
  describe "#add_normalization" do
5
8
  context "when config[:ignore] includes :accents" do
6
9
  context "when passed an Arel node" do
7
10
  it "wraps the expression in unaccent()" do
8
- config = double("config", :ignore => [:accents])
11
+ config = instance_double("PgSearch::Configuration", "config", ignore: [:accents])
9
12
  node = Arel::Nodes::NamedFunction.new("foo", [Arel::Nodes.build_quoted("bar")])
10
13
 
11
- normalizer = PgSearch::Normalizer.new(config)
14
+ normalizer = described_class.new(config)
12
15
  expect(normalizer.add_normalization(node)).to eq("unaccent(foo('bar'))")
13
16
  end
14
17
 
@@ -17,9 +20,9 @@ describe PgSearch::Normalizer do
17
20
  allow(PgSearch).to receive(:unaccent_function).and_return("my_unaccent")
18
21
  node = Arel::Nodes::NamedFunction.new("foo", [Arel::Nodes.build_quoted("bar")])
19
22
 
20
- config = double("config", :ignore => [:accents])
23
+ config = instance_double("PgSearch::Configuration", "config", ignore: [:accents])
21
24
 
22
- normalizer = PgSearch::Normalizer.new(config)
25
+ normalizer = described_class.new(config)
23
26
  expect(normalizer.add_normalization(node)).to eq("my_unaccent(foo('bar'))")
24
27
  end
25
28
  end
@@ -27,9 +30,9 @@ describe PgSearch::Normalizer do
27
30
 
28
31
  context "when passed a String" do
29
32
  it "wraps the expression in unaccent()" do
30
- config = double("config", :ignore => [:accents])
33
+ config = instance_double("PgSearch::Configuration", "config", ignore: [:accents])
31
34
 
32
- normalizer = PgSearch::Normalizer.new(config)
35
+ normalizer = described_class.new(config)
33
36
  expect(normalizer.add_normalization("foo")).to eq("unaccent(foo)")
34
37
  end
35
38
 
@@ -37,9 +40,9 @@ describe PgSearch::Normalizer do
37
40
  it "wraps the expression in that function" do
38
41
  allow(PgSearch).to receive(:unaccent_function).and_return("my_unaccent")
39
42
 
40
- config = double("config", :ignore => [:accents])
43
+ config = instance_double("PgSearch::Configuration", "config", ignore: [:accents])
41
44
 
42
- normalizer = PgSearch::Normalizer.new(config)
45
+ normalizer = described_class.new(config)
43
46
  expect(normalizer.add_normalization("foo")).to eq("my_unaccent(foo)")
44
47
  end
45
48
  end
@@ -48,11 +51,12 @@ describe PgSearch::Normalizer do
48
51
 
49
52
  context "when config[:ignore] does not include :accents" do
50
53
  it "passes the expression through" do
51
- config = double("config", :ignore => [])
54
+ config = instance_double("PgSearch::Configuration", "config", ignore: [])
52
55
 
53
- normalizer = PgSearch::Normalizer.new(config)
56
+ normalizer = described_class.new(config)
54
57
  expect(normalizer.add_normalization("foo")).to eq("foo")
55
58
  end
56
59
  end
57
60
  end
58
61
  end
62
+ # rubocop:enable RSpec/NestedGroups
@@ -1,69 +1,73 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
- # For AR 5 and greater, the association reflection's cache needs be cleared
5
+ # For Active Record 5.x, the association reflection's cache needs be cleared
4
6
  # because we're stubbing the related constants.
5
- class << PgSearch::Document
6
- if ActiveRecord::VERSION::MAJOR >= 5
7
- def clear_searchable_cache
8
- reflect_on_association(:searchable).clear_association_scope_cache
9
- end
10
- else
11
- def clear_searchable_cache
12
- end
7
+ if ActiveRecord::VERSION::MAJOR == 5
8
+ def clear_searchable_cache
9
+ PgSearch::Document.reflect_on_association(:searchable).clear_association_scope_cache
10
+ end
11
+ else
12
+ def clear_searchable_cache
13
13
  end
14
14
  end
15
15
 
16
+ # rubocop:disable RSpec/NestedGroups
16
17
  describe PgSearch do
17
18
  describe ".multisearch" do
18
- with_table "pg_search_documents", {}, &DOCUMENTS_SCHEMA
19
+ with_table "pg_search_documents", &DOCUMENTS_SCHEMA
19
20
 
20
21
  describe "delegation to PgSearch::Document.search" do
21
- subject { PgSearch.multisearch(query) }
22
+ subject { described_class.multisearch(query) }
23
+
24
+ let(:query) { instance_double("String", "query") }
25
+ let(:relation) { instance_double("ActiveRecord::Relation", "relation") }
22
26
 
23
- let(:query) { double(:query) }
24
- let(:relation) { double(:relation) }
25
27
  before do
26
- expect(PgSearch::Document).to receive(:search).with(query).and_return(relation)
28
+ allow(PgSearch::Document).to receive(:search).with(query).and_return(relation)
27
29
  end
28
30
 
29
31
  it { is_expected.to eq(relation) }
30
32
  end
31
33
 
32
34
  context "with PgSearch.multisearch_options set to a Hash" do
33
- before { allow(PgSearch).to receive(:multisearch_options).and_return(:using => :dmetaphone) }
34
35
  subject do
35
- PgSearch::Document.clear_searchable_cache
36
- PgSearch.multisearch(query).map(&:searchable)
36
+ clear_searchable_cache
37
+ described_class.multisearch(query).map(&:searchable)
37
38
  end
38
39
 
40
+ before { allow(described_class).to receive(:multisearch_options).and_return(using: :dmetaphone) }
41
+
39
42
  with_model :MultisearchableModel do
40
43
  table do |t|
41
44
  t.string :title
42
45
  end
43
46
  model do
44
- include PgSearch
45
- multisearchable :against => :title
47
+ include PgSearch::Model
48
+ multisearchable against: :title
46
49
  end
47
50
  end
48
51
 
49
- let!(:soundalike_record) { MultisearchableModel.create!(:title => 'foning') }
52
+ let!(:soundalike_record) { MultisearchableModel.create!(title: 'foning') }
50
53
  let(:query) { "Phoning" }
54
+
51
55
  it { is_expected.to include(soundalike_record) }
52
56
  end
53
57
 
54
58
  context "with PgSearch.multisearch_options set to a Proc" do
55
59
  subject do
56
- PgSearch::Document.clear_searchable_cache
57
- PgSearch.multisearch(query, soundalike).map(&:searchable)
60
+ clear_searchable_cache
61
+ described_class.multisearch(query, soundalike).map(&:searchable)
58
62
  end
59
63
 
60
64
  before do
61
- allow(PgSearch).to receive(:multisearch_options) do
65
+ allow(described_class).to receive(:multisearch_options) do
62
66
  lambda do |query, soundalike|
63
67
  if soundalike
64
- {:using => :dmetaphone, :query => query}
68
+ { using: :dmetaphone, query: query }
65
69
  else
66
- {:query => query}
70
+ { query: query }
67
71
  end
68
72
  end
69
73
  end
@@ -74,26 +78,28 @@ describe PgSearch do
74
78
  t.string :title
75
79
  end
76
80
  model do
77
- include PgSearch
78
- multisearchable :against => :title
81
+ include PgSearch::Model
82
+ multisearchable against: :title
79
83
  end
80
84
  end
81
85
 
82
- let!(:soundalike_record) { MultisearchableModel.create!(:title => 'foning') }
86
+ let!(:soundalike_record) { MultisearchableModel.create!(title: 'foning') }
83
87
  let(:query) { "Phoning" }
84
88
 
85
89
  context "with soundalike true" do
86
90
  let(:soundalike) { true }
91
+
87
92
  it { is_expected.to include(soundalike_record) }
88
93
  end
89
94
 
90
95
  context "with soundalike false" do
91
96
  let(:soundalike) { false }
97
+
92
98
  it { is_expected.not_to include(soundalike_record) }
93
99
  end
94
100
  end
95
101
 
96
- context "on an STI subclass" do
102
+ context "when on an STI subclass" do
97
103
  context "with standard type column" do
98
104
  with_model :SuperclassModel do
99
105
  table do |t|
@@ -104,8 +110,8 @@ describe PgSearch do
104
110
 
105
111
  before do
106
112
  searchable_subclass_model = Class.new(SuperclassModel) do
107
- include PgSearch
108
- multisearchable :against => :content
113
+ include PgSearch::Model
114
+ multisearchable against: :content
109
115
  end
110
116
  stub_const("SearchableSubclassModel", searchable_subclass_model)
111
117
  stub_const("AnotherSearchableSubclassModel", searchable_subclass_model)
@@ -113,43 +119,44 @@ describe PgSearch do
113
119
  end
114
120
 
115
121
  it "returns only results for that subclass" do
116
- included = SearchableSubclassModel.create!(:content => "foo bar")
122
+ included = SearchableSubclassModel.create!(content: "foo bar")
117
123
 
118
- SearchableSubclassModel.create!(:content => "baz")
119
- SuperclassModel.create!(:content => "foo bar")
120
- SuperclassModel.create!(:content => "baz")
121
- NonSearchableSubclassModel.create!(:content => "foo bar")
122
- NonSearchableSubclassModel.create!(:content => "baz")
124
+ SearchableSubclassModel.create!(content: "baz")
125
+ SuperclassModel.create!(content: "foo bar")
126
+ SuperclassModel.create!(content: "baz")
127
+ NonSearchableSubclassModel.create!(content: "foo bar")
128
+ NonSearchableSubclassModel.create!(content: "baz")
123
129
 
124
130
  expect(SuperclassModel.count).to be 6
125
131
  expect(SearchableSubclassModel.count).to be 2
126
132
 
127
133
  expect(PgSearch::Document.count).to be 2
128
134
 
129
- results = PgSearch.multisearch("foo bar")
135
+ results = described_class.multisearch("foo bar")
130
136
 
131
137
  expect(results).to eq [included.pg_search_document]
132
138
  end
133
139
 
134
140
  it "updates an existing STI model does not create a new pg_search document" do
135
- model = SearchableSubclassModel.create!(:content => "foo bar")
141
+ model = SearchableSubclassModel.create!(content: "foo bar")
136
142
  expect(SearchableSubclassModel.count).to eq(1)
137
143
  # We fetch the model from the database again otherwise
138
144
  # the pg_search_document from the cache is used.
139
145
  model = SearchableSubclassModel.find(model.id)
140
146
  model.content = "foo"
141
147
  model.save!
142
- results = PgSearch.multisearch("foo")
148
+ results = described_class.multisearch("foo")
143
149
  expect(results.size).to eq(SearchableSubclassModel.count)
144
150
  end
145
151
 
146
- it "reindexing works" do
147
- NonSearchableSubclassModel.create!(:content => "foo bar")
148
- NonSearchableSubclassModel.create!(:content => "baz")
149
- expected = SearchableSubclassModel.create!(:content => "baz")
150
- SuperclassModel.create!(:content => "foo bar")
151
- SuperclassModel.create!(:content => "baz")
152
- SuperclassModel.create!(:content => "baz2")
152
+ # rubocop:disable RSpec/MultipleExpectations
153
+ specify "reindexing works" do
154
+ NonSearchableSubclassModel.create!(content: "foo bar")
155
+ NonSearchableSubclassModel.create!(content: "baz")
156
+ expected = SearchableSubclassModel.create!(content: "baz")
157
+ SuperclassModel.create!(content: "foo bar")
158
+ SuperclassModel.create!(content: "baz")
159
+ SuperclassModel.create!(content: "baz2")
153
160
 
154
161
  expect(SuperclassModel.count).to be 6
155
162
  expect(NonSearchableSubclassModel.count).to be 2
@@ -159,22 +166,23 @@ describe PgSearch do
159
166
 
160
167
  PgSearch::Multisearch.rebuild(SearchableSubclassModel)
161
168
 
162
- PgSearch::Document.clear_searchable_cache
169
+ clear_searchable_cache
163
170
  expect(PgSearch::Document.count).to be 1
164
171
  expect(PgSearch::Document.first.searchable.class).to be SearchableSubclassModel
165
172
  expect(PgSearch::Document.first.searchable).to eq expected
166
173
  end
174
+ # rubocop:enable RSpec/MultipleExpectations
167
175
 
168
176
  it "reindexing searchable STI doesn't clobber other related STI models" do
169
- SearchableSubclassModel.create!(:content => "baz")
170
- AnotherSearchableSubclassModel.create!(:content => "baz")
177
+ SearchableSubclassModel.create!(content: "baz")
178
+ AnotherSearchableSubclassModel.create!(content: "baz")
171
179
 
172
180
  expect(PgSearch::Document.count).to be 2
173
181
  PgSearch::Multisearch.rebuild(SearchableSubclassModel)
174
182
  expect(PgSearch::Document.count).to be 2
175
183
 
176
- PgSearch::Document.clear_searchable_cache
177
- classes = PgSearch::Document.all.collect {|d| d.searchable.class }
184
+ clear_searchable_cache
185
+ classes = PgSearch::Document.all.collect { |d| d.searchable.class }
178
186
  expect(classes).to include SearchableSubclassModel
179
187
  expect(classes).to include AnotherSearchableSubclassModel
180
188
  end
@@ -194,8 +202,8 @@ describe PgSearch do
194
202
 
195
203
  before do
196
204
  searchable_subclass_model = Class.new(SuperclassModel) do
197
- include PgSearch
198
- multisearchable :against => :content
205
+ include PgSearch::Model
206
+ multisearchable against: :content
199
207
  end
200
208
  stub_const("SearchableSubclassModel", searchable_subclass_model)
201
209
  stub_const("AnotherSearchableSubclassModel", searchable_subclass_model)
@@ -203,20 +211,20 @@ describe PgSearch do
203
211
  end
204
212
 
205
213
  it "returns only results for that subclass" do
206
- included = SearchableSubclassModel.create!(:content => "foo bar")
214
+ included = SearchableSubclassModel.create!(content: "foo bar")
207
215
 
208
- SearchableSubclassModel.create!(:content => "baz")
209
- SuperclassModel.create!(:content => "foo bar")
210
- SuperclassModel.create!(:content => "baz")
211
- NonSearchableSubclassModel.create!(:content => "foo bar")
212
- NonSearchableSubclassModel.create!(:content => "baz")
216
+ SearchableSubclassModel.create!(content: "baz")
217
+ SuperclassModel.create!(content: "foo bar")
218
+ SuperclassModel.create!(content: "baz")
219
+ NonSearchableSubclassModel.create!(content: "foo bar")
220
+ NonSearchableSubclassModel.create!(content: "baz")
213
221
 
214
222
  expect(SuperclassModel.count).to be 6
215
223
  expect(SearchableSubclassModel.count).to be 2
216
224
 
217
225
  expect(PgSearch::Document.count).to be 2
218
226
 
219
- results = PgSearch.multisearch("foo bar")
227
+ results = described_class.multisearch("foo bar")
220
228
 
221
229
  expect(results).to eq [included.pg_search_document]
222
230
  end
@@ -225,57 +233,62 @@ describe PgSearch do
225
233
  end
226
234
 
227
235
  describe ".disable_multisearch" do
228
- it "should temporarily disable multisearch" do
229
- @multisearch_enabled_before = PgSearch.multisearch_enabled?
230
- PgSearch.disable_multisearch do
231
- @multisearch_enabled_inside = PgSearch.multisearch_enabled?
236
+ it "disables multisearch temporarily" do
237
+ multisearch_enabled_before = described_class.multisearch_enabled?
238
+ multisearch_enabled_inside = nil
239
+ described_class.disable_multisearch do
240
+ multisearch_enabled_inside = described_class.multisearch_enabled?
232
241
  end
233
- @multisearch_enabled_after = PgSearch.multisearch_enabled?
242
+ multisearch_enabled_after = described_class.multisearch_enabled?
234
243
 
235
- expect(@multisearch_enabled_before).to be(true)
236
- expect(@multisearch_enabled_inside).to be(false)
237
- expect(@multisearch_enabled_after).to be(true)
244
+ expect(multisearch_enabled_before).to be(true)
245
+ expect(multisearch_enabled_inside).to be(false)
246
+ expect(multisearch_enabled_after).to be(true)
238
247
  end
239
248
 
240
- it "should reenable multisearch after an error" do
241
- @multisearch_enabled_before = PgSearch.multisearch_enabled?
249
+ it "reenables multisearch after an error" do
250
+ multisearch_enabled_before = described_class.multisearch_enabled?
251
+ multisearch_enabled_inside = nil
242
252
  begin
243
- PgSearch.disable_multisearch do
244
- @multisearch_enabled_inside = PgSearch.multisearch_enabled?
253
+ described_class.disable_multisearch do
254
+ multisearch_enabled_inside = described_class.multisearch_enabled?
245
255
  raise
246
256
  end
247
257
  rescue StandardError
248
258
  end
259
+ multisearch_enabled_after = described_class.multisearch_enabled?
249
260
 
250
- @multisearch_enabled_after = PgSearch.multisearch_enabled?
251
-
252
- expect(@multisearch_enabled_before).to be(true)
253
- expect(@multisearch_enabled_inside).to be(false)
254
- expect(@multisearch_enabled_after).to be(true)
261
+ expect(multisearch_enabled_before).to be(true)
262
+ expect(multisearch_enabled_inside).to be(false)
263
+ expect(multisearch_enabled_after).to be(true)
255
264
  end
256
265
 
257
- it "should not disable multisearch on other threads" do
266
+ # rubocop:disable RSpec/ExampleLength
267
+ it "does not disable multisearch on other threads" do
258
268
  values = Queue.new
259
269
  sync = Queue.new
260
270
  Thread.new do
261
- values.push PgSearch.multisearch_enabled?
271
+ values.push described_class.multisearch_enabled?
262
272
  sync.pop # wait
263
- values.push PgSearch.multisearch_enabled?
273
+ values.push described_class.multisearch_enabled?
264
274
  sync.pop # wait
265
- values.push PgSearch.multisearch_enabled?
275
+ values.push described_class.multisearch_enabled?
266
276
  end
267
277
 
268
- @multisearch_enabled_before = values.pop
269
- PgSearch.disable_multisearch do
278
+ multisearch_enabled_before = values.pop
279
+ multisearch_enabled_inside = nil
280
+ described_class.disable_multisearch do
270
281
  sync.push :go
271
- @multisearch_enabled_inside = values.pop
282
+ multisearch_enabled_inside = values.pop
272
283
  end
273
284
  sync.push :go
274
- @multisearch_enabled_after = values.pop
285
+ multisearch_enabled_after = values.pop
275
286
 
276
- expect(@multisearch_enabled_before).to be(true)
277
- expect(@multisearch_enabled_inside).to be(true)
278
- expect(@multisearch_enabled_after).to be(true)
287
+ expect(multisearch_enabled_before).to be(true)
288
+ expect(multisearch_enabled_inside).to be(true)
289
+ expect(multisearch_enabled_after).to be(true)
279
290
  end
291
+ # rubocop:enable RSpec/ExampleLength
280
292
  end
281
293
  end
294
+ # rubocop:enable RSpec/NestedGroups
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'warning'
4
+ # Ignore Ruby 2.7 warnings from Active Record
5
+ Warning.ignore :keyword_separation
6
+
7
+ # https://github.com/grodowski/undercover#setting-up-required-lcov-reporting
1
8
  require 'simplecov'
2
- SimpleCov.start
9
+ require 'simplecov-lcov'
10
+ SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
11
+ SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
12
+ SimpleCov.start do
13
+ add_filter(%r{^/spec/})
14
+ enable_coverage(:branch)
15
+ end
16
+ require 'undercover'
3
17
 
4
18
  require "bundler/setup"
5
19
  require "pg_search"
6
20
 
7
21
  RSpec.configure do |config|
8
- config.expect_with :rspec do |c|
9
- c.syntax = :expect
22
+ config.expect_with :rspec do |expects|
23
+ expects.syntax = :expect
10
24
  end
11
25
 
12
- config.mock_with :rspec do |c|
13
- c.syntax = :expect
26
+ config.mock_with :rspec do |mocks|
27
+ mocks.syntax = :expect
28
+ mocks.verify_doubled_constant_names = true
29
+ mocks.verify_partial_doubles = true
14
30
  end
15
31
 
16
32
  config.example_status_persistence_file_path = 'tmp/examples.txt'
@@ -20,7 +36,10 @@ require 'support/database'
20
36
  require 'support/with_model'
21
37
 
22
38
  DOCUMENTS_SCHEMA = lambda do |t|
23
- t.belongs_to :searchable, :polymorphic => true, :index => true
39
+ t.belongs_to :searchable, polymorphic: true, index: true
24
40
  t.text :content
25
41
  t.timestamps null: false
42
+
43
+ # Used to test additional_attributes setup
44
+ t.text :additional_attribute_column
26
45
  end
@@ -1,27 +1,24 @@
1
- if defined? JRUBY_VERSION
1
+ # frozen_string_literal: true
2
+
3
+ case RUBY_PLATFORM
4
+ when "java"
2
5
  require "activerecord-jdbc-adapter"
3
- error_classes = [ActiveRecord::JDBCError]
6
+ ERROR_CLASS = ActiveRecord::JDBCError
4
7
  else
5
8
  require "pg"
6
- error_classes = [PG::Error]
9
+ ERROR_CLASS = PG::Error
7
10
  end
8
11
 
9
- error_classes << ActiveRecord::NoDatabaseError if defined? ActiveRecord::NoDatabaseError
10
-
11
12
  begin
12
- database_user = if ENV["TRAVIS"]
13
- "postgres"
14
- else
15
- ENV["USER"]
16
- end
17
-
18
- ActiveRecord::Base.establish_connection(:adapter => 'postgresql',
19
- :database => 'pg_search_test',
20
- :username => database_user,
21
- :min_messages => 'warning')
13
+ connection_options = { adapter: 'postgresql', database: 'pg_search_test', min_messages: 'warning' }
14
+ if ENV["CI"]
15
+ connection_options[:username] = 'postgres'
16
+ connection_options[:password] = 'postgres'
17
+ end
18
+ ActiveRecord::Base.establish_connection(connection_options)
22
19
  connection = ActiveRecord::Base.connection
23
20
  connection.execute("SELECT 1")
24
- rescue *error_classes => exception
21
+ rescue ERROR_CLASS, ActiveRecord::NoDatabaseError => e
25
22
  at_exit do
26
23
  puts "-" * 80
27
24
  puts "Unable to connect to database. Please run:"
@@ -29,31 +26,32 @@ rescue *error_classes => exception
29
26
  puts " createdb pg_search_test"
30
27
  puts "-" * 80
31
28
  end
32
- raise exception
29
+ raise e
33
30
  end
34
31
 
35
32
  if ENV["LOGGER"]
36
33
  require "logger"
37
- ActiveRecord::Base.logger = Logger.new(STDOUT)
34
+ ActiveRecord::Base.logger = Logger.new($stdout)
38
35
  end
39
36
 
40
37
  def install_extension(name)
41
38
  connection = ActiveRecord::Base.connection
42
39
  extension = connection.execute "SELECT * FROM pg_catalog.pg_extension WHERE extname = '#{name}';"
43
40
  return unless extension.none?
41
+
44
42
  connection.execute "CREATE EXTENSION #{name};"
45
- rescue StandardError => exception
43
+ rescue StandardError => e
46
44
  at_exit do
47
45
  puts "-" * 80
48
46
  puts "Please install the #{name} extension"
49
47
  puts "-" * 80
50
48
  end
51
- raise exception
49
+ raise e
52
50
  end
53
51
 
54
52
  def install_extension_if_missing(name, query, expected_result)
55
53
  result = ActiveRecord::Base.connection.select_value(query)
56
- raise "Unexpected output for #{query}: #{result.inspect}" unless result.downcase == expected_result.downcase
54
+ raise "Unexpected output for #{query}: #{result.inspect}" unless result.casecmp(expected_result).zero?
57
55
  rescue StandardError
58
56
  install_extension(name)
59
57
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "with_model"
2
4
 
3
5
  RSpec.configure do |config|