diff --git a/lib/data_mapper/validation/rule/numericalness.rb b/lib/data_mapper/validation/rule/numericalness.rb index 414e5c68..f69ac62a 100644 --- a/lib/data_mapper/validation/rule/numericalness.rb +++ b/lib/data_mapper/validation/rule/numericalness.rb @@ -28,6 +28,7 @@ def self.rules_for(attribute_name, options) lte = scour_options_of_keys(options, [:lte, :less_than_or_equal_to]) eq = scour_options_of_keys(options, [:eq, :equal, :equals, :exactly, :equal_to]) ne = scour_options_of_keys(options, [:ne, :not_equal_to]) + rules = [] rules << Integer.new(attribute_name, options) if int @@ -58,8 +59,11 @@ def valid?(resource) # if so, return a dummy validator when expected is nil return true if expected.nil? - value = resource.validation_property_value(attribute_name) + # Expected could be a Proc. + @expected = expected.call(resource) if expected.is_a?(Proc) + value = resource.validation_property_value(attribute_name) + optional?(value) || valid_numericalness?(value) end diff --git a/spec/fixtures/trip.rb b/spec/fixtures/trip.rb new file mode 100644 index 00000000..c7fe1d24 --- /dev/null +++ b/spec/fixtures/trip.rb @@ -0,0 +1,48 @@ + +# -*- coding: utf-8 -*- + +module DataMapper + module Validation + module Fixtures + class Trip + # + # Behaviors + # + + include DataMapper::Resource + + # + # Properties + # + + property :id, Serial + + without_auto_validations do + property :adults, Integer + property :infants, Integer + property :children, Integer + end + + # + # Validations + # + validates_numericality_of :adults, :gt => Proc.new { |s| s.min_adults }, :lt => Proc.new { |s| s.max_adults } + validates_numericality_of :children, :gte => Proc.new { |s| s.adults } + validates_numericality_of :infants, :lte => Proc.new { |s| s.adults } + + def min_adults; 0; end + def max_adults; 4; end + + def self.valid_instance(overrides = {}) + defaults = { + :adults => 2, + :children => 3, + :infants => 2 + } + + new(defaults.merge(overrides)) + end + end + end # Fixtures + end # Validations +end # DataMapper diff --git a/spec/integration/numeric_validator/gt_with_proc_spec.rb b/spec/integration/numeric_validator/gt_with_proc_spec.rb new file mode 100644 index 00000000..b5d7c75d --- /dev/null +++ b/spec/integration/numeric_validator/gt_with_proc_spec.rb @@ -0,0 +1,27 @@ + +require 'spec_helper' +require 'integration/numeric_validator/spec_helper' + +describe 'DataMapper::Validations::Fixtures::Trip' do + before :all do + DataMapper::Validations::Fixtures::Trip.auto_migrate! + @model = DataMapper::Validations::Fixtures::Trip.valid_instance + @model.valid? + end + + it_should_behave_like "valid model" + + + describe "when adults less than #min_adults" do + before :all do + @model.adults = 0 + @model.valid? + end + + it_should_behave_like "invalid model" + + it 'has a meaningful error message' do + @model.errors.on(:adults).should == ["Adults must be greater than #{@model.min_adults}"] + end + end +end diff --git a/spec/integration/numeric_validator/gte_with_proc_spec.rb b/spec/integration/numeric_validator/gte_with_proc_spec.rb new file mode 100644 index 00000000..69581145 --- /dev/null +++ b/spec/integration/numeric_validator/gte_with_proc_spec.rb @@ -0,0 +1,28 @@ + + +require 'spec_helper' +require 'integration/numeric_validator/spec_helper' + +describe 'DataMapper::Validations::Fixtures::Trip' do + before :all do + DataMapper::Validations::Fixtures::Trip.auto_migrate! + @model = DataMapper::Validations::Fixtures::Trip.valid_instance + @model.valid? + end + + it_should_behave_like "valid model" + + + describe "when child count less than adults" do + before :all do + @model.children = 1 + @model.valid? + end + + it_should_behave_like "invalid model" + + it 'has a meaningful error message' do + @model.errors.on(:children).should == ["Children must be greater than or equal to #{@model.adults}"] + end + end +end diff --git a/spec/integration/numeric_validator/lt_with_proc_spec.rb b/spec/integration/numeric_validator/lt_with_proc_spec.rb new file mode 100644 index 00000000..f3b92b3c --- /dev/null +++ b/spec/integration/numeric_validator/lt_with_proc_spec.rb @@ -0,0 +1,28 @@ + + +require 'spec_helper' +require 'integration/numeric_validator/spec_helper' + +describe 'DataMapper::Validations::Fixtures::Trip' do + before :all do + DataMapper::Validations::Fixtures::Trip.auto_migrate! + @model = DataMapper::Validations::Fixtures::Trip.valid_instance + @model.valid? + end + + it_should_behave_like "valid model" + + + describe "when adults greater than #max_adults" do + before :all do + @model.adults = 5 + @model.valid? + end + + it_should_behave_like "invalid model" + + it 'has a meaningful error message' do + @model.errors.on(:adults).should == ["Adults must be less than #{@model.max_adults}"] + end + end +end diff --git a/spec/integration/numeric_validator/lte_with_proc_spec.rb b/spec/integration/numeric_validator/lte_with_proc_spec.rb new file mode 100644 index 00000000..007f0f29 --- /dev/null +++ b/spec/integration/numeric_validator/lte_with_proc_spec.rb @@ -0,0 +1,29 @@ + + + +require 'spec_helper' +require 'integration/numeric_validator/spec_helper' + +describe 'DataMapper::Validations::Fixtures::Trip' do + before :all do + DataMapper::Validations::Fixtures::Trip.auto_migrate! + @model = DataMapper::Validations::Fixtures::Trip.valid_instance + @model.valid? + end + + it_should_behave_like "valid model" + + + describe "when infants greater than #adults" do + before :all do + @model.infants = 3 + @model.valid? + end + + it_should_behave_like "invalid model" + + it 'has a meaningful error message' do + @model.errors.on(:infants).should == ["Infants must be less than or equal to #{@model.adults}"] + end + end +end