validate_absence_of: cast `@attribute` to String

ActiveRecord.columns_hash returns Hash with String keys.
This is why `it { expect(offer).to validate_absence_of(:expired_at) }`
is not working.
This commit is contained in:
Alexey Blinov 2014-04-25 17:39:24 +04:00 committed by Elliot Winkler
parent c714193528
commit 165859247c
3 changed files with 39 additions and 7 deletions

View File

@ -24,6 +24,9 @@
the record had to be persisted in order for the matcher to work. Now this is
no longer the case and the record can remain unpersisted.
* Fix `validate_absence_of`: it required that a string be passed as the
attribute name rather than a symbol (which is the usual and documented usage).
### Improvements
* `have_and_belongs_to_many` now checks to make sure that the join table
@ -140,7 +143,7 @@
* Change `validate_uniqueness_of(...)` so that it provides default values for
non-nullable attributes.
* Running `rake` now installs Appraisals before running the test suite.
* Running `rake` now installs Appraisals before running the test suite.
(Additionally, we now manage Appraisals using the `appraisal` executable in
Appraisal 1.0.0.)

View File

@ -82,8 +82,10 @@ module Shoulda
else
obj
end
elsif attribute_class == Fixnum
elsif [Fixnum, Float].include?(attribute_class)
1
elsif attribute_class == BigDecimal
BigDecimal.new(1, 0)
elsif !attribute_class || attribute_class == String
'an arbitrary value'
else
@ -93,8 +95,8 @@ module Shoulda
def attribute_class
@subject.class.respond_to?(:columns_hash) &&
@subject.class.columns_hash[@attribute].respond_to?(:klass) &&
@subject.class.columns_hash[@attribute].klass
@subject.class.columns_hash[@attribute.to_s].respond_to?(:klass) &&
@subject.class.columns_hash[@attribute.to_s].klass
end
def collection?

View File

@ -2,6 +2,21 @@ require 'spec_helper'
describe Shoulda::Matchers::ActiveModel::ValidateAbsenceOfMatcher do
if active_model_4_0?
def self.available_column_types
[
:string,
:text,
:integer,
:float,
:decimal,
:datetime,
:timestamp,
:time,
:date,
:binary
]
end
context 'a model with an absence validation' do
it 'accepts' do
expect(validating_absence_of(:attr)).to validate_absence_of(:attr)
@ -10,6 +25,15 @@ describe Shoulda::Matchers::ActiveModel::ValidateAbsenceOfMatcher do
it 'does not override the default message with a present' do
expect(validating_absence_of(:attr)).to validate_absence_of(:attr).with_message(nil)
end
available_column_types.each do |type|
context "when column is of type #{type}" do
it "accepts" do
expect(validating_absence_of(:attr, {}, type: type)).
to validate_absence_of(:attr)
end
end
end
end
context 'a model without an absence validation' do
@ -95,9 +119,12 @@ describe Shoulda::Matchers::ActiveModel::ValidateAbsenceOfMatcher do
end
end
def validating_absence_of(attr, options = {})
define_model :example, attr => :string do
validates_absence_of attr, options
def validating_absence_of(attr, validation_options = {}, given_column_options = {})
default_column_options = { type: :string, options: {} }
column_options = default_column_options.merge(given_column_options)
define_model :example, attr => column_options do
validates_absence_of attr, validation_options
end.new
end