ardb 0.16.0 → 0.17.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.
@@ -3,22 +3,26 @@ module Ardb
3
3
  class RelationSpy
4
4
 
5
5
  attr_reader :applied
6
- attr_accessor :order_values, :reverse_order_value
7
6
  attr_accessor :limit_value, :offset_value
8
7
  attr_accessor :results
9
8
 
10
9
  def initialize
11
10
  @applied, @results = [], []
12
- @order_values = []
13
- @reverse_order_value = nil
14
11
  @offset_value, @limit_value = nil, nil
15
12
  end
16
13
 
14
+ def ==(other)
15
+ other.kind_of?(self.class) ? @applied == other.applied : super
16
+ end
17
+
18
+ # ActiveRecord::QueryMethods
19
+
17
20
  [ :select,
18
- :joins,
21
+ :includes, :joins,
19
22
  :where,
20
23
  :group, :having,
21
- :merge
24
+ :order, :reverse_order,
25
+ :readonly
22
26
  ].each do |type|
23
27
 
24
28
  define_method(type) do |*args|
@@ -28,12 +32,6 @@ module Ardb
28
32
 
29
33
  end
30
34
 
31
- def order(*args)
32
- @order_values += args
33
- @applied << AppliedExpression.new(:order, args)
34
- self
35
- end
36
-
37
35
  def limit(value)
38
36
  @limit_value = value ? value.to_i : nil
39
37
  @applied << AppliedExpression.new(:limit, [ value ])
@@ -41,25 +39,76 @@ module Ardb
41
39
  end
42
40
 
43
41
  def offset(value)
44
- @offset_value = value ? value.to_i : 0
42
+ @offset_value = value ? value.to_i : nil
45
43
  @applied << AppliedExpression.new(:offset, [ value ])
46
44
  self
47
45
  end
48
46
 
47
+ # ActiveRecord::SpawnMethods
48
+
49
+ def merge(other)
50
+ return self if self.equal?(other)
51
+ if other.kind_of?(self.class)
52
+ other.applied.each{ |a| self.send(a.type, *a.args) }
53
+ else
54
+ @applied << AppliedExpression.new(:merge, [ other ])
55
+ end
56
+ self
57
+ end
58
+
59
+ def except(*skips)
60
+ skips = skips.map(&:to_sym)
61
+ @applied.reject!{ |a| skips.include?(a.type) }
62
+ @limit_value = nil if skips.include?(:limit)
63
+ @offset_value = nil if skips.include?(:offset)
64
+ self
65
+ end
66
+
67
+ def only(*onlies)
68
+ onlies = onlies.map(&:to_sym)
69
+ @applied.reject!{ |a| !onlies.include?(a.type) }
70
+ @limit_value = nil unless onlies.include?(:limit)
71
+ @offset_value = nil unless onlies.include?(:offset)
72
+ self
73
+ end
74
+
75
+ # ActiveRecord::FinderMethods
76
+
77
+ def find(id)
78
+ record = @results.detect{ |result| result.id == id }
79
+ record || raise(NotFoundError)
80
+ end
81
+
82
+ def first
83
+ self.all.first
84
+ end
85
+
86
+ def first!
87
+ self.first || raise(NotFoundError)
88
+ end
89
+
90
+ def last
91
+ self.all.last
92
+ end
93
+
94
+ def last!
95
+ self.last || raise(NotFoundError)
96
+ end
97
+
49
98
  def all
50
99
  @results[(@offset_value || 0), (@limit_value || @results.size)] || []
51
100
  end
52
101
 
102
+ # ActiveRecord::Calculations
103
+
53
104
  def count
54
105
  all.size
55
106
  end
56
107
 
57
- def ==(other)
58
- @applied == other.applied
59
- end
60
-
61
108
  AppliedExpression = Struct.new(:type, :args)
62
109
 
110
+ NotFoundError = Class.new(RuntimeError)
111
+
63
112
  end
64
113
 
65
114
  end
data/lib/ardb/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ardb
2
- VERSION = "0.16.0"
2
+ VERSION = "0.17.0"
3
3
  end
@@ -12,158 +12,410 @@ class Ardb::RelationSpy
12
12
 
13
13
  should have_readers :applied
14
14
  should have_accessors :results
15
- should have_accessors :order_values, :reverse_order_value
16
15
  should have_accessors :limit_value, :offset_value
17
- should have_imeths :select, :joins, :where, :order, :group, :having, :merge
16
+ should have_imeths :select
17
+ should have_imeths :includes, :joins
18
+ should have_imeths :where
19
+ should have_imeths :order, :reverse_order
20
+ should have_imeths :group, :having
21
+ should have_imeths :readonly
18
22
  should have_imeths :limit, :offset
19
- should have_imeths :all, :count
23
+ should have_imeths :merge, :only, :except
24
+ should have_imeths :find, :first, :first!, :last, :last!, :all
25
+ should have_imeths :count
20
26
 
21
27
  should "default it's attributes" do
22
28
  assert_equal [], subject.applied
23
29
  assert_equal [], subject.results
24
- assert_equal [], subject.order_values
25
- assert_equal nil, subject.reverse_order_value
26
30
  assert_equal nil, subject.limit_value
27
31
  assert_equal nil, subject.offset_value
28
32
  end
29
33
 
30
- should "add an applied expression using `select`" do
31
- subject.select :column_a, :column_b
32
- assert_equal 1, subject.applied.size
33
- applied_expression = subject.applied.first
34
- assert_instance_of AppliedExpression, applied_expression
35
- assert_equal :select, applied_expression.type
36
- assert_equal [ :column_a, :column_b ], applied_expression.args
34
+ should "be comparable using there applied collections" do
35
+ other_relation = Ardb::RelationSpy.new
36
+ other_relation.select :column_a
37
+ assert_not_equal other_relation, subject
38
+
39
+ subject.select :column_a
40
+ assert_equal other_relation, subject
37
41
  end
38
42
 
39
- should "add an applied expression using `joins`" do
40
- subject.joins :table_a, :table_b
41
- assert_equal 1, subject.applied.size
42
- applied_expression = subject.applied.first
43
- assert_instance_of AppliedExpression, applied_expression
44
- assert_equal :joins, applied_expression.type
45
- assert_equal [ :table_a, :table_b ], applied_expression.args
43
+ end
44
+
45
+ class SelectTests < UnitTests
46
+ desc "select"
47
+ setup do
48
+ @relation_spy.select :column_a, :column_b
49
+ @applied = subject.applied.first
46
50
  end
47
51
 
48
- should "add an applied expression using `where`" do
49
- subject.where :column_a => 'some value'
50
- assert_equal 1, subject.applied.size
51
- applied_expression = subject.applied.first
52
- assert_instance_of AppliedExpression, applied_expression
53
- assert_equal :where, applied_expression.type
54
- assert_equal [ { :column_a => 'some value' } ], applied_expression.args
52
+ should "have added a select applied expression with the passed args" do
53
+ assert_instance_of AppliedExpression, @applied
54
+ assert_equal :select, @applied.type
55
+ assert_equal [ :column_a, :column_b ], @applied.args
55
56
  end
56
57
 
57
- should "add an applied expression using `order`" do
58
- subject.order :column_a, :column_b
59
- assert_equal 1, subject.applied.size
60
- applied_expression = subject.applied.first
61
- assert_instance_of AppliedExpression, applied_expression
62
- assert_equal :order, applied_expression.type
63
- assert_equal [ :column_a, :column_b ], applied_expression.args
58
+ end
59
+
60
+ class IncludesTests < UnitTests
61
+ desc "includes"
62
+ setup do
63
+ @relation_spy.includes :table_a, :table_b
64
+ @applied = subject.applied.first
64
65
  end
65
66
 
66
- should "add args to it's `order_values` using `order" do
67
- subject.order :column_a, :column_b
68
- assert_includes :column_a, subject.order_values
69
- assert_includes :column_b, subject.order_values
67
+ should "have added an includes applied expression with the passed args" do
68
+ assert_instance_of AppliedExpression, @applied
69
+ assert_equal :includes, @applied.type
70
+ assert_equal [ :table_a, :table_b ], @applied.args
70
71
  end
71
72
 
72
- should "add an applied expression using `group`" do
73
- subject.group :column_a, :column_b
74
- assert_equal 1, subject.applied.size
75
- applied_expression = subject.applied.first
76
- assert_instance_of AppliedExpression, applied_expression
77
- assert_equal :group, applied_expression.type
78
- assert_equal [ :column_a, :column_b ], applied_expression.args
73
+ end
74
+
75
+ class JoinsTests < UnitTests
76
+ desc "joins"
77
+ setup do
78
+ @relation_spy.joins :table_a, :table_b
79
+ @applied = subject.applied.first
79
80
  end
80
81
 
81
- should "add an applied expression using `having`" do
82
- subject.having 'COUNT(column_a) > 0'
83
- assert_equal 1, subject.applied.size
84
- applied_expression = subject.applied.first
85
- assert_instance_of AppliedExpression, applied_expression
86
- assert_equal :having, applied_expression.type
87
- assert_equal [ 'COUNT(column_a) > 0' ], applied_expression.args
82
+ should "have added a joins applied expression with the passed args" do
83
+ assert_instance_of AppliedExpression, @applied
84
+ assert_equal :joins, @applied.type
85
+ assert_equal [ :table_a, :table_b ], @applied.args
88
86
  end
89
87
 
90
- should "add an applied expression using `merge`" do
91
- other_relation = Ardb::RelationSpy.new
92
- subject.merge other_relation
93
- assert_equal 1, subject.applied.size
94
- applied_expression = subject.applied.first
95
- assert_instance_of AppliedExpression, applied_expression
96
- assert_equal :merge, applied_expression.type
97
- assert_equal [ other_relation ], applied_expression.args
88
+ end
89
+
90
+ class WhereTests < UnitTests
91
+ desc "where"
92
+ setup do
93
+ @relation_spy.where :column_a => 'some value'
94
+ @applied = subject.applied.first
95
+ end
96
+
97
+ should "have added a where applied expression with the passed args" do
98
+ assert_instance_of AppliedExpression, @applied
99
+ assert_equal :where, @applied.type
100
+ assert_equal [ { :column_a => 'some value' } ], @applied.args
101
+ end
102
+
103
+ end
104
+
105
+ class OrderTests < UnitTests
106
+ desc "order"
107
+ setup do
108
+ @relation_spy.order :column_a, :column_b
109
+ @applied = subject.applied.first
110
+ end
111
+
112
+ should "have added an order applied expression with the passed args" do
113
+ assert_instance_of AppliedExpression, @applied
114
+ assert_equal :order, @applied.type
115
+ assert_equal [ :column_a, :column_b ], @applied.args
116
+ end
117
+
118
+ end
119
+
120
+ class ReverseOrderTests < UnitTests
121
+ desc "reverse_order"
122
+ setup do
123
+ @relation_spy.reverse_order
124
+ @applied = subject.applied.first
125
+ end
126
+
127
+ should "have added a reverse order applied expression with the passed args" do
128
+ assert_instance_of AppliedExpression, @applied
129
+ assert_equal :reverse_order, @applied.type
130
+ end
131
+
132
+ end
133
+
134
+ class GroupTests < UnitTests
135
+ desc "group"
136
+ setup do
137
+ @relation_spy.group :column_a, :column_b
138
+ @applied = subject.applied.first
139
+ end
140
+
141
+ should "have added a group applied expression with the passed args" do
142
+ assert_instance_of AppliedExpression, @applied
143
+ assert_equal :group, @applied.type
144
+ assert_equal [ :column_a, :column_b ], @applied.args
145
+ end
146
+
147
+ end
148
+
149
+ class HavingTests < UnitTests
150
+ desc "having"
151
+ setup do
152
+ @relation_spy.having 'COUNT(column_a) > 0'
153
+ @applied = subject.applied.first
154
+ end
155
+
156
+ should "have added a having applied expression with the passed args" do
157
+ assert_instance_of AppliedExpression, @applied
158
+ assert_equal :having, @applied.type
159
+ assert_equal [ 'COUNT(column_a) > 0' ], @applied.args
160
+ end
161
+
162
+ end
163
+
164
+ class ReadonlyTests < UnitTests
165
+ desc "readonly"
166
+ setup do
167
+ @relation_spy.readonly true
168
+ @applied = subject.applied.first
169
+ end
170
+
171
+ should "have added a readonly applied expression with the passed args" do
172
+ assert_instance_of AppliedExpression, @applied
173
+ assert_equal :readonly, @applied.type
174
+ assert_equal [ true ], @applied.args
98
175
  end
99
176
 
100
- should "add an applied expression using `limit`" do
101
- subject.limit 100
102
- assert_equal 1, subject.applied.size
103
- applied_expression = subject.applied.first
104
- assert_instance_of AppliedExpression, applied_expression
105
- assert_equal :limit, applied_expression.type
106
- assert_equal [ 100 ], applied_expression.args
177
+ end
178
+
179
+ class LimitTests < UnitTests
180
+ desc "limit"
181
+ setup do
182
+ @relation_spy.limit 100
183
+ @applied = subject.applied.first
184
+ end
185
+
186
+ should "have added a limit applied expression with the passed args" do
187
+ assert_instance_of AppliedExpression, @applied
188
+ assert_equal :limit, @applied.type
189
+ assert_equal [ 100 ], @applied.args
107
190
  end
108
191
 
109
- should "set it's limit value using `limit`" do
110
- subject.limit 100
192
+ should "set it's limit value" do
111
193
  assert_equal 100, subject.limit_value
112
194
  end
113
195
 
114
- should "add an applied expression using `offset`" do
115
- subject.offset 100
116
- assert_equal 1, subject.applied.size
117
- applied_expression = subject.applied.first
118
- assert_instance_of AppliedExpression, applied_expression
119
- assert_equal :offset, applied_expression.type
120
- assert_equal [ 100 ], applied_expression.args
196
+ end
197
+
198
+ class OffsetTests < UnitTests
199
+ desc "offset"
200
+ setup do
201
+ @relation_spy.offset 100
202
+ @applied = subject.applied.first
203
+ end
204
+
205
+ should "have added a offset applied expression with the passed args" do
206
+ assert_instance_of AppliedExpression, @applied
207
+ assert_equal :offset, @applied.type
208
+ assert_equal [ 100 ], @applied.args
121
209
  end
122
210
 
123
- should "set it's offset value using `offset`" do
124
- subject.offset 100
211
+ should "set it's offset value" do
125
212
  assert_equal 100, subject.offset_value
126
213
  end
127
214
 
128
- should "return it's results using `all`" do
129
- subject.results = [ 1, 2, 3 ]
130
- assert_equal [ 1, 2, 3 ], subject.all
215
+ end
216
+
217
+ class MergeWithARelationSpyTests < UnitTests
218
+ desc "merge with a relation spy"
219
+ setup do
220
+ @other_relation_spy = Ardb::RelationSpy.new.select('column').joins('table')
221
+ @relation_spy.merge @other_relation_spy
222
+ end
223
+
224
+ should "apply another relation's applied expressions using `merge`" do
225
+ @other_relation_spy.applied.each do |applied|
226
+ assert_includes applied, @relation_spy.applied
227
+ end
228
+ end
229
+
230
+ end
231
+
232
+ class MergeWithNonRelationSpyTests < UnitTests
233
+ desc "merge without a relation spy"
234
+ setup do
235
+ @fake_relation = 'relation'
236
+ @relation_spy.merge @fake_relation
237
+ @applied = subject.applied.first
238
+ end
239
+
240
+ should "have added a merge applied expression with the passed args" do
241
+ assert_instance_of AppliedExpression, @applied
242
+ assert_equal :merge, @applied.type
243
+ assert_equal [ @fake_relation ], @applied.args
244
+ end
245
+
246
+ end
247
+
248
+ class MergeWithSelfTests < UnitTests
249
+ desc "merge with itself"
250
+ setup do
251
+ @fake_relation = 'relation'
252
+ @relation_spy.merge @relation_spy
253
+ end
254
+
255
+ should "not alter the applied expressions" do
256
+ assert_empty subject.applied
257
+ end
258
+
259
+ end
260
+
261
+ class WithExpressionsTests < UnitTests
262
+ setup do
263
+ @relation_spy.select('column').includes('table').joins('table')
264
+ @relation_spy.where(:column => 'value').order('column')
265
+ @relation_spy.group('column').having('count(*) > 1')
266
+ @relation_spy.limit(1).offset(1)
267
+ end
268
+ end
269
+
270
+ class ExceptTests < WithExpressionsTests
271
+ desc "except"
272
+
273
+ should "remove any applied expressions in the passed types" do
274
+ subject.except(:includes, :where, :group, :offset)
275
+ applied_types = subject.applied.map(&:type)
276
+ [ :select, :joins, :order, :having, :limit ].each do |type|
277
+ assert_includes type, applied_types
278
+ end
279
+ [ :includes, :where, :group, :offset ].each do |type|
280
+ assert_not_includes type, applied_types
281
+ end
282
+ end
283
+
284
+ should "unset the limit value if limit is included in the passed types" do
285
+ subject.except(:select)
286
+ assert_not_nil subject.limit_value
287
+ subject.except(:limit)
288
+ assert_nil subject.limit_value
289
+ end
290
+
291
+ should "unset the offset value if offset is included in the passed types" do
292
+ subject.except(:select)
293
+ assert_not_nil subject.offset_value
294
+ subject.except(:offset)
295
+ assert_nil subject.offset_value
296
+ end
297
+
298
+ end
299
+
300
+ class OnlyTests < WithExpressionsTests
301
+ desc "only"
302
+
303
+ should "remove any applied expressions not in the passed types" do
304
+ subject.only(:includes, :where, :group, :offset)
305
+ applied_types = subject.applied.map(&:type)
306
+ [ :includes, :where, :group, :offset ].each do |type|
307
+ assert_includes type, applied_types
308
+ end
309
+ [ :select, :joins, :order, :having, :limit ].each do |type|
310
+ assert_not_includes type, applied_types
311
+ end
312
+ end
313
+
314
+ should "unset the limit value if limit is not included in the passed types" do
315
+ subject.only(:limit)
316
+ assert_not_nil subject.limit_value
317
+ subject.only(:select)
318
+ assert_nil subject.limit_value
319
+ end
320
+
321
+ should "unset the offset value if offset is not included in the passed types" do
322
+ subject.only(:offset)
323
+ assert_not_nil subject.offset_value
324
+ subject.only(:select)
325
+ assert_nil subject.offset_value
326
+ end
327
+
328
+ end
329
+
330
+ class WithResultsTests < UnitTests
331
+ setup do
332
+ @results = [*1..5].map{ |id| Result.new(id) }
333
+ @relation_spy.results = @results
334
+ end
335
+ end
336
+
337
+ class FindTests < WithResultsTests
338
+ desc "find"
339
+
340
+ should "return a result with the matching id" do
341
+ result = subject.find(3)
342
+ assert_equal 3, result.id
343
+ end
344
+
345
+ should "raise a not found error if a result can't be found" do
346
+ assert_raises(NotFoundError){ subject.find(1000) }
347
+ end
348
+
349
+ end
350
+
351
+ class FirstTests < WithResultsTests
352
+
353
+ should "return the first item from `all` using `first`" do
354
+ assert_equal subject.all.first, subject.first
355
+ subject.offset 2
356
+ assert_equal subject.all.first, subject.first
357
+ end
358
+
359
+ should "return the first item from `all` or " \
360
+ "raise an exception if `all` is empty using `first!`" do
361
+ assert_equal subject.all.first, subject.first!
362
+ subject.limit 0
363
+ assert_raises(NotFoundError){ subject.first! }
364
+ end
365
+
366
+ end
367
+
368
+ class LastTests < WithResultsTests
369
+
370
+ should "return the last item from `all` using `last`" do
371
+ assert_equal subject.all.last, subject.last
372
+ subject.limit 2
373
+ assert_equal subject.all.last, subject.last
374
+ end
375
+
376
+ should "return the last item from `all` or " \
377
+ "raise an exception if `all` is empty using `last!`" do
378
+ assert_equal subject.all.last, subject.last!
379
+ subject.limit 0
380
+ assert_raises(NotFoundError){ subject.last! }
131
381
  end
132
382
 
133
- should "honor limit and offset values using `all`" do
134
- subject.results = [ 1, 2, 3, 4, 5 ]
383
+ end
384
+
385
+ class AllTests < WithResultsTests
386
+ desc "all"
387
+
388
+ should "return the spy's results" do
389
+ assert_equal @results, subject.all
390
+ end
135
391
 
392
+ should "honor limit and offset values" do
136
393
  subject.limit 2
137
394
  subject.offset nil
138
- assert_equal [ 1, 2 ], subject.all
395
+ assert_equal @results[0, 2], subject.all
139
396
 
140
397
  subject.limit nil
141
398
  subject.offset 3
142
- assert_equal [ 4, 5 ], subject.all
399
+ assert_equal @results[3..-1], subject.all
143
400
 
144
401
  subject.limit 2
145
402
  subject.offset 2
146
- assert_equal [ 3, 4 ], subject.all
403
+ assert_equal @results[2, 2], subject.all
147
404
  end
148
405
 
149
- should "return the size of `all` using `count`" do
150
- subject.results = [ 1, 2, 3, 4, 5 ]
151
- assert_equal 5, subject.count
152
-
153
- subject.limit 2
154
- subject.offset 2
155
- assert_equal 2, subject.count
156
- end
406
+ end
157
407
 
158
- should "be comparable using there applied collections" do
159
- other_relation = Ardb::RelationSpy.new
160
- other_relation.select :column_a
161
- assert_not_equal other_relation, subject
408
+ class CountTests < WithResultsTests
409
+ desc "count"
162
410
 
163
- subject.select :column_a
164
- assert_equal other_relation, subject
411
+ should "return the size of `all`" do
412
+ assert_equal subject.all.size, subject.count
413
+ subject.limit 2
414
+ assert_equal subject.all.size, subject.count
165
415
  end
166
416
 
167
417
  end
168
418
 
419
+ Result = Struct.new(:id)
420
+
169
421
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ardb
3
3
  version: !ruby/object:Gem::Version
4
- hash: 95
4
+ hash: 91
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 16
8
+ - 17
9
9
  - 0
10
- version: 0.16.0
10
+ version: 0.17.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kelly Redding
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2014-01-06 00:00:00 Z
19
+ date: 2014-01-09 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  version_requirements: &id001 !ruby/object:Gem::Requirement