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