This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch edje-vector-intergration
in repository efl.
View the commit online.
commit ca5917e05b2ecd6f0f9e74f1c30e078162610f31
Author: [email protected] <[email protected]>
AuthorDate: Wed Apr 29 14:04:34 2026 -0600
edje: end-to-end transition render test for state dispatch (Task 5.4)
Adds edje_vg_render_box_a_transition test exercising the full Phase 5
transition pipeline: two descriptions with stroke_width 2→10 connected
by LINEAR 1.0-second program. Test uses deterministic loop-time rewinding
(efl_loop_time_set) + canvas animator tick (ecore_evas_animator_tick) to
drive the transition synchronously without mid-frame sampling. Asserts
stroke width reaches ~10 after transition completes. Phase 5 now complete.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
---
src/tests/edje/data/test_vector_states.edc | 28 ++++++
src/tests/edje/edje_test_vector_states.c | 153 +++++++++++++++++++++++++++++
2 files changed, 181 insertions(+)
diff --git a/src/tests/edje/data/test_vector_states.edc b/src/tests/edje/data/test_vector_states.edc
index 79b873736f..5063d71373 100644
--- a/src/tests/edje/data/test_vector_states.edc
+++ b/src/tests/edje/data/test_vector_states.edc
@@ -63,6 +63,34 @@ collections {
}
}
}
+ /* Task 5.4: transition fixture.
+ * Two descriptions differing only in stroke.width (2 → 10) connected by a
+ * LINEAR 1.0 transition program. The test advances ecore_loop_time past
+ * the 1.0-second deadline and asserts the post-transition stroke_width
+ * reaches ~10. */
+ group { name: "ui/box_a_transition";
+ parts { part { name: "vg"; type: VECTOR;
+ description { state: "default" 0.0;
+ vector.use: "tile_a";
+ vector.shape { target: "body";
+ stroke.width: 2;
+ }
+ }
+ description { state: "active" 0.0;
+ inherit: "default" 0.0;
+ vector.shape { target: "body";
+ stroke.width: 10;
+ }
+ }
+ } }
+ programs {
+ program { signal: "test,activate"; source: "test";
+ action: STATE_SET "active" 0.0;
+ target: "vg";
+ transition: LINEAR 1.0;
+ }
+ }
+ }
/* Task 4.4: inherit + per-target merge fixture.
* The default description sets visible and stroke.width on "body".
* The active description inherits from default (getting those fields) and
diff --git a/src/tests/edje/edje_test_vector_states.c b/src/tests/edje/edje_test_vector_states.c
index 0dac610f67..2b9593c2de 100644
--- a/src/tests/edje/edje_test_vector_states.c
+++ b/src/tests/edje/edje_test_vector_states.c
@@ -6,6 +6,8 @@
#include <Eina.h>
#include <Eet.h>
#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Eo.h>
#include <Ecore_Evas.h>
#include "edje_suite.h"
@@ -1269,6 +1271,155 @@ EFL_START_TEST(edje_vg_tree_lerp_basic)
}
EFL_END_TEST
+/* Forward-declare ecore_evas_animator_tick — it is an EAPI symbol defined in
+ * ecore_evas.c but declared only in ecore_evas_private.h which cannot be
+ * included from tests. The symbol is present in libecore_evas at runtime. */
+EAPI void ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport,
+ double loop_time);
+
+/* Forward-declare efl_loop_time_set — it is an EAPI symbol generated in
+ * efl_loop.eo.h (build dir) and included via Ecore_Eo.h → efl_loop.eo.h, but
+ * the build-dir generated header may not resolve transitively through the
+ * source-tree include chain. Forward-declare explicitly to silence the
+ * implicit-declaration warning; the symbol is present in libefl at runtime. */
+EAPI void efl_loop_time_set(Eo *obj, double timepoint);
+
+/*
+ * edje_vg_render_box_a_transition (Task 5.4)
+ *
+ * End-to-end transition render test for ui/box_a_transition.
+ *
+ * The group has two descriptions: "default" with stroke.width=2 and "active"
+ * with stroke.width=10, connected by a LINEAR 1.0-second program.
+ *
+ * Test strategy (deterministic canvas animator tick with past-biased loop time):
+ * 1. Load the group on a buffer canvas; assert default stroke_width ~2.
+ * 2. Before emitting the signal, rewind the loop clock by 2.0 seconds using
+ * efl_loop_time_set — this bypasses ecore_loop_time_set's guard against
+ * future timestamps. The rewind makes start_time (captured when the
+ * running program is registered) approximately 2.0s behind wall clock.
+ * 3. Emit "test,activate" — Edje registers a running program with
+ * start_time = t_past and subscribes _edje_timer_cb to
+ * EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK (canvas_animator=1 because the
+ * buffer canvas has an Ecore_Evas backing).
+ * 4. Call ecore_evas_animator_tick(ee, NULL, t_tick) where t_tick is
+ * ecore_time_get() - 0.01 (just behind wall clock, so ecore_loop_time_set
+ * accepts it). Since t_tick - start_time ≈ 1.99s > 1.0s, the transition
+ * iterator clamps to 1.0, applies the "active" description, clears param2,
+ * and calls _edje_recalc.
+ * 5. Force-recalc + render; assert post-transition stroke_width ~10.
+ *
+ * This is begin/end-only (no mid-transition sample). The approach is fully
+ * deterministic: one animator tick at t>start+deadline guarantees the
+ * transition completes in a single synchronous call.
+ *
+ * Note: loop time is restored to wall clock after the final assertion so that
+ * any test added after this one in the case does not inherit the 2-second rewind.
+ */
+EFL_START_TEST(edje_vg_render_box_a_transition)
+{
+ const char *edj = TESTS_BUILD_DIR "/data/test_vector_states.edj";
+ Ecore_Evas *ee;
+ Evas *evas;
+ Evas_Object *obj;
+ Evas_Object *vg_part;
+ Efl_Canvas_Vg_Node *vg_root;
+ Efl_Canvas_Vg_Node *body_node;
+ double sw;
+ double t_past;
+ double t_tick;
+
+ /* --- Setup: buffer canvas, edje object, load group --- */
+ ee = ecore_evas_buffer_new(VG_RENDER_W, VG_RENDER_H);
+ fail_if(!ee);
+ ecore_evas_show(ee);
+ ecore_evas_manual_render_set(ee, EINA_TRUE);
+
+ evas = ecore_evas_get(ee);
+ fail_if(!evas);
+
+ obj = edje_object_add(evas);
+ fail_if(!obj);
+
+ fail_unless(edje_object_file_set(obj, edj, "ui/box_a_transition"));
+
+ evas_object_resize(obj, VG_RENDER_W, VG_RENDER_H);
+ evas_object_move(obj, 0, 0);
+ evas_object_show(obj);
+
+ edje_object_calc_force(obj);
+ ecore_evas_manual_render(ee);
+
+ /* --- Default state: stroke_width should be ~2 --- */
+ vg_part = (Evas_Object *)edje_object_part_object_get(obj, "vg");
+ fail_if(!vg_part);
+
+ vg_root = efl_canvas_vg_object_root_node_get(vg_part);
+ fail_if(vg_root == NULL);
+ fail_if(!efl_isa(vg_root, EFL_CANVAS_VG_CONTAINER_CLASS));
+
+ body_node = efl_canvas_vg_container_child_get(vg_root, "body");
+ fail_if(body_node == NULL);
+ fail_if(!efl_isa(body_node, EFL_CANVAS_VG_SHAPE_CLASS));
+
+ sw = efl_gfx_shape_stroke_width_get(body_node);
+ ck_assert_msg(sw >= 1.5 && sw <= 2.5,
+ "Default state stroke_width %.2f != expected ~2.0", sw);
+
+ /* --- Trigger the 1.0-second LINEAR transition --- */
+ /* Step 1: Rewind loop clock to 2 seconds in the past.
+ * efl_loop_time_set bypasses the "not in the future" guard in
+ * ecore_loop_time_set; the running program will capture start_time = t_past
+ * when ecore_loop_time_get() is called inside _edje_program_run. */
+ t_past = ecore_time_get() - 2.0;
+ efl_loop_time_set(efl_main_loop_get(), t_past);
+
+ /* Step 2: Emit signal — _edje_program_run registers the running program
+ * with start_time ≈ t_past and subscribes _edje_timer_cb to the canvas
+ * ANIMATOR_TICK event. */
+ edje_object_signal_emit(obj, "test,activate", "test");
+ edje_object_message_signal_process(obj);
+
+ /* Step 3: Fire the canvas animator tick at t_tick < ecore_time_get().
+ * ecore_evas_animator_tick() calls ecore_loop_time_set(t_tick) internally
+ * (which passes the guard since t_tick < wall clock) and then emits
+ * EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK on the canvas. The per-object
+ * repeater propagates to ed->obj → _edje_timer_cb → run_iterate(runp, t_tick).
+ * Since t_tick - t_past ≈ 1.99s > 1.0s, the transition completes. */
+ t_tick = ecore_time_get() - 0.01;
+ ecore_evas_animator_tick(ee, NULL, t_tick);
+
+ /* Step 4: Force recalc so _edje_vector_recalc_apply materializes the post-
+ * transition description (param2 = NULL now), then render. */
+ edje_object_calc_force(obj);
+ ecore_evas_manual_render(ee);
+
+ /* --- Post-transition state: stroke_width should be ~10 --- */
+ /* Re-fetch root and body — a fresh Efl_VG hierarchy is built each recalc,
+ * so the previous pointers are stale. */
+ vg_root = efl_canvas_vg_object_root_node_get(vg_part);
+ fail_if(vg_root == NULL);
+ fail_if(!efl_isa(vg_root, EFL_CANVAS_VG_CONTAINER_CLASS));
+
+ body_node = efl_canvas_vg_container_child_get(vg_root, "body");
+ fail_if(body_node == NULL);
+ fail_if(!efl_isa(body_node, EFL_CANVAS_VG_SHAPE_CLASS));
+
+ sw = efl_gfx_shape_stroke_width_get(body_node);
+ ck_assert_msg(sw >= 9.5 && sw <= 10.5,
+ "Post-transition stroke_width %.2f != expected ~10.0 "
+ "(transition lerp or materialize not applied)", sw);
+
+ /* Restore loop time to wall clock so any test added after this one in the
+ * case does not inherit the 2-second rewind. */
+ efl_loop_time_set(efl_main_loop_get(), ecore_time_get());
+
+ /* --- Cleanup --- */
+ evas_object_del(obj);
+ ecore_evas_free(ee);
+}
+EFL_END_TEST
+
void
edje_test_vector_states(TCase *tc)
{
@@ -1294,4 +1445,6 @@ edje_test_vector_states(TCase *tc)
tcase_add_test(tc, edje_vg_viewbox_lerp_componentwise);
/* Phase 5.2 tree lerp */
tcase_add_test(tc, edje_vg_tree_lerp_basic);
+ /* Phase 5.4 end-to-end transition */
+ tcase_add_test(tc, edje_vg_render_box_a_transition);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.