diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2010-01-17 03:20:30 +0530 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2010-01-17 03:20:30 +0530 |
commit | b04230e3bbf912d60601e9e7b797c4cd43581d51 (patch) | |
tree | 97a2f784a2ec2bfae4f960af56a9280dad6f7774 /activerecord/test/cases | |
parent | 867829b187969607aa12f2b0457f25da9c204db0 (diff) | |
parent | 6e3bee6cf1f0d2684152292db0a8b757249824fd (diff) | |
download | rails-b04230e3bbf912d60601e9e7b797c4cd43581d51.tar.gz rails-b04230e3bbf912d60601e9e7b797c4cd43581d51.tar.bz2 rails-b04230e3bbf912d60601e9e7b797c4cd43581d51.zip |
Merge remote branch 'mainstream/master'
Conflicts:
actionpack/lib/action_controller/metal/flash.rb
Diffstat (limited to 'activerecord/test/cases')
19 files changed, 402 insertions, 284 deletions
diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb index 18a1cd3cd0..43abcae75e 100644 --- a/activerecord/test/cases/associations/inner_join_association_test.rb +++ b/activerecord/test/cases/associations/inner_join_association_test.rb @@ -8,39 +8,11 @@ require 'models/categorization' class InnerJoinAssociationTest < ActiveRecord::TestCase fixtures :authors, :posts, :comments, :categories, :categories_posts, :categorizations - def test_construct_finder_sql_creates_inner_joins - sql = Author.joins(:posts).to_sql - assert_match /INNER JOIN .?posts.? ON .?posts.?.author_id = authors.id/, sql - end - - def test_construct_finder_sql_cascades_inner_joins - sql = Author.joins(:posts => :comments).to_sql - assert_match /INNER JOIN .?posts.? ON .?posts.?.author_id = authors.id/, sql - assert_match /INNER JOIN .?comments.? ON .?comments.?.post_id = posts.id/, sql - end - - def test_construct_finder_sql_inner_joins_through_associations - sql = Author.joins(:categorized_posts).to_sql - assert_match /INNER JOIN .?categorizations.?.*INNER JOIN .?posts.?/, sql - end - - def test_construct_finder_sql_applies_association_conditions - sql = Author.joins(:categories_like_general).where("TERMINATING_MARKER").to_sql - assert_match /INNER JOIN .?categories.? ON.*AND.*.?General.?(.|\n)*TERMINATING_MARKER/, sql - end - def test_construct_finder_sql_applies_aliases_tables_on_association_conditions result = Author.joins(:thinking_posts, :welcome_posts).to_a assert_equal authors(:david), result.first end - def test_construct_finder_sql_unpacks_nested_joins - sql = Author.joins(:posts => [[:comments]]).to_sql - assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present" - assert_match /INNER JOIN .?posts.? ON .?posts.?.author_id = authors.id/, sql - assert_match /INNER JOIN .?comments.? ON .?comments.?.post_id = .?posts.?.id/, sql - end - def test_construct_finder_sql_ignores_empty_joins_hash sql = Author.joins({}).to_sql assert_no_match /JOIN/i, sql diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index cf763d730a..cc36a6dc5b 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -3,6 +3,8 @@ require 'models/bird' require 'models/company' require 'models/customer' require 'models/developer' +require 'models/invoice' +require 'models/line_item' require 'models/order' require 'models/parrot' require 'models/person' @@ -699,23 +701,18 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase define_method("test_should_rollback_destructions_if_an_exception_occurred_while_saving_#{association_name}") do 2.times { |i| @pirate.send(association_name).create!(:name => "#{association_name}_#{i}") } - before = @pirate.send(association_name).map { |c| c } + before = @pirate.send(association_name).map { |c| c.mark_for_destruction ; c } - # Stub the save method of the first child to destroy and the second to raise an exception - class << before.first - def save(*args) - super - destroy - end - end + # Stub the destroy method of the the second child to raise an exception class << before.last - def save(*args) + def destroy(*args) super raise 'Oh noes!' end end assert_raise(RuntimeError) { assert !@pirate.save } + assert before.first.frozen? # the first child was indeed destroyed assert_equal before, @pirate.reload.send(association_name) end @@ -797,6 +794,14 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase assert @pirate.errors[:catchphrase].any? end + def test_should_not_ignore_different_error_messages_on_the_same_attribute + Ship.validates_format_of :name, :with => /\w/ + @pirate.ship.name = "" + @pirate.catchphrase = nil + assert @pirate.invalid? + assert_equal ["can't be blank", "is invalid"], @pirate.errors[:"ship.name"] + end + def test_should_still_allow_to_bypass_validations_on_the_associated_model @pirate.catchphrase = '' @pirate.ship.name = '' @@ -833,6 +838,18 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase end end + def test_should_not_save_and_return_false_if_a_callback_cancelled_saving + pirate = Pirate.new(:catchphrase => 'Arr') + ship = pirate.build_ship(:name => 'The Vile Insanity') + ship.cancel_save_from_callback = true + + assert_no_difference 'Pirate.count' do + assert_no_difference 'Ship.count' do + assert !pirate.save + end + end + end + def test_should_rollback_any_changes_if_an_exception_occurred_while_saving before = [@pirate.catchphrase, @pirate.ship.name] @@ -916,6 +933,18 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase end end + def test_should_not_save_and_return_false_if_a_callback_cancelled_saving + ship = Ship.new(:name => 'The Vile Insanity') + pirate = ship.build_pirate(:catchphrase => 'Arr') + pirate.cancel_save_from_callback = true + + assert_no_difference 'Ship.count' do + assert_no_difference 'Pirate.count' do + assert !ship.save + end + end + end + def test_should_rollback_any_changes_if_an_exception_occurred_while_saving before = [@ship.pirate.catchphrase, @ship.name] @@ -931,7 +960,6 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase end assert_raise(RuntimeError) { assert !@ship.save } - # TODO: Why does using reload on @ship looses the associated pirate? assert_equal before, [@ship.pirate.reload.catchphrase, @ship.reload.name] end @@ -974,9 +1002,9 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_default_invalid_error_from_i18n - I18n.backend.store_translations(:en, :activerecord => { :errors => { :models => + I18n.backend.store_translations(:en, :errors => { :models => { @association_name.to_s.singularize.to_sym => { :blank => "cannot be blank" } } - }}) + }) @pirate.send(@association_name).build(:name => '') @@ -985,9 +1013,7 @@ module AutosaveAssociationOnACollectionAssociationTests assert_equal ["#{@association_name.to_s.titleize} name cannot be blank"], @pirate.errors.full_messages assert @pirate.errors[@association_name].empty? ensure - I18n.backend.store_translations(:en, :activerecord => { :errors => { :models => - { @association_name.to_s.singularize.to_sym => nil } - }}) + I18n.backend = I18n::Backend::Simple.new end def test_should_merge_errors_on_the_associated_models_onto_the_parent_even_if_it_is_not_valid @@ -1034,6 +1060,26 @@ module AutosaveAssociationOnACollectionAssociationTests end end + def test_should_not_save_and_return_false_if_a_callback_cancelled_saving_in_either_create_or_update + @pirate.catchphrase = 'Changed' + @child_1.name = 'Changed' + @child_1.cancel_save_from_callback = true + + assert !@pirate.save + assert_equal "Don' botharrr talkin' like one, savvy?", @pirate.reload.catchphrase + assert_equal "Posideons Killer", @child_1.reload.name + + new_pirate = Pirate.new(:catchphrase => 'Arr') + new_child = new_pirate.send(@association_name).build(:name => 'Grace OMalley') + new_child.cancel_save_from_callback = true + + assert_no_difference 'Pirate.count' do + assert_no_difference "#{new_child.class.name}.count" do + assert !new_pirate.save + end + end + end + def test_should_rollback_any_changes_if_an_exception_occurred_while_saving before = [@pirate.catchphrase, *@pirate.send(@association_name).map(&:name)] new_names = ['Grace OMalley', 'Privateers Greed'] @@ -1217,3 +1263,10 @@ class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCas assert !@pirate.respond_to?(:validate_associated_records_for_non_validated_parrots) end end + +class TestAutosaveAssociationWithTouch < ActiveRecord::TestCase + def test_autosave_with_touch_should_not_raise_system_stack_error + invoice = Invoice.create + assert_nothing_raised { invoice.line_items.create(:amount => 10) } + end +end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 730d9d8df7..aea6aed8d9 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -992,7 +992,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_mass_assignment_protection_against_class_attribute_writers - [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :colorize_logging, + [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :default_timezone, :schema_format, :lock_optimistically, :record_timestamps].each do |method| assert Task.respond_to?(method) assert Task.respond_to?("#{method}=") @@ -2138,8 +2138,11 @@ class BasicsTest < ActiveRecord::TestCase end def test_type_name_with_module_should_handle_beginning + ActiveRecord::Base.store_full_sti_class = false assert_equal 'ActiveRecord::Person', ActiveRecord::Base.send(:type_name_with_module, 'Person') assert_equal '::Person', ActiveRecord::Base.send(:type_name_with_module, '::Person') + ensure + ActiveRecord::Base.store_full_sti_class = true end def test_to_param_should_return_string diff --git a/activerecord/test/cases/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb index 5a084a611e..ff2322ac15 100644 --- a/activerecord/test/cases/callbacks_test.rb +++ b/activerecord/test/cases/callbacks_test.rb @@ -113,6 +113,26 @@ class ImmutableMethodDeveloper < ActiveRecord::Base end end +class OnCallbacksDeveloper < ActiveRecord::Base + set_table_name 'developers' + + before_validation { history << :before_validation } + before_validation(:on => :create){ history << :before_validation_on_create } + before_validation(:on => :update){ history << :before_validation_on_update } + + validate do + history << :validate + end + + after_validation { history << :after_validation } + after_validation(:on => :create){ history << :after_validation_on_create } + after_validation(:on => :update){ history << :after_validation_on_update } + + def history + @history ||= [] + end +end + class CallbackCancellationDeveloper < ActiveRecord::Base set_table_name 'developers' @@ -250,7 +270,18 @@ class CallbacksTest < ActiveRecord::TestCase ], david.history end - def test_save + def test_validate_on_create + david = OnCallbacksDeveloper.create('name' => 'David', 'salary' => 1000000) + assert_equal [ + :before_validation, + :before_validation_on_create, + :validate, + :after_validation, + :after_validation_on_create + ], david.history + end + + def test_update david = CallbackDeveloper.find(1) david.save assert_equal [ @@ -297,6 +328,18 @@ class CallbacksTest < ActiveRecord::TestCase ], david.history end + def test_validate_on_update + david = OnCallbacksDeveloper.find(1) + david.save + assert_equal [ + :before_validation, + :before_validation_on_update, + :validate, + :after_validation, + :after_validation_on_update + ], david.history + end + def test_destroy david = CallbackDeveloper.find(1) david.destroy diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index eb3f03c91d..f965652a9a 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -519,8 +519,8 @@ class FoxyFixturesTest < ActiveRecord::TestCase end def test_identifies_consistently - assert_equal 1281023246, Fixtures.identify(:ruby) - assert_equal 2140105598, Fixtures.identify(:sapphire_2) + assert_equal 207281424, Fixtures.identify(:ruby) + assert_equal 1066363776, Fixtures.identify(:sapphire_2) end TIMESTAMP_COLUMNS = %w(created_at created_on updated_at updated_on) diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index 479970b2fa..fa76e2d57a 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -13,8 +13,6 @@ require 'test/unit' require 'stringio' require 'active_record' -require 'active_record/test_case' -require 'active_record/fixtures' require 'connection' begin diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index 73e51fbd91..0672fb938b 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -241,6 +241,7 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase end def test_instantiation_doesnt_try_to_require_corresponding_file + ActiveRecord::Base.store_full_sti_class = false foo = Firm.find(:first).clone foo.ruby_type = foo.type = 'FirmOnTheFly' foo.save! @@ -259,5 +260,7 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase # And instantiate will find the existing constant rather than trying # to require firm_on_the_fly. assert_nothing_raised { assert_kind_of Firm::FirmOnTheFly, Firm.find(foo.id) } + ensure + ActiveRecord::Base.store_full_sti_class = true end end diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb index cfc6f8772c..26aa3ed8d5 100644 --- a/activerecord/test/cases/method_scoping_test.rb +++ b/activerecord/test/cases/method_scoping_test.rb @@ -11,7 +11,7 @@ class MethodScopingTest < ActiveRecord::TestCase def test_set_conditions Developer.send(:with_scope, :find => { :conditions => 'just a test...' }) do - assert_equal 'just a test...', Developer.send(:current_scoped_methods)[:find][:conditions] + assert_equal '(just a test...)', Developer.scoped.send(:where_clause) end end @@ -207,7 +207,7 @@ class MethodScopingTest < ActiveRecord::TestCase new_comment = nil VerySpecialComment.send(:with_scope, :create => { :post_id => 1 }) do - assert_equal({ :post_id => 1 }, VerySpecialComment.send(:current_scoped_methods)[:create]) + assert_equal({:post_id => 1}, VerySpecialComment.scoped.send(:scope_for_create)) new_comment = VerySpecialComment.create :body => "Wonderful world" end @@ -256,8 +256,9 @@ class NestedScopingTest < ActiveRecord::TestCase def test_merge_options Developer.send(:with_scope, :find => { :conditions => 'salary = 80000' }) do Developer.send(:with_scope, :find => { :limit => 10 }) do - merged_option = Developer.instance_eval('current_scoped_methods')[:find] - assert_equal({ :conditions => 'salary = 80000', :limit => 10 }, merged_option) + devs = Developer.scoped + assert_equal '(salary = 80000)', devs.send(:where_clause) + assert_equal 10, devs.taken end end end @@ -265,26 +266,26 @@ class NestedScopingTest < ActiveRecord::TestCase def test_merge_inner_scope_has_priority Developer.send(:with_scope, :find => { :limit => 5 }) do Developer.send(:with_scope, :find => { :limit => 10 }) do - merged_option = Developer.instance_eval('current_scoped_methods')[:find] - assert_equal({ :limit => 10 }, merged_option) + assert_equal 10, Developer.scoped.taken end end end def test_replace_options - Developer.send(:with_scope, :find => { :conditions => "name = 'David'" }) do - Developer.send(:with_exclusive_scope, :find => { :conditions => "name = 'Jamis'" }) do - assert_equal({:find => { :conditions => "name = 'Jamis'" }}, Developer.instance_eval('current_scoped_methods')) - assert_equal({:find => { :conditions => "name = 'Jamis'" }}, Developer.send(:scoped_methods)[-1]) + Developer.send(:with_scope, :find => { :conditions => {:name => 'David'} }) do + Developer.send(:with_exclusive_scope, :find => { :conditions => {:name => 'Jamis'} }) do + assert_equal 'Jamis', Developer.scoped.send(:scope_for_create)[:name] end + + assert_equal 'David', Developer.scoped.send(:scope_for_create)[:name] end end def test_append_conditions Developer.send(:with_scope, :find => { :conditions => "name = 'David'" }) do Developer.send(:with_scope, :find => { :conditions => 'salary = 80000' }) do - appended_condition = Developer.instance_eval('current_scoped_methods')[:find][:conditions] - assert_equal("(name = 'David') AND (salary = 80000)", appended_condition) + devs = Developer.scoped + assert_equal "(name = 'David') AND (salary = 80000)", devs.send(:where_clause) assert_equal(1, Developer.count) end Developer.send(:with_scope, :find => { :conditions => "name = 'Maiha'" }) do @@ -296,8 +297,9 @@ class NestedScopingTest < ActiveRecord::TestCase def test_merge_and_append_options Developer.send(:with_scope, :find => { :conditions => 'salary = 80000', :limit => 10 }) do Developer.send(:with_scope, :find => { :conditions => "name = 'David'" }) do - merged_option = Developer.instance_eval('current_scoped_methods')[:find] - assert_equal({ :conditions => "(salary = 80000) AND (name = 'David')", :limit => 10 }, merged_option) + devs = Developer.scoped + assert_equal "(salary = 80000) AND (name = 'David')", devs.send(:where_clause) + assert_equal 10, devs.taken end end end @@ -325,15 +327,15 @@ class NestedScopingTest < ActiveRecord::TestCase # :include's remain unique and don't "double up" when merging Developer.send(:with_scope, :find => { :include => :projects, :conditions => "projects.id = 2" }) do Developer.send(:with_scope, :find => { :include => :projects }) do - assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length - assert_equal('David', Developer.find(:first).name) + assert_equal 1, Developer.scoped.includes_values.uniq.length + assert_equal 'David', Developer.find(:first).name end end # the nested scope doesn't remove the first :include Developer.send(:with_scope, :find => { :include => :projects, :conditions => "projects.id = 2" }) do Developer.send(:with_scope, :find => { :include => [] }) do - assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length + assert_equal 1, Developer.scoped.includes_values.uniq.length assert_equal('David', Developer.find(:first).name) end end @@ -341,7 +343,7 @@ class NestedScopingTest < ActiveRecord::TestCase # mixing array and symbol include's will merge correctly Developer.send(:with_scope, :find => { :include => [:projects], :conditions => "projects.id = 2" }) do Developer.send(:with_scope, :find => { :include => :projects }) do - assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length + assert_equal 1, Developer.scoped.includes_values.uniq.length assert_equal('David', Developer.find(:first).name) end end @@ -350,7 +352,7 @@ class NestedScopingTest < ActiveRecord::TestCase def test_nested_scoped_find_replace_include Developer.send(:with_scope, :find => { :include => :projects }) do Developer.send(:with_exclusive_scope, :find => { :include => [] }) do - assert_equal 0, Developer.instance_eval('current_scoped_methods')[:find][:include].length + assert_equal 0, Developer.scoped.includes_values.length end end end @@ -416,7 +418,7 @@ class NestedScopingTest < ActiveRecord::TestCase comment = nil Comment.send(:with_scope, :create => { :post_id => 1}) do Comment.send(:with_scope, :create => { :post_id => 2}) do - assert_equal({ :post_id => 2 }, Comment.send(:current_scoped_methods)[:create]) + assert_equal({:post_id => 2}, Comment.scoped.send(:scope_for_create)) comment = Comment.create :body => "Hey guys, nested scopes are broken. Please fix!" end end @@ -425,9 +427,11 @@ class NestedScopingTest < ActiveRecord::TestCase def test_nested_exclusive_scope_for_create comment = nil + Comment.send(:with_scope, :create => { :body => "Hey guys, nested scopes are broken. Please fix!" }) do Comment.send(:with_exclusive_scope, :create => { :post_id => 1 }) do - assert_equal({ :post_id => 1 }, Comment.send(:current_scoped_methods)[:create]) + assert_equal({:post_id => 1}, Comment.scoped.send(:scope_for_create)) + assert Comment.new.body.blank? comment = Comment.create :body => "Hey guys" end end @@ -603,44 +607,39 @@ class DefaultScopingTest < ActiveRecord::TestCase end def test_default_scoping_with_threads - scope = [{ :create => {}, :find => { :order => 'salary DESC' } }] - 2.times do - Thread.new { assert_equal scope, DeveloperOrderedBySalary.send(:scoped_methods) }.join + Thread.new { assert_equal 'salary DESC', DeveloperOrderedBySalary.scoped.send(:order_clause) }.join end end def test_default_scoping_with_inheritance - scope = [{ :create => {}, :find => { :order => 'salary DESC' } }] - # Inherit a class having a default scope and define a new default scope klass = Class.new(DeveloperOrderedBySalary) klass.send :default_scope, {} # Scopes added on children should append to parent scope - expected_klass_scope = [{ :create => {}, :find => { :order => 'salary DESC' }}, { :create => {}, :find => {} }] - assert_equal expected_klass_scope, klass.send(:scoped_methods) + assert klass.scoped.send(:order_clause).blank? # Parent should still have the original scope - assert_equal scope, DeveloperOrderedBySalary.send(:scoped_methods) + assert_equal 'salary DESC', DeveloperOrderedBySalary.scoped.send(:order_clause) end def test_method_scope - expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary } + expected = Developer.find(:all, :order => 'name DESC, salary DESC').collect { |dev| dev.salary } received = DeveloperOrderedBySalary.all_ordered_by_name.collect { |dev| dev.salary } assert_equal expected, received end def test_nested_scope - expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary } + expected = Developer.find(:all, :order => 'name DESC, salary DESC').collect { |dev| dev.salary } received = DeveloperOrderedBySalary.send(:with_scope, :find => { :order => 'name DESC'}) do DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary } end assert_equal expected, received end - def test_named_scope_overwrites_default - expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.name } + def test_named_scope_order_appended_to_default_scope_order + expected = Developer.find(:all, :order => 'name DESC, salary DESC').collect { |dev| dev.name } received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.name } assert_equal expected, received end diff --git a/activerecord/test/cases/modules_test.rb b/activerecord/test/cases/modules_test.rb index 4f559bcaa5..d781a229f4 100644 --- a/activerecord/test/cases/modules_test.rb +++ b/activerecord/test/cases/modules_test.rb @@ -12,6 +12,8 @@ class ModulesTest < ActiveRecord::TestCase [:Firm, :Client].each do |const| @undefined_consts.merge! const => Object.send(:remove_const, const) if Object.const_defined?(const) end + + ActiveRecord::Base.store_full_sti_class = false end def teardown @@ -19,6 +21,8 @@ class ModulesTest < ActiveRecord::TestCase @undefined_consts.each do |constant, value| Object.send :const_set, constant, value unless value.nil? end + + ActiveRecord::Base.store_full_sti_class = true end def test_module_spanning_associations diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb index 6155bfd50a..bd51388e05 100644 --- a/activerecord/test/cases/multiple_db_test.rb +++ b/activerecord/test/cases/multiple_db_test.rb @@ -85,7 +85,7 @@ class MultipleDbTest < ActiveRecord::TestCase end def test_arel_table_engines - assert_not_equal Entrant.active_relation_engine, Course.active_relation_engine - assert_equal Entrant.active_relation_engine, Bird.active_relation_engine + assert_not_equal Entrant.arel_engine, Course.arel_engine + assert_equal Entrant.arel_engine, Bird.arel_engine end end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 8891282915..7ca9c416cb 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -34,7 +34,10 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase end def test_should_add_a_proc_to_nested_attributes_options - [:parrots, :birds, :birds_with_reject_all_blank].each do |name| + assert_equal ActiveRecord::NestedAttributes::ClassMethods::REJECT_ALL_BLANK_PROC, + Pirate.nested_attributes_options[:birds_with_reject_all_blank][:reject_if] + + [:parrots, :birds].each do |name| assert_instance_of Proc, Pirate.nested_attributes_options[name][:reject_if] end end @@ -79,12 +82,6 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase assert ship._destroy end - def test_underscore_delete_is_deprecated - ActiveSupport::Deprecation.expects(:warn) - ship = Ship.create!(:name => 'Nights Dirty Lightning') - ship._delete - end - def test_reject_if_method_without_arguments Pirate.accepts_nested_attributes_for :ship, :reject_if => :new_record? @@ -176,6 +173,12 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name end + def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record + assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Ship with ID=1234567890 for Pirate with ID=#{@pirate.id}" do + @pirate.ship_attributes = { :id => 1234567890 } + end + end + def test_should_take_a_hash_with_string_keys_and_update_the_associated_model @pirate.reload.ship_attributes = { 'id' => @ship.id, 'name' => 'Davy Jones Gold Dagger' } @@ -269,6 +272,8 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase + include AssertRaiseWithMessage + def setup @ship = Ship.new(:name => 'Nights Dirty Lightning') @pirate = @ship.build_pirate(:catchphrase => 'Aye') @@ -323,6 +328,12 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase assert_equal 'Arr', @ship.pirate.catchphrase end + def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record + assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Pirate with ID=1234567890 for Ship with ID=#{@ship.id}" do + @ship.pirate_attributes = { :id => 1234567890 } + end + end + def test_should_take_a_hash_with_string_keys_and_update_the_associated_model @ship.reload.pirate_attributes = { 'id' => @pirate.id, 'catchphrase' => 'Arr' } @@ -384,10 +395,6 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase assert Ship.reflect_on_association(:pirate).options[:autosave] end - def test_should_accept_update_only_option - @ship.update_attribute(:update_only_pirate_attributes, { :id => @pirate.ship.id, :catchphrase => 'Arr' }) - end - def test_should_create_new_model_when_nothing_is_there_and_update_only_is_true @pirate.delete assert_difference('Pirate.count', 1) do @@ -460,6 +467,12 @@ module NestedAttributesOnACollectionAssociationTests assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.name, @child_2.name] end + def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record + assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find #{@child_1.class.name} with ID=1234567890 for Pirate with ID=#{@pirate.id}" do + @pirate.attributes = { association_getter => [{ :id => 1234567890 }] } + end + end + def test_should_automatically_build_new_associated_models_for_each_entry_in_a_hash_where_the_id_is_missing @pirate.send(@association_name).destroy_all @pirate.reload.attributes = { @@ -565,7 +578,7 @@ module NestedAttributesOnACollectionAssociationTests assert Pirate.reflect_on_association(@association_name).options[:autosave] end - def test_validate_presence_of_parent__works_with_inverse_of + def test_validate_presence_of_parent_works_with_inverse_of Man.accepts_nested_attributes_for(:interests) assert_equal :man, Man.reflect_on_association(:interests).options[:inverse_of] assert_equal :interests, Interest.reflect_on_association(:man).options[:inverse_of] @@ -582,7 +595,7 @@ module NestedAttributesOnACollectionAssociationTests end end - def test_validate_presence_of_parent__fails_without_inverse_of + def test_validate_presence_of_parent_fails_without_inverse_of Man.accepts_nested_attributes_for(:interests) Man.reflect_on_association(:interests).options.delete(:inverse_of) Interest.reflect_on_association(:man).options.delete(:inverse_of) diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb index 2529a33dab..94d6663778 100644 --- a/activerecord/test/cases/pooled_connections_test.rb +++ b/activerecord/test/cases/pooled_connections_test.rb @@ -61,12 +61,14 @@ class PooledConnectionsTest < ActiveRecord::TestCase checkout_checkin_connections 1, 2 assert_equal 2, @connection_count assert_equal 0, @timed_out + assert_equal 1, ActiveRecord::Base.connection_pool.connections.size end def test_pooled_connection_checkin_two checkout_checkin_connections 2, 3 assert_equal 3, @connection_count assert_equal 0, @timed_out + assert_equal 1, ActiveRecord::Base.connection_pool.connections.size end def test_pooled_connection_checkout_existing_first @@ -135,15 +137,4 @@ class PooledConnectionsTest < ActiveRecord::TestCase def add_record(name) ActiveRecord::Base.connection_pool.with_connection { Project.create! :name => name } end -end unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name - -class AllowConcurrencyDeprecatedTest < ActiveRecord::TestCase - def test_allow_concurrency_is_deprecated - assert_deprecated('ActiveRecord::Base.allow_concurrency') do - ActiveRecord::Base.allow_concurrency - end - assert_deprecated('ActiveRecord::Base.allow_concurrency=') do - ActiveRecord::Base.allow_concurrency = true - end - end -end +end unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
\ No newline at end of file diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index acd214eb5a..2c9158aa7b 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -4,10 +4,13 @@ require 'models/customer' require 'models/company' require 'models/company_in_module' require 'models/subscriber' +require 'models/ship' require 'models/pirate' require 'models/price_estimate' class ReflectionTest < ActiveRecord::TestCase + include ActiveRecord::Reflection + fixtures :topics, :customers, :companies, :subscribers, :price_estimates def setup @@ -68,22 +71,22 @@ class ReflectionTest < ActiveRecord::TestCase end def test_reflection_klass_for_nested_class_name - reflection = ActiveRecord::Reflection::MacroReflection.new(nil, nil, { :class_name => 'MyApplication::Business::Company' }, nil) + reflection = MacroReflection.new(nil, nil, { :class_name => 'MyApplication::Business::Company' }, nil) assert_nothing_raised do assert_equal MyApplication::Business::Company, reflection.klass end end def test_aggregation_reflection - reflection_for_address = ActiveRecord::Reflection::AggregateReflection.new( + reflection_for_address = AggregateReflection.new( :composed_of, :address, { :mapping => [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer ) - reflection_for_balance = ActiveRecord::Reflection::AggregateReflection.new( + reflection_for_balance = AggregateReflection.new( :composed_of, :balance, { :class_name => "Money", :mapping => %w(balance amount) }, Customer ) - reflection_for_gps_location = ActiveRecord::Reflection::AggregateReflection.new( + reflection_for_gps_location = AggregateReflection.new( :composed_of, :gps_location, { }, Customer ) @@ -108,7 +111,7 @@ class ReflectionTest < ActiveRecord::TestCase end def test_has_many_reflection - reflection_for_clients = ActiveRecord::Reflection::AssociationReflection.new(:has_many, :clients, { :order => "id", :dependent => :destroy }, Firm) + reflection_for_clients = AssociationReflection.new(:has_many, :clients, { :order => "id", :dependent => :destroy }, Firm) assert_equal reflection_for_clients, Firm.reflect_on_association(:clients) @@ -120,7 +123,7 @@ class ReflectionTest < ActiveRecord::TestCase end def test_has_one_reflection - reflection_for_account = ActiveRecord::Reflection::AssociationReflection.new(:has_one, :account, { :foreign_key => "firm_id", :dependent => :destroy }, Firm) + reflection_for_account = AssociationReflection.new(:has_one, :account, { :foreign_key => "firm_id", :dependent => :destroy }, Firm) assert_equal reflection_for_account, Firm.reflect_on_association(:account) assert_equal Account, Firm.reflect_on_association(:account).klass @@ -137,6 +140,8 @@ class ReflectionTest < ActiveRecord::TestCase end def test_association_reflection_in_modules + ActiveRecord::Base.store_full_sti_class = false + assert_reflection MyApplication::Business::Firm, :clients_of_firm, :klass => MyApplication::Business::Client, @@ -172,6 +177,8 @@ class ReflectionTest < ActiveRecord::TestCase :klass => MyApplication::Billing::Nested::Firm, :class_name => 'Nested::Firm', :table_name => 'companies' + ensure + ActiveRecord::Base.store_full_sti_class = true end def test_reflection_of_all_associations @@ -187,7 +194,44 @@ class ReflectionTest < ActiveRecord::TestCase end def test_has_many_through_reflection - assert_kind_of ActiveRecord::Reflection::ThroughReflection, Subscriber.reflect_on_association(:books) + assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books) + end + + def test_collection_association + assert Pirate.reflect_on_association(:birds).collection? + assert Pirate.reflect_on_association(:parrots).collection? + + assert !Pirate.reflect_on_association(:ship).collection? + assert !Ship.reflect_on_association(:pirate).collection? + end + + def test_default_association_validation + assert AssociationReflection.new(:has_many, :clients, {}, Firm).validate? + + assert !AssociationReflection.new(:has_one, :client, {}, Firm).validate? + assert !AssociationReflection.new(:belongs_to, :client, {}, Firm).validate? + assert !AssociationReflection.new(:has_and_belongs_to_many, :clients, {}, Firm).validate? + end + + def test_always_validate_association_if_explicit + assert AssociationReflection.new(:has_one, :client, { :validate => true }, Firm).validate? + assert AssociationReflection.new(:belongs_to, :client, { :validate => true }, Firm).validate? + assert AssociationReflection.new(:has_many, :clients, { :validate => true }, Firm).validate? + assert AssociationReflection.new(:has_and_belongs_to_many, :clients, { :validate => true }, Firm).validate? + end + + def test_validate_association_if_autosave + assert AssociationReflection.new(:has_one, :client, { :autosave => true }, Firm).validate? + assert AssociationReflection.new(:belongs_to, :client, { :autosave => true }, Firm).validate? + assert AssociationReflection.new(:has_many, :clients, { :autosave => true }, Firm).validate? + assert AssociationReflection.new(:has_and_belongs_to_many, :clients, { :autosave => true }, Firm).validate? + end + + def test_never_validate_association_if_explicit + assert !AssociationReflection.new(:has_one, :client, { :autosave => true, :validate => false }, Firm).validate? + assert !AssociationReflection.new(:belongs_to, :client, { :autosave => true, :validate => false }, Firm).validate? + assert !AssociationReflection.new(:has_many, :clients, { :autosave => true, :validate => false }, Firm).validate? + assert !AssociationReflection.new(:has_and_belongs_to_many, :clients, { :autosave => true, :validate => false }, Firm).validate? end private diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index f895f8b8d2..195889f1df 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -545,6 +545,14 @@ class RelationTest < ActiveRecord::TestCase assert_equal 'hen', hen.name end + def test_explicit_create_scope + hens = Bird.where(:name => 'hen') + assert_equal 'hen', hens.new.name + + hens = hens.create_with(:name => 'cock') + assert_equal 'cock', hens.new.name + end + def test_except relation = Post.where(:author_id => 1).order('id ASC').limit(1) assert_equal [posts(:welcome)], relation.all diff --git a/activerecord/test/cases/subscriber_test.rb b/activerecord/test/cases/subscriber_test.rb new file mode 100644 index 0000000000..ce91d9385d --- /dev/null +++ b/activerecord/test/cases/subscriber_test.rb @@ -0,0 +1,51 @@ +require "cases/helper" +require "models/developer" +require "rails/subscriber/test_helper" +require "active_record/railties/subscriber" + +module SubscriberTest + Rails::Subscriber.add(:active_record, ActiveRecord::Railties::Subscriber.new) + + def setup + @old_logger = ActiveRecord::Base.logger + super + end + + def teardown + super + ActiveRecord::Base.logger = @old_logger + end + + def set_logger(logger) + ActiveRecord::Base.logger = logger + end + + def test_basic_query_logging + Developer.all + wait + assert_equal 1, @logger.logged(:debug).size + assert_match /Developer Load/, @logger.logged(:debug).last + assert_match /SELECT .*?FROM .?developers.?/, @logger.logged(:debug).last + end + + def test_cached_queries + ActiveRecord::Base.cache do + Developer.all + Developer.all + end + wait + assert_equal 2, @logger.logged(:debug).size + assert_match /CACHE/, @logger.logged(:debug).last + assert_match /SELECT .*?FROM .?developers.?/, @logger.logged(:debug).last + end + + class SyncSubscriberTest < ActiveSupport::TestCase + include Rails::Subscriber::SyncTestHelper + include SubscriberTest + end + + class AsyncSubscriberTest < ActiveSupport::TestCase + include Rails::Subscriber::AsyncTestHelper + include SubscriberTest + end +end
\ No newline at end of file diff --git a/activerecord/test/cases/validations/association_validation_test.rb b/activerecord/test/cases/validations/association_validation_test.rb index 5ed997356b..1246dd4276 100644 --- a/activerecord/test/cases/validations/association_validation_test.rb +++ b/activerecord/test/cases/validations/association_validation_test.rb @@ -10,33 +10,29 @@ require 'models/interest' class AssociationValidationTest < ActiveRecord::TestCase fixtures :topics, :owners - repair_validations(Topic, Reply) + repair_validations(Topic, Reply, Owner) def test_validates_size_of_association - repair_validations(Owner) do - assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } - o = Owner.new('name' => 'nopets') - assert !o.save - assert o.errors[:pets].any? - pet = o.pets.build('name' => 'apet') - assert o.valid? - end + assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } + o = Owner.new('name' => 'nopets') + assert !o.save + assert o.errors[:pets].any? + pet = o.pets.build('name' => 'apet') + assert o.valid? end def test_validates_size_of_association_using_within - repair_validations(Owner) do - assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 } - o = Owner.new('name' => 'nopets') - assert !o.save - assert o.errors[:pets].any? + assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 } + o = Owner.new('name' => 'nopets') + assert !o.save + assert o.errors[:pets].any? - pet = o.pets.build('name' => 'apet') - assert o.valid? + pet = o.pets.build('name' => 'apet') + assert o.valid? - 2.times { o.pets.build('name' => 'apet') } - assert !o.save - assert o.errors[:pets].any? - end + 2.times { o.pets.build('name' => 'apet') } + assert !o.save + assert o.errors[:pets].any? end def test_validates_associated_many @@ -55,51 +51,43 @@ class AssociationValidationTest < ActiveRecord::TestCase end def test_validates_associated_one - repair_validations(Reply) do - Reply.validates_associated( :topic ) - Topic.validates_presence_of( :content ) - r = Reply.new("title" => "A reply", "content" => "with content!") - r.topic = Topic.create("title" => "uhohuhoh") - assert !r.valid? - assert r.errors[:topic].any? - r.topic.content = "non-empty" - assert r.valid? - end + Reply.validates :topic, :associated => true + Topic.validates_presence_of( :content ) + r = Reply.new("title" => "A reply", "content" => "with content!") + r.topic = Topic.create("title" => "uhohuhoh") + assert !r.valid? + assert r.errors[:topic].any? + r.topic.content = "non-empty" + assert r.valid? end def test_validates_associated_with_custom_message_using_quotes - repair_validations(Reply) do - Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes" - Topic.validates_presence_of :content - r = Reply.create("title" => "A reply", "content" => "with content!") - r.topic = Topic.create("title" => "uhohuhoh") - assert !r.valid? - assert_equal ["This string contains 'single' and \"double\" quotes"], r.errors[:topic] - end + Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes" + Topic.validates_presence_of :content + r = Reply.create("title" => "A reply", "content" => "with content!") + r.topic = Topic.create("title" => "uhohuhoh") + assert !r.valid? + assert_equal ["This string contains 'single' and \"double\" quotes"], r.errors[:topic] end def test_validates_associated_missing - repair_validations(Reply) do - Reply.validates_presence_of(:topic) - r = Reply.create("title" => "A reply", "content" => "with content!") - assert !r.valid? - assert r.errors[:topic].any? + Reply.validates_presence_of(:topic) + r = Reply.create("title" => "A reply", "content" => "with content!") + assert !r.valid? + assert r.errors[:topic].any? - r.topic = Topic.find :first - assert r.valid? - end + r.topic = Topic.find :first + assert r.valid? end def test_validates_size_of_association_utf8 - repair_validations(Owner) do - with_kcode('UTF8') do - assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } - o = Owner.new('name' => 'あいうえおかきくけこ') - assert !o.save - assert o.errors[:pets].any? - o.pets.build('name' => 'あいうえおかきくけこ') - assert o.valid? - end + with_kcode('UTF8') do + assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } + o = Owner.new('name' => 'あいうえおかきくけこ') + assert !o.save + assert o.errors[:pets].any? + o.pets.build('name' => 'あいうえおかきくけこ') + assert o.valid? end end diff --git a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb index 3f96d7973b..15730c2a87 100644 --- a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb @@ -6,15 +6,7 @@ class I18nGenerateMessageValidationTest < ActiveRecord::TestCase def setup Topic.reset_callbacks(:validate) @topic = Topic.new - I18n.backend.store_translations :'en', { - :activerecord => { - :errors => { - :messages => { - :taken => "has already been taken", - } - } - } - } + I18n.backend = I18n::Backend::Simple.new end # validates_associated: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb index f017f24048..5dfbb1516f 100644 --- a/activerecord/test/cases/validations/i18n_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_validation_test.rb @@ -4,13 +4,14 @@ require 'models/reply' class I18nValidationTest < ActiveRecord::TestCase repair_validations(Topic, Reply) + def setup Reply.validates_presence_of(:title) @topic = Topic.new - @old_load_path, @old_backend = I18n.load_path, I18n.backend + @old_load_path, @old_backend = I18n.load_path.dup, I18n.backend I18n.load_path.clear I18n.backend = I18n::Backend::Simple.new - I18n.backend.store_translations('en', :activerecord => {:errors => {:messages => {:custom => nil}}}) + I18n.backend.store_translations('en', :errors => {:messages => {:custom => nil}}) end def teardown @@ -30,75 +31,6 @@ class I18nValidationTest < ActiveRecord::TestCase end end - # ActiveRecord::Errors - def test_errors_generate_message_translates_custom_model_attribute_key - I18n.expects(:translate).with( - :topic, - { :count => 1, - :default => ['Topic'], - :scope => [:activerecord, :models] - } - ).returns('Topic') - - I18n.expects(:translate).with( - :"topic.title", - { :count => 1, - :default => ['Title'], - :scope => [:activerecord, :attributes] - } - ).returns('Title') - - I18n.expects(:translate).with( - :"models.topic.attributes.title.invalid", - :value => nil, - :scope => [:activerecord, :errors], - :default => [ - :"models.topic.invalid", - 'default from class def error 1', - :"messages.invalid"], - :attribute => "Title", - :model => "Topic" - ).returns('default from class def error 1') - - @topic.errors.generate_message :title, :invalid, :default => 'default from class def error 1' - end - - def test_errors_generate_message_translates_custom_model_attribute_keys_with_sti - - I18n.expects(:translate).with( - :reply, - { :count => 1, - :default => [:topic, 'Reply'], - :scope => [:activerecord, :models] - } - ).returns('Reply') - - I18n.expects(:translate).with( - :"reply.title", - { :count => 1, - :default => [:'topic.title', 'Title'], - :scope => [:activerecord, :attributes] - } - ).returns('Title') - - I18n.expects(:translate).with( - :"models.reply.attributes.title.invalid", - :value => nil, - :scope => [:activerecord, :errors], - :default => [ - :"models.reply.invalid", - :"models.topic.attributes.title.invalid", - :"models.topic.invalid", - 'default from class def', - :"messages.invalid"], - :model => 'Reply', - :attribute => 'Title' - ).returns("default from class def") - - Reply.new.errors.generate_message :title, :invalid, :default => 'default from class def' - - end - # validates_uniqueness_of w/ mocha def test_validates_uniqueness_of_generates_message @@ -115,6 +47,25 @@ class I18nValidationTest < ActiveRecord::TestCase @topic.valid? end + # validates_uniqueness_of w/o mocha + + def test_validates_associated_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :errors => {:models => {:topic => {:attributes => {:title => {:taken => 'custom message'}}}}} + I18n.backend.store_translations 'en', :errors => {:messages => {:taken => 'global message'}} + + Topic.validates_uniqueness_of :title + unique_topic.valid? + assert_equal ['custom message'], unique_topic.errors[:replies] + end + + def test_validates_associated_finds_global_default_translation + I18n.backend.store_translations 'en', :errors => {:messages => {:taken => 'global message'}} + + Topic.validates_uniqueness_of :title + unique_topic.valid? + assert_equal ['global message'], unique_topic.errors[:replies] + end + # validates_associated w/ mocha def test_validates_associated_generates_message @@ -132,8 +83,8 @@ class I18nValidationTest < ActiveRecord::TestCase # validates_associated w/o mocha def test_validates_associated_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:replies => {:invalid => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + I18n.backend.store_translations 'en', :errors => {:models => {:topic => {:attributes => {:replies => {:invalid => 'custom message'}}}}} + I18n.backend.store_translations 'en', :errors => {:messages => {:invalid => 'global message'}} Topic.validates_associated :replies replied_topic.valid? @@ -141,7 +92,7 @@ class I18nValidationTest < ActiveRecord::TestCase end def test_validates_associated_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + I18n.backend.store_translations 'en', :errors => {:messages => {:invalid => 'global message'}} Topic.validates_associated :replies replied_topic.valid? diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb index 8f84841fe6..9a863c25a8 100644 --- a/activerecord/test/cases/validations/uniqueness_validation_test.rb +++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb @@ -38,7 +38,7 @@ end class UniquenessValidationTest < ActiveRecord::TestCase fixtures :topics, 'warehouse-things', :developers - repair_validations(Topic) + repair_validations(Topic, Reply) def test_validate_uniqueness Topic.validates_uniqueness_of(:title) @@ -58,6 +58,15 @@ class UniquenessValidationTest < ActiveRecord::TestCase assert t2.save, "Should now save t2 as unique" end + def test_validates_uniqueness_with_validates + Topic.validates :title, :uniqueness => true + t = Topic.create!('title' => 'abc') + + t2 = Topic.new('title' => 'abc') + assert !t2.valid? + assert t2.errors[:title] + end + def test_validates_uniqueness_with_newline_chars Topic.validates_uniqueness_of(:title, :case_sensitive => false) @@ -66,24 +75,22 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_scope - repair_validations(Reply) do - Reply.validates_uniqueness_of(:content, :scope => "parent_id") + Reply.validates_uniqueness_of(:content, :scope => "parent_id") - t = Topic.create("title" => "I'm unique!") + t = Topic.create("title" => "I'm unique!") - r1 = t.replies.create "title" => "r1", "content" => "hello world" - assert r1.valid?, "Saving r1" + r1 = t.replies.create "title" => "r1", "content" => "hello world" + assert r1.valid?, "Saving r1" - r2 = t.replies.create "title" => "r2", "content" => "hello world" - assert !r2.valid?, "Saving r2 first time" + r2 = t.replies.create "title" => "r2", "content" => "hello world" + assert !r2.valid?, "Saving r2 first time" - r2.content = "something else" - assert r2.save, "Saving r2 second time" + r2.content = "something else" + assert r2.save, "Saving r2 second time" - t2 = Topic.create("title" => "I'm unique too!") - r3 = t2.replies.create "title" => "r3", "content" => "hello world" - assert r3.valid?, "Saving r3" - end + t2 = Topic.create("title" => "I'm unique too!") + r3 = t2.replies.create "title" => "r3", "content" => "hello world" + assert r3.valid?, "Saving r3" end def test_validate_uniqueness_scoped_to_defining_class @@ -102,29 +109,27 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_scope_array - repair_validations(Reply) do - Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id]) + Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id]) - t = Topic.create("title" => "The earth is actually flat!") + t = Topic.create("title" => "The earth is actually flat!") - r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply" - assert r1.valid?, "Saving r1" + r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply" + assert r1.valid?, "Saving r1" - r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..." - assert !r2.valid?, "Saving r2. Double reply by same author." + r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..." + assert !r2.valid?, "Saving r2. Double reply by same author." - r2.author_email_address = "jeremy_alt_email@rubyonrails.com" - assert r2.save, "Saving r2 the second time." + r2.author_email_address = "jeremy_alt_email@rubyonrails.com" + assert r2.save, "Saving r2 the second time." - r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic" - assert !r3.valid?, "Saving r3" + r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic" + assert !r3.valid?, "Saving r3" - r3.author_name = "jj" - assert r3.save, "Saving r3 the second time." + r3.author_name = "jj" + assert r3.save, "Saving r3 the second time." - r3.author_name = "jeremy" - assert !r3.save, "Saving r3 the third time." - end + r3.author_name = "jeremy" + assert !r3.save, "Saving r3 the third time." end def test_validate_case_insensitive_uniqueness |