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.
- data/CHANGELOG +250 -0
- data/README +17 -9
- data/dev-utils/eval_debugger.rb +1 -1
- data/install.rb +3 -1
- data/lib/active_record.rb +9 -2
- data/lib/active_record/acts/list.rb +178 -0
- data/lib/active_record/acts/tree.rb +44 -0
- data/lib/active_record/associations.rb +45 -8
- data/lib/active_record/associations/association_collection.rb +18 -9
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +14 -13
- data/lib/active_record/associations/has_many_association.rb +21 -12
- data/lib/active_record/base.rb +137 -37
- data/lib/active_record/callbacks.rb +30 -25
- data/lib/active_record/connection_adapters/abstract_adapter.rb +57 -33
- data/lib/active_record/connection_adapters/mysql_adapter.rb +4 -0
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +3 -2
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +298 -0
- data/lib/active_record/fixtures.rb +241 -147
- data/lib/active_record/support/class_inheritable_attributes.rb +5 -2
- data/lib/active_record/support/inflector.rb +13 -12
- data/lib/active_record/support/misc.rb +6 -0
- data/lib/active_record/timestamp.rb +33 -0
- data/lib/active_record/transactions.rb +1 -1
- data/lib/active_record/validations.rb +294 -16
- data/rakefile +3 -7
- data/test/abstract_unit.rb +1 -4
- data/test/associations_test.rb +17 -4
- data/test/base_test.rb +37 -5
- data/test/connections/native_sqlserver/connection.rb +15 -0
- data/test/deprecated_associations_test.rb +40 -38
- data/test/finder_test.rb +82 -4
- data/test/fixtures/accounts.yml +8 -0
- data/test/fixtures/company.rb +6 -0
- data/test/fixtures/company_in_module.rb +1 -1
- data/test/fixtures/db_definitions/mysql.sql +13 -0
- data/test/fixtures/db_definitions/postgresql.sql +13 -0
- data/test/fixtures/db_definitions/sqlite.sql +14 -0
- data/test/fixtures/db_definitions/sqlserver.sql +110 -0
- data/test/fixtures/db_definitions/sqlserver2.sql +4 -0
- data/test/fixtures/developer.rb +2 -2
- data/test/fixtures/developers.yml +13 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/mixin.rb +17 -0
- data/test/fixtures/mixins.yml +14 -0
- data/test/fixtures/naked/csv/accounts.csv +1 -0
- data/test/fixtures/naked/yml/accounts.yml +1 -0
- data/test/fixtures/naked/yml/companies.yml +1 -0
- data/test/fixtures/naked/yml/courses.yml +1 -0
- data/test/fixtures/project.rb +6 -0
- data/test/fixtures/reply.rb +14 -1
- data/test/fixtures/topic.rb +2 -2
- data/test/fixtures/topics/first +1 -0
- data/test/fixtures_test.rb +42 -12
- data/test/inflector_test.rb +2 -1
- data/test/inheritance_test.rb +22 -12
- data/test/mixin_test.rb +138 -0
- data/test/pk_test.rb +4 -2
- data/test/reflection_test.rb +3 -3
- data/test/transactions_test.rb +15 -0
- data/test/validations_test.rb +229 -4
- metadata +24 -10
- data/lib/active_record/associations.rb.orig +0 -555
- data/test/deprecated_associations_test.rb.orig +0 -334
- data/test/fixtures/accounts/signals37 +0 -3
- data/test/fixtures/accounts/unknown +0 -2
- data/test/fixtures/developers/david +0 -2
- data/test/fixtures/developers/jamis +0 -2
data/test/fixtures/topic.rb
CHANGED
@@ -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
|
6
|
+
before_destroy :destroy_children
|
7
7
|
|
8
8
|
def parent
|
9
9
|
self.class.find(parent_id)
|
data/test/fixtures/topics/first
CHANGED
data/test/fixtures_test.rb
CHANGED
@@ -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 !~
|
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
|
-
|
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
|
data/test/inflector_test.rb
CHANGED
@@ -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
|
-
"
|
50
|
+
"ApplicationController" => "application_controller"
|
50
51
|
}
|
51
52
|
|
52
53
|
ClassNameToForeignKeyWithUnderscore = {
|
data/test/inheritance_test.rb
CHANGED
@@ -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
|
-
|
7
|
-
@company_fixtures = create_fixtures "companies"
|
8
|
-
end
|
6
|
+
fixtures :companies, :projects
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
Company.
|
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
|
data/test/mixin_test.rb
ADDED
@@ -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
|
data/test/pk_test.rb
CHANGED
@@ -18,7 +18,8 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
topic = Topic.new
|
20
20
|
topic.title = "New Topic"
|
21
|
-
topic.
|
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)
|
data/test/reflection_test.rb
CHANGED
@@ -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
|
24
|
+
assert_equal 12, Topic.columns.length
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_content_columns
|
28
|
-
assert_equal
|
28
|
+
assert_equal 8, Topic.content_columns.length
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_column_string_type_and_limit
|
data/test/transactions_test.rb
CHANGED
@@ -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 }
|
data/test/validations_test.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
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
|