// tests/test_config_updater.cpp — Verify universal config updater #include "../transport/config_updater.h" #include #include #define VERIFY(cond, msg) do { if (!(cond)) { qCritical("FAIL: %s", msg); abort(); } } while(0) static void test_new_file() { const char* path = "/tmp/test_cfg_new.ini"; QFile::remove(path); VERIFY(config_update_option(path, "global", "my_name", "testnode"), "new file write"); QFile f(path); VERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text), "new file open for read"); QString content = f.readAll(); f.close(); VERIFY(content.contains("[global]"), "new file has [global]"); VERIFY(content.contains("my_name=testnode"), "new file has my_name"); QFile::remove(path); } static void test_replace_existing() { const char* path = "/tmp/test_cfg_replace.ini"; { QFile f(path); VERIFY(f.open(QIODevice::WriteOnly | QIODevice::Text), "replace: create file"); f.write("[global]\nmy_name=oldname\nmy_id=abc\n\n[control]\naddr=1.2.3.4\n"); f.close(); } VERIFY(config_update_option(path, "global", "my_name", "newname"), "replace: update"); QFile f(path); VERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text), "replace: open for read"); QString content = f.readAll(); f.close(); VERIFY(!content.contains("my_name=oldname"), "replace: old value gone"); VERIFY(content.contains("my_name=newname"), "replace: new value present"); VERIFY(content.contains("my_id=abc"), "replace: my_id preserved"); VERIFY(content.contains("[control]"), "replace: [control] preserved"); VERIFY(content.contains("addr=1.2.3.4"), "replace: addr preserved"); QFile::remove(path); } static void test_replace_new_param_in_section() { const char* path = "/tmp/test_cfg_newparam.ini"; { QFile f(path); VERIFY(f.open(QIODevice::WriteOnly | QIODevice::Text), "newparam: create file"); f.write("[global]\nmy_name=test\n\n[control]\naddr=1.2.3.4\n"); f.close(); } VERIFY(config_update_option(path, "global", "new_param", "newval"), "newparam: insert"); QFile f(path); VERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text), "newparam: open for read"); QString content = f.readAll(); f.close(); VERIFY(content.contains("my_name=test"), "newparam: my_name preserved"); VERIFY(content.contains("new_param=newval"), "newparam: new_param inserted"); VERIFY(content.contains("[control]"), "newparam: [control] preserved"); QFile::remove(path); } static void test_append_mode() { const char* path = "/tmp/test_cfg_append.ini"; { QFile f(path); VERIFY(f.open(QIODevice::WriteOnly | QIODevice::Text), "append: create file"); f.write("[client:peer1]\nlink=srv:addr1:port1\nlink=srv:addr2:port2\n\n[global]\nname=x\n"); f.close(); } VERIFY(config_update_option(path, "client:peer1", "link", "srv:addr3:port3", CONFIG_UPDATE_APPEND), "append: add link"); QFile f(path); VERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text), "append: open for read"); QString content = f.readAll(); f.close(); VERIFY(content.contains("link=srv:addr1:port1"), "append: link1 preserved"); VERIFY(content.contains("link=srv:addr2:port2"), "append: link2 preserved"); VERIFY(content.contains("link=srv:addr3:port3"), "append: link3 added"); QFile::remove(path); } static void test_new_section() { const char* path = "/tmp/test_cfg_newsect.ini"; { QFile f(path); VERIFY(f.open(QIODevice::WriteOnly | QIODevice::Text), "newsect: create file"); f.write("[global]\nname=x\n"); f.close(); } VERIFY(config_update_option(path, "gui", "theme", "dark"), "newsect: add [gui]"); QFile f(path); VERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text), "newsect: open for read"); QString content = f.readAll(); f.close(); VERIFY(content.contains("[global]"), "newsect: [global] preserved"); VERIFY(content.contains("name=x"), "newsect: name preserved"); VERIFY(content.contains("[gui]"), "newsect: [gui] added"); VERIFY(content.contains("theme=dark"), "newsect: theme added"); QFile::remove(path); } int main() { test_new_file(); test_replace_existing(); test_replace_new_param_in_section(); test_append_mode(); test_new_section(); return 0; }