activerecord 1.6.0 → 1.7.0
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 +78 -0
- data/README +20 -29
- data/RUNNING_UNIT_TESTS +1 -2
- data/examples/validation.rb +0 -3
- data/install.rb +3 -16
- data/lib/active_record.rb +11 -4
- data/lib/active_record/aggregations.rb +2 -2
- data/lib/active_record/associations.rb +8 -8
- data/lib/active_record/associations/association_collection.rb +1 -1
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -1
- data/lib/active_record/base.rb +117 -43
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +7 -14
- data/lib/active_record/connection_adapters/db2_adapter.rb +33 -22
- data/lib/active_record/connection_adapters/mysql_adapter.rb +74 -33
- data/lib/active_record/connection_adapters/oci_adapter.rb +265 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +23 -3
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +13 -4
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +158 -67
- data/lib/active_record/deprecated_associations.rb +4 -4
- data/lib/active_record/fixtures.rb +12 -5
- data/lib/active_record/locking.rb +22 -22
- data/lib/active_record/observer.rb +6 -3
- data/lib/active_record/timestamp.rb +15 -5
- data/lib/active_record/transactions.rb +4 -4
- data/lib/active_record/validations.rb +272 -189
- data/lib/active_record/wrappings.rb +2 -2
- data/rakefile +17 -2
- data/test/aaa_create_tables_test.rb +58 -0
- data/test/abstract_unit.rb +3 -2
- data/test/aggregations_test.rb +0 -1
- data/test/associations_test.rb +27 -28
- data/test/base_test.rb +74 -2
- data/test/binary_test.rb +6 -2
- data/test/class_inheritable_attributes_test.rb +1 -1
- data/test/column_alias_test.rb +9 -2
- data/test/connections/native_oci/connection.rb +25 -0
- data/test/connections/native_sqlite/connection.rb +4 -1
- data/test/connections/native_sqlite3/connection.rb +4 -2
- data/test/deprecated_associations_test.rb +4 -5
- data/test/finder_test.rb +20 -4
- data/test/fixtures/db_definitions/create_oracle_db.bat +5 -0
- data/test/fixtures/db_definitions/create_oracle_db.sh +5 -0
- data/test/fixtures/db_definitions/db2.drop.sql +18 -0
- data/test/fixtures/db_definitions/db2.sql +1 -0
- data/test/fixtures/db_definitions/db22.drop.sql +2 -0
- data/test/fixtures/db_definitions/db22.sql +1 -0
- data/test/fixtures/db_definitions/drop_oracle_tables.sql +35 -0
- data/test/fixtures/db_definitions/drop_oracle_tables2.sql +3 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +18 -0
- data/test/fixtures/db_definitions/mysql.sql +2 -1
- data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql2.sql +1 -0
- data/test/fixtures/db_definitions/oci.drop.sql +18 -0
- data/test/fixtures/db_definitions/oci.sql +167 -0
- data/test/fixtures/db_definitions/oci2.drop.sql +2 -0
- data/test/fixtures/db_definitions/oci2.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +18 -0
- data/test/fixtures/db_definitions/postgresql.sql +2 -1
- data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/postgresql2.sql +2 -1
- data/test/fixtures/db_definitions/sqlite.drop.sql +18 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite2.sql +1 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +18 -0
- data/test/fixtures/db_definitions/sqlserver.sql +1 -0
- data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver2.sql +1 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/topics.yml +3 -3
- data/test/lifecycle_test.rb +0 -1
- data/test/modules_test.rb +0 -1
- data/test/reflection_test.rb +0 -1
- data/test/validations_test.rb +229 -41
- metadata +36 -28
- data/dev-utils/eval_debugger.rb +0 -14
- data/lib/active_record/support/binding_of_caller.rb +0 -83
- data/lib/active_record/support/breakpoint.rb +0 -518
- data/lib/active_record/support/class_attribute_accessors.rb +0 -57
- data/lib/active_record/support/class_inheritable_attributes.rb +0 -117
- data/lib/active_record/support/clean_logger.rb +0 -10
- data/lib/active_record/support/core_ext.rb +0 -1
- data/lib/active_record/support/core_ext/hash.rb +0 -5
- data/lib/active_record/support/core_ext/hash/keys.rb +0 -35
- data/lib/active_record/support/core_ext/numeric.rb +0 -7
- data/lib/active_record/support/core_ext/numeric/bytes.rb +0 -33
- data/lib/active_record/support/core_ext/numeric/time.rb +0 -59
- data/lib/active_record/support/core_ext/object_and_class.rb +0 -24
- data/lib/active_record/support/core_ext/string.rb +0 -5
- data/lib/active_record/support/core_ext/string/inflections.rb +0 -45
- data/lib/active_record/support/dependencies.rb +0 -63
- data/lib/active_record/support/inflector.rb +0 -84
- data/lib/active_record/support/misc.rb +0 -8
- data/lib/active_record/support/module_attribute_accessors.rb +0 -57
@@ -0,0 +1,18 @@
|
|
1
|
+
DROP TABLE accounts;
|
2
|
+
DROP TABLE companies;
|
3
|
+
DROP TABLE topics;
|
4
|
+
DROP TABLE developers;
|
5
|
+
DROP TABLE projects;
|
6
|
+
DROP TABLE developers_projects;
|
7
|
+
DROP TABLE customers;
|
8
|
+
DROP TABLE movies;
|
9
|
+
DROP TABLE subscribers;
|
10
|
+
DROP TABLE booleantests;
|
11
|
+
DROP TABLE auto_id_tests;
|
12
|
+
DROP TABLE entrants;
|
13
|
+
DROP TABLE colnametests;
|
14
|
+
DROP TABLE mixins;
|
15
|
+
DROP TABLE people;
|
16
|
+
DROP TABLE binaries;
|
17
|
+
DROP TABLE computers;
|
18
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
DROP TABLE accounts;
|
2
|
+
DROP TABLE companies;
|
3
|
+
DROP TABLE topics;
|
4
|
+
DROP TABLE developers;
|
5
|
+
DROP TABLE projects;
|
6
|
+
DROP TABLE developers_projects;
|
7
|
+
DROP TABLE customers;
|
8
|
+
DROP TABLE movies;
|
9
|
+
DROP TABLE subscribers;
|
10
|
+
DROP TABLE booleantests;
|
11
|
+
DROP TABLE auto_id_tests;
|
12
|
+
DROP TABLE entrants;
|
13
|
+
DROP TABLE colnametests;
|
14
|
+
DROP TABLE mixins;
|
15
|
+
DROP TABLE people;
|
16
|
+
DROP TABLE binaries;
|
17
|
+
DROP TABLE computers;
|
18
|
+
|
Binary file
|
Binary file
|
data/test/fixtures/topics.yml
CHANGED
@@ -3,9 +3,9 @@ first:
|
|
3
3
|
title: The First Topic
|
4
4
|
author_name: David
|
5
5
|
author_email_address: david@loudthinking.com
|
6
|
-
written_on: 2003-07-
|
7
|
-
bonus_time: '12:13:14'
|
6
|
+
written_on: 2003-07-16t15:28:00.00+01:00
|
8
7
|
last_read: 2004-04-15
|
8
|
+
bonus_time: 2005-01-30t15:28:00.00+01:00
|
9
9
|
content: Have a nice day
|
10
10
|
approved: 0
|
11
11
|
replies_count: 0
|
@@ -14,7 +14,7 @@ second:
|
|
14
14
|
id: 2
|
15
15
|
title: The Second Topic's of the day
|
16
16
|
author_name: Mary
|
17
|
-
written_on: 2003-07-
|
17
|
+
written_on: 2003-07-15t15:28:00.00+01:00
|
18
18
|
content: Have a nice day
|
19
19
|
approved: 1
|
20
20
|
replies_count: 2
|
data/test/lifecycle_test.rb
CHANGED
data/test/modules_test.rb
CHANGED
data/test/reflection_test.rb
CHANGED
data/test/validations_test.rb
CHANGED
@@ -6,9 +6,10 @@ require 'fixtures/developer'
|
|
6
6
|
class ValidationsTest < Test::Unit::TestCase
|
7
7
|
fixtures :topics, :developers
|
8
8
|
|
9
|
-
def
|
10
|
-
Topic.write_inheritable_attribute(
|
11
|
-
Topic.write_inheritable_attribute(
|
9
|
+
def setup
|
10
|
+
Topic.write_inheritable_attribute(:validate, nil)
|
11
|
+
Topic.write_inheritable_attribute(:validate_on_create, nil)
|
12
|
+
Topic.write_inheritable_attribute(:validate_on_update, nil)
|
12
13
|
end
|
13
14
|
|
14
15
|
def test_single_field_validation
|
@@ -19,7 +20,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
19
20
|
r.content = "Messa content!"
|
20
21
|
assert r.save, "A reply with content should be saveable"
|
21
22
|
end
|
22
|
-
|
23
|
+
|
23
24
|
def test_single_attr_validation_and_error_msg
|
24
25
|
r = Reply.new
|
25
26
|
r.title = "There's no content!"
|
@@ -41,7 +42,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
41
42
|
|
42
43
|
assert_equal 2, r.errors.count
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
def test_error_on_create
|
46
47
|
r = Reply.new
|
47
48
|
r.title = "Wrong Create"
|
@@ -50,57 +51,55 @@ class ValidationsTest < Test::Unit::TestCase
|
|
50
51
|
assert_equal "is Wrong Create", r.errors.on("title"), "A reply with a bad content should contain an error"
|
51
52
|
end
|
52
53
|
|
53
|
-
|
54
54
|
def test_error_on_update
|
55
55
|
r = Reply.new
|
56
56
|
r.title = "Bad"
|
57
57
|
r.content = "Good"
|
58
|
-
|
59
58
|
assert r.save, "First save should be successful"
|
60
|
-
|
59
|
+
|
61
60
|
r.title = "Wrong Update"
|
62
61
|
assert !r.save, "Second save should fail"
|
63
|
-
|
62
|
+
|
64
63
|
assert r.errors.invalid?("title"), "A reply with a bad title should mark that attribute as invalid"
|
65
64
|
assert_equal "is Wrong Update", r.errors.on("title"), "A reply with a bad content should contain an error"
|
66
65
|
end
|
67
|
-
|
66
|
+
|
68
67
|
def test_single_error_per_attr_iteration
|
69
68
|
r = Reply.new
|
70
69
|
r.save
|
71
|
-
|
70
|
+
|
72
71
|
errors = []
|
73
72
|
r.errors.each { |attr, msg| errors << [attr, msg] }
|
74
|
-
|
73
|
+
|
75
74
|
assert errors.include?(["title", "Empty"])
|
76
75
|
assert errors.include?(["content", "Empty"])
|
77
76
|
end
|
78
|
-
|
77
|
+
|
79
78
|
def test_multiple_errors_per_attr_iteration_with_full_error_composition
|
80
79
|
r = Reply.new
|
81
80
|
r.title = "Wrong Create"
|
82
81
|
r.content = "Mismatch"
|
83
82
|
r.save
|
84
|
-
|
83
|
+
|
85
84
|
errors = []
|
86
85
|
r.errors.each_full { |error| errors << error }
|
87
|
-
|
86
|
+
|
88
87
|
assert_equal "Title is Wrong Create", errors[0]
|
89
88
|
assert_equal "Title is Content Mismatch", errors[1]
|
90
89
|
assert_equal 2, r.errors.count
|
91
90
|
end
|
92
|
-
|
91
|
+
|
93
92
|
def test_errors_on_base
|
94
93
|
r = Reply.new
|
95
94
|
r.content = "Mismatch"
|
96
95
|
r.save
|
97
96
|
r.errors.add_to_base "Reply is not dignifying"
|
98
|
-
|
97
|
+
|
99
98
|
errors = []
|
100
99
|
r.errors.each_full { |error| errors << error }
|
101
|
-
|
100
|
+
|
102
101
|
assert_equal "Reply is not dignifying", r.errors.on_base
|
103
|
-
|
102
|
+
|
104
103
|
assert errors.include?("Title Empty")
|
105
104
|
assert errors.include?("Reply is not dignifying")
|
106
105
|
assert_equal 2, r.errors.count
|
@@ -111,12 +110,30 @@ class ValidationsTest < Test::Unit::TestCase
|
|
111
110
|
assert !reply.save
|
112
111
|
assert reply.save(false)
|
113
112
|
end
|
114
|
-
|
113
|
+
|
114
|
+
def test_validates_each
|
115
|
+
perform = true
|
116
|
+
hits = 0
|
117
|
+
Topic.validates_each(:title, :content, [:title, :content]) do |record, attr|
|
118
|
+
if perform
|
119
|
+
record.errors.add attr, 'gotcha'
|
120
|
+
hits += 1
|
121
|
+
end
|
122
|
+
end
|
123
|
+
t = Topic.new("title" => "valid", "content" => "whatever")
|
124
|
+
assert !t.save
|
125
|
+
assert_equal 4, hits
|
126
|
+
assert_equal %w(gotcha gotcha), t.errors.on(:title)
|
127
|
+
assert_equal %w(gotcha gotcha), t.errors.on(:content)
|
128
|
+
ensure
|
129
|
+
perform = false
|
130
|
+
end
|
131
|
+
|
115
132
|
def test_errors_on_boundary_breaking
|
116
133
|
developer = Developer.new("name" => "xs")
|
117
134
|
assert !developer.save
|
118
135
|
assert_equal "is too short (min is 3 characters)", developer.errors.on("name")
|
119
|
-
|
136
|
+
|
120
137
|
developer.name = "All too very long for this boundary, it really is"
|
121
138
|
assert !developer.save
|
122
139
|
assert_equal "is too long (max is 20 characters)", developer.errors.on("name")
|
@@ -127,11 +144,11 @@ class ValidationsTest < Test::Unit::TestCase
|
|
127
144
|
|
128
145
|
def test_title_confirmation_no_confirm
|
129
146
|
Topic.validates_confirmation_of(:title)
|
130
|
-
|
147
|
+
|
131
148
|
t = Topic.create("title" => "We should not be confirmed")
|
132
149
|
assert t.save
|
133
150
|
end
|
134
|
-
|
151
|
+
|
135
152
|
def test_title_confirmation
|
136
153
|
Topic.validates_confirmation_of(:title)
|
137
154
|
|
@@ -171,7 +188,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
171
188
|
t.eula = "1"
|
172
189
|
assert t.save
|
173
190
|
end
|
174
|
-
|
191
|
+
|
175
192
|
def test_validate_presences
|
176
193
|
Topic.validates_presence_of(:title, :content)
|
177
194
|
|
@@ -179,16 +196,16 @@ class ValidationsTest < Test::Unit::TestCase
|
|
179
196
|
assert !t.save
|
180
197
|
assert_equal "can't be empty", t.errors.on(:title)
|
181
198
|
assert_equal "can't be empty", t.errors.on(:content)
|
182
|
-
|
199
|
+
|
183
200
|
t.title = "something"
|
184
201
|
t.content = "another"
|
185
|
-
|
202
|
+
|
186
203
|
assert t.save
|
187
204
|
end
|
188
|
-
|
205
|
+
|
189
206
|
def test_validate_uniqueness
|
190
207
|
Topic.validates_uniqueness_of(:title)
|
191
|
-
|
208
|
+
|
192
209
|
t = Topic.new("title" => "I'm unique!")
|
193
210
|
assert t.save, "Should save t as unique"
|
194
211
|
|
@@ -199,14 +216,14 @@ class ValidationsTest < Test::Unit::TestCase
|
|
199
216
|
assert !t2.valid?, "Shouldn't be valid"
|
200
217
|
assert !t2.save, "Shouldn't save t2 as unique"
|
201
218
|
assert_equal "has already been taken", t2.errors.on(:title)
|
202
|
-
|
219
|
+
|
203
220
|
t2.title = "Now Im really also unique"
|
204
221
|
assert t2.save, "Should now save t2 as unique"
|
205
222
|
end
|
206
223
|
|
207
224
|
def test_validate_uniqueness_with_scope
|
208
225
|
Reply.validates_uniqueness_of(:content, :scope => "parent_id")
|
209
|
-
|
226
|
+
|
210
227
|
t = Topic.create("title" => "I'm unique!")
|
211
228
|
|
212
229
|
r1 = t.replies.create "title" => "r1", "content" => "hello world"
|
@@ -246,8 +263,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
246
263
|
assert !Topic.create("title" => "a!", "content" => "abc").valid?
|
247
264
|
assert !Topic.create("title" => "a b", "content" => "abc").valid?
|
248
265
|
assert !Topic.create("title" => nil, "content" => "def").valid?
|
249
|
-
|
250
|
-
|
266
|
+
|
251
267
|
t = Topic.create("title" => "a", "content" => "I know you are but what am I?")
|
252
268
|
assert t.valid?
|
253
269
|
t.title = "uhoh"
|
@@ -272,32 +288,61 @@ class ValidationsTest < Test::Unit::TestCase
|
|
272
288
|
end
|
273
289
|
|
274
290
|
def test_validates_length_of_using_minimum
|
275
|
-
Topic.validates_length_of
|
291
|
+
Topic.validates_length_of :title, :minimum => 5
|
292
|
+
|
276
293
|
t = Topic.create("title" => "valid", "content" => "whatever")
|
277
294
|
assert t.valid?
|
295
|
+
|
278
296
|
t.title = "not"
|
279
297
|
assert !t.valid?
|
280
298
|
assert t.errors.on(:title)
|
281
299
|
assert_equal "is too short (min is 5 characters)", t.errors["title"]
|
300
|
+
|
282
301
|
t.title = ""
|
283
302
|
assert !t.valid?
|
284
303
|
assert t.errors.on(:title)
|
304
|
+
assert_equal "is too short (min is 5 characters)", t.errors["title"]
|
305
|
+
|
285
306
|
t.title = nil
|
286
307
|
assert !t.valid?
|
287
|
-
assert_equal "is too short (min is 5 characters)", t.errors["title"]
|
288
308
|
assert t.errors.on(:title)
|
309
|
+
assert_equal "is too short (min is 5 characters)", t.errors["title"]
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_optionally_validates_length_of_using_minimum
|
313
|
+
Topic.validates_length_of :title, :minimum => 5, :allow_nil => true
|
314
|
+
|
315
|
+
t = Topic.create("title" => "valid", "content" => "whatever")
|
316
|
+
assert t.valid?
|
317
|
+
|
318
|
+
t.title = nil
|
319
|
+
assert t.valid?
|
289
320
|
end
|
290
|
-
|
321
|
+
|
291
322
|
def test_validates_length_of_using_maximum
|
292
|
-
Topic.validates_length_of
|
323
|
+
Topic.validates_length_of :title, :maximum => 5
|
324
|
+
|
293
325
|
t = Topic.create("title" => "valid", "content" => "whatever")
|
294
326
|
assert t.valid?
|
327
|
+
|
295
328
|
t.title = "notvalid"
|
296
329
|
assert !t.valid?
|
297
330
|
assert t.errors.on(:title)
|
298
331
|
assert_equal "is too long (max is 5 characters)", t.errors["title"]
|
332
|
+
|
299
333
|
t.title = ""
|
300
334
|
assert t.valid?
|
335
|
+
|
336
|
+
t.title = nil
|
337
|
+
assert !t.valid?
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_optionally_validates_length_of_using_maximum
|
341
|
+
Topic.validates_length_of :title, :maximum => 5, :allow_nil => true
|
342
|
+
|
343
|
+
t = Topic.create("title" => "valid", "content" => "whatever")
|
344
|
+
assert t.valid?
|
345
|
+
|
301
346
|
t.title = nil
|
302
347
|
assert t.valid?
|
303
348
|
end
|
@@ -307,29 +352,75 @@ class ValidationsTest < Test::Unit::TestCase
|
|
307
352
|
|
308
353
|
t = Topic.create("title" => "a!", "content" => "I'm ooooooooh so very long")
|
309
354
|
assert !t.save
|
355
|
+
|
310
356
|
assert_equal "is too short (min is 3 characters)", t.errors.on(:title)
|
311
357
|
assert_equal "is too long (max is 5 characters)", t.errors.on(:content)
|
312
358
|
|
313
359
|
t.title = "abe"
|
314
360
|
t.content = "mad"
|
315
|
-
|
316
361
|
assert t.save
|
317
362
|
end
|
318
363
|
|
364
|
+
def test_optionally_validates_length_of_using_within
|
365
|
+
Topic.validates_length_of :title, :content, :within => 3..5, :allow_nil => true
|
366
|
+
|
367
|
+
t = Topic.create('title' => 'abc', 'content' => 'abcd')
|
368
|
+
assert t.valid?
|
369
|
+
|
370
|
+
t.title = nil
|
371
|
+
assert t.valid?
|
372
|
+
end
|
373
|
+
|
319
374
|
def test_validates_length_of_using_is
|
320
|
-
Topic.validates_length_of
|
375
|
+
Topic.validates_length_of :title, :is => 5
|
376
|
+
|
321
377
|
t = Topic.create("title" => "valid", "content" => "whatever")
|
322
378
|
assert t.valid?
|
379
|
+
|
323
380
|
t.title = "notvalid"
|
324
381
|
assert !t.valid?
|
325
382
|
assert t.errors.on(:title)
|
326
383
|
assert_equal "is the wrong length (should be 5 characters)", t.errors["title"]
|
384
|
+
|
327
385
|
t.title = ""
|
328
386
|
assert !t.valid?
|
387
|
+
|
329
388
|
t.title = nil
|
330
389
|
assert !t.valid?
|
331
390
|
end
|
332
391
|
|
392
|
+
def test_optionally_validates_length_of_using_is
|
393
|
+
Topic.validates_length_of :title, :is => 5, :allow_nil => true
|
394
|
+
|
395
|
+
t = Topic.create("title" => "valid", "content" => "whatever")
|
396
|
+
assert t.valid?
|
397
|
+
|
398
|
+
t.title = nil
|
399
|
+
assert t.valid?
|
400
|
+
end
|
401
|
+
|
402
|
+
def test_validates_length_of_using_bignum
|
403
|
+
bigmin = 2 ** 30
|
404
|
+
bigmax = 2 ** 32
|
405
|
+
bigrange = bigmin...bigmax
|
406
|
+
assert_nothing_raised do
|
407
|
+
Topic.validates_length_of :title, :is => bigmin + 5
|
408
|
+
Topic.validates_length_of :title, :within => bigrange
|
409
|
+
Topic.validates_length_of :title, :in => bigrange
|
410
|
+
Topic.validates_length_of :title, :minimum => bigmin
|
411
|
+
Topic.validates_length_of :title, :maximum => bigmax
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
def test_validates_size_of_association
|
416
|
+
assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 }
|
417
|
+
t = Topic.new('title' => 'noreplies', 'content' => 'whatever')
|
418
|
+
assert !t.save
|
419
|
+
assert t.errors.on(:replies)
|
420
|
+
t.replies.create('title' => 'areply', 'content' => 'whateveragain')
|
421
|
+
assert t.valid?
|
422
|
+
end
|
423
|
+
|
333
424
|
def test_validates_length_of_nasty_params
|
334
425
|
assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>6, :maximum=>9) }
|
335
426
|
assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :maximum=>9) }
|
@@ -372,7 +463,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
372
463
|
assert t.errors.on(:title)
|
373
464
|
assert_equal "hoo 5", t.errors["title"]
|
374
465
|
end
|
375
|
-
|
466
|
+
|
376
467
|
def test_validates_length_of_custom_errors_for_is_with_message
|
377
468
|
Topic.validates_length_of( :title, :is=>5, :message=>"boo %d" )
|
378
469
|
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
@@ -392,10 +483,12 @@ class ValidationsTest < Test::Unit::TestCase
|
|
392
483
|
def test_validates_associated_many
|
393
484
|
Topic.validates_associated( :replies )
|
394
485
|
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
395
|
-
t.replies << [r = Reply.create("title" => "A reply"), Reply.create("title" => "Another reply"
|
486
|
+
t.replies << [r = Reply.create("title" => "A reply"), r2 = Reply.create("title" => "Another reply")]
|
396
487
|
assert !t.valid?
|
397
488
|
assert t.errors.on(:replies)
|
398
|
-
r.
|
489
|
+
assert_equal 1, r.errors.count # make sure all associated objects have been validated
|
490
|
+
assert_equal 1, r2.errors.count
|
491
|
+
r.content = r2.content = "non-empty"
|
399
492
|
assert t.valid?
|
400
493
|
end
|
401
494
|
|
@@ -410,10 +503,105 @@ class ValidationsTest < Test::Unit::TestCase
|
|
410
503
|
assert r.valid?
|
411
504
|
end
|
412
505
|
|
506
|
+
def test_validate_block
|
507
|
+
Topic.validate { |topic| topic.errors.add("title", "will never be valid") }
|
508
|
+
t = Topic.create("title" => "Title", "content" => "whatever")
|
509
|
+
assert !t.valid?
|
510
|
+
assert t.errors.on(:title)
|
511
|
+
assert_equal "will never be valid", t.errors["title"]
|
512
|
+
end
|
513
|
+
|
514
|
+
def test_invalid_validator
|
515
|
+
Topic.validate 3
|
516
|
+
assert_raise(ActiveRecord::ActiveRecordError) { t = Topic.create }
|
517
|
+
end
|
518
|
+
|
413
519
|
def test_throw_away_typing
|
414
520
|
d = Developer.create "name" => "David", "salary" => "100,000"
|
415
521
|
assert !d.valid?
|
416
522
|
assert_equal 100, d.salary
|
417
523
|
assert_equal "100,000", d.salary_before_type_cast
|
418
524
|
end
|
525
|
+
|
526
|
+
def test_validates_acceptance_of_with_custom_error_using_quotes
|
527
|
+
Developer.validates_acceptance_of :salary, :message=> "This string contains 'single' and \"double\" quotes"
|
528
|
+
d = Developer.new
|
529
|
+
d.salary = "0"
|
530
|
+
assert !d.valid?
|
531
|
+
assert_equal d.errors.on(:salary).first, "This string contains 'single' and \"double\" quotes"
|
532
|
+
end
|
533
|
+
|
534
|
+
def test_validates_confirmation_of_with_custom_error_using_quotes
|
535
|
+
Developer.validates_confirmation_of :name, :message=> "This string contains 'single' and \"double\" quotes"
|
536
|
+
d = Developer.new
|
537
|
+
d.name = "John"
|
538
|
+
d.name_confirmation = "Johnny"
|
539
|
+
assert !d.valid?
|
540
|
+
assert_equal d.errors.on(:name), "This string contains 'single' and \"double\" quotes"
|
541
|
+
end
|
542
|
+
|
543
|
+
def test_validates_format_of_with_custom_error_using_quotes
|
544
|
+
Developer.validates_format_of :name, :with => /^(A-Z*)$/, :message=> "This string contains 'single' and \"double\" quotes"
|
545
|
+
d = Developer.new
|
546
|
+
d.name = "John 32"
|
547
|
+
assert !d.valid?
|
548
|
+
assert_equal d.errors.on(:name), "This string contains 'single' and \"double\" quotes"
|
549
|
+
end
|
550
|
+
|
551
|
+
def test_validates_inclusion_of_with_custom_error_using_quotes
|
552
|
+
Developer.validates_inclusion_of :salary, :in => 1000..80000, :message=> "This string contains 'single' and \"double\" quotes"
|
553
|
+
d = Developer.new
|
554
|
+
d.salary = "90,000"
|
555
|
+
assert !d.valid?
|
556
|
+
assert_equal d.errors.on(:salary).first, "This string contains 'single' and \"double\" quotes"
|
557
|
+
end
|
558
|
+
|
559
|
+
def test_validates_length_of_with_custom_too_long_using_quotes
|
560
|
+
Developer.validates_length_of :name, :maximum => 4, :too_long=> "This string contains 'single' and \"double\" quotes"
|
561
|
+
d = Developer.new
|
562
|
+
d.name = "Jeffrey"
|
563
|
+
assert !d.valid?
|
564
|
+
assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes"
|
565
|
+
end
|
566
|
+
|
567
|
+
def test_validates_length_of_with_custom_too_short_using_quotes
|
568
|
+
Developer.validates_length_of :name, :minimum => 4, :too_short=> "This string contains 'single' and \"double\" quotes"
|
569
|
+
d = Developer.new
|
570
|
+
d.name = "Joe"
|
571
|
+
assert !d.valid?
|
572
|
+
assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes"
|
573
|
+
end
|
574
|
+
|
575
|
+
def test_validates_length_of_with_custom_message_using_quotes
|
576
|
+
Developer.validates_length_of :name, :minimum => 4, :message=> "This string contains 'single' and \"double\" quotes"
|
577
|
+
d = Developer.new
|
578
|
+
d.name = "Joe"
|
579
|
+
assert !d.valid?
|
580
|
+
assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes"
|
581
|
+
end
|
582
|
+
|
583
|
+
def test_validates_presence_of_with_custom_message_using_quotes
|
584
|
+
Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes"
|
585
|
+
d = Developer.new
|
586
|
+
d.name = "Joe"
|
587
|
+
assert !d.valid?
|
588
|
+
assert_equal d.errors.on(:non_existent), "This string contains 'single' and \"double\" quotes"
|
589
|
+
end
|
590
|
+
|
591
|
+
def test_validates_uniqueness_of_with_custom_message_using_quotes
|
592
|
+
Developer.validates_uniqueness_of :name, :message=> "This string contains 'single' and \"double\" quotes"
|
593
|
+
d = Developer.new
|
594
|
+
d.name = "David"
|
595
|
+
assert !d.valid?
|
596
|
+
assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes"
|
597
|
+
end
|
598
|
+
|
599
|
+
def test_validates_associated_with_custom_message_using_quotes
|
600
|
+
Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes"
|
601
|
+
Topic.validates_presence_of :content
|
602
|
+
r = Reply.create("title" => "A reply", "content" => "with content!")
|
603
|
+
r.topic = Topic.create("title" => "uhohuhoh")
|
604
|
+
assert !r.valid?
|
605
|
+
assert_equal r.errors.on(:topic).first, "This string contains 'single' and \"double\" quotes"
|
606
|
+
end
|
419
607
|
end
|