diff options
Diffstat (limited to 'activerecord/test')
51 files changed, 639 insertions, 222 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb index ff553c3f1a..fa7bebf08b 100644 --- a/activerecord/test/cases/adapters/postgresql/array_test.rb +++ b/activerecord/test/cases/adapters/postgresql/array_test.rb @@ -254,6 +254,15 @@ class PostgresqlArrayTest < ActiveRecord::TestCase end end + def test_assigning_non_array_value + record = PgArray.new(tags: "not-an-array") + assert_equal "not-an-array", record.tags + e = assert_raises(ActiveRecord::StatementInvalid) do + record.save! + end + assert_instance_of PG::InvalidTextRepresentation, e.original_exception + 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 7872f91943..aeebec034d 100644 --- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb +++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb @@ -17,7 +17,6 @@ class PostgresqlByteaTest < ActiveRecord::TestCase end end @column = ByteaDataType.columns_hash['payload'] - assert(@column.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLColumn)) end teardown do @@ -25,9 +24,17 @@ class PostgresqlByteaTest < ActiveRecord::TestCase end def test_column + assert @column.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLColumn) assert_equal :binary, @column.type end + def test_binary_columns_are_limitless_the_upper_limit_is_one_GB + assert_equal 'bytea', @connection.type_to_sql(:binary, 100_000) + assert_raise ActiveRecord::ActiveRecordError do + @connection.type_to_sql :binary, 4294967295 + end + end + def test_type_cast_binary_converts_the_encoding assert @column diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index a0a34e4b87..2c4839338c 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -94,6 +94,13 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase assert @first_oid.reload assert_equal new_value, @first_oid.obj_id end + + def test_text_columns_are_limitless_the_upper_limit_is_one_GB + assert_equal 'text', @connection.type_to_sql(:text, 100_000) + assert_raise ActiveRecord::ActiveRecordError do + @connection.type_to_sql :text, 4294967295 + end + end end class PostgresqlInternalDataTypeTest < ActiveRecord::TestCase diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb index d99c4a292e..83cedc5a7b 100644 --- a/activerecord/test/cases/adapters/postgresql/enum_test.rb +++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- require "cases/helper" require 'support/connection_helper' -require 'active_record/base' -require 'active_record/connection_adapters/postgresql_adapter' class PostgresqlEnumTest < ActiveRecord::TestCase include ConnectionHelper diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index 1296eb72c0..6a9c6483fe 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -1,41 +1,38 @@ # encoding: utf-8 - require "cases/helper" -require 'active_record/base' -require 'active_record/connection_adapters/postgresql_adapter' -class PostgresqlHstoreTest < ActiveRecord::TestCase - class Hstore < ActiveRecord::Base - self.table_name = 'hstores' +if ActiveRecord::Base.connection.supports_extensions? + class PostgresqlHstoreTest < ActiveRecord::TestCase + class Hstore < ActiveRecord::Base + self.table_name = 'hstores' - store_accessor :settings, :language, :timezone - end + store_accessor :settings, :language, :timezone + end - def setup - @connection = ActiveRecord::Base.connection + def setup + @connection = ActiveRecord::Base.connection - unless @connection.extension_enabled?('hstore') - @connection.enable_extension 'hstore' - @connection.commit_db_transaction - end + unless @connection.extension_enabled?('hstore') + @connection.enable_extension 'hstore' + @connection.commit_db_transaction + end - @connection.reconnect! + @connection.reconnect! - @connection.transaction do - @connection.create_table('hstores') do |t| - t.hstore 'tags', :default => '' - t.hstore 'payload', array: true - t.hstore 'settings' + @connection.transaction do + @connection.create_table('hstores') do |t| + t.hstore 'tags', :default => '' + t.hstore 'payload', array: true + t.hstore 'settings' + end end + @column = Hstore.columns_hash['tags'] end - @column = Hstore.columns_hash['tags'] - end - teardown do - @connection.execute 'drop table if exists hstores' - end + teardown do + @connection.execute 'drop table if exists hstores' + end - if ActiveRecord::Base.connection.supports_extensions? def test_hstore_included_in_extensions assert @connection.respond_to?(:extensions), "connection should have a list of extensions" assert @connection.extensions.include?('hstore'), "extension list should include hstore" @@ -315,10 +312,8 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase dupe = record.dup assert_equal({"one" => "two"}, dupe.tags.to_hash) end - end - - private + private def assert_array_cycle(array) # test creation x = Hstore.create!(payload: array) @@ -346,4 +341,5 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase x.reload assert_equal(hash, x.tags) end + end end diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb index 86ba849445..340ca29c0e 100644 --- a/activerecord/test/cases/adapters/postgresql/json_test.rb +++ b/activerecord/test/cases/adapters/postgresql/json_test.rb @@ -1,10 +1,10 @@ # encoding: utf-8 - require "cases/helper" -require 'active_record/base' -require 'active_record/connection_adapters/postgresql_adapter' +require 'support/schema_dumping_helper' module PostgresqlJSONSharedTestCases + include SchemaDumpingHelper + class JsonDataType < ActiveRecord::Base self.table_name = 'json_data_type' @@ -64,6 +64,11 @@ module PostgresqlJSONSharedTestCases JsonDataType.reset_column_information end + def test_schema_dumping + output = dump_table_schema("json_data_type") + assert_match(/t.#{column_type.to_s}\s+"payload",\s+default: {}/, output) + end + def test_cast_value_on_write x = JsonDataType.new payload: {"string" => "foo", :symbol => :bar} assert_equal({"string" => "foo", :symbol => :bar}, x.payload_before_type_cast) diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 6f40b0d2de..350cb3e065 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -388,6 +388,14 @@ class SchemaTest < ActiveRecord::TestCase assert_equal "1", @connection.select_value("SELECT nextval('#{sequence_name}')") end + def test_set_pk_sequence + table_name = "#{SCHEMA_NAME}.#{PK_TABLE_NAME}" + _, sequence_name = @connection.pk_and_sequence_for table_name + @connection.set_pk_sequence! table_name, 123 + assert_equal "124", @connection.select_value("SELECT nextval('#{sequence_name}')") + @connection.reset_pk_sequence! table_name + 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/sql_types_test.rb b/activerecord/test/cases/adapters/postgresql/sql_types_test.rb deleted file mode 100644 index d7d40f6385..0000000000 --- a/activerecord/test/cases/adapters/postgresql/sql_types_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -require "cases/helper" - -class SqlTypesTest < ActiveRecord::TestCase - def test_binary_types - assert_equal 'bytea', type_to_sql(:binary, 100_000) - assert_raise ActiveRecord::ActiveRecordError do - type_to_sql :binary, 4294967295 - end - assert_equal 'text', type_to_sql(:text, 100_000) - assert_raise ActiveRecord::ActiveRecordError do - type_to_sql :text, 4294967295 - end - end - - def type_to_sql(*args) - ActiveRecord::Base.connection.type_to_sql(*args) - end -end diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb index ae5b409f99..5753da1173 100644 --- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb +++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb @@ -1,8 +1,6 @@ # encoding: utf-8 - require "cases/helper" -require 'active_record/base' -require 'active_record/connection_adapters/postgresql_adapter' +require 'support/schema_dumping_helper' module PostgresqlUUIDHelper def connection @@ -110,8 +108,29 @@ class PostgresqlUUIDTest < ActiveRecord::TestCase end end +class PostgresqlLargeKeysTest < ActiveRecord::TestCase + include PostgresqlUUIDHelper + include SchemaDumpingHelper + + def setup + connection.create_table('big_serials', id: :bigserial) do |t| + t.string 'name' + end + end + + def test_omg + schema = dump_table_schema "big_serials" + assert_match "create_table \"big_serials\", id: :bigserial, force: true", schema + end + + def teardown + drop_table "big_serials" + end +end + class PostgresqlUUIDGenerationTest < ActiveRecord::TestCase include PostgresqlUUIDHelper + include SchemaDumpingHelper class UUID < ActiveRecord::Base self.table_name = 'pg_uuids' @@ -171,17 +190,15 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::TestCase end def test_schema_dumper_for_uuid_primary_key - schema = StringIO.new - ActiveRecord::SchemaDumper.dump(connection, schema) - assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: "uuid_generate_v1\(\)"/, schema.string) - assert_match(/t\.uuid "other_uuid", default: "uuid_generate_v4\(\)"/, schema.string) + schema = dump_table_schema "pg_uuids" + assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: "uuid_generate_v1\(\)"/, schema) + assert_match(/t\.uuid "other_uuid", default: "uuid_generate_v4\(\)"/, schema) end def test_schema_dumper_for_uuid_primary_key_with_custom_default - schema = StringIO.new - ActiveRecord::SchemaDumper.dump(connection, schema) - assert_match(/\bcreate_table "pg_uuids_2", id: :uuid, default: "my_uuid_generator\(\)"/, schema.string) - assert_match(/t\.uuid "other_uuid_2", default: "my_uuid_generator\(\)"/, schema.string) + schema = dump_table_schema "pg_uuids_2" + assert_match(/\bcreate_table "pg_uuids_2", id: :uuid, default: "my_uuid_generator\(\)"/, schema) + assert_match(/t\.uuid "other_uuid_2", default: "my_uuid_generator\(\)"/, schema) end 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 25555bd75c..bcd0cf82d5 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -57,6 +57,35 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end end + def test_default_scope_on_relations_is_not_cached + counter = 0 + + comments = Class.new(ActiveRecord::Base) { + self.table_name = 'comments' + self.inheritance_column = 'not_there' + + posts = Class.new(ActiveRecord::Base) { + self.table_name = 'posts' + self.inheritance_column = 'not_there' + + default_scope -> { + counter += 1 + where("id = :inc", :inc => counter) + } + + has_many :comments, :class => comments + } + belongs_to :post, :class => posts, :inverse_of => false + } + + assert_equal 0, counter + comment = comments.first + assert_equal 0, counter + sql = capture_sql { comment.post } + comment.reload + assert_not_equal sql, capture_sql { comment.post } + end + def test_proxy_assignment account = Account.find(1) assert_nothing_raised { account.firm = account.firm } diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index b852bd3536..8234ee95be 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -935,6 +935,42 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal 3, authors(:david).posts_with_comments.where("length(comments.body) > 15").references(:comments).count end + def test_association_loading_notification + notifications = messages_for('instantiation.active_record') do + Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size + end + + message = notifications.first + payload = message.last + count = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size + + # eagerloaded row count should be greater than just developer count + assert_operator payload[:record_count], :>, count + assert_equal Developer.name, payload[:class_name] + end + + def test_base_messages + notifications = messages_for('instantiation.active_record') do + Developer.all.to_a + end + message = notifications.first + payload = message.last + + assert_equal Developer.all.to_a.count, payload[:record_count] + assert_equal Developer.name, payload[:class_name] + end + + def messages_for(name) + notifications = [] + ActiveSupport::Notifications.subscribe(name) do |*args| + notifications << args + end + yield + notifications + ensure + ActiveSupport::Notifications.unsubscribe(name) + end + def test_load_with_sti_sharing_association assert_queries(2) do #should not do 1 query per subclass Comment.includes(:post).to_a 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 859310575e..9a57683ee3 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 @@ -1,5 +1,6 @@ require "cases/helper" require 'models/developer' +require 'models/computer' require 'models/project' require 'models/company' require 'models/customer' @@ -80,7 +81,7 @@ end class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects, - :parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings + :parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings, :computers def setup_data_for_habtm_case ActiveRecord::Base.connection.execute('delete from countries_treaties') @@ -883,4 +884,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase child.special_projects << SpecialProject.new("name" => "Special Project") assert child.save, 'child object should be saved' end + + def test_habtm_with_reflection_using_class_name_and_fixtures + assert_not_nil Developer._reflections['shared_computers'] + # Checking the fixture for named association is important here, because it's the only way + # we've been able to reproduce this bug + assert_not_nil File.read(File.expand_path("../../../fixtures/developers.yml", __FILE__)).index("shared_computers") + assert_equal developers(:david).shared_computers.first, computers(:laptop) + 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 c72d9342a9..69f7bde4bc 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -76,6 +76,32 @@ class HasManyAssociationsTest < ActiveRecord::TestCase dev.developer_projects.map(&:project_id).sort end + def test_default_scope_on_relations_is_not_cached + counter = 0 + posts = Class.new(ActiveRecord::Base) { + self.table_name = 'posts' + self.inheritance_column = 'not_there' + post = self + + comments = Class.new(ActiveRecord::Base) { + self.table_name = 'comments' + self.inheritance_column = 'not_there' + belongs_to :post, :class => post + default_scope -> { + counter += 1 + where("id = :inc", :inc => counter) + } + } + has_many :comments, :class => comments, :foreign_key => 'post_id' + } + assert_equal 0, counter + post = posts.first + assert_equal 0, counter + sql = capture_sql { post.comments.to_a } + post.comments.reset + assert_not_equal sql, capture_sql { post.comments.to_a } + end + def test_has_many_build_with_options college = College.create(name: 'UFMT') Student.create(active: true, college_id: college.id, name: 'Sarah') @@ -1902,6 +1928,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal [bulb1, bulb2], car.all_bulbs.sort_by(&:id) end + test 'unscopes the default scope of associated model when used with include' do + car = Car.create! + bulb = Bulb.create! name: "other", car: car + + assert_equal bulb, Car.find(car.id).all_bulbs.first + assert_equal bulb, Car.includes(:all_bulbs).find(car.id).all_bulbs.first + end + test "raises RecordNotDestroyed when replaced child can't be destroyed" do car = Car.create! original_child = FailedBulb.create!(car: car) 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 089cb0a3a2..19d1aa87a8 100644 --- a/activerecord/test/cases/associations/has_one_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb @@ -289,6 +289,12 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end end + def test_has_one_through_polymorphic_association + assert_raise(ActiveRecord::HasOneAssociationPolymorphicThroughError) do + @member.premium_club + end + end + def test_has_one_through_belongs_to_should_update_when_the_through_foreign_key_changes minivan = minivans(:cool_first) diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 7ca7349528..c3e8ceb0da 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -736,11 +736,11 @@ class AttributeMethodsTest < ActiveRecord::TestCase def test_bulk_update_raise_unknown_attribute_error error = assert_raises(ActiveRecord::UnknownAttributeError) { - @target.new(:hello => "world") + Topic.new(hello: "world") } - assert_instance_of @target, error.record + assert_instance_of Topic, error.record assert_equal "hello", error.attribute - assert_equal "unknown attribute: hello", error.message + assert_equal "unknown attribute 'hello' for Topic.", error.message end def test_methods_override_in_multi_level_subclass diff --git a/activerecord/test/cases/attributes_test.rb b/activerecord/test/cases/attributes_test.rb index 79ef0502cb..dbe1eb48db 100644 --- a/activerecord/test/cases/attributes_test.rb +++ b/activerecord/test/cases/attributes_test.rb @@ -20,7 +20,7 @@ end module ActiveRecord class CustomPropertiesTest < ActiveRecord::TestCase - def test_overloading_types + test "overloading types" do data = OverloadedType.new data.overloaded_float = "1.1" @@ -30,7 +30,7 @@ module ActiveRecord assert_equal 1.1, data.unoverloaded_float end - def test_overloaded_properties_save + test "overloaded properties save" do data = OverloadedType.new data.overloaded_float = "2.2" @@ -43,18 +43,18 @@ module ActiveRecord assert_kind_of Float, UnoverloadedType.last.overloaded_float end - def test_properties_assigned_in_constructor + test "properties assigned in constructor" do data = OverloadedType.new(overloaded_float: '3.3') assert_equal 3, data.overloaded_float end - def test_overloaded_properties_with_limit + test "overloaded properties with limit" do assert_equal 50, OverloadedType.columns_hash['overloaded_string_with_limit'].limit assert_equal 255, UnoverloadedType.columns_hash['overloaded_string_with_limit'].limit end - def test_nonexistent_attribute + test "nonexistent attribute" do data = OverloadedType.new(non_existent_decimal: 1) assert_equal BigDecimal.new(1), data.non_existent_decimal @@ -63,7 +63,7 @@ module ActiveRecord end end - def test_changing_defaults + test "changing defaults" do data = OverloadedType.new unoverloaded_data = UnoverloadedType.new @@ -71,24 +71,28 @@ module ActiveRecord assert_equal 'the original default', unoverloaded_data.string_with_default end - def test_children_inherit_custom_properties + test "defaults are not touched on the columns" do + assert_equal 'the original default', OverloadedType.columns_hash['string_with_default'].default + end + + test "children inherit custom properties" do data = ChildOfOverloadedType.new(overloaded_float: '4.4') assert_equal 4, data.overloaded_float end - def test_children_can_override_parents + test "children can override parents" do data = GrandchildOfOverloadedType.new(overloaded_float: '4.4') assert_equal 4.4, data.overloaded_float end - def test_overloading_properties_does_not_change_column_order + test "overloading properties does not change column order" do column_names = OverloadedType.column_names assert_equal %w(id overloaded_float unoverloaded_float overloaded_string_with_limit string_with_default non_existent_decimal), column_names end - def test_caches_are_cleared + test "caches are cleared" do klass = Class.new(OverloadedType) assert_equal 6, klass.columns.length diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index b2a7d3956d..734fd5fe18 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -1,5 +1,6 @@ require 'cases/helper' require 'models/bird' +require 'models/comment' require 'models/company' require 'models/customer' require 'models/developer' @@ -616,6 +617,14 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase firm.save! assert !account.persisted? end + + def test_autosave_new_record_with_after_create_callback + post = PostWithAfterCreateCallback.new(title: 'Captain Murphy', body: 'is back') + post.comments.build(body: 'foo') + post.save! + + assert_not_nil post.author_id + end end class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index fb535e74fc..3675401555 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -522,6 +522,10 @@ class BasicsTest < ActiveRecord::TestCase assert_equal Topic.find(['1-meowmeow', '2-hello']), Topic.find([1, 2]) end + def test_find_by_slug_with_range + assert_equal Topic.where(id: '1-meowmeow'..'2-hello'), Topic.where(id: 1..2) + end + def test_equality_of_new_records assert_not_equal Topic.new, Topic.new assert_equal false, Topic.new == Topic.new @@ -985,7 +989,6 @@ class BasicsTest < ActiveRecord::TestCase class NumericData < ActiveRecord::Base self.table_name = 'numeric_data' - attribute :world_population, Type::Integer.new attribute :my_house_population, Type::Integer.new attribute :atoms_in_universe, Type::Integer.new end @@ -1383,7 +1386,10 @@ class BasicsTest < ActiveRecord::TestCase c1 = Post.connection.schema_cache.columns('posts') ActiveRecord::Base.clear_cache! c2 = Post.connection.schema_cache.columns('posts') - assert_not_equal c1, c2 + c1.each_with_index do |v, i| + assert_not_same v, c2[i] + end + assert_equal c1, c2 end def test_current_scope_is_reset diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index ec6a319ab5..e886268a72 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -461,7 +461,6 @@ class CalculationsTest < ActiveRecord::TestCase assert_equal 7, Company.includes(:contracts).sum(:developer_id) end - def test_from_option_with_specified_index if Edge.connection.adapter_name == 'MySQL' or Edge.connection.adapter_name == 'Mysql2' assert_equal Edge.count(:all), Edge.from('edges USE INDEX(unique_edge_index)').count(:all) diff --git a/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb b/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb index e1b2804a18..37ad469476 100644 --- a/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +++ b/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb @@ -5,10 +5,14 @@ module ActiveRecord class MergeAndResolveDefaultUrlConfigTest < ActiveRecord::TestCase def setup @previous_database_url = ENV.delete("DATABASE_URL") + @previous_rack_env = ENV.delete("RACK_ENV") + @previous_rails_env = ENV.delete("RAILS_ENV") end teardown do ENV["DATABASE_URL"] = @previous_database_url + ENV["RACK_ENV"] = @previous_rack_env + ENV["RAILS_ENV"] = @previous_rails_env end def resolve_config(config) @@ -27,6 +31,26 @@ module ActiveRecord assert_equal expected, actual end + def test_resolver_with_database_uri_and_current_env_symbol_key_and_rails_env + ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV['RAILS_ENV'] = "foo" + + config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } + actual = resolve_spec(:foo, config) + expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" } + assert_equal expected, actual + end + + def test_resolver_with_database_uri_and_current_env_symbol_key_and_rack_env + ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV['RACK_ENV'] = "foo" + + config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } + actual = resolve_spec(:foo, config) + expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" } + assert_equal expected, actual + end + def test_resolver_with_database_uri_and_and_current_env_string_key ENV['DATABASE_URL'] = "postgres://localhost/foo" config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } } @@ -35,6 +59,26 @@ module ActiveRecord assert_equal expected, actual end + def test_resolver_with_database_uri_and_and_current_env_string_key_and_rails_env + ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV['RAILS_ENV'] = "foo" + + config = { "not_production" => {"adapter" => "not_postgres", "database" => "not_foo" } } + actual = assert_deprecated { resolve_spec("foo", config) } + expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" } + assert_equal expected, actual + end + + def test_resolver_with_database_uri_and_and_current_env_string_key_and_rack_env + ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV['RACK_ENV'] = "foo" + + config = { "not_production" => {"adapter" => "not_postgres", "database" => "not_foo" } } + actual = assert_deprecated { resolve_spec("foo", config) } + expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" } + assert_equal expected, actual + end + def test_resolver_with_database_uri_and_known_key ENV['DATABASE_URL'] = "postgres://localhost/foo" config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } } @@ -139,6 +183,51 @@ module ActiveRecord assert_equal nil, actual["production"] assert_equal nil, actual["development"] assert_equal nil, actual["test"] + assert_equal nil, actual[:default_env] + assert_equal nil, actual[:production] + assert_equal nil, actual[:development] + assert_equal nil, actual[:test] + end + + def test_blank_with_database_url_with_rails_env + ENV['RAILS_ENV'] = "not_production" + ENV['DATABASE_URL'] = "postgres://localhost/foo" + + config = {} + actual = resolve_config(config) + expected = { "adapter" => "postgresql", + "database" => "foo", + "host" => "localhost" } + + assert_equal expected, actual["not_production"] + assert_equal nil, actual["production"] + assert_equal nil, actual["default_env"] + assert_equal nil, actual["development"] + assert_equal nil, actual["test"] + assert_equal nil, actual[:default_env] + assert_equal nil, actual[:not_production] + assert_equal nil, actual[:production] + assert_equal nil, actual[:development] + assert_equal nil, actual[:test] + end + + def test_blank_with_database_url_with_rack_env + ENV['RACK_ENV'] = "not_production" + ENV['DATABASE_URL'] = "postgres://localhost/foo" + + config = {} + actual = resolve_config(config) + expected = { "adapter" => "postgresql", + "database" => "foo", + "host" => "localhost" } + + assert_equal expected, actual["not_production"] + assert_equal nil, actual["production"] + assert_equal nil, actual["default_env"] + assert_equal nil, actual["development"] + assert_equal nil, actual["test"] + assert_equal nil, actual[:default_env] + assert_equal nil, actual[:not_production] assert_equal nil, actual[:production] assert_equal nil, actual[:development] assert_equal nil, actual[:test] diff --git a/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb b/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb index d4d67487db..80244d1439 100644 --- a/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb +++ b/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb @@ -22,6 +22,10 @@ module ActiveRecord assert_lookup_type :string, "SET('one', 'two', 'three')" end + def test_enum_type_with_value_matching_other_type + assert_lookup_type :string, "ENUM('unicode', '8bit', 'none')" + end + def test_binary_types assert_lookup_type :binary, 'bit' assert_lookup_type :binary, 'BIT' diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index ac570ecbe0..dc73faa5be 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -99,21 +99,10 @@ class FinderTest < ActiveRecord::TestCase end def test_exists_fails_when_parameter_has_invalid_type - if current_adapter?(:PostgreSQLAdapter, :MysqlAdapter) - assert_raises ActiveRecord::StatementInvalid do - Topic.exists?(("9"*53).to_i) # number that's bigger than int - end - else + assert_raises(RangeError) do assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int end - - if current_adapter?(:PostgreSQLAdapter) - assert_raises ActiveRecord::StatementInvalid do - Topic.exists?("foo") - end - else - assert_equal false, Topic.exists?("foo") - end + assert_equal false, Topic.exists?("foo") end def test_exists_does_not_select_columns_without_alias @@ -209,6 +198,28 @@ class FinderTest < ActiveRecord::TestCase assert_equal 2, last_devs.size end + def test_find_with_large_number + assert_raises(ActiveRecord::RecordNotFound) { Topic.find('9999999999999999999999999999999') } + end + + def test_find_by_with_large_number + assert_nil Topic.find_by(id: '9999999999999999999999999999999') + end + + def test_find_by_id_with_large_number + assert_nil Topic.find_by_id('9999999999999999999999999999999') + end + + def test_find_on_relation_with_large_number + assert_nil Topic.where('1=1').find_by(id: 9999999999999999999999999999999) + end + + def test_find_by_bang_on_relation_with_large_number + assert_raises(ActiveRecord::RecordNotFound) do + Topic.where('1=1').find_by!(id: 9999999999999999999999999999999) + end + end + def test_find_an_empty_array assert_equal [], Topic.find([]) end diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index 1050047a43..7141d3ee7f 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -822,25 +822,6 @@ class ActiveSupportSubclassWithFixturesTest < ActiveRecord::TestCase end end -class FixtureLoadingTest < ActiveRecord::TestCase - def test_logs_message_for_failed_dependency_load - ActiveRecord::Base.logger.expects(:warn).twice - ActiveRecord::TestCase.try_to_load_dependency('does_not_exist') - end - - def test_does_not_logs_message_for_dependency_that_has_been_defined_with_set_fixture_class - ActiveRecord::TestCase.set_fixture_class unknown_dead_parrots: DeadParrot - ActiveRecord::Base.logger.expects(:warn).never - ActiveRecord::TestCase.try_to_load_dependency('unknown_dead_parrot') - end - - def test_does_not_logs_message_for_successful_dependency_load - ActiveRecord::TestCase.expects(:require_dependency).with('works_out_fine') - ActiveRecord::Base.logger.expects(:warn).never - ActiveRecord::TestCase.try_to_load_dependency('works_out_fine') - end -end - class CustomNameForFixtureOrModelTest < ActiveRecord::TestCase ActiveRecord::FixtureSet.reset_cache diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index be635aeef9..80ac57ec7c 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -95,7 +95,7 @@ EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES = false def verify_default_timezone_config if Time.zone != EXPECTED_ZONE $stderr.puts <<-MSG -\n#{self.to_s} +\n#{self} Global state `Time.zone` was leaked. Expected: #{EXPECTED_ZONE} Got: #{Time.zone} @@ -103,7 +103,7 @@ def verify_default_timezone_config end if ActiveRecord::Base.default_timezone != EXPECTED_DEFAULT_TIMEZONE $stderr.puts <<-MSG -\n#{self.to_s} +\n#{self} Global state `ActiveRecord::Base.default_timezone` was leaked. Expected: #{EXPECTED_DEFAULT_TIMEZONE} Got: #{ActiveRecord::Base.default_timezone} @@ -111,7 +111,7 @@ def verify_default_timezone_config end if ActiveRecord::Base.time_zone_aware_attributes != EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES $stderr.puts <<-MSG -\n#{self.to_s} +\n#{self} Global state `ActiveRecord::Base.time_zone_aware_attributes` was leaked. Expected: #{EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES} Got: #{ActiveRecord::Base.time_zone_aware_attributes} @@ -136,19 +136,6 @@ def disable_extension!(extension, connection) connection.reconnect! end -unless ENV['FIXTURE_DEBUG'] - module ActiveRecord::TestFixtures::ClassMethods - def try_to_load_dependency_with_silence(*args) - old = ActiveRecord::Base.logger.level - ActiveRecord::Base.logger.level = ActiveSupport::Logger::ERROR - try_to_load_dependency_without_silence(*args) - ActiveRecord::Base.logger.level = old - end - - alias_method_chain :try_to_load_dependency, :silence - end -end - require "cases/validations_repair_helper" class ActiveSupport::TestCase include ActiveRecord::TestFixtures diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb index bd3dd29f4d..d91e7142b3 100644 --- a/activerecord/test/cases/migration/change_schema_test.rb +++ b/activerecord/test/cases/migration/change_schema_test.rb @@ -97,6 +97,25 @@ module ActiveRecord end end + def test_create_table_with_bigint + connection.create_table :testings do |t| + t.bigint :eight_int + end + columns = connection.columns(:testings) + eight = columns.detect { |c| c.name == "eight_int" } + + if current_adapter?(:OracleAdapter) + assert_equal 'NUMBER(8)', eight.sql_type + elsif current_adapter?(:SQLite3Adapter) + assert_equal 'bigint', eight.sql_type + else + assert_equal :integer, eight.type + assert_equal 8, eight.limit + end + ensure + connection.drop_table :testings + end + def test_create_table_with_limits connection.create_table :testings do |t| t.column :foo, :string, :limit => 255 diff --git a/activerecord/test/cases/migration/references_index_test.rb b/activerecord/test/cases/migration/references_index_test.rb index 4485701a4e..ad6b828d0b 100644 --- a/activerecord/test/cases/migration/references_index_test.rb +++ b/activerecord/test/cases/migration/references_index_test.rb @@ -55,7 +55,7 @@ module ActiveRecord t.references :foo, :polymorphic => true, :index => true end - assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type) + assert connection.index_exists?(table_name, [:foo_type, :foo_id], name: :index_testings_on_foo_type_and_foo_id) end end @@ -93,7 +93,7 @@ module ActiveRecord t.references :foo, :polymorphic => true, :index => true end - assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type) + assert connection.index_exists?(table_name, [:foo_type, :foo_id], name: :index_testings_on_foo_type_and_foo_id) end end end diff --git a/activerecord/test/cases/migration/references_statements_test.rb b/activerecord/test/cases/migration/references_statements_test.rb index b8b4fa1135..988bd9c89f 100644 --- a/activerecord/test/cases/migration/references_statements_test.rb +++ b/activerecord/test/cases/migration/references_statements_test.rb @@ -42,7 +42,7 @@ module ActiveRecord def test_creates_polymorphic_index add_reference table_name, :taggable, polymorphic: true, index: true - assert index_exists?(table_name, [:taggable_id, :taggable_type]) + assert index_exists?(table_name, [:taggable_type, :taggable_id]) end def test_creates_reference_type_column_with_default diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 270e446c69..6b7a0a9000 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -15,7 +15,6 @@ class BigNumber < ActiveRecord::Base unless current_adapter?(:PostgreSQLAdapter, :SQLite3Adapter) attribute :value_of_e, Type::Integer.new end - attribute :world_population, Type::Integer.new attribute :my_house_population, Type::Integer.new end @@ -101,6 +100,19 @@ class MigrationTest < ActiveRecord::TestCase ActiveRecord::Migrator.migrations_paths = old_path end + def test_any_migrations + old_path = ActiveRecord::Migrator.migrations_paths + ActiveRecord::Migrator.migrations_paths = MIGRATIONS_ROOT + "/valid" + + assert ActiveRecord::Migrator.any_migrations? + + ActiveRecord::Migrator.migrations_paths = MIGRATIONS_ROOT + "/empty" + + assert_not ActiveRecord::Migrator.any_migrations? + ensure + ActiveRecord::Migrator.migrations_paths = old_path + end + def test_migration_version ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/version_check", 20131219224947) end diff --git a/activerecord/test/cases/migrator_test.rb b/activerecord/test/cases/migrator_test.rb index 9809d83315..f05ca900aa 100644 --- a/activerecord/test/cases/migrator_test.rb +++ b/activerecord/test/cases/migrator_test.rb @@ -357,11 +357,11 @@ class MigratorTest < ActiveRecord::TestCase end private - def m(name, version, &block) + def m(name, version) x = Sensor.new name, version x.extend(Module.new { - define_method(:up) { block.call(:up, x); super() } - define_method(:down) { block.call(:down, x); super() } + define_method(:up) { yield(:up, x); super() } + define_method(:down) { yield(:down, x); super() } }) if block_given? end diff --git a/activerecord/test/cases/readonly_test.rb b/activerecord/test/cases/readonly_test.rb index 2afd25c989..5b903e4f2c 100644 --- a/activerecord/test/cases/readonly_test.rb +++ b/activerecord/test/cases/readonly_test.rb @@ -22,9 +22,15 @@ class ReadOnlyTest < ActiveRecord::TestCase assert !dev.save dev.name = 'Forbidden.' end - assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save } - assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save! } - assert_raise(ActiveRecord::ReadOnlyRecord) { dev.destroy } + + e = assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save } + assert_equal "Developer is marked as readonly", e.message + + e = assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save! } + assert_equal "Developer is marked as readonly", e.message + + e = assert_raise(ActiveRecord::ReadOnlyRecord) { dev.destroy } + assert_equal "Developer is marked as readonly", e.message end diff --git a/activerecord/test/cases/relation/where_chain_test.rb b/activerecord/test/cases/relation/where_chain_test.rb index b9e69bdb08..619055f1e7 100644 --- a/activerecord/test/cases/relation/where_chain_test.rb +++ b/activerecord/test/cases/relation/where_chain_test.rb @@ -149,5 +149,33 @@ module ActiveRecord assert_bound_ast value, Post.arel_table['title'], Arel::Nodes::Equality assert_equal 'alone', bind.last end + + def test_rewhere_with_range + relation = Post.where(comments_count: 1..3).rewhere(comments_count: 3..5) + + assert_equal 1, relation.where_values.size + assert_equal Post.where(comments_count: 3..5), relation + end + + def test_rewhere_with_infinite_upper_bound_range + relation = Post.where(comments_count: 1..Float::INFINITY).rewhere(comments_count: 3..5) + + assert_equal 1, relation.where_values.size + assert_equal Post.where(comments_count: 3..5), relation + end + + def test_rewhere_with_infinite_lower_bound_range + relation = Post.where(comments_count: -Float::INFINITY..1).rewhere(comments_count: 3..5) + + assert_equal 1, relation.where_values.size + assert_equal Post.where(comments_count: 3..5), relation + end + + def test_rewhere_with_infinite_range + relation = Post.where(comments_count: -Float::INFINITY..Float::INFINITY).rewhere(comments_count: 3..5) + + assert_equal 1, relation.where_values.size + assert_equal Post.where(comments_count: 3..5), relation + end end end diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index 39c8afdd23..a453203e15 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -7,6 +7,7 @@ require 'models/comment' require 'models/edge' require 'models/topic' require 'models/binary' +require 'models/vertex' module ActiveRecord class WhereTest < ActiveRecord::TestCase diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb index d6decafad9..dec01dfa76 100644 --- a/activerecord/test/cases/result_test.rb +++ b/activerecord/test/cases/result_test.rb @@ -10,6 +10,10 @@ module ActiveRecord ]) end + test "length" do + assert_equal 3, result.length + end + test "to_hash returns row_hashes" do assert_equal [ {'col_1' => 'row 1 col 1', 'col_2' => 'row 1 col 2'}, diff --git a/activerecord/test/cases/sanitize_test.rb b/activerecord/test/cases/sanitize_test.rb index dca85fb5eb..f477cf7d92 100644 --- a/activerecord/test/cases/sanitize_test.rb +++ b/activerecord/test/cases/sanitize_test.rb @@ -13,7 +13,9 @@ class SanitizeTest < ActiveRecord::TestCase quoted_table_name = ActiveRecord::Base.connection.quote_table_name("adorable_animals") expected_value = "#{quoted_table_name}.#{quoted_column_name} = #{quoted_bambi}" - assert_equal expected_value, Binary.send(:sanitize_sql_hash, {adorable_animals: {name: 'Bambi'}}) + assert_deprecated do + assert_equal expected_value, Binary.send(:sanitize_sql_hash, {adorable_animals: {name: 'Bambi'}}) + end end def test_sanitize_sql_array_handles_string_interpolation diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 93fb502410..6303393c22 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -19,7 +19,7 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_dump_schema_information_outputs_lexically_ordered_versions versions = %w{ 20100101010101 20100201010101 20100301010101 } - versions.reverse.each do |v| + versions.reverse_each do |v| ActiveRecord::SchemaMigration.create!(:version => v) end @@ -271,13 +271,6 @@ class SchemaDumperTest < ActiveRecord::TestCase end end - def test_schema_dump_includes_json_shorthand_definition - output = standard_dump - if %r{create_table "postgresql_json_data_type"} =~ output - assert_match %r|t.json "json_data", default: {}|, output - end - end - def test_schema_dump_includes_inet_shorthand_definition output = standard_dump if %r{create_table "postgresql_network_addresses"} =~ output diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb index d3546bd471..c2816c3670 100644 --- a/activerecord/test/cases/scoping/named_scoping_test.rb +++ b/activerecord/test/cases/scoping/named_scoping_test.rb @@ -132,6 +132,13 @@ class NamedScopingTest < ActiveRecord::TestCase assert_equal Post.ranked_by_comments.limit_by(5), Post.top(5) end + def test_scopes_body_is_a_callable + e = assert_raises ArgumentError do + Class.new(Post).class_eval { scope :containing_the_letter_z, where("body LIKE '%z%'") } + end + assert_equal "The scope body needs to be callable.", e.message + end + def test_active_records_have_scope_named__all__ assert !Topic.all.empty? diff --git a/activerecord/test/cases/scoping/relation_scoping_test.rb b/activerecord/test/cases/scoping/relation_scoping_test.rb index 8e512e118a..73835c85a8 100644 --- a/activerecord/test/cases/scoping/relation_scoping_test.rb +++ b/activerecord/test/cases/scoping/relation_scoping_test.rb @@ -15,6 +15,26 @@ class RelationScopingTest < ActiveRecord::TestCase developers(:david) end + def test_unscoped_breaks_caching + author = authors :mary + assert_nil author.first_post + post = FirstPost.unscoped do + author.reload.first_post + end + assert post + end + + def test_scope_breaks_caching_on_collections + author = authors :david + ids = author.reload.special_posts_with_default_scope.map(&:id) + assert_equal [1,5,6], ids.sort + scoped_posts = SpecialPostWithDefaultScope.unscoped do + author = authors :david + author.reload.special_posts_with_default_scope.to_a + end + assert_equal author.posts.map(&:id).sort, scoped_posts.map(&:id).sort + end + def test_reverse_order assert_equal Developer.order("id DESC").to_a.reverse, Developer.order("id DESC").reverse_order end diff --git a/activerecord/test/cases/serialization_test.rb b/activerecord/test/cases/serialization_test.rb index 3f52e80e11..35b13ea247 100644 --- a/activerecord/test/cases/serialization_test.rb +++ b/activerecord/test/cases/serialization_test.rb @@ -2,6 +2,8 @@ require "cases/helper" require 'models/contact' require 'models/topic' require 'models/book' +require 'models/author' +require 'models/post' class SerializationTest < ActiveRecord::TestCase fixtures :books @@ -92,4 +94,11 @@ class SerializationTest < ActiveRecord::TestCase book = klazz.find(books(:awdr).id) assert_equal 'paperback', book.read_attribute_for_serialization(:format) end + + def test_find_records_by_serialized_attributes_through_join + author = Author.create!(name: "David") + author.serialized_posts.create!(title: "Hello") + + assert_equal 1, Author.joins(:serialized_posts).where(name: "David", serialized_posts: { title: "Hello" }).length + end end diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index c5fb491b10..66f345d805 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -140,11 +140,10 @@ class SerializedAttributeTest < ActiveRecord::TestCase assert_equal 1, Topic.where(:content => nil).count end - def test_serialized_attribute_should_raise_exception_on_save_with_wrong_type + def test_serialized_attribute_should_raise_exception_on_assignment_with_wrong_type Topic.serialize(:content, Hash) assert_raise(ActiveRecord::SerializationTypeMismatch) do - topic = Topic.new(content: 'string') - topic.save + Topic.new(content: 'string') end end diff --git a/activerecord/test/cases/type/integer_test.rb b/activerecord/test/cases/type/integer_test.rb new file mode 100644 index 0000000000..53d6a3a6aa --- /dev/null +++ b/activerecord/test/cases/type/integer_test.rb @@ -0,0 +1,106 @@ +require "cases/helper" +require "models/company" + +module ActiveRecord + module Type + class IntegerTest < ActiveRecord::TestCase + test "simple values" do + type = Type::Integer.new + assert_equal 1, type.type_cast_from_user(1) + assert_equal 1, type.type_cast_from_user('1') + assert_equal 1, type.type_cast_from_user('1ignore') + assert_equal 0, type.type_cast_from_user('bad1') + assert_equal 0, type.type_cast_from_user('bad') + assert_equal 1, type.type_cast_from_user(1.7) + assert_equal 0, type.type_cast_from_user(false) + assert_equal 1, type.type_cast_from_user(true) + assert_nil type.type_cast_from_user(nil) + end + + test "random objects cast to nil" do + type = Type::Integer.new + assert_nil type.type_cast_from_user([1,2]) + assert_nil type.type_cast_from_user({1 => 2}) + assert_nil type.type_cast_from_user((1..2)) + end + + test "casting ActiveRecord models" do + type = Type::Integer.new + firm = Firm.create(:name => 'Apple') + assert_nil type.type_cast_from_user(firm) + end + + test "casting objects without to_i" do + type = Type::Integer.new + assert_nil type.type_cast_from_user(::Object.new) + end + + test "casting nan and infinity" do + type = Type::Integer.new + assert_nil type.type_cast_from_user(::Float::NAN) + assert_nil type.type_cast_from_user(1.0/0.0) + end + + test "changed?" do + type = Type::Integer.new + + assert type.changed?(5, 5, '5wibble') + assert_not type.changed?(5, 5, '5') + assert_not type.changed?(5, 5, '5.0') + assert_not type.changed?(nil, nil, nil) + end + + test "values below int min value are out of range" do + assert_raises(::RangeError) do + Integer.new.type_cast_from_user("-2147483649") + end + end + + test "values above int max value are out of range" do + assert_raises(::RangeError) do + Integer.new.type_cast_from_user("2147483648") + end + end + + test "very small numbers are out of range" do + assert_raises(::RangeError) do + Integer.new.type_cast_from_user("-9999999999999999999999999999999") + end + end + + test "very large numbers are in range" do + assert_raises(::RangeError) do + Integer.new.type_cast_from_user("9999999999999999999999999999999") + end + end + + test "normal numbers are in range" do + type = Integer.new + assert_equal(0, type.type_cast_from_user("0")) + assert_equal(-1, type.type_cast_from_user("-1")) + assert_equal(1, type.type_cast_from_user("1")) + end + + test "int max value is in range" do + assert_equal(2147483647, Integer.new.type_cast_from_user("2147483647")) + end + + test "int min value is in range" do + assert_equal(-2147483648, Integer.new.type_cast_from_user("-2147483648")) + end + + test "columns with a larger limit have larger ranges" do + type = Integer.new(limit: 8) + + assert_equal(9223372036854775807, type.type_cast_from_user("9223372036854775807")) + assert_equal(-9223372036854775808, type.type_cast_from_user("-9223372036854775808")) + assert_raises(::RangeError) do + type.type_cast_from_user("-9999999999999999999999999999999") + end + assert_raises(::RangeError) do + type.type_cast_from_user("9999999999999999999999999999999") + end + end + end + end +end diff --git a/activerecord/test/cases/type/string_test.rb b/activerecord/test/cases/type/string_test.rb index 420177ed49..4d78f287f1 100644 --- a/activerecord/test/cases/type/string_test.rb +++ b/activerecord/test/cases/type/string_test.rb @@ -4,8 +4,8 @@ module ActiveRecord class StringTypeTest < ActiveRecord::TestCase test "type casting" do type = Type::String.new - assert_equal "1", type.type_cast_from_user(true) - assert_equal "0", type.type_cast_from_user(false) + assert_equal "t", type.type_cast_from_user(true) + assert_equal "f", type.type_cast_from_user(false) assert_equal "123", type.type_cast_from_user(123) end diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb index db4f78d354..b0979cbe1f 100644 --- a/activerecord/test/cases/types_test.rb +++ b/activerecord/test/cases/types_test.rb @@ -1,5 +1,4 @@ require "cases/helper" -require 'models/company' module ActiveRecord module ConnectionAdapters @@ -29,56 +28,12 @@ module ActiveRecord assert_equal false, type.type_cast_from_user('FALSE') assert_equal false, type.type_cast_from_user('off') assert_equal false, type.type_cast_from_user('OFF') - assert_equal false, type.type_cast_from_user(' ') - assert_equal false, type.type_cast_from_user("\u3000\r\n") - assert_equal false, type.type_cast_from_user("\u0000") - assert_equal false, type.type_cast_from_user('SOMETHING RANDOM') - end - - def test_type_cast_integer - type = Type::Integer.new - assert_equal 1, type.type_cast_from_user(1) - assert_equal 1, type.type_cast_from_user('1') - assert_equal 1, type.type_cast_from_user('1ignore') - assert_equal 0, type.type_cast_from_user('bad1') - assert_equal 0, type.type_cast_from_user('bad') - assert_equal 1, type.type_cast_from_user(1.7) - assert_equal 0, type.type_cast_from_user(false) - assert_equal 1, type.type_cast_from_user(true) - assert_nil type.type_cast_from_user(nil) - end - - def test_type_cast_non_integer_to_integer - type = Type::Integer.new - assert_nil type.type_cast_from_user([1,2]) - assert_nil type.type_cast_from_user({1 => 2}) - assert_nil type.type_cast_from_user((1..2)) - end - - def test_type_cast_activerecord_to_integer - type = Type::Integer.new - firm = Firm.create(:name => 'Apple') - assert_nil type.type_cast_from_user(firm) - end - - def test_type_cast_object_without_to_i_to_integer - type = Type::Integer.new - assert_nil type.type_cast_from_user(Object.new) - end - - def test_type_cast_nan_and_infinity_to_integer - type = Type::Integer.new - assert_nil type.type_cast_from_user(Float::NAN) - assert_nil type.type_cast_from_user(1.0/0.0) - end - - def test_changing_integers - type = Type::Integer.new - - assert type.changed?(5, 5, '5wibble') - assert_not type.changed?(5, 5, '5') - assert_not type.changed?(5, 5, '5.0') - assert_not type.changed?(nil, nil, nil) + assert_deprecated do + assert_equal false, type.type_cast_from_user(' ') + assert_equal false, type.type_cast_from_user("\u3000\r\n") + assert_equal false, type.type_cast_from_user("\u0000") + assert_equal false, type.type_cast_from_user('SOMETHING RANDOM') + end end def test_type_cast_float diff --git a/activerecord/test/config.example.yml b/activerecord/test/config.example.yml index ce30cff9e7..e3b55d640e 100644 --- a/activerecord/test/config.example.yml +++ b/activerecord/test/config.example.yml @@ -69,12 +69,6 @@ connections: username: rails encoding: utf8 - openbase: - arunit: - username: admin - arunit2: - username: admin - oracle: arunit: adapter: oracle_enhanced diff --git a/activerecord/test/fixtures/computers.yml b/activerecord/test/fixtures/computers.yml index 7281a4d768..ad5ae2ec71 100644 --- a/activerecord/test/fixtures/computers.yml +++ b/activerecord/test/fixtures/computers.yml @@ -3,3 +3,8 @@ workstation: system: 'Linux' developer: 1 extendedWarranty: 1 + +laptop: + system: 'MacOS 1' + developer: 1 + extendedWarranty: 1 diff --git a/activerecord/test/fixtures/developers.yml b/activerecord/test/fixtures/developers.yml index 1a74563dc6..54b74e7a74 100644 --- a/activerecord/test/fixtures/developers.yml +++ b/activerecord/test/fixtures/developers.yml @@ -2,6 +2,7 @@ david: id: 1 name: David salary: 80000 + shared_computers: laptop jamis: id: 2 diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index 8949cf5826..3da3a1fd59 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -1,5 +1,6 @@ class Author < ActiveRecord::Base has_many :posts + has_many :serialized_posts has_one :post has_many :very_special_comments, :through => :posts has_many :posts_with_comments, -> { includes(:comments) }, :class_name => "Post" @@ -44,6 +45,7 @@ class Author < ActiveRecord::Base has_many :special_posts has_many :special_post_comments, :through => :special_posts, :source => :comments + has_many :special_posts_with_default_scope, :class_name => 'SpecialPostWithDefaultScope' has_many :sti_posts, :class_name => 'StiPost' has_many :sti_post_comments, :through => :sti_posts, :source => :comments diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 3627cfdd09..d2a5a7fc49 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -15,6 +15,8 @@ class Developer < ActiveRecord::Base accepts_nested_attributes_for :projects + has_and_belongs_to_many :shared_computers, class_name: "Computer" + has_and_belongs_to_many :projects_extended_by_name, -> { extending(DeveloperProjectsAssociationExtension) }, :class_name => "Project", diff --git a/activerecord/test/models/member.rb b/activerecord/test/models/member.rb index 72095f9236..dc0566d8a7 100644 --- a/activerecord/test/models/member.rb +++ b/activerecord/test/models/member.rb @@ -27,6 +27,9 @@ class Member < ActiveRecord::Base has_many :clubs, :through => :current_memberships has_one :club_through_many, :through => :current_memberships, :source => :club + + belongs_to :admittable, polymorphic: true + has_one :premium_club, through: :admittable end class SelfMember < ActiveRecord::Base diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index 256b720c9a..36cf221d45 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -219,8 +219,21 @@ class PostThatLoadsCommentsInAnAfterSaveHook < ActiveRecord::Base end end +class PostWithAfterCreateCallback < ActiveRecord::Base + self.table_name = 'posts' + has_many :comments, foreign_key: :post_id + + after_create do |post| + update_attribute(:author_id, comments.first.id) + end +end + class PostWithCommentWithDefaultScopeReferencesAssociation < ActiveRecord::Base self.table_name = 'posts' has_many :comment_with_default_scope_references_associations, foreign_key: :post_id has_one :first_comment, class_name: "CommentWithDefaultScopeReferencesAssociation", foreign_key: :post_id end + +class SerializedPost < ActiveRecord::Base + serialize :title +end diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb index e9294a11b9..7c3b170c08 100644 --- a/activerecord/test/schema/postgresql_specific_schema.rb +++ b/activerecord/test/schema/postgresql_specific_schema.rb @@ -1,7 +1,9 @@ ActiveRecord::Schema.define do - %w(postgresql_tsvectors postgresql_hstores postgresql_arrays postgresql_moneys postgresql_numbers postgresql_times postgresql_network_addresses postgresql_uuids postgresql_ltrees - postgresql_oids postgresql_xml_data_type defaults geometrics postgresql_timestamp_with_zones postgresql_partitioned_table postgresql_partitioned_table_parent postgresql_json_data_type postgresql_citext).each do |table_name| + %w(postgresql_tsvectors postgresql_hstores postgresql_arrays postgresql_moneys postgresql_numbers postgresql_times + postgresql_network_addresses postgresql_uuids postgresql_ltrees postgresql_oids postgresql_xml_data_type defaults + geometrics postgresql_timestamp_with_zones postgresql_partitioned_table postgresql_partitioned_table_parent + postgresql_citext).each do |table_name| execute "DROP TABLE IF EXISTS #{quote_table_name table_name}" end @@ -108,15 +110,6 @@ _SQL _SQL end - if 't' == select_value("select 'json'=ANY(select typname from pg_type)") - execute <<_SQL - CREATE TABLE postgresql_json_data_type ( - id SERIAL PRIMARY KEY, - json_data json default '{}'::json - ); -_SQL - end - execute <<_SQL CREATE TABLE postgresql_numbers ( id SERIAL PRIMARY KEY, diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 10de3d34cb..720a127585 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -228,6 +228,11 @@ ActiveRecord::Schema.define do t.integer :extendedWarranty, null: false end + create_table :computers_developers, id: false, force: true do |t| + t.references :computer + t.references :developer + end + create_table :contracts, force: true do |t| t.integer :developer_id t.integer :company_id @@ -311,7 +316,7 @@ ActiveRecord::Schema.define do end create_table :cold_jokes, force: true do |t| - t.string :name + t.string :cold_name end create_table :friendships, force: true do |t| @@ -585,6 +590,11 @@ ActiveRecord::Schema.define do t.integer :tags_with_nullify_count, default: 0 end + create_table :serialized_posts, force: true do |t| + t.integer :author_id + t.string :title, null: false + end + create_table :price_estimates, force: true do |t| t.string :estimate_of_type t.integer :estimate_of_id |