diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 177947b..5dce4a1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,6 +20,7 @@ add_executable(${PROJECT_NAME} Resources.qrc main.qml testQObject.qml testQAbstractItemModel.qml + testQDeclarative.qml ) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) target_link_libraries(${PROJECT_NAME} DOtherSideStatic Qt5::Quick Qt5::Widgets Qt5::Test Qt5::Core) diff --git a/test/MockQObject.cpp b/test/MockQObject.cpp index 63cb00f..2898591 100644 --- a/test/MockQObject.cpp +++ b/test/MockQObject.cpp @@ -61,6 +61,24 @@ namespace { } } + +MockQObject::MockQObject() + : m_vptr(dos_qobject_create(this, metaObject(), &onSlotCalled), &dos_qobject_delete) +{} + +MockQObject::~MockQObject() = default; + +DosQMetaObject *MockQObject::staticMetaObject() +{ + static VoidPointer result = initializeMetaObject(); + return result.get(); +} + +::DosQMetaObject *MockQObject::metaObject() +{ + return staticMetaObject(); +} + std::string MockQObject::objectName() const { CharPointer result (dos_qobject_objectName(m_vptr.get()), &dos_chararray_delete); @@ -72,21 +90,16 @@ void MockQObject::setObjectName(const string &objectName) dos_qobject_setObjectName(m_vptr.get(), objectName.c_str()); } -MockQObject::MockQObject() - : m_vptr(dos_qobject_create(this, metaObject(), &onSlotCalled), &dos_qobject_delete) -{} - -::DosQMetaObject *MockQObject::metaObject() -{ - static VoidPointer result = initializeMetaObject(); - return result.get(); -} - ::DosQObject *MockQObject::data() { return m_vptr.get(); } +void MockQObject::swapData(VoidPointer &data) +{ + std::swap(m_vptr, data); +} + std::string MockQObject::name() const { return m_name; diff --git a/test/MockQObject.h b/test/MockQObject.h index 549232c..de5bd68 100644 --- a/test/MockQObject.h +++ b/test/MockQObject.h @@ -6,9 +6,13 @@ class MockQObject { public: MockQObject(); + virtual ~MockQObject(); + + static ::DosQMetaObject *staticMetaObject(); + virtual ::DosQMetaObject *metaObject(); - ::DosQMetaObject *metaObject(); ::DosQObject *data(); + void swapData(VoidPointer &data); std::string objectName() const; void setObjectName(const std::string& objectName); diff --git a/test/Resources.qrc b/test/Resources.qrc index f448819..7b7e97b 100644 --- a/test/Resources.qrc +++ b/test/Resources.qrc @@ -3,5 +3,6 @@ main.qml testQAbstractItemModel.qml testQObject.qml + testQDeclarative.qml diff --git a/test/testQDeclarative.qml b/test/testQDeclarative.qml new file mode 100644 index 0000000..1d50002 --- /dev/null +++ b/test/testQDeclarative.qml @@ -0,0 +1,36 @@ +import QtQuick 2.3 +import MockModule 1.0 + +Item { + id: testCase + objectName: "testCase" + + Component { + id: mockQObjectComponent + + MockQObject {} + } + + function testQmlRegisterType() { + var testObject = mockQObjectComponent.createObject(testCase, {"name":"foo"}) + + if (!testObject) + return false + + if (testObject.name !== "foo") { + testObject.destroy() + return false + } + + var nameChangedEmitted = false + testObject.nameChanged.connect(function(name){nameChangedEmitted = name === "bar"}); + testObject.name = "bar" + if (!nameChangedEmitted || !testObject.name !== "bar") { + testObject.destroy() + return false + } + + testObject.destroy() + return true + } +} diff --git a/test/test_dotherside.cpp b/test/test_dotherside.cpp index e9a70e1..9b27abe 100644 --- a/test/test_dotherside.cpp +++ b/test/test_dotherside.cpp @@ -334,7 +334,6 @@ private slots: QVERIFY(result.toBool()); } - void testRowCount() { QObject* testCase = engine->rootObjects().first(); QVERIFY(testCase); @@ -378,6 +377,55 @@ private: unique_ptr engine; }; +/* + * Test QQmlContext + */ +class TestQDeclarativeIntegration : public QObject +{ + Q_OBJECT + +private slots: + void testQmlRegisterType() { + ::QmlRegisterType registerType; + registerType.major = 1; + registerType.minor = 0; + registerType.uri = "MockModule"; + registerType.qml = "MockQObject"; + registerType.staticMetaObject = MockQObject::staticMetaObject(); + registerType.createDObject = &mockQObjectCreator; + registerType.deleteDObject = &mockQObjectDeleter; + dos_qdeclarative_qmlregistertype(®isterType); + + auto engine = std::make_unique(); + engine->load(QUrl("qrc:///testQDeclarative.qml")); + + QObject* testCase = engine->rootObjects().first(); + QVERIFY(testCase); + QVariant result; + QVERIFY(QMetaObject::invokeMethod(testCase, "testQmlRegisterType", Q_RETURN_ARG(QVariant, result))); + QVERIFY(result.type() == QVariant::Bool); + QVERIFY(result.toBool()); + } + +private: + static void mockQObjectCreator(int typeId, void *wrapper, void **mockQObjectPtr, void **dosQObject) + { + VoidPointer data(wrapper, &emptyVoidDeleter); + auto mockQObject = new MockQObject(); + mockQObject->swapData(data); + *dosQObject = data.release(); + *mockQObjectPtr = mockQObject; + } + + static void mockQObjectDeleter(int typeId, void *mockQObject) + { + auto temp = static_cast(mockQObject); + delete temp; + } + + static void emptyVoidDeleter(void*) {} +}; + int main(int argc, char *argv[]) { using namespace DOS; @@ -389,6 +437,7 @@ int main(int argc, char *argv[]) success &= ExecuteGuiTest(argc, argv); success &= ExecuteGuiTest(argc, argv); success &= ExecuteGuiTest(argc, argv); + success &= ExecuteGuiTest(argc, argv); return success ? 0 : 1; }