Chris@1742
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@1742
|
2
|
Chris@1742
|
3 /*
|
Chris@1742
|
4 Sonic Visualiser
|
Chris@1742
|
5 An audio file viewer and annotation editor.
|
Chris@1742
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@1742
|
7
|
Chris@1742
|
8 This program is free software; you can redistribute it and/or
|
Chris@1742
|
9 modify it under the terms of the GNU General Public License as
|
Chris@1742
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@1742
|
11 License, or (at your option) any later version. See the file
|
Chris@1742
|
12 COPYING included with this distribution for more information.
|
Chris@1742
|
13 */
|
Chris@1742
|
14
|
Chris@1742
|
15 #include "../ById.h"
|
Chris@1742
|
16
|
Chris@1742
|
17 #include <QObject>
|
Chris@1742
|
18 #include <QtTest>
|
Chris@1742
|
19
|
Chris@1742
|
20 #include <iostream>
|
Chris@1742
|
21
|
Chris@1742
|
22 using namespace std;
|
Chris@1742
|
23
|
Chris@1742
|
24 struct WithoutId {};
|
Chris@1742
|
25
|
Chris@1752
|
26 // We'll need to change access levels for getId() and getUntypedId()
|
Chris@1752
|
27 // to test the raw calls
|
Chris@1752
|
28
|
Chris@1752
|
29 struct A : public WithTypedId<A> { public: using WithTypedId<A>::getId; };
|
Chris@1742
|
30 struct B1 : public A {};
|
Chris@1742
|
31 struct B2 : public A {};
|
Chris@1742
|
32
|
Chris@1742
|
33 struct M {};
|
Chris@1742
|
34
|
Chris@1742
|
35 typedef TypedById<A, A::Id> AById;
|
Chris@1742
|
36
|
Chris@1752
|
37 struct X : virtual public WithId { public: using WithId::getUntypedId; };
|
Chris@1742
|
38 struct Y : public X, public B2, public M {};
|
Chris@1742
|
39
|
Chris@1742
|
40 class TestById : public QObject
|
Chris@1742
|
41 {
|
Chris@1742
|
42 Q_OBJECT
|
Chris@1742
|
43
|
Chris@1742
|
44 private slots:
|
Chris@1742
|
45 void ids() {
|
Chris@1742
|
46 // Verify that ids are unique across all classes, not just
|
Chris@1742
|
47 // within a class. These must be the first two WithId objects
|
Chris@1742
|
48 // allocated in the first test in the suite, otherwise they
|
Chris@1742
|
49 // could be different even if they were allocated from
|
Chris@1742
|
50 // separate pools.
|
Chris@1742
|
51 A a;
|
Chris@1742
|
52 X x;
|
Chris@1742
|
53 if (a.getId().untyped == x.getUntypedId()) {
|
Chris@1742
|
54 cerr << "ERROR: a and x have the same id: " << a.getId() << endl;
|
Chris@1742
|
55 }
|
Chris@1742
|
56 QVERIFY(a.getId().untyped != x.getUntypedId());
|
Chris@1742
|
57
|
Chris@1742
|
58 A aa;
|
Chris@1742
|
59 QVERIFY(aa.getId().untyped != a.getId().untyped);
|
Chris@1742
|
60 QVERIFY(aa.getId().untyped != x.getUntypedId());
|
Chris@1742
|
61
|
Chris@1742
|
62 // Check the actual ids that have been allocated. This is
|
Chris@1742
|
63 // supposed to be a hidden implementation detail, but we want
|
Chris@1742
|
64 // to make sure the test itself hasn't become broken in terms
|
Chris@1742
|
65 // of allocation order (see comment above)
|
Chris@1742
|
66 QCOMPARE(a.getId().untyped, 0);
|
Chris@1742
|
67 QCOMPARE(x.getUntypedId(), 1);
|
Chris@1742
|
68 QCOMPARE(aa.getId().untyped, 2);
|
Chris@1742
|
69
|
Chris@1742
|
70 QVERIFY(!a.getId().isNone());
|
Chris@1742
|
71 QVERIFY(A::Id().isNone());
|
Chris@1742
|
72 }
|
Chris@1742
|
73
|
Chris@1742
|
74 // NB each test must release all the items it adds to the ById store
|
Chris@1742
|
75
|
Chris@1742
|
76 void anyEmpty() {
|
Chris@1742
|
77 auto p = AnyById::get(0);
|
Chris@1742
|
78 QVERIFY(!p);
|
Chris@1742
|
79 }
|
Chris@1742
|
80
|
Chris@1742
|
81 void anySimple() {
|
Chris@1742
|
82 auto a = std::make_shared<A>();
|
Chris@1752
|
83 int id = AnyById::add(a);
|
Chris@1752
|
84 QCOMPARE(id, a->getId().untyped);
|
Chris@1742
|
85
|
Chris@1752
|
86 auto aa = AnyById::getAs<A>(id);
|
Chris@1742
|
87 QVERIFY(!!aa);
|
Chris@1742
|
88 QCOMPARE(aa->getId(), a->getId());
|
Chris@1742
|
89 QCOMPARE(aa.get(), a.get()); // same object, not just same id!
|
Chris@1752
|
90 AnyById::release(id);
|
Chris@1742
|
91 }
|
Chris@1742
|
92
|
Chris@1742
|
93 void typedEmpty() {
|
Chris@1742
|
94 auto p = AById::get({});
|
Chris@1742
|
95 QVERIFY(!p);
|
Chris@1742
|
96 }
|
Chris@1742
|
97
|
Chris@1742
|
98 void typedSimple() {
|
Chris@1742
|
99 auto a = std::make_shared<A>();
|
Chris@1742
|
100 AById::add(a);
|
Chris@1742
|
101
|
Chris@1742
|
102 auto aa = AById::get(a->getId());
|
Chris@1742
|
103 QVERIFY(!!aa);
|
Chris@1742
|
104 QCOMPARE(aa->getId(), a->getId());
|
Chris@1742
|
105 QCOMPARE(aa.get(), a.get()); // same object, not just same id!
|
Chris@1742
|
106 AById::release(a);
|
Chris@1742
|
107 }
|
Chris@1742
|
108
|
Chris@1752
|
109 void typedReleaseById() {
|
Chris@1742
|
110 auto a = std::make_shared<A>();
|
Chris@1752
|
111 auto aid = AById::add(a);
|
Chris@1742
|
112
|
Chris@1752
|
113 auto aa = AById::get(aid);
|
Chris@1752
|
114 QVERIFY(!!aa);
|
Chris@1752
|
115 AById::release(aid);
|
Chris@1752
|
116
|
Chris@1752
|
117 aa = AById::get(aid);
|
Chris@1752
|
118 QVERIFY(!aa);
|
Chris@1752
|
119 }
|
Chris@1752
|
120
|
Chris@1752
|
121 void typedReleaseByItem() {
|
Chris@1752
|
122 auto a = std::make_shared<A>();
|
Chris@1752
|
123 auto aid = AById::add(a);
|
Chris@1752
|
124
|
Chris@1752
|
125 auto aa = AById::get(aid);
|
Chris@1742
|
126 QVERIFY(!!aa);
|
Chris@1742
|
127 AById::release(a);
|
Chris@1742
|
128
|
Chris@1752
|
129 aa = AById::get(aid);
|
Chris@1742
|
130 QVERIFY(!aa);
|
Chris@1742
|
131 }
|
Chris@1742
|
132
|
Chris@1742
|
133 void typedDowncast() {
|
Chris@1742
|
134 auto a = std::make_shared<A>();
|
Chris@1742
|
135 auto b1 = std::make_shared<B1>();
|
Chris@1742
|
136 AById::add(a);
|
Chris@1742
|
137 AById::add(b1);
|
Chris@1742
|
138
|
Chris@1742
|
139 auto bb1 = AById::getAs<B1>(a->getId());
|
Chris@1742
|
140 QVERIFY(!bb1);
|
Chris@1742
|
141
|
Chris@1742
|
142 bb1 = AById::getAs<B1>(b1->getId());
|
Chris@1742
|
143 QVERIFY(!!bb1);
|
Chris@1742
|
144 QCOMPARE(bb1->getId(), b1->getId());
|
Chris@1742
|
145
|
Chris@1742
|
146 auto bb2 = AById::getAs<B2>(b1->getId());
|
Chris@1742
|
147 QVERIFY(!bb2);
|
Chris@1742
|
148
|
Chris@1742
|
149 AById::release(a);
|
Chris@1742
|
150 AById::release(b1);
|
Chris@1742
|
151 }
|
Chris@1742
|
152
|
Chris@1742
|
153 void typedCrosscast() {
|
Chris@1742
|
154 auto y = std::make_shared<Y>();
|
Chris@1742
|
155 AById::add(y);
|
Chris@1742
|
156
|
Chris@1742
|
157 auto yy = AById::getAs<Y>(y->getId());
|
Chris@1742
|
158 QVERIFY(!!yy);
|
Chris@1742
|
159 QCOMPARE(yy->getId(), y->getId());
|
Chris@1742
|
160
|
Chris@1742
|
161 yy = AnyById::getAs<Y>(y->getId().untyped);
|
Chris@1742
|
162 QVERIFY(!!yy);
|
Chris@1742
|
163 QCOMPARE(yy->getId(), y->getId());
|
Chris@1742
|
164
|
Chris@1742
|
165 auto xx = AById::getAs<X>(y->getId());
|
Chris@1742
|
166 QVERIFY(!!xx);
|
Chris@1742
|
167 QCOMPARE(xx->getUntypedId(), y->getId().untyped);
|
Chris@1742
|
168 QCOMPARE(xx.get(), yy.get());
|
Chris@1742
|
169
|
Chris@1742
|
170 xx = AnyById::getAs<X>(y->getId().untyped);
|
Chris@1742
|
171 QVERIFY(!!xx);
|
Chris@1742
|
172 QCOMPARE(xx->getUntypedId(), y->getId().untyped);
|
Chris@1742
|
173 QCOMPARE(xx.get(), yy.get());
|
Chris@1742
|
174
|
Chris@1742
|
175 auto mm = AnyById::getAs<M>(y->getId().untyped);
|
Chris@1742
|
176 QVERIFY(!!mm);
|
Chris@1742
|
177 QCOMPARE(mm.get(), yy.get());
|
Chris@1742
|
178
|
Chris@1742
|
179 AById::release(y);
|
Chris@1742
|
180 }
|
Chris@1742
|
181
|
Chris@1742
|
182 void duplicateAdd() {
|
Chris@1742
|
183 auto a = std::make_shared<A>();
|
Chris@1742
|
184 AById::add(a);
|
Chris@1742
|
185 try {
|
Chris@1742
|
186 AById::add(a);
|
Chris@1742
|
187 cerr << "Failed to catch expected exception in duplicateAdd" << endl;
|
Chris@1742
|
188 QVERIFY(false);
|
Chris@1742
|
189 } catch (const std::logic_error &) {
|
Chris@1742
|
190 }
|
Chris@1742
|
191 AById::release(a);
|
Chris@1742
|
192 }
|
Chris@1742
|
193
|
Chris@1742
|
194 void unknownRelease() {
|
Chris@1742
|
195 auto a = std::make_shared<A>();
|
Chris@1742
|
196 auto b1 = std::make_shared<B1>();
|
Chris@1742
|
197 AById::add(a);
|
Chris@1742
|
198 try {
|
Chris@1742
|
199 AById::release(b1);
|
Chris@1742
|
200 cerr << "Failed to catch expected exception in unknownRelease" << endl;
|
Chris@1742
|
201 QVERIFY(false);
|
Chris@1742
|
202 } catch (const std::logic_error &) {
|
Chris@1742
|
203 }
|
Chris@1742
|
204 AById::release(a);
|
Chris@1742
|
205 }
|
Chris@1742
|
206 };
|
Chris@1742
|
207
|