Coverage Report

Created: 2018-09-25 14:53

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