Redundant namespace declaration in signal in order to use QSignalSpy

457 views Asked by At

I'm trying to utilize QTest in combination with Catch and QSignalSpy to test my applications. I have to say, that I'm using Qt 5.10.0, which might be important.

Recently I stumbled across a strange behavior, that I couldn't really explain.

main.cpp

#include "testing/catch2.hpp"
#include <QtTest/qtest.h>
#include "TestCases.h"

TEST_CASE("MyTest") {
    TestCases tc;
    QTest::qExec(&tc);
}

TestCases.h

#pragma once
#include <QObject>
#include <QDebug>
#include <QSignalSpy>
#include "testing/catch2.hpp"
#include "TestObject.h"

class TestCases : public QObject {
    Q_OBJECT

    private slots:
    void firstTest() {
        nameSpace::TestObject o;
        QSignalSpy s(&o, &nameSpace::TestObject::valueChanged);
        o.setValue();
        REQUIRE(s.size() == 1);
        auto var = s.takeFirst();
        CHECK(var.size() == 0);
    }
    void secondTest() {
        nameSpace::TestObject o;
        QSignalSpy s(&o, &nameSpace::TestObject::objectChanged);
        o.changeObject();
        REQUIRE(s.size() == 1);
        auto var = s.takeFirst();
        CHECK(var.size() == 1);
    }
}; 

TestObject.h

#pragma once
#include <QObject>

namespace nameSpace
{

    struct MyObject
    {

    };

    class TestObject : public QObject {
        Q_OBJECT

    public:
        TestObject() {
        }
        void setValue() {
            emit valueChanged();
        }

        void changeObject()
        {
            MyObject obj;
            emit objectChanged(obj);
        }

    signals:
        void valueChanged();
        // Why I need to add a namespace here?
        void objectChanged(const nameSpace::MyObject&); 
    };
}

Q_DECLARE_METATYPE(nameSpace::MyObject);

If I'll run the posted code I'll obtain the following output, which is fine for me.

********* Start testing of TestCases *********
Config: Using QtTest library 5.10.0, Qt 5.10.0 (i386-little_endian-ilp32 shared (dynamic) release build; by MSVC 2015)
PASS   : TestCases::initTestCase()
PASS   : TestCases::firstTest()
PASS   : TestCases::secondTest()
PASS   : TestCases::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 9ms
********* Finished testing of TestCases *********
===============================================================================

But if I change the line void objectChanged(const nameSpace::MyObject&); to void objectChanged(const MyObject&); I obtain the following erroneous output:

********* Start testing of TestCases *********
Config: Using QtTest library 5.10.0, Qt 5.10.0 (i386-little_endian-ilp32 shared (dynamic) release build; by MSVC 2015)
PASS   : TestCases::initTestCase()
PASS   : TestCases::firstTest()
QWARN  : TestCases::secondTest() QSignalSpy: Unable to handle parameter '' of type 'MyObject' of method 'objectChanged', use qRegisterMetaType to register it.
PASS   : TestCases::secondTest()
PASS   : TestCases::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 7ms
********* Finished testing of TestCases *********
===============================================================================

So it is necessary to include the seemingly redundant namespace in the signal definition. Searching and finding this error took me half a day and now I also wanted to understand what might be the reason for this behavior. It is intentional or a Qt Bug? And if it is intentional, where is this in the Qt documentation.

It is somehow similar to why one has to write

Q_DECLARE_META_TYPE(nameSpace::MyObject)

instead of

namespace nameSpace {
     Q_DECLARE_META_TYPE(MyObject)
}

See the docs: https://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE.

0

There are 0 answers