schron 0.0.2 → 0.0.3

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: a8e1d0962975ce0ce8d619f4e757b60cdf631e82
4
- data.tar.gz: 36477336e2e1a6c356cd4ba95430eb61e3d91947
3
+ metadata.gz: 7769c035395e049f20cbede7cda51f0b39c8ed28
4
+ data.tar.gz: 6eacb27127b5d4770d36dd17692697b1bd39d93e
5
5
  SHA512:
6
- metadata.gz: f691c4bf156243994fa5ca0d0e3532b88f9dfc26442a51e56036d0cec8bd11558a1789bc00a573d0f5e2c93030505da18784c82663d4f7b0c7fdd6bb04abf294
7
- data.tar.gz: 33fca3e587a68959a994bd584883426c5169340c2054b325b5a610f307408e6378c3601d8b659aa5f483b1b03e61e3fbd9ec31c05b28b19e2f7c189ab6771e48
6
+ metadata.gz: e2f2c532a880389220906e087c45772d8430159ff4b102c33aa770793ba1c0e52e7db0714cfb6e3833c3a463e9aa3b273950d362d1e490b58d5600565280fe62
7
+ data.tar.gz: a3becfbd86f34a23e6a5d3038f35df103ce72cadb31753fbacae795574644987488a9fd8c83693a92fc458f2bc04a78dfc344e116a857ceeee283408b40babca
@@ -25,14 +25,15 @@ module Schron
25
25
  end
26
26
 
27
27
  def query(&block)
28
- load_all(Query.new(@kind, @datastore, &block).all)
28
+ Query.new(self, &block)
29
29
  end
30
30
 
31
- def first(&block)
32
- query do |q|
33
- yield q if block_given?
34
- q.limit(1)
35
- end.first
31
+ def all
32
+ query.all
33
+ end
34
+
35
+ def first
36
+ query.first
36
37
  end
37
38
 
38
39
  def get(id)
@@ -50,7 +50,7 @@ module Schron
50
50
  def protect_reset
51
51
  unless ENV['SCHRON_RESET']
52
52
  raise Schron::OperationDisabledError,
53
- "Can not reset datastore with setting ENV['SCHRON_RESET'] to 1"
53
+ "Can not reset datastore without setting ENV['SCHRON_RESET'] to 1"
54
54
  end
55
55
  yield
56
56
  end
@@ -10,13 +10,17 @@ module Schron
10
10
  @data = {}
11
11
  end
12
12
 
13
- def exec_query(kind, query)
14
- results = data_for_kind(kind).values
13
+ def exec_query(query)
14
+ results = data_for_kind(query.kind).values
15
15
  results = apply_filters(query, results)
16
16
  results = apply_sorts(query, results)
17
17
  apply_limit_offset(query, results) || []
18
18
  end
19
19
 
20
+ def exec_count(query)
21
+ exec_query(query).count
22
+ end
23
+
20
24
  def multi_get(kind, ids)
21
25
  ids.map { |id| get_data(kind, id) }.compact
22
26
  end
@@ -6,15 +6,19 @@ require 'schron/datastore/serializer'
6
6
 
7
7
  module Schron
8
8
  module Datastore
9
+ class EmptyQueryError < StandardError
10
+ end
9
11
  class Mongo
10
12
  include Schron::Datastore::Interface
11
13
 
14
+ attr_reader :db
15
+
12
16
  def initialize(db)
13
17
  @db = db
14
18
  end
15
19
 
16
20
  def get(kind, id)
17
- doc = coll(kind).find(id_selector(id)).first
21
+ doc = coll(kind).find_one(id_selector(id))
18
22
  doc ?
19
23
  unserialize(kind, doc) :
20
24
  nil
@@ -65,11 +69,22 @@ module Schron
65
69
  nil
66
70
  end
67
71
 
68
- def exec_query(kind, query)
72
+ def exec_query(query)
69
73
  selector = selector_for(query)
70
74
  query_opts = query_opts_for(query)
71
- docs = coll(kind).find(selector, query_opts)
72
- docs.map{ |d| unserialize(kind, d) }
75
+ docs = coll(query.kind).find(selector, query_opts)
76
+ docs.map{ |d| unserialize(query.kind, d) }
77
+ rescue EmptyQueryError
78
+ []
79
+ end
80
+
81
+ def exec_count(query)
82
+ query_selector = selector_for(query)
83
+ query_opts = query_opts_for(query)
84
+ query_opts.delete(:sort)
85
+ coll(query.kind).count(query_opts.merge(query: query_selector))
86
+ rescue EmptyQueryError
87
+ 0
73
88
  end
74
89
 
75
90
  def reset!
@@ -133,6 +148,7 @@ module Schron
133
148
  when '!='
134
149
  selector[mongo_field] = { "$ne" => filter_value }
135
150
  when 'in'
151
+ raise EmptyQueryError if filter_value.to_a.empty?
136
152
  selector[mongo_field] = { "$in" => filter_value.to_a }
137
153
  when '>'
138
154
  selector[mongo_field] = { "$gt" => filter_value }
@@ -16,12 +16,12 @@ module Schron
16
16
  @db = db
17
17
  end
18
18
 
19
- def exec_query(kind, query)
20
- dataset = @db[kind]
21
- dataset = apply_filters(query, dataset)
22
- dataset = apply_sorts(query, dataset)
23
- dataset = apply_limit_and_offset(query, dataset)
24
- dataset.all
19
+ def exec_query(query)
20
+ dataset_for_query(query).all
21
+ end
22
+
23
+ def exec_count(query)
24
+ dataset_for_query(query).count
25
25
  end
26
26
 
27
27
  def multi_get(kind, ids)
@@ -94,6 +94,15 @@ module Schron
94
94
  hashes.map { |h| unserialize(kind, h) }
95
95
  end
96
96
 
97
+
98
+ def dataset_for_query(query)
99
+ dataset = @db[query.kind]
100
+ dataset = apply_filters(query, dataset)
101
+ dataset = apply_sorts(query, dataset)
102
+ dataset = apply_limit_and_offset(query, dataset)
103
+ dataset
104
+ end
105
+
97
106
  def apply_filters(query, data)
98
107
  final = query.filters.reduce(data) do |data, (name, op, value)|
99
108
  case op
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'time'
3
3
  require 'set'
4
+ require 'bigdecimal'
4
5
  require 'schron/util'
5
6
  module Schron
6
7
  module Datastore
@@ -33,7 +34,7 @@ module Schron
33
34
  when Array, Set
34
35
  value.map { |v| serialize_value(v) }.to_a
35
36
  when Date, DateTime, Time
36
- value.to_datetime.iso8601(9)
37
+ value.to_time.utc
37
38
  when BigDecimal
38
39
  value.to_f
39
40
  else
@@ -0,0 +1,10 @@
1
+ require 'schron/archive'
2
+ require 'schron/generic_entity'
3
+
4
+ module Schron
5
+ class GenericArchive
6
+ include Schron::Archive
7
+
8
+ entity_class GenericEntity
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ module Schron
2
+ class GenericEntity
3
+
4
+ attr_reader :attributes
5
+
6
+ def initialize(attrs={})
7
+ @attributes = attrs
8
+ end
9
+
10
+ def method_missing(method, *args)
11
+ if args.empty? && @attributes.key?(method)
12
+ @attributes[method]
13
+ else
14
+ super
15
+ end
16
+ end
17
+ end
18
+ end
@@ -6,16 +6,23 @@ module Schron
6
6
  class Query
7
7
  attr_reader :filters
8
8
  attr_reader :sorts
9
- attr_reader :kind
9
+ attr_reader :archive
10
10
 
11
- def initialize(kind=nil, datastore=nil &block)
12
- @kind = kind
13
- @datastore = datastore
11
+ def initialize(archive=nil, &block)
12
+ @archive = archive
14
13
  @filters = []
15
14
  @sorts = []
16
15
  @page = false
17
16
  yield self if block_given?
18
17
  end
18
+
19
+ def kind
20
+ archive.kind
21
+ end
22
+
23
+ def datastore
24
+ archive.datastore
25
+ end
19
26
 
20
27
 
21
28
  ##
@@ -64,15 +71,21 @@ module Schron
64
71
  ## Query Terminators
65
72
 
66
73
  def all
67
- with_pagination(@datastore.exec_query(@kind, self))
74
+ raw_results = datastore.exec_query(self)
75
+ loaded_results = archive.load_all(raw_results)
76
+ with_pagination(loaded_results)
68
77
  end
69
78
 
70
79
  def first
71
80
  limit(1).all.first
72
81
  end
73
82
 
83
+ def count
84
+ datastore.exec_count(self)
85
+ end
86
+
74
87
  def exists?
75
- !all.empty?
88
+ count > 0
76
89
  end
77
90
 
78
91
 
@@ -19,7 +19,7 @@ if defined?(RSpec)
19
19
  expect(archive.datastore).to receive(:exec_query).and_call_original
20
20
  results = archive.query do |q|
21
21
  expect(q.kind).to eq(archive.kind)
22
- end
22
+ end.all
23
23
  expect_same_entity results.first, entity
24
24
  end
25
25
  end
@@ -1,6 +1,7 @@
1
1
  if defined?(RSpec)
2
2
 
3
3
  require 'schron/query'
4
+ require 'schron/generic_archive'
4
5
  shared_examples 'schron datastore' do
5
6
  let(:entity_kind) { :entities }
6
7
  let(:named_kind) { :named }
@@ -169,8 +170,10 @@ if defined?(RSpec)
169
170
  end
170
171
 
171
172
  describe 'exec query' do
172
- let(:query) { Schron::Query.new(named_kind, ds) }
173
- let(:no_result_query) { Schron::Query.new(entity_kind, ds) }
173
+ let(:named_kind_archive) { Schron::GenericArchive.new(ds, kind: named_kind) }
174
+ let(:query) { Schron::Query.new(named_kind_archive) }
175
+ let(:entity_kind_archive) { Schron::GenericArchive.new(ds, kind: entity_kind) }
176
+ let(:no_result_query) { Schron::Query.new(entity_kind_archive) }
174
177
 
175
178
  before(:each) do
176
179
  @c = ds.insert(named_kind, name: 'c')
@@ -182,140 +185,291 @@ if defined?(RSpec)
182
185
 
183
186
  describe 'filters' do
184
187
  it 'filters by equality with a hash' do
185
- found = query.filter(name: 'b').all
188
+ found = ds.exec_query(query.filter(name: 'b'))
186
189
  expect(found.size).to eq(1)
187
190
  expect(found.first[:id]).to eq(@b[:id])
188
191
  end
189
192
 
190
193
  it 'filters by inclusion with a hash' do
191
- found = query.filter(name: ['b', 'c']).all
194
+ found = ds.exec_query(query.filter(name: ['b', 'c']))
192
195
  expect(found.size).to eq(2)
193
196
  expect(found.map{ |h| h[:id] }).to include(@b[:id], @c[:id])
194
197
  end
195
198
 
196
199
  it 'filters by "=" operator' do
197
- found = query.filter(:name, '=', 'b').all
200
+ found = ds.exec_query(query.filter(:name, '=', 'b'))
198
201
  expect(found.size).to eq(1)
199
202
  expect(found.first[:id]).to eq(@b[:id])
200
203
  end
201
204
 
202
205
  it 'filters by "in" operator' do
203
- found = query.filter(:name, 'in', ['a', 'b']).all
206
+ found = ds.exec_query(query.filter(:name, 'in', ['a', 'b']))
204
207
  expect(found.size).to eq(3)
205
208
  expect(found.map{ |h| h[:id] }).to include(@a1[:id], @a2[:id], @b[:id])
206
209
  end
207
210
 
208
211
  it 'filters by ">" operator' do
209
- found = query.filter(:name, '>', 'a').all
212
+ found = ds.exec_query(query.filter(:name, '>', 'a'))
210
213
  expect(found.size).to be(2)
211
214
  expect(found.map{ |h| h[:id] }).to include(@b[:id], @c[:id])
212
215
  end
213
216
 
214
217
  it 'filters by ">=" operator' do
215
- found = query.filter(:name, '>=', 'a').all
218
+ found = ds.exec_query(query.filter(:name, '>=', 'a'))
216
219
  expect(found.size).to be(4)
217
220
  expect(found.map{ |h| h[:id] }).to include(@a1[:id], @a2[:id], @b[:id], @c[:id])
218
221
  end
219
222
 
220
223
  it 'filters by "<" operator' do
221
- found = query.filter(:name, '<', 'b').all
224
+ found = ds.exec_query(query.filter(:name, '<', 'b'))
222
225
  expect(found.size).to be(2)
223
226
  expect(found.map{ |h| h[:id] }).to include(@a1[:id], @a2[:id])
224
227
  end
225
228
 
226
229
  it 'filters by "<=" operator' do
227
- found = query.filter(:name, '<=', 'b').all
230
+ found = ds.exec_query(query.filter(:name, '<=', 'b'))
228
231
  expect(found.size).to be(3)
229
232
  expect(found.map{ |h| h[:id] }).to include(@a1[:id], @a2[:id], @b[:id])
230
233
  end
231
234
 
232
235
  it 'filters by "!=" operator' do
233
- found = query.filter(:name, '!=', 'a').all
236
+ found = ds.exec_query(query.filter(:name, '!=', 'a'))
234
237
  expect(found.size).to eq(3)
235
238
  expect(found.map{ |h| h[:id] }).to include(@c[:id], @b[:id], @nil[:id])
236
239
  end
237
240
 
238
241
  it 'returns an empty list if no results match' do
239
- expect(query.filter(name: '123').all).to eq([])
242
+ expect(ds.exec_query(query.filter(name: '123'))).to eq([])
240
243
  end
241
244
 
242
245
  context 'nil filtering' do
243
246
  it 'filters by = nil' do
244
- found = query.filter(name: nil).all
247
+ found = ds.exec_query(query.filter(name: nil))
245
248
  expect(found.size).to eq(1)
246
249
  expect(found.first[:id]).to eq(@nil[:id])
247
250
  end
248
251
 
249
252
  it 'filters by != nil' do
250
- found = query.filter(:name, '!=', nil).all
253
+ found = ds.exec_query(query.filter(:name, '!=', nil))
251
254
  expect(found.size).to eq(4)
252
255
  expect(found.map{ |h| h[:id] }).to include(@a1[:id], @a2[:id], @b[:id], @c[:id])
253
256
  end
254
257
 
255
258
  it 'filters by in with nil' do
256
- found = query.filter(:name, 'in', [nil, 'b']).all
259
+ found = ds.exec_query(query.filter(:name, 'in', [nil, 'b']))
257
260
  expect(found.size).to eq(2)
258
261
  expect(found.map{ |h| h[:id] }).to include(@b[:id], @nil[:id])
259
262
  end
263
+
264
+ it 'filters by in with an empty list' do
265
+ found = ds.exec_query(query.filter(:name, 'in', []))
266
+ expect(found.size).to be(0)
267
+ end
260
268
  end
261
269
  end
262
270
 
263
271
  describe 'limit' do
264
272
  it 'limits the results' do
265
- found = query.limit(1).all
273
+ found = ds.exec_query(query.limit(1))
266
274
  expect(found.size).to eq(1)
267
275
  end
268
276
 
269
277
  it 'returns an empty list if no results match' do
270
278
  q = no_result_query
271
- expect(q.limit(2).all).to eq([])
279
+ expect(ds.exec_query(q.limit(2))).to eq([])
272
280
  end
273
281
  end
274
282
 
275
283
  describe 'offset' do
276
284
  it 'offsets the results' do
277
285
  all = 4.times.reduce([]) do |ary, i|
278
- ary + query.limit(1).offset(i).all
286
+ ary + ds.exec_query(query.limit(1).offset(i))
279
287
  end
280
288
  all_ids = all.map { |h| h[:id] }
281
289
  expect(all_ids).to include(@a1[:id], @a2[:id], @b[:id], @c[:id])
282
290
  end
283
291
 
284
292
  it 'returns an empty list if no results match' do
285
- expect(query.offset(10).all).to eq([])
293
+ expect(ds.exec_query(query.offset(10))).to eq([])
286
294
  end
287
295
  end
288
296
 
289
297
  describe 'sorts' do
290
298
  it 'sorts in asc direction by default' do
291
- found = query.sort(:name).all
299
+ found = ds.exec_query(query.sort(:name))
292
300
  expect(found.map{ |h| h[:name] }).to eq(
293
301
  [nil, 'a', 'a', 'b', 'c']
294
302
  )
295
303
  end
296
304
 
297
305
  it 'sorts ascending' do
298
- found = query.sort(:name, :asc).all
306
+ found = ds.exec_query(query.sort(:name, :asc))
299
307
  expect(found.map{ |h| h[:name] }).to eq([nil, 'a', 'a', 'b', 'c'])
300
308
  end
301
309
 
302
310
  it 'sorts descending' do
303
- found = query.sort(:name, :desc).all
311
+ found = ds.exec_query(query.sort(:name, :desc))
304
312
  expect(found.map { |h| h[:name] }).to eq(['c', 'b', 'a', 'a', nil])
305
313
  end
306
314
 
307
315
  it 'sorts by multiple fields' do
308
- found = query.sort(:name).sort(:id).all
316
+ found = ds.exec_query(query.sort(:name).sort(:id))
309
317
  expected = [@nil[:id]] + [@a1[:id], @a2[:id]].sort + [@b[:id], @c[:id]]
310
318
  expect(found.map { |h| h[:id] }).to eq(expected)
311
319
  end
312
320
 
313
321
  it 'returns an empty list if no results match' do
314
- expect(no_result_query.sort(:id).all).to eq([])
322
+ expect(ds.exec_query(no_result_query.sort(:id))).to eq([])
315
323
  end
316
324
  end
317
325
 
318
326
  end
327
+
328
+ describe 'exec count' do
329
+ let(:named_kind_archive) { Schron::GenericArchive.new(ds, kind: named_kind) }
330
+ let(:query) { Schron::Query.new(named_kind_archive) }
331
+ let(:entity_kind_archive) { Schron::GenericArchive.new(ds, kind: entity_kind) }
332
+ let(:no_result_query) { Schron::Query.new(entity_kind_archive) }
333
+
334
+ before(:each) do
335
+ @c = ds.insert(named_kind, name: 'c')
336
+ @a1 = ds.insert(named_kind, name: 'a')
337
+ @b = ds.insert(named_kind, name: 'b')
338
+ @a2 = ds.insert(named_kind, name: 'a')
339
+ @nil = ds.insert(named_kind, {name: nil})
340
+ end
341
+
342
+ describe 'filters' do
343
+ it 'filters by equality with a hash' do
344
+ found = ds.exec_count(query.filter(name: 'b'))
345
+ expect(found).to eq(1)
346
+ end
347
+
348
+ it 'filters by inclusion with a hash' do
349
+ found = ds.exec_count(query.filter(name: ['b', 'c']))
350
+ expect(found).to eq(2)
351
+ end
352
+
353
+ it 'filters by "=" operator' do
354
+ found = ds.exec_count(query.filter(:name, '=', 'b'))
355
+ expect(found).to eq(1)
356
+ end
357
+
358
+ it 'filters by "in" operator' do
359
+ found = ds.exec_count(query.filter(:name, 'in', ['a', 'b']))
360
+ expect(found).to eq(3)
361
+ end
362
+
363
+ it 'filters by ">" operator' do
364
+ found = ds.exec_count(query.filter(:name, '>', 'a'))
365
+ expect(found).to be(2)
366
+ end
367
+
368
+ it 'filters by ">=" operator' do
369
+ found = ds.exec_count(query.filter(:name, '>=', 'a'))
370
+ expect(found).to be(4)
371
+ end
372
+
373
+ it 'filters by "<" operator' do
374
+ found = ds.exec_count(query.filter(:name, '<', 'b'))
375
+ expect(found).to be(2)
376
+ end
377
+
378
+ it 'filters by "<=" operator' do
379
+ found = ds.exec_count(query.filter(:name, '<=', 'b'))
380
+ expect(found).to be(3)
381
+ end
382
+
383
+ it 'filters by "!=" operator' do
384
+ found = ds.exec_count(query.filter(:name, '!=', 'a'))
385
+ expect(found).to eq(3)
386
+ end
387
+
388
+ it 'returns 0 if no results match' do
389
+ expect(ds.exec_count(query.filter(name: '123'))).to eq(0)
390
+ end
391
+
392
+ context 'nil filtering' do
393
+ it 'filters by = nil' do
394
+ found = ds.exec_count(query.filter(name: nil))
395
+ expect(found).to eq(1)
396
+ end
397
+
398
+ it 'filters by != nil' do
399
+ found = ds.exec_count(query.filter(:name, '!=', nil))
400
+ expect(found).to eq(4)
401
+ end
402
+
403
+ it 'filters by in with nil' do
404
+ found = ds.exec_count(query.filter(:name, 'in', [nil, 'b']))
405
+ expect(found).to eq(2)
406
+ end
407
+
408
+ it 'filters by in with an empty list' do
409
+ found = ds.exec_count(query.filter(:name, 'in', []))
410
+ expect(found).to be(0)
411
+ end
412
+ end
413
+ end
414
+
415
+ describe 'limit' do
416
+ it 'limits the results' do
417
+ found = ds.exec_count(query.limit(1))
418
+ expect(found).to eq(1)
419
+ end
420
+
421
+ it 'returns an empty list if no results match' do
422
+ q = no_result_query
423
+ expect(ds.exec_count(q.limit(2))).to eq(0)
424
+ end
425
+ end
426
+
427
+ describe 'offset' do
428
+ it 'offsets the results' do
429
+ 4.times do |i|
430
+ found = ds.exec_count(query.limit(1).offset(i))
431
+ expect(found).to eq(1)
432
+ end
433
+ end
434
+
435
+ it 'returns an empty list if no results match' do
436
+ expect(ds.exec_count(query.offset(10))).to eq(0)
437
+ end
438
+ end
439
+
440
+ describe 'sorts' do
441
+ it 'sorts in asc direction by default' do
442
+ found = ds.exec_count(query.sort(:name))
443
+ expect(found).to eq(5)
444
+ end
445
+
446
+ it 'sorts ascending' do
447
+ found = ds.exec_count(query.sort(:name, :asc))
448
+ expect(found).to eq(5)
449
+ # expect(found.map{ |h| h[:name] }).to eq([nil, 'a', 'a', 'b', 'c'])
450
+ end
451
+
452
+ it 'sorts descending' do
453
+ found = ds.exec_count(query.sort(:name, :desc))
454
+ expect(found).to eq(5)
455
+ # expect(found.map { |h| h[:name] }).to eq(['c', 'b', 'a', 'a', nil])
456
+ end
457
+
458
+ it 'sorts by multiple fields' do
459
+ found = ds.exec_count(query.sort(:name).sort(:id))
460
+ expect(found).to eq(5)
461
+ # expected = [@nil[:id]] + [@a1[:id], @a2[:id]].sort + [@b[:id], @c[:id]]
462
+ # expect(found.map { |h| h[:id] }).to eq(expected)
463
+ end
464
+
465
+ it 'returns an empty list if no results match' do
466
+ # expect(ds.exec_count(no_result_query.sort(:id))).to eq([])
467
+ expect(ds.exec_count(no_result_query.sort(:id))).to eq(0)
468
+ end
469
+ end
470
+
471
+ end
472
+
319
473
  end
320
474
 
321
475
  describe 'datastore type handling' do
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "schron"
7
- spec.version = "0.0.2"
7
+ spec.version = "0.0.3"
8
8
  spec.authors = ["David Faber"]
9
9
  spec.email = ["david@1bios.co"]
10
10
  spec.summary = %q{Repository implementation for entity persistence}
@@ -1,10 +1,12 @@
1
1
  require 'spec_helper'
2
2
  require 'schron/query'
3
+ require 'schron/generic_archive'
3
4
  require 'schron/datastore/memory'
4
5
 
5
6
  describe Schron::Query do
6
- subject(:query) { described_class.new(kind, ds) }
7
+ subject(:query) { described_class.new(archive) }
7
8
 
9
+ let(:archive) { Schron::GenericArchive.new(ds, kind: kind) }
8
10
  let(:kind) { 'tests' }
9
11
  let(:ds) { Schron::Datastore::Memory.new }
10
12
 
@@ -43,4 +45,21 @@ describe Schron::Query do
43
45
  end
44
46
  end
45
47
  end
48
+
49
+ describe 'all' do
50
+ it 'executes the query and returns all results' do
51
+ expect(ds).to receive(:exec_query).with(query).and_return('raw results')
52
+ expect(archive).to receive(:load_all).with('raw results').and_return('loaded results')
53
+ expect(query.all).to eq('loaded results')
54
+ end
55
+ end
56
+
57
+ describe 'first' do
58
+ it 'sets the limit to 1, executes the query, and returns just the first result' do
59
+ expect(query).to receive(:limit).with(1).and_call_original
60
+ expect(ds).to receive(:exec_query).with(query).and_return(['raw'])
61
+ expect(archive).to receive(:load).with('raw').and_return('loaded')
62
+ expect(query.first).to eq('loaded')
63
+ end
64
+ end
46
65
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Faber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-08 00:00:00.000000000 Z
11
+ date: 2014-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -130,6 +130,8 @@ files:
130
130
  - lib/schron/datastore/serializer.rb
131
131
  - lib/schron/dsl.rb
132
132
  - lib/schron/error.rb
133
+ - lib/schron/generic_archive.rb
134
+ - lib/schron/generic_entity.rb
133
135
  - lib/schron/id.rb
134
136
  - lib/schron/identity_map.rb
135
137
  - lib/schron/paginated_results.rb