From 62a4abb9bf6551417130c3c6f9bba147930895ef Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Tue, 7 Oct 2025 20:56:33 +0200 Subject: cfg: New module Reads config files --- test/cfg.cc | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 test/cfg.cc (limited to 'test/cfg.cc') 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 +#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")); +} -- cgit v1.2.3-70-g09d2