/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "dusktest.h" #include "util/memory.h" #include "asset/asset.h" #include "input/input.h" #include "input/inputbutton.h" #include "input/inputbind.h" #include "script/scriptmanager.h" #include #include #include #ifndef DUSK_ASSETS_DIR #error "DUSK_ASSETS_DIR must be defined" #endif // Runs the real, shipped assets/scripts/input.js (read straight off disk, // not a copy embedded in this test) through the real require()/asset-zip // path, so this actually verifies what ships -- on whichever platform this // test binary itself was built for (Platform.current === "linux" here). static char_t *readFile(const char_t *relativePath) { char_t path[512]; snprintf(path, sizeof(path), "%s/%s", DUSK_ASSETS_DIR, relativePath); FILE *f = fopen(path, "rb"); assert_non_null(f); fseek(f, 0, SEEK_END); long size = ftell(f); fseek(f, 0, SEEK_SET); char_t *buf = (char_t *)memoryAllocate((size_t)size + 1); size_t read = fread(buf, 1, (size_t)size, f); fclose(f); buf[read] = '\0'; return buf; } static zip_t *g_zip = NULL; static int input_setup(void **state) { errorret_t ret = inputInit(); if(errorIsNotOk(ret)) { errorCatch(ret); return -1; } ret = scriptManagerInit(); if(errorIsNotOk(ret)) { errorCatch(ret); return -1; } zip_error_t err; zip_error_init(&err); zip_source_t *write_src = zip_source_buffer_create(NULL, 0, 1, &err); if(!write_src) return -1; zip_t *za = zip_open_from_source(write_src, ZIP_TRUNCATE, &err); if(!za) { zip_source_free(write_src); return -1; } char_t *inputJsSrc = readFile("scripts/input.js"); zip_source_t *s = zip_source_buffer(za, inputJsSrc, strlen(inputJsSrc), 0); if(zip_file_add(za, "scripts/input.js", s, ZIP_FL_OVERWRITE) < 0) { zip_close(za); return -1; } zip_source_keep(write_src); if(zip_close(za) != 0) { zip_source_free(write_src); return -1; } memoryFree(inputJsSrc); zip_stat_t zs; memset(&zs, 0, sizeof(zs)); if(zip_source_stat(write_src, &zs) != 0 || !(zs.valid & ZIP_STAT_SIZE)) { zip_source_free(write_src); return -1; } void *zipbuf = malloc((size_t)zs.size); if(!zipbuf) { zip_source_free(write_src); return -1; } if(zip_source_open(write_src) != 0) { free(zipbuf); zip_source_free(write_src); return -1; } zip_source_read(write_src, zipbuf, (zip_uint64_t)zs.size); zip_source_close(write_src); zip_source_free(write_src); zip_error_init(&err); zip_source_t *read_src = zip_source_buffer_create( zipbuf, (zip_uint64_t)zs.size, 1, &err ); if(!read_src) { free(zipbuf); return -1; } g_zip = zip_open_from_source(read_src, 0, &err); if(!g_zip) { zip_source_free(read_src); return -1; } ASSET.zip = g_zip; return 0; } static int input_teardown(void **state) { errorret_t ret = scriptManagerDispose(); if(errorIsNotOk(ret)) errorCatch(ret); if(g_zip) { zip_close(g_zip); g_zip = NULL; } ASSET.zip = NULL; return 0; } static void test_real_input_js_binds_linux_defaults(void **state) { errorret_t ret = scriptManagerExecFile("scripts/input.js", NULL); assert_true(errorIsOk(ret)); inputbuttondata_t *data; data = inputButtonGetData(inputButtonGetByName("W")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_UP); data = inputButtonGetData(inputButtonGetByName("ESCAPE")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_RAGEQUIT); data = inputButtonGetData(inputButtonGetByName("`")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_CONSOLE); data = inputButtonGetData(inputButtonGetByName("GAMEPAD_A")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_ACCEPT); data = inputButtonGetData(inputButtonGetByName("GAMEPAD_LSTICK_UP")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_UP); data = inputButtonGetData(inputButtonGetByName("MOUSE_X")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_POINTERX); data = inputButtonGetData(inputButtonGetByName("MOUSE_Y")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_POINTERY); } int main(void) { assertInit(); const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown( test_real_input_js_binds_linux_defaults, input_setup, input_teardown ), }; return cmocka_run_group_tests(tests, NULL, NULL); }