diff options
Diffstat (limited to 'activerecord/test')
22 files changed, 335 insertions, 56 deletions
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/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_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/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/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/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/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_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/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/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/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/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index 1009dd0f99..410f07d3ab 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -34,20 +34,21 @@ class TransactionTest < ActiveRecord::TestCase 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 @@ -76,11 +77,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 +102,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 +118,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 +144,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 +157,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 +168,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 +186,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/models/post.rb b/activerecord/test/models/post.rb index 61e5f14100..395b534c63 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -203,6 +203,10 @@ end class SubAbstractStiPost < AbstractStiPost; end +class NullPost < Post + default_scope { none } +end + class FirstPost < ActiveRecord::Base self.inheritance_column = :disabled self.table_name = "posts" diff --git a/activerecord/test/models/section.rb b/activerecord/test/models/section.rb new file mode 100644 index 0000000000..f8b4cc7936 --- /dev/null +++ b/activerecord/test/models/section.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class Section < ActiveRecord::Base + belongs_to :session, inverse_of: :sections, autosave: true + belongs_to :seminar, inverse_of: :sections, autosave: true +end diff --git a/activerecord/test/models/seminar.rb b/activerecord/test/models/seminar.rb new file mode 100644 index 0000000000..c18aa86433 --- /dev/null +++ b/activerecord/test/models/seminar.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class Seminar < ActiveRecord::Base + has_many :sections, inverse_of: :seminar, autosave: true, dependent: :destroy + has_many :sessions, through: :sections +end diff --git a/activerecord/test/models/session.rb b/activerecord/test/models/session.rb new file mode 100644 index 0000000000..db66b5297e --- /dev/null +++ b/activerecord/test/models/session.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class Session < ActiveRecord::Base + has_many :sections, inverse_of: :session, autosave: true, dependent: :destroy + has_many :seminars, through: :sections +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index ead4de2a13..7d9b8afeb6 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -19,6 +19,7 @@ ActiveRecord::Schema.define do t.references :firm, index: false t.string :firm_name t.integer :credit_limit + t.integer "a" * max_identifier_length end create_table :admin_accounts, force: true do |t| @@ -791,6 +792,24 @@ ActiveRecord::Schema.define do t.integer :lock_version, default: 0 end + disable_referential_integrity do + create_table :seminars, force: :cascade do |t| + t.string :name + end + + create_table :sessions, force: :cascade do |t| + t.date :start_date + t.date :end_date + t.string :name + end + + create_table :sections, force: :cascade do |t| + t.string :short_name + t.belongs_to :session, foreign_key: true + t.belongs_to :seminar, foreign_key: true + end + end + create_table :shape_expressions, force: true do |t| t.string :paint_type t.integer :paint_id |