Clamp keyframe interpolation to last value, add main menu scene/UI, battle HUD, and expanded test coverage
- keyframeGetValue now returns the last keyframe's value for times at or beyond it, fixes a missing util/math.h include, and asserts keyframes are sorted by time; adds test/animation/test_keyframe.c - Adds mainmenu scene/UI and a battle HUD UI frame - Adds save autosave-related fields and battle scene tweaks - Adds headless test coverage for cutscenes, entities, and map areas
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "dusktest.h"
|
||||
#include "entitytestfixture.h"
|
||||
#include "ui/rpg/textbox/uitextboxmain.h"
|
||||
#include "ui/focus/uifocus.h"
|
||||
|
||||
static entity_t *setUpItemEntity(void) {
|
||||
entityTestFixtureReset();
|
||||
uiFocusInit();
|
||||
uiTextboxMainInit();
|
||||
uiTextboxMainFocusClosed(NULL);// force-clear stale focus from a prior test
|
||||
|
||||
entityInit(&ENTITIES[0], ENTITY_TYPE_ITEM);
|
||||
return &ENTITIES[0];
|
||||
}
|
||||
|
||||
static void test_entityItemInit(void **state) {
|
||||
|
||||
entity_t *item = setUpItemEntity();
|
||||
|
||||
assert_int_equal(item->interact.type, ENTITY_INTERACT_CALLBACK);
|
||||
assert_ptr_equal(item->interact.data.callback, entityItemInteract);
|
||||
}
|
||||
|
||||
static void test_entityItemSet(void **state) {
|
||||
|
||||
entity_t *item = setUpItemEntity();
|
||||
|
||||
entityItemSet(item, ITEM_ID_POTION, 3);
|
||||
assert_int_equal(item->data.item.item, ITEM_ID_POTION);
|
||||
assert_int_equal(item->data.item.quantity, 3);
|
||||
assert_false(item->data.item.collected);
|
||||
}
|
||||
|
||||
// entityItemInteract itself is NOT covered here: it unconditionally calls
|
||||
// itemGive(), which calls itemGetName(), which dereferences
|
||||
// LOCALE.entry->data.locale -- a real locale asset populated only by the
|
||||
// async asset-loading pipeline (see localemanager.h/assetlocaleloader.h).
|
||||
// That's exactly the asset-loading dependency this test pass scoped out;
|
||||
// faking it cheaply isn't possible without hand-building the loader's
|
||||
// internal hash format, which is more coupling than it's worth. Backpack
|
||||
// bookkeeping itself is already covered by test/item/test_inventory.c-style
|
||||
// tests at the inventory/backpack layer.
|
||||
|
||||
static void test_entityItemMovementWaitsForCollectionAndTextbox(void **state) {
|
||||
|
||||
entity_t *item = setUpItemEntity();
|
||||
|
||||
// Not collected yet -- stays.
|
||||
entityItemMovement(item);
|
||||
assert_int_equal(item->type, ENTITY_TYPE_ITEM);
|
||||
|
||||
// Collected (set directly -- see note above on why entityItemInteract
|
||||
// itself isn't driven here), but a message is still showing -- stays.
|
||||
item->data.item.collected = true;
|
||||
uiTextboxMainSetText("Picked up!");
|
||||
entityItemMovement(item);
|
||||
assert_int_equal(item->type, ENTITY_TYPE_ITEM);
|
||||
|
||||
// Once the textbox is dismissed, the entity despawns.
|
||||
uiFocusPop();
|
||||
assert_false(uiTextboxMainIsActive());
|
||||
entityItemMovement(item);
|
||||
assert_int_equal(item->type, ENTITY_TYPE_NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_entityItemInit),
|
||||
cmocka_unit_test(test_entityItemSet),
|
||||
cmocka_unit_test(test_entityItemMovementWaitsForCollectionAndTextbox),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
Reference in New Issue
Block a user