/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "dusktest.h" #include "animation/keyframeset.h" static void test_keyframeSetGetValuePerTrack(void **state) { keyframe_t xKeyframes[] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR }, { .time = 1.0f, .value = 10.0f, .easing = EASING_LINEAR } }; keyframe_t yKeyframes[] = { { .time = 0.0f, .value = 100.0f, .easing = EASING_LINEAR }, { .time = 1.0f, .value = 200.0f, .easing = EASING_LINEAR } }; keyframe_t *tracks[] = { xKeyframes, yKeyframes }; uint16_t trackCounts[] = { 2, 2 }; keyframeset_t set; keyframeSetInit(&set, tracks, trackCounts, NULL, NULL, 2, NULL); assert_float_equal(keyframeSetGetValue(&set, 0, 0.5f), 5.0f, 0.0001f); assert_float_equal(keyframeSetGetValue(&set, 1, 0.5f), 150.0f, 0.0001f); } static void test_keyframeSetGetValuesFillsAllTracks(void **state) { keyframe_t xKeyframes[] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR }, { .time = 1.0f, .value = 10.0f, .easing = EASING_LINEAR } }; keyframe_t yKeyframes[] = { { .time = 0.0f, .value = 100.0f, .easing = EASING_LINEAR }, { .time = 1.0f, .value = 200.0f, .easing = EASING_LINEAR } }; keyframe_t *tracks[] = { xKeyframes, yKeyframes }; uint16_t trackCounts[] = { 2, 2 }; keyframeset_t set; keyframeSetInit(&set, tracks, trackCounts, NULL, NULL, 2, NULL); float_t values[2]; keyframeSetGetValues(&set, 0.5f, values); assert_float_equal(values[0], 5.0f, 0.0001f); assert_float_equal(values[1], 150.0f, 0.0001f); } static void test_keyframeSetGetDurationIsLongestTrack(void **state) { keyframe_t shortKeyframes[] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR }, { .time = 1.0f, .value = 10.0f, .easing = EASING_LINEAR } }; keyframe_t longKeyframes[] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR }, { .time = 3.5f, .value = 10.0f, .easing = EASING_LINEAR } }; keyframe_t *tracks[] = { shortKeyframes, longKeyframes }; uint16_t trackCounts[] = { 2, 2 }; keyframeset_t set; keyframeSetInit(&set, tracks, trackCounts, NULL, NULL, 2, NULL); assert_float_equal(keyframeSetGetDuration(&set), 3.5f, 0.0001f); } static uint32_t TEST_CALLBACK_FIRE_COUNT; static uint16_t TEST_CALLBACK_LAST_TRACK; static void *TEST_CALLBACK_LAST_USER; static void test_onTrackCallback( keyframeset_t *set, const uint16_t trackIndex, void *user ) { TEST_CALLBACK_FIRE_COUNT++; TEST_CALLBACK_LAST_TRACK = trackIndex; TEST_CALLBACK_LAST_USER = user; } static void test_keyframeSetFireCallbackInvokesPerTrackCallback(void **state) { TEST_CALLBACK_FIRE_COUNT = 0; TEST_CALLBACK_LAST_TRACK = 0xFFFF; TEST_CALLBACK_LAST_USER = NULL; keyframe_t xKeyframes[] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR }, { .time = 1.0f, .value = 10.0f, .easing = EASING_LINEAR } }; keyframe_t yKeyframes[] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR }, { .time = 1.0f, .value = 10.0f, .easing = EASING_LINEAR } }; keyframe_t *tracks[] = { xKeyframes, yKeyframes }; uint16_t trackCounts[] = { 2, 2 }; int32_t trackOneUser = 42; keyframesetcallback_t callbacks[] = { NULL, test_onTrackCallback }; void *users[] = { NULL, &trackOneUser }; int32_t setUser = 7; keyframeset_t set; keyframeSetInit(&set, tracks, trackCounts, callbacks, users, 2, &setUser); // Track 0 has no callback registered -- no-op. keyframeSetFireCallback(&set, 0); assert_int_equal(TEST_CALLBACK_FIRE_COUNT, 0); keyframeSetFireCallback(&set, 1); assert_int_equal(TEST_CALLBACK_FIRE_COUNT, 1); assert_int_equal(TEST_CALLBACK_LAST_TRACK, 1); assert_ptr_equal(TEST_CALLBACK_LAST_USER, &trackOneUser); assert_ptr_equal(set.user, &setUser); } int main(int argc, char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_keyframeSetGetValuePerTrack), cmocka_unit_test(test_keyframeSetGetValuesFillsAllTracks), cmocka_unit_test(test_keyframeSetGetDurationIsLongestTrack), cmocka_unit_test(test_keyframeSetFireCallbackInvokesPerTrackCallback), }; return cmocka_run_group_tests(tests, NULL, NULL); }