search_cop 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d50fc64d55fb96b64906163d2f2e88f253974e8aeb0653307795fcab40eb636
4
- data.tar.gz: 86184be05de8b457dbe709c89c4938aa35f600adf5cd1c20d38819a1ba933b86
3
+ metadata.gz: a1f72257612f45ef71a297f5ae8924fca0d8dad9f3c19e6e0b6e2c96e60f36ac
4
+ data.tar.gz: 2aa35b3f92c08cd24266d28f4c1e3fe195b627bb478be415ff4669b2344676de
5
5
  SHA512:
6
- metadata.gz: abc70826323ea53b7966a415d78f18a64a10e004e9e6e08687c6118ebcd60964a5732691706c3d2d52aea05d919d9154484c57517a4882b4f9056518bf8ab4f3
7
- data.tar.gz: 47c56ea7175559e06bbde1c830f6dc8437279cfb6639446babc6d2b731a86037c815fb8664f4fba64f6832cac33168a6e6f86cf79275cc410eec1b0cce17fb72
6
+ metadata.gz: ee27a86501f8c3f2588f50b5d78889b8ad6ae9e2d28fcd219617d4839590f61d98c80850f8247da34a5081e12075315d53918a61b3b9636618645d138fd7bd4c
7
+ data.tar.gz: 046c39f90c8a541d1e000f95772fb5d8eeb2095fc8afe8717b5b95f5672576d988375853525243923852029728d485b3cfd1046f6bd68c9134065738a69f31bf
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
1
 
2
2
  # Changelog
3
3
 
4
+ Version 1.3.0:
5
+
6
+ * Support json fields for postgres, mysql and sqlite
7
+ * Support jsonb and hstore fields for postgres
8
+ * Add support for timestamptz for postgres
9
+
4
10
  Version 1.2.3:
5
11
 
6
12
  * Fix table name for namespaced and inherited models #70 #67
data/Gemfile CHANGED
@@ -4,7 +4,13 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  platforms :ruby do
7
+ gem "activerecord", ">= 3.0.0"
8
+ gem "bundler"
9
+ gem "factory_bot"
10
+ gem "minitest"
7
11
  gem "mysql2"
8
12
  gem "pg"
13
+ gem "rake"
14
+ gem "rubocop"
9
15
  gem "sqlite3"
10
16
  end
data/README.md CHANGED
@@ -103,8 +103,9 @@ Book.search("Harry Potter")
103
103
  # ... WHERE (books.title LIKE '%Harry%' OR books.description LIKE '%Harry%' OR ...) AND (books.title LIKE '%Potter%' OR books.description LIKE '%Potter%' ...)
104
104
 
105
105
  Book.search("available:yes OR created_at:2014")
106
- # ... WHERE books.available = 1 OR (books.created_at >= '2014-01-01 00:00:00' and books.created_at <= '2014-12-31 00:00:00')
106
+ # ... WHERE books.available = 1 OR (books.created_at >= '2014-01-01 00:00:00.00000' and books.created_at <= '2014-12-31 23:59:59.99999')
107
107
  ```
108
+ SearchCop is using ActiveSupport's beginning_of_year and end_of_year methods for the values used in building the SQL query for this case.
108
109
 
109
110
  Of course, these `LIKE '%...%'` queries won't achieve optimal performance, but
110
111
  check out the section below on SearchCop's fulltext capabilities to
@@ -135,6 +136,30 @@ to prevent SQL injection. While we can never be 100% safe from security issues,
135
136
  SearchCop takes security issues seriously. Please report responsibly via
136
137
  security at flakks dot com in case you find any security related issues.
137
138
 
139
+ ## json/jsonb/hstore
140
+
141
+ SearchCop supports json fields for MySQL, as well as json, jsonb and hstore
142
+ fields for postgres. Currently, field values are always expected to be strings
143
+ and no arrays are supported. You can specify json attributes via:
144
+
145
+ ```ruby
146
+ search_scope :search do
147
+ attributes user_agent: "context->browser->user_agent"
148
+
149
+ # ...
150
+ end
151
+ ```
152
+
153
+ where `context` is a json/jsonb column which e.g. contains:
154
+
155
+ ```json
156
+ {
157
+ "browser": {
158
+ "user_agent": "Firefox ..."
159
+ }
160
+ }
161
+ ```
162
+
138
163
  ## Fulltext index capabilities
139
164
 
140
165
  By default, i.e. if you don't tell SearchCop about your fulltext indices,
data/docker-compose.yml CHANGED
@@ -6,10 +6,11 @@ services:
6
6
  environment:
7
7
  - MYSQL_ALLOW_EMPTY_PASSWORD=yes
8
8
  - MYSQL_ROOT_PASSWORD=
9
+ - MYSQL_DATABASE=search_cop
9
10
  ports:
10
11
  - 3306:3306
11
12
  postgres:
12
- image: postgres:9.6.6
13
+ image: styriadigital/postgres_hstore:10
13
14
  environment:
14
15
  POSTGRES_DB: search_cop
15
16
  POSTGRES_USER: search_cop
@@ -5,8 +5,13 @@ source "https://rubygems.org"
5
5
  gem "activerecord", "~> 5.1"
6
6
 
7
7
  platforms :ruby do
8
+ gem "bundler"
9
+ gem "factory_bot"
10
+ gem "minitest"
8
11
  gem "mysql2"
9
12
  gem "pg"
13
+ gem "rake"
14
+ gem "rubocop"
10
15
  gem "sqlite3"
11
16
  end
12
17
 
@@ -5,8 +5,13 @@ source "https://rubygems.org"
5
5
  gem "activerecord", "~> 6.0"
6
6
 
7
7
  platforms :ruby do
8
+ gem "bundler"
9
+ gem "factory_bot"
10
+ gem "minitest"
8
11
  gem "mysql2"
9
12
  gem "pg"
13
+ gem "rake"
14
+ gem "rubocop"
10
15
  gem "sqlite3"
11
16
  end
12
17
 
@@ -5,8 +5,13 @@ source "https://rubygems.org"
5
5
  gem "activerecord", "~> 7.0"
6
6
 
7
7
  platforms :ruby do
8
+ gem "bundler"
9
+ gem "factory_bot"
10
+ gem "minitest"
8
11
  gem "mysql2"
9
12
  gem "pg"
13
+ gem "rake"
14
+ gem "rubocop"
10
15
  gem "sqlite3"
11
16
  end
12
17
 
@@ -1,3 +1,3 @@
1
1
  module SearchCop
2
- VERSION = "1.2.3"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -3,6 +3,10 @@ module SearchCop
3
3
  module Mysql
4
4
  # rubocop:disable Naming/MethodName
5
5
 
6
+ def visit_SearchCopGrammar_Attributes_Json(attribute)
7
+ "#{quote_table_name attribute.table_alias}.#{quote_column_name attribute.column_name}->#{quote "$.#{attribute.field_names.join(".")}"}"
8
+ end
9
+
6
10
  class FulltextQuery < Visitor
7
11
  def visit_SearchCopGrammar_Nodes_MatchesFulltextNot(node)
8
12
  node.right.split(/[\s+'"<>()~-]+/).collect { |word| "-#{word}" }.join(" ")
@@ -38,8 +42,8 @@ module SearchCop
38
42
  def visit_SearchCopGrammar_Nodes_FulltextExpression(node)
39
43
  "MATCH(#{visit node.collection}) AGAINST(#{visit FulltextQuery.new(connection).visit(node.node)} IN BOOLEAN MODE)"
40
44
  end
41
- end
42
45
 
43
- # rubocop:enable Naming/MethodName
46
+ # rubocop:enable Naming/MethodName
47
+ end
44
48
  end
45
49
  end
@@ -3,6 +3,22 @@ module SearchCop
3
3
  module Postgres
4
4
  # rubocop:disable Naming/MethodName
5
5
 
6
+ def visit_SearchCopGrammar_Attributes_Json(attribute)
7
+ elements = ["#{quote_table_name attribute.table_alias}.#{quote_column_name attribute.column_name}", *attribute.field_names.map { |field_name| quote(field_name) }]
8
+
9
+ "#{elements[0...-1].join("->")}->>#{elements.last}"
10
+ end
11
+
12
+ def visit_SearchCopGrammar_Attributes_Jsonb(attribute)
13
+ elements = ["#{quote_table_name attribute.table_alias}.#{quote_column_name attribute.column_name}", *attribute.field_names.map { |field_name| quote(field_name) }]
14
+
15
+ "#{elements[0...-1].join("->")}->>#{elements.last}"
16
+ end
17
+
18
+ def visit_SearchCopGrammar_Attributes_Hstore(attribute)
19
+ "#{quote_table_name attribute.table_alias}.#{quote_column_name attribute.column_name}->#{quote attribute.field_names.first}"
20
+ end
21
+
6
22
  class FulltextQuery < Visitor
7
23
  def visit_SearchCopGrammar_Nodes_MatchesFulltextNot(node)
8
24
  "!'#{node.right.gsub(/[\s&|!:'"]+/, " ")}'"
@@ -0,0 +1,13 @@
1
+ module SearchCop
2
+ module Visitors
3
+ module Sqlite
4
+ # rubocop:disable Naming/MethodName
5
+
6
+ def visit_SearchCopGrammar_Attributes_Json(attribute)
7
+ "json_extract(#{quote_table_name attribute.table_alias}.#{quote_column_name attribute.column_name}, #{quote "$.#{attribute.field_names.join(".")}"})"
8
+ end
9
+
10
+ # rubocop:enable Naming/MethodName
11
+ end
12
+ end
13
+ end
@@ -10,10 +10,11 @@ module SearchCop
10
10
 
11
11
  extend(SearchCop::Visitors::Mysql) if @connection.adapter_name =~ /mysql/i
12
12
  extend(SearchCop::Visitors::Postgres) if @connection.adapter_name =~ /postgres|postgis/i
13
+ extend(SearchCop::Visitors::Sqlite) if @connection.adapter_name =~ /sqlite/i
13
14
  end
14
15
 
15
16
  def visit(visit_node = node)
16
- send "visit_#{visit_node.class.name.gsub(/::/, "_")}", visit_node
17
+ send "visit_#{visit_node.class.name.gsub("::", "_")}", visit_node
17
18
  end
18
19
 
19
20
  def visit_SearchCopGrammar_Nodes_And(node)
@@ -79,6 +80,7 @@ module SearchCop
79
80
  alias :visit_SearchCopGrammar_Attributes_Decimal :visit_attribute
80
81
  alias :visit_SearchCopGrammar_Attributes_Datetime :visit_attribute
81
82
  alias :visit_SearchCopGrammar_Attributes_Timestamp :visit_attribute
83
+ alias :visit_SearchCopGrammar_Attributes_Timestamptz :visit_attribute
82
84
  alias :visit_SearchCopGrammar_Attributes_Date :visit_attribute
83
85
  alias :visit_SearchCopGrammar_Attributes_Time :visit_attribute
84
86
  alias :visit_SearchCopGrammar_Attributes_Boolean :visit_attribute
@@ -1,3 +1,4 @@
1
1
  require "search_cop/visitors/visitor"
2
2
  require "search_cop/visitors/mysql"
3
3
  require "search_cop/visitors/postgres"
4
+ require "search_cop/visitors/sqlite"
@@ -88,12 +88,13 @@ module SearchCopGrammar
88
88
  def attribute_for(attribute_definition)
89
89
  query_info.references.push attribute_definition
90
90
 
91
- table, column = attribute_definition.split(".")
91
+ table, column_with_fields = attribute_definition.split(".")
92
+ column, *fields = column_with_fields.split("->")
92
93
  klass = klass_for(table)
93
94
 
94
95
  raise(SearchCop::UnknownAttribute, "Unknown attribute #{attribute_definition}") unless klass.columns_hash[column]
95
96
 
96
- Attributes.const_get(klass.columns_hash[column].type.to_s.classify).new(klass, alias_for(table), column, options)
97
+ Attributes.const_get(klass.columns_hash[column].type.to_s.classify).new(klass, alias_for(table), column, fields, options)
97
98
  end
98
99
 
99
100
  def generator_for(name)
@@ -110,13 +111,14 @@ module SearchCopGrammar
110
111
  end
111
112
 
112
113
  class Base
113
- attr_reader :attribute, :table_alias, :column_name, :options
114
+ attr_reader :attribute, :table_alias, :column_name, :field_names, :options
114
115
 
115
- def initialize(klass, table_alias, column_name, options = {})
116
+ def initialize(klass, table_alias, column_name, field_names, options = {})
116
117
  @attribute = klass.arel_table.alias(table_alias)[column_name]
117
118
  @klass = klass
118
119
  @table_alias = table_alias
119
120
  @column_name = column_name
121
+ @field_names = field_names
120
122
  @options = (options || {})
121
123
  end
122
124
 
@@ -179,6 +181,9 @@ module SearchCopGrammar
179
181
  end
180
182
 
181
183
  class Text < String; end
184
+ class Jsonb < String; end
185
+ class Json < String; end
186
+ class Hstore < String; end
182
187
 
183
188
  class WithoutMatches < Base
184
189
  def matches(value)
@@ -255,6 +260,7 @@ module SearchCopGrammar
255
260
  end
256
261
 
257
262
  class Timestamp < Datetime; end
263
+ class Timestamptz < Datetime; end
258
264
 
259
265
  class Date < Datetime
260
266
  def parse(value)
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.2.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Vetter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-14 00:00:00.000000000 Z
11
+ date: 2024-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: treetop
@@ -24,90 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: activerecord
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 3.0.0
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 3.0.0
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: factory_bot
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rubocop
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
27
  description: Search engine like fulltext query support for ActiveRecord
112
28
  email:
113
29
  - vetter@flakks.com
@@ -115,8 +31,6 @@ executables: []
115
31
  extensions: []
116
32
  extra_rdoc_files: []
117
33
  files:
118
- - ".github/workflows/test.yml"
119
- - ".gitignore"
120
34
  - ".rubocop.yml"
121
35
  - CHANGELOG.md
122
36
  - CONTRIBUTING.md
@@ -140,34 +54,19 @@ files:
140
54
  - lib/search_cop/visitors.rb
141
55
  - lib/search_cop/visitors/mysql.rb
142
56
  - lib/search_cop/visitors/postgres.rb
57
+ - lib/search_cop/visitors/sqlite.rb
143
58
  - lib/search_cop/visitors/visitor.rb
144
59
  - lib/search_cop_grammar.rb
145
60
  - lib/search_cop_grammar.treetop
146
61
  - lib/search_cop_grammar/attributes.rb
147
62
  - lib/search_cop_grammar/nodes.rb
148
- - search_cop.gemspec
149
- - test/and_test.rb
150
- - test/boolean_test.rb
151
- - test/database.yml
152
- - test/date_test.rb
153
- - test/datetime_test.rb
154
- - test/default_operator_test.rb
155
- - test/error_test.rb
156
- - test/float_test.rb
157
- - test/fulltext_test.rb
158
- - test/hash_test.rb
159
- - test/integer_test.rb
160
- - test/not_test.rb
161
- - test/or_test.rb
162
- - test/scope_test.rb
163
- - test/search_cop_test.rb
164
- - test/string_test.rb
165
- - test/test_helper.rb
166
- - test/visitor_test.rb
167
63
  homepage: https://github.com/mrkamel/search_cop
168
64
  licenses:
169
65
  - MIT
170
- metadata: {}
66
+ metadata:
67
+ homepage_uri: https://github.com/mrkamel/search_cop
68
+ source_code_uri: https://github.com/mrkamel/search_cop
69
+ changelog_uri: https://github.com/mrkamel/search_cop/blob/master/CHANGELOG.md
171
70
  post_install_message:
172
71
  rdoc_options: []
173
72
  require_paths:
@@ -1,50 +0,0 @@
1
- name: test
2
- on: [push, pull_request]
3
- jobs:
4
- build:
5
- runs-on: ubuntu-latest
6
- strategy:
7
- fail-fast: false
8
- matrix:
9
- ruby: ["2.6", "2.7", "3.0", "3.1"]
10
- rails: ["rails5", "rails6", "rails7"]
11
- database: ["sqlite", "postgres", "mysql"]
12
- exclude:
13
- - ruby: "3.0"
14
- rails: "rails5"
15
- - ruby: "3.1"
16
- rails: "rails5"
17
- - ruby: "2.6"
18
- rails: "rails7"
19
- services:
20
- postgres:
21
- image: postgres
22
- env:
23
- POSTGRES_USER: search_cop
24
- POSTGRES_PASSWORD: secret
25
- POSTGRES_DB: search_cop
26
- ports:
27
- - 5432:5432
28
- mysql:
29
- image: mysql
30
- env:
31
- MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
32
- MYSQL_ROOT_PASSWORD: ""
33
- MYSQL_DATABASE: search_cop
34
- ports:
35
- - 3306:3306
36
- steps:
37
- - uses: actions/checkout@v1
38
- - uses: ruby/setup-ruby@v1
39
- with:
40
- ruby-version: ${{ matrix.ruby }}
41
- - name: test
42
- env:
43
- DATABASE: ${{ matrix.database }}
44
- run: |
45
- gem install bundler
46
- bundle config set --local gemfile "gemfiles/${{ matrix.rails }}.gemfile"
47
- bundle config set --local path "../vendor/bundle"
48
- bundle install
49
- bundle exec rake test
50
- bundle exec rubocop
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- gemfiles/*.lock
data/search_cop.gemspec DELETED
@@ -1,27 +0,0 @@
1
- lib = File.expand_path("lib", __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "search_cop/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "search_cop"
7
- spec.version = SearchCop::VERSION
8
- spec.authors = ["Benjamin Vetter"]
9
- spec.email = ["vetter@flakks.com"]
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"
12
- spec.homepage = "https://github.com/mrkamel/search_cop"
13
- spec.license = "MIT"
14
-
15
- spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
- spec.require_paths = ["lib"]
18
-
19
- spec.add_dependency "treetop"
20
-
21
- spec.add_development_dependency "activerecord", ">= 3.0.0"
22
- spec.add_development_dependency "bundler"
23
- spec.add_development_dependency "factory_bot"
24
- spec.add_development_dependency "minitest"
25
- spec.add_development_dependency "rake"
26
- spec.add_development_dependency "rubocop"
27
- end
data/test/and_test.rb DELETED
@@ -1,25 +0,0 @@
1
- require File.expand_path("test_helper", __dir__)
2
-
3
- class AndTest < SearchCop::TestCase
4
- def test_and_string
5
- expected = create(:product, title: "expected title", description: "Description")
6
- rejected = create(:product, title: "Rejected title", description: "Description")
7
-
8
- results = Product.search("title: 'Expected title' description: Description")
9
-
10
- assert_includes results, expected
11
- refute_includes results, rejected
12
-
13
- assert_equal results, Product.search("title: 'Expected title' AND description: Description")
14
- end
15
-
16
- def test_and_hash
17
- expected = create(:product, title: "Expected title", description: "Description")
18
- rejected = create(:product, title: "Rejected title", description: "Description")
19
-
20
- results = Product.search(and: [{ title: "Expected title" }, { description: "Description" }])
21
-
22
- assert_includes results, expected
23
- refute_includes results, rejected
24
- end
25
- end
data/test/boolean_test.rb DELETED
@@ -1,51 +0,0 @@
1
- require File.expand_path("test_helper", __dir__)
2
-
3
- class BooleanTest < SearchCop::TestCase
4
- def test_mapping
5
- product = create(:product, available: true)
6
-
7
- assert_includes Product.search("available: 1"), product
8
- assert_includes Product.search("available: true"), product
9
- assert_includes Product.search("available: yes"), product
10
-
11
- product = create(:product, available: false)
12
-
13
- assert_includes Product.search("available: 0"), product
14
- assert_includes Product.search("available: false"), product
15
- assert_includes Product.search("available: no"), product
16
- end
17
-
18
- def test_anywhere
19
- product = create(:product, available: true)
20
-
21
- assert_includes Product.search("true"), product
22
- refute_includes Product.search("false"), product
23
- end
24
-
25
- def test_includes
26
- product = create(:product, available: true)
27
-
28
- assert_includes Product.search("available: true"), product
29
- refute_includes Product.search("available: false"), product
30
- end
31
-
32
- def test_equals
33
- product = create(:product, available: true)
34
-
35
- assert_includes Product.search("available = true"), product
36
- refute_includes Product.search("available = false"), product
37
- end
38
-
39
- def test_equals_not
40
- product = create(:product, available: false)
41
-
42
- assert_includes Product.search("available != true"), product
43
- refute_includes Product.search("available != false"), product
44
- end
45
-
46
- def test_incompatible_datatype
47
- assert_raises SearchCop::IncompatibleDatatype do
48
- Product.unsafe_search "available: Value"
49
- end
50
- end
51
- end
data/test/database.yml DELETED
@@ -1,20 +0,0 @@
1
-
2
- sqlite:
3
- adapter: sqlite3
4
- database: ":memory:"
5
-
6
- mysql:
7
- adapter: mysql2
8
- database: search_cop
9
- host: 127.0.0.1
10
- username: root
11
- encoding: utf8
12
-
13
- postgres:
14
- host: 127.0.0.1
15
- adapter: postgresql
16
- database: search_cop
17
- username: search_cop
18
- password: secret
19
- encoding: utf8
20
-