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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +47 -35
  3. data/.github/workflows/codeql.yml +87 -0
  4. data/.standard.yml +6 -0
  5. data/CHANGELOG.md +23 -0
  6. data/Gemfile +21 -6
  7. data/LICENSE +1 -1
  8. data/README.md +133 -114
  9. data/Rakefile +4 -13
  10. data/lib/pg_search/configuration/column.rb +6 -4
  11. data/lib/pg_search/configuration/foreign_column.rb +1 -1
  12. data/lib/pg_search/configuration.rb +11 -27
  13. data/lib/pg_search/document.rb +8 -8
  14. data/lib/pg_search/features/dmetaphone.rb +1 -1
  15. data/lib/pg_search/features/trigram.rb +4 -4
  16. data/lib/pg_search/features/tsearch.rb +23 -30
  17. data/lib/pg_search/migration/dmetaphone_generator.rb +2 -2
  18. data/lib/pg_search/migration/generator.rb +5 -5
  19. data/lib/pg_search/migration/multisearch_generator.rb +2 -2
  20. data/lib/pg_search/model.rb +12 -14
  21. data/lib/pg_search/multisearch/rebuilder.rb +4 -3
  22. data/lib/pg_search/multisearch.rb +4 -2
  23. data/lib/pg_search/multisearchable.rb +7 -7
  24. data/lib/pg_search/normalizer.rb +17 -7
  25. data/lib/pg_search/scope_options.rb +36 -8
  26. data/lib/pg_search/tasks.rb +2 -2
  27. data/lib/pg_search/version.rb +1 -1
  28. data/lib/pg_search.rb +3 -3
  29. data/pg_search.gemspec +16 -31
  30. data/spec/integration/associations_spec.rb +118 -106
  31. data/spec/integration/deprecation_spec.rb +12 -9
  32. data/spec/integration/pagination_spec.rb +1 -0
  33. data/spec/integration/pg_search_spec.rb +343 -298
  34. data/spec/integration/single_table_inheritance_spec.rb +7 -5
  35. data/spec/lib/pg_search/configuration/association_spec.rb +17 -15
  36. data/spec/lib/pg_search/configuration/column_spec.rb +13 -1
  37. data/spec/lib/pg_search/configuration/foreign_column_spec.rb +5 -4
  38. data/spec/lib/pg_search/features/dmetaphone_spec.rb +4 -4
  39. data/spec/lib/pg_search/features/trigram_spec.rb +32 -33
  40. data/spec/lib/pg_search/features/tsearch_spec.rb +57 -39
  41. data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +70 -20
  42. data/spec/lib/pg_search/multisearch_spec.rb +8 -8
  43. data/spec/lib/pg_search/multisearchable_spec.rb +34 -26
  44. data/spec/lib/pg_search/normalizer_spec.rb +11 -11
  45. data/spec/lib/pg_search_spec.rb +22 -18
  46. data/spec/spec_helper.rb +3 -18
  47. data/spec/support/database.rb +6 -6
  48. metadata +11 -219
  49. data/.codeclimate.yml +0 -17
  50. data/.rubocop.yml +0 -137
  51. data/.travis.yml +0 -37
  52. data/spec/.rubocop.yml +0 -14
  53. data/spec/integration/.rubocop.yml +0 -11
@@ -6,12 +6,13 @@ describe "a pg_search_scope on an STI subclass" do
6
6
  context "with the standard type column" do
7
7
  with_model :SuperclassModel do
8
8
  table do |t|
9
- t.text 'content'
10
- t.string 'type'
9
+ t.text "content"
10
+ t.string "type"
11
11
  end
12
12
 
13
13
  model do
14
14
  include PgSearch::Model
15
+
15
16
  pg_search_scope :search_content, against: :content
16
17
  end
17
18
  end
@@ -46,13 +47,14 @@ describe "a pg_search_scope on an STI subclass" do
46
47
  context "with a custom type column" do
47
48
  with_model :SuperclassModel do
48
49
  table do |t|
49
- t.text 'content'
50
- t.string 'custom_type'
50
+ t.text "content"
51
+ t.string "custom_type"
51
52
  end
52
53
 
53
54
  model do
54
55
  include PgSearch::Model
55
- self.inheritance_column = 'custom_type'
56
+
57
+ self.inheritance_column = "custom_type"
56
58
  pg_search_scope :search_content, against: :content
57
59
  end
58
60
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- # rubocop:disable RSpec/NestedGroups
5
+ # standard:disable RSpec/NestedGroups
6
6
  describe PgSearch::Configuration::Association do
7
7
  with_model :Avatar do
8
8
  table do |t|
@@ -19,11 +19,12 @@ describe PgSearch::Configuration::Association do
19
19
 
20
20
  model do
21
21
  include PgSearch::Model
22
+
22
23
  has_one :avatar, class_name: "Avatar"
23
24
  belongs_to :site
24
25
 
25
- pg_search_scope :with_avatar, associated_against: { avatar: :url }
26
- pg_search_scope :with_site, associated_against: { site: :title }
26
+ pg_search_scope :with_avatar, associated_against: {avatar: :url}
27
+ pg_search_scope :with_site, associated_against: {site: :title}
27
28
  end
28
29
  end
29
30
 
@@ -34,9 +35,10 @@ describe PgSearch::Configuration::Association do
34
35
 
35
36
  model do
36
37
  include PgSearch::Model
38
+
37
39
  has_many :users, class_name: "User"
38
40
 
39
- pg_search_scope :with_users, associated_against: { users: :name }
41
+ pg_search_scope :with_users, associated_against: {users: :name}
40
42
  end
41
43
  end
42
44
 
@@ -55,9 +57,9 @@ describe PgSearch::Configuration::Association do
55
57
  LEFT OUTER JOIN
56
58
  (SELECT model_id AS id,
57
59
  #{column_select} AS #{association.columns.first.alias}
58
- FROM \"#{User.table_name}\"
59
- INNER JOIN \"#{association.table_name}\"
60
- ON \"#{association.table_name}\".\"user_id\" = \"#{User.table_name}\".\"id\") #{association.subselect_alias}
60
+ FROM "#{User.table_name}"
61
+ INNER JOIN "#{association.table_name}"
62
+ ON "#{association.table_name}"."user_id" = "#{User.table_name}"."id") #{association.subselect_alias}
61
63
  ON #{association.subselect_alias}.id = model_id
62
64
  SQL
63
65
  end
@@ -86,9 +88,9 @@ describe PgSearch::Configuration::Association do
86
88
  LEFT OUTER JOIN
87
89
  (SELECT model_id AS id,
88
90
  #{column_select} AS #{association.columns.first.alias}
89
- FROM \"#{User.table_name}\"
90
- INNER JOIN \"#{association.table_name}\"
91
- ON \"#{association.table_name}\".\"id\" = \"#{User.table_name}\".\"site_id\") #{association.subselect_alias}
91
+ FROM "#{User.table_name}"
92
+ INNER JOIN "#{association.table_name}"
93
+ ON "#{association.table_name}"."id" = "#{User.table_name}"."site_id") #{association.subselect_alias}
92
94
  ON #{association.subselect_alias}.id = model_id
93
95
  SQL
94
96
  end
@@ -116,10 +118,10 @@ describe PgSearch::Configuration::Association do
116
118
  <<~SQL.squish
117
119
  LEFT OUTER JOIN
118
120
  (SELECT model_id AS id,
119
- string_agg(\"#{association.table_name}\".\"name\"::text, ' ') AS #{association.columns.first.alias}
120
- FROM \"#{Site.table_name}\"
121
- INNER JOIN \"#{association.table_name}\"
122
- ON \"#{association.table_name}\".\"site_id\" = \"#{Site.table_name}\".\"id\"
121
+ string_agg("#{association.table_name}"."name"::text, ' ') AS #{association.columns.first.alias}
122
+ FROM "#{Site.table_name}"
123
+ INNER JOIN "#{association.table_name}"
124
+ ON "#{association.table_name}"."site_id" = "#{Site.table_name}"."id"
123
125
  GROUP BY model_id) #{association.subselect_alias}
124
126
  ON #{association.subselect_alias}.id = model_id
125
127
  SQL
@@ -139,4 +141,4 @@ describe PgSearch::Configuration::Association do
139
141
  end
140
142
  end
141
143
  end
142
- # rubocop:enable RSpec/NestedGroups
144
+ # standard:enable RSpec/NestedGroups
@@ -7,6 +7,7 @@ describe PgSearch::Configuration::Column do
7
7
  with_model :Model do
8
8
  table do |t|
9
9
  t.string :name
10
+ t.json :object
10
11
  end
11
12
  end
12
13
 
@@ -14,18 +15,29 @@ describe PgSearch::Configuration::Column do
14
15
  column = described_class.new("name", nil, Model)
15
16
  expect(column.full_name).to eq(%(#{Model.quoted_table_name}."name"))
16
17
  end
18
+
19
+ it "returns nested json attributes" do
20
+ column = described_class.new(Arel.sql("object->>'name'"), nil, Model)
21
+ expect(column.full_name).to eq(%(object->>'name'))
22
+ end
17
23
  end
18
24
 
19
25
  describe "#to_sql" do
20
26
  with_model :Model do
21
27
  table do |t|
22
28
  t.string :name
29
+ t.json :object
23
30
  end
24
31
  end
25
32
 
26
33
  it "returns an expression that casts the column to text and coalesces it with an empty string" do
27
34
  column = described_class.new("name", nil, Model)
28
- expect(column.to_sql).to eq(%{coalesce(#{Model.quoted_table_name}."name"::text, '')})
35
+ expect(column.to_sql).to eq(%{coalesce((#{Model.quoted_table_name}."name")::text, '')})
36
+ end
37
+
38
+ it "returns an expression that casts the nested json attribute to text and coalesces it with an empty string" do
39
+ column = described_class.new(Arel.sql("object->>'name'"), nil, Model)
40
+ expect(column.to_sql).to eq(%{coalesce((object->>'name')::text, '')})
29
41
  end
30
42
  end
31
43
  end
@@ -18,16 +18,17 @@ describe PgSearch::Configuration::ForeignColumn do
18
18
 
19
19
  model do
20
20
  include PgSearch::Model
21
- belongs_to :another_model, class_name: 'AssociatedModel'
22
21
 
23
- pg_search_scope :with_another, associated_against: { another_model: :title }
22
+ belongs_to :another_model, class_name: "AssociatedModel"
23
+
24
+ pg_search_scope :with_another, associated_against: {another_model: :title}
24
25
  end
25
26
  end
26
27
 
27
28
  it "returns a consistent string" do
28
29
  association = PgSearch::Configuration::Association.new(Model,
29
- :another_model,
30
- :title)
30
+ :another_model,
31
+ :title)
31
32
  foreign_column = described_class.new("title", nil, Model, association)
32
33
 
33
34
  column_alias = foreign_column.alias
@@ -18,12 +18,12 @@ describe PgSearch::Features::DMetaphone do
18
18
  PgSearch::Configuration::Column.new(:content, nil, Model)
19
19
  ]
20
20
  options = {}
21
- config = instance_double("PgSearch::Configuration", :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)
25
25
  expect(feature.rank.to_sql).to eq(
26
- %{(ts_rank((to_tsvector('simple', pg_search_dmetaphone(coalesce(#{Model.quoted_table_name}."name"::text, ''))) || to_tsvector('simple', pg_search_dmetaphone(coalesce(#{Model.quoted_table_name}."content"::text, '')))), (to_tsquery('simple', ''' ' || pg_search_dmetaphone('query') || ' ''')), 0))}
26
+ %{(ts_rank((to_tsvector('simple', pg_search_dmetaphone(coalesce((#{Model.quoted_table_name}."name")::text, ''))) || to_tsvector('simple', pg_search_dmetaphone(coalesce((#{Model.quoted_table_name}."content")::text, '')))), (to_tsquery('simple', ''' ' || pg_search_dmetaphone('query') || ' ''')), 0))}
27
27
  )
28
28
  end
29
29
  end
@@ -43,12 +43,12 @@ describe PgSearch::Features::DMetaphone do
43
43
  PgSearch::Configuration::Column.new(:content, nil, Model)
44
44
  ]
45
45
  options = {}
46
- config = instance_double("PgSearch::Configuration", :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)
50
50
  expect(feature.conditions.to_sql).to eq(
51
- %{((to_tsvector('simple', pg_search_dmetaphone(coalesce(#{Model.quoted_table_name}."name"::text, ''))) || to_tsvector('simple', pg_search_dmetaphone(coalesce(#{Model.quoted_table_name}."content"::text, '')))) @@ (to_tsquery('simple', ''' ' || pg_search_dmetaphone('query') || ' ''')))}
51
+ %{((to_tsvector('simple', pg_search_dmetaphone(coalesce((#{Model.quoted_table_name}."name")::text, ''))) || to_tsvector('simple', pg_search_dmetaphone(coalesce((#{Model.quoted_table_name}."content")::text, '')))) @@ (to_tsquery('simple', ''' ' || pg_search_dmetaphone('query') || ' ''')))}
52
52
  )
53
53
  end
54
54
  end
@@ -1,13 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'ostruct'
3
+ require "spec_helper"
5
4
 
6
- # rubocop:disable RSpec/MultipleMemoizedHelpers, RSpec/NestedGroups
5
+ # standard:disable RSpec/MultipleMemoizedHelpers, RSpec/NestedGroups
7
6
  describe PgSearch::Features::Trigram do
8
7
  subject(:feature) { described_class.new(query, options, columns, Model, normalizer) }
9
8
 
10
- let(:query) { 'lolwut' }
9
+ let(:query) { "lolwut" }
11
10
  let(:options) { {} }
12
11
  let(:columns) {
13
12
  [
@@ -16,13 +15,14 @@ describe PgSearch::Features::Trigram do
16
15
  ]
17
16
  }
18
17
  let(:normalizer) { PgSearch::Normalizer.new(config) }
19
- let(:config) { OpenStruct.new(ignore: []) } # rubocop:disable Style/OpenStructUse
18
+ let(:config) { instance_double(PgSearch::Configuration, ignore: ignore) }
19
+ let(:ignore) { [] }
20
20
 
21
21
  let(:coalesced_columns) do
22
22
  <<~SQL.squish
23
- coalesce(#{Model.quoted_table_name}."name"::text, '')
23
+ coalesce((#{Model.quoted_table_name}."name")::text, '')
24
24
  || ' '
25
- || coalesce(#{Model.quoted_table_name}."content"::text, '')
25
+ || coalesce((#{Model.quoted_table_name}."content")::text, '')
26
26
  SQL
27
27
  end
28
28
 
@@ -33,34 +33,33 @@ describe PgSearch::Features::Trigram do
33
33
  end
34
34
  end
35
35
 
36
- describe 'conditions' do
37
- it 'escapes the search document and query' do
38
- config.ignore = []
36
+ describe "conditions" do
37
+ it "escapes the search document and query" do
39
38
  expect(feature.conditions.to_sql).to eq("('#{query}' % (#{coalesced_columns}))")
40
39
  end
41
40
 
42
- context 'when searching by word_similarity' do
41
+ context "when searching by word_similarity" do
43
42
  let(:options) do
44
- { word_similarity: true }
43
+ {word_similarity: true}
45
44
  end
46
45
 
47
46
  it 'uses the "<%" operator when searching by word_similarity' do
48
- config.ignore = []
49
47
  expect(feature.conditions.to_sql).to eq("('#{query}' <% (#{coalesced_columns}))")
50
48
  end
51
49
  end
52
50
 
53
- context 'when ignoring accents' do
54
- it 'escapes the search document and query, but not the accent function' do
55
- config.ignore = [:accents]
56
- expect(feature.conditions.to_sql).to eq("(unaccent('#{query}') % (unaccent(#{coalesced_columns})))")
51
+ context "when ignoring accents" do
52
+ let(:ignore) { [:accents] }
53
+
54
+ it "escapes the search document and query, but not the accent function" do
55
+ expect(feature.conditions.to_sql).to eq("(regexp_replace(unaccent('#{query}'), '[''?\\:]', '', 'g') % (regexp_replace(unaccent(#{coalesced_columns}), '[''?\\:]', '', 'g')))")
57
56
  end
58
57
  end
59
58
 
60
- context 'when a threshold is specified' do
61
- context 'when searching by similarity' do
59
+ context "when a threshold is specified" do
60
+ context "when searching by similarity" do
62
61
  let(:options) do
63
- { threshold: 0.5 }
62
+ {threshold: 0.5}
64
63
  end
65
64
 
66
65
  it 'uses a minimum similarity expression instead of the "%" operator' do
@@ -70,9 +69,9 @@ describe PgSearch::Features::Trigram do
70
69
  end
71
70
  end
72
71
 
73
- context 'when searching by word_similarity' do
72
+ context "when searching by word_similarity" do
74
73
  let(:options) do
75
- { threshold: 0.5, word_similarity: true }
74
+ {threshold: 0.5, word_similarity: true}
76
75
  end
77
76
 
78
77
  it 'uses a minimum similarity expression instead of the "<%" operator' do
@@ -83,30 +82,30 @@ describe PgSearch::Features::Trigram do
83
82
  end
84
83
  end
85
84
 
86
- context 'when only certain columns are selected' do
87
- context 'with one column' do
88
- let(:options) { { only: :name } }
85
+ context "when only certain columns are selected" do
86
+ context "with one column" do
87
+ let(:options) { {only: :name} }
89
88
 
90
- it 'only searches against the select column' do
91
- coalesced_column = "coalesce(#{Model.quoted_table_name}.\"name\"::text, '')"
89
+ it "only searches against the select column" do
90
+ coalesced_column = "coalesce((#{Model.quoted_table_name}.\"name\")::text, '')"
92
91
  expect(feature.conditions.to_sql).to eq("('#{query}' % (#{coalesced_column}))")
93
92
  end
94
93
  end
95
94
 
96
- context 'with multiple columns' do
97
- let(:options) { { only: %i[name content] } }
95
+ context "with multiple columns" do
96
+ let(:options) { {only: %i[name content]} }
98
97
 
99
- it 'concatenates when multiples columns are selected' do
98
+ it "concatenates when multiples columns are selected" do
100
99
  expect(feature.conditions.to_sql).to eq("('#{query}' % (#{coalesced_columns}))")
101
100
  end
102
101
  end
103
102
  end
104
103
  end
105
104
 
106
- describe '#rank' do
107
- it 'returns an expression using the similarity() function' do
105
+ describe "#rank" do
106
+ it "returns an expression using the similarity() function" do
108
107
  expect(feature.rank.to_sql).to eq("(similarity('#{query}', (#{coalesced_columns})))")
109
108
  end
110
109
  end
111
110
  end
112
- # rubocop:enable RSpec/MultipleMemoizedHelpers, RSpec/NestedGroups
111
+ # standard:enable RSpec/MultipleMemoizedHelpers, RSpec/NestedGroups
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
- require "active_support/deprecation"
4
+ require "active_support/core_ext/kernel/reporting"
5
5
 
6
6
  describe PgSearch::Features::TSearch do
7
7
  describe "#rank" do
@@ -19,14 +19,32 @@ describe PgSearch::Features::TSearch do
19
19
  PgSearch::Configuration::Column.new(:content, nil, Model)
20
20
  ]
21
21
  options = {}
22
- config = instance_double("PgSearch::Configuration", :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)
26
26
  expect(feature.rank.to_sql).to eq(
27
- %{(ts_rank((to_tsvector('simple', coalesce(#{Model.quoted_table_name}."name"::text, '')) || to_tsvector('simple', coalesce(#{Model.quoted_table_name}."content"::text, ''))), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 0))}
27
+ %{(ts_rank((to_tsvector('simple', coalesce((#{Model.quoted_table_name}."name")::text, '')) || to_tsvector('simple', coalesce((#{Model.quoted_table_name}."content")::text, ''))), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 0))}
28
28
  )
29
29
  end
30
+
31
+ context "with a tsvector column and a custom normalization" do
32
+ it "works?" do
33
+ query = "query"
34
+ columns = [
35
+ PgSearch::Configuration::Column.new(:name, nil, Model),
36
+ PgSearch::Configuration::Column.new(:content, nil, Model)
37
+ ]
38
+ options = {tsvector_column: :my_tsvector, normalization: 2}
39
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
40
+ normalizer = PgSearch::Normalizer.new(config)
41
+
42
+ feature = described_class.new(query, options, columns, Model, normalizer)
43
+ expect(feature.rank.to_sql).to eq(
44
+ %{(ts_rank((#{Model.quoted_table_name}."my_tsvector"), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 2))}
45
+ )
46
+ end
47
+ end
30
48
  end
31
49
 
32
50
  describe "#conditions" do
@@ -44,12 +62,12 @@ describe PgSearch::Features::TSearch do
44
62
  PgSearch::Configuration::Column.new(:content, nil, Model)
45
63
  ]
46
64
  options = {}
47
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
65
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
48
66
  normalizer = PgSearch::Normalizer.new(config)
49
67
 
50
68
  feature = described_class.new(query, options, columns, Model, normalizer)
51
69
  expect(feature.conditions.to_sql).to eq(
52
- %{((to_tsvector('simple', coalesce(#{Model.quoted_table_name}."name"::text, '')) || to_tsvector('simple', coalesce(#{Model.quoted_table_name}."content"::text, ''))) @@ (to_tsquery('simple', ''' ' || 'query' || ' ''')))}
70
+ %{((to_tsvector('simple', coalesce((#{Model.quoted_table_name}."name")::text, '')) || to_tsvector('simple', coalesce((#{Model.quoted_table_name}."content")::text, ''))) @@ (to_tsquery('simple', ''' ' || 'query' || ' ''')))}
53
71
  )
54
72
  end
55
73
 
@@ -60,13 +78,13 @@ describe PgSearch::Features::TSearch do
60
78
  PgSearch::Configuration::Column.new(:name, nil, Model),
61
79
  PgSearch::Configuration::Column.new(:content, nil, Model)
62
80
  ]
63
- options = { negation: true }
64
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
81
+ options = {negation: true}
82
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
65
83
  normalizer = PgSearch::Normalizer.new(config)
66
84
 
67
85
  feature = described_class.new(query, options, columns, Model, normalizer)
68
86
  expect(feature.conditions.to_sql).to eq(
69
- %{((to_tsvector('simple', coalesce(#{Model.quoted_table_name}."name"::text, '')) || to_tsvector('simple', coalesce(#{Model.quoted_table_name}."content"::text, ''))) @@ (to_tsquery('simple', '!' || ''' ' || 'query' || ' ''')))}
87
+ %{((to_tsvector('simple', coalesce((#{Model.quoted_table_name}."name")::text, '')) || to_tsvector('simple', coalesce((#{Model.quoted_table_name}."content")::text, ''))) @@ (to_tsquery('simple', '!' || ''' ' || 'query' || ' ''')))}
70
88
  )
71
89
  end
72
90
  end
@@ -78,49 +96,49 @@ describe PgSearch::Features::TSearch do
78
96
  PgSearch::Configuration::Column.new(:name, nil, Model),
79
97
  PgSearch::Configuration::Column.new(:content, nil, Model)
80
98
  ]
81
- options = { negation: false }
82
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
99
+ options = {negation: false}
100
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
83
101
  normalizer = PgSearch::Normalizer.new(config)
84
102
 
85
103
  feature = described_class.new(query, options, columns, Model, normalizer)
86
104
  expect(feature.conditions.to_sql).to eq(
87
- %{((to_tsvector('simple', coalesce(#{Model.quoted_table_name}."name"::text, '')) || to_tsvector('simple', coalesce(#{Model.quoted_table_name}."content"::text, ''))) @@ (to_tsquery('simple', ''' ' || '!query' || ' ''')))}
105
+ %{((to_tsvector('simple', coalesce((#{Model.quoted_table_name}."name")::text, '')) || to_tsvector('simple', coalesce((#{Model.quoted_table_name}."content")::text, ''))) @@ (to_tsquery('simple', ''' ' || '!query' || ' ''')))}
88
106
  )
89
107
  end
90
108
  end
91
109
 
92
110
  context "when options[:tsvector_column] is a string" do
93
- it 'uses the tsvector column' do
111
+ it "uses the tsvector column" do
94
112
  query = "query"
95
113
  columns = [
96
114
  PgSearch::Configuration::Column.new(:name, nil, Model),
97
115
  PgSearch::Configuration::Column.new(:content, nil, Model)
98
116
  ]
99
- options = { tsvector_column: "my_tsvector" }
100
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
117
+ options = {tsvector_column: "my_tsvector"}
118
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
101
119
  normalizer = PgSearch::Normalizer.new(config)
102
120
 
103
121
  feature = described_class.new(query, options, columns, Model, normalizer)
104
122
  expect(feature.conditions.to_sql).to eq(
105
- %{((#{Model.quoted_table_name}.\"my_tsvector\") @@ (to_tsquery('simple', ''' ' || 'query' || ' ''')))}
123
+ %{((#{Model.quoted_table_name}."my_tsvector") @@ (to_tsquery('simple', ''' ' || 'query' || ' ''')))}
106
124
  )
107
125
  end
108
126
  end
109
127
 
110
128
  context "when options[:tsvector_column] is an array of strings" do
111
- it 'uses the tsvector column' do
129
+ it "uses the tsvector column" do
112
130
  query = "query"
113
131
  columns = [
114
132
  PgSearch::Configuration::Column.new(:name, nil, Model),
115
133
  PgSearch::Configuration::Column.new(:content, nil, Model)
116
134
  ]
117
- options = { tsvector_column: ["tsvector1", "tsvector2"] }
118
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
135
+ options = {tsvector_column: ["tsvector1", "tsvector2"]}
136
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
119
137
  normalizer = PgSearch::Normalizer.new(config)
120
138
 
121
139
  feature = described_class.new(query, options, columns, Model, normalizer)
122
140
  expect(feature.conditions.to_sql).to eq(
123
- %{((#{Model.quoted_table_name}.\"tsvector1\" || #{Model.quoted_table_name}.\"tsvector2\") @@ (to_tsquery('simple', ''' ' || 'query' || ' ''')))}
141
+ %{((#{Model.quoted_table_name}."tsvector1" || #{Model.quoted_table_name}."tsvector2") @@ (to_tsquery('simple', ''' ' || 'query' || ' ''')))}
124
142
  )
125
143
  end
126
144
  end
@@ -141,18 +159,18 @@ describe PgSearch::Features::TSearch do
141
159
  ]
142
160
  options = {}
143
161
 
144
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
162
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
145
163
  normalizer = PgSearch::Normalizer.new(config)
146
164
 
147
165
  feature = described_class.new(query, options, columns, Model, normalizer)
148
166
  expect(feature.highlight.to_sql).to eq(
149
- "(ts_headline('simple', (coalesce(#{Model.quoted_table_name}.\"name\"::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), ''))"
167
+ "(ts_headline('simple', (coalesce((#{Model.quoted_table_name}.\"name\")::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), ''))"
150
168
  )
151
169
  end
152
170
 
153
171
  context "when options[:dictionary] is passed" do
154
- # rubocop:disable RSpec/ExampleLength
155
- it 'uses the provided dictionary' do
172
+ # standard:disable RSpec/ExampleLength
173
+ it "uses the provided dictionary" do
156
174
  query = "query"
157
175
  columns = [
158
176
  PgSearch::Configuration::Column.new(:name, nil, Model),
@@ -166,20 +184,20 @@ describe PgSearch::Features::TSearch do
166
184
  }
167
185
  }
168
186
 
169
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
187
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
170
188
  normalizer = PgSearch::Normalizer.new(config)
171
189
 
172
190
  feature = described_class.new(query, options, columns, Model, normalizer)
173
191
 
174
- expected_sql = %{(ts_headline('spanish', (coalesce(#{Model.quoted_table_name}."name"::text, '') || ' ' || coalesce(#{Model.quoted_table_name}."content"::text, '')), (to_tsquery('spanish', ''' ' || 'query' || ' ''')), 'StartSel = "<b>", StopSel = "</b>"'))}
192
+ expected_sql = %{(ts_headline('spanish', (coalesce((#{Model.quoted_table_name}."name")::text, '') || ' ' || coalesce((#{Model.quoted_table_name}."content")::text, '')), (to_tsquery('spanish', ''' ' || 'query' || ' ''')), 'StartSel = "<b>", StopSel = "</b>"'))}
175
193
 
176
194
  expect(feature.highlight.to_sql).to eq(expected_sql)
177
195
  end
178
- # rubocop:enable RSpec/ExampleLength
196
+ # standard:enable RSpec/ExampleLength
179
197
  end
180
198
 
181
199
  context "when options[:highlight] has options set" do
182
- # rubocop:disable RSpec/ExampleLength
200
+ # standard:disable RSpec/ExampleLength
183
201
  it "passes the options to ts_headline" do
184
202
  query = "query"
185
203
  columns = [
@@ -188,28 +206,28 @@ describe PgSearch::Features::TSearch do
188
206
  options = {
189
207
  highlight: {
190
208
  StartSel: '<start class="search">',
191
- StopSel: '<stop>',
209
+ StopSel: "<stop>",
192
210
  MaxWords: 123,
193
211
  MinWords: 456,
194
212
  ShortWord: 4,
195
213
  HighlightAll: true,
196
214
  MaxFragments: 3,
197
- FragmentDelimiter: '&hellip;'
215
+ FragmentDelimiter: "&hellip;"
198
216
  }
199
217
  }
200
218
 
201
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
219
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
202
220
  normalizer = PgSearch::Normalizer.new(config)
203
221
 
204
222
  feature = described_class.new(query, options, columns, Model, normalizer)
205
223
 
206
- expected_sql = %{(ts_headline('simple', (coalesce(#{Model.quoted_table_name}."name"::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 'StartSel = "<start class=""search"">", StopSel = "<stop>", MaxFragments = 3, MaxWords = 123, MinWords = 456, ShortWord = 4, FragmentDelimiter = "&hellip;", HighlightAll = TRUE'))}
224
+ expected_sql = %{(ts_headline('simple', (coalesce((#{Model.quoted_table_name}."name")::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 'StartSel = "<start class=""search"">", StopSel = "<stop>", MaxFragments = 3, MaxWords = 123, MinWords = 456, ShortWord = 4, FragmentDelimiter = "&hellip;", HighlightAll = TRUE'))}
207
225
 
208
226
  expect(feature.highlight.to_sql).to eq(expected_sql)
209
227
  end
210
- # rubocop:enable RSpec/ExampleLength
228
+ # standard:enable RSpec/ExampleLength
211
229
 
212
- # rubocop:disable RSpec/ExampleLength
230
+ # standard:disable RSpec/ExampleLength
213
231
  it "passes deprecated options to ts_headline" do
214
232
  query = "query"
215
233
  columns = [
@@ -218,27 +236,27 @@ describe PgSearch::Features::TSearch do
218
236
  options = {
219
237
  highlight: {
220
238
  start_sel: '<start class="search">',
221
- stop_sel: '<stop>',
239
+ stop_sel: "<stop>",
222
240
  max_words: 123,
223
241
  min_words: 456,
224
242
  short_word: 4,
225
243
  highlight_all: false,
226
244
  max_fragments: 3,
227
- fragment_delimiter: '&hellip;'
245
+ fragment_delimiter: "&hellip;"
228
246
  }
229
247
  }
230
248
 
231
- config = instance_double("PgSearch::Configuration", :config, ignore: [])
249
+ config = instance_double(PgSearch::Configuration, :config, ignore: [])
232
250
  normalizer = PgSearch::Normalizer.new(config)
233
251
 
234
252
  feature = described_class.new(query, options, columns, Model, normalizer)
235
253
 
236
- highlight_sql = ActiveSupport::Deprecation.silence { feature.highlight.to_sql }
237
- expected_sql = %{(ts_headline('simple', (coalesce(#{Model.quoted_table_name}."name"::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 'StartSel = "<start class=""search"">", StopSel = "<stop>", MaxFragments = 3, MaxWords = 123, MinWords = 456, ShortWord = 4, FragmentDelimiter = "&hellip;", HighlightAll = FALSE'))}
254
+ highlight_sql = silence_warnings { feature.highlight.to_sql }
255
+ expected_sql = %{(ts_headline('simple', (coalesce((#{Model.quoted_table_name}."name")::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 'StartSel = "<start class=""search"">", StopSel = "<stop>", MaxFragments = 3, MaxWords = 123, MinWords = 456, ShortWord = 4, FragmentDelimiter = "&hellip;", HighlightAll = FALSE'))}
238
256
 
239
257
  expect(highlight_sql).to eq(expected_sql)
240
258
  end
241
- # rubocop:enable RSpec/ExampleLength
259
+ # standard:enable RSpec/ExampleLength
242
260
  end
243
261
  end
244
262
  end