scoped_from 1.0.1 → 1.0.2

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
  SHA1:
3
- metadata.gz: 88f3cb11e67b82da5d005daacea281154d2818ba
4
- data.tar.gz: 981bb72c4e756353749084e3503ab9b03469cfd4
3
+ metadata.gz: 91ae1b8a113e2c3b176c538a4d83870913cdb16c
4
+ data.tar.gz: e06f1e812ed6ed939eaa37b90dab44728225d2b7
5
5
  SHA512:
6
- metadata.gz: 82a281b707f6eb1d102131e06c9da5dcf7dec0a178d2ecc0b034e84589dc7ec4267362c56be037792011e809c6e1eb2200f2d6f0bce92af0576fc08b2e6378d1
7
- data.tar.gz: 79c0f7e9e6b4ab871aa2243fae328f004a6a1aa8ebb4bb750d1a58903e8e059626dd52f65d0e0fb5e9937f2df67f5513a19262a0a77dc14952c6c1947faa6cf6
6
+ metadata.gz: e8c903abd9c23d0a66c4956119c810eef2523be47e7cec2772fe5afa3345e716516fd015d084da3d4cd27a1f5e5437054fe60005c0ca8ae3c66ceea96300f12d
7
+ data.tar.gz: 7eedfbdca7944970a41fffd50806c6788406bff4f37b9f1f533e3af4ef3ee03596340f79b57ce7e5c149e5507de2cd4432411d158f82d229cc11411af95e7722
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.0.2
data/scoped_from.gemspec CHANGED
@@ -9,13 +9,12 @@ 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.rubyforge_project = 'scoped_from'
13
-
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
12
+ s.files = `git ls-files | grep -vE '^(spec/|test/|\\.|Gemfile|Rakefile)'`.split("\n")
16
13
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
14
  s.require_paths = ['lib']
18
15
 
16
+ s.required_ruby_version = '>= 2.0.0'
17
+
19
18
  s.add_dependency 'activerecord', '>= 5.0.0', '< 5.1.0'
20
19
  s.add_dependency 'activesupport', '>= 5.0.0', '< 5.1.0'
21
20
 
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: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexis Toulotte
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-22 00:00:00.000000000 Z
11
+ date: 2017-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -157,30 +157,13 @@ executables: []
157
157
  extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
- - ".gitignore"
161
- - ".rspec"
162
- - Gemfile
163
160
  - MIT-LICENSE
164
161
  - README.mdown
165
- - Rakefile
166
162
  - VERSION
167
163
  - lib/scoped_from.rb
168
164
  - lib/scoped_from/active_record.rb
169
165
  - lib/scoped_from/query.rb
170
166
  - 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
167
  homepage: https://github.com/alexistoulotte/scoped_from
185
168
  licenses:
186
169
  - MIT
@@ -193,15 +176,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
193
176
  requirements:
194
177
  - - ">="
195
178
  - !ruby/object:Gem::Version
196
- version: '0'
179
+ version: 2.0.0
197
180
  required_rubygems_version: !ruby/object:Gem::Requirement
198
181
  requirements:
199
182
  - - ">="
200
183
  - !ruby/object:Gem::Version
201
184
  version: '0'
202
185
  requirements: []
203
- rubyforge_project: scoped_from
204
- rubygems_version: 2.5.1
186
+ rubyforge_project:
187
+ rubygems_version: 2.6.8
205
188
  signing_key:
206
189
  specification_version: 4
207
190
  summary: Mapping between scopes and parameters for Rails
data/.gitignore DELETED
@@ -1,7 +0,0 @@
1
- .DS_Store
2
- .byebug_history
3
- /.bundle/
4
- /.ruby-version
5
- /Gemfile.lock
6
- /pkg/
7
- /spec/test.sqlite3
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --colour
2
- --order random
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- require 'bundler'
2
- require 'rspec/core/rake_task'
3
-
4
- Bundler::GemHelper.install_tasks
5
-
6
- desc 'Default: runs specs.'
7
- task default: :spec
8
-
9
- desc 'Run all specs in spec directory.'
10
- RSpec::Core::RakeTask.new(:spec)
@@ -1,2 +0,0 @@
1
- class Comment < ActiveRecord::Base
2
- end
@@ -1,2 +0,0 @@
1
- class CommentQuery < ScopedFrom::Query
2
- end
data/spec/mocks/post.rb DELETED
@@ -1,2 +0,0 @@
1
- class Post < ActiveRecord::Base
2
- end
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
@@ -1,2 +0,0 @@
1
- class UserQuery < String
2
- end
data/spec/mocks/vote.rb DELETED
@@ -1,2 +0,0 @@
1
- class Vote < ActiveRecord::Base
2
- end
@@ -1,2 +0,0 @@
1
- module VoteQuery
2
- end
@@ -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
@@ -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)
@@ -1,13 +0,0 @@
1
- module UserMacro
2
-
3
- USERS = {}
4
-
5
- def create_user(label, attributes)
6
- USERS[label] = User.create!(attributes)
7
- end
8
-
9
- def users(label)
10
- USERS[label]
11
- end
12
-
13
- end