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@1756
|
54 std::cerr << "ERROR: a and x have the same id: " << a.getId()
|
Chris@1756
|
55 << std::endl;
|
Chris@1742
|
56 }
|
Chris@1742
|
57 QVERIFY(a.getId().untyped != x.getUntypedId());
|
Chris@1742
|
58
|
Chris@1742
|
59 A aa;
|
Chris@1742
|
60 QVERIFY(aa.getId().untyped != a.getId().untyped);
|
Chris@1742
|
61 QVERIFY(aa.getId().untyped != x.getUntypedId());
|
Chris@1742
|
62
|
Chris@1742
|
63 // Check the actual ids that have been allocated. This is
|
Chris@1742
|
64 // supposed to be a hidden implementation detail, but we want
|
Chris@1742
|
65 // to make sure the test itself hasn't become broken in terms
|
Chris@1742
|
66 // of allocation order (see comment above)
|
Chris@1742
|
67 QCOMPARE(a.getId().untyped, 0);
|
Chris@1742
|
68 QCOMPARE(x.getUntypedId(), 1);
|
Chris@1742
|
69 QCOMPARE(aa.getId().untyped, 2);
|
Chris@1742
|
70
|
Chris@1742
|
71 QVERIFY(!a.getId().isNone());
|
Chris@1742
|
72 QVERIFY(A::Id().isNone());
|
Chris@1742
|
73 }
|
Chris@1742
|
74
|
Chris@1742
|
75 // NB each test must release all the items it adds to the ById store
|
Chris@1742
|
76
|
Chris@1742
|
77 void anyEmpty() {
|
Chris@1742
|
78 auto p = AnyById::get(0);
|
Chris@1742
|
79 QVERIFY(!p);
|
Chris@1742
|
80 }
|
Chris@1742
|
81
|
Chris@1742
|
82 void anySimple() {
|
Chris@1742
|
83 auto a = std::make_shared<A>();
|
Chris@1752
|
84 int id = AnyById::add(a);
|
Chris@1752
|
85 QCOMPARE(id, a->getId().untyped);
|
Chris@1742
|
86
|
Chris@1752
|
87 auto aa = AnyById::getAs<A>(id);
|
Chris@1742
|
88 QVERIFY(!!aa);
|
Chris@1742
|
89 QCOMPARE(aa->getId(), a->getId());
|
Chris@1742
|
90 QCOMPARE(aa.get(), a.get()); // same object, not just same id!
|
Chris@1752
|
91 AnyById::release(id);
|
Chris@1742
|
92 }
|
Chris@1742
|
93
|
Chris@1742
|
94 void typedEmpty() {
|
Chris@1742
|
95 auto p = AById::get({});
|
Chris@1742
|
96 QVERIFY(!p);
|
Chris@1742
|
97 }
|
Chris@1742
|
98
|
Chris@1742
|
99 void typedSimple() {
|
Chris@1742
|
100 auto a = std::make_shared<A>();
|
Chris@1742
|
101 AById::add(a);
|
Chris@1742
|
102
|
Chris@1742
|
103 auto aa = AById::get(a->getId());
|
Chris@1742
|
104 QVERIFY(!!aa);
|
Chris@1742
|
105 QCOMPARE(aa->getId(), a->getId());
|
Chris@1742
|
106 QCOMPARE(aa.get(), a.get()); // same object, not just same id!
|
Chris@1742
|
107 AById::release(a);
|
Chris@1742
|
108 }
|
Chris@1742
|
109
|
Chris@1752
|
110 void typedReleaseById() {
|
Chris@1742
|
111 auto a = std::make_shared<A>();
|
Chris@1752
|
112 auto aid = AById::add(a);
|
Chris@1742
|
113
|
Chris@1752
|
114 auto aa = AById::get(aid);
|
Chris@1752
|
115 QVERIFY(!!aa);
|
Chris@1752
|
116 AById::release(aid);
|
Chris@1752
|
117
|
Chris@1752
|
118 aa = AById::get(aid);
|
Chris@1752
|
119 QVERIFY(!aa);
|
Chris@1752
|
120 }
|
Chris@1752
|
121
|
Chris@1752
|
122 void typedReleaseByItem() {
|
Chris@1752
|
123 auto a = std::make_shared<A>();
|
Chris@1752
|
124 auto aid = AById::add(a);
|
Chris@1752
|
125
|
Chris@1752
|
126 auto aa = AById::get(aid);
|
Chris@1742
|
127 QVERIFY(!!aa);
|
Chris@1742
|
128 AById::release(a);
|
Chris@1742
|
129
|
Chris@1752
|
130 aa = AById::get(aid);
|
Chris@1742
|
131 QVERIFY(!aa);
|
Chris@1742
|
132 }
|
Chris@1742
|
133
|
Chris@1742
|
134 void typedDowncast() {
|
Chris@1742
|
135 auto a = std::make_shared<A>();
|
Chris@1742
|
136 auto b1 = std::make_shared<B1>();
|
Chris@1742
|
137 AById::add(a);
|
Chris@1742
|
138 AById::add(b1);
|
Chris@1742
|
139
|
Chris@1742
|
140 auto bb1 = AById::getAs<B1>(a->getId());
|
Chris@1742
|
141 QVERIFY(!bb1);
|
Chris@1742
|
142
|
Chris@1742
|
143 bb1 = AById::getAs<B1>(b1->getId());
|
Chris@1742
|
144 QVERIFY(!!bb1);
|
Chris@1742
|
145 QCOMPARE(bb1->getId(), b1->getId());
|
Chris@1742
|
146
|
Chris@1742
|
147 auto bb2 = AById::getAs<B2>(b1->getId());
|
Chris@1742
|
148 QVERIFY(!bb2);
|
Chris@1742
|
149
|
Chris@1742
|
150 AById::release(a);
|
Chris@1742
|
151 AById::release(b1);
|
Chris@1742
|
152 }
|
Chris@1742
|
153
|
Chris@1742
|
154 void typedCrosscast() {
|
Chris@1742
|
155 auto y = std::make_shared<Y>();
|
Chris@1742
|
156 AById::add(y);
|
Chris@1742
|
157
|
Chris@1742
|
158 auto yy = AById::getAs<Y>(y->getId());
|
Chris@1742
|
159 QVERIFY(!!yy);
|
Chris@1742
|
160 QCOMPARE(yy->getId(), y->getId());
|
Chris@1742
|
161
|
Chris@1742
|
162 yy = AnyById::getAs<Y>(y->getId().untyped);
|
Chris@1742
|
163 QVERIFY(!!yy);
|
Chris@1742
|
164 QCOMPARE(yy->getId(), y->getId());
|
Chris@1742
|
165
|
Chris@1742
|
166 auto xx = AById::getAs<X>(y->getId());
|
Chris@1742
|
167 QVERIFY(!!xx);
|
Chris@1742
|
168 QCOMPARE(xx->getUntypedId(), y->getId().untyped);
|
Chris@1742
|
169 QCOMPARE(xx.get(), yy.get());
|
Chris@1742
|
170
|
Chris@1742
|
171 xx = AnyById::getAs<X>(y->getId().untyped);
|
Chris@1742
|
172 QVERIFY(!!xx);
|
Chris@1742
|
173 QCOMPARE(xx->getUntypedId(), y->getId().untyped);
|
Chris@1742
|
174 QCOMPARE(xx.get(), yy.get());
|
Chris@1742
|
175
|
Chris@1742
|
176 auto mm = AnyById::getAs<M>(y->getId().untyped);
|
Chris@1742
|
177 QVERIFY(!!mm);
|
Chris@1742
|
178 QCOMPARE(mm.get(), yy.get());
|
Chris@1742
|
179
|
Chris@1742
|
180 AById::release(y);
|
Chris@1742
|
181 }
|
Chris@1742
|
182
|
Chris@1742
|
183 void duplicateAdd() {
|
Chris@1742
|
184 auto a = std::make_shared<A>();
|
Chris@1742
|
185 AById::add(a);
|
Chris@1742
|
186 try {
|
Chris@1742
|
187 AById::add(a);
|
Chris@1756
|
188 std::cerr << "Failed to catch expected exception in duplicateAdd"
|
Chris@1756
|
189 << std::endl;
|
Chris@1742
|
190 QVERIFY(false);
|
Chris@1742
|
191 } catch (const std::logic_error &) {
|
Chris@1742
|
192 }
|
Chris@1742
|
193 AById::release(a);
|
Chris@1742
|
194 }
|
Chris@1742
|
195
|
Chris@1742
|
196 void unknownRelease() {
|
Chris@1742
|
197 auto a = std::make_shared<A>();
|
Chris@1742
|
198 auto b1 = std::make_shared<B1>();
|
Chris@1742
|
199 AById::add(a);
|
Chris@1742
|
200 try {
|
Chris@1742
|
201 AById::release(b1);
|
Chris@1756
|
202 std::cerr << "Failed to catch expected exception in unknownRelease"
|
Chris@1756
|
203 << std::endl;
|
Chris@1742
|
204 QVERIFY(false);
|
Chris@1742
|
205 } catch (const std::logic_error &) {
|
Chris@1742
|
206 }
|
Chris@1742
|
207 AById::release(a);
|
Chris@1742
|
208 }
|
Chris@1742
|
209 };
|
Chris@1742
|
210
|