Results 1 to 7 of 7

Thread: Trouble using custom datatype (QMetaType) in QtTest

  1. #1
    Join Date
    Mar 2009
    Posts
    14
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question Trouble using custom datatype (QMetaType) in QtTest

    I have a compilation error related to the QMetaType and QtTest. I feel like my issue is rooted in some misunderstanding I have about a Qt concept. Skip below for the complication error, or start here for the full story.

    I am trying to write a unit test for a class that I have written, CustomVector, which is a QVector over a QHash of QString to QVariant. I attach this to the metatyping system with the Q_DECLARE_METATYPE() macro after the class definiton. In the same header file, I have a TestCustomVector class which is intended to test the CustomVector. This class is encased in #ifdefs to only compile in debug configuration.

    customvector.h
    Qt Code:
    1. // ... necessary includes here ...
    2.  
    3. class CustomVector : public QVector< QHash<QString, QVariant> > { ... };
    4. Q_DECLARE_METATYPE(CustomVector)
    5.  
    6. #ifdef QT_DEBUG
    7.  
    8. #include <QtTest>
    9.  
    10. class TestCustomVector : public QObject
    11. {
    12. Q_OBJECT
    13.  
    14. private slots:
    15. void isNull_data();
    16. void isNull();
    17. };
    18.  
    19. #endif // QT_DEBUG
    To copy to clipboard, switch view to plain text mode 

    The CustomVector and TestCustomVector classes are also implemented in the same cpp file. TestCustomVector has the one isNull() test which is implemented using the data-driven testing methodology. Again, the unit testing code is only compiled in on a debug build.

    customvector.cpp
    Qt Code:
    1. // ... CustomVector functions including an isNull() function ...
    2.  
    3. #ifdef QT_DEBUG
    4.  
    5. void TestCustomVector::isNull_data()
    6. {
    7. QTest::addColumn<CustomVector>("CustomVector");
    8. QTest::addColumn<bool>("Result");
    9.  
    10. CustomVector cv_default(); // will be null
    11. CustomVector cv_notNull(/* ... parameters giving a not null state... */);
    12. CustomVector cv_null(/* ... parameters giving a null state... */)
    13.  
    14. QTest::newRow("Default Constructor")
    15. << &cv_default << true;
    16. QTest::newRow("Basic Constructor, Fully Specified")
    17. << &cv_notNull << false;
    18. QTest::newRow("Basic Constructor, Partially Specified")
    19. << &cv_nameNull << true;
    20. }
    21.  
    22. void TestCustomVector::isNull()
    23. {
    24. QFETCH(CustomVector, customVector);
    25. QFETCH(bool, result);
    26.  
    27. QCOMPARE(customVector, result);
    28. }
    29.  
    30. #endif // QT_DEBUG
    To copy to clipboard, switch view to plain text mode 

    These tests are defined in the files they refer to for ease of coding. I also intend to call QTest::qExec() in my main.cpp as a program command-line option of the main program.

    When compiling, I get the following errors:

    /opt/qt-4.5.2/include/QtCore/qmetatype.h: In static member function ‘static int QMetaTypeId2<T>::qt_metatype_id() [with T = CustomVector (*)()]’:
    /opt/qt-4.5.2/include/QtCore/qmetatype.h:199: instantiated from ‘int qMetaTypeId(T*) [with T = CustomVector (*)()]’
    /opt/qt-4.5.2/include/QtTest/qtestdata.h:82: instantiated from ‘QTestData& operator<<(QTestData&, const T&) [with T = CustomVector (*)()]’
    customvector.cpp:15: instantiated from here
    /opt/qt-4.5.2/include/QtCore/qmetatype.h:189: error: ‘qt_metatype_id’ is not a member of ‘QMetaTypeId<CustomVector (*)()>’
    /opt/qt-4.5.2/include/QtCore/qmetatype.h: In static member function ‘static int QMetaTypeId2<T>::qt_metatype_id() [with T = CustomVector*]’:
    /opt/qt-4.5.2/include/QtCore/qmetatype.h:199: instantiated from ‘int qMetaTypeId(T*) [with T = CustomVector*]’
    /opt/qt-4.5.2/include/QtTest/qtestdata.h:82: instantiated from ‘QTestData& operator<<(QTestData&, const T&) [with T = CustomVector*]’
    customvector.cpp:17: instantiated from here
    /opt/qt-4.5.2/include/QtCore/qmetatype.h:189: error: ‘qt_metatype_id’ is not a member of ‘QMetaTypeId<CustomVector*>’


    Based on other threads I have searched, I have tried:
    • Separating the code into individual files
    • Using Q_DECLARE_METATYPE(CustomVector *) and Q_DECLARE_METATYPE(CustomVector)
    • Various permutations of streaming objects, pointers, and references into QTest::newRow()

    Like I said before, I feel like whatever I am missing is a high-level Qt concept. Perhaps someone can shed some holy Qt wisdom on me?

  2. #2
    Join Date
    Mar 2009
    Posts
    14
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Unhappy Re: Trouble using custom datatype (QMetaType) in QtTest

    I've made some changes and I now get a slightly different result. I've changed my earlier code around such that the metatype is a pointer to a CustomVector and commented out the default constructor as below.

    customvector.h
    Qt Code:
    1. // ... necessary includes here ...
    2.  
    3. class CustomVector : public QVector< QHash<QString, QVariant> > { ... };
    4. Q_DECLARE_METATYPE(CustomVector *) // <-- added pointer symbol
    5.  
    6. #ifdef QT_DEBUG
    7.  
    8. #include <QtTest>
    9.  
    10. class TestCustomVector : public QObject
    11. {
    12. Q_OBJECT
    13.  
    14. private slots:
    15. void isNull_data();
    16. void isNull();
    17. };
    18.  
    19. #endif // QT_DEBUG
    To copy to clipboard, switch view to plain text mode 

    customvector.cpp
    Qt Code:
    1. // ... CustomVector functions including an isNull() function ...
    2.  
    3. #ifdef QT_DEBUG
    4.  
    5. void TestCustomVector::isNull_data()
    6. {
    7. QTest::addColumn<CustomVector *>("CustomVector"); // <-- added pointer symbol
    8. QTest::addColumn<bool>("Result");
    9.  
    10. // CustomVector cv_default(); // <-- commented out
    11. CustomVector cv_notNull(/* ... parameters giving a not null state... */);
    12. CustomVector cv_null(/* ... parameters giving a null state... */)
    13.  
    14. // QTest::newRow("Default Constructor") // <-- commented out
    15. // << &cv_default << true;
    16. QTest::newRow("Basic Constructor, Fully Specified")
    17. << &cv_notNull << false;
    18. QTest::newRow("Basic Constructor, Partially Specified")
    19. << &cv_null << true; // <-- corrected this line from earlier post
    20. }
    21.  
    22. void TestCustomVector::isNull()
    23. {
    24. QFETCH(CustomVector *, customVector); // <-- added pointer symbol
    25. QFETCH(bool, result);
    26.  
    27. QCOMPARE(customVector, result);
    28. }
    29.  
    30. #endif // QT_DEBUG
    To copy to clipboard, switch view to plain text mode 

    The entire program compiles and I have the following linker errors. Note that the CustomVector is part of a library with the same name.


    libcustomvector.a(customvector.o): In function `TestCustomVector::isNull()':
    customvector/customvector.cpp:108: undefined reference to `bool QTest::qCompare<CustomVector*, bool>(CustomVector* const&, bool const&, char const*, char const*, char const*, int)'
    collect2: ld returned 1 exit status


    I don't think this is progress because I don't think it's appropriate for an implicitly-shared class like CustomVector (extending QVector) to be metatype'd as a pointer.

    What is going on here?
    Last edited by perden; 1st September 2009 at 20:17. Reason: corrected example

  3. #3
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Trouble using custom datatype (QMetaType) in QtTest

    Qt Code:
    1. QCOMPARE(customVector, result);
    To copy to clipboard, switch view to plain text mode 
    this code compares a CustomVector* to a bool (using QTest::qCompare; as qCompare is declared as a template function, this does indeed compile). It does not link, however, as qCompare<> is not specialized for those types.
    (And probably you did not want to compare the pointer to a bool, did you? Doesn't make too much sense.)

  4. The following user says thank you to caduel for this useful post:

    perden (1st September 2009)

  5. #4
    Join Date
    Mar 2009
    Posts
    14
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Lightbulb Re: Trouble using custom datatype (QMetaType) in QtTest

    Ok! Progress!

    Thanks caduel, your comment was what I needed to get quite a bit further. I've once again, removed the pointer symbols from around the files, renamed the columns to be identical to the variables they reference, and added the .isNull() to the QTest::QCOMPARE().

    customvector.h
    Qt Code:
    1. // ... necessary includes here ...
    2.  
    3. class CustomVector : public QVector< QHash<QString, QVariant> > { ... };
    4. Q_DECLARE_METATYPE(CustomVector) // <-- removed pointer symbol
    5.  
    6. #ifdef QT_DEBUG
    7.  
    8. #include <QtTest>
    9.  
    10. class TestCustomVector : public QObject
    11. {
    12. Q_OBJECT
    13.  
    14. private slots:
    15. void isNull_data();
    16. void isNull();
    17. };
    18.  
    19. #endif // QT_DEBUG
    To copy to clipboard, switch view to plain text mode 


    customvector.cpp
    Qt Code:
    1. // ... CustomVector functions including an isNull() function ...
    2.  
    3. #ifdef QT_DEBUG
    4.  
    5. void TestCustomVector::isNull_data()
    6. {
    7. QTest::addColumn<CustomVector>("customVector"); // <-- removed pointer symbol
    8. QTest::addColumn<bool>("result");
    9. // changed both above strings to match the variable names in the QFETCH() in TestCustomVector::isNull()
    10.  
    11. // CustomVector cv_default(); // <-- still commented out
    12. CustomVector cv_notNull(/* ... parameters giving a not null state... */);
    13. CustomVector cv_null(/* ... parameters giving a null state... */)
    14.  
    15. // QTest::newRow("Default Constructor") // <-- still commented out
    16. // << cv_default << true;
    17. QTest::newRow("Basic Constructor, Fully Specified")
    18. << cv_notNull << false;
    19. QTest::newRow("Basic Constructor, Partially Specified")
    20. << cv_null << true;
    21. // removed & operators in above cv_* variables
    22. }
    23.  
    24. void TestCustomVector::isNull()
    25. {
    26. QFETCH(CustomVector, customVector); // <-- removed pointer symbol
    27. QFETCH(bool, result);
    28.  
    29. QCOMPARE(customVector.isNull(), result); // <-- added .isNull()
    30. }
    31.  
    32. #endif // QT_DEBUG
    To copy to clipboard, switch view to plain text mode 

    I guess was assuming that QTest::QCOMPARE() implicitly called the function you wanted to test based on the name of the function itself, effectively tacking-on the ".isNull()" to my CustomVector call. This is wrong.

    I've removed the pointers to take advantage of those implicitly-shared classes.

    I'm really close now. Everything builds and links fine, so long as the default constructor and related test case remain commented in TestCustomVector::isNull_data().

    Any other remarks as to why this might not be working?

  6. #5
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Trouble using custom datatype (QMetaType) in QtTest

    please elaborate on what "not working" means here

  7. #6
    Join Date
    Mar 2009
    Posts
    14
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Trouble using custom datatype (QMetaType) in QtTest

    All fixed!

    I was getting a compilation error for the default constructor on line 11 of the most recent testcustomvector.cpp example. This was due to the unnecessary parenthesis after the name of the variable. That's my early java background sneaking in again!

    So in the end, it turns out that my problems were caused by a combination of lack of QtTest knowledge and a C++ misunderstanding from my early java background.

    Thanks again for the help.

  8. #7
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Trouble using custom datatype (QMetaType) in QtTest

    ah, ok...
    Qt Code:
    1. CustomVector cv_default();
    To copy to clipboard, switch view to plain text mode 
    in C(++) declares a function named cv_default, taking no arguments and returning a CustomVector.

    Line 11 should compile. However, your use of cv_default later on would give trouble.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.