/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "dusktest.h" #include "animation/easing.h" #define EASING_TOLERANCE 0.0001f static void test_easingLinear(void **state) { assert_float_equal(easingLinear(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingLinear(0.25f), 0.25f, EASING_TOLERANCE); assert_float_equal(easingLinear(0.5f), 0.5f, EASING_TOLERANCE); assert_float_equal(easingLinear(0.75f), 0.75f, EASING_TOLERANCE); assert_float_equal(easingLinear(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInSine(void **state) { assert_float_equal(easingInSine(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInSine(0.25f), 0.076120f, EASING_TOLERANCE); assert_float_equal(easingInSine(0.5f), 0.292893f, EASING_TOLERANCE); assert_float_equal(easingInSine(0.75f), 0.617317f, EASING_TOLERANCE); assert_float_equal(easingInSine(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingOutSine(void **state) { assert_float_equal(easingOutSine(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingOutSine(0.25f), 0.382683f, EASING_TOLERANCE); assert_float_equal(easingOutSine(0.5f), 0.707107f, EASING_TOLERANCE); assert_float_equal(easingOutSine(0.75f), 0.923880f, EASING_TOLERANCE); assert_float_equal(easingOutSine(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInOutSine(void **state) { assert_float_equal(easingInOutSine(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInOutSine(0.25f), 0.146447f, EASING_TOLERANCE); assert_float_equal(easingInOutSine(0.5f), 0.5f, EASING_TOLERANCE); assert_float_equal(easingInOutSine(0.75f), 0.853553f, EASING_TOLERANCE); assert_float_equal(easingInOutSine(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInQuad(void **state) { assert_float_equal(easingInQuad(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInQuad(0.25f), 0.0625f, EASING_TOLERANCE); assert_float_equal(easingInQuad(0.5f), 0.25f, EASING_TOLERANCE); assert_float_equal(easingInQuad(0.75f), 0.5625f, EASING_TOLERANCE); assert_float_equal(easingInQuad(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingOutQuad(void **state) { assert_float_equal(easingOutQuad(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingOutQuad(0.25f), 0.4375f, EASING_TOLERANCE); assert_float_equal(easingOutQuad(0.5f), 0.75f, EASING_TOLERANCE); assert_float_equal(easingOutQuad(0.75f), 0.9375f, EASING_TOLERANCE); assert_float_equal(easingOutQuad(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInOutQuad(void **state) { assert_float_equal(easingInOutQuad(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInOutQuad(0.25f), 0.125f, EASING_TOLERANCE); assert_float_equal(easingInOutQuad(0.5f), 0.5f, EASING_TOLERANCE); assert_float_equal(easingInOutQuad(0.75f), 0.875f, EASING_TOLERANCE); assert_float_equal(easingInOutQuad(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInCubic(void **state) { assert_float_equal(easingInCubic(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInCubic(0.25f), 0.015625f, EASING_TOLERANCE); assert_float_equal(easingInCubic(0.5f), 0.125f, EASING_TOLERANCE); assert_float_equal(easingInCubic(0.75f), 0.421875f, EASING_TOLERANCE); assert_float_equal(easingInCubic(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingOutCubic(void **state) { assert_float_equal(easingOutCubic(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingOutCubic(0.25f), 0.578125f, EASING_TOLERANCE); assert_float_equal(easingOutCubic(0.5f), 0.875f, EASING_TOLERANCE); assert_float_equal(easingOutCubic(0.75f), 0.984375f, EASING_TOLERANCE); assert_float_equal(easingOutCubic(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInOutCubic(void **state) { assert_float_equal(easingInOutCubic(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInOutCubic(0.25f), 0.0625f, EASING_TOLERANCE); assert_float_equal(easingInOutCubic(0.5f), 0.5f, EASING_TOLERANCE); assert_float_equal(easingInOutCubic(0.75f), 0.9375f, EASING_TOLERANCE); assert_float_equal(easingInOutCubic(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInQuart(void **state) { assert_float_equal(easingInQuart(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInQuart(0.25f), 0.003906f, EASING_TOLERANCE); assert_float_equal(easingInQuart(0.5f), 0.0625f, EASING_TOLERANCE); assert_float_equal(easingInQuart(0.75f), 0.316406f, EASING_TOLERANCE); assert_float_equal(easingInQuart(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingOutQuart(void **state) { assert_float_equal(easingOutQuart(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingOutQuart(0.25f), 0.683594f, EASING_TOLERANCE); assert_float_equal(easingOutQuart(0.5f), 0.9375f, EASING_TOLERANCE); assert_float_equal(easingOutQuart(0.75f), 0.996094f, EASING_TOLERANCE); assert_float_equal(easingOutQuart(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInOutQuart(void **state) { assert_float_equal(easingInOutQuart(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInOutQuart(0.25f), 0.03125f, EASING_TOLERANCE); assert_float_equal(easingInOutQuart(0.5f), 0.5f, EASING_TOLERANCE); assert_float_equal(easingInOutQuart(0.75f), 0.96875f, EASING_TOLERANCE); assert_float_equal(easingInOutQuart(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInBack(void **state) { // "In back" overshoots below 0 before rising to 1 - that's the point of it. assert_float_equal(easingInBack(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInBack(0.25f), -0.064137f, EASING_TOLERANCE); assert_float_equal(easingInBack(0.5f), -0.087698f, EASING_TOLERANCE); assert_float_equal(easingInBack(0.75f), 0.182590f, EASING_TOLERANCE); assert_float_equal(easingInBack(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingOutBack(void **state) { // "Out back" overshoots above 1 before settling at 1. assert_float_equal(easingOutBack(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingOutBack(0.25f), 0.817410f, EASING_TOLERANCE); assert_float_equal(easingOutBack(0.5f), 1.087697f, EASING_TOLERANCE); assert_float_equal(easingOutBack(0.75f), 1.064137f, EASING_TOLERANCE); assert_float_equal(easingOutBack(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingInOutBack(void **state) { assert_float_equal(easingInOutBack(0.0f), 0.0f, EASING_TOLERANCE); assert_float_equal(easingInOutBack(0.25f), -0.099682f, EASING_TOLERANCE); assert_float_equal(easingInOutBack(0.5f), 0.5f, EASING_TOLERANCE); assert_float_equal(easingInOutBack(0.75f), 1.099682f, EASING_TOLERANCE); assert_float_equal(easingInOutBack(1.0f), 1.0f, EASING_TOLERANCE); } static void test_easingApplyDispatchesToEachType(void **state) { assert_float_equal(easingApply(EASING_LINEAR, 0.5f), easingLinear(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_SINE, 0.5f), easingInSine(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_OUT_SINE, 0.5f), easingOutSine(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_OUT_SINE, 0.5f), easingInOutSine(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_QUAD, 0.5f), easingInQuad(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_OUT_QUAD, 0.5f), easingOutQuad(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_OUT_QUAD, 0.5f), easingInOutQuad(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_CUBIC, 0.5f), easingInCubic(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_OUT_CUBIC, 0.5f), easingOutCubic(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_OUT_CUBIC, 0.5f), easingInOutCubic(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_QUART, 0.5f), easingInQuart(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_OUT_QUART, 0.5f), easingOutQuart(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_OUT_QUART, 0.5f), easingInOutQuart(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_BACK, 0.5f), easingInBack(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_OUT_BACK, 0.5f), easingOutBack(0.5f), EASING_TOLERANCE); assert_float_equal(easingApply(EASING_IN_OUT_BACK, 0.5f), easingInOutBack(0.5f), EASING_TOLERANCE); } static void test_easingApplyInvalidTypeAsserts(void **state) { expect_assert_failure(easingApply(EASING_COUNT, 0.5f)); } int main(int argc, char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_easingLinear), cmocka_unit_test(test_easingInSine), cmocka_unit_test(test_easingOutSine), cmocka_unit_test(test_easingInOutSine), cmocka_unit_test(test_easingInQuad), cmocka_unit_test(test_easingOutQuad), cmocka_unit_test(test_easingInOutQuad), cmocka_unit_test(test_easingInCubic), cmocka_unit_test(test_easingOutCubic), cmocka_unit_test(test_easingInOutCubic), cmocka_unit_test(test_easingInQuart), cmocka_unit_test(test_easingOutQuart), cmocka_unit_test(test_easingInOutQuart), cmocka_unit_test(test_easingInBack), cmocka_unit_test(test_easingOutBack), cmocka_unit_test(test_easingInOutBack), cmocka_unit_test(test_easingApplyDispatchesToEachType), cmocka_unit_test(test_easingApplyInvalidTypeAsserts), }; return cmocka_run_group_tests(tests, NULL, NULL); }