#include "AppConfigProvider.h" #include #include #include #include #include namespace { int gFailures = 0; void Expect(bool condition, const std::string& message) { if (condition) return; ++gFailures; std::cerr << "FAILED: " << message << "\n"; } std::filesystem::path WriteConfigFixture() { const std::filesystem::path path = std::filesystem::temp_directory_path() / "render-cadence-compositor-config-test.json"; std::ofstream output(path, std::ios::binary); output << "{\n" << " \"shaderLibrary\": \"test-shaders\",\n" << " \"serverPort\": 8181,\n" << " \"oscBindAddress\": \"127.0.0.1\",\n" << " \"oscPort\": 9100,\n" << " \"oscSmoothing\": 0.25,\n" << " \"inputVideoFormat\": \"720p\",\n" << " \"inputFrameRate\": \"50\",\n" << " \"outputVideoFormat\": \"2160p\",\n" << " \"outputFrameRate\": \"60\",\n" << " \"autoReload\": false,\n" << " \"maxTemporalHistoryFrames\": 8,\n" << " \"previewFps\": 24,\n" << " \"startupSettleMs\": 2500,\n" << " \"enableExternalKeying\": true\n" << "}\n"; return path; } void TestLoadsRuntimeHostConfig() { using namespace RenderCadenceCompositor; const std::filesystem::path path = WriteConfigFixture(); AppConfigProvider provider; std::string error; const bool loaded = provider.Load(path, error); const AppConfig& config = provider.Config(); Expect(loaded, "config loads"); Expect(error.empty(), "config load has no error"); Expect(provider.LoadedFromFile(), "provider records file load"); Expect(config.shaderLibrary == "test-shaders", "shader library loads"); Expect(config.http.preferredPort == 8181, "server port loads"); Expect(config.oscBindAddress == "127.0.0.1", "OSC bind address loads"); Expect(config.oscPort == 9100, "OSC port loads"); Expect(config.oscSmoothing == 0.25, "OSC smoothing loads"); Expect(config.inputVideoFormat == "720p", "input format loads"); Expect(config.inputFrameRate == "50", "input frame rate loads"); Expect(config.outputVideoFormat == "2160p", "output format loads"); Expect(config.outputFrameRate == "60", "output frame rate loads"); Expect(!config.autoReload, "auto reload loads"); Expect(config.maxTemporalHistoryFrames == 8, "history length loads"); Expect(config.previewFps == 24.0, "preview fps loads"); Expect(config.startupSettle == std::chrono::milliseconds(2500), "startup settle loads"); Expect(config.deckLink.externalKeyingEnabled, "external keying loads"); std::filesystem::remove(path); } void TestCommandLineOverrides() { using namespace RenderCadenceCompositor; AppConfigProvider provider; const char* argv[] = { "app.exe", "--shader", "solid-color", "--port", "8282" }; provider.ApplyCommandLine(5, const_cast(argv)); const AppConfig& config = provider.Config(); Expect(config.runtimeShaderId == "solid-color", "shader CLI override applies"); Expect(config.http.preferredPort == 8282, "port CLI override applies"); } void TestHelpers() { using namespace RenderCadenceCompositor; unsigned width = 0; unsigned height = 0; VideoFormatDimensions("720p", width, height); Expect(width == 1280 && height == 720, "720p dimensions resolve"); VideoFormatDimensions("2160p", width, height); Expect(width == 3840 && height == 2160, "2160p dimensions resolve"); const double duration = FrameDurationMillisecondsFromRateString("50"); Expect(duration > 19.9 && duration < 20.1, "frame duration parses numeric rate"); const std::filesystem::path configPath = FindConfigFile(); Expect(!configPath.empty(), "default config is discoverable from test working directory"); Expect(configPath.filename() == "runtime-host.json", "default config discovery returns runtime-host.json"); } } int main() { TestLoadsRuntimeHostConfig(); TestCommandLineOverrides(); TestHelpers(); if (gFailures != 0) { std::cerr << gFailures << " RenderCadenceCompositorAppConfigProvider test failure(s).\n"; return 1; } std::cout << "RenderCadenceCompositorAppConfigProvider tests passed.\n"; return 0; }