From bc80bbb325d1814489d72bd1bc0760e8f7423a2f Mon Sep 17 00:00:00 2001 From: Christian Gruber Date: Mon, 21 Sep 2020 00:47:53 +0200 Subject: [PATCH] Simplify type checking for GObject mockups A type conversion function is introduced for each GObject mockup. This function does a runtime type check and generates a GoogleTest failure in case of any type error. This avoids checking GObject type twice. --- libgnucash/engine/mocks/gmock-Account.cpp | 28 +++--- libgnucash/engine/mocks/gmock-Account.h | 20 ++++ libgnucash/engine/mocks/gmock-Split.cpp | 92 ++++++++----------- libgnucash/engine/mocks/gmock-Split.h | 20 ++++ libgnucash/engine/mocks/gmock-Transaction.cpp | 76 ++++++--------- libgnucash/engine/mocks/gmock-Transaction.h | 20 ++++ libgnucash/engine/mocks/gmock-qofbook.cpp | 5 +- libgnucash/engine/mocks/gmock-qofbook.h | 21 +++++ 8 files changed, 161 insertions(+), 121 deletions(-) diff --git a/libgnucash/engine/mocks/gmock-Account.cpp b/libgnucash/engine/mocks/gmock-Account.cpp index c25b1157ff..d92679f4a0 100644 --- a/libgnucash/engine/mocks/gmock-Account.cpp +++ b/libgnucash/engine/mocks/gmock-Account.cpp @@ -27,45 +27,39 @@ void xaccAccountBeginEdit (Account *account) { ASSERT_TRUE(GNC_IS_MOCKACCOUNT(account)); - ((MockAccount*)account)->begin_edit(); + gnc_mockaccount(account)->begin_edit(); } void xaccAccountCommitEdit (Account *account) { ASSERT_TRUE(GNC_IS_MOCKACCOUNT(account)); - ((MockAccount*)account)->commit_edit(); + gnc_mockaccount(account)->commit_edit(); } QofBook * gnc_account_get_book(const Account *account) { - EXPECT_TRUE(GNC_IS_MOCKACCOUNT(account)); - if (GNC_IS_MOCKACCOUNT(account)) - return ((MockAccount*)account)->get_book(); - else - return nullptr; + SCOPED_TRACE(""); + const MockAccount* mockaccount = gnc_mockaccount(account); + return mockaccount ? mockaccount->get_book() : nullptr; } gint xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, void *data) { - EXPECT_TRUE(GNC_IS_MOCKACCOUNT(acc)); - if (GNC_IS_MOCKACCOUNT(acc)) - return ((MockAccount*)acc)->for_each_transaction(proc, data); - else - return 0; + SCOPED_TRACE(""); + const MockAccount* mockaccount = gnc_mockaccount(acc); + return mockaccount ? mockaccount->for_each_transaction(proc, data) : 0; } GncImportMatchMap * gnc_account_imap_create_imap (Account *acc) { - EXPECT_TRUE(GNC_IS_MOCKACCOUNT(acc)); - if (GNC_IS_MOCKACCOUNT(acc)) - return ((MockAccount*)acc)->create_imap(); - else - return nullptr; + SCOPED_TRACE(""); + MockAccount* mockaccount = gnc_mockaccount(acc); + return mockaccount ? mockaccount->create_imap() : nullptr; } Account* diff --git a/libgnucash/engine/mocks/gmock-Account.h b/libgnucash/engine/mocks/gmock-Account.h index 9552301a5a..04a48b5d80 100644 --- a/libgnucash/engine/mocks/gmock-Account.h +++ b/libgnucash/engine/mocks/gmock-Account.h @@ -67,4 +67,24 @@ public: MOCK_METHOD2(add_account_bayes, void(std::vector&, Account*)); }; + +// type conversion functions +static inline MockAccount* +gnc_mockaccount (Account *account) +{ + if (GNC_IS_MOCKACCOUNT(account)) + return static_cast(account); + ADD_FAILURE() << "Expected 'account' to be of type 'MockAccount'"; + return nullptr; +} + +static inline const MockAccount* +gnc_mockaccount (const Account *account) +{ + if (GNC_IS_MOCKACCOUNT(account)) + return static_cast(account); + ADD_FAILURE() << "Expected 'account' to be of type 'MockAccount'"; + return nullptr; +} + #endif diff --git a/libgnucash/engine/mocks/gmock-Split.cpp b/libgnucash/engine/mocks/gmock-Split.cpp index d33a44a1d7..5db4cad974 100644 --- a/libgnucash/engine/mocks/gmock-Split.cpp +++ b/libgnucash/engine/mocks/gmock-Split.cpp @@ -30,31 +30,25 @@ gnc_mocksplit_class_init (MockSplitClass *klass) Split * xaccMallocSplit (QofBook *book) { - EXPECT_TRUE(QOF_IS_MOCKBOOK(book)); - if (QOF_IS_MOCKBOOK(book)) - return ((QofMockBook*)book)->malloc_split(); - else - return nullptr; + SCOPED_TRACE(""); + QofMockBook* mockbook = qof_mockbook(book); + return mockbook ? mockbook->malloc_split() : nullptr; } QofBook * xaccSplitGetBook (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_book(); - else - return nullptr; + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_book() : nullptr; } Account * xaccSplitGetAccount (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_account(); - else - return nullptr; + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_account() : nullptr; } void @@ -62,105 +56,91 @@ xaccSplitSetAccount (Split *split, Account *acc) { ASSERT_TRUE(GNC_IS_MOCKSPLIT(split)); ASSERT_TRUE(GNC_IS_MOCKACCOUNT(acc)); - ((MockSplit*)split)->set_account(acc); + gnc_mocksplit(split)->set_account(acc); } gnc_numeric xaccSplitGetAmount (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_amount(); - else - return gnc_numeric_zero(); + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_amount() : gnc_numeric_zero(); } void xaccSplitSetAmount (Split *split, gnc_numeric amt) { ASSERT_TRUE(GNC_IS_MOCKSPLIT(split)); - ((MockSplit*)split)->set_amount(amt); + gnc_mocksplit(split)->set_amount(amt); } gnc_numeric xaccSplitGetValue (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_value(); - else - return gnc_numeric_zero(); + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_value() : gnc_numeric_zero(); } void xaccSplitSetValue (Split *split, gnc_numeric val) { ASSERT_TRUE(GNC_IS_MOCKSPLIT(split)); - ((MockSplit*)split)->set_value(val); + gnc_mocksplit(split)->set_value(val); } const char * xaccSplitGetMemo (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_memo(); - else - return nullptr; + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_memo() : ""; } char xaccSplitGetReconcile (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_reconcile(); - else - return VREC; + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_reconcile() : VREC; } void xaccSplitSetReconcile (Split *split, char recn) { ASSERT_TRUE(GNC_IS_MOCKSPLIT(split)); - ((MockSplit*)split)->set_reconcile(recn); + gnc_mocksplit(split)->set_reconcile(recn); } void xaccSplitSetDateReconciledSecs (Split *split, time64 secs) { ASSERT_TRUE(GNC_IS_MOCKSPLIT(split)); - ((MockSplit*)split)->set_date_reconciled_secs(secs); + gnc_mocksplit(split)->set_date_reconciled_secs(secs); } const char * xaccSplitGetAction (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_action(); - else - return nullptr; + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_action() : ""; } Split * xaccSplitGetOtherSplit (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_other_split(); - else - return nullptr; + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_other_split() : nullptr; } Transaction * xaccSplitGetParent (const Split *split) { - EXPECT_TRUE(GNC_IS_MOCKSPLIT(split)); - if (GNC_IS_MOCKSPLIT(split)) - return ((MockSplit*)split)->get_parent(); - else - return nullptr; + SCOPED_TRACE(""); + const MockSplit* mocksplit = gnc_mocksplit(split); + return mocksplit ? mocksplit->get_parent() : nullptr; } void @@ -168,5 +148,5 @@ xaccSplitSetParent(Split *split, Transaction *trans) { ASSERT_TRUE(GNC_IS_MOCKSPLIT(split)); ASSERT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - ((MockSplit*)split)->set_parent(trans); + gnc_mocksplit(split)->set_parent(trans); } diff --git a/libgnucash/engine/mocks/gmock-Split.h b/libgnucash/engine/mocks/gmock-Split.h index c8ed05ab47..b60da9387b 100644 --- a/libgnucash/engine/mocks/gmock-Split.h +++ b/libgnucash/engine/mocks/gmock-Split.h @@ -82,4 +82,24 @@ protected: ~MockSplit() {} }; + +// type conversion functions +static inline MockSplit* +gnc_mocksplit (Split *split) +{ + if (GNC_IS_MOCKSPLIT(split)) + return static_cast(split); + ADD_FAILURE() << "Expected 'split' to be of type 'MockSplit'"; + return nullptr; +} + +static inline const MockSplit* +gnc_mocksplit (const Split *split) +{ + if (GNC_IS_MOCKSPLIT(split)) + return static_cast(split); + ADD_FAILURE() << "Expected 'split' to be of type 'MockSplit'"; + return nullptr; +} + #endif diff --git a/libgnucash/engine/mocks/gmock-Transaction.cpp b/libgnucash/engine/mocks/gmock-Transaction.cpp index 5310ef5266..487a5b4d8c 100644 --- a/libgnucash/engine/mocks/gmock-Transaction.cpp +++ b/libgnucash/engine/mocks/gmock-Transaction.cpp @@ -29,121 +29,105 @@ void xaccTransBeginEdit (Transaction *trans) { ASSERT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - ((MockTransaction*)trans)->begin_edit(); + gnc_mocktransaction(trans)->begin_edit(); } void xaccTransCommitEdit (Transaction *trans) { ASSERT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - ((MockTransaction*)trans)->commit_edit(); + gnc_mocktransaction(trans)->commit_edit(); } Split * xaccTransGetSplit (const Transaction *trans, int i) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->get_split(i); - else - return nullptr; + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); + return mocktrans ? mocktrans->get_split(i) : nullptr; } Split * xaccTransFindSplitByAccount(const Transaction *trans, const Account *acc) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); EXPECT_TRUE(GNC_IS_MOCKACCOUNT(acc)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->find_split_by_account(acc); - else - return nullptr; + return mocktrans ? mocktrans->find_split_by_account(acc) : nullptr; } time64 xaccTransGetDate (const Transaction *trans) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->get_date(); - else - return 0; + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); + return mocktrans ? mocktrans->get_date() : 0; } void xaccTransSetDatePostedSecsNormalized (Transaction *trans, time64 time) { ASSERT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - ((MockTransaction*)trans)->set_date_posted_secs_normalized(time); + gnc_mocktransaction(trans)->set_date_posted_secs_normalized(time); } const char * xaccTransGetDescription (const Transaction *trans) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->get_description(); - else - return nullptr; + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); + return mocktrans ? mocktrans->get_description() : ""; } void xaccTransSetDescription (Transaction *trans, const char *desc) { ASSERT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - ((MockTransaction*)trans)->set_description(desc); + gnc_mocktransaction(trans)->set_description(desc); } const char * xaccTransGetNotes (const Transaction *trans) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->get_notes(); - else - return nullptr; + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); + return mocktrans ? mocktrans->get_notes() : ""; } void xaccTransSetNotes (Transaction *trans, const char *notes) { ASSERT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - ((MockTransaction*)trans)->set_description(notes); + gnc_mocktransaction(trans)->set_description(notes); } gnc_numeric xaccTransGetImbalanceValue (const Transaction * trans) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->get_imbalance_value(); - else - return gnc_numeric_zero(); + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); + return mocktrans ? mocktrans->get_imbalance_value() : gnc_numeric_zero(); } const char * xaccTransGetNum (const Transaction *trans) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->get_num(); - else - return nullptr; + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); + return mocktrans ? mocktrans->get_num() : ""; } gboolean xaccTransIsOpen (const Transaction *trans) { - EXPECT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - if (GNC_IS_MOCKTRANSACTION(trans)) - return ((MockTransaction*)trans)->is_open(); - else - return FALSE; + SCOPED_TRACE(""); + const MockTransaction* mocktrans = gnc_mocktransaction(trans); + return mocktrans ? mocktrans->is_open() : FALSE; } void xaccTransDestroy (Transaction *trans) { ASSERT_TRUE(GNC_IS_MOCKTRANSACTION(trans)); - ((MockTransaction*)trans)->destroy(); + gnc_mocktransaction(trans)->destroy(); } diff --git a/libgnucash/engine/mocks/gmock-Transaction.h b/libgnucash/engine/mocks/gmock-Transaction.h index 150f168a22..f0901fb1b4 100644 --- a/libgnucash/engine/mocks/gmock-Transaction.h +++ b/libgnucash/engine/mocks/gmock-Transaction.h @@ -70,4 +70,24 @@ protected: ~MockTransaction() {} }; + +// type conversion functions +static inline MockTransaction* +gnc_mocktransaction (Transaction *trans) +{ + if (GNC_IS_MOCKTRANSACTION(trans)) + return static_cast(trans); + ADD_FAILURE() << "Expected 'trans' to be of type 'MockTransaction'"; + return nullptr; +} + +static inline const MockTransaction* +gnc_mocktransaction (const Transaction *trans) +{ + if (GNC_IS_MOCKTRANSACTION(trans)) + return static_cast(trans); + ADD_FAILURE() << "Expected 'trans' to be of type 'MockTransaction'"; + return nullptr; +} + #endif diff --git a/libgnucash/engine/mocks/gmock-qofbook.cpp b/libgnucash/engine/mocks/gmock-qofbook.cpp index 72b755e693..17a7f0061f 100644 --- a/libgnucash/engine/mocks/gmock-qofbook.cpp +++ b/libgnucash/engine/mocks/gmock-qofbook.cpp @@ -23,7 +23,8 @@ qof_mockbook_class_init(QofMockBookClass *klass) gboolean qof_book_use_split_action_for_num_field (const QofBook *book) { - g_return_val_if_fail(QOF_IS_MOCKBOOK(book), FALSE); - return ((QofMockBook*)book)->use_split_action_for_num_field(); + SCOPED_TRACE(""); + const QofMockBook* mockbook = qof_mockbook(book); + return mockbook ? mockbook->use_split_action_for_num_field() : FALSE; } diff --git a/libgnucash/engine/mocks/gmock-qofbook.h b/libgnucash/engine/mocks/gmock-qofbook.h index 8be7cb331e..035eb1a9c1 100644 --- a/libgnucash/engine/mocks/gmock-qofbook.h +++ b/libgnucash/engine/mocks/gmock-qofbook.h @@ -59,4 +59,25 @@ protected: ~QofMockBook() {} }; + +// type conversion functions +static inline QofMockBook* +qof_mockbook (QofBook *book) +{ + if (QOF_IS_MOCKBOOK(book)) + return static_cast(book); + ADD_FAILURE() << "Expected 'book' to be of type 'QofMockBook'"; + return nullptr; +} + +static inline const QofMockBook* +qof_mockbook (const QofBook *book) +{ + if (QOF_IS_MOCKBOOK(book)) + return static_cast(book); + ADD_FAILURE() << "Expected 'book' to be of type 'QofMockBook'"; + return nullptr; +} + + #endif