search_cop 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.travis.yml +33 -0
- data/Appraisals +14 -0
- data/Gemfile +23 -0
- data/LICENSE.txt +22 -0
- data/MIGRATION.md +66 -0
- data/README.md +530 -0
- data/Rakefile +9 -0
- data/gemfiles/3.2.gemfile +26 -0
- data/gemfiles/4.0.gemfile +26 -0
- data/gemfiles/4.1.gemfile +26 -0
- data/lib/search_cop/arel/visitors.rb +223 -0
- data/lib/search_cop/arel.rb +4 -0
- data/lib/search_cop/grammar_parser.rb +22 -0
- data/lib/search_cop/hash_parser.rb +42 -0
- data/lib/search_cop/query_builder.rb +26 -0
- data/lib/search_cop/query_info.rb +13 -0
- data/lib/search_cop/search_scope.rb +62 -0
- data/lib/search_cop/version.rb +3 -0
- data/lib/search_cop.rb +71 -0
- data/lib/search_cop_grammar/attributes.rb +229 -0
- data/lib/search_cop_grammar/nodes.rb +183 -0
- data/lib/search_cop_grammar.rb +133 -0
- data/lib/search_cop_grammar.treetop +55 -0
- data/search_cop.gemspec +29 -0
- data/test/and_test.rb +27 -0
- data/test/boolean_test.rb +53 -0
- data/test/database.yml +17 -0
- data/test/date_test.rb +75 -0
- data/test/datetime_test.rb +76 -0
- data/test/error_test.rb +17 -0
- data/test/float_test.rb +67 -0
- data/test/fulltext_test.rb +27 -0
- data/test/hash_test.rb +97 -0
- data/test/integer_test.rb +67 -0
- data/test/not_test.rb +27 -0
- data/test/or_test.rb +29 -0
- data/test/scope_test.rb +35 -0
- data/test/search_cop_test.rb +131 -0
- data/test/string_test.rb +84 -0
- data/test/test_helper.rb +150 -0
- metadata +216 -0
data/test/float_test.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class FloatTest < SearchCop::TestCase
|
5
|
+
def test_anywhere
|
6
|
+
product = create(:product, :price => 10.5, :created_at => Time.now - 1.day)
|
7
|
+
|
8
|
+
assert_includes Product.search("10.5"), product
|
9
|
+
refute_includes Product.search("11.5"), product
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_includes
|
13
|
+
product = create(:product, :price => 10.5)
|
14
|
+
|
15
|
+
assert_includes Product.search("price: 10.5"), product
|
16
|
+
refute_includes Product.search("price: 11.5"), product
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_equals
|
20
|
+
product = create(:product, :price => 10.5)
|
21
|
+
|
22
|
+
assert_includes Product.search("price = 10.5"), product
|
23
|
+
refute_includes Product.search("price = 11.5"), product
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_equals_not
|
27
|
+
product = create(:product, :price => 10.5)
|
28
|
+
|
29
|
+
assert_includes Product.search("price != 11.5"), product
|
30
|
+
refute_includes Product.search("price != 10.5"), product
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_greater
|
34
|
+
product = create(:product, :price => 10.5)
|
35
|
+
|
36
|
+
assert_includes Product.search("price > 10.4"), product
|
37
|
+
refute_includes Product.search("price < 10.5"), product
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_greater_equals
|
41
|
+
product = create(:product, :price => 10.5)
|
42
|
+
|
43
|
+
assert_includes Product.search("price >= 10.5"), product
|
44
|
+
refute_includes Product.search("price >= 10.6"), product
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_less
|
48
|
+
product = create(:product, :price => 10.5)
|
49
|
+
|
50
|
+
assert_includes Product.search("price < 10.6"), product
|
51
|
+
refute_includes Product.search("price < 10.5"), product
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_less_equals
|
55
|
+
product = create(:product, :price => 10.5)
|
56
|
+
|
57
|
+
assert_includes Product.search("price <= 10.5"), product
|
58
|
+
refute_includes Product.search("price <= 10.4"), product
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_incompatible_datatype
|
62
|
+
assert_raises SearchCop::IncompatibleDatatype do
|
63
|
+
Product.unsafe_search "price: Value"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class FulltextTest < SearchCop::TestCase
|
5
|
+
def test_complex
|
6
|
+
product1 = create(:product, :title => "word1")
|
7
|
+
product2 = create(:product, :title => "word2 word3")
|
8
|
+
product3 = create(:product, :title => "word2")
|
9
|
+
|
10
|
+
results = Product.search("title:word1 OR (title:word2 -title:word3)")
|
11
|
+
|
12
|
+
assert_includes results, product1
|
13
|
+
refute_includes results, product2
|
14
|
+
assert_includes results, product3
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_mixed
|
18
|
+
expected = create(:product, :title => "Expected title", :stock => 1)
|
19
|
+
rejected = create(:product, :title => "Expected title", :stock => 0)
|
20
|
+
|
21
|
+
results = Product.search("title:Expected title:Title stock > 0")
|
22
|
+
|
23
|
+
assert_includes results, expected
|
24
|
+
refute_includes results, rejected
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
data/test/hash_test.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class HashTest < SearchCop::TestCase
|
5
|
+
def test_subquery
|
6
|
+
product1 = create(:product, :title => "Title1", :description => "Description")
|
7
|
+
product2 = create(:product, :title => "Title2", :description => "Description")
|
8
|
+
product3 = create(:product, :title => "TItle3", :description => "Description")
|
9
|
+
|
10
|
+
results = Product.search(:or => [{ :query => "Description Title1" }, { :query => "Description Title2" }])
|
11
|
+
|
12
|
+
assert_includes results, product1
|
13
|
+
assert_includes results, product2
|
14
|
+
refute_includes results, product3
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_matches
|
18
|
+
expected = create(:product, :title => "Expected")
|
19
|
+
rejected = create(:product, :title => "Rejected")
|
20
|
+
|
21
|
+
results = Product.search(:title => { :matches => "Expected" })
|
22
|
+
|
23
|
+
assert_includes results, expected
|
24
|
+
refute_includes results, rejected
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_matches_default
|
28
|
+
expected = create(:product, :title => "Expected")
|
29
|
+
rejected = create(:product, :title => "Rejected")
|
30
|
+
|
31
|
+
results = Product.search(:title => "Expected")
|
32
|
+
|
33
|
+
assert_includes results, expected
|
34
|
+
refute_includes results, rejected
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_eq
|
38
|
+
expected = create(:product, :title => "Expected")
|
39
|
+
rejected = create(:product, :title => "Rejected")
|
40
|
+
|
41
|
+
results = Product.search(:title => { :eq => "Expected" })
|
42
|
+
|
43
|
+
assert_includes results, expected
|
44
|
+
refute_includes results, rejected
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_not_eq
|
48
|
+
expected = create(:product, :title => "Expected")
|
49
|
+
rejected = create(:product, :title => "Rejected")
|
50
|
+
|
51
|
+
results = Product.search(:title => { :not_eq => "Rejected" })
|
52
|
+
|
53
|
+
assert_includes results, expected
|
54
|
+
refute_includes results, rejected
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_gt
|
58
|
+
expected = create(:product, :stock => 1)
|
59
|
+
rejected = create(:product, :stock => 0)
|
60
|
+
|
61
|
+
results = Product.search(:stock => { :gt => 0 })
|
62
|
+
|
63
|
+
assert_includes results, expected
|
64
|
+
refute_includes results, rejected
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_gteq
|
68
|
+
expected = create(:product, :stock => 1)
|
69
|
+
rejected = create(:product, :stock => 0)
|
70
|
+
|
71
|
+
results = Product.search(:stock => { :gteq => 1 })
|
72
|
+
|
73
|
+
assert_includes results, expected
|
74
|
+
refute_includes results, rejected
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_lt
|
78
|
+
expected = create(:product, :stock => 0)
|
79
|
+
rejected = create(:product, :stock => 1)
|
80
|
+
|
81
|
+
results = Product.search(:stock => { :lt => 1 })
|
82
|
+
|
83
|
+
assert_includes results, expected
|
84
|
+
refute_includes results, rejected
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_lteq
|
88
|
+
expected = create(:product, :stock => 0)
|
89
|
+
rejected = create(:product, :stock => 1)
|
90
|
+
|
91
|
+
results = Product.search(:stock => { :lteq => 0 })
|
92
|
+
|
93
|
+
assert_includes results, expected
|
94
|
+
refute_includes results, rejected
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class IntegerTest < SearchCop::TestCase
|
5
|
+
def test_anywhere
|
6
|
+
product = create(:product, :stock => 1)
|
7
|
+
|
8
|
+
assert_includes Product.search("1"), product
|
9
|
+
refute_includes Product.search("0"), product
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_includes
|
13
|
+
product = create(:product, :stock => 1)
|
14
|
+
|
15
|
+
assert_includes Product.search("stock: 1"), product
|
16
|
+
refute_includes Product.search("stock: 10"), product
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_equals
|
20
|
+
product = create(:product, :stock => 1)
|
21
|
+
|
22
|
+
assert_includes Product.search("stock = 1"), product
|
23
|
+
refute_includes Product.search("stock = 0"), product
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_equals_not
|
27
|
+
product = create(:product, :stock => 1)
|
28
|
+
|
29
|
+
assert_includes Product.search("stock != 0"), product
|
30
|
+
refute_includes Product.search("stock != 1"), product
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_greater
|
34
|
+
product = create(:product, :stock => 1)
|
35
|
+
|
36
|
+
assert_includes Product.search("stock > 0"), product
|
37
|
+
refute_includes Product.search("stock < 1"), product
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_greater_equals
|
41
|
+
product = create(:product, :stock => 1)
|
42
|
+
|
43
|
+
assert_includes Product.search("stock >= 1"), product
|
44
|
+
refute_includes Product.search("stock >= 2"), product
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_less
|
48
|
+
product = create(:product, :stock => 1)
|
49
|
+
|
50
|
+
assert_includes Product.search("stock < 2"), product
|
51
|
+
refute_includes Product.search("stock < 1"), product
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_less_equals
|
55
|
+
product = create(:product, :stock => 1)
|
56
|
+
|
57
|
+
assert_includes Product.search("stock <= 1"), product
|
58
|
+
refute_includes Product.search("stock <= 0"), product
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_incompatible_datatype
|
62
|
+
assert_raises SearchCop::IncompatibleDatatype do
|
63
|
+
Product.unsafe_search "stock: Value"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
data/test/not_test.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class NotTest < SearchCop::TestCase
|
5
|
+
def test_not_string
|
6
|
+
expected = create(:product, :title => "Expected title")
|
7
|
+
rejected = create(:product, :title => "Rejected title")
|
8
|
+
|
9
|
+
results = Product.search("title: Title NOT title: Rejected")
|
10
|
+
|
11
|
+
assert_includes results, expected
|
12
|
+
refute_includes results, rejected
|
13
|
+
|
14
|
+
assert_equal results, Product.search("title: Title -title: Rejected")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_not_hash
|
18
|
+
expected = create(:product, :title => "Expected title")
|
19
|
+
rejected = create(:product, :title => "Rejected title")
|
20
|
+
|
21
|
+
results = Product.search(:and => [{:title => "Title"}, {:not => {:title => "Rejected"}}])
|
22
|
+
|
23
|
+
assert_includes results, expected
|
24
|
+
refute_includes results, rejected
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
data/test/or_test.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class OrTest < SearchCop::TestCase
|
5
|
+
def test_or_string
|
6
|
+
product1 = create(:product, :title => "Title1")
|
7
|
+
product2 = create(:product, :title => "Title2")
|
8
|
+
product3 = create(:product, :title => "Title3")
|
9
|
+
|
10
|
+
results = Product.search("title: Title1 OR title: Title2")
|
11
|
+
|
12
|
+
assert_includes results, product1
|
13
|
+
assert_includes results, product2
|
14
|
+
refute_includes results, product3
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_or_hash
|
18
|
+
product1 = create(:product, :title => "Title1")
|
19
|
+
product2 = create(:product, :title => "Title2")
|
20
|
+
product3 = create(:product, :title => "Title3")
|
21
|
+
|
22
|
+
results = Product.search(:or => [{:title => "Title1"}, {:title => "Title2"}])
|
23
|
+
|
24
|
+
assert_includes results, product1
|
25
|
+
assert_includes results, product2
|
26
|
+
refute_includes results, product3
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/test/scope_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class ScopeTest < SearchCop::TestCase
|
5
|
+
def test_user_search
|
6
|
+
expected = create(:product, :title => "Expected")
|
7
|
+
rejected = create(:product, :notice => "Expected")
|
8
|
+
|
9
|
+
results = Product.user_search("Expected")
|
10
|
+
|
11
|
+
assert_includes results, expected
|
12
|
+
refute_includes results, rejected
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_options
|
16
|
+
expected = create(:product, :title => "Expected")
|
17
|
+
rejected = create(:product, :description => "Expected")
|
18
|
+
|
19
|
+
results = Product.user_search("Expected")
|
20
|
+
|
21
|
+
assert_includes results, expected
|
22
|
+
refute_includes results, rejected
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_aliases
|
26
|
+
expected = create(:product, :comments => [create(:comment, :user => create(:user, :username => "Expected"))])
|
27
|
+
rejected = create(:product, :comments => [create(:comment, :user => create(:user, :username => "Rejected"))])
|
28
|
+
|
29
|
+
results = Product.search("user: Expected")
|
30
|
+
|
31
|
+
assert_includes results, expected
|
32
|
+
refute_includes results, rejected
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,131 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class SearchCopTest < SearchCop::TestCase
|
5
|
+
def test_scope_before
|
6
|
+
expected = create(:product, :stock => 1, :title => "Title")
|
7
|
+
rejected = create(:product, :stock => 0, :title => "Title")
|
8
|
+
|
9
|
+
results = Product.where(:stock => 1).search("Title")
|
10
|
+
|
11
|
+
assert_includes results, expected
|
12
|
+
refute_includes results, rejected
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_scope_after
|
16
|
+
expected = create(:product, :stock => 1, :title => "Title")
|
17
|
+
rejected = create(:product, :stock => 0, :title => "Title")
|
18
|
+
|
19
|
+
results = Product.search("Title").where(:stock => 1)
|
20
|
+
|
21
|
+
assert_includes results, expected
|
22
|
+
refute_includes results, rejected
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_scope
|
26
|
+
expected = create(:product, :stock => 1, :title => "Title")
|
27
|
+
rejected = create(:product, :stock => 0, :title => "Title")
|
28
|
+
|
29
|
+
results = with_scope(Product.search_scopes[:search], lambda { where :stock => 1 }) { Product.search("title: Title") }
|
30
|
+
|
31
|
+
assert_includes results, expected
|
32
|
+
refute_includes results, rejected
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_multi_associations
|
36
|
+
product = create(:product, :comments => [
|
37
|
+
create(:comment, :title => "Title1", :message => "Message1"),
|
38
|
+
create(:comment, :title => "Title2", :message => "Message2")
|
39
|
+
])
|
40
|
+
|
41
|
+
assert_includes Product.search("comment: Title1 comment: Message1"), product
|
42
|
+
assert_includes Product.search("comment: Title2 comment: Message2"), product
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_single_association
|
46
|
+
expected = create(:comment, :user => create(:user, :username => "Expected"))
|
47
|
+
rejected = create(:comment, :user => create(:user, :username => "Rejected"))
|
48
|
+
|
49
|
+
results = Comment.search("user: Expected")
|
50
|
+
|
51
|
+
assert_includes results, expected
|
52
|
+
refute_includes results, rejected
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_deep_associations
|
56
|
+
expected = create(:product, :comments => [create(:comment, :user => create(:user, :username => "Expected"))])
|
57
|
+
rejected = create(:product, :comments => [create(:comment, :user => create(:user, :username => "Rejected"))])
|
58
|
+
|
59
|
+
results = Product.search("user: Expected")
|
60
|
+
|
61
|
+
assert_includes results, expected
|
62
|
+
refute_includes results, rejected
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_multiple
|
66
|
+
product = create(:product, :comments => [create(:comment, :title => "Title", :message => "Message")])
|
67
|
+
|
68
|
+
assert_includes Product.search("comment: Title"), product
|
69
|
+
assert_includes Product.search("comment: Message"), product
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_default
|
73
|
+
product1 = create(:product, :title => "Expected")
|
74
|
+
product2 = create(:product, :description => "Expected")
|
75
|
+
|
76
|
+
results = Product.search("Expected")
|
77
|
+
|
78
|
+
assert_includes results, product1
|
79
|
+
assert_includes results, product2
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_custom_default_enabled
|
83
|
+
product1 = create(:product, :title => "Expected")
|
84
|
+
product2 = create(:product, :description => "Expected")
|
85
|
+
product3 = create(:product, :brand => "Expected")
|
86
|
+
|
87
|
+
results = with_options(Product.search_scopes[:search], :primary, :default => true) { Product.search "Expected" }
|
88
|
+
|
89
|
+
assert_includes results, product1
|
90
|
+
assert_includes results, product2
|
91
|
+
refute_includes results, product3
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_custom_default_disabled
|
95
|
+
product1 = create(:product, :brand => "Expected")
|
96
|
+
product2 = create(:product, :notice => "Expected")
|
97
|
+
|
98
|
+
results = with_options(Product.search_scopes[:search], :notice, :default => false) { Product.search "Expected" }
|
99
|
+
|
100
|
+
assert_includes results, product1
|
101
|
+
refute_includes results, product2
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_count
|
105
|
+
create_list :product, 2, :title => "Expected"
|
106
|
+
|
107
|
+
assert_equal 2, Product.search("Expected").count
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_default_attributes_true
|
111
|
+
with_options(Product.search_scopes[:search], :title, :default => true) do
|
112
|
+
with_options(Product.search_scopes[:search], :description, :default => true) do
|
113
|
+
assert_equal ["title", "description"], Product.search_scopes[:search].reflection.default_attributes.keys
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_default_attributes_fales
|
119
|
+
with_options(Product.search_scopes[:search], :title, :default => false) do
|
120
|
+
with_options(Product.search_scopes[:search], :description, :default => false) do
|
121
|
+
assert_equal Product.search_scopes[:search].reflection.attributes.keys - ["title", "description"], Product.search_scopes[:search].reflection.default_attributes.keys
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_search_reflection
|
127
|
+
assert_not_nil Product.search_reflection(:search)
|
128
|
+
assert_not_nil Product.search_reflection(:user_search)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
data/test/string_test.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class StringTest < SearchCop::TestCase
|
5
|
+
def test_anywhere
|
6
|
+
product = create(:product, :title => "Expected title")
|
7
|
+
|
8
|
+
assert_includes Product.search("Expected"), product
|
9
|
+
refute_includes Product.search("Rejected"), product
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_multiple
|
13
|
+
product = create(:product, :comments => [create(:comment, :title => "Expected title", :message => "Expected message")])
|
14
|
+
|
15
|
+
assert_includes Product.search("Expected"), product
|
16
|
+
refute_includes Product.search("Rejected"), product
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_includes
|
20
|
+
product = create(:product, :title => "Expected")
|
21
|
+
|
22
|
+
assert_includes Product.search("title: Expected"), product
|
23
|
+
refute_includes Product.search("title: Rejected"), product
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_includes_with_left_wildcard
|
27
|
+
product = create(:product, :title => "Some title")
|
28
|
+
|
29
|
+
assert_includes Product.search("title: Title"), product
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_includes_without_left_wildcard
|
33
|
+
expected = create(:product, :brand => "Brand")
|
34
|
+
rejected = create(:product, :brand => "Rejected brand")
|
35
|
+
|
36
|
+
results = with_options(Product.search_scopes[:search], :brand, :left_wildcard => false) { Product.search "brand: Brand" }
|
37
|
+
|
38
|
+
assert_includes results, expected
|
39
|
+
refute_includes results, rejected
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_equals
|
43
|
+
product = create(:product, :title => "Expected title")
|
44
|
+
|
45
|
+
assert_includes Product.search("title = 'Expected title'"), product
|
46
|
+
refute_includes Product.search("title = Expected"), product
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_equals_not
|
50
|
+
product = create(:product, :title => "Expected")
|
51
|
+
|
52
|
+
assert_includes Product.search("title != Rejected"), product
|
53
|
+
refute_includes Product.search("title != Expected"), product
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_greater
|
57
|
+
product = create(:product, :title => "Title B")
|
58
|
+
|
59
|
+
assert_includes Product.search("title > 'Title A'"), product
|
60
|
+
refute_includes Product.search("title > 'Title B'"), product
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_greater_equals
|
64
|
+
product = create(:product, :title => "Title A")
|
65
|
+
|
66
|
+
assert_includes Product.search("title >= 'Title A'"), product
|
67
|
+
refute_includes Product.search("title >= 'Title B'"), product
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_less
|
71
|
+
product = create(:product, :title => "Title A")
|
72
|
+
|
73
|
+
assert_includes Product.search("title < 'Title B'"), product
|
74
|
+
refute_includes Product.search("title < 'Title A'"), product
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_less_or_greater
|
78
|
+
product = create(:product, :title => "Title B")
|
79
|
+
|
80
|
+
assert_includes Product.search("title <= 'Title B'"), product
|
81
|
+
refute_includes Product.search("title <= 'Title A'"), product
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|