search_cop 1.1.0 → 1.2.2
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.
- 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
|
-
|