#include "cfg.hh" #include "testdir.hh" #include "testenv.hh" #include #include #include #include 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 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 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 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 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 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 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")); }