/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "dusktest.h" #include "script/scriptmanager.h" #include "script/module/modulebase.h" #include "input/input.h" #include "input/inputbutton.h" #include "input/inputbind.h" 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; } return 0; } static int input_teardown(void **state) { errorret_t ret = scriptManagerDispose(); if(errorIsNotOk(ret)) errorCatch(ret); return 0; } static void test_inputbind_exposes_action_ordinals(void **state) { jerry_value_t result; errorret_t ret = scriptManagerExec("InputBind.UP;", &result); assert_true(errorIsOk(ret)); assert_true(jerry_value_is_number(result)); assert_int_equal(moduleBaseValueInt(result), (int32_t)INPUT_BIND_UP); jerry_value_free(result); ret = scriptManagerExec("InputBind.ACCEPT;", &result); assert_true(errorIsOk(ret)); assert_int_equal(moduleBaseValueInt(result), (int32_t)INPUT_BIND_ACCEPT); jerry_value_free(result); } static void test_inputbutton_exposes_platform_button_names(void **state) { jerry_value_t result; errorret_t ret = scriptManagerExec("InputButton.UP;", &result); assert_true(errorIsOk(ret)); assert_true(jerry_value_is_string(result)); char_t buf[16]; moduleBaseToString(result, buf, sizeof(buf)); assert_string_equal(buf, "UP"); jerry_value_free(result); } static void test_input_bind_updates_button_action(void **state) { jerry_value_t result; errorret_t ret = scriptManagerExec( "Input.bind(InputButton.UP, InputBind.ACCEPT);", &result ); assert_true(errorIsOk(ret)); jerry_value_free(result); inputbuttondata_t *data = inputButtonGetData(inputButtonGetByName("UP")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_ACCEPT); } static void test_input_bind_accepts_plain_string(void **state) { // InputButton.* values are just the button's own name string, so a bare // string works identically -- confirms Input.bind() doesn't require the // constant object. jerry_value_t result; errorret_t ret = scriptManagerExec( "Input.bind('down', InputBind.CANCEL);", &result ); assert_true(errorIsOk(ret)); jerry_value_free(result); inputbuttondata_t *data = inputButtonGetData(inputButtonGetByName("DOWN")); assert_non_null(data); assert_int_equal(data->action, INPUT_BIND_CANCEL); } static void test_input_query_functions_default_to_zero(void **state) { // No inputUpdate() has run (it would touch real SDL/platform input state, // unavailable in this headless test), so every action still reads its // inputInit()-zeroed default. jerry_value_t result; errorret_t ret = scriptManagerExec("Input.isDown(InputBind.UP);", &result); assert_true(errorIsOk(ret)); assert_false(jerry_value_is_true(result)); jerry_value_free(result); ret = scriptManagerExec("Input.wasDown(InputBind.UP);", &result); assert_true(errorIsOk(ret)); assert_false(jerry_value_is_true(result)); jerry_value_free(result); ret = scriptManagerExec("Input.pressed(InputBind.UP);", &result); assert_true(errorIsOk(ret)); assert_false(jerry_value_is_true(result)); jerry_value_free(result); ret = scriptManagerExec("Input.released(InputBind.UP);", &result); assert_true(errorIsOk(ret)); assert_false(jerry_value_is_true(result)); jerry_value_free(result); ret = scriptManagerExec("Input.value(InputBind.UP);", &result); assert_true(errorIsOk(ret)); assert_true(jerry_value_is_number(result)); assert_float_equal((float_t)jerry_value_as_number(result), 0.0f, 0.0001f); jerry_value_free(result); ret = scriptManagerExec("Input.lastValue(InputBind.UP);", &result); assert_true(errorIsOk(ret)); assert_float_equal((float_t)jerry_value_as_number(result), 0.0f, 0.0001f); jerry_value_free(result); } static void test_input_deadzone_readback(void **state) { jerry_value_t result; errorret_t ret = scriptManagerExec("Input.deadzone = 0.25;", &result); assert_true(errorIsOk(ret)); jerry_value_free(result); assert_float_equal(INPUT.deadzone, 0.25f, 0.0001f); ret = scriptManagerExec("Input.deadzone;", &result); assert_true(errorIsOk(ret)); assert_float_equal((float_t)jerry_value_as_number(result), 0.25f, 0.0001f); jerry_value_free(result); } int main(void) { assertInit(); const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown( test_inputbind_exposes_action_ordinals, input_setup, input_teardown ), cmocka_unit_test_setup_teardown( test_input_deadzone_readback, input_setup, input_teardown ), cmocka_unit_test_setup_teardown( test_inputbutton_exposes_platform_button_names, input_setup, input_teardown ), cmocka_unit_test_setup_teardown( test_input_bind_updates_button_action, input_setup, input_teardown ), cmocka_unit_test_setup_teardown( test_input_bind_accepts_plain_string, input_setup, input_teardown ), cmocka_unit_test_setup_teardown( test_input_query_functions_default_to_zero, input_setup, input_teardown ), }; return cmocka_run_group_tests(tests, NULL, NULL); }