scoped_search 2.7.1 → 3.0.0
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/.travis.yml +14 -23
- data/CHANGELOG.rdoc +193 -0
- data/CONTRIBUTING.rdoc +38 -0
- data/{Gemfile.activerecord4 → Gemfile.activerecord40} +1 -1
- data/{Gemfile.activerecord2 → Gemfile.activerecord41} +2 -2
- data/README.rdoc +15 -20
- data/app/assets/stylesheets/scoped_search.scss +0 -4
- data/lib/scoped_search.rb +2 -27
- data/lib/scoped_search/auto_complete_builder.rb +40 -34
- data/lib/scoped_search/definition.rb +7 -5
- data/lib/scoped_search/query_builder.rb +3 -34
- data/lib/scoped_search/query_language.rb +0 -3
- data/lib/scoped_search/rails_helper.rb +45 -46
- data/lib/scoped_search/railtie.rb +11 -6
- data/lib/scoped_search/version.rb +1 -1
- data/scoped_search.gemspec +8 -7
- data/spec/integration/api_spec.rb +2 -41
- data/spec/integration/auto_complete_spec.rb +5 -5
- data/spec/integration/key_value_querying_spec.rb +9 -9
- data/spec/integration/ordinal_querying_spec.rb +46 -48
- data/spec/integration/relation_querying_spec.rb +30 -30
- data/spec/integration/set_query_spec.rb +7 -7
- data/spec/integration/string_querying_spec.rb +48 -50
- data/spec/lib/matchers.rb +2 -2
- data/spec/spec_helper.rb +8 -0
- data/spec/unit/ast_spec.rb +3 -3
- metadata +26 -22
- data/init.rb +0 -1
@@ -35,15 +35,15 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should find the record status = 1" do
|
38
|
-
@class.search_for('status = up').should
|
38
|
+
@class.search_for('status = up').length.should == 1
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should find the record with status = 0" do
|
42
|
-
@class.search_for('status = unknown').should
|
42
|
+
@class.search_for('status = unknown').length.should == 1
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should find two record with status != 1" do
|
46
|
-
@class.search_for('status != up').should
|
46
|
+
@class.search_for('status != up').length.should == 2
|
47
47
|
end
|
48
48
|
end
|
49
49
|
context 'querying boolean fields' do
|
@@ -61,16 +61,16 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
61
61
|
end
|
62
62
|
|
63
63
|
it "should find the record bool = true" do
|
64
|
-
@class.search_for('bool = yes').should
|
64
|
+
@class.search_for('bool = yes').length.should == 1
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should find two record with bool = false" do
|
68
|
-
@class.search_for('bool = no').should
|
68
|
+
@class.search_for('bool = no').length.should == 2
|
69
69
|
end
|
70
70
|
|
71
71
|
it "should find two record with bool = false" do
|
72
|
-
@class.search_for('bool != yes').should
|
72
|
+
@class.search_for('bool != yes').length.should == 2
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
|
-
end
|
76
|
+
end
|
@@ -8,7 +8,7 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
8
8
|
|
9
9
|
before(:all) do
|
10
10
|
ScopedSearch::RSpec::Database.establish_named_connection(db)
|
11
|
-
|
11
|
+
|
12
12
|
@class = ScopedSearch::RSpec::Database.create_model(
|
13
13
|
:string => :string,
|
14
14
|
:another => :string,
|
@@ -33,187 +33,187 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
33
33
|
|
34
34
|
context 'in an implicit string field' do
|
35
35
|
it "should find the record with an exact string match" do
|
36
|
-
@class.search_for('foo').should
|
36
|
+
@class.search_for('foo').length.should == 1
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should find the other two records using NOT with an exact string match" do
|
40
|
-
@class.search_for('-foo').should
|
40
|
+
@class.search_for('-foo').length.should == 2
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should find the record with an exact string match and an explicit field operator" do
|
44
|
-
@class.search_for('string = foo').should
|
44
|
+
@class.search_for('string = foo').length.should == 1
|
45
45
|
end
|
46
46
|
|
47
47
|
it "should find the record with an exact string match and an explicit field operator" do
|
48
|
-
@class.search_for('another = foo').should
|
48
|
+
@class.search_for('another = foo').length.should == 0
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should find the record with an partial string match" do
|
52
|
-
@class.search_for('fo').should
|
52
|
+
@class.search_for('fo').length.should == 1
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should find the other two records using NOT with an partial string match" do
|
56
|
-
@class.search_for('-fo').should
|
56
|
+
@class.search_for('-fo').length.should == 2
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should not find the record with an explicit equals operator and a partial match" do
|
60
|
-
@class.search_for('= fo').should
|
60
|
+
@class.search_for('= fo').length.should == 0
|
61
61
|
end
|
62
62
|
|
63
63
|
it "should find the record with an explicit LIKE operator and a partial match" do
|
64
|
-
@class.search_for('~ fo').should
|
64
|
+
@class.search_for('~ fo').length.should == 1
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should find the all other record with an explicit NOT LIKE operator and a partial match" do
|
68
|
-
@class.search_for('string !~ fo').should
|
68
|
+
@class.search_for('string !~ fo').length.should == @class.count - 1
|
69
69
|
end
|
70
70
|
|
71
71
|
it "should not find a record with a non-match" do
|
72
|
-
@class.search_for('nonsense').should
|
72
|
+
@class.search_for('nonsense').length.should == 0
|
73
73
|
end
|
74
74
|
|
75
75
|
it "should find two records if it partially matches them" do
|
76
|
-
@class.search_for('ba').should
|
76
|
+
@class.search_for('ba').length.should == 2
|
77
77
|
end
|
78
78
|
|
79
79
|
it "should find no records starting with an a" do
|
80
|
-
@class.search_for('a%').should
|
80
|
+
@class.search_for('a%').length.should == 0
|
81
81
|
end
|
82
82
|
|
83
83
|
it "should find one records ending with an oo" do
|
84
|
-
@class.search_for('%oo').should
|
84
|
+
@class.search_for('%oo').length.should == 1
|
85
85
|
end
|
86
86
|
|
87
87
|
it "should find records without case sensitivity when using the LIKE operator" do
|
88
|
-
@class.search_for('string ~ FOO').should
|
88
|
+
@class.search_for('string ~ FOO').length.should == 1
|
89
89
|
end
|
90
90
|
|
91
91
|
it "should not find records without case sensitivity when using the = operator" do
|
92
|
-
@class.search_for('string = FOO').should
|
92
|
+
@class.search_for('string = FOO').length.should == 0
|
93
93
|
end
|
94
94
|
|
95
95
|
it "should find records without case sensitivity when using the != operator" do
|
96
|
-
@class.search_for('string != FOO').should
|
96
|
+
@class.search_for('string != FOO').length.should == 3
|
97
97
|
end
|
98
98
|
|
99
99
|
it "should find records without case sensitivity when using the NOT LIKE operator" do
|
100
|
-
@class.search_for('string !~ FOO').should
|
100
|
+
@class.search_for('string !~ FOO').length.should == 2
|
101
101
|
end
|
102
102
|
|
103
103
|
it "should find the record if one of the query words match using OR" do
|
104
|
-
@class.search_for('foo OR nonsense').should
|
104
|
+
@class.search_for('foo OR nonsense').length.should == 1
|
105
105
|
end
|
106
106
|
|
107
107
|
it "should find no records in one of the AND conditions isn't met" do
|
108
|
-
@class.search_for('foo AND nonsense').should
|
108
|
+
@class.search_for('foo AND nonsense').length.should == 0
|
109
109
|
end
|
110
110
|
|
111
111
|
it "should find two records every single OR conditions matches one single record" do
|
112
|
-
@class.search_for('foo OR baz').should
|
112
|
+
@class.search_for('foo OR baz').length.should == 2
|
113
113
|
end
|
114
114
|
|
115
115
|
it "should find two records every single AND conditions matches one single record" do
|
116
|
-
@class.search_for('foo AND baz').should
|
116
|
+
@class.search_for('foo AND baz').length.should == 0
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
context 'in a field with a different default operator' do
|
121
121
|
it "should find an exact match" do
|
122
|
-
@class.search_for('"temp 1"').should
|
122
|
+
@class.search_for('"temp 1"').length.should == 1
|
123
123
|
end
|
124
124
|
|
125
125
|
it "should find the orther records using NOT and an exact match" do
|
126
|
-
@class.search_for('-"temp 1"').should
|
126
|
+
@class.search_for('-"temp 1"').length.should == 2
|
127
127
|
end
|
128
128
|
|
129
129
|
it "should find an explicit match" do
|
130
|
-
@class.search_for('another = "temp 1"').should
|
130
|
+
@class.search_for('another = "temp 1"').length.should == 1
|
131
131
|
end
|
132
132
|
|
133
133
|
it "should not find a partial match" do
|
134
|
-
@class.search_for('temp').should
|
134
|
+
@class.search_for('temp').length.should == 0
|
135
135
|
end
|
136
136
|
|
137
137
|
it "should find all records using a NOT with a partial match on all records" do
|
138
|
-
@class.search_for('-temp"').should
|
138
|
+
@class.search_for('-temp"').length.should == 3
|
139
139
|
end
|
140
140
|
|
141
141
|
it "should find a partial match when the like operator is given" do
|
142
|
-
@class.search_for('~ temp').should
|
142
|
+
@class.search_for('~ temp').length.should == 2
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
it "should find a negation of partial match when the like operator is give with an explicit NOT operator" do
|
146
|
-
@class.search_for('!(~ temp)').should
|
146
|
+
@class.search_for('!(~ temp)').length.should == 1
|
147
147
|
end
|
148
148
|
|
149
149
|
it "should find a partial match when the like operator and the field name is given" do
|
150
|
-
@class.search_for('another ~ temp').should
|
150
|
+
@class.search_for('another ~ temp').length.should == 2
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
154
|
context 'using an aliased field' do
|
155
155
|
it "should find an explicit match using its alias" do
|
156
|
-
@class.search_for('alias = "temp 1"').should
|
156
|
+
@class.search_for('alias = "temp 1"').length.should == 1
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
160
|
context 'in an explicit string field' do
|
161
161
|
|
162
162
|
it "should not find the records if the explicit field is not given in the query" do
|
163
|
-
@class.search_for('= baz').should
|
163
|
+
@class.search_for('= baz').length.should == 1
|
164
164
|
end
|
165
165
|
|
166
166
|
it "should find all records when searching on the explicit field" do
|
167
|
-
@class.search_for('explicit = baz').should
|
167
|
+
@class.search_for('explicit = baz').length.should == 2
|
168
168
|
end
|
169
169
|
|
170
170
|
it "should find no records if the value in the explicit field is not an exact match" do
|
171
|
-
@class.search_for('explicit = ba').should
|
171
|
+
@class.search_for('explicit = ba').length.should == 0
|
172
172
|
end
|
173
173
|
|
174
174
|
it "should find all records when searching on the explicit field" do
|
175
|
-
@class.search_for('explicit ~ ba').should
|
175
|
+
@class.search_for('explicit ~ ba').length.should == 2
|
176
176
|
end
|
177
177
|
|
178
178
|
it "should only find the record with string = foo and explicit = baz" do
|
179
|
-
@class.search_for('foo, explicit = baz').should
|
179
|
+
@class.search_for('foo, explicit = baz').length.should == 1
|
180
180
|
end
|
181
181
|
end
|
182
182
|
|
183
183
|
context 'using null? and set? queries' do
|
184
184
|
|
185
185
|
it "should return all records if the string field is being checked with set?" do
|
186
|
-
@class.search_for('set? string').should
|
186
|
+
@class.search_for('set? string').length.should == 3
|
187
187
|
end
|
188
188
|
|
189
189
|
it "should return no records if the string field is being checked with null?" do
|
190
|
-
@class.search_for('null? string').should
|
190
|
+
@class.search_for('null? string').length.should == 0
|
191
191
|
end
|
192
192
|
|
193
193
|
it "should return all records with a value if the string field is being checked with set?" do
|
194
|
-
@class.search_for('set? explicit').should
|
194
|
+
@class.search_for('set? explicit').length.should == 2
|
195
195
|
end
|
196
196
|
|
197
197
|
it "should return all records without a value if the string field is being checked with null?" do
|
198
|
-
@class.search_for('null? explicit').should
|
198
|
+
@class.search_for('null? explicit').length.should == 1
|
199
199
|
end
|
200
200
|
end
|
201
201
|
|
202
202
|
context 'using order' do
|
203
203
|
it "sort by string ASC" do
|
204
|
-
@class.search_for(''
|
204
|
+
@class.search_for('', :order => 'string ASC').first.string.should eql('bar')
|
205
205
|
end
|
206
206
|
|
207
207
|
it "sort by string DESC" do
|
208
|
-
@class.search_for(''
|
208
|
+
@class.search_for('', :order => 'string DESC').first.string.should eql('foo')
|
209
209
|
end
|
210
210
|
|
211
211
|
it "sort by description ASC" do
|
212
|
-
@class.search_for(''
|
212
|
+
@class.search_for('', :order => 'description ASC').first.description.should eql('1 - one')
|
213
213
|
end
|
214
214
|
|
215
215
|
it "sort by description DESC" do
|
216
|
-
@class.search_for(''
|
216
|
+
@class.search_for('', :order => 'description DESC').first.description.should eql('3 - three')
|
217
217
|
end
|
218
218
|
|
219
219
|
it "default order by another DESC" do
|
@@ -221,14 +221,12 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
221
221
|
end
|
222
222
|
|
223
223
|
it "resetting order when selecting distinct values" do
|
224
|
-
distinct_search =
|
225
|
-
|
226
|
-
|
227
|
-
Set.new(distinct_search.map(&:explicit)).should == Set['baz', nil]
|
224
|
+
distinct_search = @class.search_for('', :order => '').select('DISTINCT(explicit)')
|
225
|
+
Set.new(distinct_search.to_a.map(&:explicit)).should == Set['baz', nil]
|
228
226
|
end
|
229
227
|
|
230
228
|
it 'should order using symbol' do
|
231
|
-
@class.search_for(''
|
229
|
+
@class.search_for('', :order => :string).first.string.should eql('bar')
|
232
230
|
end
|
233
231
|
end
|
234
232
|
end
|
data/spec/lib/matchers.rb
CHANGED
@@ -23,11 +23,11 @@ RSpec::Matchers.define :parse_to do |tree|
|
|
23
23
|
end
|
24
24
|
|
25
25
|
RSpec::Matchers.define :contain do |*expected|
|
26
|
-
|
26
|
+
match do |actual|
|
27
27
|
expected.all? { |e| actual.include?(e) }
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
match_when_negated do |actual|
|
31
31
|
expected.none? { |e| actual.include?(e) }
|
32
32
|
end
|
33
33
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,4 +13,12 @@ require "#{File.dirname(__FILE__)}/lib/mocks"
|
|
13
13
|
|
14
14
|
RSpec.configure do |config|
|
15
15
|
config.include ScopedSearch::RSpec::Mocks
|
16
|
+
|
17
|
+
config.expect_with :rspec do |c|
|
18
|
+
c.syntax = :should
|
19
|
+
end
|
20
|
+
|
21
|
+
config.mock_with :rspec do |mocks|
|
22
|
+
mocks.syntax = :should
|
23
|
+
end
|
16
24
|
end
|
data/spec/unit/ast_spec.rb
CHANGED
@@ -24,7 +24,7 @@ describe ScopedSearch::QueryLanguage::AST do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should create a child node for every subsequent array item" do
|
27
|
-
@ast.should
|
27
|
+
@ast.children.length.should == 1
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should create set the RHS the the first child value" do
|
@@ -42,7 +42,7 @@ describe ScopedSearch::QueryLanguage::AST do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should create a child node for every subsequent array item" do
|
45
|
-
@ast.should
|
45
|
+
@ast.children.length.should == 2
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should create set the LHS the the first child value" do
|
@@ -64,7 +64,7 @@ describe ScopedSearch::QueryLanguage::AST do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should create a child node for every subsequent array item" do
|
67
|
-
@ast.should
|
67
|
+
@ast.children.length.should == 2
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should create a nested OR structure for a nested array" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scoped_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amos Benari
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-11-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -18,28 +18,28 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - '>='
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version:
|
28
|
+
version: 3.0.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: rspec
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - ~>
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
35
|
+
version: '3.0'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - ~>
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '3.0'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: rake
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,17 +54,17 @@ dependencies:
|
|
54
54
|
- - '>='
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
|
-
description:
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
57
|
+
description: |2
|
58
|
+
Scoped search makes it easy to search your ActiveRecord-based models.
|
59
|
+
|
60
|
+
It will create a named scope :search_for that can be called with a query string. It will build an SQL query using
|
61
|
+
the provided query string and a definition that specifies on what fields to search. Because the functionality is
|
62
|
+
built on named_scope, the result of the search_for call can be used like any other named_scope, so it can be
|
63
|
+
chained with another scope or combined with will_paginate.
|
64
|
+
|
65
|
+
Because it uses standard SQL, it does not require any setup, indexers or daemons. This makes scoped_search
|
66
|
+
suitable to quickly add basic search functionality to your application with little hassle. On the other hand,
|
67
|
+
it may not be the best choice if it is going to be used on very large datasets or by a large user base.
|
68
68
|
email:
|
69
69
|
- abenari@redhat.com
|
70
70
|
- willem@railsdoctors.com
|
@@ -73,20 +73,24 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files:
|
75
75
|
- README.rdoc
|
76
|
+
- CHANGELOG.rdoc
|
77
|
+
- CONTRIBUTING.rdoc
|
78
|
+
- LICENSE
|
76
79
|
files:
|
77
80
|
- .gitignore
|
78
81
|
- .travis.yml
|
82
|
+
- CHANGELOG.rdoc
|
83
|
+
- CONTRIBUTING.rdoc
|
79
84
|
- Gemfile
|
80
|
-
- Gemfile.activerecord2
|
81
85
|
- Gemfile.activerecord3
|
82
|
-
- Gemfile.
|
86
|
+
- Gemfile.activerecord40
|
87
|
+
- Gemfile.activerecord41
|
83
88
|
- LICENSE
|
84
89
|
- README.rdoc
|
85
90
|
- Rakefile
|
86
91
|
- app/assets/images/spinner.gif
|
87
92
|
- app/assets/javascripts/scoped_search.js
|
88
93
|
- app/assets/stylesheets/scoped_search.scss
|
89
|
-
- init.rb
|
90
94
|
- lib/scoped_search.rb
|
91
95
|
- lib/scoped_search/auto_complete_builder.rb
|
92
96
|
- lib/scoped_search/compass.rb
|
@@ -139,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
143
|
requirements:
|
140
144
|
- - '>='
|
141
145
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
146
|
+
version: 1.9.3
|
143
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
148
|
requirements:
|
145
149
|
- - '>='
|
@@ -147,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
151
|
version: '0'
|
148
152
|
requirements: []
|
149
153
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.0.
|
154
|
+
rubygems_version: 2.0.14
|
151
155
|
signing_key:
|
152
156
|
specification_version: 4
|
153
157
|
summary: Easily search you ActiveRecord models with a simple query language using
|