diff options
author | Hiroyuki Sato <sathiroyuki@gmail.com> | 2017-08-23 19:54:14 +0900 |
---|---|---|
committer | Hiroyuki Sato <sathiroyuki@gmail.com> | 2017-08-31 03:14:58 +0900 |
commit | 59e5393827e9e9eddb9bb0a960f1cda1f6d9511d (patch) | |
tree | 6bc579b71c2e6ec77832a9316355d25144032f99 /spec | |
parent | d6e956d3a89fbb7f1a503f152fe9a4e2ca931d85 (diff) | |
download | gitlab-ce-59e5393827e9e9eddb9bb0a960f1cda1f6d9511d.tar.gz |
Fuzzy search issuable title or description
Diffstat (limited to 'spec')
-rw-r--r-- | spec/lib/gitlab/sql/pattern_spec.rb | 120 | ||||
-rw-r--r-- | spec/models/concerns/issuable_spec.rb | 42 |
2 files changed, 151 insertions, 11 deletions
diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb index 9d7b2136dab..0b0e905483f 100644 --- a/spec/lib/gitlab/sql/pattern_spec.rb +++ b/spec/lib/gitlab/sql/pattern_spec.rb @@ -52,4 +52,124 @@ describe Gitlab::SQL::Pattern do end end end + + describe '.select_fuzzy_words' do + subject(:select_fuzzy_words) { Issue.select_fuzzy_words(query) } + + context 'with a word equal to 3 chars' do + let(:query) { 'foo' } + + it 'returns array cotaining a word' do + expect(select_fuzzy_words).to match_array(['foo']) + end + end + + context 'with a word shorter than 3 chars' do + let(:query) { 'fo' } + + it 'returns empty array' do + expect(select_fuzzy_words).to match_array([]) + end + end + + context 'with two words both equal to 3 chars' do + let(:query) { 'foo baz' } + + it 'returns array containing two words' do + expect(select_fuzzy_words).to match_array(%w[foo baz]) + end + end + + context 'with two words divided by two speces both equal to 3 chars' do + let(:query) { 'foo baz' } + + it 'returns array containing two words' do + expect(select_fuzzy_words).to match_array(%w[foo baz]) + end + end + + context 'with two words equal to 3 chars and shorter than 3 chars' do + let(:query) { 'foo ba' } + + it 'returns array containing a word' do + expect(select_fuzzy_words).to match_array(['foo']) + end + end + + context 'with a multi-word surrounded by double quote' do + let(:query) { '"really bar"' } + + it 'returns array containing a multi-word' do + expect(select_fuzzy_words).to match_array(['really bar']) + end + end + + context 'with a multi-word surrounded by double quote and two words' do + let(:query) { 'foo "really bar" baz' } + + it 'returns array containing a multi-word and tow words' do + expect(select_fuzzy_words).to match_array(['foo', 'really bar', 'baz']) + end + end + + context 'with a multi-word surrounded by double quote missing a spece before the first double quote' do + let(:query) { 'foo"really bar"' } + + it 'returns array containing two words with double quote' do + expect(select_fuzzy_words).to match_array(['foo"really', 'bar"']) + end + end + + context 'with a multi-word surrounded by double quote missing a spece after the second double quote' do + let(:query) { '"really bar"baz' } + + it 'returns array containing two words with double quote' do + expect(select_fuzzy_words).to match_array(['"really', 'bar"baz']) + end + end + + context 'with two multi-word surrounded by double quote and two words' do + let(:query) { 'foo "really bar" baz "awesome feature"' } + + it 'returns array containing two multi-words and tow words' do + expect(select_fuzzy_words).to match_array(['foo', 'really bar', 'baz', 'awesome feature']) + end + end + end + + describe '.to_fuzzy_arel' do + subject(:to_fuzzy_arel) { Issue.to_fuzzy_arel(:title, query) } + + context 'with a word equal to 3 chars' do + let(:query) { 'foo' } + + it 'returns a single ILIKE condition' do + expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%')) + end + end + + context 'with a word shorter than 3 chars' do + let(:query) { 'fo' } + + it 'returns nil' do + expect(to_fuzzy_arel).to be_nil + end + end + + context 'with two words both equal to 3 chars' do + let(:query) { 'foo baz' } + + it 'returns a joining ILIKE condition using a AND' do + expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%' AND "issues"."title" ILIKE '%baz%')) + end + end + + context 'with a multi-word surrounded by double quote and two words' do + let(:query) { 'foo "really bar" baz' } + + it 'returns a joining ILIKE condition using a AND' do + expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%' AND "issues"."title" ILIKE '%baz%' AND "issues"."title" ILIKE '%really bar%')) + end + end + end end diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index dfbe1a7c192..37f6fd3a25b 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -66,56 +66,76 @@ describe Issuable do end describe ".search" do - let!(:searchable_issue) { create(:issue, title: "Searchable issue") } + let!(:searchable_issue) { create(:issue, title: "Searchable awesome issue") } - it 'returns notes with a matching title' do + it 'returns issues with a matching title' do expect(issuable_class.search(searchable_issue.title)) .to eq([searchable_issue]) end - it 'returns notes with a partially matching title' do + it 'returns issues with a partially matching title' do expect(issuable_class.search('able')).to eq([searchable_issue]) end - it 'returns notes with a matching title regardless of the casing' do + it 'returns issues with a matching title regardless of the casing' do expect(issuable_class.search(searchable_issue.title.upcase)) .to eq([searchable_issue]) end + + it 'returns issues with a fuzzy matching title' do + expect(issuable_class.search('searchable issue')).to eq([searchable_issue]) + end + + it 'returns all issues with a query shorter than 3 chars' do + expect(issuable_class.search('zz')).to eq(issuable_class.all) + end end describe ".full_search" do let!(:searchable_issue) do - create(:issue, title: "Searchable issue", description: 'kittens') + create(:issue, title: "Searchable awesome issue", description: 'Many cute kittens') end - it 'returns notes with a matching title' do + it 'returns issues with a matching title' do expect(issuable_class.full_search(searchable_issue.title)) .to eq([searchable_issue]) end - it 'returns notes with a partially matching title' do + it 'returns issues with a partially matching title' do expect(issuable_class.full_search('able')).to eq([searchable_issue]) end - it 'returns notes with a matching title regardless of the casing' do + it 'returns issues with a matching title regardless of the casing' do expect(issuable_class.full_search(searchable_issue.title.upcase)) .to eq([searchable_issue]) end - it 'returns notes with a matching description' do + it 'returns issues with a fuzzy matching title' do + expect(issuable_class.full_search('searchable issue')).to eq([searchable_issue]) + end + + it 'returns issues with a matching description' do expect(issuable_class.full_search(searchable_issue.description)) .to eq([searchable_issue]) end - it 'returns notes with a partially matching description' do + it 'returns issues with a partially matching description' do expect(issuable_class.full_search(searchable_issue.description)) .to eq([searchable_issue]) end - it 'returns notes with a matching description regardless of the casing' do + it 'returns issues with a matching description regardless of the casing' do expect(issuable_class.full_search(searchable_issue.description.upcase)) .to eq([searchable_issue]) end + + it 'returns issues with a fuzzy matching description' do + expect(issuable_class.full_search('many kittens')).to eq([searchable_issue]) + end + + it 'returns all issues with a query shorter than 3 chars' do + expect(issuable_class.search('zz')).to eq(issuable_class.all) + end end describe '.to_ability_name' do |