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
|
require_relative "spec_helper"
describe "AssociationDependencies plugin" do
before do
@mods = []
@c = Class.new(Sequel::Model)
@c.plugin :association_dependencies
@Artist = Class.new(@c).set_dataset(:artists)
@Artist.dataset = @Artist.dataset.with_fetch(:id=>2, :name=>'Ar')
@Album = Class.new(@c).set_dataset(:albums)
@Album.dataset = @Album.dataset.with_fetch(:id=>1, :name=>'Al', :artist_id=>2)
@Artist.columns :id, :name
@Album.columns :id, :name, :artist_id
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
@Artist.one_to_one :first_album, :class=>@Album, :key=>:artist_id, :conditions=>{:position=>1}
@Artist.many_to_many :other_artists, :class=>@Artist, :join_table=>:aoa, :left_key=>:l, :right_key=>:r
@Album.many_to_one :artist, :class=>@Artist
DB.reset
end
it "should allow destroying associated many_to_one associated object" do
@Album.add_association_dependencies :artist=>:destroy
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
end
it "should allow deleting associated many_to_one associated object" do
@Album.add_association_dependencies :artist=>:delete
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE id = 1', 'DELETE FROM artists WHERE (artists.id = 2)']
end
it "should allow destroying associated one_to_one associated object" do
@Artist.add_association_dependencies :first_album=>:destroy
@Artist.load(:id=>2, :name=>'Ar').destroy
DB.sqls.must_equal ['SELECT * FROM albums WHERE ((position = 1) AND (albums.artist_id = 2)) LIMIT 1', 'DELETE FROM albums WHERE id = 1', 'DELETE FROM artists WHERE id = 2']
end
it "should allow deleting associated one_to_one associated object" do
@Artist.add_association_dependencies :first_album=>:delete
@Artist.load(:id=>2, :name=>'Ar').destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE ((position = 1) AND (albums.artist_id = 2))', 'DELETE FROM artists WHERE id = 2']
end
it "should allow destroying associated one_to_many objects" do
@Artist.add_association_dependencies :albums=>:destroy
@Artist.load(:id=>2, :name=>'Ar').destroy
DB.sqls.must_equal ['SELECT * FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM albums WHERE id = 1', 'DELETE FROM artists WHERE id = 2']
end
it "should allow deleting associated one_to_many objects" do
@Artist.add_association_dependencies :albums=>:delete
@Artist.load(:id=>2, :name=>'Ar').destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM artists WHERE id = 2']
end
it "should allow nullifying associated one_to_one objects" do
@Artist.add_association_dependencies :first_album=>:nullify
@Artist.load(:id=>2, :name=>'Ar').destroy
DB.sqls.must_equal ['UPDATE albums SET artist_id = NULL WHERE ((position = 1) AND (artist_id = 2))', 'DELETE FROM artists WHERE id = 2']
end
it "should allow nullifying associated one_to_many objects" do
@Artist.add_association_dependencies :albums=>:nullify
@Artist.load(:id=>2, :name=>'Ar').destroy
DB.sqls.must_equal ['UPDATE albums SET artist_id = NULL WHERE (artist_id = 2)', 'DELETE FROM artists WHERE id = 2']
end
it "should allow nullifying associated many_to_many associations" do
@Artist.add_association_dependencies :other_artists=>:nullify
@Artist.load(:id=>2, :name=>'Ar').destroy
DB.sqls.must_equal ['DELETE FROM aoa WHERE (l = 2)', 'DELETE FROM artists WHERE id = 2']
end
it "should not allow modifications if class is frozen" do
@Artist.add_association_dependencies :other_artists=>:nullify
@Artist.freeze
proc{@Artist.add_association_dependencies :albums=>:nullify}.must_raise RuntimeError, TypeError
@Artist.association_dependencies.frozen?.must_equal true
@Artist.association_dependencies[:before_nullify].frozen?.must_equal true
end
it "should raise an error if attempting to nullify a many_to_one association" do
proc{@Album.add_association_dependencies :artist=>:nullify}.must_raise(Sequel::Error)
end
it "should raise an error if using an unrecognized dependence action" do
proc{@Album.add_association_dependencies :artist=>:blah}.must_raise(Sequel::Error)
end
it "should raise an error if a nonexistent association is used" do
proc{@Album.add_association_dependencies :blah=>:delete}.must_raise(Sequel::Error)
end
it "should raise an error if a invalid association type is used" do
@Artist.plugin :many_through_many
@Artist.many_through_many :other_albums, [[:id, :id, :id]]
proc{@Artist.add_association_dependencies :other_albums=>:nullify}.must_raise(Sequel::Error)
end
it "should raise an error if using a many_to_many association type without nullify" do
proc{@Artist.add_association_dependencies :other_artists=>:delete}.must_raise(Sequel::Error)
end
it "should allow specifying association dependencies in the plugin call" do
@Album.plugin :association_dependencies, :artist=>:destroy
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
end
it "should work with subclasses" do
c = Class.new(@Album)
c.add_association_dependencies :artist=>:destroy
c.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE id = 1']
@Album.add_association_dependencies :artist=>:destroy
c2 = Class.new(@Album)
c2.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
DB.sqls.must_equal ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
end
end
|