activerecord 1.1.0 → 1.2.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.

Files changed (68) hide show
  1. data/CHANGELOG +250 -0
  2. data/README +17 -9
  3. data/dev-utils/eval_debugger.rb +1 -1
  4. data/install.rb +3 -1
  5. data/lib/active_record.rb +9 -2
  6. data/lib/active_record/acts/list.rb +178 -0
  7. data/lib/active_record/acts/tree.rb +44 -0
  8. data/lib/active_record/associations.rb +45 -8
  9. data/lib/active_record/associations/association_collection.rb +18 -9
  10. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +14 -13
  11. data/lib/active_record/associations/has_many_association.rb +21 -12
  12. data/lib/active_record/base.rb +137 -37
  13. data/lib/active_record/callbacks.rb +30 -25
  14. data/lib/active_record/connection_adapters/abstract_adapter.rb +57 -33
  15. data/lib/active_record/connection_adapters/mysql_adapter.rb +4 -0
  16. data/lib/active_record/connection_adapters/sqlite_adapter.rb +3 -2
  17. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +298 -0
  18. data/lib/active_record/fixtures.rb +241 -147
  19. data/lib/active_record/support/class_inheritable_attributes.rb +5 -2
  20. data/lib/active_record/support/inflector.rb +13 -12
  21. data/lib/active_record/support/misc.rb +6 -0
  22. data/lib/active_record/timestamp.rb +33 -0
  23. data/lib/active_record/transactions.rb +1 -1
  24. data/lib/active_record/validations.rb +294 -16
  25. data/rakefile +3 -7
  26. data/test/abstract_unit.rb +1 -4
  27. data/test/associations_test.rb +17 -4
  28. data/test/base_test.rb +37 -5
  29. data/test/connections/native_sqlserver/connection.rb +15 -0
  30. data/test/deprecated_associations_test.rb +40 -38
  31. data/test/finder_test.rb +82 -4
  32. data/test/fixtures/accounts.yml +8 -0
  33. data/test/fixtures/company.rb +6 -0
  34. data/test/fixtures/company_in_module.rb +1 -1
  35. data/test/fixtures/db_definitions/mysql.sql +13 -0
  36. data/test/fixtures/db_definitions/postgresql.sql +13 -0
  37. data/test/fixtures/db_definitions/sqlite.sql +14 -0
  38. data/test/fixtures/db_definitions/sqlserver.sql +110 -0
  39. data/test/fixtures/db_definitions/sqlserver2.sql +4 -0
  40. data/test/fixtures/developer.rb +2 -2
  41. data/test/fixtures/developers.yml +13 -0
  42. data/test/fixtures/fixture_database.sqlite +0 -0
  43. data/test/fixtures/fixture_database_2.sqlite +0 -0
  44. data/test/fixtures/mixin.rb +17 -0
  45. data/test/fixtures/mixins.yml +14 -0
  46. data/test/fixtures/naked/csv/accounts.csv +1 -0
  47. data/test/fixtures/naked/yml/accounts.yml +1 -0
  48. data/test/fixtures/naked/yml/companies.yml +1 -0
  49. data/test/fixtures/naked/yml/courses.yml +1 -0
  50. data/test/fixtures/project.rb +6 -0
  51. data/test/fixtures/reply.rb +14 -1
  52. data/test/fixtures/topic.rb +2 -2
  53. data/test/fixtures/topics/first +1 -0
  54. data/test/fixtures_test.rb +42 -12
  55. data/test/inflector_test.rb +2 -1
  56. data/test/inheritance_test.rb +22 -12
  57. data/test/mixin_test.rb +138 -0
  58. data/test/pk_test.rb +4 -2
  59. data/test/reflection_test.rb +3 -3
  60. data/test/transactions_test.rb +15 -0
  61. data/test/validations_test.rb +229 -4
  62. metadata +24 -10
  63. data/lib/active_record/associations.rb.orig +0 -555
  64. data/test/deprecated_associations_test.rb.orig +0 -334
  65. data/test/fixtures/accounts/signals37 +0 -3
  66. data/test/fixtures/accounts/unknown +0 -2
  67. data/test/fixtures/developers/david +0 -2
  68. data/test/fixtures/developers/jamis +0 -2
@@ -1,9 +1,9 @@
1
1
  class Topic < ActiveRecord::Base
2
- has_many :replies, :foreign_key => "parent_id"
2
+ has_many :replies, :dependent => true, :foreign_key => "parent_id"
3
3
  serialize :content
4
4
 
5
5
  before_create :default_written_on
6
- before_destroy :destroy_children #'self.class.delete_all "parent_id = #{id}"'
6
+ before_destroy :destroy_children
7
7
 
8
8
  def parent
9
9
  self.class.find(parent_id)
@@ -3,6 +3,7 @@ title => The First Topic
3
3
  author_name => David
4
4
  author_email_address => david@loudthinking.com
5
5
  written_on => 2003-07-16 15:28
6
+ bonus_time => 12:13:14
6
7
  last_read => 2004-04-15
7
8
  content => Have a nice day
8
9
  approved => 0
@@ -1,19 +1,16 @@
1
1
  require 'abstract_unit'
2
2
  require 'fixtures/topic'
3
3
  require 'fixtures/developer'
4
+ require 'fixtures/company'
4
5
 
5
6
  class FixturesTest < Test::Unit::TestCase
6
- fixtures :topics, :developers
7
-
7
+ fixtures :topics, :developers, :accounts
8
+
8
9
  FIXTURES = %w( accounts companies customers
9
10
  developers developers_projects entrants
10
11
  movies projects subscribers topics )
11
12
  MATCH_ATTRIBUTE_NAME = /[a-zA-Z][-_\w]*/
12
13
 
13
- def setup
14
- # just to annoy
15
- end
16
-
17
14
  def test_clean_fixtures
18
15
  FIXTURES.each do |name|
19
16
  fixtures = nil
@@ -52,28 +49,61 @@ class FixturesTest < Test::Unit::TestCase
52
49
  def test_bad_format
53
50
  path = File.join(File.dirname(__FILE__), 'fixtures', 'bad_fixtures')
54
51
  Dir.entries(path).each do |file|
55
- next unless File.file?(file) and file !~ %r(^.|.yaml$)
52
+ next unless File.file?(file) and file !~ Fixtures::DEFAULT_FILTER_RE
56
53
  assert_raise(Fixture::FormatError) {
57
54
  Fixture.new(bad_fixtures_path, file)
58
55
  }
59
56
  end
60
57
  end
61
58
 
59
+ def test_deprecated_yaml_extension
60
+ assert_raise(Fixture::FormatError) {
61
+ Fixtures.new(nil, 'bad_extension', File.join(File.dirname(__FILE__), 'fixtures'))
62
+ }
63
+ end
64
+
62
65
  def test_logger_level_invariant
63
66
  level = ActiveRecord::Base.logger.level
64
67
  create_fixtures('topics')
65
68
  assert_equal level, ActiveRecord::Base.logger.level
66
69
  end
67
-
70
+
68
71
  def test_instantiation
69
72
  topics = create_fixtures("topics")
70
73
  assert_kind_of Topic, topics["first"].find
71
74
  end
72
-
75
+
73
76
  def test_complete_instantiation
74
- # instantiate_fixtures "topics", "developers"
75
77
  assert_equal 2, @topics.size
76
- assert_equal 2, @developers.size
77
78
  assert_equal "The First Topic", @first.title
78
79
  end
79
- end
80
+
81
+ def test_fixtures_from_root_yml_with_instantiation
82
+ # assert_equal 2, @accounts.size
83
+ assert_equal 50, @unknown.credit_limit
84
+ end
85
+
86
+ def test_erb_in_fixtures
87
+ assert_equal 10, @developers.size
88
+ assert_equal "fixture_5", @dev_5.name
89
+ end
90
+
91
+ def test_empty_yaml_fixture
92
+ assert_not_nil Fixtures.new( Account.connection, "accounts", File.dirname(__FILE__) + "/fixtures/naked/yml/accounts")
93
+ end
94
+
95
+ def test_empty_yaml_fixture_with_a_comment_in_it
96
+ assert_not_nil Fixtures.new( Account.connection, "companies", File.dirname(__FILE__) + "/fixtures/naked/yml/companies")
97
+ end
98
+
99
+ def test_dirty_dirty_yaml_file
100
+ assert_raises(Fixture::FormatError) do
101
+ Fixtures.new( Account.connection, "courses", File.dirname(__FILE__) + "/fixtures/naked/yml/courses")
102
+ end
103
+ end
104
+
105
+ def test_empty_csv_fixtures
106
+ assert_not_nil Fixtures.new( Account.connection, "accounts", File.dirname(__FILE__) + "/fixtures/naked/csv/accounts")
107
+ end
108
+
109
+ end
@@ -15,6 +15,7 @@ class InflectorTest < Test::Unit::TestCase
15
15
  "query" => "queries",
16
16
  "ability" => "abilities",
17
17
  "agency" => "agencies",
18
+ "movie" => "movies",
18
19
 
19
20
  "wife" => "wives",
20
21
  "safe" => "saves",
@@ -46,7 +47,7 @@ class InflectorTest < Test::Unit::TestCase
46
47
  CamelToUnderscore = {
47
48
  "Product" => "product",
48
49
  "SpecialGuest" => "special_guest",
49
- "AbstractApplicationController" => "abstract_application_controller"
50
+ "ApplicationController" => "application_controller"
50
51
  }
51
52
 
52
53
  ClassNameToForeignKeyWithUnderscore = {
@@ -1,20 +1,13 @@
1
1
  require 'abstract_unit'
2
2
  require 'fixtures/company'
3
-
3
+ require 'fixtures/project'
4
4
 
5
5
  class InheritanceTest < Test::Unit::TestCase
6
- def setup
7
- @company_fixtures = create_fixtures "companies"
8
- end
6
+ fixtures :companies, :projects
9
7
 
10
- def switch_to_alt_inheritance_column
11
- # we don't want misleading test results, so get rid of the values in the type column
12
- Company.find_all(nil, "id").each do |c|
13
- c['type'] = nil
14
- c.save
15
- end
16
-
17
- def Company.inheritance_column() "ruby_type" end
8
+ def test_a_bad_type_column
9
+ Company.connection.insert "INSERT INTO companies (id, type, name) VALUES(100, 'bad_class!', 'Not happening')"
10
+ assert_raises(ActiveRecord::SubclassNotFound) { Company.find(100) }
18
11
  end
19
12
 
20
13
  def test_inheritance_find
@@ -122,4 +115,21 @@ class InheritanceTest < Test::Unit::TestCase
122
115
  switch_to_alt_inheritance_column
123
116
  test_complex_inheritance
124
117
  end
118
+
119
+ def test_inheritance_without_mapping
120
+ assert_kind_of SpecialProject, SpecialProject.find(1)
121
+ assert_nothing_raised { SpecialProject.create("name" => "And breaaaaathe!") }
122
+
123
+ end
124
+
125
+ private
126
+ def switch_to_alt_inheritance_column
127
+ # we don't want misleading test results, so get rid of the values in the type column
128
+ Company.find_all(nil, "id").each do |c|
129
+ c['type'] = nil
130
+ c.save
131
+ end
132
+
133
+ def Company.inheritance_column() "ruby_type" end
134
+ end
125
135
  end
@@ -0,0 +1,138 @@
1
+ require 'abstract_unit'
2
+ require 'active_record/acts/tree'
3
+ require 'active_record/acts/list'
4
+ require 'fixtures/mixin'
5
+
6
+
7
+ class ListTest < Test::Unit::TestCase
8
+ fixtures :mixins
9
+
10
+ def test_injection
11
+ l = ListMixin.new("parent_id"=>1)
12
+ assert_equal "parent_id = 1", l.scope_condition
13
+ assert_equal "pos", l.position_column
14
+
15
+ end
16
+
17
+ def test_reordering
18
+
19
+ assert_equal [ListMixin.find(2), ListMixin.find(3)], ListMixin.find_all("parent_id=1", "pos")
20
+
21
+ ListMixin.find(2).move_lower
22
+
23
+ assert_equal [ListMixin.find(3), ListMixin.find(2)], ListMixin.find_all("parent_id=1", "pos")
24
+
25
+ ListMixin.find(2).move_higher
26
+
27
+ assert_equal [ListMixin.find(2), ListMixin.find(3)], ListMixin.find_all("parent_id=1", "pos")
28
+
29
+ end
30
+
31
+ def test_insert
32
+ new = ListMixin.create("parent_id"=>5)
33
+ assert_equal 1, new.pos
34
+ assert new.first?
35
+ assert new.last?
36
+
37
+ new = ListMixin.create("parent_id"=>5)
38
+ assert_equal 2, new.pos
39
+ assert !new.first?
40
+ assert new.last?
41
+
42
+ new = ListMixin.create("parent_id"=>5)
43
+ assert_equal 3, new.pos
44
+ assert !new.first?
45
+ assert new.last?
46
+
47
+ new = ListMixin.create("parent_id"=>10)
48
+ assert_equal 1, new.pos
49
+ assert new.first?
50
+ assert new.last?
51
+ end
52
+
53
+ def test_delete_middle
54
+ first = ListMixin.create("parent_id"=>5)
55
+ assert_equal 1, first.pos
56
+
57
+ second = ListMixin.create("parent_id"=>5)
58
+ assert_equal 2, second.pos
59
+
60
+ third = ListMixin.create("parent_id"=>5)
61
+ assert_equal 3, third.pos
62
+
63
+ second.destroy
64
+
65
+ assert_equal 1, @mixins["first"].find.pos
66
+ assert_equal 2, @mixins["third"].find.pos
67
+
68
+ end
69
+
70
+ def test_with_string_based_scope
71
+ new = ListWithStringScopeMixin.create("parent_id"=>5)
72
+ assert_equal 1, new.pos
73
+ assert new.first?
74
+ assert new.last?
75
+ end
76
+ end
77
+
78
+ class TreeTest < Test::Unit::TestCase
79
+ fixtures :mixins
80
+
81
+ def test_has_child
82
+ assert_equal true, @first.has_children?
83
+ assert_equal false, @second.has_children?
84
+ assert_equal false, @third.has_children?
85
+ end
86
+
87
+ def test_children
88
+ assert_equal @first.children, [@second, @third]
89
+ assert_equal @second.children, []
90
+ end
91
+
92
+ def test_parent
93
+ assert_equal @second.parent, @first
94
+ assert_equal @second.parent, @third.parent
95
+ assert_nil @first.parent
96
+ end
97
+
98
+ def test_insert
99
+ @extra = @first.children.create
100
+
101
+ assert @extra
102
+
103
+ assert_equal @extra.parent, @first
104
+ assert_equal [@second, @third, @extra], @first.children
105
+ end
106
+
107
+ def test_delete
108
+ assert_equal 3, Mixin.count
109
+ @first.destroy
110
+ assert_equal 0, Mixin.count
111
+ end
112
+ end
113
+
114
+ class TouchTest < Test::Unit::TestCase
115
+ fixtures :mixins
116
+
117
+ def test_update
118
+ assert_nil @first.updated_at
119
+ @first.save
120
+ assert_not_nil @first.updated_at
121
+ end
122
+
123
+ def test_create
124
+ @obj = Mixin.create({"parent" => @third})
125
+ assert_not_nil @obj.updated_at
126
+ assert_not_nil @obj.created_at
127
+ end
128
+
129
+ def test_create_turned_off
130
+ Mixin.record_timestamps = false
131
+
132
+ assert_nil @first.updated_at
133
+ @first.save
134
+ assert_nil @first.updated_at
135
+
136
+ Mixin.record_timestamps = true
137
+ end
138
+ end
@@ -18,7 +18,8 @@ class PrimaryKeysTest < Test::Unit::TestCase
18
18
 
19
19
  topic = Topic.new
20
20
  topic.title = "New Topic"
21
- topic.save
21
+ assert_equal(nil, topic.id)
22
+ assert_nothing_raised{ topic.save }
22
23
  id = topic.id
23
24
 
24
25
  topicReloaded = Topic.find(id)
@@ -33,8 +34,9 @@ class PrimaryKeysTest < Test::Unit::TestCase
33
34
 
34
35
  subscriber = Subscriber.new
35
36
  subscriber.id = "jdoe"
37
+ assert_equal("jdoe", subscriber.id)
36
38
  subscriber.name = "John Doe"
37
- subscriber.save
39
+ assert_nothing_raised{ subscriber.save }
38
40
 
39
41
  subscriberReloaded = Subscriber.find("jdoe")
40
42
  assert_equal("John Doe", subscriberReloaded.name)
@@ -15,17 +15,17 @@ class ReflectionTest < Test::Unit::TestCase
15
15
 
16
16
  def test_read_attribute_names
17
17
  assert_equal(
18
- %w( id title author_name author_email_address written_on last_read content approved replies_count parent_id type ).sort,
18
+ %w( id title author_name author_email_address bonus_time written_on last_read content approved replies_count parent_id type ).sort,
19
19
  @first.attribute_names
20
20
  )
21
21
  end
22
22
 
23
23
  def test_columns
24
- assert_equal 11, Topic.columns.length
24
+ assert_equal 12, Topic.columns.length
25
25
  end
26
26
 
27
27
  def test_content_columns
28
- assert_equal 7, Topic.content_columns.length
28
+ assert_equal 8, Topic.content_columns.length
29
29
  end
30
30
 
31
31
  def test_column_string_type_and_limit
@@ -84,6 +84,21 @@ class TransactionTest < Test::Unit::TestCase
84
84
  end
85
85
  end
86
86
 
87
+ def xtest_nested_explicit_transactions
88
+ Topic.transaction do
89
+ Topic.transaction do
90
+ @first.approved = 1
91
+ @second.approved = 0
92
+ @first.save
93
+ @second.save
94
+ end
95
+ end
96
+
97
+ assert Topic.find(1).approved?, "First should have been approved"
98
+ assert !Topic.find(2).approved?, "Second should have been unapproved"
99
+ end
100
+
101
+
87
102
  private
88
103
  def add_exception_raising_after_save_callback_to_topic
89
104
  Topic.class_eval { def after_save() raise "Make the transaction rollback" end }
@@ -3,11 +3,12 @@ require 'fixtures/topic'
3
3
  require 'fixtures/reply'
4
4
  require 'fixtures/developer'
5
5
 
6
-
7
6
  class ValidationsTest < Test::Unit::TestCase
8
- def setup
9
- @topic_fixtures = create_fixtures("topics")
10
- @developers = create_fixtures("developers")
7
+ fixtures :topics, :developers
8
+
9
+ def teardown
10
+ Topic.write_inheritable_attribute("validate", [])
11
+ Topic.write_inheritable_attribute("validate_on_create", [])
11
12
  end
12
13
 
13
14
  def test_single_field_validation
@@ -123,4 +124,228 @@ class ValidationsTest < Test::Unit::TestCase
123
124
  developer.name = "Just right"
124
125
  assert developer.save
125
126
  end
127
+
128
+ def test_title_confirmation
129
+ Topic.validates_confirmation_of(:title)
130
+
131
+ t = Topic.create("title" => "We should be confirmed")
132
+ assert !t.save
133
+
134
+ t.title_confirmation = "We should be confirmed"
135
+ assert t.save
136
+ end
137
+
138
+ def test_terms_of_service_agreement
139
+ Topic.validates_acceptance_of(:terms_of_service, :on => :create)
140
+
141
+ t = Topic.create("title" => "We should be confirmed")
142
+ assert !t.save
143
+ assert_equal "must be accepted", t.errors.on(:terms_of_service)
144
+
145
+ t.terms_of_service = "1"
146
+ assert t.save
147
+ end
148
+
149
+
150
+ def test_eula
151
+ Topic.validates_acceptance_of(:eula, :message => "must be abided", :on => :create)
152
+
153
+ t = Topic.create("title" => "We should be confirmed")
154
+ assert !t.save
155
+ assert_equal "must be abided", t.errors.on(:eula)
156
+
157
+ t.eula = "1"
158
+ assert t.save
159
+ end
160
+
161
+ def test_validate_presences
162
+ Topic.validates_presence_of(:title, :content)
163
+
164
+ t = Topic.create
165
+ assert !t.save
166
+ assert_equal "can't be empty", t.errors.on(:title)
167
+ assert_equal "can't be empty", t.errors.on(:content)
168
+
169
+ t.title = "something"
170
+ t.content = "another"
171
+
172
+ assert t.save
173
+ end
174
+
175
+ def test_validate_uniqueness
176
+ Topic.validates_uniqueness_of(:title)
177
+
178
+ t = Topic.new("title" => "I'm unique!")
179
+ assert t.save, "Should save t as unique"
180
+
181
+ t.content = "Remaining unique"
182
+ assert t.save, "Should still save t as unique"
183
+
184
+ t2 = Topic.new("title" => "I'm unique!")
185
+ assert !t2.valid?, "Shouldn't be valid"
186
+ assert !t2.save, "Shouldn't save t2 as unique"
187
+ assert_equal "has already been taken", t2.errors.on(:title)
188
+
189
+ t2.title = "Now Im really also unique"
190
+ assert t2.save, "Should now save t2 as unique"
191
+ end
192
+
193
+ def test_validate_format
194
+ Topic.validates_format_of(:title, :content, :with => /^Validation macros rule!$/, :message => "is bad data")
195
+
196
+ t = Topic.create("title" => "i'm incorrect", "content" => "Validation macros rule!")
197
+ assert !t.valid?, "Shouldn't be valid"
198
+ assert !t.save, "Shouldn't save because it's invalid"
199
+ assert_equal "is bad data", t.errors.on(:title)
200
+ assert_nil t.errors.on(:content)
201
+
202
+ t.title = "Validation macros rule!"
203
+
204
+ assert t.save
205
+ assert_nil t.errors.on(:title)
206
+
207
+ assert_raise(ArgumentError) { Topic.validates_format_of(:title, :content) }
208
+ end
209
+
210
+ def test_validates_inclusion_of
211
+ Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ) )
212
+
213
+ assert !Topic.create("title" => "a!", "content" => "abc").valid?
214
+ assert !Topic.create("title" => "a b", "content" => "abc").valid?
215
+ assert !Topic.create("title" => nil, "content" => "def").valid?
216
+ assert !Topic.create("title" => %w(a b c), "content" => "def").valid?
217
+
218
+ t = Topic.create("title" => "a", "content" => "I know you are but what am I?")
219
+ assert t.valid?
220
+ t.title = "uhoh"
221
+ assert !t.valid?
222
+ assert t.errors.on(:title)
223
+ assert_equal "is not included in the list", t.errors["title"]
224
+
225
+ assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => nil ) }
226
+ assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => 0) }
227
+
228
+ assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => "hi!" ) }
229
+ assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => {} ) }
230
+ assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => [] ) }
231
+ end
232
+
233
+ def test_validates_length_of_using_minimum
234
+ Topic.validates_length_of( :title, :minimum=>5 )
235
+ t = Topic.create("title" => "valid", "content" => "whatever")
236
+ assert t.valid?
237
+ t.title = "not"
238
+ assert !t.valid?
239
+ assert t.errors.on(:title)
240
+ assert_equal "is too short (min is 5 characters)", t.errors["title"]
241
+ t.title = ""
242
+ assert !t.valid?
243
+ assert t.errors.on(:title)
244
+ t.title = nil
245
+ assert !t.valid?
246
+ assert_equal "is too short (min is 5 characters)", t.errors["title"]
247
+ assert t.errors.on(:title)
248
+ end
249
+
250
+ def test_validates_length_of_using_maximum
251
+ Topic.validates_length_of( :title, :maximum=>5 )
252
+ t = Topic.create("title" => "valid", "content" => "whatever")
253
+ assert t.valid?
254
+ t.title = "notvalid"
255
+ assert !t.valid?
256
+ assert t.errors.on(:title)
257
+ assert_equal "is too long (max is 5 characters)", t.errors["title"]
258
+ t.title = ""
259
+ assert t.valid?
260
+ t.title = nil
261
+ assert t.valid?
262
+ end
263
+
264
+ def test_validates_length_of_using_within
265
+ Topic.validates_length_of(:title, :content, :within => 3..5)
266
+
267
+ t = Topic.create("title" => "a!", "content" => "I'm ooooooooh so very long")
268
+ assert !t.save
269
+ assert_equal "is too short (min is 3 characters)", t.errors.on(:title)
270
+ assert_equal "is too long (max is 5 characters)", t.errors.on(:content)
271
+
272
+ t.title = "abe"
273
+ t.content = "mad"
274
+
275
+ assert t.save
276
+ end
277
+
278
+ def test_validates_length_of_using_is
279
+ Topic.validates_length_of( :title, :is=>5 )
280
+ t = Topic.create("title" => "valid", "content" => "whatever")
281
+ assert t.valid?
282
+ t.title = "notvalid"
283
+ assert !t.valid?
284
+ assert t.errors.on(:title)
285
+ assert_equal "is the wrong length (should be 5 characters)", t.errors["title"]
286
+ t.title = ""
287
+ assert !t.valid?
288
+ t.title = nil
289
+ assert !t.valid?
290
+ end
291
+
292
+ def test_validates_length_of_nasty_params
293
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>6, :maximum=>9) }
294
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :maximum=>9) }
295
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :minimum=>9) }
296
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :is=>9) }
297
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>"a") }
298
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :maximum=>"a") }
299
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>"a") }
300
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is=>"a") }
301
+ end
302
+
303
+ def test_validates_length_of_custom_errors_for_minimum_with_message
304
+ Topic.validates_length_of( :title, :minimum=>5, :message=>"boo %d" )
305
+ t = Topic.create("title" => "uhoh", "content" => "whatever")
306
+ assert !t.valid?
307
+ assert t.errors.on(:title)
308
+ assert_equal "boo 5", t.errors["title"]
309
+ end
310
+
311
+ def test_validates_length_of_custom_errors_for_minimum_with_too_short
312
+ Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo %d" )
313
+ t = Topic.create("title" => "uhoh", "content" => "whatever")
314
+ assert !t.valid?
315
+ assert t.errors.on(:title)
316
+ assert_equal "hoo 5", t.errors["title"]
317
+ end
318
+
319
+ def test_validates_length_of_custom_errors_for_maximum_with_message
320
+ Topic.validates_length_of( :title, :maximum=>5, :message=>"boo %d" )
321
+ t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
322
+ assert !t.valid?
323
+ assert t.errors.on(:title)
324
+ assert_equal "boo 5", t.errors["title"]
325
+ end
326
+
327
+ def test_validates_length_of_custom_errors_for_maximum_with_too_long
328
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d" )
329
+ t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
330
+ assert !t.valid?
331
+ assert t.errors.on(:title)
332
+ assert_equal "hoo 5", t.errors["title"]
333
+ end
334
+
335
+ def test_validates_length_of_custom_errors_for_is_with_message
336
+ Topic.validates_length_of( :title, :is=>5, :message=>"boo %d" )
337
+ t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
338
+ assert !t.valid?
339
+ assert t.errors.on(:title)
340
+ assert_equal "boo 5", t.errors["title"]
341
+ end
342
+
343
+ def test_validates_length_of_custom_errors_for_is_with_wrong_length
344
+ Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo %d" )
345
+ t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
346
+ assert !t.valid?
347
+ assert t.errors.on(:title)
348
+ assert_equal "hoo 5", t.errors["title"]
349
+ end
350
+
126
351
  end