activerecord 2.1.2 → 2.2.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 +32 -6
- data/README +0 -0
- data/Rakefile +4 -5
- data/lib/active_record.rb +11 -10
- data/lib/active_record/aggregations.rb +110 -38
- data/lib/active_record/association_preload.rb +104 -15
- data/lib/active_record/associations.rb +427 -212
- data/lib/active_record/associations/association_collection.rb +101 -16
- data/lib/active_record/associations/association_proxy.rb +65 -13
- data/lib/active_record/associations/belongs_to_association.rb +2 -2
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +13 -3
- data/lib/active_record/associations/has_many_association.rb +28 -28
- data/lib/active_record/associations/has_many_through_association.rb +21 -19
- data/lib/active_record/associations/has_one_association.rb +24 -7
- data/lib/active_record/associations/has_one_through_association.rb +3 -4
- data/lib/active_record/attribute_methods.rb +13 -5
- data/lib/active_record/base.rb +435 -212
- data/lib/active_record/calculations.rb +12 -5
- data/lib/active_record/callbacks.rb +28 -9
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +355 -0
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +42 -215
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +30 -5
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +48 -7
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +10 -4
- data/lib/active_record/connection_adapters/abstract_adapter.rb +67 -26
- data/lib/active_record/connection_adapters/mysql_adapter.rb +71 -45
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +155 -84
- data/lib/active_record/dirty.rb +25 -7
- data/lib/active_record/dynamic_finder_match.rb +41 -0
- data/lib/active_record/fixtures.rb +10 -9
- data/lib/active_record/i18n_interpolation_deprecation.rb +26 -0
- data/lib/active_record/locale/en.yml +54 -0
- data/lib/active_record/migration.rb +47 -10
- data/lib/active_record/named_scope.rb +29 -16
- data/lib/active_record/reflection.rb +118 -54
- data/lib/active_record/schema_dumper.rb +13 -7
- data/lib/active_record/test_case.rb +18 -5
- data/lib/active_record/transactions.rb +89 -34
- data/lib/active_record/validations.rb +270 -180
- data/lib/active_record/version.rb +1 -1
- data/test/cases/active_schema_test_mysql.rb +5 -0
- data/test/cases/adapter_test.rb +6 -0
- data/test/cases/aggregations_test.rb +39 -0
- data/test/cases/associations/belongs_to_associations_test.rb +10 -0
- data/test/cases/associations/eager_load_nested_include_test.rb +30 -12
- data/test/cases/associations/eager_test.rb +54 -5
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +77 -10
- data/test/cases/associations/has_many_associations_test.rb +74 -7
- data/test/cases/associations/has_many_through_associations_test.rb +50 -3
- data/test/cases/associations/has_one_associations_test.rb +17 -0
- data/test/cases/associations/has_one_through_associations_test.rb +49 -1
- data/test/cases/associations_test.rb +0 -0
- data/test/cases/attribute_methods_test.rb +59 -4
- data/test/cases/base_test.rb +93 -21
- data/test/cases/binary_test.rb +1 -5
- data/test/cases/calculations_test.rb +5 -0
- data/test/cases/callbacks_observers_test.rb +38 -0
- data/test/cases/connection_test_mysql.rb +1 -1
- data/test/cases/defaults_test.rb +32 -1
- data/test/cases/deprecated_finder_test.rb +0 -0
- data/test/cases/dirty_test.rb +13 -0
- data/test/cases/finder_test.rb +162 -12
- data/test/cases/fixtures_test.rb +32 -3
- data/test/cases/helper.rb +15 -0
- data/test/cases/i18n_test.rb +41 -0
- data/test/cases/inheritance_test.rb +2 -2
- data/test/cases/lifecycle_test.rb +0 -0
- data/test/cases/locking_test.rb +4 -9
- data/test/cases/method_scoping_test.rb +109 -2
- data/test/cases/migration_test.rb +43 -8
- data/test/cases/multiple_db_test.rb +25 -0
- data/test/cases/named_scope_test.rb +74 -0
- data/test/cases/pooled_connections_test.rb +103 -0
- data/test/cases/readonly_test.rb +0 -0
- data/test/cases/reflection_test.rb +11 -3
- data/test/cases/reload_models_test.rb +20 -0
- data/test/cases/sanitize_test.rb +25 -0
- data/test/cases/schema_authorization_test_postgresql.rb +2 -2
- data/test/cases/transactions_test.rb +62 -12
- data/test/cases/unconnected_test.rb +0 -0
- data/test/cases/validations_i18n_test.rb +921 -0
- data/test/cases/validations_test.rb +44 -33
- data/test/connections/native_mysql/connection.rb +1 -3
- data/test/fixtures/companies.yml +1 -0
- data/test/fixtures/customers.yml +10 -1
- data/test/fixtures/fixture_database.sqlite3 +0 -0
- data/test/fixtures/fixture_database_2.sqlite3 +0 -0
- data/test/fixtures/organizations.yml +5 -0
- data/test/migrations/broken/100_migration_that_raises_exception.rb +10 -0
- data/test/models/author.rb +3 -0
- data/test/models/category.rb +3 -0
- data/test/models/club.rb +6 -0
- data/test/models/company.rb +25 -1
- data/test/models/customer.rb +19 -1
- data/test/models/member.rb +2 -0
- data/test/models/member_detail.rb +4 -0
- data/test/models/organization.rb +4 -0
- data/test/models/parrot.rb +1 -0
- data/test/models/post.rb +3 -0
- data/test/models/reply.rb +0 -0
- data/test/models/topic.rb +3 -0
- data/test/schema/schema.rb +12 -1
- metadata +22 -10
- data/lib/active_record/vendor/mysql.rb +0 -1214
- data/test/cases/adapter_test_sqlserver.rb +0 -95
- data/test/cases/table_name_test_sqlserver.rb +0 -23
- data/test/cases/threaded_connections_test.rb +0 -48
- data/test/schema/sqlserver_specific_schema.rb +0 -5
@@ -0,0 +1,103 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
|
3
|
+
class PooledConnectionsTest < ActiveRecord::TestCase
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
@connection = ActiveRecord::Base.remove_connection
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
ActiveRecord::Base.clear_all_connections!
|
11
|
+
ActiveRecord::Base.establish_connection(@connection)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def checkout_connections
|
16
|
+
ActiveRecord::Base.establish_connection(@connection.merge({:pool => 2, :wait_timeout => 0.3}))
|
17
|
+
@connections = []
|
18
|
+
@timed_out = 0
|
19
|
+
|
20
|
+
4.times do
|
21
|
+
Thread.new do
|
22
|
+
begin
|
23
|
+
@connections << ActiveRecord::Base.connection_pool.checkout
|
24
|
+
rescue ActiveRecord::ConnectionTimeoutError
|
25
|
+
@timed_out += 1
|
26
|
+
end
|
27
|
+
end.join
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Will deadlock due to lack of Monitor timeouts in 1.9
|
32
|
+
if RUBY_VERSION < '1.9'
|
33
|
+
def test_pooled_connection_checkout
|
34
|
+
checkout_connections
|
35
|
+
assert_equal @connections.length, 2
|
36
|
+
assert_equal @timed_out, 2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def checkout_checkin_connections(pool_size, threads)
|
41
|
+
ActiveRecord::Base.establish_connection(@connection.merge({:pool => pool_size, :wait_timeout => 0.5}))
|
42
|
+
@connection_count = 0
|
43
|
+
@timed_out = 0
|
44
|
+
threads.times do
|
45
|
+
Thread.new do
|
46
|
+
begin
|
47
|
+
conn = ActiveRecord::Base.connection_pool.checkout
|
48
|
+
sleep 0.1
|
49
|
+
ActiveRecord::Base.connection_pool.checkin conn
|
50
|
+
@connection_count += 1
|
51
|
+
rescue ActiveRecord::ConnectionTimeoutError
|
52
|
+
@timed_out += 1
|
53
|
+
end
|
54
|
+
end.join
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_pooled_connection_checkin_one
|
59
|
+
checkout_checkin_connections 1, 2
|
60
|
+
assert_equal 2, @connection_count
|
61
|
+
assert_equal 0, @timed_out
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_pooled_connection_checkin_two
|
65
|
+
checkout_checkin_connections 2, 3
|
66
|
+
assert_equal 3, @connection_count
|
67
|
+
assert_equal 0, @timed_out
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_pooled_connection_checkout_existing_first
|
71
|
+
ActiveRecord::Base.establish_connection(@connection.merge({:pool => 1}))
|
72
|
+
conn_pool = ActiveRecord::Base.connection_pool
|
73
|
+
conn = conn_pool.checkout
|
74
|
+
conn_pool.checkin(conn)
|
75
|
+
conn = conn_pool.checkout
|
76
|
+
assert ActiveRecord::ConnectionAdapters::AbstractAdapter === conn
|
77
|
+
conn_pool.checkin(conn)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_not_connected_defined_connection_returns_false
|
81
|
+
ActiveRecord::Base.establish_connection(@connection)
|
82
|
+
assert ! ActiveRecord::Base.connected?
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_undefined_connection_returns_false
|
86
|
+
old_handler = ActiveRecord::Base.connection_handler
|
87
|
+
ActiveRecord::Base.connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
88
|
+
assert_equal false, ActiveRecord::Base.connected?
|
89
|
+
ensure
|
90
|
+
ActiveRecord::Base.connection_handler = old_handler
|
91
|
+
end
|
92
|
+
end unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
|
93
|
+
|
94
|
+
class AllowConcurrencyDeprecatedTest < ActiveRecord::TestCase
|
95
|
+
def test_allow_concurrency_is_deprecated
|
96
|
+
assert_deprecated('ActiveRecord::Base.allow_concurrency') do
|
97
|
+
ActiveRecord::Base.allow_concurrency
|
98
|
+
end
|
99
|
+
assert_deprecated('ActiveRecord::Base.allow_concurrency=') do
|
100
|
+
ActiveRecord::Base.allow_concurrency = true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/test/cases/readonly_test.rb
CHANGED
File without changes
|
@@ -160,12 +160,20 @@ class ReflectionTest < ActiveRecord::TestCase
|
|
160
160
|
|
161
161
|
def test_reflection_of_all_associations
|
162
162
|
# FIXME these assertions bust a lot
|
163
|
-
assert_equal
|
164
|
-
assert_equal
|
165
|
-
assert_equal
|
163
|
+
assert_equal 26, Firm.reflect_on_all_associations.size
|
164
|
+
assert_equal 20, Firm.reflect_on_all_associations(:has_many).size
|
165
|
+
assert_equal 6, Firm.reflect_on_all_associations(:has_one).size
|
166
166
|
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
|
167
167
|
end
|
168
168
|
|
169
|
+
def test_reflection_should_not_raise_error_when_compared_to_other_object
|
170
|
+
assert_nothing_raised { Firm.reflections[:clients] == Object.new }
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_has_many_through_reflection
|
174
|
+
assert_kind_of ActiveRecord::Reflection::ThroughReflection, Subscriber.reflect_on_association(:books)
|
175
|
+
end
|
176
|
+
|
169
177
|
private
|
170
178
|
def assert_reflection(klass, association, options)
|
171
179
|
assert reflection = klass.reflect_on_association(association)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/owner'
|
3
|
+
require 'models/pet'
|
4
|
+
|
5
|
+
class ReloadModelsTest < ActiveRecord::TestCase
|
6
|
+
def test_has_one_with_reload
|
7
|
+
pet = Pet.find_by_name('parrot')
|
8
|
+
pet.owner = Owner.find_by_name('ashley')
|
9
|
+
|
10
|
+
# Reload the class Owner, simulating auto-reloading of model classes in a
|
11
|
+
# development environment. Note that meanwhile the class Pet is not
|
12
|
+
# reloaded, simulating a class that is present in a plugin.
|
13
|
+
Object.class_eval { remove_const :Owner }
|
14
|
+
Kernel.load(File.expand_path(File.join(File.dirname(__FILE__), "../models/owner.rb")))
|
15
|
+
|
16
|
+
pet = Pet.find_by_name('parrot')
|
17
|
+
pet.owner = Owner.find_by_name('ashley')
|
18
|
+
assert_equal pet.owner, Owner.find_by_name('ashley')
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/binary'
|
3
|
+
|
4
|
+
class SanitizeTest < ActiveRecord::TestCase
|
5
|
+
def setup
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_sanitize_sql_array_handles_string_interpolation
|
9
|
+
quoted_bambi = ActiveRecord::Base.connection.quote_string("Bambi")
|
10
|
+
assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=%s", "Bambi"])
|
11
|
+
assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=%s", "Bambi".mb_chars])
|
12
|
+
quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote_string("Bambi\nand\nThumper")
|
13
|
+
assert_equal "name=#{quoted_bambi_and_thumper}",Binary.send(:sanitize_sql_array, ["name=%s", "Bambi\nand\nThumper"])
|
14
|
+
assert_equal "name=#{quoted_bambi_and_thumper}",Binary.send(:sanitize_sql_array, ["name=%s", "Bambi\nand\nThumper".mb_chars])
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_sanitize_sql_array_handles_bind_variables
|
18
|
+
quoted_bambi = ActiveRecord::Base.connection.quote("Bambi")
|
19
|
+
assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi"])
|
20
|
+
assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi".mb_chars])
|
21
|
+
quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper")
|
22
|
+
assert_equal "name=#{quoted_bambi_and_thumper}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi\nand\nThumper"])
|
23
|
+
assert_equal "name=#{quoted_bambi_and_thumper}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi\nand\nThumper".mb_chars])
|
24
|
+
end
|
25
|
+
end
|
@@ -18,8 +18,8 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
|
|
18
18
|
@connection.execute "SET search_path TO '$user',public"
|
19
19
|
set_session_auth
|
20
20
|
USERS.each do |u|
|
21
|
-
@connection.execute "CREATE USER #{u}"
|
22
|
-
@connection.execute "CREATE SCHEMA AUTHORIZATION #{u}"
|
21
|
+
@connection.execute "CREATE USER #{u}" rescue nil
|
22
|
+
@connection.execute "CREATE SCHEMA AUTHORIZATION #{u}" rescue nil
|
23
23
|
set_session_auth u
|
24
24
|
@connection.execute "CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
|
25
25
|
@connection.execute "INSERT INTO #{TABLE_NAME} (name) VALUES ('#{u}')"
|
@@ -2,6 +2,7 @@ require "cases/helper"
|
|
2
2
|
require 'models/topic'
|
3
3
|
require 'models/reply'
|
4
4
|
require 'models/developer'
|
5
|
+
require 'models/book'
|
5
6
|
|
6
7
|
class TransactionTest < ActiveRecord::TestCase
|
7
8
|
self.use_transactional_fixtures = false
|
@@ -86,8 +87,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
86
87
|
assert Topic.find(2).approved?, "Second should still be approved"
|
87
88
|
end
|
88
89
|
|
89
|
-
|
90
|
-
def test_callback_rollback_in_save
|
90
|
+
def test_raising_exception_in_callback_rollbacks_in_save
|
91
91
|
add_exception_raising_after_save_callback_to_topic
|
92
92
|
|
93
93
|
begin
|
@@ -102,6 +102,54 @@ class TransactionTest < ActiveRecord::TestCase
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
+
def test_cancellation_from_before_destroy_rollbacks_in_destroy
|
106
|
+
add_cancelling_before_destroy_with_db_side_effect_to_topic
|
107
|
+
begin
|
108
|
+
nbooks_before_destroy = Book.count
|
109
|
+
status = @first.destroy
|
110
|
+
assert !status
|
111
|
+
assert_nothing_raised(ActiveRecord::RecordNotFound) { @first.reload }
|
112
|
+
assert_equal nbooks_before_destroy, Book.count
|
113
|
+
ensure
|
114
|
+
remove_cancelling_before_destroy_with_db_side_effect_to_topic
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_cancellation_from_before_filters_rollbacks_in_save
|
119
|
+
%w(validation save).each do |filter|
|
120
|
+
send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic")
|
121
|
+
begin
|
122
|
+
nbooks_before_save = Book.count
|
123
|
+
original_author_name = @first.author_name
|
124
|
+
@first.author_name += '_this_should_not_end_up_in_the_db'
|
125
|
+
status = @first.save
|
126
|
+
assert !status
|
127
|
+
assert_equal original_author_name, @first.reload.author_name
|
128
|
+
assert_equal nbooks_before_save, Book.count
|
129
|
+
ensure
|
130
|
+
send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_cancellation_from_before_filters_rollbacks_in_save!
|
136
|
+
%w(validation save).each do |filter|
|
137
|
+
send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic")
|
138
|
+
begin
|
139
|
+
nbooks_before_save = Book.count
|
140
|
+
original_author_name = @first.author_name
|
141
|
+
@first.author_name += '_this_should_not_end_up_in_the_db'
|
142
|
+
@first.save!
|
143
|
+
flunk
|
144
|
+
rescue => e
|
145
|
+
assert_equal original_author_name, @first.reload.author_name
|
146
|
+
assert_equal nbooks_before_save, Book.count
|
147
|
+
ensure
|
148
|
+
send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
105
153
|
def test_callback_rollback_in_create
|
106
154
|
new_topic = Topic.new(
|
107
155
|
:title => "A new topic",
|
@@ -168,6 +216,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
168
216
|
uses_mocha 'mocking connection.commit_db_transaction' do
|
169
217
|
def test_rollback_when_commit_raises
|
170
218
|
Topic.connection.expects(:begin_db_transaction)
|
219
|
+
Topic.connection.expects(:transaction_active?).returns(true) if current_adapter?(:PostgreSQLAdapter)
|
171
220
|
Topic.connection.expects(:commit_db_transaction).raises('OH NOES')
|
172
221
|
Topic.connection.expects(:rollback_db_transaction)
|
173
222
|
|
@@ -221,20 +270,21 @@ class TransactionTest < ActiveRecord::TestCase
|
|
221
270
|
def remove_exception_raising_after_create_callback_to_topic
|
222
271
|
Topic.class_eval { remove_method :after_create }
|
223
272
|
end
|
273
|
+
|
274
|
+
%w(validation save destroy).each do |filter|
|
275
|
+
define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do
|
276
|
+
Topic.class_eval "def before_#{filter}() Book.create; false end"
|
277
|
+
end
|
278
|
+
|
279
|
+
define_method("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") do
|
280
|
+
Topic.class_eval "remove_method :before_#{filter}"
|
281
|
+
end
|
282
|
+
end
|
224
283
|
end
|
225
284
|
|
226
285
|
if current_adapter?(:PostgreSQLAdapter)
|
227
286
|
class ConcurrentTransactionTest < TransactionTest
|
228
|
-
|
229
|
-
@allow_concurrency = ActiveRecord::Base.allow_concurrency
|
230
|
-
ActiveRecord::Base.allow_concurrency = true
|
231
|
-
super
|
232
|
-
end
|
233
|
-
|
234
|
-
def teardown
|
235
|
-
super
|
236
|
-
ActiveRecord::Base.allow_concurrency = @allow_concurrency
|
237
|
-
end
|
287
|
+
use_concurrent_connections
|
238
288
|
|
239
289
|
# This will cause transactions to overlap and fail unless they are performed on
|
240
290
|
# separate database connections.
|
File without changes
|
@@ -0,0 +1,921 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/topic'
|
3
|
+
require 'models/reply'
|
4
|
+
|
5
|
+
class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
reset_callbacks Topic
|
8
|
+
@topic = Topic.new
|
9
|
+
@old_load_path, @old_backend = I18n.load_path, I18n.backend
|
10
|
+
I18n.load_path.clear
|
11
|
+
I18n.backend = I18n::Backend::Simple.new
|
12
|
+
I18n.backend.store_translations('en', :activerecord => {:errors => {:messages => {:custom => nil}}})
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
reset_callbacks Topic
|
17
|
+
I18n.load_path.replace @old_load_path
|
18
|
+
I18n.backend = @old_backend
|
19
|
+
end
|
20
|
+
|
21
|
+
def unique_topic
|
22
|
+
@unique ||= Topic.create :title => 'unique!'
|
23
|
+
end
|
24
|
+
|
25
|
+
def replied_topic
|
26
|
+
@replied_topic ||= begin
|
27
|
+
topic = Topic.create(:title => "topic")
|
28
|
+
topic.replies << Reply.new
|
29
|
+
topic
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def reset_callbacks(*models)
|
34
|
+
models.each do |model|
|
35
|
+
model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
36
|
+
model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
37
|
+
model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_default_error_messages_is_deprecated
|
42
|
+
assert_deprecated('ActiveRecord::Errors.default_error_messages') do
|
43
|
+
ActiveRecord::Errors.default_error_messages
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_percent_s_interpolation_syntax_in_error_messages_still_works
|
48
|
+
ActiveSupport::Deprecation.silence do
|
49
|
+
result = I18n.t :does_not_exist, :default => "%s interpolation syntax is deprecated", :value => 'this'
|
50
|
+
assert_equal result, "this interpolation syntax is deprecated"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_percent_s_interpolation_syntax_in_error_messages_is_deprecated
|
55
|
+
assert_deprecated('using %s in messages') do
|
56
|
+
I18n.t :does_not_exist, :default => "%s interpolation syntax is deprected", :value => 'this'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_percent_d_interpolation_syntax_in_error_messages_still_works
|
61
|
+
ActiveSupport::Deprecation.silence do
|
62
|
+
result = I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprecated", :count => 2
|
63
|
+
assert_equal result, "2 interpolation syntaxes are deprecated"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_percent_d_interpolation_syntax_in_error_messages_is_deprecated
|
68
|
+
assert_deprecated('using %d in messages') do
|
69
|
+
I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprected", :count => 2
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# ActiveRecord::Errors
|
74
|
+
uses_mocha 'ActiveRecord::Errors' do
|
75
|
+
|
76
|
+
def test_errors_generate_message_translates_custom_model_attribute_key
|
77
|
+
|
78
|
+
I18n.expects(:translate).with(
|
79
|
+
:topic,
|
80
|
+
{ :count => 1,
|
81
|
+
:default => ['Topic'],
|
82
|
+
:scope => [:activerecord, :models]
|
83
|
+
}
|
84
|
+
).returns('Topic')
|
85
|
+
|
86
|
+
I18n.expects(:translate).with(
|
87
|
+
:"topic.title",
|
88
|
+
{ :count => 1,
|
89
|
+
:default => ['Title'],
|
90
|
+
:scope => [:activerecord, :attributes]
|
91
|
+
}
|
92
|
+
).returns('Title')
|
93
|
+
|
94
|
+
I18n.expects(:translate).with(
|
95
|
+
:"models.topic.attributes.title.invalid",
|
96
|
+
:value => nil,
|
97
|
+
:scope => [:activerecord, :errors],
|
98
|
+
:default => [
|
99
|
+
:"models.topic.invalid",
|
100
|
+
'default from class def error 1',
|
101
|
+
:"messages.invalid"],
|
102
|
+
:attribute => "Title",
|
103
|
+
:model => "Topic"
|
104
|
+
).returns('default from class def error 1')
|
105
|
+
|
106
|
+
@topic.errors.generate_message :title, :invalid, :default => 'default from class def error 1'
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_errors_generate_message_translates_custom_model_attribute_keys_with_sti
|
110
|
+
|
111
|
+
I18n.expects(:translate).with(
|
112
|
+
:reply,
|
113
|
+
{ :count => 1,
|
114
|
+
:default => [:topic, 'Reply'],
|
115
|
+
:scope => [:activerecord, :models]
|
116
|
+
}
|
117
|
+
).returns('Reply')
|
118
|
+
|
119
|
+
I18n.expects(:translate).with(
|
120
|
+
:"reply.title",
|
121
|
+
{ :count => 1,
|
122
|
+
:default => [:'topic.title', 'Title'],
|
123
|
+
:scope => [:activerecord, :attributes]
|
124
|
+
}
|
125
|
+
).returns('Title')
|
126
|
+
|
127
|
+
I18n.expects(:translate).with(
|
128
|
+
:"models.reply.attributes.title.invalid",
|
129
|
+
:value => nil,
|
130
|
+
:scope => [:activerecord, :errors],
|
131
|
+
:default => [
|
132
|
+
:"models.reply.invalid",
|
133
|
+
:"models.topic.attributes.title.invalid",
|
134
|
+
:"models.topic.invalid",
|
135
|
+
'default from class def',
|
136
|
+
:"messages.invalid"],
|
137
|
+
:model => 'Reply',
|
138
|
+
:attribute => 'Title'
|
139
|
+
).returns("default from class def")
|
140
|
+
|
141
|
+
Reply.new.errors.generate_message :title, :invalid, :default => 'default from class def'
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_errors_add_on_empty_generates_message
|
146
|
+
@topic.errors.expects(:generate_message).with(:title, :empty, {:default => nil})
|
147
|
+
@topic.errors.add_on_empty :title
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_errors_add_on_empty_generates_message_with_custom_default_message
|
151
|
+
@topic.errors.expects(:generate_message).with(:title, :empty, {:default => 'custom'})
|
152
|
+
@topic.errors.add_on_empty :title, 'custom'
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_errors_add_on_blank_generates_message
|
156
|
+
@topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil})
|
157
|
+
@topic.errors.add_on_blank :title
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_errors_add_on_blank_generates_message_with_custom_default_message
|
161
|
+
@topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'})
|
162
|
+
@topic.errors.add_on_blank :title, 'custom'
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_errors_full_messages_translates_human_attribute_name_for_model_attributes
|
166
|
+
@topic.errors.instance_variable_set :@errors, { 'title' => ['empty'] }
|
167
|
+
I18n.expects(:translate).with(:"topic.title", :default => ['Title'], :scope => [:activerecord, :attributes], :count => 1).returns('Title')
|
168
|
+
@topic.errors.full_messages :locale => 'en'
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# ActiveRecord::Validations
|
173
|
+
uses_mocha 'ActiveRecord::Validations' do
|
174
|
+
# validates_confirmation_of w/ mocha
|
175
|
+
|
176
|
+
def test_validates_confirmation_of_generates_message
|
177
|
+
Topic.validates_confirmation_of :title
|
178
|
+
@topic.title_confirmation = 'foo'
|
179
|
+
@topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => nil})
|
180
|
+
@topic.valid?
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_validates_confirmation_of_generates_message_with_custom_default_message
|
184
|
+
Topic.validates_confirmation_of :title, :message => 'custom'
|
185
|
+
@topic.title_confirmation = 'foo'
|
186
|
+
@topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => 'custom'})
|
187
|
+
@topic.valid?
|
188
|
+
end
|
189
|
+
|
190
|
+
# validates_acceptance_of w/ mocha
|
191
|
+
|
192
|
+
def test_validates_acceptance_of_generates_message
|
193
|
+
Topic.validates_acceptance_of :title, :allow_nil => false
|
194
|
+
@topic.errors.expects(:generate_message).with(:title, :accepted, {:default => nil})
|
195
|
+
@topic.valid?
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_validates_acceptance_of_generates_message_with_custom_default_message
|
199
|
+
Topic.validates_acceptance_of :title, :message => 'custom', :allow_nil => false
|
200
|
+
@topic.errors.expects(:generate_message).with(:title, :accepted, {:default => 'custom'})
|
201
|
+
@topic.valid?
|
202
|
+
end
|
203
|
+
|
204
|
+
# validates_presence_of w/ mocha
|
205
|
+
|
206
|
+
def test_validates_presence_of_generates_message
|
207
|
+
Topic.validates_presence_of :title
|
208
|
+
@topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil})
|
209
|
+
@topic.valid?
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_validates_presence_of_generates_message_with_custom_default_message
|
213
|
+
Topic.validates_presence_of :title, :message => 'custom'
|
214
|
+
@topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'})
|
215
|
+
@topic.valid?
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_validates_length_of_within_generates_message_with_title_too_short
|
219
|
+
Topic.validates_length_of :title, :within => 3..5
|
220
|
+
@topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil})
|
221
|
+
@topic.valid?
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message
|
225
|
+
Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom'
|
226
|
+
@topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'})
|
227
|
+
@topic.valid?
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_validates_length_of_within_generates_message_with_title_too_long
|
231
|
+
Topic.validates_length_of :title, :within => 3..5
|
232
|
+
@topic.title = 'this title is too long'
|
233
|
+
@topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil})
|
234
|
+
@topic.valid?
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message
|
238
|
+
Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom'
|
239
|
+
@topic.title = 'this title is too long'
|
240
|
+
@topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'})
|
241
|
+
@topic.valid?
|
242
|
+
end
|
243
|
+
|
244
|
+
# validates_length_of :within w/ mocha
|
245
|
+
|
246
|
+
def test_validates_length_of_within_generates_message_with_title_too_short
|
247
|
+
Topic.validates_length_of :title, :within => 3..5
|
248
|
+
@topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil})
|
249
|
+
@topic.valid?
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message
|
253
|
+
Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom'
|
254
|
+
@topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'})
|
255
|
+
@topic.valid?
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_validates_length_of_within_generates_message_with_title_too_long
|
259
|
+
Topic.validates_length_of :title, :within => 3..5
|
260
|
+
@topic.title = 'this title is too long'
|
261
|
+
@topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil})
|
262
|
+
@topic.valid?
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message
|
266
|
+
Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom'
|
267
|
+
@topic.title = 'this title is too long'
|
268
|
+
@topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'})
|
269
|
+
@topic.valid?
|
270
|
+
end
|
271
|
+
|
272
|
+
# validates_length_of :is w/ mocha
|
273
|
+
|
274
|
+
def test_validates_length_of_is_generates_message
|
275
|
+
Topic.validates_length_of :title, :is => 5
|
276
|
+
@topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => nil})
|
277
|
+
@topic.valid?
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_validates_length_of_is_generates_message_with_custom_default_message
|
281
|
+
Topic.validates_length_of :title, :is => 5, :message => 'custom'
|
282
|
+
@topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => 'custom'})
|
283
|
+
@topic.valid?
|
284
|
+
end
|
285
|
+
|
286
|
+
# validates_uniqueness_of w/ mocha
|
287
|
+
|
288
|
+
def test_validates_uniqueness_of_generates_message
|
289
|
+
Topic.validates_uniqueness_of :title
|
290
|
+
@topic.title = unique_topic.title
|
291
|
+
@topic.errors.expects(:generate_message).with(:title, :taken, {:default => nil, :value => 'unique!'})
|
292
|
+
@topic.valid?
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_validates_uniqueness_of_generates_message_with_custom_default_message
|
296
|
+
Topic.validates_uniqueness_of :title, :message => 'custom'
|
297
|
+
@topic.title = unique_topic.title
|
298
|
+
@topic.errors.expects(:generate_message).with(:title, :taken, {:default => 'custom', :value => 'unique!'})
|
299
|
+
@topic.valid?
|
300
|
+
end
|
301
|
+
|
302
|
+
# validates_format_of w/ mocha
|
303
|
+
|
304
|
+
def test_validates_format_of_generates_message
|
305
|
+
Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/
|
306
|
+
@topic.title = '72x'
|
307
|
+
@topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => nil})
|
308
|
+
@topic.valid?
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_validates_format_of_generates_message_with_custom_default_message
|
312
|
+
Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/, :message => 'custom'
|
313
|
+
@topic.title = '72x'
|
314
|
+
@topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => 'custom'})
|
315
|
+
@topic.valid?
|
316
|
+
end
|
317
|
+
|
318
|
+
# validates_inclusion_of w/ mocha
|
319
|
+
|
320
|
+
def test_validates_inclusion_of_generates_message
|
321
|
+
Topic.validates_inclusion_of :title, :in => %w(a b c)
|
322
|
+
@topic.title = 'z'
|
323
|
+
@topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => nil})
|
324
|
+
@topic.valid?
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_validates_inclusion_of_generates_message_with_custom_default_message
|
328
|
+
Topic.validates_inclusion_of :title, :in => %w(a b c), :message => 'custom'
|
329
|
+
@topic.title = 'z'
|
330
|
+
@topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => 'custom'})
|
331
|
+
@topic.valid?
|
332
|
+
end
|
333
|
+
|
334
|
+
# validates_exclusion_of w/ mocha
|
335
|
+
|
336
|
+
def test_validates_exclusion_of_generates_message
|
337
|
+
Topic.validates_exclusion_of :title, :in => %w(a b c)
|
338
|
+
@topic.title = 'a'
|
339
|
+
@topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => nil})
|
340
|
+
@topic.valid?
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_validates_exclusion_of_generates_message_with_custom_default_message
|
344
|
+
Topic.validates_exclusion_of :title, :in => %w(a b c), :message => 'custom'
|
345
|
+
@topic.title = 'a'
|
346
|
+
@topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => 'custom'})
|
347
|
+
@topic.valid?
|
348
|
+
end
|
349
|
+
|
350
|
+
# validates_numericality_of without :only_integer w/ mocha
|
351
|
+
|
352
|
+
def test_validates_numericality_of_generates_message
|
353
|
+
Topic.validates_numericality_of :title
|
354
|
+
@topic.title = 'a'
|
355
|
+
@topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil})
|
356
|
+
@topic.valid?
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_validates_numericality_of_generates_message_with_custom_default_message
|
360
|
+
Topic.validates_numericality_of :title, :message => 'custom'
|
361
|
+
@topic.title = 'a'
|
362
|
+
@topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'})
|
363
|
+
@topic.valid?
|
364
|
+
end
|
365
|
+
|
366
|
+
# validates_numericality_of with :only_integer w/ mocha
|
367
|
+
|
368
|
+
def test_validates_numericality_of_only_integer_generates_message
|
369
|
+
Topic.validates_numericality_of :title, :only_integer => true
|
370
|
+
@topic.title = 'a'
|
371
|
+
@topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil})
|
372
|
+
@topic.valid?
|
373
|
+
end
|
374
|
+
|
375
|
+
def test_validates_numericality_of_only_integer_generates_message_with_custom_default_message
|
376
|
+
Topic.validates_numericality_of :title, :only_integer => true, :message => 'custom'
|
377
|
+
@topic.title = 'a'
|
378
|
+
@topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'})
|
379
|
+
@topic.valid?
|
380
|
+
end
|
381
|
+
|
382
|
+
# validates_numericality_of :odd w/ mocha
|
383
|
+
|
384
|
+
def test_validates_numericality_of_odd_generates_message
|
385
|
+
Topic.validates_numericality_of :title, :only_integer => true, :odd => true
|
386
|
+
@topic.title = 0
|
387
|
+
@topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => nil})
|
388
|
+
@topic.valid?
|
389
|
+
end
|
390
|
+
|
391
|
+
def test_validates_numericality_of_odd_generates_message_with_custom_default_message
|
392
|
+
Topic.validates_numericality_of :title, :only_integer => true, :odd => true, :message => 'custom'
|
393
|
+
@topic.title = 0
|
394
|
+
@topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => 'custom'})
|
395
|
+
@topic.valid?
|
396
|
+
end
|
397
|
+
|
398
|
+
# validates_numericality_of :less_than w/ mocha
|
399
|
+
|
400
|
+
def test_validates_numericality_of_less_than_generates_message
|
401
|
+
Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0
|
402
|
+
@topic.title = 1
|
403
|
+
@topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => nil})
|
404
|
+
@topic.valid?
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_validates_numericality_of_odd_generates_message_with_custom_default_message
|
408
|
+
Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0, :message => 'custom'
|
409
|
+
@topic.title = 1
|
410
|
+
@topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => 'custom'})
|
411
|
+
@topic.valid?
|
412
|
+
end
|
413
|
+
|
414
|
+
# validates_associated w/ mocha
|
415
|
+
|
416
|
+
def test_validates_associated_generates_message
|
417
|
+
Topic.validates_associated :replies
|
418
|
+
replied_topic.errors.expects(:generate_message).with(:replies, :invalid, {:value => replied_topic.replies, :default => nil})
|
419
|
+
replied_topic.valid?
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_validates_associated_generates_message_with_custom_default_message
|
423
|
+
Topic.validates_associated :replies
|
424
|
+
replied_topic.errors.expects(:generate_message).with(:replies, :invalid, {:value => replied_topic.replies, :default => nil})
|
425
|
+
replied_topic.valid?
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
# validates_confirmation_of w/o mocha
|
430
|
+
|
431
|
+
def test_validates_confirmation_of_finds_custom_model_key_translation
|
432
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:confirmation => 'custom message'}}}}}}
|
433
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}}
|
434
|
+
|
435
|
+
Topic.validates_confirmation_of :title
|
436
|
+
@topic.title_confirmation = 'foo'
|
437
|
+
@topic.valid?
|
438
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_validates_confirmation_of_finds_global_default_translation
|
442
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}}
|
443
|
+
|
444
|
+
Topic.validates_confirmation_of :title
|
445
|
+
@topic.title_confirmation = 'foo'
|
446
|
+
@topic.valid?
|
447
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
448
|
+
end
|
449
|
+
|
450
|
+
# validates_acceptance_of w/o mocha
|
451
|
+
|
452
|
+
def test_validates_acceptance_of_finds_custom_model_key_translation
|
453
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:accepted => 'custom message'}}}}}}
|
454
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}}
|
455
|
+
|
456
|
+
Topic.validates_acceptance_of :title, :allow_nil => false
|
457
|
+
@topic.valid?
|
458
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
459
|
+
end
|
460
|
+
|
461
|
+
def test_validates_acceptance_of_finds_global_default_translation
|
462
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}}
|
463
|
+
|
464
|
+
Topic.validates_acceptance_of :title, :allow_nil => false
|
465
|
+
@topic.valid?
|
466
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
467
|
+
end
|
468
|
+
|
469
|
+
# validates_presence_of w/o mocha
|
470
|
+
|
471
|
+
def test_validates_presence_of_finds_custom_model_key_translation
|
472
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:blank => 'custom message'}}}}}}
|
473
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}}
|
474
|
+
|
475
|
+
Topic.validates_presence_of :title
|
476
|
+
@topic.valid?
|
477
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
478
|
+
end
|
479
|
+
|
480
|
+
def test_validates_presence_of_finds_global_default_translation
|
481
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}}
|
482
|
+
|
483
|
+
Topic.validates_presence_of :title
|
484
|
+
@topic.valid?
|
485
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
486
|
+
end
|
487
|
+
|
488
|
+
# validates_length_of :within w/o mocha
|
489
|
+
|
490
|
+
def test_validates_length_of_within_finds_custom_model_key_translation
|
491
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:too_short => 'custom message'}}}}}}
|
492
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}}
|
493
|
+
|
494
|
+
Topic.validates_length_of :title, :within => 3..5
|
495
|
+
@topic.valid?
|
496
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_validates_length_of_within_finds_global_default_translation
|
500
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}}
|
501
|
+
|
502
|
+
Topic.validates_length_of :title, :within => 3..5
|
503
|
+
@topic.valid?
|
504
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
505
|
+
end
|
506
|
+
|
507
|
+
# validates_length_of :is w/o mocha
|
508
|
+
|
509
|
+
def test_validates_length_of_within_finds_custom_model_key_translation
|
510
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
|
511
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
512
|
+
|
513
|
+
Topic.validates_length_of :title, :is => 5
|
514
|
+
@topic.valid?
|
515
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
516
|
+
end
|
517
|
+
|
518
|
+
def test_validates_length_of_within_finds_global_default_translation
|
519
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
520
|
+
|
521
|
+
Topic.validates_length_of :title, :is => 5
|
522
|
+
@topic.valid?
|
523
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
524
|
+
end
|
525
|
+
|
526
|
+
# validates_uniqueness_of w/o mocha
|
527
|
+
|
528
|
+
def test_validates_length_of_within_finds_custom_model_key_translation
|
529
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
|
530
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
531
|
+
|
532
|
+
Topic.validates_length_of :title, :is => 5
|
533
|
+
@topic.valid?
|
534
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
535
|
+
end
|
536
|
+
|
537
|
+
def test_validates_length_of_within_finds_global_default_translation
|
538
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
539
|
+
|
540
|
+
Topic.validates_length_of :title, :is => 5
|
541
|
+
@topic.valid?
|
542
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
543
|
+
end
|
544
|
+
|
545
|
+
|
546
|
+
# validates_format_of w/o mocha
|
547
|
+
|
548
|
+
def test_validates_format_of_finds_custom_model_key_translation
|
549
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:invalid => 'custom message'}}}}}}
|
550
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
|
551
|
+
|
552
|
+
Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/
|
553
|
+
@topic.valid?
|
554
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
555
|
+
end
|
556
|
+
|
557
|
+
def test_validates_format_of_finds_global_default_translation
|
558
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
|
559
|
+
|
560
|
+
Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/
|
561
|
+
@topic.valid?
|
562
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
563
|
+
end
|
564
|
+
|
565
|
+
# validates_inclusion_of w/o mocha
|
566
|
+
|
567
|
+
def test_validates_inclusion_of_finds_custom_model_key_translation
|
568
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:inclusion => 'custom message'}}}}}}
|
569
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}}
|
570
|
+
|
571
|
+
Topic.validates_inclusion_of :title, :in => %w(a b c)
|
572
|
+
@topic.valid?
|
573
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
574
|
+
end
|
575
|
+
|
576
|
+
def test_validates_inclusion_of_finds_global_default_translation
|
577
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}}
|
578
|
+
|
579
|
+
Topic.validates_inclusion_of :title, :in => %w(a b c)
|
580
|
+
@topic.valid?
|
581
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
582
|
+
end
|
583
|
+
|
584
|
+
# validates_exclusion_of w/o mocha
|
585
|
+
|
586
|
+
def test_validates_exclusion_of_finds_custom_model_key_translation
|
587
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:exclusion => 'custom message'}}}}}}
|
588
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}}
|
589
|
+
|
590
|
+
Topic.validates_exclusion_of :title, :in => %w(a b c)
|
591
|
+
@topic.title = 'a'
|
592
|
+
@topic.valid?
|
593
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
594
|
+
end
|
595
|
+
|
596
|
+
def test_validates_exclusion_of_finds_global_default_translation
|
597
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}}
|
598
|
+
|
599
|
+
Topic.validates_exclusion_of :title, :in => %w(a b c)
|
600
|
+
@topic.title = 'a'
|
601
|
+
@topic.valid?
|
602
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
603
|
+
end
|
604
|
+
|
605
|
+
# validates_numericality_of without :only_integer w/o mocha
|
606
|
+
|
607
|
+
def test_validates_numericality_of_finds_custom_model_key_translation
|
608
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
|
609
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
|
610
|
+
|
611
|
+
Topic.validates_numericality_of :title
|
612
|
+
@topic.title = 'a'
|
613
|
+
@topic.valid?
|
614
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
615
|
+
end
|
616
|
+
|
617
|
+
def test_validates_numericality_of_finds_global_default_translation
|
618
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
|
619
|
+
|
620
|
+
Topic.validates_numericality_of :title, :only_integer => true
|
621
|
+
@topic.title = 'a'
|
622
|
+
@topic.valid?
|
623
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
624
|
+
end
|
625
|
+
|
626
|
+
# validates_numericality_of with :only_integer w/o mocha
|
627
|
+
|
628
|
+
def test_validates_numericality_of_only_integer_finds_custom_model_key_translation
|
629
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
|
630
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
|
631
|
+
|
632
|
+
Topic.validates_numericality_of :title, :only_integer => true
|
633
|
+
@topic.title = 'a'
|
634
|
+
@topic.valid?
|
635
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
636
|
+
end
|
637
|
+
|
638
|
+
def test_validates_numericality_of_only_integer_finds_global_default_translation
|
639
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
|
640
|
+
|
641
|
+
Topic.validates_numericality_of :title, :only_integer => true
|
642
|
+
@topic.title = 'a'
|
643
|
+
@topic.valid?
|
644
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
645
|
+
end
|
646
|
+
|
647
|
+
# validates_numericality_of :odd w/o mocha
|
648
|
+
|
649
|
+
def test_validates_numericality_of_odd_finds_custom_model_key_translation
|
650
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:odd => 'custom message'}}}}}}
|
651
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}}
|
652
|
+
|
653
|
+
Topic.validates_numericality_of :title, :only_integer => true, :odd => true
|
654
|
+
@topic.title = 0
|
655
|
+
@topic.valid?
|
656
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
657
|
+
end
|
658
|
+
|
659
|
+
def test_validates_numericality_of_odd_finds_global_default_translation
|
660
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}}
|
661
|
+
|
662
|
+
Topic.validates_numericality_of :title, :only_integer => true, :odd => true
|
663
|
+
@topic.title = 0
|
664
|
+
@topic.valid?
|
665
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
666
|
+
end
|
667
|
+
|
668
|
+
# validates_numericality_of :less_than w/o mocha
|
669
|
+
|
670
|
+
def test_validates_numericality_of_less_than_finds_custom_model_key_translation
|
671
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:less_than => 'custom message'}}}}}}
|
672
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}}
|
673
|
+
|
674
|
+
Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0
|
675
|
+
@topic.title = 1
|
676
|
+
@topic.valid?
|
677
|
+
assert_equal 'custom message', @topic.errors.on(:title)
|
678
|
+
end
|
679
|
+
|
680
|
+
def test_validates_numericality_of_less_than_finds_global_default_translation
|
681
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}}
|
682
|
+
|
683
|
+
Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0
|
684
|
+
@topic.title = 1
|
685
|
+
@topic.valid?
|
686
|
+
assert_equal 'global message', @topic.errors.on(:title)
|
687
|
+
end
|
688
|
+
|
689
|
+
|
690
|
+
# validates_associated w/o mocha
|
691
|
+
|
692
|
+
def test_validates_associated_finds_custom_model_key_translation
|
693
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:replies => {:invalid => 'custom message'}}}}}}
|
694
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
|
695
|
+
|
696
|
+
Topic.validates_associated :replies
|
697
|
+
replied_topic.valid?
|
698
|
+
assert_equal 'custom message', replied_topic.errors.on(:replies)
|
699
|
+
end
|
700
|
+
|
701
|
+
def test_validates_associated_finds_global_default_translation
|
702
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
|
703
|
+
|
704
|
+
Topic.validates_associated :replies
|
705
|
+
replied_topic.valid?
|
706
|
+
assert_equal 'global message', replied_topic.errors.on(:replies)
|
707
|
+
end
|
708
|
+
|
709
|
+
def test_validations_with_message_symbol_must_translate
|
710
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:custom_error => "I am a custom error"}}}
|
711
|
+
Topic.validates_presence_of :title, :message => :custom_error
|
712
|
+
@topic.title = nil
|
713
|
+
@topic.valid?
|
714
|
+
assert_equal "I am a custom error", @topic.errors.on(:title)
|
715
|
+
end
|
716
|
+
|
717
|
+
def test_validates_with_message_symbol_must_translate_per_attribute
|
718
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:custom_error => "I am a custom error"}}}}}}
|
719
|
+
Topic.validates_presence_of :title, :message => :custom_error
|
720
|
+
@topic.title = nil
|
721
|
+
@topic.valid?
|
722
|
+
assert_equal "I am a custom error", @topic.errors.on(:title)
|
723
|
+
end
|
724
|
+
|
725
|
+
def test_validates_with_message_symbol_must_translate_per_model
|
726
|
+
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:custom_error => "I am a custom error"}}}}
|
727
|
+
Topic.validates_presence_of :title, :message => :custom_error
|
728
|
+
@topic.title = nil
|
729
|
+
@topic.valid?
|
730
|
+
assert_equal "I am a custom error", @topic.errors.on(:title)
|
731
|
+
end
|
732
|
+
|
733
|
+
def test_validates_with_message_string
|
734
|
+
Topic.validates_presence_of :title, :message => "I am a custom error"
|
735
|
+
@topic.title = nil
|
736
|
+
@topic.valid?
|
737
|
+
assert_equal "I am a custom error", @topic.errors.on(:title)
|
738
|
+
end
|
739
|
+
|
740
|
+
end
|
741
|
+
|
742
|
+
class ActiveRecordValidationsGenerateMessageI18nTests < Test::Unit::TestCase
|
743
|
+
def setup
|
744
|
+
reset_callbacks Topic
|
745
|
+
@topic = Topic.new
|
746
|
+
I18n.backend.store_translations :'en', {
|
747
|
+
:activerecord => {
|
748
|
+
:errors => {
|
749
|
+
:messages => {
|
750
|
+
:inclusion => "is not included in the list",
|
751
|
+
:exclusion => "is reserved",
|
752
|
+
:invalid => "is invalid",
|
753
|
+
:confirmation => "doesn't match confirmation",
|
754
|
+
:accepted => "must be accepted",
|
755
|
+
:empty => "can't be empty",
|
756
|
+
:blank => "can't be blank",
|
757
|
+
:too_long => "is too long (maximum is {{count}} characters)",
|
758
|
+
:too_short => "is too short (minimum is {{count}} characters)",
|
759
|
+
:wrong_length => "is the wrong length (should be {{count}} characters)",
|
760
|
+
:taken => "has already been taken",
|
761
|
+
:not_a_number => "is not a number",
|
762
|
+
:greater_than => "must be greater than {{count}}",
|
763
|
+
:greater_than_or_equal_to => "must be greater than or equal to {{count}}",
|
764
|
+
:equal_to => "must be equal to {{count}}",
|
765
|
+
:less_than => "must be less than {{count}}",
|
766
|
+
:less_than_or_equal_to => "must be less than or equal to {{count}}",
|
767
|
+
:odd => "must be odd",
|
768
|
+
:even => "must be even"
|
769
|
+
}
|
770
|
+
}
|
771
|
+
}
|
772
|
+
}
|
773
|
+
end
|
774
|
+
|
775
|
+
def reset_callbacks(*models)
|
776
|
+
models.each do |model|
|
777
|
+
model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
778
|
+
model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
779
|
+
model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
# validates_inclusion_of: generate_message(attr_name, :inclusion, :default => configuration[:message], :value => value)
|
784
|
+
def test_generate_message_inclusion_with_default_message
|
785
|
+
assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title')
|
786
|
+
end
|
787
|
+
|
788
|
+
def test_generate_message_inclusion_with_custom_message
|
789
|
+
assert_equal 'custom message title', @topic.errors.generate_message(:title, :inclusion, :default => 'custom message {{value}}', :value => 'title')
|
790
|
+
end
|
791
|
+
|
792
|
+
# validates_exclusion_of: generate_message(attr_name, :exclusion, :default => configuration[:message], :value => value)
|
793
|
+
def test_generate_message_exclusion_with_default_message
|
794
|
+
assert_equal 'is reserved', @topic.errors.generate_message(:title, :exclusion, :default => nil, :value => 'title')
|
795
|
+
end
|
796
|
+
|
797
|
+
def test_generate_message_exclusion_with_custom_message
|
798
|
+
assert_equal 'custom message title', @topic.errors.generate_message(:title, :exclusion, :default => 'custom message {{value}}', :value => 'title')
|
799
|
+
end
|
800
|
+
|
801
|
+
# validates_associated: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value)
|
802
|
+
# validates_format_of: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value)
|
803
|
+
def test_generate_message_invalid_with_default_message
|
804
|
+
assert_equal 'is invalid', @topic.errors.generate_message(:title, :invalid, :default => nil, :value => 'title')
|
805
|
+
end
|
806
|
+
|
807
|
+
def test_generate_message_invalid_with_custom_message
|
808
|
+
assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title')
|
809
|
+
end
|
810
|
+
|
811
|
+
# validates_confirmation_of: generate_message(attr_name, :confirmation, :default => configuration[:message])
|
812
|
+
def test_generate_message_confirmation_with_default_message
|
813
|
+
assert_equal "doesn't match confirmation", @topic.errors.generate_message(:title, :confirmation, :default => nil)
|
814
|
+
end
|
815
|
+
|
816
|
+
def test_generate_message_confirmation_with_custom_message
|
817
|
+
assert_equal 'custom message', @topic.errors.generate_message(:title, :confirmation, :default => 'custom message')
|
818
|
+
end
|
819
|
+
|
820
|
+
# validates_acceptance_of: generate_message(attr_name, :accepted, :default => configuration[:message])
|
821
|
+
def test_generate_message_accepted_with_default_message
|
822
|
+
assert_equal "must be accepted", @topic.errors.generate_message(:title, :accepted, :default => nil)
|
823
|
+
end
|
824
|
+
|
825
|
+
def test_generate_message_accepted_with_custom_message
|
826
|
+
assert_equal 'custom message', @topic.errors.generate_message(:title, :accepted, :default => 'custom message')
|
827
|
+
end
|
828
|
+
|
829
|
+
# add_on_empty: generate_message(attr, :empty, :default => custom_message)
|
830
|
+
def test_generate_message_empty_with_default_message
|
831
|
+
assert_equal "can't be empty", @topic.errors.generate_message(:title, :empty, :default => nil)
|
832
|
+
end
|
833
|
+
|
834
|
+
def test_generate_message_empty_with_custom_message
|
835
|
+
assert_equal 'custom message', @topic.errors.generate_message(:title, :empty, :default => 'custom message')
|
836
|
+
end
|
837
|
+
|
838
|
+
# add_on_blank: generate_message(attr, :blank, :default => custom_message)
|
839
|
+
def test_generate_message_blank_with_default_message
|
840
|
+
assert_equal "can't be blank", @topic.errors.generate_message(:title, :blank, :default => nil)
|
841
|
+
end
|
842
|
+
|
843
|
+
def test_generate_message_blank_with_custom_message
|
844
|
+
assert_equal 'custom message', @topic.errors.generate_message(:title, :blank, :default => 'custom message')
|
845
|
+
end
|
846
|
+
|
847
|
+
# validates_length_of: generate_message(attr, :too_long, :default => options[:too_long], :count => option_value.end)
|
848
|
+
def test_generate_message_too_long_with_default_message
|
849
|
+
assert_equal "is too long (maximum is 10 characters)", @topic.errors.generate_message(:title, :too_long, :default => nil, :count => 10)
|
850
|
+
end
|
851
|
+
|
852
|
+
def test_generate_message_too_long_with_custom_message
|
853
|
+
assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_long, :default => 'custom message {{count}}', :count => 10)
|
854
|
+
end
|
855
|
+
|
856
|
+
# validates_length_of: generate_message(attr, :too_short, :default => options[:too_short], :count => option_value.begin)
|
857
|
+
def test_generate_message_too_short_with_default_message
|
858
|
+
assert_equal "is too short (minimum is 10 characters)", @topic.errors.generate_message(:title, :too_short, :default => nil, :count => 10)
|
859
|
+
end
|
860
|
+
|
861
|
+
def test_generate_message_too_short_with_custom_message
|
862
|
+
assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_short, :default => 'custom message {{count}}', :count => 10)
|
863
|
+
end
|
864
|
+
|
865
|
+
# validates_length_of: generate_message(attr, key, :default => custom_message, :count => option_value)
|
866
|
+
def test_generate_message_wrong_length_with_default_message
|
867
|
+
assert_equal "is the wrong length (should be 10 characters)", @topic.errors.generate_message(:title, :wrong_length, :default => nil, :count => 10)
|
868
|
+
end
|
869
|
+
|
870
|
+
def test_generate_message_wrong_length_with_custom_message
|
871
|
+
assert_equal 'custom message 10', @topic.errors.generate_message(:title, :wrong_length, :default => 'custom message {{count}}', :count => 10)
|
872
|
+
end
|
873
|
+
|
874
|
+
# validates_uniqueness_of: generate_message(attr_name, :taken, :default => configuration[:message])
|
875
|
+
def test_generate_message_taken_with_default_message
|
876
|
+
assert_equal "has already been taken", @topic.errors.generate_message(:title, :taken, :default => nil, :value => 'title')
|
877
|
+
end
|
878
|
+
|
879
|
+
def test_generate_message_taken_with_custom_message
|
880
|
+
assert_equal 'custom message title', @topic.errors.generate_message(:title, :taken, :default => 'custom message {{value}}', :value => 'title')
|
881
|
+
end
|
882
|
+
|
883
|
+
# validates_numericality_of: generate_message(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message])
|
884
|
+
def test_generate_message_not_a_number_with_default_message
|
885
|
+
assert_equal "is not a number", @topic.errors.generate_message(:title, :not_a_number, :default => nil, :value => 'title')
|
886
|
+
end
|
887
|
+
|
888
|
+
def test_generate_message_not_a_number_with_custom_message
|
889
|
+
assert_equal 'custom message title', @topic.errors.generate_message(:title, :not_a_number, :default => 'custom message {{value}}', :value => 'title')
|
890
|
+
end
|
891
|
+
|
892
|
+
# validates_numericality_of: generate_message(attr_name, option, :value => raw_value, :default => configuration[:message])
|
893
|
+
def test_generate_message_greater_than_with_default_message
|
894
|
+
assert_equal "must be greater than 10", @topic.errors.generate_message(:title, :greater_than, :default => nil, :value => 'title', :count => 10)
|
895
|
+
end
|
896
|
+
|
897
|
+
def test_generate_message_greater_than_or_equal_to_with_default_message
|
898
|
+
assert_equal "must be greater than or equal to 10", @topic.errors.generate_message(:title, :greater_than_or_equal_to, :default => nil, :value => 'title', :count => 10)
|
899
|
+
end
|
900
|
+
|
901
|
+
def test_generate_message_equal_to_with_default_message
|
902
|
+
assert_equal "must be equal to 10", @topic.errors.generate_message(:title, :equal_to, :default => nil, :value => 'title', :count => 10)
|
903
|
+
end
|
904
|
+
|
905
|
+
def test_generate_message_less_than_with_default_message
|
906
|
+
assert_equal "must be less than 10", @topic.errors.generate_message(:title, :less_than, :default => nil, :value => 'title', :count => 10)
|
907
|
+
end
|
908
|
+
|
909
|
+
def test_generate_message_less_than_or_equal_to_with_default_message
|
910
|
+
assert_equal "must be less than or equal to 10", @topic.errors.generate_message(:title, :less_than_or_equal_to, :default => nil, :value => 'title', :count => 10)
|
911
|
+
end
|
912
|
+
|
913
|
+
def test_generate_message_odd_with_default_message
|
914
|
+
assert_equal "must be odd", @topic.errors.generate_message(:title, :odd, :default => nil, :value => 'title', :count => 10)
|
915
|
+
end
|
916
|
+
|
917
|
+
def test_generate_message_even_with_default_message
|
918
|
+
assert_equal "must be even", @topic.errors.generate_message(:title, :even, :default => nil, :value => 'title', :count => 10)
|
919
|
+
end
|
920
|
+
|
921
|
+
end
|