tests/genlist: add behavior testing for nearly all genlist events
authorMike Blumenkrantz <zmike@samsung.com>
Fri, 25 Oct 2019 14:06:56 +0000 (10:06 -0400)
committerWonki Kim <wonki_.kim@samsung.com>
Mon, 11 Nov 2019 02:20:40 +0000 (11:20 +0900)
this simulates a number of user interactions to ensure that various
functionalities of genlist actually work, including but not limited to:
* selection
* highlighting
* item focus
* scrolling
* filtering
* dragging
* item reordering

ref T8433

Differential Revision: https://phab.enlightenment.org/D10528

src/tests/elementary/elm_test_genlist.c

index 3d6474a..81eca40 100644 (file)
@@ -134,6 +134,15 @@ _item_content_get(void *data EINA_UNUSED, Evas_Object *obj, const char *part EIN
    return ic;
 }
 
+static char *
+_item_text_get(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *part)
+{
+   char buf[128];
+   /* just some random-ish (not really) text */
+   snprintf(buf, sizeof(buf), "%p", part);
+   return strdup(buf);
+}
+
 EFL_START_TEST(elm_genlist_test_item_content)
 {
    Elm_Genlist_Item_Class *gtc;
@@ -563,6 +572,182 @@ EFL_START_TEST(elm_genlist_test_focus_state)
 }
 EFL_END_TEST
 
+/* keep in sync with elm_genlist.c value */
+#define MAX_ITEMS_PER_BLOCK 32
+
+EFL_START_TEST(elm_genlist_test_events)
+{
+   unsigned int i, called[10] = {0};
+   Eina_Bool norender = EINA_FALSE;
+   /* need focus for item focus tests */
+   win = win_add_focused(NULL, "genlist", ELM_WIN_BASIC);
+
+   itc.func.text_get = _item_text_get;
+
+   genlist = elm_genlist_add(win);
+   elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
+
+   for (i = 0; i < 2 * MAX_ITEMS_PER_BLOCK; i++)
+     elm_genlist_item_append(genlist, &itc,
+                             NULL/* item data */, NULL/* parent */,
+                             0, NULL/* func */,
+                             NULL/* func data */);
+
+   /* show 10ish items */
+   evas_object_resize(genlist, 200, 10 + GL_ITEM_SIZE_ISH * 10);
+   evas_object_show(genlist);
+   evas_object_show(win);
+   evas_object_resize(win, 200, 10 + GL_ITEM_SIZE_ISH * 10);
+   get_me_to_those_events(genlist);
+
+/* add callbacks only for the name array passed,
+ * verify that each callback is triggered based on event callback type
+ * remove callbacks so they don't break successive testing
+ * note: order is not tested or useful
+ */
+#define CB_TEST(namearray, ev_func, ...) \
+   do { \
+     const char **names = namearray; \
+     memset(called, 0, sizeof(called)); \
+     norender = EINA_FALSE; \
+     for (i = 0; *names; i++, names++) \
+       evas_object_smart_callback_add(genlist, *names, ev_func, &(called[i])); \
+     __VA_ARGS__ \
+     if (!norender) \
+       get_me_to_those_events(genlist); \
+     for (i = 0, names = namearray; *names; i++, names++) \
+       { \
+          evas_object_smart_callback_del_full(genlist, *names, ev_func, &(called[i])); \
+          if (!called[i]) fprintf(stderr, "GENLIST EVENT TEST ERROR: \"%s\" failed to trigger as expected!\n", namearray[i]); \
+          if (ev_func == event_callback_that_increments_an_int_when_called) \
+            ck_assert_int_ge(called[i], 1); \
+          else \
+            ck_assert_int_eq(called[i], 1); \
+       } \
+   } while (0)
+#define NAMEARRAY(...) \
+  (const char*[]){__VA_ARGS__, NULL}
+
+   /* first item: double click ->
+    *   "activated" + "clicked,double" + "selected" + "highlighted" */
+   CB_TEST(NAMEARRAY("activated", "clicked,double", "selected", "highlighted"),
+     event_callback_single_call_int_data,
+     click_object_at_flags(genlist, 5, 5, EVAS_BUTTON_DOUBLE_CLICK);
+   );
+
+   /* first item: right click ->
+    *   "clicked,right" */
+   CB_TEST(
+      NAMEARRAY("clicked,right"),
+      event_callback_single_call_int_data,
+      Evas *e = evas_object_evas_get(genlist);
+      norender = EINA_TRUE;
+      evas_event_feed_mouse_move(e, 5, 5, 0, NULL);
+      /* no util function for this since we never use right click */
+      evas_event_feed_mouse_down(e, 3, 0, 0, NULL);
+      evas_event_feed_mouse_up(e, 3, 0, 0, NULL);
+   );
+   /* some other item:
+    * click ->
+    *   "unselected" + "unhighlighted" + "item,unfocused" on first item
+    *   "pressed" + "released" + "item,focused" on other item */
+   CB_TEST(
+      NAMEARRAY("unselected", "unhighlighted", "pressed", "released", "item,focused", "item,unfocused"),
+      event_callback_single_call_int_data,
+      /* click on some other random item to trigger different selection/highlight */
+      click_object_at(genlist, 5, 50);
+   );
+
+   /* wheel ->
+    *   "realized" on unrealized items
+    *   "unrealized" on first item */
+   CB_TEST(
+      NAMEARRAY("realized", "unrealized"),
+      event_callback_that_increments_an_int_when_called,
+      /* disable animations to avoid having to wait an indeterminate amount of time for scrolling */
+      elm_config_scroll_animation_disabled_set(EINA_TRUE);
+      /* wheel to trigger realize/unrealize */
+      wheel_object_at(genlist, 50, 50, 0, 1);
+      /* re-enable animations before failure to avoid triggering cascading test failures */
+      elm_config_scroll_animation_disabled_set(EINA_FALSE);
+   );
+
+   /* filter_set ->
+    *   "filter,done"
+    */
+   CB_TEST(
+      NAMEARRAY("filter,done"),
+      event_callback_single_call_int_data,
+      elm_genlist_filter_set(genlist, "2");
+   );
+   elm_genlist_filter_set(genlist, NULL);
+
+   /* simple drag ->
+    *   "swipe" + "drag,start,right" + "drag,stop"
+    * also multiple "drag" events
+    */
+  evas_object_smart_callback_add(genlist, "drag", event_callback_that_increments_an_int_when_called, &called[5]);
+   CB_TEST(
+      NAMEARRAY("swipe", "drag,start,right", "drag,stop"),
+      event_callback_single_call_int_data,
+      click_object_at(genlist, 5, 50);
+      drag_object(genlist, 5, 50, 150, 0, EINA_FALSE);
+   );
+  evas_object_smart_callback_del_full(genlist, "drag", event_callback_that_increments_an_int_when_called, &called[5]);
+  /* there should be DRAG_OBJECT_NUM_MOVES - 1 "drag" events */
+  ck_assert_int_eq(called[5], DRAG_OBJECT_NUM_MOVES - 1);
+
+   /* continuous simple drags ->
+    *   "drag,start,left", "drag,start,up", "drag,start,down"
+    */
+   evas_object_smart_callback_add(genlist, "drag,stop", event_callback_that_increments_an_int_when_called, &called[3]);
+   CB_TEST(
+      NAMEARRAY("drag,start,left", "drag,start,up", "drag,start,down"),
+      event_callback_single_call_int_data,
+      /* left */
+      click_object_at(genlist, 155, 50);
+      drag_object(genlist, 155, 50, -150, 0, EINA_FALSE);
+      /* down */
+      click_object_at(genlist, 5, 50);
+      drag_object(genlist, 5, 50, 0, 100, EINA_FALSE);
+      /* up */
+      click_object_at(genlist, 5, 150);
+      drag_object(genlist, 5, 150, 0, -100, EINA_FALSE);
+   );
+   evas_object_smart_callback_del_full(genlist, "drag", event_callback_that_increments_an_int_when_called, &called[3]);
+   ck_assert_int_eq(called[3], DRAG_OBJECT_NUM_MOVES - 1);
+
+   /* intensive drag down ->
+    *   "longpressed" + "moved" + ("moved,after" || "moved,before")
+    * also "index,update" on all affected items
+    */
+   evas_object_smart_callback_add(genlist, "index,update", event_callback_that_increments_an_int_when_called, &called[3]);
+   /* exactly one of these will be called */
+   evas_object_smart_callback_add(genlist, "moved,before", event_callback_single_call_int_data, &called[2]);
+   evas_object_smart_callback_add(genlist, "moved,after", event_callback_single_call_int_data, &called[2]);
+   CB_TEST(
+      /* "moved,before" can only be triggered on the first item and is a bit finnicky/unreliable
+       * to trigger in unit tests so it's being ignored for now
+       */
+      NAMEARRAY("longpressed", "moved"),
+      event_callback_single_call_int_data,
+      double lp = elm_genlist_longpress_timeout_get(genlist);
+      elm_genlist_reorder_mode_set(genlist, EINA_TRUE);
+      elm_genlist_longpress_timeout_set(genlist, 0);
+      click_object_at(genlist, 5, 5);
+      drag_object(genlist, 5, 5, 0, 90, EINA_TRUE);
+      elm_genlist_reorder_mode_set(genlist, EINA_FALSE);
+      elm_genlist_longpress_timeout_set(genlist, lp);
+   );
+   evas_object_smart_callback_del_full(genlist, "moved,before", event_callback_single_call_int_data, &called[2]);
+   evas_object_smart_callback_del_full(genlist, "moved,after", event_callback_single_call_int_data, &called[2]);
+   ck_assert_int_eq(called[2], 1);
+   evas_object_smart_callback_del_full(genlist, "index,update", event_callback_that_increments_an_int_when_called, &called[3]);
+   /* at minimum, 2 items should have been changed */
+   ck_assert_int_ge(called[3], 2);
+}
+EFL_END_TEST
+
 void elm_test_genlist(TCase *tc)
 {
    tcase_add_test(tc, elm_genlist_test_legacy_type_check);
@@ -578,4 +763,6 @@ void elm_test_genlist(TCase *tc)
 
    tcase_add_test(tc, elm_genlist_test_focus_state);
    tcase_add_test(tc, elm_genlist_test_tree_expand);
+
+   tcase_add_test(tc, elm_genlist_test_events);
 }