search_cop 1.0.9 → 1.2.1
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 +5 -5
- data/.github/workflows/test.yml +50 -0
- data/.rubocop.yml +134 -0
- data/CHANGELOG.md +29 -7
- data/Gemfile +4 -17
- data/README.md +69 -3
- data/Rakefile +0 -1
- data/docker-compose.yml +18 -0
- data/gemfiles/rails5.gemfile +13 -0
- data/gemfiles/rails6.gemfile +13 -0
- data/gemfiles/rails7.gemfile +13 -0
- data/lib/search_cop/grammar_parser.rb +3 -4
- data/lib/search_cop/hash_parser.rb +20 -18
- data/lib/search_cop/helpers.rb +15 -0
- data/lib/search_cop/query_builder.rb +3 -5
- data/lib/search_cop/query_info.rb +0 -2
- data/lib/search_cop/search_scope.rb +2 -4
- 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 +7 -5
- data/lib/search_cop/visitors.rb +0 -2
- data/lib/search_cop.rb +15 -13
- data/lib/search_cop_grammar/attributes.rb +53 -34
- data/lib/search_cop_grammar/nodes.rb +0 -2
- data/lib/search_cop_grammar.rb +13 -4
- data/lib/search_cop_grammar.treetop +6 -4
- data/search_cop.gemspec +9 -11
- data/test/and_test.rb +6 -8
- data/test/boolean_test.rb +7 -9
- data/test/database.yml +4 -1
- data/test/date_test.rb +38 -12
- data/test/datetime_test.rb +45 -12
- data/test/default_operator_test.rb +51 -0
- data/test/error_test.rb +2 -4
- data/test/float_test.rb +16 -11
- data/test/fulltext_test.rb +6 -8
- data/test/hash_test.rb +32 -34
- data/test/integer_test.rb +9 -11
- 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 +42 -36
- data/test/string_test.rb +67 -19
- data/test/test_helper.rb +28 -18
- data/test/visitor_test.rb +4 -6
- metadata +25 -42
- data/.travis.yml +0 -45
- data/Appraisals +0 -21
- data/gemfiles/3.2.gemfile +0 -25
- data/gemfiles/4.0.gemfile +0 -25
- data/gemfiles/4.1.gemfile +0 -25
- data/gemfiles/4.2.gemfile +0 -25
- data/gemfiles/5.0.gemfile +0 -25
data/test/search_cop_test.rb
CHANGED
@@ -1,41 +1,40 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class SearchCopTest < SearchCop::TestCase
|
5
4
|
def test_scope_before
|
6
|
-
expected = create(:product, :
|
7
|
-
rejected = create(:product, :
|
5
|
+
expected = create(:product, stock: 1, title: "Title")
|
6
|
+
rejected = create(:product, stock: 0, title: "Title")
|
8
7
|
|
9
|
-
results = Product.where(:
|
8
|
+
results = Product.where(stock: 1).search("Title")
|
10
9
|
|
11
10
|
assert_includes results, expected
|
12
11
|
refute_includes results, rejected
|
13
12
|
end
|
14
13
|
|
15
14
|
def test_scope_after
|
16
|
-
expected = create(:product, :
|
17
|
-
rejected = create(:product, :
|
15
|
+
expected = create(:product, stock: 1, title: "Title")
|
16
|
+
rejected = create(:product, stock: 0, title: "Title")
|
18
17
|
|
19
|
-
results = Product.search("Title").where(:
|
18
|
+
results = Product.search("Title").where(stock: 1)
|
20
19
|
|
21
20
|
assert_includes results, expected
|
22
21
|
refute_includes results, rejected
|
23
22
|
end
|
24
23
|
|
25
24
|
def test_scope
|
26
|
-
expected = create(:product, :
|
27
|
-
rejected = create(:product, :
|
25
|
+
expected = create(:product, stock: 1, title: "Title")
|
26
|
+
rejected = create(:product, stock: 0, title: "Title")
|
28
27
|
|
29
|
-
results = with_scope(Product.search_scopes[:search],
|
28
|
+
results = with_scope(Product.search_scopes[:search], -> { where stock: 1 }) { Product.search("title: Title") }
|
30
29
|
|
31
30
|
assert_includes results, expected
|
32
31
|
refute_includes results, rejected
|
33
32
|
end
|
34
33
|
|
35
34
|
def test_multi_associations
|
36
|
-
product = create(:product, :
|
37
|
-
create(:comment, :
|
38
|
-
create(:comment, :
|
35
|
+
product = create(:product, comments: [
|
36
|
+
create(:comment, title: "Title1", message: "Message1"),
|
37
|
+
create(:comment, title: "Title2", message: "Message2")
|
39
38
|
])
|
40
39
|
|
41
40
|
assert_includes Product.search("comment: Title1 comment: Message1"), product
|
@@ -43,8 +42,8 @@ class SearchCopTest < SearchCop::TestCase
|
|
43
42
|
end
|
44
43
|
|
45
44
|
def test_single_association
|
46
|
-
expected = create(:comment, :
|
47
|
-
rejected = create(:comment, :
|
45
|
+
expected = create(:comment, user: create(:user, username: "Expected"))
|
46
|
+
rejected = create(:comment, user: create(:user, username: "Rejected"))
|
48
47
|
|
49
48
|
results = Comment.search("user: Expected")
|
50
49
|
|
@@ -53,8 +52,8 @@ class SearchCopTest < SearchCop::TestCase
|
|
53
52
|
end
|
54
53
|
|
55
54
|
def test_deep_associations
|
56
|
-
expected = create(:product, :
|
57
|
-
rejected = create(:product, :
|
55
|
+
expected = create(:product, comments: [create(:comment, user: create(:user, username: "Expected"))])
|
56
|
+
rejected = create(:product, comments: [create(:comment, user: create(:user, username: "Rejected"))])
|
58
57
|
|
59
58
|
results = Product.search("user: Expected")
|
60
59
|
|
@@ -62,16 +61,25 @@ class SearchCopTest < SearchCop::TestCase
|
|
62
61
|
refute_includes results, rejected
|
63
62
|
end
|
64
63
|
|
64
|
+
def test_inherited_model
|
65
|
+
expected = create(:available_product, comments: [create(:comment, user: create(:user, username: "Expected"))])
|
66
|
+
rejected = create(:available_product, comments: [create(:comment, user: create(:user, username: "Rejected"))])
|
67
|
+
|
68
|
+
results = AvailableProduct.search("user: Expected")
|
69
|
+
assert_includes results, expected
|
70
|
+
refute_includes results, rejected
|
71
|
+
end
|
72
|
+
|
65
73
|
def test_multiple
|
66
|
-
product = create(:product, :
|
74
|
+
product = create(:product, comments: [create(:comment, title: "Title", message: "Message")])
|
67
75
|
|
68
76
|
assert_includes Product.search("comment: Title"), product
|
69
77
|
assert_includes Product.search("comment: Message"), product
|
70
78
|
end
|
71
79
|
|
72
80
|
def test_default
|
73
|
-
product1 = create(:product, :
|
74
|
-
product2 = create(:product, :
|
81
|
+
product1 = create(:product, title: "Expected")
|
82
|
+
product2 = create(:product, description: "Expected")
|
75
83
|
|
76
84
|
results = Product.search("Expected")
|
77
85
|
|
@@ -80,11 +88,11 @@ class SearchCopTest < SearchCop::TestCase
|
|
80
88
|
end
|
81
89
|
|
82
90
|
def test_custom_default_enabled
|
83
|
-
product1 = create(:product, :
|
84
|
-
product2 = create(:product, :
|
85
|
-
product3 = create(:product, :
|
91
|
+
product1 = create(:product, title: "Expected")
|
92
|
+
product2 = create(:product, description: "Expected")
|
93
|
+
product3 = create(:product, brand: "Expected")
|
86
94
|
|
87
|
-
results = with_options(Product.search_scopes[:search], :primary, :
|
95
|
+
results = with_options(Product.search_scopes[:search], :primary, default: true) { Product.search "Expected" }
|
88
96
|
|
89
97
|
assert_includes results, product1
|
90
98
|
assert_includes results, product2
|
@@ -92,32 +100,32 @@ class SearchCopTest < SearchCop::TestCase
|
|
92
100
|
end
|
93
101
|
|
94
102
|
def test_custom_default_disabled
|
95
|
-
product1 = create(:product, :
|
96
|
-
product2 = create(:product, :
|
103
|
+
product1 = create(:product, brand: "Expected")
|
104
|
+
product2 = create(:product, notice: "Expected")
|
97
105
|
|
98
|
-
results = with_options(Product.search_scopes[:search], :notice, :
|
106
|
+
results = with_options(Product.search_scopes[:search], :notice, default: false) { Product.search "Expected" }
|
99
107
|
|
100
108
|
assert_includes results, product1
|
101
109
|
refute_includes results, product2
|
102
110
|
end
|
103
111
|
|
104
112
|
def test_count
|
105
|
-
create_list :product, 2, :
|
113
|
+
create_list :product, 2, title: "Expected"
|
106
114
|
|
107
115
|
assert_equal 2, Product.search("Expected").count
|
108
116
|
end
|
109
117
|
|
110
118
|
def test_default_attributes_true
|
111
|
-
with_options(Product.search_scopes[:search], :title, :
|
112
|
-
with_options(Product.search_scopes[:search], :description, :
|
119
|
+
with_options(Product.search_scopes[:search], :title, default: true) do
|
120
|
+
with_options(Product.search_scopes[:search], :description, default: true) do
|
113
121
|
assert_equal ["title", "description"], Product.search_scopes[:search].reflection.default_attributes.keys
|
114
122
|
end
|
115
123
|
end
|
116
124
|
end
|
117
125
|
|
118
126
|
def test_default_attributes_fales
|
119
|
-
with_options(Product.search_scopes[:search], :title, :
|
120
|
-
with_options(Product.search_scopes[:search], :description, :
|
127
|
+
with_options(Product.search_scopes[:search], :title, default: false) do
|
128
|
+
with_options(Product.search_scopes[:search], :description, default: false) do
|
121
129
|
assert_equal Product.search_scopes[:search].reflection.attributes.keys - ["title", "description"], Product.search_scopes[:search].reflection.default_attributes.keys
|
122
130
|
end
|
123
131
|
end
|
@@ -133,8 +141,6 @@ class SearchCopTest < SearchCop::TestCase
|
|
133
141
|
end
|
134
142
|
|
135
143
|
def test_not_adding_search_to_object
|
136
|
-
|
137
|
-
assert_equal false, Object.respond_to?(:search)
|
144
|
+
refute Object.respond_to?(:search)
|
138
145
|
end
|
139
146
|
end
|
140
|
-
|
data/test/string_test.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class StringTest < SearchCop::TestCase
|
5
4
|
def test_anywhere
|
6
|
-
product = create(:product, :
|
5
|
+
product = create(:product, title: "Expected title")
|
7
6
|
|
8
7
|
assert_includes Product.search("Expected"), product
|
9
8
|
refute_includes Product.search("Rejected"), product
|
10
9
|
end
|
11
10
|
|
12
11
|
def test_anywhere_quoted
|
13
|
-
product = create(:product, :
|
12
|
+
product = create(:product, title: "Expected title")
|
14
13
|
|
15
14
|
assert_includes Product.search("'Expected title'"), product
|
16
15
|
assert_includes Product.search('"Expected title"'), product
|
@@ -20,75 +19,124 @@ class StringTest < SearchCop::TestCase
|
|
20
19
|
end
|
21
20
|
|
22
21
|
def test_multiple
|
23
|
-
product = create(:product, :
|
22
|
+
product = create(:product, comments: [create(:comment, title: "Expected title", message: "Expected message")])
|
24
23
|
|
25
24
|
assert_includes Product.search("Expected"), product
|
26
25
|
refute_includes Product.search("Rejected"), product
|
27
26
|
end
|
28
27
|
|
29
28
|
def test_includes
|
30
|
-
product = create(:product, :
|
29
|
+
product = create(:product, title: "Expected")
|
31
30
|
|
32
31
|
assert_includes Product.search("title: Expected"), product
|
33
32
|
refute_includes Product.search("title: Rejected"), product
|
34
33
|
end
|
35
34
|
|
35
|
+
def test_query_string_wildcards
|
36
|
+
product1 = create(:product, brand: "First brand")
|
37
|
+
product2 = create(:product, brand: "Second brand")
|
38
|
+
|
39
|
+
assert_equal Product.search("brand: First*"), [product1]
|
40
|
+
assert_equal Product.search("brand: br*nd"), []
|
41
|
+
assert_equal Product.search("brand: brand*"), []
|
42
|
+
assert_equal Product.search("brand: *brand*").to_set, [product1, product2].to_set
|
43
|
+
assert_equal Product.search("brand: *brand").to_set, [product1, product2].to_set
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_query_string_wildcard_escaping
|
47
|
+
product1 = create(:product, brand: "som% brand")
|
48
|
+
product2 = create(:product, brand: "som_ brand")
|
49
|
+
product3 = create(:product, brand: "som\\ brand")
|
50
|
+
_product4 = create(:product, brand: "some brand")
|
51
|
+
|
52
|
+
assert_equal Product.search("brand: som% brand"), [product1]
|
53
|
+
assert_equal Product.search("brand: som_ brand"), [product2]
|
54
|
+
assert_equal Product.search("brand: som\\ brand"), [product3]
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_query_string_wildcards_with_left_wildcard_false
|
58
|
+
product = create(:product, brand: "Some brand")
|
59
|
+
|
60
|
+
with_options(Product.search_scopes[:search], :brand, left_wildcard: false) do
|
61
|
+
refute_includes Product.search("brand: *brand"), product
|
62
|
+
assert_includes Product.search("brand: Some"), product
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_query_string_wildcards_with_right_wildcard_false
|
67
|
+
product = create(:product, brand: "Some brand")
|
68
|
+
|
69
|
+
with_options(Product.search_scopes[:search], :brand, right_wildcard: false) do
|
70
|
+
refute_includes Product.search("brand: Some*"), product
|
71
|
+
assert_includes Product.search("brand: brand"), product
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
36
75
|
def test_includes_with_left_wildcard
|
37
|
-
product = create(:product, :
|
76
|
+
product = create(:product, brand: "Some brand")
|
77
|
+
|
78
|
+
assert_includes Product.search("brand: brand"), product
|
79
|
+
end
|
38
80
|
|
39
|
-
|
81
|
+
def test_includes_with_left_wildcard_false
|
82
|
+
expected = create(:product, brand: "Brand")
|
83
|
+
rejected = create(:product, brand: "Rejected brand")
|
84
|
+
|
85
|
+
results = with_options(Product.search_scopes[:search], :brand, left_wildcard: false) { Product.search "brand: Brand" }
|
86
|
+
|
87
|
+
assert_includes results, expected
|
88
|
+
refute_includes results, rejected
|
40
89
|
end
|
41
90
|
|
42
|
-
def
|
43
|
-
expected = create(:product, :
|
44
|
-
rejected = create(:product, :
|
91
|
+
def test_includes_with_right_wildcard_false
|
92
|
+
expected = create(:product, brand: "Brand")
|
93
|
+
rejected = create(:product, brand: "Brand rejected")
|
45
94
|
|
46
|
-
results = with_options(Product.search_scopes[:search], :brand, :
|
95
|
+
results = with_options(Product.search_scopes[:search], :brand, right_wildcard: false) { Product.search "brand: Brand" }
|
47
96
|
|
48
97
|
assert_includes results, expected
|
49
98
|
refute_includes results, rejected
|
50
99
|
end
|
51
100
|
|
52
101
|
def test_equals
|
53
|
-
product = create(:product, :
|
102
|
+
product = create(:product, title: "Expected title")
|
54
103
|
|
55
104
|
assert_includes Product.search("title = 'Expected title'"), product
|
56
105
|
refute_includes Product.search("title = Expected"), product
|
57
106
|
end
|
58
107
|
|
59
108
|
def test_equals_not
|
60
|
-
product = create(:product, :
|
109
|
+
product = create(:product, title: "Expected")
|
61
110
|
|
62
111
|
assert_includes Product.search("title != Rejected"), product
|
63
112
|
refute_includes Product.search("title != Expected"), product
|
64
113
|
end
|
65
114
|
|
66
115
|
def test_greater
|
67
|
-
product = create(:product, :
|
116
|
+
product = create(:product, title: "Title B")
|
68
117
|
|
69
118
|
assert_includes Product.search("title > 'Title A'"), product
|
70
119
|
refute_includes Product.search("title > 'Title B'"), product
|
71
120
|
end
|
72
121
|
|
73
122
|
def test_greater_equals
|
74
|
-
product = create(:product, :
|
123
|
+
product = create(:product, title: "Title A")
|
75
124
|
|
76
125
|
assert_includes Product.search("title >= 'Title A'"), product
|
77
126
|
refute_includes Product.search("title >= 'Title B'"), product
|
78
127
|
end
|
79
128
|
|
80
129
|
def test_less
|
81
|
-
product = create(:product, :
|
130
|
+
product = create(:product, title: "Title A")
|
82
131
|
|
83
132
|
assert_includes Product.search("title < 'Title B'"), product
|
84
133
|
refute_includes Product.search("title < 'Title A'"), product
|
85
134
|
end
|
86
135
|
|
87
136
|
def test_less_or_greater
|
88
|
-
product = create(:product, :
|
137
|
+
product = create(:product, title: "Title B")
|
89
138
|
|
90
139
|
assert_includes Product.search("title <= 'Title B'"), product
|
91
140
|
refute_includes Product.search("title <= 'Title A'"), product
|
92
141
|
end
|
93
142
|
end
|
94
|
-
|
data/test/test_helper.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "search_cop"
|
3
2
|
|
4
3
|
begin
|
@@ -13,12 +12,12 @@ end
|
|
13
12
|
|
14
13
|
require "minitest/autorun"
|
15
14
|
require "active_record"
|
16
|
-
require "
|
15
|
+
require "factory_bot"
|
17
16
|
require "yaml"
|
18
17
|
|
19
18
|
DATABASE = ENV["DATABASE"] || "sqlite"
|
20
19
|
|
21
|
-
ActiveRecord::Base.establish_connection YAML.load_file(File.expand_path("
|
20
|
+
ActiveRecord::Base.establish_connection YAML.load_file(File.expand_path("database.yml", __dir__))[DATABASE]
|
22
21
|
|
23
22
|
class User < ActiveRecord::Base; end
|
24
23
|
|
@@ -28,7 +27,7 @@ class Comment < ActiveRecord::Base
|
|
28
27
|
belongs_to :user
|
29
28
|
|
30
29
|
search_scope :search do
|
31
|
-
attributes :
|
30
|
+
attributes user: "user.username"
|
32
31
|
attributes :title, :message
|
33
32
|
end
|
34
33
|
end
|
@@ -38,19 +37,19 @@ class Product < ActiveRecord::Base
|
|
38
37
|
|
39
38
|
search_scope :search do
|
40
39
|
attributes :title, :description, :brand, :notice, :stock, :price, :created_at, :created_on, :available
|
41
|
-
attributes :
|
42
|
-
attributes :
|
40
|
+
attributes comment: ["comments.title", "comments.message"], user: ["users.username", "users_products.username"]
|
41
|
+
attributes primary: [:title, :description]
|
43
42
|
|
44
|
-
aliases :
|
43
|
+
aliases users_products: :user
|
45
44
|
|
46
45
|
if DATABASE != "sqlite"
|
47
|
-
options :title, :
|
48
|
-
options :description, :
|
49
|
-
options :comment, :
|
46
|
+
options :title, type: :fulltext, coalesce: true
|
47
|
+
options :description, type: :fulltext, coalesce: true
|
48
|
+
options :comment, type: :fulltext, coalesce: true
|
50
49
|
end
|
51
50
|
|
52
51
|
if DATABASE == "postgres"
|
53
|
-
options :title, :
|
52
|
+
options :title, dictionary: "english"
|
54
53
|
end
|
55
54
|
|
56
55
|
generator :custom_eq do |column_name, raw_value|
|
@@ -62,22 +61,34 @@ class Product < ActiveRecord::Base
|
|
62
61
|
scope { joins "LEFT OUTER JOIN users users_products ON users_products.id = products.user_id" }
|
63
62
|
|
64
63
|
attributes :title, :description
|
65
|
-
attributes :
|
64
|
+
attributes user: "users_products.username"
|
65
|
+
|
66
|
+
options :title, default: true
|
67
|
+
aliases users_products: User
|
68
|
+
end
|
66
69
|
|
67
|
-
|
68
|
-
|
70
|
+
search_scope :search_multi_columns do
|
71
|
+
attributes all: [:title, :description]
|
69
72
|
end
|
70
73
|
|
71
74
|
has_many :comments
|
72
|
-
has_many :users, :
|
75
|
+
has_many :users, through: :comments
|
73
76
|
|
74
77
|
belongs_to :user
|
75
78
|
end
|
76
79
|
|
77
|
-
|
80
|
+
class AvailableProduct < Product
|
81
|
+
default_scope { where(available: true) }
|
82
|
+
end
|
83
|
+
|
84
|
+
FactoryBot.define do
|
78
85
|
factory :product do
|
79
86
|
end
|
80
87
|
|
88
|
+
factory :available_product do
|
89
|
+
available { true }
|
90
|
+
end
|
91
|
+
|
81
92
|
factory :comment do
|
82
93
|
end
|
83
94
|
|
@@ -122,7 +133,7 @@ if DATABASE == "mysql"
|
|
122
133
|
end
|
123
134
|
|
124
135
|
class SearchCop::TestCase
|
125
|
-
include
|
136
|
+
include FactoryBot::Syntax::Methods
|
126
137
|
|
127
138
|
def teardown
|
128
139
|
Product.delete_all
|
@@ -169,4 +180,3 @@ class SearchCop::TestCase
|
|
169
180
|
ActiveRecord::Base.connection.quote object
|
170
181
|
end
|
171
182
|
end
|
172
|
-
|
data/test/visitor_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../test_helper", __FILE__)
|
1
|
+
require File.expand_path("test_helper", __dir__)
|
3
2
|
|
4
3
|
class VisitorTest < SearchCop::TestCase
|
5
4
|
def test_and
|
@@ -53,8 +52,8 @@ class VisitorTest < SearchCop::TestCase
|
|
53
52
|
def test_matches
|
54
53
|
node = SearchCopGrammar::Attributes::String.new(Product, "products", "notice").matches("Notice")
|
55
54
|
|
56
|
-
assert_equal("(#{quote_table_name "products"}.#{quote_column_name "notice"} IS NOT NULL AND #{quote_table_name "products"}.#{quote_column_name "notice"} LIKE #{quote "%Notice%"})", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] != "postgres"
|
57
|
-
assert_equal("(#{quote_table_name "products"}.#{quote_column_name "notice"} IS NOT NULL AND #{quote_table_name "products"}.#{quote_column_name "notice"} ILIKE #{quote "%Notice%"})", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
55
|
+
assert_equal("(#{quote_table_name "products"}.#{quote_column_name "notice"} IS NOT NULL AND #{quote_table_name "products"}.#{quote_column_name "notice"} LIKE #{quote "%Notice%"} ESCAPE #{quote "\\"})", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] != "postgres"
|
56
|
+
assert_equal("(#{quote_table_name "products"}.#{quote_column_name "notice"} IS NOT NULL AND #{quote_table_name "products"}.#{quote_column_name "notice"} ILIKE #{quote "%Notice%"} ESCAPE #{quote "\\"})", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
58
57
|
end
|
59
58
|
|
60
59
|
def test_not
|
@@ -99,7 +98,7 @@ class VisitorTest < SearchCop::TestCase
|
|
99
98
|
end
|
100
99
|
|
101
100
|
def test_generator
|
102
|
-
generator =
|
101
|
+
generator = lambda do |column_name, value|
|
103
102
|
"#{column_name} = #{quote value}"
|
104
103
|
end
|
105
104
|
node = SearchCopGrammar::Attributes::Collection.new(SearchCop::QueryInfo.new(Product, Product.search_scopes[:search]), "title").generator(generator, "value").optimize!
|
@@ -107,4 +106,3 @@ class VisitorTest < SearchCop::TestCase
|
|
107
106
|
assert_equal "#{quote_table_name "products"}.#{quote_column_name "title"} = 'value'", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)
|
108
107
|
end
|
109
108
|
end
|
110
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_cop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Vetter
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: treetop
|
@@ -25,21 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 3.0.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 3.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,21 +53,21 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: factory_bot
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: minitest
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rubocop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -115,9 +115,9 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
+
- ".github/workflows/test.yml"
|
118
119
|
- ".gitignore"
|
119
|
-
- ".
|
120
|
-
- Appraisals
|
120
|
+
- ".rubocop.yml"
|
121
121
|
- CHANGELOG.md
|
122
122
|
- CONTRIBUTING.md
|
123
123
|
- Gemfile
|
@@ -125,14 +125,14 @@ files:
|
|
125
125
|
- MIGRATION.md
|
126
126
|
- README.md
|
127
127
|
- Rakefile
|
128
|
-
-
|
129
|
-
- gemfiles/
|
130
|
-
- gemfiles/
|
131
|
-
- gemfiles/
|
132
|
-
- gemfiles/5.0.gemfile
|
128
|
+
- docker-compose.yml
|
129
|
+
- gemfiles/rails5.gemfile
|
130
|
+
- gemfiles/rails6.gemfile
|
131
|
+
- gemfiles/rails7.gemfile
|
133
132
|
- lib/search_cop.rb
|
134
133
|
- lib/search_cop/grammar_parser.rb
|
135
134
|
- lib/search_cop/hash_parser.rb
|
135
|
+
- lib/search_cop/helpers.rb
|
136
136
|
- lib/search_cop/query_builder.rb
|
137
137
|
- lib/search_cop/query_info.rb
|
138
138
|
- lib/search_cop/search_scope.rb
|
@@ -151,6 +151,7 @@ files:
|
|
151
151
|
- test/database.yml
|
152
152
|
- test/date_test.rb
|
153
153
|
- test/datetime_test.rb
|
154
|
+
- test/default_operator_test.rb
|
154
155
|
- test/error_test.rb
|
155
156
|
- test/float_test.rb
|
156
157
|
- test/fulltext_test.rb
|
@@ -167,7 +168,7 @@ homepage: https://github.com/mrkamel/search_cop
|
|
167
168
|
licenses:
|
168
169
|
- MIT
|
169
170
|
metadata: {}
|
170
|
-
post_install_message:
|
171
|
+
post_install_message:
|
171
172
|
rdoc_options: []
|
172
173
|
require_paths:
|
173
174
|
- lib
|
@@ -182,27 +183,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
183
|
- !ruby/object:Gem::Version
|
183
184
|
version: '0'
|
184
185
|
requirements: []
|
185
|
-
|
186
|
-
|
187
|
-
signing_key:
|
186
|
+
rubygems_version: 3.3.3
|
187
|
+
signing_key:
|
188
188
|
specification_version: 4
|
189
189
|
summary: Easily perform complex search engine like fulltext queries on your ActiveRecord
|
190
190
|
models
|
191
|
-
test_files:
|
192
|
-
- test/and_test.rb
|
193
|
-
- test/boolean_test.rb
|
194
|
-
- test/database.yml
|
195
|
-
- test/date_test.rb
|
196
|
-
- test/datetime_test.rb
|
197
|
-
- test/error_test.rb
|
198
|
-
- test/float_test.rb
|
199
|
-
- test/fulltext_test.rb
|
200
|
-
- test/hash_test.rb
|
201
|
-
- test/integer_test.rb
|
202
|
-
- test/not_test.rb
|
203
|
-
- test/or_test.rb
|
204
|
-
- test/scope_test.rb
|
205
|
-
- test/search_cop_test.rb
|
206
|
-
- test/string_test.rb
|
207
|
-
- test/test_helper.rb
|
208
|
-
- test/visitor_test.rb
|
191
|
+
test_files: []
|