annotate base/test/TestById.h @ 1753:d954dfccd922 by-id

Comments
author Chris Cannam
date Fri, 05 Jul 2019 16:55:20 +0100
parents 6d09d68165a4
children 043e05c956fb
rev   line source
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