5 require 'models/person'
6 require 'models/developer'
7 require 'models/warehouse_thing'
10 # The following methods in Topic are used in test_conditional_validation_*
12 has_many
:unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
13 has_many
:silly_unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
19 def condition_is_true_but_its_not
24 class ProtectedPerson
< ActiveRecord
::Base
25 set_table_name
'people'
27 attr_protected
:first_name
30 class UniqueReply
< Reply
31 validates_uniqueness_of
:content, :scope => 'parent_id'
34 class PlagiarizedReply
< Reply
35 validates_acceptance_of
:author_name
38 class SillyUniqueReply
< UniqueReply
41 class Wizard
< ActiveRecord
::Base
42 self.abstract_class
= true
44 validates_uniqueness_of
:name
47 class IneptWizard
< Wizard
48 validates_uniqueness_of
:city
51 class Conjurer
< IneptWizard
54 class Thaumaturgist
< IneptWizard
58 class ValidationsTest
< ActiveRecord
::TestCase
59 fixtures
:topics, :developers, 'warehouse-things'
62 Topic
.instance_variable_set("@validate_callbacks", ActiveSupport
::Callbacks::CallbackChain.new
)
63 Topic
.instance_variable_set("@validate_on_create_callbacks", ActiveSupport
::Callbacks::CallbackChain.new
)
64 Topic
.instance_variable_set("@validate_on_update_callbacks", ActiveSupport
::Callbacks::CallbackChain.new
)
67 def test_single_field_validation
69 r
.title
= "There's no content!"
70 assert
!r
.valid
?, "A reply without content shouldn't be saveable"
72 r
.content
= "Messa content!"
73 assert r
.valid
?, "A reply with content should be saveable"
76 def test_single_attr_validation_and_error_msg
78 r
.title
= "There's no content!"
80 assert r
.errors
.invalid
?("content"), "A reply without content should mark that attribute as invalid"
81 assert_equal
"Empty", r
.errors
.on("content"), "A reply without content should contain an error"
82 assert_equal
1, r
.errors
.count
85 def test_double_attr_validation_and_error_msg
89 assert r
.errors
.invalid
?("title"), "A reply without title should mark that attribute as invalid"
90 assert_equal
"Empty", r
.errors
.on("title"), "A reply without title should contain an error"
92 assert r
.errors
.invalid
?("content"), "A reply without content should mark that attribute as invalid"
93 assert_equal
"Empty", r
.errors
.on("content"), "A reply without content should contain an error"
95 assert_equal
2, r
.errors
.count
98 def test_error_on_create
100 r
.title
= "Wrong Create"
102 assert r
.errors
.invalid
?("title"), "A reply with a bad title should mark that attribute as invalid"
103 assert_equal
"is Wrong Create", r
.errors
.on("title"), "A reply with a bad content should contain an error"
106 def test_error_on_update
110 assert r
.save
, "First save should be successful"
112 r
.title
= "Wrong Update"
113 assert
!r
.save
, "Second save should fail"
115 assert r
.errors
.invalid
?("title"), "A reply with a bad title should mark that attribute as invalid"
116 assert_equal
"is Wrong Update", r
.errors
.on("title"), "A reply with a bad content should contain an error"
119 def test_invalid_record_exception
120 assert_raises(ActiveRecord
::RecordInvalid) { Reply
.create
! }
121 assert_raises(ActiveRecord
::RecordInvalid) { Reply
.new
.save
! }
127 rescue ActiveRecord
::RecordInvalid => invalid
128 assert_equal r
, invalid
.record
132 def test_exception_on_create_bang_many
133 assert_raises(ActiveRecord
::RecordInvalid) do
134 Reply
.create
!([ { "title" => "OK" }, { "title" => "Wrong Create" }])
138 def test_exception_on_create_bang_with_block
139 assert_raises(ActiveRecord
::RecordInvalid) do
140 Reply
.create
!({ "title" => "OK" }) do |r
|
146 def test_exception_on_create_bang_many_with_block
147 assert_raises(ActiveRecord
::RecordInvalid) do
148 Reply
.create
!([{ "title" => "OK" }, { "title" => "Wrong Create" }]) do |r
|
154 def test_scoped_create_without_attributes
155 Reply
.with_scope(:create => {}) do
156 assert_raises(ActiveRecord
::RecordInvalid) { Reply
.create
! }
160 def test_create_with_exceptions_using_scope_for_protected_attributes
161 assert_nothing_raised
do
162 ProtectedPerson
.with_scope( :create => { :first_name => "Mary" } ) do
163 person
= ProtectedPerson
.create
! :addon => "Addon"
164 assert_equal person
.first_name
, "Mary", "scope should ignore attr_protected"
169 def test_create_with_exceptions_using_scope_and_empty_attributes
170 assert_nothing_raised
do
171 ProtectedPerson
.with_scope( :create => { :first_name => "Mary" } ) do
172 person
= ProtectedPerson
.create
!
173 assert_equal person
.first_name
, "Mary", "should be ok when no attributes are passed to create!"
178 def test_single_error_per_attr_iteration
183 r
.errors
.each
{ |attr
, msg
| errors
<< [attr
, msg
] }
185 assert errors
.include?(["title", "Empty"])
186 assert errors
.include?(["content", "Empty"])
189 def test_multiple_errors_per_attr_iteration_with_full_error_composition
191 r
.title
= "Wrong Create"
192 r
.content
= "Mismatch"
196 r
.errors
.each_full
{ |error
| errors
<< error
}
198 assert_equal
"Title is Wrong Create", errors
[0]
199 assert_equal
"Title is Content Mismatch", errors
[1]
200 assert_equal
2, r
.errors
.count
203 def test_errors_on_base
205 r
.content
= "Mismatch"
207 r
.errors
.add_to_base
"Reply is not dignifying"
210 r
.errors
.each_full
{ |error
| errors
<< error
}
212 assert_equal
"Reply is not dignifying", r
.errors
.on_base
214 assert errors
.include?("Title Empty")
215 assert errors
.include?("Reply is not dignifying")
216 assert_equal
2, r
.errors
.count
219 def test_create_without_validation
222 assert reply
.save(false)
225 def test_create_without_validation_bang
227 assert_nothing_raised
{ Reply
.new
.save_without_validation
! }
228 assert count
+1, Reply
.count
231 def test_validates_each
234 Topic
.validates_each(:title, :content, [:title, :content]) do |record
, attr
|
236 record
.errors
.add attr
, 'gotcha'
240 t
= Topic
.new("title" => "valid", "content" => "whatever")
243 assert_equal
%w(gotcha gotcha
), t
.errors
.on(:title)
244 assert_equal
%w(gotcha gotcha
), t
.errors
.on(:content)
249 def test_no_title_confirmation
250 Topic
.validates_confirmation_of(:title)
252 t
= Topic
.new(:author_name => "Plutarch")
255 t
.title_confirmation
= "Parallel Lives"
258 t
.title_confirmation
= nil
259 t
.title
= "Parallel Lives"
262 t
.title_confirmation
= "Parallel Lives"
266 def test_title_confirmation
267 Topic
.validates_confirmation_of(:title)
269 t
= Topic
.create("title" => "We should be confirmed","title_confirmation" => "")
272 t
.title_confirmation
= "We should be confirmed"
276 def test_terms_of_service_agreement_no_acceptance
277 Topic
.validates_acceptance_of(:terms_of_service, :on => :create)
279 t
= Topic
.create("title" => "We should not be confirmed")
283 def test_terms_of_service_agreement
284 Topic
.validates_acceptance_of(:terms_of_service, :on => :create)
286 t
= Topic
.create("title" => "We should be confirmed","terms_of_service" => "")
288 assert_equal
"must be accepted", t
.errors
.on(:terms_of_service)
290 t
.terms_of_service
= "1"
296 Topic
.validates_acceptance_of(:eula, :message => "must be abided", :on => :create)
298 t
= Topic
.create("title" => "We should be confirmed","eula" => "")
300 assert_equal
"must be abided", t
.errors
.on(:eula)
306 def test_terms_of_service_agreement_with_accept_value
307 Topic
.validates_acceptance_of(:terms_of_service, :on => :create, :accept => "I agree.")
309 t
= Topic
.create("title" => "We should be confirmed", "terms_of_service" => "")
311 assert_equal
"must be accepted", t
.errors
.on(:terms_of_service)
313 t
.terms_of_service
= "I agree."
317 def test_validates_acceptance_of_as_database_column
318 reply
= PlagiarizedReply
.create("author_name" => "Dan Brown")
319 assert_equal
"Dan Brown", reply
["author_name"]
322 def test_validates_acceptance_of_with_non_existant_table
323 Object
.const_set
:IncorporealModel, Class
.new(ActiveRecord
::Base)
325 assert_nothing_raised ActiveRecord
::StatementInvalid do
326 IncorporealModel
.validates_acceptance_of(:incorporeal_column)
330 def test_validate_presences
331 Topic
.validates_presence_of(:title, :content)
335 assert_equal
"can't be blank", t
.errors
.on(:title)
336 assert_equal
"can't be blank", t
.errors
.on(:content)
338 t
.title
= "something"
342 assert_equal
"can't be blank", t
.errors
.on(:content)
344 t
.content
= "like stuff"
349 def test_validate_uniqueness
350 Topic
.validates_uniqueness_of(:title)
352 t
= Topic
.new("title" => "I'm unique!")
353 assert t
.save
, "Should save t as unique"
355 t
.content
= "Remaining unique"
356 assert t
.save
, "Should still save t as unique"
358 t2
= Topic
.new("title" => "I'm unique!")
359 assert
!t2
.valid
?, "Shouldn't be valid"
360 assert
!t2
.save
, "Shouldn't save t2 as unique"
361 assert_equal
"has already been taken", t2
.errors
.on(:title)
363 t2
.title
= "Now Im really also unique"
364 assert t2
.save
, "Should now save t2 as unique"
367 def test_validates_uniquness_with_newline_chars
368 Topic
.validates_uniqueness_of(:title, :case_sensitive => false)
370 t
= Topic
.new("title" => "new\nline")
371 assert t
.save
, "Should save t as unique"
374 def test_validate_uniqueness_with_scope
375 Reply
.validates_uniqueness_of(:content, :scope => "parent_id")
377 t
= Topic
.create("title" => "I'm unique!")
379 r1
= t
.replies
.create
"title" => "r1", "content" => "hello world"
380 assert r1
.valid
?, "Saving r1"
382 r2
= t
.replies
.create
"title" => "r2", "content" => "hello world"
383 assert
!r2
.valid
?, "Saving r2 first time"
385 r2
.content
= "something else"
386 assert r2
.save
, "Saving r2 second time"
388 t2
= Topic
.create("title" => "I'm unique too!")
389 r3
= t2
.replies
.create
"title" => "r3", "content" => "hello world"
390 assert r3
.valid
?, "Saving r3"
393 def test_validate_uniqueness_scoped_to_defining_class
394 t
= Topic
.create("title" => "What, me worry?")
396 r1
= t
.unique_replies
.create
"title" => "r1", "content" => "a barrel of fun"
397 assert r1
.valid
?, "Saving r1"
399 r2
= t
.silly_unique_replies
.create
"title" => "r2", "content" => "a barrel of fun"
400 assert
!r2
.valid
?, "Saving r2"
402 # Should succeed as validates_uniqueness_of only applies to
403 # UniqueReply and its subclasses
404 r3
= t
.replies
.create
"title" => "r2", "content" => "a barrel of fun"
405 assert r3
.valid
?, "Saving r3"
408 def test_validate_uniqueness_with_scope_array
409 Reply
.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
411 t
= Topic
.create("title" => "The earth is actually flat!")
413 r1
= t
.replies
.create
"author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply"
414 assert r1
.valid
?, "Saving r1"
416 r2
= t
.replies
.create
"author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..."
417 assert
!r2
.valid
?, "Saving r2. Double reply by same author."
419 r2
.author_email_address
= "jeremy_alt_email@rubyonrails.com"
420 assert r2
.save
, "Saving r2 the second time."
422 r3
= t
.replies
.create
"author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic"
423 assert
!r3
.valid
?, "Saving r3"
425 r3
.author_name
= "jj"
426 assert r3
.save
, "Saving r3 the second time."
428 r3
.author_name
= "jeremy"
429 assert
!r3
.save
, "Saving r3 the third time."
432 def test_validate_case_insensitive_uniqueness
433 Topic
.validates_uniqueness_of(:title, :parent_id, :case_sensitive => false, :allow_nil => true)
435 t
= Topic
.new("title" => "I'm unique!", :parent_id => 2)
436 assert t
.save
, "Should save t as unique"
438 t
.content
= "Remaining unique"
439 assert t
.save
, "Should still save t as unique"
441 t2
= Topic
.new("title" => "I'm UNIQUE!", :parent_id => 1)
442 assert
!t2
.valid
?, "Shouldn't be valid"
443 assert
!t2
.save
, "Shouldn't save t2 as unique"
444 assert t2
.errors
.on(:title)
445 assert t2
.errors
.on(:parent_id)
446 assert_equal
"has already been taken", t2
.errors
.on(:title)
448 t2
.title
= "I'm truly UNIQUE!"
449 assert
!t2
.valid
?, "Shouldn't be valid"
450 assert
!t2
.save
, "Shouldn't save t2 as unique"
451 assert_nil t2
.errors
.on(:title)
452 assert t2
.errors
.on(:parent_id)
455 assert t2
.save
, "Should now save t2 as unique"
459 assert t2
.valid
?, "should validate with nil"
460 assert t2
.save
, "should save with nil"
462 with_kcode('UTF8') do
463 t_utf8
= Topic
.new("title" => "Я тоже уникальный!")
464 assert t_utf8
.save
, "Should save t_utf8 as unique"
466 # If database hasn't UTF-8 character set, this test fails
467 if Topic
.find(t_utf8
, :select => 'LOWER(title) AS title').title
== "я тоже уникальный!"
468 t2_utf8
= Topic
.new("title" => "я тоже УНИКАЛЬНЫЙ!")
469 assert
!t2_utf8
.valid
?, "Shouldn't be valid"
470 assert
!t2_utf8
.save
, "Shouldn't save t2_utf8 as unique"
475 def test_validate_case_sensitive_uniqueness
476 Topic
.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true)
478 t
= Topic
.new("title" => "I'm unique!")
479 assert t
.save
, "Should save t as unique"
481 t
.content
= "Remaining unique"
482 assert t
.save
, "Should still save t as unique"
484 t2
= Topic
.new("title" => "I'M UNIQUE!")
485 assert t2
.valid
?, "Should be valid"
486 assert t2
.save
, "Should save t2 as unique"
487 assert
!t2
.errors
.on(:title)
488 assert
!t2
.errors
.on(:parent_id)
489 assert_not_equal
"has already been taken", t2
.errors
.on(:title)
491 t3
= Topic
.new("title" => "I'M uNiQUe!")
492 assert t3
.valid
?, "Should be valid"
493 assert t3
.save
, "Should save t2 as unique"
494 assert
!t3
.errors
.on(:title)
495 assert
!t3
.errors
.on(:parent_id)
496 assert_not_equal
"has already been taken", t3
.errors
.on(:title)
499 def test_validate_case_sensitive_uniqueness_with_attribute_passed_as_integer
500 Topic
.validates_uniqueness_of(:title, :case_sensitve => true)
501 t
= Topic
.create
!('title' => 101)
503 t2
= Topic
.new('title' => 101)
505 assert t2
.errors
.on(:title)
508 def test_validate_uniqueness_with_non_standard_table_names
509 i1
= WarehouseThing
.create(:value => 1000)
510 assert
!i1
.valid
?, "i1 should not be valid"
511 assert i1
.errors
.on(:value), "Should not be empty"
514 def test_validates_uniqueness_inside_with_scope
515 Topic
.validates_uniqueness_of(:title)
517 Topic
.with_scope(:find => { :conditions => { :author_name => "David" } }) do
518 t1
= Topic
.new("title" => "I'm unique!", "author_name" => "Mary")
520 t2
= Topic
.new("title" => "I'm unique!", "author_name" => "David")
525 def test_validate_uniqueness_with_columns_which_are_sql_keywords
526 Guid
.validates_uniqueness_of
:key
529 assert_nothing_raised
{ !g
.valid
? }
532 def test_validate_straight_inheritance_uniqueness
533 w1
= IneptWizard
.create(:name => "Rincewind", :city => "Ankh-Morpork")
534 assert w1
.valid
?, "Saving w1"
536 # Should use validation from base class (which is abstract)
537 w2
= IneptWizard
.new(:name => "Rincewind", :city => "Quirm")
538 assert
!w2
.valid
?, "w2 shouldn't be valid"
539 assert w2
.errors
.on(:name), "Should have errors for name"
540 assert_equal
"has already been taken", w2
.errors
.on(:name), "Should have uniqueness message for name"
542 w3
= Conjurer
.new(:name => "Rincewind", :city => "Quirm")
543 assert
!w3
.valid
?, "w3 shouldn't be valid"
544 assert w3
.errors
.on(:name), "Should have errors for name"
545 assert_equal
"has already been taken", w3
.errors
.on(:name), "Should have uniqueness message for name"
547 w4
= Conjurer
.create(:name => "The Amazing Bonko", :city => "Quirm")
548 assert w4
.valid
?, "Saving w4"
550 w5
= Thaumaturgist
.new(:name => "The Amazing Bonko", :city => "Lancre")
551 assert
!w5
.valid
?, "w5 shouldn't be valid"
552 assert w5
.errors
.on(:name), "Should have errors for name"
553 assert_equal
"has already been taken", w5
.errors
.on(:name), "Should have uniqueness message for name"
555 w6
= Thaumaturgist
.new(:name => "Mustrum Ridcully", :city => "Quirm")
556 assert
!w6
.valid
?, "w6 shouldn't be valid"
557 assert w6
.errors
.on(:city), "Should have errors for city"
558 assert_equal
"has already been taken", w6
.errors
.on(:city), "Should have uniqueness message for city"
561 def test_validate_format
562 Topic
.validates_format_of(:title, :content, :with => /^Validation\smacros \w+!$/, :message => "is bad data")
564 t
= Topic
.create("title" => "i'm incorrect", "content" => "Validation macros rule!")
565 assert
!t
.valid
?, "Shouldn't be valid"
566 assert
!t
.save
, "Shouldn't save because it's invalid"
567 assert_equal
"is bad data", t
.errors
.on(:title)
568 assert_nil t
.errors
.on(:content)
570 t
.title
= "Validation macros rule!"
573 assert_nil t
.errors
.on(:title)
575 assert_raise(ArgumentError
) { Topic
.validates_format_of(:title, :content) }
578 def test_validate_format_with_allow_blank
579 Topic
.validates_format_of(:title, :with => /^Validation\smacros \w+!$/, :allow_blank=>true)
580 assert
!Topic
.create("title" => "Shouldn't be valid").valid
?
581 assert Topic
.create("title" => "").valid
?
582 assert Topic
.create("title" => nil).valid
?
583 assert Topic
.create("title" => "Validation macros rule!").valid
?
586 # testing ticket #3142
587 def test_validate_format_numeric
588 Topic
.validates_format_of(:title, :content, :with => /^[1-9][0-9]*$/, :message => "is bad data")
590 t
= Topic
.create("title" => "72x", "content" => "6789")
591 assert
!t
.valid
?, "Shouldn't be valid"
592 assert
!t
.save
, "Shouldn't save because it's invalid"
593 assert_equal
"is bad data", t
.errors
.on(:title)
594 assert_nil t
.errors
.on(:content)
597 assert
!t
.valid
?, "Shouldn't be valid"
600 assert
!t
.valid
?, "Shouldn't be valid"
603 assert
!t
.valid
?, "Shouldn't be valid"
606 assert
!t
.valid
?, "Shouldn't be valid"
611 assert_nil t
.errors
.on(:title)
614 def test_validate_format_with_formatted_message
615 Topic
.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be {{value}}")
616 t
= Topic
.create(:title => 'Invalid title')
617 assert_equal
"can't be Invalid title", t
.errors
.on(:title)
620 def test_validates_inclusion_of
621 Topic
.validates_inclusion_of( :title, :in => %w( a b c d e f g
) )
623 assert
!Topic
.create("title" => "a!", "content" => "abc").valid
?
624 assert
!Topic
.create("title" => "a b", "content" => "abc").valid
?
625 assert
!Topic
.create("title" => nil, "content" => "def").valid
?
627 t
= Topic
.create("title" => "a", "content" => "I know you are but what am I?")
631 assert t
.errors
.on(:title)
632 assert_equal
"is not included in the list", t
.errors
["title"]
634 assert_raise(ArgumentError
) { Topic
.validates_inclusion_of( :title, :in => nil ) }
635 assert_raise(ArgumentError
) { Topic
.validates_inclusion_of( :title, :in => 0) }
637 assert_nothing_raised(ArgumentError
) { Topic
.validates_inclusion_of( :title, :in => "hi!" ) }
638 assert_nothing_raised(ArgumentError
) { Topic
.validates_inclusion_of( :title, :in => {} ) }
639 assert_nothing_raised(ArgumentError
) { Topic
.validates_inclusion_of( :title, :in => [] ) }
642 def test_validates_inclusion_of_with_allow_nil
643 Topic
.validates_inclusion_of( :title, :in => %w( a b c d e f g
), :allow_nil=>true )
645 assert
!Topic
.create("title" => "a!", "content" => "abc").valid
?
646 assert
!Topic
.create("title" => "", "content" => "abc").valid
?
647 assert Topic
.create("title" => nil, "content" => "abc").valid
?
650 def test_numericality_with_getter_method
651 Developer
.validates_numericality_of( :salary )
652 developer
= Developer
.new("name" => "michael", "salary" => nil)
653 developer
.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end")
654 assert developer
.valid
?
657 def test_validates_length_of_with_allow_nil
658 Topic
.validates_length_of( :title, :is => 5, :allow_nil=>true )
660 assert
!Topic
.create("title" => "ab").valid
?
661 assert
!Topic
.create("title" => "").valid
?
662 assert Topic
.create("title" => nil).valid
?
663 assert Topic
.create("title" => "abcde").valid
?
666 def test_validates_length_of_with_allow_blank
667 Topic
.validates_length_of( :title, :is => 5, :allow_blank=>true )
669 assert
!Topic
.create("title" => "ab").valid
?
670 assert Topic
.create("title" => "").valid
?
671 assert Topic
.create("title" => nil).valid
?
672 assert Topic
.create("title" => "abcde").valid
?
675 def test_validates_inclusion_of_with_formatted_message
676 Topic
.validates_inclusion_of( :title, :in => %w( a b c d e f g
), :message => "option {{value}} is not in the list" )
678 assert Topic
.create("title" => "a", "content" => "abc").valid
?
680 t
= Topic
.create("title" => "uhoh", "content" => "abc")
682 assert t
.errors
.on(:title)
683 assert_equal
"option uhoh is not in the list", t
.errors
["title"]
686 def test_numericality_with_allow_nil_and_getter_method
687 Developer
.validates_numericality_of( :salary, :allow_nil => true)
688 developer
= Developer
.new("name" => "michael", "salary" => nil)
689 developer
.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end")
690 assert developer
.valid
?
693 def test_validates_exclusion_of
694 Topic
.validates_exclusion_of( :title, :in => %w( abe monkey
) )
696 assert Topic
.create("title" => "something", "content" => "abc").valid
?
697 assert
!Topic
.create("title" => "monkey", "content" => "abc").valid
?
700 def test_validates_exclusion_of_with_formatted_message
701 Topic
.validates_exclusion_of( :title, :in => %w( abe monkey
), :message => "option {{value}} is restricted" )
703 assert Topic
.create("title" => "something", "content" => "abc")
705 t
= Topic
.create("title" => "monkey")
707 assert t
.errors
.on(:title)
708 assert_equal
"option monkey is restricted", t
.errors
["title"]
711 def test_validates_length_of_using_minimum
712 Topic
.validates_length_of
:title, :minimum => 5
714 t
= Topic
.create("title" => "valid", "content" => "whatever")
719 assert t
.errors
.on(:title)
720 assert_equal
"is too short (minimum is 5 characters)", t
.errors
["title"]
724 assert t
.errors
.on(:title)
725 assert_equal
"is too short (minimum is 5 characters)", t
.errors
["title"]
729 assert t
.errors
.on(:title)
730 assert_equal
"is too short (minimum is 5 characters)", t
.errors
["title"]
733 def test_optionally_validates_length_of_using_minimum
734 Topic
.validates_length_of
:title, :minimum => 5, :allow_nil => true
736 t
= Topic
.create("title" => "valid", "content" => "whatever")
743 def test_validates_length_of_using_maximum
744 Topic
.validates_length_of
:title, :maximum => 5
746 t
= Topic
.create("title" => "valid", "content" => "whatever")
751 assert t
.errors
.on(:title)
752 assert_equal
"is too long (maximum is 5 characters)", t
.errors
["title"]
761 def test_optionally_validates_length_of_using_maximum
762 Topic
.validates_length_of
:title, :maximum => 5, :allow_nil => true
764 t
= Topic
.create("title" => "valid", "content" => "whatever")
771 def test_validates_length_of_using_within
772 Topic
.validates_length_of(:title, :content, :within => 3..5)
774 t
= Topic
.new("title" => "a!", "content" => "I'm ooooooooh so very long")
776 assert_equal
"is too short (minimum is 3 characters)", t
.errors
.on(:title)
777 assert_equal
"is too long (maximum is 5 characters)", t
.errors
.on(:content)
782 assert_equal
"is too short (minimum is 3 characters)", t
.errors
.on(:title)
783 assert_equal
"is too short (minimum is 3 characters)", t
.errors
.on(:content)
790 def test_optionally_validates_length_of_using_within
791 Topic
.validates_length_of
:title, :content, :within => 3..5, :allow_nil => true
793 t
= Topic
.create('title' => 'abc', 'content' => 'abcd')
800 def test_optionally_validates_length_of_using_within_on_create
801 Topic
.validates_length_of
:title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: {{count}}"
803 t
= Topic
.create("title" => "thisisnotvalid", "content" => "whatever")
805 assert t
.errors
.on(:title)
806 assert_equal
"my string is too long: 10", t
.errors
[:title]
808 t
.title
= "butthisis"
814 t
.content
= "andthisislong"
817 t
.content
= t
.title
= "iamfine"
821 def test_optionally_validates_length_of_using_within_on_update
822 Topic
.validates_length_of
:title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: {{count}}"
824 t
= Topic
.create("title" => "vali", "content" => "whatever")
826 assert t
.errors
.on(:title)
830 assert t
.errors
.on(:title)
831 assert_equal
"my string is too short: 5", t
.errors
[:title]
834 t
.content
= "andthisistoolong"
836 assert t
.errors
.on(:content)
838 t
.content
= "iamfine"
842 def test_validates_length_of_using_is
843 Topic
.validates_length_of
:title, :is => 5
845 t
= Topic
.create("title" => "valid", "content" => "whatever")
850 assert t
.errors
.on(:title)
851 assert_equal
"is the wrong length (should be 5 characters)", t
.errors
["title"]
860 def test_optionally_validates_length_of_using_is
861 Topic
.validates_length_of
:title, :is => 5, :allow_nil => true
863 t
= Topic
.create("title" => "valid", "content" => "whatever")
870 def test_validates_length_of_using_bignum
873 bigrange
= bigmin
...bigmax
874 assert_nothing_raised
do
875 Topic
.validates_length_of
:title, :is => bigmin
+ 5
876 Topic
.validates_length_of
:title, :within => bigrange
877 Topic
.validates_length_of
:title, :in => bigrange
878 Topic
.validates_length_of
:title, :minimum => bigmin
879 Topic
.validates_length_of
:title, :maximum => bigmax
883 def test_validates_length_with_globally_modified_error_message
884 ActiveSupport
::Deprecation.silence
do
885 ActiveRecord
::Errors.default_error_messages
[:too_short] = 'tu est trops petit hombre {{count}}'
887 Topic
.validates_length_of
:title, :minimum => 10
888 t
= Topic
.create(:title => 'too short')
891 assert_equal
'tu est trops petit hombre 10', t
.errors
['title']
894 def test_validates_size_of_association
895 assert_nothing_raised
{ Topic
.validates_size_of
:replies, :minimum => 1 }
896 t
= Topic
.new('title' => 'noreplies', 'content' => 'whatever')
898 assert t
.errors
.on(:replies)
899 reply
= t
.replies
.build('title' => 'areply', 'content' => 'whateveragain')
903 def test_validates_size_of_association_using_within
904 assert_nothing_raised
{ Topic
.validates_size_of
:replies, :within => 1..2 }
905 t
= Topic
.new('title' => 'noreplies', 'content' => 'whatever')
907 assert t
.errors
.on(:replies)
909 reply
= t
.replies
.build('title' => 'areply', 'content' => 'whateveragain')
912 2.times
{ t
.replies
.build('title' => 'areply', 'content' => 'whateveragain') }
914 assert t
.errors
.on(:replies)
917 def test_validates_length_of_nasty_params
918 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :minimum=>6, :maximum=>9) }
919 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :within=>6, :maximum=>9) }
920 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :within=>6, :minimum=>9) }
921 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :within=>6, :is=>9) }
922 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :minimum=>"a") }
923 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :maximum=>"a") }
924 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :within=>"a") }
925 assert_raise(ArgumentError
) { Topic
.validates_length_of(:title, :is=>"a") }
928 def test_validates_length_of_custom_errors_for_minimum_with_message
929 Topic
.validates_length_of( :title, :minimum=>5, :message=>"boo {{count}}" )
930 t
= Topic
.create("title" => "uhoh", "content" => "whatever")
932 assert t
.errors
.on(:title)
933 assert_equal
"boo 5", t
.errors
["title"]
936 def test_validates_length_of_custom_errors_for_minimum_with_too_short
937 Topic
.validates_length_of( :title, :minimum=>5, :too_short=>"hoo {{count}}" )
938 t
= Topic
.create("title" => "uhoh", "content" => "whatever")
940 assert t
.errors
.on(:title)
941 assert_equal
"hoo 5", t
.errors
["title"]
944 def test_validates_length_of_custom_errors_for_maximum_with_message
945 Topic
.validates_length_of( :title, :maximum=>5, :message=>"boo {{count}}" )
946 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
948 assert t
.errors
.on(:title)
949 assert_equal
"boo 5", t
.errors
["title"]
952 def test_validates_length_of_custom_errors_for_maximum_with_too_long
953 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}" )
954 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
956 assert t
.errors
.on(:title)
957 assert_equal
"hoo 5", t
.errors
["title"]
960 def test_validates_length_of_custom_errors_for_is_with_message
961 Topic
.validates_length_of( :title, :is=>5, :message=>"boo {{count}}" )
962 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
964 assert t
.errors
.on(:title)
965 assert_equal
"boo 5", t
.errors
["title"]
968 def test_validates_length_of_custom_errors_for_is_with_wrong_length
969 Topic
.validates_length_of( :title, :is=>5, :wrong_length=>"hoo {{count}}" )
970 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
972 assert t
.errors
.on(:title)
973 assert_equal
"hoo 5", t
.errors
["title"]
976 def test_validates_length_of_using_minimum_utf8
977 with_kcode('UTF8') do
978 Topic
.validates_length_of
:title, :minimum => 5
980 t
= Topic
.create("title" => "一二三四五", "content" => "whatever")
985 assert t
.errors
.on(:title)
986 assert_equal
"is too short (minimum is 5 characters)", t
.errors
["title"]
990 def test_validates_length_of_using_maximum_utf8
991 with_kcode('UTF8') do
992 Topic
.validates_length_of
:title, :maximum => 5
994 t
= Topic
.create("title" => "一二三四五", "content" => "whatever")
999 assert t
.errors
.on(:title)
1000 assert_equal
"is too long (maximum is 5 characters)", t
.errors
["title"]
1004 def test_validates_length_of_using_within_utf8
1005 with_kcode('UTF8') do
1006 Topic
.validates_length_of(:title, :content, :within => 3..5)
1008 t
= Topic
.new("title" => "一二", "content" => "12三四五六七")
1010 assert_equal
"is too short (minimum is 3 characters)", t
.errors
.on(:title)
1011 assert_equal
"is too long (maximum is 5 characters)", t
.errors
.on(:content)
1018 def test_optionally_validates_length_of_using_within_utf8
1019 with_kcode('UTF8') do
1020 Topic
.validates_length_of
:title, :within => 3..5, :allow_nil => true
1022 t
= Topic
.create(:title => "一二三四五")
1023 assert t
.valid
?, t
.errors
.inspect
1025 t
= Topic
.create(:title => "一二三")
1026 assert t
.valid
?, t
.errors
.inspect
1029 assert t
.valid
?, t
.errors
.inspect
1033 def test_optionally_validates_length_of_using_within_on_create_utf8
1034 with_kcode('UTF8') do
1035 Topic
.validates_length_of
:title, :within => 5..10, :on => :create, :too_long => "長すぎます: {{count}}"
1037 t
= Topic
.create("title" => "一二三四五六七八九十A", "content" => "whatever")
1039 assert t
.errors
.on(:title)
1040 assert_equal
"長すぎます: 10", t
.errors
[:title]
1042 t
.title
= "一二三四五六七八九"
1048 t
.content
= "一二三四五六七八九十"
1051 t
.content
= t
.title
= "一二三四五六"
1056 def test_optionally_validates_length_of_using_within_on_update_utf8
1057 with_kcode('UTF8') do
1058 Topic
.validates_length_of
:title, :within => 5..10, :on => :update, :too_short => "短すぎます: {{count}}"
1060 t
= Topic
.create("title" => "一二三4", "content" => "whatever")
1062 assert t
.errors
.on(:title)
1066 assert t
.errors
.on(:title)
1067 assert_equal
"短すぎます: 5", t
.errors
[:title]
1069 t
.title
= "一二三四五六七八九十A"
1071 assert t
.errors
.on(:title)
1078 def test_validates_length_of_using_is_utf8
1079 with_kcode('UTF8') do
1080 Topic
.validates_length_of
:title, :is => 5
1082 t
= Topic
.create("title" => "一二345", "content" => "whatever")
1087 assert t
.errors
.on(:title)
1088 assert_equal
"is the wrong length (should be 5 characters)", t
.errors
["title"]
1092 def test_validates_length_of_with_block
1093 Topic
.validates_length_of
:content, :minimum => 5, :too_short=>"Your essay must be at least {{count}} words.",
1094 :tokenizer => lambda
{|str
| str
.scan(/\w+/) }
1095 t
= Topic
.create
!(:content => "this content should be long enough")
1098 t
.content
= "not long enough"
1100 assert t
.errors
.on(:content)
1101 assert_equal
"Your essay must be at least 5 words.", t
.errors
[:content]
1104 def test_validates_size_of_association_utf8
1105 with_kcode('UTF8') do
1106 assert_nothing_raised
{ Topic
.validates_size_of
:replies, :minimum => 1 }
1107 t
= Topic
.new('title' => 'あいうえお', 'content' => 'かきくけこ')
1109 assert t
.errors
.on(:replies)
1110 t
.replies
.build('title' => 'あいうえお', 'content' => 'かきくけこ')
1115 def test_validates_associated_many
1116 Topic
.validates_associated( :replies )
1117 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1118 t
.replies
<< [r
= Reply
.new("title" => "A reply"), r2
= Reply
.new("title" => "Another reply", "content" => "non-empty"), r3
= Reply
.new("title" => "Yet another reply"), r4
= Reply
.new("title" => "The last reply", "content" => "non-empty")]
1120 assert t
.errors
.on(:replies)
1121 assert_equal
1, r
.errors
.count
# make sure all associated objects have been validated
1122 assert_equal
0, r2
.errors
.count
1123 assert_equal
1, r3
.errors
.count
1124 assert_equal
0, r4
.errors
.count
1125 r
.content
= r3
.content
= "non-empty"
1129 def test_validates_associated_one
1130 Reply
.validates_associated( :topic )
1131 Topic
.validates_presence_of( :content )
1132 r
= Reply
.new("title" => "A reply", "content" => "with content!")
1133 r
.topic
= Topic
.create("title" => "uhohuhoh")
1135 assert r
.errors
.on(:topic)
1136 r
.topic
.content
= "non-empty"
1140 def test_validate_block
1141 Topic
.validate
{ |topic
| topic
.errors
.add("title", "will never be valid") }
1142 t
= Topic
.create("title" => "Title", "content" => "whatever")
1144 assert t
.errors
.on(:title)
1145 assert_equal
"will never be valid", t
.errors
["title"]
1148 def test_invalid_validator
1150 assert_raise(ArgumentError
) { t
= Topic
.create
}
1153 def test_throw_away_typing
1154 d
= Developer
.new("name" => "David", "salary" => "100,000")
1156 assert_equal
100, d
.salary
1157 assert_equal
"100,000", d
.salary_before_type_cast
1160 def test_validates_acceptance_of_with_custom_error_using_quotes
1161 Developer
.validates_acceptance_of
:salary, :message=> "This string contains 'single' and \"double\" quotes"
1165 assert_equal
"This string contains 'single' and \"double\" quotes", d
.errors
.on(:salary).last
1168 def test_validates_confirmation_of_with_custom_error_using_quotes
1169 Developer
.validates_confirmation_of
:name, :message=> "confirm 'single' and \"double\" quotes"
1172 d
.name_confirmation
= "Johnny"
1174 assert_equal
"confirm 'single' and \"double\" quotes", d
.errors
.on(:name)
1177 def test_validates_format_of_with_custom_error_using_quotes
1178 Developer
.validates_format_of
:name, :with => /^(A-Z*)$/, :message=> "format 'single' and \"double\" quotes"
1180 d
.name
= d
.name_confirmation
= "John 32"
1182 assert_equal
"format 'single' and \"double\" quotes", d
.errors
.on(:name)
1185 def test_validates_inclusion_of_with_custom_error_using_quotes
1186 Developer
.validates_inclusion_of
:salary, :in => 1000..80000, :message=> "This string contains 'single' and \"double\" quotes"
1190 assert_equal
"This string contains 'single' and \"double\" quotes", d
.errors
.on(:salary).last
1193 def test_validates_length_of_with_custom_too_long_using_quotes
1194 Developer
.validates_length_of
:name, :maximum => 4, :too_long=> "This string contains 'single' and \"double\" quotes"
1198 assert_equal
"This string contains 'single' and \"double\" quotes", d
.errors
.on(:name).last
1201 def test_validates_length_of_with_custom_too_short_using_quotes
1202 Developer
.validates_length_of
:name, :minimum => 4, :too_short=> "This string contains 'single' and \"double\" quotes"
1206 assert_equal
"This string contains 'single' and \"double\" quotes", d
.errors
.on(:name).last
1209 def test_validates_length_of_with_custom_message_using_quotes
1210 Developer
.validates_length_of
:name, :minimum => 4, :message=> "This string contains 'single' and \"double\" quotes"
1214 assert_equal
"This string contains 'single' and \"double\" quotes", d
.errors
.on(:name).last
1217 def test_validates_presence_of_with_custom_message_using_quotes
1218 Developer
.validates_presence_of
:non_existent, :message=> "This string contains 'single' and \"double\" quotes"
1222 assert_equal
"This string contains 'single' and \"double\" quotes", d
.errors
.on(:non_existent)
1225 def test_validates_uniqueness_of_with_custom_message_using_quotes
1226 Developer
.validates_uniqueness_of
:name, :message=> "This string contains 'single' and \"double\" quotes"
1230 assert_equal
"This string contains 'single' and \"double\" quotes", d
.errors
.on(:name).last
1233 def test_validates_associated_with_custom_message_using_quotes
1234 Reply
.validates_associated
:topic, :message=> "This string contains 'single' and \"double\" quotes"
1235 Topic
.validates_presence_of
:content
1236 r
= Reply
.create("title" => "A reply", "content" => "with content!")
1237 r
.topic
= Topic
.create("title" => "uhohuhoh")
1239 assert_equal
"This string contains 'single' and \"double\" quotes", r
.errors
.on(:topic).last
1242 def test_if_validation_using_method_true
1243 # When the method returns true
1244 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true )
1245 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1247 assert t
.errors
.on(:title)
1248 assert_equal
"hoo 5", t
.errors
["title"]
1251 def test_unless_validation_using_method_true
1252 # When the method returns true
1253 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true )
1254 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1256 assert
!t
.errors
.on(:title)
1259 def test_if_validation_using_method_false
1260 # When the method returns false
1261 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true_but_its_not )
1262 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1264 assert
!t
.errors
.on(:title)
1267 def test_unless_validation_using_method_false
1268 # When the method returns false
1269 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true_but_its_not )
1270 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1272 assert t
.errors
.on(:title)
1273 assert_equal
"hoo 5", t
.errors
["title"]
1276 def test_if_validation_using_string_true
1277 # When the evaluated string returns true
1278 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "a = 1; a == 1" )
1279 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1281 assert t
.errors
.on(:title)
1282 assert_equal
"hoo 5", t
.errors
["title"]
1285 def test_unless_validation_using_string_true
1286 # When the evaluated string returns true
1287 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "a = 1; a == 1" )
1288 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1290 assert
!t
.errors
.on(:title)
1293 def test_if_validation_using_string_false
1294 # When the evaluated string returns false
1295 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "false")
1296 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1298 assert
!t
.errors
.on(:title)
1301 def test_unless_validation_using_string_false
1302 # When the evaluated string returns false
1303 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "false")
1304 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1306 assert t
.errors
.on(:title)
1307 assert_equal
"hoo 5", t
.errors
["title"]
1310 def test_if_validation_using_block_true
1311 # When the block returns true
1312 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
1313 :if => Proc
.new
{ |r
| r
.content
.size
> 4 } )
1314 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1316 assert t
.errors
.on(:title)
1317 assert_equal
"hoo 5", t
.errors
["title"]
1320 def test_unless_validation_using_block_true
1321 # When the block returns true
1322 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
1323 :unless => Proc
.new
{ |r
| r
.content
.size
> 4 } )
1324 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1326 assert
!t
.errors
.on(:title)
1329 def test_if_validation_using_block_false
1330 # When the block returns false
1331 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
1332 :if => Proc
.new
{ |r
| r
.title
!= "uhohuhoh"} )
1333 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1335 assert
!t
.errors
.on(:title)
1338 def test_unless_validation_using_block_false
1339 # When the block returns false
1340 Topic
.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
1341 :unless => Proc
.new
{ |r
| r
.title
!= "uhohuhoh"} )
1342 t
= Topic
.create("title" => "uhohuhoh", "content" => "whatever")
1344 assert t
.errors
.on(:title)
1345 assert_equal
"hoo 5", t
.errors
["title"]
1348 def test_validates_associated_missing
1349 Reply
.validates_presence_of(:topic)
1350 r
= Reply
.create("title" => "A reply", "content" => "with content!")
1352 assert r
.errors
.on(:topic)
1354 r
.topic
= Topic
.find
:first
1358 def test_errors_to_xml
1359 r
= Reply
.new
:title => "Wrong Create"
1361 xml
= r
.errors
.to_xml(:skip_instruct => true)
1362 assert_equal
"<errors>", xml
.first(8)
1363 assert xml
.include?("<error>Title is Wrong Create</error>")
1364 assert xml
.include?("<error>Content Empty</error>")
1367 def test_validation_order
1368 Topic
.validates_presence_of
:title
1369 Topic
.validates_length_of
:title, :minimum => 2
1371 t
= Topic
.new("title" => "")
1373 assert_equal
"can't be blank", t
.errors
.on("title").first
1376 # previous implementation of validates_presence_of eval'd the
1377 # string with the wrong binding, this regression test is to
1378 # ensure that it works correctly
1379 def test_validation_with_if_as_string
1380 Topic
.validates_presence_of(:title)
1381 Topic
.validates_presence_of(:author_name, :if => "title.to_s.match('important')")
1384 assert
!t
.valid
?, "A topic without a title should not be valid"
1385 assert
!t
.errors
.invalid
?("author_name"), "A topic without an 'important' title should not require an author"
1387 t
.title
= "Just a title"
1388 assert t
.valid
?, "A topic with a basic title should be valid"
1390 t
.title
= "A very important title"
1391 assert
!t
.valid
?, "A topic with an important title, but without an author, should not be valid"
1392 assert t
.errors
.invalid
?("author_name"), "A topic with an 'important' title should require an author"
1394 t
.author_name
= "Hubert J. Farnsworth"
1395 assert t
.valid
?, "A topic with an important title and author should be valid"
1399 def with_kcode(kcode
)
1400 if RUBY_VERSION < '1.9'
1401 orig_kcode
, $KCODE = $KCODE, kcode
1414 class ValidatesNumericalityTest
< ActiveRecord
::TestCase
1416 BLANK
= ["", " ", " \t \r \n"]
1417 BIGDECIMAL_STRINGS
= %w(12345678901234567890.1234567890) # 30 significent digits
1418 FLOAT_STRINGS
= %w(0.0 +0.0 -0.0 10.0 10.5 -10.5 -0.0001 -090.1 90.1e1
-90.1e5
-90.1e-5 90e-5)
1419 INTEGER_STRINGS
= %w(0 +0 -0 10 +10 -10 0090 -090)
1420 FLOATS
= [0.0, 10.0, 10.5, -10.5, -0.0001] + FLOAT_STRINGS
1421 INTEGERS
= [0, 10, -10] + INTEGER_STRINGS
1422 BIGDECIMAL
= BIGDECIMAL_STRINGS
.collect
! { |bd
| BigDecimal
.new(bd
) }
1423 JUNK
= ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12", "123\nnot a number"]
1424 INFINITY
= [1.0/0.0]
1427 Topic
.instance_variable_set("@validate_callbacks", ActiveSupport
::Callbacks::CallbackChain.new
)
1428 Topic
.instance_variable_set("@validate_on_create_callbacks", ActiveSupport
::Callbacks::CallbackChain.new
)
1429 Topic
.instance_variable_set("@validate_on_update_callbacks", ActiveSupport
::Callbacks::CallbackChain.new
)
1432 def test_default_validates_numericality_of
1433 Topic
.validates_numericality_of
:approved
1435 invalid
!(NIL + BLANK
+ JUNK
)
1436 valid
!(FLOATS
+ INTEGERS
+ BIGDECIMAL
+ INFINITY
)
1439 def test_validates_numericality_of_with_nil_allowed
1440 Topic
.validates_numericality_of
:approved, :allow_nil => true
1443 valid
!(NIL + BLANK
+ FLOATS
+ INTEGERS
+ BIGDECIMAL
+ INFINITY
)
1446 def test_validates_numericality_of_with_integer_only
1447 Topic
.validates_numericality_of
:approved, :only_integer => true
1449 invalid
!(NIL + BLANK
+ JUNK
+ FLOATS
+ BIGDECIMAL
+ INFINITY
)
1453 def test_validates_numericality_of_with_integer_only_and_nil_allowed
1454 Topic
.validates_numericality_of
:approved, :only_integer => true, :allow_nil => true
1456 invalid
!(JUNK
+ FLOATS
+ BIGDECIMAL
+ INFINITY
)
1457 valid
!(NIL + BLANK
+ INTEGERS
)
1460 def test_validates_numericality_with_greater_than
1461 Topic
.validates_numericality_of
:approved, :greater_than => 10
1463 invalid
!([-10, 10], 'must be greater than 10')
1467 def test_validates_numericality_with_greater_than_or_equal
1468 Topic
.validates_numericality_of
:approved, :greater_than_or_equal_to => 10
1470 invalid
!([-9, 9], 'must be greater than or equal to 10')
1474 def test_validates_numericality_with_equal_to
1475 Topic
.validates_numericality_of
:approved, :equal_to => 10
1477 invalid
!([-10, 11] + INFINITY
, 'must be equal to 10')
1481 def test_validates_numericality_with_less_than
1482 Topic
.validates_numericality_of
:approved, :less_than => 10
1484 invalid
!([10], 'must be less than 10')
1488 def test_validates_numericality_with_less_than_or_equal_to
1489 Topic
.validates_numericality_of
:approved, :less_than_or_equal_to => 10
1491 invalid
!([11], 'must be less than or equal to 10')
1495 def test_validates_numericality_with_odd
1496 Topic
.validates_numericality_of
:approved, :odd => true
1498 invalid
!([-2, 2], 'must be odd')
1502 def test_validates_numericality_with_even
1503 Topic
.validates_numericality_of
:approved, :even => true
1505 invalid
!([-1, 1], 'must be even')
1509 def test_validates_numericality_with_greater_than_less_than_and_even
1510 Topic
.validates_numericality_of
:approved, :greater_than => 1, :less_than => 4, :even => true
1516 def test_validates_numericality_with_numeric_message
1517 Topic
.validates_numericality_of
:approved, :less_than => 4, :message => "smaller than {{count}}"
1518 topic
= Topic
.new("title" => "numeric test", "approved" => 10)
1520 assert
!topic
.valid
?
1521 assert_equal
"smaller than 4", topic
.errors
.on(:approved)
1523 Topic
.validates_numericality_of
:approved, :greater_than => 4, :message => "greater than {{count}}"
1524 topic
= Topic
.new("title" => "numeric test", "approved" => 1)
1526 assert
!topic
.valid
?
1527 assert_equal
"greater than 4", topic
.errors
.on(:approved)
1531 def invalid
!(values
, error
=nil)
1532 with_each_topic_approved_value(values
) do |topic
, value
|
1533 assert
!topic
.valid
?, "#{value.inspect} not rejected as a number"
1534 assert topic
.errors
.on(:approved)
1535 assert_equal error
, topic
.errors
.on(:approved) if error
1540 with_each_topic_approved_value(values
) do |topic
, value
|
1541 assert topic
.valid
?, "#{value.inspect} not accepted as a number"
1545 def with_each_topic_approved_value(values
)
1546 topic
= Topic
.new("title" => "numeric test", "content" => "whatever")
1547 values
.each
do |value
|
1548 topic
.approved
= value