Add another test

master
Jos van den Oever 2017-08-11 21:55:51 +02:00
parent b7cd97a4f8
commit 8a35c76e7c
8 changed files with 280 additions and 31 deletions

View File

@ -364,11 +364,9 @@ public:
}
~DifferentFileWriter() {
const QByteArray old = read();
// write if file does not exists
if ((!old.isNull() && overwrite) || old == buffer) {
return;
if (old != buffer && (old.isNull() || overwrite)) {
write();
}
write();
}
QByteArray read() const {
QByteArray content;

View File

@ -1,32 +1,53 @@
enable_testing()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/src/interface.rs"
COMMAND ${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator --overwrite-implementation "${CMAKE_CURRENT_SOURCE_DIR}/test_object.json"
DEPENDS rust_qt_binding_generator test_object.json
)
SET(GENERATOR "${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/${RUST_TARGET_DIR}/librust.a"
COMMAND cargo build ${RUST_BUILD_FLAG}
DEPENDS rust_object/src/lib.rs
rust_object/src/implementation.rs
rust_object/src/interface.rs
rust_object/src/types.rs
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/rust_object"
)
add_custom_target(test_rust_object DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/${RUST_TARGET_DIR}/librust.a")
function(rust_test NAME DIRECTORY)
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}")
set(DIR "${SRC}/${DIRECTORY}")
add_executable(test_object test_object.cpp test_object_rust.cpp)
add_dependencies(test_object test_rust_object)
target_link_libraries(test_object
Qt5::Core
Qt5::Test
"${CMAKE_CURRENT_SOURCE_DIR}/rust_object/${RUST_TARGET_DIR}/librust.a"
)
add_custom_command(
OUTPUT "${DIR}/src/interface.rs"
"${DIR}/src/implementation.rs"
"${SRC}/${NAME}_rust.h"
# if the cpp file is marked GENERATED, CMake will not check it for moc
# "${SRC}/${NAME}_rust.cpp"
COMMAND "${GENERATOR}" --overwrite-implementation "${SRC}/${NAME}.json"
MAIN_DEPENDENCY "${NAME}.json"
DEPENDS "${GENERATOR}"
)
# add_custom_target("${DIRECTORY}"
# DEPENDS "${DIR}/src/inferface.rs")
add_custom_command(
OUTPUT "${DIR}/${RUST_TARGET_DIR}/librust.a"
COMMAND cargo build ${RUST_BUILD_FLAG}
DEPENDS "${DIRECTORY}/src/lib.rs"
"${DIRECTORY}/src/implementation.rs"
"${DIRECTORY}/src/interface.rs"
"${DIRECTORY}/src/types.rs"
WORKING_DIRECTORY "${DIR}"
)
add_custom_target("test_${DIRECTORY}"
DEPENDS "${DIR}/${RUST_TARGET_DIR}/librust.a")
add_executable("${NAME}" "${NAME}.cpp" "${NAME}_rust.cpp" "${NAME}_rust.h")
add_dependencies("${NAME}" "test_${DIRECTORY}")
target_link_libraries("${NAME}"
Qt5::Core
Qt5::Test
"${DIR}/${RUST_TARGET_DIR}/librust.a"
)
set_property(TARGET ${NAME}
APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "${SRC}/${NAME}_rust.h")
add_test("build_${NAME}"
"${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target "${NAME}")
add_test("${NAME}" "${NAME}")
set_tests_properties("${NAME}" PROPERTIES DEPENDS "build_${NAME}")
endfunction(rust_test)
rust_test(test_object rust_object)
rust_test(test_object_types rust_object_types)
add_test(remove_test_object "${CMAKE_COMMAND}" -E remove test_object)
add_test(build_test_object "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target test_object)
set_tests_properties(build_test_object PROPERTIES DEPENDS remove_test_object)
add_test(test_object test_object)
set_tests_properties(test_object PROPERTIES DEPENDS build_test_object)

View File

@ -0,0 +1,10 @@
[package]
name = "rust_object"
version = "1.0.0"
[dependencies]
libc = "*"
[lib]
name = "rust"
crate-type = ["staticlib"]

View File

@ -0,0 +1,5 @@
extern crate libc;
mod types;
pub mod interface;
mod implementation;

View File

@ -0,0 +1,41 @@
#include "test_object_rust.h"
#include <QTest>
#include <QSignalSpy>
class TestRustObject : public QObject
{
Q_OBJECT
private slots:
void testConstructor();
void testStringGetter();
void testStringSetter();
};
void TestRustObject::testConstructor()
{
Person person;
}
void TestRustObject::testStringGetter()
{
Person person;
person.setUserName("Konqi");
}
void TestRustObject::testStringSetter()
{
// GIVEN
Person person;
QSignalSpy spy(&person, &Person::userNameChanged);
// WHEN
person.setUserName("Konqi");
// THEN
QVERIFY(spy.isValid());
QCOMPARE(spy.count(), 1);
QCOMPARE(person.userName(), QString("Konqi"));
}
QTEST_MAIN(TestRustObject)
#include "test_object_types.moc"

View File

@ -0,0 +1,17 @@
{
"cppFile": "test_object_types_rust.cpp",
"rust": {
"dir": "rust_object_types",
"interfaceModule": "interface",
"implementationModule": "implementation"
},
"objects": [{
"name": "Person",
"type": "Object",
"properties": [{
"name": "userName",
"type": "QString",
"write": true
}]
}]
}

View File

@ -0,0 +1,132 @@
/* generated by rust_qt_binding_generator */
#include "test_object_types_rust.h"
#include <QModelIndex>
namespace {
struct qbytearray_t {
private:
const char* data;
int len;
public:
qbytearray_t(const QByteArray& v):
data(v.data()),
len(v.size()) {
}
operator QByteArray() const {
return QByteArray(data, len);
}
};
struct qstring_t {
private:
const void* data;
int len;
public:
qstring_t(const QString& v):
data(static_cast<const void*>(v.utf16())),
len(v.size()) {
}
operator QString() const {
return QString::fromUtf8(static_cast<const char*>(data), len);
}
};
struct qmodelindex_t {
int row;
int column;
uint64_t id;
qmodelindex_t(const QModelIndex& m):
row(m.row()), column(m.column()), id(m.internalId()) {}
};
struct qvariant_t {
unsigned int type;
int value;
const char* data;
};
QVariant variant(const qvariant_t& v) {
switch (v.type) {
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value);
default:;
}
return QVariant();
}
void variant(const QByteArray& v, void* d, void (*set)(void*, qvariant_t)) {
set(d, {
.type = QVariant::ByteArray,
.value = v.length(),
.data = v.data()
});
}
void variant(const QString& v, void* d, void (*set)(void*, qvariant_t)) {
set(d, {
.type = QVariant::String,
.value = v.size(),
.data = static_cast<const char*>(static_cast<const void*>(v.utf16()))
});
}
void variant(const QVariant& v, void* d, void (*set)(void*, qvariant_t)) {
switch (v.type()) {
case QVariant::Bool:
set(d, {
.type = QVariant::Bool,
.value = v.toBool(),
.data = 0
});
break;
case QVariant::Int:
set(d, {
.type = QVariant::Int,
.value = v.toInt(),
.data = 0
});
break;
case QVariant::ByteArray:
variant(v.toByteArray(), d, set);
break;
case QVariant::String:
variant(v.toString(), d, set);
break;
default:
set(d, {
.type = QVariant::Invalid,
.value = 0,
.data = 0
});
}
}
}
typedef void (*qstring_set)(QString*, qstring_t*);
void set_qstring(QString* v, qstring_t* val) {
*v = *val;
}
typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*);
void set_qbytearray(QByteArray* v, qbytearray_t* val) {
*v = *val;
}
typedef void (*qvariant_set)(QVariant*, qvariant_t*);
void set_qvariant(QVariant* v, qvariant_t* val) {
*v = variant(*val);
}
extern "C" {
PersonInterface* person_new(Person*, void (*)(Person*));
void person_free(PersonInterface*);
void person_user_name_get(PersonInterface*, QString*, qstring_set);
void person_user_name_set(void*, qstring_t);
};
Person::Person(QObject *parent):
QObject(parent),
d(person_new(this,
[](Person* o) { emit o->userNameChanged(); })) {}
Person::~Person() {
person_free(d);
}
QString Person::userName() const
{
QString v;
person_user_name_get(d, &v, set_qstring);
return v;
}
void Person::setUserName(const QString& v) {
person_user_name_set(d, v);
}

View File

@ -0,0 +1,25 @@
/* generated by rust_qt_binding_generator */
#ifndef TEST_OBJECT_TYPES_RUST_H
#define TEST_OBJECT_TYPES_RUST_H
#include <QObject>
#include <QVariant>
#include <QAbstractItemModel>
class PersonInterface;
class Person : public QObject
{
Q_OBJECT
PersonInterface * const d;
Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged FINAL)
public:
explicit Person(QObject *parent = nullptr);
~Person();
QString userName() const;
void setUserName(const QString& v);
signals:
void userNameChanged();
private:
QString m_userName;
};
#endif // TEST_OBJECT_TYPES_RUST_H