diff options
Diffstat (limited to 'tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp')
-rw-r--r-- | tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp | 156 |
1 files changed, 150 insertions, 6 deletions
diff --git a/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp b/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp index adad544..1601b7e 100644 --- a/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp +++ b/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp @@ -41,6 +41,9 @@ #include <QtTest/QtTest> #include <e32base.h> +#include <typeinfo> +#include <stdexcept> +#include <euserhl.h> #ifdef Q_OS_SYMBIAN @@ -55,6 +58,7 @@ public: void TestSchedulerCatchesError(TLeavingFunc* f, int error); void TestSymbianRoundTrip(int leave, int trap); + void TestStdRoundTrip(const std::exception& thrown, const std::exception& caught); bool event(QEvent *event); @@ -72,6 +76,8 @@ private slots: void testDtor1(); void testDtor2(); void testNestedExceptions(); + void testScopedPointer(); + void testHybrid(); }; class CDummy : public CBase @@ -169,7 +175,7 @@ void ThrowBadAlloc() void TranslateThrowBadAllocL() { - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(ThrowBadAlloc()); + QT_TRYCATCH_LEAVING(ThrowBadAlloc()); } void tst_qmainexceptions::testTranslateBadAlloc() @@ -186,7 +192,7 @@ void BigAlloc() void TranslateBigAllocL() { - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(BigAlloc()); + QT_TRYCATCH_LEAVING(BigAlloc()); } void tst_qmainexceptions::testTranslateBigAlloc() @@ -199,13 +205,27 @@ void tst_qmainexceptions::TestSymbianRoundTrip(int leave, int trap) { // check that leave converted to exception, converted to error gives expected error code int trapped; - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR( + QT_TRYCATCH_ERROR( trapped, - QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION( + QT_TRAP_THROWING( User::LeaveIfError(leave))); QCOMPARE(trap, trapped); } +void tst_qmainexceptions::TestStdRoundTrip(const std::exception& thrown, const std::exception& caught) +{ + bool ok = false; + try { + QT_TRAP_THROWING(qt_exception2SymbianLeaveL(thrown)); + } catch (const std::exception& ex) { + const std::type_info& exType = typeid(ex); + const std::type_info& caughtType = typeid(caught); + QCOMPARE(exType, caughtType); + ok = true; + } + QCOMPARE(ok, true); +} + void tst_qmainexceptions::testRoundTrip() { for (int e=-50; e<0; e++) @@ -214,12 +234,16 @@ void tst_qmainexceptions::testRoundTrip() // positive error codes are not errors TestSymbianRoundTrip(1, KErrNone); TestSymbianRoundTrip(1000000000, KErrNone); + TestStdRoundTrip(std::bad_alloc(), std::bad_alloc()); + TestStdRoundTrip(std::invalid_argument("abc"), std::invalid_argument("")); + TestStdRoundTrip(std::underflow_error("abc"), std::underflow_error("")); + TestStdRoundTrip(std::overflow_error("abc"), std::overflow_error("")); } void tst_qmainexceptions::testTrap() { - // testing qt_translateExceptionToSymbianErrorL - TRAPD(err, qt_translateExceptionToSymbianErrorL(std::bad_alloc())); + // testing qt_exception2SymbianLeaveL + TRAPD(err, qt_exception2SymbianLeaveL(std::bad_alloc())); QCOMPARE(err, KErrNoMemory); } @@ -310,6 +334,126 @@ void tst_qmainexceptions::testNestedExceptions() catch (const std::exception&) {} } +class CTestRef : public CBase +{ +public: + CTestRef(int& aX) : iX(aX) { iX++; } + ~CTestRef() { iX--; } + int& iX; +}; + +void tst_qmainexceptions::testScopedPointer() +{ + int x = 0; + { + QScopedPointer<CTestRef> ptr(q_check_ptr(new CTestRef(x))); + QCOMPARE(x, 1); + } + QCOMPARE(x, 0); + try { + QScopedPointer<CTestRef> ptr(q_check_ptr(new CTestRef(x))); + QCOMPARE(x, 1); + throw 1; + } catch (int) { + QCOMPARE(x, 0); + } + QCOMPARE(x, 0); +} + +int dtorFired[20]; +int* recDtor; + +class CDtorOrder : public CBase +{ +public: + CDtorOrder(TInt aId) : iId(aId) {} + ~CDtorOrder() { *(recDtor++)=iId; } + TInt iId; +}; + +class QDtorOrder +{ +public: + QDtorOrder(int aId) : iId(aId) {} + ~QDtorOrder() { *(recDtor++)=iId; } + int iId; +}; + +class RDtorOrder : public RHandleBase +{ +public: + TInt Connect(TInt aId) {iId = aId; SetHandle(aId); return KErrNone; } + void Close() { *(recDtor++)=iId; } + TInt iId; +}; + +enum THybridAction {EHybridLeave, EHybridThrow, EHybridPass}; + +void HybridFuncLX(THybridAction aAction) +{ + recDtor = dtorFired; + QDtorOrder q1(1); + {QDtorOrder q2(2);} + CDtorOrder* c1 = new(ELeave) CDtorOrder(11); + CleanupStack::PushL(c1); + {LManagedHandle<RDtorOrder> r1; + r1->Connect(21) OR_LEAVE;} + CDtorOrder* c2 = new(ELeave) CDtorOrder(12); + CleanupStack::PushL(c2); + QDtorOrder q3(3); + LManagedHandle<RDtorOrder> r2; + r2->Connect(22) OR_LEAVE; + CDtorOrder* c3 = new(ELeave) CDtorOrder(13); + CleanupStack::PushL(c3); + CleanupStack::PopAndDestroy(c3); + QDtorOrder q4(4); + switch (aAction) + { + case EHybridLeave: + User::Leave(KErrNotFound); + break; + case EHybridThrow: + throw std::bad_alloc(); + break; + default: + break; + } + CleanupStack::PopAndDestroy(2); +} + +void tst_qmainexceptions::testHybrid() +{ + TRAPD(error, + QT_TRYCATCH_LEAVING( + HybridFuncLX(EHybridLeave); + ) ); + QCOMPARE(error, KErrNotFound); + int expected1[] = {2, 21, 13, 12, 11, 4, 22, 3, 1}; + QCOMPARE(int(sizeof(expected1)/sizeof(int)), int(recDtor - dtorFired)); + for (int i=0; i<sizeof(expected1)/sizeof(int); i++) + QCOMPARE(expected1[i], dtorFired[i]); + + TRAP(error, + QT_TRYCATCH_LEAVING( + HybridFuncLX(EHybridThrow); + ) ); + QCOMPARE(error, KErrNoMemory); + int expected2[] = {2, 21, 13, 4, 22, 3, 1, 12, 11}; + QCOMPARE(int(sizeof(expected2)/sizeof(int)), int(recDtor - dtorFired)); + for (int i=0; i<sizeof(expected2)/sizeof(int); i++) + QCOMPARE(expected2[i], dtorFired[i]); + + TRAP(error, + QT_TRYCATCH_LEAVING( + HybridFuncLX(EHybridPass); + ) ); + QCOMPARE(error, KErrNone); + int expected3[] = {2, 21, 13, 12, 11, 4, 22, 3, 1}; + QCOMPARE(int(sizeof(expected3)/sizeof(int)), int(recDtor - dtorFired)); + for (int i=0; i<sizeof(expected3)/sizeof(int); i++) + QCOMPARE(expected3[i], dtorFired[i]); +} + QTEST_MAIN(tst_qmainexceptions) #include "tst_qmainexceptions.moc" |