File: model_test.rb

package info (click to toggle)
ruby-sequel 5.63.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,408 kB
  • sloc: ruby: 113,747; makefile: 3
file content (203 lines) | stat: -rw-r--r-- 6,056 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
require_relative "spec_helper"

describe "Sequel::Model basic support" do 
  before do
    @db = DB
    @db.create_table!(:items, :engine=>:InnoDB) do
      primary_key :id
      String :name
    end
    class ::Item < Sequel::Model(@db)
    end
  end
  after do
    @db.drop_table?(:items)
    Object.send(:remove_const, :Item)
  end

  it ".find should return first matching item" do
    Item.all.must_equal []
    Item.find(:name=>'J').must_be_nil
    Item.create(:name=>'J')
    Item.find(:name=>'J').must_equal Item.load(:id=>1, :name=>'J')
  end
  
  it ".finder should create method that returns first matching item" do
    def Item.by_name(name) where(:name=>name) end
    Item.plugin :finder
    Item.finder :by_name
    Item.first_by_name('J').must_be_nil
    Item.create(:name=>'J')
    Item.first_by_name('J').must_equal Item.load(:id=>1, :name=>'J')
    Item.first_by_name(['J', 'K']).must_equal Item.load(:id=>1, :name=>'J')
  end
  
  it ".prepared_finder should create method that returns first matching item" do
    def Item.by_name(name) where(:name=>name) end
    Item.plugin :finder
    Item.prepared_finder :by_name
    Item.first_by_name('J').must_be_nil
    Item.create(:name=>'J')
    Item.first_by_name('J').must_equal Item.load(:id=>1, :name=>'J')
  end
  
  it ".find_or_create should return first matching item, or create it if it doesn't exist" do
    Item.all.must_equal []
    Item.find_or_create(:name=>'J').must_equal Item.load(:id=>1, :name=>'J')
    Item.all.must_equal [Item.load(:id=>1, :name=>'J')]
    Item.find_or_create(:name=>'J').must_equal Item.load(:id=>1, :name=>'J')
    Item.all.must_equal [Item.load(:id=>1, :name=>'J')]
  end

  it "should raise an error if the implied database table doesn't exist" do
    proc do
      class ::Item::Thing < Sequel::Model
      end
    end.must_raise Sequel::Error
  end

  it "should not raise an error if the implied database table doesn't exist if require_valid_table is false" do
    c = Sequel::Model(@db)
    c.require_valid_table = false
    class ::Item::Thing < c
      set_dataset :items
    end
    Item.create(:name=>'J')
    Item::Thing.first.must_equal Item::Thing.load(:id=>1, :name=>'J')
  end

  it "should create accessors for all table columns even if all dataset columns aren't selected" do
    c = Class.new(Sequel::Model(@db[:items].select(:id)))
    o = c.new
    o.name = 'A'
    o.save.must_equal c.load(:id=>1)
    c.select_map(:name).must_equal ['A']
  end

  it "should work correctly when a dataset restricts the colums it selects" do
    class ::Item::Thing < Sequel::Model(@db[:items].select(:name))
    end
    Item.create(:name=>'J')
    Item::Thing.first.must_equal Item::Thing.load(:name=>'J')
  end

  it "#delete should delete items correctly" do
    i = Item.create(:name=>'J')
    Item.count.must_equal 1
    i.delete
    Item.count.must_equal 0
  end

  it "#save should return nil if raise_on_save_failure is false and save isn't successful" do
    i = Item.new(:name=>'J')
    i.use_transactions = true
    def i.after_save
      raise Sequel::Rollback
    end
    i.save.must_be_nil
  end

  it "#exists? should return whether the item is still in the database" do
    i = Item.create(:name=>'J')
    i.exists?.must_equal true
    Item.dataset.delete
    i.exists?.must_equal false
  end

  it "#save should only update specified columns when saving" do
    @db.create_table!(:items) do
      primary_key :id
      String :name
      Integer :num
    end
    Item.dataset = Item.dataset
    i = Item.create(:name=>'J', :num=>1)
    Item.all.must_equal [Item.load(:id=>1, :name=>'J', :num=>1)]
    i.set(:name=>'K', :num=>2)
    i.save(:columns=>:name)
    Item.all.must_equal [Item.load(:id=>1, :name=>'K', :num=>1)]
    i.set(:name=>'L')
    i.save(:columns=>:num)
    Item.all.must_equal [Item.load(:id=>1, :name=>'K', :num=>2)]
  end
  
  it "#save should check that the only a single row is modified, unless require_modification is false" do
    i = Item.create(:name=>'a')
    i.require_modification = true
    i.delete
    proc{i.save}.must_raise(Sequel::NoExistingObject)
    proc{i.delete}.must_raise(Sequel::NoExistingObject)
    
    i.require_modification = false
    i.save
    i.delete
  end

  it ".to_hash should return a hash keyed on primary key if no argument provided" do
    Item.create(:name=>'J')
    Item.to_hash.must_equal(1=>Item.load(:id=>1, :name=>'J'))
  end
  
  it ".to_hash should return a hash keyed on argument if one argument provided" do
    Item.create(:name=>'J')
    Item.to_hash(:name).must_equal('J'=>Item.load(:id=>1, :name=>'J'))
  end
  
  it "should be marshallable before and after saving if marshallable! is called" do
    i = Item.new(:name=>'J')
    s = nil
    i2 = nil
    i.marshallable!
    s = Marshal.dump(i)
    i2 = Marshal.load(s)
    i2.must_equal i

    i.save
    i.marshallable!
    s = Marshal.dump(i)
    i2 = Marshal.load(s)
    i2.must_equal i

    i.save
    i.marshallable!
    s = Marshal.dump(i)
    i2 = Marshal.load(s)
    i2.must_equal i
  end
  
  it "#lock! should lock records" do
    Item.db.transaction do
      i = Item.create(:name=>'J')
      i.lock!
      i.update(:name=>'K')
    end
  end
end

describe "Sequel::Model with no existing table" do 
  it "should not raise an error when setting the dataset" do
    db = DB
    db.drop_table?(:items)
    c = Class.new(Sequel::Model)
    proc{c.set_dataset(db[:items])}.must_raise Sequel::Error
    db.transaction do
      c = Class.new(Sequel::Model)
      proc{c.dataset = db[:items]}.must_raise Sequel::Error
      db.get(Sequel.cast(1, Integer)).must_equal 1
    end
  end

  it "should not raise an error when setting the dataset when require_valid_table is false" do
    db = DB
    db.drop_table?(:items)
    c = Class.new(Sequel::Model)
    c.require_valid_table = false
    c.set_dataset(db[:items])
    db.transaction do
      c = Class.new(Sequel::Model)
      c.require_valid_table = false
      c.dataset = db[:items]
      db.get(Sequel.cast(1, Integer)).must_equal 1
    end
  end
end