opium 1.5.0 → 1.5.1

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: be31fe012527b39345bdd8e4977074bcbb628b0e
4
- data.tar.gz: 6765d23444bdc1cff577c6cbc153fcd9ed44ea00
3
+ metadata.gz: afcd218c0464f3b8a8b47c9f3203007f78a3096c
4
+ data.tar.gz: 899c86f06d5e7b5ff90e4fe24573964a0f4dc1f7
5
5
  SHA512:
6
- metadata.gz: 376965c434078ecb12f2b4b27550c49e7040b42eddbaf4c7e749385328ecccb157f31eb3c2405fee5ec8f1fd9ea4f58d09f531029bd1175f1887d074ff79b641
7
- data.tar.gz: 8b6ff96b019e20a0a8436e72c211ea29657b721fdc98190208346d714f972fe6859a12b697382629e4e37814fa97a9971a753ce1399931af3785fd37a362008d
6
+ metadata.gz: aac084bb325da3d6b1bb5458c4c63cbf39e811daa97c3d06a48e96951937ac18d7b9af9b0b18d47b3cf5caa16574fba50d7412937516b99d704010ef43e689d9
7
+ data.tar.gz: 3deaf7216912daad377f38e4a4dd34afbf9d8be1c49cbe6b142a904d8558e7ba6905a350b7a12e3df9ae0bc8f546eca60a8e6f2bb60214bc76e736817e36a282
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.5.1
2
+ ### Resolved Issues
3
+ - Model::Criteria should now respond to #size correctly.
4
+
1
5
  ## 1.5.0
2
6
  ### New Features
3
7
  - Opium will now work with ActiveModel 5.* going forward. Use a version before 1.5 if ActiveModel 4.* compatibility is needed. As a side-effect, supported rubies moves to anything above 2.2.2
@@ -3,73 +3,73 @@ module Opium
3
3
  class Criteria
4
4
  include Opium::Model::Queryable::ClassMethods
5
5
  include Enumerable
6
-
6
+
7
7
  class_attribute :models
8
8
  self.models = {}.with_indifferent_access
9
-
9
+
10
10
  def initialize( model_name )
11
11
  @model_name = model_name.respond_to?(:name) ? model_name.name : model_name
12
12
  constraints[:count] = 1
13
13
  end
14
-
14
+
15
15
  attr_reader :model_name
16
-
16
+
17
17
  def to_partial_path
18
18
  model._to_partial_path
19
19
  end
20
-
20
+
21
21
  def model
22
22
  models[model_name] ||= model_name.constantize
23
23
  end
24
-
24
+
25
25
  def chain
26
26
  Marshal.load( Marshal.dump( self ) ).tap {|m| m.instance_variable_set( :@cache, nil )}
27
27
  end
28
-
28
+
29
29
  def constraints
30
30
  @constraints ||= {}.with_indifferent_access
31
31
  end
32
-
32
+
33
33
  def update_constraint( constraint, value )
34
34
  chain.tap {|c| c.update_constraint!( constraint, value )}
35
35
  end
36
-
36
+
37
37
  def update_constraint!( constraint, value )
38
38
  update_hash_value :constraints, constraint, value
39
39
  end
40
-
40
+
41
41
  def constraints?
42
42
  !constraints.except(:count).empty?
43
43
  end
44
-
44
+
45
45
  def variables
46
46
  @variables ||= {}.with_indifferent_access
47
47
  end
48
-
48
+
49
49
  def update_variable( variable, value )
50
50
  chain.tap {|c| c.update_variable!( variable, value )}
51
51
  end
52
-
52
+
53
53
  def update_variable!( variable, value )
54
54
  update_hash_value :variables, variable, value
55
55
  end
56
-
56
+
57
57
  def variables?
58
58
  !variables.empty?
59
59
  end
60
-
60
+
61
61
  def empty?
62
62
  count == 0
63
63
  end
64
-
64
+
65
65
  def criteria
66
66
  self
67
67
  end
68
-
68
+
69
69
  def ==( other )
70
70
  other.is_a?( self.class ) && self.model_name == other.model_name && self.constraints == other.constraints && self.variables == other.variables
71
71
  end
72
-
72
+
73
73
  def each(&block)
74
74
  if !block_given?
75
75
  to_enum(:each)
@@ -88,34 +88,35 @@ module Opium
88
88
  end
89
89
  end
90
90
  end
91
-
91
+
92
92
  def inspect
93
93
  inspected_constraints = constraints.map {|k, v| [k, v.inspect].join(': ')}.join(', ')
94
94
  inspected_constraints.prepend ' ' if inspected_constraints.size > 0
95
95
  "#<#{ self.class.name }<#{ model_name }>#{ inspected_constraints }>"
96
96
  end
97
-
97
+
98
98
  def to_parse
99
99
  {}.with_indifferent_access.tap do |result|
100
100
  result[:query] = { where: constraints[:where], className: model_name } if constraints[:where]
101
101
  result[:key] = constraints[:keys] if constraints[:keys]
102
102
  end
103
103
  end
104
-
104
+
105
105
  def uncache
106
106
  super.tap do |criteria|
107
107
  criteria.instance_variable_set(:@cache, nil)
108
108
  end
109
109
  end
110
-
110
+
111
111
  def total_count
112
112
  count && variables[:total_count]
113
113
  end
114
-
114
+
115
+ alias_method :size, :total_count
115
116
  alias_method :to_ary, :to_a
116
-
117
+
117
118
  private
118
-
119
+
119
120
  def update_hash_value( hash_name, key, value )
120
121
  hash = self.send( hash_name )
121
122
  if hash[key].nil? || !value.is_a?(Hash)
@@ -126,4 +127,4 @@ module Opium
126
127
  end
127
128
  end
128
129
  end
129
- end
130
+ end
data/lib/opium/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Opium
2
- VERSION = "1.5.0"
2
+ VERSION = "1.5.1"
3
3
  end
@@ -6,10 +6,10 @@ describe Opium::Model::Criteria do
6
6
  include Opium::Model
7
7
  field :title, type: String
8
8
  field :price, type: Float
9
-
9
+
10
10
  stub('model_name').and_return(ActiveModel::Name.new(klass, nil, 'Game'))
11
11
  end )
12
-
12
+
13
13
  stub_request( :get, 'https://api.parse.com/1/classes/Game?count=1' ).with( body: {} ).
14
14
  to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: {
15
15
  count: 10,
@@ -19,13 +19,13 @@ describe Opium::Model::Criteria do
19
19
  ]
20
20
  }.to_json )
21
21
  end
22
-
22
+
23
23
  after do
24
24
  Opium::Model::Criteria.models.clear
25
25
  end
26
-
26
+
27
27
  subject { Opium::Model::Criteria.new( 'Object' ) }
28
-
28
+
29
29
  it { is_expected.to be_a( Opium::Model::Queryable::ClassMethods ) }
30
30
  it { is_expected.to be_an( Enumerable ) }
31
31
  it { is_expected.to respond_to( :chain ) }
@@ -37,9 +37,9 @@ describe Opium::Model::Criteria do
37
37
  it { is_expected.to respond_to( :to_parse ) }
38
38
  it { is_expected.to respond_to( :each ) }
39
39
  it { is_expected.to respond_to( :to_a, :to_ary ) }
40
- it { is_expected.to respond_to( :count, :total_count ) }
40
+ it { is_expected.to respond_to( :count, :total_count, :size ) }
41
41
  it { is_expected.to respond_to( :to_partial_path ) }
42
-
42
+
43
43
  describe '#chain' do
44
44
  it 'returns a copy of the object' do
45
45
  result = subject.chain
@@ -48,8 +48,8 @@ describe Opium::Model::Criteria do
48
48
  result.should_not equal( subject )
49
49
  end
50
50
  end
51
-
52
- describe '#update_constraint' do
51
+
52
+ describe '#update_constraint' do
53
53
  it 'chains the criteria and alter the specified constraint on the copy' do
54
54
  result = subject.update_constraint( :order, ['title', 1] )
55
55
  result.should be_a( Opium::Model::Criteria )
@@ -58,20 +58,20 @@ describe Opium::Model::Criteria do
58
58
  result.constraints.should have_key( :order )
59
59
  result.constraints[:order].should == ['title', 1]
60
60
  end
61
-
61
+
62
62
  it 'merges hash-valued constraints' do
63
63
  subject.constraints['where'] = { score: { '$lte' => 321 } }
64
64
  result = subject.update_constraint( 'where', price: { '$gte' => 123 } )
65
65
  result.constraints['where'].should =~ { 'score' => { '$lte' => 321 }, 'price' => { '$gte' => 123 } }
66
66
  end
67
-
67
+
68
68
  it 'deep merges hash-valued constraints' do
69
69
  subject.constraints['where'] = { score: { '$lte' => 321 } }
70
70
  result = subject.update_constraint( 'where', score: { '$gte' => 123 } )
71
71
  result.constraints['where'].should =~ { 'score' => { '$lte' => 321, '$gte' => 123 } }
72
72
  end
73
73
  end
74
-
74
+
75
75
  describe '#update_variable' do
76
76
  it 'chains the criteria and alter the specified instance variable on the copy' do
77
77
  result = subject.update_variable( :cache, true )
@@ -83,136 +83,136 @@ describe Opium::Model::Criteria do
83
83
  result.variables[:cache].should == true
84
84
  end
85
85
  end
86
-
86
+
87
87
  describe '#==' do
88
88
  let( :first ) { Opium::Model::Criteria.new( 'Object' ).update_constraint( :order, ['title', 1] ) }
89
89
  let( :second ) { Opium::Model::Criteria.new( 'Object' ).update_constraint( :order, ['title', 1] ) }
90
-
90
+
91
91
  it 'should not affect :equal?' do
92
92
  first.should_not equal( second )
93
93
  end
94
-
94
+
95
95
  it 'is based on the criteria constraints' do
96
96
  first.should == second
97
97
  end
98
-
98
+
99
99
  it 'is based on the criteria variables' do
100
100
  third = first.update_variable( :cache, true )
101
101
  second.should_not == third
102
102
  end
103
103
  end
104
-
104
+
105
105
  describe '#criteria' do
106
106
  subject { Opium::Model::Criteria.new( 'Object' ).update_constraint( :order, ['title', 1] ) }
107
-
107
+
108
108
  it 'is == to self' do
109
109
  subject.criteria.should == subject
110
110
  end
111
-
111
+
112
112
  it 'is not a duplicate of self' do
113
113
  subject.criteria.should equal( subject )
114
114
  end
115
115
  end
116
-
116
+
117
117
  describe '#model' do
118
118
  subject { Opium::Model::Criteria.new( 'Game' ) }
119
-
119
+
120
120
  it 'is the constantized version of :model_name' do
121
121
  subject.model_name.should == 'Game'
122
122
  subject.model.should == Game
123
123
  end
124
124
  end
125
-
125
+
126
126
  describe '#empty?' do
127
127
  before do
128
128
  stub_request(:get, "https://api.parse.com/1/classes/Game?count=1&where=%7B%22price%22:%7B%22$gte%22:9000.0%7D%7D").
129
129
  to_return(
130
- status: 200,
130
+ status: 200,
131
131
  body: {
132
132
  count: 0,
133
133
  results: []
134
- }.to_json,
134
+ }.to_json,
135
135
  headers: { content_type: 'application/json' }
136
136
  )
137
137
  end
138
-
138
+
139
139
  subject { Game.criteria }
140
-
140
+
141
141
  it { expect { subject.empty? }.to_not raise_exception }
142
142
  it do
143
143
  expect( subject ).to receive(:count).once.and_call_original
144
144
  subject.empty?
145
145
  end
146
-
146
+
147
147
  it 'returns true if count is 0' do
148
148
  subject.gte( price: 9000.0 ).empty?.should == true
149
149
  end
150
-
150
+
151
151
  it 'returns false if count is not 0' do
152
152
  subject.criteria.empty? == false
153
153
  end
154
154
  end
155
-
155
+
156
156
  describe '#constraints?' do
157
157
  it 'returns true if count is not the only constraint' do
158
158
  Game.limit( 10 ).constraints?.should == true
159
159
  end
160
-
160
+
161
161
  it 'returns false if count is the only constraint' do
162
162
  Game.criteria.constraints?.should == false
163
163
  end
164
164
  end
165
-
165
+
166
166
  describe '#each' do
167
167
  subject { Game.criteria }
168
-
168
+
169
169
  context 'without a block' do
170
170
  it 'returns an Enumerator' do
171
171
  subject.each.should be_a( Enumerator )
172
172
  end
173
173
  end
174
-
174
+
175
175
  context 'with a block' do
176
176
  it "calls its :model's :http_get" do
177
177
  subject.model.should receive(:http_get).with(query: subject.constraints)
178
178
  subject.each {|model| }
179
179
  end
180
-
180
+
181
181
  it 'yields to its block any results it finds' do
182
182
  expect {|b| subject.each &b }.to yield_control.twice
183
183
  end
184
-
184
+
185
185
  it 'yields to its block Opium::Model objects (Game in context)' do
186
186
  expect {|b| subject.each &b }.to yield_successive_args(Opium::Model, Opium::Model)
187
187
  expect {|b| subject.each &b }.to yield_successive_args(Game, Game)
188
188
  end
189
-
189
+
190
190
  it "calls its :model's :http_get when counting" do
191
191
  subject.model.should receive(:http_get).with(query: subject.constraints).twice
192
192
  subject.each {|model| }
193
193
  subject.each.count
194
194
  end
195
195
  end
196
-
196
+
197
197
  context 'when #cached?' do
198
198
  subject { Game.criteria.cache }
199
-
199
+
200
200
  it 'calls its :model\'s :http_get only once' do
201
201
  subject.model.should receive(:http_get).with(query: subject.constraints).once
202
202
  subject.each {|model| }
203
203
  subject.each {|model| }
204
204
  end
205
-
205
+
206
206
  it 'yields to its block any results it finds' do
207
207
  expect {|b| subject.each &b }.to yield_control.twice
208
208
  expect {|b| subject.each &b }.to yield_control.twice
209
209
  end
210
-
210
+
211
211
  it 'yields to its block Opium::Model objects (Game in context)' do
212
212
  expect {|b| subject.each &b }.to yield_successive_args(Opium::Model, Opium::Model)
213
213
  expect {|b| subject.each &b }.to yield_successive_args(Game, Game)
214
214
  end
215
-
215
+
216
216
  it "does not call its :model's :http_get when counting" do
217
217
  subject.model.should receive(:http_get).with(query: subject.constraints).once
218
218
  subject.each {|model| }
@@ -220,62 +220,76 @@ describe Opium::Model::Criteria do
220
220
  end
221
221
  end
222
222
  end
223
-
223
+
224
224
  describe '#uncache' do
225
225
  subject { Game.criteria.cache }
226
-
226
+
227
227
  it 'causes #each to call its :model\'s :http_get twice' do
228
228
  subject.model.should receive(:http_get).with(query: subject.constraints).twice
229
229
  subject.each {|model| }
230
230
  subject.uncache.each {|model| }
231
231
  end
232
-
232
+
233
233
  it 'deletes its @cache' do
234
234
  subject.each {|model| }
235
235
  subject.uncache.instance_variable_get(:@cache).should be_nil
236
236
  end
237
237
  end
238
-
238
+
239
239
  describe '#count' do
240
240
  subject { Game.criteria }
241
-
241
+
242
242
  it { expect { subject.count }.to_not raise_exception }
243
243
  it do
244
244
  expect( subject ).to receive(:each).and_call_original
245
245
  subject.count
246
246
  end
247
-
247
+
248
248
  it 'equals the number of items from #each' do
249
249
  expect( subject.count ).to be == 2
250
250
  end
251
251
  end
252
-
252
+
253
253
  describe '#total_count' do
254
254
  subject { Game.criteria }
255
-
255
+
256
256
  it { expect { subject.total_count }.to_not raise_exception }
257
257
  it do
258
258
  expect( subject ).to receive(:each).and_call_original
259
259
  subject.total_count
260
260
  end
261
-
261
+
262
262
  it "equals the 'count' result returned from parse" do
263
263
  expect( subject.total_count ).to be == 10
264
264
  end
265
265
  end
266
-
266
+
267
+ describe '#size' do
268
+ subject { Game.criteria }
269
+
270
+ it { expect { subject.size }.to_not raise_exception }
271
+ it do
272
+ expect( subject ).to receive(:each).and_call_original
273
+ subject.size
274
+ end
275
+
276
+ it "equals the 'count' result returned from parse" do
277
+ expect( subject.size ).to be == 10
278
+ end
279
+ end
280
+
267
281
  describe '#to_parse' do
268
282
  subject { Game.criteria }
269
-
283
+
270
284
  it { expect( subject.to_parse ).to be_a( Hash ) }
271
-
285
+
272
286
  it 'has a "query" key, if a "where" constraint exists, containing a "where" and a "className"' do
273
287
  Game.between( price: 5..10 ).to_parse.tap do |criteria|
274
288
  criteria.should have_key( 'query' )
275
289
  criteria['query'].should =~ { 'where' => { 'price' => { '$gte' => 5, '$lte' => 10 } }, 'className' => 'Game' }
276
290
  end
277
291
  end
278
-
292
+
279
293
  it 'should have a "key" key, if a "keys" constraint exists' do
280
294
  Game.keys( :price ).to_parse.tap do |criteria|
281
295
  criteria.should have_key( 'key' )
@@ -283,14 +297,14 @@ describe Opium::Model::Criteria do
283
297
  end
284
298
  end
285
299
  end
286
-
300
+
287
301
  describe '#to_partial_path' do
288
302
  subject { Game.criteria }
289
-
303
+
290
304
  it { expect { subject.to_partial_path }.to_not raise_exception }
291
-
305
+
292
306
  it 'comes from the model class' do
293
307
  expect( subject.to_partial_path ).to eq 'games/game'
294
308
  end
295
309
  end
296
- end
310
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opium
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Bowers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-25 00:00:00.000000000 Z
11
+ date: 2017-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler