feat(TOML & Glaze): YAML -> TOML
YAML is a horrid format with far too many edge cases. We have switched to TOML. Further, we have completly reworked the framework so that 1. There is no longer any global config state. Config objects now must be passed between scopes by the caller. This will introduce some more friction but whill also make order of initialization clear 2. Config objects are now strongly typed and there is a single sourth of truth for any given config object baked in using the some struct.
This commit is contained in:
@@ -7,38 +7,46 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "fourdst/config/config.h"
|
||||
#include "test_schema.h"
|
||||
|
||||
std::string EXAMPLE_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/config/example.yaml";
|
||||
|
||||
std::string get_good_example_file() {
|
||||
const char* source_root = getenv("MESON_SOURCE_ROOT");
|
||||
if (source_root == nullptr) {
|
||||
throw std::runtime_error("MESON_SOURCE_ROOT environment variable is not set.");
|
||||
}
|
||||
return std::string(source_root) + "/tests/config/example_config_files/example.good.toml";
|
||||
}
|
||||
|
||||
|
||||
enum class BAD_FILES {
|
||||
UNKNOWN_KEY,
|
||||
INVALID_TYPE,
|
||||
INCORRECT_ARRAY_SIZE
|
||||
};
|
||||
|
||||
std::string get_bad_example_file(BAD_FILES type) {
|
||||
const char* source_root = getenv("MESON_SOURCE_ROOT");
|
||||
if (source_root == nullptr) {
|
||||
throw std::runtime_error("MESON_SOURCE_ROOT environment variable is not set.");
|
||||
}
|
||||
switch (type) {
|
||||
case BAD_FILES::UNKNOWN_KEY:
|
||||
return std::string(source_root) + "/tests/config/example_config_files/example.unknownkey.toml";
|
||||
case BAD_FILES::INVALID_TYPE:
|
||||
return std::string(source_root) + "/tests/config/example_config_files/example.invalidtype.toml";
|
||||
case BAD_FILES::INCORRECT_ARRAY_SIZE:
|
||||
return std::string(source_root) + "/tests/config/example_config_files/example.incorrectarraysize.toml";
|
||||
}
|
||||
throw std::runtime_error("Invalid BAD_FILES type.");
|
||||
}
|
||||
|
||||
// std::string EXAMPLE_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/config/example.toml";
|
||||
/**
|
||||
* @file configTest.cpp
|
||||
* @brief Unit tests for the Config class.
|
||||
*/
|
||||
|
||||
class configTestPrivateAccessor {
|
||||
public:
|
||||
static bool callIsKeyInCache(fourdst::config::Config& config, const std::string& key) {
|
||||
return config.isKeyInCache(key);
|
||||
}
|
||||
|
||||
static int callCacheSize(fourdst::config::Config& config) {
|
||||
return config.configMap.size();
|
||||
}
|
||||
|
||||
static void callAddToCache(fourdst::config::Config& config, const std::string& key, const YAML::Node& node) {
|
||||
config.addToCache(key, node);
|
||||
}
|
||||
|
||||
static void callRegisterKeyNotFound(fourdst::config::Config& config, const std::string& key) {
|
||||
config.registerUnknownKey(key);
|
||||
}
|
||||
|
||||
static bool CheckIfKeyUnknown(fourdst::config::Config& config, const std::string& key) {
|
||||
if (std::find(config.unknownKeys.begin(), config.unknownKeys.end(), key) == config.unknownKeys.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Test suite for the Config class.
|
||||
@@ -49,64 +57,77 @@ class configTest : public ::testing::Test {};
|
||||
* @brief Test the constructor of the Config class.
|
||||
*/
|
||||
TEST_F(configTest, constructor) {
|
||||
EXPECT_NO_THROW(fourdst::config::Config::getInstance());
|
||||
EXPECT_NO_THROW(fourdst::config::Config<TestConfigSchema>());
|
||||
}
|
||||
|
||||
TEST_F(configTest, loadConfig) {
|
||||
fourdst::config::Config& config = fourdst::config::Config::getInstance();
|
||||
EXPECT_TRUE(config.loadConfig(EXAMPLE_FILENAME));
|
||||
TEST_F(configTest, load_good_file) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.load(get_good_example_file()));
|
||||
}
|
||||
|
||||
TEST_F(configTest, singletonTest) {
|
||||
fourdst::config::Config& config1 = fourdst::config::Config::getInstance();
|
||||
fourdst::config::Config& config2 = fourdst::config::Config::getInstance();
|
||||
EXPECT_EQ(&config1, &config2);
|
||||
TEST_F(configTest, load_unknown_key_file) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_THROW(cfg.load(get_bad_example_file(BAD_FILES::UNKNOWN_KEY)), exceptions::ConfigParseError);
|
||||
}
|
||||
|
||||
TEST_F(configTest, getTest) {
|
||||
fourdst::config::Config& config = fourdst::config::Config::getInstance();
|
||||
config.loadConfig(EXAMPLE_FILENAME);
|
||||
int maxIter = config.get<int>("opac:lowTemp:numeric:maxIter", 10);
|
||||
EXPECT_EQ(maxIter, 100);
|
||||
EXPECT_NE(maxIter, 10);
|
||||
|
||||
std::string logLevel = config.get<std::string>("logLevel", "DEBUG");
|
||||
EXPECT_EQ(logLevel, "INFO");
|
||||
EXPECT_NE(logLevel, "DEBUG");
|
||||
|
||||
float polytropicIndex = config.get<float>("poly:physics:index", 2);
|
||||
EXPECT_EQ(polytropicIndex, 1.5);
|
||||
EXPECT_NE(polytropicIndex, 2);
|
||||
|
||||
float polytropicIndex2 = config.get<float>("poly:physics:index2", 2.0);
|
||||
EXPECT_EQ(polytropicIndex2, 2.0);
|
||||
TEST_F(configTest, load_invalid_type_file) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_THROW(cfg.load(get_bad_example_file(BAD_FILES::INVALID_TYPE)), exceptions::ConfigParseError);
|
||||
}
|
||||
|
||||
TEST_F(configTest, secondSingletonTest) {
|
||||
fourdst::config::Config& config = fourdst::config::Config::getInstance();
|
||||
EXPECT_EQ(config.get<int>("opac:lowTemp:numeric:maxIter", 10), 100);
|
||||
TEST_F(configTest, load_incorrect_array_size_file) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_THROW(cfg.load(get_bad_example_file(BAD_FILES::INCORRECT_ARRAY_SIZE)), exceptions::ConfigParseError);
|
||||
}
|
||||
|
||||
TEST_F(configTest, isKeyInCacheTest) {
|
||||
fourdst::config::Config& config = fourdst::config::Config::getInstance();
|
||||
config.loadConfig(EXAMPLE_FILENAME);
|
||||
EXPECT_TRUE(configTestPrivateAccessor::callIsKeyInCache(config, "opac:lowTemp:numeric:maxIter"));
|
||||
EXPECT_FALSE(configTestPrivateAccessor::callIsKeyInCache(config, "opac:lowTemp:numeric:maxIter2"));
|
||||
TEST_F(configTest, check_value) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.load(get_good_example_file()));
|
||||
EXPECT_EQ(cfg->author, "Example Author");
|
||||
}
|
||||
|
||||
TEST_F(configTest, cacheSize) {
|
||||
fourdst::config::Config& config = fourdst::config::Config::getInstance();
|
||||
config.loadConfig(EXAMPLE_FILENAME);
|
||||
EXPECT_EQ(configTestPrivateAccessor::callCacheSize(config), 3);
|
||||
EXPECT_NE(configTestPrivateAccessor::callCacheSize(config), 4);
|
||||
config.get<std::string>("outputDir", "DEBUG");
|
||||
EXPECT_EQ(configTestPrivateAccessor::callCacheSize(config), 4);
|
||||
TEST_F(configTest, nested_values) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.load(get_good_example_file()));
|
||||
EXPECT_EQ(cfg->physics.convection, false);
|
||||
}
|
||||
|
||||
TEST_F(configTest, unknownKeyTest) {
|
||||
fourdst::config::Config& config = fourdst::config::Config::getInstance();
|
||||
config.loadConfig(EXAMPLE_FILENAME);
|
||||
config.get<int>("opac:lowTemp:numeric:random", 10);
|
||||
EXPECT_FALSE(configTestPrivateAccessor::CheckIfKeyUnknown(config, "opac:lowTemp:numeric:maxIter"));
|
||||
EXPECT_TRUE(configTestPrivateAccessor::CheckIfKeyUnknown(config, "opac:lowTemp:numeric:random"));
|
||||
TEST_F(configTest, override_default) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.load(get_good_example_file()));
|
||||
EXPECT_EQ(cfg->simulation.time_step, 0.01);
|
||||
}
|
||||
|
||||
TEST_F(configTest, array_values) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.load(get_good_example_file()));
|
||||
constexpr std::array<int, 3> expected = {1, 0, 1};
|
||||
EXPECT_EQ(cfg->physics.flags, expected);
|
||||
}
|
||||
|
||||
TEST_F(configTest, string_values) {
|
||||
using namespace fourdst::config;
|
||||
Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.load(get_good_example_file()));
|
||||
EXPECT_EQ(cfg->output.format, "csv");
|
||||
}
|
||||
|
||||
TEST_F(configTest, save_default) {
|
||||
using namespace fourdst::config;
|
||||
const Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.save("TestConfigSchema.toml"));
|
||||
}
|
||||
|
||||
TEST_F(configTest, save_schema) {
|
||||
using namespace fourdst::config;
|
||||
const Config<TestConfigSchema> cfg;
|
||||
EXPECT_NO_THROW(cfg.save_schema("./"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user