spec/integration/plugin_test.rb in sequel-3.12.1 vs spec/integration/plugin_test.rb in sequel-3.13.0
- old
+ new
@@ -1,6 +1,6 @@
-require File.join(File.dirname(__FILE__), 'spec_helper.rb')
+require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
# H2 and MSSQL don't support USING joins
unless [:h2, :mssql].include?(INTEGRATION_DB.database_type)
describe "Class Table Inheritance Plugin" do
before do
@@ -958,7 +958,322 @@
@db[:albums_tags].filter(:album_id=>@al3).select_order_map(:tag_id).should == []
Album[@al3].tag_pks = [@t1, @t3]
@db[:albums_tags].filter(:album_id=>@al3).select_order_map(:tag_id).should == [@t1, @t3]
Album[@al3].tag_pks = []
@db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).should == []
+ end
+end
+
+
+describe "List plugin without a scope" do
+ before do
+ @db = INTEGRATION_DB
+ @db.create_table :sites do
+ primary_key :id
+ String :name
+ Integer :position
+ end
+
+ @c = Class.new(Sequel::Model(@db[:sites]))
+ @c.plugin :list
+ @c.delete
+ @c.create :name => "hig", :position => 3
+ @c.create :name => "def", :position => 2
+ @c.create :name => "abc", :position => 1
+ end
+
+ after do
+ @db.drop_table(:sites)
+ end
+
+ it "should return rows in order of position" do
+ @c.map(:position).should == [1,2,3]
+ @c.map(:name).should == %w[ abc def hig ]
+ end
+
+ it "should define prev and next" do
+ i = @c[:name => "abc"]
+ i.prev.should == nil
+ i = @c[:name => "def"]
+ i.prev.should == @c[:name => "abc"]
+ i.next.should == @c[:name => "hig"]
+ i = @c[:name => "hig"]
+ i.next.should == nil
+ end
+
+ it "should define move_to" do
+ @c[:name => "def"].move_to(1)
+ @c.map(:name).should == %w[ def abc hig ]
+
+ @c[:name => "abc"].move_to(3)
+ @c.map(:name).should == %w[ def hig abc ]
+
+ proc { @c[:name => "abc"].move_to(-1) }.should raise_error(Sequel::Error)
+ proc { @c[:name => "abc"].move_to(10) }.should raise_error(Sequel::Error)
+ end
+
+ it "should define move_to_top and move_to_bottom" do
+ @c[:name => "def"].move_to_top
+ @c.map(:name).should == %w[ def abc hig ]
+
+ @c[:name => "def"].move_to_bottom
+ @c.map(:name).should == %w[ abc hig def ]
+ end
+
+ it "should define move_up and move_down" do
+ @c[:name => "def"].move_up
+ @c.map(:name).should == %w[ def abc hig ]
+
+ @c[:name => "abc"].move_down
+ @c.map(:name).should == %w[ def hig abc ]
+
+ @c[:name => "abc"].move_up(2)
+ @c.map(:name).should == %w[ abc def hig ]
+
+ @c[:name => "abc"].move_down(2)
+ @c.map(:name).should == %w[ def hig abc ]
+
+ proc { @c[:name => "def"].move_up(10) }.should raise_error(Sequel::Error)
+ proc { @c[:name => "def"].move_down(10) }.should raise_error(Sequel::Error)
+ end
+end
+
+describe "List plugin with a scope" do
+ before do
+ @db = INTEGRATION_DB
+ @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
+ 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
+ @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 ]
+ end
+
+ it "should define prev and next" do
+ @c[:name => "Ps"].next.name.should == 'Au'
+ @c[:name => "Au"].prev.name.should == 'Ps'
+ @c[:name => "P1"].next.name.should == 'P2'
+ @c[:name => "P2"].prev.name.should == 'P1'
+
+ @c[:name => "P1"].next(2).name.should == 'P3'
+ @c[:name => "P2"].next(-1).name.should == 'P1'
+ @c[:name => "P3"].prev(2).name.should == 'P1'
+ @c[:name => "P2"].prev(-1).name.should == 'P3'
+
+ @c[:name => "Ps"].prev.should == nil
+ @c[:name => "Au"].next.should == nil
+ @c[:name => "P1"].prev.should == nil
+ @c[:name => "P3"].next.should == nil
+ end
+
+ it "should define move_to" do
+ @c[:name => "P2"].move_to(1)
+ @c.map(:name).should == %w[ Hm Ps Au P2 P1 P3 ]
+
+ @c[:name => "P2"].move_to(3)
+ @c.map(:name).should == %w[ Hm Ps Au P1 P3 P2 ]
+
+ proc { @c[:name => "P2"].move_to(-1) }.should raise_error(Sequel::Error)
+ proc { @c[:name => "P2"].move_to(10) }.should raise_error(Sequel::Error)
+ end
+
+ it "should define move_to_top and move_to_bottom" do
+ @c[:name => "Au"].move_to_top
+ @c.map(:name).should == %w[ Hm Au Ps P1 P2 P3 ]
+
+ @c[:name => "Au"].move_to_bottom
+ @c.map(:name).should == %w[ Hm Ps Au P1 P2 P3 ]
+ end
+
+ it "should define move_up and move_down" do
+ @c[:name => "P2"].move_up
+ @c.map(:name).should == %w[ Hm Ps Au P2 P1 P3 ]
+
+ @c[:name => "P1"].move_down
+ @c.map(:name).should == %w[ Hm Ps Au P2 P3 P1 ]
+
+ proc { @c[:name => "P1"].move_up(10) }.should raise_error(Sequel::Error)
+ proc { @c[:name => "P1"].move_down(10) }.should raise_error(Sequel::Error)
+ end
+end
+
+describe "Sequel::Plugins::Tree" do
+ before do
+ @db = INTEGRATION_DB
+ end
+
+ describe "with natural database order" do
+ before do
+ @db.create_table!(:nodes) do
+ Integer :id, :primary_key=>true
+ String :name
+ Integer :parent_id
+ Integer :position
+ end
+
+ @nodes = [{:id => 1, :name => 'one', :parent_id => nil, :position => 1},
+ {:id => 2, :name => 'two', :parent_id => nil, :position => 2},
+ {:id => 3, :name => 'three', :parent_id => nil, :position => 3},
+ {:id => 4, :name => "two.one", :parent_id => 2, :position => 1},
+ {:id => 5, :name => "two.two", :parent_id => 2, :position => 2},
+ {:id => 6, :name => "two.two.one", :parent_id => 5, :position => 1},
+ {:id => 7, :name => "one.two", :parent_id => 1, :position => 2},
+ {:id => 8, :name => "one.one", :parent_id => 1, :position => 1},
+ {:id => 9, :name => "five", :parent_id => nil, :position => 5},
+ {:id => 10, :name => "four", :parent_id => nil, :position => 4},
+ {:id => 11, :name => "five.one", :parent_id => 9, :position => 1},
+ {:id => 12, :name => "two.three", :parent_id => 2, :position => 3}]
+ @nodes.each{|node| @db[:nodes].insert(node)}
+
+ class ::Node < Sequel::Model
+ plugin :tree
+ end
+ end
+ after do
+ @db.drop_table(:nodes)
+ Object.send(:remove_const, :Node)
+ end
+
+ it "should instantiate" do
+ Node.all.size.should == 12
+ end
+
+ it "should find top level nodes" do
+ Node.roots_dataset.count.should == 5
+ end
+
+ it "should find all descendants of a node" do
+ two = Node.find(:id => 2)
+ two.name.should == "two"
+ two.descendants.map{|m| m[:id]}.should == [4, 5, 12, 6]
+ end
+
+ it "should find all ancestors of a node" do
+ twotwoone = Node.find(:id => 6)
+ twotwoone.name.should == "two.two.one"
+ twotwoone.ancestors.map{|m| m[:id]}.should == [5, 2]
+ end
+
+ it "should find all siblings of a node, excepting self" do
+ twoone = Node.find(:id => 4)
+ twoone.name.should == "two.one"
+ twoone.siblings.map{|m| m[:id]}.should == [5, 12]
+ end
+
+ it "should find all siblings of a node, including self" do
+ twoone = Node.find(:id => 4)
+ twoone.name.should == "two.one"
+ twoone.self_and_siblings.map{|m| m[:id]}.should == [4, 5, 12]
+ end
+
+ it "should find siblings for root nodes" do
+ three = Node.find(:id => 3)
+ three.name.should == "three"
+ three.self_and_siblings.map{|m| m[:id]}.should == [1, 2, 3, 9, 10]
+ end
+
+ it "should find correct root for a node" do
+ twotwoone = Node.find(:id => 6)
+ twotwoone.name.should == "two.two.one"
+ twotwoone.root[:id].should == 2
+
+ three = Node.find(:id => 3)
+ three.name.should == "three"
+ three.root[:id].should == 3
+
+ fiveone = Node.find(:id => 11)
+ fiveone.name.should == "five.one"
+ fiveone.root[:id].should == 9
+ end
+
+ it "iterate top-level nodes in natural database order" do
+ Node.roots_dataset.count.should == 5
+ Node.roots.inject([]){|ids, p| ids << p.position}.should == [1, 2, 3, 5, 4]
+ end
+
+ it "should have children" do
+ one = Node.find(:id => 1)
+ one.name.should == "one"
+ one.children.size.should == 2
+ end
+
+ it "children should be natural database order" do
+ one = Node.find(:id => 1)
+ one.name.should == "one"
+ one.children.map{|m| m[:position]}.should == [2, 1]
+ end
+
+ describe "Nodes in specified order" do
+ before do
+ class ::OrderedNode < Sequel::Model(:nodes)
+ plugin :tree, :order => :position
+ end
+ end
+ after do
+ Object.send(:remove_const, :OrderedNode)
+ end
+
+ it "iterate top-level nodes in order by position" do
+ OrderedNode.roots_dataset.count.should == 5
+ OrderedNode.roots.inject([]){|ids, p| ids << p.position}.should == [1, 2, 3, 4, 5]
+ end
+
+ it "children should be in specified order" do
+ one = OrderedNode.find(:id => 1)
+ one.name.should == "one"
+ one.children.map{|m| m[:position]}.should == [1, 2]
+ end
+ end
+ end
+
+ describe "Lorems in specified order" do
+ before do
+ @db.create_table!(:lorems) do
+ Integer :id, :primary_key=>true
+ String :name
+ Integer :ipsum_id
+ Integer :neque
+ end
+
+ @lorems = [{:id => 1, :name => 'Lorem', :ipsum_id => nil, :neque => 4},
+ {:id => 2, :name => 'Ipsum', :ipsum_id => nil, :neque => 3},
+ {:id => 4, :name => "Neque", :ipsum_id => 2, :neque => 2},
+ {:id => 5, :name => "Porro", :ipsum_id => 2, :neque => 1}]
+ @lorems.each{|lorem| @db[:lorems].insert(lorem)}
+
+ class ::Lorem < Sequel::Model
+ plugin :tree, :key => :ipsum_id, :order => :neque
+ end
+ end
+ after do
+ @db.drop_table(:lorems)
+ Object.send(:remove_const, :Lorem)
+ end
+
+ it "iterate top-level nodes in order by position" do
+ Lorem.roots_dataset.count.should == 2
+ Lorem.roots.inject([]){|ids, p| ids << p.neque}.should == [3, 4]
+ end
+
+ it "children should be specified order" do
+ one = Lorem.find(:id => 2)
+ one.children.map{|m| m[:neque]}.should == [1, 2]
+ end
end
end