opium 1.5.0 → 1.5.1

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 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