initial commit
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
#include "config/config_manager.h"
|
||||
#include "config/yaml_parser.h"
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
using namespace radiantwave::config;
|
||||
|
||||
TEST(YamlParserTest, ParseBasicYaml) {
|
||||
std::string yaml = R"(
|
||||
license_key: "KEY-12345"
|
||||
email_address: "test@example.com"
|
||||
provisioning_status: "READY"
|
||||
|
||||
audio:
|
||||
volume: 95
|
||||
output_device: "hdmi"
|
||||
|
||||
proclamation:
|
||||
scroll_speed: 2.5
|
||||
font_size: 40
|
||||
)";
|
||||
|
||||
YamlNode root = parseYaml(yaml);
|
||||
EXPECT_TRUE(root.hasChild("license_key"));
|
||||
EXPECT_EQ(root.getChild("license_key").asString(), "KEY-12345");
|
||||
EXPECT_EQ(root.getChild("email_address").asString(), "test@example.com");
|
||||
|
||||
EXPECT_TRUE(root.hasChild("audio"));
|
||||
EXPECT_EQ(root.getChild("audio").getChild("volume").asInt(), 95);
|
||||
EXPECT_EQ(root.getChild("audio").getChild("output_device").asString(), "hdmi");
|
||||
|
||||
EXPECT_TRUE(root.hasChild("proclamation"));
|
||||
EXPECT_FLOAT_EQ(root.getChild("proclamation").getChild("scroll_speed").asFloat(), 2.5f);
|
||||
EXPECT_EQ(root.getChild("proclamation").getChild("font_size").asInt(), 40);
|
||||
}
|
||||
|
||||
TEST(YamlParserTest, ConfigRoundTrip) {
|
||||
AppConfig original;
|
||||
original.license_key = "RW-TEST-99";
|
||||
original.email_address = "admin@radiantwave.com";
|
||||
original.audio.volume = 60;
|
||||
original.audio.dynamic_audio = false;
|
||||
original.proclamation.scroll_speed = 1.8f;
|
||||
|
||||
std::string serialized = serializeConfigToYaml(original);
|
||||
AppConfig parsed = parseConfigFromYaml(serialized);
|
||||
|
||||
EXPECT_EQ(parsed.license_key, original.license_key);
|
||||
EXPECT_EQ(parsed.email_address, original.email_address);
|
||||
EXPECT_EQ(parsed.audio.volume, original.audio.volume);
|
||||
EXPECT_EQ(parsed.audio.dynamic_audio, original.audio.dynamic_audio);
|
||||
EXPECT_FLOAT_EQ(parsed.proclamation.scroll_speed, original.proclamation.scroll_speed);
|
||||
}
|
||||
|
||||
TEST(ConfigManagerTest, DefaultGeneration) {
|
||||
std::string temp_path = (std::filesystem::temp_directory_path() / "test_rw_config1.yaml").string();
|
||||
if (std::filesystem::exists(temp_path)) {
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
ConfigManager manager;
|
||||
EXPECT_TRUE(manager.initialize(temp_path));
|
||||
|
||||
AppConfig cfg = manager.get();
|
||||
EXPECT_EQ(cfg.audio.volume, 80);
|
||||
EXPECT_EQ(cfg.audio.dynamic_audio, true);
|
||||
EXPECT_EQ(cfg.proclamation.font_size, 32);
|
||||
|
||||
EXPECT_TRUE(std::filesystem::exists(temp_path));
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
TEST(ConfigManagerTest, MergePreservesExistingValues) {
|
||||
std::string temp_path = (std::filesystem::temp_directory_path() / "test_rw_config2.yaml").string();
|
||||
|
||||
// Write partial config
|
||||
{
|
||||
std::ofstream file(temp_path);
|
||||
file << "license_key: \"MY-LICENSE\"\n";
|
||||
file << "audio:\n";
|
||||
file << " volume: 42\n";
|
||||
}
|
||||
|
||||
ConfigManager manager;
|
||||
EXPECT_TRUE(manager.initialize(temp_path));
|
||||
|
||||
AppConfig cfg = manager.get();
|
||||
// Preserved custom values
|
||||
EXPECT_EQ(cfg.license_key, "MY-LICENSE");
|
||||
EXPECT_EQ(cfg.audio.volume, 42);
|
||||
|
||||
// Default values populated for missing fields
|
||||
EXPECT_EQ(cfg.proclamation.font_size, 32);
|
||||
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
TEST(ConfigManagerTest, HotReloadWatcher) {
|
||||
std::string temp_path = (std::filesystem::temp_directory_path() / "test_rw_config3.yaml").string();
|
||||
if (std::filesystem::exists(temp_path)) {
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
ConfigManager manager;
|
||||
EXPECT_TRUE(manager.initialize(temp_path));
|
||||
|
||||
std::atomic<bool> reloaded{false};
|
||||
int new_font_size = 0;
|
||||
|
||||
manager.onChanged([&](const AppConfig& new_cfg) {
|
||||
new_font_size = new_cfg.proclamation.font_size;
|
||||
reloaded = true;
|
||||
});
|
||||
|
||||
// Pause briefly then write modified config to disk
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(600));
|
||||
|
||||
{
|
||||
std::ofstream file(temp_path, std::ios::out | std::ios::trunc);
|
||||
file << "proclamation:\n";
|
||||
file << " font_size: 48\n";
|
||||
}
|
||||
|
||||
// Wait for file watcher thread to pick up change
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (reloaded) break;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(reloaded);
|
||||
EXPECT_EQ(new_font_size, 48);
|
||||
|
||||
manager.shutdown();
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
Reference in New Issue
Block a user