summaryrefslogtreecommitdiff
path: root/test/cfg.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/cfg.cc')
-rw-r--r--test/cfg.cc190
1 files changed, 190 insertions, 0 deletions
diff --git a/test/cfg.cc b/test/cfg.cc
new file mode 100644
index 0000000..80ebba9
--- /dev/null
+++ b/test/cfg.cc
@@ -0,0 +1,190 @@
+#include "cfg.hh"
+
+#include "testdir.hh"
+#include "testenv.hh"
+
+#include <fstream>
+#include <gtest/gtest.h>
+#include <string>
+#include <vector>
+
+namespace {
+
+class ConfigTest : public TestEnv {
+ protected:
+ void SetUp() override { ASSERT_TRUE(dir_.good()); }
+
+ TestDir dir_;
+};
+
+} // namespace
+
+TEST_F(ConfigTest, empty) {
+ auto does_not_exist = dir_.path() / "does-not-exist";
+ std::vector<std::string> errors;
+ auto cfg = cfg::Config::load(does_not_exist.string(), errors);
+ ASSERT_TRUE(cfg);
+ EXPECT_EQ(1, errors.size());
+
+ EXPECT_FALSE(cfg->has(""));
+ EXPECT_FALSE(cfg->get("").has_value());
+
+ EXPECT_FALSE(cfg->has("foo"));
+ EXPECT_FALSE(cfg->get("foo").has_value());
+}
+
+TEST_F(ConfigTest, values) {
+ auto file = dir_.path() / "file";
+ {
+ std::ofstream out(file);
+ out << "# Comment\n"
+ << "key=value\n"
+ << " foo = bar \n"
+ << "i1 = 12\n"
+ << "b1 = true\n"
+ << "b2=FaLSe\n"
+ << "i2 = -12313\n";
+ }
+ std::vector<std::string> errors;
+ auto cfg = cfg::Config::load(file.string(), errors);
+ ASSERT_TRUE(cfg);
+ EXPECT_EQ(0, errors.size());
+
+ EXPECT_FALSE(cfg->has(""));
+ EXPECT_FALSE(cfg->get("").has_value());
+
+ EXPECT_TRUE(cfg->has("key"));
+ EXPECT_EQ("value", cfg->get("key").value_or(""));
+
+ EXPECT_TRUE(cfg->has("foo"));
+ EXPECT_EQ("bar", cfg->get("foo").value_or(""));
+ EXPECT_FALSE(cfg->get_int64("foo").has_value());
+
+ EXPECT_TRUE(cfg->has("i1"));
+ EXPECT_EQ("12", cfg->get("i1").value_or(""));
+ EXPECT_EQ(12, cfg->get_int64("i1").value_or(0));
+ EXPECT_EQ(12, cfg->get_uint64("i1").value_or(0));
+
+ EXPECT_TRUE(cfg->has("b1"));
+ EXPECT_EQ("true", cfg->get("b1").value_or(""));
+ EXPECT_TRUE(cfg->get_bool("b1").value_or(false));
+
+ EXPECT_TRUE(cfg->has("b2"));
+ EXPECT_EQ("FaLSe", cfg->get("b2").value_or(""));
+ EXPECT_FALSE(cfg->get_bool("b2").value_or(true));
+
+ EXPECT_TRUE(cfg->has("i2"));
+ EXPECT_EQ("-12313", cfg->get("i2").value_or(""));
+ EXPECT_EQ(-12313, cfg->get_int64("i2").value_or(0));
+ EXPECT_EQ(0, cfg->get_uint64("i2").value_or(0));
+}
+
+TEST_F(ConfigTest, bools) {
+ auto file = dir_.path() / "file";
+ {
+ std::ofstream out(file);
+ out << "key1=True\n"
+ << "key2=yES\n"
+ << "key3=false\n"
+ << "key4=NO\n"
+ << "key5=ja\n";
+ }
+ std::vector<std::string> errors;
+ auto cfg = cfg::Config::load(file.string(), errors);
+ ASSERT_TRUE(cfg);
+ EXPECT_EQ(0, errors.size());
+
+ EXPECT_TRUE(cfg->get_bool("key1").value_or(false));
+ EXPECT_TRUE(cfg->get_bool("key2").value_or(false));
+ EXPECT_FALSE(cfg->get_bool("key3").value_or(true));
+ EXPECT_FALSE(cfg->get_bool("key4").value_or(true));
+ EXPECT_FALSE(cfg->get_bool("key5").has_value());
+}
+
+TEST_F(ConfigTest, errors) {
+ auto file = dir_.path() / "file";
+ {
+ std::ofstream out(file);
+ out << "bad line\n"
+ << "key=value\n"
+ << "key=duplicate\n";
+ }
+ std::vector<std::string> errors;
+ auto cfg = cfg::Config::load(file.string(), errors);
+ ASSERT_TRUE(cfg);
+ EXPECT_EQ(2, errors.size());
+}
+
+TEST_F(ConfigTest, merge) {
+ auto dir1 = dir_.path() / "dir1";
+ auto dir2 = dir_.path() / "dir2";
+ auto dir3 = dir_.path() / "dir3";
+ std::filesystem::create_directory(dir1);
+ std::filesystem::create_directory(dir2);
+ std::filesystem::create_directory(dir3);
+ setenv("XDG_CONFIG_HOME", dir1);
+ setenv("XDG_CONFIG_DIRS", dir2.string() + ":" + dir3.string());
+ auto file1 = dir1 / "file";
+ auto file2 = dir2 / "file";
+ {
+ std::ofstream out(file2);
+ out << "key1 = value1\n"
+ << "key2 = value2\n";
+ }
+ {
+ std::ofstream out(file1);
+ out << "key1 = 12\n"
+ << "key3 = value3";
+ }
+ std::vector<std::string> errors;
+ auto cfg = cfg::Config::load("file", errors);
+ ASSERT_TRUE(cfg);
+ EXPECT_EQ(0, errors.size());
+
+ EXPECT_FALSE(cfg->has(""));
+ EXPECT_FALSE(cfg->get("").has_value());
+
+ EXPECT_TRUE(cfg->has("key1"));
+ EXPECT_EQ("12", cfg->get("key1").value_or(""));
+
+ EXPECT_TRUE(cfg->has("key2"));
+ EXPECT_EQ("value2", cfg->get("key2").value_or(""));
+
+ EXPECT_TRUE(cfg->has("key3"));
+ EXPECT_EQ("value3", cfg->get("key3").value_or(""));
+}
+
+TEST_F(ConfigTest, merge_errors) {
+ auto dir1 = dir_.path() / "dir1";
+ auto dir2 = dir_.path() / "dir2";
+ std::filesystem::create_directory(dir1);
+ std::filesystem::create_directory(dir2);
+ setenv("XDG_CONFIG_HOME", dir1);
+ setenv("XDG_CONFIG_DIRS", dir2);
+ auto file1 = dir1 / "file";
+ auto file2 = dir2 / "file";
+ {
+ std::ofstream out(file2);
+ out << "key1 = value1\n"
+ << "key2 = value2\n";
+ }
+ {
+ std::ofstream out(file1);
+ out << "invalid line";
+ }
+ std::vector<std::string> errors;
+ auto cfg = cfg::Config::load("file", errors);
+ ASSERT_TRUE(cfg);
+ EXPECT_EQ(1, errors.size());
+
+ EXPECT_FALSE(cfg->has(""));
+ EXPECT_FALSE(cfg->get("").has_value());
+
+ EXPECT_TRUE(cfg->has("key1"));
+ EXPECT_EQ("value1", cfg->get("key1").value_or(""));
+
+ EXPECT_TRUE(cfg->has("key2"));
+ EXPECT_EQ("value2", cfg->get("key2").value_or(""));
+
+ EXPECT_FALSE(cfg->has("key3"));
+}