ardb 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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