/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "dusktest.h" #include "save/savesettings.h" #include "save/savejson.h" #include "util/memory.h" #include #include // ============================================================ // Helpers - wrap the writeInit/readInit macros (which can only be used // inside a function returning errorret_t) so tests can call them plainly. // ============================================================ static errorret_t settingsToJSON( savesettings_t *settings, char_t **outJson, size_t *outLen ) { writeInit(); errorret_t writeResult = saveSettingsWriteJSON(settings, doc, object); if(errorIsNotOk(writeResult)) { yyjson_mut_doc_free(doc); errorChain(writeResult); } *outJson = yyjson_mut_write(doc, 0, outLen); yyjson_mut_doc_free(doc); assertNotNull(*outJson, "Failed to write settings JSON"); errorOk(); } static errorret_t settingsFromJSON(savesettings_t *settings, const char_t *json) { readInit(json, strlen(json)); errorret_t readResult = saveSettingsReadJSON(settings, object); yyjson_doc_free(jsonDoc); errorChain(readResult); errorOk(); } // ============================================================ // saveSettingsInit // ============================================================ static void test_saveSettingsInit_zeroesSomeSetting(void **state) { savesettings_t settings; memoryZero(&settings, sizeof(settings)); settings.someSetting = 42; saveSettingsInit(&settings); assert_int_equal(settings.someSetting, 0); } static void test_saveSettingsInit_nullAsserts(void **state) { expect_assert_failure(saveSettingsInit(NULL)); } // ============================================================ // saveSettingsWriteJSON / saveSettingsReadJSON // ============================================================ static void test_saveSettingsWriteJSON_nullAsserts(void **state) { savesettings_t settings; saveSettingsInit(&settings); writeInit(); expect_assert_failure(saveSettingsWriteJSON(NULL, doc, object)); expect_assert_failure(saveSettingsWriteJSON(&settings, NULL, object)); expect_assert_failure(saveSettingsWriteJSON(&settings, doc, NULL)); yyjson_mut_doc_free(doc); } static void test_saveSettingsReadJSON_nullAsserts(void **state) { savesettings_t settings; saveSettingsInit(&settings); writeInit(); yyjson_mut_obj_add_int(doc, object, "someSetting", 1); size_t len; char_t *json = yyjson_mut_write(doc, 0, &len); yyjson_mut_doc_free(doc); assert_non_null(json); yyjson_doc *readDoc = yyjson_read(json, len, 0); yyjson_val *readObject = yyjson_doc_get_root(readDoc); expect_assert_failure(saveSettingsReadJSON(NULL, readObject)); expect_assert_failure(saveSettingsReadJSON(&settings, NULL)); yyjson_doc_free(readDoc); free(json); } static void test_saveSettingsWriteReadJSON_roundTrip(void **state) { savesettings_t written; saveSettingsInit(&written); written.someSetting = 12345; char_t *json; size_t len; errorret_t writeRet = settingsToJSON(&written, &json, &len); assert_true(errorIsOk(writeRet)); savesettings_t read; saveSettingsInit(&read); read.someSetting = -1;// sentinel, should be overwritten errorret_t readRet = settingsFromJSON(&read, json); assert_true(errorIsOk(readRet)); assert_int_equal(read.someSetting, 12345); free(json); } static void test_saveSettingsReadJSON_missingKeyDefaultsToZero(void **state) { savesettings_t settings; saveSettingsInit(&settings); settings.someSetting = 999;// sentinel errorret_t ret = settingsFromJSON(&settings, "{}"); assert_true(errorIsOk(ret)); assert_int_equal(settings.someSetting, 0); } int main(void) { assertInit(); const struct CMUnitTest tests[] = { cmocka_unit_test(test_saveSettingsInit_zeroesSomeSetting), cmocka_unit_test(test_saveSettingsInit_nullAsserts), cmocka_unit_test(test_saveSettingsWriteJSON_nullAsserts), cmocka_unit_test(test_saveSettingsReadJSON_nullAsserts), cmocka_unit_test(test_saveSettingsWriteReadJSON_roundTrip), cmocka_unit_test(test_saveSettingsReadJSON_missingKeyDefaultsToZero), }; return cmocka_run_group_tests(tests, NULL, NULL); }