aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r--activerecord/test/cases/adapter_test.rb71
-rw-r--r--activerecord/test/cases/adapters/mysql2/active_schema_test.rb51
-rw-r--r--activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb58
-rw-r--r--activerecord/test/cases/adapters/postgresql/active_schema_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/infinity_test.rb18
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb56
-rw-r--r--activerecord/test/cases/adapters/postgresql/quoting_test.rb5
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_test.rb20
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb56
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb18
-rw-r--r--activerecord/test/cases/aggregations_test.rb2
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb18
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb48
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb44
-rw-r--r--activerecord/test/cases/associations/required_test.rb50
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb6
-rw-r--r--activerecord/test/cases/base_test.rb60
-rw-r--r--activerecord/test/cases/calculations_test.rb12
-rw-r--r--activerecord/test/cases/callbacks_test.rb2
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb21
-rw-r--r--activerecord/test/cases/connection_pool_test.rb30
-rw-r--r--activerecord/test/cases/enum_test.rb9
-rw-r--r--activerecord/test/cases/errors_test.rb8
-rw-r--r--activerecord/test/cases/filter_attributes_test.rb32
-rw-r--r--activerecord/test/cases/finder_respond_to_test.rb6
-rw-r--r--activerecord/test/cases/finder_test.rb2
-rw-r--r--activerecord/test/cases/fixtures_test.rb14
-rw-r--r--activerecord/test/cases/habtm_destroy_order_test.rb28
-rw-r--r--activerecord/test/cases/migration/references_foreign_key_test.rb30
-rw-r--r--activerecord/test/cases/migration_test.rb44
-rw-r--r--activerecord/test/cases/multiple_db_test.rb12
-rw-r--r--activerecord/test/cases/pooled_connections_test.rb28
-rw-r--r--activerecord/test/cases/query_cache_test.rb117
-rw-r--r--activerecord/test/cases/relation/update_all_test.rb8
-rw-r--r--activerecord/test/cases/relations_test.rb39
-rw-r--r--activerecord/test/cases/scoping/relation_scoping_test.rb7
-rw-r--r--activerecord/test/cases/serialized_attribute_test.rb6
-rw-r--r--activerecord/test/cases/test_case.rb4
-rw-r--r--activerecord/test/cases/transactions_test.rb2
-rw-r--r--activerecord/test/cases/validations/absence_validation_test.rb2
-rw-r--r--activerecord/test/cases/validations/length_validation_test.rb2
-rw-r--r--activerecord/test/cases/validations/presence_validation_test.rb2
-rw-r--r--activerecord/test/cases/validations_test.rb7
44 files changed, 740 insertions, 327 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index e40ae3090c..66e594d771 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -132,19 +132,17 @@ module ActiveRecord
end
def test_not_specifying_database_name_for_cross_database_selects
- begin
- assert_nothing_raised do
- ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["arunit"].except(:database))
-
- config = ARTest.connection_config
- ActiveRecord::Base.connection.execute(
- "SELECT #{config['arunit']['database']}.pirates.*, #{config['arunit2']['database']}.courses.* " \
- "FROM #{config['arunit']['database']}.pirates, #{config['arunit2']['database']}.courses"
- )
- end
- ensure
- ActiveRecord::Base.establish_connection :arunit
+ assert_nothing_raised do
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["arunit"].except(:database))
+
+ config = ARTest.connection_config
+ ActiveRecord::Base.connection.execute(
+ "SELECT #{config['arunit']['database']}.pirates.*, #{config['arunit2']['database']}.courses.* " \
+ "FROM #{config['arunit']['database']}.pirates, #{config['arunit2']['database']}.courses"
+ )
end
+ ensure
+ ActiveRecord::Base.establish_connection :arunit
end
end
@@ -165,6 +163,55 @@ module ActiveRecord
end
end
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
+ assert_no_queries do
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @connection.while_preventing_writes do
+ @connection.transaction do
+ @connection.insert("INSERT INTO subscribers(nick) VALUES ('138853948594')", nil, false)
+ end
+ end
+ end
+ end
+ end
+
+ def test_errors_when_an_update_query_is_called_while_preventing_writes
+ @connection.insert("INSERT INTO subscribers(nick) VALUES ('138853948594')")
+
+ assert_no_queries do
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @connection.while_preventing_writes do
+ @connection.transaction do
+ @connection.update("UPDATE subscribers SET nick = '9989' WHERE nick = '138853948594'")
+ end
+ end
+ end
+ end
+ end
+
+ def test_errors_when_a_delete_query_is_called_while_preventing_writes
+ @connection.insert("INSERT INTO subscribers(nick) VALUES ('138853948594')")
+
+ assert_no_queries do
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @connection.while_preventing_writes do
+ @connection.transaction do
+ @connection.delete("DELETE FROM subscribers WHERE nick = '138853948594'")
+ end
+ end
+ end
+ end
+ end
+
+ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
+ @connection.insert("INSERT INTO subscribers(nick) VALUES ('138853948594')")
+
+ @connection.while_preventing_writes do
+ result = @connection.select_all("SELECT subscribers.* FROM subscribers WHERE nick = '138853948594'")
+ assert_equal 1, result.length
+ end
+ end
+
def test_uniqueness_violations_are_translated_to_specific_exception
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
error = assert_raises(ActiveRecord::RecordNotUnique) do
diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
index 261fee13eb..2d71ee2f15 100644
--- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
@@ -7,6 +7,7 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
include ConnectionHelper
def setup
+ ActiveRecord::Base.connection.send(:default_row_format)
ActiveRecord::Base.connection.singleton_class.class_eval do
alias_method :execute_without_stub, :execute
def execute(sql, name = nil) sql end
@@ -68,18 +69,18 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
def (ActiveRecord::Base.connection).data_source_exists?(*); false; end
%w(SPATIAL FULLTEXT UNIQUE).each do |type|
- expected = "CREATE TABLE `people` (#{type} INDEX `index_people_on_last_name` (`last_name`))"
+ expected = /\ACREATE TABLE `people` \(#{type} INDEX `index_people_on_last_name` \(`last_name`\)\)/
actual = ActiveRecord::Base.connection.create_table(:people, id: false) do |t|
t.index :last_name, type: type
end
- assert_equal expected, actual
+ assert_match expected, actual
end
- expected = "CREATE TABLE `people` ( INDEX `index_people_on_last_name` USING btree (`last_name`(10)))"
+ expected = /\ACREATE TABLE `people` \( INDEX `index_people_on_last_name` USING btree \(`last_name`\(10\)\)\)/
actual = ActiveRecord::Base.connection.create_table(:people, id: false) do |t|
t.index :last_name, length: 10, using: :btree
end
- assert_equal expected, actual
+ assert_match expected, actual
end
def test_index_in_bulk_change
@@ -106,7 +107,13 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
end
def test_create_mysql_database_with_encoding
- assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8mb4`", create_database(:matt)
+ if row_format_dynamic_by_default?
+ assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8mb4`", create_database(:matt)
+ else
+ error = assert_raises(RuntimeError) { create_database(:matt) }
+ expected = "Configure a supported :charset and ensure innodb_large_prefix is enabled to support indexes on varchar(255) string columns."
+ assert_equal expected, error.message
+ end
assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, charset: "latin1")
assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT COLLATE `utf8mb4_bin`", create_database(:matt_aimonetti, collation: "utf8mb4_bin")
end
@@ -130,29 +137,25 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
def test_add_timestamps
with_real_execute do
- begin
- ActiveRecord::Base.connection.create_table :delete_me
- ActiveRecord::Base.connection.add_timestamps :delete_me, null: true
- assert column_present?("delete_me", "updated_at", "datetime")
- assert column_present?("delete_me", "created_at", "datetime")
- ensure
- ActiveRecord::Base.connection.drop_table :delete_me rescue nil
- end
+ ActiveRecord::Base.connection.create_table :delete_me
+ ActiveRecord::Base.connection.add_timestamps :delete_me, null: true
+ assert column_present?("delete_me", "updated_at", "datetime")
+ assert column_present?("delete_me", "created_at", "datetime")
+ ensure
+ ActiveRecord::Base.connection.drop_table :delete_me rescue nil
end
end
def test_remove_timestamps
with_real_execute do
- begin
- ActiveRecord::Base.connection.create_table :delete_me do |t|
- t.timestamps null: true
- end
- ActiveRecord::Base.connection.remove_timestamps :delete_me, null: true
- assert_not column_present?("delete_me", "updated_at", "datetime")
- assert_not column_present?("delete_me", "created_at", "datetime")
- ensure
- ActiveRecord::Base.connection.drop_table :delete_me rescue nil
+ ActiveRecord::Base.connection.create_table :delete_me do |t|
+ t.timestamps null: true
end
+ ActiveRecord::Base.connection.remove_timestamps :delete_me, null: true
+ assert_not column_present?("delete_me", "updated_at", "datetime")
+ assert_not column_present?("delete_me", "created_at", "datetime")
+ ensure
+ ActiveRecord::Base.connection.drop_table :delete_me rescue nil
end
end
@@ -163,12 +166,12 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
[:temp],
returns: false
) do
- expected = "CREATE TEMPORARY TABLE `temp` ( INDEX `index_temp_on_zip` (`zip`)) AS SELECT id, name, zip FROM a_really_complicated_query"
+ expected = /\ACREATE TEMPORARY TABLE `temp` \( INDEX `index_temp_on_zip` \(`zip`\)\)(?: ROW_FORMAT=DYNAMIC)? AS SELECT id, name, zip FROM a_really_complicated_query/
actual = ActiveRecord::Base.connection.create_table(:temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query") do |t|
t.index :zip
end
- assert_equal expected, actual
+ assert_match expected, actual
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 0719baaa23..7bc86476b6 100644
--- a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
@@ -69,6 +69,64 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
@conn.exec_query("ALTER TABLE engines DROP COLUMN old_car_id")
end
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.insert("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
+ end
+ end
+ end
+
+ def test_errors_when_an_update_query_is_called_while_preventing_writes
+ @conn.insert("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.update("UPDATE `engines` SET `engines`.`car_id` = '9989' WHERE `engines`.`car_id` = '138853948594'")
+ end
+ end
+ end
+
+ def test_errors_when_a_delete_query_is_called_while_preventing_writes
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.execute("DELETE FROM `engines` where `engines`.`car_id` = '138853948594'")
+ end
+ end
+ end
+
+ def test_errors_when_a_replace_query_is_called_while_preventing_writes
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.execute("REPLACE INTO `engines` SET `engines`.`car_id` = '249823948'")
+ end
+ end
+ end
+
+ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
+
+ @conn.while_preventing_writes do
+ assert_equal 1, @conn.execute("SELECT `engines`.* FROM `engines` WHERE `engines`.`car_id` = '138853948594'").entries.count
+ end
+ end
+
+ def test_doesnt_error_when_a_show_query_is_called_while_preventing_writes
+ @conn.while_preventing_writes do
+ assert_equal 2, @conn.execute("SHOW FULL FIELDS FROM `engines`").entries.count
+ end
+ end
+
+ def test_doesnt_error_when_a_set_query_is_called_while_preventing_writes
+ @conn.while_preventing_writes do
+ assert_nil @conn.execute("SET NAMES utf8")
+ end
+ end
+
private
def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block)
diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
index afd422881b..62efaf3bfe 100644
--- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
@@ -29,7 +29,7 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
def test_add_index
# add_index calls index_name_exists? which can't work since execute is stubbed
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_exists?) { |*| false }
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.define_method(:index_name_exists?) { |*| false }
expected = %(CREATE UNIQUE INDEX "index_people_on_last_name" ON "people" ("last_name") WHERE state = 'active')
assert_equal expected, add_index(:people, :last_name, unique: true, where: "state = 'active'")
@@ -74,12 +74,12 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
add_index(:people, :last_name, algorithm: :copy)
end
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :remove_method, :index_name_exists?
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.remove_method :index_name_exists?
end
def test_remove_index
# remove_index calls index_name_for_remove which can't work since execute is stubbed
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_for_remove) do |*|
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.define_method(:index_name_for_remove) do |*|
"index_people_on_last_name"
end
@@ -90,7 +90,7 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
add_index(:people, :last_name, algorithm: :copy)
end
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :remove_method, :index_name_for_remove
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.remove_method :index_name_for_remove
end
def test_remove_index_when_name_is_specified
diff --git a/activerecord/test/cases/adapters/postgresql/infinity_test.rb b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
index 5e56ce8427..b1bf06d9e9 100644
--- a/activerecord/test/cases/adapters/postgresql/infinity_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
@@ -71,17 +71,15 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
end
test "assigning 'infinity' on a datetime column with TZ aware attributes" do
- begin
- in_time_zone "Pacific Time (US & Canada)" do
- record = PostgresqlInfinity.create!(datetime: "infinity")
- assert_equal Float::INFINITY, record.datetime
- assert_equal record.datetime, record.reload.datetime
- end
- ensure
- # setting time_zone_aware_attributes causes the types to change.
- # There is no way to do this automatically since it can be set on a superclass
- PostgresqlInfinity.reset_column_information
+ in_time_zone "Pacific Time (US & Canada)" do
+ record = PostgresqlInfinity.create!(datetime: "infinity")
+ assert_equal Float::INFINITY, record.datetime
+ assert_equal record.datetime, record.reload.datetime
end
+ ensure
+ # setting time_zone_aware_attributes causes the types to change.
+ # There is no way to do this automatically since it can be set on a superclass
+ PostgresqlInfinity.reset_column_information
end
test "where clause with infinite range on a datetime column" do
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index cbb6cd42b5..34b4fc344b 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -376,6 +376,62 @@ module ActiveRecord
end
end
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
+ with_example_table do
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @connection.while_preventing_writes do
+ @connection.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_an_update_query_is_called_while_preventing_writes
+ with_example_table do
+ @connection.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @connection.while_preventing_writes do
+ @connection.execute("UPDATE ex SET data = '9989' WHERE data = '138853948594'")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_a_delete_query_is_called_while_preventing_writes
+ with_example_table do
+ @connection.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @connection.while_preventing_writes do
+ @connection.execute("DELETE FROM ex where data = '138853948594'")
+ end
+ end
+ end
+ end
+
+ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
+ with_example_table do
+ @connection.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ @connection.while_preventing_writes do
+ assert_equal 1, @connection.execute("SELECT * FROM ex WHERE data = '138853948594'").entries.count
+ end
+ end
+ end
+
+ def test_doesnt_error_when_a_show_query_is_called_while_preventing_writes
+ @connection.while_preventing_writes do
+ assert_equal 1, @connection.execute("SHOW TIME ZONE").entries.count
+ end
+ end
+
+ def test_doesnt_error_when_a_set_query_is_called_while_preventing_writes
+ @connection.while_preventing_writes do
+ assert_equal [], @connection.execute("SET standard_conforming_strings = on").entries
+ end
+ end
+
private
def with_example_table(definition = "id serial primary key, number integer, data character varying(255)", &block)
diff --git a/activerecord/test/cases/adapters/postgresql/quoting_test.rb b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
index d50dc49276..d571355a9c 100644
--- a/activerecord/test/cases/adapters/postgresql/quoting_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
@@ -39,6 +39,11 @@ module ActiveRecord
type = OID::Bit.new
assert_nil @conn.quote(type.serialize(value))
end
+
+ def test_quote_table_name_with_spaces
+ value = "user posts"
+ assert_equal "\"user posts\"", @conn.quote_table_name(value)
+ end
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb
index 931a9bd0be..336cec30ca 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb
@@ -108,23 +108,19 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
end
def test_create_schema
- begin
- @connection.create_schema "test_schema3"
- assert @connection.schema_names.include? "test_schema3"
- ensure
- @connection.drop_schema "test_schema3"
- end
+ @connection.create_schema "test_schema3"
+ assert @connection.schema_names.include? "test_schema3"
+ ensure
+ @connection.drop_schema "test_schema3"
end
def test_raise_create_schema_with_existing_schema
- begin
+ @connection.create_schema "test_schema3"
+ assert_raises(ActiveRecord::StatementInvalid) do
@connection.create_schema "test_schema3"
- assert_raises(ActiveRecord::StatementInvalid) do
- @connection.create_schema "test_schema3"
- end
- ensure
- @connection.drop_schema "test_schema3"
end
+ ensure
+ @connection.drop_schema "test_schema3"
end
def test_drop_schema
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 8536dcf183..56ceb45040 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -573,6 +573,62 @@ module ActiveRecord
end
end
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_an_update_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.execute("UPDATE ex SET data = '9989' WHERE data = '138853948594'")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_a_delete_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.execute("DELETE FROM ex where data = '138853948594'")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_a_replace_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::ReadOnlyError) do
+ @conn.while_preventing_writes do
+ @conn.execute("REPLACE INTO ex (data) VALUES ('249823948')")
+ end
+ end
+ end
+ end
+
+ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ @conn.while_preventing_writes do
+ assert_equal 1, @conn.execute("SELECT data from ex WHERE data = '138853948594'").count
+ end
+ end
+ end
+
private
def assert_logged(logs)
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb
index d70486605f..cfc9853aba 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb
@@ -8,17 +8,15 @@ module ActiveRecord
class SQLite3CreateFolder < ActiveRecord::SQLite3TestCase
def test_sqlite_creates_directory
Dir.mktmpdir do |dir|
- begin
- dir = Pathname.new(dir)
- @conn = Base.sqlite3_connection database: dir.join("db/foo.sqlite3"),
- adapter: "sqlite3",
- timeout: 100
+ dir = Pathname.new(dir)
+ @conn = Base.sqlite3_connection database: dir.join("db/foo.sqlite3"),
+ adapter: "sqlite3",
+ timeout: 100
- assert Dir.exist? dir.join("db")
- assert File.exist? dir.join("db/foo.sqlite3")
- ensure
- @conn.disconnect! if @conn
- end
+ assert Dir.exist? dir.join("db")
+ assert File.exist? dir.join("db/foo.sqlite3")
+ ensure
+ @conn.disconnect! if @conn
end
end
end
diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb
index fbdf2ada4b..d270175af4 100644
--- a/activerecord/test/cases/aggregations_test.rb
+++ b/activerecord/test/cases/aggregations_test.rb
@@ -27,7 +27,7 @@ class AggregationsTest < ActiveRecord::TestCase
def test_immutable_value_objects
customers(:david).balance = Money.new(100)
- assert_raise(frozen_error_class) { customers(:david).balance.instance_eval { @amount = 20 } }
+ assert_raise(FrozenError) { customers(:david).balance.instance_eval { @amount = 20 } }
end
def test_inferred_mapping
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index d1e4ebe86b..acafbe0b4d 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -43,8 +43,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
def test_assigning_belongs_to_on_destroyed_object
client = Client.create!(name: "Client")
client.destroy!
- assert_raise(frozen_error_class) { client.firm = nil }
- assert_raise(frozen_error_class) { client.firm = Firm.new(name: "Firm") }
+ assert_raise(FrozenError) { client.firm = nil }
+ assert_raise(FrozenError) { client.firm = Firm.new(name: "Firm") }
end
def test_eager_loading_wont_mutate_owner_record
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 515eb65d37..fe8bdd03ba 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
@@ -1007,16 +1007,14 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
end
def test_has_and_belongs_to_many_while_partial_writes_false
- begin
- original_partial_writes = ActiveRecord::Base.partial_writes
- ActiveRecord::Base.partial_writes = false
- developer = Developer.new(name: "Mehmet Emin İNAÇ")
- developer.projects << Project.new(name: "Bounty")
-
- assert developer.save
- ensure
- ActiveRecord::Base.partial_writes = original_partial_writes
- end
+ original_partial_writes = ActiveRecord::Base.partial_writes
+ ActiveRecord::Base.partial_writes = false
+ developer = Developer.new(name: "Mehmet Emin İNAÇ")
+ developer.projects << Project.new(name: "Bounty")
+
+ assert developer.save
+ ensure
+ ActiveRecord::Base.partial_writes = original_partial_writes
end
def test_has_and_belongs_to_many_with_belongs_to
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 6024a9e354..5921193374 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -264,7 +264,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
car = Car.create(name: "honda")
car.funky_bulbs.create!
assert_equal 1, car.funky_bulbs.count
- assert_nothing_raised { car.reload.funky_bulbs.delete_all }
+ assert_equal 1, car.reload.funky_bulbs.delete_all
assert_equal 0, car.funky_bulbs.count, "bulbs should have been deleted using :delete_all strategy"
end
@@ -294,6 +294,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal(expected_sql, loaded_sql)
end
+ def test_delete_all_on_association_clears_scope
+ author = Author.create!(name: "Gannon")
+ posts = author.posts
+ posts.create!(title: "test", body: "body")
+ posts.delete_all
+ assert_nil posts.first
+ end
+
def test_building_the_associated_object_with_implicit_sti_base_class
firm = DependentFirm.new
company = firm.companies.build
@@ -1405,7 +1413,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 3, clients.count
assert_difference "Client.count", -(clients.count) do
- companies(:first_firm).dependent_clients_of_firm.delete_all
+ assert_equal clients.count, companies(:first_firm).dependent_clients_of_firm.delete_all
end
end
@@ -1502,10 +1510,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_delete_all_with_option_delete_all
firm = companies(:first_firm)
client_id = firm.dependent_clients_of_firm.first.id
- firm.dependent_clients_of_firm.delete_all(:delete_all)
+ count = firm.dependent_clients_of_firm.count
+ assert_equal count, firm.dependent_clients_of_firm.delete_all(:delete_all)
assert_nil Client.find_by_id(client_id)
end
+ def test_delete_all_with_option_nullify
+ firm = companies(:first_firm)
+ client_id = firm.dependent_clients_of_firm.first.id
+ count = firm.dependent_clients_of_firm.count
+ assert_equal firm, Client.find(client_id).firm
+ assert_equal count, firm.dependent_clients_of_firm.delete_all(:nullify)
+ assert_nil Client.find(client_id).firm
+ end
+
def test_delete_all_accepts_limited_parameters
firm = companies(:first_firm)
assert_raise(ArgumentError) do
@@ -1710,6 +1728,30 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert companies(:first_firm).clients_of_firm.reload.empty?, "37signals has no clients after destroy all and refresh"
end
+ def test_destroy_all_on_association_clears_scope
+ author = Author.create!(name: "Gannon")
+ posts = author.posts
+ posts.create!(title: "test", body: "body")
+ posts.destroy_all
+ assert_nil posts.first
+ end
+
+ def test_destroy_on_association_clears_scope
+ author = Author.create!(name: "Gannon")
+ posts = author.posts
+ post = posts.create!(title: "test", body: "body")
+ posts.destroy(post)
+ assert_nil posts.first
+ end
+
+ def test_delete_on_association_clears_scope
+ author = Author.create!(name: "Gannon")
+ posts = author.posts
+ post = posts.create!(title: "test", body: "body")
+ posts.delete(post)
+ assert_nil posts.first
+ end
+
def test_dependence
firm = companies(:first_firm)
assert_equal 3, firm.clients.size
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index cf514957ca..bd535357ee 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -200,7 +200,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_no_difference "Job.count" do
assert_difference "Reference.count", -1 do
- person.reload.jobs_with_dependent_destroy.delete_all
+ assert_equal 1, person.reload.jobs_with_dependent_destroy.delete_all
end
end
end
@@ -211,7 +211,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_no_difference "Job.count" do
assert_no_difference "Reference.count" do
- person.reload.jobs_with_dependent_nullify.delete_all
+ assert_equal 1, person.reload.jobs_with_dependent_nullify.delete_all
end
end
end
@@ -222,11 +222,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_no_difference "Job.count" do
assert_difference "Reference.count", -1 do
- person.reload.jobs_with_dependent_delete_all.delete_all
+ assert_equal 1, person.reload.jobs_with_dependent_delete_all.delete_all
end
end
end
+ def test_delete_all_on_association_clears_scope
+ post = Post.create!(title: "Rails 6", body: "")
+ people = post.people
+ people.create!(first_name: "Jeb")
+ people.delete_all
+ assert_nil people.first
+ end
+
def test_concat
person = people(:david)
post = posts(:thinking)
@@ -366,7 +374,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
end
def test_delete_association
- assert_queries(2) { posts(:welcome);people(:michael); }
+ assert_queries(2) { posts(:welcome); people(:michael); }
assert_queries(1) do
posts(:welcome).people.delete(people(:michael))
@@ -401,6 +409,30 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_empty posts(:welcome).people.reload
end
+ def test_destroy_all_on_association_clears_scope
+ post = Post.create!(title: "Rails 6", body: "")
+ people = post.people
+ people.create!(first_name: "Jeb")
+ people.destroy_all
+ assert_nil people.first
+ end
+
+ def test_destroy_on_association_clears_scope
+ post = Post.create!(title: "Rails 6", body: "")
+ people = post.people
+ person = people.create!(first_name: "Jeb")
+ people.destroy(person)
+ assert_nil people.first
+ end
+
+ def test_delete_on_association_clears_scope
+ post = Post.create!(title: "Rails 6", body: "")
+ people = post.people
+ person = people.create!(first_name: "Jeb")
+ people.delete(person)
+ assert_nil people.first
+ end
+
def test_should_raise_exception_for_destroying_mismatching_records
assert_no_difference ["Person.count", "Reader.count"] do
assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:welcome).people.destroy(posts(:thinking)) }
@@ -569,7 +601,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
end
def test_replace_association
- assert_queries(4) { posts(:welcome);people(:david);people(:michael); posts(:welcome).people.reload }
+ assert_queries(4) { posts(:welcome); people(:david); people(:michael); posts(:welcome).people.reload }
# 1 query to delete the existing reader (michael)
# 1 query to associate the new reader (david)
@@ -708,7 +740,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
end
def test_clear_associations
- assert_queries(2) { posts(:welcome);posts(:welcome).people.reload }
+ assert_queries(2) { posts(:welcome); posts(:welcome).people.reload }
assert_queries(1) do
posts(:welcome).people.clear
diff --git a/activerecord/test/cases/associations/required_test.rb b/activerecord/test/cases/associations/required_test.rb
index 65a3bb5efe..c7a78e6bc4 100644
--- a/activerecord/test/cases/associations/required_test.rb
+++ b/activerecord/test/cases/associations/required_test.rb
@@ -25,20 +25,18 @@ class RequiredAssociationsTest < ActiveRecord::TestCase
end
test "belongs_to associations can be optional by default" do
- begin
- original_value = ActiveRecord::Base.belongs_to_required_by_default
- ActiveRecord::Base.belongs_to_required_by_default = false
+ original_value = ActiveRecord::Base.belongs_to_required_by_default
+ ActiveRecord::Base.belongs_to_required_by_default = false
- model = subclass_of(Child) do
- belongs_to :parent, inverse_of: false,
- class_name: "RequiredAssociationsTest::Parent"
- end
-
- assert model.new.save
- assert model.new(parent: Parent.new).save
- ensure
- ActiveRecord::Base.belongs_to_required_by_default = original_value
+ model = subclass_of(Child) do
+ belongs_to :parent, inverse_of: false,
+ class_name: "RequiredAssociationsTest::Parent"
end
+
+ assert model.new.save
+ assert model.new(parent: Parent.new).save
+ ensure
+ ActiveRecord::Base.belongs_to_required_by_default = original_value
end
test "required belongs_to associations have presence validated" do
@@ -56,24 +54,22 @@ class RequiredAssociationsTest < ActiveRecord::TestCase
end
test "belongs_to associations can be required by default" do
- begin
- original_value = ActiveRecord::Base.belongs_to_required_by_default
- ActiveRecord::Base.belongs_to_required_by_default = true
+ original_value = ActiveRecord::Base.belongs_to_required_by_default
+ ActiveRecord::Base.belongs_to_required_by_default = true
- model = subclass_of(Child) do
- belongs_to :parent, inverse_of: false,
- class_name: "RequiredAssociationsTest::Parent"
- end
+ model = subclass_of(Child) do
+ belongs_to :parent, inverse_of: false,
+ class_name: "RequiredAssociationsTest::Parent"
+ end
- record = model.new
- assert_not record.save
- assert_equal ["Parent must exist"], record.errors.full_messages
+ record = model.new
+ assert_not record.save
+ assert_equal ["Parent must exist"], record.errors.full_messages
- record.parent = Parent.new
- assert record.save
- ensure
- ActiveRecord::Base.belongs_to_required_by_default = original_value
- end
+ record.parent = Parent.new
+ assert record.save
+ ensure
+ ActiveRecord::Base.belongs_to_required_by_default = original_value
end
test "has_one associations are not required by default" do
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index 12a4027a4e..d341dd0083 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -323,6 +323,12 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert_raises(ActiveModel::UnknownAttributeError) { topic.update(no_column_exists: "Hello!") }
end
+ test "write_attribute allows writing to aliased attributes" do
+ topic = Topic.first
+ assert_nothing_raised { topic.update_columns(heading: "Hello!") }
+ assert_nothing_raised { topic.update(heading: "Hello!") }
+ end
+
test "read_attribute" do
topic = Topic.new
topic.title = "Don't change the topic"
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 63a73101c4..4938b6865f 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1488,4 +1488,64 @@ class BasicsTest < ActiveRecord::TestCase
ensure
ActiveRecord::Base.protected_environments = previous_protected_environments
end
+
+ test "creating a record raises if preventing writes" do
+ error = assert_raises ActiveRecord::ReadOnlyError do
+ ActiveRecord::Base.connection.while_preventing_writes do
+ Bird.create! name: "Bluejay"
+ end
+ end
+
+ assert_match %r/\AWrite query attempted while in readonly mode: INSERT /, error.message
+ end
+
+ test "updating a record raises if preventing writes" do
+ bird = Bird.create! name: "Bluejay"
+
+ error = assert_raises ActiveRecord::ReadOnlyError do
+ ActiveRecord::Base.connection.while_preventing_writes do
+ bird.update! name: "Robin"
+ end
+ end
+
+ assert_match %r/\AWrite query attempted while in readonly mode: UPDATE /, error.message
+ end
+
+ test "deleting a record raises if preventing writes" do
+ bird = Bird.create! name: "Bluejay"
+
+ error = assert_raises ActiveRecord::ReadOnlyError do
+ ActiveRecord::Base.connection.while_preventing_writes do
+ bird.destroy!
+ end
+ end
+
+ assert_match %r/\AWrite query attempted while in readonly mode: DELETE /, error.message
+ end
+
+ test "selecting a record does not raise if preventing writes" do
+ bird = Bird.create! name: "Bluejay"
+
+ ActiveRecord::Base.connection.while_preventing_writes do
+ assert_equal bird, Bird.where(name: "Bluejay").first
+ end
+ end
+
+ test "an explain query does not raise if preventing writes" do
+ Bird.create!(name: "Bluejay")
+
+ ActiveRecord::Base.connection.while_preventing_writes do
+ assert_queries(2) { Bird.where(name: "Bluejay").explain }
+ end
+ end
+
+ test "an empty transaction does not raise if preventing writes" do
+ ActiveRecord::Base.connection.while_preventing_writes do
+ assert_queries(2, ignore_none: true) do
+ Bird.transaction do
+ ActiveRecord::Base.connection.materialize_transactions
+ end
+ end
+ end
+ end
end
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 97bce90c8b..4d3db912c5 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -57,8 +57,12 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal 3, value
end
- def test_should_return_nil_as_average
- assert_nil NumericData.average(:bank_balance)
+ def test_should_return_nil_to_d_as_average
+ if nil.respond_to?(:to_d)
+ assert_equal BigDecimal(0), NumericData.average(:bank_balance)
+ else
+ assert_nil NumericData.average(:bank_balance)
+ end
end
def test_should_get_maximum_of_field
@@ -717,6 +721,10 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal [], Topic.includes(:replies).order(:id).offset(5).pluck(:id)
end
+ def test_pluck_with_join
+ assert_equal [[2, 2], [4, 4]], Reply.includes(:topic).pluck(:id, :"topics.id")
+ end
+
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/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb
index 0ea3fb86a6..4d6a112af5 100644
--- a/activerecord/test/cases/callbacks_test.rb
+++ b/activerecord/test/cases/callbacks_test.rb
@@ -21,7 +21,7 @@ class CallbackDeveloper < ActiveRecord::Base
def callback_object(callback_method)
klass = Class.new
- klass.send(:define_method, callback_method) do |model|
+ klass.define_method(callback_method) do |model|
model.history << [callback_method, :object]
end
klass.new
diff --git a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
index 393b577c1d..0b3fb82e12 100644
--- a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
@@ -108,11 +108,15 @@ module ActiveRecord
ActiveRecord::Base.connected_to(role: :reading) do
@ro_handler = ActiveRecord::Base.connection_handler
assert_equal ActiveRecord::Base.connection_handler, ActiveRecord::Base.connection_handlers[:reading]
+ assert ActiveRecord::Base.connected_to?(role: :reading)
+ assert_not ActiveRecord::Base.connected_to?(role: :writing)
end
ActiveRecord::Base.connected_to(role: :writing) do
assert_equal ActiveRecord::Base.connection_handler, ActiveRecord::Base.connection_handlers[:writing]
assert_not_equal @ro_handler, ActiveRecord::Base.connection_handler
+ assert ActiveRecord::Base.connected_to?(role: :writing)
+ assert_not ActiveRecord::Base.connected_to?(role: :reading)
end
ensure
ActiveRecord::Base.configurations = @prev_configs
@@ -125,6 +129,8 @@ module ActiveRecord
previous_url, ENV["DATABASE_URL"] = ENV["DATABASE_URL"], "postgres://localhost/foo"
ActiveRecord::Base.connected_to(database: { writing: "postgres://localhost/bar" }) do
+ assert ActiveRecord::Base.connected_to?(role: :writing)
+
handler = ActiveRecord::Base.connection_handler
assert_equal handler, ActiveRecord::Base.connection_handlers[:writing]
@@ -142,6 +148,8 @@ module ActiveRecord
config = { adapter: "sqlite3", database: "db/readonly.sqlite3" }
ActiveRecord::Base.connected_to(database: { writing: config }) do
+ assert ActiveRecord::Base.connected_to?(role: :writing)
+
handler = ActiveRecord::Base.connection_handler
assert_equal handler, ActiveRecord::Base.connection_handlers[:writing]
@@ -179,6 +187,8 @@ module ActiveRecord
@prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
ActiveRecord::Base.connected_to(database: :readonly) do
+ assert ActiveRecord::Base.connected_to?(role: :readonly)
+
handler = ActiveRecord::Base.connection_handler
assert_equal handler, ActiveRecord::Base.connection_handlers[:readonly]
@@ -201,6 +211,7 @@ module ActiveRecord
assert_equal 1, ActiveRecord::Base.connection_handlers.size
assert_equal ActiveRecord::Base.connection_handler, ActiveRecord::Base.connection_handlers[:writing]
+ assert ActiveRecord::Base.connected_to?(role: :writing)
ensure
ActiveRecord::Base.configurations = @prev_configs
ActiveRecord::Base.establish_connection(:arunit)
@@ -317,6 +328,16 @@ module ActiveRecord
ensure
ActiveRecord::Base.connection_handlers = original_handlers
end
+
+ def test_calling_connected_to_on_a_non_existent_handler_raises
+ error = assert_raises ArgumentError do
+ ActiveRecord::Base.connected_to(role: :reading) do
+ yield
+ end
+ end
+
+ assert_equal "The reading role does not exist. Add it by establishing a connection with `connects_to` or use an existing role (writing).", error.message
+ end
end
end
end
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index 633d56e479..a15ad9a45b 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -567,23 +567,21 @@ module ActiveRecord
def test_disconnect_and_clear_reloadable_connections_attempt_to_wait_for_threads_to_return_their_conns
[:disconnect, :disconnect!, :clear_reloadable_connections, :clear_reloadable_connections!].each do |group_action_method|
- begin
- thread = timed_join_result = nil
- @pool.with_connection do |connection|
- thread = Thread.new { @pool.send(group_action_method) }
-
- # give the other `thread` some time to get stuck in `group_action_method`
- timed_join_result = thread.join(0.3)
- # thread.join # => `nil` means the other thread hasn't finished running and is still waiting for us to
- # release our connection
- assert_nil timed_join_result
-
- # assert that since this is within default timeout our connection hasn't been forcefully taken away from us
- assert_predicate @pool, :active_connection?
- end
- ensure
- thread.join if thread && !timed_join_result # clean up the other thread
+ thread = timed_join_result = nil
+ @pool.with_connection do |connection|
+ thread = Thread.new { @pool.send(group_action_method) }
+
+ # give the other `thread` some time to get stuck in `group_action_method`
+ timed_join_result = thread.join(0.3)
+ # thread.join # => `nil` means the other thread hasn't finished running and is still waiting for us to
+ # release our connection
+ assert_nil timed_join_result
+
+ # assert that since this is within default timeout our connection hasn't been forcefully taken away from us
+ assert_predicate @pool, :active_connection?
end
+ ensure
+ thread.join if thread && !timed_join_result # clean up the other thread
end
end
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index fef06e6edd..8a0f6f6df1 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -551,4 +551,13 @@ class EnumTest < ActiveRecord::TestCase
test "data type of Enum type" do
assert_equal :integer, Book.type_for_attribute("status").type
end
+
+ test "scopes can be disabled" do
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = "books"
+ enum status: [:proposed, :written], _scopes: false
+ end
+
+ assert_raises(NoMethodError) { klass.proposed }
+ end
end
diff --git a/activerecord/test/cases/errors_test.rb b/activerecord/test/cases/errors_test.rb
index b90e6a66c5..0d2be944b5 100644
--- a/activerecord/test/cases/errors_test.rb
+++ b/activerecord/test/cases/errors_test.rb
@@ -8,11 +8,9 @@ class ErrorsTest < ActiveRecord::TestCase
error_klasses = ObjectSpace.each_object(Class).select { |klass| klass < base }
(error_klasses - [ActiveRecord::AmbiguousSourceReflectionForThroughAssociation]).each do |error_klass|
- begin
- error_klass.new.inspect
- rescue ArgumentError
- raise "Instance of #{error_klass} can't be initialized with no arguments"
- end
+ error_klass.new.inspect
+ rescue ArgumentError
+ raise "Instance of #{error_klass} can't be initialized with no arguments"
end
end
end
diff --git a/activerecord/test/cases/filter_attributes_test.rb b/activerecord/test/cases/filter_attributes_test.rb
index 47161a547a..2f4c9b0ef7 100644
--- a/activerecord/test/cases/filter_attributes_test.rb
+++ b/activerecord/test/cases/filter_attributes_test.rb
@@ -90,15 +90,13 @@ class FilterAttributesTest < ActiveRecord::TestCase
end
test "filter_attributes should handle [FILTERED] value properly" do
- begin
- User.filter_attributes = ["auth"]
- user = User.new(token: "[FILTERED]", auth_token: "[FILTERED]")
+ User.filter_attributes = ["auth"]
+ user = User.new(token: "[FILTERED]", auth_token: "[FILTERED]")
- assert_includes user.inspect, "auth_token: [FILTERED]"
- assert_includes user.inspect, 'token: "[FILTERED]"'
- ensure
- User.remove_instance_variable(:@filter_attributes)
- end
+ assert_includes user.inspect, "auth_token: [FILTERED]"
+ assert_includes user.inspect, 'token: "[FILTERED]"'
+ ensure
+ User.remove_instance_variable(:@filter_attributes)
end
test "filter_attributes on pretty_print" do
@@ -121,16 +119,14 @@ class FilterAttributesTest < ActiveRecord::TestCase
end
test "filter_attributes on pretty_print should handle [FILTERED] value properly" do
- begin
- User.filter_attributes = ["auth"]
- user = User.new(token: "[FILTERED]", auth_token: "[FILTERED]")
- actual = "".dup
- PP.pp(user, StringIO.new(actual))
+ User.filter_attributes = ["auth"]
+ user = User.new(token: "[FILTERED]", auth_token: "[FILTERED]")
+ actual = "".dup
+ PP.pp(user, StringIO.new(actual))
- assert_includes actual, "auth_token: [FILTERED]"
- assert_includes actual, 'token: "[FILTERED]"'
- ensure
- User.remove_instance_variable(:@filter_attributes)
- end
+ assert_includes actual, "auth_token: [FILTERED]"
+ assert_includes actual, 'token: "[FILTERED]"'
+ ensure
+ User.remove_instance_variable(:@filter_attributes)
end
end
diff --git a/activerecord/test/cases/finder_respond_to_test.rb b/activerecord/test/cases/finder_respond_to_test.rb
index e0acd30c22..66413a98e4 100644
--- a/activerecord/test/cases/finder_respond_to_test.rb
+++ b/activerecord/test/cases/finder_respond_to_test.rb
@@ -12,10 +12,10 @@ class FinderRespondToTest < ActiveRecord::TestCase
end
def test_should_preserve_normal_respond_to_behaviour_and_respond_to_newly_added_method
- class << Topic; self; end.send(:define_method, :method_added_for_finder_respond_to_test) { }
+ Topic.singleton_class.define_method(:method_added_for_finder_respond_to_test) { }
assert_respond_to Topic, :method_added_for_finder_respond_to_test
ensure
- class << Topic; self; end.send(:remove_method, :method_added_for_finder_respond_to_test)
+ Topic.singleton_class.remove_method :method_added_for_finder_respond_to_test
end
def test_should_preserve_normal_respond_to_behaviour_and_respond_to_standard_object_method
@@ -56,6 +56,6 @@ class FinderRespondToTest < ActiveRecord::TestCase
private
def ensure_topic_method_is_not_cached(method_id)
- class << Topic; self; end.send(:remove_method, method_id) if Topic.public_methods.include? method_id
+ Topic.singleton_class.remove_method method_id if Topic.public_methods.include? method_id
end
end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 21e84d850b..961ae03a4c 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -1116,7 +1116,7 @@ class FinderTest < ActiveRecord::TestCase
def test_dynamic_finder_on_one_attribute_with_conditions_returns_same_results_after_caching
# ensure this test can run independently of order
- class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.public_methods.include?(:find_by_credit_limit)
+ Account.singleton_class.remove_method :find_by_credit_limit if Account.public_methods.include?(:find_by_credit_limit)
a = Account.where("firm_id = ?", 6).find_by_credit_limit(50)
assert_equal a, Account.where("firm_id = ?", 6).find_by_credit_limit(50) # find_by_credit_limit has been cached
end
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index a5592fc86a..fe2f417a04 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -73,14 +73,12 @@ class FixturesTest < ActiveRecord::TestCase
if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)
def test_bulk_insert
- begin
- subscriber = InsertQuerySubscriber.new
- subscription = ActiveSupport::Notifications.subscribe("sql.active_record", subscriber)
- create_fixtures("bulbs")
- assert_equal 1, subscriber.events.size, "It takes one INSERT query to insert two fixtures"
- ensure
- ActiveSupport::Notifications.unsubscribe(subscription)
- end
+ subscriber = InsertQuerySubscriber.new
+ subscription = ActiveSupport::Notifications.subscribe("sql.active_record", subscriber)
+ create_fixtures("bulbs")
+ assert_equal 1, subscriber.events.size, "It takes one INSERT query to insert two fixtures"
+ ensure
+ ActiveSupport::Notifications.unsubscribe(subscription)
end
def test_bulk_insert_multiple_table_with_a_multi_statement_query
diff --git a/activerecord/test/cases/habtm_destroy_order_test.rb b/activerecord/test/cases/habtm_destroy_order_test.rb
index b15e1b48c4..9dbd339fe7 100644
--- a/activerecord/test/cases/habtm_destroy_order_test.rb
+++ b/activerecord/test/cases/habtm_destroy_order_test.rb
@@ -30,23 +30,21 @@ class HabtmDestroyOrderTest < ActiveRecord::TestCase
test "not destroying a student with lessons leaves student<=>lesson association intact" do
# test a normal before_destroy doesn't destroy the habtm joins
- begin
- sicp = Lesson.new(name: "SICP")
- ben = Student.new(name: "Ben Bitdiddle")
- # add a before destroy to student
- Student.class_eval do
- before_destroy do
- raise ActiveRecord::Rollback unless lessons.empty?
- end
+ sicp = Lesson.new(name: "SICP")
+ ben = Student.new(name: "Ben Bitdiddle")
+ # add a before destroy to student
+ Student.class_eval do
+ before_destroy do
+ raise ActiveRecord::Rollback unless lessons.empty?
end
- ben.lessons << sicp
- ben.save!
- ben.destroy
- assert_not_empty ben.reload.lessons
- ensure
- # get rid of it so Student is still like it was
- Student.reset_callbacks(:destroy)
end
+ ben.lessons << sicp
+ ben.save!
+ ben.destroy
+ assert_not_empty ben.reload.lessons
+ ensure
+ # get rid of it so Student is still like it was
+ Student.reset_callbacks(:destroy)
end
test "not destroying a lesson with students leaves student<=>lesson association intact" do
diff --git a/activerecord/test/cases/migration/references_foreign_key_test.rb b/activerecord/test/cases/migration/references_foreign_key_test.rb
index 7a092103c7..620e9ab6ca 100644
--- a/activerecord/test/cases/migration/references_foreign_key_test.rb
+++ b/activerecord/test/cases/migration/references_foreign_key_test.rb
@@ -152,25 +152,23 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
end
test "foreign key methods respect pluralize_table_names" do
- begin
- original_pluralize_table_names = ActiveRecord::Base.pluralize_table_names
- ActiveRecord::Base.pluralize_table_names = false
- @connection.create_table :testing
- @connection.change_table :testing_parents do |t|
- t.references :testing, foreign_key: true
- end
+ original_pluralize_table_names = ActiveRecord::Base.pluralize_table_names
+ ActiveRecord::Base.pluralize_table_names = false
+ @connection.create_table :testing
+ @connection.change_table :testing_parents do |t|
+ t.references :testing, foreign_key: true
+ end
- fk = @connection.foreign_keys("testing_parents").first
- assert_equal "testing_parents", fk.from_table
- assert_equal "testing", fk.to_table
+ fk = @connection.foreign_keys("testing_parents").first
+ assert_equal "testing_parents", fk.from_table
+ assert_equal "testing", fk.to_table
- assert_difference "@connection.foreign_keys('testing_parents').size", -1 do
- @connection.remove_reference :testing_parents, :testing, foreign_key: true
- end
- ensure
- ActiveRecord::Base.pluralize_table_names = original_pluralize_table_names
- @connection.drop_table "testing", if_exists: true
+ assert_difference "@connection.foreign_keys('testing_parents').size", -1 do
+ @connection.remove_reference :testing_parents, :testing, foreign_key: true
end
+ ensure
+ ActiveRecord::Base.pluralize_table_names = original_pluralize_table_names
+ @connection.drop_table "testing", if_exists: true
end
class CreateDogsMigration < ActiveRecord::Migration::Current
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 661163b4a1..8b0ecd2516 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -576,29 +576,25 @@ class MigrationTest < ActiveRecord::TestCase
# table name is 29 chars, the standard sequence name will
# be 33 chars and should be shortened
assert_nothing_raised do
- begin
- Person.connection.create_table :table_with_name_thats_just_ok do |t|
- t.column :foo, :string, null: false
- end
- ensure
- Person.connection.drop_table :table_with_name_thats_just_ok rescue nil
+ Person.connection.create_table :table_with_name_thats_just_ok do |t|
+ t.column :foo, :string, null: false
end
+ ensure
+ Person.connection.drop_table :table_with_name_thats_just_ok rescue nil
end
# should be all good w/ a custom sequence name
assert_nothing_raised do
- begin
- Person.connection.create_table :table_with_name_thats_just_ok,
- sequence_name: "suitably_short_seq" do |t|
- t.column :foo, :string, null: false
- end
+ Person.connection.create_table :table_with_name_thats_just_ok,
+ sequence_name: "suitably_short_seq" do |t|
+ t.column :foo, :string, null: false
+ end
- Person.connection.execute("select suitably_short_seq.nextval from dual")
+ Person.connection.execute("select suitably_short_seq.nextval from dual")
- ensure
- Person.connection.drop_table :table_with_name_thats_just_ok,
- sequence_name: "suitably_short_seq" rescue nil
- end
+ ensure
+ Person.connection.drop_table :table_with_name_thats_just_ok,
+ sequence_name: "suitably_short_seq" rescue nil
end
# confirm the custom sequence got dropped
@@ -742,15 +738,13 @@ class MigrationTest < ActiveRecord::TestCase
test_terminated = Concurrent::CountDownLatch.new
other_process = Thread.new do
- begin
- conn = ActiveRecord::Base.connection_pool.checkout
- conn.get_advisory_lock(lock_id)
- thread_lock.count_down
- test_terminated.wait # hold the lock open until we tested everything
- ensure
- conn.release_advisory_lock(lock_id)
- ActiveRecord::Base.connection_pool.checkin(conn)
- end
+ conn = ActiveRecord::Base.connection_pool.checkout
+ conn.get_advisory_lock(lock_id)
+ thread_lock.count_down
+ test_terminated.wait # hold the lock open until we tested everything
+ ensure
+ conn.release_advisory_lock(lock_id)
+ ActiveRecord::Base.connection_pool.checkin(conn)
end
thread_lock.wait # wait until the 'other process' has the lock
diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb
index 192d2f5251..f11c441c65 100644
--- a/activerecord/test/cases/multiple_db_test.rb
+++ b/activerecord/test/cases/multiple_db_test.rb
@@ -106,14 +106,12 @@ class MultipleDbTest < ActiveRecord::TestCase
end
def test_associations_should_work_when_model_has_no_connection
- begin
- ActiveRecord::Base.remove_connection
- assert_nothing_raised do
- College.first.courses.first
- end
- ensure
- ActiveRecord::Base.establish_connection :arunit
+ ActiveRecord::Base.remove_connection
+ assert_nothing_raised do
+ College.first.courses.first
end
+ ensure
+ ActiveRecord::Base.establish_connection :arunit
end
end
end
diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb
index fa7f759e51..080aeb0989 100644
--- a/activerecord/test/cases/pooled_connections_test.rb
+++ b/activerecord/test/cases/pooled_connections_test.rb
@@ -25,14 +25,12 @@ class PooledConnectionsTest < ActiveRecord::TestCase
@timed_out = 0
threads.times do
Thread.new do
- begin
- conn = ActiveRecord::Base.connection_pool.checkout
- sleep 0.1
- ActiveRecord::Base.connection_pool.checkin conn
- @connection_count += 1
- rescue ActiveRecord::ConnectionTimeoutError
- @timed_out += 1
- end
+ conn = ActiveRecord::Base.connection_pool.checkout
+ sleep 0.1
+ ActiveRecord::Base.connection_pool.checkin conn
+ @connection_count += 1
+ rescue ActiveRecord::ConnectionTimeoutError
+ @timed_out += 1
end.join
end
end
@@ -42,14 +40,12 @@ class PooledConnectionsTest < ActiveRecord::TestCase
@connection_count = 0
@timed_out = 0
loops.times do
- begin
- conn = ActiveRecord::Base.connection_pool.checkout
- ActiveRecord::Base.connection_pool.checkin conn
- @connection_count += 1
- ActiveRecord::Base.connection.data_sources
- rescue ActiveRecord::ConnectionTimeoutError
- @timed_out += 1
- end
+ conn = ActiveRecord::Base.connection_pool.checkout
+ ActiveRecord::Base.connection_pool.checkin conn
+ @connection_count += 1
+ ActiveRecord::Base.connection.data_sources
+ rescue ActiveRecord::ConnectionTimeoutError
+ @timed_out += 1
end
end
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 02ead8d914..04bbc7d136 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -56,6 +56,11 @@ class QueryCacheTest < ActiveRecord::TestCase
end
def test_query_cache_is_applied_to_connections_in_all_handlers
+ ActiveRecord::Base.connection_handlers = {
+ writing: ActiveRecord::Base.default_connection_handler,
+ reading: ActiveRecord::ConnectionAdapters::ConnectionHandler.new
+ }
+
ActiveRecord::Base.connected_to(role: :reading) do
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["arunit"])
end
@@ -73,76 +78,74 @@ class QueryCacheTest < ActiveRecord::TestCase
def test_query_cache_across_threads
with_temporary_connection_pool do
- begin
- if in_memory_db?
- # Separate connections to an in-memory database create an entirely new database,
- # with an empty schema etc, so we just stub out this schema on the fly.
- ActiveRecord::Base.connection_pool.with_connection do |connection|
- connection.create_table :tasks do |t|
- t.datetime :starting
- t.datetime :ending
- end
+ if in_memory_db?
+ # Separate connections to an in-memory database create an entirely new database,
+ # with an empty schema etc, so we just stub out this schema on the fly.
+ ActiveRecord::Base.connection_pool.with_connection do |connection|
+ connection.create_table :tasks do |t|
+ t.datetime :starting
+ t.datetime :ending
end
- ActiveRecord::FixtureSet.create_fixtures(self.class.fixture_path, ["tasks"], {}, ActiveRecord::Base)
end
+ ActiveRecord::FixtureSet.create_fixtures(self.class.fixture_path, ["tasks"], {}, ActiveRecord::Base)
+ end
- ActiveRecord::Base.connection_pool.connections.each do |conn|
- assert_cache :off, conn
- end
+ ActiveRecord::Base.connection_pool.connections.each do |conn|
+ assert_cache :off, conn
+ end
- assert_not_predicate ActiveRecord::Base.connection, :nil?
- assert_cache :off
+ assert_not_predicate ActiveRecord::Base.connection, :nil?
+ assert_cache :off
- middleware {
- assert_cache :clean
+ middleware {
+ assert_cache :clean
- Task.find 1
- assert_cache :dirty
+ Task.find 1
+ assert_cache :dirty
- thread_1_connection = ActiveRecord::Base.connection
- ActiveRecord::Base.clear_active_connections!
- assert_cache :off, thread_1_connection
+ thread_1_connection = ActiveRecord::Base.connection
+ ActiveRecord::Base.clear_active_connections!
+ assert_cache :off, thread_1_connection
- started = Concurrent::Event.new
- checked = Concurrent::Event.new
+ started = Concurrent::Event.new
+ checked = Concurrent::Event.new
- thread_2_connection = nil
- thread = Thread.new {
- thread_2_connection = ActiveRecord::Base.connection
+ thread_2_connection = nil
+ thread = Thread.new {
+ thread_2_connection = ActiveRecord::Base.connection
- assert_equal thread_2_connection, thread_1_connection
- assert_cache :off
+ assert_equal thread_2_connection, thread_1_connection
+ assert_cache :off
- middleware {
- assert_cache :clean
+ middleware {
+ assert_cache :clean
- Task.find 1
- assert_cache :dirty
+ Task.find 1
+ assert_cache :dirty
- started.set
- checked.wait
+ started.set
+ checked.wait
- ActiveRecord::Base.clear_active_connections!
- }.call({})
- }
+ ActiveRecord::Base.clear_active_connections!
+ }.call({})
+ }
- started.wait
+ started.wait
- thread_1_connection = ActiveRecord::Base.connection
- assert_not_equal thread_1_connection, thread_2_connection
- assert_cache :dirty, thread_2_connection
- checked.set
- thread.join
+ thread_1_connection = ActiveRecord::Base.connection
+ assert_not_equal thread_1_connection, thread_2_connection
+ assert_cache :dirty, thread_2_connection
+ checked.set
+ thread.join
- assert_cache :off, thread_2_connection
- }.call({})
+ assert_cache :off, thread_2_connection
+ }.call({})
- ActiveRecord::Base.connection_pool.connections.each do |conn|
- assert_cache :off, conn
- end
- ensure
- ActiveRecord::Base.connection_pool.disconnect!
+ ActiveRecord::Base.connection_pool.connections.each do |conn|
+ assert_cache :off, conn
end
+ ensure
+ ActiveRecord::Base.connection_pool.disconnect!
end
end
@@ -311,7 +314,7 @@ class QueryCacheTest < ActiveRecord::TestCase
payload[:sql].downcase!
end
- assert_raises frozen_error_class do
+ assert_raises FrozenError do
ActiveRecord::Base.cache do
assert_queries(1) { Task.find(1); Task.find(1) }
end
@@ -369,12 +372,10 @@ class QueryCacheTest < ActiveRecord::TestCase
assert_not_predicate Task, :connected?
Task.cache do
- begin
- assert_queries(1) { Task.find(1); Task.find(1) }
- ensure
- ActiveRecord::Base.connection_handler.remove_connection(Task.connection_specification_name)
- Task.connection_specification_name = spec_name
- end
+ assert_queries(1) { Task.find(1); Task.find(1) }
+ ensure
+ ActiveRecord::Base.connection_handler.remove_connection(Task.connection_specification_name)
+ Task.connection_specification_name = spec_name
end
end
end
diff --git a/activerecord/test/cases/relation/update_all_test.rb b/activerecord/test/cases/relation/update_all_test.rb
index 09c365f31b..bb6912148c 100644
--- a/activerecord/test/cases/relation/update_all_test.rb
+++ b/activerecord/test/cases/relation/update_all_test.rb
@@ -198,11 +198,9 @@ class UpdateAllTest < ActiveRecord::TestCase
def test_update_all_doesnt_ignore_order
assert_equal authors(:david).id + 1, authors(:mary).id # make sure there is going to be a duplicate PK error
test_update_with_order_succeeds = lambda do |order|
- begin
- Author.order(order).update_all("id = id + 1")
- rescue ActiveRecord::ActiveRecordError
- false
- end
+ Author.order(order).update_all("id = id + 1")
+ rescue ActiveRecord::ActiveRecordError
+ false
end
if test_update_with_order_succeeds.call("id DESC")
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index e471ee8039..756eeca35f 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -1315,6 +1315,13 @@ class RelationTest < ActiveRecord::TestCase
assert_not_equal subscriber, Subscriber.create_or_find_by(nick: "cat")
end
+ def test_create_or_find_by_should_not_raise_due_to_validation_errors
+ assert_nothing_raised do
+ bird = Bird.create_or_find_by(color: "green")
+ assert_predicate bird, :invalid?
+ end
+ end
+
def test_create_or_find_by_with_non_unique_attributes
Subscriber.create!(nick: "bob", name: "the builder")
@@ -1334,6 +1341,38 @@ class RelationTest < ActiveRecord::TestCase
end
end
+ def test_create_or_find_by_with_bang
+ assert_nil Subscriber.find_by(nick: "bob")
+
+ subscriber = Subscriber.create!(nick: "bob")
+
+ assert_equal subscriber, Subscriber.create_or_find_by!(nick: "bob")
+ assert_not_equal subscriber, Subscriber.create_or_find_by!(nick: "cat")
+ end
+
+ def test_create_or_find_by_with_bang_should_raise_due_to_validation_errors
+ assert_raises(ActiveRecord::RecordInvalid) { Bird.create_or_find_by!(color: "green") }
+ end
+
+ def test_create_or_find_by_with_bang_with_non_unique_attributes
+ Subscriber.create!(nick: "bob", name: "the builder")
+
+ assert_raises(ActiveRecord::RecordNotFound) do
+ Subscriber.create_or_find_by!(nick: "bob", name: "the cat")
+ end
+ end
+
+ def test_create_or_find_by_with_bang_within_transaction
+ assert_nil Subscriber.find_by(nick: "bob")
+
+ subscriber = Subscriber.create!(nick: "bob")
+
+ Subscriber.transaction do
+ assert_equal subscriber, Subscriber.create_or_find_by!(nick: "bob")
+ assert_not_equal subscriber, Subscriber.create_or_find_by!(nick: "cat")
+ end
+ end
+
def test_find_or_initialize_by
assert_nil Bird.find_by(name: "bob")
diff --git a/activerecord/test/cases/scoping/relation_scoping_test.rb b/activerecord/test/cases/scoping/relation_scoping_test.rb
index b4f4379e5e..b1f2ffe29c 100644
--- a/activerecord/test/cases/scoping/relation_scoping_test.rb
+++ b/activerecord/test/cases/scoping/relation_scoping_test.rb
@@ -254,11 +254,16 @@ class RelationScopingTest < ActiveRecord::TestCase
end
end
- def test_scoping_works_in_the_scope_block
+ def test_scoping_with_klass_method_works_in_the_scope_block
expected = SpecialPostWithDefaultScope.unscoped.to_a
assert_equal expected, SpecialPostWithDefaultScope.unscoped_all
end
+ def test_scoping_with_query_method_works_in_the_scope_block
+ expected = SpecialPostWithDefaultScope.unscoped.where(author_id: 0).to_a
+ assert_equal expected, SpecialPostWithDefaultScope.authorless
+ end
+
def test_circular_joins_with_scoping_does_not_crash
posts = Post.joins(comments: :post).scoping do
Post.first(10)
diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb
index 1192b30b14..f6cd4f85ee 100644
--- a/activerecord/test/cases/serialized_attribute_test.rb
+++ b/activerecord/test/cases/serialized_attribute_test.rb
@@ -13,6 +13,10 @@ class SerializedAttributeTest < ActiveRecord::TestCase
MyObject = Struct.new :attribute1, :attribute2
+ # NOTE: Use a duplicate of Topic so attribute
+ # changes don't bleed into other tests
+ Topic = ::Topic.dup
+
teardown do
Topic.serialize("content")
end
@@ -367,7 +371,7 @@ class SerializedAttributeTest < ActiveRecord::TestCase
end
def test_serialized_attribute_works_under_concurrent_initial_access
- model = Topic.dup
+ model = ::Topic.dup
topic = model.last
topic.update group: "1"
diff --git a/activerecord/test/cases/test_case.rb b/activerecord/test/cases/test_case.rb
index 40947767f3..5b25432dc0 100644
--- a/activerecord/test/cases/test_case.rb
+++ b/activerecord/test/cases/test_case.rb
@@ -79,10 +79,6 @@ module ActiveRecord
model.reset_column_information
model.column_names.include?(column_name.to_s)
end
-
- def frozen_error_class
- Object.const_defined?(:FrozenError) ? FrozenError : RuntimeError
- end
end
class PostgreSQLTestCase < TestCase
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 50740054f7..45c93ca949 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -587,7 +587,7 @@ class TransactionTest < ActiveRecord::TestCase
def test_rollback_when_saving_a_frozen_record
topic = Topic.new(title: "test")
topic.freeze
- e = assert_raise(frozen_error_class) { topic.save }
+ e = assert_raise(FrozenError) { topic.save }
# Not good enough, but we can't do much
# about it since there is no specific error
# for frozen objects.
diff --git a/activerecord/test/cases/validations/absence_validation_test.rb b/activerecord/test/cases/validations/absence_validation_test.rb
index 8235a54d8a..1982734f02 100644
--- a/activerecord/test/cases/validations/absence_validation_test.rb
+++ b/activerecord/test/cases/validations/absence_validation_test.rb
@@ -61,7 +61,7 @@ class AbsenceValidationTest < ActiveRecord::TestCase
def test_validates_absence_of_virtual_attribute_on_model
repair_validations(Interest) do
- Interest.send(:attr_accessor, :token)
+ Interest.attr_accessor(:token)
Interest.validates_absence_of(:token)
interest = Interest.create!(topic: "Thought Leadering")
diff --git a/activerecord/test/cases/validations/length_validation_test.rb b/activerecord/test/cases/validations/length_validation_test.rb
index 1fbcdc271b..a7cb718043 100644
--- a/activerecord/test/cases/validations/length_validation_test.rb
+++ b/activerecord/test/cases/validations/length_validation_test.rb
@@ -64,7 +64,7 @@ class LengthValidationTest < ActiveRecord::TestCase
def test_validates_length_of_virtual_attribute_on_model
repair_validations(Pet) do
- Pet.send(:attr_accessor, :nickname)
+ Pet.attr_accessor(:nickname)
Pet.validates_length_of(:name, minimum: 1)
Pet.validates_length_of(:nickname, minimum: 1)
diff --git a/activerecord/test/cases/validations/presence_validation_test.rb b/activerecord/test/cases/validations/presence_validation_test.rb
index 63c3f67da2..4b9cbe9098 100644
--- a/activerecord/test/cases/validations/presence_validation_test.rb
+++ b/activerecord/test/cases/validations/presence_validation_test.rb
@@ -69,7 +69,7 @@ class PresenceValidationTest < ActiveRecord::TestCase
def test_validates_presence_of_virtual_attribute_on_model
repair_validations(Interest) do
- Interest.send(:attr_accessor, :abbreviation)
+ Interest.attr_accessor(:abbreviation)
Interest.validates_presence_of(:topic)
Interest.validates_presence_of(:abbreviation)
diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb
index 66763c727f..9a70934b7e 100644
--- a/activerecord/test/cases/validations_test.rb
+++ b/activerecord/test/cases/validations_test.rb
@@ -144,6 +144,13 @@ class ValidationsTest < ActiveRecord::TestCase
assert_equal "100,000", d.salary_before_type_cast
end
+ def test_validates_acceptance_of_with_undefined_attribute_methods
+ Topic.validates_acceptance_of(:approved)
+ topic = Topic.new(approved: true)
+ Topic.undefine_attribute_methods
+ assert topic.approved
+ end
+
def test_validates_acceptance_of_as_database_column
Topic.validates_acceptance_of(:approved)
topic = Topic.create("approved" => true)