summaryrefslogtreecommitdiff
path: root/tests/yaml
diff options
context:
space:
mode:
Diffstat (limited to 'tests/yaml')
-rw-r--r--tests/yaml/data/cache1.yaml13
-rw-r--r--tests/yaml/data/cache2.yaml14
-rw-r--r--tests/yaml/data/test.yaml45
-rw-r--r--tests/yaml/tst_yaml.cpp340
-rw-r--r--tests/yaml/yaml.pro12
5 files changed, 424 insertions, 0 deletions
diff --git a/tests/yaml/data/cache1.yaml b/tests/yaml/data/cache1.yaml
new file mode 100644
index 00000000..b3fcddb9
--- /dev/null
+++ b/tests/yaml/data/cache1.yaml
@@ -0,0 +1,13 @@
+name: cache1
+file: ${FILE}
+
+## content for a merge test
+#bool: true
+#list: [ 1, 2 ]
+#map:
+# key1: value1
+# key2: value2
+# key3:
+# key31: value31
+# key32: value32
+# key4: 4
diff --git a/tests/yaml/data/cache2.yaml b/tests/yaml/data/cache2.yaml
new file mode 100644
index 00000000..8ce7bae3
--- /dev/null
+++ b/tests/yaml/data/cache2.yaml
@@ -0,0 +1,14 @@
+name: cache2
+file: ${FILE}
+
+## content for a merge test
+#bool: false
+#list: [ 3, 4, 5 ]
+#map:
+# key1: value1
+# key2: not-value2
+# key3:
+# key31: [ 5, 6 ]
+# key32: not-value32
+# key33: true
+# key5: 5
diff --git a/tests/yaml/data/test.yaml b/tests/yaml/data/test.yaml
new file mode 100644
index 00000000..b16e3d39
--- /dev/null
+++ b/tests/yaml/data/test.yaml
@@ -0,0 +1,45 @@
+formatVersion: 42
+formatType: testfile
+---
+dec: 10
+hex: 0x10
+oct: 010
+bin: 0b10
+float1: 10.10
+float2: 0.10
+float3: .10
+number-separators: 1_234_567
+bool-true: true
+bool-yes: yes
+bool-false: false
+bool-no: no
+null-literal: null
+null-tilde: ~
+string-unquoted: unquoted
+string-singlequoted: 'singlequoted'
+string-doublequoted: "doublequoted"
+list-int:
+- 1
+- 2
+- 3
+list-mixed:
+- 1
+- two
+- [yes, ~]
+map1:
+ a: 1
+ b: two
+ c: [ 1, 2, 3]
+
+extended:
+ ext-string: 'ext string'
+
+stringlist-string: string
+stringlist-list1: [ string ]
+stringlist-list2: [ string1, string2 ]
+
+list-of-maps:
+- index: 1
+ name: '1'
+- index: 2
+ name: '2'
diff --git a/tests/yaml/tst_yaml.cpp b/tests/yaml/tst_yaml.cpp
new file mode 100644
index 00000000..1b53e533
--- /dev/null
+++ b/tests/yaml/tst_yaml.cpp
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Application Manager.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtTest>
+
+#include "qtyaml.h"
+#include "configcache.h"
+#include "exception.h"
+#include "global.h"
+
+QT_USE_NAMESPACE_AM
+
+class tst_Yaml : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_Yaml();
+
+private slots:
+ void parser();
+ void documentParser();
+ void cache();
+ void mergedCache();
+};
+
+
+tst_Yaml::tst_Yaml()
+{ }
+
+void tst_Yaml::parser()
+{
+ static const QVariant vnull = QVariant::fromValue(nullptr);
+
+ QVector<QPair<const char *, QVariant>> tests = {
+ { "dec", QVariant::fromValue<int>(10) },
+ { "hex", QVariant::fromValue<int>(16) },
+ { "bin", QVariant::fromValue<int>(2) },
+ { "oct", QVariant::fromValue<int>(8) },
+ { "float1", QVariant::fromValue<double>(10.1) },
+ { "float2", QVariant::fromValue<double>(.1) },
+ { "float3", QVariant::fromValue<double>(.1) },
+ { "number-separators", QVariant::fromValue<int>(1234567) },
+ { "bool-true", true },
+ { "bool-yes", true },
+ { "bool-false", false },
+ { "bool-no", false },
+ { "null-literal", vnull },
+ { "null-tilde", vnull },
+ { "string-unquoted", QVariant::fromValue<QString>("unquoted") },
+ { "string-singlequoted", QVariant::fromValue<QString>("singlequoted") },
+ { "string-doublequoted", QVariant::fromValue<QString>("doublequoted") },
+ { "list-int", QVariantList { 1, 2, 3 } },
+ { "list-mixed", QVariantList { 1, "two", QVariantList { true, vnull } } },
+ { "map1", QVariantMap { { "a", 1 }, { "b", "two" }, { "c", QVariantList { 1, 2, 3 } } } }
+ };
+
+ try {
+ QFile f(":/data/test.yaml");
+ QVERIFY2(f.open(QFile::ReadOnly), qPrintable(f.errorString()));
+ QByteArray ba = f.readAll();
+ QVERIFY(!ba.isEmpty());
+ YamlParser p(ba);
+ auto header = p.parseHeader();
+
+ QCOMPARE(header.first, "testfile");
+ QCOMPARE(header.second, 42);
+
+ QVERIFY(p.nextDocument());
+
+ YamlParser::Fields fields;
+ for (const auto &pair : tests) {
+ YamlParser::FieldType type = YamlParser::Scalar;
+ if (pair.second.type() == QVariant::List)
+ type = YamlParser::List;
+ else if (pair.second.type() == QVariant::Map)
+ type = YamlParser::Map;
+ QVariant value = pair.second;
+
+ fields.emplace_back(pair.first, true, type, [type, value](YamlParser *p) {
+ switch (type) {
+ case YamlParser::Scalar: {
+ QVERIFY(p->isScalar());
+ QVariant v = p->parseScalar();
+ QCOMPARE(int(v.type()), int(value.type()));
+ QVERIFY(v == value);
+ break;
+ }
+ case YamlParser::List: {
+ QVERIFY(p->isList());
+ QVariantList vl = p->parseList();
+ QVERIFY(vl == value.toList());
+ break;
+ }
+ case YamlParser::Map: {
+ QVERIFY(p->isMap());
+ QVariantMap vm = p->parseMap();
+ QVERIFY(vm == value.toMap());
+ break;
+ }
+ }
+ });
+ }
+ fields.emplace_back("extended", true, YamlParser::Map, [](YamlParser *p) {
+ YamlParser::Fields extFields = {
+ { "ext-string", true, YamlParser::Scalar, [](YamlParser *p) {
+ QVERIFY(p->isScalar());
+ QVariant v = p->parseScalar();
+ QCOMPARE(v.type(), QVariant::String);
+ QCOMPARE(v.toString(), "ext string");
+ } }
+ };
+ p->parseFields(extFields);
+ });
+
+ fields.emplace_back("stringlist-string", true, YamlParser::Scalar | YamlParser::List, [](YamlParser *p) {
+ QCOMPARE(p->parseStringOrStringList(), QStringList { "string" });
+ });
+ fields.emplace_back("stringlist-list1", true, YamlParser::Scalar | YamlParser::List, [](YamlParser *p) {
+ QCOMPARE(p->parseStringOrStringList(), QStringList { "string" });
+ });
+ fields.emplace_back("stringlist-list2", true, YamlParser::Scalar | YamlParser::List, [](YamlParser *p) {
+ QCOMPARE(p->parseStringOrStringList(), QStringList({ "string1", "string2" }));
+ });
+
+ fields.emplace_back("list-of-maps", true, YamlParser::List, [](YamlParser *p) {
+ int index = 0;
+ p->parseList([&index](YamlParser *p) {
+ ++index;
+ YamlParser::Fields lomFields = {
+ { "index", true, YamlParser::Scalar, [&index](YamlParser *p) {
+ QCOMPARE(p->parseScalar().toInt(), index);
+ } },
+ { "name", true, YamlParser::Scalar, [&index](YamlParser *p) {
+ QCOMPARE(p->parseScalar().toString(), QString::number(index));
+ } }
+ };
+ p->parseFields(lomFields);
+ });
+ QCOMPARE(index, 2);
+ });
+
+ p.parseFields(fields);
+
+ QVERIFY(!p.nextDocument());
+
+ } catch (const Exception &e) {
+ QVERIFY2(false, e.what());
+ }
+}
+
+void tst_Yaml::documentParser()
+{
+ static const QVariant vnull = QVariant::fromValue(nullptr);
+
+ try {
+ QFile f(":/data/test.yaml");
+ QVERIFY2(f.open(QFile::ReadOnly), qPrintable(f.errorString()));
+ QByteArray ba = f.readAll();
+ QVERIFY(!ba.isEmpty());
+ QVector<QVariant> docs = YamlParser::parseAllDocuments(ba);
+ QCOMPARE(docs.size(), 2);
+ QCOMPARE(docs.at(0).toMap().size(), 2);
+
+ QVariantMap header = {
+ { "formatVersion", 42 }, { "formatType", "testfile" }
+ };
+
+ QVariantMap main = {
+ { "dec", 10 },
+ { "hex", 16 },
+ { "bin", 2 },
+ { "oct", 8 },
+ { "float1", 10.1 },
+ { "float2", .1 },
+ { "float3", .1 },
+ { "number-separators", 1234567 },
+ { "bool-true", true },
+ { "bool-yes", true },
+ { "bool-false", false },
+ { "bool-no", false },
+ { "null-literal", vnull },
+ { "null-tilde", vnull },
+ { "string-unquoted", "unquoted" },
+ { "string-singlequoted", "singlequoted" },
+ { "string-doublequoted", "doublequoted" },
+ { "list-int", QVariantList { 1, 2, 3 } },
+ { "list-mixed", QVariantList { 1, qSL("two"), QVariantList { true, vnull } } },
+ { "map1", QVariantMap { { "a", 1 }, { "b", "two" }, { "c", QVariantList { 1, 2, 3 } } } },
+
+
+ { "extended", QVariantMap { { "ext-string", "ext string" } } },
+
+ { "stringlist-string", "string" },
+ { "stringlist-list1", QVariantList { "string" } },
+ { "stringlist-list2", QVariantList { "string1", "string2" } },
+
+ { "list-of-maps", QVariantList { QVariantMap { { "index", 1 }, { "name", "1" } },
+ QVariantMap { { "index", 2 }, { "name", "2" } } } }
+ };
+
+ QCOMPARE(header, docs.at(0).toMap());
+ QCOMPARE(main, docs.at(1).toMap());
+
+ } catch (const Exception &e) {
+ QVERIFY2(false, e.what());
+ }
+}
+struct CacheTest
+{
+ QString name;
+ QString file;
+};
+
+// GCC < 7 bug, currently still in RHEL7, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
+// this should simply be:
+// template<> class QT_PREPEND_NAMESPACE_AM(ConfigCacheAdaptor<CacheTest>)
+
+QT_BEGIN_NAMESPACE_AM
+template<> class ConfigCacheAdaptor<CacheTest>
+{
+public:
+ CacheTest *loadFromSource(QIODevice *source, const QString &fileName)
+ {
+ QScopedPointer<CacheTest> ct(new CacheTest);
+ YamlParser p(source->readAll(), fileName);
+ p.nextDocument();
+ p.parseFields({ { "name", true, YamlParser::Scalar, [&ct](YamlParser *p) {
+ ct->name = p->parseScalar().toString(); } },
+ { "file", true, YamlParser::Scalar, [&ct](YamlParser *p) {
+ ct->file = p->parseScalar().toString(); } }
+ });
+ return ct.take();
+ }
+ CacheTest *loadFromCache(QDataStream &ds)
+ {
+ CacheTest *ct = new CacheTest;
+ ds >> ct->name >> ct->file;
+ return ct;
+ }
+ void saveToCache(QDataStream &ds, const CacheTest *ct)
+ {
+ ds << ct->name << ct->file;
+ }
+
+ void merge(CacheTest *ct1, const CacheTest *ct2)
+ {
+ ct1->name = ct2->name;
+ ct1->file = ct1->file + qSL(",") + ct2->file;
+ }
+ void preProcessSourceContent(QByteArray &sourceContent, const QString &fileName)
+ {
+ sourceContent.replace("${FILE}", fileName.toUtf8());
+ }
+ QStringList *warnings;
+};
+QT_END_NAMESPACE_AM
+
+void tst_Yaml::cache()
+{
+ QStringList files = { ":/data/cache1.yaml", ":/data/cache2.yaml" };
+ QStringList warnings;
+
+ for (int step = 0; step < 2; ++step) {
+ try {
+ ConfigCache<CacheTest> cache(files, "cache-test", step == 0 ? AbstractConfigCache::ClearCache
+ : AbstractConfigCache::None);
+ cache.parse(&warnings);
+ QVERIFY2(warnings.isEmpty(), qPrintable(warnings.join(qSL("\n"))));
+ CacheTest *ct1 = cache.takeResult(0);
+ QVERIFY(ct1);
+ QCOMPARE(ct1->name, "cache1");
+ QCOMPARE(ct1->file, ":/data/cache1.yaml");
+ CacheTest *ct2 = cache.takeResult(1);
+ QVERIFY(ct2);
+ QCOMPARE(ct2->name, "cache2");
+ QCOMPARE(ct2->file, ":/data/cache2.yaml");
+ } catch (const Exception &e) {
+ QVERIFY2(false, e.what());
+ }
+ }
+}
+
+void tst_Yaml::mergedCache()
+{
+ QStringList files = { ":/data/cache1.yaml", ":/data/cache2.yaml" };
+ QStringList warnings;
+
+ for (int step = 0; step < 4; ++step) {
+ AbstractConfigCache::Options options = AbstractConfigCache::MergedResult;
+ if (step % 2 == 0)
+ options |= AbstractConfigCache::ClearCache;
+ if (step == 2)
+ std::reverse(files.begin(), files.end());
+
+ try {
+ ConfigCache<CacheTest> cache(files, "cache-test", options);
+ cache.parse(&warnings);
+ QVERIFY2(warnings.isEmpty(), qPrintable(warnings.join(qSL("\n"))));
+ CacheTest *ct = cache.takeMergedResult();
+ QVERIFY(ct);
+ QCOMPARE(ct->name, QFileInfo(files.last()).baseName());
+ QCOMPARE(ct->file, files.join(qSL(",")));
+ } catch (const Exception &e) {
+ QVERIFY2(false, e.what());
+ }
+ }
+}
+
+QTEST_MAIN(tst_Yaml)
+
+#include "tst_yaml.moc"
diff --git a/tests/yaml/yaml.pro b/tests/yaml/yaml.pro
new file mode 100644
index 00000000..5cc4bbb5
--- /dev/null
+++ b/tests/yaml/yaml.pro
@@ -0,0 +1,12 @@
+TARGET = tst_yaml
+
+include($$PWD/../tests.pri)
+
+QT *= appman_common-private
+
+SOURCES += tst_yaml.cpp
+
+RESOURCES += \
+ data/test.yaml \
+ data/cache1.yaml \
+ data/cache2.yaml \