TestTXMgr.cpp (63779B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "gtest/gtest.h" 7 8 #include "nsITransactionManager.h" 9 #include "nsComponentManagerUtils.h" 10 #include "mozilla/gtest/MozAssertions.h" 11 #include "mozilla/EditTransactionBase.h" 12 #include "mozilla/TransactionManager.h" 13 14 using mozilla::EditTransactionBase; 15 using mozilla::TransactionManager; 16 17 static int32_t sConstructorCount = 0; 18 static int32_t sDoCount = 0; 19 static int32_t* sDoOrderArr = 0; 20 static int32_t sUndoCount = 0; 21 static int32_t* sUndoOrderArr = 0; 22 static int32_t sRedoCount = 0; 23 static int32_t* sRedoOrderArr = 0; 24 25 int32_t sSimpleTestDoOrderArr[] = { 26 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 27 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 28 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 29 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 30 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 31 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 32 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 33 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 34 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131}; 35 36 int32_t sSimpleTestUndoOrderArr[] = {41, 40, 39, 38, 62, 39, 38, 37, 37 69, 71, 70, 111, 110, 109, 108, 107, 38 106, 105, 104, 103, 102, 131, 130, 129, 39 128, 127, 126, 125, 124, 123, 122}; 40 41 static int32_t sSimpleTestRedoOrderArr[] = {38, 39, 70}; 42 43 int32_t sAggregateTestDoOrderArr[] = { 44 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 45 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 46 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 48 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 49 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 51 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 52 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 53 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 54 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 55 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 56 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 57 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 58 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 59 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 60 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 61 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 62 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 63 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 64 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 65 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 66 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 67 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 68 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 69 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 70 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 71 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 72 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 73 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 74 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 75 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 76 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 77 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 78 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 79 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 80 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 81 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 82 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 83 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 84 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 85 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 86 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 87 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 88 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 89 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 90 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 91 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 92 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 93 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 94 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 95 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 96 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 97 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 98 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 99 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 100 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 101 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 102 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 103 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 104 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913}; 105 106 int32_t sAggregateTestUndoOrderArr[] = { 107 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, 274, 273, 108 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, 434, 433, 109 432, 431, 430, 429, 428, 273, 272, 271, 270, 269, 268, 267, 266, 265, 264, 110 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, 253, 479, 478, 477, 476, 111 475, 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, 483, 482, 481, 480, 112 485, 484, 483, 482, 481, 480, 773, 772, 771, 770, 769, 768, 767, 766, 765, 113 764, 763, 762, 761, 760, 759, 758, 757, 756, 755, 754, 753, 752, 751, 750, 114 749, 748, 747, 746, 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, 735, 115 734, 733, 732, 731, 730, 729, 728, 727, 726, 725, 724, 723, 722, 721, 720, 116 719, 718, 717, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 117 704, 913, 912, 911, 910, 909, 908, 907, 906, 905, 904, 903, 902, 901, 900, 118 899, 898, 897, 896, 895, 894, 893, 892, 891, 890, 889, 888, 887, 886, 885, 119 884, 883, 882, 881, 880, 879, 878, 877, 876, 875, 874, 873, 872, 871, 870, 120 869, 868, 867, 866, 865, 864, 863, 862, 861, 860, 859, 858, 857, 856, 855, 121 854, 853, 852, 851, 850, 849, 848, 847, 846, 845, 844}; 122 123 int32_t sAggregateTestRedoOrderArr[] = { 124 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 125 273, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486}; 126 127 int32_t sSimpleBatchTestDoOrderArr[] = { 128 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 129 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 130 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 131 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 132 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 133 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 134 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107}; 135 136 int32_t sSimpleBatchTestUndoOrderArr[] = { 137 43, 42, 41, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 138 8, 7, 6, 5, 4, 3, 2, 1, 43, 42, 41, 63, 62, 61, 60, 139 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 140 44, 65, 67, 66, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98}; 141 142 int32_t sSimpleBatchTestRedoOrderArr[] = {1, 2, 3, 4, 5, 6, 7, 8, 143 9, 10, 11, 12, 13, 14, 15, 16, 144 17, 18, 19, 20, 41, 42, 43, 66}; 145 146 int32_t sAggregateBatchTestDoOrderArr[] = { 147 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 148 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 149 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 150 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 151 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 152 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 153 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 154 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 155 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 156 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 157 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 158 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 159 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 160 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 161 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 162 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 163 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 164 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 165 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 166 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 167 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 168 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 169 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 170 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 171 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 172 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 173 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 174 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 175 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 176 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 177 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 178 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 179 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 180 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 181 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 182 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 183 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 184 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 185 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 186 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 187 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 188 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 189 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 190 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 191 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 192 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 193 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 194 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 195 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 196 736, 737, 738, 739, 740, 741, 742, 743, 744, 745}; 197 198 int32_t sAggregateBatchTestUndoOrderArr[] = { 199 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, 287, 200 286, 285, 284, 283, 282, 281, 140, 139, 138, 137, 136, 135, 134, 133, 132, 201 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 202 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 203 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 204 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 205 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 206 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 207 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 208 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 209 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 301, 300, 299, 298, 210 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 211 282, 281, 441, 440, 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, 212 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 213 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 214 398, 397, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 385, 384, 215 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, 216 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, 354, 217 353, 352, 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 218 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 219 323, 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, 312, 311, 310, 309, 220 308, 307, 306, 305, 304, 303, 302, 451, 450, 449, 448, 447, 465, 464, 463, 221 462, 461, 460, 459, 458, 457, 456, 455, 454, 453, 452, 457, 456, 455, 454, 222 453, 452, 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, 735, 734, 733, 223 732, 731, 730, 729, 728, 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, 224 717, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, 703, 225 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 226 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676}; 227 228 int32_t sAggregateBatchTestRedoOrderArr[] = { 229 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 230 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 231 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 232 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 233 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 234 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 235 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 236 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 237 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 238 136, 137, 138, 139, 140, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 239 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 448, 449, 450, 451, 240 452, 453, 454, 455, 456, 457, 458}; 241 242 class TestTransaction : public nsITransaction { 243 protected: 244 virtual ~TestTransaction() = default; 245 246 public: 247 TestTransaction() {} 248 249 NS_DECL_ISUPPORTS 250 251 NS_IMETHOD GetAsEditTransactionBase(EditTransactionBase**) final { 252 return NS_ERROR_NOT_IMPLEMENTED; 253 } 254 }; 255 256 NS_IMPL_ISUPPORTS(TestTransaction, nsITransaction) 257 258 class SimpleTransaction : public TestTransaction { 259 protected: 260 #define NONE_FLAG 0 261 #define THROWS_DO_ERROR_FLAG 1 262 #define THROWS_UNDO_ERROR_FLAG 2 263 #define THROWS_REDO_ERROR_FLAG 4 264 #define MERGE_FLAG 8 265 #define TRANSIENT_FLAG 16 266 #define BATCH_FLAG 32 267 #define ALL_ERROR_FLAGS \ 268 (THROWS_DO_ERROR_FLAG | THROWS_UNDO_ERROR_FLAG | THROWS_REDO_ERROR_FLAG) 269 270 int32_t mVal; 271 int32_t mFlags; 272 273 public: 274 explicit SimpleTransaction(int32_t aFlags = NONE_FLAG) 275 : mVal(++sConstructorCount), mFlags(aFlags) {} 276 277 ~SimpleTransaction() override = default; 278 279 MOZ_CAN_RUN_SCRIPT NS_IMETHOD DoTransaction() override { 280 // 281 // Make sure DoTransaction() is called in the order we expect! 282 // Notice that we don't check to see if we go past the end of the array. 283 // This is done on purpose since we want to crash if the order array is out 284 // of date. 285 // 286 if (sDoOrderArr) { 287 EXPECT_EQ(mVal, sDoOrderArr[sDoCount]); 288 } 289 290 ++sDoCount; 291 292 return (mFlags & THROWS_DO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK; 293 } 294 295 MOZ_CAN_RUN_SCRIPT NS_IMETHOD UndoTransaction() override { 296 // 297 // Make sure UndoTransaction() is called in the order we expect! 298 // Notice that we don't check to see if we go past the end of the array. 299 // This is done on purpose since we want to crash if the order array is out 300 // of date. 301 // 302 if (sUndoOrderArr) { 303 EXPECT_EQ(mVal, sUndoOrderArr[sUndoCount]); 304 } 305 306 ++sUndoCount; 307 308 return (mFlags & THROWS_UNDO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK; 309 } 310 311 MOZ_CAN_RUN_SCRIPT NS_IMETHOD RedoTransaction() override { 312 // 313 // Make sure RedoTransaction() is called in the order we expect! 314 // Notice that we don't check to see if we go past the end of the array. 315 // This is done on purpose since we want to crash if the order array is out 316 // of date. 317 // 318 if (sRedoOrderArr) { 319 EXPECT_EQ(mVal, sRedoOrderArr[sRedoCount]); 320 } 321 322 ++sRedoCount; 323 324 return (mFlags & THROWS_REDO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK; 325 } 326 327 NS_IMETHOD GetIsTransient(bool* aIsTransient) override { 328 if (aIsTransient) { 329 *aIsTransient = (mFlags & TRANSIENT_FLAG) ? true : false; 330 } 331 return NS_OK; 332 } 333 334 NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) override { 335 if (aDidMerge) { 336 *aDidMerge = (mFlags & MERGE_FLAG) ? true : false; 337 } 338 return NS_OK; 339 } 340 }; 341 342 class AggregateTransaction : public SimpleTransaction { 343 private: 344 AggregateTransaction(nsITransactionManager* aTXMgr, int32_t aLevel, 345 int32_t aNumber, int32_t aMaxLevel, 346 int32_t aNumChildrenPerNode, int32_t aFlags) { 347 mLevel = aLevel; 348 mNumber = aNumber; 349 mTXMgr = aTXMgr; 350 mFlags = aFlags & (~ALL_ERROR_FLAGS); 351 mErrorFlags = aFlags & ALL_ERROR_FLAGS; 352 mTXMgr = aTXMgr; 353 mMaxLevel = aMaxLevel; 354 mNumChildrenPerNode = aNumChildrenPerNode; 355 } 356 357 nsITransactionManager* mTXMgr; 358 359 int32_t mLevel; 360 int32_t mNumber; 361 int32_t mErrorFlags; 362 363 int32_t mMaxLevel; 364 int32_t mNumChildrenPerNode; 365 366 public: 367 AggregateTransaction(nsITransactionManager* aTXMgr, int32_t aMaxLevel, 368 int32_t aNumChildrenPerNode, 369 int32_t aFlags = NONE_FLAG) { 370 mLevel = 1; 371 mNumber = 1; 372 mFlags = aFlags & (~ALL_ERROR_FLAGS); 373 mErrorFlags = aFlags & ALL_ERROR_FLAGS; 374 mTXMgr = aTXMgr; 375 mMaxLevel = aMaxLevel; 376 mNumChildrenPerNode = aNumChildrenPerNode; 377 } 378 379 ~AggregateTransaction() override = default; 380 381 MOZ_CAN_RUN_SCRIPT NS_IMETHOD DoTransaction() override { 382 if (mLevel >= mMaxLevel) { 383 // Only leaf nodes can throw errors! 384 mFlags |= mErrorFlags; 385 } 386 387 nsresult rv = SimpleTransaction::DoTransaction(); 388 if (NS_FAILED(rv)) { 389 // fail("QueryInterface() failed for transaction level %d. (%d)\n", 390 // mLevel, rv); 391 return rv; 392 } 393 394 if (mLevel >= mMaxLevel) { 395 return NS_OK; 396 } 397 398 if (mFlags & BATCH_FLAG) { 399 rv = MOZ_KnownLive(mTXMgr)->BeginBatch(nullptr); 400 if (NS_FAILED(rv)) { 401 return rv; 402 } 403 } 404 405 int32_t cLevel = mLevel + 1; 406 407 for (int i = 1; i <= mNumChildrenPerNode; i++) { 408 int32_t flags = mErrorFlags & THROWS_DO_ERROR_FLAG; 409 410 if ((mErrorFlags & THROWS_REDO_ERROR_FLAG) && i == mNumChildrenPerNode) { 411 // Make the rightmost leaf transaction throw the error! 412 flags = THROWS_REDO_ERROR_FLAG; 413 mErrorFlags = mErrorFlags & (~THROWS_REDO_ERROR_FLAG); 414 } else if ((mErrorFlags & THROWS_UNDO_ERROR_FLAG) && i == 1) { 415 // Make the leftmost leaf transaction throw the error! 416 flags = THROWS_UNDO_ERROR_FLAG; 417 mErrorFlags = mErrorFlags & (~THROWS_UNDO_ERROR_FLAG); 418 } 419 420 flags |= mFlags & BATCH_FLAG; 421 422 RefPtr<AggregateTransaction> tximpl = new AggregateTransaction( 423 mTXMgr, cLevel, i, mMaxLevel, mNumChildrenPerNode, flags); 424 425 rv = MOZ_KnownLive(mTXMgr)->DoTransaction(tximpl); 426 if (NS_FAILED(rv)) { 427 if (mFlags & BATCH_FLAG) { 428 mTXMgr->EndBatch(false); 429 } 430 return rv; 431 } 432 } 433 434 if (mFlags & BATCH_FLAG) { 435 mTXMgr->EndBatch(false); 436 } 437 return rv; 438 } 439 }; 440 441 class TestTransactionFactory { 442 public: 443 virtual TestTransaction* create(nsITransactionManager* txmgr, 444 int32_t flags) = 0; 445 }; 446 447 class SimpleTransactionFactory : public TestTransactionFactory { 448 public: 449 TestTransaction* create(nsITransactionManager* txmgr, 450 int32_t flags) override { 451 return (TestTransaction*)new SimpleTransaction(flags); 452 } 453 }; 454 455 class AggregateTransactionFactory : public TestTransactionFactory { 456 private: 457 int32_t mMaxLevel; 458 int32_t mNumChildrenPerNode; 459 int32_t mFixedFlags; 460 461 public: 462 AggregateTransactionFactory(int32_t aMaxLevel, int32_t aNumChildrenPerNode, 463 int32_t aFixedFlags = NONE_FLAG) 464 : mMaxLevel(aMaxLevel), 465 mNumChildrenPerNode(aNumChildrenPerNode), 466 mFixedFlags(aFixedFlags) {} 467 468 TestTransaction* create(nsITransactionManager* txmgr, 469 int32_t flags) override { 470 return (TestTransaction*)new AggregateTransaction( 471 txmgr, mMaxLevel, mNumChildrenPerNode, flags | mFixedFlags); 472 } 473 }; 474 475 void reset_globals() { 476 sConstructorCount = 0; 477 478 sDoCount = 0; 479 sDoOrderArr = 0; 480 481 sUndoCount = 0; 482 sUndoOrderArr = 0; 483 484 sRedoCount = 0; 485 sRedoOrderArr = 0; 486 } 487 488 /** 489 * Test behaviors in non-batch mode. 490 **/ 491 MOZ_CAN_RUN_SCRIPT_BOUNDARY void quick_test(TestTransactionFactory* factory) { 492 /******************************************************************* 493 * 494 * Create a transaction manager implementation: 495 * 496 *******************************************************************/ 497 498 nsCOMPtr<nsITransactionManager> mgr = new TransactionManager(); 499 500 /******************************************************************* 501 * 502 * Call DoTransaction() with a null transaction: 503 * 504 *******************************************************************/ 505 506 nsresult rv = mgr->DoTransaction(nullptr); 507 EXPECT_EQ(rv, NS_ERROR_NULL_POINTER); 508 509 /******************************************************************* 510 * 511 * Call UndoTransaction() with an empty undo stack: 512 * 513 *******************************************************************/ 514 515 rv = mgr->UndoTransaction(); 516 EXPECT_NS_SUCCEEDED(rv); 517 518 /******************************************************************* 519 * 520 * Call RedoTransaction() with an empty redo stack: 521 * 522 *******************************************************************/ 523 524 rv = mgr->RedoTransaction(); 525 EXPECT_NS_SUCCEEDED(rv); 526 527 /******************************************************************* 528 * 529 * Call SetMaxTransactionCount(-1) with empty undo and redo stacks: 530 * 531 *******************************************************************/ 532 533 rv = mgr->SetMaxTransactionCount(-1); 534 EXPECT_NS_SUCCEEDED(rv); 535 536 /******************************************************************* 537 * 538 * Call SetMaxTransactionCount(0) with empty undo and redo stacks: 539 * 540 *******************************************************************/ 541 542 rv = mgr->SetMaxTransactionCount(0); 543 EXPECT_NS_SUCCEEDED(rv); 544 545 /******************************************************************* 546 * 547 * Call SetMaxTransactionCount(10) with empty undo and redo stacks: 548 * 549 *******************************************************************/ 550 551 rv = mgr->SetMaxTransactionCount(10); 552 EXPECT_NS_SUCCEEDED(rv); 553 554 /******************************************************************* 555 * 556 * Call Clear() with empty undo and redo stacks: 557 * 558 *******************************************************************/ 559 560 rv = mgr->Clear(); 561 EXPECT_NS_SUCCEEDED(rv); 562 563 /******************************************************************* 564 * 565 * Call GetNumberOfUndoItems() with an empty undo stack: 566 * 567 *******************************************************************/ 568 569 int32_t numitems; 570 rv = mgr->GetNumberOfUndoItems(&numitems); 571 EXPECT_NS_SUCCEEDED(rv); 572 EXPECT_EQ(numitems, 0); 573 574 /******************************************************************* 575 * 576 * Call GetNumberOfRedoItems() with an empty redo stack: 577 * 578 *******************************************************************/ 579 580 rv = mgr->GetNumberOfRedoItems(&numitems); 581 EXPECT_NS_SUCCEEDED(rv); 582 EXPECT_EQ(numitems, 0); 583 584 /******************************************************************* 585 * 586 * Call PeekUndoStack() with an empty undo stack: 587 * 588 *******************************************************************/ 589 590 { 591 nsCOMPtr<nsITransaction> tx; 592 rv = mgr->PeekUndoStack(getter_AddRefs(tx)); 593 EXPECT_NS_SUCCEEDED(rv); 594 EXPECT_EQ(tx, nullptr); 595 } 596 597 /******************************************************************* 598 * 599 * Call PeekRedoStack() with an empty undo stack: 600 * 601 *******************************************************************/ 602 603 { 604 nsCOMPtr<nsITransaction> tx; 605 rv = mgr->PeekRedoStack(getter_AddRefs(tx)); 606 EXPECT_NS_SUCCEEDED(rv); 607 EXPECT_EQ(tx, nullptr); 608 } 609 610 /******************************************************************* 611 * 612 * Test coalescing by executing a transaction that can merge any 613 * command into itself. Then execute 20 transaction. Afterwards, 614 * we should still have the first transaction sitting on the undo 615 * stack. Then clear the undo and redo stacks. 616 * 617 *******************************************************************/ 618 619 int32_t i; 620 RefPtr<TestTransaction> tximpl; 621 nsCOMPtr<nsITransaction> u1, u2, r1, r2; 622 623 rv = mgr->SetMaxTransactionCount(10); 624 EXPECT_NS_SUCCEEDED(rv); 625 626 tximpl = factory->create(mgr, MERGE_FLAG); 627 rv = mgr->DoTransaction(tximpl); 628 EXPECT_NS_SUCCEEDED(rv); 629 630 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 631 EXPECT_NS_SUCCEEDED(rv); 632 EXPECT_EQ(u1, tximpl); 633 634 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 635 EXPECT_NS_SUCCEEDED(rv); 636 637 for (i = 1; i <= 20; i++) { 638 tximpl = factory->create(mgr, NONE_FLAG); 639 rv = mgr->DoTransaction(tximpl); 640 EXPECT_NS_SUCCEEDED(rv); 641 } 642 643 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 644 EXPECT_NS_SUCCEEDED(rv); 645 EXPECT_EQ(u1, u2); 646 647 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 648 EXPECT_NS_SUCCEEDED(rv); 649 EXPECT_EQ(r1, r2); 650 651 rv = mgr->GetNumberOfUndoItems(&numitems); 652 EXPECT_NS_SUCCEEDED(rv); 653 EXPECT_EQ(numitems, 1); 654 655 rv = mgr->GetNumberOfRedoItems(&numitems); 656 EXPECT_NS_SUCCEEDED(rv); 657 EXPECT_EQ(numitems, 0); 658 659 rv = mgr->Clear(); 660 EXPECT_NS_SUCCEEDED(rv); 661 662 /******************************************************************* 663 * 664 * Execute 20 transactions. Afterwards, we should have 10 665 * transactions on the undo stack: 666 * 667 *******************************************************************/ 668 669 for (i = 1; i <= 20; i++) { 670 tximpl = factory->create(mgr, NONE_FLAG); 671 rv = mgr->DoTransaction(tximpl); 672 EXPECT_NS_SUCCEEDED(rv); 673 } 674 675 rv = mgr->GetNumberOfUndoItems(&numitems); 676 EXPECT_NS_SUCCEEDED(rv); 677 EXPECT_EQ(numitems, 10); 678 679 rv = mgr->GetNumberOfRedoItems(&numitems); 680 EXPECT_NS_SUCCEEDED(rv); 681 EXPECT_EQ(numitems, 0); 682 683 /******************************************************************* 684 * 685 * Execute 20 transient transactions. Afterwards, we should still 686 * have the same 10 transactions on the undo stack: 687 * 688 *******************************************************************/ 689 690 u1 = u2 = r1 = r2 = nullptr; 691 692 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 693 EXPECT_NS_SUCCEEDED(rv); 694 695 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 696 EXPECT_NS_SUCCEEDED(rv); 697 698 for (i = 1; i <= 20; i++) { 699 tximpl = factory->create(mgr, TRANSIENT_FLAG); 700 rv = mgr->DoTransaction(tximpl); 701 EXPECT_NS_SUCCEEDED(rv); 702 } 703 704 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 705 EXPECT_NS_SUCCEEDED(rv); 706 EXPECT_EQ(u1, u2); 707 708 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 709 EXPECT_NS_SUCCEEDED(rv); 710 EXPECT_EQ(r1, r2); 711 712 rv = mgr->GetNumberOfUndoItems(&numitems); 713 EXPECT_NS_SUCCEEDED(rv); 714 EXPECT_EQ(numitems, 10); 715 716 rv = mgr->GetNumberOfRedoItems(&numitems); 717 EXPECT_NS_SUCCEEDED(rv); 718 EXPECT_EQ(numitems, 0); 719 720 /******************************************************************* 721 * 722 * Undo 4 transactions. Afterwards, we should have 6 transactions 723 * on the undo stack, and 4 on the redo stack: 724 * 725 *******************************************************************/ 726 727 for (i = 1; i <= 4; i++) { 728 rv = mgr->UndoTransaction(); 729 EXPECT_NS_SUCCEEDED(rv); 730 } 731 732 rv = mgr->GetNumberOfUndoItems(&numitems); 733 EXPECT_NS_SUCCEEDED(rv); 734 EXPECT_EQ(numitems, 6); 735 736 rv = mgr->GetNumberOfRedoItems(&numitems); 737 EXPECT_NS_SUCCEEDED(rv); 738 EXPECT_EQ(numitems, 4); 739 740 /******************************************************************* 741 * 742 * Redo 2 transactions. Afterwards, we should have 8 transactions 743 * on the undo stack, and 2 on the redo stack: 744 * 745 *******************************************************************/ 746 747 for (i = 1; i <= 2; ++i) { 748 rv = mgr->RedoTransaction(); 749 EXPECT_NS_SUCCEEDED(rv); 750 } 751 752 rv = mgr->GetNumberOfUndoItems(&numitems); 753 EXPECT_NS_SUCCEEDED(rv); 754 EXPECT_EQ(numitems, 8); 755 756 rv = mgr->GetNumberOfRedoItems(&numitems); 757 EXPECT_NS_SUCCEEDED(rv); 758 EXPECT_EQ(numitems, 2); 759 760 /******************************************************************* 761 * 762 * Execute a new transaction. The redo stack should get pruned! 763 * 764 *******************************************************************/ 765 766 tximpl = factory->create(mgr, NONE_FLAG); 767 rv = mgr->DoTransaction(tximpl); 768 EXPECT_NS_SUCCEEDED(rv); 769 770 rv = mgr->GetNumberOfUndoItems(&numitems); 771 EXPECT_NS_SUCCEEDED(rv); 772 EXPECT_EQ(numitems, 9); 773 774 rv = mgr->GetNumberOfRedoItems(&numitems); 775 EXPECT_NS_SUCCEEDED(rv); 776 EXPECT_EQ(numitems, 0); 777 778 /******************************************************************* 779 * 780 * Undo 4 transactions then clear the undo and redo stacks. 781 * 782 *******************************************************************/ 783 784 for (i = 1; i <= 4; ++i) { 785 rv = mgr->UndoTransaction(); 786 EXPECT_NS_SUCCEEDED(rv); 787 } 788 789 rv = mgr->GetNumberOfUndoItems(&numitems); 790 EXPECT_NS_SUCCEEDED(rv); 791 EXPECT_EQ(numitems, 5); 792 793 rv = mgr->GetNumberOfRedoItems(&numitems); 794 EXPECT_NS_SUCCEEDED(rv); 795 EXPECT_EQ(numitems, 4); 796 797 rv = mgr->Clear(); 798 EXPECT_NS_SUCCEEDED(rv); 799 800 rv = mgr->GetNumberOfUndoItems(&numitems); 801 EXPECT_NS_SUCCEEDED(rv); 802 EXPECT_EQ(numitems, 0); 803 804 rv = mgr->GetNumberOfRedoItems(&numitems); 805 EXPECT_NS_SUCCEEDED(rv); 806 EXPECT_EQ(numitems, 0); 807 808 /******************************************************************* 809 * 810 * Execute 5 transactions. 811 * 812 *******************************************************************/ 813 814 for (i = 1; i <= 5; i++) { 815 tximpl = factory->create(mgr, NONE_FLAG); 816 rv = mgr->DoTransaction(tximpl); 817 EXPECT_NS_SUCCEEDED(rv); 818 } 819 820 rv = mgr->GetNumberOfUndoItems(&numitems); 821 EXPECT_NS_SUCCEEDED(rv); 822 EXPECT_EQ(numitems, 5); 823 824 rv = mgr->GetNumberOfRedoItems(&numitems); 825 EXPECT_NS_SUCCEEDED(rv); 826 EXPECT_EQ(numitems, 0); 827 828 /******************************************************************* 829 * 830 * Test transaction DoTransaction() error: 831 * 832 *******************************************************************/ 833 834 tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG); 835 836 u1 = u2 = r1 = r2 = nullptr; 837 838 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 839 EXPECT_NS_SUCCEEDED(rv); 840 841 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 842 EXPECT_NS_SUCCEEDED(rv); 843 844 rv = mgr->DoTransaction(tximpl); 845 EXPECT_EQ(rv, NS_ERROR_FAILURE); 846 847 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 848 EXPECT_NS_SUCCEEDED(rv); 849 EXPECT_EQ(u1, u2); 850 851 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 852 EXPECT_NS_SUCCEEDED(rv); 853 EXPECT_EQ(r1, r2); 854 855 rv = mgr->GetNumberOfUndoItems(&numitems); 856 EXPECT_NS_SUCCEEDED(rv); 857 EXPECT_EQ(numitems, 5); 858 859 rv = mgr->GetNumberOfRedoItems(&numitems); 860 EXPECT_NS_SUCCEEDED(rv); 861 EXPECT_EQ(numitems, 0); 862 863 /******************************************************************* 864 * 865 * Test transaction UndoTransaction() error: 866 * 867 *******************************************************************/ 868 869 tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG); 870 rv = mgr->DoTransaction(tximpl); 871 EXPECT_NS_SUCCEEDED(rv); 872 873 u1 = u2 = r1 = r2 = nullptr; 874 875 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 876 EXPECT_NS_SUCCEEDED(rv); 877 878 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 879 EXPECT_NS_SUCCEEDED(rv); 880 881 rv = mgr->UndoTransaction(); 882 EXPECT_EQ(rv, NS_ERROR_FAILURE); 883 884 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 885 EXPECT_NS_SUCCEEDED(rv); 886 EXPECT_EQ(u1, u2); 887 888 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 889 EXPECT_NS_SUCCEEDED(rv); 890 EXPECT_EQ(r1, r2); 891 892 rv = mgr->GetNumberOfUndoItems(&numitems); 893 EXPECT_NS_SUCCEEDED(rv); 894 EXPECT_EQ(numitems, 6); 895 896 rv = mgr->GetNumberOfRedoItems(&numitems); 897 EXPECT_NS_SUCCEEDED(rv); 898 EXPECT_EQ(numitems, 0); 899 900 /******************************************************************* 901 * 902 * Test transaction RedoTransaction() error: 903 * 904 *******************************************************************/ 905 906 tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG); 907 rv = mgr->DoTransaction(tximpl); 908 EXPECT_NS_SUCCEEDED(rv); 909 910 // 911 // Execute a normal transaction to be used in a later test: 912 // 913 914 tximpl = factory->create(mgr, NONE_FLAG); 915 rv = mgr->DoTransaction(tximpl); 916 EXPECT_NS_SUCCEEDED(rv); 917 918 // 919 // Undo the 2 transactions just executed. 920 // 921 922 for (i = 1; i <= 2; ++i) { 923 rv = mgr->UndoTransaction(); 924 EXPECT_NS_SUCCEEDED(rv); 925 } 926 927 // 928 // The RedoErrorTransaction should now be at the top of the redo stack! 929 // 930 931 u1 = u2 = r1 = r2 = nullptr; 932 933 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 934 EXPECT_NS_SUCCEEDED(rv); 935 936 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 937 EXPECT_NS_SUCCEEDED(rv); 938 939 rv = mgr->RedoTransaction(); 940 EXPECT_EQ(rv, NS_ERROR_FAILURE); 941 942 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 943 EXPECT_NS_SUCCEEDED(rv); 944 EXPECT_EQ(u1, u2); 945 946 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 947 EXPECT_NS_SUCCEEDED(rv); 948 EXPECT_EQ(r1, r2); 949 950 rv = mgr->GetNumberOfUndoItems(&numitems); 951 EXPECT_NS_SUCCEEDED(rv); 952 EXPECT_EQ(numitems, 6); 953 954 rv = mgr->GetNumberOfRedoItems(&numitems); 955 EXPECT_NS_SUCCEEDED(rv); 956 EXPECT_EQ(numitems, 2); 957 958 /******************************************************************* 959 * 960 * Make sure that setting the transaction manager's max transaction 961 * count to zero, clears both the undo and redo stacks, and executes 962 * all new commands without pushing them on the undo stack! 963 * 964 *******************************************************************/ 965 966 rv = mgr->SetMaxTransactionCount(0); 967 EXPECT_NS_SUCCEEDED(rv); 968 969 rv = mgr->GetNumberOfUndoItems(&numitems); 970 EXPECT_NS_SUCCEEDED(rv); 971 EXPECT_EQ(numitems, 0); 972 973 rv = mgr->GetNumberOfRedoItems(&numitems); 974 EXPECT_NS_SUCCEEDED(rv); 975 EXPECT_EQ(numitems, 0); 976 977 for (i = 1; i <= 20; i++) { 978 tximpl = factory->create(mgr, NONE_FLAG); 979 rv = mgr->DoTransaction(tximpl); 980 EXPECT_NS_SUCCEEDED(rv); 981 982 rv = mgr->GetNumberOfUndoItems(&numitems); 983 EXPECT_NS_SUCCEEDED(rv); 984 EXPECT_EQ(numitems, 0); 985 986 rv = mgr->GetNumberOfRedoItems(&numitems); 987 EXPECT_NS_SUCCEEDED(rv); 988 EXPECT_EQ(numitems, 0); 989 } 990 991 /******************************************************************* 992 * 993 * Make sure that setting the transaction manager's max transaction 994 * count to something greater than the number of transactions on 995 * both the undo and redo stacks causes no pruning of the stacks: 996 * 997 *******************************************************************/ 998 999 rv = mgr->SetMaxTransactionCount(-1); 1000 EXPECT_NS_SUCCEEDED(rv); 1001 1002 // Push 20 transactions on the undo stack: 1003 1004 for (i = 1; i <= 20; i++) { 1005 tximpl = factory->create(mgr, NONE_FLAG); 1006 rv = mgr->DoTransaction(tximpl); 1007 EXPECT_NS_SUCCEEDED(rv); 1008 1009 rv = mgr->GetNumberOfUndoItems(&numitems); 1010 EXPECT_NS_SUCCEEDED(rv); 1011 EXPECT_EQ(numitems, i); 1012 1013 rv = mgr->GetNumberOfRedoItems(&numitems); 1014 EXPECT_NS_SUCCEEDED(rv); 1015 EXPECT_EQ(numitems, 0); 1016 } 1017 1018 for (i = 1; i <= 10; i++) { 1019 rv = mgr->UndoTransaction(); 1020 EXPECT_NS_SUCCEEDED(rv); 1021 } 1022 rv = mgr->GetNumberOfUndoItems(&numitems); 1023 EXPECT_NS_SUCCEEDED(rv); 1024 EXPECT_EQ(numitems, 10); 1025 1026 rv = mgr->GetNumberOfRedoItems(&numitems); 1027 EXPECT_NS_SUCCEEDED(rv); 1028 EXPECT_EQ(numitems, 10); 1029 1030 u1 = u2 = r1 = r2 = nullptr; 1031 1032 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 1033 EXPECT_NS_SUCCEEDED(rv); 1034 1035 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 1036 EXPECT_NS_SUCCEEDED(rv); 1037 1038 rv = mgr->SetMaxTransactionCount(25); 1039 EXPECT_NS_SUCCEEDED(rv); 1040 1041 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 1042 EXPECT_NS_SUCCEEDED(rv); 1043 EXPECT_EQ(u1, u2); 1044 1045 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 1046 EXPECT_NS_SUCCEEDED(rv); 1047 EXPECT_EQ(r1, r2); 1048 1049 rv = mgr->GetNumberOfUndoItems(&numitems); 1050 EXPECT_NS_SUCCEEDED(rv); 1051 EXPECT_EQ(numitems, 10); 1052 1053 rv = mgr->GetNumberOfRedoItems(&numitems); 1054 EXPECT_NS_SUCCEEDED(rv); 1055 EXPECT_EQ(numitems, 10); 1056 1057 /******************************************************************* 1058 * 1059 * Test undo stack pruning by setting the transaction 1060 * manager's max transaction count to a number lower than the 1061 * number of transactions on both the undo and redo stacks: 1062 * 1063 *******************************************************************/ 1064 1065 u1 = u2 = r1 = r2 = nullptr; 1066 1067 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 1068 EXPECT_NS_SUCCEEDED(rv); 1069 1070 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 1071 EXPECT_NS_SUCCEEDED(rv); 1072 1073 rv = mgr->SetMaxTransactionCount(15); 1074 EXPECT_NS_SUCCEEDED(rv); 1075 1076 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 1077 EXPECT_NS_SUCCEEDED(rv); 1078 EXPECT_EQ(u1, u2); 1079 1080 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 1081 EXPECT_NS_SUCCEEDED(rv); 1082 EXPECT_EQ(r1, r2); 1083 1084 rv = mgr->GetNumberOfUndoItems(&numitems); 1085 EXPECT_NS_SUCCEEDED(rv); 1086 EXPECT_EQ(numitems, 5); 1087 1088 rv = mgr->GetNumberOfRedoItems(&numitems); 1089 EXPECT_NS_SUCCEEDED(rv); 1090 EXPECT_EQ(numitems, 10); 1091 1092 /******************************************************************* 1093 * 1094 * Test redo stack pruning by setting the transaction 1095 * manager's max transaction count to a number lower than the 1096 * number of transactions on both the undo and redo stacks: 1097 * 1098 *******************************************************************/ 1099 1100 u1 = u2 = r1 = r2 = nullptr; 1101 1102 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 1103 EXPECT_NS_SUCCEEDED(rv); 1104 1105 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 1106 EXPECT_NS_SUCCEEDED(rv); 1107 1108 rv = mgr->SetMaxTransactionCount(5); 1109 EXPECT_NS_SUCCEEDED(rv); 1110 1111 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 1112 EXPECT_NS_SUCCEEDED(rv); 1113 EXPECT_FALSE(u2); 1114 1115 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 1116 EXPECT_NS_SUCCEEDED(rv); 1117 EXPECT_EQ(r1, r2); 1118 1119 rv = mgr->GetNumberOfUndoItems(&numitems); 1120 EXPECT_NS_SUCCEEDED(rv); 1121 EXPECT_EQ(numitems, 0); 1122 1123 rv = mgr->GetNumberOfRedoItems(&numitems); 1124 EXPECT_NS_SUCCEEDED(rv); 1125 EXPECT_EQ(numitems, 5); 1126 1127 /******************************************************************* 1128 * 1129 * Release the transaction manager. Any transactions on the undo 1130 * and redo stack should automatically be released: 1131 * 1132 *******************************************************************/ 1133 1134 rv = mgr->SetMaxTransactionCount(-1); 1135 EXPECT_NS_SUCCEEDED(rv); 1136 1137 // Push 20 transactions on the undo stack: 1138 1139 for (i = 1; i <= 20; i++) { 1140 tximpl = factory->create(mgr, NONE_FLAG); 1141 rv = mgr->DoTransaction(tximpl); 1142 EXPECT_NS_SUCCEEDED(rv); 1143 1144 rv = mgr->GetNumberOfUndoItems(&numitems); 1145 EXPECT_NS_SUCCEEDED(rv); 1146 EXPECT_EQ(numitems, i); 1147 1148 rv = mgr->GetNumberOfRedoItems(&numitems); 1149 EXPECT_NS_SUCCEEDED(rv); 1150 EXPECT_EQ(numitems, 0); 1151 } 1152 1153 for (i = 1; i <= 10; i++) { 1154 rv = mgr->UndoTransaction(); 1155 EXPECT_NS_SUCCEEDED(rv); 1156 } 1157 1158 rv = mgr->GetNumberOfUndoItems(&numitems); 1159 EXPECT_NS_SUCCEEDED(rv); 1160 EXPECT_EQ(numitems, 10); 1161 1162 rv = mgr->GetNumberOfRedoItems(&numitems); 1163 EXPECT_NS_SUCCEEDED(rv); 1164 EXPECT_EQ(numitems, 10); 1165 1166 rv = mgr->Clear(); 1167 EXPECT_NS_SUCCEEDED(rv); 1168 } 1169 1170 TEST(TestTXMgr, SimpleTest) 1171 { 1172 /******************************************************************* 1173 * 1174 * Initialize globals for test. 1175 * 1176 *******************************************************************/ 1177 reset_globals(); 1178 sDoOrderArr = sSimpleTestDoOrderArr; 1179 sUndoOrderArr = sSimpleTestUndoOrderArr; 1180 sRedoOrderArr = sSimpleTestRedoOrderArr; 1181 1182 /******************************************************************* 1183 * 1184 * Run the quick test. 1185 * 1186 *******************************************************************/ 1187 1188 SimpleTransactionFactory factory; 1189 1190 quick_test(&factory); 1191 } 1192 1193 TEST(TestTXMgr, AggregationTest) 1194 { 1195 /******************************************************************* 1196 * 1197 * Initialize globals for test. 1198 * 1199 *******************************************************************/ 1200 1201 reset_globals(); 1202 sDoOrderArr = sAggregateTestDoOrderArr; 1203 sUndoOrderArr = sAggregateTestUndoOrderArr; 1204 sRedoOrderArr = sAggregateTestRedoOrderArr; 1205 1206 /******************************************************************* 1207 * 1208 * Run the quick test. 1209 * 1210 *******************************************************************/ 1211 1212 AggregateTransactionFactory factory(3, 2); 1213 1214 quick_test(&factory); 1215 } 1216 1217 /** 1218 * Test behaviors in batch mode. 1219 **/ 1220 MOZ_CAN_RUN_SCRIPT_BOUNDARY void quick_batch_test( 1221 TestTransactionFactory* factory) { 1222 /******************************************************************* 1223 * 1224 * Create a transaction manager implementation: 1225 * 1226 *******************************************************************/ 1227 1228 nsCOMPtr<nsITransactionManager> mgr = new TransactionManager(); 1229 1230 int32_t numitems; 1231 1232 /******************************************************************* 1233 * 1234 * Make sure an unbalanced call to EndBatch(false) with empty undo stack 1235 * throws an error! 1236 * 1237 *******************************************************************/ 1238 1239 nsresult rv = mgr->GetNumberOfUndoItems(&numitems); 1240 EXPECT_NS_SUCCEEDED(rv); 1241 EXPECT_EQ(numitems, 0); 1242 1243 rv = mgr->EndBatch(false); 1244 EXPECT_EQ(rv, NS_ERROR_FAILURE); 1245 1246 rv = mgr->GetNumberOfUndoItems(&numitems); 1247 EXPECT_NS_SUCCEEDED(rv); 1248 EXPECT_EQ(numitems, 0); 1249 1250 /******************************************************************* 1251 * 1252 * Make sure that an empty batch is not added to the undo stack 1253 * when it is closed. 1254 * 1255 *******************************************************************/ 1256 1257 rv = mgr->GetNumberOfUndoItems(&numitems); 1258 EXPECT_NS_SUCCEEDED(rv); 1259 EXPECT_EQ(numitems, 0); 1260 1261 rv = mgr->BeginBatch(nullptr); 1262 EXPECT_NS_SUCCEEDED(rv); 1263 1264 rv = mgr->GetNumberOfUndoItems(&numitems); 1265 EXPECT_NS_SUCCEEDED(rv); 1266 EXPECT_EQ(numitems, 0); 1267 1268 rv = mgr->EndBatch(false); 1269 EXPECT_NS_SUCCEEDED(rv); 1270 1271 rv = mgr->GetNumberOfUndoItems(&numitems); 1272 EXPECT_NS_SUCCEEDED(rv); 1273 EXPECT_EQ(numitems, 0); 1274 1275 int32_t i; 1276 RefPtr<TestTransaction> tximpl; 1277 1278 /******************************************************************* 1279 * 1280 * Execute 20 transactions. Afterwards, we should have 1 1281 * transaction on the undo stack: 1282 * 1283 *******************************************************************/ 1284 1285 rv = mgr->BeginBatch(nullptr); 1286 EXPECT_NS_SUCCEEDED(rv); 1287 1288 for (i = 1; i <= 20; i++) { 1289 tximpl = factory->create(mgr, NONE_FLAG); 1290 rv = mgr->DoTransaction(tximpl); 1291 EXPECT_NS_SUCCEEDED(rv); 1292 } 1293 1294 rv = mgr->GetNumberOfUndoItems(&numitems); 1295 EXPECT_NS_SUCCEEDED(rv); 1296 EXPECT_EQ(numitems, 0); 1297 1298 rv = mgr->EndBatch(false); 1299 EXPECT_NS_SUCCEEDED(rv); 1300 1301 rv = mgr->GetNumberOfUndoItems(&numitems); 1302 EXPECT_NS_SUCCEEDED(rv); 1303 EXPECT_EQ(numitems, 1); 1304 1305 nsCOMPtr<nsITransaction> u1, u2, r1, r2; 1306 1307 /******************************************************************* 1308 * 1309 * Execute 20 transient transactions. Afterwards, we should still 1310 * have the same transaction on the undo stack: 1311 * 1312 *******************************************************************/ 1313 1314 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 1315 EXPECT_NS_SUCCEEDED(rv); 1316 1317 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 1318 EXPECT_NS_SUCCEEDED(rv); 1319 1320 rv = mgr->BeginBatch(nullptr); 1321 EXPECT_NS_SUCCEEDED(rv); 1322 1323 for (i = 1; i <= 20; i++) { 1324 tximpl = factory->create(mgr, TRANSIENT_FLAG); 1325 rv = mgr->DoTransaction(tximpl); 1326 EXPECT_NS_SUCCEEDED(rv); 1327 } 1328 1329 rv = mgr->EndBatch(false); 1330 EXPECT_NS_SUCCEEDED(rv); 1331 1332 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 1333 EXPECT_NS_SUCCEEDED(rv); 1334 EXPECT_EQ(u1, u2); 1335 1336 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 1337 EXPECT_NS_SUCCEEDED(rv); 1338 EXPECT_EQ(r1, r2); 1339 1340 rv = mgr->GetNumberOfUndoItems(&numitems); 1341 EXPECT_NS_SUCCEEDED(rv); 1342 EXPECT_EQ(numitems, 1); 1343 1344 rv = mgr->GetNumberOfRedoItems(&numitems); 1345 EXPECT_NS_SUCCEEDED(rv); 1346 EXPECT_EQ(numitems, 0); 1347 1348 /******************************************************************* 1349 * 1350 * Test nested batching. Afterwards, we should have 2 transactions 1351 * on the undo stack: 1352 * 1353 *******************************************************************/ 1354 1355 rv = mgr->BeginBatch(nullptr); 1356 EXPECT_NS_SUCCEEDED(rv); 1357 1358 tximpl = factory->create(mgr, NONE_FLAG); 1359 rv = mgr->DoTransaction(tximpl); 1360 EXPECT_NS_SUCCEEDED(rv); 1361 1362 rv = mgr->GetNumberOfUndoItems(&numitems); 1363 EXPECT_NS_SUCCEEDED(rv); 1364 EXPECT_EQ(numitems, 1); 1365 1366 rv = mgr->BeginBatch(nullptr); 1367 EXPECT_NS_SUCCEEDED(rv); 1368 1369 tximpl = factory->create(mgr, NONE_FLAG); 1370 rv = mgr->DoTransaction(tximpl); 1371 EXPECT_NS_SUCCEEDED(rv); 1372 1373 rv = mgr->GetNumberOfUndoItems(&numitems); 1374 EXPECT_NS_SUCCEEDED(rv); 1375 EXPECT_EQ(numitems, 1); 1376 1377 rv = mgr->BeginBatch(nullptr); 1378 EXPECT_NS_SUCCEEDED(rv); 1379 1380 tximpl = factory->create(mgr, NONE_FLAG); 1381 rv = mgr->DoTransaction(tximpl); 1382 EXPECT_NS_SUCCEEDED(rv); 1383 1384 rv = mgr->GetNumberOfUndoItems(&numitems); 1385 EXPECT_NS_SUCCEEDED(rv); 1386 EXPECT_EQ(numitems, 1); 1387 1388 rv = mgr->EndBatch(false); 1389 EXPECT_NS_SUCCEEDED(rv); 1390 1391 rv = mgr->EndBatch(false); 1392 EXPECT_NS_SUCCEEDED(rv); 1393 1394 rv = mgr->EndBatch(false); 1395 EXPECT_NS_SUCCEEDED(rv); 1396 1397 rv = mgr->GetNumberOfUndoItems(&numitems); 1398 EXPECT_NS_SUCCEEDED(rv); 1399 EXPECT_EQ(numitems, 2); 1400 1401 /******************************************************************* 1402 * 1403 * Undo 2 batch transactions. Afterwards, we should have 0 1404 * transactions on the undo stack and 2 on the redo stack. 1405 * 1406 *******************************************************************/ 1407 1408 for (i = 1; i <= 2; ++i) { 1409 rv = mgr->UndoTransaction(); 1410 EXPECT_NS_SUCCEEDED(rv); 1411 } 1412 1413 rv = mgr->GetNumberOfUndoItems(&numitems); 1414 EXPECT_NS_SUCCEEDED(rv); 1415 EXPECT_EQ(numitems, 0); 1416 1417 rv = mgr->GetNumberOfRedoItems(&numitems); 1418 EXPECT_NS_SUCCEEDED(rv); 1419 EXPECT_EQ(numitems, 2); 1420 1421 /******************************************************************* 1422 * 1423 * Redo 2 batch transactions. Afterwards, we should have 2 1424 * transactions on the undo stack and 0 on the redo stack. 1425 * 1426 *******************************************************************/ 1427 1428 for (i = 1; i <= 2; ++i) { 1429 rv = mgr->RedoTransaction(); 1430 EXPECT_NS_SUCCEEDED(rv); 1431 } 1432 1433 rv = mgr->GetNumberOfUndoItems(&numitems); 1434 EXPECT_NS_SUCCEEDED(rv); 1435 EXPECT_EQ(numitems, 2); 1436 1437 rv = mgr->GetNumberOfRedoItems(&numitems); 1438 EXPECT_NS_SUCCEEDED(rv); 1439 EXPECT_EQ(numitems, 0); 1440 1441 /******************************************************************* 1442 * 1443 * Call undo. Afterwards, we should have 1 transaction 1444 * on the undo stack, and 1 on the redo stack: 1445 * 1446 *******************************************************************/ 1447 1448 rv = mgr->UndoTransaction(); 1449 EXPECT_NS_SUCCEEDED(rv); 1450 1451 rv = mgr->GetNumberOfUndoItems(&numitems); 1452 EXPECT_NS_SUCCEEDED(rv); 1453 EXPECT_EQ(numitems, 1); 1454 1455 rv = mgr->GetNumberOfRedoItems(&numitems); 1456 EXPECT_NS_SUCCEEDED(rv); 1457 EXPECT_EQ(numitems, 1); 1458 1459 /******************************************************************* 1460 * 1461 * Make sure an unbalanced call to EndBatch(false) throws an error and 1462 * doesn't affect the undo and redo stacks! 1463 * 1464 *******************************************************************/ 1465 1466 rv = mgr->EndBatch(false); 1467 EXPECT_EQ(rv, NS_ERROR_FAILURE); 1468 1469 rv = mgr->GetNumberOfUndoItems(&numitems); 1470 EXPECT_NS_SUCCEEDED(rv); 1471 EXPECT_EQ(numitems, 1); 1472 1473 rv = mgr->GetNumberOfRedoItems(&numitems); 1474 EXPECT_NS_SUCCEEDED(rv); 1475 EXPECT_EQ(numitems, 1); 1476 1477 /******************************************************************* 1478 * 1479 * Make sure that an empty batch is not added to the undo stack 1480 * when it is closed, and that it does not affect the undo and redo 1481 * stacks. 1482 * 1483 *******************************************************************/ 1484 1485 rv = mgr->BeginBatch(nullptr); 1486 EXPECT_NS_SUCCEEDED(rv); 1487 1488 rv = mgr->GetNumberOfUndoItems(&numitems); 1489 EXPECT_NS_SUCCEEDED(rv); 1490 EXPECT_EQ(numitems, 1); 1491 1492 rv = mgr->GetNumberOfRedoItems(&numitems); 1493 EXPECT_NS_SUCCEEDED(rv); 1494 EXPECT_EQ(numitems, 1); 1495 1496 rv = mgr->EndBatch(false); 1497 EXPECT_NS_SUCCEEDED(rv); 1498 1499 rv = mgr->GetNumberOfUndoItems(&numitems); 1500 EXPECT_NS_SUCCEEDED(rv); 1501 EXPECT_EQ(numitems, 1); 1502 1503 rv = mgr->GetNumberOfRedoItems(&numitems); 1504 EXPECT_NS_SUCCEEDED(rv); 1505 EXPECT_EQ(numitems, 1); 1506 1507 /******************************************************************* 1508 * 1509 * Execute a new transaction. The redo stack should get pruned! 1510 * 1511 *******************************************************************/ 1512 1513 rv = mgr->BeginBatch(nullptr); 1514 EXPECT_NS_SUCCEEDED(rv); 1515 1516 for (i = 1; i <= 20; i++) { 1517 tximpl = factory->create(mgr, NONE_FLAG); 1518 rv = mgr->DoTransaction(tximpl); 1519 EXPECT_NS_SUCCEEDED(rv); 1520 } 1521 1522 rv = mgr->GetNumberOfUndoItems(&numitems); 1523 EXPECT_NS_SUCCEEDED(rv); 1524 EXPECT_EQ(numitems, 1); 1525 1526 rv = mgr->GetNumberOfRedoItems(&numitems); 1527 EXPECT_NS_SUCCEEDED(rv); 1528 EXPECT_EQ(numitems, 1); 1529 1530 rv = mgr->EndBatch(false); 1531 EXPECT_NS_SUCCEEDED(rv); 1532 1533 rv = mgr->GetNumberOfUndoItems(&numitems); 1534 EXPECT_NS_SUCCEEDED(rv); 1535 EXPECT_EQ(numitems, 2); 1536 1537 rv = mgr->GetNumberOfRedoItems(&numitems); 1538 EXPECT_NS_SUCCEEDED(rv); 1539 EXPECT_EQ(numitems, 0); 1540 1541 /******************************************************************* 1542 * 1543 * Call undo. 1544 * 1545 *******************************************************************/ 1546 1547 // Move a transaction over to the redo stack, so that we have one 1548 // transaction on the undo stack, and one on the redo stack! 1549 1550 rv = mgr->UndoTransaction(); 1551 EXPECT_NS_SUCCEEDED(rv); 1552 1553 rv = mgr->GetNumberOfUndoItems(&numitems); 1554 EXPECT_NS_SUCCEEDED(rv); 1555 EXPECT_EQ(numitems, 1); 1556 1557 rv = mgr->GetNumberOfRedoItems(&numitems); 1558 EXPECT_NS_SUCCEEDED(rv); 1559 EXPECT_EQ(numitems, 1); 1560 1561 /******************************************************************* 1562 * 1563 * Test transaction DoTransaction() error: 1564 * 1565 *******************************************************************/ 1566 1567 tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG); 1568 1569 u1 = u2 = r1 = r2 = nullptr; 1570 1571 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 1572 EXPECT_NS_SUCCEEDED(rv); 1573 1574 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 1575 EXPECT_NS_SUCCEEDED(rv); 1576 1577 rv = mgr->BeginBatch(nullptr); 1578 EXPECT_NS_SUCCEEDED(rv); 1579 1580 rv = mgr->DoTransaction(tximpl); 1581 EXPECT_EQ(rv, NS_ERROR_FAILURE); 1582 1583 rv = mgr->EndBatch(false); 1584 EXPECT_NS_SUCCEEDED(rv); 1585 1586 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 1587 EXPECT_NS_SUCCEEDED(rv); 1588 EXPECT_EQ(u1, u2); 1589 1590 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 1591 EXPECT_NS_SUCCEEDED(rv); 1592 EXPECT_EQ(r1, r2); 1593 1594 rv = mgr->GetNumberOfUndoItems(&numitems); 1595 EXPECT_NS_SUCCEEDED(rv); 1596 EXPECT_EQ(numitems, 1); 1597 1598 rv = mgr->GetNumberOfRedoItems(&numitems); 1599 EXPECT_NS_SUCCEEDED(rv); 1600 EXPECT_EQ(numitems, 1); 1601 1602 /******************************************************************* 1603 * 1604 * Test transaction UndoTransaction() error: 1605 * 1606 *******************************************************************/ 1607 1608 tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG); 1609 1610 rv = mgr->BeginBatch(nullptr); 1611 EXPECT_NS_SUCCEEDED(rv); 1612 1613 rv = mgr->DoTransaction(tximpl); 1614 EXPECT_NS_SUCCEEDED(rv); 1615 1616 rv = mgr->EndBatch(false); 1617 EXPECT_NS_SUCCEEDED(rv); 1618 1619 u1 = u2 = r1 = r2 = nullptr; 1620 1621 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 1622 EXPECT_NS_SUCCEEDED(rv); 1623 1624 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 1625 EXPECT_NS_SUCCEEDED(rv); 1626 1627 rv = mgr->UndoTransaction(); 1628 EXPECT_EQ(rv, NS_ERROR_FAILURE); 1629 1630 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 1631 EXPECT_NS_SUCCEEDED(rv); 1632 EXPECT_EQ(u1, u2); 1633 1634 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 1635 EXPECT_NS_SUCCEEDED(rv); 1636 EXPECT_EQ(r1, r2); 1637 1638 rv = mgr->GetNumberOfUndoItems(&numitems); 1639 EXPECT_NS_SUCCEEDED(rv); 1640 EXPECT_EQ(numitems, 2); 1641 1642 rv = mgr->GetNumberOfRedoItems(&numitems); 1643 EXPECT_NS_SUCCEEDED(rv); 1644 EXPECT_EQ(numitems, 0); 1645 1646 /******************************************************************* 1647 * 1648 * Test transaction RedoTransaction() error: 1649 * 1650 *******************************************************************/ 1651 1652 tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG); 1653 1654 rv = mgr->BeginBatch(nullptr); 1655 EXPECT_NS_SUCCEEDED(rv); 1656 1657 rv = mgr->DoTransaction(tximpl); 1658 EXPECT_NS_SUCCEEDED(rv); 1659 1660 rv = mgr->EndBatch(false); 1661 EXPECT_NS_SUCCEEDED(rv); 1662 1663 // 1664 // Execute a normal transaction to be used in a later test: 1665 // 1666 1667 tximpl = factory->create(mgr, NONE_FLAG); 1668 rv = mgr->DoTransaction(tximpl); 1669 EXPECT_NS_SUCCEEDED(rv); 1670 1671 // 1672 // Undo the 2 transactions just executed. 1673 // 1674 1675 for (i = 1; i <= 2; ++i) { 1676 rv = mgr->UndoTransaction(); 1677 EXPECT_NS_SUCCEEDED(rv); 1678 } 1679 1680 // 1681 // The RedoErrorTransaction should now be at the top of the redo stack! 1682 // 1683 1684 u1 = u2 = r1 = r2 = nullptr; 1685 1686 rv = mgr->PeekUndoStack(getter_AddRefs(u1)); 1687 EXPECT_NS_SUCCEEDED(rv); 1688 1689 rv = mgr->PeekRedoStack(getter_AddRefs(r1)); 1690 EXPECT_NS_SUCCEEDED(rv); 1691 1692 rv = mgr->RedoTransaction(); 1693 EXPECT_EQ(rv, NS_ERROR_FAILURE); 1694 1695 rv = mgr->PeekUndoStack(getter_AddRefs(u2)); 1696 EXPECT_NS_SUCCEEDED(rv); 1697 EXPECT_EQ(u1, u2); 1698 1699 rv = mgr->PeekRedoStack(getter_AddRefs(r2)); 1700 EXPECT_NS_SUCCEEDED(rv); 1701 EXPECT_EQ(r1, r2); 1702 1703 rv = mgr->GetNumberOfUndoItems(&numitems); 1704 EXPECT_NS_SUCCEEDED(rv); 1705 EXPECT_EQ(numitems, 2); 1706 1707 rv = mgr->GetNumberOfRedoItems(&numitems); 1708 EXPECT_NS_SUCCEEDED(rv); 1709 EXPECT_EQ(numitems, 2); 1710 1711 /******************************************************************* 1712 * 1713 * Make sure that setting the transaction manager's max transaction 1714 * count to zero, clears both the undo and redo stacks, and executes 1715 * all new commands without pushing them on the undo stack! 1716 * 1717 *******************************************************************/ 1718 1719 rv = mgr->SetMaxTransactionCount(0); 1720 EXPECT_NS_SUCCEEDED(rv); 1721 1722 rv = mgr->GetNumberOfUndoItems(&numitems); 1723 EXPECT_NS_SUCCEEDED(rv); 1724 EXPECT_EQ(numitems, 0); 1725 1726 rv = mgr->GetNumberOfRedoItems(&numitems); 1727 EXPECT_NS_SUCCEEDED(rv); 1728 EXPECT_EQ(numitems, 0); 1729 1730 for (i = 1; i <= 20; i++) { 1731 tximpl = factory->create(mgr, NONE_FLAG); 1732 1733 rv = mgr->BeginBatch(nullptr); 1734 EXPECT_NS_SUCCEEDED(rv); 1735 1736 rv = mgr->DoTransaction(tximpl); 1737 EXPECT_NS_SUCCEEDED(rv); 1738 1739 rv = mgr->EndBatch(false); 1740 EXPECT_NS_SUCCEEDED(rv); 1741 1742 rv = mgr->GetNumberOfUndoItems(&numitems); 1743 EXPECT_NS_SUCCEEDED(rv); 1744 EXPECT_EQ(numitems, 0); 1745 1746 rv = mgr->GetNumberOfRedoItems(&numitems); 1747 EXPECT_NS_SUCCEEDED(rv); 1748 EXPECT_EQ(numitems, 0); 1749 } 1750 1751 /******************************************************************* 1752 * 1753 * Release the transaction manager. Any transactions on the undo 1754 * and redo stack should automatically be released: 1755 * 1756 *******************************************************************/ 1757 1758 rv = mgr->SetMaxTransactionCount(-1); 1759 EXPECT_NS_SUCCEEDED(rv); 1760 1761 // Push 20 transactions on the undo stack: 1762 1763 for (i = 1; i <= 20; i++) { 1764 tximpl = factory->create(mgr, NONE_FLAG); 1765 1766 rv = mgr->BeginBatch(nullptr); 1767 EXPECT_NS_SUCCEEDED(rv); 1768 1769 rv = mgr->DoTransaction(tximpl); 1770 EXPECT_NS_SUCCEEDED(rv); 1771 1772 rv = mgr->EndBatch(false); 1773 EXPECT_NS_SUCCEEDED(rv); 1774 1775 rv = mgr->GetNumberOfUndoItems(&numitems); 1776 EXPECT_NS_SUCCEEDED(rv); 1777 EXPECT_EQ(numitems, i); 1778 1779 rv = mgr->GetNumberOfRedoItems(&numitems); 1780 EXPECT_NS_SUCCEEDED(rv); 1781 EXPECT_EQ(numitems, 0); 1782 } 1783 1784 for (i = 1; i <= 10; i++) { 1785 rv = mgr->UndoTransaction(); 1786 EXPECT_NS_SUCCEEDED(rv); 1787 } 1788 rv = mgr->GetNumberOfUndoItems(&numitems); 1789 EXPECT_NS_SUCCEEDED(rv); 1790 EXPECT_EQ(numitems, 10); 1791 1792 rv = mgr->GetNumberOfRedoItems(&numitems); 1793 EXPECT_NS_SUCCEEDED(rv); 1794 EXPECT_EQ(numitems, 10); 1795 1796 rv = mgr->Clear(); 1797 EXPECT_NS_SUCCEEDED(rv); 1798 } 1799 1800 TEST(TestTXMgr, SimpleBatchTest) 1801 { 1802 /******************************************************************* 1803 * 1804 * Initialize globals for test. 1805 * 1806 *******************************************************************/ 1807 reset_globals(); 1808 sDoOrderArr = sSimpleBatchTestDoOrderArr; 1809 sUndoOrderArr = sSimpleBatchTestUndoOrderArr; 1810 sRedoOrderArr = sSimpleBatchTestRedoOrderArr; 1811 1812 /******************************************************************* 1813 * 1814 * Run the quick batch test. 1815 * 1816 *******************************************************************/ 1817 1818 SimpleTransactionFactory factory; 1819 quick_batch_test(&factory); 1820 } 1821 1822 TEST(TestTXMgr, AggregationBatchTest) 1823 { 1824 /******************************************************************* 1825 * 1826 * Initialize globals for test. 1827 * 1828 *******************************************************************/ 1829 1830 reset_globals(); 1831 sDoOrderArr = sAggregateBatchTestDoOrderArr; 1832 sUndoOrderArr = sAggregateBatchTestUndoOrderArr; 1833 sRedoOrderArr = sAggregateBatchTestRedoOrderArr; 1834 1835 /******************************************************************* 1836 * 1837 * Run the quick batch test. 1838 * 1839 *******************************************************************/ 1840 1841 AggregateTransactionFactory factory(3, 2, BATCH_FLAG); 1842 1843 quick_batch_test(&factory); 1844 } 1845 1846 /** 1847 * Create 'iterations * (iterations + 1) / 2' transactions; 1848 * do/undo/redo/undo them. 1849 **/ 1850 MOZ_CAN_RUN_SCRIPT_BOUNDARY void stress_test(TestTransactionFactory* factory, 1851 int32_t iterations) { 1852 /******************************************************************* 1853 * 1854 * Create a transaction manager: 1855 * 1856 *******************************************************************/ 1857 1858 nsCOMPtr<nsITransactionManager> mgr = new TransactionManager(); 1859 1860 nsresult rv; 1861 int32_t i, j; 1862 1863 for (i = 1; i <= iterations; i++) { 1864 /******************************************************************* 1865 * 1866 * Create and execute a bunch of transactions: 1867 * 1868 *******************************************************************/ 1869 1870 for (j = 1; j <= i; j++) { 1871 RefPtr<TestTransaction> tximpl = factory->create(mgr, NONE_FLAG); 1872 rv = mgr->DoTransaction(tximpl); 1873 EXPECT_NS_SUCCEEDED(rv); 1874 } 1875 1876 /******************************************************************* 1877 * 1878 * Undo all the transactions: 1879 * 1880 *******************************************************************/ 1881 1882 for (j = 1; j <= i; j++) { 1883 rv = mgr->UndoTransaction(); 1884 EXPECT_NS_SUCCEEDED(rv); 1885 } 1886 1887 /******************************************************************* 1888 * 1889 * Redo all the transactions: 1890 * 1891 *******************************************************************/ 1892 1893 for (j = 1; j <= i; j++) { 1894 rv = mgr->RedoTransaction(); 1895 EXPECT_NS_SUCCEEDED(rv); 1896 } 1897 1898 /******************************************************************* 1899 * 1900 * Undo all the transactions again so that they all end up on 1901 * the redo stack for pruning the next time we execute a new 1902 * transaction 1903 * 1904 *******************************************************************/ 1905 1906 for (j = 1; j <= i; j++) { 1907 rv = mgr->UndoTransaction(); 1908 EXPECT_NS_SUCCEEDED(rv); 1909 } 1910 } 1911 1912 rv = mgr->Clear(); 1913 EXPECT_NS_SUCCEEDED(rv); 1914 } 1915 1916 TEST(TestTXMgr, SimpleStressTest) 1917 { 1918 /******************************************************************* 1919 * 1920 * Initialize globals for test. 1921 * 1922 *******************************************************************/ 1923 1924 reset_globals(); 1925 1926 /******************************************************************* 1927 * 1928 * Do the stress test: 1929 * 1930 *******************************************************************/ 1931 1932 SimpleTransactionFactory factory; 1933 1934 int32_t iterations = 1935 #ifdef DEBUG 1936 10 1937 #else 1938 // 1939 // 1500 iterations sends 1,125,750 transactions through the system!! 1940 // 1941 1500 1942 #endif 1943 ; 1944 stress_test(&factory, iterations); 1945 } 1946 1947 TEST(TestTXMgr, AggregationStressTest) 1948 { 1949 /******************************************************************* 1950 * 1951 * Initialize globals for test. 1952 * 1953 *******************************************************************/ 1954 1955 reset_globals(); 1956 1957 /******************************************************************* 1958 * 1959 * Do the stress test: 1960 * 1961 *******************************************************************/ 1962 1963 AggregateTransactionFactory factory(3, 4); 1964 1965 int32_t iterations = 1966 #ifdef DEBUG 1967 10 1968 #else 1969 // 1970 // 500 iterations sends 2,630,250 transactions through the system!! 1971 // 1972 500 1973 #endif 1974 ; 1975 stress_test(&factory, iterations); 1976 } 1977 1978 TEST(TestTXMgr, AggregationBatchStressTest) 1979 { 1980 /******************************************************************* 1981 * 1982 * Initialize globals for test. 1983 * 1984 *******************************************************************/ 1985 1986 reset_globals(); 1987 1988 /******************************************************************* 1989 * 1990 * Do the stress test: 1991 * 1992 *******************************************************************/ 1993 1994 AggregateTransactionFactory factory(3, 4, BATCH_FLAG); 1995 1996 int32_t iterations = 1997 #ifdef DEBUG 1998 10 1999 #else 2000 # if defined(MOZ_ASAN) || defined(MOZ_WIDGET_ANDROID) 2001 // See Bug 929985: 500 is too many for ASAN and Android, 100 is safe. 2002 100 2003 # else 2004 // 2005 // 500 iterations sends 2,630,250 transactions through the system!! 2006 // 2007 500 2008 # endif 2009 #endif 2010 ; 2011 stress_test(&factory, iterations); 2012 }