require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper") describe Sequel::Model::Errors do before do @errors = Sequel::Model::Errors.new end specify "should be clearable using #clear" do @errors.add(:a, 'b') @errors.should == {:a=>['b']} @errors.clear @errors.should == {} end specify "should be empty if there are no errors" do @errors.should be_empty end specify "should not be empty if there are errors" do @errors.add(:blah, "blah") @errors.should_not be_empty end specify "should return an array of errors for a specific attribute using #on if there are errors" do @errors.add(:blah, 'blah') @errors.on(:blah).should == ['blah'] end specify "should return nil using #on if there are no errors for that attribute" do @errors.on(:blah).should == nil end specify "should accept errors using #add" do @errors.add :blah, 'zzzz' @errors[:blah].should == ['zzzz'] end specify "should return full messages using #full_messages" do @errors.full_messages.should == [] @errors.add(:blow, 'blieuh') @errors.add(:blow, 'blich') @errors.add(:blay, 'bliu') msgs = @errors.full_messages msgs.size.should == 3 msgs.should include('blow blieuh', 'blow blich', 'blay bliu') end specify "should not add column names for LiteralStrings" do @errors.full_messages.should == [] @errors.add(:blow, 'blieuh') @errors.add(:blow, Sequel.lit('blich')) @errors.add(:blay, 'bliu') msgs = @errors.full_messages msgs.size.should == 3 msgs.should include('blow blieuh', 'blich', 'blay bliu') end specify "should return the number of error messages using #count" do @errors.count.should == 0 @errors.add(:a, 'b') @errors.count.should == 1 @errors.add(:a, 'c') @errors.count.should == 2 @errors.add(:b, 'c') @errors.count.should == 3 end specify "should return the array of error messages for a given attribute using #on" do @errors.add(:a, 'b') @errors.on(:a).should == ['b'] @errors.add(:a, 'c') @errors.on(:a).should == ['b', 'c'] @errors.add(:b, 'c') @errors.on(:a).should == ['b', 'c'] end specify "should return nil if there are no error messages for a given attribute using #on" do @errors.on(:a).should == nil @errors.add(:b, 'b') @errors.on(:a).should == nil end end describe Sequel::Model do before do @c = Class.new(Sequel::Model) do columns :score def validate errors.add(:score, 'too low') if score < 87 end end @o = @c.new end specify "should supply a #valid? method that returns true if validations pass" do @o.score = 50 @o.should_not be_valid @o.score = 100 @o.should be_valid end specify "should provide an errors object" do @o.score = 100 @o.should be_valid @o.errors.should be_empty @o.score = 86 @o.should_not be_valid @o.errors[:score].should == ['too low'] @o.errors.on(:blah).should be_nil end specify "should allow raising of ValidationFailed with a Model instance with errors" do @o.errors.add(:score, 'is too low') begin raise Sequel::ValidationFailed, @o rescue Sequel::ValidationFailed => e end e.model.should equal(@o) e.errors.should equal(@o.errors) e.message.should == 'score is too low' end specify "should allow raising of ValidationFailed with an Errors instance" do @o.errors.add(:score, 'is too low') begin raise Sequel::ValidationFailed, @o.errors rescue Sequel::ValidationFailed => e end e.model.should be_nil e.errors.should equal(@o.errors) e.message.should == 'score is too low' end specify "should allow raising of ValidationFailed with a string" do proc{raise Sequel::ValidationFailed, "no reason"}.should raise_error(Sequel::ValidationFailed, "no reason") end end describe "Model#save" do before do @c = Class.new(Sequel::Model(:people)) do columns :id, :x def validate errors.add(:id, 'blah') unless x == 7 end end @m = @c.load(:id => 4, :x=>6) DB.reset end specify "should save only if validations pass" do @m.raise_on_save_failure = false @m.should_not be_valid @m.save DB.sqls.should be_empty @m.x = 7 @m.should be_valid @m.save.should_not be_false DB.sqls.should == ['UPDATE people SET x = 7 WHERE (id = 4)'] end specify "should skip validations if the :validate=>false option is used" do @m.raise_on_save_failure = false @m.should_not be_valid @m.save(:validate=>false) DB.sqls.should == ['UPDATE people SET x = 6 WHERE (id = 4)'] end specify "should raise error if validations fail and raise_on_save_failure is true" do proc{@m.save}.should(raise_error(Sequel::ValidationFailed) do |e| e.model.should equal(@m) e.errors.should equal(@m.errors) end) end specify "should raise error if validations fail and :raise_on_failure option is true" do @m.raise_on_save_failure = false proc{@m.save(:raise_on_failure => true)}.should raise_error(Sequel::ValidationFailed) end specify "should return nil if validations fail and raise_on_save_faiure is false" do @m.raise_on_save_failure = false @m.save.should == nil end end