searchable-by 0.5.2 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21e09cdcdb1a9bebd3df6bb7a28d4f4cfc566a478b757390ea7f71445f195edd
4
- data.tar.gz: 3bad5ea302c2c46bceee3a966b298799c133d1c2db0ffecf6a4bd38bf5393ccc
3
+ metadata.gz: 412ef1f5428799d4fa13cd47f5fb61ff0f1f0ac2b24aa57080a78fe822cb3163
4
+ data.tar.gz: eb464947796e011504c2b56d4f23d870b74569991d63e8bb56e1f3c6cde5803c
5
5
  SHA512:
6
- metadata.gz: be511c786fae03cf6f37f392bc122446101ddb7dee1ed7af52bd1d21b92e4512d8493687baa9fa842aef5460f1b6d750f83f7ad9e54b30a2c74a42a8b14971b7
7
- data.tar.gz: 8029a6c09870555dcf1d9235127ae1d8312e1cb226b93cf7428176f74efee991235158b2faf12b2b0dd7b7a83f7cfc705ffdfa9e2bb032edbcc8a65a6a0e2bd3
6
+ metadata.gz: 3bd7cf0127afe48ffde887f891237e8875db6c84e78ed77d95c800cd77c7c6a34626b81965f4661be34d73f13200c9a1bfb73caf7e3f0aeeb3441f13e641a96f
7
+ data.tar.gz: ae8f9671375e16ec060ac6952abad79c57f232011f799086322d3e409ce202076c94e546a2712b1b22401b0045832662438595e3b8e91129aa4504c8ff0500ff
data/.rubocop.yml CHANGED
@@ -3,8 +3,8 @@ inherit_from:
3
3
  - https://gitlab.com/bsm/misc/raw/master/rubocop/default.yml
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: "2.4"
6
+ TargetRubyVersion: "2.5"
7
7
 
8
8
  Naming/FileName:
9
9
  Exclude:
10
- - lib/searchable-by.rb
10
+ - lib/searchable-by.rb
data/.travis.yml CHANGED
@@ -2,7 +2,6 @@ language: ruby
2
2
  rvm:
3
3
  - 2.6
4
4
  - 2.5
5
- - 2.4
6
5
  cache: bundler
7
6
  before_install:
8
7
  - gem install bundler
data/Gemfile.lock CHANGED
@@ -1,58 +1,57 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- searchable-by (0.5.2)
4
+ searchable-by (0.5.4)
5
5
  activerecord
6
6
  activesupport
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- activemodel (5.2.3)
12
- activesupport (= 5.2.3)
13
- activerecord (5.2.3)
14
- activemodel (= 5.2.3)
15
- activesupport (= 5.2.3)
16
- arel (>= 9.0)
17
- activesupport (5.2.3)
11
+ activemodel (6.0.1)
12
+ activesupport (= 6.0.1)
13
+ activerecord (6.0.1)
14
+ activemodel (= 6.0.1)
15
+ activesupport (= 6.0.1)
16
+ activesupport (6.0.1)
18
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
18
  i18n (>= 0.7, < 2)
20
19
  minitest (~> 5.1)
21
20
  tzinfo (~> 1.1)
22
- arel (9.0.0)
21
+ zeitwerk (~> 2.2)
23
22
  ast (2.4.0)
24
23
  concurrent-ruby (1.1.5)
25
24
  diff-lcs (1.3)
26
- i18n (1.6.0)
25
+ i18n (1.7.0)
27
26
  concurrent-ruby (~> 1.0)
28
- jaro_winkler (1.5.3)
29
- minitest (5.11.3)
30
- parallel (1.17.0)
31
- parser (2.6.3.0)
27
+ jaro_winkler (1.5.4)
28
+ minitest (5.13.0)
29
+ parallel (1.18.0)
30
+ parser (2.6.5.0)
32
31
  ast (~> 2.4.0)
33
32
  rainbow (3.0.0)
34
- rake (12.3.3)
35
- rspec (3.8.0)
36
- rspec-core (~> 3.8.0)
37
- rspec-expectations (~> 3.8.0)
38
- rspec-mocks (~> 3.8.0)
39
- rspec-core (3.8.2)
40
- rspec-support (~> 3.8.0)
41
- rspec-expectations (3.8.4)
33
+ rake (13.0.1)
34
+ rspec (3.9.0)
35
+ rspec-core (~> 3.9.0)
36
+ rspec-expectations (~> 3.9.0)
37
+ rspec-mocks (~> 3.9.0)
38
+ rspec-core (3.9.0)
39
+ rspec-support (~> 3.9.0)
40
+ rspec-expectations (3.9.0)
42
41
  diff-lcs (>= 1.2.0, < 2.0)
43
- rspec-support (~> 3.8.0)
44
- rspec-mocks (3.8.1)
42
+ rspec-support (~> 3.9.0)
43
+ rspec-mocks (3.9.0)
45
44
  diff-lcs (>= 1.2.0, < 2.0)
46
- rspec-support (~> 3.8.0)
47
- rspec-support (3.8.2)
48
- rubocop (0.73.0)
45
+ rspec-support (~> 3.9.0)
46
+ rspec-support (3.9.0)
47
+ rubocop (0.76.0)
49
48
  jaro_winkler (~> 1.5.1)
50
49
  parallel (~> 1.10)
51
50
  parser (>= 2.6)
52
51
  rainbow (>= 2.2.2, < 4.0)
53
52
  ruby-progressbar (~> 1.7)
54
53
  unicode-display_width (>= 1.4.0, < 1.7)
55
- rubocop-performance (1.4.0)
54
+ rubocop-performance (1.5.0)
56
55
  rubocop (>= 0.71.0)
57
56
  ruby-progressbar (1.10.1)
58
57
  sqlite3 (1.4.1)
@@ -60,6 +59,7 @@ GEM
60
59
  tzinfo (1.2.5)
61
60
  thread_safe (~> 0.1)
62
61
  unicode-display_width (1.6.0)
62
+ zeitwerk (2.2.1)
63
63
 
64
64
  PLATFORMS
65
65
  ruby
@@ -74,4 +74,4 @@ DEPENDENCIES
74
74
  sqlite3
75
75
 
76
76
  BUNDLED WITH
77
- 2.0.1
77
+ 2.0.2
data/lib/searchable_by.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'active_record'
2
- require 'shellwords'
3
2
 
4
3
  module ActiveRecord
5
4
  module SearchableBy
@@ -42,19 +41,37 @@ module ActiveRecord
42
41
  end
43
42
  end
44
43
 
44
+ Value = Struct.new(:term, :negate)
45
+
45
46
  def self.norm_values(query)
46
- values = Shellwords.split(query.to_s)
47
- values.flatten!
48
- values.reject!(&:blank?)
47
+ values = []
48
+ query = query.to_s.dup
49
+
50
+ # capture any terms inside double quotes
51
+ # exclude from seach if preceded by '-'
52
+ query.gsub!(/([\-\+]?)"+([^"]*)"+/) do |_|
53
+ term = Regexp.last_match(2)
54
+ negate = Regexp.last_match(1) == '-'
55
+
56
+ values.push Value.new(term, negate) unless term.blank?
57
+ ''
58
+ end
59
+
60
+ # for the remaining terms remove sign if precedes
61
+ # exclude term from search if sign preceding is '-'
62
+ query.split(' ').each do |term|
63
+ negate = term[0] == '-'
64
+ term.slice!(0) if negate || term[0] == '+'
65
+
66
+ values.push Value.new(term, negate) unless term.blank?
67
+ end
68
+
49
69
  values.uniq!
50
70
  values
51
71
  end
52
72
 
53
73
  def self.build_clauses(columns, values)
54
74
  clauses = values.map do |value|
55
- negate = value[0] == '-'
56
- value.slice!(0) if negate || value[0] == '+'
57
-
58
75
  grouping = columns.map do |column|
59
76
  build_condition(column, value)
60
77
  end
@@ -62,7 +79,7 @@ module ActiveRecord
62
79
  next if grouping.empty?
63
80
 
64
81
  clause = grouping.inject(&:or)
65
- clause = clause.not if negate
82
+ clause = clause.not if value.negate
66
83
  clause
67
84
  end
68
85
  clauses.compact!
@@ -73,15 +90,15 @@ module ActiveRecord
73
90
  case column.type
74
91
  when :int, :integer
75
92
  begin
76
- column.node.not_eq(nil).and(column.node.eq(Integer(value)))
93
+ column.node.not_eq(nil).and(column.node.eq(Integer(value.term)))
77
94
  rescue ArgumentError
78
95
  nil
79
96
  end
80
97
  else
81
- value = value.dup
82
- value.gsub!('%', '\%')
83
- value.gsub!('_', '\_')
84
- column.node.not_eq(nil).and(column.node.matches("%#{value}%"))
98
+ term = value.term.dup
99
+ term.gsub!('%', '\%')
100
+ term.gsub!('_', '\_')
101
+ column.node.not_eq(nil).and(column.node.matches("%#{term}%"))
85
102
  end
86
103
  end
87
104
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'searchable-by'
3
- s.version = '0.5.2'
3
+ s.version = '0.5.4'
4
4
  s.authors = ['Dimitrij Denissenko']
5
5
  s.email = ['dimitrij@blacksquaremedia.com']
6
6
  s.summary = 'Generate search scopes'
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^spec/}) }
12
12
  s.test_files = `git ls-files -z -- spec/*`.split("\x0")
13
13
  s.require_paths = ['lib']
14
- s.required_ruby_version = '>= 2.4'
14
+ s.required_ruby_version = '>= 2.5'
15
15
 
16
16
  s.add_dependency 'activerecord'
17
17
  s.add_dependency 'activesupport'
@@ -1,6 +1,37 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ActiveRecord::SearchableBy do
4
+ context 'norm_values' do
5
+ def norm(str)
6
+ described_class.norm_values(str).each_with_object({}) do |val, acc|
7
+ acc[val.term] = val.negate
8
+ end
9
+ end
10
+
11
+ it 'should tokenise strings' do
12
+ expect(norm(nil)).to eq({})
13
+ expect(norm('""')).to eq({})
14
+ expect(norm('-+""')).to eq({})
15
+ expect(norm('simple words')).to eq('simple' => false, 'words' => false)
16
+ expect(norm(" with \t spaces\n")).to eq('with' => false, 'spaces' => false)
17
+ expect(norm('with with duplicates with')).to eq('with' => false, 'duplicates' => false)
18
+ expect(norm('with "full term"')).to eq('full term' => false, 'with' => false)
19
+ expect(norm('"""odd double quotes around"""')).to eq('odd double quotes around' => false)
20
+ expect(norm('""even double quotes around""')).to eq('even double quotes around'=> false)
21
+ expect(norm('with\'apostrophe')).to eq("with'apostrophe" => false)
22
+ expect(norm('with -minus')).to eq('minus' => true, 'with' => false)
23
+ expect(norm('with +plus')).to eq('plus' => false, 'with' => false)
24
+ expect(norm('with-minus')).to eq('with-minus' => false)
25
+ expect(norm('with+plus')).to eq('with+plus' => false)
26
+ expect(norm('with -"minus before"')).to eq('minus before' => true, 'with' => false)
27
+ expect(norm('with "-minus within"')).to eq('-minus within' => false, 'with' => false)
28
+ expect(norm('with +"plus before"')).to eq('plus before' => false, 'with' => false)
29
+ expect(norm('with "+plus within"')).to eq('+plus within' => false, 'with' => false)
30
+ expect(norm('+plus "in other term"')).to eq('in other term' => false, 'plus' => false)
31
+ expect(norm('with_blank \'\'')).to eq('with_blank' => false, '\'\'' => false)
32
+ expect(norm('with_blank_doubles ""')).to eq('with_blank_doubles' => false)
33
+ end
34
+ end
4
35
 
5
36
  it 'should ignore bad inputs' do
6
37
  expect(Post.search_by(nil).count).to eq(5)
data/spec/spec_helper.rb CHANGED
@@ -2,7 +2,7 @@ ENV['RACK_ENV'] ||= 'test'
2
2
  require 'searchable-by'
3
3
  require 'rspec'
4
4
 
5
- ActiveRecord::Base.configurations['test'] = { 'adapter' => 'sqlite3', 'database' => ':memory:' }
5
+ ActiveRecord::Base.configurations = { 'test' => { 'adapter' => 'sqlite3', 'database' => ':memory:' } }
6
6
  ActiveRecord::Base.establish_connection :test
7
7
 
8
8
  ActiveRecord::Base.connection.instance_eval do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchable-by
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-26 00:00:00.000000000 Z
11
+ date: 2019-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -154,14 +154,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
154
  requirements:
155
155
  - - ">="
156
156
  - !ruby/object:Gem::Version
157
- version: '2.4'
157
+ version: '2.5'
158
158
  required_rubygems_version: !ruby/object:Gem::Requirement
159
159
  requirements:
160
160
  - - ">="
161
161
  - !ruby/object:Gem::Version
162
162
  version: '0'
163
163
  requirements: []
164
- rubygems_version: 3.0.3
164
+ rubygems_version: 3.0.6
165
165
  signing_key:
166
166
  specification_version: 4
167
167
  summary: Generate search scopes