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
|