#139 Ready to merge changes related to core protobuf types in qml to master

Unito
semlanik ha unito 3 commit da semlanik/dev_semlanik a semlanik/master 5 anni fa

+ 24 - 3
cmake/QtProtobufCommon.cmake

@@ -43,7 +43,7 @@ endfunction(protobuf_generate_all)
 function(add_test_target)
     set(options)
     set(oneValueArgs TARGET)
-    set(multiValueArgs SOURCES GENERATED_HEADERS)
+    set(multiValueArgs SOURCES GENERATED_HEADERS PROTO_FILES)
     cmake_parse_arguments(add_test_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
     ## test sources build
@@ -54,7 +54,11 @@ function(add_test_target)
 
     set(GENERATED_SOURCES_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
 
-    file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/proto/*.proto)
+    if(DEFINED add_test_target_PROTO_FILES)
+        file(GLOB PROTO_FILES ABSOLUTE ${add_test_target_PROTO_FILES})
+    else()
+        file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/proto/*.proto)
+    endif()
 
     generate_qtprotobuf(TARGET ${add_test_target_TARGET}
         OUT_DIR ${GENERATED_SOURCES_DIR}
@@ -68,5 +72,22 @@ function(add_test_target)
     endif()
     add_dependencies(${add_test_target_TARGET} ${QtProtobuf_GENERATED})
     target_link_libraries(${add_test_target_TARGET} gtest_main gtest ${QtProtobuf_GENERATED} ${QTPROTOBUF_COMMON_NAMESPACE}::QtProtobuf ${QTPROTOBUF_COMMON_NAMESPACE}::QtGrpc Qt5::Core Qt5::Qml Qt5::Network)
-    target_include_directories(${add_test_target_TARGET} PRIVATE ${GENERATED_SOURCES_DIR})
 endfunction(add_test_target)
+
+function(add_target_qml)
+    set(options)
+    set(oneValueArgs TARGET QMLDIR_FILE)
+    set(multiValueArgs QML_FILES)
+    cmake_parse_arguments(add_target_qml "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    add_custom_target(${add_target_qml_TARGET}_qml DEPENDS ${add_qml_QML_FILES} ${add_target_qml_QMLDIR_FILE})
+    foreach(QML_FILE IN LISTS add_target_qml_QML_FILES)
+        add_custom_command(TARGET ${add_target_qml_TARGET}_qml COMMAND ${CMAKE_COMMAND} -E copy ${QML_FILE}
+            ${CMAKE_CURRENT_BINARY_DIR})
+    endforeach()
+    if(DEFINED ${add_target_qml_QMLDIR_FILE})
+        add_custom_command(TARGET ${add_target_qml_TARGET}_qml COMMAND ${CMAKE_COMMAND} -E copy ${add_qml_QMLDIR_FILE}
+            ${CMAKE_CURRENT_BINARY_DIR})
+    endif()
+    add_dependencies(${add_target_qml_TARGET} ${add_target_qml_TARGET}_qml)
+endfunction()

+ 0 - 1
examples/addressbook/CMakeLists.txt

@@ -33,7 +33,6 @@ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../addressbookserver/cert.pem DESTINATION
 
 add_executable(${TARGET} ${SOURCES} resources.qrc)
 add_dependencies(${TARGET} ${QtProtobuf_GENERATED} examples_common)
-target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated)
 target_link_libraries(${TARGET} examples_common QtProtobufProject::QtProtobuf QtProtobufProject::QtGrpc ${QtProtobuf_GENERATED} Qt5::Quick Qt5::Qml)
 
 set(CLIENT_EXEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} PARENT_SCOPE)

+ 0 - 1
examples/simplechat/CMakeLists.txt

@@ -30,7 +30,6 @@ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../simplechatserver/cert.pem DESTINATION $
 
 add_executable(${TARGET} ${SOURCES} resources.qrc)
 add_dependencies(${TARGET} ${QtProtobuf_GENERATED} examples_common)
-target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated)
 target_link_libraries(${TARGET} examples_common QtProtobufProject::QtProtobuf QtProtobufProject::QtGrpc ${QtProtobuf_GENERATED} Qt5::Quick Qt5::Qml)
 
 set(CLIENT_EXEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} PARENT_SCOPE)

+ 3 - 0
src/protobuf/CMakeLists.txt

@@ -67,3 +67,6 @@ install(FILES "${CMAKE_BINARY_DIR}/QtProtobufGen.cmake" DESTINATION "${TARGET_CM
 
 configure_file("${CMAKE_SOURCE_DIR}/cmake/ProtobufLookup.cmake" "${CMAKE_BINARY_DIR}/ProtobufLookup.cmake" COPYONLY)
 install(FILES "${CMAKE_BINARY_DIR}/ProtobufLookup.cmake" DESTINATION "${TARGET_CMAKE_DIR}")
+
+# TODO: keep quick plugin for future development, but it's useless for now
+add_subdirectory("quick")

+ 1 - 1
src/protobuf/QtProtobufGen.cmake.in

@@ -55,7 +55,7 @@ function(generate_qtprotobuf)
     set_source_files_properties(${QTPROTOBUF_GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
     add_library(${QtProtobuf_GENERATED} ${QTPROTOBUF_GENERATED_SOURCES} ${MOC_SOURCES})
     add_dependencies(${QtProtobuf_GENERATED} ${GEN_TARGET})
-    target_include_directories(${QtProtobuf_GENERATED} PRIVATE ${Qt5Core_INCLUDE_DIRS}
+    target_include_directories(${QtProtobuf_GENERATED} PUBLIC ${OUT_DIR} PRIVATE ${Qt5Core_INCLUDE_DIRS}
         $<TARGET_PROPERTY:@QTPROTOBUF_COMMON_NAMESPACE@::QtProtobuf,INTERFACE_INCLUDE_DIRECTORIES>
         $<TARGET_PROPERTY:@QTPROTOBUF_COMMON_NAMESPACE@::QtGrpc,INTERFACE_INCLUDE_DIRECTORIES> ${OUT_DIR})
 endfunction()

+ 53 - 22
src/protobuf/qtprotobuf.cpp

@@ -27,12 +27,59 @@
 #include "qprotobufobject.h"
 #include "registrationhelper.h"
 
+#include <type_traits>
+
 #define registerProtobufType(X) qRegisterMetaType<X>(# X);\
                                 qRegisterMetaType<X>("qtprotobuf::"# X);
 
 namespace qtprotobuf {
 
 namespace  {
+
+template<typename T, typename std::enable_if_t<sizeof(T) == sizeof(int32_t)
+                                      && std::is_signed<decltype(T::_t)>::value, int> = 0>
+void registerBasicConverters() {
+    QMetaType::registerConverter<int32_t, T>(T::fromType);
+    QMetaType::registerConverter<T, int32_t>(T::toType);
+    QMetaType::registerConverter<double, T>(T::fromType);
+    QMetaType::registerConverter<T, double>(T::toType);
+    QMetaType::registerConverter<T, QString>(T::toString);
+}
+
+template<typename T, typename std::enable_if_t<sizeof(T) == sizeof(int64_t)
+                                      && std::is_signed<decltype(T::_t)>::value, int> = 0>
+void registerBasicConverters() {
+    QMetaType::registerConverter<int64_t, T>(T::fromType);
+    QMetaType::registerConverter<T, int64_t>(T::toType);
+    QMetaType::registerConverter<qint64, T>(T::fromType);
+    QMetaType::registerConverter<T, qint64>(T::toType);
+    QMetaType::registerConverter<int32_t, T>(T::fromType);
+    QMetaType::registerConverter<T, QString>(T::toString);
+}
+
+template<typename T, typename std::enable_if_t<sizeof(T) == sizeof(int32_t)
+                                      && !std::is_signed<decltype(T::_t)>::value, int> = 0>
+void registerBasicConverters() {
+    QMetaType::registerConverter<uint32_t, T>(T::fromType);
+    QMetaType::registerConverter<T, uint32_t>(T::toType);
+    QMetaType::registerConverter<int32_t, T>(T::fromType);
+    QMetaType::registerConverter<T, int32_t>(T::toType);
+    QMetaType::registerConverter<double, T>(T::fromType);
+    QMetaType::registerConverter<T, double>(T::toType);
+    QMetaType::registerConverter<T, QString>(T::toString);
+}
+
+template<typename T, typename std::enable_if_t<sizeof(T) == sizeof(int64_t)
+                                      && !std::is_signed<decltype(T::_t)>::value, int> = 0>
+void registerBasicConverters() {
+    QMetaType::registerConverter<uint64_t, T>(T::fromType);
+    QMetaType::registerConverter<T, uint64_t>(T::toType);
+    QMetaType::registerConverter<quint64, T>(T::fromType);
+    QMetaType::registerConverter<T, quint64>(T::toType);
+    QMetaType::registerConverter<uint32_t, T>(T::fromType);
+    QMetaType::registerConverter<T, QString>(T::toString);
+}
+
 void registerTypes() {
     registerProtobufType(int32);
     registerProtobufType(int64);
@@ -59,29 +106,13 @@ void registerTypes() {
     registerProtobufType(DoubleList);
     registerProtobufType(FloatList);
 
-    QMetaType::registerConverter<int32_t, int32>(int32::fromType);
-    QMetaType::registerConverter<int32, int32_t>(int32::toType);
-
-    QMetaType::registerConverter<int64_t, int64>(int64::fromType);
-    QMetaType::registerConverter<int64, int64_t>(int64::toType);
-    QMetaType::registerConverter<qint64, int64>(int64::fromType);
-    QMetaType::registerConverter<int64, qint64>(int64::toType);
-
-    QMetaType::registerConverter<uint32_t, fixed32>(fixed32::fromType);
-    QMetaType::registerConverter<fixed32, uint32_t>(fixed32::toType);
-
-    QMetaType::registerConverter<uint64_t, fixed64>(fixed64::fromType);
-    QMetaType::registerConverter<fixed64, uint64_t>(fixed64::toType);
-    QMetaType::registerConverter<quint64, fixed64>(fixed64::fromType);
-    QMetaType::registerConverter<fixed64, quint64>(fixed64::toType);
-
-    QMetaType::registerConverter<int32_t, sfixed32>(sfixed32::fromType);
-    QMetaType::registerConverter<sfixed32, int32_t>(sfixed32::toType);
+    registerBasicConverters<int32>();
+    registerBasicConverters<int64>();
+    registerBasicConverters<sfixed32>();
+    registerBasicConverters<sfixed64>();
+    registerBasicConverters<fixed32>();
+    registerBasicConverters<fixed64>();
 
-    QMetaType::registerConverter<int64_t, sfixed64>(sfixed64::fromType);
-    QMetaType::registerConverter<sfixed64, int64_t>(sfixed64::toType);
-    QMetaType::registerConverter<qint64, sfixed64>(sfixed64::fromType);
-    QMetaType::registerConverter<sfixed64, qint64>(sfixed64::toType);
     ProtobufObjectPrivate::registerSerializers();
 }
 }

+ 4 - 2
src/protobuf/qtprotobuftypes.h

@@ -49,8 +49,10 @@ struct transparent {
     operator T() const { return _t; }
     transparent &operator =(const T &t) { _t = t; return *this; }
 
-    static T toType( transparent t ) { return t._t; }
-    static transparent fromType( T _t ) { return transparent(_t); }
+    static T toType(transparent t) { return t._t; }
+    static transparent fromType(T _t) { return transparent(_t); }
+
+    static QString toString(transparent t) { return QString::number(t._t); }
 };
 
 using int32 = transparent<int32_t>;

+ 38 - 0
src/protobuf/quick/CMakeLists.txt

@@ -0,0 +1,38 @@
+# TODO: keep quick plugin for future features, but it's useless for now
+set(TARGET protobufquickplugin)
+
+set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET})
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+find_package(Qt5 COMPONENTS Core Qml REQUIRED)
+
+execute_process(
+    COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_QML
+    OUTPUT_VARIABLE TARGET_IMPORTS_DIR
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+file(GLOB SOURCES
+    qtprotobufquickplugin.cpp)
+
+file(GLOB HEADERS
+    qtprotobufquickplugin.h
+    qtprotobufquick_global.h)
+
+add_library(${TARGET} SHARED ${SOURCES})
+target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QTPROTOBUF_COMMON_NAMESPACE}::QtProtobuf)
+set_target_properties(${TARGET} PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/QtProtobuf")
+target_compile_definitions(${TARGET} PRIVATE QTPROTOBUFQUICK_LIB)
+target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../)
+install(TARGETS ${TARGET}
+    PUBLIC_HEADER DESTINATION ${TARGET_INCLUDE_DIR}
+    LIBRARY DESTINATION ${TARGET_IMPORTS_DIR})
+
+add_custom_command(TARGET ${TARGET}
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir $<TARGET_FILE_DIR:${TARGET}>/qmldir
+    COMMENT "Copying qmldir to binary directory")
+
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/qmldir DESTINATION "${TARGET_IMPORTS_DIR}/QtProtobuf")

+ 4 - 0
src/protobuf/quick/qmldir

@@ -0,0 +1,4 @@
+module QtProtobuf
+plugin protobufquickplugin
+classname QtProtobufQuickPlugin
+

+ 34 - 0
src/protobuf/quick/qtprotobufquick_global.h

@@ -0,0 +1,34 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <QtCore/QtGlobal>
+
+#ifdef QTPROTOBUFQUICK_LIB
+    #define QTPROTOBUFQUICKSHARED_EXPORT Q_DECL_EXPORT
+#else
+    #define QTPROTOBUFQUICKSHARED_EXPORT Q_DECL_IMPORT
+#endif

+ 32 - 0
src/protobuf/quick/qtprotobufquickplugin.cpp

@@ -0,0 +1,32 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "qtprotobufquickplugin.h"
+#include <QDebug>
+
+void QtProtobufQuickPlugin::registerTypes(const char *uri)
+{
+    Q_ASSERT(uri == QLatin1String("QtProtobuf"));
+}

+ 39 - 0
src/protobuf/quick/qtprotobufquickplugin.h

@@ -0,0 +1,39 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <QQmlExtensionPlugin>
+#include "qtprotobufquick_global.h"
+
+class QTPROTOBUFQUICKSHARED_EXPORT QtProtobufQuickPlugin : public QQmlExtensionPlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+
+public:
+    ~QtProtobufQuickPlugin() = default;
+    void registerTypes(const char *) override;
+};

+ 1 - 0
tests/CMakeLists.txt

@@ -1,2 +1,3 @@
 add_subdirectory("test_protobuf")
 add_subdirectory("test_grpc")
+add_subdirectory("test_qml")

+ 16 - 0
tests/test_qml/CMakeLists.txt

@@ -0,0 +1,16 @@
+set(TARGET qtprotobuf_qml_test)
+
+find_package(Qt5 COMPONENTS Core Quick Network Test QuickTest REQUIRED)
+find_package(QtProtobufProject COMPONENTS QtProtobuf REQUIRED)
+
+include(${CMAKE_SOURCE_DIR}/cmake/QtProtobufCommon.cmake)
+
+file(GLOB SOURCES main.cpp)
+file(GLOB QML_FILES qml/tst_simple.qml)
+
+add_executable(${TARGET} ${SOURCES} ${QML_FILES})
+target_link_libraries(${TARGET} Qt5::Core Qt5::Qml Qt5::Network Qt5::Quick Qt5::Test Qt5::QuickTest QtProtobufProject::QtProtobuf qtprotobuf_test_qtprotobuf_gen)
+
+add_target_qml(TARGET ${TARGET} QML_FILES ${QML_FILES})
+
+add_test(NAME ${TARGET} COMMAND ${TARGET})

+ 63 - 0
tests/test_qml/main.cpp

@@ -0,0 +1,63 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <QtQuickTest/quicktest.h>
+
+#include "simpleboolmessage.h"
+#include "simplebytesmessage.h"
+#include "simpledoublemessage.h"
+#include "simplefloatmessage.h"
+#include "simplefixedint32message.h"
+#include "simplefixedint64message.h"
+#include "simplesfixedint32message.h"
+#include "simplesfixedint64message.h"
+#include "simpleintmessage.h"
+#include "simpleint64message.h"
+#include "simplesintmessage.h"
+#include "simplesint64message.h"
+#include "simpleuintmessage.h"
+#include "simpleuint64message.h"
+#include "simplestringmessage.h"
+
+using namespace qtprotobufnamespace::tests;
+
+class TestSetup : public QObject {
+public:
+    TestSetup() {
+        SimpleBoolMessage();
+        SimpleBytesMessage();
+        SimpleDoubleMessage();
+        SimpleFloatMessage();
+        SimpleFixedInt32Message();
+        SimpleIntMessage();
+        SimpleSIntMessage();
+        SimpleUIntMessage();
+        SimpleStringMessage();
+        SimpleSFixedInt32Message();
+    }
+    ~TestSetup() = default;
+};
+
+QUICK_TEST_MAIN_WITH_SETUP(qtprotobuf_qml_test, TestSetup)

+ 181 - 0
tests/test_qml/qml/tst_simple.qml

@@ -0,0 +1,181 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+import QtQuick 2.12
+import QtTest 1.0
+
+import qtprotobufnamespace.tests 1.0
+
+TestCase {
+    name: "Simple values assignment"
+    SimpleBoolMessage {
+        id: boolMsg
+        testFieldBool: false
+    }
+    SimpleIntMessage {
+        id: int32Msg
+        testFieldInt: 2147483647
+    }
+    SimpleSIntMessage {
+        id: sint32Msg
+        testFieldInt: 2147483647
+    }
+    SimpleUIntMessage {
+        id: uint32Msg
+        testFieldInt: 4294967295
+    }
+    SimpleFixedInt32Message {
+        id: fixed32Msg
+        testFieldFixedInt32: 4294967295
+    }
+    SimpleSFixedInt32Message {
+        id: sfixed32Msg
+        testFieldFixedInt32: 2147483647
+    }
+    SimpleStringMessage {
+        id: stringMsg
+        testFieldString: "Test string"
+    }
+
+    function test_simpleboolmessage() {
+        boolMsg.testFieldBool = true;
+        compare(boolMsg.testFieldBool, true, "SimpleBoolMessage == true")
+        boolMsg.testFieldBool = false;
+        compare(boolMsg.testFieldBool, false, "SimpleBoolMessage == false")
+    }
+
+    function test_simpleintmessage() {
+        int32Msg.testFieldInt = 0;
+        compare(int32Msg.testFieldInt == 0, true, "SimpleIntMessage == 0")
+        int32Msg.testFieldInt = -128;
+        compare(int32Msg.testFieldInt == -128, true, "SimpleIntMessage == -128")
+        int32Msg.testFieldInt = 127;
+        compare(int32Msg.testFieldInt == 127, true, "SimpleIntMessage == 127")
+        int32Msg.testFieldInt = -256;
+        compare(int32Msg.testFieldInt == -256, true, "SimpleIntMessage == -256")
+        int32Msg.testFieldInt = 255;
+        compare(int32Msg.testFieldInt == 255, true, "SimpleIntMessage == 255")
+        int32Msg.testFieldInt = -32768;
+        compare(int32Msg.testFieldInt == -32768, true, "SimpleIntMessage == -32768")
+        int32Msg.testFieldInt = 32767;
+        compare(int32Msg.testFieldInt == 32767, true, "SimpleIntMessage == 32767")
+        int32Msg.testFieldInt = -65536;
+        compare(int32Msg.testFieldInt == -65536, true, "SimpleIntMessage == -65536")
+        int32Msg.testFieldInt = 65535;
+        compare(int32Msg.testFieldInt == 65535, true, "SimpleIntMessage == 65535")
+        int32Msg.testFieldInt = -2147483648;
+        compare(int32Msg.testFieldInt == -2147483648, true, "SimpleIntMessage == -2147483648")
+        int32Msg.testFieldInt = 2147483647;
+        compare(int32Msg.testFieldInt == 2147483647, true, "SimpleIntMessage == 2147483647")
+    }
+
+    function test_simplesintmessage() {
+        sint32Msg.testFieldInt = 0;
+        compare(sint32Msg.testFieldInt, 0, "SimpleSIntMessage == 0")
+        sint32Msg.testFieldInt = -128;
+        compare(sint32Msg.testFieldInt, -128, "SimpleSIntMessage == -128")
+        sint32Msg.testFieldInt = 127;
+        compare(sint32Msg.testFieldInt, 127, "SimpleSIntMessage == 127")
+        sint32Msg.testFieldInt = -256;
+        compare(sint32Msg.testFieldInt, -256, "SimpleSIntMessage == -256")
+        sint32Msg.testFieldInt = 255;
+        compare(sint32Msg.testFieldInt, 255, "SimpleSIntMessage == 255")
+        sint32Msg.testFieldInt = -32768;
+        compare(sint32Msg.testFieldInt, -32768, "SimpleSIntMessage == -32768")
+        sint32Msg.testFieldInt = 32767;
+        compare(sint32Msg.testFieldInt, 32767, "SimpleSIntMessage == 32767")
+        sint32Msg.testFieldInt = -65536;
+        compare(sint32Msg.testFieldInt, -65536, "SimpleSIntMessage == -65536")
+        sint32Msg.testFieldInt = 65535;
+        compare(sint32Msg.testFieldInt, 65535, "SimpleSIntMessage == 65535")
+        sint32Msg.testFieldInt = -2147483648;
+        compare(sint32Msg.testFieldInt, -2147483648, "SimpleSIntMessage == -2147483648")
+        sint32Msg.testFieldInt = 2147483647;
+        compare(sint32Msg.testFieldInt, 2147483647, "SimpleSIntMessage == 2147483647")
+    }
+
+    function test_simpleuintmessage() {
+        uint32Msg.testFieldInt = 0;
+        compare(uint32Msg.testFieldInt == 0, true, "SimpleUIntMessage == 0")
+        uint32Msg.testFieldInt = 127;
+        compare(uint32Msg.testFieldInt == 127, true, "SimpleUIntMessage == 127")
+        uint32Msg.testFieldInt = 255;
+        compare(uint32Msg.testFieldInt == 255, true, "SimpleUIntMessage == 255")
+        uint32Msg.testFieldInt = 32767;
+        compare(uint32Msg.testFieldInt == 32767, true, "SimpleUIntMessage == 32767")
+        uint32Msg.testFieldInt = 65535;
+        compare(uint32Msg.testFieldInt == 65535, true, "SimpleUIntMessage == 65535")
+        uint32Msg.testFieldInt = 2147483647;
+        compare(uint32Msg.testFieldInt == 2147483647, true, "SimpleUIntMessage == 2147483647")
+        uint32Msg.testFieldInt = 4294967295;
+        compare(uint32Msg.testFieldInt == 4294967295, true, "SimpleUIntMessage == 2147483647")
+    }
+
+    function test_simplefixed32message() {
+        fixed32Msg.testFieldFixedInt32 = 0;
+        compare(fixed32Msg.testFieldFixedInt32 == 0, true, "SimpleFixedInt32Message == 0")
+        fixed32Msg.testFieldFixedInt32 = 127;
+        compare(fixed32Msg.testFieldFixedInt32 == 127, true, "SimpleFixedInt32Message == 127")
+        fixed32Msg.testFieldFixedInt32 = 255;
+        compare(fixed32Msg.testFieldFixedInt32 == 255, true, "SimpleFixedInt32Message == 255")
+        fixed32Msg.testFieldFixedInt32 = 32767;
+        compare(fixed32Msg.testFieldFixedInt32 == 32767, true, "SimpleFixedInt32Message == 32767")
+        fixed32Msg.testFieldFixedInt32 = 65535;
+        compare(fixed32Msg.testFieldFixedInt32 == 65535, true, "SimpleFixedInt32Message == 65535")
+        fixed32Msg.testFieldFixedInt32 = 2147483647;
+        compare(fixed32Msg.testFieldFixedInt32 == 2147483647, true, "SimpleFixedInt32Message == 2147483647")
+        fixed32Msg.testFieldFixedInt32 = 4294967295;
+        compare(fixed32Msg.testFieldFixedInt32 == 4294967295, true, "SimpleFixedInt32Message == 2147483647")
+    }
+
+    function test_simplesfixed32message() {
+        sfixed32Msg.testFieldFixedInt32 = 0;
+        compare(sfixed32Msg.testFieldFixedInt32 == 0, true, "SimpleSFixedInt32Message == 0")
+        sfixed32Msg.testFieldFixedInt32 = -128;
+        compare(sfixed32Msg.testFieldFixedInt32 == -128, true, "SimpleSFixedInt32Message == -128")
+        sfixed32Msg.testFieldFixedInt32 = 127;
+        compare(sfixed32Msg.testFieldFixedInt32 == 127, true, "SimpleSFixedInt32Message == 127")
+        sfixed32Msg.testFieldFixedInt32 = -256;
+        compare(sfixed32Msg.testFieldFixedInt32 == -256, true, "SimpleSFixedInt32Message == -256")
+        sfixed32Msg.testFieldFixedInt32 = 255;
+        compare(sfixed32Msg.testFieldFixedInt32 == 255, true, "SimpleSFixedInt32Message == 255")
+        sfixed32Msg.testFieldFixedInt32 = -32768;
+        compare(sfixed32Msg.testFieldFixedInt32 == -32768, true, "SimpleSFixedInt32Message == -32768")
+        sfixed32Msg.testFieldFixedInt32 = 32767;
+        compare(sfixed32Msg.testFieldFixedInt32 == 32767, true, "SimpleSFixedInt32Message == 32767")
+        sfixed32Msg.testFieldFixedInt32 = -65536;
+        compare(sfixed32Msg.testFieldFixedInt32 == -65536, true, "SimpleSFixedInt32Message == -65536")
+        sfixed32Msg.testFieldFixedInt32 = 65535;
+        compare(sfixed32Msg.testFieldFixedInt32 == 65535, true, "SimpleSFixedInt32Message == 65535")
+        sfixed32Msg.testFieldFixedInt32 = -2147483648;
+        compare(sfixed32Msg.testFieldFixedInt32 == -2147483648, true, "SimpleSFixedInt32Message == -2147483648")
+        sfixed32Msg.testFieldFixedInt32 = 2147483647;
+        compare(sfixed32Msg.testFieldFixedInt32 == 2147483647, true, "SimpleSFixedInt32Message == 2147483647")
+    }
+
+    function test_simplesstringmessage() {
+        compare(stringMsg.testFieldString, "Test string", "SimpleStringMessage")
+    }
+}