sequel_model 0.5.0.2 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,74 +0,0 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
2
-
3
- module Sequel::Plugins
4
-
5
- module Timestamped
6
- def self.apply(m, opts)
7
- m.class_def(:get_stamp) {@values[:stamp]}
8
- m.meta_def(:stamp_opts) {opts}
9
- m.before_save {@values[:stamp] = Time.now}
10
- end
11
-
12
- module InstanceMethods
13
- def abc; timestamped_opts; end
14
- end
15
-
16
- module ClassMethods
17
- def deff; timestamped_opts; end
18
- end
19
-
20
- module DatasetMethods
21
- def ghi; timestamped_opts; end
22
- end
23
- end
24
-
25
- end
26
-
27
- describe Sequel::Model, "using a plugin" do
28
-
29
- it "should fail if the plugin is not found" do
30
- proc do
31
- c = Class.new(Sequel::Model) do
32
- is :something_or_other
33
- end
34
- end.should raise_error(LoadError)
35
- end
36
-
37
- it "should apply the plugin to the class" do
38
- c = nil
39
- proc do
40
- c = Class.new(Sequel::Model) do
41
- set_dataset MODEL_DB[:items]
42
- is :timestamped, :a => 1, :b => 2
43
- end
44
- end.should_not raise_error(LoadError)
45
-
46
- c.should respond_to(:stamp_opts)
47
- c.stamp_opts.should == {:a => 1, :b => 2}
48
-
49
- # instance methods
50
- m = c.new
51
- m.should respond_to(:get_stamp)
52
- m.should respond_to(:abc)
53
- m.abc.should == {:a => 1, :b => 2}
54
- t = Time.now
55
- m[:stamp] = t
56
- m.get_stamp.should == t
57
-
58
- # class methods
59
- c.should respond_to(:deff)
60
- c.deff.should == {:a => 1, :b => 2}
61
-
62
- # dataset methods
63
- c.dataset.should respond_to(:ghi)
64
- c.dataset.ghi.should == {:a => 1, :b => 2}
65
- end
66
-
67
- it "should fail to apply if the plugin has DatasetMethod and the model has no datset" do
68
- proc do
69
- Class.new(Sequel::Model) do
70
- is :timestamped, :a => 1, :b => 2
71
- end
72
- end.should raise_error(Sequel::Error)
73
- end
74
- end
@@ -1,4 +0,0 @@
1
- --exclude
2
- gems
3
- --exclude
4
- spec
@@ -1,575 +0,0 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
2
-
3
- describe "Model#save" do
4
-
5
- before(:each) do
6
- MODEL_DB.reset
7
-
8
- @c = Class.new(Sequel::Model(:items)) do
9
- def columns
10
- [:id, :x, :y]
11
- end
12
- end
13
- end
14
-
15
- it "should insert a record for a new model instance" do
16
- o = @c.new(:x => 1)
17
- o.save
18
-
19
- MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
20
- end
21
-
22
- it "should update a record for an existing model instance" do
23
- o = @c.load(:id => 3, :x => 1)
24
- o.save
25
-
26
- MODEL_DB.sqls.first.should =~
27
- /UPDATE items SET (id = 3, x = 1|x = 1, id = 3) WHERE \(id = 3\)/
28
- end
29
-
30
- it "should update only the given columns if given" do
31
- o = @c.load(:id => 3, :x => 1, :y => nil)
32
- o.save(:y)
33
-
34
- MODEL_DB.sqls.first.should == "UPDATE items SET y = NULL WHERE (id = 3)"
35
- end
36
-
37
- it "should mark saved columns as not changed" do
38
- o = @c.new(:id => 3, :x => 1, :y => nil)
39
- o[:y] = 4
40
- o.changed_columns.should == [:y]
41
- o.save(:x)
42
- o.changed_columns.should == [:y]
43
- o.save(:y)
44
- o.changed_columns.should == []
45
- end
46
-
47
- end
48
-
49
- describe "Model#save_changes" do
50
-
51
- before(:each) do
52
- MODEL_DB.reset
53
-
54
- @c = Class.new(Sequel::Model(:items)) do
55
- def columns
56
- [:id, :x, :y]
57
- end
58
- end
59
- end
60
-
61
- it "should do nothing if no changed columns" do
62
- o = @c.new(:id => 3, :x => 1, :y => nil)
63
- o.save_changes
64
-
65
- MODEL_DB.sqls.should be_empty
66
-
67
- o = @c.load(:id => 3, :x => 1, :y => nil)
68
- o.save_changes
69
-
70
- MODEL_DB.sqls.should be_empty
71
- end
72
-
73
- it "should update only changed columns" do
74
- o = @c.load(:id => 3, :x => 1, :y => nil)
75
- o.x = 2
76
-
77
- o.save_changes
78
- MODEL_DB.sqls.should == ["UPDATE items SET x = 2 WHERE (id = 3)"]
79
- o.save_changes
80
- o.save_changes
81
- MODEL_DB.sqls.should == ["UPDATE items SET x = 2 WHERE (id = 3)"]
82
- MODEL_DB.reset
83
-
84
- o.y = 4
85
- o.save_changes
86
- MODEL_DB.sqls.should == ["UPDATE items SET y = 4 WHERE (id = 3)"]
87
- o.save_changes
88
- o.save_changes
89
- MODEL_DB.sqls.should == ["UPDATE items SET y = 4 WHERE (id = 3)"]
90
- end
91
-
92
- end
93
-
94
- describe "Model#set" do
95
-
96
- before(:each) do
97
- MODEL_DB.reset
98
-
99
- @c = Class.new(Sequel::Model(:items)) do
100
- def columns
101
- [:id, :x, :y]
102
- end
103
- end
104
- end
105
-
106
- it "should generate an update statement" do
107
- o = @c.new(:id => 1)
108
- o.set(:x => 1)
109
- MODEL_DB.sqls.first.should == "UPDATE items SET x = 1 WHERE (id = 1)"
110
- end
111
-
112
- it "should update attribute values" do
113
- o = @c.new(:id => 1)
114
- o.x.should be_nil
115
- o.set(:x => 1)
116
- o.x.should == 1
117
- end
118
-
119
- it "should support string keys" do
120
- o = @c.new(:id => 1)
121
- o.x.should be_nil
122
- o.set('x' => 1)
123
- o.x.should == 1
124
- MODEL_DB.sqls.first.should == "UPDATE items SET x = 1 WHERE (id = 1)"
125
- end
126
-
127
- it "should be aliased by #update" do
128
- o = @c.new(:id => 1)
129
- o.update(:x => 1)
130
- MODEL_DB.sqls.first.should == "UPDATE items SET x = 1 WHERE (id = 1)"
131
- end
132
- end
133
-
134
-
135
- describe "Model#new?" do
136
-
137
- before(:each) do
138
- MODEL_DB.reset
139
-
140
- @c = Class.new(Sequel::Model(:items)) do
141
- end
142
- end
143
-
144
- it "should be true for a new instance" do
145
- n = @c.new(:x => 1)
146
- n.should be_new
147
- end
148
-
149
- it "should be false after saving" do
150
- n = @c.new(:x => 1)
151
- n.save
152
- n.should_not be_new
153
- end
154
-
155
- it "should alias new_record? to new?" do
156
- n = @c.new(:x => 1)
157
- n.should respond_to(:new_record?)
158
- n.should be_new_record
159
- n.save
160
- n.should_not be_new_record
161
- end
162
-
163
- end
164
-
165
- describe Sequel::Model, "w/ primary key" do
166
-
167
- it "should default to ':id'" do
168
- model_a = Class.new Sequel::Model
169
- model_a.primary_key.should be_equal(:id)
170
- end
171
-
172
- it "should be changed through 'set_primary_key'" do
173
- model_a = Class.new(Sequel::Model) { set_primary_key :a }
174
- model_a.primary_key.should be_equal(:a)
175
- end
176
-
177
- it "should support multi argument composite keys" do
178
- model_a = Class.new(Sequel::Model) { set_primary_key :a, :b }
179
- model_a.primary_key.should be_eql([:a, :b])
180
- end
181
-
182
- it "should accept single argument composite keys" do
183
- model_a = Class.new(Sequel::Model) { set_primary_key [:a, :b] }
184
- model_a.primary_key.should be_eql([:a, :b])
185
- end
186
-
187
- end
188
-
189
- describe Sequel::Model, "w/o primary key" do
190
- it "should return nil for primary key" do
191
- Class.new(Sequel::Model) { no_primary_key }.primary_key.should be_nil
192
- end
193
-
194
- it "should raise a Sequel::Error on 'this'" do
195
- instance = Class.new(Sequel::Model) { no_primary_key }.new
196
- proc { instance.this }.should raise_error(Sequel::Error)
197
- end
198
- end
199
-
200
- describe Sequel::Model, "with this" do
201
-
202
- before { @example = Class.new Sequel::Model(:examples) }
203
-
204
- it "should return a dataset identifying the record" do
205
- instance = @example.new :id => 3
206
- instance.this.sql.should be_eql("SELECT * FROM examples WHERE (id = 3) LIMIT 1")
207
- end
208
-
209
- it "should support arbitary primary keys" do
210
- @example.set_primary_key :a
211
-
212
- instance = @example.new :a => 3
213
- instance.this.sql.should be_eql("SELECT * FROM examples WHERE (a = 3) LIMIT 1")
214
- end
215
-
216
- it "should support composite primary keys" do
217
- @example.set_primary_key :x, :y
218
- instance = @example.new :x => 4, :y => 5
219
-
220
- parts = [
221
- 'SELECT * FROM examples WHERE %s LIMIT 1',
222
- '(x = 4) AND (y = 5)',
223
- '(y = 5) AND (x = 4)'
224
- ].map { |expr| Regexp.escape expr }
225
- regexp = Regexp.new parts.first % "(?:#{parts[1]}|#{parts[2]})"
226
-
227
- instance.this.sql.should match(regexp)
228
- end
229
-
230
- end
231
-
232
- describe "Model#pk" do
233
- before(:each) do
234
- @m = Class.new(Sequel::Model)
235
- end
236
-
237
- it "should be default return the value of the :id column" do
238
- m = @m.new(:id => 111, :x => 2, :y => 3)
239
- m.pk.should == 111
240
- end
241
-
242
- it "should be return the primary key value for custom primary key" do
243
- @m.set_primary_key :x
244
- m = @m.new(:id => 111, :x => 2, :y => 3)
245
- m.pk.should == 2
246
- end
247
-
248
- it "should be return the primary key value for composite primary key" do
249
- @m.set_primary_key [:y, :x]
250
- m = @m.new(:id => 111, :x => 2, :y => 3)
251
- m.pk.should == [3, 2]
252
- end
253
-
254
- it "should raise if no primary key" do
255
- @m.set_primary_key nil
256
- m = @m.new(:id => 111, :x => 2, :y => 3)
257
- proc {m.pk}.should raise_error(Sequel::Error)
258
-
259
- @m.no_primary_key
260
- m = @m.new(:id => 111, :x => 2, :y => 3)
261
- proc {m.pk}.should raise_error(Sequel::Error)
262
- end
263
- end
264
-
265
- describe "Model#pk_hash" do
266
- before(:each) do
267
- @m = Class.new(Sequel::Model)
268
- end
269
-
270
- it "should be default return the value of the :id column" do
271
- m = @m.new(:id => 111, :x => 2, :y => 3)
272
- m.pk_hash.should == {:id => 111}
273
- end
274
-
275
- it "should be return the primary key value for custom primary key" do
276
- @m.set_primary_key :x
277
- m = @m.new(:id => 111, :x => 2, :y => 3)
278
- m.pk_hash.should == {:x => 2}
279
- end
280
-
281
- it "should be return the primary key value for composite primary key" do
282
- @m.set_primary_key [:y, :x]
283
- m = @m.new(:id => 111, :x => 2, :y => 3)
284
- m.pk_hash.should == {:y => 3, :x => 2}
285
- end
286
-
287
- it "should raise if no primary key" do
288
- @m.set_primary_key nil
289
- m = @m.new(:id => 111, :x => 2, :y => 3)
290
- proc {m.pk_hash}.should raise_error(Sequel::Error)
291
-
292
- @m.no_primary_key
293
- m = @m.new(:id => 111, :x => 2, :y => 3)
294
- proc {m.pk_hash}.should raise_error(Sequel::Error)
295
- end
296
- end
297
-
298
- describe Sequel::Model, "update_with_params" do
299
-
300
- before(:each) do
301
- MODEL_DB.reset
302
-
303
- @c = Class.new(Sequel::Model(:items)) do
304
- def self.columns; [:x, :y]; end
305
- end
306
- @o1 = @c.new
307
- @o2 = @c.load(:id => 5)
308
- end
309
-
310
- it "should filter the given params using the model columns" do
311
- @o1.update_with_params(:x => 1, :z => 2)
312
- MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
313
-
314
- MODEL_DB.reset
315
- @o2.update_with_params(:y => 1, :abc => 2)
316
- MODEL_DB.sqls.first.should == "UPDATE items SET y = 1 WHERE (id = 5)"
317
- end
318
-
319
- it "should be aliased by create_with" do
320
- @o1.update_with(:x => 1, :z => 2)
321
- MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
322
-
323
- MODEL_DB.reset
324
- @o2.update_with(:y => 1, :abc => 2)
325
- MODEL_DB.sqls.first.should == "UPDATE items SET y = 1 WHERE (id = 5)"
326
- end
327
-
328
- it "should support virtual attributes" do
329
- @c.class_def(:blah=) {|v| self.x = v}
330
- @o1.update_with(:blah => 333)
331
- MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (333)"
332
- end
333
- end
334
-
335
- describe Sequel::Model, "create_with_params" do
336
-
337
- before(:each) do
338
- MODEL_DB.reset
339
-
340
- @c = Class.new(Sequel::Model(:items)) do
341
- def self.columns; [:x, :y]; end
342
- end
343
- end
344
-
345
- it "should filter the given params using the model columns" do
346
- @c.create_with_params(:x => 1, :z => 2)
347
- MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
348
-
349
- MODEL_DB.reset
350
- @c.create_with_params(:y => 1, :abc => 2)
351
- MODEL_DB.sqls.first.should == "INSERT INTO items (y) VALUES (1)"
352
- end
353
-
354
- it "should be aliased by create_with" do
355
- @c.create_with(:x => 1, :z => 2)
356
- MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
357
-
358
- MODEL_DB.reset
359
- @c.create_with(:y => 1, :abc => 2)
360
- MODEL_DB.sqls.first.should == "INSERT INTO items (y) VALUES (1)"
361
- end
362
-
363
- it "should support virtual attributes" do
364
- @c.class_def(:blah=) {|v| self.x = v}
365
- o = @c.create_with(:blah => 333)
366
- MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (333)"
367
- end
368
- end
369
-
370
- describe Sequel::Model, "#destroy" do
371
-
372
- before(:each) do
373
- MODEL_DB.reset
374
- @model = Class.new(Sequel::Model(:items))
375
- @model.dataset.meta_def(:delete) {MODEL_DB.execute delete_sql}
376
-
377
- @instance = @model.new(:id => 1234)
378
- #@model.stub!(:delete).and_return(:true)
379
- end
380
-
381
- it "should run within a transaction" do
382
- @model.db.should_receive(:transaction)
383
- @instance.destroy
384
- end
385
-
386
- it "should run before_destroy and after_destroy hooks" do
387
- @model.before_destroy {MODEL_DB.execute('before blah')}
388
- @model.after_destroy {MODEL_DB.execute('after blah')}
389
- @instance.destroy
390
-
391
- MODEL_DB.sqls.should == [
392
- "before blah",
393
- "DELETE FROM items WHERE (id = 1234)",
394
- "after blah"
395
- ]
396
- end
397
- end
398
-
399
- describe Sequel::Model, "#exists?" do
400
- before(:each) do
401
- @model = Class.new(Sequel::Model(:items))
402
- @m = @model.new
403
- end
404
-
405
- it "should returns true when #this.count > 0" do
406
- @m.this.meta_def(:count) {1}
407
- @m.exists?.should be_true
408
- end
409
-
410
- it "should return false when #this.count == 0" do
411
- @m.this.meta_def(:count) {0}
412
- @m.exists?.should be_false
413
- end
414
- end
415
-
416
- describe Sequel::Model, "#each" do
417
- setup do
418
- @model = Class.new(Sequel::Model(:items))
419
- @m = @model.new(:a => 1, :b => 2, :id => 4444)
420
- end
421
-
422
- specify "should iterate over the values" do
423
- h = {}
424
- @m.each {|k, v| h[k] = v}
425
- h.should == {:a => 1, :b => 2, :id => 4444}
426
- end
427
- end
428
-
429
- describe Sequel::Model, "#keys" do
430
- setup do
431
- @model = Class.new(Sequel::Model(:items))
432
- @m = @model.new(:a => 1, :b => 2, :id => 4444)
433
- end
434
-
435
- specify "should return the value keys" do
436
- @m.keys.size.should == 3
437
- @m.keys.should include(:a, :b, :id)
438
-
439
- @m = @model.new()
440
- @m.keys.should == []
441
- end
442
- end
443
-
444
- describe Sequel::Model, "#===" do
445
- specify "should compare instances by values" do
446
- a = Sequel::Model.new(:id => 1, :x => 3)
447
- b = Sequel::Model.new(:id => 1, :x => 4)
448
- c = Sequel::Model.new(:id => 1, :x => 3)
449
-
450
- a.should_not == b
451
- a.should == c
452
- b.should_not == c
453
- end
454
- end
455
-
456
- describe Sequel::Model, "#===" do
457
- specify "should compare instances by pk only" do
458
- a = Sequel::Model.new(:id => 1, :x => 3)
459
- b = Sequel::Model.new(:id => 1, :x => 4)
460
- c = Sequel::Model.new(:id => 2, :x => 3)
461
-
462
- a.should === b
463
- a.should_not === c
464
- end
465
- end
466
-
467
- describe Sequel::Model, "#initialize" do
468
- setup do
469
- @c = Class.new(Sequel::Model) do
470
- end
471
- end
472
-
473
- specify "should accept values" do
474
- m = @c.new(:id => 1, :x => 2)
475
- m.values.should == {:id => 1, :x => 2}
476
- end
477
-
478
- specify "should accept no values" do
479
- m = @c.new
480
- m.values.should == {}
481
- end
482
-
483
- specify "should accept nil values" do
484
- m = @c.new(nil)
485
- m.values.should == {}
486
- end
487
-
488
- specify "should accept a block to execute" do
489
- m = @c.new {|o| o[:id] = 1234}
490
- m.id.should == 1234
491
- end
492
-
493
- specify "should accept virtual attributes" do
494
- @c.class_def(:blah=) {|x| @blah = x}
495
- @c.class_def(:blah) {@blah}
496
-
497
- m = @c.new(:id => 1, :x => 2, :blah => 3)
498
- m.values.should == {:id => 1, :x => 2}
499
- m.blah.should == 3
500
- end
501
-
502
- specify "should convert string keys into symbol keys" do
503
- m = @c.new('id' => 1, 'x' => 2)
504
- m.values.should == {:id => 1, :x => 2}
505
- end
506
- end
507
-
508
- describe Sequel::Model, ".create" do
509
-
510
- before(:each) do
511
- MODEL_DB.reset
512
- @c = Class.new(Sequel::Model(:items)) do
513
- def columns; [:x]; end
514
- end
515
- end
516
-
517
- it "should be able to create rows in the associated table" do
518
- o = @c.create(:x => 1)
519
- o.class.should == @c
520
- MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1)', "SELECT * FROM items WHERE (id IN ('INSERT INTO items (x) VALUES (1)')) LIMIT 1"]
521
- end
522
-
523
- it "should be able to create rows without any values specified" do
524
- o = @c.create
525
- o.class.should == @c
526
- MODEL_DB.sqls.should == ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE (id IN ('INSERT INTO items DEFAULT VALUES')) LIMIT 1"]
527
- end
528
-
529
- it "should accept a block and run it" do
530
- o1, o2, o3 = nil, nil, nil
531
- o = @c.create {|o3| o1 = o3; o2 = :blah; o3.x = 333}
532
- o.class.should == @c
533
- o1.should === o
534
- o3.should === o
535
- o2.should == :blah
536
- MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id IN ('INSERT INTO items (x) VALUES (333)')) LIMIT 1"]
537
- end
538
-
539
- it "should create a row for a model with custom primary key" do
540
- @c.set_primary_key :x
541
- o = @c.create(:x => 30)
542
- o.class.should == @c
543
- MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (30)", "SELECT * FROM items WHERE (x = 30) LIMIT 1"]
544
- end
545
- end
546
-
547
- describe Sequel::Model, "#refresh" do
548
- setup do
549
- MODEL_DB.reset
550
- @c = Class.new(Sequel::Model(:items)) do
551
- def columns; [:x]; end
552
- end
553
- end
554
-
555
- specify "should reload the instance values from the database" do
556
- @m = @c.new(:id => 555)
557
- @m[:x] = 'blah'
558
- @m.this.should_receive(:first).and_return({:x => 'kaboom', :id => 555})
559
- @m.refresh
560
- @m[:x].should == 'kaboom'
561
- end
562
-
563
- specify "should raise if the instance is not found" do
564
- @m = @c.new(:id => 555)
565
- @m.this.should_receive(:first).and_return(nil)
566
- proc {@m.refresh}.should raise_error(Sequel::Error)
567
- end
568
-
569
- specify "should be aliased by #reload" do
570
- @m = @c.new(:id => 555)
571
- @m.this.should_receive(:first).and_return({:x => 'kaboom', :id => 555})
572
- @m.reload
573
- @m[:x].should == 'kaboom'
574
- end
575
- end