annotate base/test/TestById.h @ 1773:fadd9f8aaa27

This output is too annoying, in the perfectly innocuous case of reading from an aggregate model whose components are different lengths
author Chris Cannam
date Wed, 14 Aug 2019 13:54:23 +0100
parents 043e05c956fb
children
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@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