activerecord 2.2.3 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +438 -396
- data/Rakefile +4 -2
- data/lib/active_record.rb +46 -43
- data/lib/active_record/association_preload.rb +34 -19
- data/lib/active_record/associations.rb +193 -251
- data/lib/active_record/associations/association_collection.rb +38 -21
- data/lib/active_record/associations/association_proxy.rb +11 -4
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +2 -2
- data/lib/active_record/associations/has_many_association.rb +2 -2
- data/lib/active_record/associations/has_many_through_association.rb +8 -8
- data/lib/active_record/associations/has_one_association.rb +11 -2
- data/lib/active_record/attribute_methods.rb +1 -0
- data/lib/active_record/autosave_association.rb +349 -0
- data/lib/active_record/base.rb +292 -106
- data/lib/active_record/batches.rb +73 -0
- data/lib/active_record/calculations.rb +34 -16
- data/lib/active_record/callbacks.rb +37 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +16 -0
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +3 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +103 -15
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +28 -25
- data/lib/active_record/connection_adapters/abstract_adapter.rb +29 -5
- data/lib/active_record/connection_adapters/mysql_adapter.rb +50 -21
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +26 -41
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +41 -21
- data/lib/active_record/dirty.rb +1 -1
- data/lib/active_record/dynamic_scope_match.rb +25 -0
- data/lib/active_record/fixtures.rb +193 -198
- data/lib/active_record/locale/en.yml +1 -1
- data/lib/active_record/locking/optimistic.rb +33 -0
- data/lib/active_record/migration.rb +8 -2
- data/lib/active_record/named_scope.rb +13 -6
- data/lib/active_record/nested_attributes.rb +329 -0
- data/lib/active_record/query_cache.rb +25 -13
- data/lib/active_record/reflection.rb +6 -1
- data/lib/active_record/schema_dumper.rb +2 -0
- data/lib/active_record/serialization.rb +3 -1
- data/lib/active_record/serializers/json_serializer.rb +19 -0
- data/lib/active_record/serializers/xml_serializer.rb +28 -13
- data/lib/active_record/session_store.rb +318 -0
- data/lib/active_record/test_case.rb +15 -9
- data/lib/active_record/timestamp.rb +2 -2
- data/lib/active_record/transactions.rb +58 -8
- data/lib/active_record/validations.rb +29 -24
- data/lib/active_record/version.rb +2 -2
- data/test/cases/ar_schema_test.rb +0 -1
- data/test/cases/associations/belongs_to_associations_test.rb +35 -131
- data/test/cases/associations/cascaded_eager_loading_test.rb +8 -0
- data/test/cases/associations/eager_load_nested_include_test.rb +29 -0
- data/test/cases/associations/eager_test.rb +137 -7
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +45 -7
- data/test/cases/associations/has_many_associations_test.rb +110 -149
- data/test/cases/associations/has_many_through_associations_test.rb +39 -7
- data/test/cases/associations/has_one_associations_test.rb +39 -92
- data/test/cases/associations/has_one_through_associations_test.rb +34 -3
- data/test/cases/associations/inner_join_association_test.rb +0 -5
- data/test/cases/associations/join_model_test.rb +5 -7
- data/test/cases/attribute_methods_test.rb +13 -1
- data/test/cases/autosave_association_test.rb +901 -0
- data/test/cases/base_test.rb +41 -21
- data/test/cases/batches_test.rb +61 -0
- data/test/cases/calculations_test.rb +37 -17
- data/test/cases/callbacks_test.rb +43 -5
- data/test/cases/connection_pool_test.rb +25 -0
- data/test/cases/copy_table_test_sqlite.rb +11 -0
- data/test/cases/datatype_test_postgresql.rb +1 -0
- data/test/cases/defaults_test.rb +37 -26
- data/test/cases/dirty_test.rb +26 -2
- data/test/cases/finder_test.rb +79 -44
- data/test/cases/fixtures_test.rb +15 -19
- data/test/cases/helper.rb +26 -19
- data/test/cases/inheritance_test.rb +2 -2
- data/test/cases/json_serialization_test.rb +1 -1
- data/test/cases/locking_test.rb +23 -5
- data/test/cases/method_scoping_test.rb +126 -3
- data/test/cases/migration_test.rb +253 -237
- data/test/cases/named_scope_test.rb +73 -3
- data/test/cases/nested_attributes_test.rb +509 -0
- data/test/cases/query_cache_test.rb +0 -4
- data/test/cases/reflection_test.rb +13 -3
- data/test/cases/reload_models_test.rb +3 -1
- data/test/cases/repair_helper.rb +50 -0
- data/test/cases/schema_dumper_test.rb +0 -1
- data/test/cases/transactions_test.rb +177 -12
- data/test/cases/validations_i18n_test.rb +288 -294
- data/test/cases/validations_test.rb +230 -180
- data/test/cases/xml_serialization_test.rb +19 -1
- data/test/fixtures/fixture_database.sqlite3 +0 -0
- data/test/fixtures/fixture_database_2.sqlite3 +0 -0
- data/test/fixtures/member_types.yml +6 -0
- data/test/fixtures/members.yml +3 -1
- data/test/fixtures/people.yml +10 -1
- data/test/fixtures/toys.yml +4 -0
- data/test/models/author.rb +1 -2
- data/test/models/bird.rb +3 -0
- data/test/models/category.rb +1 -0
- data/test/models/company.rb +3 -0
- data/test/models/developer.rb +12 -0
- data/test/models/event.rb +3 -0
- data/test/models/member.rb +1 -0
- data/test/models/member_detail.rb +1 -0
- data/test/models/member_type.rb +3 -0
- data/test/models/owner.rb +2 -1
- data/test/models/parrot.rb +2 -0
- data/test/models/person.rb +6 -0
- data/test/models/pet.rb +2 -1
- data/test/models/pirate.rb +55 -1
- data/test/models/post.rb +6 -0
- data/test/models/project.rb +1 -0
- data/test/models/reply.rb +6 -0
- data/test/models/ship.rb +8 -1
- data/test/models/ship_part.rb +5 -0
- data/test/models/topic.rb +13 -1
- data/test/models/toy.rb +4 -0
- data/test/schema/schema.rb +35 -2
- metadata +70 -9
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
@@ -6,6 +6,9 @@ require 'models/person'
|
|
6
6
|
require 'models/developer'
|
7
7
|
require 'models/warehouse_thing'
|
8
8
|
require 'models/guid'
|
9
|
+
require 'models/owner'
|
10
|
+
require 'models/pet'
|
11
|
+
require 'models/event'
|
9
12
|
|
10
13
|
# The following methods in Topic are used in test_conditional_validation_*
|
11
14
|
class Topic
|
@@ -31,10 +34,6 @@ class UniqueReply < Reply
|
|
31
34
|
validates_uniqueness_of :content, :scope => 'parent_id'
|
32
35
|
end
|
33
36
|
|
34
|
-
class PlagiarizedReply < Reply
|
35
|
-
validates_acceptance_of :author_name
|
36
|
-
end
|
37
|
-
|
38
37
|
class SillyUniqueReply < UniqueReply
|
39
38
|
end
|
40
39
|
|
@@ -58,11 +57,9 @@ end
|
|
58
57
|
class ValidationsTest < ActiveRecord::TestCase
|
59
58
|
fixtures :topics, :developers, 'warehouse-things'
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
Topic.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
65
|
-
end
|
60
|
+
# Most of the tests mess with the validations of Topic, so lets repair it all the time.
|
61
|
+
# Other classes we mess with will be dealt with in the specific tests
|
62
|
+
repair_validations(Topic)
|
66
63
|
|
67
64
|
def test_single_field_validation
|
68
65
|
r = Reply.new
|
@@ -117,8 +114,8 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
117
114
|
end
|
118
115
|
|
119
116
|
def test_invalid_record_exception
|
120
|
-
|
121
|
-
|
117
|
+
assert_raise(ActiveRecord::RecordInvalid) { Reply.create! }
|
118
|
+
assert_raise(ActiveRecord::RecordInvalid) { Reply.new.save! }
|
122
119
|
|
123
120
|
begin
|
124
121
|
r = Reply.new
|
@@ -130,21 +127,21 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
130
127
|
end
|
131
128
|
|
132
129
|
def test_exception_on_create_bang_many
|
133
|
-
|
130
|
+
assert_raise(ActiveRecord::RecordInvalid) do
|
134
131
|
Reply.create!([ { "title" => "OK" }, { "title" => "Wrong Create" }])
|
135
132
|
end
|
136
133
|
end
|
137
|
-
|
134
|
+
|
138
135
|
def test_exception_on_create_bang_with_block
|
139
|
-
|
136
|
+
assert_raise(ActiveRecord::RecordInvalid) do
|
140
137
|
Reply.create!({ "title" => "OK" }) do |r|
|
141
138
|
r.content = nil
|
142
139
|
end
|
143
140
|
end
|
144
141
|
end
|
145
|
-
|
142
|
+
|
146
143
|
def test_exception_on_create_bang_many_with_block
|
147
|
-
|
144
|
+
assert_raise(ActiveRecord::RecordInvalid) do
|
148
145
|
Reply.create!([{ "title" => "OK" }, { "title" => "Wrong Create" }]) do |r|
|
149
146
|
r.content = nil
|
150
147
|
end
|
@@ -153,7 +150,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
153
150
|
|
154
151
|
def test_scoped_create_without_attributes
|
155
152
|
Reply.with_scope(:create => {}) do
|
156
|
-
|
153
|
+
assert_raise(ActiveRecord::RecordInvalid) { Reply.create! }
|
157
154
|
end
|
158
155
|
end
|
159
156
|
|
@@ -173,7 +170,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
173
170
|
assert_equal person.first_name, "Mary", "should be ok when no attributes are passed to create!"
|
174
171
|
end
|
175
172
|
end
|
176
|
-
|
173
|
+
end
|
177
174
|
|
178
175
|
def test_single_error_per_attr_iteration
|
179
176
|
r = Reply.new
|
@@ -229,21 +226,16 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
229
226
|
end
|
230
227
|
|
231
228
|
def test_validates_each
|
232
|
-
perform = true
|
233
229
|
hits = 0
|
234
230
|
Topic.validates_each(:title, :content, [:title, :content]) do |record, attr|
|
235
|
-
|
236
|
-
|
237
|
-
hits += 1
|
238
|
-
end
|
231
|
+
record.errors.add attr, 'gotcha'
|
232
|
+
hits += 1
|
239
233
|
end
|
240
234
|
t = Topic.new("title" => "valid", "content" => "whatever")
|
241
235
|
assert !t.save
|
242
236
|
assert_equal 4, hits
|
243
237
|
assert_equal %w(gotcha gotcha), t.errors.on(:title)
|
244
238
|
assert_equal %w(gotcha gotcha), t.errors.on(:content)
|
245
|
-
ensure
|
246
|
-
perform = false
|
247
239
|
end
|
248
240
|
|
249
241
|
def test_no_title_confirmation
|
@@ -315,8 +307,12 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
315
307
|
end
|
316
308
|
|
317
309
|
def test_validates_acceptance_of_as_database_column
|
318
|
-
|
319
|
-
|
310
|
+
repair_validations(Reply) do
|
311
|
+
Reply.validates_acceptance_of(:author_name)
|
312
|
+
|
313
|
+
reply = Reply.create("author_name" => "Dan Brown")
|
314
|
+
assert_equal "Dan Brown", reply["author_name"]
|
315
|
+
end
|
320
316
|
end
|
321
317
|
|
322
318
|
def test_validates_acceptance_of_with_non_existant_table
|
@@ -372,22 +368,24 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
372
368
|
end
|
373
369
|
|
374
370
|
def test_validate_uniqueness_with_scope
|
375
|
-
Reply
|
371
|
+
repair_validations(Reply) do
|
372
|
+
Reply.validates_uniqueness_of(:content, :scope => "parent_id")
|
376
373
|
|
377
|
-
|
374
|
+
t = Topic.create("title" => "I'm unique!")
|
378
375
|
|
379
|
-
|
380
|
-
|
376
|
+
r1 = t.replies.create "title" => "r1", "content" => "hello world"
|
377
|
+
assert r1.valid?, "Saving r1"
|
381
378
|
|
382
|
-
|
383
|
-
|
379
|
+
r2 = t.replies.create "title" => "r2", "content" => "hello world"
|
380
|
+
assert !r2.valid?, "Saving r2 first time"
|
384
381
|
|
385
|
-
|
386
|
-
|
382
|
+
r2.content = "something else"
|
383
|
+
assert r2.save, "Saving r2 second time"
|
387
384
|
|
388
|
-
|
389
|
-
|
390
|
-
|
385
|
+
t2 = Topic.create("title" => "I'm unique too!")
|
386
|
+
r3 = t2.replies.create "title" => "r3", "content" => "hello world"
|
387
|
+
assert r3.valid?, "Saving r3"
|
388
|
+
end
|
391
389
|
end
|
392
390
|
|
393
391
|
def test_validate_uniqueness_scoped_to_defining_class
|
@@ -406,27 +404,29 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
406
404
|
end
|
407
405
|
|
408
406
|
def test_validate_uniqueness_with_scope_array
|
409
|
-
Reply
|
407
|
+
repair_validations(Reply) do
|
408
|
+
Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
|
410
409
|
|
411
|
-
|
410
|
+
t = Topic.create("title" => "The earth is actually flat!")
|
412
411
|
|
413
|
-
|
414
|
-
|
412
|
+
r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply"
|
413
|
+
assert r1.valid?, "Saving r1"
|
415
414
|
|
416
|
-
|
417
|
-
|
415
|
+
r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..."
|
416
|
+
assert !r2.valid?, "Saving r2. Double reply by same author."
|
418
417
|
|
419
|
-
|
420
|
-
|
418
|
+
r2.author_email_address = "jeremy_alt_email@rubyonrails.com"
|
419
|
+
assert r2.save, "Saving r2 the second time."
|
421
420
|
|
422
|
-
|
423
|
-
|
421
|
+
r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic"
|
422
|
+
assert !r3.valid?, "Saving r3"
|
424
423
|
|
425
|
-
|
426
|
-
|
424
|
+
r3.author_name = "jj"
|
425
|
+
assert r3.save, "Saving r3 the second time."
|
427
426
|
|
428
|
-
|
429
|
-
|
427
|
+
r3.author_name = "jeremy"
|
428
|
+
assert !r3.save, "Saving r3 the third time."
|
429
|
+
end
|
430
430
|
end
|
431
431
|
|
432
432
|
def test_validate_case_insensitive_uniqueness
|
@@ -523,10 +523,20 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
523
523
|
end
|
524
524
|
|
525
525
|
def test_validate_uniqueness_with_columns_which_are_sql_keywords
|
526
|
-
Guid
|
527
|
-
|
528
|
-
|
529
|
-
|
526
|
+
repair_validations(Guid) do
|
527
|
+
Guid.validates_uniqueness_of :key
|
528
|
+
g = Guid.new
|
529
|
+
g.key = "foo"
|
530
|
+
assert_nothing_raised { !g.valid? }
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
def test_validate_uniqueness_with_limit
|
535
|
+
# Event.title is limited to 5 characters
|
536
|
+
e1 = Event.create(:title => "abcde")
|
537
|
+
assert e1.valid?, "Could not create an event with a unique, 5 character title"
|
538
|
+
e2 = Event.create(:title => "abcdefgh")
|
539
|
+
assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique"
|
530
540
|
end
|
531
541
|
|
532
542
|
def test_validate_straight_inheritance_uniqueness
|
@@ -648,10 +658,12 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
648
658
|
end
|
649
659
|
|
650
660
|
def test_numericality_with_getter_method
|
651
|
-
Developer
|
652
|
-
|
653
|
-
|
654
|
-
|
661
|
+
repair_validations(Developer) do
|
662
|
+
Developer.validates_numericality_of( :salary )
|
663
|
+
developer = Developer.new("name" => "michael", "salary" => nil)
|
664
|
+
developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end")
|
665
|
+
assert developer.valid?
|
666
|
+
end
|
655
667
|
end
|
656
668
|
|
657
669
|
def test_validates_length_of_with_allow_nil
|
@@ -684,10 +696,12 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
684
696
|
end
|
685
697
|
|
686
698
|
def test_numericality_with_allow_nil_and_getter_method
|
687
|
-
Developer
|
688
|
-
|
689
|
-
|
690
|
-
|
699
|
+
repair_validations(Developer) do
|
700
|
+
Developer.validates_numericality_of( :salary, :allow_nil => true)
|
701
|
+
developer = Developer.new("name" => "michael", "salary" => nil)
|
702
|
+
developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end")
|
703
|
+
assert developer.valid?
|
704
|
+
end
|
691
705
|
end
|
692
706
|
|
693
707
|
def test_validates_exclusion_of
|
@@ -892,26 +906,30 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
892
906
|
end
|
893
907
|
|
894
908
|
def test_validates_size_of_association
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
909
|
+
repair_validations(Owner) do
|
910
|
+
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
|
911
|
+
o = Owner.new('name' => 'nopets')
|
912
|
+
assert !o.save
|
913
|
+
assert o.errors.on(:pets)
|
914
|
+
pet = o.pets.build('name' => 'apet')
|
915
|
+
assert o.valid?
|
916
|
+
end
|
901
917
|
end
|
902
918
|
|
903
919
|
def test_validates_size_of_association_using_within
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
920
|
+
repair_validations(Owner) do
|
921
|
+
assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 }
|
922
|
+
o = Owner.new('name' => 'nopets')
|
923
|
+
assert !o.save
|
924
|
+
assert o.errors.on(:pets)
|
925
|
+
|
926
|
+
pet = o.pets.build('name' => 'apet')
|
927
|
+
assert o.valid?
|
928
|
+
|
929
|
+
2.times { o.pets.build('name' => 'apet') }
|
930
|
+
assert !o.save
|
931
|
+
assert o.errors.on(:pets)
|
932
|
+
end
|
915
933
|
end
|
916
934
|
|
917
935
|
def test_validates_length_of_nasty_params
|
@@ -949,6 +967,19 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
949
967
|
assert_equal "boo 5", t.errors["title"]
|
950
968
|
end
|
951
969
|
|
970
|
+
def test_validates_length_of_custom_errors_for_in
|
971
|
+
Topic.validates_length_of(:title, :in => 10..20, :message => "hoo {{count}}")
|
972
|
+
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
973
|
+
assert !t.valid?
|
974
|
+
assert t.errors.on(:title)
|
975
|
+
assert_equal "hoo 10", t.errors["title"]
|
976
|
+
|
977
|
+
t = Topic.create("title" => "uhohuhohuhohuhohuhohuhohuhohuhoh", "content" => "whatever")
|
978
|
+
assert !t.valid?
|
979
|
+
assert t.errors.on(:title)
|
980
|
+
assert_equal "hoo 20", t.errors["title"]
|
981
|
+
end
|
982
|
+
|
952
983
|
def test_validates_length_of_custom_errors_for_maximum_with_too_long
|
953
984
|
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}" )
|
954
985
|
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
@@ -1102,13 +1133,15 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
1102
1133
|
end
|
1103
1134
|
|
1104
1135
|
def test_validates_size_of_association_utf8
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1136
|
+
repair_validations(Owner) do
|
1137
|
+
with_kcode('UTF8') do
|
1138
|
+
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
|
1139
|
+
o = Owner.new('name' => 'あいうえおかきくけこ')
|
1140
|
+
assert !o.save
|
1141
|
+
assert o.errors.on(:pets)
|
1142
|
+
o.pets.build('name' => 'あいうえおかきくけこ')
|
1143
|
+
assert o.valid?
|
1144
|
+
end
|
1112
1145
|
end
|
1113
1146
|
end
|
1114
1147
|
|
@@ -1127,14 +1160,16 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
1127
1160
|
end
|
1128
1161
|
|
1129
1162
|
def test_validates_associated_one
|
1130
|
-
Reply
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1163
|
+
repair_validations(Reply) do
|
1164
|
+
Reply.validates_associated( :topic )
|
1165
|
+
Topic.validates_presence_of( :content )
|
1166
|
+
r = Reply.new("title" => "A reply", "content" => "with content!")
|
1167
|
+
r.topic = Topic.create("title" => "uhohuhoh")
|
1168
|
+
assert !r.valid?
|
1169
|
+
assert r.errors.on(:topic)
|
1170
|
+
r.topic.content = "non-empty"
|
1171
|
+
assert r.valid?
|
1172
|
+
end
|
1138
1173
|
end
|
1139
1174
|
|
1140
1175
|
def test_validate_block
|
@@ -1158,85 +1193,105 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
1158
1193
|
end
|
1159
1194
|
|
1160
1195
|
def test_validates_acceptance_of_with_custom_error_using_quotes
|
1161
|
-
Developer
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1196
|
+
repair_validations(Developer) do
|
1197
|
+
Developer.validates_acceptance_of :salary, :message=> "This string contains 'single' and \"double\" quotes"
|
1198
|
+
d = Developer.new
|
1199
|
+
d.salary = "0"
|
1200
|
+
assert !d.valid?
|
1201
|
+
assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:salary).last
|
1202
|
+
end
|
1166
1203
|
end
|
1167
1204
|
|
1168
1205
|
def test_validates_confirmation_of_with_custom_error_using_quotes
|
1169
|
-
Developer
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1206
|
+
repair_validations(Developer) do
|
1207
|
+
Developer.validates_confirmation_of :name, :message=> "confirm 'single' and \"double\" quotes"
|
1208
|
+
d = Developer.new
|
1209
|
+
d.name = "John"
|
1210
|
+
d.name_confirmation = "Johnny"
|
1211
|
+
assert !d.valid?
|
1212
|
+
assert_equal "confirm 'single' and \"double\" quotes", d.errors.on(:name)
|
1213
|
+
end
|
1175
1214
|
end
|
1176
1215
|
|
1177
1216
|
def test_validates_format_of_with_custom_error_using_quotes
|
1178
|
-
Developer
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1217
|
+
repair_validations(Developer) do
|
1218
|
+
Developer.validates_format_of :name, :with => /^(A-Z*)$/, :message=> "format 'single' and \"double\" quotes"
|
1219
|
+
d = Developer.new
|
1220
|
+
d.name = d.name_confirmation = "John 32"
|
1221
|
+
assert !d.valid?
|
1222
|
+
assert_equal "format 'single' and \"double\" quotes", d.errors.on(:name)
|
1223
|
+
end
|
1183
1224
|
end
|
1184
1225
|
|
1185
1226
|
def test_validates_inclusion_of_with_custom_error_using_quotes
|
1186
|
-
Developer
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1227
|
+
repair_validations(Developer) do
|
1228
|
+
Developer.validates_inclusion_of :salary, :in => 1000..80000, :message=> "This string contains 'single' and \"double\" quotes"
|
1229
|
+
d = Developer.new
|
1230
|
+
d.salary = "90,000"
|
1231
|
+
assert !d.valid?
|
1232
|
+
assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:salary).last
|
1233
|
+
end
|
1191
1234
|
end
|
1192
1235
|
|
1193
1236
|
def test_validates_length_of_with_custom_too_long_using_quotes
|
1194
|
-
Developer
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1237
|
+
repair_validations(Developer) do
|
1238
|
+
Developer.validates_length_of :name, :maximum => 4, :too_long=> "This string contains 'single' and \"double\" quotes"
|
1239
|
+
d = Developer.new
|
1240
|
+
d.name = "Jeffrey"
|
1241
|
+
assert !d.valid?
|
1242
|
+
assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name)
|
1243
|
+
end
|
1199
1244
|
end
|
1200
1245
|
|
1201
1246
|
def test_validates_length_of_with_custom_too_short_using_quotes
|
1202
|
-
Developer
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1247
|
+
repair_validations(Developer) do
|
1248
|
+
Developer.validates_length_of :name, :minimum => 4, :too_short=> "This string contains 'single' and \"double\" quotes"
|
1249
|
+
d = Developer.new
|
1250
|
+
d.name = "Joe"
|
1251
|
+
assert !d.valid?
|
1252
|
+
assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name)
|
1253
|
+
end
|
1207
1254
|
end
|
1208
1255
|
|
1209
1256
|
def test_validates_length_of_with_custom_message_using_quotes
|
1210
|
-
Developer
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1257
|
+
repair_validations(Developer) do
|
1258
|
+
Developer.validates_length_of :name, :minimum => 4, :message=> "This string contains 'single' and \"double\" quotes"
|
1259
|
+
d = Developer.new
|
1260
|
+
d.name = "Joe"
|
1261
|
+
assert !d.valid?
|
1262
|
+
assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name)
|
1263
|
+
end
|
1215
1264
|
end
|
1216
1265
|
|
1217
1266
|
def test_validates_presence_of_with_custom_message_using_quotes
|
1218
|
-
Developer
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1267
|
+
repair_validations(Developer) do
|
1268
|
+
Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes"
|
1269
|
+
d = Developer.new
|
1270
|
+
d.name = "Joe"
|
1271
|
+
assert !d.valid?
|
1272
|
+
assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:non_existent)
|
1273
|
+
end
|
1223
1274
|
end
|
1224
1275
|
|
1225
1276
|
def test_validates_uniqueness_of_with_custom_message_using_quotes
|
1226
|
-
Developer
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1277
|
+
repair_validations(Developer) do
|
1278
|
+
Developer.validates_uniqueness_of :name, :message=> "This string contains 'single' and \"double\" quotes"
|
1279
|
+
d = Developer.new
|
1280
|
+
d.name = "David"
|
1281
|
+
assert !d.valid?
|
1282
|
+
assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name)
|
1283
|
+
end
|
1231
1284
|
end
|
1232
1285
|
|
1233
1286
|
def test_validates_associated_with_custom_message_using_quotes
|
1234
|
-
Reply
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1287
|
+
repair_validations(Reply) do
|
1288
|
+
Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes"
|
1289
|
+
Topic.validates_presence_of :content
|
1290
|
+
r = Reply.create("title" => "A reply", "content" => "with content!")
|
1291
|
+
r.topic = Topic.create("title" => "uhohuhoh")
|
1292
|
+
assert !r.valid?
|
1293
|
+
assert_equal "This string contains 'single' and \"double\" quotes", r.errors.on(:topic)
|
1294
|
+
end
|
1240
1295
|
end
|
1241
1296
|
|
1242
1297
|
def test_if_validation_using_method_true
|
@@ -1346,13 +1401,15 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
1346
1401
|
end
|
1347
1402
|
|
1348
1403
|
def test_validates_associated_missing
|
1349
|
-
Reply
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1404
|
+
repair_validations(Reply) do
|
1405
|
+
Reply.validates_presence_of(:topic)
|
1406
|
+
r = Reply.create("title" => "A reply", "content" => "with content!")
|
1407
|
+
assert !r.valid?
|
1408
|
+
assert r.errors.on(:topic)
|
1409
|
+
|
1410
|
+
r.topic = Topic.find :first
|
1411
|
+
assert r.valid?
|
1412
|
+
end
|
1356
1413
|
end
|
1357
1414
|
|
1358
1415
|
def test_errors_to_xml
|
@@ -1364,14 +1421,25 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
1364
1421
|
assert xml.include?("<error>Content Empty</error>")
|
1365
1422
|
end
|
1366
1423
|
|
1367
|
-
|
1424
|
+
def test_validation_order
|
1425
|
+
Topic.validates_presence_of :title
|
1426
|
+
Topic.validates_length_of :title, :minimum => 2
|
1427
|
+
|
1428
|
+
t = Topic.new("title" => "")
|
1429
|
+
assert !t.valid?
|
1430
|
+
assert_equal "can't be blank", t.errors.on("title").first
|
1431
|
+
end
|
1432
|
+
|
1433
|
+
def test_invalid_should_be_the_opposite_of_valid
|
1368
1434
|
Topic.validates_presence_of :title
|
1369
|
-
Topic.validates_length_of :title, :minimum => 2
|
1370
1435
|
|
1371
|
-
t = Topic.new
|
1372
|
-
assert
|
1373
|
-
|
1374
|
-
|
1436
|
+
t = Topic.new
|
1437
|
+
assert t.invalid?
|
1438
|
+
assert t.errors.invalid?(:title)
|
1439
|
+
|
1440
|
+
t.title = 'Things are going to change'
|
1441
|
+
assert !t.invalid?
|
1442
|
+
end
|
1375
1443
|
|
1376
1444
|
# previous implementation of validates_presence_of eval'd the
|
1377
1445
|
# string with the wrong binding, this regression test is to
|
@@ -1394,20 +1462,6 @@ class ValidationsTest < ActiveRecord::TestCase
|
|
1394
1462
|
t.author_name = "Hubert J. Farnsworth"
|
1395
1463
|
assert t.valid?, "A topic with an important title and author should be valid"
|
1396
1464
|
end
|
1397
|
-
|
1398
|
-
private
|
1399
|
-
def with_kcode(kcode)
|
1400
|
-
if RUBY_VERSION < '1.9'
|
1401
|
-
orig_kcode, $KCODE = $KCODE, kcode
|
1402
|
-
begin
|
1403
|
-
yield
|
1404
|
-
ensure
|
1405
|
-
$KCODE = orig_kcode
|
1406
|
-
end
|
1407
|
-
else
|
1408
|
-
yield
|
1409
|
-
end
|
1410
|
-
end
|
1411
1465
|
end
|
1412
1466
|
|
1413
1467
|
|
@@ -1423,11 +1477,7 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase
|
|
1423
1477
|
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
1478
|
INFINITY = [1.0/0.0]
|
1425
1479
|
|
1426
|
-
|
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)
|
1430
|
-
end
|
1480
|
+
repair_validations(Topic)
|
1431
1481
|
|
1432
1482
|
def test_default_validates_numericality_of
|
1433
1483
|
Topic.validates_numericality_of :approved
|