diff options
Diffstat (limited to 'activerecord/test')
19 files changed, 1088 insertions, 14 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index 11f9870534..04770646b2 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -65,6 +65,12 @@ class AdapterTest < ActiveRecord::TestCase end end + if current_adapter?(:PostgreSQLAdapter) + def test_encoding + assert_not_nil @connection.encoding + end + end + def test_table_alias def @connection.test_table_alias_length() 10; end class << @connection diff --git a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb new file mode 100644 index 0000000000..7c470616a5 --- /dev/null +++ b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb @@ -0,0 +1,36 @@ +require 'cases/helper' +require 'models/post' +require 'models/tagging' + +module Namespaced + class Post < ActiveRecord::Base + set_table_name 'posts' + has_one :tagging, :as => :taggable, :class_name => 'Tagging' + end +end + +class EagerLoadIncludeFullStiClassNamesTest < ActiveRecord::TestCase + + def setup + generate_test_objects + end + + def generate_test_objects + post = Namespaced::Post.create( :title => 'Great stuff', :body => 'This is not', :author_id => 1 ) + tagging = Tagging.create( :taggable => post ) + end + + def test_class_names + old = ActiveRecord::Base.store_full_sti_class + + ActiveRecord::Base.store_full_sti_class = false + post = Namespaced::Post.find_by_title( 'Great stuff', :include => :tagging ) + assert_nil post.tagging + + ActiveRecord::Base.store_full_sti_class = true + post = Namespaced::Post.find_by_title( 'Great stuff', :include => :tagging ) + assert_equal 'Tagging', post.tagging.class.name + ensure + ActiveRecord::Base.store_full_sti_class = old + end +end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index e90edbb213..f8b8b1f96d 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -425,6 +425,37 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 2, first_topic.replies.to_ary.size end + def test_build_via_block + company = companies(:first_firm) + new_client = assert_no_queries { company.clients_of_firm.build {|client| client.name = "Another Client" } } + assert !company.clients_of_firm.loaded? + + assert_equal "Another Client", new_client.name + assert new_client.new_record? + assert_equal new_client, company.clients_of_firm.last + company.name += '-changed' + assert_queries(2) { assert company.save } + assert !new_client.new_record? + assert_equal 2, company.clients_of_firm(true).size + end + + def test_build_many_via_block + company = companies(:first_firm) + new_clients = assert_no_queries do + company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client| + client.name = "changed" + end + end + + assert_equal 2, new_clients.size + assert_equal "changed", new_clients.first.name + assert_equal "changed", new_clients.last.name + + company.name += '-changed' + assert_queries(3) { assert company.save } + assert_equal 3, company.clients_of_firm(true).size + end + def test_create_without_loading_association first_firm = companies(:first_firm) Firm.column_names @@ -968,4 +999,22 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert firm.clients.loaded? end + def test_joins_with_namespaced_model_should_use_correct_type + old = ActiveRecord::Base.store_full_sti_class + ActiveRecord::Base.store_full_sti_class = true + + firm = Namespaced::Firm.create({ :name => 'Some Company' }) + firm.clients.create({ :name => 'Some Client' }) + + stats = Namespaced::Firm.find(firm.id, { + :select => "#{Namespaced::Firm.table_name}.*, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients", + :joins => :clients, + :group => "#{Namespaced::Firm.table_name}.id" + }) + assert_equal 1, stats.num_clients.to_i + + ensure + ActiveRecord::Base.store_full_sti_class = old + end + end diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 59349dd7cf..4904feeb7d 100755 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -189,6 +189,114 @@ class AssociationProxyTest < ActiveRecord::TestCase end end + def test_belongs_to_mass_assignment + post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' } + author_attributes = { :name => 'David Dollar' } + + assert_no_difference 'Author.count' do + assert_raise(ActiveRecord::AssociationTypeMismatch) do + Post.create(post_attributes.merge({:author => author_attributes})) + end + end + + assert_difference 'Author.count' do + post = Post.create(post_attributes.merge({:creatable_author => author_attributes})) + assert_equal post.creatable_author.name, author_attributes[:name] + end + end + + def test_has_one_mass_assignment + post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' } + comment_attributes = { :body => 'Setter Takes Hash' } + + assert_no_difference 'Comment.count' do + assert_raise(ActiveRecord::AssociationTypeMismatch) do + Post.create(post_attributes.merge({:uncreatable_comment => comment_attributes})) + end + end + + assert_difference 'Comment.count' do + post = Post.create(post_attributes.merge({:creatable_comment => comment_attributes})) + assert_equal post.creatable_comment.body, comment_attributes[:body] + end + end + + def test_has_many_mass_assignment + post = posts(:welcome) + post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' } + comment_attributes = { :body => 'Setter Takes Hash' } + + assert_no_difference 'Comment.count' do + assert_raise(ActiveRecord::AssociationTypeMismatch) do + Post.create(post_attributes.merge({:comments => [comment_attributes]})) + end + assert_raise(ActiveRecord::AssociationTypeMismatch) do + post.comments << comment_attributes + end + end + + assert_difference 'Comment.count' do + post = Post.create(post_attributes.merge({:creatable_comments => [comment_attributes]})) + assert_equal post.creatable_comments.last.body, comment_attributes[:body] + end + + assert_difference 'Comment.count' do + post.creatable_comments << comment_attributes + assert_equal post.comments.last.body, comment_attributes[:body] + end + + post.creatable_comments = [comment_attributes, comment_attributes] + assert_equal post.creatable_comments.count, 2 + end + + def test_has_and_belongs_to_many_mass_assignment + post = posts(:welcome) + post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' } + category_attributes = { :name => 'Accessible Association', :type => 'Category' } + + assert_no_difference 'Category.count' do + assert_raise(ActiveRecord::AssociationTypeMismatch) do + Post.create(post_attributes.merge({:categories => [category_attributes]})) + end + assert_raise(ActiveRecord::AssociationTypeMismatch) do + post.categories << category_attributes + end + end + + assert_difference 'Category.count' do + post = Post.create(post_attributes.merge({:creatable_categories => [category_attributes]})) + assert_equal post.creatable_categories.last.name, category_attributes[:name] + end + + assert_difference 'Category.count' do + post.creatable_categories << category_attributes + assert_equal post.creatable_categories.last.name, category_attributes[:name] + end + + post.creatable_categories = [category_attributes, category_attributes] + assert_equal post.creatable_categories.count, 2 + end + + def test_association_proxy_setter_can_take_hash + special_comment_attributes = { :body => 'Setter Takes Hash' } + + post = posts(:welcome) + post.creatable_comment = { :body => 'Setter Takes Hash' } + + assert_equal post.creatable_comment.body, special_comment_attributes[:body] + end + + def test_association_collection_can_take_hash + post_attributes = { :title => 'Setter Takes', :body => 'Hash' } + david = authors(:david) + + post = (david.posts << post_attributes).last + assert_equal post.title, post_attributes[:title] + + david.posts = [post_attributes, post_attributes] + assert_equal david.posts.count, 2 + end + def setup_dangling_association josh = Author.create(:name => "Josh") p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index a4be629fbd..9e4f268db7 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -19,6 +19,7 @@ require 'models/warehouse_thing' require 'rexml/document' class Category < ActiveRecord::Base; end +class Categorization < ActiveRecord::Base; end class Smarts < ActiveRecord::Base; end class CreditCard < ActiveRecord::Base class PinNumber < ActiveRecord::Base @@ -75,7 +76,7 @@ class TopicWithProtectedContentAndAccessibleAuthorName < ActiveRecord::Base end class BasicsTest < ActiveRecord::TestCase - fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors + fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations def test_table_exists assert !NonExistentTable.table_exists? @@ -130,7 +131,7 @@ class BasicsTest < ActiveRecord::TestCase def test_read_attributes_before_type_cast category = Category.new({:name=>"Test categoty", :type => nil}) - category_attrs = {"name"=>"Test categoty", "type" => nil} + category_attrs = {"name"=>"Test categoty", "type" => nil, "categorizations_count" => nil} assert_equal category_attrs , category.attributes_before_type_cast end @@ -614,6 +615,22 @@ class BasicsTest < ActiveRecord::TestCase assert_equal -2, Topic.find(2).replies_count end + def test_update_counter + category = Category.first + assert_nil category.categorizations_count + assert_equal 2, category.categorizations.count + + Category.update_counters(category.id, "categorizations_count" => category.categorizations.count) + category.reload + assert_not_nil category.categorizations_count + assert_equal 2, category.categorizations_count + + Category.update_counters(category.id, "categorizations_count" => category.categorizations.count) + category.reload + assert_not_nil category.categorizations_count + assert_equal 4, category.categorizations_count + end + def test_update_all assert_equal Topic.count, Topic.update_all("content = 'bulk updated!'") assert_equal "bulk updated!", Topic.find(1).content diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb new file mode 100644 index 0000000000..540f42f4b6 --- /dev/null +++ b/activerecord/test/cases/column_definition_test.rb @@ -0,0 +1,36 @@ +require "cases/helper" + +class ColumnDefinitionTest < ActiveRecord::TestCase + def setup + @adapter = ActiveRecord::ConnectionAdapters::AbstractAdapter.new(nil) + def @adapter.native_database_types + {:string => "varchar"} + end + end + + # Avoid column definitions in create table statements like: + # `title` varchar(255) DEFAULT NULL NULL + def test_should_not_include_default_clause_when_default_is_null + column = ActiveRecord::ConnectionAdapters::Column.new("title", nil, "varchar(20)") + column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new( + @adapter, column.name, "string", + column.limit, column.precision, column.scale, column.default, column.null) + assert_equal "title varchar(20) NULL", column_def.to_sql + end + + def test_should_include_default_clause_when_default_is_present + column = ActiveRecord::ConnectionAdapters::Column.new("title", "Hello", "varchar(20)") + column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new( + @adapter, column.name, "string", + column.limit, column.precision, column.scale, column.default, column.null) + assert_equal %Q{title varchar(20) DEFAULT 'Hello' NULL}, column_def.to_sql + end + + def test_should_specify_not_null_if_null_option_is_false + column = ActiveRecord::ConnectionAdapters::Column.new("title", "Hello", "varchar(20)", false) + column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new( + @adapter, column.name, "string", + column.limit, column.precision, column.scale, column.default, column.null) + assert_equal %Q{title varchar(20) DEFAULT 'Hello' NOT NULL}, column_def.to_sql + end +end
\ No newline at end of file diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index aca7cfb367..6ba7597f56 100755 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -15,6 +15,7 @@ require 'models/pirate' require 'models/treasure' require 'models/matey' require 'models/ship' +require 'models/book' class FixturesTest < ActiveRecord::TestCase self.use_instantiated_fixtures = true @@ -373,6 +374,34 @@ class CheckSetTableNameFixturesTest < ActiveRecord::TestCase end end +class FixtureNameIsNotTableNameFixturesTest < ActiveRecord::TestCase + set_fixture_class :items => Book + fixtures :items + # Set to false to blow away fixtures cache and ensure our fixtures are loaded + # and thus takes into account our set_fixture_class + self.use_transactional_fixtures = false + + def test_named_accessor + assert_kind_of Book, items(:dvd) + end +end + +class FixtureNameIsNotTableNameMultipleFixturesTest < ActiveRecord::TestCase + set_fixture_class :items => Book, :funny_jokes => Joke + fixtures :items, :funny_jokes + # Set to false to blow away fixtures cache and ensure our fixtures are loaded + # and thus takes into account our set_fixture_class + self.use_transactional_fixtures = false + + def test_named_accessor_of_differently_named_fixture + assert_kind_of Book, items(:dvd) + end + + def test_named_accessor_of_same_named_fixture + assert_kind_of Joke, funny_jokes(:a_joke) + end +end + class CustomConnectionFixturesTest < ActiveRecord::TestCase set_fixture_class :courses => Course fixtures :courses @@ -432,11 +461,11 @@ class FixturesBrokenRollbackTest < ActiveRecord::TestCase alias_method :teardown, :blank_teardown def test_no_rollback_in_teardown_unless_transaction_active - assert_equal 0, Thread.current['open_transactions'] + assert_equal 0, ActiveRecord::Base.connection.open_transactions assert_raise(RuntimeError) { ar_setup_fixtures } - assert_equal 0, Thread.current['open_transactions'] + assert_equal 0, ActiveRecord::Base.connection.open_transactions assert_nothing_raised { ar_teardown_fixtures } - assert_equal 0, Thread.current['open_transactions'] + assert_equal 0, ActiveRecord::Base.connection.open_transactions end private diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index dc83300efa..0530ba9bd9 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -32,13 +32,13 @@ end ActiveRecord::Base.connection.class.class_eval do IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/] - def execute_with_counting(sql, name = nil, &block) - $query_count ||= 0 - $query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r } - execute_without_counting(sql, name, &block) + def execute_with_query_record(sql, name = nil, &block) + $queries_executed ||= [] + $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r } + execute_without_query_record(sql, name, &block) end - alias_method_chain :execute, :counting + alias_method_chain :execute, :query_record end # Make with_scope public for tests diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index 47fb5c608f..4fd38bfbc9 100755 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -191,6 +191,13 @@ class InheritanceTest < ActiveRecord::TestCase assert_not_nil account.instance_variable_get("@firm"), "nil proves eager load failed" end + def test_eager_load_belongs_to_primary_key_quoting + con = Account.connection + assert_sql(/\(#{con.quote_table_name('companies')}.#{con.quote_column_name('id')} IN \(1\)\)/) do + Account.find(1, :include => :firm) + end + end + def test_alt_eager_loading switch_to_alt_inheritance_column test_eager_load_belongs_to_something_inherited diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb index 258f7c7a0f..ab005c6b00 100755 --- a/activerecord/test/cases/lifecycle_test.rb +++ b/activerecord/test/cases/lifecycle_test.rb @@ -143,7 +143,7 @@ class LifecycleTest < ActiveRecord::TestCase assert_equal developer.name, multi_observer.record.name end - def test_observing_after_find_when_not_defined_on_the_model + def test_after_find_can_be_observed_when_its_not_defined_on_the_model observer = MinimalisticObserver.instance assert_equal Minimalistic, MinimalisticObserver.observed_class @@ -151,6 +151,42 @@ class LifecycleTest < ActiveRecord::TestCase assert_equal minimalistic, observer.minimalistic end + def test_after_find_can_be_observed_when_its_defined_on_the_model + observer = TopicObserver.instance + assert_equal Topic, TopicObserver.observed_class + + topic = Topic.find(1) + assert_equal topic, observer.topic + end + + def test_after_find_is_not_created_if_its_not_used + # use a fresh class so an observer can't have defined an + # after_find on it + model_class = Class.new(ActiveRecord::Base) + observer_class = Class.new(ActiveRecord::Observer) + observer_class.observe(model_class) + + observer = observer_class.instance + + assert !model_class.method_defined?(:after_find) + end + + def test_after_find_is_not_clobbered_if_it_already_exists + # use a fresh observer class so we can instantiate it (Observer is + # a Singleton) + model_class = Class.new(ActiveRecord::Base) do + def after_find; end + end + original_method = model_class.instance_method(:after_find) + observer_class = Class.new(ActiveRecord::Observer) do + def after_find; end + end + observer_class.observe(model_class) + + observer = observer_class.instance + assert_equal original_method, model_class.instance_method(:after_find) + end + def test_invalid_observer assert_raise(ArgumentError) { Topic.observers = Object.new; Topic.instantiate_observers } end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 4482b487dd..7ecf755ef8 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -3,6 +3,7 @@ require 'bigdecimal/util' require 'models/person' require 'models/topic' +require 'models/developer' require MIGRATIONS_ROOT + "/valid/1_people_have_last_names" require MIGRATIONS_ROOT + "/valid/2_we_need_reminders" @@ -511,7 +512,12 @@ if ActiveRecord::Base.connection.supports_migrations? ActiveRecord::Base.connection.create_table(:hats) do |table| table.column :hat_name, :string, :default => nil end - assert_raises(ActiveRecord::ActiveRecordError) do + exception = if current_adapter?(:PostgreSQLAdapter) + ActiveRecord::StatementInvalid + else + ActiveRecord::ActiveRecordError + end + assert_raises(exception) do Person.connection.rename_column "hats", "nonexistent", "should_fail" end ensure @@ -697,6 +703,55 @@ if ActiveRecord::Base.connection.supports_migrations? Person.connection.drop_table :testings rescue nil end + def test_keeping_default_and_notnull_constaint_on_change + Person.connection.create_table :testings do |t| + t.column :title, :string + end + person_klass = Class.new(Person) + person_klass.set_table_name 'testings' + + person_klass.connection.add_column "testings", "wealth", :integer, :null => false, :default => 99 + person_klass.reset_column_information + assert_equal 99, person_klass.columns_hash["wealth"].default + assert_equal false, person_klass.columns_hash["wealth"].null + assert_nothing_raised {person_klass.connection.execute("insert into testings (title) values ('tester')")} + + # change column default to see that column doesn't lose its not null definition + person_klass.connection.change_column_default "testings", "wealth", 100 + person_klass.reset_column_information + assert_equal 100, person_klass.columns_hash["wealth"].default + assert_equal false, person_klass.columns_hash["wealth"].null + + # rename column to see that column doesn't lose its not null and/or default definition + person_klass.connection.rename_column "testings", "wealth", "money" + person_klass.reset_column_information + assert_nil person_klass.columns_hash["wealth"] + assert_equal 100, person_klass.columns_hash["money"].default + assert_equal false, person_klass.columns_hash["money"].null + + # change column + person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000 + person_klass.reset_column_information + assert_equal 1000, person_klass.columns_hash["money"].default + assert_equal false, person_klass.columns_hash["money"].null + + # change column, make it nullable and clear default + person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil + person_klass.reset_column_information + assert_nil person_klass.columns_hash["money"].default + assert_equal true, person_klass.columns_hash["money"].null + + # change_column_null, make it not nullable and set null values to a default value + person_klass.connection.execute('UPDATE testings SET money = NULL') + person_klass.connection.change_column_null "testings", "money", false, 2000 + person_klass.reset_column_information + assert_nil person_klass.columns_hash["money"].default + assert_equal false, person_klass.columns_hash["money"].null + assert_equal [2000], Person.connection.select_values("SELECT money FROM testings").map { |s| s.to_i }.sort + ensure + Person.connection.drop_table :testings rescue nil + end + def test_change_column_default_to_null Person.connection.change_column_default "people", "first_name", nil Person.reset_column_information diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb index eb3e43c8ac..7c3e0f2ca6 100644 --- a/activerecord/test/cases/multiple_db_test.rb +++ b/activerecord/test/cases/multiple_db_test.rb @@ -57,4 +57,29 @@ class MultipleDbTest < ActiveRecord::TestCase assert Course.connection end + + def test_transactions_across_databases + c1 = Course.find(1) + e1 = Entrant.find(1) + + begin + Course.transaction do + Entrant.transaction do + c1.name = "Typo" + e1.name = "Typo" + c1.save + e1.save + raise "No I messed up." + end + end + rescue + # Yup caught it + end + + assert_equal "Typo", c1.name + assert_equal "Typo", e1.name + + assert_equal "Ruby Development", Course.find(1).name + assert_equal "Ruby Developer", Entrant.find(1).name + end end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 0c1eb23428..e21ffbbdba 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -184,6 +184,28 @@ class NamedScopeTest < ActiveRecord::TestCase end end + def test_any_should_not_load_results + topics = Topic.base + assert_queries(1) do + topics.expects(:empty?).returns(true) + assert !topics.any? + end + end + + def test_any_should_call_proxy_found_if_using_a_block + topics = Topic.base + assert_queries(1) do + topics.expects(:empty?).never + topics.any? { true } + end + end + + def test_any_should_not_fire_query_if_named_scope_loaded + topics = Topic.base + topics.collect # force load + assert_no_queries { assert topics.any? } + end + def test_should_build_with_proxy_options topic = Topic.approved.build({}) assert topic.approved diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb new file mode 100644 index 0000000000..86834fe920 --- /dev/null +++ b/activerecord/test/cases/validations_i18n_test.rb @@ -0,0 +1,623 @@ +require "cases/helper" +require 'models/topic' +require 'models/reply' + +class ActiveRecordValidationsI18nTests < Test::Unit::TestCase + def setup + reset_callbacks Topic + @topic = Topic.new + I18n.backend.store_translations('en-US', :active_record => {:error_messages => {:custom => nil}}) + end + + def teardown + reset_callbacks Topic + load 'active_record/locale/en-US.rb' + end + + def unique_topic + @unique ||= Topic.create :title => 'unique!' + end + + def replied_topic + @replied_topic ||= begin + topic = Topic.create(:title => "topic") + topic.replies << Reply.new + topic + end + end + + def reset_callbacks(*models) + models.each do |model| + model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + end + end + + def test_default_error_messages_is_deprecated + assert_deprecated('ActiveRecord::Errors.default_error_messages') do + ActiveRecord::Errors.default_error_messages + end + end + + # ActiveRecord::Errors + uses_mocha 'ActiveRecord::Errors' do + def test_errors_generate_message_translates_custom_model_attribute_key + global_scope = [:active_record, :error_messages] + custom_scope = global_scope + [:custom, 'topic', :title] + + I18n.expects(:t).with nil, :scope => [:active_record, :error_messages], :default => [:"custom.topic.title.invalid", 'default from class def', :invalid] + @topic.errors.generate_message :title, :invalid, :default => 'default from class def' + end + + def test_errors_generate_message_translates_custom_model_attribute_keys_with_sti + custom_scope = [:active_record, :error_messages, :custom, 'topic', :title] + + I18n.expects(:t).with nil, :scope => [:active_record, :error_messages], :default => [:"custom.reply.title.invalid", :"custom.topic.title.invalid", 'default from class def', :invalid] + Reply.new.errors.generate_message :title, :invalid, :default => 'default from class def' + end + + def test_errors_add_on_empty_generates_message + @topic.errors.expects(:generate_message).with(:title, :empty, {:default => nil}) + @topic.errors.add_on_empty :title + end + + def test_errors_add_on_empty_generates_message_with_custom_default_message + @topic.errors.expects(:generate_message).with(:title, :empty, {:default => 'custom'}) + @topic.errors.add_on_empty :title, 'custom' + end + + def test_errors_add_on_blank_generates_message + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) + @topic.errors.add_on_blank :title + end + + def test_errors_add_on_blank_generates_message_with_custom_default_message + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) + @topic.errors.add_on_blank :title, 'custom' + end + + def test_errors_full_messages_translates_human_attribute_name_for_model_attributes + @topic.errors.instance_variable_set :@errors, { 'title' => 'empty' } + I18n.expects(:translate).with(:"active_record.human_attribute_names.topic.title", :locale => 'en-US', :default => 'Title').returns('Title') + @topic.errors.full_messages :locale => 'en-US' + end + end + + # ActiveRecord::Validations + uses_mocha 'ActiveRecord::Validations' do + # validates_confirmation_of w/ mocha + + def test_validates_confirmation_of_generates_message + Topic.validates_confirmation_of :title + @topic.title_confirmation = 'foo' + @topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => nil}) + @topic.valid? + end + + def test_validates_confirmation_of_generates_message_with_custom_default_message + Topic.validates_confirmation_of :title, :message => 'custom' + @topic.title_confirmation = 'foo' + @topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => 'custom'}) + @topic.valid? + end + + # validates_acceptance_of w/ mocha + + def test_validates_acceptance_of_generates_message + Topic.validates_acceptance_of :title, :allow_nil => false + @topic.errors.expects(:generate_message).with(:title, :accepted, {:default => nil}) + @topic.valid? + end + + def test_validates_acceptance_of_generates_message_with_custom_default_message + Topic.validates_acceptance_of :title, :message => 'custom', :allow_nil => false + @topic.errors.expects(:generate_message).with(:title, :accepted, {:default => 'custom'}) + @topic.valid? + end + + # validates_presence_of w/ mocha + + def test_validates_presence_of_generates_message + Topic.validates_presence_of :title + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) + @topic.valid? + end + + def test_validates_presence_of_generates_message_with_custom_default_message + Topic.validates_presence_of :title, :message => 'custom' + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_short + Topic.validates_length_of :title, :within => 3..5 + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom' + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long + Topic.validates_length_of :title, :within => 3..5 + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom' + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) + @topic.valid? + end + + # validates_length_of :within w/ mocha + + def test_validates_length_of_within_generates_message_with_title_too_short + Topic.validates_length_of :title, :within => 3..5 + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom' + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long + Topic.validates_length_of :title, :within => 3..5 + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom' + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) + @topic.valid? + end + + # validates_length_of :is w/ mocha + + def test_validates_length_of_is_generates_message + Topic.validates_length_of :title, :is => 5 + @topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_is_generates_message_with_custom_default_message + Topic.validates_length_of :title, :is => 5, :message => 'custom' + @topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => 'custom'}) + @topic.valid? + end + + # validates_uniqueness_of w/ mocha + + def test_validates_uniqueness_of_generates_message + Topic.validates_uniqueness_of :title + @topic.title = unique_topic.title + @topic.errors.expects(:generate_message).with(:title, :taken, {:default => nil}) + @topic.valid? + end + + def test_validates_uniqueness_of_generates_message_with_custom_default_message + Topic.validates_uniqueness_of :title, :message => 'custom' + @topic.title = unique_topic.title + @topic.errors.expects(:generate_message).with(:title, :taken, {:default => 'custom'}) + @topic.valid? + end + + # validates_format_of w/ mocha + + def test_validates_format_of_generates_message + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @topic.title = '72x' + @topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => nil}) + @topic.valid? + end + + def test_validates_format_of_generates_message_with_custom_default_message + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/, :message => 'custom' + @topic.title = '72x' + @topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => 'custom'}) + @topic.valid? + end + + # validates_inclusion_of w/ mocha + + def test_validates_inclusion_of_generates_message + Topic.validates_inclusion_of :title, :in => %w(a b c) + @topic.title = 'z' + @topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => nil}) + @topic.valid? + end + + def test_validates_inclusion_of_generates_message_with_custom_default_message + Topic.validates_inclusion_of :title, :in => %w(a b c), :message => 'custom' + @topic.title = 'z' + @topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => 'custom'}) + @topic.valid? + end + + # validates_exclusion_of w/ mocha + + def test_validates_exclusion_of_generates_message + Topic.validates_exclusion_of :title, :in => %w(a b c) + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => nil}) + @topic.valid? + end + + def test_validates_exclusion_of_generates_message_with_custom_default_message + Topic.validates_exclusion_of :title, :in => %w(a b c), :message => 'custom' + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of without :only_integer w/ mocha + + def test_validates_numericality_of_generates_message + Topic.validates_numericality_of :title + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :message => 'custom' + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of with :only_integer w/ mocha + + def test_validates_numericality_of_only_integer_generates_message + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_only_integer_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :only_integer => true, :message => 'custom' + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of :odd w/ mocha + + def test_validates_numericality_of_odd_generates_message + Topic.validates_numericality_of :title, :only_integer => true, :odd => true + @topic.title = 0 + @topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_odd_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :only_integer => true, :odd => true, :message => 'custom' + @topic.title = 0 + @topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of :less_than w/ mocha + + def test_validates_numericality_of_less_than_generates_message + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @topic.title = 1 + @topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_odd_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0, :message => 'custom' + @topic.title = 1 + @topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => 'custom'}) + @topic.valid? + end + + # validates_associated w/ mocha + + def test_validates_associated_generates_message + Topic.validates_associated :replies + replied_topic.errors.expects(:generate_message).with(:replies, :invalid, {:value => replied_topic.replies, :default => nil}) + replied_topic.valid? + end + + def test_validates_associated_generates_message_with_custom_default_message + Topic.validates_associated :replies + replied_topic.errors.expects(:generate_message).with(:replies, :invalid, {:value => replied_topic.replies, :default => nil}) + replied_topic.valid? + end + end + + # validates_confirmation_of w/o mocha + + def test_validates_confirmation_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:confirmation => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:confirmation => 'global message'}} + + Topic.validates_confirmation_of :title + @topic.title_confirmation = 'foo' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_confirmation_of_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:confirmation => 'global message'}} + + Topic.validates_confirmation_of :title + @topic.title_confirmation = 'foo' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_acceptance_of w/o mocha + + def test_validates_acceptance_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:accepted => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:accepted => 'global message'}} + + Topic.validates_acceptance_of :title, :allow_nil => false + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_acceptance_of_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:accepted => 'global message'}} + + Topic.validates_acceptance_of :title, :allow_nil => false + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_presence_of w/o mocha + + def test_validates_presence_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:blank => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:blank => 'global message'}} + + Topic.validates_presence_of :title + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_presence_of_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:blank => 'global message'}} + + Topic.validates_presence_of :title + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_length_of :within w/o mocha + + def test_validates_length_of_within_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:too_short => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:too_short => 'global message'}} + + Topic.validates_length_of :title, :within => 3..5 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_length_of_within_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:too_short => 'global message'}} + + Topic.validates_length_of :title, :within => 3..5 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_length_of :is w/o mocha + + def test_validates_length_of_within_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:wrong_length => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:wrong_length => 'global message'}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_length_of_within_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:wrong_length => 'global message'}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_uniqueness_of w/o mocha + + def test_validates_length_of_within_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:wrong_length => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:wrong_length => 'global message'}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_length_of_within_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:wrong_length => 'global message'}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + + # validates_format_of w/o mocha + + def test_validates_format_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:invalid => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:invalid => 'global message'}} + + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_format_of_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:invalid => 'global message'}} + + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_inclusion_of w/o mocha + + def test_validates_inclusion_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:inclusion => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:inclusion => 'global message'}} + + Topic.validates_inclusion_of :title, :in => %w(a b c) + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_inclusion_of_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:inclusion => 'global message'}} + + Topic.validates_inclusion_of :title, :in => %w(a b c) + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_exclusion_of w/o mocha + + def test_validates_exclusion_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:exclusion => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:exclusion => 'global message'}} + + Topic.validates_exclusion_of :title, :in => %w(a b c) + @topic.title = 'a' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_exclusion_of_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:exclusion => 'global message'}} + + Topic.validates_exclusion_of :title, :in => %w(a b c) + @topic.title = 'a' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_numericality_of without :only_integer w/o mocha + + def test_validates_numericality_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:not_a_number => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:not_a_number => 'global message'}} + + Topic.validates_numericality_of :title + @topic.title = 'a' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:not_a_number => 'global message'}} + + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_numericality_of with :only_integer w/o mocha + + def test_validates_numericality_of_only_integer_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:not_a_number => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:not_a_number => 'global message'}} + + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_only_integer_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:not_a_number => 'global message'}} + + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_numericality_of :odd w/o mocha + + def test_validates_numericality_of_odd_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:odd => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:odd => 'global message'}} + + Topic.validates_numericality_of :title, :only_integer => true, :odd => true + @topic.title = 0 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_odd_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:odd => 'global message'}} + + Topic.validates_numericality_of :title, :only_integer => true, :odd => true + @topic.title = 0 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_numericality_of :less_than w/o mocha + + def test_validates_numericality_of_less_than_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:title => {:less_than => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:less_than => 'global message'}} + + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @topic.title = 1 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_less_than_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:less_than => 'global message'}} + + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @topic.title = 1 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + + # validates_associated w/o mocha + + def test_validates_associated_finds_custom_model_key_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:custom => {:topic => {:replies => {:invalid => 'custom message'}}}}} + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:invalid => 'global message'}} + + Topic.validates_associated :replies + replied_topic.valid? + assert_equal 'custom message', replied_topic.errors.on(:replies) + end + + def test_validates_associated_finds_global_default_translation + I18n.backend.store_translations 'en-US', :active_record => {:error_messages => {:invalid => 'global message'}} + + Topic.validates_associated :replies + replied_topic.valid? + assert_equal 'global message', replied_topic.errors.on(:replies) + end +end
\ No newline at end of file diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index 0742e2c632..4b2d28c80b 100755 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -477,6 +477,15 @@ class ValidationsTest < ActiveRecord::TestCase assert_not_equal "has already been taken", t3.errors.on(:title) end + def test_validate_case_sensitive_uniqueness_with_attribute_passed_as_integer + Topic.validates_uniqueness_of(:title, :case_sensitve => true) + t = Topic.create!('title' => 101) + + t2 = Topic.new('title' => 101) + assert !t2.valid? + assert t2.errors.on(:title) + end + def test_validate_uniqueness_with_non_standard_table_names i1 = WarehouseThing.create(:value => 1000) assert !i1.valid?, "i1 should not be valid" @@ -853,7 +862,9 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_length_with_globally_modified_error_message - ActiveRecord::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre %d' + ActiveSupport::Deprecation.silence do + ActiveRecord::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre %d' + end Topic.validates_length_of :title, :minimum => 10 t = Topic.create(:title => 'too short') assert !t.valid? diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index 82e069005a..136dc39cf3 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -1,5 +1,5 @@ class Author < ActiveRecord::Base - has_many :posts + has_many :posts, :accessible => true has_many :posts_with_comments, :include => :comments, :class_name => "Post" has_many :posts_with_comments_sorted_by_comment_id, :include => :comments, :class_name => "Post", :order => 'comments.id' has_many :posts_with_categories, :include => :categories, :class_name => "Post" diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index e6aa810146..cd435948a1 100755 --- a/activerecord/test/models/company.rb +++ b/activerecord/test/models/company.rb @@ -18,6 +18,13 @@ end module Namespaced class Company < ::Company end + + class Firm < ::Company + has_many :clients, :class_name => 'Namespaced::Client' + end + + class Client < ::Company + end end class Firm < Company diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index 3adbc0ce1f..e23818eb33 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -33,6 +33,12 @@ class Post < ActiveRecord::Base has_and_belongs_to_many :categories has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id' + belongs_to :creatable_author, :class_name => 'Author', :accessible => true + has_one :uncreatable_comment, :class_name => 'Comment', :accessible => false, :order => 'id desc' + has_one :creatable_comment, :class_name => 'Comment', :accessible => true, :order => 'id desc' + has_many :creatable_comments, :class_name => 'Comment', :accessible => true, :dependent => :destroy + has_and_belongs_to_many :creatable_categories, :class_name => 'Category', :accessible => true + has_many :taggings, :as => :taggable has_many :tags, :through => :taggings do def add_joins_and_select diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 29c91a4464..487a08f4ab 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -66,6 +66,7 @@ ActiveRecord::Schema.define do create_table :categories, :force => true do |t| t.string :name, :null => false t.string :type + t.integer :categorizations_count end create_table :categories_posts, :force => true, :id => false do |t| |