require_relative "spec_helper" describe "Sequel::Plugins::DefaultsSetter" do before do @db = db = Sequel.mock def db.supports_schema_parsing?() true end def db.schema(*) [] end @c = c = Class.new(Sequel::Model(db[:foo])) @c.instance_variable_set(:@db_schema, {:a=>{}}) @c.plugin :defaults_setter @c.columns :a @pr = proc{|x| db.define_singleton_method(:schema){|*| [[:id, {:primary_key=>true}], [:a, {:ruby_default => x, :primary_key=>false}]]}; c.dataset = c.dataset; c} end after do Sequel.datetime_class = Time end it "should set default value upon initialization" do @pr.call(2).new.a.must_equal 2 end it "should not mark the column as modified" do @pr.call(2).new.changed_columns.must_equal [] end it "should not set a default of nil" do @pr.call(nil).new.class.default_values.must_equal({}) end it "should set a default of false" do @pr.call(false).new.a.must_equal false end it "should handle Sequel::CURRENT_DATE default by using the current Date" do @pr.call(Sequel::CURRENT_DATE).new.a.must_equal Date.today end it "should handle Sequel::CURRENT_TIMESTAMP default by using the current Time" do t = @pr.call(Sequel::CURRENT_TIMESTAMP).new.a t.must_be_kind_of(Time) (t - Time.now).must_be :<, 1 end it "should handle :callable_default values in schema in preference to :ruby_default" do @db.define_singleton_method(:schema) do |*| [[:id, {:primary_key=>true}], [:a, {:ruby_default => Time.now, :callable_default=>lambda{Date.today}, :primary_key=>false}]] end @c.dataset = @c.dataset @c.new.a.must_equal Date.today end it "should handle Sequel::CURRENT_TIMESTAMP default by using the current DateTime if Sequel.datetime_class is DateTime" do Sequel.datetime_class = DateTime t = @pr.call(Sequel::CURRENT_TIMESTAMP).new.a t.must_be_kind_of(DateTime) (t - DateTime.now).must_be :<, 1/86400.0 end it "should work correctly with the current_datetime_timestamp extension" do @db.autoid = 1 @db.fetch = {:id=>1} @c.dataset = @c.dataset.extension(:current_datetime_timestamp) c = @pr.call(Sequel::CURRENT_TIMESTAMP) @db.sqls o = c.new o.a = o.a o.save @db.sqls.must_equal ["INSERT INTO foo (a) VALUES (CURRENT_TIMESTAMP)", "SELECT * FROM foo WHERE id = 1"] end it "should cache default values if :cache plugin option is used" do @c.plugin :defaults_setter, :cache => true @c.default_values[:a] = 'a' o = @c.new o.a.must_equal 'a' o.values[:a].must_equal 'a' o.a.must_be_same_as(o.a) end it "should not override a given value" do @pr.call(2) @c.new('a'=>3).a.must_equal 3 @c.new('a'=>nil).a.must_be_nil end it "should work correctly when subclassing" do Class.new(@pr.call(2)).new.a.must_equal 2 end it "should contain the default values in default_values" do @pr.call(2).default_values.must_equal(:a=>2) @c.default_values.clear @pr.call(nil).default_values.must_equal({}) end it "should allow modifications of default values" do @pr.call(2) @c.default_values[:a] = 3 @c.new.a.must_equal 3 end it "should allow proc default values" do @pr.call(2) @c.default_values[:a] = proc{3} @c.new.a.must_equal 3 end it "should have procs that set default values set them to nil" do @pr.call(2) @c.default_values[:a] = proc{nil} @c.new.a.must_be_nil end it "should work in subclasses" do @pr.call(2) @c.default_values[:a] = proc{1} c = Class.new(@c) @c.new.a.must_equal 1 c.new.a.must_equal 1 c.default_values[:a] = proc{2} @c.new.a.must_equal 1 c.new.a.must_equal 2 end it "should work correctly on a model without a dataset" do @pr.call(2) c = Class.new(Sequel::Model(@db[:bar])) c.plugin :defaults_setter c.default_values.must_equal(:a=>2) end it "should freeze default values when freezing model class" do c = Class.new(Sequel::Model(@db[:bar])) c.plugin :defaults_setter c.freeze c.default_values.frozen?.must_equal true end end