1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include <QtCore/QScopedValueRollback>
31
32/*!
33 \class tst_QScopedValueRollback
34 \internal
35 \since 4.8
36 \brief Tests class QScopedValueRollback.
37
38 */
39class tst_QScopedValueRollback : public QObject
40{
41 Q_OBJECT
42
43private Q_SLOTS:
44 void leavingScope();
45 void leavingScopeAfterCommit();
46 void rollbackToPreviousCommit();
47 void exceptions();
48 void earlyExitScope();
49 void moveOnly();
50private:
51 void earlyExitScope_helper(int exitpoint, int &member);
52};
53
54void tst_QScopedValueRollback::leavingScope()
55{
56 int i = 0;
57 bool b = false;
58 bool b2 = false;
59 QString s("This is useful");
60
61 //test rollback on going out of scope
62 {
63 QScopedValueRollback<int> ri(i);
64 QScopedValueRollback<bool> rb(b);
65 QScopedValueRollback<bool> rb2(b2, true);
66 QScopedValueRollback<QString> rs(s);
67 QCOMPARE(b, false);
68 QCOMPARE(b2, true);
69 QCOMPARE(i, 0);
70 QCOMPARE(s, QString("This is useful"));
71 b = true;
72 i = 1;
73 s = "Useless";
74 QCOMPARE(b, true);
75 QCOMPARE(i, 1);
76 QCOMPARE(s, QString("Useless"));
77 }
78 QCOMPARE(b, false);
79 QCOMPARE(b2, false);
80 QCOMPARE(i, 0);
81 QCOMPARE(s, QString("This is useful"));
82}
83
84void tst_QScopedValueRollback::leavingScopeAfterCommit()
85{
86 int i = 0;
87 bool b = false;
88 QString s("This is useful");
89
90 //test rollback on going out of scope
91 {
92 QScopedValueRollback<int> ri(i);
93 QScopedValueRollback<bool> rb(b);
94 QScopedValueRollback<QString> rs(s);
95 QCOMPARE(b, false);
96 QCOMPARE(i, 0);
97 QCOMPARE(s, QString("This is useful"));
98 b = true;
99 i = 1;
100 s = "Useless";
101 QCOMPARE(b, true);
102 QCOMPARE(i, 1);
103 QCOMPARE(s, QString("Useless"));
104 ri.commit();
105 rb.commit();
106 rs.commit();
107 }
108 QCOMPARE(b, true);
109 QCOMPARE(i, 1);
110 QCOMPARE(s, QString("Useless"));
111}
112
113void tst_QScopedValueRollback::rollbackToPreviousCommit()
114{
115 int i=0;
116 {
117 QScopedValueRollback<int> ri(i);
118 i++;
119 ri.commit();
120 i++;
121 }
122 QCOMPARE(i,1);
123 {
124 QScopedValueRollback<int> ri1(i);
125 i++;
126 ri1.commit();
127 i++;
128 ri1.commit();
129 i++;
130 }
131 QCOMPARE(i,3);
132}
133
134void tst_QScopedValueRollback::exceptions()
135{
136 bool b = false;
137 bool caught = false;
138 QT_TRY
139 {
140 QScopedValueRollback<bool> rb(b);
141 b = true;
142 QT_THROW(std::bad_alloc()); //if Qt compiled without exceptions this is noop
143 rb.commit(); //if Qt compiled without exceptions, true is committed
144 }
145 QT_CATCH(...)
146 {
147 caught = true;
148 }
149 QCOMPARE(b, !caught); //expect false if exception was thrown, true otherwise
150}
151
152void tst_QScopedValueRollback::earlyExitScope()
153{
154 int i=0;
155 int j=0;
156 while (true) {
157 QScopedValueRollback<int> ri(i);
158 i++;
159 j=i;
160 if (i>8) break;
161 ri.commit();
162 }
163 QCOMPARE(i,8);
164 QCOMPARE(j,9);
165
166 for (i = 0; i < 5; i++) {
167 j=1;
168 earlyExitScope_helper(exitpoint: i,member&: j);
169 QCOMPARE(j, 1<<i);
170 }
171}
172
173void tst_QScopedValueRollback::earlyExitScope_helper(int exitpoint, int& member)
174{
175 QScopedValueRollback<int> r(member);
176 member *= 2;
177 if (exitpoint == 0)
178 return;
179 r.commit();
180 member *= 2;
181 if (exitpoint == 1)
182 return;
183 r.commit();
184 member *= 2;
185 if (exitpoint == 2)
186 return;
187 r.commit();
188 member *= 2;
189 if (exitpoint == 3)
190 return;
191 r.commit();
192}
193
194void tst_QScopedValueRollback::moveOnly()
195{
196 std::unique_ptr<int> uniquePtr;
197 std::unique_ptr<int> newVal(new int(5));
198 QVERIFY(!uniquePtr);
199 {
200 QScopedValueRollback<std::unique_ptr<int>> r(uniquePtr, std::move(newVal));
201 QVERIFY(uniquePtr);
202 }
203 QVERIFY(!uniquePtr);
204}
205
206QTEST_MAIN(tst_QScopedValueRollback)
207#include "tst_qscopedvaluerollback.moc"
208

source code of qtbase/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp