diff options
Diffstat (limited to 'activerecord/test')
23 files changed, 309 insertions, 121 deletions
diff --git a/activerecord/test/cases/adapters/mysql/schema_test.rb b/activerecord/test/cases/adapters/mysql/schema_test.rb index 807a7a155e..87c5277e64 100644 --- a/activerecord/test/cases/adapters/mysql/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql/schema_test.rb @@ -17,6 +17,44 @@ module ActiveRecord self.table_name = "#{db}.#{table}" def self.name; 'Post'; end end + + @connection.create_table "mysql_doubles" + end + + teardown do + @connection.execute "drop table if exists mysql_doubles" + end + + class MysqlDouble < ActiveRecord::Base + self.table_name = "mysql_doubles" + end + + def test_float_limits + @connection.add_column :mysql_doubles, :float_no_limit, :float + @connection.add_column :mysql_doubles, :float_short, :float, limit: 5 + @connection.add_column :mysql_doubles, :float_long, :float, limit: 53 + + @connection.add_column :mysql_doubles, :float_23, :float, limit: 23 + @connection.add_column :mysql_doubles, :float_24, :float, limit: 24 + @connection.add_column :mysql_doubles, :float_25, :float, limit: 25 + MysqlDouble.reset_column_information + + column_no_limit = MysqlDouble.columns.find { |c| c.name == 'float_no_limit' } + column_short = MysqlDouble.columns.find { |c| c.name == 'float_short' } + column_long = MysqlDouble.columns.find { |c| c.name == 'float_long' } + + column_23 = MysqlDouble.columns.find { |c| c.name == 'float_23' } + column_24 = MysqlDouble.columns.find { |c| c.name == 'float_24' } + column_25 = MysqlDouble.columns.find { |c| c.name == 'float_25' } + + # Mysql floats are precision 0..24, Mysql doubles are precision 25..53 + assert_equal 24, column_no_limit.limit + assert_equal 24, column_short.limit + assert_equal 53, column_long.limit + + assert_equal 24, column_23.limit + assert_equal 24, column_24.limit + assert_equal 53, column_25.limit end def test_schema diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb index 18dd4a6de8..c20030ca64 100644 --- a/activerecord/test/cases/adapters/postgresql/array_test.rb +++ b/activerecord/test/cases/adapters/postgresql/array_test.rb @@ -16,7 +16,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase t.integer 'ratings', array: true end end - @column = PgArray.columns.find { |c| c.name == 'tags' } + @column = PgArray.columns_hash['tags'] end teardown do @@ -61,10 +61,10 @@ class PostgresqlArrayTest < ActiveRecord::TestCase def test_change_column_with_array @connection.add_column :pg_arrays, :snippets, :string, array: true, default: [] - @connection.change_column :pg_arrays, :snippets, :text, array: true, default: "{}" + @connection.change_column :pg_arrays, :snippets, :text, array: true, default: [] PgArray.reset_column_information - column = PgArray.columns.find { |c| c.name == 'snippets' } + column = PgArray.columns_hash['snippets'] assert_equal :text, column.type assert_equal [], column.default @@ -80,6 +80,14 @@ class PostgresqlArrayTest < ActiveRecord::TestCase end end + def test_change_column_default_with_array + @connection.change_column_default :pg_arrays, :tags, [] + + PgArray.reset_column_information + column = PgArray.columns_hash['tags'] + assert_equal [], column.default + end + def test_type_cast_array data = '{1,2,3}' oid_type = @column.instance_variable_get('@oid_type').subtype @@ -101,17 +109,32 @@ class PostgresqlArrayTest < ActiveRecord::TestCase assert_equal(['1', '2'], x.ratings) end - def test_rewrite + def test_select_with_strings @connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')" x = PgArray.first - x.tags = ['1','2','3','4'] - assert x.save! + assert_equal(['1','2','3'], x.tags) end - def test_select + def test_rewrite_with_strings @connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')" x = PgArray.first - assert_equal(['1','2','3'], x.tags) + x.tags = ['1','2','3','4'] + x.save! + assert_equal ['1','2','3','4'], x.reload.tags + end + + def test_select_with_integers + @connection.execute "insert into pg_arrays (ratings) VALUES ('{1,2,3}')" + x = PgArray.first + assert_equal([1, 2, 3], x.ratings) + end + + def test_rewrite_with_integers + @connection.execute "insert into pg_arrays (ratings) VALUES ('{1,2,3}')" + x = PgArray.first + x.ratings = [2, '3', 4] + x.save! + assert_equal [2, 3, 4], x.reload.ratings end def test_multi_dimensional_with_strings @@ -175,6 +198,14 @@ class PostgresqlArrayTest < ActiveRecord::TestCase assert_equal [], pg_array.reload.tags end + def test_escaping + unknown = 'foo\\",bar,baz,\\' + tags = ["hello_#{unknown}"] + ar = PgArray.create!(tags: tags) + ar.reload + assert_equal tags, ar.tags + end + private def assert_cycle field, array # test creation diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb index e3478856c8..fadadfa57c 100644 --- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb +++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb @@ -19,7 +19,7 @@ class PostgresqlByteaTest < ActiveRecord::TestCase end end end - @column = ByteaDataType.columns.find { |c| c.name == 'payload' } + @column = ByteaDataType.columns_hash['payload'] assert(@column.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLColumn)) end diff --git a/activerecord/test/cases/adapters/postgresql/citext_test.rb b/activerecord/test/cases/adapters/postgresql/citext_test.rb index 948bf49a54..8493050726 100644 --- a/activerecord/test/cases/adapters/postgresql/citext_test.rb +++ b/activerecord/test/cases/adapters/postgresql/citext_test.rb @@ -50,7 +50,7 @@ if ActiveRecord::Base.connection.supports_extensions? t.citext 'username' end Citext.reset_column_information - column = Citext.columns.find { |c| c.name == 'username' } + column = Citext.columns_hash['username'] assert_equal :citext, column.type raise ActiveRecord::Rollback # reset the schema change diff --git a/activerecord/test/cases/adapters/postgresql/composite_test.rb b/activerecord/test/cases/adapters/postgresql/composite_test.rb index 224b1b770b..68b9e6daf7 100644 --- a/activerecord/test/cases/adapters/postgresql/composite_test.rb +++ b/activerecord/test/cases/adapters/postgresql/composite_test.rb @@ -1,19 +1,19 @@ # -*- coding: utf-8 -*- require "cases/helper" +require 'support/connection_helper' require 'active_record/base' require 'active_record/connection_adapters/postgresql_adapter' -class PostgresqlCompositeTest < ActiveRecord::TestCase +module PostgresqlCompositeBehavior + include ConnectionHelper + class PostgresqlComposite < ActiveRecord::Base self.table_name = "postgresql_composites" end - teardown do - @connection.execute 'DROP TABLE IF EXISTS postgresql_composites' - @connection.execute 'DROP TYPE IF EXISTS full_address' - end - def setup + super + @connection = ActiveRecord::Base.connection @connection.transaction do @connection.execute <<-SQL @@ -29,9 +29,27 @@ class PostgresqlCompositeTest < ActiveRecord::TestCase end end + def teardown + super + + @connection.execute 'DROP TABLE IF EXISTS postgresql_composites' + @connection.execute 'DROP TYPE IF EXISTS full_address' + reset_connection + PostgresqlComposite.reset_column_information + end +end + +# Composites are mapped to `OID::Identity` by default. The user is informed by a warning like: +# "unknown OID 5653508: failed to recognize type of 'address'. It will be treated as String." +# To take full advantage of composite types, we suggest you register your own +OID::Type+. +# See PostgresqlCompositeWithCustomOIDTest +class PostgresqlCompositeTest < ActiveRecord::TestCase + include PostgresqlCompositeBehavior + def test_column + ensure_warning_is_issued + column = PostgresqlComposite.columns_hash["address"] - # TODO: Composite columns should have a type assert_nil column.type assert_equal "full_address", column.sql_type assert_not column.number? @@ -41,6 +59,8 @@ class PostgresqlCompositeTest < ActiveRecord::TestCase end def test_composite_mapping + ensure_warning_is_issued + @connection.execute "INSERT INTO postgresql_composites VALUES (1, ROW('Paris', 'Champs-Élysées'));" composite = PostgresqlComposite.first assert_equal "(Paris,Champs-Élysées)", composite.address @@ -50,4 +70,71 @@ class PostgresqlCompositeTest < ActiveRecord::TestCase assert_equal '(Paris,"Rue Basse")', composite.reload.address end + + private + def ensure_warning_is_issued + warning = capture(:stderr) do + PostgresqlComposite.columns_hash + end + assert_match(/unknown OID \d+: failed to recognize type of 'address'\. It will be treated as String\./, warning) + end +end + +class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::TestCase + include PostgresqlCompositeBehavior + + class FullAddressType + def type; :full_address end + def simplified_type(sql_type); type end + + def type_cast(value) + if value =~ /\("?([^",]*)"?,"?([^",]*)"?\)/ + FullAddress.new($1, $2) + end + end + + def type_cast_for_write(value) + "(#{value.city},#{value.street})" + end + end + + FullAddress = Struct.new(:city, :street) + + def setup + super + + @registration = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID + @registration.register_type "full_address", FullAddressType.new + end + + def teardown + super + + # there is currently no clean way to unregister a OID::Type + @registration::NAMES.delete("full_address") + end + + def test_column + column = PostgresqlComposite.columns_hash["address"] + assert_equal :full_address, column.type + assert_equal "full_address", column.sql_type + assert_not column.number? + assert_not column.text? + assert_not column.binary? + assert_not column.array + end + + def test_composite_mapping + @connection.execute "INSERT INTO postgresql_composites VALUES (1, ROW('Paris', 'Champs-Élysées'));" + composite = PostgresqlComposite.first + assert_equal "Paris", composite.address.city + assert_equal "Champs-Élysées", composite.address.street + + composite.address = FullAddress.new("Paris", "Rue Basse") + skip "Saving with custom OID type is currently not supported." + composite.save! + + assert_equal 'Paris', composite.reload.address.city + assert_equal 'Rue Basse', composite.reload.address.street + end end diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index e7dda1a1af..ea433d391f 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -1,4 +1,5 @@ require "cases/helper" +require 'support/ddl_helper' class PostgresqlArray < ActiveRecord::Base end @@ -37,9 +38,6 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase @connection = ActiveRecord::Base.connection @connection.execute("set lc_monetary = 'C'") - @connection.execute("INSERT INTO postgresql_arrays (id, commission_by_quarter, nicknames) VALUES (1, '{35000,21000,18000,17000}', '{foo,bar,baz}')") - @first_array = PostgresqlArray.find(1) - @connection.execute("INSERT INTO postgresql_tsvectors (id, text_vector) VALUES (1, ' ''text'' ''vector'' ')") @first_tsvector = PostgresqlTsvector.find(1) @@ -50,7 +48,11 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase @second_money = PostgresqlMoney.find(2) @connection.execute("INSERT INTO postgresql_numbers (id, single, double) VALUES (1, 123.456, 123456.789)") + @connection.execute("INSERT INTO postgresql_numbers (id, single, double) VALUES (2, '-Infinity', 'Infinity')") + @connection.execute("INSERT INTO postgresql_numbers (id, single, double) VALUES (3, 123.456, 'NaN')") @first_number = PostgresqlNumber.find(1) + @second_number = PostgresqlNumber.find(2) + @third_number = PostgresqlNumber.find(3) @connection.execute("INSERT INTO postgresql_times (id, time_interval, scaled_time_interval) VALUES (1, '1 year 2 days ago', '3 weeks ago')") @first_time = PostgresqlTime.find(1) @@ -68,23 +70,10 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase end teardown do - [PostgresqlArray, PostgresqlTsvector, PostgresqlMoney, PostgresqlNumber, PostgresqlTime, PostgresqlNetworkAddress, + [PostgresqlTsvector, PostgresqlMoney, PostgresqlNumber, PostgresqlTime, PostgresqlNetworkAddress, PostgresqlBitString, PostgresqlOid, PostgresqlTimestampWithZone].each(&:delete_all) end - def test_array_escaping - unknown = %(foo\\",bar,baz,\\) - nicknames = ["hello_#{unknown}"] - ar = PostgresqlArray.create!(nicknames: nicknames, id: 100) - ar.reload - assert_equal nicknames, ar.nicknames - end - - def test_data_type_of_array_types - assert_equal :integer, @first_array.column_for_attribute(:commission_by_quarter).type - assert_equal :text, @first_array.column_for_attribute(:nicknames).type - end - def test_data_type_of_tsvector_types assert_equal :tsvector, @first_tsvector.column_for_attribute(:text_vector).type end @@ -118,11 +107,6 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase assert_equal :integer, @first_oid.column_for_attribute(:obj_id).type end - def test_array_values - assert_equal [35000,21000,18000,17000], @first_array.commission_by_quarter - assert_equal ['foo','bar','baz'], @first_array.nicknames - end - def test_tsvector_values assert_equal "'text' 'vector'", @first_tsvector.text_vector end @@ -133,7 +117,7 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase end def test_money_type_cast - column = PostgresqlMoney.columns.find { |c| c.name == 'wealth' } + column = PostgresqlMoney.columns_hash['wealth'] assert_equal(12345678.12, column.type_cast("$12,345,678.12")) assert_equal(12345678.12, column.type_cast("$12.345.678,12")) assert_equal(-1.15, column.type_cast("-$1.15")) @@ -154,6 +138,9 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase def test_number_values assert_equal 123.456, @first_number.single assert_equal 123456.789, @first_number.double + assert_equal(-::Float::INFINITY, @second_number.single) + assert_equal ::Float::INFINITY, @second_number.double + assert_same ::Float::NAN, @third_number.double end def test_time_values @@ -179,30 +166,6 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase assert_equal 1234, @first_oid.obj_id end - def test_update_integer_array - new_value = [32800,95000,29350,17000] - @first_array.commission_by_quarter = new_value - assert @first_array.save - assert @first_array.reload - assert_equal new_value, @first_array.commission_by_quarter - @first_array.commission_by_quarter = new_value - assert @first_array.save - assert @first_array.reload - assert_equal new_value, @first_array.commission_by_quarter - end - - def test_update_text_array - new_value = ['robby','robert','rob','robbie'] - @first_array.nicknames = new_value - assert @first_array.save - assert @first_array.reload - assert_equal new_value, @first_array.nicknames - @first_array.nicknames = new_value - assert @first_array.save - assert @first_array.reload - assert_equal new_value, @first_array.nicknames - end - def test_update_money new_value = BigDecimal.new('123.45') @first_money.wealth = new_value @@ -308,3 +271,25 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase @connection.reconnect! end end + +class PostgresqlInternalDataTypeTest < ActiveRecord::TestCase + include DdlHelper + + setup do + @connection = ActiveRecord::Base.connection + end + + def test_name_column_type + with_example_table @connection, 'ex', 'data name' do + column = @connection.columns('ex').find { |col| col.name == 'data' } + assert_equal :string, column.type + end + end + + def test_char_column_type + with_example_table @connection, 'ex', 'data "char"' do + column = @connection.columns('ex').find { |col| col.name == 'data' } + assert_equal :string, column.type + end + end +end diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index c24c4b0d56..67a610b459 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -28,7 +28,7 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase t.hstore 'settings' end end - @column = Hstore.columns.find { |c| c.name == 'tags' } + @column = Hstore.columns_hash['tags'] end teardown do @@ -78,7 +78,7 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase t.hstore 'users', default: '' end Hstore.reset_column_information - column = Hstore.columns.find { |c| c.name == 'users' } + column = Hstore.columns_hash['users'] assert_equal :hstore, column.type raise ActiveRecord::Rollback # reset the schema change diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb index ee793ffff2..d25f8bf958 100644 --- a/activerecord/test/cases/adapters/postgresql/json_test.rb +++ b/activerecord/test/cases/adapters/postgresql/json_test.rb @@ -23,7 +23,7 @@ class PostgresqlJSONTest < ActiveRecord::TestCase rescue ActiveRecord::StatementInvalid skip "do not test on PG without json" end - @column = JsonDataType.columns.find { |c| c.name == 'payload' } + @column = JsonDataType.columns_hash['payload'] end teardown do @@ -57,7 +57,7 @@ class PostgresqlJSONTest < ActiveRecord::TestCase t.json 'users', default: '{}' end JsonDataType.reset_column_information - column = JsonDataType.columns.find { |c| c.name == 'users' } + column = JsonDataType.columns_hash['users'] assert_equal :json, column.type raise ActiveRecord::Rollback # reset the schema change diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 11ec7599a3..9d4d79c0c6 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -352,6 +352,21 @@ class SchemaTest < ActiveRecord::TestCase end end + def test_extract_schema_and_table + { + %(table_name) => [nil,'table_name'], + %("table.name") => [nil,'table.name'], + %(schema.table_name) => %w{schema table_name}, + %("schema".table_name) => %w{schema table_name}, + %(schema."table_name") => %w{schema table_name}, + %("schema"."table_name") => %w{schema table_name}, + %("even spaces".table) => ['even spaces','table'], + %(schema."table.name") => ['schema', 'table.name'] + }.each do |given, expect| + assert_equal expect, @connection.send(:extract_schema_and_table, given) + end + end + private def columns(table_name) @connection.send(:column_definitions, table_name).map do |name, type, default| diff --git a/activerecord/test/cases/adapters/postgresql/utils_test.rb b/activerecord/test/cases/adapters/postgresql/utils_test.rb deleted file mode 100644 index 9e7b08ef34..0000000000 --- a/activerecord/test/cases/adapters/postgresql/utils_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'cases/helper' - -class PostgreSQLUtilsTest < ActiveSupport::TestCase - include ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::Utils - - def test_extract_schema_and_table - { - %(table_name) => [nil,'table_name'], - %("table.name") => [nil,'table.name'], - %(schema.table_name) => %w{schema table_name}, - %("schema".table_name) => %w{schema table_name}, - %(schema."table_name") => %w{schema table_name}, - %("schema"."table_name") => %w{schema table_name}, - %("even spaces".table) => ['even spaces','table'], - %(schema."table.name") => ['schema', 'table.name'] - }.each do |given, expect| - assert_equal expect, extract_schema_and_table(given) - end - end -end diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb index ffce7c0d5f..40ed0f64a4 100644 --- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb +++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb @@ -43,13 +43,13 @@ class PostgresqlUUIDTest < ActiveRecord::TestCase def test_change_column_default @connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v1()" UUIDType.reset_column_information - column = UUIDType.columns.find { |c| c.name == 'thingy' } + column = UUIDType.columns_hash['thingy'] assert_equal "uuid_generate_v1()", column.default_function @connection.change_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v4()" UUIDType.reset_column_information - column = UUIDType.columns.find { |c| c.name == 'thingy' } + column = UUIDType.columns_hash['thingy'] assert_equal "uuid_generate_v4()", column.default_function ensure UUIDType.reset_column_information diff --git a/activerecord/test/cases/adapters/postgresql/xml_test.rb b/activerecord/test/cases/adapters/postgresql/xml_test.rb index ae299697b1..c1c85f8c92 100644 --- a/activerecord/test/cases/adapters/postgresql/xml_test.rb +++ b/activerecord/test/cases/adapters/postgresql/xml_test.rb @@ -20,7 +20,7 @@ class PostgresqlXMLTest < ActiveRecord::TestCase rescue ActiveRecord::StatementInvalid skip "do not test on PG without xml" end - @column = XmlDataType.columns.find { |c| c.name == 'payload' } + @column = XmlDataType.columns_hash['payload'] end teardown do 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 cfdfff6af9..878f1877db 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 @@ -22,6 +22,9 @@ require 'models/sponsor' require 'models/country' require 'models/treaty' require 'models/vertex' +require 'models/publisher' +require 'models/publisher/article' +require 'models/publisher/magazine' require 'active_support/core_ext/string/conversions' class ProjectWithAfterCreateHook < ActiveRecord::Base @@ -848,4 +851,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_custom_join_table assert_equal 'edges', Vertex.reflect_on_association(:sources).join_table end + + def test_namespaced_habtm + magazine = Publisher::Magazine.create + article = Publisher::Article.create + magazine.articles << article + magazine.save + + assert_includes magazine.articles, article + end end diff --git a/activerecord/test/cases/relation/merging_test.rb b/activerecord/test/cases/relation/merging_test.rb index 48f45d45b1..2b5c2fd5a4 100644 --- a/activerecord/test/cases/relation/merging_test.rb +++ b/activerecord/test/cases/relation/merging_test.rb @@ -108,6 +108,11 @@ class RelationMergingTest < ActiveRecord::TestCase merged = left.merge(right) assert_equal post, merged.first end + + def test_merging_compares_symbols_and_strings_as_equal + post = PostThatLoadsCommentsInAnAfterSaveHook.create!(title: "First Post", body: "Blah blah blah.") + assert_equal "First comment!", post.comments.where(body: "First comment!").first_or_create.body + end end class MergingDifferentRelationsTest < ActiveRecord::TestCase diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index 978cee9cfb..6a34c55011 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -163,6 +163,22 @@ class StoreTest < ActiveRecord::TestCase assert_equal [:width, :height], second_model.stored_attributes[:data] end + test "stored_attributes are tracked per subclass" do + first_model = Class.new(ActiveRecord::Base) do + store_accessor :data, :color + end + second_model = Class.new(first_model) do + store_accessor :data, :width, :height + end + third_model = Class.new(first_model) do + store_accessor :data, :area, :volume + end + + assert_equal [:color], first_model.stored_attributes[:data] + assert_equal [:color, :width, :height], second_model.stored_attributes[:data] + assert_equal [:color, :area, :volume], third_model.stored_attributes[:data] + end + test "YAML coder initializes the store when a Nil value is given" do assert_equal({}, @john.params) end diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index e6ed85394b..de1f624191 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -123,6 +123,19 @@ class TransactionTest < ActiveRecord::TestCase assert !Topic.find(1).approved? end + def test_rolling_back_in_a_callback_rollbacks_before_save + def @first.before_save_for_transaction + raise ActiveRecord::Rollback + end + assert !@first.approved + + Topic.transaction do + @first.approved = true + @first.save! + end + assert !Topic.find(@first.id).approved?, "Should not commit the approved flag" + end + def test_raising_exception_in_nested_transaction_restore_state_in_save topic = Topic.new diff --git a/activerecord/test/config.example.yml b/activerecord/test/config.example.yml index 479b8c050d..a54914c372 100644 --- a/activerecord/test/config.example.yml +++ b/activerecord/test/config.example.yml @@ -51,28 +51,6 @@ connections: password: arunit database: arunit2 - firebird: - arunit: - host: localhost - username: rails - password: rails - charset: UTF8 - arunit2: - host: localhost - username: rails - password: rails - charset: UTF8 - - frontbase: - arunit: - host: localhost - username: rails - session_name: unittest-<%= $$ %> - arunit2: - host: localhost - username: rails - session_name: unittest-<%= $$ %> - mysql: arunit: username: rails @@ -130,11 +108,3 @@ connections: arunit2: adapter: sqlite3 database: ':memory:' - - sybase: - arunit: - host: database_ASE - username: sa - arunit2: - host: database_ASE - username: sa diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb index f82df417ce..bf0162d09b 100644 --- a/activerecord/test/models/comment.rb +++ b/activerecord/test/models/comment.rb @@ -40,3 +40,11 @@ end class VerySpecialComment < Comment end + +class CommentThatAutomaticallyAltersPostBody < Comment + belongs_to :post, class_name: "PostThatLoadsCommentsInAnAfterSaveHook", foreign_key: :post_id + + after_save do |comment| + comment.post.update_attributes(body: "Automatically altered") + end +end diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index b1e56c14d1..5f01ab0a82 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -208,3 +208,12 @@ class SpecialPostWithDefaultScope < ActiveRecord::Base self.table_name = 'posts' default_scope { where(:id => [1, 5,6]) } end + +class PostThatLoadsCommentsInAnAfterSaveHook < ActiveRecord::Base + self.table_name = 'posts' + has_many :comments, class_name: "CommentThatAutomaticallyAltersPostBody", foreign_key: :post_id + + after_save do |post| + post.comments.load + end +end diff --git a/activerecord/test/models/publisher.rb b/activerecord/test/models/publisher.rb new file mode 100644 index 0000000000..0d4a7f9235 --- /dev/null +++ b/activerecord/test/models/publisher.rb @@ -0,0 +1,2 @@ +module Publisher +end diff --git a/activerecord/test/models/publisher/article.rb b/activerecord/test/models/publisher/article.rb new file mode 100644 index 0000000000..03a277bbdd --- /dev/null +++ b/activerecord/test/models/publisher/article.rb @@ -0,0 +1,3 @@ +class Publisher::Article < ActiveRecord::Base + has_and_belongs_to_many :magazines +end diff --git a/activerecord/test/models/publisher/magazine.rb b/activerecord/test/models/publisher/magazine.rb new file mode 100644 index 0000000000..82e1a14008 --- /dev/null +++ b/activerecord/test/models/publisher/magazine.rb @@ -0,0 +1,3 @@ +class Publisher::Magazine < ActiveRecord::Base + has_and_belongs_to_many :articles +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index da3074e90f..a78074d530 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -62,6 +62,14 @@ ActiveRecord::Schema.define do t.string :name end + create_table :articles, force: true do |t| + end + + create_table :articles_magazines, force: true do |t| + t.references :article + t.references :magazine + end + create_table :audit_logs, force: true do |t| t.column :message, :string, null: false t.column :developer_id, :integer, null: false @@ -385,6 +393,9 @@ ActiveRecord::Schema.define do t.column :custom_lock_version, :integer end + create_table :magazines, force: true do |t| + end + create_table :mateys, id: false, force: true do |t| t.column :pirate_id, :integer t.column :target_id, :integer |