Browse Source

added coreapp and viewmodel tests

pull/2/head
Skycoder42 7 years ago
parent
commit
1925d2c977
No known key found for this signature in database GPG Key ID: 8E01AD9EF0578D2B
  1. 5
      src/mvvmcore/coreapp.cpp
  2. 9
      src/mvvmcore/coreapp.h
  3. 19
      tests/auto/mvvmcore/coreapp/coreapp.pro
  4. 27
      tests/auto/mvvmcore/coreapp/testapp.cpp
  5. 29
      tests/auto/mvvmcore/coreapp/testapp.h
  6. 15
      tests/auto/mvvmcore/coreapp/testpresenter.cpp
  7. 24
      tests/auto/mvvmcore/coreapp/testpresenter.h
  8. 42
      tests/auto/mvvmcore/coreapp/testviewmodel.cpp
  9. 52
      tests/auto/mvvmcore/coreapp/testviewmodel.h
  10. 396
      tests/auto/mvvmcore/coreapp/tst_coreapp.cpp
  11. 9
      tests/auto/mvvmcore/mvvmcore.pro

5
src/mvvmcore/coreapp.cpp

@ -129,6 +129,11 @@ void CoreApp::registerInputTypeMapping(const QByteArray &type, int targetType)
CoreAppPrivate::dInstance()->inputTypeMapping.insert(type, targetType); CoreAppPrivate::dInstance()->inputTypeMapping.insert(type, targetType);
} }
IPresenter *CoreApp::presenter()
{
return CoreAppPrivate::dInstance()->presenter;
}
void CoreApp::bootApp() void CoreApp::bootApp()
{ {
if(!d->presenter) { if(!d->presenter) {

9
src/mvvmcore/coreapp.h

@ -52,6 +52,8 @@ public:
template <typename T> template <typename T>
static void registerInputTypeMapping(const QByteArray &type); static void registerInputTypeMapping(const QByteArray &type);
static IPresenter *presenter();
public Q_SLOTS: public Q_SLOTS:
//! Boots up the app and starts the mvvm presenting //! Boots up the app and starts the mvvm presenting
void bootApp(); void bootApp();
@ -95,13 +97,14 @@ void CoreApp::registerInputTypeMapping(const QByteArray &type)
} }
//! Registers you custom CoreApp class as CoreApp to be used //! Registers you custom CoreApp class as CoreApp to be used
#define QTMVVM_REGISTER_CORE_APP(T) \ #define QTMVVM_REGISTER_CORE_APP(T) namespace {\
static void _setup_ ## T ## _hook() { \ void __setup_ ## T ## _hook() { \
static_assert(std::is_base_of<QtMvvm::CoreApp, T>::value, "QTMVVM_REGISTER_CORE_APP must be used with a class that extends QtMvvm::CoreApp"); \ static_assert(std::is_base_of<QtMvvm::CoreApp, T>::value, "QTMVVM_REGISTER_CORE_APP must be used with a class that extends QtMvvm::CoreApp"); \
auto app = new T(nullptr); \ auto app = new T(nullptr); \
app->registerApp(); \ app->registerApp(); \
} \ } \
Q_COREAPP_STARTUP_FUNCTION(_setup_ ## T ## _hook) } \
Q_COREAPP_STARTUP_FUNCTION(__setup_ ## T ## _hook)
//! A define as shortcut to the CoreApp. Can be redefined to cast to your custom class type //! A define as shortcut to the CoreApp. Can be redefined to cast to your custom class type
#define coreApp QtMvvm::CoreApp::instance() #define coreApp QtMvvm::CoreApp::instance()

19
tests/auto/mvvmcore/coreapp/coreapp.pro

@ -0,0 +1,19 @@
TEMPLATE = app
QT += testlib mvvmcore
QT -= gui
CONFIG += console
CONFIG -= app_bundle
TARGET = tst_coreapp
SOURCES += \
tst_coreapp.cpp \
testapp.cpp \
testpresenter.cpp \
testviewmodel.cpp
HEADERS += \
testapp.h \
testpresenter.h \
testviewmodel.h

27
tests/auto/mvvmcore/coreapp/testapp.cpp

@ -0,0 +1,27 @@
#include "testapp.h"
#include <QtMvvmCore/ServiceRegistry>
TestApp::TestApp(QObject *parent) :
CoreApp(parent)
{}
TestPresenter *TestApp::presenter()
{
return static_cast<TestPresenter*>(CoreApp::presenter());
}
void TestApp::performRegistrations()
{
wasRegistered = true;
}
int TestApp::startApp(const QStringList &arguments)
{
startArgs = arguments;
return EXIT_SUCCESS;
}
void TestApp::closeApp()
{
wasClosed = false;
}

29
tests/auto/mvvmcore/coreapp/testapp.h

@ -0,0 +1,29 @@
#ifndef TESTAPP_H
#define TESTAPP_H
#include <QtMvvmCore/CoreApp>
#include "testpresenter.h"
class TestApp : public QtMvvm::CoreApp
{
Q_OBJECT
public:
explicit TestApp(QObject *parent = nullptr);
bool wasRegistered = false;
QStringList startArgs;
bool wasClosed = false;
static TestPresenter *presenter();
protected:
void performRegistrations() override;
int startApp(const QStringList &arguments) override;
void closeApp() override;
};
#undef coreApp
#define coreApp static_cast<TestApp*>(QtMvvm::CoreApp::instance())
#endif // TESTAPP_H

15
tests/auto/mvvmcore/coreapp/testpresenter.cpp

@ -0,0 +1,15 @@
#include "testpresenter.h"
TestPresenter::TestPresenter(QObject *parent) :
QObject{parent}
{}
void TestPresenter::present(QtMvvm::ViewModel *viewModel, const QVariantHash &params, QPointer<QtMvvm::ViewModel> parent)
{
presented.append(std::make_tuple(viewModel, params, parent));
emit presentDone();
}
void TestPresenter::showDialog(const QtMvvm::MessageConfig &config, QtMvvm::MessageResult *result)
{
}

24
tests/auto/mvvmcore/coreapp/testpresenter.h

@ -0,0 +1,24 @@
#ifndef TESTPRESENTER_H
#define TESTPRESENTER_H
#include <QObject>
#include <QtMvvmCore/IPresenter>
class TestPresenter : public QObject, public QtMvvm::IPresenter
{
Q_OBJECT
Q_INTERFACES(QtMvvm::IPresenter)
public:
Q_INVOKABLE explicit TestPresenter(QObject *parent = nullptr);
void present(QtMvvm::ViewModel *viewModel, const QVariantHash &params, QPointer<QtMvvm::ViewModel> parent) override;
void showDialog(const QtMvvm::MessageConfig &config, QtMvvm::MessageResult *result) override;
QList<std::tuple<QtMvvm::ViewModel*, QVariantHash, QPointer<QtMvvm::ViewModel>>> presented;
Q_SIGNALS:
void presentDone();
};
#endif // TESTPRESENTER_H

42
tests/auto/mvvmcore/coreapp/testviewmodel.cpp

@ -0,0 +1,42 @@
#include "testviewmodel.h"
TestViewModel::TestViewModel(QObject *parent) :
ViewModel(parent)
{}
void TestViewModel::presenChild(const QVariantHash &params)
{
show<TestViewModel>(params);
}
void TestViewModel::presentResult(quint32 code)
{
showForResult<TestViewModel>(code);
}
void TestViewModel::onInit(const QVariantHash &params)
{
}
void TestViewModel::onResult(quint32 requestCode, const QVariant &result)
{
results.append(std::make_tuple(requestCode, result));
}
TestSingleViewModel::TestSingleViewModel(QObject *parent) :
ViewModel(parent)
{}
TestContainedViewModel::TestContainedViewModel(QObject *parent) :
ViewModel(parent)
{}
TestContainedSingleViewModel::TestContainedSingleViewModel(QObject *parent) :
ViewModel(parent)
{}

52
tests/auto/mvvmcore/coreapp/testviewmodel.h

@ -0,0 +1,52 @@
#ifndef TESTVIEWMODEL_H
#define TESTVIEWMODEL_H
#include <QtMvvmCore/ViewModel>
class TestViewModel : public QtMvvm::ViewModel
{
Q_OBJECT
public:
Q_INVOKABLE explicit TestViewModel(QObject *parent = nullptr);
void presenChild(const QVariantHash &params = {});
void presentResult(quint32 code);
QList<std::tuple<quint32, QVariant>> results;
public Q_SLOTS:
void onInit(const QVariantHash &params) override;
void onResult(quint32 requestCode, const QVariant &result) override;
};
Q_DECLARE_METATYPE(TestViewModel*)
class TestSingleViewModel : public QtMvvm::ViewModel
{
Q_OBJECT
QTMVVM_SINGLETON
public:
Q_INVOKABLE explicit TestSingleViewModel(QObject *parent = nullptr);
};
Q_DECLARE_METATYPE(TestSingleViewModel*)
class TestContainedViewModel : public QtMvvm::ViewModel
{
Q_OBJECT
QTMVVM_CONTAINER_VM(TestViewModel)
public:
Q_INVOKABLE explicit TestContainedViewModel(QObject *parent = nullptr);
};
class TestContainedSingleViewModel : public QtMvvm::ViewModel
{
Q_OBJECT
QTMVVM_CONTAINER_VM(TestSingleViewModel)
public:
Q_INVOKABLE explicit TestContainedSingleViewModel(QObject *parent = nullptr);
};
#endif // TESTVIEWMODEL_H

396
tests/auto/mvvmcore/coreapp/tst_coreapp.cpp

@ -0,0 +1,396 @@
#include <QtTest>
#include <QtMvvmCore/ServiceRegistry>
#include "testapp.h"
#include "testviewmodel.h"
using namespace QtMvvm;
QTMVVM_REGISTER_CORE_APP(TestApp)
class CoreAppTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void testAppBoot();
void testTypeMapping_data();
void testTypeMapping();
void testPresentVm();
void testPresentVmArgs();
void testPresentVmChild();
void testPresentVmForResult();
void testPresentVmContainer();
void testPresentVmSingleton();
void testPresentDialog();
void testPresentMessage_data();
void testPresentMessage();
void testProgressMessage();
};
void CoreAppTest::initTestCase()
{
qRegisterMetaType<TestViewModel*>();
qRegisterMetaType<TestSingleViewModel*>();
QtMvvm::ServiceRegistry::instance()->registerInterface<QtMvvm::IPresenter, TestPresenter>();
}
void CoreAppTest::testAppBoot()
{
QVERIFY(coreApp);
QVERIFY(coreApp->wasRegistered);
QVERIFY(coreApp->startArgs.isEmpty());
QSignalSpy startSpy{coreApp, &TestApp::appStarted};
QCoreApplication::processEvents();
QVERIFY(!coreApp->startArgs.isEmpty());
QCOMPARE(coreApp->startArgs, QCoreApplication::arguments());
QCOMPARE(startSpy.size(), 1);
}
void CoreAppTest::testTypeMapping_data()
{
QTest::addColumn<QByteArray>("type");
QTest::addColumn<int>("targetType");
QTest::addColumn<QVariant>("value");
QTest::addColumn<bool>("needRegister");
QTest::addColumn<QVariant>("result");
QTest::newRow("builtin.switch") << QByteArrayLiteral("switch")
<< static_cast<int>(QMetaType::Bool)
<< QVariant{QStringLiteral("true")}
<< false
<< QVariant{true};
QTest::newRow("builtin.string") << QByteArrayLiteral("string")
<< static_cast<int>(QMetaType::QString)
<< QVariant{QStringLiteral("test")}
<< false
<< QVariant{QStringLiteral("test")};
QTest::newRow("builtin.number") << QByteArrayLiteral("number")
<< static_cast<int>(QMetaType::Double)
<< QVariant{QStringLiteral("4.2")}
<< false
<< QVariant{4.2};
QTest::newRow("builtin.range") << QByteArrayLiteral("range")
<< static_cast<int>(QMetaType::Int)
<< QVariant{QStringLiteral("55")}
<< false
<< QVariant{55};
QTest::newRow("builtin.date") << QByteArrayLiteral("date")
<< static_cast<int>(QMetaType::QDateTime)
<< QVariant{QStringLiteral("2018-10-10T10:10")}
<< false
<< QVariant{QDateTime{{2018, 10, 10}, {10, 10}}};
QTest::newRow("builtin.color") << QByteArrayLiteral("color")
<< static_cast<int>(QMetaType::QColor)
<< QVariant{QStringLiteral("#123456")}
<< false
<< QVariant{QColor{0x12, 0x34, 0x56}};
QTest::newRow("builtin.url") << QByteArrayLiteral("url")
<< static_cast<int>(QMetaType::QUrl)
<< QVariant{QStringLiteral("file:///root.txt")}
<< false
<< QVariant{QUrl::fromLocalFile(QStringLiteral("/root.txt"))};
QTest::newRow("builtin.var") << QByteArrayLiteral("var")
<< static_cast<int>(QMetaType::QVariant)
<< QVariant{42}
<< false
<< QVariant{42};
QTest::newRow("builtin.variant") << QByteArrayLiteral("variant")
<< static_cast<int>(QMetaType::QVariant)
<< QVariant{43}
<< false
<< QVariant{43};
QTest::newRow("builtin.selection") << QByteArrayLiteral("selection")
<< static_cast<int>(QMetaType::QVariant)
<< QVariant{44}
<< false
<< QVariant{44};
QTest::newRow("builtin.list") << QByteArrayLiteral("list")
<< static_cast<int>(QMetaType::QVariant)
<< QVariant{45}
<< false
<< QVariant{45};
QTest::newRow("builtin.radiolist") << QByteArrayLiteral("radiolist")
<< static_cast<int>(QMetaType::QVariant)
<< QVariant{46}
<< false
<< QVariant{46};
QTest::newRow("known") << QByteArrayLiteral("int")
<< static_cast<int>(QMetaType::Int)
<< QVariant{QStringLiteral("66")}
<< false
<< QVariant{66};
QTest::newRow("custom") << QByteArrayLiteral("salt")
<< static_cast<int>(QMetaType::Double)
<< QVariant{QStringLiteral("0.5")}
<< true
<< QVariant{0.5};
QTest::newRow("invalid.unknown") << QByteArrayLiteral("sugar")
<< static_cast<int>(QMetaType::Int)
<< QVariant{QStringLiteral("66")}
<< false
<< QVariant{};
QTest::newRow("invalid.inconvertible") << QByteArrayLiteral("color")
<< static_cast<int>(QMetaType::QColor)
<< QVariant{true}
<< false
<< QVariant{};
}
void CoreAppTest::testTypeMapping()
{
QFETCH(QByteArray, type);
QFETCH(int, targetType);
QFETCH(QVariant, value);
QFETCH(bool, needRegister);
QFETCH(QVariant, result);
if(needRegister)
CoreApp::registerInputTypeMapping(type, targetType);
auto res = CoreApp::safeCastInputType(type, value);
if(result.isValid()) {
if(targetType == QMetaType::QVariant)
QVERIFY(res.userType() != targetType);
else
QCOMPARE(res.userType(), targetType);
QVERIFY(res.isValid());
QCOMPARE(res, result);
} else {
QCOMPARE(res.userType(), value.userType());
QVERIFY(res.userType() != targetType);
}
}
void CoreAppTest::testPresentVm()
{
auto presenter = TestApp::presenter();
presenter->presented.clear();
QSignalSpy presentSpy{presenter, &TestPresenter::presentDone};
CoreApp::show<TestViewModel>();
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 1);
QCOMPARE(presenter->presented.size(), 1);
auto vm = std::get<0>(presenter->presented[0]);
QVERIFY(vm);
QCOMPARE(vm->metaObject(), &TestViewModel::staticMetaObject);
QVERIFY(std::get<1>(presenter->presented[0]).isEmpty());
QVERIFY(!std::get<2>(presenter->presented[0]));
}
void CoreAppTest::testPresentVmArgs()
{
QVariantHash params {
{QStringLiteral("key"), QStringLiteral("value")},
{QStringLiteral("baum"), 42}
};
auto presenter = TestApp::presenter();
presenter->presented.clear();
QSignalSpy presentSpy{presenter, &TestPresenter::presentDone};
CoreApp::show<TestViewModel>(params);
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 1);
QCOMPARE(presenter->presented.size(), 1);
auto vm = std::get<0>(presenter->presented[0]);
QVERIFY(vm);
QCOMPARE(vm->metaObject(), &TestViewModel::staticMetaObject);
QCOMPARE(std::get<1>(presenter->presented[0]), params);
QVERIFY(!std::get<2>(presenter->presented[0]));
}
void CoreAppTest::testPresentVmChild()
{
QVariantHash params {
{QStringLiteral("key"), QStringLiteral("value")},
{QStringLiteral("baum"), 42}
};
auto presenter = TestApp::presenter();
presenter->presented.clear();
QSignalSpy presentSpy{presenter, &TestPresenter::presentDone};
CoreApp::show<TestViewModel>();
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 1);
QCOMPARE(presenter->presented.size(), 1);
auto vm = static_cast<TestViewModel*>(std::get<0>(presenter->presented[0]));
QVERIFY(vm);
vm->presenChild(params);
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 2);
QCOMPARE(presenter->presented.size(), 2);
auto child = std::get<0>(presenter->presented[1]);
QVERIFY(child);
QCOMPARE(child->metaObject(), &TestViewModel::staticMetaObject);
QCOMPARE(std::get<1>(presenter->presented[1]), params);
QCOMPARE(std::get<2>(presenter->presented[1]), vm);
}
void CoreAppTest::testPresentVmForResult()
{
auto presenter = TestApp::presenter();
presenter->presented.clear();
QSignalSpy presentSpy{presenter, &TestPresenter::presentDone};
CoreApp::show<TestViewModel>();
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 1);
QCOMPARE(presenter->presented.size(), 1);
auto vm = static_cast<TestViewModel*>(std::get<0>(presenter->presented[0]));
QVERIFY(vm);
// show with result
vm->presentResult(42);
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 2);
QCOMPARE(presenter->presented.size(), 2);
auto child = std::get<0>(presenter->presented[1]);
QVERIFY(child);
QCOMPARE(child->metaObject(), &TestViewModel::staticMetaObject);
QVERIFY(std::get<1>(presenter->presented[1]).isEmpty());
QCOMPARE(std::get<2>(presenter->presented[1]), vm);
QVariant result{5.5};
emit child->resultReady(result);
QCOMPARE(vm->results.size(), 1);
QCOMPARE(std::get<0>(vm->results[0]), 42u);
QCOMPARE(std::get<1>(vm->results[0]), result);
delete child;
QCOMPARE(vm->results.size(), 1);
//show without result
vm->presentResult(24);
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 3);
QCOMPARE(presenter->presented.size(), 3);
child = std::get<0>(presenter->presented[2]);
QVERIFY(child);
delete child;
QCOMPARE(vm->results.size(), 2);
QCOMPARE(std::get<0>(vm->results[1]), 24u);
QVERIFY(!std::get<1>(vm->results[1]).isValid());
}
void CoreAppTest::testPresentVmContainer()
{
QVariantHash initMap {
{QStringLiteral("qtmvvm_container_for"), QByteArray{TestContainedViewModel::staticMetaObject.className()}},
{QStringLiteral("qtmvvm_child_params"), QVariantHash{}}
};
auto presenter = TestApp::presenter();
presenter->presented.clear();
QSignalSpy presentSpy{presenter, &TestPresenter::presentDone};
CoreApp::show<TestContainedViewModel>();
while(presentSpy.size() < 2)
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 2);
QCOMPARE(presenter->presented.size(), 2);
auto vm = std::get<0>(presenter->presented[0]);
QVERIFY(vm);
QCOMPARE(vm->metaObject(), &TestViewModel::staticMetaObject);
QCOMPARE(std::get<1>(presenter->presented[0]), initMap);
QVERIFY(!std::get<2>(presenter->presented[0]));
auto child = std::get<0>(presenter->presented[1]);
QVERIFY(child);
QCOMPARE(child->metaObject(), &TestContainedViewModel::staticMetaObject);
QVERIFY(std::get<1>(presenter->presented[1]).isEmpty());
QCOMPARE(std::get<2>(presenter->presented[1]), vm);
}
void CoreAppTest::testPresentVmSingleton()
{
auto presenter = TestApp::presenter();
presenter->presented.clear();
QSignalSpy presentSpy{presenter, &TestPresenter::presentDone};
CoreApp::show<TestSingleViewModel>();
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 1);
QCOMPARE(presenter->presented.size(), 1);
auto vm = std::get<0>(presenter->presented[0]);
QVERIFY(vm);
QCOMPARE(vm->metaObject(), &TestSingleViewModel::staticMetaObject);
QVERIFY(std::get<1>(presenter->presented[0]).isEmpty());
QVERIFY(!std::get<2>(presenter->presented[0]));
QSignalSpy instSpy{vm, &ViewModel::instanceInvoked};
CoreApp::show<TestSingleViewModel>();
QVERIFY(!presentSpy.wait());
QCOMPARE(presentSpy.size(), 1);
QCOMPARE(presenter->presented.size(), 1);
QCOMPARE(instSpy.size(), 1);
// test single container
CoreApp::show<TestContainedSingleViewModel>();
QVERIFY(presentSpy.wait());
QCOMPARE(presentSpy.size(), 2);
QCOMPARE(presenter->presented.size(), 2);
auto child = std::get<0>(presenter->presented[1]);
QVERIFY(child);
QCOMPARE(child->metaObject(), &TestContainedSingleViewModel::staticMetaObject);
QVERIFY(std::get<1>(presenter->presented[1]).isEmpty());
QCOMPARE(std::get<2>(presenter->presented[1]), vm);
QCOMPARE(instSpy.size(), 2);
}
void CoreAppTest::testPresentDialog()
{
Q_UNIMPLEMENTED();
}
void CoreAppTest::testPresentMessage_data()
{
Q_UNIMPLEMENTED();
}
void CoreAppTest::testPresentMessage()
{
Q_UNIMPLEMENTED();
}
void CoreAppTest::testProgressMessage()
{
Q_UNIMPLEMENTED();
}
QTEST_MAIN(CoreAppTest)
#include "tst_coreapp.moc"

9
tests/auto/mvvmcore/mvvmcore.pro

@ -6,8 +6,13 @@ SUBDIRS += \
serviceregistrytestplugin \ serviceregistrytestplugin \
binding \ binding \
qsettingsaccessor \ qsettingsaccessor \
settingsconfigloader settingsconfigloader \
coreapp
serviceregistry.depends += serviceregistrytestplugin serviceregistry.depends += serviceregistrytestplugin
equals(MSVC_VER, 14.0): SUBDIRS -= settingsgenerator equals(MSVC_VER, 14.0) {
SUBDIRS -= \
settingsgenerator \
settingsconfigloader
}

Loading…
Cancel
Save