aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/active_record/connection_adapters/fake_adapter.rb3
-rw-r--r--activerecord/test/cases/adapters/mysql2/annotate_test.rb37
-rw-r--r--activerecord/test/cases/adapters/mysql2/enum_test.rb14
-rw-r--r--activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb27
-rw-r--r--activerecord/test/cases/adapters/mysql2/set_test.rb32
-rw-r--r--activerecord/test/cases/adapters/mysql2/transaction_test.rb6
-rw-r--r--activerecord/test/cases/adapters/postgresql/annotate_test.rb37
-rw-r--r--activerecord/test/cases/adapters/postgresql/money_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb12
-rw-r--r--activerecord/test/cases/adapters/sqlite3/annotate_test.rb37
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb16
-rw-r--r--activerecord/test/cases/annotate_test.rb46
-rw-r--r--activerecord/test/cases/arel/attributes/attribute_test.rb24
-rw-r--r--activerecord/test/cases/arel/attributes_test.rb41
-rw-r--r--activerecord/test/cases/autosave_association_test.rb57
-rw-r--r--activerecord/test/cases/base_test.rb17
-rw-r--r--activerecord/test/cases/batches_test.rb2
-rw-r--r--activerecord/test/cases/bind_parameter_test.rb2
-rw-r--r--activerecord/test/cases/calculations_test.rb13
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handler_test.rb2
-rw-r--r--activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb74
-rw-r--r--activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb2
-rw-r--r--activerecord/test/cases/finder_test.rb14
-rw-r--r--activerecord/test/cases/inheritance_test.rb4
-rw-r--r--activerecord/test/cases/json_serialization_test.rb2
-rw-r--r--activerecord/test/cases/query_cache_test.rb17
-rw-r--r--activerecord/test/cases/relation_test.rb7
-rw-r--r--activerecord/test/cases/relations_test.rb8
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb1
-rw-r--r--activerecord/test/cases/validations/i18n_validation_test.rb4
-rw-r--r--activerecord/test/models/author.rb1
-rw-r--r--activerecord/test/models/book.rb6
-rw-r--r--activerecord/test/models/contact.rb18
-rw-r--r--activerecord/test/models/mouse.rb6
-rw-r--r--activerecord/test/models/ship.rb3
-rw-r--r--activerecord/test/models/squeak.rb6
-rw-r--r--activerecord/test/schema/mysql2_specific_schema.rb4
-rw-r--r--activerecord/test/schema/schema.rb11
38 files changed, 430 insertions, 187 deletions
diff --git a/activerecord/test/active_record/connection_adapters/fake_adapter.rb b/activerecord/test/active_record/connection_adapters/fake_adapter.rb
index f977b2997b..f1f457aedd 100644
--- a/activerecord/test/active_record/connection_adapters/fake_adapter.rb
+++ b/activerecord/test/active_record/connection_adapters/fake_adapter.rb
@@ -32,7 +32,8 @@ module ActiveRecord
name.to_s,
options[:default],
fetch_type_metadata(sql_type),
- options[:null])
+ options[:null],
+ )
end
def columns(table_name)
diff --git a/activerecord/test/cases/adapters/mysql2/annotate_test.rb b/activerecord/test/cases/adapters/mysql2/annotate_test.rb
deleted file mode 100644
index b512540073..0000000000
--- a/activerecord/test/cases/adapters/mysql2/annotate_test.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require "cases/helper"
-require "models/post"
-
-class Mysql2AnnotateTest < ActiveRecord::Mysql2TestCase
- fixtures :posts
-
- def test_annotate_wraps_content_in_an_inline_comment
- assert_sql(%r{\ASELECT `posts`\.`id` FROM `posts` /\* foo \*/}) do
- posts = Post.select(:id).annotate("foo")
- assert posts.first
- end
- end
-
- def test_annotate_is_sanitized
- assert_sql(%r{\ASELECT `posts`\.`id` FROM `posts` /\* foo \*/}) do
- posts = Post.select(:id).annotate("*/foo/*")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT `posts`\.`id` FROM `posts` /\* foo \*/}) do
- posts = Post.select(:id).annotate("**//foo//**")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT `posts`\.`id` FROM `posts` /\* foo \*/ /\* bar \*/}) do
- posts = Post.select(:id).annotate("*/foo/*").annotate("*/bar")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT `posts`\.`id` FROM `posts` /\* \+ MAX_EXECUTION_TIME\(1\) \*/}) do
- posts = Post.select(:id).annotate("+ MAX_EXECUTION_TIME(1)")
- assert posts.first
- end
- end
-end
diff --git a/activerecord/test/cases/adapters/mysql2/enum_test.rb b/activerecord/test/cases/adapters/mysql2/enum_test.rb
index 832f5d61d1..1168b3677e 100644
--- a/activerecord/test/cases/adapters/mysql2/enum_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/enum_test.rb
@@ -1,11 +1,20 @@
# frozen_string_literal: true
require "cases/helper"
+require "support/schema_dumping_helper"
class Mysql2EnumTest < ActiveRecord::Mysql2TestCase
+ include SchemaDumpingHelper
+
class EnumTest < ActiveRecord::Base
end
+ def setup
+ EnumTest.connection.create_table :enum_tests, id: false, force: true do |t|
+ t.column :enum_column, "enum('text','blob','tiny','medium','long','unsigned','bigint')"
+ end
+ end
+
def test_enum_limit
column = EnumTest.columns_hash["enum_column"]
assert_equal 8, column.limit
@@ -20,4 +29,9 @@ class Mysql2EnumTest < ActiveRecord::Mysql2TestCase
column = EnumTest.columns_hash["enum_column"]
assert_not_predicate column, :bigint?
end
+
+ def test_schema_dumping
+ schema = dump_table_schema "enum_tests"
+ assert_match %r{t\.column "enum_column", "enum\('text','blob','tiny','medium','long','unsigned','bigint'\)"$}, schema
+ end
end
diff --git a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
index e1f7a0b7c5..cfc1823773 100644
--- a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
@@ -20,6 +20,18 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
end
end
+ def test_database_exists_returns_false_if_database_does_not_exist
+ config = ActiveRecord::Base.configurations["arunit"].merge(database: "inexistent_activerecord_unittest")
+ assert_not ActiveRecord::ConnectionAdapters::Mysql2Adapter.database_exists?(config),
+ "expected database to not exist"
+ end
+
+ def test_database_exists_returns_true_when_the_database_exists
+ config = ActiveRecord::Base.configurations["arunit"]
+ assert ActiveRecord::ConnectionAdapters::Mysql2Adapter.database_exists?(config),
+ "expected database #{config[:database]} to exist"
+ end
+
def test_columns_for_distinct_zero_orders
assert_equal "posts.id",
@conn.columns_for_distinct("posts.id", [])
@@ -213,6 +225,21 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
end
end
+ def test_read_timeout_exception
+ ActiveRecord::Base.establish_connection(
+ ActiveRecord::Base.configurations[:arunit].merge("read_timeout" => 1)
+ )
+
+ error = assert_raises(ActiveRecord::AdapterTimeout) do
+ ActiveRecord::Base.connection.execute("SELECT SLEEP(2)")
+ end
+ assert_kind_of ActiveRecord::QueryAborted, error
+
+ assert_equal Mysql2::Error::TimeoutError, error.cause.class
+ ensure
+ ActiveRecord::Base.establish_connection :arunit
+ end
+
private
def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block)
super(@conn, "ex", definition, &block)
diff --git a/activerecord/test/cases/adapters/mysql2/set_test.rb b/activerecord/test/cases/adapters/mysql2/set_test.rb
new file mode 100644
index 0000000000..89107e142f
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql2/set_test.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "support/schema_dumping_helper"
+
+class Mysql2SetTest < ActiveRecord::Mysql2TestCase
+ include SchemaDumpingHelper
+
+ class SetTest < ActiveRecord::Base
+ end
+
+ def setup
+ SetTest.connection.create_table :set_tests, id: false, force: true do |t|
+ t.column :set_column, "set('text','blob','tiny','medium','long','unsigned','bigint')"
+ end
+ end
+
+ def test_should_not_be_unsigned
+ column = SetTest.columns_hash["set_column"]
+ assert_not_predicate column, :unsigned?
+ end
+
+ def test_should_not_be_bigint
+ column = SetTest.columns_hash["set_column"]
+ assert_not_predicate column, :bigint?
+ end
+
+ def test_schema_dumping
+ schema = dump_table_schema "set_tests"
+ assert_match %r{t\.column "set_column", "set\('text','blob','tiny','medium','long','unsigned','bigint'\)"$}, schema
+ end
+end
diff --git a/activerecord/test/cases/adapters/mysql2/transaction_test.rb b/activerecord/test/cases/adapters/mysql2/transaction_test.rb
index 52e283f247..2041cc308f 100644
--- a/activerecord/test/cases/adapters/mysql2/transaction_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/transaction_test.rb
@@ -92,7 +92,7 @@ module ActiveRecord
test "raises StatementTimeout when statement timeout exceeded" do
skip unless ActiveRecord::Base.connection.show_variable("max_execution_time")
- assert_raises(ActiveRecord::StatementTimeout) do
+ error = assert_raises(ActiveRecord::StatementTimeout) do
s = Sample.create!(value: 1)
latch1 = Concurrent::CountDownLatch.new
latch2 = Concurrent::CountDownLatch.new
@@ -117,10 +117,11 @@ module ActiveRecord
thread.join
end
end
+ assert_kind_of ActiveRecord::QueryAborted, error
end
test "raises QueryCanceled when canceling statement due to user request" do
- assert_raises(ActiveRecord::QueryCanceled) do
+ error = assert_raises(ActiveRecord::QueryCanceled) do
s = Sample.create!(value: 1)
latch = Concurrent::CountDownLatch.new
@@ -144,6 +145,7 @@ module ActiveRecord
thread.join
end
end
+ assert_kind_of ActiveRecord::QueryAborted, error
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/annotate_test.rb b/activerecord/test/cases/adapters/postgresql/annotate_test.rb
deleted file mode 100644
index 42a2861511..0000000000
--- a/activerecord/test/cases/adapters/postgresql/annotate_test.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require "cases/helper"
-require "models/post"
-
-class PostgresqlAnnotateTest < ActiveRecord::PostgreSQLTestCase
- fixtures :posts
-
- def test_annotate_wraps_content_in_an_inline_comment
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/}) do
- posts = Post.select(:id).annotate("foo")
- assert posts.first
- end
- end
-
- def test_annotate_is_sanitized
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/}) do
- posts = Post.select(:id).annotate("*/foo/*")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/}) do
- posts = Post.select(:id).annotate("**//foo//**")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/ /\* bar \*/}) do
- posts = Post.select(:id).annotate("*/foo/*").annotate("*/bar")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* \+ MAX_EXECUTION_TIME\(1\) \*/}) do
- posts = Post.select(:id).annotate("+ MAX_EXECUTION_TIME(1)")
- assert posts.first
- end
- end
-end
diff --git a/activerecord/test/cases/adapters/postgresql/money_test.rb b/activerecord/test/cases/adapters/postgresql/money_test.rb
index 1aa0348879..ff2ab22a80 100644
--- a/activerecord/test/cases/adapters/postgresql/money_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/money_test.rb
@@ -54,8 +54,12 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
type = PostgresqlMoney.type_for_attribute("wealth")
assert_equal(12345678.12, type.cast(+"$12,345,678.12"))
assert_equal(12345678.12, type.cast(+"$12.345.678,12"))
+ assert_equal(12345678.12, type.cast(+"12,345,678.12"))
+ assert_equal(12345678.12, type.cast(+"12.345.678,12"))
assert_equal(-1.15, type.cast(+"-$1.15"))
assert_equal(-2.25, type.cast(+"($2.25)"))
+ assert_equal(-1.15, type.cast(+"-1.15"))
+ assert_equal(-2.25, type.cast(+"(2.25)"))
end
def test_schema_dumping
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index 68bc87eaf8..d99593817a 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -24,6 +24,18 @@ module ActiveRecord
end
end
+ def test_database_exists_returns_false_when_the_database_does_not_exist
+ config = { database: "non_extant_database", adapter: "postgresql" }
+ assert_not ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.database_exists?(config),
+ "expected database #{config[:database]} to not exist"
+ end
+
+ def test_database_exists_returns_true_when_the_database_exists
+ config = ActiveRecord::Base.configurations["arunit"]
+ assert ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.database_exists?(config),
+ "expected database #{config[:database]} to exist"
+ end
+
def test_primary_key
with_example_table do
assert_equal "id", @connection.primary_key("ex")
diff --git a/activerecord/test/cases/adapters/sqlite3/annotate_test.rb b/activerecord/test/cases/adapters/sqlite3/annotate_test.rb
deleted file mode 100644
index 6567a5eca3..0000000000
--- a/activerecord/test/cases/adapters/sqlite3/annotate_test.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require "cases/helper"
-require "models/post"
-
-class SQLite3AnnotateTest < ActiveRecord::SQLite3TestCase
- fixtures :posts
-
- def test_annotate_wraps_content_in_an_inline_comment
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/}) do
- posts = Post.select(:id).annotate("foo")
- assert posts.first
- end
- end
-
- def test_annotate_is_sanitized
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/}) do
- posts = Post.select(:id).annotate("*/foo/*")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/}) do
- posts = Post.select(:id).annotate("**//foo//**")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* foo \*/ /\* bar \*/}) do
- posts = Post.select(:id).annotate("*/foo/*").annotate("*/bar")
- assert posts.first
- end
-
- assert_sql(%r{\ASELECT "posts"\."id" FROM "posts" /\* \+ MAX_EXECUTION_TIME\(1\) \*/}) do
- posts = Post.select(:id).annotate("+ MAX_EXECUTION_TIME(1)")
- assert posts.first
- end
- end
-end
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 508f7d8945..b6d72c7bcd 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -30,6 +30,17 @@ module ActiveRecord
end
end
+ def test_database_exists_returns_false_when_the_database_does_not_exist
+ assert_not SQLite3Adapter.database_exists?(adapter: "sqlite3", database: "non_extant_db"),
+ "expected non_extant_db to not exist"
+ end
+
+ def test_database_exists_returns_true_when_databae_exists
+ config = ActiveRecord::Base.configurations["arunit"]
+ assert SQLite3Adapter.database_exists?(config),
+ "expected #{config[:database]} to exist"
+ end
+
unless in_memory_db?
def test_connect_with_url
original_connection = ActiveRecord::Base.remove_connection
@@ -53,6 +64,11 @@ module ActiveRecord
end
end
+ def test_database_exists_returns_true_for_an_in_memory_db
+ assert SQLite3Adapter.database_exists?(database: ":memory:"),
+ "Expected in memory database to exist"
+ end
+
def test_column_types
owner = Owner.create!(name: "hello".encode("ascii-8bit"))
owner.reload
diff --git a/activerecord/test/cases/annotate_test.rb b/activerecord/test/cases/annotate_test.rb
new file mode 100644
index 0000000000..4d71d28f83
--- /dev/null
+++ b/activerecord/test/cases/annotate_test.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "models/post"
+
+class AnnotateTest < ActiveRecord::TestCase
+ fixtures :posts
+
+ def test_annotate_wraps_content_in_an_inline_comment
+ quoted_posts_id, quoted_posts = regexp_escape_table_name("posts.id"), regexp_escape_table_name("posts")
+
+ assert_sql(%r{\ASELECT #{quoted_posts_id} FROM #{quoted_posts} /\* foo \*/}i) do
+ posts = Post.select(:id).annotate("foo")
+ assert posts.first
+ end
+ end
+
+ def test_annotate_is_sanitized
+ quoted_posts_id, quoted_posts = regexp_escape_table_name("posts.id"), regexp_escape_table_name("posts")
+
+ assert_sql(%r{\ASELECT #{quoted_posts_id} FROM #{quoted_posts} /\* foo \*/}i) do
+ posts = Post.select(:id).annotate("*/foo/*")
+ assert posts.first
+ end
+
+ assert_sql(%r{\ASELECT #{quoted_posts_id} FROM #{quoted_posts} /\* foo \*/}i) do
+ posts = Post.select(:id).annotate("**//foo//**")
+ assert posts.first
+ end
+
+ assert_sql(%r{\ASELECT #{quoted_posts_id} FROM #{quoted_posts} /\* foo \*/ /\* bar \*/}i) do
+ posts = Post.select(:id).annotate("*/foo/*").annotate("*/bar")
+ assert posts.first
+ end
+
+ assert_sql(%r{\ASELECT #{quoted_posts_id} FROM #{quoted_posts} /\* \+ MAX_EXECUTION_TIME\(1\) \*/}i) do
+ posts = Post.select(:id).annotate("+ MAX_EXECUTION_TIME(1)")
+ assert posts.first
+ end
+ end
+
+ private
+ def regexp_escape_table_name(name)
+ Regexp.escape(Post.connection.quote_table_name(name))
+ end
+end
diff --git a/activerecord/test/cases/arel/attributes/attribute_test.rb b/activerecord/test/cases/arel/attributes/attribute_test.rb
index c7bd0a053b..7ebb90c6fd 100644
--- a/activerecord/test/cases/arel/attributes/attribute_test.rb
+++ b/activerecord/test/cases/arel/attributes/attribute_test.rb
@@ -638,6 +638,18 @@ module Arel
)
end
+ if Gem::Version.new("2.7.0") <= Gem::Version.new(RUBY_VERSION)
+ it "can be constructed with a range implicitly starting at Infinity" do
+ attribute = Attribute.new nil, nil
+ node = attribute.between(eval("..0")) # eval for backwards compatibility
+
+ node.must_equal Nodes::LessThanOrEqual.new(
+ attribute,
+ Nodes::Casted.new(0, attribute)
+ )
+ end
+ end
+
if Gem::Version.new("2.6.0") <= Gem::Version.new(RUBY_VERSION)
it "can be constructed with a range implicitly ending at Infinity" do
attribute = Attribute.new nil, nil
@@ -839,6 +851,18 @@ module Arel
)
end
+ if Gem::Version.new("2.7.0") <= Gem::Version.new(RUBY_VERSION)
+ it "can be constructed with a range implicitly starting at Infinity" do
+ attribute = Attribute.new nil, nil
+ node = attribute.not_between(eval("..0")) # eval for backwards compatibility
+
+ node.must_equal Nodes::GreaterThan.new(
+ attribute,
+ Nodes::Casted.new(0, attribute)
+ )
+ end
+ end
+
if Gem::Version.new("2.6.0") <= Gem::Version.new(RUBY_VERSION)
it "can be constructed with a range implicitly ending at Infinity" do
attribute = Attribute.new nil, nil
diff --git a/activerecord/test/cases/arel/attributes_test.rb b/activerecord/test/cases/arel/attributes_test.rb
index b00af4bd29..1712633ae9 100644
--- a/activerecord/test/cases/arel/attributes_test.rb
+++ b/activerecord/test/cases/arel/attributes_test.rb
@@ -23,46 +23,5 @@ module Arel
assert_equal 2, array.uniq.size
end
end
-
- describe "for" do
- it "deals with unknown column types" do
- column = Struct.new(:type).new :crazy
- Attributes.for(column).must_equal Attributes::Undefined
- end
-
- it "returns the correct constant for strings" do
- [:string, :text, :binary].each do |type|
- column = Struct.new(:type).new type
- Attributes.for(column).must_equal Attributes::String
- end
- end
-
- it "returns the correct constant for ints" do
- column = Struct.new(:type).new :integer
- Attributes.for(column).must_equal Attributes::Integer
- end
-
- it "returns the correct constant for floats" do
- column = Struct.new(:type).new :float
- Attributes.for(column).must_equal Attributes::Float
- end
-
- it "returns the correct constant for decimals" do
- column = Struct.new(:type).new :decimal
- Attributes.for(column).must_equal Attributes::Decimal
- end
-
- it "returns the correct constant for boolean" do
- column = Struct.new(:type).new :boolean
- Attributes.for(column).must_equal Attributes::Boolean
- end
-
- it "returns the correct constant for time" do
- [:date, :datetime, :timestamp, :time].each do |type|
- column = Struct.new(:type).new type
- Attributes.for(column).must_equal Attributes::Time
- end
- end
- end
end
end
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 7e61ac9d8b..3528ac045f 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -2,6 +2,7 @@
require "cases/helper"
require "models/author"
+require "models/book"
require "models/bird"
require "models/post"
require "models/comment"
@@ -12,12 +13,14 @@ require "models/developer"
require "models/computer"
require "models/invoice"
require "models/line_item"
+require "models/mouse"
require "models/order"
require "models/parrot"
require "models/pirate"
require "models/project"
require "models/ship"
require "models/ship_part"
+require "models/squeak"
require "models/tag"
require "models/tagging"
require "models/treasure"
@@ -385,6 +388,20 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
assert_predicate auditlog, :valid?
end
+
+ def test_validation_does_not_validate_non_dirty_association_target
+ mouse = Mouse.create!(name: "Will")
+ Squeak.create!(mouse: mouse)
+
+ mouse.name = nil
+ mouse.save! validate: false
+
+ squeak = Squeak.last
+
+ assert_equal true, squeak.valid?
+ assert_equal true, squeak.mouse.present?
+ assert_equal true, squeak.valid?
+ end
end
class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase
@@ -1671,6 +1688,10 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
super
@pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
@pirate.birds.create(name: "cookoo")
+
+ @author = Author.new(name: "DHH")
+ @author.published_books.build(name: "Rework", isbn: "1234")
+ @author.published_books.build(name: "Remote", isbn: "1234")
end
test "should automatically validate associations" do
@@ -1679,6 +1700,42 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
assert_not_predicate @pirate, :valid?
end
+
+ test "rollbacks whole transaction and raises ActiveRecord::RecordInvalid when associations fail to #save! due to uniqueness validation failure" do
+ author_count_before_save = Author.count
+ book_count_before_save = Book.count
+
+ assert_no_difference "Author.count" do
+ assert_no_difference "Book.count" do
+ exception = assert_raises(ActiveRecord::RecordInvalid) do
+ @author.save!
+ end
+
+ assert_equal("Validation failed: Published books is invalid", exception.message)
+ end
+ end
+
+ assert_equal(author_count_before_save, Author.count)
+ assert_equal(book_count_before_save, Book.count)
+ end
+
+ test "rollbacks whole transaction when associations fail to #save due to uniqueness validation failure" do
+ author_count_before_save = Author.count
+ book_count_before_save = Book.count
+
+ assert_no_difference "Author.count" do
+ assert_no_difference "Book.count" do
+ assert_nothing_raised do
+ result = @author.save
+
+ assert_not(result)
+ end
+ end
+ end
+
+ assert_equal(author_count_before_save, Author.count)
+ assert_equal(book_count_before_save, Book.count)
+ end
end
class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 4035347d4e..1324bdf9b8 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1141,11 +1141,14 @@ class BasicsTest < ActiveRecord::TestCase
def test_clear_cache!
# preheat cache
c1 = Post.connection.schema_cache.columns("posts")
+ assert_not_equal 0, Post.connection.schema_cache.size
+
ActiveRecord::Base.clear_cache!
+ assert_equal 0, Post.connection.schema_cache.size
+
c2 = Post.connection.schema_cache.columns("posts")
- c1.each_with_index do |v, i|
- assert_not_same v, c2[i]
- end
+ assert_not_equal 0, Post.connection.schema_cache.size
+
assert_equal c1, c2
end
@@ -1412,6 +1415,14 @@ class BasicsTest < ActiveRecord::TestCase
assert_not_includes SymbolIgnoredDeveloper.columns_hash.keys, "first_name"
end
+ test ".columns_hash raises an error if the record has an empty table name" do
+ expected_message = "FirstAbstractClass has no table configured. Set one with FirstAbstractClass.table_name="
+ exception = assert_raises(ActiveRecord::TableNotSpecified) do
+ FirstAbstractClass.columns_hash
+ end
+ assert_equal expected_message, exception.message
+ end
+
test "ignored columns have no attribute methods" do
assert_not_respond_to Developer.new, :first_name
assert_not_respond_to Developer.new, :first_name=
diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb
index cf6e280898..0d0bf39f79 100644
--- a/activerecord/test/cases/batches_test.rb
+++ b/activerecord/test/cases/batches_test.rb
@@ -146,7 +146,7 @@ class EachTest < ActiveRecord::TestCase
def test_find_in_batches_should_quote_batch_order
c = Post.connection
- assert_sql(/ORDER BY #{c.quote_table_name('posts')}\.#{c.quote_column_name('id')}/) do
+ assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name("posts.id"))}/i) do
Post.find_in_batches(batch_size: 1) do |batch|
assert_kind_of Array, batch
assert_kind_of Post, batch.first
diff --git a/activerecord/test/cases/bind_parameter_test.rb b/activerecord/test/cases/bind_parameter_test.rb
index 85685d1d00..720446b39d 100644
--- a/activerecord/test/cases/bind_parameter_test.rb
+++ b/activerecord/test/cases/bind_parameter_test.rb
@@ -93,7 +93,7 @@ if ActiveRecord::Base.connection.prepared_statements
def test_statement_cache_with_in_clause
@connection.clear_cache!
- topics = Topic.where(id: [1, 3])
+ topics = Topic.where(id: [1, 3]).order(:id)
assert_equal [1, 3], topics.map(&:id)
assert_not_includes statement_cache, to_sql_key(topics.arel)
end
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 5dabff1431..dbd1d03c4c 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -139,6 +139,13 @@ class CalculationsTest < ActiveRecord::TestCase
end
end
+ def test_should_not_use_alias_for_grouped_field
+ assert_sql(/GROUP BY #{Regexp.escape(Account.connection.quote_table_name("accounts.firm_id"))}/i) do
+ c = Account.group(:firm_id).order("accounts_firm_id").sum(:credit_limit)
+ assert_equal [1, 2, 6, 9], c.keys.compact
+ end
+ end
+
def test_should_order_by_grouped_field
c = Account.group(:firm_id).order("firm_id").sum(:credit_limit)
assert_equal [1, 2, 6, 9], c.keys.compact
@@ -767,6 +774,12 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal [[2, 2], [4, 4]], Reply.includes(:topic).pluck(:id, :"topics.id")
end
+ def test_group_by_with_order_by_virtual_count_attribute
+ expected = { "SpecialPost" => 1, "StiPost" => 2 }
+ actual = Post.group(:type).order(:count).limit(2).maximum(:comments_count)
+ assert_equal expected, actual
+ end if current_adapter?(:PostgreSQLAdapter)
+
def test_group_by_with_limit
expected = { "Post" => 8, "SpecialPost" => 1 }
actual = Post.includes(:comments).group(:type).order(:type).limit(2).count("comments.id")
diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
index 27589966af..843242a897 100644
--- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
@@ -29,7 +29,7 @@ module ActiveRecord
def test_establish_connection_uses_spec_name
old_config = ActiveRecord::Base.configurations
- config = { "readonly" => { "adapter" => "sqlite3" } }
+ config = { "readonly" => { "adapter" => "sqlite3", "pool" => "5" } }
ActiveRecord::Base.configurations = config
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(ActiveRecord::Base.configurations)
spec = resolver.spec(:readonly)
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 515bf5df06..15a045ed23 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
@@ -244,6 +244,25 @@ module ActiveRecord
assert_equal expected, actual
end
+ def test_no_url_sub_key_with_database_url_doesnt_trample_other_envs
+ ENV["DATABASE_URL"] = "postgres://localhost/baz"
+
+ config = { "default_env" => { "database" => "foo" }, "other_env" => { "url" => "postgres://foohost/bardb" } }
+ actual = resolve_config(config)
+ expected = { "default_env" =>
+ { "database" => "baz",
+ "adapter" => "postgresql",
+ "host" => "localhost"
+ },
+ "other_env" =>
+ { "adapter" => "postgresql",
+ "database" => "bardb",
+ "host" => "foohost"
+ }
+ }
+ assert_equal expected, actual
+ end
+
def test_merge_no_conflicts_with_database_url
ENV["DATABASE_URL"] = "postgres://localhost/foo"
@@ -273,6 +292,61 @@ module ActiveRecord
}
assert_equal expected, actual
end
+
+ def test_merge_no_conflicts_with_database_url_and_adapter
+ ENV["DATABASE_URL"] = "postgres://localhost/foo"
+
+ config = { "default_env" => { "adapter" => "postgresql", "pool" => "5" } }
+ actual = resolve_config(config)
+ expected = { "default_env" =>
+ { "adapter" => "postgresql",
+ "database" => "foo",
+ "host" => "localhost",
+ "pool" => "5"
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_merge_no_conflicts_with_database_url_and_numeric_pool
+ ENV["DATABASE_URL"] = "postgres://localhost/foo"
+
+ config = { "default_env" => { "pool" => 5 } }
+ actual = resolve_config(config)
+ expected = { "default_env" =>
+ { "adapter" => "postgresql",
+ "database" => "foo",
+ "host" => "localhost",
+ "pool" => 5
+ }
+ }
+
+ assert_equal expected, actual
+ end
+
+ def test_tiered_configs_with_database_url
+ ENV["DATABASE_URL"] = "postgres://localhost/foo"
+
+ config = {
+ "default_env" => {
+ "primary" => { "pool" => 5 },
+ "animals" => { "pool" => 5 }
+ }
+ }
+
+ expected = {
+ "adapter" => "postgresql",
+ "database" => "foo",
+ "host" => "localhost",
+ "pool" => 5
+ }
+
+ ["primary", "animals"].each do |spec_name|
+ configs = ActiveRecord::DatabaseConfigurations.new(config)
+ actual = configs.configs_for(env_name: "default_env", spec_name: spec_name).config
+ assert_equal expected, actual
+ end
+ end
end
end
end
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 bc823fd072..774380d7e0 100644
--- a/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb
+++ b/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb
@@ -40,7 +40,7 @@ if current_adapter?(:Mysql2Adapter)
end
def test_enum_type_with_value_matching_other_type
- assert_lookup_type :string, "ENUM('unicode', '8bit', 'none')"
+ assert_lookup_type :string, "ENUM('unicode', '8bit', 'none', 'time')"
end
def test_binary_types
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index ca114d468e..1f2058cc0a 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -245,7 +245,8 @@ class FinderTest < ActiveRecord::TestCase
end
def test_exists_does_not_select_columns_without_alias
- assert_sql(/SELECT\W+1 AS one FROM ["`]topics["`]/i) do
+ c = Topic.connection
+ assert_sql(/SELECT 1 AS one FROM #{Regexp.escape(c.quote_table_name("topics"))}/i) do
Topic.exists?
end
end
@@ -282,6 +283,11 @@ class FinderTest < ActiveRecord::TestCase
assert_not Post.select(:body).distinct.offset(4).exists?
end
+ def test_exists_with_distinct_and_offset_and_eagerload_and_order
+ assert Post.eager_load(:comments).distinct.offset(10).merge(Comment.order(post_id: :asc)).exists?
+ assert_not Post.eager_load(:comments).distinct.offset(11).merge(Comment.order(post_id: :asc)).exists?
+ end
+
# Ensure +exists?+ runs without an error by excluding distinct value.
# See https://github.com/rails/rails/pull/26981.
def test_exists_with_order_and_distinct
@@ -517,6 +523,7 @@ class FinderTest < ActiveRecord::TestCase
expected.touch # PostgreSQL changes the default order if no order clause is used
assert_equal expected, Topic.first
assert_equal expected, Topic.limit(5).first
+ assert_equal expected, Topic.order(nil).first
end
def test_model_class_responds_to_first_bang
@@ -540,6 +547,7 @@ class FinderTest < ActiveRecord::TestCase
expected.touch # PostgreSQL changes the default order if no order clause is used
assert_equal expected, Topic.second
assert_equal expected, Topic.limit(5).second
+ assert_equal expected, Topic.order(nil).second
end
def test_model_class_responds_to_second_bang
@@ -563,6 +571,7 @@ class FinderTest < ActiveRecord::TestCase
expected.touch # PostgreSQL changes the default order if no order clause is used
assert_equal expected, Topic.third
assert_equal expected, Topic.limit(5).third
+ assert_equal expected, Topic.order(nil).third
end
def test_model_class_responds_to_third_bang
@@ -586,6 +595,7 @@ class FinderTest < ActiveRecord::TestCase
expected.touch # PostgreSQL changes the default order if no order clause is used
assert_equal expected, Topic.fourth
assert_equal expected, Topic.limit(5).fourth
+ assert_equal expected, Topic.order(nil).fourth
end
def test_model_class_responds_to_fourth_bang
@@ -609,6 +619,7 @@ class FinderTest < ActiveRecord::TestCase
expected.touch # PostgreSQL changes the default order if no order clause is used
assert_equal expected, Topic.fifth
assert_equal expected, Topic.limit(5).fifth
+ assert_equal expected, Topic.order(nil).fifth
end
def test_model_class_responds_to_fifth_bang
@@ -777,6 +788,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal expected, clients.first(2)
assert_equal expected, clients.limit(5).first(2)
+ assert_equal expected, clients.order(nil).first(2)
end
def test_implicit_order_column_is_configurable
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index 629167e9ed..01e4878c3f 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -471,9 +471,9 @@ class InheritanceTest < ActiveRecord::TestCase
end
def test_eager_load_belongs_to_primary_key_quoting
- con = Account.connection
+ c = Account.connection
bind_param = Arel::Nodes::BindParam.new(nil)
- assert_sql(/#{con.quote_table_name('companies')}\.#{con.quote_column_name('id')} = (?:#{Regexp.quote(bind_param.to_sql)}|1)/) do
+ assert_sql(/#{Regexp.escape(c.quote_table_name("companies.id"))} = (?:#{Regexp.escape(bind_param.to_sql)}|1)/i) do
Account.all.merge!(includes: :firm).find(1)
end
end
diff --git a/activerecord/test/cases/json_serialization_test.rb b/activerecord/test/cases/json_serialization_test.rb
index 31691d83fc..d68e208617 100644
--- a/activerecord/test/cases/json_serialization_test.rb
+++ b/activerecord/test/cases/json_serialization_test.rb
@@ -23,7 +23,7 @@ class JsonSerializationTest < ActiveRecord::TestCase
include JsonSerializationHelpers
class NamespacedContact < Contact
- column :name, :string
+ column :name, "string"
end
def setup
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 53a4963909..79bd6906d1 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -536,6 +536,23 @@ class QueryCacheTest < ActiveRecord::TestCase
ActiveRecord::Base.connection_handlers = { writing: ActiveRecord::Base.default_connection_handler }
end
+ test "query cache is enabled in threads with shared connection" do
+ ActiveRecord::Base.connection_pool.lock_thread = true
+
+ assert_cache :off
+
+ thread_a = Thread.new do
+ middleware { |env|
+ assert_cache :clean
+ [200, {}, nil]
+ }.call({})
+ end
+
+ thread_a.join
+
+ ActiveRecord::Base.connection_pool.lock_thread = false
+ end
+
private
def with_temporary_connection_pool
old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index e0743de94b..e74fb1a098 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -363,6 +363,13 @@ module ActiveRecord
assert_match %r{/\*\+ BADHINT \*/}, post_with_hint.to_sql
end
+ def test_does_not_duplicate_optimizer_hints_on_merge
+ escaped_table = Post.connection.quote_table_name("posts")
+ expected = "SELECT /*+ OMGHINT */ #{escaped_table}.* FROM #{escaped_table}"
+ query = Post.optimizer_hints("OMGHINT").merge(Post.optimizer_hints("OMGHINT")).to_sql
+ assert_equal expected, query
+ end
+
class EnsureRoundTripTypeCasting < ActiveRecord::Type::Value
def type
:string
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index a5c162af33..1a20fe5dc2 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -308,9 +308,9 @@ class RelationTest < ActiveRecord::TestCase
end
def test_reverse_order_with_function_other_predicates
- topics = Topic.order(Arel.sql("author_name, length(title), id")).reverse_order
+ topics = Topic.order("author_name, length(title), id").reverse_order
assert_equal topics(:second).title, topics.first.title
- topics = Topic.order(Arel.sql("length(author_name), id, length(title)")).reverse_order
+ topics = Topic.order("length(author_name), id, length(title)").reverse_order
assert_equal topics(:fifth).title, topics.first.title
end
@@ -1955,8 +1955,8 @@ class RelationTest < ActiveRecord::TestCase
test "joins with order by custom attribute" do
companies = Company.create!([{ name: "test1" }, { name: "test2" }])
companies.each { |company| company.contracts.create! }
- assert_equal companies, Company.joins(:contracts).order(:metadata)
- assert_equal companies.reverse, Company.joins(:contracts).order(metadata: :desc)
+ assert_equal companies, Company.joins(:contracts).order(:metadata, :count)
+ assert_equal companies.reverse, Company.joins(:contracts).order(metadata: :desc, count: :desc)
end
test "delegations do not leak to other classes" do
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 49e9be9565..bb7184c5fc 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -33,6 +33,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
schema_info = ActiveRecord::Base.connection.dump_schema_information
assert_match(/20100201010101.*20100301010101/m, schema_info)
+ assert_includes schema_info, "20100101010101"
ensure
ActiveRecord::SchemaMigration.delete_all
end
diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb
index 2645776ab7..4dd8a4a82b 100644
--- a/activerecord/test/cases/validations/i18n_validation_test.rb
+++ b/activerecord/test/cases/validations/i18n_validation_test.rb
@@ -51,7 +51,7 @@ class I18nValidationTest < ActiveRecord::TestCase
test "validates_uniqueness_of on generated message #{name}" do
Topic.validates_uniqueness_of :title, validation_options
@topic.title = unique_topic.title
- assert_called_with(@topic.errors, :generate_message, [:title, :taken, generate_message_options.merge(value: "unique!")]) do
+ assert_called_with(ActiveModel::Error, :generate_message, [:title, :taken, @topic, generate_message_options.merge(value: "unique!")]) do
@topic.valid?
@topic.errors.messages
end
@@ -61,7 +61,7 @@ class I18nValidationTest < ActiveRecord::TestCase
COMMON_CASES.each do |name, validation_options, generate_message_options|
test "validates_associated on generated message #{name}" do
Topic.validates_associated :replies, validation_options
- assert_called_with(replied_topic.errors, :generate_message, [:replies, :invalid, generate_message_options.merge(value: replied_topic.replies)]) do
+ assert_called_with(ActiveModel::Error, :generate_message, [:replies, :invalid, replied_topic, generate_message_options.merge(value: replied_topic.replies)]) do
replied_topic.save
replied_topic.errors.messages
end
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index b52b643ad7..da7e4139b1 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -116,6 +116,7 @@ class Author < ActiveRecord::Base
has_many :tags_with_primary_key, through: :posts
has_many :books
+ has_many :published_books, class_name: "PublishedBook"
has_many :unpublished_books, -> { where(status: [:proposed, :written]) }, class_name: "Book"
has_many :subscriptions, through: :books
has_many :subscribers, -> { order("subscribers.nick") }, through: :subscriptions
diff --git a/activerecord/test/models/book.rb b/activerecord/test/models/book.rb
index afdda1a81e..43b82e6047 100644
--- a/activerecord/test/models/book.rb
+++ b/activerecord/test/models/book.rb
@@ -24,3 +24,9 @@ class Book < ActiveRecord::Base
"do publish work..."
end
end
+
+class PublishedBook < ActiveRecord::Base
+ self.table_name = "books"
+
+ validates_uniqueness_of :isbn
+end
diff --git a/activerecord/test/models/contact.rb b/activerecord/test/models/contact.rb
index 6e02ff199b..d5f6f00691 100644
--- a/activerecord/test/models/contact.rb
+++ b/activerecord/test/models/contact.rb
@@ -10,14 +10,14 @@ module ContactFakeColumns
table_name => "id"
}
- column :id, :integer
- column :name, :string
- column :age, :integer
- column :avatar, :binary
- column :created_at, :datetime
- column :awesome, :boolean
- column :preferences, :string
- column :alternative_id, :integer
+ column :id, "integer"
+ column :name, "string"
+ column :age, "integer"
+ column :avatar, "binary"
+ column :created_at, "datetime"
+ column :awesome, "boolean"
+ column :preferences, "string"
+ column :alternative_id, "integer"
serialize :preferences
@@ -37,7 +37,7 @@ end
class ContactSti < ActiveRecord::Base
extend ContactFakeColumns
- column :type, :string
+ column :type, "string"
def type; "ContactSti" end
end
diff --git a/activerecord/test/models/mouse.rb b/activerecord/test/models/mouse.rb
new file mode 100644
index 0000000000..75a55c125d
--- /dev/null
+++ b/activerecord/test/models/mouse.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+class Mouse < ActiveRecord::Base
+ has_many :squeaks, autosave: true
+ validates :name, presence: true
+end
diff --git a/activerecord/test/models/ship.rb b/activerecord/test/models/ship.rb
index 7973219a79..6bab7a1eb9 100644
--- a/activerecord/test/models/ship.rb
+++ b/activerecord/test/models/ship.rb
@@ -27,7 +27,8 @@ class ShipWithoutNestedAttributes < ActiveRecord::Base
has_many :prisoners, inverse_of: :ship, foreign_key: :ship_id
has_many :parts, class_name: "ShipPart", foreign_key: :ship_id
- validates :name, presence: true
+ validates :name, presence: true, if: -> { true }
+ validates :name, presence: true, if: -> { true }
end
class Prisoner < ActiveRecord::Base
diff --git a/activerecord/test/models/squeak.rb b/activerecord/test/models/squeak.rb
new file mode 100644
index 0000000000..e0a643c238
--- /dev/null
+++ b/activerecord/test/models/squeak.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+class Squeak < ActiveRecord::Base
+ belongs_to :mouse
+ accepts_nested_attributes_for :mouse
+end
diff --git a/activerecord/test/schema/mysql2_specific_schema.rb b/activerecord/test/schema/mysql2_specific_schema.rb
index b143035213..911ac808c6 100644
--- a/activerecord/test/schema/mysql2_specific_schema.rb
+++ b/activerecord/test/schema/mysql2_specific_schema.rb
@@ -62,10 +62,6 @@ ActiveRecord::Schema.define do
t.binary :binary_column, limit: 1
end
- create_table :enum_tests, id: false, force: true do |t|
- t.column :enum_column, "ENUM('text','blob','tiny','medium','long','unsigned','bigint')"
- end
-
execute "DROP PROCEDURE IF EXISTS ten"
execute <<~SQL
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 41920b3719..dd0ff759b6 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -115,7 +115,7 @@ ActiveRecord::Schema.define do
t.column :font_size, :integer, **default_zero
t.column :difficulty, :integer, **default_zero
t.column :cover, :string, default: "hard"
- t.string :isbn
+ t.string :isbn, **case_sensitive_options
t.datetime :published_on
t.index [:author_id, :name], unique: true
t.index :isbn, where: "published_on IS NOT NULL", unique: true
@@ -261,6 +261,7 @@ ActiveRecord::Schema.define do
t.references :developer, index: false
t.references :company, index: false
t.string :metadata
+ t.integer :count
end
create_table :customers, force: true do |t|
@@ -562,6 +563,10 @@ ActiveRecord::Schema.define do
t.string :type
end
+ create_table :mice, force: true do |t|
+ t.string :name
+ end
+
create_table :movies, force: true, id: false do |t|
t.primary_key :movieid
t.string :name
@@ -842,6 +847,10 @@ ActiveRecord::Schema.define do
end
end
+ create_table :squeaks, force: true do |t|
+ t.integer :mouse_id
+ end
+
create_table :prisoners, force: true do |t|
t.belongs_to :ship
end