Initial commit

This commit is contained in:
Senad Uka
2020-01-28 13:31:56 +01:00
parent 7f7c6e95bc
commit 2749c53aac
56 changed files with 6516 additions and 1 deletions

103
spec/support/models.rb Executable file
View File

@@ -0,0 +1,103 @@
# frozen_string_literal: true
class VectorModel < ActiveRecord::Base
include PgSearchable
pg_search fields: %i[id name value], cache: :search_cache
end
class VectorModelWithoutCallback < ActiveRecord::Base
self.table_name = :vector_models
include PgSearchable
pg_search fields: %i[id name value], cache: :search_cache, skip_callback: true
end
class VectorWithCustomCallback < ActiveRecord::Base
self.table_name = :vector_models
include PgSearchable
pg_search fields: %i[id name value], cache: :search_cache, skip_callback: true, external_cache_data: :colors
after_save :update_pg_search_cache
def colors
%w[orange blue]
end
end
class VectorWithCustomPrimaryKeyModel < ActiveRecord::Base
include PgSearchable
pg_search fields: %i[uuid name value]
self.primary_key = :uuid
before_save { self.uuid = SecureRandom.uuid }
end
class SimpleVectorModel < ActiveRecord::Base
self.table_name = :vector_models
include PgSearchable
pg_search fields: %i[id name value], cache: :search_cache, language: :simple
end
class VectorWithoutWildcardModel < ActiveRecord::Base
self.table_name = :vector_models
include PgSearchable
pg_search fields: %i[id name value], cache: :search_cache, wildcard: false
end
class VectorModelWithCustomSearchScope < ActiveRecord::Base
self.table_name = :vector_models
include PgSearchable
pg_search fields: %i[id name value], cache: :search_cache, scope: 'fulltext'
end
class VectorModelWithTagValues < ActiveRecord::Base
self.table_name = :vector_models
include PgSearchable
pg_search fields: %i[id name value], cache: :search_cache, external_cache_data: :tag_values
has_many :tags, as: :taggable
def tag_values
tags.pluck(:value)
end
end
class DynamicModel < ActiveRecord::Base
include PgSearchable
pg_search fields: %i[id name value]
end
class DynamicModelWithTagValues < ActiveRecord::Base
self.table_name = :dynamic_models
include PgSearchable
pg_search fields: %i[dynamic_models.id dynamic_models.name dynamic_models.value tags.value], joins: [:tags]
has_many :tags, as: :taggable
end
class DynamicModelWithCategory < ActiveRecord::Base
self.table_name = :dynamic_models
include PgSearchable
pg_search fields: %i[dynamic_models.id dynamic_models.name dynamic_models.value tags.value categories.name],
joins: { tags: :category }
has_many :tags, as: :taggable
end
class DynamicModelWithSectionsTrhough < ActiveRecord::Base
self.table_name = :dynamic_models
include PgSearchable
pg_search fields: %i[dynamic_models.id dynamic_models.name dynamic_models.value tags.value sections.name],
joins: [{ tags: :category }, :sections]
has_many :tags, as: :taggable
has_many :sections, through: :tags
end
class Tag < ActiveRecord::Base
belongs_to :category
has_many :sections
belongs_to :taggable, polymorphic: true
after_save { taggable.update_pg_search_cache if taggable.class.ts_cache_field.present? }
end
class Section < ActiveRecord::Base
belongs_to :tag
end
class Category < ActiveRecord::Base
has_many :tags
end

View File

@@ -0,0 +1,68 @@
# frozen_string_literal: true
shared_examples 'pg_search' do |mock_class, scope_method = 'scope_search'|
describe 'searchable fields' do
let!(:record) { mock_class.create name: 'something', value: 'amazing' }
it { expect(mock_class.send(scope_method, record.id)).to include(record) }
it { expect(mock_class.send(scope_method, 'something')).to include(record) }
it { expect(mock_class.send(scope_method, 'amazing')).to include(record) }
it { expect(mock_class.send(scope_method, 'candy')).not_to include(record) }
end
describe 'operators' do
before do
mock_class.create(name: 'uno', value: 'one')
mock_class.create(name: 'dos', value: 'two')
mock_class.create(name: 'tres', value: 'three')
mock_class.create(name: 'cuatro', value: 'four')
mock_class.create(name: 'cuatro', value: 'five')
mock_class.create(name: 'cinco', value: 'one-two-three')
end
it 'returns all records if search query is blank' do
expect(mock_class.send(scope_method, ' ').first).not_to be_blank
end
describe 'AND searches' do
it { expect(mock_class.send(scope_method, 'uno one').count).to eq(1) }
it { expect(mock_class.send(scope_method, 'uno&one').count).to eq(1) }
it { expect(mock_class.send(scope_method, 'uno&&one').count).to eq(1) }
it { expect(mock_class.send(scope_method, 'uno & one').count).to eq(1) }
it { expect(mock_class.send(scope_method, 'uno one').count).to eq(1) }
it { expect(mock_class.send(scope_method, 'uno and one').count).to eq(1) }
it { expect(mock_class.send(scope_method, 'dos AND two').count).to eq(1) }
it { expect(mock_class.send(scope_method, 'uno dos').count).to eq(0) }
end
describe 'OR searches' do
it { expect(mock_class.send(scope_method, 'uno or dos').count).to eq(2) }
it { expect(mock_class.send(scope_method, 'uno or dos').count).to eq(2) }
it { expect(mock_class.send(scope_method, 'uno or or dos').count).to eq(2) }
it { expect(mock_class.send(scope_method, 'uno or or dos').count).to eq(2) }
it { expect(mock_class.send(scope_method, 'one OR two').count).to eq(3) }
it { expect(mock_class.send(scope_method, 'uno or two').count).to eq(3) }
end
describe 'AND and OR searches' do
it { expect(mock_class.send(scope_method, 'uno or dos two').count).to eq(2) }
it { expect(mock_class.send(scope_method, 'uno or dos one').count).to eq(1) }
end
describe 'NOT searches' do
it { expect(mock_class.send(scope_method, '!cuatro').count).to eq(4) }
it { expect(mock_class.send(scope_method, 'cuatro !four').count).to eq(1) }
end
describe 'exact match' do
it { expect(mock_class.send(scope_method, '"cinco"').count).to eq(1) }
it { expect(mock_class.send(scope_method, '"one-two-three"').count).to eq(1) }
it { expect(mock_class.send(scope_method, '"one two"').count).to eq(1) }
it { expect(mock_class.send(scope_method, '"one&two"').count).to eq(1) }
it { expect(mock_class.send(scope_method, '"one|two"').count).to eq(1) }
it { expect(mock_class.send(scope_method, '"one-two-three" or two').count).to eq(2) }
it { expect(mock_class.send(scope_method, '"one-two"').count).to eq(0) }
it { expect(mock_class.send(scope_method, '"cinco one"').count).to eq(1) }
end
end
end