Files
radiantwave/tests/test_config.cpp
T
2026-08-07 14:51:41 -05:00

139 lines
4.2 KiB
C++

#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);
}