aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/adapters/mysql/active_schema_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql/connection_test.rb7
-rw-r--r--activerecord/test/cases/adapters/mysql/consistency_test.rb1
-rw-r--r--activerecord/test/cases/adapters/mysql2/active_schema_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql2/boolean_test.rb1
-rw-r--r--activerecord/test/cases/adapters/mysql2/connection_test.rb7
-rw-r--r--activerecord/test/cases/adapters/mysql2/schema_test.rb14
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/citext_test.rb9
-rw-r--r--activerecord/test/cases/adapters/postgresql/explain_test.rb3
-rw-r--r--activerecord/test/cases/adapters/postgresql/ltree_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb20
-rw-r--r--activerecord/test/cases/adapters/postgresql/timestamp_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/uuid_test.rb25
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb4
-rw-r--r--activerecord/test/cases/ar_schema_test.rb62
-rw-r--r--activerecord/test/cases/associations/eager_test.rb10
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb8
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb34
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb21
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb2
-rw-r--r--activerecord/test/cases/associations/required_test.rb4
-rw-r--r--activerecord/test/cases/associations_test.rb23
-rw-r--r--activerecord/test/cases/attribute_decorators_test.rb3
-rw-r--r--activerecord/test/cases/attribute_methods/read_test.rb1
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb20
-rw-r--r--activerecord/test/cases/attribute_test.rb30
-rw-r--r--activerecord/test/cases/autosave_association_test.rb8
-rw-r--r--activerecord/test/cases/base_test.rb14
-rw-r--r--activerecord/test/cases/calculations_test.rb4
-rw-r--r--activerecord/test/cases/dirty_test.rb37
-rw-r--r--activerecord/test/cases/enum_test.rb3
-rw-r--r--activerecord/test/cases/finder_test.rb86
-rw-r--r--activerecord/test/cases/fixtures_test.rb16
-rw-r--r--activerecord/test/cases/forbidden_attributes_protection_test.rb30
-rw-r--r--activerecord/test/cases/helper.rb26
-rw-r--r--activerecord/test/cases/invertible_migration_test.rb5
-rw-r--r--activerecord/test/cases/locking_test.rb23
-rw-r--r--activerecord/test/cases/migration/change_schema_test.rb7
-rw-r--r--activerecord/test/cases/migration/change_table_test.rb4
-rw-r--r--activerecord/test/cases/migration/columns_test.rb3
-rw-r--r--activerecord/test/cases/migration/foreign_key_test.rb4
-rw-r--r--activerecord/test/cases/migration/helper.rb6
-rw-r--r--activerecord/test/cases/migration/index_test.rb6
-rw-r--r--activerecord/test/cases/migration/rename_table_test.rb3
-rw-r--r--activerecord/test/cases/migration_test.rb58
-rw-r--r--activerecord/test/cases/migrator_test.rb569
-rw-r--r--activerecord/test/cases/primary_keys_test.rb10
-rw-r--r--activerecord/test/cases/relation/merging_test.rb15
-rw-r--r--activerecord/test/cases/relation/where_test.rb15
-rw-r--r--activerecord/test/cases/relations_test.rb16
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb44
-rw-r--r--activerecord/test/cases/scoping/default_scoping_test.rb21
-rw-r--r--activerecord/test/cases/scoping/named_scoping_test.rb7
-rw-r--r--activerecord/test/cases/scoping/relation_scoping_test.rb8
-rw-r--r--activerecord/test/cases/serialized_attribute_test.rb2
-rw-r--r--activerecord/test/cases/tasks/database_tasks_test.rb1
-rw-r--r--activerecord/test/cases/test_case.rb4
-rw-r--r--activerecord/test/cases/timestamp_test.rb19
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb89
-rw-r--r--activerecord/test/cases/transactions_test.rb28
-rw-r--r--activerecord/test/cases/type/decimal_test.rb5
-rw-r--r--activerecord/test/cases/types_test.rb6
-rw-r--r--activerecord/test/cases/validations/i18n_validation_test.rb1
-rw-r--r--activerecord/test/cases/validations_repair_helper.rb2
-rw-r--r--activerecord/test/cases/view_test.rb95
-rw-r--r--activerecord/test/config.example.yml2
-rw-r--r--activerecord/test/fixtures/developers.yml2
-rw-r--r--activerecord/test/models/comment.rb6
-rw-r--r--activerecord/test/models/company.rb1
-rw-r--r--activerecord/test/models/developer.rb2
-rw-r--r--activerecord/test/models/person.rb2
-rw-r--r--activerecord/test/models/personal_legacy_thing.rb4
-rw-r--r--activerecord/test/models/post.rb7
-rw-r--r--activerecord/test/schema/schema.rb19
-rw-r--r--activerecord/test/support/schema_dumping_helper.rb9
76 files changed, 1190 insertions, 497 deletions
diff --git a/activerecord/test/cases/adapters/mysql/active_schema_test.rb b/activerecord/test/cases/adapters/mysql/active_schema_test.rb
index 7c0f11b033..a84673e452 100644
--- a/activerecord/test/cases/adapters/mysql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql/active_schema_test.rb
@@ -105,7 +105,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase
with_real_execute do
begin
ActiveRecord::Base.connection.create_table :delete_me do |t|
- t.timestamps
+ t.timestamps null: true
end
ActiveRecord::Base.connection.remove_timestamps :delete_me
assert !column_present?('delete_me', 'updated_at', 'datetime')
diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb
index b0759dffde..3dabb1104a 100644
--- a/activerecord/test/cases/adapters/mysql/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql/connection_test.rb
@@ -129,6 +129,11 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
end
+ def test_mysql_connection_collation_is_configured
+ assert_equal 'utf8_unicode_ci', @connection.show_variable('collation_connection')
+ assert_equal 'utf8_general_ci', ARUnit2Model.connection.show_variable('collation_connection')
+ end
+
def test_mysql_default_in_strict_mode
result = @connection.exec_query "SELECT @@SESSION.sql_mode"
assert_equal [["STRICT_ALL_TABLES"]], result.rows
@@ -150,7 +155,7 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
end
- def test_mysql_sql_mode_variable_overides_strict_mode
+ def test_mysql_sql_mode_variable_overrides_strict_mode
run_without_connection do |orig_connection|
ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { 'sql_mode' => 'ansi' }))
result = ActiveRecord::Base.connection.exec_query 'SELECT @@SESSION.sql_mode'
diff --git a/activerecord/test/cases/adapters/mysql/consistency_test.rb b/activerecord/test/cases/adapters/mysql/consistency_test.rb
index 083d533bb2..e972d6b330 100644
--- a/activerecord/test/cases/adapters/mysql/consistency_test.rb
+++ b/activerecord/test/cases/adapters/mysql/consistency_test.rb
@@ -12,6 +12,7 @@ class MysqlConsistencyTest < ActiveRecord::TestCase
ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false
@connection = ActiveRecord::Base.connection
+ @connection.clear_cache!
@connection.create_table("mysql_consistency") do |t|
t.boolean "a_bool"
t.string "a_string"
diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
index cefc3e3c7e..49cfafd7a5 100644
--- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
@@ -105,7 +105,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase
with_real_execute do
begin
ActiveRecord::Base.connection.create_table :delete_me do |t|
- t.timestamps
+ t.timestamps null: true
end
ActiveRecord::Base.connection.remove_timestamps :delete_me
assert !column_present?('delete_me', 'updated_at', 'datetime')
diff --git a/activerecord/test/cases/adapters/mysql2/boolean_test.rb b/activerecord/test/cases/adapters/mysql2/boolean_test.rb
index f3c711a64b..03627135b2 100644
--- a/activerecord/test/cases/adapters/mysql2/boolean_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/boolean_test.rb
@@ -9,6 +9,7 @@ class Mysql2BooleanTest < ActiveRecord::TestCase
setup do
@connection = ActiveRecord::Base.connection
+ @connection.clear_cache!
@connection.create_table("mysql_booleans") do |t|
t.boolean "archived"
t.string "published", limit: 1
diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb
index 3b35e69e0d..0b2f59b0eb 100644
--- a/activerecord/test/cases/adapters/mysql2/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb
@@ -52,6 +52,11 @@ class MysqlConnectionTest < ActiveRecord::TestCase
assert @connection.active?
end
+ def test_mysql_connection_collation_is_configured
+ assert_equal 'utf8_unicode_ci', @connection.show_variable('collation_connection')
+ assert_equal 'utf8_general_ci', ARUnit2Model.connection.show_variable('collation_connection')
+ end
+
# TODO: Below is a straight up copy/paste from mysql/connection_test.rb
# I'm not sure what the correct way is to share these tests between
# adapters in minitest.
@@ -76,7 +81,7 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
end
- def test_mysql_sql_mode_variable_overides_strict_mode
+ def test_mysql_sql_mode_variable_overrides_strict_mode
run_without_connection do |orig_connection|
ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { 'sql_mode' => 'ansi' }))
result = ActiveRecord::Base.connection.exec_query 'SELECT @@SESSION.sql_mode'
diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb
index 43c9116b5a..1b7e60565d 100644
--- a/activerecord/test/cases/adapters/mysql2/schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb
@@ -66,12 +66,14 @@ module ActiveRecord
assert_equal :fulltext, index_c.type
end
- def test_drop_temporary_table
- @connection.transaction do
- @connection.create_table(:temp_table, temporary: true)
- # if it doesn't properly say DROP TEMPORARY TABLE, the transaction commit
- # will complain that no transaction is active
- @connection.drop_table(:temp_table, temporary: true)
+ unless mysql_enforcing_gtid_consistency?
+ def test_drop_temporary_table
+ @connection.transaction do
+ @connection.create_table(:temp_table, temporary: true)
+ # if it doesn't properly say DROP TEMPORARY TABLE, the transaction commit
+ # will complain that no transaction is active
+ @connection.drop_table(:temp_table, temporary: true)
+ end
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 8df1b7d18c..ff553c3f1a 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -12,12 +12,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
def setup
@connection = ActiveRecord::Base.connection
- unless @connection.extension_enabled?('hstore')
- @connection.enable_extension 'hstore'
- @connection.commit_db_transaction
- end
-
- @connection.reconnect!
+ enable_extension!('hstore', @connection)
@connection.transaction do
@connection.create_table('pg_arrays') do |t|
@@ -32,6 +27,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
teardown do
@connection.execute 'drop table if exists pg_arrays'
+ disable_extension!('hstore', @connection)
end
def test_column
diff --git a/activerecord/test/cases/adapters/postgresql/citext_test.rb b/activerecord/test/cases/adapters/postgresql/citext_test.rb
index 2acb64f81c..cb024463c9 100644
--- a/activerecord/test/cases/adapters/postgresql/citext_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/citext_test.rb
@@ -10,12 +10,7 @@ if ActiveRecord::Base.connection.supports_extensions?
def setup
@connection = ActiveRecord::Base.connection
- unless @connection.extension_enabled?('citext')
- @connection.enable_extension 'citext'
- @connection.commit_db_transaction
- end
-
- @connection.reconnect!
+ enable_extension!('citext', @connection)
@connection.create_table('citexts') do |t|
t.citext 'cival'
@@ -24,7 +19,7 @@ if ActiveRecord::Base.connection.supports_extensions?
teardown do
@connection.execute 'DROP TABLE IF EXISTS citexts;'
- @connection.execute 'DROP EXTENSION IF EXISTS citext CASCADE;'
+ disable_extension!('citext', @connection)
end
def test_citext_enabled
diff --git a/activerecord/test/cases/adapters/postgresql/explain_test.rb b/activerecord/test/cases/adapters/postgresql/explain_test.rb
index 416f84cb38..19053b6732 100644
--- a/activerecord/test/cases/adapters/postgresql/explain_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/explain_test.rb
@@ -11,16 +11,13 @@ module ActiveRecord
explain = Developer.where(:id => 1).explain
assert_match %(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = $1), explain
assert_match %(QUERY PLAN), explain
- assert_match %(Index Scan using developers_pkey on developers), explain
end
def test_explain_with_eager_loading
explain = Developer.where(:id => 1).includes(:audit_logs).explain
assert_match %(QUERY PLAN), explain
assert_match %(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = $1), explain
- assert_match %(Index Scan using developers_pkey on developers), explain
assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" IN (1)), explain
- assert_match %(Seq Scan on audit_logs), explain
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/ltree_test.rb b/activerecord/test/cases/adapters/postgresql/ltree_test.rb
index 889e369bd6..2968109346 100644
--- a/activerecord/test/cases/adapters/postgresql/ltree_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/ltree_test.rb
@@ -9,9 +9,7 @@ class PostgresqlLtreeTest < ActiveRecord::TestCase
def setup
@connection = ActiveRecord::Base.connection
- unless @connection.extension_enabled?('ltree')
- @connection.enable_extension 'ltree'
- end
+ enable_extension!('ltree', @connection)
@connection.transaction do
@connection.create_table('ltrees') do |t|
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index cfff1f980b..a71c0dfb26 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -134,18 +134,18 @@ module ActiveRecord
end
def test_default_sequence_name
- assert_equal PostgreSQL::Name.new('public', 'accounts_id_seq'),
+ assert_equal 'public.accounts_id_seq',
@connection.default_sequence_name('accounts', 'id')
- assert_equal PostgreSQL::Name.new('public', 'accounts_id_seq'),
+ assert_equal 'public.accounts_id_seq',
@connection.default_sequence_name('accounts')
end
def test_default_sequence_name_bad_table
- assert_equal PostgreSQL::Name.new(nil, 'zomg_id_seq'),
+ assert_equal 'zomg_id_seq',
@connection.default_sequence_name('zomg', 'id')
- assert_equal PostgreSQL::Name.new(nil, 'zomg_id_seq'),
+ assert_equal 'zomg_id_seq',
@connection.default_sequence_name('zomg')
end
@@ -153,7 +153,7 @@ module ActiveRecord
with_example_table do
pk, seq = @connection.pk_and_sequence_for('ex')
assert_equal 'id', pk
- assert_equal @connection.default_sequence_name('ex', 'id'), seq
+ assert_equal @connection.default_sequence_name('ex', 'id'), seq.to_s
end
end
@@ -161,7 +161,7 @@ module ActiveRecord
with_example_table 'code serial primary key' do
pk, seq = @connection.pk_and_sequence_for('ex')
assert_equal 'code', pk
- assert_equal @connection.default_sequence_name('ex', 'code'), seq
+ assert_equal @connection.default_sequence_name('ex', 'code'), seq.to_s
end
end
@@ -334,6 +334,14 @@ module ActiveRecord
@connection.columns_for_distinct("posts.id", ["posts.created_at desc", "posts.position asc"])
end
+ def test_columns_for_distinct_with_case
+ assert_equal(
+ 'posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0',
+ @connection.columns_for_distinct('posts.id',
+ ["CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END"])
+ )
+ end
+
def test_columns_for_distinct_blank_not_nil_orders
assert_equal "posts.id, posts.created_at AS alias_0",
@connection.columns_for_distinct("posts.id", ["posts.created_at desc", "", " "])
diff --git a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
index 3614b29190..eb32c4d2c2 100644
--- a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
@@ -87,7 +87,7 @@ class TimestampTest < ActiveRecord::TestCase
def test_timestamps_helper_with_custom_precision
ActiveRecord::Base.connection.create_table(:foos) do |t|
- t.timestamps :precision => 4
+ t.timestamps :null => true, :precision => 4
end
assert_equal 4, activerecord_column_option('foos', 'created_at', 'precision')
assert_equal 4, activerecord_column_option('foos', 'updated_at', 'precision')
@@ -95,7 +95,7 @@ class TimestampTest < ActiveRecord::TestCase
def test_passing_precision_to_timestamp_does_not_set_limit
ActiveRecord::Base.connection.create_table(:foos) do |t|
- t.timestamps :precision => 4
+ t.timestamps :null => true, :precision => 4
end
assert_nil activerecord_column_option("foos", "created_at", "limit")
assert_nil activerecord_column_option("foos", "updated_at", "limit")
@@ -104,14 +104,14 @@ class TimestampTest < ActiveRecord::TestCase
def test_invalid_timestamp_precision_raises_error
assert_raises ActiveRecord::ActiveRecordError do
ActiveRecord::Base.connection.create_table(:foos) do |t|
- t.timestamps :precision => 7
+ t.timestamps :null => true, :precision => 7
end
end
end
def test_postgres_agrees_with_activerecord_about_precision
ActiveRecord::Base.connection.create_table(:foos) do |t|
- t.timestamps :precision => 4
+ t.timestamps :null => true, :precision => 4
end
assert_equal '4', pg_datetime_precision('foos', 'created_at')
assert_equal '4', pg_datetime_precision('foos', 'updated_at')
diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
index 66006d718f..ae5b409f99 100644
--- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
@@ -118,7 +118,7 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::TestCase
end
setup do
- enable_uuid_ossp!(connection)
+ enable_extension!('uuid-ossp', connection)
connection.create_table('pg_uuids', id: :uuid, default: 'uuid_generate_v1()') do |t|
t.string 'name'
@@ -144,6 +144,7 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::TestCase
drop_table "pg_uuids"
drop_table 'pg_uuids_2'
connection.execute 'DROP FUNCTION IF EXISTS my_uuid_generator();'
+ disable_extension!('uuid-ossp', connection)
end
if ActiveRecord::Base.connection.supports_extensions?
@@ -189,7 +190,7 @@ class PostgresqlUUIDTestNilDefault < ActiveRecord::TestCase
include PostgresqlUUIDHelper
setup do
- enable_uuid_ossp!(connection)
+ enable_extension!('uuid-ossp', connection)
connection.create_table('pg_uuids', id: false) do |t|
t.primary_key :id, :uuid, default: nil
@@ -199,6 +200,7 @@ class PostgresqlUUIDTestNilDefault < ActiveRecord::TestCase
teardown do
drop_table "pg_uuids"
+ disable_extension!('uuid-ossp', connection)
end
if ActiveRecord::Base.connection.supports_extensions?
@@ -226,7 +228,7 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::TestCase
end
setup do
- enable_uuid_ossp!(connection)
+ enable_extension!('uuid-ossp', connection)
connection.transaction do
connection.create_table('pg_uuid_posts', id: :uuid) do |t|
@@ -240,10 +242,9 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::TestCase
end
teardown do
- connection.transaction do
drop_table "pg_uuid_comments"
drop_table "pg_uuid_posts"
- end
+ disable_extension!('uuid-ossp', connection)
end
if ActiveRecord::Base.connection.supports_extensions?
@@ -252,5 +253,19 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::TestCase
comment = post.uuid_comments.create!
assert post.uuid_comments.find(comment.id)
end
+
+ def test_find_with_uuid
+ UuidPost.create!
+ assert_raise ActiveRecord::RecordNotFound do
+ UuidPost.find(123456)
+ end
+
+ end
+
+ def test_find_by_with_uuid
+ UuidPost.create!
+ assert_nil UuidPost.find_by(id: 789)
+ 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 b2bf9480dd..8c1c22d3bf 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -297,7 +297,7 @@ module ActiveRecord
def test_tables_logs_name
sql = <<-SQL
SELECT name FROM sqlite_master
- WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+ WHERE (type = 'table' OR type = 'view') AND NOT name = 'sqlite_sequence'
SQL
assert_logged [[sql.squish, 'SCHEMA', []]] do
@conn.tables('hello')
@@ -316,7 +316,7 @@ module ActiveRecord
with_example_table do
sql = <<-SQL
SELECT name FROM sqlite_master
- WHERE type = 'table'
+ WHERE (type = 'table' OR type = 'view')
AND NOT name = 'sqlite_sequence' AND name = \"ex\"
SQL
assert_logged [[sql.squish, 'SCHEMA', []]] do
diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb
index 8700b20dee..b6333240a8 100644
--- a/activerecord/test/cases/ar_schema_test.rb
+++ b/activerecord/test/cases/ar_schema_test.rb
@@ -5,7 +5,9 @@ if ActiveRecord::Base.connection.supports_migrations?
class ActiveRecordSchemaTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
- def setup
+ setup do
+ @original_verbose = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
@connection = ActiveRecord::Base.connection
ActiveRecord::SchemaMigration.drop_table
end
@@ -14,7 +16,9 @@ if ActiveRecord::Base.connection.supports_migrations?
@connection.drop_table :fruits rescue nil
@connection.drop_table :nep_fruits rescue nil
@connection.drop_table :nep_schema_migrations rescue nil
+ @connection.drop_table :has_timestamps rescue nil
ActiveRecord::SchemaMigration.delete_all rescue nil
+ ActiveRecord::Migration.verbose = @original_verbose
end
def test_has_no_primary_key
@@ -88,5 +92,61 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal "017", ActiveRecord::SchemaMigration.normalize_migration_number("0017")
assert_equal "20131219224947", ActiveRecord::SchemaMigration.normalize_migration_number("20131219224947")
end
+
+ def test_timestamps_without_null_is_deprecated_on_create_table
+ assert_deprecated do
+ ActiveRecord::Schema.define do
+ create_table :has_timestamps do |t|
+ t.timestamps
+ end
+ end
+ end
+ end
+
+ def test_timestamps_without_null_is_deprecated_on_change_table
+ assert_deprecated do
+ ActiveRecord::Schema.define do
+ create_table :has_timestamps
+
+ change_table :has_timestamps do |t|
+ t.timestamps
+ end
+ end
+ end
+ end
+
+ def test_no_deprecation_warning_from_timestamps_on_create_table
+ assert_not_deprecated do
+ ActiveRecord::Schema.define do
+ create_table :has_timestamps do |t|
+ t.timestamps null: true
+ end
+
+ drop_table :has_timestamps
+
+ create_table :has_timestamps do |t|
+ t.timestamps null: false
+ end
+ end
+ end
+ end
+
+ def test_no_deprecation_warning_from_timestamps_on_change_table
+ assert_not_deprecated do
+ ActiveRecord::Schema.define do
+ create_table :has_timestamps
+ change_table :has_timestamps do |t|
+ t.timestamps null: true
+ end
+
+ drop_table :has_timestamps
+
+ create_table :has_timestamps
+ change_table :has_timestamps do |t|
+ t.timestamps null: false, default: Time.now
+ end
+ end
+ end
+ end
end
end
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 21912fdf0f..b852bd3536 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -1290,4 +1290,14 @@ class EagerAssociationTest < ActiveRecord::TestCase
david = Author.where(id: "1").eager_load(:readonly_comments).first!
assert david.readonly_comments.first.readonly?
end
+
+ test "preloading a polymorphic association with references to the associated table" do
+ post = Post.includes(:tags).references(:tags).where('tags.name = ?', 'General').first
+ assert_equal posts(:welcome), post
+ end
+
+ test "eager-loading a polymorphic association with references to the associated table" do
+ post = Post.eager_load(:tags).where('tags.name = ?', 'General').first
+ assert_equal posts(:welcome), post
+ end
end
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 cc58a4a1a2..859310575e 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
@@ -254,7 +254,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
def test_build
devel = Developer.find(1)
- proj = assert_no_queries { devel.projects.build("name" => "Projekt") }
+ proj = assert_no_queries(ignore_none: false) { devel.projects.build("name" => "Projekt") }
assert !devel.projects.loaded?
assert_equal devel.projects.last, proj
@@ -269,7 +269,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
def test_new_aliased_to_build
devel = Developer.find(1)
- proj = assert_no_queries { devel.projects.new("name" => "Projekt") }
+ proj = assert_no_queries(ignore_none: false) { devel.projects.new("name" => "Projekt") }
assert !devel.projects.loaded?
assert_equal devel.projects.last, proj
@@ -503,7 +503,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
developer = project.developers.first
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert project.developers.loaded?
assert project.developers.include?(developer)
end
@@ -824,7 +824,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
def test_has_and_belongs_to_many_associations_on_new_records_use_null_relations
projects = Developer.new.projects
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal [], projects
assert_equal [], projects.where(title: 'omg')
assert_equal [], projects.pluck(:title)
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index fe961e871c..e34b993029 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -28,6 +28,7 @@ require 'models/college'
require 'models/student'
require 'models/pirate'
require 'models/ship'
+require 'models/tyre'
class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase
fixtures :authors, :posts, :comments
@@ -606,7 +607,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_transactions_when_adding_to_new_record
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
firm = Firm.new
firm.clients_of_firm.concat(Client.new("name" => "Natural Company"))
end
@@ -621,7 +622,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_new_aliased_to_build
company = companies(:first_firm)
- new_client = assert_no_queries { company.clients_of_firm.new("name" => "Another Client") }
+ new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.new("name" => "Another Client") }
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
@@ -631,7 +632,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_build
company = companies(:first_firm)
- new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
+ new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build("name" => "Another Client") }
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
@@ -667,7 +668,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_build_many
company = companies(:first_firm)
- new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
+ new_clients = assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
assert_equal 2, new_clients.size
end
@@ -693,7 +694,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_build_via_block
company = companies(:first_firm)
- new_client = assert_no_queries { company.clients_of_firm.build {|client| client.name = "Another Client" } }
+ new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build {|client| client.name = "Another Client" } }
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
@@ -703,7 +704,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_build_many_via_block
company = companies(:first_firm)
- new_clients = assert_no_queries do
+ new_clients = assert_no_queries(ignore_none: false) do
company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client|
client.name = "changed"
end
@@ -928,7 +929,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_transaction_when_deleting_new_record
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
firm = Firm.new
client = Client.new("name" => "New Client")
firm.clients_of_firm << client
@@ -1349,7 +1350,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_transactions_when_replacing_on_new_record
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
firm = Firm.new
firm.clients_of_firm = [Client.new("name" => "New Client")]
end
@@ -1487,7 +1488,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
firm.clients.load_target
assert firm.clients.loaded?
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
firm.clients.first
assert_equal 2, firm.clients.first(2).size
firm.clients.last
@@ -1835,7 +1836,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
test "has many associations on new records use null relations" do
post = Post.new
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal [], post.comments
assert_equal [], post.comments.where(body: 'omg')
assert_equal [], post.comments.pluck(:body)
@@ -1941,4 +1942,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal [], authors(:david).posts_with_signature.map(&:title)
end
+
+ test 'associations autosaves when object is already persited' do
+ bulb = Bulb.create!
+ tyre = Tyre.create!
+
+ car = Car.create! do |c|
+ c.bulbs << bulb
+ c.tyres << tyre
+ end
+
+ assert_equal 1, car.bulbs.count
+ assert_equal 1, car.tyres.count
+ end
end
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 a85e020f0c..cddf1a1f72 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -1095,7 +1095,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
def test_has_many_through_associations_on_new_records_use_null_relations
person = Person.new
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal [], person.posts
assert_equal [], person.posts.where(body: 'omg')
assert_equal [], person.posts.pluck(:body)
@@ -1147,23 +1147,4 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
club.members << member
assert_equal 1, SuperMembership.where(member_id: member.id, club_id: club.id).count
end
-
- class ClubWithCallbacks < ActiveRecord::Base
- self.table_name = 'clubs'
- after_create :add_a_member
-
- has_many :memberships, inverse_of: :club, foreign_key: :club_id
- has_many :members, through: :memberships
-
- def add_a_member
- members << Member.last
- end
- end
-
- def test_has_many_with_callback_before_association
- Member.create!
- club = ClubWithCallbacks.create!
-
- assert_equal 1, club.reload.memberships.count
- end
end
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index a4650ccdf2..d412b3168e 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -200,7 +200,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
end
def test_build_association_dont_create_transaction
- assert_no_queries {
+ assert_no_queries(ignore_none: false) {
Firm.new.build_account
}
end
diff --git a/activerecord/test/cases/associations/required_test.rb b/activerecord/test/cases/associations/required_test.rb
index a6934a056e..321fb6c8dd 100644
--- a/activerecord/test/cases/associations/required_test.rb
+++ b/activerecord/test/cases/associations/required_test.rb
@@ -18,8 +18,8 @@ class RequiredAssociationsTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute("DROP TABLE IF EXISTS parents")
- @connection.execute("DROP TABLE IF EXISTS children")
+ @connection.drop_table 'parents' if @connection.table_exists? 'parents'
+ @connection.drop_table 'children' if @connection.table_exists? 'children'
end
test "belongs_to associations are not required by default" do
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index f663b5490c..9b0cf4c18f 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -23,7 +23,7 @@ require 'models/interest'
class AssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
- :computers, :people, :readers
+ :computers, :people, :readers, :authors, :author_favorites
def test_eager_loading_should_not_change_count_of_children
liquid = Liquid.create(:name => 'salty')
@@ -35,6 +35,13 @@ class AssociationsTest < ActiveRecord::TestCase
assert_equal 1, liquids[0].molecules.length
end
+ def test_subselect
+ author = authors :david
+ favs = author.author_favorites
+ fav2 = author.author_favorites.where(:author => Author.where(id: author.id)).to_a
+ assert_equal favs, fav2
+ end
+
def test_clear_association_cache_stored
firm = Firm.find(1)
assert_kind_of Firm, firm
@@ -350,4 +357,18 @@ class GeneratedMethodsTest < ActiveRecord::TestCase
def test_model_method_overrides_association_method
assert_equal(comments(:greetings).body, posts(:welcome).first_comment)
end
+
+ module MyModule
+ def comments; :none end
+ end
+
+ class MyArticle < ActiveRecord::Base
+ self.table_name = "articles"
+ include MyModule
+ has_many :comments, inverse_of: false
+ end
+
+ def test_included_module_overwrites_association_methods
+ assert_equal :none, MyArticle.new.comments
+ end
end
diff --git a/activerecord/test/cases/attribute_decorators_test.rb b/activerecord/test/cases/attribute_decorators_test.rb
index cbc2c4e5d7..53bd58e22e 100644
--- a/activerecord/test/cases/attribute_decorators_test.rb
+++ b/activerecord/test/cases/attribute_decorators_test.rb
@@ -28,7 +28,7 @@ module ActiveRecord
teardown do
return unless @connection
- @connection.execute 'DROP TABLE IF EXISTS attribute_decorators_model'
+ @connection.drop_table 'attribute_decorators_model' if @connection.table_exists? 'attribute_decorators_model'
Model.attribute_type_decorations.clear
Model.reset_column_information
end
@@ -44,6 +44,7 @@ module ActiveRecord
end
test "decoration does not eagerly load existing columns" do
+ Model.reset_column_information
assert_no_queries do
Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) }
end
diff --git a/activerecord/test/cases/attribute_methods/read_test.rb b/activerecord/test/cases/attribute_methods/read_test.rb
index 4741ee8799..e38b32d7fc 100644
--- a/activerecord/test/cases/attribute_methods/read_test.rb
+++ b/activerecord/test/cases/attribute_methods/read_test.rb
@@ -13,6 +13,7 @@ module ActiveRecord
def self.superclass; Base; end
def self.base_class; self; end
def self.decorate_matching_attribute_types(*); end
+ def self.initialize_generated_modules; end
include ActiveRecord::AttributeMethods
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index ab67cf4085..b4917e727a 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -263,7 +263,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
end
assert_equal klass.column_names, klass.new.attributes.keys
- assert_not klass.new.attributes.key?('id')
+ assert_not klass.new.has_attribute?('id')
end
def test_hashes_not_mangled
@@ -810,6 +810,24 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert_equal "lol", topic.author_name
end
+ def test_inherited_custom_accessors_with_reserved_names
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'computers'
+ self.abstract_class = true
+ def system; "omg"; end
+ def system=(val); self.developer = val; end
+ end
+
+ subklass = Class.new(klass)
+ [klass, subklass].each(&:define_attribute_methods)
+
+ computer = subklass.find(1)
+ assert_equal "omg", computer.system
+
+ computer.developer = 99
+ assert_equal 99, computer.developer
+ end
+
def test_on_the_fly_super_invokable_generated_attribute_methods_via_method_missing
klass = new_topic_like_ar_class do
def title
diff --git a/activerecord/test/cases/attribute_test.rb b/activerecord/test/cases/attribute_test.rb
index 91f6aee931..7b325abf1d 100644
--- a/activerecord/test/cases/attribute_test.rb
+++ b/activerecord/test/cases/attribute_test.rb
@@ -138,5 +138,35 @@ module ActiveRecord
test "uninitialized attributes have no value" do
assert_nil Attribute.uninitialized(:foo, nil).value
end
+
+ test "attributes equal other attributes with the same constructor arguments" do
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
+ second = Attribute.from_database(:foo, 1, Type::Integer.new)
+ assert_equal first, second
+ end
+
+ test "attributes do not equal attributes with different names" do
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
+ second = Attribute.from_database(:bar, 1, Type::Integer.new)
+ assert_not_equal first, second
+ end
+
+ test "attributes do not equal attributes with different types" do
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
+ second = Attribute.from_database(:foo, 1, Type::Float.new)
+ assert_not_equal first, second
+ end
+
+ test "attributes do not equal attributes with different values" do
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
+ second = Attribute.from_database(:foo, 2, Type::Integer.new)
+ assert_not_equal first, second
+ end
+
+ test "attributes do not equal attributes of other classes" do
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
+ second = Attribute.from_user(:foo, 1, Type::Integer.new)
+ assert_not_equal first, second
+ end
end
end
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 09892d50ba..025cdbeba9 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -499,7 +499,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_before_save
company = companies(:first_firm)
- new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
+ new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build("name" => "Another Client") }
assert !company.clients_of_firm.loaded?
company.name += '-changed'
@@ -510,7 +510,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_many_before_save
company = companies(:first_firm)
- assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
+ assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
company.name += '-changed'
assert_queries(3) { assert company.save }
@@ -519,7 +519,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_via_block_before_save
company = companies(:first_firm)
- new_client = assert_no_queries { company.clients_of_firm.build {|client| client.name = "Another Client" } }
+ new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build {|client| client.name = "Another Client" } }
assert !company.clients_of_firm.loaded?
company.name += '-changed'
@@ -530,7 +530,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_many_via_block_before_save
company = companies(:first_firm)
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client|
client.name = "changed"
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 4c0b0c868a..fb535e74fc 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1540,20 +1540,6 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal "", Company.new.description
end
- ["find_by", "find_by!"].each do |meth|
- test "#{meth} delegates to scoped" do
- record = stub
-
- scope = mock
- scope.expects(meth).with(:foo, :bar).returns(record)
-
- klass = Class.new(ActiveRecord::Base)
- klass.stubs(:all => scope)
-
- assert_equal record, klass.public_send(meth, :foo, :bar)
- end
- end
-
test "scoped can take a values hash" do
klass = Class.new(ActiveRecord::Base)
assert_equal ['foo'], klass.all.merge!(select: 'foo').select_values
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 319ea9260a..ec6a319ab5 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -11,8 +11,6 @@ require 'models/minivan'
require 'models/speedometer'
require 'models/ship_part'
-Company.has_many :accounts
-
class NumericData < ActiveRecord::Base
self.table_name = 'numeric_data'
@@ -22,7 +20,7 @@ class NumericData < ActiveRecord::Base
end
class CalculationsTest < ActiveRecord::TestCase
- fixtures :companies, :accounts, :topics
+ fixtures :companies, :accounts, :topics, :speedometers, :minivans
def test_should_sum_field
assert_equal 318, Account.sum(:credit_limit)
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 69a7f25213..eb9b1a2d74 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -661,6 +661,43 @@ class DirtyTest < ActiveRecord::TestCase
assert_not model.foo_changed?
end
+ test "in place mutation detection" do
+ pirate = Pirate.create!(catchphrase: "arrrr")
+ pirate.catchphrase << " matey!"
+
+ assert pirate.catchphrase_changed?
+ expected_changes = {
+ "catchphrase" => ["arrrr", "arrrr matey!"]
+ }
+ assert_equal(expected_changes, pirate.changes)
+ assert_equal("arrrr", pirate.catchphrase_was)
+ assert pirate.catchphrase_changed?(from: "arrrr")
+ assert_not pirate.catchphrase_changed?(from: "anything else")
+ assert pirate.changed_attributes.include?(:catchphrase)
+
+ pirate.save!
+ pirate.reload
+
+ assert_equal "arrrr matey!", pirate.catchphrase
+ assert_not pirate.changed?
+ end
+
+ test "in place mutation for binary" do
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = :binaries
+ serialize :data
+ end
+
+ klass.create!(data: "foo")
+ binary = klass.last
+
+ assert_not binary.changed?
+
+ binary.data << "bar"
+
+ assert binary.changed?
+ end
+
private
def with_partial_writes(klass, on = true)
old = klass.partial_writes?
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index 3b2f0dfe07..346fcab6ea 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -194,7 +194,8 @@ class EnumTest < ActiveRecord::TestCase
:valid, # generates #valid?, which conflicts with an AR method
:save, # generates #save!, which conflicts with an AR method
:proposed, # same value as an existing enum
- :public, :private, :protected, # generates a method that conflict with ruby words
+ :public, :private, :protected, # some important methods on Module and Class
+ :name, :parent, :superclass
]
conflicts.each_with_index do |value, i|
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 40e51a0cdc..fc91b728c2 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -4,6 +4,7 @@ require 'models/author'
require 'models/categorization'
require 'models/comment'
require 'models/company'
+require 'models/tagging'
require 'models/topic'
require 'models/reply'
require 'models/entrant'
@@ -51,7 +52,7 @@ class FinderTest < ActiveRecord::TestCase
end
def test_symbols_table_ref
- Post.first # warm up
+ Post.where("author_id" => nil) # warm up
x = Symbol.all_symbols.count
Post.where("title" => {"xxxqqqq" => "bar"})
assert_equal x, Symbol.all_symbols.count
@@ -78,6 +79,19 @@ class FinderTest < ActiveRecord::TestCase
assert_raise(NoMethodError) { Topic.exists?([1,2]) }
end
+ def test_exists_with_polymorphic_relation
+ post = Post.create!(title: 'Post', body: 'default', taggings: [Tagging.new(comment: 'tagging comment')])
+ relation = Post.tagged_with_comment('tagging comment')
+
+ assert_equal true, relation.exists?(title: ['Post'])
+ assert_equal true, relation.exists?(['title LIKE ?', 'Post%'])
+ assert_equal true, relation.exists?
+ assert_equal true, relation.exists?(post.id)
+ assert_equal true, relation.exists?(post.id.to_s)
+
+ assert_equal false, relation.exists?(false)
+ end
+
def test_exists_passing_active_record_object_is_deprecated
assert_deprecated do
Topic.exists?(Topic.new)
@@ -507,6 +521,34 @@ class FinderTest < ActiveRecord::TestCase
assert_equal [1,2,3,5,6,7,8,9], Comment.where(id: [1..2, 3, 5, 6..8, 9]).to_a.map(&:id).sort
end
+ def test_find_on_hash_conditions_with_array_of_ranges
+ assert_equal [1,2,6,7,8], Comment.where(id: [1..2, 6..8]).to_a.map(&:id).sort
+ end
+
+ def test_find_on_hash_conditions_with_nested_array_of_integers_and_ranges
+ assert_deprecated do
+ assert_equal [1,2,3,5,6,7,8,9], Comment.where(id: [[1..2], 3, [5], 6..8, 9]).to_a.map(&:id).sort
+ end
+ end
+
+ def test_find_on_hash_conditions_with_array_of_integers_and_arrays
+ assert_deprecated do
+ assert_equal [1,2,3,5,6,7,8,9], Comment.where(id: [[1, 2], 3, 5, [6, [7], 8], 9]).to_a.map(&:id).sort
+ end
+ end
+
+ def test_find_on_hash_conditions_with_nested_array_of_integers_and_ranges_and_nils
+ assert_deprecated do
+ assert_equal [1,3,4,5], Topic.where(parent_id: [[2..6], nil]).to_a.map(&:id).sort
+ end
+ end
+
+ def test_find_on_hash_conditions_with_nested_array_of_integers_and_ranges_and_more_nils
+ assert_deprecated do
+ assert_equal [], Topic.where(parent_id: [[7..10, nil, [nil]], [nil]]).to_a.map(&:id).sort
+ end
+ end
+
def test_find_on_multiple_hash_conditions
assert Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: false).find(1)
assert_raise(ActiveRecord::RecordNotFound) { Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: true).find(1) }
@@ -1013,6 +1055,48 @@ class FinderTest < ActiveRecord::TestCase
assert_nothing_raised(ActiveRecord::StatementInvalid) { Topic.offset("3").to_a }
end
+ test "find_by with hash conditions returns the first matching record" do
+ assert_equal posts(:eager_other), Post.find_by(id: posts(:eager_other).id)
+ end
+
+ test "find_by with non-hash conditions returns the first matching record" do
+ assert_equal posts(:eager_other), Post.find_by("id = #{posts(:eager_other).id}")
+ end
+
+ test "find_by with multi-arg conditions returns the first matching record" do
+ assert_equal posts(:eager_other), Post.find_by('id = ?', posts(:eager_other).id)
+ end
+
+ test "find_by returns nil if the record is missing" do
+ assert_equal nil, Post.find_by("1 = 0")
+ end
+
+ test "find_by doesn't have implicit ordering" do
+ assert_sql(/^((?!ORDER).)*$/) { Post.find_by(id: posts(:eager_other).id) }
+ end
+
+ test "find_by! with hash conditions returns the first matching record" do
+ assert_equal posts(:eager_other), Post.find_by!(id: posts(:eager_other).id)
+ end
+
+ test "find_by! with non-hash conditions returns the first matching record" do
+ assert_equal posts(:eager_other), Post.find_by!("id = #{posts(:eager_other).id}")
+ end
+
+ test "find_by! with multi-arg conditions returns the first matching record" do
+ assert_equal posts(:eager_other), Post.find_by!('id = ?', posts(:eager_other).id)
+ end
+
+ test "find_by! doesn't have implicit ordering" do
+ assert_sql(/^((?!ORDER).)*$/) { Post.find_by!(id: posts(:eager_other).id) }
+ end
+
+ test "find_by! raises RecordNotFound if the record is missing" do
+ assert_raises(ActiveRecord::RecordNotFound) do
+ Post.find_by!("1 = 0")
+ end
+ end
+
protected
def bind(statement, *vars)
if vars.first.is_a?(Hash)
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 042fdaf0bb..385ec48005 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -644,6 +644,7 @@ class LoadAllFixturesWithPathnameTest < ActiveRecord::TestCase
end
class FasterFixturesTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
fixtures :categories, :authors
def load_extra_fixture(name)
@@ -823,15 +824,20 @@ end
class FixtureLoadingTest < ActiveRecord::TestCase
def test_logs_message_for_failed_dependency_load
- ActiveRecord::TestCase.expects(:require_dependency).with(:does_not_exist).raises(LoadError)
- ActiveRecord::Base.logger.expects(:warn)
- ActiveRecord::TestCase.try_to_load_dependency(:does_not_exist)
+ ActiveRecord::Base.logger.expects(:warn).twice
+ ActiveRecord::TestCase.try_to_load_dependency('does_not_exist')
+ end
+
+ def test_does_not_logs_message_for_dependency_that_has_been_defined_with_set_fixture_class
+ ActiveRecord::TestCase.set_fixture_class unknown_dead_parrots: DeadParrot
+ ActiveRecord::Base.logger.expects(:warn).never
+ ActiveRecord::TestCase.try_to_load_dependency('unknown_dead_parrot')
end
def test_does_not_logs_message_for_successful_dependency_load
- ActiveRecord::TestCase.expects(:require_dependency).with(:works_out_fine)
+ ActiveRecord::TestCase.expects(:require_dependency).with('works_out_fine')
ActiveRecord::Base.logger.expects(:warn).never
- ActiveRecord::TestCase.try_to_load_dependency(:works_out_fine)
+ ActiveRecord::TestCase.try_to_load_dependency('works_out_fine')
end
end
diff --git a/activerecord/test/cases/forbidden_attributes_protection_test.rb b/activerecord/test/cases/forbidden_attributes_protection_test.rb
index 981a75faf6..f4e7646f03 100644
--- a/activerecord/test/cases/forbidden_attributes_protection_test.rb
+++ b/activerecord/test/cases/forbidden_attributes_protection_test.rb
@@ -66,4 +66,34 @@ class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase
person = Person.new
assert_nil person.assign_attributes(ProtectedParams.new({}))
end
+
+ def test_create_with_checks_permitted
+ params = ProtectedParams.new(first_name: 'Guille', gender: 'm')
+
+ assert_raises(ActiveModel::ForbiddenAttributesError) do
+ Person.create_with(params).create!
+ end
+ end
+
+ def test_create_with_works_with_params_values
+ params = ProtectedParams.new(first_name: 'Guille')
+
+ person = Person.create_with(first_name: params[:first_name]).create!
+ assert_equal 'Guille', person.first_name
+ end
+
+ def test_where_checks_permitted
+ params = ProtectedParams.new(first_name: 'Guille', gender: 'm')
+
+ assert_raises(ActiveModel::ForbiddenAttributesError) do
+ Person.where(params).create!
+ end
+ end
+
+ def test_where_works_with_params_values
+ params = ProtectedParams.new(first_name: 'Guille')
+
+ person = Person.where(first_name: params[:first_name]).create!
+ assert_equal 'Guille', person.first_name
+ end
end
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index 6a8aff4b69..3d9328b198 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -24,6 +24,9 @@ ActiveSupport::Deprecation.debug = true
# Disable available locale checks to avoid warnings running the test suite.
I18n.enforce_available_locales = false
+# Enable raise errors in after_commit and after_rollback.
+ActiveRecord::Base.raise_in_transactional_callbacks = true
+
# Connect to the database
ARTest.connect
@@ -47,6 +50,10 @@ def mysql_56?
ActiveRecord::Base.connection.send(:version).join(".") >= "5.6.0"
end
+def mysql_enforcing_gtid_consistency?
+ current_adapter?(:MysqlAdapter, :Mysql2Adapter) && 'ON' == ActiveRecord::Base.connection.show_variable('enforce_gtid_consistency')
+end
+
def supports_savepoints?
ActiveRecord::Base.connection.supports_savepoints?
end
@@ -112,15 +119,23 @@ def verify_default_timezone_config
end
end
-def enable_uuid_ossp!(connection)
+def enable_extension!(extension, connection)
return false unless connection.supports_extensions?
- return true if connection.extension_enabled?('uuid-ossp')
+ return connection.reconnect! if connection.extension_enabled?(extension)
- connection.enable_extension 'uuid-ossp'
+ connection.enable_extension extension
connection.commit_db_transaction
connection.reconnect!
end
+def disable_extension!(extension, connection)
+ return false unless connection.supports_extensions?
+ return true unless connection.extension_enabled?(extension)
+
+ connection.disable_extension extension
+ connection.reconnect!
+end
+
unless ENV['FIXTURE_DEBUG']
module ActiveRecord::TestFixtures::ClassMethods
def try_to_load_dependency_with_silence(*args)
@@ -201,3 +216,8 @@ module InTimeZone
end
require 'mocha/setup' # FIXME: stop using mocha
+
+# FIXME: we have tests that depend on run order, we should fix that and
+# remove this method call.
+require 'active_support/test_case'
+ActiveSupport::TestCase.my_tests_are_order_dependent!
diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb
index 285172d33e..8144f3e5c5 100644
--- a/activerecord/test/cases/invertible_migration_test.rb
+++ b/activerecord/test/cases/invertible_migration_test.rb
@@ -122,12 +122,17 @@ module ActiveRecord
end
end
+ setup do
+ @verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, false
+ end
+
teardown do
%w[horses new_horses].each do |table|
if ActiveRecord::Base.connection.table_exists?(table)
ActiveRecord::Base.connection.drop_table(table)
end
end
+ ActiveRecord::Migration.verbose = @verbose_was
end
def test_no_reverse
diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb
index 0c9dff2c25..5a4b1fb919 100644
--- a/activerecord/test/cases/locking_test.rb
+++ b/activerecord/test/cases/locking_test.rb
@@ -5,6 +5,7 @@ require 'models/job'
require 'models/reader'
require 'models/ship'
require 'models/legacy_thing'
+require 'models/personal_legacy_thing'
require 'models/reference'
require 'models/string_key_object'
require 'models/car'
@@ -311,30 +312,24 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
# See Lighthouse ticket #1966
def test_destroy_dependents
- # Establish dependent relationship between People and LegacyThing
- add_counter_column_to(Person, 'legacy_things_count')
- LegacyThing.connection.add_column LegacyThing.table_name, 'person_id', :integer
- LegacyThing.reset_column_information
- LegacyThing.class_eval do
- belongs_to :person, :counter_cache => true
- end
- Person.class_eval do
- has_many :legacy_things, :dependent => :destroy
- end
+ # Establish dependent relationship between Person and PersonalLegacyThing
+ add_counter_column_to(Person, 'personal_legacy_things_count')
+ PersonalLegacyThing.reset_column_information
# Make sure that counter incrementing doesn't cause problems
p1 = Person.new(:first_name => 'fjord')
p1.save!
- t = LegacyThing.new(:person => p1)
+ t = PersonalLegacyThing.new(:person => p1)
t.save!
p1.reload
- assert_equal 1, p1.legacy_things_count
+ assert_equal 1, p1.personal_legacy_things_count
assert p1.destroy
assert_equal true, p1.frozen?
assert_raises(ActiveRecord::RecordNotFound) { Person.find(p1.id) }
- assert_raises(ActiveRecord::RecordNotFound) { LegacyThing.find(t.id) }
+ assert_raises(ActiveRecord::RecordNotFound) { PersonalLegacyThing.find(t.id) }
ensure
- remove_counter_column_from(Person, 'legacy_things_count')
+ remove_counter_column_from(Person, 'personal_legacy_things_count')
+ PersonalLegacyThing.reset_column_information
end
private
diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb
index c66eaf1ee1..bd3dd29f4d 100644
--- a/activerecord/test/cases/migration/change_schema_test.rb
+++ b/activerecord/test/cases/migration/change_schema_test.rb
@@ -176,8 +176,11 @@ module ActiveRecord
end
def test_create_table_with_timestamps_should_create_datetime_columns
- connection.create_table table_name do |t|
- t.timestamps
+ # FIXME: Remove the silence when we change the default `null` behavior
+ ActiveSupport::Deprecation.silence do
+ connection.create_table table_name do |t|
+ t.timestamps
+ end
end
created_columns = connection.columns(table_name)
diff --git a/activerecord/test/cases/migration/change_table_test.rb b/activerecord/test/cases/migration/change_table_test.rb
index 3e9d957ed3..777a48ad14 100644
--- a/activerecord/test/cases/migration/change_table_test.rb
+++ b/activerecord/test/cases/migration/change_table_test.rb
@@ -88,8 +88,8 @@ module ActiveRecord
def test_timestamps_creates_updated_at_and_created_at
with_change_table do |t|
- @connection.expect :add_timestamps, nil, [:delete_me]
- t.timestamps
+ @connection.expect :add_timestamps, nil, [:delete_me, null: true]
+ t.timestamps null: true
end
end
diff --git a/activerecord/test/cases/migration/columns_test.rb b/activerecord/test/cases/migration/columns_test.rb
index 4e6d7963aa..e6aa901814 100644
--- a/activerecord/test/cases/migration/columns_test.rb
+++ b/activerecord/test/cases/migration/columns_test.rb
@@ -66,6 +66,9 @@ module ActiveRecord
def test_mysql_rename_column_preserves_auto_increment
rename_column "test_models", "id", "id_test"
assert_equal "auto_increment", connection.columns("test_models").find { |c| c.name == "id_test" }.extra
+ TestModel.reset_column_information
+ ensure
+ rename_column "test_models", "id_test", "id"
end
end
diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb
index c985092b4c..406dd70c37 100644
--- a/activerecord/test/cases/migration/foreign_key_test.rb
+++ b/activerecord/test/cases/migration/foreign_key_test.rb
@@ -29,8 +29,8 @@ module ActiveRecord
teardown do
if defined?(@connection)
- @connection.execute "DROP TABLE IF EXISTS astronauts"
- @connection.execute "DROP TABLE IF EXISTS rockets"
+ @connection.drop_table "astronauts" if @connection.table_exists? 'astronauts'
+ @connection.drop_table "rockets" if @connection.table_exists? 'rockets'
end
end
diff --git a/activerecord/test/cases/migration/helper.rb b/activerecord/test/cases/migration/helper.rb
index e28feedcf9..5bc0898f33 100644
--- a/activerecord/test/cases/migration/helper.rb
+++ b/activerecord/test/cases/migration/helper.rb
@@ -5,10 +5,6 @@ module ActiveRecord
class << self; attr_accessor :message_count; end
self.message_count = 0
- def puts(text="")
- ActiveRecord::Migration.message_count += 1
- end
-
module TestHelper
attr_reader :connection, :table_name
@@ -22,7 +18,7 @@ module ActiveRecord
super
@connection = ActiveRecord::Base.connection
connection.create_table :test_models do |t|
- t.timestamps
+ t.timestamps null: true
end
TestModel.reset_column_information
diff --git a/activerecord/test/cases/migration/index_test.rb b/activerecord/test/cases/migration/index_test.rb
index 93c3bfae7a..ac932378fd 100644
--- a/activerecord/test/cases/migration/index_test.rb
+++ b/activerecord/test/cases/migration/index_test.rb
@@ -95,6 +95,12 @@ module ActiveRecord
assert connection.index_exists?(:testings, [:foo, :bar])
end
+ def test_index_exists_with_custom_name_checks_columns
+ connection.add_index :testings, [:foo, :bar], name: "my_index"
+ assert connection.index_exists?(:testings, [:foo, :bar], name: "my_index")
+ assert_not connection.index_exists?(:testings, [:foo], name: "my_index")
+ end
+
def test_valid_index_options
assert_raise ArgumentError do
connection.add_index :testings, :foo, unqiue: true
diff --git a/activerecord/test/cases/migration/rename_table_test.rb b/activerecord/test/cases/migration/rename_table_test.rb
index ba39fb1dec..c8b3f75e10 100644
--- a/activerecord/test/cases/migration/rename_table_test.rb
+++ b/activerecord/test/cases/migration/rename_table_test.rb
@@ -78,11 +78,12 @@ module ActiveRecord
end
def test_renaming_table_doesnt_attempt_to_rename_non_existent_sequences
- enable_uuid_ossp!(connection)
+ enable_extension!('uuid-ossp', connection)
connection.create_table :cats, id: :uuid
assert_nothing_raised { rename_table :cats, :felines }
assert connection.table_exists? :felines
ensure
+ disable_extension!('uuid-ossp', connection)
connection.drop_table :cats if connection.table_exists? :cats
connection.drop_table :felines if connection.table_exists? :felines
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index ef3f073472..270e446c69 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -34,8 +34,7 @@ class MigrationTest < ActiveRecord::TestCase
Reminder.connection.drop_table(table) rescue nil
end
Reminder.reset_column_information
- ActiveRecord::Migration.verbose = true
- ActiveRecord::Migration.message_count = 0
+ @verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, false
ActiveRecord::Base.connection.schema_cache.clear!
end
@@ -65,6 +64,8 @@ class MigrationTest < ActiveRecord::TestCase
Person.connection.remove_column("people", "middle_name") rescue nil
Person.connection.add_column("people", "first_name", :string)
Person.reset_column_information
+
+ ActiveRecord::Migration.verbose = @verbose_was
end
def test_migrator_versions
@@ -81,6 +82,21 @@ class MigrationTest < ActiveRecord::TestCase
assert_equal 0, ActiveRecord::Migrator.current_version
assert_equal 3, ActiveRecord::Migrator.last_version
assert_equal true, ActiveRecord::Migrator.needs_migration?
+
+ ActiveRecord::SchemaMigration.create!(:version => ActiveRecord::Migrator.last_version)
+ assert_equal true, ActiveRecord::Migrator.needs_migration?
+ ensure
+ ActiveRecord::Migrator.migrations_paths = old_path
+ end
+
+ def test_migration_detection_without_schema_migration_table
+ ActiveRecord::Base.connection.drop_table('schema_migrations') if ActiveRecord::Base.connection.table_exists?('schema_migrations')
+
+ migrations_path = MIGRATIONS_ROOT + "/valid"
+ old_path = ActiveRecord::Migrator.migrations_paths
+ ActiveRecord::Migrator.migrations_paths = migrations_path
+
+ assert_equal true, ActiveRecord::Migrator.needs_migration?
ensure
ActiveRecord::Migrator.migrations_paths = old_path
end
@@ -414,30 +430,32 @@ class MigrationTest < ActiveRecord::TestCase
Person.connection.drop_table :binary_testings rescue nil
end
- def test_create_table_with_query
- Person.connection.drop_table :table_from_query_testings rescue nil
- Person.connection.create_table(:person, force: true)
+ unless mysql_enforcing_gtid_consistency?
+ def test_create_table_with_query
+ Person.connection.drop_table :table_from_query_testings rescue nil
+ Person.connection.create_table(:person, force: true)
- Person.connection.create_table :table_from_query_testings, as: "SELECT id FROM person"
+ Person.connection.create_table :table_from_query_testings, as: "SELECT id FROM person"
- columns = Person.connection.columns(:table_from_query_testings)
- assert_equal 1, columns.length
- assert_equal "id", columns.first.name
+ columns = Person.connection.columns(:table_from_query_testings)
+ assert_equal 1, columns.length
+ assert_equal "id", columns.first.name
- Person.connection.drop_table :table_from_query_testings rescue nil
- end
+ Person.connection.drop_table :table_from_query_testings rescue nil
+ end
- def test_create_table_with_query_from_relation
- Person.connection.drop_table :table_from_query_testings rescue nil
- Person.connection.create_table(:person, force: true)
+ def test_create_table_with_query_from_relation
+ Person.connection.drop_table :table_from_query_testings rescue nil
+ Person.connection.create_table(:person, force: true)
- Person.connection.create_table :table_from_query_testings, as: Person.select(:id)
+ Person.connection.create_table :table_from_query_testings, as: Person.select(:id)
- columns = Person.connection.columns(:table_from_query_testings)
- assert_equal 1, columns.length
- assert_equal "id", columns.first.name
+ columns = Person.connection.columns(:table_from_query_testings)
+ assert_equal 1, columns.length
+ assert_equal "id", columns.first.name
- Person.connection.drop_table :table_from_query_testings rescue nil
+ Person.connection.drop_table :table_from_query_testings rescue nil
+ end
end
if current_adapter? :OracleAdapter
@@ -561,7 +579,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter?
t.string :qualification, :experience
t.integer :age, :default => 0
t.date :birthdate
- t.timestamps
+ t.timestamps null: true
end
end
diff --git a/activerecord/test/cases/migrator_test.rb b/activerecord/test/cases/migrator_test.rb
index 9568aa2217..9809d83315 100644
--- a/activerecord/test/cases/migrator_test.rb
+++ b/activerecord/test/cases/migrator_test.rb
@@ -1,377 +1,388 @@
require "cases/helper"
require "cases/migration/helper"
-module ActiveRecord
- class MigratorTest < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+class MigratorTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
- # Use this class to sense if migrations have gone
- # up or down.
- class Sensor < ActiveRecord::Migration
- attr_reader :went_up, :went_down
+ # Use this class to sense if migrations have gone
+ # up or down.
+ class Sensor < ActiveRecord::Migration
+ attr_reader :went_up, :went_down
- def initialize name = self.class.name, version = nil
- super
- @went_up = false
- @went_down = false
- end
-
- def up; @went_up = true; end
- def down; @went_down = true; end
- end
-
- def setup
+ def initialize name = self.class.name, version = nil
super
- ActiveRecord::SchemaMigration.create_table
- ActiveRecord::SchemaMigration.delete_all rescue nil
+ @went_up = false
+ @went_down = false
end
- teardown do
- ActiveRecord::SchemaMigration.delete_all rescue nil
- ActiveRecord::Migration.verbose = true
- end
+ def up; @went_up = true; end
+ def down; @went_down = true; end
+ end
- def test_migrator_with_duplicate_names
- assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do
- list = [Migration.new('Chunky'), Migration.new('Chunky')]
- ActiveRecord::Migrator.new(:up, list)
+ def setup
+ super
+ ActiveRecord::SchemaMigration.create_table
+ ActiveRecord::SchemaMigration.delete_all rescue nil
+ @verbose_was = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.message_count = 0
+ ActiveRecord::Migration.class_eval do
+ undef :puts
+ def puts(*)
+ ActiveRecord::Migration.message_count += 1
end
end
+ end
- def test_migrator_with_duplicate_versions
- assert_raises(ActiveRecord::DuplicateMigrationVersionError) do
- list = [Migration.new('Foo', 1), Migration.new('Bar', 1)]
- ActiveRecord::Migrator.new(:up, list)
+ teardown do
+ ActiveRecord::SchemaMigration.delete_all rescue nil
+ ActiveRecord::Migration.verbose = @verbose_was
+ ActiveRecord::Migration.class_eval do
+ undef :puts
+ def puts(*)
+ super
end
end
+ end
- def test_migrator_with_missing_version_numbers
- assert_raises(ActiveRecord::UnknownMigrationVersionError) do
- list = [Migration.new('Foo', 1), Migration.new('Bar', 2)]
- ActiveRecord::Migrator.new(:up, list, 3).run
- end
+ def test_migrator_with_duplicate_names
+ assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do
+ list = [ActiveRecord::Migration.new('Chunky'), ActiveRecord::Migration.new('Chunky')]
+ ActiveRecord::Migrator.new(:up, list)
end
+ end
- def test_finds_migrations
- migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid")
+ def test_migrator_with_duplicate_versions
+ assert_raises(ActiveRecord::DuplicateMigrationVersionError) do
+ list = [ActiveRecord::Migration.new('Foo', 1), ActiveRecord::Migration.new('Bar', 1)]
+ ActiveRecord::Migrator.new(:up, list)
+ end
+ end
- [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
- assert_equal migrations[i].version, pair.first
- assert_equal migrations[i].name, pair.last
- end
+ def test_migrator_with_missing_version_numbers
+ assert_raises(ActiveRecord::UnknownMigrationVersionError) do
+ list = [ActiveRecord::Migration.new('Foo', 1), ActiveRecord::Migration.new('Bar', 2)]
+ ActiveRecord::Migrator.new(:up, list, 3).run
end
+ end
- def test_finds_migrations_in_subdirectories
- migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid_with_subdirectories")
+ def test_finds_migrations
+ migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid")
- [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
- assert_equal migrations[i].version, pair.first
- assert_equal migrations[i].name, pair.last
- end
+ [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
+ assert_equal migrations[i].version, pair.first
+ assert_equal migrations[i].name, pair.last
end
+ end
- def test_finds_migrations_from_two_directories
- directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps']
- migrations = ActiveRecord::Migrator.migrations directories
-
- [[20090101010101, "PeopleHaveHobbies"],
- [20090101010202, "PeopleHaveDescriptions"],
- [20100101010101, "ValidWithTimestampsPeopleHaveLastNames"],
- [20100201010101, "ValidWithTimestampsWeNeedReminders"],
- [20100301010101, "ValidWithTimestampsInnocentJointable"]].each_with_index do |pair, i|
- assert_equal pair.first, migrations[i].version
- assert_equal pair.last, migrations[i].name
- end
- end
+ def test_finds_migrations_in_subdirectories
+ migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid_with_subdirectories")
- def test_finds_migrations_in_numbered_directory
- migrations = ActiveRecord::Migrator.migrations [MIGRATIONS_ROOT + '/10_urban']
- assert_equal 9, migrations[0].version
- assert_equal 'AddExpressions', migrations[0].name
+ [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
+ assert_equal migrations[i].version, pair.first
+ assert_equal migrations[i].name, pair.last
end
+ end
- def test_relative_migrations
- list = Dir.chdir(MIGRATIONS_ROOT) do
- ActiveRecord::Migrator.migrations("valid")
- end
+ def test_finds_migrations_from_two_directories
+ directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps']
+ migrations = ActiveRecord::Migrator.migrations directories
+
+ [[20090101010101, "PeopleHaveHobbies"],
+ [20090101010202, "PeopleHaveDescriptions"],
+ [20100101010101, "ValidWithTimestampsPeopleHaveLastNames"],
+ [20100201010101, "ValidWithTimestampsWeNeedReminders"],
+ [20100301010101, "ValidWithTimestampsInnocentJointable"]].each_with_index do |pair, i|
+ assert_equal pair.first, migrations[i].version
+ assert_equal pair.last, migrations[i].name
+ end
+ end
- migration_proxy = list.find { |item|
- item.name == 'ValidPeopleHaveLastNames'
- }
- assert migration_proxy, 'should find pending migration'
+ def test_finds_migrations_in_numbered_directory
+ migrations = ActiveRecord::Migrator.migrations [MIGRATIONS_ROOT + '/10_urban']
+ assert_equal 9, migrations[0].version
+ assert_equal 'AddExpressions', migrations[0].name
+ end
+
+ def test_relative_migrations
+ list = Dir.chdir(MIGRATIONS_ROOT) do
+ ActiveRecord::Migrator.migrations("valid")
end
- def test_finds_pending_migrations
- ActiveRecord::SchemaMigration.create!(:version => '1')
- migration_list = [ Migration.new('foo', 1), Migration.new('bar', 3) ]
- migrations = ActiveRecord::Migrator.new(:up, migration_list).pending_migrations
+ migration_proxy = list.find { |item|
+ item.name == 'ValidPeopleHaveLastNames'
+ }
+ assert migration_proxy, 'should find pending migration'
+ end
- assert_equal 1, migrations.size
- assert_equal migration_list.last, migrations.first
- end
+ def test_finds_pending_migrations
+ ActiveRecord::SchemaMigration.create!(:version => '1')
+ migration_list = [ActiveRecord::Migration.new('foo', 1), ActiveRecord::Migration.new('bar', 3)]
+ migrations = ActiveRecord::Migrator.new(:up, migration_list).pending_migrations
- def test_migrator_interleaved_migrations
- pass_one = [Sensor.new('One', 1)]
+ assert_equal 1, migrations.size
+ assert_equal migration_list.last, migrations.first
+ end
- ActiveRecord::Migrator.new(:up, pass_one).migrate
- assert pass_one.first.went_up
- assert_not pass_one.first.went_down
+ def test_migrator_interleaved_migrations
+ pass_one = [Sensor.new('One', 1)]
- pass_two = [Sensor.new('One', 1), Sensor.new('Three', 3)]
- ActiveRecord::Migrator.new(:up, pass_two).migrate
- assert_not pass_two[0].went_up
- assert pass_two[1].went_up
- assert pass_two.all? { |x| !x.went_down }
+ ActiveRecord::Migrator.new(:up, pass_one).migrate
+ assert pass_one.first.went_up
+ assert_not pass_one.first.went_down
- pass_three = [Sensor.new('One', 1),
- Sensor.new('Two', 2),
- Sensor.new('Three', 3)]
+ pass_two = [Sensor.new('One', 1), Sensor.new('Three', 3)]
+ ActiveRecord::Migrator.new(:up, pass_two).migrate
+ assert_not pass_two[0].went_up
+ assert pass_two[1].went_up
+ assert pass_two.all? { |x| !x.went_down }
- ActiveRecord::Migrator.new(:down, pass_three).migrate
- assert pass_three[0].went_down
- assert_not pass_three[1].went_down
- assert pass_three[2].went_down
- end
+ pass_three = [Sensor.new('One', 1),
+ Sensor.new('Two', 2),
+ Sensor.new('Three', 3)]
- def test_up_calls_up
- migrations = [Sensor.new(nil, 0), Sensor.new(nil, 1), Sensor.new(nil, 2)]
- ActiveRecord::Migrator.new(:up, migrations).migrate
- assert migrations.all? { |m| m.went_up }
- assert migrations.all? { |m| !m.went_down }
- assert_equal 2, ActiveRecord::Migrator.current_version
- end
+ ActiveRecord::Migrator.new(:down, pass_three).migrate
+ assert pass_three[0].went_down
+ assert_not pass_three[1].went_down
+ assert pass_three[2].went_down
+ end
- def test_down_calls_down
- test_up_calls_up
+ def test_up_calls_up
+ migrations = [Sensor.new(nil, 0), Sensor.new(nil, 1), Sensor.new(nil, 2)]
+ ActiveRecord::Migrator.new(:up, migrations).migrate
+ assert migrations.all? { |m| m.went_up }
+ assert migrations.all? { |m| !m.went_down }
+ assert_equal 2, ActiveRecord::Migrator.current_version
+ end
- migrations = [Sensor.new(nil, 0), Sensor.new(nil, 1), Sensor.new(nil, 2)]
- ActiveRecord::Migrator.new(:down, migrations).migrate
- assert migrations.all? { |m| !m.went_up }
- assert migrations.all? { |m| m.went_down }
- assert_equal 0, ActiveRecord::Migrator.current_version
- end
+ def test_down_calls_down
+ test_up_calls_up
- def test_current_version
- ActiveRecord::SchemaMigration.create!(:version => '1000')
- assert_equal 1000, ActiveRecord::Migrator.current_version
- end
+ migrations = [Sensor.new(nil, 0), Sensor.new(nil, 1), Sensor.new(nil, 2)]
+ ActiveRecord::Migrator.new(:down, migrations).migrate
+ assert migrations.all? { |m| !m.went_up }
+ assert migrations.all? { |m| m.went_down }
+ assert_equal 0, ActiveRecord::Migrator.current_version
+ end
- def test_migrator_one_up
- calls, migrations = sensors(3)
+ def test_current_version
+ ActiveRecord::SchemaMigration.create!(:version => '1000')
+ assert_equal 1000, ActiveRecord::Migrator.current_version
+ end
- ActiveRecord::Migrator.new(:up, migrations, 1).migrate
- assert_equal [[:up, 1]], calls
- calls.clear
+ def test_migrator_one_up
+ calls, migrations = sensors(3)
- ActiveRecord::Migrator.new(:up, migrations, 2).migrate
- assert_equal [[:up, 2]], calls
- end
+ ActiveRecord::Migrator.new(:up, migrations, 1).migrate
+ assert_equal [[:up, 1]], calls
+ calls.clear
- def test_migrator_one_down
- calls, migrations = sensors(3)
+ ActiveRecord::Migrator.new(:up, migrations, 2).migrate
+ assert_equal [[:up, 2]], calls
+ end
- ActiveRecord::Migrator.new(:up, migrations).migrate
- assert_equal [[:up, 1], [:up, 2], [:up, 3]], calls
- calls.clear
+ def test_migrator_one_down
+ calls, migrations = sensors(3)
- ActiveRecord::Migrator.new(:down, migrations, 1).migrate
+ ActiveRecord::Migrator.new(:up, migrations).migrate
+ assert_equal [[:up, 1], [:up, 2], [:up, 3]], calls
+ calls.clear
- assert_equal [[:down, 3], [:down, 2]], calls
- end
+ ActiveRecord::Migrator.new(:down, migrations, 1).migrate
- def test_migrator_one_up_one_down
- calls, migrations = sensors(3)
+ assert_equal [[:down, 3], [:down, 2]], calls
+ end
- ActiveRecord::Migrator.new(:up, migrations, 1).migrate
- assert_equal [[:up, 1]], calls
- calls.clear
+ def test_migrator_one_up_one_down
+ calls, migrations = sensors(3)
- ActiveRecord::Migrator.new(:down, migrations, 0).migrate
- assert_equal [[:down, 1]], calls
- end
+ ActiveRecord::Migrator.new(:up, migrations, 1).migrate
+ assert_equal [[:up, 1]], calls
+ calls.clear
- def test_migrator_double_up
- calls, migrations = sensors(3)
- assert_equal(0, ActiveRecord::Migrator.current_version)
+ ActiveRecord::Migrator.new(:down, migrations, 0).migrate
+ assert_equal [[:down, 1]], calls
+ end
- ActiveRecord::Migrator.new(:up, migrations, 1).migrate
- assert_equal [[:up, 1]], calls
- calls.clear
+ def test_migrator_double_up
+ calls, migrations = sensors(3)
+ assert_equal(0, ActiveRecord::Migrator.current_version)
- ActiveRecord::Migrator.new(:up, migrations, 1).migrate
- assert_equal [], calls
- end
+ ActiveRecord::Migrator.new(:up, migrations, 1).migrate
+ assert_equal [[:up, 1]], calls
+ calls.clear
- def test_migrator_double_down
- calls, migrations = sensors(3)
+ ActiveRecord::Migrator.new(:up, migrations, 1).migrate
+ assert_equal [], calls
+ end
- assert_equal(0, ActiveRecord::Migrator.current_version)
+ def test_migrator_double_down
+ calls, migrations = sensors(3)
- ActiveRecord::Migrator.new(:up, migrations, 1).run
- assert_equal [[:up, 1]], calls
- calls.clear
+ assert_equal(0, ActiveRecord::Migrator.current_version)
- ActiveRecord::Migrator.new(:down, migrations, 1).run
- assert_equal [[:down, 1]], calls
- calls.clear
+ ActiveRecord::Migrator.new(:up, migrations, 1).run
+ assert_equal [[:up, 1]], calls
+ calls.clear
- ActiveRecord::Migrator.new(:down, migrations, 1).run
- assert_equal [], calls
+ ActiveRecord::Migrator.new(:down, migrations, 1).run
+ assert_equal [[:down, 1]], calls
+ calls.clear
- assert_equal(0, ActiveRecord::Migrator.current_version)
- end
+ ActiveRecord::Migrator.new(:down, migrations, 1).run
+ assert_equal [], calls
- def test_migrator_verbosity
- _, migrations = sensors(3)
+ assert_equal(0, ActiveRecord::Migrator.current_version)
+ end
- ActiveRecord::Migrator.new(:up, migrations, 1).migrate
- assert_not_equal 0, ActiveRecord::Migration.message_count
+ def test_migrator_verbosity
+ _, migrations = sensors(3)
- ActiveRecord::Migration.message_count = 0
+ ActiveRecord::Migrator.new(:up, migrations, 1).migrate
+ assert_not_equal 0, ActiveRecord::Migration.message_count
- ActiveRecord::Migrator.new(:down, migrations, 0).migrate
- assert_not_equal 0, ActiveRecord::Migration.message_count
- ActiveRecord::Migration.message_count = 0
- end
+ ActiveRecord::Migration.message_count = 0
- def test_migrator_verbosity_off
- _, migrations = sensors(3)
+ ActiveRecord::Migrator.new(:down, migrations, 0).migrate
+ assert_not_equal 0, ActiveRecord::Migration.message_count
+ end
- ActiveRecord::Migration.message_count = 0
- ActiveRecord::Migration.verbose = false
- ActiveRecord::Migrator.new(:up, migrations, 1).migrate
- assert_equal 0, ActiveRecord::Migration.message_count
- ActiveRecord::Migrator.new(:down, migrations, 0).migrate
- assert_equal 0, ActiveRecord::Migration.message_count
- end
+ def test_migrator_verbosity_off
+ _, migrations = sensors(3)
- def test_target_version_zero_should_run_only_once
- calls, migrations = sensors(3)
+ ActiveRecord::Migration.message_count = 0
+ ActiveRecord::Migration.verbose = false
+ ActiveRecord::Migrator.new(:up, migrations, 1).migrate
+ assert_equal 0, ActiveRecord::Migration.message_count
+ ActiveRecord::Migrator.new(:down, migrations, 0).migrate
+ assert_equal 0, ActiveRecord::Migration.message_count
+ end
- # migrate up to 1
- ActiveRecord::Migrator.new(:up, migrations, 1).migrate
- assert_equal [[:up, 1]], calls
- calls.clear
+ def test_target_version_zero_should_run_only_once
+ calls, migrations = sensors(3)
- # migrate down to 0
- ActiveRecord::Migrator.new(:down, migrations, 0).migrate
- assert_equal [[:down, 1]], calls
- calls.clear
+ # migrate up to 1
+ ActiveRecord::Migrator.new(:up, migrations, 1).migrate
+ assert_equal [[:up, 1]], calls
+ calls.clear
- # migrate down to 0 again
- ActiveRecord::Migrator.new(:down, migrations, 0).migrate
- assert_equal [], calls
- end
+ # migrate down to 0
+ ActiveRecord::Migrator.new(:down, migrations, 0).migrate
+ assert_equal [[:down, 1]], calls
+ calls.clear
- def test_migrator_going_down_due_to_version_target
- calls, migrator = migrator_class(3)
+ # migrate down to 0 again
+ ActiveRecord::Migrator.new(:down, migrations, 0).migrate
+ assert_equal [], calls
+ end
- migrator.up("valid", 1)
- assert_equal [[:up, 1]], calls
- calls.clear
+ def test_migrator_going_down_due_to_version_target
+ calls, migrator = migrator_class(3)
- migrator.migrate("valid", 0)
- assert_equal [[:down, 1]], calls
- calls.clear
+ migrator.up("valid", 1)
+ assert_equal [[:up, 1]], calls
+ calls.clear
- migrator.migrate("valid")
- assert_equal [[:up, 1], [:up, 2], [:up, 3]], calls
- end
+ migrator.migrate("valid", 0)
+ assert_equal [[:down, 1]], calls
+ calls.clear
- def test_migrator_rollback
- _, migrator = migrator_class(3)
+ migrator.migrate("valid")
+ assert_equal [[:up, 1], [:up, 2], [:up, 3]], calls
+ end
- migrator.migrate("valid")
- assert_equal(3, ActiveRecord::Migrator.current_version)
+ def test_migrator_rollback
+ _, migrator = migrator_class(3)
- migrator.rollback("valid")
- assert_equal(2, ActiveRecord::Migrator.current_version)
+ migrator.migrate("valid")
+ assert_equal(3, ActiveRecord::Migrator.current_version)
- migrator.rollback("valid")
- assert_equal(1, ActiveRecord::Migrator.current_version)
+ migrator.rollback("valid")
+ assert_equal(2, ActiveRecord::Migrator.current_version)
- migrator.rollback("valid")
- assert_equal(0, ActiveRecord::Migrator.current_version)
+ migrator.rollback("valid")
+ assert_equal(1, ActiveRecord::Migrator.current_version)
- migrator.rollback("valid")
- assert_equal(0, ActiveRecord::Migrator.current_version)
- end
+ migrator.rollback("valid")
+ assert_equal(0, ActiveRecord::Migrator.current_version)
- def test_migrator_db_has_no_schema_migrations_table
- _, migrator = migrator_class(3)
+ migrator.rollback("valid")
+ assert_equal(0, ActiveRecord::Migrator.current_version)
+ end
- ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations")
- assert_not ActiveRecord::Base.connection.table_exists?('schema_migrations')
- migrator.migrate("valid", 1)
- assert ActiveRecord::Base.connection.table_exists?('schema_migrations')
- end
+ def test_migrator_db_has_no_schema_migrations_table
+ _, migrator = migrator_class(3)
- def test_migrator_forward
- _, migrator = migrator_class(3)
- migrator.migrate("/valid", 1)
- assert_equal(1, ActiveRecord::Migrator.current_version)
+ ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations")
+ assert_not ActiveRecord::Base.connection.table_exists?('schema_migrations')
+ migrator.migrate("valid", 1)
+ assert ActiveRecord::Base.connection.table_exists?('schema_migrations')
+ end
- migrator.forward("/valid", 2)
- assert_equal(3, ActiveRecord::Migrator.current_version)
+ def test_migrator_forward
+ _, migrator = migrator_class(3)
+ migrator.migrate("/valid", 1)
+ assert_equal(1, ActiveRecord::Migrator.current_version)
- migrator.forward("/valid")
- assert_equal(3, ActiveRecord::Migrator.current_version)
- end
+ migrator.forward("/valid", 2)
+ assert_equal(3, ActiveRecord::Migrator.current_version)
- def test_only_loads_pending_migrations
- # migrate up to 1
- ActiveRecord::SchemaMigration.create!(:version => '1')
+ migrator.forward("/valid")
+ assert_equal(3, ActiveRecord::Migrator.current_version)
+ end
- calls, migrator = migrator_class(3)
- migrator.migrate("valid", nil)
+ def test_only_loads_pending_migrations
+ # migrate up to 1
+ ActiveRecord::SchemaMigration.create!(:version => '1')
- assert_equal [[:up, 2], [:up, 3]], calls
- end
+ calls, migrator = migrator_class(3)
+ migrator.migrate("valid", nil)
- def test_get_all_versions
- _, migrator = migrator_class(3)
+ assert_equal [[:up, 2], [:up, 3]], calls
+ end
- migrator.migrate("valid")
- assert_equal([1,2,3], ActiveRecord::Migrator.get_all_versions)
+ def test_get_all_versions
+ _, migrator = migrator_class(3)
- migrator.rollback("valid")
- assert_equal([1,2], ActiveRecord::Migrator.get_all_versions)
+ migrator.migrate("valid")
+ assert_equal([1,2,3], ActiveRecord::Migrator.get_all_versions)
- migrator.rollback("valid")
- assert_equal([1], ActiveRecord::Migrator.get_all_versions)
+ migrator.rollback("valid")
+ assert_equal([1,2], ActiveRecord::Migrator.get_all_versions)
- migrator.rollback("valid")
- assert_equal([], ActiveRecord::Migrator.get_all_versions)
- end
+ migrator.rollback("valid")
+ assert_equal([1], ActiveRecord::Migrator.get_all_versions)
- private
- def m(name, version, &block)
- x = Sensor.new name, version
- x.extend(Module.new {
- define_method(:up) { block.call(:up, x); super() }
- define_method(:down) { block.call(:down, x); super() }
- }) if block_given?
- end
+ migrator.rollback("valid")
+ assert_equal([], ActiveRecord::Migrator.get_all_versions)
+ end
+
+ private
+ def m(name, version, &block)
+ x = Sensor.new name, version
+ x.extend(Module.new {
+ define_method(:up) { block.call(:up, x); super() }
+ define_method(:down) { block.call(:down, x); super() }
+ }) if block_given?
+ end
- def sensors(count)
- calls = []
- migrations = count.times.map { |i|
- m(nil, i + 1) { |c,migration|
- calls << [c, migration.version]
- }
+ def sensors(count)
+ calls = []
+ migrations = count.times.map { |i|
+ m(nil, i + 1) { |c,migration|
+ calls << [c, migration.version]
}
- [calls, migrations]
- end
+ }
+ [calls, migrations]
+ end
- def migrator_class(count)
- calls, migrations = sensors(count)
+ def migrator_class(count)
+ calls, migrations = sensors(count)
- migrator = Class.new(Migrator).extend(Module.new {
- define_method(:migrations) { |paths|
- migrations
- }
- })
- [calls, migrator]
- end
+ migrator = Class.new(ActiveRecord::Migrator).extend(Module.new {
+ define_method(:migrations) { |paths|
+ migrations
+ }
+ })
+ [calls, migrator]
end
end
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index b04df7ce43..f19a6ea5e3 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -5,6 +5,7 @@ require 'models/subscriber'
require 'models/movie'
require 'models/keyboard'
require 'models/mixed_case_monkey'
+require 'models/dashboard'
class PrimaryKeysTest < ActiveRecord::TestCase
fixtures :topics, :subscribers, :movies, :mixed_case_monkeys
@@ -164,6 +165,15 @@ class PrimaryKeysTest < ActiveRecord::TestCase
MixedCaseMonkey.reset_primary_key
assert_equal "monkeyID", MixedCaseMonkey.primary_key
end
+
+ def test_primary_key_update_with_custom_key_name
+ dashboard = Dashboard.create!(dashboard_id: '1')
+ dashboard.id = '2'
+ dashboard.save!
+
+ dashboard = Dashboard.first
+ assert_equal '2', dashboard.id
+ end
end
class PrimaryKeyWithNoConnectionTest < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/relation/merging_test.rb b/activerecord/test/cases/relation/merging_test.rb
index 2b5c2fd5a4..8f40a1890d 100644
--- a/activerecord/test/cases/relation/merging_test.rb
+++ b/activerecord/test/cases/relation/merging_test.rb
@@ -4,6 +4,7 @@ require 'models/comment'
require 'models/developer'
require 'models/post'
require 'models/project'
+require 'models/rating'
class RelationMergingTest < ActiveRecord::TestCase
fixtures :developers, :comments, :authors, :posts
@@ -116,7 +117,7 @@ class RelationMergingTest < ActiveRecord::TestCase
end
class MergingDifferentRelationsTest < ActiveRecord::TestCase
- fixtures :posts, :authors
+ fixtures :posts, :authors, :developers
test "merging where relations" do
hello_by_bob = Post.where(body: "hello").joins(:author).
@@ -144,4 +145,16 @@ class MergingDifferentRelationsTest < ActiveRecord::TestCase
assert_equal ["Mary", "Mary", "Mary", "David"], posts_by_author_name
end
+
+ test "relation merging (using a proc argument)" do
+ dev = Developer.where(name: "Jamis").first
+
+ comment_1 = dev.comments.create!(body: "I'm Jamis", post: Post.first)
+ rating_1 = comment_1.ratings.create!
+
+ comment_2 = dev.comments.create!(body: "I'm John", post: Post.first)
+ comment_2.ratings.create!
+
+ assert_equal dev.ratings, [rating_1]
+ end
end
diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb
index a6a36a6fd9..39c8afdd23 100644
--- a/activerecord/test/cases/relation/where_test.rb
+++ b/activerecord/test/cases/relation/where_test.rb
@@ -61,6 +61,15 @@ module ActiveRecord
assert_equal expected.to_sql, actual.to_sql
end
+ def test_belongs_to_nested_where_with_relation
+ author = authors(:david)
+
+ expected = Author.where(id: author ).joins(:posts)
+ actual = Author.where(posts: { author_id: Author.where(id: author.id) }).joins(:posts)
+
+ assert_equal expected.to_a, actual.to_a
+ end
+
def test_polymorphic_shallow_where
treasure = Treasure.new
treasure.id = 1
@@ -171,6 +180,12 @@ module ActiveRecord
assert_equal 0, Post.where(:id => []).count
end
+ def test_where_with_table_name_and_nested_empty_array
+ assert_deprecated do
+ assert_equal [], Post.where(:id => [[]]).to_a
+ end
+ end
+
def test_where_with_empty_hash_and_no_foreign_key
assert_equal 0, Edge.where(:sink => {}).count
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 88df997a2f..7163697a68 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -311,26 +311,26 @@ class RelationTest < ActiveRecord::TestCase
end
def test_none
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal [], Developer.none
assert_equal [], Developer.all.none
end
end
def test_none_chainable
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal [], Developer.none.where(:name => 'David')
end
end
def test_none_chainable_to_existing_scope_extension_method
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal 1, Topic.anonymous_extension.none.one
end
end
def test_none_chained_to_methods_firing_queries_straight_to_db
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal [], Developer.none.pluck(:id, :name)
assert_equal 0, Developer.none.delete_all
assert_equal 0, Developer.none.update_all(:name => 'David')
@@ -340,7 +340,7 @@ class RelationTest < ActiveRecord::TestCase
end
def test_null_relation_content_size_methods
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal 0, Developer.none.size
assert_equal 0, Developer.none.count
assert_equal true, Developer.none.empty?
@@ -350,7 +350,7 @@ class RelationTest < ActiveRecord::TestCase
end
def test_null_relation_calculations_methods
- assert_no_queries do
+ assert_no_queries(ignore_none: false) do
assert_equal 0, Developer.none.count
assert_equal 0, Developer.none.calculate(:count, nil, {})
assert_equal nil, Developer.none.calculate(:average, 'salary')
@@ -1570,7 +1570,7 @@ class RelationTest < ActiveRecord::TestCase
end
test "find_by doesn't have implicit ordering" do
- assert_sql(/^((?!ORDER).)*$/) { Post.find_by(author_id: 2) }
+ assert_sql(/^((?!ORDER).)*$/) { Post.all.find_by(author_id: 2) }
end
test "find_by! with hash conditions returns the first matching record" do
@@ -1586,7 +1586,7 @@ class RelationTest < ActiveRecord::TestCase
end
test "find_by! doesn't have implicit ordering" do
- assert_sql(/^((?!ORDER).)*$/) { Post.find_by!(author_id: 2) }
+ assert_sql(/^((?!ORDER).)*$/) { Post.all.find_by!(author_id: 2) }
end
test "find_by! raises RecordNotFound if the record is missing" do
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 4e71d04bc0..d5584ad06c 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -2,15 +2,20 @@ require "cases/helper"
require 'support/schema_dumping_helper'
class SchemaDumperTest < ActiveRecord::TestCase
+ include SchemaDumpingHelper
+ self.use_transactional_fixtures = false
+
setup do
ActiveRecord::SchemaMigration.create_table
end
def standard_dump
@stream = StringIO.new
- ActiveRecord::SchemaDumper.ignore_tables = []
+ old_ignore_tables, ActiveRecord::SchemaDumper.ignore_tables = ActiveRecord::SchemaDumper.ignore_tables, []
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, @stream)
@stream.string
+ ensure
+ ActiveRecord::SchemaDumper.ignore_tables = old_ignore_tables
end
def test_dump_schema_information_outputs_lexically_ordered_versions
@@ -21,6 +26,8 @@ class SchemaDumperTest < ActiveRecord::TestCase
schema_info = ActiveRecord::Base.connection.dump_schema_information
assert_match(/20100201010101.*20100301010101/m, schema_info)
+ ensure
+ ActiveRecord::SchemaMigration.delete_all
end
def test_magic_comment
@@ -86,20 +93,12 @@ class SchemaDumperTest < ActiveRecord::TestCase
end
def test_schema_dump_includes_not_null_columns
- stream = StringIO.new
-
- ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/]
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
- output = stream.string
+ output = dump_all_table_schema([/^[^r]/])
assert_match %r{null: false}, output
end
def test_schema_dump_includes_limit_constraint_for_integer_columns
- stream = StringIO.new
-
- ActiveRecord::SchemaDumper.ignore_tables = [/^(?!integer_limits)/]
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
- output = stream.string
+ output = dump_all_table_schema([/^(?!integer_limits)/])
if current_adapter?(:PostgreSQLAdapter)
assert_match %r{c_int_1.*limit: 2}, output
@@ -146,22 +145,14 @@ class SchemaDumperTest < ActiveRecord::TestCase
end
def test_schema_dump_with_string_ignored_table
- stream = StringIO.new
-
- ActiveRecord::SchemaDumper.ignore_tables = ['accounts']
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
- output = stream.string
+ output = dump_all_table_schema(['accounts'])
assert_no_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_migrations"}, output
end
def test_schema_dump_with_regexp_ignored_table
- stream = StringIO.new
-
- ActiveRecord::SchemaDumper.ignore_tables = [/^account/]
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
- output = stream.string
+ output = dump_all_table_schema([/^account/])
assert_no_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_migrations"}, output
@@ -169,10 +160,12 @@ class SchemaDumperTest < ActiveRecord::TestCase
def test_schema_dump_illegal_ignored_table_value
stream = StringIO.new
- ActiveRecord::SchemaDumper.ignore_tables = [5]
+ old_ignore_tables, ActiveRecord::SchemaDumper.ignore_tables = ActiveRecord::SchemaDumper.ignore_tables, [5]
assert_raise(StandardError) do
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
end
+ ensure
+ ActiveRecord::SchemaDumper.ignore_tables = old_ignore_tables
end
def test_schema_dumps_index_columns_in_right_order
@@ -241,10 +234,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
end
def test_schema_dump_includes_decimal_options
- stream = StringIO.new
- ActiveRecord::SchemaDumper.ignore_tables = [/^[^n]/]
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
- output = stream.string
+ output = dump_all_table_schema([/^[^n]/])
assert_match %r{precision: 3,[[:space:]]+scale: 2,[[:space:]]+default: 2.78}, output
end
@@ -437,7 +427,7 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
teardown do
return unless @connection
- @connection.execute 'DROP TABLE IF EXISTS defaults'
+ @connection.execute 'DROP TABLE defaults' if @connection.table_exists? 'defaults'
end
def test_schema_dump_defaults_with_universally_supported_types
diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb
index 9a4d8c6740..a5c4404175 100644
--- a/activerecord/test/cases/scoping/default_scoping_test.rb
+++ b/activerecord/test/cases/scoping/default_scoping_test.rb
@@ -1,9 +1,10 @@
require 'cases/helper'
require 'models/post'
+require 'models/comment'
require 'models/developer'
class DefaultScopingTest < ActiveRecord::TestCase
- fixtures :developers, :posts
+ fixtures :developers, :posts, :comments
def test_default_scope
expected = Developer.all.merge!(:order => 'salary DESC').to_a.collect { |dev| dev.salary }
@@ -378,6 +379,24 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal 1, DeveloperWithIncludes.where(:audit_logs => { :message => 'foo' }).count
end
+ def test_default_scope_with_references_works_through_collection_association
+ post = PostWithCommentWithDefaultScopeReferencesAssociation.create!(title: "Hello World", body: "Here we go.")
+ comment = post.comment_with_default_scope_references_associations.create!(body: "Great post.", developer_id: Developer.first.id)
+ assert_equal comment, post.comment_with_default_scope_references_associations.to_a.first
+ end
+
+ def test_default_scope_with_references_works_through_association
+ post = PostWithCommentWithDefaultScopeReferencesAssociation.create!(title: "Hello World", body: "Here we go.")
+ comment = post.comment_with_default_scope_references_associations.create!(body: "Great post.", developer_id: Developer.first.id)
+ assert_equal comment, post.first_comment
+ end
+
+ def test_default_scope_with_references_works_with_find_by
+ post = PostWithCommentWithDefaultScopeReferencesAssociation.create!(title: "Hello World", body: "Here we go.")
+ comment = post.comment_with_default_scope_references_associations.create!(body: "Great post.", developer_id: Developer.first.id)
+ assert_equal comment, CommentWithDefaultScopeReferencesAssociation.find_by(id: comment.id)
+ end
+
unless in_memory_db?
def test_default_scope_is_threadsafe
threads = []
diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb
index 59ec2dd6a4..d3546bd471 100644
--- a/activerecord/test/cases/scoping/named_scoping_test.rb
+++ b/activerecord/test/cases/scoping/named_scoping_test.rb
@@ -291,9 +291,12 @@ class NamedScopingTest < ActiveRecord::TestCase
:relation, # private class method on AR::Base
:new, # redefined class method on AR::Base
:all, # a default scope
- :public,
+ :public, # some imporant methods on Module and Class
:protected,
- :private
+ :private,
+ :name,
+ :parent,
+ :superclass
]
non_conflicts = [
diff --git a/activerecord/test/cases/scoping/relation_scoping_test.rb b/activerecord/test/cases/scoping/relation_scoping_test.rb
index d8a467ec4d..8e512e118a 100644
--- a/activerecord/test/cases/scoping/relation_scoping_test.rb
+++ b/activerecord/test/cases/scoping/relation_scoping_test.rb
@@ -11,6 +11,10 @@ require 'models/reference'
class RelationScopingTest < ActiveRecord::TestCase
fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects
+ setup do
+ developers(:david)
+ end
+
def test_reverse_order
assert_equal Developer.order("id DESC").to_a.reverse, Developer.order("id DESC").reverse_order
end
@@ -260,7 +264,7 @@ class NestedRelationScopingTest < ActiveRecord::TestCase
end
end
-class HasManyScopingTest< ActiveRecord::TestCase
+class HasManyScopingTest < ActiveRecord::TestCase
fixtures :comments, :posts, :people, :references
def setup
@@ -306,7 +310,7 @@ class HasManyScopingTest< ActiveRecord::TestCase
end
end
-class HasAndBelongsToManyScopingTest< ActiveRecord::TestCase
+class HasAndBelongsToManyScopingTest < ActiveRecord::TestCase
fixtures :posts, :categories, :categories_posts
def setup
diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb
index f8d87a3661..c5fb491b10 100644
--- a/activerecord/test/cases/serialized_attribute_test.rb
+++ b/activerecord/test/cases/serialized_attribute_test.rb
@@ -16,8 +16,8 @@ class SerializedAttributeTest < ActiveRecord::TestCase
end
def test_serialize_does_not_eagerly_load_columns
+ Topic.reset_column_information
assert_no_queries do
- Topic.reset_column_information
Topic.serialize(:content)
end
end
diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb
index 01d373b691..2fa033ed45 100644
--- a/activerecord/test/cases/tasks/database_tasks_test.rb
+++ b/activerecord/test/cases/tasks/database_tasks_test.rb
@@ -309,6 +309,7 @@ module ActiveRecord
ActiveRecord::Tasks::DatabaseTasks.expects(:purge).
with('database' => 'prod-db')
+ ActiveRecord::Base.expects(:establish_connection).with(:production)
ActiveRecord::Tasks::DatabaseTasks.purge_current('production')
end
diff --git a/activerecord/test/cases/test_case.rb b/activerecord/test/cases/test_case.rb
index 23a170388e..eb44c4a83c 100644
--- a/activerecord/test/cases/test_case.rb
+++ b/activerecord/test/cases/test_case.rb
@@ -93,8 +93,8 @@ module ActiveRecord
# ignored SQL, or better yet, use a different notification for the queries
# instead examining the SQL content.
oracle_ignored = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im, /^\s*select .* from all_constraints/im, /^\s*select .* from all_tab_cols/im]
- mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i]
- postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
+ mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i, /^SHOW VARIABLES /]
+ postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select tablename\b.*from pg_tables\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
sqlite3_ignored = [/^\s*SELECT name\b.*\bFROM sqlite_master/im]
[oracle_ignored, mysql_ignored, postgresql_ignored, sqlite3_ignored].each do |db_ignored_sql|
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index 0472246f71..abf6becc17 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -1,4 +1,5 @@
require 'cases/helper'
+require 'support/ddl_helper'
require 'models/developer'
require 'models/owner'
require 'models/pet'
@@ -424,3 +425,21 @@ class TimestampTest < ActiveRecord::TestCase
assert_equal [:created_at, :updated_at], toy.send(:all_timestamp_attributes_in_model)
end
end
+
+class TimestampsWithoutTransactionTest < ActiveRecord::TestCase
+ include DdlHelper
+ self.use_transactional_fixtures = false
+
+ class TimestampAttributePost < ActiveRecord::Base
+ attr_accessor :created_at, :updated_at
+ end
+
+ def test_do_not_write_timestamps_on_save_if_they_are_not_attributes
+ with_example_table ActiveRecord::Base.connection, "timestamp_attribute_posts", "id integer primary key" do
+ post = TimestampAttributePost.new(id: 1)
+ post.save! # should not try to assign and persist created_at, updated_at
+ assert_nil post.created_at
+ assert_nil post.updated_at
+ end
+ end
+end
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index 3d64ecb464..b5ac1bdaf9 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -129,6 +129,19 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
assert_equal [:commit_on_update], @first.history
end
+ def test_only_call_after_commit_on_top_level_transactions
+ @first.after_commit_block{|r| r.history << :after_commit}
+ assert @first.history.empty?
+
+ @first.transaction do
+ @first.transaction(requires_new: true) do
+ @first.touch
+ end
+ assert @first.history.empty?
+ end
+ assert_equal [:after_commit], @first.history
+ end
+
def test_call_after_rollback_after_transaction_rollsback
@first.after_commit_block{|r| r.history << :after_commit}
@first.after_rollback_block{|r| r.history << :after_rollback}
@@ -254,6 +267,9 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
end
def test_after_transaction_callbacks_should_prevent_callbacks_from_being_called
+ old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
+ ActiveRecord::Base.raise_in_transactional_callbacks = false
+
def @first.last_after_transaction_error=(e); @last_transaction_error = e; end
def @first.last_after_transaction_error; @last_transaction_error; end
@first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";}
@@ -278,6 +294,79 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
end
assert_equal :rollback, @first.last_after_transaction_error
assert_equal [:after_rollback], second.history
+ ensure
+ ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
+ end
+
+ def test_after_commit_should_not_raise_when_raise_in_transactional_callbacks_false
+ old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
+ ActiveRecord::Base.raise_in_transactional_callbacks = false
+ @first.after_commit_block{ fail "boom" }
+ Topic.transaction { @first.save! }
+ ensure
+ ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
+ end
+
+ def test_after_commit_callback_should_not_swallow_errors
+ @first.after_commit_block{ fail "boom" }
+ assert_raises(RuntimeError) do
+ Topic.transaction do
+ @first.save!
+ end
+ end
+ end
+
+ def test_after_commit_callback_when_raise_should_not_restore_state
+ first = TopicWithCallbacks.new
+ second = TopicWithCallbacks.new
+ first.after_commit_block{ fail "boom" }
+ second.after_commit_block{ fail "boom" }
+
+ begin
+ Topic.transaction do
+ first.save!
+ assert_not_nil first.id
+ second.save!
+ assert_not_nil second.id
+ end
+ rescue
+ end
+ assert_not_nil first.id
+ assert_not_nil second.id
+ assert first.reload
+ end
+
+ def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
+ error_class = Class.new(StandardError)
+ @first.after_rollback_block{ raise error_class }
+ assert_raises(error_class) do
+ Topic.transaction do
+ @first.save!
+ raise ActiveRecord::Rollback
+ end
+ end
+ end
+
+ def test_after_rollback_callback_when_raise_should_restore_state
+ error_class = Class.new(StandardError)
+
+ first = TopicWithCallbacks.new
+ second = TopicWithCallbacks.new
+ first.after_rollback_block{ raise error_class }
+ second.after_rollback_block{ raise error_class }
+
+ begin
+ Topic.transaction do
+ first.save!
+ assert_not_nil first.id
+ second.save!
+ assert_not_nil second.id
+ raise ActiveRecord::Rollback
+ end
+ rescue error_class
+ end
+ assert_nil first.id
+ assert_nil second.id
end
def test_after_rollback_callbacks_should_validate_on_condition
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index e518033192..9cfe041de2 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -80,6 +80,30 @@ class TransactionTest < ActiveRecord::TestCase
end
end
+ def test_number_of_transactions_in_commit
+ num = nil
+
+ Topic.connection.class_eval do
+ alias :real_commit_db_transaction :commit_db_transaction
+ define_method(:commit_db_transaction) do
+ num = transaction_manager.open_transactions
+ real_commit_db_transaction
+ end
+ end
+
+ Topic.transaction do
+ @first.approved = true
+ @first.save!
+ end
+
+ assert_equal 0, num
+ ensure
+ Topic.connection.class_eval do
+ remove_method :commit_db_transaction
+ alias :commit_db_transaction :real_commit_db_transaction rescue nil
+ end
+ end
+
def test_successful_with_instance_method
@first.transaction do
@first.approved = true
@@ -552,7 +576,7 @@ class TransactionTest < ActiveRecord::TestCase
assert !transaction.state.rolledback?
assert !transaction.state.committed?
- transaction.perform_rollback
+ transaction.rollback
assert transaction.state.rolledback?
assert !transaction.state.committed?
@@ -566,7 +590,7 @@ class TransactionTest < ActiveRecord::TestCase
assert !transaction.state.rolledback?
assert !transaction.state.committed?
- transaction.perform_commit
+ transaction.commit
assert !transaction.state.rolledback?
assert transaction.state.committed?
diff --git a/activerecord/test/cases/type/decimal_test.rb b/activerecord/test/cases/type/decimal_test.rb
index 951cd879dd..da30de373e 100644
--- a/activerecord/test/cases/type/decimal_test.rb
+++ b/activerecord/test/cases/type/decimal_test.rb
@@ -10,6 +10,11 @@ module ActiveRecord
assert_equal BigDecimal.new("1"), type.type_cast_from_user(:"1")
end
+ def test_type_cast_decimal_from_float_with_large_precision
+ type = Decimal.new(precision: ::Float::DIG + 2)
+ assert_equal BigDecimal.new("123.0"), type.type_cast_from_user(123.0)
+ end
+
def test_type_cast_decimal_from_rational_with_precision
type = Decimal.new(precision: 2)
assert_equal BigDecimal("0.33"), type.type_cast_from_user(Rational(1, 3))
diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb
index 5c54812f30..db4f78d354 100644
--- a/activerecord/test/cases/types_test.rb
+++ b/activerecord/test/cases/types_test.rb
@@ -149,6 +149,12 @@ module ActiveRecord
end
end
+ def test_type_equality
+ assert_equal Type::Value.new, Type::Value.new
+ assert_not_equal Type::Value.new, Type::Integer.new
+ assert_not_equal Type::Value.new(precision: 1), Type::Value.new(precision: 2)
+ end
+
if current_adapter?(:SQLite3Adapter)
def test_binary_encoding
type = SQLite3Binary.new
diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb
index 3db742c15b..268d7914b5 100644
--- a/activerecord/test/cases/validations/i18n_validation_test.rb
+++ b/activerecord/test/cases/validations/i18n_validation_test.rb
@@ -6,6 +6,7 @@ class I18nValidationTest < ActiveRecord::TestCase
repair_validations(Topic, Reply)
def setup
+ repair_validations(Topic, Reply)
Reply.validates_presence_of(:title)
@topic = Topic.new
@old_load_path, @old_backend = I18n.load_path.dup, I18n.backend
diff --git a/activerecord/test/cases/validations_repair_helper.rb b/activerecord/test/cases/validations_repair_helper.rb
index c02b3241cd..2bbf0f23b3 100644
--- a/activerecord/test/cases/validations_repair_helper.rb
+++ b/activerecord/test/cases/validations_repair_helper.rb
@@ -13,7 +13,7 @@ module ActiveRecord
end
def repair_validations(*model_classes)
- yield
+ yield if block_given?
ensure
model_classes.each do |k|
k.clear_validators!
diff --git a/activerecord/test/cases/view_test.rb b/activerecord/test/cases/view_test.rb
new file mode 100644
index 0000000000..357265aa05
--- /dev/null
+++ b/activerecord/test/cases/view_test.rb
@@ -0,0 +1,95 @@
+require "cases/helper"
+require "models/book"
+
+if ActiveRecord::Base.connection.supports_views?
+class ViewWithPrimaryKeyTest < ActiveRecord::TestCase
+ fixtures :books
+
+ class Ebook < ActiveRecord::Base
+ self.primary_key = "id"
+ end
+
+ setup do
+ @connection = ActiveRecord::Base.connection
+ @connection.execute <<-SQL
+ CREATE VIEW ebooks
+ AS SELECT id, name, status FROM books WHERE format = 'ebook'
+ SQL
+ end
+
+ teardown do
+ @connection.execute "DROP VIEW ebooks" if @connection.table_exists? "ebooks"
+ end
+
+ def test_reading
+ books = Ebook.all
+ assert_equal [books(:rfr).id], books.map(&:id)
+ assert_equal ["Ruby for Rails"], books.map(&:name)
+ end
+
+ def test_table_exists
+ view_name = Ebook.table_name
+ assert @connection.table_exists?(view_name), "'#{view_name}' table should exist"
+ end
+
+ def test_column_definitions
+ assert_equal([["id", :integer],
+ ["name", :string],
+ ["status", :integer]], Ebook.columns.map { |c| [c.name, c.type] })
+ end
+
+ def test_attributes
+ assert_equal({"id" => 2, "name" => "Ruby for Rails", "status" => 0},
+ Ebook.first.attributes)
+ end
+
+ def test_does_not_assume_id_column_as_primary_key
+ model = Class.new(ActiveRecord::Base) do
+ self.table_name = "ebooks"
+ end
+ assert_nil model.primary_key
+ end
+end
+
+class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase
+ fixtures :books
+
+ class Paperback < ActiveRecord::Base; end
+
+ setup do
+ @connection = ActiveRecord::Base.connection
+ @connection.execute <<-SQL
+ CREATE VIEW paperbacks
+ AS SELECT name, status FROM books WHERE format = 'paperback'
+ SQL
+ end
+
+ teardown do
+ @connection.execute "DROP VIEW paperbacks" if @connection.table_exists? "paperbacks"
+ end
+
+ def test_reading
+ books = Paperback.all
+ assert_equal ["Agile Web Development with Rails"], books.map(&:name)
+ end
+
+ def test_table_exists
+ view_name = Paperback.table_name
+ assert @connection.table_exists?(view_name), "'#{view_name}' table should exist"
+ end
+
+ def test_column_definitions
+ assert_equal([["name", :string],
+ ["status", :integer]], Paperback.columns.map { |c| [c.name, c.type] })
+ end
+
+ def test_attributes
+ assert_equal({"name" => "Agile Web Development with Rails", "status" => 0},
+ Paperback.first.attributes)
+ end
+
+ def test_does_not_have_a_primary_key
+ assert_nil Paperback.primary_key
+ end
+end
+end
diff --git a/activerecord/test/config.example.yml b/activerecord/test/config.example.yml
index a54914c372..ce30cff9e7 100644
--- a/activerecord/test/config.example.yml
+++ b/activerecord/test/config.example.yml
@@ -55,6 +55,7 @@ connections:
arunit:
username: rails
encoding: utf8
+ collation: utf8_unicode_ci
arunit2:
username: rails
encoding: utf8
@@ -63,6 +64,7 @@ connections:
arunit:
username: rails
encoding: utf8
+ collation: utf8_unicode_ci
arunit2:
username: rails
encoding: utf8
diff --git a/activerecord/test/fixtures/developers.yml b/activerecord/test/fixtures/developers.yml
index 3656564f63..1a74563dc6 100644
--- a/activerecord/test/fixtures/developers.yml
+++ b/activerecord/test/fixtures/developers.yml
@@ -18,4 +18,4 @@ dev_<%= digit %>:
poor_jamis:
id: 11
name: Jamis
- salary: 9000 \ No newline at end of file
+ salary: 9000
diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb
index 15970758db..b38b17e90e 100644
--- a/activerecord/test/models/comment.rb
+++ b/activerecord/test/models/comment.rb
@@ -9,6 +9,7 @@ class Comment < ActiveRecord::Base
belongs_to :post, :counter_cache => true
belongs_to :author, polymorphic: true
belongs_to :resource, polymorphic: true
+ belongs_to :developer
has_many :ratings
@@ -51,3 +52,8 @@ class CommentThatAutomaticallyAltersPostBody < Comment
comment.post.update_attributes(body: "Automatically altered")
end
end
+
+class CommentWithDefaultScopeReferencesAssociation < Comment
+ default_scope ->{ includes(:developer).order('developers.name').references(:developer) }
+ belongs_to :developer
+end
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index 76411ecb37..42f7fb4680 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -10,6 +10,7 @@ class Company < AbstractCompany
has_one :dummy_account, :foreign_key => "firm_id", :class_name => "Account"
has_many :contracts
has_many :developers, :through => :contracts
+ has_many :accounts
scope :of_first_firm, lambda {
joins(:account => :firm).
diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb
index 5bd2f00129..3627cfdd09 100644
--- a/activerecord/test/models/developer.rb
+++ b/activerecord/test/models/developer.rb
@@ -46,6 +46,8 @@ class Developer < ActiveRecord::Base
has_many :audit_logs
has_many :contracts
has_many :firms, :through => :contracts, :source => :firm
+ has_many :comments, ->(developer) { where(body: "I'm #{developer.name}") }
+ has_many :ratings, through: :comments
scope :jamises, -> { where(:name => 'Jamis') }
diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb
index c7e54e7b63..ad12f00d42 100644
--- a/activerecord/test/models/person.rb
+++ b/activerecord/test/models/person.rb
@@ -30,6 +30,8 @@ class Person < ActiveRecord::Base
has_many :agents_of_agents, :through => :agents, :source => :agents
belongs_to :number1_fan, :class_name => 'Person'
+ has_many :personal_legacy_things, :dependent => :destroy
+
has_many :agents_posts, :through => :agents, :source => :posts
has_many :agents_posts_authors, :through => :agents_posts, :source => :author
has_many :essays, primary_key: "first_name", foreign_key: "writer_id"
diff --git a/activerecord/test/models/personal_legacy_thing.rb b/activerecord/test/models/personal_legacy_thing.rb
new file mode 100644
index 0000000000..a7ee3a0bca
--- /dev/null
+++ b/activerecord/test/models/personal_legacy_thing.rb
@@ -0,0 +1,4 @@
+class PersonalLegacyThing < ActiveRecord::Base
+ self.locking_column = :version
+ belongs_to :person, :counter_cache => true
+end
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index a29858213b..256b720c9a 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -41,6 +41,7 @@ class Post < ActiveRecord::Base
scope :with_tags, -> { preload(:taggings) }
scope :tagged_with, ->(id) { joins(:taggings).where(taggings: { tag_id: id }) }
+ scope :tagged_with_comment, ->(comment) { joins(:taggings).where(taggings: { comment: comment }) }
has_many :comments do
def find_most_recent
@@ -217,3 +218,9 @@ class PostThatLoadsCommentsInAnAfterSaveHook < ActiveRecord::Base
post.comments.load
end
end
+
+class PostWithCommentWithDefaultScopeReferencesAssociation < ActiveRecord::Base
+ self.table_name = 'posts'
+ has_many :comment_with_default_scope_references_associations, foreign_key: :post_id
+ has_one :first_comment, class_name: "CommentWithDefaultScopeReferencesAssociation", foreign_key: :post_id
+end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index a8b21904ac..10de3d34cb 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -10,7 +10,7 @@ ActiveRecord::Schema.define do
#put adapter specific setup here
case adapter_name
when "PostgreSQL"
- enable_uuid_ossp!(ActiveRecord::Base.connection)
+ enable_extension!('uuid-ossp', ActiveRecord::Base.connection)
create_table :uuid_parents, id: :uuid, force: true do |t|
t.string :name
end
@@ -138,7 +138,7 @@ ActiveRecord::Schema.define do
t.integer :engines_count
t.integer :wheels_count
t.column :lock_version, :integer, null: false, default: 0
- t.timestamps
+ t.timestamps null: false
end
create_table :categories, force: true do |t|
@@ -198,6 +198,7 @@ ActiveRecord::Schema.define do
t.references :author, polymorphic: true
t.string :resource_id
t.string :resource_type
+ t.integer :developer_id
end
create_table :companies, force: true do |t|
@@ -537,7 +538,7 @@ ActiveRecord::Schema.define do
t.references :best_friend_of
t.integer :insures, null: false, default: 0
t.timestamp :born_at
- t.timestamps
+ t.timestamps null: false
end
create_table :peoples_treasures, id: false, force: true do |t|
@@ -545,10 +546,16 @@ ActiveRecord::Schema.define do
t.column :treasure_id, :integer
end
+ create_table :personal_legacy_things, force: true do |t|
+ t.integer :tps_report_number
+ t.integer :person_id
+ t.integer :version, null: false, default: 0
+ end
+
create_table :pets, primary_key: :pet_id, force: true do |t|
t.string :name
t.integer :owner_id, :integer
- t.timestamps
+ t.timestamps null: false
end
create_table :pirates, force: true do |t|
@@ -726,13 +733,13 @@ ActiveRecord::Schema.define do
t.string :parent_title
t.string :type
t.string :group
- t.timestamps
+ t.timestamps null: true
end
create_table :toys, primary_key: :toy_id, force: true do |t|
t.string :name
t.integer :pet_id, :integer
- t.timestamps
+ t.timestamps null: false
end
create_table :traffic_lights, force: true do |t|
diff --git a/activerecord/test/support/schema_dumping_helper.rb b/activerecord/test/support/schema_dumping_helper.rb
index 2ae8d299e5..2d1651454d 100644
--- a/activerecord/test/support/schema_dumping_helper.rb
+++ b/activerecord/test/support/schema_dumping_helper.rb
@@ -8,4 +8,13 @@ module SchemaDumpingHelper
ensure
ActiveRecord::SchemaDumper.ignore_tables = old_ignore_tables
end
+
+ def dump_all_table_schema(ignore_tables)
+ old_ignore_tables, ActiveRecord::SchemaDumper.ignore_tables = ActiveRecord::SchemaDumper.ignore_tables, ignore_tables
+ stream = StringIO.new
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
+ stream.string
+ ensure
+ ActiveRecord::SchemaDumper.ignore_tables = old_ignore_tables
+ end
end