diff options
Diffstat (limited to 'activerecord/test')
31 files changed, 841 insertions, 203 deletions
diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb index 1f8a1090eb..8c9ae8a031 100644 --- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb +++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb @@ -68,6 +68,18 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end end + def test_eager_association_loading_with_has_many_sti_and_subclasses + silly = SillyReply.new(:title => "gaga", :content => "boo-boo", :parent_id => 1) + silly.parent_id = 1 + assert silly.save + + topics = Topic.find(:all, :include => :replies, :order => 'topics.id, replies_topics.id') + assert_no_queries do + assert_equal 2, topics[0].replies.size + assert_equal 0, topics[1].replies.size + end + end + def test_eager_association_loading_with_belongs_to_sti replies = Reply.find(:all, :include => :topic, :order => 'topics.id') assert replies.include?(topics(:second)) diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb index 80cfc84b32..12dec5ccd1 100644 --- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb +++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb @@ -1,5 +1,20 @@ require 'cases/helper' +module Remembered + def self.included(base) + base.extend ClassMethods + base.class_eval do + after_create :remember + protected + def remember; self.class.remembered << self; end + end + end + + module ClassMethods + def remembered; @@remembered ||= []; end + def rand; @@remembered.rand; end + end +end class ShapeExpression < ActiveRecord::Base belongs_to :shape, :polymorphic => true @@ -8,26 +23,33 @@ end class Circle < ActiveRecord::Base has_many :shape_expressions, :as => :shape + include Remembered end class Square < ActiveRecord::Base has_many :shape_expressions, :as => :shape + include Remembered end class Triangle < ActiveRecord::Base has_many :shape_expressions, :as => :shape + include Remembered end class PaintColor < ActiveRecord::Base has_many :shape_expressions, :as => :paint belongs_to :non_poly, :foreign_key => "non_poly_one_id", :class_name => "NonPolyOne" + include Remembered end class PaintTexture < ActiveRecord::Base has_many :shape_expressions, :as => :paint belongs_to :non_poly, :foreign_key => "non_poly_two_id", :class_name => "NonPolyTwo" + include Remembered end class NonPolyOne < ActiveRecord::Base has_many :paint_colors + include Remembered end class NonPolyTwo < ActiveRecord::Base has_many :paint_textures + include Remembered end @@ -49,23 +71,19 @@ class EagerLoadPolyAssocsTest < ActiveRecord::TestCase end - # meant to be supplied as an ID, never returns 0 - def rand_simple - val = (NUM_SIMPLE_OBJS * rand).round - val == 0 ? 1 : val - end - def generate_test_object_graphs 1.upto(NUM_SIMPLE_OBJS) do [Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!) end - 1.upto(NUM_SIMPLE_OBJS) do |i| - PaintColor.create!(:non_poly_one_id => rand_simple) - PaintTexture.create!(:non_poly_two_id => rand_simple) + 1.upto(NUM_SIMPLE_OBJS) do + PaintColor.create!(:non_poly_one_id => NonPolyOne.rand.id) + PaintTexture.create!(:non_poly_two_id => NonPolyTwo.rand.id) end - 1.upto(NUM_SHAPE_EXPRESSIONS) do |i| - ShapeExpression.create!(:shape_type => [Circle, Square, Triangle].rand.to_s, :shape_id => rand_simple, - :paint_type => [PaintColor, PaintTexture].rand.to_s, :paint_id => rand_simple) + 1.upto(NUM_SHAPE_EXPRESSIONS) do + shape_type = [Circle, Square, Triangle].rand + paint_type = [PaintColor, PaintTexture].rand + ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.rand.id, + :paint_type => paint_type.to_s, :paint_id => paint_type.rand.id) end end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 58506574f8..e78624a98d 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -38,6 +38,12 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal Post.find(1).last_comment, post.last_comment end + def test_loading_with_one_association_with_non_preload + posts = Post.find(:all, :include => :last_comment, :order => 'comments.id DESC') + post = posts.find { |p| p.id == 1 } + assert_equal Post.find(1).last_comment, post.last_comment + end + def test_loading_conditions_with_or posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'") assert_nil posts.detect { |p| p.author_id != authors(:david).id }, @@ -254,9 +260,9 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_has_many_through - posts_with_comments = people(:michael).posts.find(:all, :include => :comments) - posts_with_author = people(:michael).posts.find(:all, :include => :author ) - posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ]) + posts_with_comments = people(:michael).posts.find(:all, :include => :comments, :order => 'posts.id') + posts_with_author = people(:michael).posts.find(:all, :include => :author, :order => 'posts.id') + posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ], :order => 'posts.id') assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size } assert_equal authors(:david), assert_no_queries { posts_with_author.first.author } assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author } @@ -559,6 +565,13 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_nothing_raised { Post.find(:all, :include => 'comments') } end + def test_eager_with_floating_point_numbers + assert_queries(2) do + # Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query + Comment.find :all, :conditions => "123.456 = 123.456", :include => :post + end + end + def test_preconfigured_includes_with_belongs_to author = posts(:welcome).author_with_posts assert_no_queries {assert_equal 5, author.posts.size} diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index f71b122ff0..0572418e3b 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -450,6 +450,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find" end + def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations + # interpolate once: + assert_equal [developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql, "first interpolation" + # interpolate again, for a different project id + assert_equal [developers(:david)], projects(:action_controller).developers_with_finder_sql, "second interpolation" + end + def test_find_in_association_with_custom_finder_sql_and_string_id assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find" end @@ -640,8 +647,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase developer.save developer.reload assert_equal 2, developer.projects.length - assert_equal projects(:active_record), developer.projects[0] - assert_equal projects(:action_controller), developer.projects[1] + assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort end def test_assign_ids_ignoring_blanks @@ -650,8 +656,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase developer.save developer.reload assert_equal 2, developer.projects.length - assert_equal projects(:active_record), developer.projects[0] - assert_equal projects(:action_controller), developer.projects[1] + assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort end def test_select_limited_ids_list diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index b806e885e1..17fd88ce65 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -48,6 +48,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 2, Firm.find(:first).plain_clients.count(:name) end + def test_counting_with_association_limit + firm = companies(:first_firm) + assert_equal firm.limited_clients.length, firm.limited_clients.size + assert_equal firm.limited_clients.length, firm.limited_clients.count + end + def test_finding assert_equal 2, Firm.find(:first).clients.length end @@ -395,6 +401,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 3, company.clients_of_firm.size end + def test_collection_size_twice_for_regressions + post = posts(:thinking) + assert_equal 0, post.readers.size + # This test needs a post that has no readers, we assert it to ensure it holds, + # but need to reload the post because the very call to #size hides the bug. + post.reload + post.readers.build + size1 = post.readers.size + size2 = post.readers.size + assert_equal size1, size2 + end + def test_build_many company = companies(:first_firm) new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) } diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index d51a3c7e1c..353262c81b 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -196,4 +196,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase # due to Unknown column 'comments.id' assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title('Welcome to the weblog') end + + def test_count_with_include_should_alias_join_table + assert_equal 2, people(:michael).posts.count(:include => :readers) + end end diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index 99639849a5..ec06be5eba 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -79,6 +79,16 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) } end + def test_natural_assignment_to_already_associated_record + company = companies(:first_firm) + account = accounts(:signals37) + assert_equal company.account, account + company.account = account + company.reload + account.reload + assert_equal company.account, account + end + def test_assignment_without_replacement apple = Firm.create("name" => "Apple") citibank = Account.create("credit_limit" => 10) diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb index 3eb66bc941..77e3cb1776 100644 --- a/activerecord/test/cases/associations/has_one_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb @@ -44,19 +44,23 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase def test_has_one_through_polymorphic assert_equal clubs(:moustache_club), @member.sponsor_club end - + def has_one_through_to_has_many assert_equal 2, @member.fellow_members.size end - + def test_has_one_through_eager_loading - members = Member.find(:all, :include => :club, :conditions => ["name = ?", "Groucho Marx"]) + members = assert_queries(3) do #base table, through table, clubs table + Member.find(:all, :include => :club, :conditions => ["name = ?", "Groucho Marx"]) + end assert_equal 1, members.size assert_not_nil assert_no_queries {members[0].club} end - + def test_has_one_through_eager_loading_through_polymorphic - members = Member.find(:all, :include => :sponsor_club, :conditions => ["name = ?", "Groucho Marx"]) + members = assert_queries(3) do #base table, through table, clubs table + Member.find(:all, :include => :sponsor_club, :conditions => ["name = ?", "Groucho Marx"]) + end assert_equal 1, members.size assert_not_nil assert_no_queries {members[0].sponsor_club} end @@ -71,4 +75,39 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase assert_not_nil assert_no_queries {clubs[0].sponsored_member} end + def test_has_one_through_nonpreload_eagerloading + members = assert_queries(1) do + Member.find(:all, :include => :club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name') #force fallback + end + assert_equal 1, members.size + assert_not_nil assert_no_queries {members[0].club} + end + + def test_has_one_through_nonpreload_eager_loading_through_polymorphic + members = assert_queries(1) do + Member.find(:all, :include => :sponsor_club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name') #force fallback + end + assert_equal 1, members.size + assert_not_nil assert_no_queries {members[0].sponsor_club} + end + + def test_has_one_through_nonpreload_eager_loading_through_polymorphic_with_more_than_one_through_record + Sponsor.new(:sponsor_club => clubs(:crazy_club), :sponsorable => members(:groucho)).save! + members = assert_queries(1) do + Member.find(:all, :include => :sponsor_club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name DESC') #force fallback + end + assert_equal 1, members.size + assert_not_nil assert_no_queries { members[0].sponsor_club } + assert_equal clubs(:crazy_club), members[0].sponsor_club + end + + def test_uninitialized_has_one_through_should_return_nil_for_unsaved_record + assert_nil Member.new.club + end + + def test_assigning_association_correctly_assigns_target + new_member = Member.create(:name => "Chris") + new_member.club = new_club = Club.create(:name => "LRUG") + assert_equal new_club, new_member.club.target + end end diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb index 9e79d9c8a1..7a0427aabc 100644 --- a/activerecord/test/cases/associations/join_model_test.rb +++ b/activerecord/test/cases/associations/join_model_test.rb @@ -694,6 +694,13 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert ! david.categories.include?(category) end + def test_has_many_through_goes_through_all_sti_classes + sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1) + new_comment = sub_sti_post.comments.create(:body => 'test') + + assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort + end + private # create dynamic Post models to allow different dependency options def find_post_with_dependency(post_id, association, association_name, dependency) diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 4904feeb7d..0b2731ecd7 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -27,7 +27,7 @@ require 'models/sponsor' class AssociationsTest < ActiveRecord::TestCase fixtures :accounts, :companies, :developers, :projects, :developers_projects, - :computers + :computers, :people, :readers def test_include_with_order_works assert_nothing_raised {Account.find(:first, :order => 'id', :include => :firm)} @@ -45,7 +45,7 @@ class AssociationsTest < ActiveRecord::TestCase assert_equal [], person.readers.find(:all) person.save! reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar") - assert_equal [reader], person.readers.find(:all) + assert person.readers.find(reader.id) end def test_force_reload diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 36d30ade5e..c8111358e3 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -138,7 +138,7 @@ class BasicsTest < ActiveRecord::TestCase if current_adapter?(:MysqlAdapter) def test_read_attributes_before_type_cast_on_boolean bool = Booleantest.create({ "value" => false }) - assert_equal 0, bool.attributes_before_type_cast["value"] + assert_equal "0", bool.reload.attributes_before_type_cast["value"] end end @@ -616,7 +616,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_update_counter - category = Category.first + category = categories(:general) assert_nil category.categorizations_count assert_equal 2, category.categorizations.count @@ -1114,11 +1114,15 @@ class BasicsTest < ActiveRecord::TestCase end def test_boolean + b_nil = Booleantest.create({ "value" => nil }) + nil_id = b_nil.id b_false = Booleantest.create({ "value" => false }) false_id = b_false.id b_true = Booleantest.create({ "value" => true }) true_id = b_true.id + b_nil = Booleantest.find(nil_id) + assert_nil b_nil.value b_false = Booleantest.find(false_id) assert !b_false.value? b_true = Booleantest.find(true_id) @@ -1126,11 +1130,15 @@ class BasicsTest < ActiveRecord::TestCase end def test_boolean_cast_from_string + b_blank = Booleantest.create({ "value" => "" }) + blank_id = b_blank.id b_false = Booleantest.create({ "value" => "0" }) false_id = b_false.id b_true = Booleantest.create({ "value" => "1" }) true_id = b_true.id + b_blank = Booleantest.find(blank_id) + assert_nil b_blank.value b_false = Booleantest.find(false_id) assert !b_false.value? b_true = Booleantest.find(true_id) diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb index 540f42f4b6..98abc8eac8 100644 --- a/activerecord/test/cases/column_definition_test.rb +++ b/activerecord/test/cases/column_definition_test.rb @@ -9,13 +9,13 @@ class ColumnDefinitionTest < ActiveRecord::TestCase end # Avoid column definitions in create table statements like: - # `title` varchar(255) DEFAULT NULL NULL + # `title` varchar(255) DEFAULT 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 + assert_equal "title varchar(20)", column_def.to_sql end def test_should_include_default_clause_when_default_is_present @@ -23,7 +23,7 @@ class ColumnDefinitionTest < ActiveRecord::TestCase 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 + assert_equal %Q{title varchar(20) DEFAULT 'Hello'}, column_def.to_sql end def test_should_specify_not_null_if_null_option_is_false @@ -33,4 +33,4 @@ class ColumnDefinitionTest < ActiveRecord::TestCase 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 +end diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb index 2ea85417da..3473b846a0 100644 --- a/activerecord/test/cases/defaults_test.rb +++ b/activerecord/test/cases/defaults_test.rb @@ -5,7 +5,7 @@ require 'models/entrant' class DefaultTest < ActiveRecord::TestCase def test_nil_defaults_for_not_null_columns column_defaults = - if current_adapter?(:MysqlAdapter) && Mysql.client_version < 50051 + if current_adapter?(:MysqlAdapter) && (Mysql.client_version < 50051 || (50100..50122).include?(Mysql.client_version)) { 'id' => nil, 'name' => '', 'course_id' => nil } else { 'id' => nil, 'name' => nil, 'course_id' => nil } diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index feb47a15a8..4fe1d79f4d 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -191,6 +191,42 @@ class DirtyTest < ActiveRecord::TestCase assert !pirate.changed? end + def test_reverted_changes_are_not_dirty + phrase = "shiver me timbers" + pirate = Pirate.create!(:catchphrase => phrase) + pirate.catchphrase = "*hic*" + assert pirate.changed? + pirate.catchphrase = phrase + assert !pirate.changed? + end + + def test_reverted_changes_are_not_dirty_after_multiple_changes + phrase = "shiver me timbers" + pirate = Pirate.create!(:catchphrase => phrase) + 10.times do |i| + pirate.catchphrase = "*hic*" * i + assert pirate.changed? + end + assert pirate.changed? + pirate.catchphrase = phrase + assert !pirate.changed? + end + + + def test_reverted_changes_are_not_dirty_going_from_nil_to_value_and_back + pirate = Pirate.create!(:catchphrase => "Yar!") + + pirate.parrot_id = 1 + assert pirate.changed? + assert pirate.parrot_id_changed? + assert !pirate.catchphrase_changed? + + pirate.parrot_id = nil + assert !pirate.changed? + assert !pirate.parrot_id_changed? + assert !pirate.catchphrase_changed? + end + def test_save_should_store_serialized_attributes_even_with_partial_updates with_partial_updates(Topic) do topic = Topic.create!(:content => {:a => "a"}) diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index b97db73b68..2ce49ed76f 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -12,6 +12,57 @@ require 'models/customer' require 'models/job' require 'models/categorization' +class DynamicFinderMatchTest < ActiveRecord::TestCase + def test_find_no_match + assert_nil ActiveRecord::DynamicFinderMatch.match("not_a_finder") + end + + def test_find_by + match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location") + assert_not_nil match + assert match.finder? + assert_equal :find_initial, match.finder + assert_equal %w(age sex location), match.attribute_names + end + + def find_by_bang + match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location!") + assert_not_nil match + assert match.finder? + assert match.bang? + assert_equal :find_initial, match.finder + assert_equal %w(age sex location), match.attribute_names + end + + def test_find_all_by + match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location") + assert_not_nil match + assert match.finder? + assert_equal :find_every, match.finder + assert_equal %w(age sex location), match.attribute_names + end + + def test_find_or_initialize_by + match = ActiveRecord::DynamicFinderMatch.match("find_or_initialize_by_age_and_sex_and_location") + assert_not_nil match + assert !match.finder? + assert match.instantiator? + assert_equal :find_initial, match.finder + assert_equal :new, match.instantiator + assert_equal %w(age sex location), match.attribute_names + end + + def test_find_or_create_by + match = ActiveRecord::DynamicFinderMatch.match("find_or_create_by_age_and_sex_and_location") + assert_not_nil match + assert !match.finder? + assert match.instantiator? + assert_equal :find_initial, match.finder + assert_equal :create, match.instantiator + assert_equal %w(age sex location), match.attribute_names + end +end + class FinderTest < ActiveRecord::TestCase fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers @@ -440,6 +491,11 @@ class FinderTest < ActiveRecord::TestCase assert_nil Topic.find_by_title("The First Topic!") end + def test_find_by_one_attribute_bang + assert_equal topics(:first), Topic.find_by_title!("The First Topic") + assert_raises(ActiveRecord::RecordNotFound) { Topic.find_by_title!("The First Topic!") } + end + def test_find_by_one_attribute_caches_dynamic_finder # ensure this test can run independently of order class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' } diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index 0530ba9bd9..f30d58546e 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -1,4 +1,5 @@ $:.unshift(File.dirname(__FILE__) + '/../../lib') +$:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib') require 'config' require 'test/unit' diff --git a/activerecord/test/cases/i18n_test.rb b/activerecord/test/cases/i18n_test.rb new file mode 100644 index 0000000000..ea06e377e3 --- /dev/null +++ b/activerecord/test/cases/i18n_test.rb @@ -0,0 +1,41 @@ +require "cases/helper" +require 'models/topic' +require 'models/reply' + +class ActiveRecordI18nTests < Test::Unit::TestCase + + def setup + I18n.backend = I18n::Backend::Simple.new + end + + def test_translated_model_attributes + I18n.backend.store_translations 'en-US', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } } + assert_equal 'topic title attribute', Topic.human_attribute_name('title') + end + + def test_translated_model_attributes_with_sti + I18n.backend.store_translations 'en-US', :activerecord => {:attributes => {:reply => {:title => 'reply title attribute'} } } + assert_equal 'reply title attribute', Reply.human_attribute_name('title') + end + + def test_translated_model_attributes_with_sti_fallback + I18n.backend.store_translations 'en-US', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } } + assert_equal 'topic title attribute', Reply.human_attribute_name('title') + end + + def test_translated_model_names + I18n.backend.store_translations 'en-US', :activerecord => {:models => {:topic => 'topic model'} } + assert_equal 'topic model', Topic.human_name + end + + def test_translated_model_names_with_sti + I18n.backend.store_translations 'en-US', :activerecord => {:models => {:reply => 'reply model'} } + assert_equal 'reply model', Reply.human_name + end + + def test_translated_model_names_with_sti_fallback + I18n.backend.store_translations 'en-US', :activerecord => {:models => {:topic => 'topic model'} } + assert_equal 'topic model', Reply.human_name + end +end + diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 920f719995..c1a8da2270 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -237,6 +237,39 @@ if ActiveRecord::Base.connection.supports_migrations? end end + def test_create_table_with_timestamps_should_create_datetime_columns + table_name = :testings + + Person.connection.create_table table_name do |t| + t.timestamps + end + created_columns = Person.connection.columns(table_name) + + created_at_column = created_columns.detect {|c| c.name == 'created_at' } + updated_at_column = created_columns.detect {|c| c.name == 'updated_at' } + + assert created_at_column.null + assert updated_at_column.null + ensure + Person.connection.drop_table table_name rescue nil + end + + def test_create_table_with_timestamps_should_create_datetime_columns_with_options + table_name = :testings + + Person.connection.create_table table_name do |t| + t.timestamps :null => false + end + created_columns = Person.connection.columns(table_name) + + created_at_column = created_columns.detect {|c| c.name == 'created_at' } + updated_at_column = created_columns.detect {|c| c.name == 'updated_at' } + + assert !created_at_column.null + assert !updated_at_column.null + ensure + Person.connection.drop_table table_name rescue nil + end # SQL Server, Sybase, and SQLite3 will not allow you to add a NOT NULL # column to a table without a default value. @@ -409,10 +442,7 @@ if ActiveRecord::Base.connection.supports_migrations? ActiveRecord::Migration.add_column :people, :intelligence_quotient, :tinyint Person.reset_column_information - Person.create :intelligence_quotient => 300 - jonnyg = Person.find(:first) - assert_equal 127, jonnyg.intelligence_quotient - jonnyg.destroy + assert_match /tinyint/, Person.columns_hash['intelligence_quotient'].sql_type ensure ActiveRecord::Migration.remove_column :people, :intelligence_quotient rescue nil end @@ -904,6 +934,21 @@ if ActiveRecord::Base.connection.supports_migrations? assert_equal(0, ActiveRecord::Migrator.current_version) end + if current_adapter?(:PostgreSQLAdapter) + def test_migrator_one_up_with_exception_and_rollback + assert !Person.column_methods_hash.include?(:last_name) + + e = assert_raises(StandardError) do + ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/broken", 100) + end + + assert_equal "An error has occurred, this and all later migrations canceled:\n\nSomething broke", e.message + + Person.reset_column_information + assert !Person.column_methods_hash.include?(:last_name) + end + end + def test_finds_migrations migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations [['1', 'people_have_last_names'], @@ -1192,8 +1237,8 @@ if ActiveRecord::Base.connection.supports_migrations? def test_timestamps_creates_updated_at_and_created_at with_new_table do |t| - t.expects(:column).with(:created_at, :datetime) - t.expects(:column).with(:updated_at, :datetime) + t.expects(:column).with(:created_at, :datetime, kind_of(Hash)) + t.expects(:column).with(:updated_at, :datetime, kind_of(Hash)) t.timestamps end end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index bd6ec23853..6f6ea1cbe9 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -4,6 +4,7 @@ require 'models/topic' require 'models/comment' require 'models/reply' require 'models/author' +require 'models/developer' class NamedScopeTest < ActiveRecord::TestCase fixtures :posts, :authors, :topics, :comments, :author_addresses @@ -51,6 +52,11 @@ class NamedScopeTest < ActiveRecord::TestCase assert Topic.approved.respond_to?(:length) end + def test_respond_to_respects_include_private_parameter + assert !Topic.approved.respond_to?(:load_found) + assert Topic.approved.respond_to?(:load_found, true) + end + def test_subclasses_inherit_scopes assert Topic.scopes.include?(:base) @@ -238,4 +244,12 @@ class NamedScopeTest < ActiveRecord::TestCase assert topic.approved assert_equal 'lifo', topic.author_name end + + def test_find_all_should_behave_like_select + assert_equal Topic.base.select(&:approved), Topic.base.find_all(&:approved) + end + + def test_should_use_where_in_query_for_named_scope + assert_equal Developer.find_all_by_name('Jamis'), Developer.find_all_by_id(Developer.jamises) + end end diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index eae2104531..171d0e6dae 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -116,8 +116,9 @@ class QueryCacheExpiryTest < ActiveRecord::TestCase def test_cache_is_expired_by_habtm_delete ActiveRecord::Base.connection.expects(:clear_query_cache).times(2) ActiveRecord::Base.cache do - c = Category.find(:first) - p = Post.find(:first) + c = Category.find(1) + p = Post.find(1) + assert p.categories.any? p.categories.delete_all end end diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 723062e3b8..4b86e32dbf 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -166,6 +166,10 @@ class ReflectionTest < ActiveRecord::TestCase assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size end + def test_reflection_should_not_raise_error_when_compared_to_other_object + assert_nothing_raised { Firm.reflections[:clients] == Object.new } + end + private def assert_reflection(klass, association, options) assert reflection = klass.reflect_on_association(association) diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index 06a76eacc3..af3ee6ddba 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -2,6 +2,7 @@ require "cases/helper" require 'models/topic' require 'models/reply' require 'models/developer' +require 'models/book' class TransactionTest < ActiveRecord::TestCase self.use_transactional_fixtures = false @@ -86,8 +87,7 @@ class TransactionTest < ActiveRecord::TestCase assert Topic.find(2).approved?, "Second should still be approved" end - - def test_callback_rollback_in_save + def test_raising_exception_in_callback_rollbacks_in_save add_exception_raising_after_save_callback_to_topic begin @@ -102,6 +102,54 @@ class TransactionTest < ActiveRecord::TestCase end end + def test_cancellation_from_before_destroy_rollbacks_in_destroy + add_cancelling_before_destroy_with_db_side_effect_to_topic + begin + nbooks_before_destroy = Book.count + status = @first.destroy + assert !status + assert_nothing_raised(ActiveRecord::RecordNotFound) { @first.reload } + assert_equal nbooks_before_destroy, Book.count + ensure + remove_cancelling_before_destroy_with_db_side_effect_to_topic + end + end + + def test_cancellation_from_before_filters_rollbacks_in_save + %w(validation save).each do |filter| + send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") + begin + nbooks_before_save = Book.count + original_author_name = @first.author_name + @first.author_name += '_this_should_not_end_up_in_the_db' + status = @first.save + assert !status + assert_equal original_author_name, @first.reload.author_name + assert_equal nbooks_before_save, Book.count + ensure + send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") + end + end + end + + def test_cancellation_from_before_filters_rollbacks_in_save! + %w(validation save).each do |filter| + send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") + begin + nbooks_before_save = Book.count + original_author_name = @first.author_name + @first.author_name += '_this_should_not_end_up_in_the_db' + @first.save! + flunk + rescue => e + assert_equal original_author_name, @first.reload.author_name + assert_equal nbooks_before_save, Book.count + ensure + send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") + end + end + end + def test_callback_rollback_in_create new_topic = Topic.new( :title => "A new topic", @@ -221,6 +269,16 @@ class TransactionTest < ActiveRecord::TestCase def remove_exception_raising_after_create_callback_to_topic Topic.class_eval { remove_method :after_create } end + + %w(validation save destroy).each do |filter| + define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do + Topic.class_eval "def before_#{filter}() Book.create; false end" + end + + define_method("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") do + Topic.class_eval "remove_method :before_#{filter}" + end + end end if current_adapter?(:PostgreSQLAdapter) diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb index 86834fe920..43592bcee3 100644 --- a/activerecord/test/cases/validations_i18n_test.rb +++ b/activerecord/test/cases/validations_i18n_test.rb @@ -6,18 +6,18 @@ 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}}) + I18n.backend.store_translations('en-US', :activerecord => {:errors => {:messages => {:custom => nil}}}) end - + def teardown reset_callbacks Topic - load 'active_record/locale/en-US.rb' + I18n.load_translations File.dirname(__FILE__) + '/../../lib/active_record/locale/en-US.yml' end - + def unique_topic @unique ||= Topic.create :title => 'unique!' end - + def replied_topic @replied_topic ||= begin topic = Topic.create(:title => "topic") @@ -25,7 +25,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase topic end end - + def reset_callbacks(*models) models.each do |model| model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) @@ -33,28 +33,83 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase 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' + 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 - 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] + 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 def test_errors_add_on_empty_generates_message @@ -78,12 +133,12 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase 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.instance_variable_set :@errors, { 'title' => ['empty'] } + I18n.expects(:translate).with(:"topic.title", :default => ['Title'], :scope => [:activerecord, :attributes], :count => 1).returns('Title') @topic.errors.full_messages :locale => 'en-US' end - end - + end + # ActiveRecord::Validations uses_mocha 'ActiveRecord::Validations' do # validates_confirmation_of w/ mocha @@ -101,7 +156,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -115,9 +170,9 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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}) @@ -129,7 +184,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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}) @@ -183,7 +238,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -197,23 +252,23 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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.errors.expects(:generate_message).with(:title, :taken, {:default => nil, :value => 'unique!'}) @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.errors.expects(:generate_message).with(:title, :taken, {:default => 'custom', :value => 'unique!'}) @topic.valid? end - + # validates_format_of w/ mocha def test_validates_format_of_generates_message @@ -229,7 +284,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -245,7 +300,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -261,7 +316,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -277,7 +332,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -293,7 +348,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -309,7 +364,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -325,7 +380,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase @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 @@ -340,284 +395,464 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase 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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:confirmation => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:accepted => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:blank => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:too_short => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:invalid => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:inclusion => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:exclusion => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:odd => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:less_than => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:replies => {:invalid => 'custom message'}}}}}} + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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'}} - + I18n.backend.store_translations 'en-US', :activerecord => {:errors => {: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 +end + +class ActiveRecordValidationsGenerateMessageI18nTests < Test::Unit::TestCase + def setup + reset_callbacks Topic + @topic = Topic.new + I18n.backend.store_translations :'en-US', { + :activerecord => { + :errors => { + :messages => { + :inclusion => "is not included in the list", + :exclusion => "is reserved", + :invalid => "is invalid", + :confirmation => "doesn't match confirmation", + :accepted => "must be accepted", + :empty => "can't be empty", + :blank => "can't be blank", + :too_long => "is too long (maximum is {{count}} characters)", + :too_short => "is too short (minimum is {{count}} characters)", + :wrong_length => "is the wrong length (should be {{count}} characters)", + :taken => "has already been taken", + :not_a_number => "is not a number", + :greater_than => "must be greater than {{count}}", + :greater_than_or_equal_to => "must be greater than or equal to {{count}}", + :equal_to => "must be equal to {{count}}", + :less_than => "must be less than {{count}}", + :less_than_or_equal_to => "must be less than or equal to {{count}}", + :odd => "must be odd", + :even => "must be even" + } + } + } + } + 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 + + # validates_inclusion_of: generate_message(attr_name, :inclusion, :default => configuration[:message], :value => value) + def test_generate_message_inclusion_with_default_message + assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title') + end + + def test_generate_message_inclusion_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :inclusion, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_exclusion_of: generate_message(attr_name, :exclusion, :default => configuration[:message], :value => value) + def test_generate_message_exclusion_with_default_message + assert_equal 'is reserved', @topic.errors.generate_message(:title, :exclusion, :default => nil, :value => 'title') + end + + def test_generate_message_exclusion_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :exclusion, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_associated: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) + # validates_format_of: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) + def test_generate_message_invalid_with_default_message + assert_equal 'is invalid', @topic.errors.generate_message(:title, :invalid, :default => nil, :value => 'title') + end + + def test_generate_message_invalid_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_confirmation_of: generate_message(attr_name, :confirmation, :default => configuration[:message]) + def test_generate_message_confirmation_with_default_message + assert_equal "doesn't match confirmation", @topic.errors.generate_message(:title, :confirmation, :default => nil) + end + + def test_generate_message_confirmation_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :confirmation, :default => 'custom message') + end + + # validates_acceptance_of: generate_message(attr_name, :accepted, :default => configuration[:message]) + def test_generate_message_accepted_with_default_message + assert_equal "must be accepted", @topic.errors.generate_message(:title, :accepted, :default => nil) + end + + def test_generate_message_accepted_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :accepted, :default => 'custom message') + end + + # add_on_empty: generate_message(attr, :empty, :default => custom_message) + def test_generate_message_empty_with_default_message + assert_equal "can't be empty", @topic.errors.generate_message(:title, :empty, :default => nil) + end + + def test_generate_message_empty_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :empty, :default => 'custom message') + end + + # add_on_blank: generate_message(attr, :blank, :default => custom_message) + def test_generate_message_blank_with_default_message + assert_equal "can't be blank", @topic.errors.generate_message(:title, :blank, :default => nil) + end + + def test_generate_message_blank_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :blank, :default => 'custom message') + end + + # validates_length_of: generate_message(attr, :too_long, :default => options[:too_long], :count => option_value.end) + def test_generate_message_too_long_with_default_message + assert_equal "is too long (maximum is 10 characters)", @topic.errors.generate_message(:title, :too_long, :default => nil, :count => 10) + end + + def test_generate_message_too_long_with_custom_message + assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_long, :default => 'custom message {{count}}', :count => 10) + end + + # validates_length_of: generate_message(attr, :too_short, :default => options[:too_short], :count => option_value.begin) + def test_generate_message_too_short_with_default_message + assert_equal "is too short (minimum is 10 characters)", @topic.errors.generate_message(:title, :too_short, :default => nil, :count => 10) + end + + def test_generate_message_too_short_with_custom_message + assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_short, :default => 'custom message {{count}}', :count => 10) + end + + # validates_length_of: generate_message(attr, key, :default => custom_message, :count => option_value) + def test_generate_message_wrong_length_with_default_message + assert_equal "is the wrong length (should be 10 characters)", @topic.errors.generate_message(:title, :wrong_length, :default => nil, :count => 10) + end + + def test_generate_message_wrong_length_with_custom_message + assert_equal 'custom message 10', @topic.errors.generate_message(:title, :wrong_length, :default => 'custom message {{count}}', :count => 10) + end + + # validates_uniqueness_of: generate_message(attr_name, :taken, :default => configuration[:message]) + def test_generate_message_taken_with_default_message + assert_equal "has already been taken", @topic.errors.generate_message(:title, :taken, :default => nil, :value => 'title') + end + + def test_generate_message_taken_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :taken, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_numericality_of: generate_message(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message]) + def test_generate_message_not_a_number_with_default_message + assert_equal "is not a number", @topic.errors.generate_message(:title, :not_a_number, :default => nil, :value => 'title') + end + + def test_generate_message_not_a_number_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :not_a_number, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_numericality_of: generate_message(attr_name, option, :value => raw_value, :default => configuration[:message]) + def test_generate_message_greater_than_with_default_message + assert_equal "must be greater than 10", @topic.errors.generate_message(:title, :greater_than, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_greater_than_or_equal_to_with_default_message + assert_equal "must be greater than or equal to 10", @topic.errors.generate_message(:title, :greater_than_or_equal_to, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_equal_to_with_default_message + assert_equal "must be equal to 10", @topic.errors.generate_message(:title, :equal_to, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_less_than_with_default_message + assert_equal "must be less than 10", @topic.errors.generate_message(:title, :less_than, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_less_than_or_equal_to_with_default_message + assert_equal "must be less than or equal to 10", @topic.errors.generate_message(:title, :less_than_or_equal_to, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_odd_with_default_message + assert_equal "must be odd", @topic.errors.generate_message(:title, :odd, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_even_with_default_message + assert_equal "must be even", @topic.errors.generate_message(:title, :even, :default => nil, :value => 'title', :count => 10) + end +end diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index 4b2d28c80b..a40bda2533 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -1420,8 +1420,8 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase def test_validates_numericality_of_with_nil_allowed Topic.validates_numericality_of :approved, :allow_nil => true - invalid!(BLANK + JUNK) - valid!(NIL + FLOATS + INTEGERS + BIGDECIMAL + INFINITY) + invalid!(JUNK) + valid!(NIL + BLANK + FLOATS + INTEGERS + BIGDECIMAL + INFINITY) end def test_validates_numericality_of_with_integer_only @@ -1434,8 +1434,8 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase def test_validates_numericality_of_with_integer_only_and_nil_allowed Topic.validates_numericality_of :approved, :only_integer => true, :allow_nil => true - invalid!(BLANK + JUNK + FLOATS + BIGDECIMAL + INFINITY) - valid!(NIL + INTEGERS) + invalid!(JUNK + FLOATS + BIGDECIMAL + INFINITY) + valid!(NIL + BLANK + INTEGERS) end def test_validates_numericality_with_greater_than diff --git a/activerecord/test/connections/native_mysql/connection.rb b/activerecord/test/connections/native_mysql/connection.rb index 1fab444e58..140e06d631 100644 --- a/activerecord/test/connections/native_mysql/connection.rb +++ b/activerecord/test/connections/native_mysql/connection.rb @@ -2,9 +2,7 @@ print "Using native MySQL\n" require_dependency 'models/course' require 'logger' -RAILS_DEFAULT_LOGGER = Logger.new('debug.log') -RAILS_DEFAULT_LOGGER.level = Logger::DEBUG -ActiveRecord::Base.logger = RAILS_DEFAULT_LOGGER +ActiveRecord::Base.logger = Logger.new("debug.log") # GRANT ALL PRIVILEGES ON activerecord_unittest.* to 'rails'@'localhost'; # GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost'; diff --git a/activerecord/test/migrations/broken/100_migration_that_raises_exception.rb b/activerecord/test/migrations/broken/100_migration_that_raises_exception.rb new file mode 100644 index 0000000000..ffb224dad9 --- /dev/null +++ b/activerecord/test/migrations/broken/100_migration_that_raises_exception.rb @@ -0,0 +1,10 @@ +class MigrationThatRaisesException < ActiveRecord::Migration + def self.up + add_column "people", "last_name", :string + raise 'Something broke' + end + + def self.down + remove_column "people", "last_name" + end +end diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index 136dc39cf3..c6aa0293c2 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -32,6 +32,9 @@ class Author < ActiveRecord::Base has_many :special_posts has_many :special_post_comments, :through => :special_posts, :source => :comments + has_many :sti_posts, :class_name => 'StiPost' + has_many :sti_post_comments, :through => :sti_posts, :source => :comments + has_many :special_nonexistant_posts, :class_name => "SpecialPost", :conditions => "posts.body = 'nonexistant'" has_many :special_nonexistant_post_comments, :through => :special_nonexistant_posts, :source => :comments, :conditions => "comments.post_id = 0" has_many :nonexistant_comments, :through => :posts diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 9f26cacdec..c08476f728 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -43,6 +43,8 @@ class Developer < ActiveRecord::Base has_many :audit_logs + named_scope :jamises, :conditions => {:name => 'Jamis'} + validates_inclusion_of :salary, :in => 50000..200000 validates_length_of :name, :within => 3..20 diff --git a/activerecord/test/models/project.rb b/activerecord/test/models/project.rb index e1ab89eca5..44c692b5e7 100644 --- a/activerecord/test/models/project.rb +++ b/activerecord/test/models/project.rb @@ -7,7 +7,7 @@ class Project < ActiveRecord::Base has_and_belongs_to_many :developers_named_david, :class_name => "Developer", :conditions => "name = 'David'", :uniq => true has_and_belongs_to_many :developers_named_david_with_hash_conditions, :class_name => "Developer", :conditions => { :name => 'David' }, :uniq => true has_and_belongs_to_many :salaried_developers, :class_name => "Developer", :conditions => "salary > 0" - has_and_belongs_to_many :developers_with_finder_sql, :class_name => "Developer", :finder_sql => 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id}' + has_and_belongs_to_many :developers_with_finder_sql, :class_name => "Developer", :finder_sql => 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id} ORDER BY t.id' has_and_belongs_to_many :developers_by_sql, :class_name => "Developer", :delete_sql => "DELETE FROM developers_projects WHERE project_id = \#{id} AND developer_id = \#{record.id}" has_and_belongs_to_many :developers_with_callbacks, :class_name => "Developer", :before_add => Proc.new {|o, r| o.developers_log << "before_adding#{r.id || '<new>'}"}, :after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id || '<new>'}"}, diff --git a/activerecord/test/schema/mysql_specific_schema.rb b/activerecord/test/schema/mysql_specific_schema.rb index 5ae062c97c..f44c33ae67 100644 --- a/activerecord/test/schema/mysql_specific_schema.rb +++ b/activerecord/test/schema/mysql_specific_schema.rb @@ -1,5 +1,5 @@ ActiveRecord::Schema.define do - create_table :binary_fields, :force => true do |t| + create_table :binary_fields, :force => true, :options => 'CHARACTER SET latin1' do |t| t.binary :tiny_blob, :limit => 255 t.binary :normal_blob, :limit => 65535 t.binary :medium_blob, :limit => 16777215 @@ -9,4 +9,4 @@ ActiveRecord::Schema.define do t.text :medium_text, :limit => 16777215 t.text :long_text, :limit => 2147483647 end -end
\ No newline at end of file +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 487a08f4ab..ab5c7c520b 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -60,7 +60,7 @@ ActiveRecord::Schema.define do end create_table :booleantests, :force => true do |t| - t.integer :value + t.boolean :value end create_table :categories, :force => true do |t| |