diff --git a/src/dusk/script/script.c b/src/dusk/script/script.c index 48ee0caa..0df19e85 100644 --- a/src/dusk/script/script.c +++ b/src/dusk/script/script.c @@ -9,8 +9,8 @@ #include "native/scriptnativeconsole.h" #include "builtin/scriptbuiltinregister.h" #include "console/console.h" +#include "asset/asset.h" #include "util/memory.h" -#include script_t SCRIPT; @@ -29,14 +29,33 @@ void scriptPrintHandler(const char *text, const size_t length) { } size_t scriptLoadHandler(const char *path, char *buffer, const size_t capacity) { - FILE *file; - size_t length; + assetfile_t file; + size_t size; - file = fopen(path, "rb"); - if(!file) return (size_t)-1; - length = fread(buffer, 1, capacity, file); - fclose(file); - return length; + // Scripts are packed into dusk.dsk like every other asset, so this reads + // through the asset system rather than the real filesystem - a missing + // entry or one too big for capacity both just fail the include/load. + if(errorIsNotOk(assetFileInit(&file, path, NULL, NULL))) return SCRIPT_LOAD_FAILED; + + size = (size_t)file.size; + if(size > capacity) { + assetFileDispose(&file); + return SCRIPT_LOAD_FAILED; + } + + if(errorIsNotOk(assetFileOpen(&file))) { + assetFileDispose(&file); + return SCRIPT_LOAD_FAILED; + } + + if(errorIsNotOk(assetFileRead(&file, buffer, size))) { + assetFileDispose(&file); + return SCRIPT_LOAD_FAILED; + } + + assetFileClose(&file); + assetFileDispose(&file); + return size; } errorret_t scriptInit(void) { diff --git a/test/duskscript/CMakeLists.txt b/test/duskscript/CMakeLists.txt index 6c5c607c..71aa5620 100644 --- a/test/duskscript/CMakeLists.txt +++ b/test/duskscript/CMakeLists.txt @@ -7,29 +7,32 @@ include(dusktest) dusktest(test_duskscript.c) -# Compile the fixture scripts to bytecode with duskscriptcc at build time, so -# the test exercises the real compiler -> runtime -> consolePrint pipeline. -set(DUSKSCRIPT_TEST_FIXTURE_DS ${CMAKE_CURRENT_LIST_DIR}/fixture.ds) -set(DUSKSCRIPT_TEST_FIXTURE_DSB ${CMAKE_CURRENT_BINARY_DIR}/fixture.dsb) -set(DUSKSCRIPT_TEST_NUMBERS_DS ${CMAKE_CURRENT_LIST_DIR}/fixture_numbers.ds) -set(DUSKSCRIPT_TEST_NUMBERS_DSB ${CMAKE_CURRENT_BINARY_DIR}/fixture_numbers.dsb) +# Scripts are loaded through the asset system (see scriptLoadHandler in +# src/dusk/script/script.c), not the real filesystem, so the fixtures are +# packed into a small test.dsk with the same tools.asset.pack used for the +# game's own dusk.dsk - this exercises the real compiler -> pack -> asset -> +# runtime -> consolePrint pipeline rather than a shortcut around it. +set(DUSKSCRIPT_TEST_ASSETS_DIR ${CMAKE_CURRENT_LIST_DIR}/assets) +set(DUSKSCRIPT_TEST_DSK ${CMAKE_CURRENT_BINARY_DIR}/test.dsk) add_custom_command( - OUTPUT ${DUSKSCRIPT_TEST_FIXTURE_DSB} - COMMAND duskscriptcc ${DUSKSCRIPT_TEST_FIXTURE_DS} -o ${DUSKSCRIPT_TEST_FIXTURE_DSB} - DEPENDS duskscriptcc ${DUSKSCRIPT_TEST_FIXTURE_DS} - COMMENT "Compiling duskscript test fixture" + OUTPUT ${DUSKSCRIPT_TEST_DSK} + COMMAND ${Python3_EXECUTABLE} -m tools.asset.pack + --input ${DUSKSCRIPT_TEST_ASSETS_DIR} + --output ${DUSKSCRIPT_TEST_DSK} + --duskscriptcc "$" + WORKING_DIRECTORY ${DUSK_ROOT_DIR} + DEPENDS + duskscriptcc + ${DUSKSCRIPT_TEST_ASSETS_DIR}/fixture.ds + ${DUSKSCRIPT_TEST_ASSETS_DIR}/fixture_numbers.ds + COMMENT "Packing duskscript test fixtures" ) -add_custom_command( - OUTPUT ${DUSKSCRIPT_TEST_NUMBERS_DSB} - COMMAND duskscriptcc ${DUSKSCRIPT_TEST_NUMBERS_DS} -o ${DUSKSCRIPT_TEST_NUMBERS_DSB} - DEPENDS duskscriptcc ${DUSKSCRIPT_TEST_NUMBERS_DS} - COMMENT "Compiling duskscript numbers test fixture" -) -add_custom_target(duskscript_test_fixture DEPENDS ${DUSKSCRIPT_TEST_FIXTURE_DSB} ${DUSKSCRIPT_TEST_NUMBERS_DSB}) +add_custom_target(duskscript_test_fixture DEPENDS ${DUSKSCRIPT_TEST_DSK}) add_dependencies(test_duskscript duskscript_test_fixture) target_compile_definitions(test_duskscript PRIVATE - DUSKSCRIPT_TEST_FIXTURE="${DUSKSCRIPT_TEST_FIXTURE_DSB}" - DUSKSCRIPT_TEST_NUMBERS="${DUSKSCRIPT_TEST_NUMBERS_DSB}" + DUSKSCRIPT_TEST_DSK="${DUSKSCRIPT_TEST_DSK}" + DUSKSCRIPT_TEST_FIXTURE="fixture.dsb" + DUSKSCRIPT_TEST_NUMBERS="fixture_numbers.dsb" ) diff --git a/test/duskscript/fixture.ds b/test/duskscript/assets/fixture.ds similarity index 100% rename from test/duskscript/fixture.ds rename to test/duskscript/assets/fixture.ds diff --git a/test/duskscript/fixture_numbers.ds b/test/duskscript/assets/fixture_numbers.ds similarity index 100% rename from test/duskscript/fixture_numbers.ds rename to test/duskscript/assets/fixture_numbers.ds diff --git a/test/duskscript/test_duskscript.c b/test/duskscript/test_duskscript.c index 7a095fad..8b8efe6f 100644 --- a/test/duskscript/test_duskscript.c +++ b/test/duskscript/test_duskscript.c @@ -8,6 +8,9 @@ #include "dusktest.h" #include "script/script.h" #include "console/console.h" +#include "asset/asset.h" +#include "asset/assetdsk.h" +#include "util/memory.h" static void test_scriptRunsAndPrintsToConsole(void **state) { scripterror_t error; @@ -52,10 +55,27 @@ static void test_scriptNumbersAreAllFloats(void **state) { consoleDispose(); } +// Fixtures load through the asset system now, so ASSET needs a real zip +// behind it - open the packed test.dsk directly rather than the full +// assetInit()/assetInitPlatform(), which expects a real launched engine. +static int duskscript_test_setup(void **state) { + memoryZero(&ASSET, sizeof(ASSET)); + threadMutexInit(&ASSET.zipLock); + assert_int_equal(errorIsOk(assetDskOpenFromPath(DUSKSCRIPT_TEST_DSK, &ASSET.zip)), true); + return 0; +} + +static int duskscript_test_teardown(void **state) { + zip_close(ASSET.zip); + threadMutexDispose(&ASSET.zipLock); + memoryZero(&ASSET, sizeof(ASSET)); + return 0; +} + int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_scriptRunsAndPrintsToConsole), cmocka_unit_test(test_scriptNumbersAreAllFloats), }; - return cmocka_run_group_tests(tests, NULL, NULL); + return cmocka_run_group_tests(tests, duskscript_test_setup, duskscript_test_teardown); }