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
|
require_relative "spec_helper"
describe Sequel::Model::DatasetMethods, "#destroy" do
before do
@c = Class.new(Sequel::Model(:items)) do
self::Destroyed = []
def destroy
model::Destroyed << self
end
end
@d = @c.dataset
@d = @d.with_fetch([{:id=>1}, {:id=>2}])
DB.reset
end
it "should instantiate objects in the dataset and call destroy on each" do
@d.destroy
@c::Destroyed.collect{|x| x.values}.must_equal [{:id=>1}, {:id=>2}]
end
it "should return the number of records destroyed" do
@d.destroy.must_equal 2
@d = @d.with_fetch([[{:id=>1}], []])
@d.destroy.must_equal 1
@d.destroy.must_equal 0
end
it "should use a transaction if use_transactions is true for the model" do
@c.use_transactions = true
@d.destroy
DB.sqls.must_equal ["BEGIN", "SELECT * FROM items", "COMMIT"]
end
it "should not use a transaction if use_transactions is false for the model" do
@c.use_transactions = false
@d.destroy
DB.sqls.must_equal ["SELECT * FROM items"]
end
end
describe Sequel::Model::DatasetMethods, "#as_hash" do
before do
@c = Class.new(Sequel::Model(:items)) do
set_primary_key :name
end
@d = @c.dataset
end
it "should result in a hash with primary key value keys and model object values" do
@d = @d.with_fetch([{:name=>1}, {:name=>2}])
h = @d.as_hash
h.must_be_kind_of(Hash)
a = h.to_a
a.collect{|x| x[1].class}.must_equal [@c, @c]
a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.must_equal [[1, {:name=>1}], [2, {:name=>2}]]
end
it "should be aliased as to_hash" do
@d = @d.with_fetch([{:name=>1}, {:name=>2}])
h = @d.to_hash
h.must_be_kind_of(Hash)
a = h.to_a
a.collect{|x| x[1].class}.must_equal [@c, @c]
a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.must_equal [[1, {:name=>1}], [2, {:name=>2}]]
end
it "should result in a hash with given value keys and model object values" do
@d = @d.with_fetch([{:name=>1, :number=>3}, {:name=>2, :number=>4}])
h = @d.as_hash(:number)
h.must_be_kind_of(Hash)
a = h.to_a
a.collect{|x| x[1].class}.must_equal [@c, @c]
a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.must_equal [[3, {:name=>1, :number=>3}], [4, {:name=>2, :number=>4}]]
end
it "should raise an error if the class doesn't have a primary key" do
@c.no_primary_key
proc{@d.as_hash}.must_raise(Sequel::Error)
end
end
describe Sequel::Model::DatasetMethods do
before do
@c = Class.new(Sequel::Model(:items))
@c.columns :id
@c.db.reset
end
it "#first should handle no primary key" do
@c.no_primary_key
@c.first.must_be_kind_of(@c)
@c.db.sqls.must_equal ['SELECT * FROM items LIMIT 1']
end
it "#last should reverse order by primary key if not already ordered" do
@c.last.must_be_kind_of(@c)
@c.db.sqls.must_equal ['SELECT * FROM items ORDER BY id DESC LIMIT 1']
@c.where(:id=>2).last(:foo=>2){{bar=>3}}.must_be_kind_of(@c)
@c.db.sqls.must_equal ['SELECT * FROM items WHERE ((id = 2) AND (foo = 2) AND (bar = 3)) ORDER BY id DESC LIMIT 1']
end
it "#last should use existing order if there is one" do
@c.order(:foo).last.must_be_kind_of(@c)
@c.db.sqls.must_equal ['SELECT * FROM items ORDER BY foo DESC LIMIT 1']
end
it "#last should handle a composite primary key" do
@c.set_primary_key [:id1, :id2]
@c.last.must_be_kind_of(@c)
@c.db.sqls.must_equal ['SELECT * FROM items ORDER BY id1 DESC, id2 DESC LIMIT 1']
end
it "#last should raise an error if no primary key" do
@c.no_primary_key
proc{@c.last}.must_raise(Sequel::Error)
end
it "#paged_each should order by primary key if not already ordered" do
@c.paged_each{|r| r.must_be_kind_of(@c)}
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY id LIMIT 1000 OFFSET 0', 'COMMIT']
@c.paged_each(:rows_per_fetch=>5){|r|}
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY id LIMIT 5 OFFSET 0', 'COMMIT']
end
it "#paged_each should use existing order if there is one" do
@c.order(:foo).paged_each{|r| r.must_be_kind_of(@c)}
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY foo LIMIT 1000 OFFSET 0', 'COMMIT']
end
it "#paged_each should handle a composite primary key" do
@c.set_primary_key [:id1, :id2]
@c.paged_each{|r| r.must_be_kind_of(@c)}
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY id1, id2 LIMIT 1000 OFFSET 0', 'COMMIT']
end
it "#paged_each should raise an error if no primary key" do
@c.no_primary_key
proc{@c.paged_each{|r| }}.must_raise(Sequel::Error)
end
end
describe Sequel::Model::DatasetMethods, "#where_all" do
before do
@c = Class.new(Sequel::Model(DB[:items].freeze))
DB.reset
end
it "should filter dataset with condition, and return related rows" do
5.times do
@c.where_all(:id=>1).must_equal [@c.load(:id=>1, :x=>1)]
@c.db.sqls.must_equal ['SELECT * FROM items WHERE (id = 1)']
end
end
it "should yield each row to the given block" do
5.times do
a = []
@c.where_all(:id=>1){|r| a << r}.must_equal [@c.load(:id=>1, :x=>1)]
a.must_equal [@c.load(:id=>1, :x=>1)]
@c.db.sqls.must_equal ['SELECT * FROM items WHERE (id = 1)']
end
end
end
describe Sequel::Model::DatasetMethods, "#where_each" do
before do
@c = Class.new(Sequel::Model(DB[:items].freeze))
DB.reset
end
it "should yield each row to the given block" do
5.times do
a = []
@c.where_each(:id=>1){|r| a << r}
a.must_equal [@c.load(:id=>1, :x=>1)]
@c.db.sqls.must_equal ['SELECT * FROM items WHERE (id = 1)']
end
end
end
describe Sequel::Model::DatasetMethods, "#where_single_value" do
before do
@c = Class.new(Sequel::Model(DB[:items].freeze))
@c.class_eval do
dataset_module do
select :only_id, :id
end
end
DB.reset
end
it "should return single value" do
5.times do
@c.only_id.where_single_value(:id=>1).must_equal 1
@c.db.sqls.must_equal ['SELECT id FROM items WHERE (id = 1) LIMIT 1']
end
end
end
|