aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r--activerecord/test/cases/adapter_test.rb16
-rw-r--r--activerecord/test/cases/adapters/mysql2/active_schema_test.rb24
-rw-r--r--activerecord/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb28
-rw-r--r--activerecord/test/cases/adapters/postgresql/bytea_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/datatype_test.rb2
-rw-r--r--activerecord/test/cases/ar_schema_test.rb8
-rw-r--r--activerecord/test/cases/arel/visitors/oracle12_test.rb21
-rw-r--r--activerecord/test/cases/arel/visitors/oracle_test.rb21
-rw-r--r--activerecord/test/cases/associations/eager_load_nested_include_test.rb4
-rw-r--r--activerecord/test/cases/associations/eager_test.rb23
-rw-r--r--activerecord/test/cases/associations/extension_test.rb2
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb16
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb16
-rw-r--r--activerecord/test/cases/associations/inverse_associations_test.rb9
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb4
-rw-r--r--activerecord/test/cases/base_test.rb12
-rw-r--r--activerecord/test/cases/calculations_test.rb11
-rw-r--r--activerecord/test/cases/callbacks_test.rb4
-rw-r--r--activerecord/test/cases/collection_cache_key_test.rb34
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb43
-rw-r--r--activerecord/test/cases/connection_adapters/schema_cache_test.rb4
-rw-r--r--activerecord/test/cases/date_time_precision_test.rb2
-rw-r--r--activerecord/test/cases/insert_all_test.rb87
-rw-r--r--activerecord/test/cases/invertible_migration_test.rb59
-rw-r--r--activerecord/test/cases/locking_test.rb11
-rw-r--r--activerecord/test/cases/migration/column_attributes_test.rb6
-rw-r--r--activerecord/test/cases/migration/command_recorder_test.rb34
-rw-r--r--activerecord/test/cases/migration/compatibility_test.rb33
-rw-r--r--activerecord/test/cases/migration_test.rb10
-rw-r--r--activerecord/test/cases/primary_keys_test.rb8
-rw-r--r--activerecord/test/cases/relation/delegation_test.rb2
-rw-r--r--activerecord/test/cases/relation/update_all_test.rb32
-rw-r--r--activerecord/test/cases/relation/where_clause_test.rb2
-rw-r--r--activerecord/test/cases/relation/where_test.rb55
-rw-r--r--activerecord/test/cases/relation_test.rb4
-rw-r--r--activerecord/test/cases/scoping/relation_scoping_test.rb28
-rw-r--r--activerecord/test/cases/tasks/database_tasks_test.rb6
-rw-r--r--activerecord/test/cases/time_precision_test.rb2
-rw-r--r--activerecord/test/cases/timestamp_test.rb14
-rw-r--r--activerecord/test/cases/touch_later_test.rb2
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb32
-rw-r--r--activerecord/test/cases/transactions_test.rb160
-rw-r--r--activerecord/test/cases/validations_test.rb12
43 files changed, 783 insertions, 122 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index ba04859bf0..ce2ed06c1d 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -490,6 +490,8 @@ module ActiveRecord
@connection.truncate("posts")
assert_equal 0, Post.count
+ ensure
+ reset_fixtures("posts")
end
def test_truncate_with_query_cache
@@ -501,6 +503,7 @@ module ActiveRecord
assert_equal 0, Post.count
ensure
+ reset_fixtures("posts")
@connection.disable_query_cache!
end
@@ -514,6 +517,8 @@ module ActiveRecord
assert_equal 0, Post.count
assert_equal 0, Author.count
assert_equal 0, AuthorAddress.count
+ ensure
+ reset_fixtures("posts", "authors", "author_addresses")
end
def test_truncate_tables_with_query_cache
@@ -529,6 +534,7 @@ module ActiveRecord
assert_equal 0, Author.count
assert_equal 0, AuthorAddress.count
ensure
+ reset_fixtures("posts", "authors", "author_addresses")
@connection.disable_query_cache!
end
@@ -551,6 +557,16 @@ module ActiveRecord
assert_nothing_raised { sub.save! }
end
end
+
+ private
+
+ def reset_fixtures(*fixture_names)
+ ActiveRecord::FixtureSet.reset_cache
+
+ fixture_names.each do |fixture_name|
+ ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT, fixture_name)
+ end
+ end
end
end
diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
index 88c2ac5d0a..c2c357d0c1 100644
--- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
@@ -10,7 +10,15 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
ActiveRecord::Base.connection.send(:default_row_format)
ActiveRecord::Base.connection.singleton_class.class_eval do
alias_method :execute_without_stub, :execute
- def execute(sql, name = nil) sql end
+ def execute(sql, name = nil)
+ ActiveSupport::Notifications.instrumenter.instrument(
+ "sql.active_record",
+ sql: sql,
+ name: name,
+ connection: self) do
+ sql
+ end
+ end
end
end
@@ -89,17 +97,19 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
%w(SPATIAL FULLTEXT UNIQUE).each do |type|
expected = "ALTER TABLE `people` ADD #{type} INDEX `index_people_on_last_name` (`last_name`)"
- actual = ActiveRecord::Base.connection.change_table(:people, bulk: true) do |t|
- t.index :last_name, type: type
+ assert_sql(expected) do
+ ActiveRecord::Base.connection.change_table(:people, bulk: true) do |t|
+ t.index :last_name, type: type
+ end
end
- assert_equal expected, actual
end
expected = "ALTER TABLE `people` ADD INDEX `index_people_on_last_name` USING btree (`last_name`(10)), ALGORITHM = COPY"
- actual = ActiveRecord::Base.connection.change_table(:people, bulk: true) do |t|
- t.index :last_name, length: 10, using: :btree, algorithm: :copy
+ assert_sql(expected) do
+ ActiveRecord::Base.connection.change_table(:people, bulk: true) do |t|
+ t.index :last_name, length: 10, using: :btree, algorithm: :copy
+ end
end
- assert_equal expected, actual
end
def test_drop_table
diff --git a/activerecord/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb b/activerecord/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb
new file mode 100644
index 0000000000..4d361e405c
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "support/connection_helper"
+require "models/author"
+require "models/bulb"
+
+module ActiveRecord
+ class CountDeletedRowsWithLockTest < ActiveRecord::Mysql2TestCase
+ test "delete and create in different threads synchronize correctly" do
+ Bulb.unscoped.delete_all
+ Bulb.create!(name: "Jimmy", color: "blue")
+
+ delete_thread = Thread.new do
+ Bulb.unscoped.delete_all
+ end
+
+ create_thread = Thread.new do
+ Author.create!(name: "Tommy")
+ end
+
+ delete_thread.join
+ create_thread.join
+
+ assert_equal 1, delete_thread.value
+ end
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
index 3988c2adca..531e6b2328 100644
--- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
@@ -35,7 +35,7 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
def test_binary_columns_are_limitless_the_upper_limit_is_one_GB
assert_equal "bytea", @connection.type_to_sql(:binary, limit: 100_000)
- assert_raise ActiveRecord::ActiveRecordError do
+ assert_raise ArgumentError do
@connection.type_to_sql(:binary, limit: 4294967295)
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
index b7535d5c9a..562cf1f2d1 100644
--- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
@@ -64,7 +64,7 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase
def test_text_columns_are_limitless_the_upper_limit_is_one_GB
assert_equal "text", @connection.type_to_sql(:text, limit: 100_000)
- assert_raise ActiveRecord::ActiveRecordError do
+ assert_raise ArgumentError do
@connection.type_to_sql(:text, limit: 4294967295)
end
end
diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb
index 9027cc582a..7aa6d089c5 100644
--- a/activerecord/test/cases/ar_schema_test.rb
+++ b/activerecord/test/cases/ar_schema_test.rb
@@ -160,7 +160,7 @@ class ActiveRecordSchemaTest < ActiveRecord::TestCase
end
if subsecond_precision_supported?
- def test_timestamps_sets_presicion_on_create_table
+ def test_timestamps_sets_precision_on_create_table
ActiveRecord::Schema.define do
create_table :has_timestamps do |t|
t.timestamps
@@ -171,7 +171,7 @@ class ActiveRecordSchemaTest < ActiveRecord::TestCase
assert @connection.column_exists?(:has_timestamps, :updated_at, precision: 6, null: false)
end
- def test_timestamps_sets_presicion_on_change_table
+ def test_timestamps_sets_precision_on_change_table
ActiveRecord::Schema.define do
create_table :has_timestamps
@@ -185,7 +185,7 @@ class ActiveRecordSchemaTest < ActiveRecord::TestCase
end
if ActiveRecord::Base.connection.supports_bulk_alter?
- def test_timestamps_sets_presicion_on_change_table_with_bulk
+ def test_timestamps_sets_precision_on_change_table_with_bulk
ActiveRecord::Schema.define do
create_table :has_timestamps
@@ -199,7 +199,7 @@ class ActiveRecordSchemaTest < ActiveRecord::TestCase
end
end
- def test_timestamps_sets_presicion_on_add_timestamps
+ def test_timestamps_sets_precision_on_add_timestamps
ActiveRecord::Schema.define do
create_table :has_timestamps
add_timestamps :has_timestamps, default: Time.now
diff --git a/activerecord/test/cases/arel/visitors/oracle12_test.rb b/activerecord/test/cases/arel/visitors/oracle12_test.rb
index 4ce5cab4db..ebea12910d 100644
--- a/activerecord/test/cases/arel/visitors/oracle12_test.rb
+++ b/activerecord/test/cases/arel/visitors/oracle12_test.rb
@@ -8,6 +8,7 @@ module Arel
before do
@visitor = Oracle12.new Table.engine.connection
@table = Table.new(:users)
+ @attr = @table[:id]
end
def compile(node)
@@ -95,6 +96,26 @@ module Arel
sql.must_be_like %{ "users"."name" IS NOT NULL }
end
end
+
+ describe "Nodes::In" do
+ it "should know how to visit" do
+ ary = (1 .. 1001).to_a
+ node = @attr.in ary
+ compile(node).must_be_like %{
+ "users"."id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000) OR \"users\".\"id\" IN (1001)
+ }
+ end
+ end
+
+ describe "Nodes::NotIn" do
+ it "should know how to visit" do
+ ary = (1 .. 1001).to_a
+ node = @attr.not_in ary
+ compile(node).must_be_like %{
+ "users"."id" NOT IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000) AND \"users\".\"id\" NOT IN (1001)
+ }
+ end
+ end
end
end
end
diff --git a/activerecord/test/cases/arel/visitors/oracle_test.rb b/activerecord/test/cases/arel/visitors/oracle_test.rb
index 893edc7f74..f69b201855 100644
--- a/activerecord/test/cases/arel/visitors/oracle_test.rb
+++ b/activerecord/test/cases/arel/visitors/oracle_test.rb
@@ -8,6 +8,7 @@ module Arel
before do
@visitor = Oracle.new Table.engine.connection
@table = Table.new(:users)
+ @attr = @table[:id]
end
def compile(node)
@@ -231,6 +232,26 @@ module Arel
sql.must_be_like %{ "users"."name" IS NOT NULL }
end
end
+
+ describe "Nodes::In" do
+ it "should know how to visit" do
+ ary = (1 .. 1001).to_a
+ node = @attr.in ary
+ compile(node).must_be_like %{
+ "users"."id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000) OR \"users\".\"id\" IN (1001)
+ }
+ end
+ end
+
+ describe "Nodes::NotIn" do
+ it "should know how to visit" do
+ ary = (1 .. 1001).to_a
+ node = @attr.not_in ary
+ compile(node).must_be_like %{
+ "users"."id" NOT IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000) AND \"users\".\"id\" NOT IN (1001)
+ }
+ end
+ end
end
end
end
diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb
index 525ad3197a..849939de75 100644
--- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb
+++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb
@@ -110,10 +110,10 @@ class EagerLoadNestedIncludeWithMissingDataTest < ActiveRecord::TestCase
end
teardown do
- @davey_mcdave.destroy
- @first_post.destroy
@first_comment.destroy
@first_categorization.destroy
+ @davey_mcdave.destroy
+ @first_post.destroy
end
def test_missing_data_in_a_nested_include_should_not_cause_errors_when_constructing_objects
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index cd9c8a5285..594d161fa3 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -1400,11 +1400,24 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_equal expected, FirstPost.unscoped.find(2)
end
- test "preload ignores the scoping" do
- assert_equal(
- Comment.find(1).post,
- Post.where("1 = 0").scoping { Comment.preload(:post).find(1).post }
- )
+ test "belongs_to association ignores the scoping" do
+ post = Comment.find(1).post
+
+ Post.where("1=0").scoping do
+ assert_equal post, Comment.find(1).post
+ assert_equal post, Comment.preload(:post).find(1).post
+ assert_equal post, Comment.eager_load(:post).find(1).post
+ end
+ end
+
+ test "has_many association ignores the scoping" do
+ comments = Post.find(1).comments.to_a
+
+ Comment.where("1=0").scoping do
+ assert_equal comments, Post.find(1).comments
+ assert_equal comments, Post.preload(:comments).find(1).comments
+ assert_equal comments, Post.eager_load(:comments).find(1).comments
+ end
end
test "deep preload" do
diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb
index aef8f31112..d93d787f7c 100644
--- a/activerecord/test/cases/associations/extension_test.rb
+++ b/activerecord/test/cases/associations/extension_test.rb
@@ -89,6 +89,6 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase
private
def extend!(model)
- ActiveRecord::Associations::Builder::HasMany.define_extensions(model, :association_name) { }
+ ActiveRecord::Associations::Builder::HasMany.send(:define_extensions, model, :association_name) { }
end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 6a7efe2121..32285f269a 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -2578,22 +2578,22 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
test "association with extend option" do
post = posts(:welcome)
- assert_equal "lifo", post.comments_with_extend.author
- assert_equal "hello", post.comments_with_extend.greeting
+ assert_equal "lifo", post.comments_with_extend.author
+ assert_equal "hello :)", post.comments_with_extend.greeting
end
test "association with extend option with multiple extensions" do
post = posts(:welcome)
- assert_equal "lifo", post.comments_with_extend_2.author
- assert_equal "hullo", post.comments_with_extend_2.greeting
+ assert_equal "lifo", post.comments_with_extend_2.author
+ assert_equal "hullo :)", post.comments_with_extend_2.greeting
end
test "extend option affects per association" do
post = posts(:welcome)
- assert_equal "lifo", post.comments_with_extend.author
- assert_equal "lifo", post.comments_with_extend_2.author
- assert_equal "hello", post.comments_with_extend.greeting
- assert_equal "hullo", post.comments_with_extend_2.greeting
+ assert_equal "lifo", post.comments_with_extend.author
+ assert_equal "lifo", post.comments_with_extend_2.author
+ assert_equal "hello :)", post.comments_with_extend.greeting
+ assert_equal "hullo :)", post.comments_with_extend_2.greeting
end
test "delete record with complex joins" do
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 fa540c9dab..c13789f7ec 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -33,6 +33,9 @@ require "models/organization"
require "models/user"
require "models/family"
require "models/family_tree"
+require "models/section"
+require "models/seminar"
+require "models/session"
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
fixtures :posts, :readers, :people, :comments, :authors, :categories, :taggings, :tags,
@@ -1492,6 +1495,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
end
end
+ def test_circular_autosave_association_correctly_saves_multiple_records
+ cs180 = Seminar.new(name: "CS180")
+ fall = Session.new(name: "Fall")
+ sections = [
+ cs180.sections.build(short_name: "A"),
+ cs180.sections.build(short_name: "B"),
+ ]
+ fall.sections << sections
+ fall.save!
+ fall.reload
+ assert_equal sections, fall.sections.sort_by(&:id)
+ end
+
private
def make_model(name)
Class.new(ActiveRecord::Base) { define_singleton_method(:name) { name } }
diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb
index da3a42e2b5..669e176dcb 100644
--- a/activerecord/test/cases/associations/inverse_associations_test.rb
+++ b/activerecord/test/cases/associations/inverse_associations_test.rb
@@ -8,6 +8,7 @@ require "models/zine"
require "models/club"
require "models/sponsor"
require "models/rating"
+require "models/post"
require "models/comment"
require "models/car"
require "models/bulb"
@@ -62,6 +63,14 @@ class AutomaticInverseFindingTests < ActiveRecord::TestCase
assert_equal rating_reflection, comment_reflection.inverse_of, "The Comment reflection's inverse should be the Rating reflection"
end
+ def test_has_many_and_belongs_to_should_find_inverse_automatically_for_extension_block
+ comment_reflection = Comment.reflect_on_association(:post)
+ post_reflection = Post.reflect_on_association(:comments)
+
+ assert_predicate post_reflection, :has_inverse?
+ assert_equal comment_reflection, post_reflection.inverse_of
+ end
+
def test_has_many_and_belongs_to_should_find_inverse_automatically_for_sti
author_reflection = Author.reflect_on_association(:posts)
author_child_reflection = Author.reflect_on_association(:special_posts)
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index 9fd62dcf72..5cbe5d796d 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -1081,9 +1081,9 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert_equal ["title"], model.accessed_fields
end
- test "generated attribute methods ancestors have correct class" do
+ test "generated attribute methods ancestors have correct module" do
mod = Topic.send(:generated_attribute_methods)
- assert_match %r(Topic::GeneratedAttributeMethods), mod.inspect
+ assert_equal "Topic::GeneratedAttributeMethods", mod.inspect
end
private
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 99f47cfe37..ddafa468ed 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -67,6 +67,16 @@ end
class BasicsTest < ActiveRecord::TestCase
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, "warehouse-things", :authors, :author_addresses, :categorizations, :categories, :posts
+ def test_generated_association_methods_module_name
+ mod = Post.send(:generated_association_methods)
+ assert_equal "Post::GeneratedAssociationMethods", mod.inspect
+ end
+
+ def test_generated_relation_methods_module_name
+ mod = Post.send(:generated_relation_methods)
+ assert_equal "Post::GeneratedRelationMethods", mod.inspect
+ end
+
def test_column_names_are_escaped
conn = ActiveRecord::Base.connection
classname = conn.class.name[/[^:]*$/]
@@ -1205,6 +1215,8 @@ class BasicsTest < ActiveRecord::TestCase
wr.close
assert Marshal.load rd.read
rd.close
+ ensure
+ self.class.send(:remove_const, "Post") if self.class.const_defined?("Post", false)
end
end
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index c4070fc341..16c2a3661d 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -363,6 +363,17 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal 60, c[2]
end
+ def test_should_calculate_grouped_with_longer_field
+ field = "a" * Account.connection.max_identifier_length
+
+ Account.update_all("#{field} = credit_limit")
+
+ c = Account.group(:firm_id).sum(field)
+ assert_equal 50, c[1]
+ assert_equal 105, c[6]
+ assert_equal 60, c[2]
+ end
+
def test_should_calculate_with_invalid_field
assert_equal 6, Account.calculate(:count, "*")
assert_equal 6, Account.calculate(:count, :all)
diff --git a/activerecord/test/cases/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb
index 4d6a112af5..b4026078f1 100644
--- a/activerecord/test/cases/callbacks_test.rb
+++ b/activerecord/test/cases/callbacks_test.rb
@@ -458,10 +458,6 @@ class CallbacksTest < ActiveRecord::TestCase
[ :before_validation, :object ],
[ :before_validation, :block ],
[ :before_validation, :throwing_abort ],
- [ :after_rollback, :block ],
- [ :after_rollback, :object ],
- [ :after_rollback, :proc ],
- [ :after_rollback, :method ],
], david.history
end
diff --git a/activerecord/test/cases/collection_cache_key_test.rb b/activerecord/test/cases/collection_cache_key_test.rb
index 483383257b..f07f3c42e6 100644
--- a/activerecord/test/cases/collection_cache_key_test.rb
+++ b/activerecord/test/cases/collection_cache_key_test.rb
@@ -171,5 +171,39 @@ module ActiveRecord
assert_match(/\Adevelopers\/query-(\h+)-(\d+)-(\d+)\z/, developers.cache_key)
end
+
+ test "cache_key should be stable when using collection_cache_versioning" do
+ with_collection_cache_versioning do
+ developers = Developer.where(salary: 100000)
+
+ assert_match(/\Adevelopers\/query-(\h+)\z/, developers.cache_key)
+
+ /\Adevelopers\/query-(\h+)\z/ =~ developers.cache_key
+
+ assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
+ end
+ end
+
+ test "cache_version for relation" do
+ with_collection_cache_versioning do
+ developers = Developer.where(salary: 100000).order(updated_at: :desc)
+ last_developer_timestamp = developers.first.updated_at
+
+ assert_match(/(\d+)-(\d+)\z/, developers.cache_version)
+
+ /(\d+)-(\d+)\z/ =~ developers.cache_version
+
+ assert_equal developers.count.to_s, $1
+ assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $2
+ end
+ end
+
+ def with_collection_cache_versioning(value = true)
+ @old_collection_cache_versioning = ActiveRecord::Base.collection_cache_versioning
+ ActiveRecord::Base.collection_cache_versioning = value
+ yield
+ ensure
+ ActiveRecord::Base.collection_cache_versioning = @old_collection_cache_versioning
+ end
end
end
diff --git a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
index 36591097b6..d3184f39f5 100644
--- a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
@@ -203,26 +203,53 @@ module ActiveRecord
assert_equal "must provide a `database` or a `role`.", error.message
end
- def test_switching_connections_with_database_symbol
+ def test_switching_connections_with_database_symbol_uses_default_role
previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
config = {
"default_env" => {
- "readonly" => { adapter: "sqlite3", database: "db/readonly.sqlite3" },
- "primary" => { adapter: "sqlite3", database: "db/primary.sqlite3" }
+ "animals" => { adapter: "sqlite3", database: "db/animals.sqlite3" },
+ "primary" => { adapter: "sqlite3", database: "db/primary.sqlite3" }
}
}
@prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
- ActiveRecord::Base.connected_to(database: :readonly) do
- assert_equal :readonly, ActiveRecord::Base.current_role
- assert ActiveRecord::Base.connected_to?(role: :readonly)
+ ActiveRecord::Base.connected_to(database: :animals) do
+ assert_equal :writing, ActiveRecord::Base.current_role
+ assert ActiveRecord::Base.connected_to?(role: :writing)
handler = ActiveRecord::Base.connection_handler
- assert_equal handler, ActiveRecord::Base.connection_handlers[:readonly]
+ assert_equal handler, ActiveRecord::Base.connection_handlers[:writing]
+
+ assert_not_nil pool = handler.retrieve_connection_pool("primary")
+ assert_equal(config["default_env"]["animals"], pool.spec.config)
+ end
+ ensure
+ ActiveRecord::Base.configurations = @prev_configs
+ ActiveRecord::Base.establish_connection(:arunit)
+ ENV["RAILS_ENV"] = previous_env
+ end
+
+ def test_switching_connections_with_database_hash_uses_passed_role_and_database
+ previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
+
+ config = {
+ "default_env" => {
+ "animals" => { adapter: "sqlite3", database: "db/animals.sqlite3" },
+ "primary" => { adapter: "sqlite3", database: "db/primary.sqlite3" }
+ }
+ }
+ @prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
+
+ ActiveRecord::Base.connected_to(database: { writing: :primary }) do
+ assert_equal :writing, ActiveRecord::Base.current_role
+ assert ActiveRecord::Base.connected_to?(role: :writing)
+
+ handler = ActiveRecord::Base.connection_handler
+ assert_equal handler, ActiveRecord::Base.connection_handlers[:writing]
assert_not_nil pool = handler.retrieve_connection_pool("primary")
- assert_equal(config["default_env"]["readonly"], pool.spec.config)
+ assert_equal(config["default_env"]["primary"], pool.spec.config)
end
ensure
ActiveRecord::Base.configurations = @prev_configs
diff --git a/activerecord/test/cases/connection_adapters/schema_cache_test.rb b/activerecord/test/cases/connection_adapters/schema_cache_test.rb
index 89a9c30f9b..28e232b88f 100644
--- a/activerecord/test/cases/connection_adapters/schema_cache_test.rb
+++ b/activerecord/test/cases/connection_adapters/schema_cache_test.rb
@@ -95,6 +95,10 @@ module ActiveRecord
assert_no_queries do
assert_equal @database_version.to_s, @cache.database_version.to_s
+
+ if current_adapter?(:Mysql2Adapter)
+ assert_not_nil @cache.database_version.full_version_string
+ end
end
end
diff --git a/activerecord/test/cases/date_time_precision_test.rb b/activerecord/test/cases/date_time_precision_test.rb
index 9d1af9362d..79d63949ca 100644
--- a/activerecord/test/cases/date_time_precision_test.rb
+++ b/activerecord/test/cases/date_time_precision_test.rb
@@ -82,7 +82,7 @@ if subsecond_precision_supported?
end
def test_invalid_datetime_precision_raises_error
- assert_raises ActiveRecord::ActiveRecordError do
+ assert_raises ArgumentError do
@connection.create_table(:foos, force: true) do |t|
t.timestamps precision: 7
end
diff --git a/activerecord/test/cases/insert_all_test.rb b/activerecord/test/cases/insert_all_test.rb
index fc25701c80..f24c63031c 100644
--- a/activerecord/test/cases/insert_all_test.rb
+++ b/activerecord/test/cases/insert_all_test.rb
@@ -104,6 +104,44 @@ class InsertAllTest < ActiveRecord::TestCase
end
end
+ def test_insert_all_with_skip_duplicates_and_autonumber_id_not_given
+ skip unless supports_insert_on_duplicate_skip?
+
+ assert_difference "Book.count", 1 do
+ # These two books are duplicates according to an index on %i[author_id name]
+ # but their IDs are not specified so they will be assigned different IDs
+ # by autonumber. We will get an exception from MySQL if we attempt to skip
+ # one of these records by assigning its ID.
+ Book.insert_all [
+ { author_id: 8, name: "Refactoring" },
+ { author_id: 8, name: "Refactoring" }
+ ]
+ end
+ end
+
+ def test_insert_all_with_skip_duplicates_and_autonumber_id_given
+ skip unless supports_insert_on_duplicate_skip?
+
+ assert_difference "Book.count", 1 do
+ Book.insert_all [
+ { id: 200, author_id: 8, name: "Refactoring" },
+ { id: 201, author_id: 8, name: "Refactoring" }
+ ]
+ end
+ end
+
+ def test_skip_duplicates_strategy_does_not_secretly_upsert
+ skip unless supports_insert_on_duplicate_skip?
+
+ book = Book.create!(author_id: 8, name: "Refactoring", format: "EXPECTED")
+
+ assert_no_difference "Book.count" do
+ Book.insert(author_id: 8, name: "Refactoring", format: "UNEXPECTED")
+ end
+
+ assert_equal "EXPECTED", book.reload.format
+ end
+
def test_insert_all_will_raise_if_duplicates_are_skipped_only_for_a_certain_conflict_target
skip unless supports_insert_on_duplicate_skip? && supports_insert_conflict_target?
@@ -143,6 +181,42 @@ class InsertAllTest < ActiveRecord::TestCase
end
end
+ def test_insert_logs_message_including_model_name
+ skip unless supports_insert_conflict_target?
+
+ capture_log_output do |output|
+ Book.insert(name: "Rework", author_id: 1)
+ assert_match "Book Insert", output.string
+ end
+ end
+
+ def test_insert_all_logs_message_including_model_name
+ skip unless supports_insert_conflict_target?
+
+ capture_log_output do |output|
+ Book.insert_all [{ name: "Remote", author_id: 1 }, { name: "Renote", author_id: 1 }]
+ assert_match "Book Bulk Insert", output.string
+ end
+ end
+
+ def test_upsert_logs_message_including_model_name
+ skip unless supports_insert_on_duplicate_update?
+
+ capture_log_output do |output|
+ Book.upsert(name: "Remote", author_id: 1)
+ assert_match "Book Upsert", output.string
+ end
+ end
+
+ def test_upsert_all_logs_message_including_model_name
+ skip unless supports_insert_on_duplicate_update?
+
+ capture_log_output do |output|
+ Book.upsert_all [{ name: "Remote", author_id: 1 }, { name: "Renote", author_id: 1 }]
+ assert_match "Book Bulk Upsert", output.string
+ end
+ end
+
def test_upsert_all_updates_existing_records
skip unless supports_insert_on_duplicate_update?
@@ -186,4 +260,17 @@ class InsertAllTest < ActiveRecord::TestCase
Book.insert_all! [{ unknown_attribute: "Test" }]
end
end
+
+ private
+
+ def capture_log_output
+ output = StringIO.new
+ old_logger, ActiveRecord::Base.logger = ActiveRecord::Base.logger, ActiveSupport::Logger.new(output)
+
+ begin
+ yield output
+ ensure
+ ActiveRecord::Base.logger = old_logger
+ end
+ end
end
diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb
index d68cc40107..7f67b945f0 100644
--- a/activerecord/test/cases/invertible_migration_test.rb
+++ b/activerecord/test/cases/invertible_migration_test.rb
@@ -103,6 +103,32 @@ module ActiveRecord
end
end
+ class ChangeColumnComment1 < SilentMigration
+ def change
+ create_table("horses") do |t|
+ t.column :name, :string, comment: "Sekitoba"
+ end
+ end
+ end
+
+ class ChangeColumnComment2 < SilentMigration
+ def change
+ change_column_comment :horses, :name, from: "Sekitoba", to: "Diomed"
+ end
+ end
+
+ class ChangeTableComment1 < SilentMigration
+ def change
+ create_table("horses", comment: "Sekitoba")
+ end
+ end
+
+ class ChangeTableComment2 < SilentMigration
+ def change
+ change_table_comment :horses, from: "Sekitoba", to: "Diomed"
+ end
+ end
+
class DisableExtension1 < SilentMigration
def change
enable_extension "hstore"
@@ -290,6 +316,7 @@ module ActiveRecord
def test_migrate_revert_change_column_default
migration1 = ChangeColumnDefault1.new
migration1.migrate(:up)
+ Horse.reset_column_information
assert_equal "Sekitoba", Horse.new.name
migration2 = ChangeColumnDefault2.new
@@ -302,6 +329,38 @@ module ActiveRecord
assert_equal "Sekitoba", Horse.new.name
end
+ if ActiveRecord::Base.connection.supports_comments?
+ def test_migrate_revert_change_column_comment
+ migration1 = ChangeColumnComment1.new
+ migration1.migrate(:up)
+ Horse.reset_column_information
+ assert_equal "Sekitoba", Horse.columns_hash["name"].comment
+
+ migration2 = ChangeColumnComment2.new
+ migration2.migrate(:up)
+ Horse.reset_column_information
+ assert_equal "Diomed", Horse.columns_hash["name"].comment
+
+ migration2.migrate(:down)
+ Horse.reset_column_information
+ assert_equal "Sekitoba", Horse.columns_hash["name"].comment
+ end
+
+ def test_migrate_revert_change_table_comment
+ connection = ActiveRecord::Base.connection
+ migration1 = ChangeTableComment1.new
+ migration1.migrate(:up)
+ assert_equal "Sekitoba", connection.table_comment("horses")
+
+ migration2 = ChangeTableComment2.new
+ migration2.migrate(:up)
+ assert_equal "Diomed", connection.table_comment("horses")
+
+ migration2.migrate(:down)
+ assert_equal "Sekitoba", connection.table_comment("horses")
+ end
+ end
+
if current_adapter?(:PostgreSQLAdapter)
def test_migrate_enable_and_disable_extension
migration1 = InvertibleMigration.new
diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb
index 33bd74e114..04f9b26960 100644
--- a/activerecord/test/cases/locking_test.rb
+++ b/activerecord/test/cases/locking_test.rb
@@ -182,7 +182,9 @@ class OptimisticLockingTest < ActiveRecord::TestCase
p1.touch
assert_equal 1, p1.lock_version
- assert_not p1.changed?, "Changes should have been cleared"
+ assert_not_predicate p1, :changed?, "Changes should have been cleared"
+ assert_predicate p1, :saved_changes?
+ assert_equal ["lock_version", "updated_at"], p1.saved_changes.keys.sort
end
def test_touch_stale_object
@@ -193,6 +195,8 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_raises(ActiveRecord::StaleObjectError) do
stale_person.touch
end
+
+ assert_not_predicate stale_person, :saved_changes?
end
def test_update_with_dirty_primary_key
@@ -296,6 +300,9 @@ class OptimisticLockingTest < ActiveRecord::TestCase
t1.touch
assert_equal 1, t1.lock_version
+ assert_not_predicate t1, :changed?
+ assert_predicate t1, :saved_changes?
+ assert_equal ["lock_version", "updated_at"], t1.saved_changes.keys.sort
end
def test_touch_stale_object_with_lock_without_default
@@ -307,6 +314,8 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_raises(ActiveRecord::StaleObjectError) do
stale_object.touch
end
+
+ assert_not_predicate stale_object, :saved_changes?
end
def test_lock_without_default_should_work_with_null_in_the_database
diff --git a/activerecord/test/cases/migration/column_attributes_test.rb b/activerecord/test/cases/migration/column_attributes_test.rb
index 6f9190c110..b6064500ee 100644
--- a/activerecord/test/cases/migration/column_attributes_test.rb
+++ b/activerecord/test/cases/migration/column_attributes_test.rb
@@ -176,9 +176,9 @@ module ActiveRecord
if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)
def test_out_of_range_limit_should_raise
- assert_raise(ActiveRecordError) { add_column :test_models, :integer_too_big, :integer, limit: 10 }
- assert_raise(ActiveRecordError) { add_column :test_models, :text_too_big, :text, limit: 0xfffffffff }
- assert_raise(ActiveRecordError) { add_column :test_models, :binary_too_big, :binary, limit: 0xfffffffff }
+ assert_raise(ArgumentError) { add_column :test_models, :integer_too_big, :integer, limit: 10 }
+ assert_raise(ArgumentError) { add_column :test_models, :text_too_big, :text, limit: 0xfffffffff }
+ assert_raise(ArgumentError) { add_column :test_models, :binary_too_big, :binary, limit: 0xfffffffff }
end
end
end
diff --git a/activerecord/test/cases/migration/command_recorder_test.rb b/activerecord/test/cases/migration/command_recorder_test.rb
index 01f8628fc5..c9f3756b1f 100644
--- a/activerecord/test/cases/migration/command_recorder_test.rb
+++ b/activerecord/test/cases/migration/command_recorder_test.rb
@@ -182,6 +182,40 @@ module ActiveRecord
assert_equal [:change_column_default, [:table, :column, from: false, to: true]], change
end
+ if ActiveRecord::Base.connection.supports_comments?
+ def test_invert_change_column_comment
+ assert_raises(ActiveRecord::IrreversibleMigration) do
+ @recorder.inverse_of :change_column_comment, [:table, :column, "comment"]
+ end
+ end
+
+ def test_invert_change_column_comment_with_from_and_to
+ change = @recorder.inverse_of :change_column_comment, [:table, :column, from: "old_value", to: "new_value"]
+ assert_equal [:change_column_comment, [:table, :column, from: "new_value", to: "old_value"]], change
+ end
+
+ def test_invert_change_column_comment_with_from_and_to_with_nil
+ change = @recorder.inverse_of :change_column_comment, [:table, :column, from: nil, to: "new_value"]
+ assert_equal [:change_column_comment, [:table, :column, from: "new_value", to: nil]], change
+ end
+
+ def test_invert_change_table_comment
+ assert_raises(ActiveRecord::IrreversibleMigration) do
+ @recorder.inverse_of :change_column_comment, [:table, :column, "comment"]
+ end
+ end
+
+ def test_invert_change_table_comment_with_from_and_to
+ change = @recorder.inverse_of :change_table_comment, [:table, from: "old_value", to: "new_value"]
+ assert_equal [:change_table_comment, [:table, from: "new_value", to: "old_value"]], change
+ end
+
+ def test_invert_change_table_comment_with_from_and_to_with_nil
+ change = @recorder.inverse_of :change_table_comment, [:table, from: nil, to: "new_value"]
+ assert_equal [:change_table_comment, [:table, from: "new_value", to: nil]], change
+ end
+ end
+
def test_invert_change_column_null
add = @recorder.inverse_of :change_column_null, [:table, :column, true]
assert_equal [:change_column_null, [:table, :column, false]], add
diff --git a/activerecord/test/cases/migration/compatibility_test.rb b/activerecord/test/cases/migration/compatibility_test.rb
index 5753bd7117..726ccf925e 100644
--- a/activerecord/test/cases/migration/compatibility_test.rb
+++ b/activerecord/test/cases/migration/compatibility_test.rb
@@ -220,6 +220,35 @@ module ActiveRecord
end
end
+ if ActiveRecord::Base.connection.supports_comments?
+ def test_change_column_comment_can_be_reverted
+ migration = Class.new(ActiveRecord::Migration[5.2]) {
+ def migrate(x)
+ revert do
+ change_column_comment(:testings, :foo, "comment")
+ end
+ end
+ }.new
+
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+ assert connection.column_exists?(:testings, :foo, comment: "comment")
+ end
+
+ def test_change_table_comment_can_be_reverted
+ migration = Class.new(ActiveRecord::Migration[5.2]) {
+ def migrate(x)
+ revert do
+ change_table_comment(:testings, "comment")
+ end
+ end
+ }.new
+
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+
+ assert_equal "comment", connection.table_comment("testings")
+ end
+ end
+
if current_adapter?(:PostgreSQLAdapter)
class Testing < ActiveRecord::Base
end
@@ -242,9 +271,9 @@ module ActiveRecord
private
def precision_implicit_default
if current_adapter?(:Mysql2Adapter)
- { presicion: 0 }
+ { precision: 0 }
else
- { presicion: nil }
+ { precision: nil }
end
end
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index f10c26c308..8e8ed494d9 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -583,7 +583,7 @@ class MigrationTest < ActiveRecord::TestCase
if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)
def test_out_of_range_integer_limit_should_raise
- e = assert_raise(ActiveRecord::ActiveRecordError, "integer limit didn't raise") do
+ e = assert_raise(ArgumentError) do
Person.connection.create_table :test_integer_limits, force: true do |t|
t.column :bigone, :integer, limit: 10
end
@@ -595,7 +595,7 @@ class MigrationTest < ActiveRecord::TestCase
end
def test_out_of_range_text_limit_should_raise
- e = assert_raise(ActiveRecord::ActiveRecordError, "text limit didn't raise") do
+ e = assert_raise(ArgumentError) do
Person.connection.create_table :test_text_limits, force: true do |t|
t.text :bigtext, limit: 0xfffffffff
end
@@ -607,15 +607,15 @@ class MigrationTest < ActiveRecord::TestCase
end
def test_out_of_range_binary_limit_should_raise
- e = assert_raise(ActiveRecord::ActiveRecordError) do
- Person.connection.create_table :test_text_limits, force: true do |t|
+ e = assert_raise(ArgumentError) do
+ Person.connection.create_table :test_binary_limits, force: true do |t|
t.binary :bigbinary, limit: 0xfffffffff
end
end
assert_includes e.message, "No binary type has byte size #{0xfffffffff}"
ensure
- Person.connection.drop_table :test_text_limits, if_exists: true
+ Person.connection.drop_table :test_binary_limits, if_exists: true
end
end
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 4759d3b6b2..511d7fc982 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -203,6 +203,14 @@ class PrimaryKeysTest < ActiveRecord::TestCase
assert_queries(3, ignore_none: true) { klass.create! }
end
+ def test_assign_id_raises_error_if_primary_key_doesnt_exist
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = "dashboards"
+ end
+ dashboard = klass.new
+ assert_raises(ActiveModel::MissingAttributeError) { dashboard.id = "1" }
+ end
+
if current_adapter?(:PostgreSQLAdapter)
def test_serial_with_quoted_sequence_name
column = MixedCaseMonkey.columns_hash[MixedCaseMonkey.primary_key]
diff --git a/activerecord/test/cases/relation/delegation_test.rb b/activerecord/test/cases/relation/delegation_test.rb
index 8208c45df1..085006c9a2 100644
--- a/activerecord/test/cases/relation/delegation_test.rb
+++ b/activerecord/test/cases/relation/delegation_test.rb
@@ -56,7 +56,7 @@ module ActiveRecord
:first_or_create, :first_or_create!, :first_or_initialize,
:find_or_create_by, :find_or_create_by!, :find_or_initialize_by,
:create_or_find_by, :create_or_find_by!,
- :destroy_all, :delete_all, :update_all, :delete_by, :destroy_by
+ :destroy_all, :delete_all, :update_all, :touch_all, :delete_by, :destroy_by
]
def test_delegate_querying_methods
diff --git a/activerecord/test/cases/relation/update_all_test.rb b/activerecord/test/cases/relation/update_all_test.rb
index 0500574f28..e45531b4a9 100644
--- a/activerecord/test/cases/relation/update_all_test.rb
+++ b/activerecord/test/cases/relation/update_all_test.rb
@@ -241,6 +241,38 @@ class UpdateAllTest < ActiveRecord::TestCase
end
end
+ def test_klass_level_update_all
+ travel 5.seconds do
+ now = Time.now.utc
+
+ Person.all.each do |person|
+ assert_not_equal now, person.updated_at
+ end
+
+ Person.update_all(updated_at: now)
+
+ Person.all.each do |person|
+ assert_equal now, person.updated_at
+ end
+ end
+ end
+
+ def test_klass_level_touch_all
+ travel 5.seconds do
+ now = Time.now.utc
+
+ Person.all.each do |person|
+ assert_not_equal now, person.updated_at
+ end
+
+ Person.touch_all(time: now)
+
+ Person.all.each do |person|
+ assert_equal now, person.updated_at
+ end
+ end
+ end
+
# Oracle UPDATE does not support ORDER BY
unless current_adapter?(:OracleAdapter)
def test_update_all_ignores_order_without_limit_from_association
diff --git a/activerecord/test/cases/relation/where_clause_test.rb b/activerecord/test/cases/relation/where_clause_test.rb
index 0b06cec40b..b26a1a1d80 100644
--- a/activerecord/test/cases/relation/where_clause_test.rb
+++ b/activerecord/test/cases/relation/where_clause_test.rb
@@ -106,7 +106,7 @@ class ActiveRecord::Relation
Arel::Nodes::Not.new(random_object)
])
- assert_equal expected, original.invert
+ assert_equal expected, original.invert(:nor)
end
test "except removes binary predicates referencing a given column" do
diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb
index b045184d7d..2ecccfe1f3 100644
--- a/activerecord/test/cases/relation/where_test.rb
+++ b/activerecord/test/cases/relation/where_test.rb
@@ -115,13 +115,58 @@ module ActiveRecord
assert_equal expected.to_sql, actual.to_sql
end
- def test_polymorphic_shallow_where_not
- treasure = treasures(:sapphire)
+ def test_where_not_polymorphic_association
+ sapphire = treasures(:sapphire)
- expected = [price_estimates(:diamond), price_estimates(:honda)]
- actual = PriceEstimate.where.not(estimate_of: treasure)
+ all = [treasures(:diamond), sapphire, cars(:honda), sapphire]
+ assert_equal all, PriceEstimate.all.sort_by(&:id).map(&:estimate_of)
- assert_equal expected.sort_by(&:id), actual.sort_by(&:id)
+ actual = PriceEstimate.where.not(estimate_of: sapphire)
+ only = PriceEstimate.where(estimate_of: sapphire)
+
+ expected = all - [sapphire]
+ assert_equal expected, actual.sort_by(&:id).map(&:estimate_of)
+ assert_equal all - expected, only.sort_by(&:id).map(&:estimate_of)
+ end
+
+ def test_where_not_polymorphic_id_and_type_as_nand
+ sapphire = treasures(:sapphire)
+
+ all = [treasures(:diamond), sapphire, cars(:honda), sapphire]
+ assert_equal all, PriceEstimate.all.sort_by(&:id).map(&:estimate_of)
+
+ actual = PriceEstimate.where.yield_self do |where_chain|
+ where_chain.stub(:not_behaves_as_nor?, false) do
+ where_chain.not(estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id)
+ end
+ end
+ only = PriceEstimate.where(estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id)
+
+ expected = all - [sapphire]
+ assert_equal expected, actual.sort_by(&:id).map(&:estimate_of)
+ assert_equal all - expected, only.sort_by(&:id).map(&:estimate_of)
+ end
+
+ def test_where_not_polymorphic_id_and_type_as_nor_is_deprecated
+ sapphire = treasures(:sapphire)
+
+ all = [treasures(:diamond), sapphire, cars(:honda), sapphire]
+ assert_equal all, PriceEstimate.all.sort_by(&:id).map(&:estimate_of)
+
+ message = <<~MSG.squish
+ NOT conditions will no longer behave as NOR in Rails 6.1.
+ To continue using NOR conditions, NOT each conditions manually
+ (`.where.not(:estimate_of_type => ...).where.not(:estimate_of_id => ...)`).
+ MSG
+ actual = assert_deprecated(message) do
+ PriceEstimate.where.not(estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id)
+ end
+ only = PriceEstimate.where(estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id)
+
+ expected = all - [sapphire]
+ # NOT (estimate_of_type = 'Treasure' OR estimate_of_id = sapphire.id) matches only `cars(:honda)` unfortunately.
+ assert_not_equal expected, actual.sort_by(&:id).map(&:estimate_of)
+ assert_equal all - expected, only.sort_by(&:id).map(&:estimate_of)
end
def test_polymorphic_nested_array_where
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index 00a7b3841f..3f370e5ede 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -101,6 +101,9 @@ module ActiveRecord
relation.merge!(relation)
assert_predicate relation, :empty_scope?
+
+ assert_not_predicate NullPost.all, :empty_scope?
+ assert_not_predicate FirstPost.all, :empty_scope?
end
def test_bad_constants_raise_errors
@@ -289,6 +292,7 @@ module ActiveRecord
klass.create!(description: "foo")
assert_equal ["foo"], klass.select(:description).from(klass.all).map(&:desc)
+ assert_equal ["foo"], klass.reselect(:description).from(klass.all).map(&:desc)
end
def test_relation_merging_with_merged_joins_as_strings
diff --git a/activerecord/test/cases/scoping/relation_scoping_test.rb b/activerecord/test/cases/scoping/relation_scoping_test.rb
index a95ab0f429..50b514d464 100644
--- a/activerecord/test/cases/scoping/relation_scoping_test.rb
+++ b/activerecord/test/cases/scoping/relation_scoping_test.rb
@@ -411,7 +411,19 @@ class HasManyScopingTest < ActiveRecord::TestCase
def test_nested_scope_finder
Comment.where("1=0").scoping do
- assert_equal 0, @welcome.comments.count
+ assert_equal 2, @welcome.comments.count
+ assert_equal "a comment...", @welcome.comments.what_are_you
+ end
+
+ Comment.where("1=1").scoping do
+ assert_equal 2, @welcome.comments.count
+ assert_equal "a comment...", @welcome.comments.what_are_you
+ end
+ end
+
+ def test_none_scoping
+ Comment.none.scoping do
+ assert_equal 2, @welcome.comments.count
assert_equal "a comment...", @welcome.comments.what_are_you
end
@@ -452,7 +464,19 @@ class HasAndBelongsToManyScopingTest < ActiveRecord::TestCase
def test_nested_scope_finder
Category.where("1=0").scoping do
- assert_equal 0, @welcome.categories.count
+ assert_equal 2, @welcome.categories.count
+ assert_equal "a category...", @welcome.categories.what_are_you
+ end
+
+ Category.where("1=1").scoping do
+ assert_equal 2, @welcome.categories.count
+ assert_equal "a category...", @welcome.categories.what_are_you
+ end
+ end
+
+ def test_none_scoping
+ Category.none.scoping do
+ assert_equal 2, @welcome.categories.count
assert_equal "a category...", @welcome.categories.what_are_you
end
diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb
index dd4a0b0455..ffe94eee0f 100644
--- a/activerecord/test/cases/tasks/database_tasks_test.rb
+++ b/activerecord/test/cases/tasks/database_tasks_test.rb
@@ -760,7 +760,7 @@ module ActiveRecord
end
class DatabaseTasksMigrateTest < DatabaseTasksMigrationTestCase
- def test_migrate_set_and_unset_verbose_and_version_env_vars
+ def test_can_migrate_from_pending_migration_error_action_dispatch
verbose, version = ENV["VERBOSE"], ENV["VERSION"]
ENV["VERSION"] = "2"
ENV["VERBOSE"] = "false"
@@ -772,7 +772,9 @@ module ActiveRecord
ENV.delete("VERBOSE")
# re-run up migration
- assert_includes capture_migration_output, "migrating"
+ assert_includes(capture(:stdout) do
+ ActiveSupport::ActionableError.dispatch ActiveRecord::PendingMigrationError, "Run pending migrations"
+ end, "migrating")
ensure
ENV["VERBOSE"], ENV["VERSION"] = verbose, version
end
diff --git a/activerecord/test/cases/time_precision_test.rb b/activerecord/test/cases/time_precision_test.rb
index 2f534ea110..1abd857216 100644
--- a/activerecord/test/cases/time_precision_test.rb
+++ b/activerecord/test/cases/time_precision_test.rb
@@ -75,7 +75,7 @@ if subsecond_precision_supported?
end
def test_invalid_time_precision_raises_error
- assert_raises ActiveRecord::ActiveRecordError do
+ assert_raises ArgumentError do
@connection.create_table(:foos, force: true) do |t|
t.time :start, precision: 7
t.time :finish, precision: 7
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index 75ecd6fc40..232e018e03 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -40,17 +40,25 @@ class TimestampTest < ActiveRecord::TestCase
assert_not_equal @previously_updated_at, @developer.updated_at
assert_equal previous_salary + 10000, @developer.salary
- assert @developer.salary_changed?, "developer salary should have changed"
- assert @developer.changed?, "developer should be marked as changed"
+ assert_predicate @developer, :salary_changed?, "developer salary should have changed"
+ assert_predicate @developer, :changed?, "developer should be marked as changed"
+ assert_equal ["salary"], @developer.changed
+ assert_predicate @developer, :saved_changes?
+ assert_equal ["updated_at", "updated_on"], @developer.saved_changes.keys.sort
+
@developer.reload
assert_equal previous_salary, @developer.salary
end
def test_touching_a_record_with_default_scope_that_excludes_it_updates_its_timestamp
developer = @developer.becomes(DeveloperCalledJamis)
-
developer.touch
+
assert_not_equal @previously_updated_at, developer.updated_at
+ assert_not_predicate developer, :changed?
+ assert_predicate developer, :saved_changes?
+ assert_equal ["updated_at", "updated_on"], developer.saved_changes.keys.sort
+
developer.reload
assert_not_equal @previously_updated_at, developer.updated_at
end
diff --git a/activerecord/test/cases/touch_later_test.rb b/activerecord/test/cases/touch_later_test.rb
index cd3d5ed7d1..f1a9cf2d05 100644
--- a/activerecord/test/cases/touch_later_test.rb
+++ b/activerecord/test/cases/touch_later_test.rb
@@ -10,7 +10,7 @@ require "models/tree"
class TouchLaterTest < ActiveRecord::TestCase
fixtures :nodes, :trees
- def test_touch_laster_raise_if_non_persisted
+ def test_touch_later_raise_if_non_persisted
invoice = Invoice.new
Invoice.transaction do
assert_not_predicate invoice, :persisted?
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index e88d20a453..53fe31e087 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -111,6 +111,32 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
assert_equal [:after_commit], @first.history
end
+ def test_dont_call_any_callbacks_after_transaction_commits_for_invalid_record
+ @first.after_commit_block { |r| r.history << :after_commit }
+ @first.after_rollback_block { |r| r.history << :after_rollback }
+
+ def @first.valid?(*)
+ false
+ end
+
+ assert_not @first.save
+ assert_equal [], @first.history
+ end
+
+ def test_dont_call_any_callbacks_after_explicit_transaction_commits_for_invalid_record
+ @first.after_commit_block { |r| r.history << :after_commit }
+ @first.after_rollback_block { |r| r.history << :after_rollback }
+
+ def @first.valid?(*)
+ false
+ end
+
+ @first.transaction do
+ assert_not @first.save
+ end
+ assert_equal [], @first.history
+ end
+
def test_only_call_after_commit_on_save_after_transaction_commits_for_saving_record
record = TopicWithCallbacks.new(title: "New topic", written_on: Date.today)
record.after_commit_block(:save) { |r| r.history << :after_save }
@@ -598,7 +624,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
@topic.content = "foo"
@topic.save!
end
- @topic.class.connection.add_transaction_record(@topic)
+ @topic.send(:add_to_transaction)
end
assert_equal [:before_commit, :after_commit], @topic.history
end
@@ -608,7 +634,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
@topic.transaction(requires_new: true) do
@topic.content = "foo"
@topic.save!
- @topic.class.connection.add_transaction_record(@topic)
+ @topic.send(:add_to_transaction)
end
end
assert_equal [:before_commit, :after_commit], @topic.history
@@ -629,7 +655,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
@topic.content = "foo"
@topic.save!
end
- @topic.class.connection.add_transaction_record(@topic)
+ @topic.send(:add_to_transaction)
raise ActiveRecord::Rollback
end
assert_equal [:rollback], @topic.history
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 1009dd0f99..6795996cca 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -18,6 +18,65 @@ class TransactionTest < ActiveRecord::TestCase
@first, @second = Topic.find(1, 2).sort_by(&:id)
end
+ def test_rollback_dirty_changes
+ topic = topics(:fifth)
+
+ ActiveRecord::Base.transaction do
+ topic.update(title: "Ruby on Rails")
+ raise ActiveRecord::Rollback
+ end
+
+ title_change = ["The Fifth Topic of the day", "Ruby on Rails"]
+ assert_equal title_change, topic.changes["title"]
+ end
+
+ def test_rollback_dirty_changes_multiple_saves
+ topic = topics(:fifth)
+
+ ActiveRecord::Base.transaction do
+ topic.update(title: "Ruby on Rails")
+ topic.update(title: "Another Title")
+ raise ActiveRecord::Rollback
+ end
+
+ title_change = ["The Fifth Topic of the day", "Another Title"]
+ assert_equal title_change, topic.changes["title"]
+ end
+
+ def test_rollback_dirty_changes_then_retry_save
+ topic = topics(:fifth)
+
+ ActiveRecord::Base.transaction do
+ topic.update(title: "Ruby on Rails")
+ raise ActiveRecord::Rollback
+ end
+
+ title_change = ["The Fifth Topic of the day", "Ruby on Rails"]
+ assert_equal title_change, topic.changes["title"]
+
+ assert topic.save
+
+ assert_equal title_change, topic.saved_changes["title"]
+ assert_equal topic.title, topic.reload.title
+ end
+
+ def test_rollback_dirty_changes_then_retry_save_on_new_record
+ topic = Topic.new(title: "Ruby on Rails")
+
+ ActiveRecord::Base.transaction do
+ topic.save
+ raise ActiveRecord::Rollback
+ end
+
+ title_change = [nil, "Ruby on Rails"]
+ assert_equal title_change, topic.changes["title"]
+
+ assert topic.save
+
+ assert_equal title_change, topic.saved_changes["title"]
+ assert_equal topic.title, topic.reload.title
+ end
+
def test_persisted_in_a_model_with_custom_primary_key_after_failed_save
movie = Movie.create
assert_not_predicate movie, :persisted?
@@ -26,28 +85,31 @@ class TransactionTest < ActiveRecord::TestCase
def test_raise_after_destroy
assert_not_predicate @first, :frozen?
- assert_raises(RuntimeError) {
- Topic.transaction do
- @first.destroy
- assert_predicate @first, :frozen?
- raise
+ assert_not_called(@first, :rolledback!) do
+ assert_raises(RuntimeError) do
+ Topic.transaction do
+ @first.destroy
+ assert_predicate @first, :frozen?
+ raise
+ end
end
- }
+ end
- assert @first.reload
assert_not_predicate @first, :frozen?
end
def test_successful
- Topic.transaction do
- @first.approved = true
- @second.approved = false
- @first.save
- @second.save
+ assert_not_called(@first, :committed!) do
+ Topic.transaction do
+ @first.approved = true
+ @second.approved = false
+ @first.save
+ @second.save
+ end
end
- assert Topic.find(1).approved?, "First should have been approved"
- assert_not Topic.find(2).approved?, "Second should have been unapproved"
+ assert_predicate Topic.find(1), :approved?, "First should have been approved"
+ assert_not_predicate Topic.find(2), :approved?, "Second should have been unapproved"
end
def transaction_with_return
@@ -62,7 +124,7 @@ class TransactionTest < ActiveRecord::TestCase
def test_add_to_null_transaction
topic = Topic.new
- topic.add_to_transaction
+ topic.send(:add_to_transaction)
end
def test_successful_with_return
@@ -76,11 +138,13 @@ class TransactionTest < ActiveRecord::TestCase
end
end
- transaction_with_return
+ assert_not_called(@first, :committed!) do
+ transaction_with_return
+ end
assert committed
- assert Topic.find(1).approved?, "First should have been approved"
- assert_not Topic.find(2).approved?, "Second should have been unapproved"
+ assert_predicate Topic.find(1), :approved?, "First should have been approved"
+ assert_not_predicate Topic.find(2), :approved?, "Second should have been unapproved"
ensure
Topic.connection.class_eval do
remove_method :commit_db_transaction
@@ -99,9 +163,11 @@ class TransactionTest < ActiveRecord::TestCase
end
end
- Topic.transaction do
- @first.approved = true
- @first.save!
+ assert_not_called(@first, :committed!) do
+ Topic.transaction do
+ @first.approved = true
+ @first.save!
+ end
end
assert_equal 0, num
@@ -113,19 +179,21 @@ class TransactionTest < ActiveRecord::TestCase
end
def test_successful_with_instance_method
- @first.transaction do
- @first.approved = true
- @second.approved = false
- @first.save
- @second.save
+ assert_not_called(@first, :committed!) do
+ @first.transaction do
+ @first.approved = true
+ @second.approved = false
+ @first.save
+ @second.save
+ end
end
- assert Topic.find(1).approved?, "First should have been approved"
- assert_not Topic.find(2).approved?, "Second should have been unapproved"
+ assert_predicate Topic.find(1), :approved?, "First should have been approved"
+ assert_not_predicate Topic.find(2), :approved?, "Second should have been unapproved"
end
def test_failing_on_exception
- begin
+ assert_not_called(@first, :rolledback!) do
Topic.transaction do
@first.approved = true
@second.approved = false
@@ -137,11 +205,11 @@ class TransactionTest < ActiveRecord::TestCase
# caught it
end
- assert @first.approved?, "First should still be changed in the objects"
- assert_not @second.approved?, "Second should still be changed in the objects"
+ assert_predicate @first, :approved?, "First should still be changed in the objects"
+ assert_not_predicate @second, :approved?, "Second should still be changed in the objects"
- assert_not Topic.find(1).approved?, "First shouldn't have been approved"
- assert Topic.find(2).approved?, "Second should still be approved"
+ assert_not_predicate Topic.find(1), :approved?, "First shouldn't have been approved"
+ assert_predicate Topic.find(2), :approved?, "Second should still be approved"
end
def test_raising_exception_in_callback_rollbacks_in_save
@@ -150,8 +218,10 @@ class TransactionTest < ActiveRecord::TestCase
end
@first.approved = true
- e = assert_raises(RuntimeError) { @first.save }
- assert_equal "Make the transaction rollback", e.message
+ assert_not_called(@first, :rolledback!) do
+ e = assert_raises(RuntimeError) { @first.save }
+ assert_equal "Make the transaction rollback", e.message
+ end
assert_not_predicate Topic.find(1), :approved?
end
@@ -159,13 +229,15 @@ class TransactionTest < ActiveRecord::TestCase
def @first.before_save_for_transaction
raise ActiveRecord::Rollback
end
- assert_not @first.approved
+ assert_not_predicate @first, :approved?
- Topic.transaction do
- @first.approved = true
- @first.save!
+ assert_not_called(@first, :rolledback!) do
+ Topic.transaction do
+ @first.approved = true
+ @first.save!
+ end
end
- assert_not Topic.find(@first.id).approved?, "Should not commit the approved flag"
+ assert_not_predicate Topic.find(@first.id), :approved?, "Should not commit the approved flag"
end
def test_raising_exception_in_nested_transaction_restore_state_in_save
@@ -175,11 +247,13 @@ class TransactionTest < ActiveRecord::TestCase
raise "Make the transaction rollback"
end
- assert_raises(RuntimeError) do
- Topic.transaction { topic.save }
+ assert_not_called(topic, :rolledback!) do
+ assert_raises(RuntimeError) do
+ Topic.transaction { topic.save }
+ end
end
- assert topic.new_record?, "#{topic.inspect} should be new record"
+ assert_predicate topic, :new_record?, "#{topic.inspect} should be new record"
end
def test_transaction_state_is_cleared_when_record_is_persisted
diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb
index 9a70934b7e..4f98a6b7fc 100644
--- a/activerecord/test/cases/validations_test.rb
+++ b/activerecord/test/cases/validations_test.rb
@@ -145,15 +145,17 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_acceptance_of_with_undefined_attribute_methods
- Topic.validates_acceptance_of(:approved)
- topic = Topic.new(approved: true)
- Topic.undefine_attribute_methods
+ klass = Class.new(Topic)
+ klass.validates_acceptance_of(:approved)
+ topic = klass.new(approved: true)
+ klass.undefine_attribute_methods
assert topic.approved
end
def test_validates_acceptance_of_as_database_column
- Topic.validates_acceptance_of(:approved)
- topic = Topic.create("approved" => true)
+ klass = Class.new(Topic)
+ klass.validates_acceptance_of(:approved)
+ topic = klass.create("approved" => true)
assert topic["approved"]
end