[gtksourceview/wip/custom-word-boundaries-2] iter: more unit tests and bug fixes



commit bf95a2e1f38d51177e58e0810acdf0fbf6b73802
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Dec 21 17:40:08 2014 +0100

    iter: more unit tests and bug fixes

 gtksourceview/gtksourceiter.c |  228 +++++++++++++++++++++++++++++++++++------
 tests/test-iter.c             |   10 ++-
 2 files changed, 203 insertions(+), 35 deletions(-)
---
diff --git a/gtksourceview/gtksourceiter.c b/gtksourceview/gtksourceiter.c
index 9bc6241..b5ca203 100644
--- a/gtksourceview/gtksourceiter.c
+++ b/gtksourceview/gtksourceiter.c
@@ -47,20 +47,31 @@
 static void
 forward_full_word_end (GtkTextIter *iter)
 {
+       GtkTextIter pos;
+       gboolean non_blank_found = FALSE;
+
        /* It would be better to use gtk_text_iter_forward_visible_char(), but
         * it doesn't exist. So move by cursor position instead, it should be
         * equivalent here.
         */
 
-       while (g_unichar_isspace (gtk_text_iter_get_char (iter)))
+       pos = *iter;
+
+       while (g_unichar_isspace (gtk_text_iter_get_char (&pos)))
+       {
+               gtk_text_iter_forward_visible_cursor_position (&pos);
+       }
+
+       while (!gtk_text_iter_is_end (&pos) &&
+              !g_unichar_isspace (gtk_text_iter_get_char (&pos)))
        {
-               gtk_text_iter_forward_visible_cursor_position (iter);
+               non_blank_found = TRUE;
+               gtk_text_iter_forward_visible_cursor_position (&pos);
        }
 
-       while (!gtk_text_iter_is_end (iter) &&
-              !g_unichar_isspace (gtk_text_iter_get_char (iter)))
+       if (non_blank_found)
        {
-               gtk_text_iter_forward_visible_cursor_position (iter);
+               *iter = pos;
        }
 }
 
@@ -68,11 +79,15 @@ forward_full_word_end (GtkTextIter *iter)
 static void
 backward_full_word_start (GtkTextIter *iter)
 {
+       GtkTextIter pos;
        GtkTextIter prev;
+       gboolean non_blank_found = FALSE;
 
-       while (!gtk_text_iter_is_start (iter))
+       pos = *iter;
+
+       while (!gtk_text_iter_is_start (&pos))
        {
-               prev = *iter;
+               prev = pos;
                gtk_text_iter_backward_visible_cursor_position (&prev);
 
                if (!g_unichar_isspace (gtk_text_iter_get_char (&prev)))
@@ -80,12 +95,12 @@ backward_full_word_start (GtkTextIter *iter)
                        break;
                }
 
-               *iter = prev;
+               pos = prev;
        }
 
-       while (!gtk_text_iter_is_start (iter))
+       while (!gtk_text_iter_is_start (&pos))
        {
-               prev = *iter;
+               prev = pos;
                gtk_text_iter_backward_visible_cursor_position (&prev);
 
                if (g_unichar_isspace (gtk_text_iter_get_char (&prev)))
@@ -93,7 +108,13 @@ backward_full_word_start (GtkTextIter *iter)
                        break;
                }
 
-               *iter = prev;
+               non_blank_found = TRUE;
+               pos = prev;
+       }
+
+       if (non_blank_found)
+       {
+               *iter = pos;
        }
 }
 
@@ -102,9 +123,14 @@ starts_full_word (const GtkTextIter *iter)
 {
        GtkTextIter prev = *iter;
 
+       if (gtk_text_iter_is_end (iter))
+       {
+               return FALSE;
+       }
+
        if (!gtk_text_iter_backward_visible_cursor_position (&prev))
        {
-               return TRUE;
+               return !g_unichar_isspace (gtk_text_iter_get_char (iter));
        }
 
        return (g_unichar_isspace (gtk_text_iter_get_char (&prev)) &&
@@ -155,10 +181,7 @@ forward_extra_natural_word_end (GtkTextIter *iter)
 static void
 backward_extra_natural_word_start (GtkTextIter *iter)
 {
-       if (!gtk_text_iter_backward_visible_word_start (iter))
-       {
-               gtk_text_iter_set_offset (iter, 0);
-       }
+       gtk_text_iter_backward_visible_word_start (iter);
 
        while (!gtk_text_iter_is_start (iter))
        {
@@ -191,7 +214,7 @@ starts_extra_natural_word (const GtkTextIter *iter)
        prev = *iter;
        if (!gtk_text_iter_backward_visible_cursor_position (&prev))
        {
-               return starts_word;
+               return starts_word || gtk_text_iter_get_char (iter) == '_';
        }
 
        if (starts_word)
@@ -207,12 +230,20 @@ starts_extra_natural_word (const GtkTextIter *iter)
 static gboolean
 ends_extra_natural_word (const GtkTextIter *iter)
 {
-       gboolean ends_word = gtk_text_iter_ends_word (iter);
-       GtkTextIter next;
+       GtkTextIter prev;
+       gboolean ends_word;
+
+       prev = *iter;
+       if (!gtk_text_iter_backward_visible_cursor_position (&prev))
+       {
+               return FALSE;
+       }
+
+       ends_word = gtk_text_iter_ends_word (iter);
 
        if (gtk_text_iter_is_end (iter))
        {
-               return ends_word;
+               return ends_word || gtk_text_iter_get_char (&prev) == '_';
        }
 
        if (ends_word)
@@ -220,13 +251,9 @@ ends_extra_natural_word (const GtkTextIter *iter)
                return gtk_text_iter_get_char (iter) != '_';
        }
 
-       next = *iter;
-       gtk_text_iter_forward_visible_cursor_position (&next);
-
-       return (gtk_text_iter_get_char (iter) == '_' &&
-               (gtk_text_iter_is_end (&next) ||
-                (gtk_text_iter_get_char (&next) != '_' &&
-                 !gtk_text_iter_starts_word (&next))));
+       return (gtk_text_iter_get_char (&prev) == '_' &&
+               gtk_text_iter_get_char (iter) != '_' &&
+               !gtk_text_iter_starts_word (iter));
 }
 
 /* Similar to gtk_text_iter_forward_visible_word_end, but with a custom
@@ -278,9 +305,9 @@ _gtk_source_iter_forward_visible_word_end (GtkTextIter *iter)
         * word_start:    " |abcd()"
         *
         * Example 3:
-        * iter:          "abcd|()efgk"
-        * next_word_end: "abcd()efgk|"
-        * word_start:    "abcd()|efgk" -> the good one, at the end of the word "()".
+        * iter:          "abcd|()efgh"
+        * next_word_end: "abcd()efgh|"
+        * word_start:    "abcd()|efgh" -> the good one, at the end of the word "()".
         */
        word_start = next_word_end;
        backward_extra_natural_word_start (&word_start);
@@ -441,7 +468,7 @@ ends_word (const GtkTextIter *iter)
                return TRUE;
        }
 
-       /* Example: "abcd()|efgk", at the end of the word "()". */
+       /* Example: "abcd()|efgh", at the end of the word "()". */
        return !starts_full_word (iter) && starts_extra_natural_word (iter);
 }
 
@@ -570,7 +597,7 @@ test_forward_full_word_end (void)
        check_full_word_boundaries (TRUE, "  ---- abcd ", 0, 6);
        check_full_word_boundaries (TRUE, "  ---- abcd ", 4, 6);
        check_full_word_boundaries (TRUE, "  ---- abcd ", 8, 11);
-       check_full_word_boundaries (TRUE, "  ---- abcd ", 11, 12);
+       check_full_word_boundaries (TRUE, "  ---- abcd ", 11, 11);
        check_full_word_boundaries (TRUE, "  ---- abcd \n  ----", 11, 19);
 }
 
@@ -581,7 +608,7 @@ test_backward_full_word_start (void)
        check_full_word_boundaries (FALSE, "---- abcd  ", 11, 5);
        check_full_word_boundaries (FALSE, "---- abcd  ", 7, 5);
        check_full_word_boundaries (FALSE, "---- abcd  ", 3, 0);
-       check_full_word_boundaries (FALSE, " ---- abcd  ", 1, 0);
+       check_full_word_boundaries (FALSE, " ---- abcd  ", 1, 1);
        check_full_word_boundaries (FALSE, "abcd \n ---- abcd  ", 7, 0);
 }
 
@@ -606,6 +633,13 @@ test_starts_full_word (void)
        gtk_text_buffer_get_iter_at_offset (buffer, &iter, 10);
        g_assert (!starts_full_word (&iter));
 
+       gtk_text_buffer_set_text (buffer, " ab ", -1);
+       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+       g_assert (!starts_full_word (&iter));
+
+       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
+       g_assert (!starts_full_word (&iter));
+
        g_object_unref (buffer);
 }
 
@@ -616,7 +650,10 @@ test_ends_full_word (void)
        GtkTextIter iter;
 
        buffer = gtk_text_buffer_new (NULL);
-       gtk_text_buffer_set_text (buffer, "foo--- ---bar", -1);
+       gtk_text_buffer_set_text (buffer, "foo--- ---bar ", -1);
+
+       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 14);
+       g_assert (!ends_full_word (&iter));
 
        gtk_text_buffer_get_iter_at_offset (buffer, &iter, 13);
        g_assert (ends_full_word (&iter));
@@ -675,6 +712,11 @@ test_forward_extra_natural_word_end (void)
        check_extra_natural_word_boundaries (TRUE, str, 6, 11);
        check_extra_natural_word_boundaries (TRUE, str, 11, 21);
        check_extra_natural_word_boundaries (TRUE, str, 21, 21);
+
+       check_extra_natural_word_boundaries (TRUE, "ab ", 2, 2);
+       check_extra_natural_word_boundaries (TRUE, "a_ ", 2, 2);
+       check_extra_natural_word_boundaries (TRUE, "ab \ncd", 2, 6);
+       check_extra_natural_word_boundaries (TRUE, "a_ \n_d", 2, 6);
 }
 
 static void
@@ -689,15 +731,133 @@ test_backward_extra_natural_word_start (void)
        check_extra_natural_word_boundaries (FALSE, str, 6, 0);
        check_extra_natural_word_boundaries (FALSE, str, 5, 0);
        check_extra_natural_word_boundaries (FALSE, str, 0, 0);
+
+       check_extra_natural_word_boundaries (FALSE, " cd", 1, 1);
+       check_extra_natural_word_boundaries (FALSE, " _d", 1, 1);
+       check_extra_natural_word_boundaries (FALSE, "ab\n cd", 4, 0);
+       check_extra_natural_word_boundaries (FALSE, "_b\n c_", 4, 0);
+}
+
+static void
+check_starts_extra_natural_word (const gchar *buffer_text,
+                                gint         offset,
+                                gboolean     starts)
+{
+       GtkTextBuffer *buffer;
+       GtkTextIter iter;
+
+       buffer = gtk_text_buffer_new (NULL);
+       gtk_text_buffer_set_text (buffer, buffer_text, -1);
+
+       gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+       g_assert_cmpint (starts, ==, starts_extra_natural_word (&iter));
+
+       g_object_unref (buffer);
+}
+
+static void
+test_starts_extra_natural_word (void)
+{
+       check_starts_extra_natural_word ("ab", 2, FALSE);
+       check_starts_extra_natural_word ("hello", 0, TRUE);
+       check_starts_extra_natural_word ("__", 0, TRUE);
+       check_starts_extra_natural_word (" hello", 0, FALSE);
+       check_starts_extra_natural_word (" hello", 1, TRUE);
+       check_starts_extra_natural_word ("_hello", 1, FALSE);
+       check_starts_extra_natural_word ("()", 1, FALSE);
+       check_starts_extra_natural_word ("__", 1, FALSE);
+       check_starts_extra_natural_word (" __", 1, TRUE);
+       check_starts_extra_natural_word (" __hello", 1, TRUE);
+       check_starts_extra_natural_word ("hello_", 5, FALSE);
+}
+
+static void
+check_ends_extra_natural_word (const gchar *buffer_text,
+                              gint         offset,
+                              gboolean     ends)
+{
+       GtkTextBuffer *buffer;
+       GtkTextIter iter;
+
+       buffer = gtk_text_buffer_new (NULL);
+       gtk_text_buffer_set_text (buffer, buffer_text, -1);
+
+       gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+       g_assert_cmpint (ends, ==, ends_extra_natural_word (&iter));
+
+       g_object_unref (buffer);
+}
+
+static void
+test_ends_extra_natural_word (void)
+{
+       check_ends_extra_natural_word ("ab", 0, FALSE);
+       check_ends_extra_natural_word ("ab", 2, TRUE);
+       check_ends_extra_natural_word ("__", 2, TRUE);
+       check_ends_extra_natural_word ("ab ", 3, FALSE);
+       check_ends_extra_natural_word ("ab ", 2, TRUE);
+       check_ends_extra_natural_word ("ab_", 2, FALSE);
+       check_ends_extra_natural_word ("()", 1, FALSE);
+       check_ends_extra_natural_word ("__ ", 1, FALSE);
+       check_ends_extra_natural_word ("__ab ", 2, FALSE);
+       check_ends_extra_natural_word ("__ ", 2, TRUE);
+}
+
+static void
+check_word_boundaries (const gchar *buffer_text,
+                      gint         offset,
+                      gboolean     starts_word_result,
+                      gboolean     ends_word_result,
+                      gboolean     inside_word_result)
+{
+       GtkTextBuffer *buffer;
+       GtkTextIter iter;
+
+       buffer = gtk_text_buffer_new (NULL);
+       gtk_text_buffer_set_text (buffer, buffer_text, -1);
+
+       gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+
+       g_assert_cmpint (starts_word_result, ==, starts_word (&iter));
+       g_assert_cmpint (ends_word_result, ==, ends_word (&iter));
+       g_assert_cmpint (inside_word_result, ==, inside_word (&iter));
+
+       g_object_unref (buffer);
+}
+
+static void
+test_word_boundaries (void)
+{
+       check_word_boundaries ("ab()cd", 0, TRUE, FALSE, TRUE);
+       check_word_boundaries ("ab()cd", 1, FALSE, FALSE, TRUE);
+       check_word_boundaries ("ab()cd", 2, TRUE, TRUE, TRUE);
+       check_word_boundaries ("ab()cd", 3, FALSE, FALSE, TRUE);
+       check_word_boundaries ("ab()cd", 4, TRUE, TRUE, TRUE);
+       check_word_boundaries ("ab()cd", 5, FALSE, FALSE, TRUE);
+       check_word_boundaries ("ab()cd", 6, FALSE, TRUE, FALSE);
+
+       check_word_boundaries (" ab", 0, FALSE, FALSE, FALSE);
+       check_word_boundaries ("ab ", 3, FALSE, FALSE, FALSE);
+
+       check_word_boundaries (" () ", 1, TRUE, FALSE, TRUE);
+       check_word_boundaries (" () ", 3, FALSE, TRUE, FALSE);
 }
 
 void
 _gtk_source_iter_run_internal_unit_tests (void)
 {
+       /* Full word */
        test_forward_full_word_end ();
        test_backward_full_word_start ();
        test_starts_full_word ();
        test_ends_full_word ();
+
+       /* Extra-natural word */
        test_forward_extra_natural_word_end ();
        test_backward_extra_natural_word_start ();
+       test_starts_extra_natural_word ();
+       test_ends_extra_natural_word ();
+
+       /* Custom word */
+       test_word_boundaries ();
 }
diff --git a/tests/test-iter.c b/tests/test-iter.c
index 6f8c0fc..0dd129f 100644
--- a/tests/test-iter.c
+++ b/tests/test-iter.c
@@ -57,7 +57,11 @@ test_forward_word_end (void)
        check_word_boundaries (TRUE, "abcd", 2, 4, FALSE);
        check_word_boundaries (TRUE, "abcd ", 2, 4, TRUE);
        check_word_boundaries (TRUE, " abcd()", 0, 5, TRUE);
-       check_word_boundaries (TRUE, "abcd()efgk", 4, 6, TRUE);
+       check_word_boundaries (TRUE, "abcd()efgh", 4, 6, TRUE);
+
+       check_word_boundaries (TRUE, "ab ", 2, 2, FALSE);
+       check_word_boundaries (TRUE, "ab \n", 2, 2, FALSE);
+       check_word_boundaries (TRUE, "ab \ncd", 2, 6, FALSE);
 }
 
 static void
@@ -68,6 +72,10 @@ test_backward_word_start (void)
        check_word_boundaries (FALSE, "()abcd ", 7, 2, TRUE);
        check_word_boundaries (FALSE, "abcd()", 6, 4, TRUE);
        check_word_boundaries (FALSE, "abcd()", 0, 0, FALSE);
+
+       check_word_boundaries (FALSE, " cd", 1, 1, FALSE);
+       check_word_boundaries (FALSE, "\n cd", 2, 2, FALSE);
+       check_word_boundaries (FALSE, "ab\n cd", 4, 0, TRUE);
 }
 
 int


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]