Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a4c517a75 | ||
|
|
a0a745df0c |
@@ -1,2 +1,3 @@
|
||||
cmake*
|
||||
!CMakePresets.json
|
||||
build
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
url = https://github.com/semihc/qdecimal.git
|
||||
[submodule "3rdparty/QxOrm"]
|
||||
path = 3rdparty/QxOrm
|
||||
url = https://github.com/PepaRokos/QxOrm.git
|
||||
url = https://github.com/QxOrm/QxOrm.git
|
||||
[submodule "3rdparty/LimeReport"]
|
||||
path = 3rdparty/LimeReport
|
||||
url = https://github.com/PepaRokos/LimeReport.git
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/QxOrm updated: 975c3b5ad3...44fd7f1617
@@ -1,6 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(prodejna-root)
|
||||
|
||||
include(CTest)
|
||||
option(ENABLE_ZINT "Enable LimeReport barcode support" ON)
|
||||
|
||||
find_package(Qt6 6.11.2 REQUIRED COMPONENTS Core Core5Compat Test Gui Widgets PrintSupport Sql Qml Network Xml Svg)
|
||||
|
||||
set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
|
||||
|
||||
add_subdirectory(3rdparty/qdecimal)
|
||||
add_subdirectory(3rdparty/QxOrm)
|
||||
add_subdirectory(3rdparty/LimeReport)
|
||||
@@ -15,3 +22,7 @@ add_subdirectory(shop)
|
||||
add_subdirectory(commodity)
|
||||
add_subdirectory(camp)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"version": 5,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 24,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "qt6-debug",
|
||||
"displayName": "Qt 6.11.2+ Debug",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/presets/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "qt6-debug",
|
||||
"configurePreset": "qt6-debug"
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
{
|
||||
"name": "qt6-debug",
|
||||
"configurePreset": "qt6-debug",
|
||||
"output": {
|
||||
"outputOnFailure": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -84,7 +84,7 @@ QDecDouble CommodityData::price() const
|
||||
|
||||
void CommodityData::setPrice(const QDecDouble &price)
|
||||
{
|
||||
m_price = price.toDouble() * DEC_MULTIPLE;
|
||||
m_price = qRound(price.toDouble() * DEC_MULTIPLE);
|
||||
}
|
||||
Enums::VatType CommodityData::vat() const
|
||||
{
|
||||
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
#ifndef DEFINE_H
|
||||
#define DEFINE_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#define ALL(arr) arr.begin(), arr.end()
|
||||
|
||||
// default rights
|
||||
@@ -11,7 +13,7 @@
|
||||
|
||||
#define DEC_MULTIPLE 100
|
||||
#define TO_DEC(num) (QDecDouble(num) / QDecDouble(DEC_MULTIPLE))
|
||||
#define FROM_DEC(num) (num * QDecDouble(DEC_MULTIPLE)).toDouble()
|
||||
#define FROM_DEC(num) qRound((num * QDecDouble(DEC_MULTIPLE)).toDouble())
|
||||
|
||||
#ifndef PLUGIN_ROOT
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -237,7 +237,10 @@ protected:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Context::instance().currentUser().isNull()) {
|
||||
obj->setProperty("updatedBy", Context::instance().currentUser()->login());
|
||||
}
|
||||
|
||||
obj->setProperty("updated", QDateTime::currentDateTime());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ QDecDouble AccService::price() const
|
||||
|
||||
void AccService::setPrice(QDecDouble price)
|
||||
{
|
||||
m_price = price.toDouble() * DEC_MULTIPLE;
|
||||
m_price = qRound(price.toDouble() * DEC_MULTIPLE);
|
||||
}
|
||||
bool AccService::active() const
|
||||
{
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QtTest>
|
||||
|
||||
#include "data/campdata.h"
|
||||
#include "data/serviceitem.h"
|
||||
#include "data/addressitem.h"
|
||||
#include "data/personprice.h"
|
||||
|
||||
class CampTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void campDataDefaultsAreZeroed()
|
||||
{
|
||||
CampData camp;
|
||||
|
||||
QCOMPARE(camp.totalPrice().toDouble(), 0.0);
|
||||
QCOMPARE(camp.sale().toDouble(), 0.0);
|
||||
QCOMPARE(camp.totalSale().toDouble(), 0.0);
|
||||
QCOMPARE(camp.fullPrice().toDouble(), 0.0);
|
||||
QVERIFY(!camp.fixedSale());
|
||||
QVERIFY(!camp.onVoucher());
|
||||
}
|
||||
|
||||
void campPricesRoundTripWithoutLoss()
|
||||
{
|
||||
CampData camp;
|
||||
|
||||
camp.setTotalPrice(QDecDouble(19.9));
|
||||
camp.setSale(QDecDouble(4.9));
|
||||
camp.setFullPrice(QDecDouble(24.8));
|
||||
|
||||
QVERIFY(qAbs(camp.totalPrice().toDouble() - 19.9) < 0.0001);
|
||||
QVERIFY(qAbs(camp.sale().toDouble() - 4.9) < 0.0001);
|
||||
QVERIFY(qAbs(camp.fullPrice().toDouble() - 24.8) < 0.0001);
|
||||
}
|
||||
|
||||
void campCollectsPeopleAndServices()
|
||||
{
|
||||
CampData camp;
|
||||
auto person = QSharedPointer<AddressItem>::create();
|
||||
auto service = QSharedPointer<ServiceItem>::create();
|
||||
|
||||
camp.addPerson(person);
|
||||
camp.addServiceItem(service);
|
||||
QCOMPARE(camp.people().size(), 1);
|
||||
QCOMPARE(camp.services().size(), 1);
|
||||
|
||||
camp.removePerson(person);
|
||||
camp.removeServiceItem(service);
|
||||
QVERIFY(camp.people().isEmpty());
|
||||
QVERIFY(camp.services().isEmpty());
|
||||
}
|
||||
|
||||
void serviceItemPricesRoundTrip()
|
||||
{
|
||||
ServiceItem item;
|
||||
|
||||
item.setPrice(QDecDouble(33.3));
|
||||
item.setTotalPrice(QDecDouble(66.6));
|
||||
item.setSale(QDecDouble(3.3));
|
||||
|
||||
QVERIFY(qAbs(item.price().toDouble() - 33.3) < 0.0001);
|
||||
QVERIFY(qAbs(item.totalPrice().toDouble() - 66.6) < 0.0001);
|
||||
QVERIFY(qAbs(item.sale().toDouble() - 3.3) < 0.0001);
|
||||
}
|
||||
|
||||
void addressItemOwnerFlagAndPrice()
|
||||
{
|
||||
AddressItem person;
|
||||
|
||||
person.setOwner(true);
|
||||
person.setPrice(QDecDouble(12.5));
|
||||
|
||||
QVERIFY(person.owner());
|
||||
QVERIFY(qAbs(person.price().toDouble() - 12.5) < 0.0001);
|
||||
}
|
||||
|
||||
void personPriceAgeRangeAndPrice()
|
||||
{
|
||||
PersonPrice price;
|
||||
|
||||
price.setFromAge(3);
|
||||
price.setToAge(12);
|
||||
price.setPrice(QDecDouble(7.5));
|
||||
price.setActive(true);
|
||||
|
||||
QCOMPARE(price.fromAge(), 3);
|
||||
QCOMPARE(price.toAge(), 12);
|
||||
QVERIFY(qAbs(price.price().toDouble() - 7.5) < 0.0001);
|
||||
QVERIFY(price.active());
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
CampTests tests;
|
||||
return QTest::qExec(&tests, argc, argv);
|
||||
}
|
||||
|
||||
#include "camp_tests.moc"
|
||||
@@ -0,0 +1,82 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QtTest>
|
||||
|
||||
#include "data/commoditydata.h"
|
||||
|
||||
class CommodityTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void defaultsAreZero()
|
||||
{
|
||||
CommodityData commodity;
|
||||
|
||||
QCOMPARE(commodity.price().toDouble(), 0.0);
|
||||
QCOMPARE(commodity.count(), 0);
|
||||
QCOMPARE(commodity.vat(), Enums::NONE);
|
||||
QVERIFY(!commodity.favorite());
|
||||
}
|
||||
|
||||
void priceRoundTripUsesFixedPointStorage()
|
||||
{
|
||||
CommodityData commodity;
|
||||
|
||||
commodity.setPrice(QDecDouble(19.9));
|
||||
|
||||
QVERIFY(qAbs(commodity.price().toDouble() - 19.9) < 0.0001);
|
||||
QCOMPARE(commodity.price(), commodity.unitPrice());
|
||||
}
|
||||
|
||||
void priceRoundTripHandlesWholeAmounts()
|
||||
{
|
||||
CommodityData commodity;
|
||||
|
||||
commodity.setPrice(QDecDouble(125));
|
||||
|
||||
QCOMPARE(commodity.price().toDouble(), 125.0);
|
||||
}
|
||||
|
||||
void vatMirrorsShopItemInterface()
|
||||
{
|
||||
CommodityData commodity;
|
||||
|
||||
commodity.setVat(Enums::HIGH);
|
||||
|
||||
QCOMPARE(commodity.vat(), Enums::HIGH);
|
||||
QCOMPARE(commodity.vatType(), Enums::HIGH);
|
||||
}
|
||||
|
||||
void pluginIdMatchesEmbeddedMetadata()
|
||||
{
|
||||
CommodityData commodity;
|
||||
|
||||
QCOMPARE(commodity.pluginId(), QStringLiteral("COMMODITY"));
|
||||
}
|
||||
|
||||
void basicPropertiesRoundTrip()
|
||||
{
|
||||
CommodityData commodity;
|
||||
|
||||
commodity.setName(QStringLiteral("Položka"));
|
||||
commodity.setShortName(QStringLiteral("Pol."));
|
||||
commodity.setCode(QStringLiteral("A-01"));
|
||||
commodity.setCount(7);
|
||||
commodity.setFavorite(true);
|
||||
|
||||
QCOMPARE(commodity.name(), QStringLiteral("Položka"));
|
||||
QCOMPARE(commodity.shortName(), QStringLiteral("Pol."));
|
||||
QCOMPARE(commodity.code(), QStringLiteral("A-01"));
|
||||
QCOMPARE(commodity.count(), 7);
|
||||
QVERIFY(commodity.favorite());
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
CommodityTests tests;
|
||||
return QTest::qExec(&tests, argc, argv);
|
||||
}
|
||||
|
||||
#include "commodity_tests.moc"
|
||||
@@ -0,0 +1,157 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QLocale>
|
||||
#include <QSettings>
|
||||
#include <QSignalSpy>
|
||||
#include <QTemporaryDir>
|
||||
#include <QtTest>
|
||||
|
||||
#include "context.h"
|
||||
#include "data/permission.h"
|
||||
#include "data/role.h"
|
||||
#include "data/user.h"
|
||||
#include "imetadataplugin.h"
|
||||
#include "permissionevaluator.h"
|
||||
|
||||
class CoreTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void init()
|
||||
{
|
||||
Context::instance().setCurrentUser({});
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
Context::instance().setCurrentUser({});
|
||||
}
|
||||
|
||||
void metadataRejectsMissingObject()
|
||||
{
|
||||
QVERIFY(!IMetaDataPlugin::loadBaseMetaData({}));
|
||||
QVERIFY(!IMetaDataPlugin::loadBaseMetaData(QJsonObject{{"MetaData", QStringLiteral("invalid")}}));
|
||||
}
|
||||
|
||||
void metadataUsesDefaultLocaleAndExtractsSchema()
|
||||
{
|
||||
const QJsonObject metadata{
|
||||
{"id", QStringLiteral("EXAMPLE")},
|
||||
{"schemaVersion", 2},
|
||||
{"name", QJsonObject{{"default", QStringLiteral("Example plugin")}}},
|
||||
{"description", QJsonObject{{"default", QStringLiteral("Example description")}}},
|
||||
{"sql", QJsonArray{QStringLiteral("CREATE TABLE example (id INTEGER)")}},
|
||||
{"dependencies", QJsonArray{QStringLiteral("CORE")}}
|
||||
};
|
||||
|
||||
const MetaDataPtr result = IMetaDataPlugin::loadBaseMetaData(QJsonObject{{"MetaData", metadata}});
|
||||
|
||||
QVERIFY(result);
|
||||
QCOMPARE(result->getId(), QStringLiteral("EXAMPLE"));
|
||||
QCOMPARE(result->getName(), QStringLiteral("Example plugin"));
|
||||
QCOMPARE(result->getDescription(), QStringLiteral("Example description"));
|
||||
QCOMPARE(result->getSchemaVersion(), 2);
|
||||
QCOMPARE(result->getSchemas(), QStringList{QStringLiteral("CREATE TABLE example (id INTEGER)")});
|
||||
QCOMPARE(result->getDependsOn(), QStringList{QStringLiteral("CORE")});
|
||||
}
|
||||
|
||||
void metadataPrefersSystemLocale()
|
||||
{
|
||||
const QString locale = QLocale::system().name();
|
||||
const QJsonObject metadata{
|
||||
{"id", QStringLiteral("LOCALIZED")},
|
||||
{"name", QJsonObject{{"default", QStringLiteral("Fallback")}, {locale, QStringLiteral("Localized")}}},
|
||||
{"description", QJsonObject{{"default", QStringLiteral("Fallback description")}}}
|
||||
};
|
||||
|
||||
const MetaDataPtr result = IMetaDataPlugin::loadBaseMetaData(QJsonObject{{"MetaData", metadata}});
|
||||
|
||||
QVERIFY(result);
|
||||
QCOMPARE(result->getName(), QStringLiteral("Localized"));
|
||||
QCOMPARE(result->getDescription(), QStringLiteral("Fallback description"));
|
||||
}
|
||||
|
||||
void permissionDeniedWithoutUser()
|
||||
{
|
||||
PermissionEvaluator evaluator;
|
||||
QSignalSpy denied(&evaluator, &PermissionEvaluator::permissionDenied);
|
||||
|
||||
QVERIFY(!evaluator.hasPermission(QStringLiteral("SHOP"), QStringLiteral("READ")));
|
||||
QCOMPARE(denied.count(), 0);
|
||||
}
|
||||
|
||||
void administratorBypassesPermissionLookup()
|
||||
{
|
||||
auto user = QSharedPointer<User>::create();
|
||||
user->setIsAdmin(true);
|
||||
Context::instance().setCurrentUser(user);
|
||||
|
||||
PermissionEvaluator evaluator;
|
||||
QSignalSpy denied(&evaluator, &PermissionEvaluator::permissionDenied);
|
||||
|
||||
QVERIFY(evaluator.hasPermission(QStringLiteral("SHOP"), QStringLiteral("DELETE")));
|
||||
QCOMPARE(denied.count(), 0);
|
||||
}
|
||||
|
||||
void matchingRolePermissionIsGranted()
|
||||
{
|
||||
auto permission = QSharedPointer<Permission>::create();
|
||||
permission->setPluginId(QStringLiteral("SHOP"));
|
||||
permission->setPermissionName(QStringLiteral("READ"));
|
||||
|
||||
auto role = QSharedPointer<Role>::create();
|
||||
role->addPermission(permission);
|
||||
|
||||
auto user = QSharedPointer<User>::create();
|
||||
user->setIsAdmin(false);
|
||||
user->addRole(role);
|
||||
Context::instance().setCurrentUser(user);
|
||||
|
||||
PermissionEvaluator evaluator;
|
||||
QSignalSpy denied(&evaluator, &PermissionEvaluator::permissionDenied);
|
||||
|
||||
QVERIFY(evaluator.hasPermission(QStringLiteral("SHOP"), QStringLiteral("READ")));
|
||||
QCOMPARE(denied.count(), 0);
|
||||
}
|
||||
|
||||
void mismatchedPermissionIsDeniedAndEmitsSignal()
|
||||
{
|
||||
auto permission = QSharedPointer<Permission>::create();
|
||||
permission->setPluginId(QStringLiteral("SHOP"));
|
||||
permission->setPermissionName(QStringLiteral("READ"));
|
||||
|
||||
auto role = QSharedPointer<Role>::create();
|
||||
role->addPermission(permission);
|
||||
|
||||
auto user = QSharedPointer<User>::create();
|
||||
user->setIsAdmin(false);
|
||||
user->addRole(role);
|
||||
Context::instance().setCurrentUser(user);
|
||||
|
||||
PermissionEvaluator evaluator;
|
||||
QSignalSpy denied(&evaluator, &PermissionEvaluator::permissionDenied);
|
||||
|
||||
QVERIFY(!evaluator.hasPermission(QStringLiteral("SHOP"), QStringLiteral("DELETE")));
|
||||
QCOMPARE(denied.count(), 1);
|
||||
QCOMPARE(denied.takeFirst().at(0).toString(), QStringLiteral("DELETE"));
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
QTemporaryDir settingsDirectory;
|
||||
if (!settingsDirectory.isValid()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, settingsDirectory.path());
|
||||
|
||||
CoreTests tests;
|
||||
return QTest::qExec(&tests, argc, argv);
|
||||
}
|
||||
|
||||
#include "core_tests.moc"
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QSettings>
|
||||
#include <QTemporaryDir>
|
||||
#include <QtTest>
|
||||
|
||||
#include <QxOrm.h>
|
||||
|
||||
#include "context.h"
|
||||
#include "service.h"
|
||||
#include "../countryregister/data/countrydata.h"
|
||||
|
||||
class PersistenceTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void crudCycleOnTemporaryDatabase()
|
||||
{
|
||||
QTemporaryDir dir;
|
||||
QVERIFY(dir.isValid());
|
||||
const QString dbPath = dir.filePath(QStringLiteral("countries.db"));
|
||||
|
||||
qx::QxSqlDatabase::getSingleton()->setDriverName(QStringLiteral("QSQLITE"));
|
||||
qx::QxSqlDatabase::getSingleton()->setDatabaseName(dbPath);
|
||||
|
||||
const QSqlError createError = qx::dao::create_table<CountryData>();
|
||||
QVERIFY2(!createError.isValid(), qPrintable(createError.text()));
|
||||
QVERIFY(QFileInfo::exists(dbPath));
|
||||
|
||||
Service<CountryData> service;
|
||||
|
||||
auto country = QSharedPointer<CountryData>::create();
|
||||
country->setCode2(QStringLiteral("CZ"));
|
||||
country->setCode3(QStringLiteral("CZE"));
|
||||
country->setCzechName(QStringLiteral("Česko"));
|
||||
country->setEnglishName(QStringLiteral("Czechia"));
|
||||
|
||||
QSignalSpy errorSpy(&service, &Service<CountryData>::dbError);
|
||||
service.save(country);
|
||||
QCOMPARE(errorSpy.count(), 0);
|
||||
QVERIFY(country->id() > 0);
|
||||
|
||||
const QList<QSharedPointer<CountryData>> all = service.all();
|
||||
QCOMPARE(all.size(), 1);
|
||||
QCOMPARE(all.first()->code2(), QStringLiteral("CZ"));
|
||||
QCOMPARE(all.first()->czechName(), QStringLiteral("Česko"));
|
||||
|
||||
auto loaded = service.loadById(country->id());
|
||||
QVERIFY(!loaded.isNull());
|
||||
QCOMPARE(loaded->code3(), QStringLiteral("CZE"));
|
||||
|
||||
loaded->setCzechName(QStringLiteral("Česká republika"));
|
||||
service.update(loaded);
|
||||
QCOMPARE(errorSpy.count(), 0);
|
||||
|
||||
auto reloaded = service.loadById(country->id());
|
||||
QCOMPARE(reloaded->czechName(), QStringLiteral("Česká republika"));
|
||||
|
||||
service.erase(reloaded);
|
||||
QCOMPARE(errorSpy.count(), 0);
|
||||
QVERIFY(service.all().isEmpty());
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
QTemporaryDir settingsDirectory;
|
||||
if (!settingsDirectory.isValid()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, settingsDirectory.path());
|
||||
|
||||
PersistenceTests tests;
|
||||
return QTest::qExec(&tests, argc, argv);
|
||||
}
|
||||
|
||||
#include "persistence_tests.moc"
|
||||
@@ -0,0 +1,73 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QPluginLoader>
|
||||
#include <QtTest>
|
||||
|
||||
#include "imetadataplugin.h"
|
||||
#include "iplugin.h"
|
||||
|
||||
struct PluginExpectation
|
||||
{
|
||||
QString path;
|
||||
QString id;
|
||||
};
|
||||
|
||||
class PluginMetadataTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PluginMetadataTests(QList<PluginExpectation> plugins)
|
||||
: m_plugins(std::move(plugins))
|
||||
{
|
||||
}
|
||||
|
||||
private slots:
|
||||
void embeddedMetadataMatchesPluginContract()
|
||||
{
|
||||
for (const PluginExpectation &plugin : m_plugins) {
|
||||
QVERIFY2(QFileInfo::exists(plugin.path), qPrintable(plugin.path));
|
||||
|
||||
QPluginLoader loader(plugin.path);
|
||||
const QJsonObject metadata = loader.metaData();
|
||||
QVERIFY2(!metadata.isEmpty(), qPrintable(loader.errorString()));
|
||||
QCOMPARE(metadata.value(QStringLiteral("IID")).toString(), QString::fromLatin1(PluginInterface_iid));
|
||||
|
||||
const QJsonObject data = metadata.value(QStringLiteral("MetaData")).toObject();
|
||||
QVERIFY2(!data.isEmpty(), qPrintable(plugin.path));
|
||||
QCOMPARE(data.value(QStringLiteral("id")).toString(), plugin.id);
|
||||
QVERIFY(data.value(QStringLiteral("schemaVersion")).toInt() > 0);
|
||||
QVERIFY(data.value(QStringLiteral("sql")).isArray());
|
||||
QVERIFY(data.value(QStringLiteral("dependencies")).isArray());
|
||||
|
||||
const MetaDataPtr parsed = IMetaDataPlugin::loadBaseMetaData(metadata);
|
||||
QVERIFY(parsed);
|
||||
QCOMPARE(parsed->getId(), plugin.id);
|
||||
QCOMPARE(parsed->getSchemaVersion(), data.value(QStringLiteral("schemaVersion")).toInt());
|
||||
QCOMPARE(parsed->getSchemas().size(), data.value(QStringLiteral("sql")).toArray().size());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QList<PluginExpectation> m_plugins;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
if (argc < 3 || (argc - 1) % 2 != 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
QList<PluginExpectation> plugins;
|
||||
for (int index = 1; index < argc; index += 2) {
|
||||
plugins.append({QString::fromLocal8Bit(argv[index]), QString::fromLocal8Bit(argv[index + 1])});
|
||||
}
|
||||
|
||||
PluginMetadataTests tests(std::move(plugins));
|
||||
return QTest::qExec(&tests, 1, argv);
|
||||
}
|
||||
|
||||
#include "plugin_metadata_tests.moc"
|
||||
@@ -0,0 +1,67 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QtTest>
|
||||
|
||||
#include "data/accservice.h"
|
||||
|
||||
class ServicesTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void defaultsMatchExpectedInitialState()
|
||||
{
|
||||
AccService service;
|
||||
|
||||
QCOMPARE(service.price().toDouble(), 0.0);
|
||||
QVERIFY(service.active());
|
||||
QVERIFY(!service.salePossible());
|
||||
QCOMPARE(service.serviceType(), AccService::OTHER);
|
||||
QCOMPARE(service.vatType(), Enums::NONE);
|
||||
}
|
||||
|
||||
void priceRoundTripUsesFixedPointStorage()
|
||||
{
|
||||
AccService service;
|
||||
|
||||
service.setPrice(QDecDouble(19.9));
|
||||
|
||||
QVERIFY(qAbs(service.price().toDouble() - 19.9) < 0.0001);
|
||||
}
|
||||
|
||||
void priceRoundTripHandlesWholeAmounts()
|
||||
{
|
||||
AccService service;
|
||||
|
||||
service.setPrice(QDecDouble(250));
|
||||
|
||||
QCOMPARE(service.price().toDouble(), 250.0);
|
||||
}
|
||||
|
||||
void basicPropertiesRoundTrip()
|
||||
{
|
||||
AccService service;
|
||||
|
||||
service.setAccServiceName(QStringLiteral("Ubytování"));
|
||||
service.setAccServiceCode(QStringLiteral("UB-1"));
|
||||
service.setActive(false);
|
||||
service.setSalePossible(true);
|
||||
service.setServiceType(AccService::TENT);
|
||||
service.setVatType(Enums::FIRST_LOWER);
|
||||
|
||||
QCOMPARE(service.accServiceName(), QStringLiteral("Ubytování"));
|
||||
QCOMPARE(service.accServiceCode(), QStringLiteral("UB-1"));
|
||||
QVERIFY(!service.active());
|
||||
QVERIFY(service.salePossible());
|
||||
QCOMPARE(service.serviceType(), AccService::TENT);
|
||||
QCOMPARE(service.vatType(), Enums::FIRST_LOWER);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
ServicesTests tests;
|
||||
return QTest::qExec(&tests, argc, argv);
|
||||
}
|
||||
|
||||
#include "services_tests.moc"
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QtTest>
|
||||
|
||||
#include "data/voucher.h"
|
||||
|
||||
class ShopTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void defaultsMatchNewVoucherState()
|
||||
{
|
||||
Voucher voucher;
|
||||
|
||||
QCOMPARE(voucher.totalPrice().toDouble(), 0.0);
|
||||
QCOMPARE(voucher.status(), Voucher::NEW);
|
||||
QCOMPARE(voucher.eetStatus(), Voucher::EET_FOR_SEND);
|
||||
}
|
||||
|
||||
void totalPriceRoundTripUsesFixedPointStorage()
|
||||
{
|
||||
Voucher voucher;
|
||||
|
||||
voucher.setTotalPrice(QDecDouble(19.9));
|
||||
|
||||
QVERIFY(qAbs(voucher.totalPrice().toDouble() - 19.9) < 0.0001);
|
||||
}
|
||||
|
||||
void vatAmountIsDifferenceBetweenTotalAndBase()
|
||||
{
|
||||
Voucher voucher;
|
||||
|
||||
voucher.setTotalPriceVatHigh(QDecDouble(121));
|
||||
voucher.setPriceVatHigh(QDecDouble(100));
|
||||
|
||||
QVERIFY(qAbs(voucher.vatAmountHigh().toDouble() - 21.0) < 0.0001);
|
||||
}
|
||||
|
||||
void voucherSumAccumulatesPricesWithoutTruncation()
|
||||
{
|
||||
VoucherSum sum(0, 0);
|
||||
|
||||
sum.addPrice(QDecDouble(19.9));
|
||||
sum.addPrice(QDecDouble(0.1));
|
||||
|
||||
QVERIFY(qAbs(sum.totalPrice().toDouble() - 20.0) < 0.0001);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
ShopTests tests;
|
||||
return QTest::qExec(&tests, argc, argv);
|
||||
}
|
||||
|
||||
#include "shop_tests.moc"
|
||||
Reference in New Issue
Block a user