scoped_from 1.0.1 → 2.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 +5 -5
- data/VERSION +1 -1
- data/lib/scoped_from/query.rb +8 -8
- data/lib/scoped_from.rb +2 -2
- data/scoped_from.gemspec +13 -11
- metadata +85 -43
- data/.gitignore +0 -7
- data/.rspec +0 -2
- data/Gemfile +0 -3
- data/Rakefile +0 -10
- data/spec/mocks/comment.rb +0 -2
- data/spec/mocks/comment_query.rb +0 -2
- data/spec/mocks/post.rb +0 -2
- data/spec/mocks/user.rb +0 -8
- data/spec/mocks/user_query.rb +0 -2
- data/spec/mocks/vote.rb +0 -2
- data/spec/mocks/vote_query.rb +0 -2
- data/spec/scoped_from/active_record_spec.rb +0 -125
- data/spec/scoped_from/query_spec.rb +0 -490
- data/spec/scoped_from_spec.rb +0 -20
- data/spec/spec_helper.rb +0 -27
- data/spec/support/bootstrap/database.rb +0 -12
- data/spec/support/macros/user_macro.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c174dce6961320bbde11d567cc8182fddef4ece108a0e606100dc089884490ae
|
4
|
+
data.tar.gz: 040e97a0b3d983fd099d1f3cd306a2d61cd43b2e00b45ab183359b16a86d2bbb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f66fb8926e1e5d443df1b896540f207951c416b4ef47bb969d7e090ccfc73cae75d36996019f7dd48edaa70f1472b427a35d96268a8d3882a07ecd2cb127e2e1
|
7
|
+
data.tar.gz: 9e718bc1814ca6259f8bf62290199a36f026d94afdc5dc49ed615cfec8a5b0f7a12ff41b55514e2f90873e58b501ea412389c8da7a64bd9e521a446c66e84ad1
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/lib/scoped_from/query.rb
CHANGED
@@ -27,8 +27,8 @@ module ScopedFrom
|
|
27
27
|
def relation
|
28
28
|
relation = @relation
|
29
29
|
params.each do |name, value|
|
30
|
-
[value].flatten.each do |
|
31
|
-
relation = invoke_param(relation, name,
|
30
|
+
[value].flatten.each do |val|
|
31
|
+
relation = invoke_param(relation, name, val)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
decorate_relation(relation)
|
@@ -83,14 +83,14 @@ module ScopedFrom
|
|
83
83
|
orders = parse_orders(values).map { |order| "#{order[:column]}.#{order[:direction]}" }
|
84
84
|
@params[name] = (orders.many? ? orders : orders.first) if orders.any?
|
85
85
|
elsif @relation.scope_without_argument?(name)
|
86
|
-
@params[name] = true if values.all? { |
|
86
|
+
@params[name] = true if values.all? { |val| true?(val) }
|
87
87
|
elsif @relation.scope_with_one_argument?(name)
|
88
88
|
value = values.many? ? values : values.first
|
89
89
|
@params[name] = @params[name] ? [@params[name], value].flatten : value
|
90
90
|
elsif @options[:exclude_columns].blank? && @relation.column_names.include?(name.to_s)
|
91
91
|
if @relation.columns_hash[name.to_s].type == :boolean
|
92
|
-
@params[name] = true if values.all? { |
|
93
|
-
@params[name] = false if values.all? { |
|
92
|
+
@params[name] = true if values.all? { |val| true?(val) }
|
93
|
+
@params[name] = false if values.all? { |val| false?(val) }
|
94
94
|
else
|
95
95
|
value = values.many? ? values : values.first
|
96
96
|
@params[name] = @params[name] ? [@params[name], value].flatten : value
|
@@ -102,17 +102,17 @@ module ScopedFrom
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def parse_order(value)
|
105
|
-
column, direction = value.to_s.split(/[
|
105
|
+
column, direction = value.to_s.split(/[.:\s]+/, 2)
|
106
106
|
direction = direction.to_s.downcase
|
107
107
|
direction = ORDER_DIRECTIONS.first unless ORDER_DIRECTIONS.include?(direction)
|
108
|
-
@relation.column_names.include?(column) ? { column
|
108
|
+
@relation.column_names.include?(column) ? { column:, direction: } : {}
|
109
109
|
end
|
110
110
|
|
111
111
|
def parse_orders(values)
|
112
112
|
[].tap do |orders|
|
113
113
|
values.each do |value|
|
114
114
|
order = parse_order(value)
|
115
|
-
orders << order if order.present? &&
|
115
|
+
orders << order if order.present? && orders.none? { |o| o[:column] == order[:column] }
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|
data/lib/scoped_from.rb
CHANGED
@@ -9,7 +9,7 @@ require 'active_support/core_ext/object/to_query'
|
|
9
9
|
module ScopedFrom
|
10
10
|
|
11
11
|
def self.version
|
12
|
-
|
12
|
+
@version ||= File.read(File.expand_path("#{__dir__}/../VERSION")).strip.freeze
|
13
13
|
end
|
14
14
|
|
15
15
|
end
|
@@ -19,4 +19,4 @@ lib_path = "#{__dir__}/scoped_from"
|
|
19
19
|
require "#{lib_path}/active_record"
|
20
20
|
require "#{lib_path}/query"
|
21
21
|
|
22
|
-
ActiveRecord::Base.
|
22
|
+
ActiveRecord::Base.include(ScopedFrom::ActiveRecord)
|
data/scoped_from.gemspec
CHANGED
@@ -9,19 +9,21 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.description = 'Provides a simple mapping between Active Record scopes and controller parameters for Ruby On Rails 4'
|
10
10
|
s.license = 'MIT'
|
11
11
|
|
12
|
-
s.
|
13
|
-
|
14
|
-
s.files = `git ls-files`.split("\n")
|
15
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
s.files = %x(git ls-files | grep -vE '^(spec/|test/|\\.|Gemfile|Rakefile)').split("\n")
|
13
|
+
s.executables = %x(git ls-files -- bin/*).split("\n").map { |f| File.basename(f) }
|
17
14
|
s.require_paths = ['lib']
|
18
15
|
|
19
|
-
s.
|
20
|
-
|
16
|
+
s.required_ruby_version = '>= 3.1.0'
|
17
|
+
|
18
|
+
s.add_dependency 'activerecord', '>= 7.0.0', '< 8.0.0'
|
19
|
+
s.add_dependency 'activesupport', '>= 7.0.0', '< 8.0.0'
|
21
20
|
|
22
|
-
s.add_development_dependency 'actionpack', '>=
|
23
|
-
s.add_development_dependency 'byebug', '>= 3.2.0', '<
|
24
|
-
s.add_development_dependency 'rake', '>= 10.3.0', '<
|
25
|
-
s.add_development_dependency 'rspec', '>= 3.1.0', '< 3.
|
21
|
+
s.add_development_dependency 'actionpack', '>= 7.0.0', '< 8.0.0'
|
22
|
+
s.add_development_dependency 'byebug', '>= 3.2.0', '< 12.0.0'
|
23
|
+
s.add_development_dependency 'rake', '>= 10.3.0', '< 14.0.0'
|
24
|
+
s.add_development_dependency 'rspec', '>= 3.1.0', '< 3.11.0'
|
25
|
+
s.add_development_dependency 'rubocop', '>= 1.25.0', '< 2.0.0'
|
26
|
+
s.add_development_dependency 'rubocop-rake', '>= 0.6.0', '< 1.0.0'
|
27
|
+
s.add_development_dependency 'rubocop-rspec', '>= 2.8.0', '< 3.0.0'
|
26
28
|
s.add_development_dependency 'sqlite3-ruby', '>= 1.3.0', '< 1.4.0'
|
27
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scoped_from
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Toulotte
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,60 +16,60 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 7.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 8.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 7.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 8.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 7.0.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
42
|
+
version: 8.0.0
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 7.0.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
52
|
+
version: 8.0.0
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: actionpack
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version:
|
59
|
+
version: 7.0.0
|
60
60
|
- - "<"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: 8.0.0
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 7.0.0
|
70
70
|
- - "<"
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version:
|
72
|
+
version: 8.0.0
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
74
|
name: byebug
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,7 +79,7 @@ dependencies:
|
|
79
79
|
version: 3.2.0
|
80
80
|
- - "<"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 12.0.0
|
83
83
|
type: :development
|
84
84
|
prerelease: false
|
85
85
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -89,7 +89,7 @@ dependencies:
|
|
89
89
|
version: 3.2.0
|
90
90
|
- - "<"
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
92
|
+
version: 12.0.0
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
94
|
name: rake
|
95
95
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,7 +99,7 @@ dependencies:
|
|
99
99
|
version: 10.3.0
|
100
100
|
- - "<"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
102
|
+
version: 14.0.0
|
103
103
|
type: :development
|
104
104
|
prerelease: false
|
105
105
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
version: 10.3.0
|
110
110
|
- - "<"
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
112
|
+
version: 14.0.0
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: rspec
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,7 +119,7 @@ dependencies:
|
|
119
119
|
version: 3.1.0
|
120
120
|
- - "<"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: 3.
|
122
|
+
version: 3.11.0
|
123
123
|
type: :development
|
124
124
|
prerelease: false
|
125
125
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -129,7 +129,67 @@ dependencies:
|
|
129
129
|
version: 3.1.0
|
130
130
|
- - "<"
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version: 3.
|
132
|
+
version: 3.11.0
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: rubocop
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 1.25.0
|
140
|
+
- - "<"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 2.0.0
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 1.25.0
|
150
|
+
- - "<"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 2.0.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop-rake
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.6.0
|
160
|
+
- - "<"
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: 1.0.0
|
163
|
+
type: :development
|
164
|
+
prerelease: false
|
165
|
+
version_requirements: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: 0.6.0
|
170
|
+
- - "<"
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: 1.0.0
|
173
|
+
- !ruby/object:Gem::Dependency
|
174
|
+
name: rubocop-rspec
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: 2.8.0
|
180
|
+
- - "<"
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: 3.0.0
|
183
|
+
type: :development
|
184
|
+
prerelease: false
|
185
|
+
version_requirements: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 2.8.0
|
190
|
+
- - "<"
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: 3.0.0
|
133
193
|
- !ruby/object:Gem::Dependency
|
134
194
|
name: sqlite3-ruby
|
135
195
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,35 +217,18 @@ executables: []
|
|
157
217
|
extensions: []
|
158
218
|
extra_rdoc_files: []
|
159
219
|
files:
|
160
|
-
- ".gitignore"
|
161
|
-
- ".rspec"
|
162
|
-
- Gemfile
|
163
220
|
- MIT-LICENSE
|
164
221
|
- README.mdown
|
165
|
-
- Rakefile
|
166
222
|
- VERSION
|
167
223
|
- lib/scoped_from.rb
|
168
224
|
- lib/scoped_from/active_record.rb
|
169
225
|
- lib/scoped_from/query.rb
|
170
226
|
- scoped_from.gemspec
|
171
|
-
- spec/mocks/comment.rb
|
172
|
-
- spec/mocks/comment_query.rb
|
173
|
-
- spec/mocks/post.rb
|
174
|
-
- spec/mocks/user.rb
|
175
|
-
- spec/mocks/user_query.rb
|
176
|
-
- spec/mocks/vote.rb
|
177
|
-
- spec/mocks/vote_query.rb
|
178
|
-
- spec/scoped_from/active_record_spec.rb
|
179
|
-
- spec/scoped_from/query_spec.rb
|
180
|
-
- spec/scoped_from_spec.rb
|
181
|
-
- spec/spec_helper.rb
|
182
|
-
- spec/support/bootstrap/database.rb
|
183
|
-
- spec/support/macros/user_macro.rb
|
184
227
|
homepage: https://github.com/alexistoulotte/scoped_from
|
185
228
|
licenses:
|
186
229
|
- MIT
|
187
230
|
metadata: {}
|
188
|
-
post_install_message:
|
231
|
+
post_install_message:
|
189
232
|
rdoc_options: []
|
190
233
|
require_paths:
|
191
234
|
- lib
|
@@ -193,16 +236,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
193
236
|
requirements:
|
194
237
|
- - ">="
|
195
238
|
- !ruby/object:Gem::Version
|
196
|
-
version:
|
239
|
+
version: 3.1.0
|
197
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
241
|
requirements:
|
199
242
|
- - ">="
|
200
243
|
- !ruby/object:Gem::Version
|
201
244
|
version: '0'
|
202
245
|
requirements: []
|
203
|
-
|
204
|
-
|
205
|
-
signing_key:
|
246
|
+
rubygems_version: 3.3.3
|
247
|
+
signing_key:
|
206
248
|
specification_version: 4
|
207
249
|
summary: Mapping between scopes and parameters for Rails
|
208
250
|
test_files: []
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
data/spec/mocks/comment.rb
DELETED
data/spec/mocks/comment_query.rb
DELETED
data/spec/mocks/post.rb
DELETED
data/spec/mocks/user.rb
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
class User < ActiveRecord::Base
|
2
|
-
|
3
|
-
scope :enabled, -> { where(enabled: true) }
|
4
|
-
scope :search, -> (pattern) { where('firstname LIKE ? OR lastname LIKE ?', "%#{pattern}%", "%#{pattern}%") }
|
5
|
-
scope :created_between, -> (after, before) { where('created_at >= ? AND created_at <= ?', after, before) }
|
6
|
-
scope :latest, -> { where('created_at >= ?', 1.week.ago) }
|
7
|
-
|
8
|
-
end
|
data/spec/mocks/user_query.rb
DELETED
data/spec/mocks/vote.rb
DELETED
data/spec/mocks/vote_query.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ScopedFrom::ActiveRecord do
|
4
|
-
|
5
|
-
describe '#scope_with_one_argument?' do
|
6
|
-
|
7
|
-
it 'is true if scope has one argument' do
|
8
|
-
expect(User.scope_with_one_argument?(:search)).to be(true)
|
9
|
-
expect(User.scope_with_one_argument?('search')).to be(true)
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'is false if scope has no argument' do
|
13
|
-
expect(User.scope_with_one_argument?(:latest)).to be(false)
|
14
|
-
expect(User.scope_with_one_argument?('latest')).to be(false)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'is false if scope has more than one argument' do
|
18
|
-
expect(User.scope_with_one_argument?(:created_between)).to be(false)
|
19
|
-
expect(User.scope_with_one_argument?('created_between')).to be(false)
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'is false if scope is not a proc' do
|
23
|
-
expect(User.scope_with_one_argument?(:enabled)).to be(false)
|
24
|
-
expect(User.scope_with_one_argument?('enabled')).to be(false)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'is false if scope does not exist' do
|
28
|
-
expect(User.scope_with_one_argument?(:foo)).to be(false)
|
29
|
-
expect(User.scope_with_one_argument?('foo')).to be(false)
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
describe 'scope_without_argument?' do
|
35
|
-
|
36
|
-
it 'is true if scope has no argument' do
|
37
|
-
expect(User.scope_without_argument?(:latest)).to be(true)
|
38
|
-
expect(User.scope_without_argument?('latest')).to be(true)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'is true if scope is not a proc' do
|
42
|
-
expect(User.scope_without_argument?(:enabled)).to be(true)
|
43
|
-
expect(User.scope_without_argument?('enabled')).to be(true)
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'is false if scope has one argument' do
|
47
|
-
expect(User.scope_without_argument?(:search)).to be(false)
|
48
|
-
expect(User.scope_without_argument?('search')).to be(false)
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'is false if scope has more than one argument' do
|
52
|
-
expect(User.scope_without_argument?(:created_between)).to be(false)
|
53
|
-
expect(User.scope_without_argument?('created_between')).to be(false)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'is false if scope does not exist' do
|
57
|
-
expect(User.scope_without_argument?(:foo)).to be(false)
|
58
|
-
expect(User.scope_without_argument?('foo')).to be(false)
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#scoped_from' do
|
64
|
-
|
65
|
-
it 'just build a new query and return its scope' do
|
66
|
-
query = double(:query)
|
67
|
-
expect(query).to receive(:relation).and_return(42)
|
68
|
-
expect(ScopedFrom::Query).to receive(:new).with(User, 'foo', except: 'bam').and_return(query)
|
69
|
-
expect(User.scoped_from('foo', except: 'bam')).to eq(42)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'build scopes' do
|
73
|
-
expect(User.scoped_from(search: 'jane')).to eq([users(:jane)])
|
74
|
-
expect(User.scoped_from(search: 'john')).to eq([users(:john)])
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'can be chained with other scopes' do
|
78
|
-
expect(User.scoped_from(search: 'jane')).to eq([users(:jane)])
|
79
|
-
expect(User.enabled.scoped_from(search: 'jane')).to eq([])
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'can be used with order as parameter' do
|
83
|
-
expect(User.scoped_from(order: 'firstname').first).to eq(users(:jane))
|
84
|
-
expect(User.scoped_from(order: 'firstname.desc').first).to eq(users(:john))
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'builds a ScopedFrom::Query' do
|
88
|
-
expect(User.scoped_from({}).query.class).to be(ScopedFrom::Query)
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'builds a ScopedFrom::Query if #{RecordClassName}Query is not defined' do
|
92
|
-
expect(Post.scoped_from({}).query.class).to be(ScopedFrom::Query)
|
93
|
-
expect(Object.const_defined?('PostQuery')).to be(false)
|
94
|
-
expect {
|
95
|
-
PostQuery
|
96
|
-
}.to raise_error(NameError, 'uninitialized constant PostQuery')
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'builds a #{Class}Query if #{RecordClassName}Query is defined and is a ScopedFrom::Query' do
|
100
|
-
expect(Comment.scoped_from({}).query.class).to be(CommentQuery)
|
101
|
-
expect(Comment.where(foo: 'bar').scoped_from({}).query.class).to be(CommentQuery)
|
102
|
-
expect(CommentQuery).to be_a(Class)
|
103
|
-
expect(CommentQuery.ancestors).to include(ScopedFrom::Query)
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'builds a ScopedFrom::Query if #{RecordClassName}Query is defined but not a subclass of ScopedFrom::Query' do
|
107
|
-
expect(User.scoped_from({}).query.class).to be(ScopedFrom::Query)
|
108
|
-
expect(Object.const_defined?('UserQuery')).to be(true)
|
109
|
-
expect(UserQuery).to be_a(Class)
|
110
|
-
expect(UserQuery.ancestors).not_to include(ScopedFrom::Query)
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'builds a ScopedFrom::Query if #{RecordClassName}Query is defined but is a module' do
|
114
|
-
expect(Vote.scoped_from({}).query.class).to be(ScopedFrom::Query)
|
115
|
-
expect(Object.const_defined?('VoteQuery')).to be(true)
|
116
|
-
expect(VoteQuery).to be_a(Module)
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'is accepts ActionController::Parameters' do
|
120
|
-
expect(User.scoped_from(ActionController::Parameters.new(search: 'jane'))).to eq([users(:jane)])
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
@@ -1,490 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ScopedFrom::Query do
|
4
|
-
|
5
|
-
def query(relation = User, params = {}, options = {})
|
6
|
-
ScopedFrom::Query.new(relation, params, options)
|
7
|
-
end
|
8
|
-
|
9
|
-
describe '#false?' do
|
10
|
-
|
11
|
-
it 'is true if false is given' do
|
12
|
-
expect(query.send(:false?, false)).to be(true)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'is true if "false" is given' do
|
16
|
-
expect(query.send(:false?, 'false')).to be(true)
|
17
|
-
expect(query.send(:false?, 'False')).to be(true)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'is true if "0" is given' do
|
21
|
-
expect(query.send(:false?, '0')).to be(true)
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'is true if "off" is given' do
|
25
|
-
expect(query.send(:false?, 'off')).to be(true)
|
26
|
-
expect(query.send(:false?, 'OFF ')).to be(true)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'is true if "no" is given' do
|
30
|
-
expect(query.send(:false?, 'no')).to be(true)
|
31
|
-
expect(query.send(:false?, ' No ')).to be(true)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'is true if "n" is given' do
|
35
|
-
expect(query.send(:false?, 'n')).to be(true)
|
36
|
-
expect(query.send(:false?, 'N ')).to be(true)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'is false if true is given' do
|
40
|
-
expect(query.send(:false?, true)).to be(false)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'is false if "true" is given' do
|
44
|
-
expect(query.send(:false?, 'true')).to be(false)
|
45
|
-
expect(query.send(:false?, 'TrUe')).to be(false)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'is false if "1" is given' do
|
49
|
-
expect(query.send(:false?, '1')).to be(false)
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'is false if "on" is given' do
|
53
|
-
expect(query.send(:false?, "on")).to be(false)
|
54
|
-
expect(query.send(:false?, "On")).to be(false)
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'is false otherwise' do
|
58
|
-
expect(query.send(:false?, 42)).to be(false)
|
59
|
-
expect(query.send(:false?, 'bam')).to be(false)
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
describe '#initialize' do
|
65
|
-
|
66
|
-
it 'invokes .all method on given class' do
|
67
|
-
expect(User).to receive(:all)
|
68
|
-
ScopedFrom::Query.new(User, {})
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'does not invokes .all method on given relation' do
|
72
|
-
relation = User.all
|
73
|
-
expect(relation).not_to receive(:all)
|
74
|
-
ScopedFrom::Query.new(relation, {})
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
describe '#invoke_param' do
|
80
|
-
|
81
|
-
it 'returns given scope if it has no scope with specified name' do
|
82
|
-
expect(query.send(:invoke_param, User, :foo, true)).to eq(User)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'returns given scope if scope takes more than 1 argument' do
|
86
|
-
expect(query.send(:invoke_param, User, :created_between, true)).to eq(User)
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'invokes scope without arguments if scope takes no arguments' do
|
90
|
-
expect(query.send(:invoke_param, User.all, :enabled, true)).to eq([users(:john)])
|
91
|
-
expect(query.send(:invoke_param, User.all, :enabled, ' 1 ')).to eq([users(:john)])
|
92
|
-
expect(query.send(:invoke_param, User.all, :enabled, 'off')).to eq([users(:john)])
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'invokes scope with value has argument if scope takes one argument' do
|
96
|
-
expect(query.send(:invoke_param, User.all, :search, 'doe')).to eq([users(:john), users(:jane)])
|
97
|
-
expect(query.send(:invoke_param, User.all, :search, 'john')).to eq([users(:john)])
|
98
|
-
expect(query.send(:invoke_param, User.all, :search, 'jane')).to eq([users(:jane)])
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'scope on column conditions' do
|
102
|
-
expect(query.send(:invoke_param, User.all, :firstname, 'Jane')).to eq([users(:jane)])
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'invokes "order"' do
|
106
|
-
expect(query.send(:invoke_param, User.all, :order, 'firstname.asc')).to eq([users(:jane), users(:john)])
|
107
|
-
expect(query.send(:invoke_param, User.all, :order, 'firstname.desc')).to eq([users(:john), users(:jane)])
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
describe '#options' do
|
113
|
-
|
114
|
-
it 'is set at initialization' do
|
115
|
-
expect(ScopedFrom::Query.new(User, {}, bar: 'foo').instance_variable_get(:@options)).to eq(bar: 'foo')
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'keys are symbolized' do
|
119
|
-
expect(ScopedFrom::Query.new(User, {}, 'bar' => 'foo').instance_variable_get(:@options)).to eq(bar: 'foo')
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
describe '#order_column' do
|
125
|
-
|
126
|
-
it 'is column specified into "order" parameter' do
|
127
|
-
expect(query(User, order: 'firstname').order_column).to eq('firstname')
|
128
|
-
expect(query(User, order: 'lastname.desc').order_column).to eq('lastname')
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'is nil if column does not exist' do
|
132
|
-
expect(query(User, order: 'foo').order_column).to be_nil
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'is nil if "order" param is not specified' do
|
136
|
-
expect(query(User, search: 'foo').order_column).to be_nil
|
137
|
-
end
|
138
|
-
|
139
|
-
end
|
140
|
-
|
141
|
-
describe '#order_direction' do
|
142
|
-
|
143
|
-
it 'is direction specified into "order" parameter' do
|
144
|
-
expect(query(User, order: 'firstname.asc').order_direction).to eq('asc')
|
145
|
-
expect(query(User, order: 'firstname.desc').order_direction).to eq('desc')
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'is "asc" if direction is not specified' do
|
149
|
-
expect(query(User, order: 'firstname').order_direction).to eq('asc')
|
150
|
-
end
|
151
|
-
|
152
|
-
it 'is "asc" if direction is invalid' do
|
153
|
-
expect(query(User, order: 'firstname.foo').order_direction).to eq('asc')
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'is direction even specified in another case' do
|
157
|
-
expect(query(User, order: 'firstname.ASc').order_direction).to eq('asc')
|
158
|
-
expect(query(User, order: 'firstname.DeSC').order_direction).to eq('desc')
|
159
|
-
end
|
160
|
-
|
161
|
-
it 'is nil if column does not exist' do
|
162
|
-
expect(query(User, order: 'foo.desc').order_direction).to be_nil
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'is nil if "order" param is not specified' do
|
166
|
-
expect(query(User, search: 'foo').order_direction).to be_nil
|
167
|
-
end
|
168
|
-
|
169
|
-
end
|
170
|
-
|
171
|
-
describe '#params' do
|
172
|
-
|
173
|
-
it 'returns params specified at initialization' do
|
174
|
-
expect(query(User, search: 'foo', 'enabled' => true).params).to eq({ 'search' => 'foo', 'enabled' => true })
|
175
|
-
end
|
176
|
-
|
177
|
-
it 'returns an hash with indifferent access' do
|
178
|
-
expect(query(User, 'search' => 'bar').params).to be_a(ActiveSupport::HashWithIndifferentAccess)
|
179
|
-
expect(query(User, 'search' => 'bar').params[:search]).to eq('bar')
|
180
|
-
expect(query(User, search: 'bar').params['search']).to eq('bar')
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'can be converted to query string' do
|
184
|
-
expect(query(User, search: ['foo', 'bar'], 'enabled' => '1').params.to_query).to eq('enabled=true&search%5B%5D=foo&search%5B%5D=bar')
|
185
|
-
end
|
186
|
-
|
187
|
-
end
|
188
|
-
|
189
|
-
describe '#params=' do
|
190
|
-
|
191
|
-
it 'does not fails if nil is given' do
|
192
|
-
expect(query(User, nil).params).to eq({})
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'removes values that are not scopes' do
|
196
|
-
expect(query(User, foo: 'bar', 'search' => 'foo', enabled: true).params).to eq({ 'search' => 'foo', 'enabled' => true })
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'is case sensitive' do
|
200
|
-
expect(query(User, 'Enabled' => true, "SEARCH" => 'bar').params).to be_empty
|
201
|
-
end
|
202
|
-
|
203
|
-
it 'parse query string' do
|
204
|
-
expect(query(User, 'search=foo%26baz&latest=true').params).to eq({ 'search' => 'foo&baz', 'latest' => true })
|
205
|
-
end
|
206
|
-
|
207
|
-
it 'removes blank values from query string' do
|
208
|
-
expect(query(User, 'search=baz&toto=&bar=%20').params).to eq({ 'search' => 'baz' })
|
209
|
-
end
|
210
|
-
|
211
|
-
it 'unescapes UTF-8 chars' do
|
212
|
-
expect(query(User, 'search=%C3%A9').params).to eq({ 'search' => 'é' })
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'can have multiple values (from hash)' do
|
216
|
-
expect(query(User, search: ['bar', 'baz']).params).to eq({ 'search' => ['bar', 'baz'] })
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'can have multiple values (from query string)' do
|
220
|
-
expect(query(User, 'search=bar&search=baz').params).to eq({ 'search' => ['bar', 'baz'] })
|
221
|
-
end
|
222
|
-
|
223
|
-
it 'converts value to true (or remove it) if scope takes no argument' do
|
224
|
-
expect(query(User, latest: 'y').params).to eq({ 'latest' => true })
|
225
|
-
expect(query(User, latest: 'no').params).to eq({})
|
226
|
-
end
|
227
|
-
|
228
|
-
it 'converts value to true (or false) if column is a boolean one' do
|
229
|
-
expect(query(User, admin: 'y').params).to eq({ 'admin' => true })
|
230
|
-
expect(query(User, admin: 'False').params).to eq({ 'admin' => false })
|
231
|
-
expect(query(User, admin: 'bar').params).to eq({})
|
232
|
-
expect(query(User, admin: ['y', false]).params).to eq({})
|
233
|
-
end
|
234
|
-
|
235
|
-
it 'converts array value to true (or remove it) if scope takes no argument' do
|
236
|
-
expect(query(User, latest: true).params).to eq({ 'latest' => true })
|
237
|
-
expect(query(User, latest: ['Yes']).params).to eq({ 'latest' => true })
|
238
|
-
expect(query(User, latest: ['no', 'yes']).params).to eq({})
|
239
|
-
expect(query(User, latest: ['no', nil]).params).to eq({})
|
240
|
-
expect(query(User, latest: ['fo']).params).to eq({})
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'flats array' do
|
244
|
-
expect(query(User, search: [nil, ['bar', '', 'foo', ["\n ", 'baz']]]).params).to eq({ 'search' => [nil, 'bar', '', 'foo', "\n ", 'baz'] })
|
245
|
-
end
|
246
|
-
|
247
|
-
it 'change array with a single value in one value' do
|
248
|
-
expect(query(User, search: ['bar']).params).to eq({ 'search' => 'bar' })
|
249
|
-
end
|
250
|
-
|
251
|
-
it 'does not modify given hash' do
|
252
|
-
hash = { search: 'foo', enabled: '1', bar: 'foo' }
|
253
|
-
query(User, hash)
|
254
|
-
expect(hash).to eq({ search: 'foo', enabled: '1', bar: 'foo' })
|
255
|
-
end
|
256
|
-
|
257
|
-
it 'does not modify given array' do
|
258
|
-
items = ['bar', 'foo', nil]
|
259
|
-
query(User, search: items)
|
260
|
-
expect(items).to eq(['bar', 'foo', nil])
|
261
|
-
end
|
262
|
-
|
263
|
-
it 'accepts :only option' do
|
264
|
-
expect(query(User, { search: 'bar', enabled: 'true' }, only: [:search]).params).to eq({ 'search' => 'bar' })
|
265
|
-
expect(query(User, { search: 'bar', enabled: 'true' }, only: 'search').params).to eq({ 'search' => 'bar' })
|
266
|
-
expect(query(User, { search: 'bar', firstname: 'Jane', enabled: 'true' }, only: 'search').params).to eq({ 'search' => 'bar' })
|
267
|
-
expect(query(User, { search: 'bar', firstname: 'Jane', enabled: 'true' }, only: ['search', :firstname]).params).to eq({ 'search' => 'bar', 'firstname' => 'Jane' })
|
268
|
-
end
|
269
|
-
|
270
|
-
it 'accepts :except option' do
|
271
|
-
expect(query(User, { search: 'bar', enabled: true }, except: [:search]).params).to eq({ 'enabled' => true })
|
272
|
-
expect(query(User, { search: 'bar', enabled: true }, except: 'search').params).to eq({ 'enabled' => true })
|
273
|
-
expect(query(User, { search: 'bar', firstname: 'Jane', enabled: true }, except: 'search').params).to eq({ 'enabled' => true, 'firstname' => 'Jane' })
|
274
|
-
expect(query(User, { search: 'bar', firstname: 'Jane', enabled: true }, except: ['search', :firstname]).params).to eq({ 'enabled' => true })
|
275
|
-
end
|
276
|
-
|
277
|
-
it 'accepts a query instance' do
|
278
|
-
expect(query(User, query(User, search: 'toto')).params).to eq({ 'search' => 'toto' })
|
279
|
-
end
|
280
|
-
|
281
|
-
it 'preserve blank values' do
|
282
|
-
expect(query(User, { search: "\n ", 'enabled' => true }).params).to eq({ 'search' => "\n ", 'enabled' => true })
|
283
|
-
end
|
284
|
-
|
285
|
-
it 'preserve blank values from array' do
|
286
|
-
expect(query(User, { 'search' => ["\n ", 'toto', 'titi'] }).params).to eq({ 'search' => ["\n ", 'toto', 'titi'] })
|
287
|
-
expect(query(User, { 'search' => [] }).params).to eq({})
|
288
|
-
end
|
289
|
-
|
290
|
-
it 'also preserve blank on query string' do
|
291
|
-
expect(query(User, 'search=%20&enabled=true&search=foo').params).to eq({ 'search' => [' ', 'foo'], 'enabled' => true })
|
292
|
-
end
|
293
|
-
|
294
|
-
it 'includes column values' do
|
295
|
-
expect(query(User, 'firstname' => 'Jane', 'foo' => 'bar').params).to eq({ 'firstname' => 'Jane' })
|
296
|
-
expect(query(User, firstname: 'Jane', 'foo' => 'bar').params).to eq({ 'firstname' => 'Jane' })
|
297
|
-
end
|
298
|
-
|
299
|
-
it 'exclude column values if :exclude_columns option is specified' do
|
300
|
-
expect(query(User, { enabled: true, 'firstname' => 'Jane', 'foo' => 'bar' }, exclude_columns: true).params).to eq({ 'enabled' => true })
|
301
|
-
expect(query(User, { enabled: true, firstname: 'Jane', foo: 'bar' }, exclude_columns: true).params).to eq({ 'enabled' => true })
|
302
|
-
end
|
303
|
-
|
304
|
-
it 'scopes have priority on columns' do
|
305
|
-
expect(query(User, enabled: false).params).to eq({})
|
306
|
-
end
|
307
|
-
|
308
|
-
it 'maps an "order"' do
|
309
|
-
expect(query(User, { 'order' => 'firstname.asc' }).params).to eq({ 'order' => 'firstname.asc' })
|
310
|
-
end
|
311
|
-
|
312
|
-
it 'does not map "order" if column is invalid' do
|
313
|
-
expect(query(User, { 'order' => 'foo.asc' }).params).to eq({})
|
314
|
-
end
|
315
|
-
|
316
|
-
it 'use "asc" order direction by default' do
|
317
|
-
expect(query(User, { 'order' => 'firstname' }).params).to eq({ 'order' => 'firstname.asc' })
|
318
|
-
end
|
319
|
-
|
320
|
-
it 'use "asc" order direction if invalid' do
|
321
|
-
expect(query(User, { 'order' => 'firstname.bar' }).params).to eq({ 'order' => 'firstname.asc' })
|
322
|
-
end
|
323
|
-
|
324
|
-
it 'use "desc" order direction if specified' do
|
325
|
-
expect(query(User, { 'order' => 'firstname.desc' }).params).to eq({ 'order' => 'firstname.desc' })
|
326
|
-
end
|
327
|
-
|
328
|
-
it 'order direction is case insensitive' do
|
329
|
-
expect(query(User, { 'order' => 'firstname.Asc' }).params).to eq({ 'order' => 'firstname.asc' })
|
330
|
-
expect(query(User, { 'order' => 'firstname.DESC' }).params).to eq({ 'order' => 'firstname.desc' })
|
331
|
-
end
|
332
|
-
|
333
|
-
it 'order can be specified as symbol' do
|
334
|
-
expect(query(User, { order: 'firstname.desc' }).params).to eq({ 'order' => 'firstname.desc' })
|
335
|
-
end
|
336
|
-
|
337
|
-
it "order is case sensitive" do
|
338
|
-
expect(query(User, { 'Order' => 'firstname.desc' }).params).to eq({})
|
339
|
-
end
|
340
|
-
|
341
|
-
it 'many order can be specified' do
|
342
|
-
expect(query(User, { 'order' => ['firstname.Asc', 'lastname.DESC'] }).params).to eq({ 'order' => ['firstname.asc', 'lastname.desc'] })
|
343
|
-
expect(query(User, { 'order' => ['firstname.Asc', 'firstname.desc'] }).params).to eq({ 'order' => 'firstname.asc' })
|
344
|
-
expect(query(User, { 'order' => ['firstname.Asc', 'lastname.DESC', 'firstname.desc'] }).params).to eq({ 'order' => ['firstname.asc', 'lastname.desc'] })
|
345
|
-
expect(query(User, { 'order' => ['firstname.Asc', 'foo', 'lastname.DESC', 'firstname.desc'] }).params).to eq({ 'order' => ['firstname.asc', 'lastname.desc'] })
|
346
|
-
end
|
347
|
-
|
348
|
-
it 'order can be delimited by a space' do
|
349
|
-
expect(query(User, { 'order' => 'firstname ASC' }).params).to eq({ 'order' => 'firstname.asc' })
|
350
|
-
end
|
351
|
-
|
352
|
-
it 'order can be delimited by any white space' do
|
353
|
-
expect(query(User, { 'order' => "firstname\nASC" }).params).to eq({ 'order' => 'firstname.asc' })
|
354
|
-
expect(query(User, { 'order' => "firstname\t ASC" }).params).to eq({ 'order' => 'firstname.asc' })
|
355
|
-
end
|
356
|
-
|
357
|
-
it 'order can be delimited by a ":"' do
|
358
|
-
expect(query(User, { 'order' => "firstname:ASC" }).params).to eq({ 'order' => 'firstname.asc' })
|
359
|
-
end
|
360
|
-
|
361
|
-
it 'order can be delimited by more than one delimiter' do
|
362
|
-
expect(query(User, { 'order' => "firstname :. ASC" }).params).to eq({ 'order' => 'firstname.asc' })
|
363
|
-
end
|
364
|
-
|
365
|
-
end
|
366
|
-
|
367
|
-
describe '#relation' do
|
368
|
-
|
369
|
-
it 'does not execute any query' do
|
370
|
-
expect(User).not_to receive(:connection)
|
371
|
-
query(User, enabled: true).relation
|
372
|
-
end
|
373
|
-
|
374
|
-
it 'works with scopes with a lambda without arguments' do
|
375
|
-
users(:jane).update_attribute(:created_at, 10.days.ago)
|
376
|
-
expect(query(User, latest: true).relation).to eq([users(:john)])
|
377
|
-
expect(query(User, latest: false).relation).to eq([users(:john), users(:jane)])
|
378
|
-
end
|
379
|
-
|
380
|
-
it 'does not modify relation specified at initialization' do
|
381
|
-
relation = User.search('foo')
|
382
|
-
q = query(relation, enabled: true)
|
383
|
-
expect {
|
384
|
-
expect {
|
385
|
-
q.relation
|
386
|
-
}.not_to change { q.instance_variable_get('@relation') }
|
387
|
-
}.not_to change { relation }
|
388
|
-
end
|
389
|
-
|
390
|
-
it 'returns relation specified at construction if params are empty' do
|
391
|
-
expect(query.relation).not_to eq(User)
|
392
|
-
expect(query.relation).to eq(User.all)
|
393
|
-
end
|
394
|
-
|
395
|
-
it 'invokes many times relation if an array is given' do
|
396
|
-
expect(query(User, search: ['John', 'Doe']).relation).to eq([users(:john)])
|
397
|
-
expect(query(User, search: ['John', 'Done']).relation).to eq([])
|
398
|
-
expect(query(User, search: ['John', 'Doe']).params).to eq({ 'search' => ['John', 'Doe'] })
|
399
|
-
end
|
400
|
-
|
401
|
-
it 'invokes many times relation if given twice (as string & symbol)' do
|
402
|
-
expect(query(User, search: 'John', 'search' => 'Done').params['search']).to contain_exactly('John', 'Done')
|
403
|
-
expect(query(User, search: 'John', 'search' => ['Did', 'Done']).params['search']).to contain_exactly('John', 'Did', 'Done')
|
404
|
-
end
|
405
|
-
|
406
|
-
it 'invokes last order if an array is given' do
|
407
|
-
create_user(:jane2, firstname: 'Jane', lastname: 'Zoe')
|
408
|
-
|
409
|
-
expect(query(User, order: ['lastname', 'firstname']).relation).to eq([users(:jane), users(:john), users(:jane2)])
|
410
|
-
expect(query(User, order: ['lastname', 'firstname.desc']).relation).to eq([users(:john), users(:jane), users(:jane2)])
|
411
|
-
expect(query(User, order: ['firstname', 'lastname.desc']).relation).to eq([users(:jane2), users(:jane), users(:john)])
|
412
|
-
expect(query(User, order: ['firstname.desc', 'lastname']).relation.order_values.map(&:class)).to eq([Arel::Nodes::Descending, Arel::Nodes::Ascending])
|
413
|
-
expect(query(User, order: ['firstname.desc', 'lastname']).relation.order_values.map(&:expr).map(&:name)).to eq(['firstname', 'lastname'])
|
414
|
-
end
|
415
|
-
|
416
|
-
it 'defines #query method on returned relation' do
|
417
|
-
expect(query(User).relation).to respond_to(:query)
|
418
|
-
end
|
419
|
-
|
420
|
-
it 'does not define #query method for future relations' do
|
421
|
-
expect(query(User).relation.query).to be_present
|
422
|
-
expect(User).not_to respond_to(:query)
|
423
|
-
expect(User.all).not_to respond_to(:query)
|
424
|
-
expect(User.enabled).not_to respond_to(:query)
|
425
|
-
end
|
426
|
-
|
427
|
-
it 'defined #query method returns query' do
|
428
|
-
q = query(User)
|
429
|
-
expect(q.relation.query).to be_a(ScopedFrom::Query)
|
430
|
-
expect(q.relation.query).to be(q)
|
431
|
-
end
|
432
|
-
|
433
|
-
end
|
434
|
-
|
435
|
-
describe '#true?' do
|
436
|
-
|
437
|
-
it 'is true if true is given' do
|
438
|
-
expect(query.send(:true?, true)).to be(true)
|
439
|
-
end
|
440
|
-
|
441
|
-
it 'is true if "true" is given' do
|
442
|
-
expect(query.send(:true?, 'true')).to be(true)
|
443
|
-
expect(query.send(:true?, 'True')).to be(true)
|
444
|
-
end
|
445
|
-
|
446
|
-
it 'is true if "1" is given' do
|
447
|
-
expect(query.send(:true?, '1')).to be(true)
|
448
|
-
end
|
449
|
-
|
450
|
-
it 'is true if "on" is given' do
|
451
|
-
expect(query.send(:true?, 'on')).to be(true)
|
452
|
-
expect(query.send(:true?, 'ON ')).to be(true)
|
453
|
-
end
|
454
|
-
|
455
|
-
it 'is true if "yes" is given' do
|
456
|
-
expect(query.send(:true?, 'yes')).to be(true)
|
457
|
-
expect(query.send(:true?, ' Yes ')).to be(true)
|
458
|
-
end
|
459
|
-
|
460
|
-
it 'is true if "y" is given' do
|
461
|
-
expect(query.send(:true?, 'y')).to be(true)
|
462
|
-
expect(query.send(:true?, 'Y ')).to be(true)
|
463
|
-
end
|
464
|
-
|
465
|
-
it 'is false if false is given' do
|
466
|
-
expect(query.send(:true?, false)).to be(false)
|
467
|
-
end
|
468
|
-
|
469
|
-
it 'is false if "false" is given' do
|
470
|
-
expect(query.send(:true?, 'false')).to be(false)
|
471
|
-
expect(query.send(:true?, 'FsALSE')).to be(false)
|
472
|
-
end
|
473
|
-
|
474
|
-
it 'is false if "0" is given' do
|
475
|
-
expect(query.send(:true?, '0')).to be(false)
|
476
|
-
end
|
477
|
-
|
478
|
-
it 'is false if "off" is given' do
|
479
|
-
expect(query.send(:true?, "off")).to be(false)
|
480
|
-
expect(query.send(:true?, "Off")).to be(false)
|
481
|
-
end
|
482
|
-
|
483
|
-
it 'is false otherwise' do
|
484
|
-
expect(query.send(:true?, 42)).to be(false)
|
485
|
-
expect(query.send(:true?, 'bam')).to be(false)
|
486
|
-
end
|
487
|
-
|
488
|
-
end
|
489
|
-
|
490
|
-
end
|
data/spec/scoped_from_spec.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ScopedFrom do
|
4
|
-
|
5
|
-
describe '.version' do
|
6
|
-
|
7
|
-
subject { ScopedFrom.version }
|
8
|
-
|
9
|
-
it { should be_a(String) }
|
10
|
-
it { should match(/^\d+\.\d+(\.\d+)?/) }
|
11
|
-
|
12
|
-
it 'is freezed' do
|
13
|
-
expect {
|
14
|
-
ScopedFrom.version.gsub!('.', '#')
|
15
|
-
}.to raise_error(/can't modify frozen string/i)
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
ENV["RAILS_ENV"] ||= 'test'
|
2
|
-
|
3
|
-
require File.expand_path("#{__dir__}/../lib/scoped_from")
|
4
|
-
require 'action_controller'
|
5
|
-
require 'byebug'
|
6
|
-
|
7
|
-
# Support
|
8
|
-
Dir["#{__dir__}/support/**/*.rb"].each { |f| require File.expand_path(f) }
|
9
|
-
|
10
|
-
# Mocks
|
11
|
-
ActiveSupport::Dependencies.autoload_paths << "#{__dir__}/mocks"
|
12
|
-
|
13
|
-
RSpec.configure do |config|
|
14
|
-
config.raise_errors_for_deprecations!
|
15
|
-
|
16
|
-
config.include(UserMacro)
|
17
|
-
|
18
|
-
config.before(:each) do
|
19
|
-
Comment.delete_all
|
20
|
-
Post.delete_all
|
21
|
-
User.delete_all
|
22
|
-
Vote.delete_all
|
23
|
-
|
24
|
-
create_user(:john, firstname: 'John', lastname: 'Doe', enabled: true, admin: true)
|
25
|
-
create_user(:jane, firstname: 'Jane', lastname: 'Doe', enabled: false, admin: false)
|
26
|
-
end
|
27
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: File.expand_path("#{__dir__}/../../test.sqlite3"), timeout: 5000)
|
2
|
-
|
3
|
-
ActiveRecord::Base.connection.create_table(:comments, force: true)
|
4
|
-
ActiveRecord::Base.connection.create_table(:posts, force: true)
|
5
|
-
ActiveRecord::Base.connection.create_table(:users, force: true) do |t|
|
6
|
-
t.string :firstname, null: false
|
7
|
-
t.string :lastname, null: false
|
8
|
-
t.boolean :enabled, null: false, default: false
|
9
|
-
t.boolean :admin, null: false, default: false
|
10
|
-
t.timestamps null: false
|
11
|
-
end
|
12
|
-
ActiveRecord::Base.connection.create_table(:votes, force: true)
|