spec/integration/plugin_test.rb in sequel-3.28.0 vs spec/integration/plugin_test.rb in sequel-3.29.0

- old
+ new

@@ -1,59 +1,63 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb') # H2 and MSSQL don't support USING joins # DB2 does not seem to support USING joins in every version; it seems to be # valid expression in DB2 iSeries UDB though. -unless [:h2, :mssql, :db2].include?(INTEGRATION_DB.database_type) +unless Sequel.guarded?(:h2, :mssql, :db2) describe "Class Table Inheritance Plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.instance_variable_set(:@schemas, {}) - @db.create_table!(:employees) do + [:staff, :executives, :managers, :employees].each{|t| @db.drop_table(t) if @db.table_exists?(t)} + @db.create_table(:employees) do primary_key :id String :name String :kind end - @db.create_table!(:managers) do + @db.create_table(:managers) do foreign_key :id, :employees, :primary_key=>true Integer :num_staff end - @db.create_table!(:executives) do + @db.create_table(:executives) do foreign_key :id, :managers, :primary_key=>true Integer :num_managers end - @db.create_table!(:staff) do + @db.create_table(:staff) do foreign_key :id, :employees, :primary_key=>true foreign_key :manager_id, :managers end + end + before do + [:staff, :executives, :managers, :employees].each{|t| @db[t].delete} class ::Employee < Sequel::Model(@db) plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff} end class ::Manager < Employee one_to_many :staff_members, :class=>:Staff end class ::Executive < Manager end class ::Staff < Employee - many_to_one :manager + many_to_one :manager, :qualify=>false end @i1 =@db[:employees].insert(:name=>'E', :kind=>'Employee') @i2 = @db[:employees].insert(:name=>'S', :kind=>'Staff') @i3 = @db[:employees].insert(:name=>'M', :kind=>'Manager') @i4 = @db[:employees].insert(:name=>'Ex', :kind=>'Executive') @db[:managers].insert(:id=>@i3, :num_staff=>7) @db[:managers].insert(:id=>@i4, :num_staff=>5) @db[:executives].insert(:id=>@i4, :num_managers=>6) @db[:staff].insert(:id=>@i2, :manager_id=>@i4) - - clear_sqls end after do - @db.drop_table :staff, :executives, :managers, :employees [:Executive, :Manager, :Staff, :Employee].each{|s| Object.send(:remove_const, s)} end + after(:all) do + @db.drop_table :staff, :executives, :managers, :employees + end specify "should return rows as subclass instances" do Employee.order(:id).all.should == [ Employee.load(:id=>@i1, :name=>'E', :kind=>'Employee'), Staff.load(:id=>@i2, :name=>'S', :kind=>'Staff'), @@ -120,11 +124,11 @@ specify "should handle eagerly loading many_to_one relationships" do Staff.limit(1).eager(:manager).all.map{|x| x.manager}.should == [Manager[@i4]] end - cspecify "should handle eagerly graphing many_to_one relationships", :sqlite do + specify "should handle eagerly graphing many_to_one relationships" do ss = Staff.eager_graph(:manager).all ss.should == [Staff[@i2]] ss.map{|x| x.manager}.should == [Manager[@i4]] end @@ -143,25 +147,29 @@ end end end describe "Many Through Many Plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.instance_variable_set(:@schemas, {}) - @db.create_table!(:albums) do + [:albums_artists, :albums, :artists].each{|t| @db.drop_table(t) if @db.table_exists?(t)} + @db.create_table(:albums) do primary_key :id String :name end - @db.create_table!(:artists) do + @db.create_table(:artists) do primary_key :id String :name end - @db.create_table!(:albums_artists) do + @db.create_table(:albums_artists) do foreign_key :album_id, :albums foreign_key :artist_id, :artists end + end + before do + [:albums_artists, :albums, :artists].each{|t| @db[t].delete} class ::Album < Sequel::Model(@db) many_to_many :artists end class ::Artist < Sequel::Model(@db) plugin :many_through_many @@ -181,30 +189,30 @@ @album3.add_artist(@artist2) @album3.add_artist(@artist3) @album4 = Album.create(:name=>'D') @album4.add_artist(@artist1) @album4.add_artist(@artist4) - - clear_sqls end after do - @db.drop_table :albums_artists, :albums, :artists [:Album, :Artist].each{|s| Object.send(:remove_const, s)} end + after(:all) do + @db.drop_table :albums_artists, :albums, :artists + end specify "should handle super simple case with 1 join table" do Artist.many_through_many :albums, [[:albums_artists, :artist_id, :album_id]] - Artist[1].albums.map{|x| x.name}.sort.should == %w'A D' - Artist[2].albums.map{|x| x.name}.sort.should == %w'A C' - Artist[3].albums.map{|x| x.name}.sort.should == %w'B C' - Artist[4].albums.map{|x| x.name}.sort.should == %w'B D' + Artist[@artist1.id].albums.map{|x| x.name}.sort.should == %w'A D' + Artist[@artist2.id].albums.map{|x| x.name}.sort.should == %w'A C' + Artist[@artist3.id].albums.map{|x| x.name}.sort.should == %w'B C' + Artist[@artist4.id].albums.map{|x| x.name}.sort.should == %w'B D' Artist.plugin :prepared_statements_associations - Artist[1].albums.map{|x| x.name}.sort.should == %w'A D' - Artist[2].albums.map{|x| x.name}.sort.should == %w'A C' - Artist[3].albums.map{|x| x.name}.sort.should == %w'B C' - Artist[4].albums.map{|x| x.name}.sort.should == %w'B D' + Artist[@artist1.id].albums.map{|x| x.name}.sort.should == %w'A D' + Artist[@artist2.id].albums.map{|x| x.name}.sort.should == %w'A C' + Artist[@artist3.id].albums.map{|x| x.name}.sort.should == %w'B C' + Artist[@artist4.id].albums.map{|x| x.name}.sort.should == %w'B D' Artist.filter(:id=>1).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A D' Artist.filter(:id=>2).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A C' Artist.filter(:id=>3).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B C' Artist.filter(:id=>4).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B D' @@ -234,30 +242,30 @@ Artist.exclude(:albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'4' end specify "should handle typical case with 3 join tables" do Artist.many_through_many :related_artists, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id]], :class=>Artist, :distinct=>true - Artist[1].related_artists.map{|x| x.name}.sort.should == %w'1 2 4' - Artist[2].related_artists.map{|x| x.name}.sort.should == %w'1 2 3' - Artist[3].related_artists.map{|x| x.name}.sort.should == %w'2 3 4' - Artist[4].related_artists.map{|x| x.name}.sort.should == %w'1 3 4' + Artist[@artist1.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 4' + Artist[@artist2.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 3' + Artist[@artist3.id].related_artists.map{|x| x.name}.sort.should == %w'2 3 4' + Artist[@artist4.id].related_artists.map{|x| x.name}.sort.should == %w'1 3 4' Artist.plugin :prepared_statements_associations - Artist[1].related_artists.map{|x| x.name}.sort.should == %w'1 2 4' - Artist[2].related_artists.map{|x| x.name}.sort.should == %w'1 2 3' - Artist[3].related_artists.map{|x| x.name}.sort.should == %w'2 3 4' - Artist[4].related_artists.map{|x| x.name}.sort.should == %w'1 3 4' + Artist[@artist1.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 4' + Artist[@artist2.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 3' + Artist[@artist3.id].related_artists.map{|x| x.name}.sort.should == %w'2 3 4' + Artist[@artist4.id].related_artists.map{|x| x.name}.sort.should == %w'1 3 4' - Artist.filter(:id=>1).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4' - Artist.filter(:id=>2).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3' - Artist.filter(:id=>3).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4' - Artist.filter(:id=>4).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4' + Artist.filter(:id=>@artist1.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4' + Artist.filter(:id=>@artist2.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3' + Artist.filter(:id=>@artist3.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4' + Artist.filter(:id=>@artist4.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4' - Artist.filter(:artists__id=>1).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4' - Artist.filter(:artists__id=>2).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3' - Artist.filter(:artists__id=>3).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4' - Artist.filter(:artists__id=>4).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4' + Artist.filter(:artists__id=>@artist1.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4' + Artist.filter(:artists__id=>@artist2.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3' + Artist.filter(:artists__id=>@artist3.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4' + Artist.filter(:artists__id=>@artist4.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4' Artist.filter(:related_artists=>@artist1).all.map{|a| a.name}.sort.should == %w'1 2 4' Artist.filter(:related_artists=>@artist2).all.map{|a| a.name}.sort.should == %w'1 2 3' Artist.filter(:related_artists=>@artist3).all.map{|a| a.name}.sort.should == %w'2 3 4' Artist.filter(:related_artists=>@artist4).all.map{|a| a.name}.sort.should == %w'1 3 4' @@ -283,30 +291,30 @@ @album2.add_artist(@artist3) @album3.add_artist(@artist1) @album4.add_artist(@artist3) @album4.add_artist(@artist4) - Artist[1].related_albums.map{|x| x.name}.sort.should == %w'A B C' - Artist[2].related_albums.map{|x| x.name}.sort.should == %w'A B C D' - Artist[3].related_albums.map{|x| x.name}.sort.should == %w'A B D' - Artist[4].related_albums.map{|x| x.name}.sort.should == %w'B D' + Artist[@artist1.id].related_albums.map{|x| x.name}.sort.should == %w'A B C' + Artist[@artist2.id].related_albums.map{|x| x.name}.sort.should == %w'A B C D' + Artist[@artist3.id].related_albums.map{|x| x.name}.sort.should == %w'A B D' + Artist[@artist4.id].related_albums.map{|x| x.name}.sort.should == %w'B D' Artist.plugin :prepared_statements_associations - Artist[1].related_albums.map{|x| x.name}.sort.should == %w'A B C' - Artist[2].related_albums.map{|x| x.name}.sort.should == %w'A B C D' - Artist[3].related_albums.map{|x| x.name}.sort.should == %w'A B D' - Artist[4].related_albums.map{|x| x.name}.sort.should == %w'B D' + Artist[@artist1.id].related_albums.map{|x| x.name}.sort.should == %w'A B C' + Artist[@artist2.id].related_albums.map{|x| x.name}.sort.should == %w'A B C D' + Artist[@artist3.id].related_albums.map{|x| x.name}.sort.should == %w'A B D' + Artist[@artist4.id].related_albums.map{|x| x.name}.sort.should == %w'B D' - Artist.filter(:id=>1).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C' - Artist.filter(:id=>2).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D' - Artist.filter(:id=>3).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D' - Artist.filter(:id=>4).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D' + Artist.filter(:id=>@artist1.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C' + Artist.filter(:id=>@artist2.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D' + Artist.filter(:id=>@artist3.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D' + Artist.filter(:id=>@artist4.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D' - Artist.filter(:artists__id=>1).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C' - Artist.filter(:artists__id=>2).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D' - Artist.filter(:artists__id=>3).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D' - Artist.filter(:artists__id=>4).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D' + Artist.filter(:artists__id=>@artist1.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C' + Artist.filter(:artists__id=>@artist2.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D' + Artist.filter(:artists__id=>@artist3.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D' + Artist.filter(:artists__id=>@artist4.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D' Artist.filter(:related_albums=>@album1).all.map{|a| a.name}.sort.should == %w'1 2 3' Artist.filter(:related_albums=>@album2).all.map{|a| a.name}.sort.should == %w'1 2 3 4' Artist.filter(:related_albums=>@album3).all.map{|a| a.name}.sort.should == %w'1 2' Artist.filter(:related_albums=>@album4).all.map{|a| a.name}.sort.should == %w'2 3 4' @@ -326,23 +334,24 @@ Artist.exclude(:related_albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'4' end end describe "Lazy Attributes plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.create_table!(:items) do primary_key :id String :name Integer :num end + @db[:items].delete class ::Item < Sequel::Model(@db) plugin :lazy_attributes, :num end Item.create(:name=>'J', :num=>1) end - after do + after(:all) do @db.drop_table(:items) Object.send(:remove_const, :Item) end specify "should not include lazy attribute columns by default" do @@ -371,11 +380,11 @@ end end end describe "Tactical Eager Loading Plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.instance_variable_set(:@schemas, {}) @db.create_table!(:artists) do primary_key :id String :name @@ -383,10 +392,14 @@ @db.create_table!(:albums) do primary_key :id String :name foreign_key :artist_id, :artists end + end + before do + @db[:albums].delete + @db[:artists].delete class ::Album < Sequel::Model(@db) plugin :tactical_eager_loading many_to_one :artist end class ::Artist < Sequel::Model(@db) @@ -400,17 +413,17 @@ @artist4 = Artist.create(:name=>'4') @album1 = Album.create(:name=>'A', :artist=>@artist1) @album2 = Album.create(:name=>'B', :artist=>@artist1) @album3 = Album.create(:name=>'C', :artist=>@artist2) @album4 = Album.create(:name=>'D', :artist=>@artist3) - - clear_sqls end after do - @db.drop_table :albums, :artists [:Album, :Artist].each{|s| Object.send(:remove_const, s)} end + after(:all) do + @db.drop_table :albums, :artists + end specify "should eagerly load associations for all items when accessing any item" do a = Artist.order(:name).all a.map{|x| x.associations}.should == [{}, {}, {}, {}] a.first.albums.should == [@album1, @album2] @@ -454,11 +467,11 @@ end end end describe "Touch plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.instance_variable_set(:@schemas, {}) @db.create_table!(:artists) do primary_key :id String :name @@ -468,10 +481,14 @@ primary_key :id String :name foreign_key :artist_id, :artists DateTime :updated_at end + end + before do + @db[:albums].delete + @db[:artists].delete class ::Album < Sequel::Model(@db) many_to_one :artist plugin :touch, :associations=>:artist end class ::Artist < Sequel::Model(@db) @@ -479,13 +496,15 @@ @artist = Artist.create(:name=>'1') @album = Album.create(:name=>'A', :artist=>@artist) end after do - @db.drop_table :albums, :artists [:Album, :Artist].each{|s| Object.send(:remove_const, s)} end + after(:all) do + @db.drop_table :albums, :artists + end specify "should update the timestamp column when touching the record" do @album.updated_at.should == nil @album.touch @album.updated_at.to_i.should be_within(2).of(Time.now.to_i) @@ -536,43 +555,46 @@ Item.first.stuff.should == Item.new end end describe "OptimisticLocking plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.create_table!(:people) do primary_key :id String :name Integer :lock_version, :default=>0, :null=>false end class ::Person < Sequel::Model(@db) plugin :optimistic_locking - create(:name=>'John') end end - after do + before do + @db[:people].delete + @p = Person.create(:name=>'John') + end + after(:all) do @db.drop_table(:people) Object.send(:remove_const, :Person) end specify "should raise an error when updating a stale record" do - p1 = Person[1] - p2 = Person[1] + p1 = Person[@p.id] + p2 = Person[@p.id] p1.update(:name=>'Jim') proc{p2.update(:name=>'Bob')}.should raise_error(Sequel::Plugins::OptimisticLocking::Error) end specify "should raise an error when destroying a stale record" do - p1 = Person[1] - p2 = Person[1] + p1 = Person[@p.id] + p2 = Person[@p.id] p1.update(:name=>'Jim') proc{p2.destroy}.should raise_error(Sequel::Plugins::OptimisticLocking::Error) end specify "should not raise an error when updating the same record twice" do - p1 = Person[1] + p1 = Person[@p.id] p1.update(:name=>'Jim') proc{p1.update(:name=>'Bob')}.should_not raise_error end end @@ -628,38 +650,42 @@ @e2.day.should == 2 end end # DB2's implemention of CTE is too limited to use this plugin -if INTEGRATION_DB.dataset.supports_cte? and INTEGRATION_DB.database_type != :db2 +if INTEGRATION_DB.dataset.supports_cte? and !Sequel.guarded?(:db2) describe "RcteTree Plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.create_table!(:nodes) do primary_key :id Integer :parent_id String :name end class ::Node < Sequel::Model(@db) plugin :rcte_tree, :order=>:name end - @a = Node.create(:name=>'a') - @b = Node.create(:name=>'b') - @aa = Node.create(:name=>'aa', :parent=>@a) - @ab = Node.create(:name=>'ab', :parent=>@a) - @ba = Node.create(:name=>'ba', :parent=>@b) - @bb = Node.create(:name=>'bb', :parent=>@b) - @aaa = Node.create(:name=>'aaa', :parent=>@aa) - @aab = Node.create(:name=>'aab', :parent=>@aa) - @aba = Node.create(:name=>'aba', :parent=>@ab) - @abb = Node.create(:name=>'abb', :parent=>@ab) - @aaaa = Node.create(:name=>'aaaa', :parent=>@aaa) - @aaab = Node.create(:name=>'aaab', :parent=>@aaa) - @aaaaa = Node.create(:name=>'aaaaa', :parent=>@aaaa) + @nodes = [] + @nodes << @a = Node.create(:name=>'a') + @nodes << @b = Node.create(:name=>'b') + @nodes << @aa = Node.create(:name=>'aa', :parent=>@a) + @nodes << @ab = Node.create(:name=>'ab', :parent=>@a) + @nodes << @ba = Node.create(:name=>'ba', :parent=>@b) + @nodes << @bb = Node.create(:name=>'bb', :parent=>@b) + @nodes << @aaa = Node.create(:name=>'aaa', :parent=>@aa) + @nodes << @aab = Node.create(:name=>'aab', :parent=>@aa) + @nodes << @aba = Node.create(:name=>'aba', :parent=>@ab) + @nodes << @abb = Node.create(:name=>'abb', :parent=>@ab) + @nodes << @aaaa = Node.create(:name=>'aaaa', :parent=>@aaa) + @nodes << @aaab = Node.create(:name=>'aaab', :parent=>@aaa) + @nodes << @aaaaa = Node.create(:name=>'aaaaa', :parent=>@aaaa) end - after do + before do + @nodes.each{|n| n.associations.clear} + end + after(:all) do @db.drop_table :nodes Object.send(:remove_const, :Node) end specify "should load all standard (not-CTE) methods correctly" do @@ -732,17 +758,19 @@ nodes[1].ancestors.should == [@a, @aa] nodes[2].ancestors.should == [] end specify "should work correctly if not all columns are selected" do - Node.plugin :lazy_attributes, :name - @aaaa.descendants.should == [Node.load(:parent_id=>11, :id=>13)] - @aa.ancestors.should == [Node.load(:parent_id=>nil, :id=>1)] - nodes = Node.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:ancestors, :descendants).all - nodes.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>3, :id=>7}, {:parent_id=>nil, :id=>2}].map{|x| Node.load(x)} - nodes[2].descendants.should == [{:parent_id=>2, :id=>5}, {:parent_id=>2, :id=>6}].map{|x| Node.load(x)} - nodes[1].ancestors.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>1, :id=>3}].map{|x| Node.load(x)} + c = Class.new(Sequel::Model(@db[:nodes])) + c.plugin :rcte_tree, :order=>:name + c.plugin :lazy_attributes, :name + c[:name=>'aaaa'].descendants.should == [c.load(:parent_id=>11, :id=>13)] + c[:name=>'aa'].ancestors.should == [c.load(:parent_id=>nil, :id=>1)] + nodes = c.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:ancestors, :descendants).all + nodes.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>3, :id=>7}, {:parent_id=>nil, :id=>2}].map{|x| c.load(x)} + nodes[2].descendants.should == [{:parent_id=>2, :id=>5}, {:parent_id=>2, :id=>6}].map{|x| c.load(x)} + nodes[1].ancestors.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>1, :id=>3}].map{|x| c.load(x)} end specify "should eagerly load descendants to a given level" do nodes = Node.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:descendants=>1).all nodes.should == [@a, @aaa, @b] @@ -856,26 +884,29 @@ end end end describe "Instance Filters plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.create_table!(:items) do primary_key :id String :name Integer :cost Integer :number end class ::Item < Sequel::Model(@db) plugin :instance_filters end + end + before do + @db[:items].delete @i = Item.create(:name=>'J', :number=>1, :cost=>2) @i.instance_filter(:number=>1) @i.set(:name=>'K') end - after do + after(:all) do @db.drop_table(:items) Object.send(:remove_const, :Item) end specify "should not raise an error if saving only updates one row" do @@ -916,24 +947,27 @@ proc{@i.destroy}.should raise_error(Sequel::Error) end end describe "UpdatePrimaryKey plugin" do - before do + before(:all) do @db = INTEGRATION_DB @db.create_table!(:t) do Integer :a, :primary_key=>true Integer :b end @ds = @db[:t] - @ds.insert(:a=>1, :b=>3) @c = Class.new(Sequel::Model(@ds)) @c.set_primary_key(:a) @c.unrestrict_primary_key @c.plugin :update_primary_key end - after do + before do + @ds.delete + @ds.insert(:a=>1, :b=>3) + end + after(:all) do @db.drop_table(:t) end specify "should handle regular updates" do @c.first.update(:b=>4) @@ -971,26 +1005,27 @@ @db[:t].all.should == [{:a=>2, :b=>5}] end end describe "AssociationPks plugin" do - before do + before(:all) do @db = INTEGRATION_DB - @db.create_table!(:artists) do + [:albums_tags, :tags, :albums, :artists].each{|t| @db.drop_table(t) if @db.table_exists?(t)} + @db.create_table(:artists) do primary_key :id String :name end - @db.create_table!(:albums) do + @db.create_table(:albums) do primary_key :id String :name foreign_key :artist_id, :artists end - @db.create_table!(:tags) do + @db.create_table(:tags) do primary_key :id String :name end - @db.create_table!(:albums_tags) do + @db.create_table(:albums_tags) do foreign_key :album_id, :albums foreign_key :tag_id, :tags end class ::Artist < Sequel::Model plugin :association_pks @@ -1000,11 +1035,13 @@ plugin :association_pks many_to_many :tags, :order=>:id end class ::Tag < Sequel::Model end - + end + before do + [:albums_tags, :tags, :albums, :artists].each{|t| @db[t].delete} @ar1 =@db[:artists].insert(:name=>'YJM') @ar2 =@db[:artists].insert(:name=>'AS') @al1 =@db[:albums].insert(:name=>'RF', :artist_id=>@ar1) @al2 =@db[:albums].insert(:name=>'MO', :artist_id=>@ar1) @al3 =@db[:albums].insert(:name=>'T', :artist_id=>@ar1) @@ -1013,11 +1050,11 @@ @t3 = @db[:tags].insert(:name=>'C') {@al1=>[@t1, @t2, @t3], @al2=>[@t2]}.each do |aid, tids| tids.each{|tid| @db[:albums_tags].insert([aid, tid])} end end - after do + after(:all) do @db.drop_table :albums_tags, :tags, :albums, :artists [:Artist, :Album, :Tag].each{|s| Object.send(:remove_const, s)} end specify "should return correct associated pks for one_to_many associations" do @@ -1067,27 +1104,28 @@ end end describe "List plugin without a scope" do - before do + before(:all) do @db = INTEGRATION_DB - @db.create_table :sites do + @db.create_table!(:sites) do primary_key :id String :name Integer :position end @c = Class.new(Sequel::Model(@db[:sites])) @c.plugin :list + end + before do @c.delete @c.create :name => "hig", :position => 3 @c.create :name => "def", :position => 2 @c.create :name => "abc", :position => 1 end - - after do + after(:all) do @db.drop_table(:sites) end it "should return rows in order of position" do @c.map(:position).should == [1,2,3] @@ -1140,30 +1178,32 @@ proc { @c[:name => "def"].move_down(10) }.should raise_error(Sequel::Error) end end describe "List plugin with a scope" do - before do + before(:all) do @db = INTEGRATION_DB - @db.create_table :pages do + @db.create_table!(:pages) do primary_key :id String :name Integer :pos Integer :parent_id end @c = Class.new(Sequel::Model(@db[:pages])) @c.plugin :list, :field => :pos, :scope => :parent_id + end + before do + @c.delete p1 = @c.create :name => "Hm", :pos => 1, :parent_id => 0 p2 = @c.create :name => "Ps", :pos => 1, :parent_id => p1.id @c.create :name => "P1", :pos => 1, :parent_id => p2.id @c.create :name => "P2", :pos => 2, :parent_id => p2.id @c.create :name => "P3", :pos => 3, :parent_id => p2.id @c.create :name => "Au", :pos => 2, :parent_id => p1.id end - - after do + after(:all) do @db.drop_table(:pages) end it "should return rows in order of position" do @c.map(:name).should == %w[ Hm Ps Au P1 P2 P3 ] @@ -1216,16 +1256,16 @@ proc { @c[:name => "P1"].move_down(10) }.should raise_error(Sequel::Error) end end describe "Sequel::Plugins::Tree" do - before do + before(:all) do @db = INTEGRATION_DB end describe "with natural database order" do - before do + before(:all) do @db.create_table!(:nodes) do Integer :id, :primary_key=>true String :name Integer :parent_id Integer :position @@ -1247,11 +1287,11 @@ class ::Node < Sequel::Model plugin :tree end end - after do + after(:all) do @db.drop_table(:nodes) Object.send(:remove_const, :Node) end it "should instantiate" do @@ -1322,16 +1362,16 @@ one.name.should == "one" one.children.map{|m| m[:position]}.should == [2, 1] end describe "Nodes in specified order" do - before do + before(:all) do class ::OrderedNode < Sequel::Model(:nodes) plugin :tree, :order => :position end end - after do + after(:all) do Object.send(:remove_const, :OrderedNode) end it "iterate top-level nodes in order by position" do OrderedNode.roots_dataset.count.should == 5 @@ -1345,11 +1385,11 @@ end end end describe "Lorems in specified order" do - before do + before(:all) do @db.create_table!(:lorems) do Integer :id, :primary_key=>true String :name Integer :ipsum_id Integer :neque @@ -1363,11 +1403,11 @@ class ::Lorem < Sequel::Model plugin :tree, :key => :ipsum_id, :order => :neque end end - after do + after(:all) do @db.drop_table(:lorems) Object.send(:remove_const, :Lorem) end it "iterate top-level nodes in order by position" do @@ -1381,43 +1421,50 @@ end end end describe "Sequel::Plugins::PreparedStatements" do - before do + before(:all) do @db = INTEGRATION_DB @db.create_table!(:ps_test) do primary_key :id String :name Integer :i end @c = Class.new(Sequel::Model(@db[:ps_test])) + @c.plugin :prepared_statements_with_pk + end + before do + @c.delete @foo = @c.create(:name=>'foo', :i=>10) @bar = @c.create(:name=>'bar', :i=>20) - @c.plugin :prepared_statements_with_pk end - after do + after(:all) do @db.drop_table(:ps_test) end it "should work with looking up using Model.[]" do @c[@foo.id].should == @foo @c[@bar.id].should == @bar @c[0].should == nil + @c[nil].should == nil end it "should work with looking up using Dataset#with_pk" do @c.dataset.with_pk(@foo.id).should == @foo @c.dataset.with_pk(@bar.id).should == @bar @c.dataset.with_pk(0).should == nil + @c.dataset.with_pk(nil).should == nil @c.dataset.filter(:i=>0).with_pk(@foo.id).should == nil @c.dataset.filter(:i=>10).with_pk(@foo.id).should == @foo @c.dataset.filter(:i=>20).with_pk(@bar.id).should == @bar + @c.dataset.filter(:i=>10).with_pk(nil).should == nil @c.dataset.filter(:name=>'foo').with_pk(@foo.id).should == @foo @c.dataset.filter(:name=>'bar').with_pk(@bar.id).should == @bar @c.dataset.filter(:name=>'baz').with_pk(@bar.id).should == nil + @c.dataset.filter(:name=>'bar').with_pk(nil).should == nil end it "should work with Model#destroy" do @foo.destroy @bar.destroy @@ -1430,16 +1477,20 @@ @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo2', :i=>30) @foo.update(:name=>'foo3') @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>30) @foo.update(:i=>40) @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>40) + @foo.update(:i=>nil) + @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>nil) end it "should work with Model#create" do o = @c.create(:name=>'foo2', :i=>30) @c[o.id].should == @c.load(:id=>o.id, :name=>'foo2', :i=>30) o = @c.create(:name=>'foo2') @c[o.id].should == @c.load(:id=>o.id, :name=>'foo2', :i=>nil) o = @c.create(:i=>30) @c[o.id].should == @c.load(:id=>o.id, :name=>nil, :i=>30) + o = @c.create(:name=>nil, :i=>40) + @c[o.id].should == @c.load(:id=>o.id, :name=>nil, :i=>40) end end