diff options
Diffstat (limited to 'activerecord/test')
17 files changed, 235 insertions, 8 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb new file mode 100644 index 0000000000..5ed2d8aba2 --- /dev/null +++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb @@ -0,0 +1,46 @@ +# encoding: utf-8 + +require "cases/helper" +require 'active_record/base' +require 'active_record/connection_adapters/postgresql_adapter' + +class PostgresqlByteaTest < ActiveRecord::TestCase + class ByteaDataType < ActiveRecord::Base + self.table_name = 'bytea_data_type' + end + + def setup + @connection = ActiveRecord::Base.connection + begin + @connection.transaction do + @connection.create_table('bytea_data_type') do |t| + t.binary 'payload' + t.binary 'serialized' + end + end + end + @column = ByteaDataType.columns.find { |c| c.name == 'payload' } + assert(@column.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLColumn)) + end + + def teardown + @connection.execute 'drop table if exists bytea_data_type' + end + + class Serializer + def load(str); str; end + def dump(str); str; end + end + + def test_serialize + serializer = Serializer.new + klass = Class.new(ByteaDataType) { + serialize :serialized, Serializer.new + } + obj = klass.new + obj.serialized = "hello world" + obj.save! + obj.reload + assert_equal "hello world", obj.serialized + end +end diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index c9b26895ae..58c788e42d 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -387,6 +387,26 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal 15, topic.replies.size end + def test_counter_cache_double_destroy + topic = Topic.create :title => "Zoom-zoom-zoom" + + 5.times do + topic.replies.create(:title => "re: zoom", :content => "speedy quick!") + end + + assert_equal 5, topic.reload[:replies_count] + assert_equal 5, topic.replies.size + + reply = topic.replies.first + + reply.destroy + assert_equal 4, topic.reload[:replies_count] + + reply.destroy + assert_equal 4, topic.reload[:replies_count] + assert_equal 4, topic.replies.size + end + def test_custom_counter_cache reply = Reply.create(:title => "re: zoom", :content => "speedy quick!") assert_equal 0, reply[:replies_count] diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 944f135153..42061d3d73 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1118,4 +1118,11 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_no_queries { assert_equal 2, author.comments_with_order_and_conditions.size } assert_no_queries { assert_equal 5, author.posts.size, "should not cache a subset of the association" } end + + test "preloading a through association twice does not reset it" do + members = Member.includes(:current_membership => :club).includes(:club).to_a + assert_no_queries { + assert_equal 3, members.map(&:current_membership).map(&:club).size + } + end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 869ec1e4b8..d94f5d3207 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -1311,6 +1311,33 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert !company.clients.loaded? end + def test_get_ids_for_association_on_new_record_does_not_try_to_find_records + Company.columns # Load schema information so we don't query below + Contract.columns # if running just this test. + + company = Company.new + assert_queries(0) do + company.contract_ids + end + + assert_equal [], company.contract_ids + end + + def test_set_ids_for_association_on_new_record_applies_association_correctly + contract_a = Contract.create! + contract_b = Contract.create! + Contract.create! # another contract + company = Company.new(:name => "Some Company") + + company.contract_ids = [contract_a.id, contract_b.id] + assert_equal [contract_a.id, contract_b.id], company.contract_ids + assert_equal [contract_a, contract_b], company.contracts + + company.save! + assert_equal company, contract_a.reload.company + assert_equal company, contract_b.reload.company + end + def test_get_ids_ignores_include_option assert_equal [readers(:michael_welcome).id], posts(:welcome).readers_with_person_ids end @@ -1492,6 +1519,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal david.essays, Essay.find_all_by_writer_id("David") end + def test_has_many_assignment_with_custom_primary_key + david = people(:david) + + assert_equal ["A Modest Proposal"], david.essays.map(&:name) + david.essays = [Essay.create!(:name => "Remote Work" )] + assert_equal ["Remote Work"], david.essays.map(&:name) + end + def test_blank_custom_primary_key_on_new_record_should_not_run_queries author = Author.new assert !author.essays.loaded? diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index bba1b2b66d..656798300d 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -596,7 +596,7 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase end class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase - self.use_transactional_fixtures = false unless supports_savepoints? + self.use_transactional_fixtures = false def setup @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") @@ -793,6 +793,20 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase assert_equal 2, @pirate.birds.reload.length end + def test_should_save_new_record_that_has_same_value_as_existing_record_marked_for_destruction_on_field_that_has_unique_index + Bird.connection.add_index :birds, :name, :unique => true + + 3.times { |i| @pirate.birds.create(:name => "unique_birds_#{i}") } + + @pirate.birds[0].mark_for_destruction + @pirate.birds.build(:name => @pirate.birds[0].name) + @pirate.save! + + assert_equal 3, @pirate.birds.reload.length + ensure + Bird.connection.remove_index :birds, :column => :name + end + # Add and remove callbacks tests for association collections. %w{ method proc }.each do |callback_type| define_method("test_should_run_add_callback_#{callback_type}s_for_has_many") do @@ -875,8 +889,10 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase @pirate.parrots.each { |parrot| parrot.mark_for_destruction } assert @pirate.save - assert_queries(0) do - assert @pirate.save + Pirate.transaction do + assert_queries(0) do + assert @pirate.save + end end end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 97d6c0cf88..67b5d174aa 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1540,6 +1540,16 @@ class BasicsTest < ActiveRecord::TestCase end end + def test_dont_clear_inheritnce_column_when_setting_explicitly + Joke.inheritance_column = "my_type" + before_inherit = Joke.inheritance_column + + Joke.reset_column_information + after_inherit = Joke.inheritance_column + + assert_equal before_inherit, after_inherit unless before_inherit.blank? && after_inherit.blank? + end + def test_set_table_name_symbol_converted_to_string Joke.table_name = :cold_jokes assert_equal 'cold_jokes', Joke.table_name diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index a1dc1de38d..8755e1f580 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -493,10 +493,10 @@ class CalculationsTest < ActiveRecord::TestCase assert_equal [1,2,3,4], Topic.order(:id).pluck("topics.id") end - def test_pluck_replaces_select_clause - taks_relation = Topic.select([:approved, :id]).order(:id) - assert_equal [1,2,3,4], taks_relation.pluck(:id) - assert_equal [false, true, true, true], taks_relation.pluck(:approved) + def test_pluck_does_not_replace_select_clause + taks_relation = Topic.select("approved, id, id AS foo_id").order('foo_id DESC') + assert_equal [4,3,2,1], taks_relation.pluck(:id) + assert_equal [true, true, true, false], taks_relation.pluck(:approved) end def test_pluck_auto_table_name_prefix diff --git a/activerecord/test/cases/disconnected_test.rb b/activerecord/test/cases/disconnected_test.rb new file mode 100644 index 0000000000..cc2c1f6489 --- /dev/null +++ b/activerecord/test/cases/disconnected_test.rb @@ -0,0 +1,26 @@ +require "cases/helper" + +class TestRecord < ActiveRecord::Base +end + +class TestDisconnectedAdapter < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + def setup + @connection = ActiveRecord::Base.connection + end + + def teardown + spec = ActiveRecord::Base.connection_config + ActiveRecord::Base.establish_connection(spec) + @connection = nil + end + + test "can't execute statements while disconnected" do + @connection.execute "SELECT count(*) from products" + @connection.disconnect! + assert_raises(ActiveRecord::StatementInvalid) do + @connection.execute "SELECT count(*) from products" + end + end +end diff --git a/activerecord/test/cases/explain_subscriber_test.rb b/activerecord/test/cases/explain_subscriber_test.rb index 7b852a625d..0546e793fe 100644 --- a/activerecord/test/cases/explain_subscriber_test.rb +++ b/activerecord/test/cases/explain_subscriber_test.rb @@ -38,6 +38,13 @@ if ActiveRecord::Base.connection.supports_explain? end end + def test_collects_nothing_if_the_statement_is_only_partially_matched + with_queries([]) do |queries| + SUBSCRIBER.call(:name => 'SQL', :sql => 'select_db yo_mama') + assert queries.empty? + end + end + def test_collects_nothing_if_unexplained_sqls with_queries([]) do |queries| SUBSCRIBER.call(:name => 'SQL', :sql => 'SHOW max_identifier_length') diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 7d63d76c34..2efafe5c24 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -31,6 +31,13 @@ class FinderTest < ActiveRecord::TestCase assert_equal(topics(:first).title, Topic.find(1).title) end + def test_symbols_table_ref + Post.first # warm up + x = Symbol.all_symbols.count + Post.where("title" => {"xxxqqqq" => "bar"}) + assert_equal x, Symbol.all_symbols.count + end + # find should handle strings that come from URLs # (example: Category.find(params[:id])) def test_find_with_string @@ -86,6 +93,18 @@ class FinderTest < ActiveRecord::TestCase assert !Topic.includes(:replies).limit(1).where('0 = 1').exists? end + def test_exists_with_distinct_association_includes_and_limit + author = Author.first + assert !author.unique_categorized_posts.includes(:special_comments).limit(0).exists? + assert author.unique_categorized_posts.includes(:special_comments).limit(1).exists? + end + + def test_exists_with_distinct_association_includes_limit_and_order + author = Author.first + assert !author.unique_categorized_posts.includes(:special_comments).order('comments.taggings_count DESC').limit(0).exists? + assert author.unique_categorized_posts.includes(:special_comments).order('comments.taggings_count DESC').limit(1).exists? + end + def test_exists_with_empty_table_and_no_args_given Topic.delete_all assert !Topic.exists? diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb index 5153945546..13f90e8eef 100644 --- a/activerecord/test/cases/mass_assignment_security_test.rb +++ b/activerecord/test/cases/mass_assignment_security_test.rb @@ -300,6 +300,16 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase assert_admin_attributes(p, true) end + def test_attr_protected_with_newline + p = LoosePerson.new + assert_raises(ActiveRecord::UnknownAttributeError) do + p.attributes = {"comments=\n"=>"hax"} + end + assert_nil p.comments, "Comments is meant to be attr_protected but I assigned it with attributes=" + p.attributes= {"comments(1)\n" => "hax"} + assert_nil p.comments, "Comments is meant to be attr_protected but I assigned it with attributes=" + end + end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index ada4294401..f14eee2eb8 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -4,6 +4,7 @@ require 'models/tagging' require 'models/post' require 'models/topic' require 'models/comment' +require 'models/rating' require 'models/reply' require 'models/author' require 'models/comment' @@ -19,7 +20,7 @@ require 'models/minivan' class RelationTest < ActiveRecord::TestCase fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments, - :tags, :taggings, :cars, :minivans + :ratings, :tags, :taggings, :cars, :minivans def test_do_not_double_quote_string_id van = Minivan.last @@ -332,6 +333,13 @@ class RelationTest < ActiveRecord::TestCase end end + def test_preload_applies_to_all_chained_preloaded_scopes + assert_queries(3) do + post = Post.with_tags.with_comments.first + assert post + end + end + def test_find_with_included_associations assert_queries(2) do posts = Post.includes(:comments).order('posts.id') @@ -689,6 +697,12 @@ class RelationTest < ActiveRecord::TestCase assert_equal 1, comments.count end + def test_relation_merging_with_merged_joins + special_comments_with_ratings = SpecialComment.joins(:ratings) + posts_with_special_comments_with_ratings = Post.group('posts.id').joins(:special_comments).merge(special_comments_with_ratings) + assert_equal 1, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length + end + def test_count posts = Post.scoped diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 0a9643b7e0..629e5e0fff 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -206,6 +206,11 @@ class SchemaDumperTest < ActiveRecord::TestCase end if current_adapter?(:PostgreSQLAdapter) + def test_schema_dump_includes_bigint_default + output = standard_dump + assert_match %r{t.integer\s+"bigint_default",\s+:limit => 8,\s+:default => 0}, output + end + def test_schema_dump_includes_xml_shorthand_definition output = standard_dump if %r{create_table "postgresql_xml_data_type"} =~ output diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index 277fc9d676..bbcbeac959 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -40,4 +40,11 @@ class StoreTest < ActiveRecord::TestCase @john.remember_login = false assert_equal false, @john.remember_login end + + test "updating the store will track changes correctly" do + @john.color = "blue" + assert_equal [{:color => "black"}, {:color => "blue"}], @john.settings_change + @john.homepage = "37signals.com" + assert_equal [{:color => "black"}, {:color => "blue", :homepage => "37signals.com"}], @john.settings_change + end end diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index 07c529d685..d316a0b992 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -27,6 +27,7 @@ class Person < ActiveRecord::Base has_many :agents_posts, :through => :agents, :source => :posts has_many :agents_posts_authors, :through => :agents_posts, :source => :author + has_many :essays, :primary_key => "first_name", :foreign_key => "writer_id" scope :males, :conditions => { :gender => 'M' } scope :females, :conditions => { :gender => 'F' } diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index 9aa02fa18f..3cfd1a0f76 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -76,6 +76,9 @@ class Post < ActiveRecord::Base end end + scope :with_comments, preload(:comments) + scope :with_tags, preload(:taggings) + has_many :interpolated_taggings, :class_name => 'Tagging', :as => :taggable, :conditions => proc { "1 = #{1}" } has_many :interpolated_tags, :through => :taggings has_many :interpolated_tags_2, :through => :interpolated_taggings, :source => :tag diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb index b2c655ddcd..4f546df2eb 100644 --- a/activerecord/test/schema/postgresql_specific_schema.rb +++ b/activerecord/test/schema/postgresql_specific_schema.rb @@ -30,6 +30,7 @@ ActiveRecord::Schema.define do char3 text default 'a text field', positive_integer integer default 1, negative_integer integer default -1, + bigint_default bigint default 0::bigint, decimal_number decimal(3,2) default 2.78, multiline_default text DEFAULT '--- [] |