Add tests for flat navi
authorMichal Jagiello <m.jagiello@samsung.com>
Mon, 2 Mar 2015 11:21:52 +0000 (12:21 +0100)
committerMichal Jagiello <m.jagiello@samsung.com>
Tue, 17 Mar 2015 13:45:38 +0000 (14:45 +0100)
Change-Id: I9038c646c28af5ba1aca240069a57a79eee64805

src/flat_navi.c
tests/CMakeLists.txt
tests/atspi/atspi.c
tests/atspi/atspi.h
tests/screen_reader_test_suite.c

index 86a4367..aa0ffd1 100644 (file)
@@ -275,11 +275,15 @@ void flat_navi_context_free(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_current_get(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    return eina_list_data_get(ctx->current);
 }
 
 Eina_Bool flat_navi_context_current_set(FlatNaviContext *ctx, AtspiAccessible *target)
 {
+   if(!ctx || !target) return EINA_FALSE;
+
    Eina_List *l, *l2, *line;
    AtspiAccessible *obj;
    Eina_Bool found = EINA_FALSE;
@@ -305,6 +309,8 @@ Eina_Bool flat_navi_context_current_set(FlatNaviContext *ctx, AtspiAccessible *t
 
 AtspiAccessible *flat_navi_context_next(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = eina_list_next(ctx->current);
 
    if (ret)
@@ -317,6 +323,8 @@ AtspiAccessible *flat_navi_context_next(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_prev(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = eina_list_prev(ctx->current);
 
    if (ret)
@@ -329,6 +337,8 @@ AtspiAccessible *flat_navi_context_prev(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_first(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = eina_list_data_get(ctx->current_line);
 
    if (ret)
@@ -341,6 +351,8 @@ AtspiAccessible *flat_navi_context_first(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_last(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = eina_list_last(ctx->current);
 
    if (ret)
@@ -353,6 +365,8 @@ AtspiAccessible *flat_navi_context_last(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_line_next(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = eina_list_next(ctx->current_line);
    if (!ret) return NULL;
 
@@ -364,6 +378,8 @@ AtspiAccessible *flat_navi_context_line_next(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_line_prev(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = eina_list_prev(ctx->current_line);
    if (!ret) return NULL;
 
@@ -375,6 +391,8 @@ AtspiAccessible *flat_navi_context_line_prev(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_line_first(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = ctx->lines;
 
    ctx->current_line = ret;
@@ -385,6 +403,8 @@ AtspiAccessible *flat_navi_context_line_first(FlatNaviContext *ctx)
 
 AtspiAccessible *flat_navi_context_line_last(FlatNaviContext *ctx)
 {
+   if(!ctx) return NULL;
+
    Eina_List *ret = eina_list_last(ctx->current_line);
 
    ctx->current_line = ret;
index 7e0d71a..f1e0859 100644 (file)
@@ -35,7 +35,10 @@ SET(TESTED_SRCS ${CMAKE_SOURCE_DIR}/src/screen_reader.c
                 ${CMAKE_SOURCE_DIR}/src/screen_reader_vconf.c
                 ${CMAKE_SOURCE_DIR}/src/screen_reader_spi.c
                 ${CMAKE_SOURCE_DIR}/src/screen_reader_tts.c
-                ${CMAKE_SOURCE_DIR}/src/logger.c)
+                ${CMAKE_SOURCE_DIR}/src/logger.c
+                ${CMAKE_SOURCE_DIR}/src/flat_navi.c
+                ${CMAKE_SOURCE_DIR}/src/position_sort.c
+                ${CMAKE_SOURCE_DIR}/src/object_cache.c)
 
 ADD_EXECUTABLE(screen_reader_test_suite screen_reader_test_suite.c ${TESTED_SRCS})
 TARGET_LINK_LIBRARIES(screen_reader_test_suite atspi ${tests_LDFLAGS} ${SLP_LD_PATH_FLAGS} ${SLP_LD_FLAGS} ${SLP_LINKER_FLAGS})
index 14e4962..72b7370 100644 (file)
@@ -7,6 +7,28 @@
 static AtspiValue *value = NULL;
 static AtspiText *text = NULL;
 static AtspiEditableText *editable_text = NULL;
+//static AtspiComponent *component = NULL;
+
+G_DEFINE_TYPE(AtspiAccessible, atspi_accessible, G_TYPE_OBJECT);
+G_DEFINE_TYPE(AtspiComponent, atspi_component, G_TYPE_OBJECT);
+
+void atspi_rect_free (AtspiRect *rect)
+{
+  g_free (rect);
+}
+
+AtspiRect *atspi_rect_copy (AtspiRect *src)
+{
+  AtspiRect *dst = g_new (AtspiRect, 1);
+  dst->x = src->x;
+  dst->y = src->y;
+  dst->height = src->height;
+  dst->width = src->width;
+  return dst;
+}
+
+G_DEFINE_BOXED_TYPE (AtspiRect, atspi_rect, atspi_rect_copy, atspi_rect_free)
+
 
 void atspi_alloc_memory()
 {
@@ -35,8 +57,16 @@ gchar * atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error)
     AtspiRole role = obj->role;
     switch(role)
     {
-        case ATSPI_ROLE_IMAGE:
-            return strdup("Image");
+        case ATSPI_ROLE_APPLICATION:
+            return strdup("Application");
+        case ATSPI_ROLE_PUSH_BUTTON:
+            return strdup("Push button");
+        case ATSPI_ROLE_ICON:
+            return strdup("Icon");
+        case ATSPI_ROLE_CHECK_BOX:
+            return strdup("Check box");
+        case ATSPI_ROLE_ENTRY:
+            return strdup("Entry");
         default:
             return strdup("\0");
     }
@@ -126,7 +156,7 @@ AtspiStateSet * atspi_accessible_get_state_set (AtspiAccessible *obj)
 
 gboolean atspi_state_set_contains (AtspiStateSet *set, AtspiStateType state)
 {
-    return FALSE;
+    return TRUE;
 }
 
 gboolean atspi_component_grab_highlight (AtspiComponent *obj, GError **error)
@@ -144,6 +174,146 @@ gboolean atspi_component_clear_highlight (AtspiComponent *obj, GError **error)
     return FALSE;
 }
 
+AtspiRole atspi_accessible_get_role (AtspiAccessible *obj, GError **error)
+{
+    if(!obj) return ATSPI_ROLE_INVALID;
+    return obj->role;
+}
+
+gint atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error)
+{
+    if(!obj || !obj->children) return 0;
+    return g_list_length(obj->children);
+}
+
+AtspiAccessible * atspi_accessible_get_child_at_index (AtspiAccessible *obj, gint child_index, GError **error)
+{
+    if(!obj || child_index >= g_list_length(obj->children)) return NULL;
+    return g_object_ref(g_list_nth_data(obj->children, child_index));
+}
+
+AtspiComponent * atspi_accessible_get_component (AtspiAccessible *obj)
+{
+    if(!obj) return NULL;
+    AtspiComponent *component = g_object_new(ATSPI_COMPONENT_OBJECT_TYPE, 0);
+    *(component->role) = obj->role;
+    return component;
+}
+
+AtspiRect *atspi_component_get_extents (AtspiComponent *component, AtspiCoordType ctype, GError **error)
+{
+    if(!component) return NULL;
+
+    AtspiRect rect;
+    if(*(component->role) == ATSPI_ROLE_APPLICATION)
+    {
+        rect.x = 0;
+        rect.y = 0;
+        rect.width = 100;
+        rect.height = 100;
+    }
+    else if(*(component->role) == ATSPI_ROLE_PUSH_BUTTON)
+    {
+        rect.x = 0;
+        rect.y = 0;
+        rect.width = 50;
+        rect.height = 50;
+    }
+    else if(*(component->role) == ATSPI_ROLE_ICON)
+    {
+        rect.x = 50;
+        rect.y = 0;
+        rect.width = 50;
+        rect.height = 50;
+    }
+    else if(*(component->role) == ATSPI_ROLE_CHECK_BOX)
+    {
+        rect.x = 0;
+        rect.y = 50;
+        rect.width = 50;
+        rect.height = 50;
+    }
+    else if(*(component->role) == ATSPI_ROLE_ENTRY)
+    {
+        rect.x = 50;
+        rect.y = 50;
+        rect.width = 50;
+        rect.height = 50;
+    }
+    else
+    {
+        rect.x = 0;
+        rect.y = 0;
+        rect.width = 0;
+        rect.height = 0;
+    }
+    return atspi_rect_copy(&rect);
+}
+
+AtspiAccessible *atspi_create_accessible()
+{
+    g_type_init();
+    AtspiAccessible *obj = g_object_new(ATSPI_ACCESSIBLE_OBJECT_TYPE, 0);
+    obj->children = NULL;
+    return obj;
+}
+
+void atspi_delete_accessible(AtspiAccessible *obj)
+{
+    if(!obj) return;
+    if(obj->children)
+    {
+        atpis_accessible_remove_children(obj);
+    }
+    g_object_unref(obj);
+}
+
+void atspi_accessible_add_child(AtspiAccessible *obj, AtspiAccessible *child)
+{
+    obj->children = g_list_append(obj->children, child);
+}
+
+void atpis_accessible_remove_children(AtspiAccessible *obj)
+{
+    GList *l = obj->children;
+    while (l != NULL)
+    {
+        GList *next = l->next;
+        if(l->data)
+        {
+            atspi_delete_accessible(l->data);
+        }
+        l = next;
+    }
+    g_list_free(obj->children);
+}
+
+static void atspi_accessible_class_init(AtspiAccessibleClass *_class)
+{
+}
+
+static void atspi_accessible_init(AtspiAccessible* obj)
+{
+}
+
+static void atspi_component_finalize(GObject *obj)
+{
+    AtspiComponent *component = (AtspiComponent*)obj;
+    free(component->role);
+}
+
+static void atspi_component_class_init(AtspiComponentClass *class)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+    gobject_class->finalize = atspi_component_finalize;
+}
+
+static void atspi_component_init(AtspiComponent* obj)
+{
+    obj->role = (AtspiRole*)malloc(sizeof(AtspiRole));
+}
+
 AtspiEditableText * atspi_accessible_get_editable_text (AtspiAccessible *obj)
 {
     return editable_text;
index 3538506..6d60e02 100644 (file)
@@ -7,6 +7,20 @@
 #include <glib-2.0/glib-object.h>
 #include <dbus/dbus.h>
 
+#define ATSPI_ACCESSIBLE_OBJECT_TYPE                (atspi_accessible_get_type ())
+#define ATSPI_ACCESSIBLE(obj)                       (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATSPI_ACCESSIBLE_OBJECT_TYPE, AtspiAccessible))
+#define ATSPI_ACESSIBLE_IS_OBJECT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATSPI_ACCESSIBLE_OBJECT_TYPE))
+#define ATSPI_ACCESSIBLE_CLASS(_class)              (G_TYPE_CHECK_CLASS_CAST ((_class), ATSPI_ACCESSIBLE_OBJECT_TYPE, AtspiAccessibleClass))
+#define ATSPI_ACCESSIBLE_IS_OBJECT_CLASS(_class)    (G_TYPE_CHECK_CLASS_TYPE ((_class), ATSPI_ACCESSIBLE_OBJECT_TYPE))
+#define ATSPI_ACCESSIBLE_GET_CLASS(obj)             (G_TYPE_INSTANCE_GET_CLASS ((obj), ATSPI_ACCESSIBLE_OBJECT_TYPE, AtspiAccessibleClass))
+
+#define ATSPI_COMPONENT_OBJECT_TYPE                 (atspi_component_get_type ())
+#define ATSPI_COMPONENT(obj)                        (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATSPI_COMPONENT_OBJECT_TYPE, AtspiAccessible))
+#define ATSPI_COMPONENT_IS_OBJECT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATSPI_COMPONENT_OBJECT_TYPE))
+#define ATSPI_COMPONENT_CLASS(_class)               (G_TYPE_CHECK_CLASS_CAST ((_class), ATSPI_COMPONENT_OBJECT_TYPE, AtspiAccessibleClass))
+#define ATSPI_COMPONENT_IS_OBJECT_CLASS(_class)     (G_TYPE_CHECK_CLASS_TYPE ((_class), ATSPI_COMPONENT_OBJECT_TYPE))
+#define ATSPI_COMPONENT_GET_CLASS(obj)              (G_TYPE_INSTANCE_GET_CLASS ((obj), ATSPI_COMPONENT_OBJECT_TYPE, AtspiAccessibleClass))
+
 typedef struct _AtspiApplication AtspiApplication;
 typedef struct _AtspiObject AtspiObject;
 typedef struct _AtspiAccessible AtspiAccessible;
@@ -17,9 +31,13 @@ typedef struct _AtspiText AtspiText;
 typedef struct _AtspiValue AtspiValue;
 typedef struct _AtspiComponent AtspiComponent;
 typedef struct _AtspiScrollable AtspiScrollable;
+typedef struct _AtspiRect AtspiRect;
 typedef struct _AtspiEditableText AtspiEditableText;
 typedef struct _AtspiRelation AtspiRelation;
 
+typedef struct _AtspiAccessibleClass AtspiAccessibleClass;
+typedef struct _AtspiComponentClass AtspiComponentClass;
+
 typedef void (*AtspiEventListenerCB) (const AtspiEvent *event, void *user_data);
 
 
@@ -226,16 +244,27 @@ struct _AtspiObject
 
 struct _AtspiAccessible
 {
-  AtspiObject parent;
-  AtspiAccessible *accessible_parent;
-  GList *children;
-  AtspiRole role;
-  gint interfaces;
-  char *name;
-  char *description;
-  AtspiStateSet *states;
-  GHashTable *attributes;
-  guint cached_properties;
+    //GObject parent;
+    AtspiObject parent;
+    AtspiAccessible *accessible_parent;
+    GList *children;
+    AtspiRole role;
+    gint interfaces;
+    char *name;
+    char *description;
+    AtspiStateSet *states;
+    GHashTable *attributes;
+    guint cached_properties;
+};
+
+struct _AtspiAccessibleClass
+{
+    GObjectClass parent_class;
+};
+
+struct _AtspiComponentClass
+{
+    GObjectClass parent_class;
 };
 
 struct _AtspiEvent
@@ -279,7 +308,8 @@ struct _AtspiValue
 
 struct _AtspiComponent
 {
-    GTypeInterface parent;
+  GTypeInterface parent;
+  AtspiRole *role;
 };
 
 struct _AtspiScrollable
@@ -292,6 +322,19 @@ struct _AtspiRelation
     GTypeInterface parent;
 };
 
+struct _AtspiRect
+{
+  gint x;
+  gint y;
+  gint width;
+  gint height;
+};
+
+typedef enum {
+    ATSPI_COORD_TYPE_SCREEN,
+    ATSPI_COORD_TYPE_WINDOW,
+} AtspiCoordType;
+
 gchar * atspi_accessible_get_name (AtspiAccessible *obj, GError **error);
 gchar * atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error);
 gchar * atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error);
@@ -322,6 +365,15 @@ void atspi_free_memory(void);
 gboolean atspi_component_grab_highlight (AtspiComponent *obj, GError **error);
 AtspiScrollable *atspi_accessible_get_scrollable (AtspiAccessible *accessible);
 gboolean atspi_component_clear_highlight (AtspiComponent *obj, GError **error);
+AtspiRole atspi_accessible_get_role (AtspiAccessible *obj, GError **error);
+gint atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error);
+AtspiAccessible * atspi_accessible_get_child_at_index (AtspiAccessible *obj, gint child_index, GError **error);
+AtspiComponent * atspi_accessible_get_component (AtspiAccessible *obj);
+AtspiRect *atspi_component_get_extents (AtspiComponent *obj, AtspiCoordType ctype, GError **error);
+AtspiAccessible *atspi_create_accessible(void);
+void atspi_delete_accessible(AtspiAccessible *obj);
+void atspi_accessible_add_child(AtspiAccessible *obj, AtspiAccessible *child);
+void atpis_accessible_remove_children(AtspiAccessible *obj);
 AtspiEditableText * atspi_accessible_get_editable_text (AtspiAccessible *obj);
 GArray * atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error);
 AtspiRelationType atspi_relation_get_relation_type (AtspiRelation *obj);
index 3ebaf38..c2825f6 100644 (file)
@@ -1,8 +1,17 @@
 
 #include "screen_reader_spi.h"
+#include "flat_navi.h"
 #include <check.h>
 #include <stdio.h>
 #include <atspi/atspi.h>
+#include <Eina.h>
+
+static AtspiAccessible *root;
+static AtspiAccessible *child1;
+static AtspiAccessible *child2;
+static AtspiAccessible *child3;
+static AtspiAccessible *child4;
+static FlatNaviContext *ctx;
 
 void setup(void)
 {
@@ -28,6 +37,37 @@ void teardown(void)
 {
 }
 
+void setup_flat_navi()
+{
+    setup();
+    root = atspi_create_accessible();
+    root->role = ATSPI_ROLE_APPLICATION;
+    child1 = atspi_create_accessible();
+    child2 = atspi_create_accessible();
+    child3 = atspi_create_accessible();
+    child4 = atspi_create_accessible();
+    child1->role = ATSPI_ROLE_PUSH_BUTTON;
+    child2->role = ATSPI_ROLE_ICON;
+    child3->role = ATSPI_ROLE_CHECK_BOX;
+    child4->role = ATSPI_ROLE_ENTRY;
+    atspi_accessible_add_child(root, child1);
+    atspi_accessible_add_child(root, child2);
+    atspi_accessible_add_child(root, child3);
+    atspi_accessible_add_child(root, child4);
+    eina_init();
+    atspi_alloc_memory();
+    ctx = flat_navi_context_create(root);
+}
+
+void teardown_flat_navi()
+{
+    flat_navi_context_free(ctx);
+    atspi_free_memory();
+    eina_shutdown();
+    atspi_delete_accessible(root);
+    teardown();
+}
+
 START_TEST(spi_init_null_parameter)
 {
     spi_init(NULL);
@@ -83,12 +123,12 @@ START_TEST(spi_on_state_change_role)
     event.type = "test_event";
     sd->tracking_signal_name = "test_event";
     event.detail1 = 1;
-    accessible.role = ATSPI_ROLE_IMAGE;
+    accessible.role = ATSPI_ROLE_ICON;
     accessible.name = NULL;
     accessible.description = NULL;
     event.source = &accessible;
     char *return_value = spi_event_get_text_to_read(&event, sd);
-    fail_if(!return_value || strcmp(return_value, "Image"));
+    fail_if(!return_value || strcmp(return_value, atspi_accessible_get_role_name(&accessible, NULL)));
     free(return_value);
 }
 END_TEST
@@ -125,6 +165,175 @@ Service_Data *sd = get_pointer_to_service_data_struct();
 }
 END_TEST
 
+START_TEST(spi_flat_navi_context_create_null_parameter)
+{
+    FlatNaviContext *test_ctx = flat_navi_context_create(NULL);
+    fail_if(!test_ctx);
+    free(test_ctx);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_create_valid_parameter)
+{
+    FlatNaviContext *test_ctx = flat_navi_context_create(root);
+    fail_if(!test_ctx);
+    flat_navi_context_free(test_ctx);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_get_current_null_parameter)
+{
+    AtspiAccessible *current = flat_navi_context_current_get(NULL);
+    fail_if(current);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_get_current_valid_parameter)
+{
+    AtspiAccessible *current = flat_navi_context_current_get(ctx);
+    fail_if(!current || current != child1);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_next_null_parameter)
+{
+    AtspiAccessible *next = flat_navi_context_next(NULL);
+    fail_if(next);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_next_valid_parameter)
+{
+    AtspiAccessible *next = flat_navi_context_next(ctx);
+    fail_if(!next || next != child2);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_prev_null_parameter)
+{
+    AtspiAccessible *prev = flat_navi_context_prev(NULL);
+    fail_if(prev);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_prev_valid_parameter)
+{
+    AtspiAccessible *prev = flat_navi_context_prev(ctx);
+    fail_if(prev);
+    flat_navi_context_current_set(ctx, child4);
+    prev = flat_navi_context_prev(ctx);
+    fail_if(!prev || prev != child3);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_last_null_parameter)
+{
+    AtspiAccessible *last = flat_navi_context_last(NULL);
+    fail_if(last);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_last_valid_parameter)
+{
+    AtspiAccessible *last = flat_navi_context_last(ctx);
+    fail_if(!last || last != child2);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_first_null_parameter)
+{
+    AtspiAccessible *first = flat_navi_context_first(NULL);
+    fail_if(first);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_first_valid_parameter)
+{
+    AtspiAccessible *first = flat_navi_context_first(ctx);
+    fail_if(!first || first != child1);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_current_set_null_parameters)
+{
+    Eina_Bool ret = flat_navi_context_current_set(NULL, NULL);
+    fail_if(ret != EINA_FALSE);
+    ret = flat_navi_context_current_set(ctx, NULL);
+    fail_if(ret != EINA_FALSE);
+    AtspiAccessible *last = flat_navi_context_last(ctx);
+    ret = flat_navi_context_current_set(NULL, last);
+    fail_if(ret != EINA_FALSE);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_current_set_valid_parameters)
+{
+    AtspiAccessible *last = flat_navi_context_last(ctx);
+    Eina_Bool ret = flat_navi_context_current_set(ctx, last);
+    AtspiAccessible *current = flat_navi_context_current_get(ctx);
+    fail_if(ret != EINA_TRUE || current != last);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_prev_null_parameter)
+{
+    AtspiAccessible *prev = flat_navi_context_line_prev(NULL);
+    fail_if(prev);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_prev_valid_parameter)
+{
+    AtspiAccessible *prev = flat_navi_context_line_prev(ctx);
+    fail_if(prev);
+    flat_navi_context_current_set(ctx, child4);
+    prev = flat_navi_context_line_prev(ctx);
+    fail_if(!prev || prev != child1);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_next_null_parameter)
+{
+    AtspiAccessible *next = flat_navi_context_line_next(NULL);
+    fail_if(next);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_next_valid_parameter)
+{
+    AtspiAccessible *next = flat_navi_context_line_next(ctx);
+    fail_if(!next || next != child3);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_first_null_parameter)
+{
+    AtspiAccessible *first = flat_navi_context_line_first(NULL);
+    fail_if(first);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_first_valid_parameter)
+{
+    AtspiAccessible *first = flat_navi_context_line_first(ctx);
+    fail_if(!first || first != child1);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_last_null_parameter)
+{
+    AtspiAccessible *last = flat_navi_context_line_last(NULL);
+    fail_if(last);
+}
+END_TEST
+
+START_TEST(spi_flat_navi_context_line_last_valid_parameter)
+{
+    AtspiAccessible *last = flat_navi_context_line_last(ctx);
+    fail_if(!last || last != child3);
+}
+END_TEST
+
 Suite *screen_reader_suite(void)
 {
     Suite *s;
@@ -132,17 +341,20 @@ Suite *screen_reader_suite(void)
     TCase *tc_spi_screen_reader_on_state_changed;
     TCase *tc_spi_screen_reader_on_caret_move;
     TCase *tc_spi_screen_reader_on_access_value;
+    TCase *tc_spi_screen_reader_flat_navi;
 
     s = suite_create("Screen reader");
     tc_spi_screen_reader_init = tcase_create("tc_spi_screen_reader_init");
     tc_spi_screen_reader_on_state_changed = tcase_create("tc_spi_screen_reader_on_state_changed");
     tc_spi_screen_reader_on_caret_move = tcase_create("tc_spi_screen_reader_on_caret_move");
     tc_spi_screen_reader_on_access_value = tcase_create("tc_spi_screen_reader_on_access_value");
+    tc_spi_screen_reader_flat_navi = tcase_create("tc_scpi_screen_reader_flat_navi");
 
     tcase_add_checked_fixture(tc_spi_screen_reader_init, setup, teardown);
     tcase_add_checked_fixture(tc_spi_screen_reader_on_state_changed, setup, teardown);
     tcase_add_checked_fixture(tc_spi_screen_reader_on_caret_move, setup, teardown);
     tcase_add_checked_fixture(tc_spi_screen_reader_on_access_value, setup, teardown);
+    tcase_add_checked_fixture(tc_spi_screen_reader_flat_navi, setup_flat_navi, teardown_flat_navi);
 
     tcase_add_test(tc_spi_screen_reader_init, spi_init_null_parameter);
     tcase_add_test(tc_spi_screen_reader_init, spi_init_service_data_parameter);
@@ -151,11 +363,34 @@ Suite *screen_reader_suite(void)
     tcase_add_test(tc_spi_screen_reader_on_state_changed, spi_on_state_change_role);
     tcase_add_test(tc_spi_screen_reader_on_caret_move, spi_on_caret_move);
     tcase_add_test(tc_spi_screen_reader_on_access_value, spi_on_value_changed);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_create_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_create_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_get_current_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_get_current_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_next_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_next_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_prev_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_prev_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_last_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_last_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_first_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_first_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_current_set_null_parameters);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_current_set_valid_parameters);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_prev_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_prev_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_next_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_next_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_first_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_first_valid_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_last_null_parameter);
+    tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_last_valid_parameter);
 
     suite_add_tcase(s, tc_spi_screen_reader_init);
     suite_add_tcase(s, tc_spi_screen_reader_on_state_changed);
     suite_add_tcase(s, tc_spi_screen_reader_on_caret_move);
     suite_add_tcase(s, tc_spi_screen_reader_on_access_value);
+    suite_add_tcase(s, tc_spi_screen_reader_flat_navi);
 
     return s;
 }