aboutsummaryrefslogtreecommitdiff
path: root/lib/configuration/test/parser.cpp
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2020-03-22 14:59:04 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2020-03-22 14:59:04 +0200
commit74870600fa54a48d4c1ce4b19861a9b0ce027fee (patch)
treed79eb50c18f1f62e937a1d1fe2e7180c7c14d06a /lib/configuration/test/parser.cpp
parentRemove ProfileInterface (diff)
downloadsmolbote-74870600fa54a48d4c1ce4b19861a9b0ce027fee.tar.xz
lib/configuration improvements
Configuration changes: - Configuration::value return type is now [[nodiscard]] - Configuration::value<T> is now a generic template that only works with the exact types of the underlying std::variant - Add Configuration::value<concept_value_t> for standard library types compatible with the types of std::variant - Add Configuration::shortcut<> placeholder, and QAction and QKeySequence specializations as a convenient way to set up shortcuts - Deprecate setShortcut - Add Configuration::read_file convenience member that takes file path as parameter Format changes: - Configuration files can now have sections, specified as [section name]. Section names are prepended to keys. Section names cannot be nested. - Configuration files can now have @@include directives, causing another file to be read as well. The included file is not treated as nested into a section, and will overwrite values previously set. Others: - add some tests for libconfiguration. QAction/QKeySequence require a QApplication be set up, so the test application may require running xorg/wayland. old coverage: lines: 15.6% (960 out of 6172) branches: 9.9% (1187 out of 12012) new coverage: lines: 17.1% (1067 out of 6254) branches: 11.0% (1388 out of 12644)
Diffstat (limited to 'lib/configuration/test/parser.cpp')
-rw-r--r--lib/configuration/test/parser.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/configuration/test/parser.cpp b/lib/configuration/test/parser.cpp
new file mode 100644
index 0000000..3ad64a5
--- /dev/null
+++ b/lib/configuration/test/parser.cpp
@@ -0,0 +1,126 @@
+#include "configuration.h"
+#include <QApplication>
+#include <cstdlib>
+#include <fstream>
+#include <gtest/gtest.h>
+#include <sstream>
+
+class ConfigurationTest : public ::testing::Test
+{
+protected:
+ void SetUp() override
+ {
+ conf.read_file(std::getenv("CONFIGFILE"));
+ }
+
+ Configuration conf{
+ { "name", std::string() },
+ { "over", std::string() },
+ { "other", std::string("not in cfg") }, // this entry is not in the conf file
+ { "comment", std::string() }, // commented out entry in the conf file
+ { "number", int(0) },
+ { "toggle", bool(false) },
+
+ { "main/name", std::string() },
+ { "main/number", int(0) },
+ { "main/toggle", bool(true) },
+
+ { "extra/name", std::string() },
+ { "extra/number", int(0) },
+ { "extra/toggle", bool(false) },
+ };
+
+ std::unique_ptr<Configuration> global_conf = std::make_unique<Configuration, std::initializer_list<std::pair<std::string, conf_value_t>>>({
+ { "name", std::string("global") },
+ { "number", int(123) },
+ { "toggle", bool(true) },
+
+ });
+};
+
+TEST_F(ConfigurationTest, NoSection)
+{
+ EXPECT_EQ(conf.value<std::string>("name").value(), "Top level");
+ EXPECT_EQ(conf.value<std::string>("other").value(), "not in cfg");
+ EXPECT_EQ(conf.value<std::string>("comment").value(), "");
+ EXPECT_EQ(conf.value<int>("number").value(), 12);
+ EXPECT_TRUE(conf.value<bool>("toggle").value());
+ EXPECT_FALSE(conf.value<int>("nullopt"));
+ EXPECT_FALSE(conf.value<bool>("nullopt"));
+ EXPECT_FALSE(conf.value<std::string>("nullopt"));
+}
+
+TEST_F(ConfigurationTest, TypeCasts)
+{
+ EXPECT_EQ(conf.value<std::string>("number").value(), "12");
+ EXPECT_EQ(conf.value<std::string>("toggle").value(), "true");
+ EXPECT_EQ(conf.value<std::string>("main/toggle").value(), "false");
+}
+
+TEST_F(ConfigurationTest, QtSpecialization)
+{
+ EXPECT_EQ(conf.value<QString>("name").value(), "Top level");
+ EXPECT_EQ(conf.value<QString>("number").value(), "12");
+ EXPECT_EQ(conf.value<QString>("toggle").value(), "true");
+ EXPECT_EQ(conf.value<QString>("main/toggle").value(), "false");
+ EXPECT_FALSE(conf.value<QString>("nullopt"));
+
+ EXPECT_EQ(conf.value<QStringList>("list").value(), QStringList({ "one", "two", "three", "for four" }));
+ EXPECT_FALSE(conf.value<QStringList>("nullopt"));
+}
+
+TEST_F(ConfigurationTest, QtShortcut)
+{
+ QAction action;
+ EXPECT_EQ(conf.shortcut<QAction>(action, "qt/shortcut").shortcut().toString(), "Ctrl+Q");
+ EXPECT_EQ(conf.shortcut<QAction>(action, "qt/nil").shortcut().toString(), "Ctrl+Q");
+
+ QKeySequence sequence;
+ EXPECT_EQ(conf.shortcut<QKeySequence>(sequence, "qt/shortcut").toString(), "Ctrl+Q");
+ EXPECT_EQ(conf.shortcut<QKeySequence>(sequence, "qt/nil").toString(), "Ctrl+Q");
+}
+
+TEST_F(ConfigurationTest, MainSection)
+{
+ EXPECT_EQ(conf.value<std::string>("main/name").value(), "Section Testing");
+ EXPECT_EQ(conf.value<int>("main/number").value(), 10);
+ EXPECT_FALSE(conf.value<bool>("main/toggle").value());
+}
+
+TEST_F(ConfigurationTest, ExtraSection)
+{
+ EXPECT_EQ(conf.value<std::string>("over").value(), "extra");
+ EXPECT_EQ(conf.value<std::string>("extra/name").value(), "extra section");
+ EXPECT_EQ(conf.value<int>("extra/number").value(), 12);
+ EXPECT_TRUE(conf.value<bool>("extra/toggle").value());
+}
+
+TEST_F(ConfigurationTest, GlobalInstance)
+{
+ std::stringstream output;
+
+ output << *global_conf;
+ EXPECT_EQ(output.str(), "name=global\nnumber=123\ntoggle=true\n") << "operator<< on global_conf before move";
+
+ Configuration::move_global(std::move(global_conf));
+ Configuration g;
+ EXPECT_TRUE(g.value<std::string>("name"));
+ EXPECT_EQ(g.value<std::string>("name").value(), "global");
+ EXPECT_TRUE(g.value<int>("number"));
+ EXPECT_EQ(g.value<int>("number").value(), 123);
+ EXPECT_TRUE(g.value<bool>("toggle"));
+ EXPECT_EQ(g.value<bool>("toggle").value(), true);
+ EXPECT_FALSE(g.value<std::string>("nullopt"));
+
+ output.str(std::string());
+ output << g;
+ EXPECT_EQ(output.str(), "name=global\nnumber=123\ntoggle=true\n") << "operator<< on global_conf after move";
+}
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}