sequel_model 0.5.0.2 → 3.8.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.
@@ -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