search_cop 1.1.0 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +50 -0
- data/.rubocop.yml +134 -0
- data/CHANGELOG.md +23 -9
- data/Gemfile +4 -5
- data/README.md +11 -1
- data/Rakefile +0 -1
- data/docker-compose.yml +8 -1
- data/gemfiles/{5.1.gemfile → rails5.gemfile} +2 -2
- data/gemfiles/rails6.gemfile +13 -0
- data/gemfiles/rails7.gemfile +13 -0
- data/lib/search_cop/grammar_parser.rb +1 -3
- data/lib/search_cop/hash_parser.rb +19 -19
- data/lib/search_cop/helpers.rb +15 -0
- data/lib/search_cop/query_builder.rb +1 -3
- data/lib/search_cop/query_info.rb +0 -2
- data/lib/search_cop/search_scope.rb +3 -5
- data/lib/search_cop/version.rb +1 -1
- data/lib/search_cop/visitors/mysql.rb +4 -2
- data/lib/search_cop/visitors/postgres.rb +5 -3
- data/lib/search_cop/visitors/visitor.rb +5 -3
- data/lib/search_cop/visitors.rb +0 -2
- data/lib/search_cop.rb +5 -23
- data/lib/search_cop_grammar/attributes.rb +45 -34
- data/lib/search_cop_grammar/nodes.rb +0 -2
- data/lib/search_cop_grammar.rb +1 -3
- data/search_cop.gemspec +8 -9
- data/test/and_test.rb +6 -8
- data/test/boolean_test.rb +7 -9
- data/test/database.yml +2 -1
- data/test/date_test.rb +14 -16
- data/test/datetime_test.rb +15 -17
- data/test/default_operator_test.rb +14 -10
- data/test/error_test.rb +2 -4
- data/test/float_test.rb +9 -11
- data/test/fulltext_test.rb +6 -8
- data/test/hash_test.rb +32 -34
- data/test/integer_test.rb +9 -11
- data/test/namespace_test.rb +23 -0
- data/test/not_test.rb +6 -8
- data/test/or_test.rb +8 -10
- data/test/scope_test.rb +11 -13
- data/test/search_cop_test.rb +41 -34
- data/test/string_test.rb +67 -19
- data/test/test_helper.rb +34 -15
- data/test/visitor_test.rb +4 -6
- metadata +34 -35
- data/.travis.yml +0 -34
- data/gemfiles/4.2.gemfile +0 -13
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "treetop"
|
3
2
|
|
4
3
|
module SearchCopGrammar
|
@@ -28,9 +27,9 @@ module SearchCopGrammar
|
|
28
27
|
end
|
29
28
|
|
30
29
|
[:eq, :not_eq, :lt, :lteq, :gt, :gteq].each do |method|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
define_method method do |value|
|
31
|
+
attributes.collect! { |attribute| attribute.send method, value }.inject(:or)
|
32
|
+
end
|
34
33
|
end
|
35
34
|
|
36
35
|
def generator(generator, value)
|
@@ -137,7 +136,7 @@ module SearchCopGrammar
|
|
137
136
|
false
|
138
137
|
end
|
139
138
|
|
140
|
-
{ :
|
139
|
+
{ eq: "Equality", not_eq: "NotEqual", lt: "LessThan", lteq: "LessThanOrEqual", gt: "GreaterThan", gteq: "GreaterThanOrEqual", matches: "Matches" }.each do |method, class_name|
|
141
140
|
define_method method do |value|
|
142
141
|
raise(SearchCop::IncompatibleDatatype, "Incompatible datatype for #{value}") unless compatible?(value)
|
143
142
|
|
@@ -146,19 +145,32 @@ module SearchCopGrammar
|
|
146
145
|
end
|
147
146
|
|
148
147
|
def method_missing(name, *args, &block)
|
149
|
-
@attribute.
|
148
|
+
if @attribute.respond_to?(name)
|
149
|
+
@attribute.send(name, *args, &block)
|
150
|
+
else
|
151
|
+
super
|
152
|
+
end
|
150
153
|
end
|
151
154
|
|
152
|
-
def
|
153
|
-
|
155
|
+
def respond_to_missing?(*args)
|
156
|
+
@attribute.respond_to?(*args) || super
|
154
157
|
end
|
155
158
|
end
|
156
159
|
|
157
160
|
class String < Base
|
158
161
|
def matches_value(value)
|
159
|
-
|
162
|
+
res = value.gsub(/[%_\\]/) { |char| "\\#{char}" }
|
160
163
|
|
161
|
-
|
164
|
+
if value.strip =~ /^\*|\*$/
|
165
|
+
res = res.gsub(/^\*/, "%") if options[:left_wildcard] != false
|
166
|
+
res = res.gsub(/\*$/, "%") if options[:right_wildcard] != false
|
167
|
+
|
168
|
+
return res
|
169
|
+
end
|
170
|
+
|
171
|
+
res = "%#{res}" if options[:left_wildcard] != false
|
172
|
+
res = "#{res}%" if options[:right_wildcard] != false
|
173
|
+
res
|
162
174
|
end
|
163
175
|
|
164
176
|
def matches(value)
|
@@ -176,7 +188,7 @@ module SearchCopGrammar
|
|
176
188
|
|
177
189
|
class Float < WithoutMatches
|
178
190
|
def compatible?(value)
|
179
|
-
return true if value.to_s =~
|
191
|
+
return true if value.to_s =~ /^-?[0-9]+(\.[0-9]+)?$/
|
180
192
|
|
181
193
|
false
|
182
194
|
end
|
@@ -196,24 +208,24 @@ module SearchCopGrammar
|
|
196
208
|
|
197
209
|
class Datetime < WithoutMatches
|
198
210
|
def parse(value)
|
199
|
-
return value
|
211
|
+
return value..value unless value.is_a?(::String)
|
200
212
|
|
201
213
|
if value =~ /^[0-9]+ (hour|day|week|month|year)s{0,1} (ago)$/
|
202
|
-
number,period,ago = value.split(
|
214
|
+
number, period, ago = value.split(" ")
|
203
215
|
time = number.to_i.send(period.to_sym).send(ago.to_sym)
|
204
|
-
time
|
216
|
+
time..::Time.now
|
205
217
|
elsif value =~ /^[0-9]{4}$/
|
206
|
-
::Time.new(value).beginning_of_year
|
207
|
-
elsif value =~
|
208
|
-
::Time.new(
|
209
|
-
elsif value =~
|
210
|
-
::Time.new(
|
211
|
-
elsif value =~
|
218
|
+
::Time.new(value).beginning_of_year..::Time.new(value).end_of_year
|
219
|
+
elsif value =~ %r{^([0-9]{4})(\.|-|/)([0-9]{1,2})$}
|
220
|
+
::Time.new(Regexp.last_match(1), Regexp.last_match(3), 15).beginning_of_month..::Time.new(Regexp.last_match(1), Regexp.last_match(3), 15).end_of_month
|
221
|
+
elsif value =~ %r{^([0-9]{1,2})(\.|-|/)([0-9]{4})$}
|
222
|
+
::Time.new(Regexp.last_match(3), Regexp.last_match(1), 15).beginning_of_month..::Time.new(Regexp.last_match(3), Regexp.last_match(1), 15).end_of_month
|
223
|
+
elsif value =~ %r{^[0-9]{4}(\.|-|/)[0-9]{1,2}(\.|-|/)[0-9]{1,2}$} || value =~ %r{^[0-9]{1,2}(\.|-|/)[0-9]{1,2}(\.|-|/)[0-9]{4}$}
|
212
224
|
time = ::Time.parse(value)
|
213
|
-
time.beginning_of_day
|
214
|
-
elsif value =~
|
225
|
+
time.beginning_of_day..time.end_of_day
|
226
|
+
elsif value =~ %r{[0-9]{4}(\.|-|/)[0-9]{1,2}(\.|-|/)[0-9]{1,2}} || value =~ %r{[0-9]{1,2}(\.|-|/)[0-9]{1,2}(\.|-|/)[0-9]{4}}
|
215
227
|
time = ::Time.parse(value)
|
216
|
-
time
|
228
|
+
time..time
|
217
229
|
else
|
218
230
|
raise ArgumentError
|
219
231
|
end
|
@@ -246,21 +258,21 @@ module SearchCopGrammar
|
|
246
258
|
|
247
259
|
class Date < Datetime
|
248
260
|
def parse(value)
|
249
|
-
return value
|
261
|
+
return value..value unless value.is_a?(::String)
|
250
262
|
|
251
263
|
if value =~ /^[0-9]+ (day|week|month|year)s{0,1} (ago)$/
|
252
|
-
number,period,ago = value.split(
|
264
|
+
number, period, ago = value.split(" ")
|
253
265
|
time = number.to_i.send(period.to_sym).send(ago.to_sym)
|
254
|
-
time.to_date
|
266
|
+
time.to_date..::Date.today
|
255
267
|
elsif value =~ /^[0-9]{4}$/
|
256
|
-
::Date.new(value.to_i).beginning_of_year
|
257
|
-
elsif value =~
|
258
|
-
::Date.new(
|
259
|
-
elsif value =~
|
260
|
-
::Date.new(
|
261
|
-
elsif value =~
|
268
|
+
::Date.new(value.to_i).beginning_of_year..::Date.new(value.to_i).end_of_year
|
269
|
+
elsif value =~ %r{^([0-9]{4})(\.|-|/)([0-9]{1,2})$}
|
270
|
+
::Date.new(Regexp.last_match(1).to_i, Regexp.last_match(3).to_i, 15).beginning_of_month..::Date.new(Regexp.last_match(1).to_i, Regexp.last_match(3).to_i, 15).end_of_month
|
271
|
+
elsif value =~ %r{^([0-9]{1,2})(\.|-|/)([0-9]{4})$}
|
272
|
+
::Date.new(Regexp.last_match(3).to_i, Regexp.last_match(1).to_i, 15).beginning_of_month..::Date.new(Regexp.last_match(3).to_i, Regexp.last_match(1).to_i, 15).end_of_month
|
273
|
+
elsif value =~ %r{[0-9]{4}(\.|-|/)[0-9]{1,2}(\.|-|/)[0-9]{1,2}} || value =~ %r{[0-9]{1,2}(\.|-|/)[0-9]{1,2}(\.|-|/)[0-9]{4}}
|
262
274
|
date = ::Date.parse(value)
|
263
|
-
date
|
275
|
+
date..date
|
264
276
|
else
|
265
277
|
raise ArgumentError
|
266
278
|
end
|
@@ -281,4 +293,3 @@ module SearchCopGrammar
|
|
281
293
|
end
|
282
294
|
end
|
283
295
|
end
|
284
|
-
|
data/lib/search_cop_grammar.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "search_cop_grammar/attributes"
|
3
2
|
require "search_cop_grammar/nodes"
|
4
3
|
|
@@ -19,7 +18,7 @@ module SearchCopGrammar
|
|
19
18
|
end
|
20
19
|
|
21
20
|
def elements
|
22
|
-
super.
|
21
|
+
super.reject { |element| element.instance_of?(Treetop::Runtime::SyntaxNode) }
|
23
22
|
end
|
24
23
|
|
25
24
|
def collection_for(key)
|
@@ -153,4 +152,3 @@ module SearchCopGrammar
|
|
153
152
|
|
154
153
|
class Value < BaseNode; end
|
155
154
|
end
|
156
|
-
|
data/search_cop.gemspec
CHANGED
@@ -1,28 +1,27 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "search_cop/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
spec.name = "search_cop"
|
8
7
|
spec.version = SearchCop::VERSION
|
9
8
|
spec.authors = ["Benjamin Vetter"]
|
10
9
|
spec.email = ["vetter@flakks.com"]
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
10
|
+
spec.description = "Search engine like fulltext query support for ActiveRecord"
|
11
|
+
spec.summary = "Easily perform complex search engine like fulltext queries on your ActiveRecord models"
|
13
12
|
spec.homepage = "https://github.com/mrkamel/search_cop"
|
14
13
|
spec.license = "MIT"
|
15
14
|
|
16
|
-
spec.files = `git ls-files`.split(
|
15
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
17
|
spec.require_paths = ["lib"]
|
20
18
|
|
21
19
|
spec.add_dependency "treetop"
|
22
20
|
|
23
|
-
spec.add_development_dependency "bundler"
|
24
|
-
spec.add_development_dependency "rake"
|
25
21
|
spec.add_development_dependency "activerecord", ">= 3.0.0"
|
22
|
+
spec.add_development_dependency "bundler"
|
26
23
|
spec.add_development_dependency "factory_bot"
|
27
24
|
spec.add_development_dependency "minitest"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rubocop"
|
28
27
|
end
|
data/test/and_test.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class AndTest < SearchCop::TestCase
|
5
4
|
def test_and_string
|
6
|
-
expected = create(:product, :
|
7
|
-
rejected = create(:product, :
|
5
|
+
expected = create(:product, title: "expected title", description: "Description")
|
6
|
+
rejected = create(:product, title: "Rejected title", description: "Description")
|
8
7
|
|
9
8
|
results = Product.search("title: 'Expected title' description: Description")
|
10
9
|
|
@@ -15,13 +14,12 @@ class AndTest < SearchCop::TestCase
|
|
15
14
|
end
|
16
15
|
|
17
16
|
def test_and_hash
|
18
|
-
expected = create(:product, :
|
19
|
-
rejected = create(:product, :
|
17
|
+
expected = create(:product, title: "Expected title", description: "Description")
|
18
|
+
rejected = create(:product, title: "Rejected title", description: "Description")
|
20
19
|
|
21
|
-
results = Product.search(:
|
20
|
+
results = Product.search(and: [{ title: "Expected title" }, { description: "Description" }])
|
22
21
|
|
23
22
|
assert_includes results, expected
|
24
23
|
refute_includes results, rejected
|
25
24
|
end
|
26
25
|
end
|
27
|
-
|
data/test/boolean_test.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class BooleanTest < SearchCop::TestCase
|
5
4
|
def test_mapping
|
6
|
-
product = create(:product, :
|
5
|
+
product = create(:product, available: true)
|
7
6
|
|
8
7
|
assert_includes Product.search("available: 1"), product
|
9
8
|
assert_includes Product.search("available: true"), product
|
10
9
|
assert_includes Product.search("available: yes"), product
|
11
10
|
|
12
|
-
product = create(:product, :
|
11
|
+
product = create(:product, available: false)
|
13
12
|
|
14
13
|
assert_includes Product.search("available: 0"), product
|
15
14
|
assert_includes Product.search("available: false"), product
|
@@ -17,28 +16,28 @@ class BooleanTest < SearchCop::TestCase
|
|
17
16
|
end
|
18
17
|
|
19
18
|
def test_anywhere
|
20
|
-
product = create(:product, :
|
19
|
+
product = create(:product, available: true)
|
21
20
|
|
22
21
|
assert_includes Product.search("true"), product
|
23
22
|
refute_includes Product.search("false"), product
|
24
23
|
end
|
25
24
|
|
26
25
|
def test_includes
|
27
|
-
product = create(:product, :
|
26
|
+
product = create(:product, available: true)
|
28
27
|
|
29
28
|
assert_includes Product.search("available: true"), product
|
30
29
|
refute_includes Product.search("available: false"), product
|
31
30
|
end
|
32
31
|
|
33
32
|
def test_equals
|
34
|
-
product = create(:product, :
|
33
|
+
product = create(:product, available: true)
|
35
34
|
|
36
35
|
assert_includes Product.search("available = true"), product
|
37
36
|
refute_includes Product.search("available = false"), product
|
38
37
|
end
|
39
38
|
|
40
39
|
def test_equals_not
|
41
|
-
product = create(:product, :
|
40
|
+
product = create(:product, available: false)
|
42
41
|
|
43
42
|
assert_includes Product.search("available != true"), product
|
44
43
|
refute_includes Product.search("available != false"), product
|
@@ -50,4 +49,3 @@ class BooleanTest < SearchCop::TestCase
|
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
53
|
-
|
data/test/database.yml
CHANGED
data/test/date_test.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class DateTest < SearchCop::TestCase
|
5
4
|
def test_mapping
|
6
|
-
product = create(:product, :
|
5
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
7
6
|
|
8
7
|
assert_includes Product.search("created_on: 2014"), product
|
9
8
|
assert_includes Product.search("created_on: 2014-05"), product
|
@@ -11,84 +10,84 @@ class DateTest < SearchCop::TestCase
|
|
11
10
|
end
|
12
11
|
|
13
12
|
def test_anywhere
|
14
|
-
product = create(:product, :
|
13
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
15
14
|
|
16
15
|
assert_includes Product.search("2014-05-01"), product
|
17
16
|
refute_includes Product.search("2014-05-02"), product
|
18
17
|
end
|
19
18
|
|
20
19
|
def test_includes
|
21
|
-
product = create(:product, :
|
20
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
22
21
|
|
23
22
|
assert_includes Product.search("created_on: 2014-05-01"), product
|
24
23
|
refute_includes Product.search("created_on: 2014-05-02"), product
|
25
24
|
end
|
26
25
|
|
27
26
|
def test_equals
|
28
|
-
product = create(:product, :
|
27
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
29
28
|
|
30
29
|
assert_includes Product.search("created_on = 2014-05-01"), product
|
31
30
|
refute_includes Product.search("created_on = 2014-05-02"), product
|
32
31
|
end
|
33
32
|
|
34
33
|
def test_equals_not
|
35
|
-
product = create(:product, :
|
34
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
36
35
|
|
37
36
|
assert_includes Product.search("created_on != 2014-05-02"), product
|
38
37
|
refute_includes Product.search("created_on != 2014-05-01"), product
|
39
38
|
end
|
40
39
|
|
41
40
|
def test_greater
|
42
|
-
product = create(:product, :
|
41
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
43
42
|
|
44
43
|
assert_includes Product.search("created_on > 2014-04-01"), product
|
45
44
|
refute_includes Product.search("created_on > 2014-05-01"), product
|
46
45
|
end
|
47
46
|
|
48
47
|
def test_greater_equals
|
49
|
-
product = create(:product, :
|
48
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
50
49
|
|
51
50
|
assert_includes Product.search("created_on >= 2014-05-01"), product
|
52
51
|
refute_includes Product.search("created_on >= 2014-05-02"), product
|
53
52
|
end
|
54
53
|
|
55
54
|
def test_less
|
56
|
-
product = create(:product, :
|
55
|
+
product = create(:product, created_on: Date.parse("2014-05-01"))
|
57
56
|
|
58
57
|
assert_includes Product.search("created_on < 2014-05-02"), product
|
59
58
|
refute_includes Product.search("created_on < 2014-05-01"), product
|
60
59
|
end
|
61
60
|
|
62
61
|
def test_less_equals
|
63
|
-
product = create(:product, :
|
62
|
+
product = create(:product, created_on: Date.parse("2014-05-02"))
|
64
63
|
|
65
64
|
assert_includes Product.search("created_on <= 2014-05-02"), product
|
66
65
|
refute_includes Product.search("created_on <= 2014-05-01"), product
|
67
66
|
end
|
68
67
|
|
69
68
|
def test_days_ago
|
70
|
-
product = create(:product, :
|
69
|
+
product = create(:product, created_at: 2.days.ago.to_date)
|
71
70
|
|
72
71
|
assert_includes Product.search("created_at <= '1 day ago'"), product
|
73
72
|
refute_includes Product.search("created_at <= '3 days ago'"), product
|
74
73
|
end
|
75
74
|
|
76
75
|
def test_weeks_ago
|
77
|
-
product = create(:product, :
|
76
|
+
product = create(:product, created_at: 2.weeks.ago.to_date)
|
78
77
|
|
79
78
|
assert_includes Product.search("created_at <= '1 weeks ago'"), product
|
80
79
|
refute_includes Product.search("created_at <= '3 weeks ago'"), product
|
81
80
|
end
|
82
81
|
|
83
82
|
def test_months_ago
|
84
|
-
product = create(:product, :
|
83
|
+
product = create(:product, created_at: 2.months.ago.to_date)
|
85
84
|
|
86
85
|
assert_includes Product.search("created_at <= '1 months ago'"), product
|
87
86
|
refute_includes Product.search("created_at <= '3 months ago'"), product
|
88
87
|
end
|
89
88
|
|
90
89
|
def test_years_ago
|
91
|
-
product = create(:product, :
|
90
|
+
product = create(:product, created_at: 2.years.ago.to_date)
|
92
91
|
|
93
92
|
assert_includes Product.search("created_at <= '1 years ago'"), product
|
94
93
|
refute_includes Product.search("created_at <= '3 years ago'"), product
|
@@ -106,4 +105,3 @@ class DateTest < SearchCop::TestCase
|
|
106
105
|
end
|
107
106
|
end
|
108
107
|
end
|
109
|
-
|
data/test/datetime_test.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class DatetimeTest < SearchCop::TestCase
|
5
4
|
def test_mapping
|
6
|
-
product = create(:product, :
|
5
|
+
product = create(:product, created_at: Time.parse("2014-05-01 12:30:30"))
|
7
6
|
|
8
7
|
assert_includes Product.search("created_at: 2014"), product
|
9
8
|
assert_includes Product.search("created_at: 2014-05"), product
|
@@ -12,91 +11,91 @@ class DatetimeTest < SearchCop::TestCase
|
|
12
11
|
end
|
13
12
|
|
14
13
|
def test_anywhere
|
15
|
-
product = create(:product, :
|
14
|
+
product = create(:product, created_at: Time.parse("2014-05-01"))
|
16
15
|
|
17
16
|
assert_includes Product.search("2014-05-01"), product
|
18
17
|
refute_includes Product.search("2014-05-02"), product
|
19
18
|
end
|
20
19
|
|
21
20
|
def test_includes
|
22
|
-
product = create(:product, :
|
21
|
+
product = create(:product, created_at: Time.parse("2014-05-01"))
|
23
22
|
|
24
23
|
assert_includes Product.search("created_at: 2014-05-01"), product
|
25
24
|
refute_includes Product.search("created_at: 2014-05-02"), product
|
26
25
|
end
|
27
26
|
|
28
27
|
def test_equals
|
29
|
-
product = create(:product, :
|
28
|
+
product = create(:product, created_at: Time.parse("2014-05-01"))
|
30
29
|
|
31
30
|
assert_includes Product.search("created_at = 2014-05-01"), product
|
32
31
|
refute_includes Product.search("created_at = 2014-05-02"), product
|
33
32
|
end
|
34
33
|
|
35
34
|
def test_equals_not
|
36
|
-
product = create(:product, :
|
35
|
+
product = create(:product, created_at: Time.parse("2014-05-01"))
|
37
36
|
|
38
37
|
assert_includes Product.search("created_at != 2014-05-02"), product
|
39
38
|
refute_includes Product.search("created_at != 2014-05-01"), product
|
40
39
|
end
|
41
40
|
|
42
41
|
def test_greater
|
43
|
-
product = create(:product, :
|
42
|
+
product = create(:product, created_at: Time.parse("2014-05-01"))
|
44
43
|
|
45
44
|
assert_includes Product.search("created_at > 2014-04-01"), product
|
46
45
|
refute_includes Product.search("created_at > 2014-05-01"), product
|
47
46
|
end
|
48
47
|
|
49
48
|
def test_greater_equals
|
50
|
-
product = create(:product, :
|
49
|
+
product = create(:product, created_at: Time.parse("2014-05-01"))
|
51
50
|
|
52
51
|
assert_includes Product.search("created_at >= 2014-05-01"), product
|
53
52
|
refute_includes Product.search("created_at >= 2014-05-02"), product
|
54
53
|
end
|
55
54
|
|
56
55
|
def test_less
|
57
|
-
product = create(:product, :
|
56
|
+
product = create(:product, created_at: Time.parse("2014-05-01"))
|
58
57
|
|
59
58
|
assert_includes Product.search("created_at < 2014-05-02"), product
|
60
59
|
refute_includes Product.search("created_at < 2014-05-01"), product
|
61
60
|
end
|
62
61
|
|
63
62
|
def test_less_equals
|
64
|
-
product = create(:product, :
|
63
|
+
product = create(:product, created_at: Time.parse("2014-05-02"))
|
65
64
|
|
66
65
|
assert_includes Product.search("created_at <= 2014-05-02"), product
|
67
66
|
refute_includes Product.search("created_at <= 2014-05-01"), product
|
68
67
|
end
|
69
68
|
|
70
69
|
def test_hours_ago
|
71
|
-
product = create(:product, :
|
70
|
+
product = create(:product, created_at: 5.hours.ago)
|
72
71
|
|
73
72
|
assert_includes Product.search("created_at <= '4 hours ago'"), product
|
74
73
|
refute_includes Product.search("created_at <= '6 hours ago'"), product
|
75
74
|
end
|
76
75
|
|
77
76
|
def test_days_ago
|
78
|
-
product = create(:product, :
|
77
|
+
product = create(:product, created_at: 2.days.ago)
|
79
78
|
|
80
79
|
assert_includes Product.search("created_at <= '1 day ago'"), product
|
81
80
|
refute_includes Product.search("created_at <= '3 days ago'"), product
|
82
81
|
end
|
83
82
|
|
84
83
|
def test_weeks_ago
|
85
|
-
product = create(:product, :
|
84
|
+
product = create(:product, created_at: 2.weeks.ago)
|
86
85
|
|
87
86
|
assert_includes Product.search("created_at <= '1 weeks ago'"), product
|
88
87
|
refute_includes Product.search("created_at <= '3 weeks ago'"), product
|
89
88
|
end
|
90
89
|
|
91
90
|
def test_months_ago
|
92
|
-
product = create(:product, :
|
91
|
+
product = create(:product, created_at: 2.months.ago)
|
93
92
|
|
94
93
|
assert_includes Product.search("created_at <= '1 months ago'"), product
|
95
94
|
refute_includes Product.search("created_at <= '3 months ago'"), product
|
96
95
|
end
|
97
96
|
|
98
97
|
def test_years_ago
|
99
|
-
product = create(:product, :
|
98
|
+
product = create(:product, created_at: 2.years.ago)
|
100
99
|
|
101
100
|
assert_includes Product.search("created_at <= '1 years ago'"), product
|
102
101
|
refute_includes Product.search("created_at <= '3 years ago'"), product
|
@@ -114,4 +113,3 @@ class DatetimeTest < SearchCop::TestCase
|
|
114
113
|
end
|
115
114
|
end
|
116
115
|
end
|
117
|
-
|
@@ -1,7 +1,6 @@
|
|
1
|
-
require File.expand_path(
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
2
2
|
|
3
3
|
class DefaultOperatorTest < SearchCop::TestCase
|
4
|
-
|
5
4
|
def test_without_default_operator
|
6
5
|
avengers = create(:product, title: "Title Avengers", description: "2012")
|
7
6
|
inception = create(:product, title: "Title Inception", description: "2010")
|
@@ -25,23 +24,28 @@ class DefaultOperatorTest < SearchCop::TestCase
|
|
25
24
|
|
26
25
|
def test_with_specific_default_operator
|
27
26
|
matrix = create(:product, title: "Matrix", description: "1999 Fantasy Sci-fi 2h 30m")
|
28
|
-
|
27
|
+
star_wars = create(:product, title: "Star Wars", description: "2010 Sci-fi Thriller 2h 28m")
|
28
|
+
|
29
|
+
results = Product.search("Star Wars", default_operator: "AND")
|
30
|
+
refute_includes results, matrix
|
31
|
+
assert_includes results, star_wars
|
29
32
|
|
30
|
-
results = Product.search_multi_columns("Matrix movie", default_operator:
|
33
|
+
results = Product.search_multi_columns("Matrix movie", default_operator: "OR")
|
31
34
|
assert_includes results, matrix
|
32
|
-
refute_includes results,
|
35
|
+
refute_includes results, star_wars
|
33
36
|
|
34
|
-
results = Product.search(title: "Matrix", description: "2000", default_operator: :or)
|
37
|
+
results = Product.search({ title: "Matrix", description: "2000" }, default_operator: :or)
|
35
38
|
assert_includes results, matrix
|
36
|
-
refute_includes results,
|
39
|
+
refute_includes results, star_wars
|
37
40
|
end
|
38
41
|
|
39
42
|
def test_with_invalid_default_operator
|
40
43
|
assert_raises SearchCop::UnknownDefaultOperator do
|
41
|
-
Product.search_multi_columns(
|
44
|
+
Product.search_multi_columns("Matrix movie", default_operator: :xpto)
|
42
45
|
end
|
46
|
+
|
43
47
|
assert_raises SearchCop::UnknownDefaultOperator do
|
44
|
-
Product.search_multi_columns(title:
|
48
|
+
Product.search_multi_columns({ title: "Matrix movie" }, default_operator: :xpto)
|
45
49
|
end
|
46
50
|
end
|
47
|
-
end
|
51
|
+
end
|
data/test/error_test.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class ErrorTest < SearchCop::TestCase
|
5
4
|
def test_parse_error
|
6
5
|
assert_raises SearchCop::ParseError do
|
7
|
-
Product.unsafe_search :
|
6
|
+
Product.unsafe_search title: { unknown_operator: "Value" }
|
8
7
|
end
|
9
8
|
end
|
10
9
|
|
@@ -14,4 +13,3 @@ class ErrorTest < SearchCop::TestCase
|
|
14
13
|
end
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|