/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "dusktest.h" #include "save/settings/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_resetsAudioMasterVolume(void **state) { savesettings_t settings; memoryZero(&settings, sizeof(settings)); settings.audioMasterVolume = 42.0f; saveSettingsInit(&settings); assert_true(settings.audioMasterVolume == 1.0f); } 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(); 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.audioMasterVolume = 2.5f; char_t *json; size_t len; errorret_t writeRet = settingsToJSON(&written, &json, &len); assert_true(errorIsOk(writeRet)); savesettings_t read; saveSettingsInit(&read); read.audioMasterVolume = -1.0f;// sentinel, should be overwritten errorret_t readRet = settingsFromJSON(&read, json); assert_true(errorIsOk(readRet)); assert_true(read.audioMasterVolume == 2.5f); free(json); } static void test_saveSettingsReadJSON_missingKeyUsesDefault(void **state) { savesettings_t settings; saveSettingsInit(&settings); settings.audioMasterVolume = 999.0f;// sentinel errorret_t ret = settingsFromJSON(&settings, "{\"version\":1}"); assert_true(errorIsOk(ret)); assert_true(settings.audioMasterVolume == 1.0f); } // ============================================================ // saveSettingsReadJSON - version enforcement // ============================================================ static void test_saveSettingsReadJSON_versionMissing_errors(void **state) { savesettings_t settings; saveSettingsInit(&settings); errorret_t ret = settingsFromJSON(&settings, "{}"); assert_true(errorIsNotOk(ret)); errorCatch(ret); } static void test_saveSettingsReadJSON_versionMismatch_errors(void **state) { savesettings_t settings; saveSettingsInit(&settings); errorret_t ret = settingsFromJSON(&settings, "{\"version\":999}"); assert_true(errorIsNotOk(ret)); errorCatch(ret); } int main(void) { assertInit(); const struct CMUnitTest tests[] = { cmocka_unit_test(test_saveSettingsInit_resetsAudioMasterVolume), 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_missingKeyUsesDefault), cmocka_unit_test(test_saveSettingsReadJSON_versionMissing_errors), cmocka_unit_test(test_saveSettingsReadJSON_versionMismatch_errors), }; return cmocka_run_group_tests(tests, NULL, NULL); }