 419f3e9bcc
			
		
	
	419f3e9bcc
	
	
	
		
			
			2001-11-14 Havoc Pennington <hp@redhat.com> * tests/testtextbuffer.c (main): bulk of the tests were commented out, oops. * gtk/gtktextiter.c (find_paragraph_delimiter_for_line): make this function work, should resolve #63426 (gtk_text_iter_ends_line): return TRUE for the end iterator * gtk/gtktextiter.h: put padding back in GtkTextIter, I thought of a couple things that might get cached in here.
		
			
				
	
	
		
			1165 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1165 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Simplistic test suite */
 | |
| 
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| 
 | |
| #include <gtk/gtk.h>
 | |
| #include "../gtk/gtktexttypes.h" /* Private header, for UNKNOWN_CHAR */
 | |
| 
 | |
| static void
 | |
| gtk_text_iter_spew (const GtkTextIter *iter, const gchar *desc)
 | |
| {
 | |
|   g_print (" %20s: line %d / char %d / line char %d / line byte %d\n",
 | |
|            desc,
 | |
|            gtk_text_iter_get_line (iter),
 | |
|            gtk_text_iter_get_offset (iter),
 | |
|            gtk_text_iter_get_line_offset (iter),
 | |
|            gtk_text_iter_get_line_index (iter));
 | |
| }
 | |
| 
 | |
| static void fill_buffer (GtkTextBuffer *buffer);
 | |
| 
 | |
| static void run_tests (GtkTextBuffer *buffer);
 | |
| 
 | |
| static void check_get_set_text (GtkTextBuffer *buffer,
 | |
|                                 const char    *str);
 | |
| 
 | |
| 
 | |
| static void line_separator_tests (void);
 | |
| 
 | |
| static void logical_motion_tests (void);
 | |
| 
 | |
| int
 | |
| main (int argc, char** argv)
 | |
| {
 | |
|   GtkTextBuffer *buffer;
 | |
|   int n;
 | |
|   gunichar ch;
 | |
|   GtkTextIter start, end;
 | |
|   
 | |
|   gtk_init (&argc, &argv);
 | |
| 
 | |
|   /* Check UTF8 unknown char thing */
 | |
|   g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
 | |
|   ch = g_utf8_get_char (gtk_text_unknown_char_utf8);
 | |
|   g_assert (ch == GTK_TEXT_UNKNOWN_CHAR);
 | |
| 
 | |
|   /* First, we turn on btree debugging. */
 | |
|   gtk_debug_flags |= GTK_DEBUG_TEXT;
 | |
| 
 | |
|   /* Check some line separator stuff */
 | |
|   line_separator_tests ();
 | |
| 
 | |
|   /* Check log attr motion */
 | |
|   logical_motion_tests ();
 | |
|   
 | |
|   /* Create a buffer */
 | |
|   buffer = gtk_text_buffer_new (NULL);
 | |
| 
 | |
|   /* Check that buffer starts with one empty line and zero chars */
 | |
| 
 | |
|   n = gtk_text_buffer_get_line_count (buffer);
 | |
|   if (n != 1)
 | |
|     g_error ("%d lines, expected 1", n);
 | |
| 
 | |
|   n = gtk_text_buffer_get_char_count (buffer);
 | |
|   if (n != 0)
 | |
|     g_error ("%d chars, expected 0", n);
 | |
| 
 | |
|   /* empty first line contains 0 chars */
 | |
|   gtk_text_buffer_get_start_iter (buffer, &start);
 | |
|   n = gtk_text_iter_get_chars_in_line (&start);
 | |
|   if (n != 0)
 | |
|     g_error ("%d chars in first line, expected 0", n);
 | |
|   n = gtk_text_iter_get_bytes_in_line (&start);
 | |
|   if (n != 0)
 | |
|     g_error ("%d bytes in first line, expected 0", n);
 | |
|   
 | |
|   /* Run gruesome alien test suite on buffer */
 | |
|   run_tests (buffer);
 | |
| 
 | |
|   /* Check set/get text */
 | |
|   check_get_set_text (buffer, "Hello");
 | |
|   check_get_set_text (buffer, "Hello\n");
 | |
|   check_get_set_text (buffer, "Hello\r\n");
 | |
|   check_get_set_text (buffer, "Hello\r");
 | |
|   check_get_set_text (buffer, "Hello\nBar\nFoo");
 | |
|   check_get_set_text (buffer, "Hello\nBar\nFoo\n");
 | |
| 
 | |
|   g_print ("get/set tests passed.\n");
 | |
|   
 | |
|   /* Put stuff in the buffer */
 | |
| 
 | |
|   fill_buffer (buffer);
 | |
| 
 | |
|   /* Subject stuff-bloated buffer to further torment */
 | |
|   run_tests (buffer);
 | |
| 
 | |
|   /* Delete all stuff from the buffer */
 | |
|   gtk_text_buffer_get_bounds (buffer, &start, &end);
 | |
|   gtk_text_buffer_delete (buffer, &start, &end);
 | |
| 
 | |
|   /* Check buffer for emptiness (note that a single
 | |
|      empty line always remains in the buffer) */
 | |
|   n = gtk_text_buffer_get_line_count (buffer);
 | |
|   if (n != 1)
 | |
|     g_error ("%d lines, expected 1", n);
 | |
| 
 | |
|   n = gtk_text_buffer_get_char_count (buffer);
 | |
|   if (n != 0)
 | |
|     g_error ("%d chars, expected 0", n);
 | |
| 
 | |
|   run_tests (buffer);
 | |
| 
 | |
|   gtk_text_buffer_set_text (buffer, "adcdef", -1);
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &start, 1);
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &end, 3);
 | |
|   gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &start, &end);
 | |
|   
 | |
|   run_tests (buffer);
 | |
|   
 | |
|   g_object_unref (G_OBJECT (buffer));
 | |
|   
 | |
|   g_print ("All tests passed.\n");
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static void
 | |
| check_get_set_text (GtkTextBuffer *buffer,
 | |
|                     const char    *str)
 | |
| {
 | |
|   GtkTextIter start, end, iter;
 | |
|   char *text;
 | |
|   int n;
 | |
|   
 | |
|   gtk_text_buffer_set_text (buffer, str, -1);
 | |
|   if (gtk_text_buffer_get_char_count (buffer) != g_utf8_strlen (str, -1))
 | |
|     g_error ("Wrong number of chars (%d not %d)",
 | |
|              gtk_text_buffer_get_char_count (buffer),
 | |
|              (int) g_utf8_strlen (str, -1));
 | |
|   gtk_text_buffer_get_bounds (buffer, &start, &end);
 | |
|   text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
 | |
|   if (strcmp (text, str) != 0)
 | |
|     g_error ("Got '%s' as buffer contents", text);
 | |
|   g_free (text);
 | |
| 
 | |
|   /* line char counts */
 | |
|   iter = start;
 | |
|   n = 0;
 | |
|   do
 | |
|     {
 | |
|       n += gtk_text_iter_get_chars_in_line (&iter);
 | |
|     }
 | |
|   while (gtk_text_iter_forward_line (&iter));
 | |
| 
 | |
|   if (n != gtk_text_buffer_get_char_count (buffer))
 | |
|     g_error ("Sum of chars in lines is %d but buffer char count is %d",
 | |
|              n, gtk_text_buffer_get_char_count (buffer));
 | |
| 
 | |
|   /* line byte counts */
 | |
|   iter = start;
 | |
|   n = 0;
 | |
|   do
 | |
|     {
 | |
|       n += gtk_text_iter_get_bytes_in_line (&iter);
 | |
|     }
 | |
|   while (gtk_text_iter_forward_line (&iter));
 | |
| 
 | |
|   if (n != strlen (str))
 | |
|     g_error ("Sum of chars in lines is %d but buffer byte count is %d",
 | |
|              n, strlen (str));
 | |
|   
 | |
|   gtk_text_buffer_set_text (buffer, "", -1);
 | |
| 
 | |
|   n = gtk_text_buffer_get_line_count (buffer);
 | |
|   if (n != 1)
 | |
|     g_error ("%d lines, expected 1", n);
 | |
| 
 | |
|   n = gtk_text_buffer_get_char_count (buffer);
 | |
|   if (n != 0)
 | |
|     g_error ("%d chars, expected 0", n);
 | |
| }
 | |
| 
 | |
| static gint
 | |
| count_toggles_at_iter (GtkTextIter *iter,
 | |
|                        GtkTextTag  *of_tag)
 | |
| {
 | |
|   GSList *tags;
 | |
|   GSList *tmp;
 | |
|   gint count = 0;
 | |
|   
 | |
|   /* get toggle-ons and toggle-offs */
 | |
|   tags = gtk_text_iter_get_toggled_tags (iter, TRUE);
 | |
|   tags = g_slist_concat (tags,
 | |
|                          gtk_text_iter_get_toggled_tags (iter, FALSE));
 | |
|   
 | |
|   tmp = tags;
 | |
|   while (tmp != NULL)
 | |
|     {
 | |
|       if (of_tag == NULL)
 | |
|         ++count;
 | |
|       else if (of_tag == tmp->data)
 | |
|         ++count;
 | |
|       
 | |
|       tmp = g_slist_next (tmp);
 | |
|     }
 | |
|   
 | |
|   g_slist_free (tags);
 | |
| 
 | |
|   return count;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| count_toggles_in_range_by_char (GtkTextBuffer     *buffer,
 | |
|                                 GtkTextTag        *of_tag,
 | |
|                                 const GtkTextIter *start,
 | |
|                                 const GtkTextIter *end)
 | |
| {
 | |
|   GtkTextIter iter;
 | |
|   gint count = 0;
 | |
|   
 | |
|   iter = *start;
 | |
|   do
 | |
|     {
 | |
|       count += count_toggles_at_iter (&iter, of_tag);
 | |
|       if (!gtk_text_iter_forward_char (&iter))
 | |
|         {
 | |
|           /* end iterator */
 | |
|           count += count_toggles_at_iter (&iter, of_tag);
 | |
|           break;
 | |
|         }
 | |
|     }
 | |
|   while (gtk_text_iter_compare (&iter, end) <= 0);
 | |
|   
 | |
|   return count;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| count_toggles_in_buffer (GtkTextBuffer *buffer,
 | |
|                          GtkTextTag    *of_tag)
 | |
| {
 | |
|   GtkTextIter start, end;
 | |
| 
 | |
|   gtk_text_buffer_get_bounds (buffer, &start, &end);
 | |
| 
 | |
|   return count_toggles_in_range_by_char (buffer, of_tag, &start, &end);
 | |
| }
 | |
| 
 | |
| static void
 | |
| check_specific_tag_in_range (GtkTextBuffer     *buffer,
 | |
|                              const gchar       *tag_name,
 | |
|                              const GtkTextIter *start,
 | |
|                              const GtkTextIter *end)
 | |
| {
 | |
|   GtkTextIter iter;
 | |
|   GtkTextTag *tag;
 | |
|   gboolean state;
 | |
|   gint count;
 | |
|   gint buffer_count;
 | |
|   gint last_offset;
 | |
| 
 | |
|   if (gtk_text_iter_compare (start, end) > 0)
 | |
|     {
 | |
|       g_print ("  (inverted range for checking tags, skipping)\n");
 | |
|       return;
 | |
|     }
 | |
|   
 | |
|   tag = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer),
 | |
|                                    tag_name);
 | |
| 
 | |
|   buffer_count = count_toggles_in_range_by_char (buffer, tag, start, end);
 | |
|   
 | |
|   state = FALSE;
 | |
|   count = 0;
 | |
| 
 | |
|   last_offset = -1;
 | |
|   iter = *start;
 | |
|   if (gtk_text_iter_toggles_tag (&iter, tag) ||
 | |
|       gtk_text_iter_forward_to_tag_toggle (&iter, tag))
 | |
|     {
 | |
|       do
 | |
|         {
 | |
|           gint this_offset;
 | |
|           
 | |
|           ++count;
 | |
| 
 | |
|           this_offset = gtk_text_iter_get_offset (&iter);
 | |
| 
 | |
|           if (this_offset <= last_offset)
 | |
|             g_error ("forward_to_tag_toggle moved in wrong direction");
 | |
| 
 | |
|           last_offset = this_offset;
 | |
|           
 | |
|           if (gtk_text_iter_begins_tag (&iter, tag))
 | |
|             {
 | |
|               if (state)
 | |
|                 g_error ("Tag %p is already on, and was toggled on?", tag);
 | |
|               state = TRUE;
 | |
|             }          
 | |
|           else if (gtk_text_iter_ends_tag (&iter, tag))
 | |
|             {
 | |
|               if (!state)
 | |
|                 g_error ("Tag %p toggled off, but wasn't toggled on?", tag);
 | |
|               state = FALSE;
 | |
|             }
 | |
|           else
 | |
|             g_error ("forward_to_tag_toggle went to a location without a toggle");
 | |
|         }
 | |
|       while (gtk_text_iter_forward_to_tag_toggle (&iter, tag) &&
 | |
|              gtk_text_iter_compare (&iter, end) <= 0);
 | |
|     }
 | |
| 
 | |
|   if (count != buffer_count)
 | |
|     g_error ("Counted %d tags iterating by char, %d iterating forward by tag toggle\n",
 | |
|              buffer_count, count);
 | |
|   
 | |
|   state = FALSE;
 | |
|   count = 0;
 | |
|   
 | |
|   iter = *end;
 | |
|   last_offset = gtk_text_iter_get_offset (&iter);
 | |
|   if (gtk_text_iter_toggles_tag (&iter, tag) ||
 | |
|       gtk_text_iter_backward_to_tag_toggle (&iter, tag))
 | |
|     {
 | |
|       do
 | |
|         {
 | |
|           gint this_offset;
 | |
|           
 | |
|           ++count;
 | |
| 
 | |
|           this_offset = gtk_text_iter_get_offset (&iter);
 | |
|           
 | |
|           if (this_offset >= last_offset)
 | |
|             g_error ("backward_to_tag_toggle moved in wrong direction");
 | |
|           
 | |
|           last_offset = this_offset;
 | |
| 
 | |
|           if (gtk_text_iter_begins_tag (&iter, tag))
 | |
|             {
 | |
|               if (!state)
 | |
|                 g_error ("Tag %p wasn't on when we got to the on toggle going backward?", tag);
 | |
|               state = FALSE;
 | |
|             }
 | |
|           else if (gtk_text_iter_ends_tag (&iter, tag))
 | |
|             {
 | |
|               if (state)
 | |
|                 g_error ("Tag %p off toggle, but we were already inside a tag?", tag);
 | |
|               state = TRUE;
 | |
|             }
 | |
|           else
 | |
|             g_error ("backward_to_tag_toggle went to a location without a toggle");
 | |
|         }
 | |
|       while (gtk_text_iter_backward_to_tag_toggle (&iter, tag) &&
 | |
|              gtk_text_iter_compare (&iter, start) >= 0);
 | |
|     }
 | |
| 
 | |
|   if (count != buffer_count)
 | |
|     g_error ("Counted %d tags iterating by char, %d iterating backward by tag toggle\n",
 | |
|              buffer_count, count);
 | |
| }
 | |
| 
 | |
| static void
 | |
| check_specific_tag (GtkTextBuffer *buffer,
 | |
|                     const gchar   *tag_name)
 | |
| {
 | |
|   GtkTextIter start, end;
 | |
| 
 | |
|   gtk_text_buffer_get_bounds (buffer, &start, &end);
 | |
|   check_specific_tag_in_range (buffer, tag_name, &start, &end);
 | |
|   gtk_text_iter_forward_chars (&start, 2);
 | |
|   gtk_text_iter_backward_chars (&end, 2);
 | |
|   if (gtk_text_iter_compare (&start, &end) < 0)
 | |
|     check_specific_tag_in_range (buffer, tag_name, &start, &end);
 | |
| }
 | |
| 
 | |
| static void
 | |
| run_tests (GtkTextBuffer *buffer)
 | |
| {
 | |
|   GtkTextIter iter;
 | |
|   GtkTextIter start;
 | |
|   GtkTextIter end;
 | |
|   GtkTextIter mark;
 | |
|   gint i, j;
 | |
|   gint num_chars;
 | |
|   GtkTextMark *bar_mark;
 | |
|   GtkTextTag *tag;
 | |
|   GHashTable *tag_states;
 | |
|   gint count;
 | |
|   gint buffer_count;
 | |
|   
 | |
|   gtk_text_buffer_get_bounds (buffer, &start, &end);
 | |
| 
 | |
|   /* Check that walking the tree via chars and via iterators produces
 | |
|    * the same number of indexable locations.
 | |
|    */
 | |
|   num_chars = gtk_text_buffer_get_char_count (buffer);
 | |
|   iter = start;
 | |
|   bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
 | |
|   i = 0;
 | |
|   while (i < num_chars)
 | |
|     {
 | |
|       GtkTextIter current;
 | |
|       GtkTextMark *foo_mark;
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, ¤t, i);
 | |
| 
 | |
|       if (!gtk_text_iter_equal (&iter, ¤t))
 | |
|         {
 | |
|           g_error ("get_char_index didn't return current iter");
 | |
|         }
 | |
| 
 | |
|       j = gtk_text_iter_get_offset (&iter);
 | |
| 
 | |
|       if (i != j)
 | |
|         {
 | |
|           g_error ("iter converted to %d not %d", j, i);
 | |
|         }
 | |
| 
 | |
|       /* get/set mark */
 | |
|       gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
 | |
| 
 | |
|       if (!gtk_text_iter_equal (&iter, &mark))
 | |
|         {
 | |
|           gtk_text_iter_spew (&iter, "iter");
 | |
|           gtk_text_iter_spew (&mark, "mark");
 | |
|           g_error ("Mark not moved to the right place.");
 | |
|         }
 | |
| 
 | |
|       foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
 | |
|       gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
 | |
|       gtk_text_buffer_delete_mark (buffer, foo_mark);
 | |
| 
 | |
|       if (!gtk_text_iter_equal (&iter, &mark))
 | |
|         {
 | |
|           gtk_text_iter_spew (&iter, "iter");
 | |
|           gtk_text_iter_spew (&mark, "mark");
 | |
|           g_error ("Mark not created in the right place.");
 | |
|         }
 | |
| 
 | |
|       if (gtk_text_iter_is_end (&iter))
 | |
|         g_error ("iterators ran out before chars (offset %d of %d)",
 | |
|                  i, num_chars);
 | |
| 
 | |
|       gtk_text_iter_forward_char (&iter);
 | |
| 
 | |
|       gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
 | |
| 
 | |
|       ++i;
 | |
|     }
 | |
| 
 | |
|   if (!gtk_text_iter_equal (&iter, &end))
 | |
|     g_error ("Iterating over all chars didn't end with the end iter");
 | |
| 
 | |
|   /* Do the tree-walk backward
 | |
|    */
 | |
|   num_chars = gtk_text_buffer_get_char_count (buffer);
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
 | |
| 
 | |
|   gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
 | |
| 
 | |
|   i = num_chars;
 | |
| 
 | |
|   if (!gtk_text_iter_equal (&iter, &end))
 | |
|     g_error ("iter at char -1 is not equal to the end iterator");
 | |
| 
 | |
|   while (i >= 0)
 | |
|     {
 | |
|       GtkTextIter current;
 | |
|       GtkTextMark *foo_mark;
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, ¤t, i);
 | |
| 
 | |
|       if (!gtk_text_iter_equal (&iter, ¤t))
 | |
|         {
 | |
|           g_error ("get_char_index didn't return current iter while going backward");
 | |
|         }
 | |
|       j = gtk_text_iter_get_offset (&iter);
 | |
| 
 | |
|       if (i != j)
 | |
|         {
 | |
|           g_error ("going backward, iter converted to %d not %d", j, i);
 | |
|         }
 | |
| 
 | |
|       /* get/set mark */
 | |
|       gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
 | |
| 
 | |
|       if (!gtk_text_iter_equal (&iter, &mark))
 | |
|         {
 | |
|           gtk_text_iter_spew (&iter, "iter");
 | |
|           gtk_text_iter_spew (&mark, "mark");
 | |
|           g_error ("Mark not moved to the right place.");
 | |
|         }
 | |
| 
 | |
|       foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
 | |
|       gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
 | |
|       gtk_text_buffer_delete_mark (buffer, foo_mark);
 | |
| 
 | |
|       if (!gtk_text_iter_equal (&iter, &mark))
 | |
|         {
 | |
|           gtk_text_iter_spew (&iter, "iter");
 | |
|           gtk_text_iter_spew (&mark, "mark");
 | |
|           g_error ("Mark not created in the right place.");
 | |
|         }
 | |
| 
 | |
|       if (i > 0)
 | |
|         {
 | |
|           if (!gtk_text_iter_backward_char (&iter))
 | |
|             g_error ("iterators ran out before char indexes");
 | |
| 
 | |
|           gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
 | |
|         }
 | |
|       else
 | |
|         {
 | |
|           if (gtk_text_iter_backward_char (&iter))
 | |
|             g_error ("went backward from 0?");
 | |
|         }
 | |
| 
 | |
|       --i;
 | |
|     }
 | |
| 
 | |
|   if (!gtk_text_iter_equal (&iter, &start))
 | |
|     g_error ("Iterating backward over all chars didn't end with the start iter");
 | |
| 
 | |
|   /*
 | |
|    * Check that get_line_count returns the same number of lines
 | |
|    * as walking the tree by line
 | |
|    */
 | |
|   i = 1; /* include current (first) line */
 | |
|   gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
 | |
|   while (gtk_text_iter_forward_line (&iter))
 | |
|     ++i;
 | |
| 
 | |
|   if (i != gtk_text_buffer_get_line_count (buffer))
 | |
|     g_error ("Counted %d lines, buffer has %d", i,
 | |
|              gtk_text_buffer_get_line_count (buffer));
 | |
| 
 | |
|   /*
 | |
|    * Check that moving over tag toggles thinks about working.
 | |
|    */
 | |
| 
 | |
|   buffer_count = count_toggles_in_buffer (buffer, NULL);
 | |
|   
 | |
|   tag_states = g_hash_table_new (NULL, NULL);
 | |
|   count = 0;
 | |
|   
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
 | |
|   if (gtk_text_iter_toggles_tag (&iter, NULL) ||
 | |
|       gtk_text_iter_forward_to_tag_toggle (&iter, NULL))
 | |
|     {
 | |
|       do
 | |
|         {
 | |
|           GSList *tags;
 | |
|           GSList *tmp;
 | |
|           gboolean found_some = FALSE;
 | |
|           
 | |
|           /* get toggled-on tags */
 | |
|           tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
 | |
| 
 | |
|           if (tags)
 | |
|             found_some = TRUE;
 | |
|           
 | |
|           tmp = tags;
 | |
|           while (tmp != NULL)
 | |
|             {
 | |
|               ++count;
 | |
|               
 | |
|               tag = tmp->data;
 | |
|               
 | |
|               if (g_hash_table_lookup (tag_states, tag))
 | |
|                 g_error ("Tag %p is already on, and was toggled on?", tag);
 | |
| 
 | |
|               g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
 | |
|           
 | |
|               tmp = g_slist_next (tmp);
 | |
|             }
 | |
| 
 | |
|           g_slist_free (tags);
 | |
|       
 | |
|           /* get toggled-off tags */
 | |
|           tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
 | |
| 
 | |
|           if (tags)
 | |
|             found_some = TRUE;
 | |
|           
 | |
|           tmp = tags;
 | |
|           while (tmp != NULL)
 | |
|             {
 | |
|               ++count;
 | |
|               
 | |
|               tag = tmp->data;
 | |
| 
 | |
|               if (!g_hash_table_lookup (tag_states, tag))
 | |
|                 g_error ("Tag %p is already off, and was toggled off?", tag);
 | |
| 
 | |
|               g_hash_table_remove (tag_states, tag);
 | |
|           
 | |
|               tmp = g_slist_next (tmp);
 | |
|             }
 | |
| 
 | |
|           g_slist_free (tags);
 | |
| 
 | |
|           if (!found_some)
 | |
|             g_error ("No tags found going forward to tag toggle.");
 | |
| 
 | |
|         }
 | |
|       while (gtk_text_iter_forward_to_tag_toggle (&iter, NULL));
 | |
|     }
 | |
|   
 | |
|   g_hash_table_destroy (tag_states);
 | |
| 
 | |
|   if (count != buffer_count)
 | |
|     g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
 | |
|              buffer_count, count);
 | |
|   
 | |
|   /* Go backward; here TRUE in the hash means we saw
 | |
|    * an off toggle last.
 | |
|    */
 | |
|   
 | |
|   tag_states = g_hash_table_new (NULL, NULL);
 | |
|   count = 0;
 | |
|   
 | |
|   gtk_text_buffer_get_end_iter (buffer, &iter);
 | |
|   if (gtk_text_iter_toggles_tag (&iter, NULL) ||
 | |
|       gtk_text_iter_backward_to_tag_toggle (&iter, NULL))
 | |
|     {
 | |
|       do
 | |
|         {
 | |
|           GSList *tags;
 | |
|           GSList *tmp;
 | |
|           gboolean found_some = FALSE;
 | |
|           
 | |
|           /* get toggled-off tags */
 | |
|           tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
 | |
| 
 | |
|           if (tags)
 | |
|             found_some = TRUE;
 | |
|           
 | |
|           tmp = tags;
 | |
|           while (tmp != NULL)
 | |
|             {
 | |
|               ++count;
 | |
|               
 | |
|               tag = tmp->data;
 | |
| 
 | |
|               if (g_hash_table_lookup (tag_states, tag))
 | |
|                 g_error ("Tag %p has two off-toggles in a row?", tag);
 | |
|           
 | |
|               g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
 | |
|           
 | |
|               tmp = g_slist_next (tmp);
 | |
|             }
 | |
| 
 | |
|           g_slist_free (tags);
 | |
|       
 | |
|           /* get toggled-on tags */
 | |
|           tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
 | |
| 
 | |
|           if (tags)
 | |
|             found_some = TRUE;
 | |
|           
 | |
|           tmp = tags;
 | |
|           while (tmp != NULL)
 | |
|             {
 | |
|               ++count;
 | |
|               
 | |
|               tag = tmp->data;
 | |
| 
 | |
|               if (!g_hash_table_lookup (tag_states, tag))
 | |
|                 g_error ("Tag %p was toggled on, but saw no off-toggle?", tag);
 | |
| 
 | |
|               g_hash_table_remove (tag_states, tag);
 | |
|           
 | |
|               tmp = g_slist_next (tmp);
 | |
|             }
 | |
| 
 | |
|           g_slist_free (tags);
 | |
| 
 | |
|           if (!found_some)
 | |
|             g_error ("No tags found going backward to tag toggle.");
 | |
|         }
 | |
|       while (gtk_text_iter_backward_to_tag_toggle (&iter, NULL));
 | |
|     }
 | |
|   
 | |
|   g_hash_table_destroy (tag_states);
 | |
| 
 | |
|   if (count != buffer_count)
 | |
|     g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
 | |
|              buffer_count, count);
 | |
| 
 | |
|   check_specific_tag (buffer, "fg_red");
 | |
|   check_specific_tag (buffer, "bg_green");
 | |
|   check_specific_tag (buffer, "front_tag");
 | |
|   check_specific_tag (buffer, "center_tag");
 | |
|   check_specific_tag (buffer, "end_tag");
 | |
| }
 | |
| 
 | |
| 
 | |
| static const char  *book_closed_xpm[] = {
 | |
| "16 16 6 1",
 | |
| "       c None s None",
 | |
| ".      c black",
 | |
| "X      c red",
 | |
| "o      c yellow",
 | |
| "O      c #808080",
 | |
| "#      c white",
 | |
| "                ",
 | |
| "       ..       ",
 | |
| "     ..XX.      ",
 | |
| "   ..XXXXX.     ",
 | |
| " ..XXXXXXXX.    ",
 | |
| ".ooXXXXXXXXX.   ",
 | |
| "..ooXXXXXXXXX.  ",
 | |
| ".X.ooXXXXXXXXX. ",
 | |
| ".XX.ooXXXXXX..  ",
 | |
| " .XX.ooXXX..#O  ",
 | |
| "  .XX.oo..##OO. ",
 | |
| "   .XX..##OO..  ",
 | |
| "    .X.#OO..    ",
 | |
| "     ..O..      ",
 | |
| "      ..        ",
 | |
| "                "};
 | |
| 
 | |
| static void
 | |
| fill_buffer (GtkTextBuffer *buffer)
 | |
| {
 | |
|   GtkTextTag *tag;
 | |
|   GdkColor color, color2;
 | |
|   GtkTextIter iter;
 | |
|   GtkTextIter iter2;
 | |
|   GdkPixbuf *pixbuf;
 | |
|   int i;
 | |
| 
 | |
|   color.red = color.green = 0;
 | |
|   color.blue = 0xffff;
 | |
|   color2.red = 0xfff;
 | |
|   color2.blue = 0x0;
 | |
|   color2.green = 0;
 | |
|   
 | |
|   gtk_text_buffer_create_tag (buffer, "fg_blue",
 | |
|                               "foreground_gdk", &color,
 | |
|                               "background_gdk", &color2,
 | |
|                               "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
 | |
|                               NULL);
 | |
| 
 | |
|   color.blue = color.green = 0;
 | |
|   color.red = 0xffff;
 | |
|   
 | |
|   gtk_text_buffer_create_tag (buffer, "fg_red",
 | |
|                               "rise", -4,
 | |
|                               "foreground_gdk", &color,
 | |
|                               NULL);
 | |
| 
 | |
|   color.blue = color.red = 0;
 | |
|   color.green = 0xffff;
 | |
|   
 | |
|   gtk_text_buffer_create_tag (buffer, "bg_green",
 | |
|                               "background_gdk", &color,
 | |
|                               "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
 | |
|                               NULL);
 | |
| 
 | |
|   pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
 | |
| 
 | |
|   g_assert (pixbuf != NULL);
 | |
| 
 | |
|   i = 0;
 | |
|   while (i < 10)
 | |
|     {
 | |
|       gchar *str;
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
 | |
| 
 | |
|       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
 | |
| 
 | |
|       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
 | |
| 
 | |
|       str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
 | |
|                             i);
 | |
| 
 | |
|       gtk_text_buffer_insert (buffer, &iter, str, -1);
 | |
| 
 | |
|       g_free (str);
 | |
| 
 | |
|       gtk_text_buffer_insert (buffer, &iter,
 | |
|                               "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
 | |
|                               /* This is UTF8 stuff, Emacs doesn't
 | |
|                                  really know how to display it */
 | |
|                               "Spanish (Español) ¡Hola! / French (Français) Bonjour, Salut / German (Deutsch Süd) Grüß Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash)  (ภาษาไทย)  สวัสดีครับ, สวัสดีค่ะ\n",
 | |
|                               -1);
 | |
| 
 | |
|       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
 | |
|       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
 | |
| 
 | |
|       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
 | |
| 
 | |
|       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
 | |
| 
 | |
|       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
 | |
| 
 | |
|       gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
 | |
|       iter2 = iter;
 | |
|       gtk_text_iter_forward_chars (&iter2, 10);
 | |
| 
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 | |
| 
 | |
|       gtk_text_iter_forward_chars (&iter, 7);
 | |
|       gtk_text_iter_forward_chars (&iter2, 10);
 | |
| 
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 | |
| 
 | |
|       gtk_text_iter_forward_chars (&iter, 12);
 | |
|       gtk_text_iter_forward_chars (&iter2, 10);
 | |
| 
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 | |
| 
 | |
|       gtk_text_iter_forward_chars (&iter, 10);
 | |
|       gtk_text_iter_forward_chars (&iter2, 15);
 | |
| 
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 | |
| 
 | |
|       gtk_text_iter_forward_chars (&iter, 20);
 | |
|       gtk_text_iter_forward_chars (&iter2, 20);
 | |
| 
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 | |
| 
 | |
|       gtk_text_iter_backward_chars (&iter, 25);
 | |
|       gtk_text_iter_forward_chars (&iter2, 5);
 | |
| 
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
 | |
|       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 | |
| 
 | |
|       gtk_text_iter_forward_chars (&iter, 15);
 | |
|       gtk_text_iter_backward_chars (&iter2, 10);
 | |
| 
 | |
|       gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
 | |
|       gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 | |
| 
 | |
|       ++i;
 | |
|     }
 | |
| 
 | |
|   /* Put in tags that are just at the beginning, and just near the end,
 | |
|    * and just near the middle.
 | |
|    */
 | |
|   tag = gtk_text_buffer_create_tag (buffer, "front_tag", NULL);
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &iter2, 300);
 | |
| 
 | |
|   gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
 | |
|   
 | |
|   tag = gtk_text_buffer_create_tag (buffer, "end_tag", NULL);
 | |
|   gtk_text_buffer_get_end_iter (buffer, &iter2);
 | |
|   gtk_text_iter_backward_chars (&iter2, 12);
 | |
|   iter = iter2;
 | |
|   gtk_text_iter_backward_chars (&iter, 157);
 | |
| 
 | |
|   gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
 | |
|   
 | |
|   tag = gtk_text_buffer_create_tag (buffer, "center_tag", NULL);
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &iter,
 | |
|                                       gtk_text_buffer_get_char_count (buffer)/2);
 | |
|   gtk_text_iter_backward_chars (&iter, 37);
 | |
|   iter2 = iter;
 | |
|   gtk_text_iter_forward_chars (&iter2, 57);
 | |
| 
 | |
|   gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
 | |
| 
 | |
|   gdk_pixbuf_unref (pixbuf);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Line separator tests (initially to avoid regression on bugzilla #57428)
 | |
|  */
 | |
| 
 | |
| static void
 | |
| test_line_separation (const char* str,
 | |
|                       gboolean    expect_next_line,
 | |
|                       gboolean    expect_end_iter,
 | |
|                       int         expected_line_count,
 | |
|                       int         expected_line_break,
 | |
|                       int         expected_next_line_start)
 | |
| {
 | |
|   GtkTextIter iter;
 | |
|   GtkTextBuffer* buffer;
 | |
|   gboolean on_next_line;
 | |
|   gboolean on_end_iter;
 | |
|   gint new_pos;
 | |
| 
 | |
|   buffer = gtk_text_buffer_new (NULL);
 | |
| 
 | |
|   gtk_text_buffer_set_text (buffer, str, -1);
 | |
|   gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
 | |
| 
 | |
|   g_assert (gtk_text_iter_ends_line (&iter) || gtk_text_iter_is_end (&iter));
 | |
| 
 | |
|   g_assert (gtk_text_buffer_get_line_count (buffer) == expected_line_count);
 | |
|   
 | |
|   on_next_line = gtk_text_iter_forward_line (&iter);
 | |
| 
 | |
|   g_assert (expect_next_line == on_next_line);
 | |
| 
 | |
|   on_end_iter = gtk_text_iter_is_end (&iter);
 | |
| 
 | |
|   g_assert (on_end_iter == expect_end_iter);
 | |
|   
 | |
|   new_pos = gtk_text_iter_get_offset (&iter);
 | |
|     
 | |
|   if (on_next_line)
 | |
|     g_assert (expected_next_line_start == new_pos);
 | |
| 
 | |
|   ++expected_line_break;
 | |
|   while (expected_line_break < expected_next_line_start)
 | |
|     {
 | |
|       gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
 | |
| 
 | |
|       g_assert (!gtk_text_iter_ends_line (&iter));
 | |
| 
 | |
|       on_next_line = gtk_text_iter_forward_line (&iter);
 | |
|         
 | |
|       g_assert (expect_next_line == on_next_line);
 | |
|         
 | |
|       new_pos = gtk_text_iter_get_offset (&iter);
 | |
|         
 | |
|       if (on_next_line)
 | |
|         g_assert (expected_next_line_start == new_pos);
 | |
|         
 | |
|       ++expected_line_break;
 | |
|     }
 | |
| 
 | |
|   /* FIXME tests for backward line */
 | |
|   
 | |
|   g_object_unref (G_OBJECT (buffer));
 | |
| }
 | |
| 
 | |
| 
 | |
| static void
 | |
| line_separator_tests (void)
 | |
| {
 | |
|   char *str;
 | |
|   char buf[7] = { '\0', };
 | |
| 
 | |
|   /* Only one character has type G_UNICODE_PARAGRAPH_SEPARATOR in
 | |
|    * Unicode 3.0; update this if that changes.
 | |
|    */
 | |
| #define PARAGRAPH_SEPARATOR 0x2029
 | |
|   
 | |
|   test_line_separation ("line", FALSE, TRUE, 1, 4, 4);
 | |
|   test_line_separation ("line\r\n", FALSE, TRUE, 2, 4, 6);
 | |
|   test_line_separation ("line\r", FALSE, TRUE, 2, 4, 5);
 | |
|   test_line_separation ("line\n", FALSE, TRUE, 2, 4, 5);
 | |
|   test_line_separation ("line\rqw", TRUE, FALSE, 2, 4, 5);
 | |
|   test_line_separation ("line\nqw", TRUE, FALSE, 2, 4, 5);
 | |
|   test_line_separation ("line\r\nqw", TRUE, FALSE, 2, 4, 6);
 | |
|   
 | |
|   g_unichar_to_utf8 (PARAGRAPH_SEPARATOR, buf);
 | |
|   
 | |
|   str = g_strdup_printf ("line%s", buf);
 | |
|   test_line_separation (str, FALSE, TRUE, 2, 4, 5);
 | |
|   g_free (str);
 | |
|   str = g_strdup_printf ("line%sqw", buf);
 | |
|   test_line_separation (str, TRUE, FALSE, 2, 4, 5);
 | |
|   g_free (str);
 | |
| 
 | |
|   g_print ("Line separator tests passed\n");
 | |
| }
 | |
| 
 | |
| static void
 | |
| logical_motion_tests (void)
 | |
| {
 | |
|   char *str;
 | |
|   char buf1[7] = { '\0', };
 | |
|   char buf2[7] = { '\0', };
 | |
|   char buf3[7] = { '\0', };
 | |
|   int expected[30];
 | |
|   int expected_steps;
 | |
|   int i;
 | |
|   GtkTextBuffer *buffer;
 | |
|   GtkTextIter iter;
 | |
|   
 | |
|   buffer = gtk_text_buffer_new (NULL);
 | |
|   
 | |
| #define LEADING_JAMO 0x1111
 | |
| #define VOWEL_JAMO 0x1167
 | |
| #define TRAILING_JAMO 0x11B9
 | |
|   
 | |
|   g_unichar_to_utf8 (LEADING_JAMO, buf1);
 | |
|   g_unichar_to_utf8 (VOWEL_JAMO, buf2);
 | |
|   g_unichar_to_utf8 (TRAILING_JAMO, buf3);
 | |
| 
 | |
|   /* Build the string "abc<leading><vowel><trailing>def\r\nxyz" */
 | |
|   str = g_strconcat ("abc", buf1, buf2, buf3, "def\r\nxyz", NULL);
 | |
|   gtk_text_buffer_set_text (buffer, str, -1);
 | |
|   g_free (str);
 | |
|   
 | |
|   /* Check cursor positions */
 | |
|   memset (expected, 0, sizeof (expected));
 | |
|   expected[0] = 0;    /* before 'a' */
 | |
|   expected[1] = 1;    /* before 'b' */
 | |
|   expected[2] = 2;    /* before 'c' */
 | |
|   expected[3] = 3;    /* before jamo */
 | |
|   expected[4] = 6;    /* before 'd' */
 | |
|   expected[5] = 7;    /* before 'e' */
 | |
|   expected[6] = 8;    /* before 'f' */
 | |
|   expected[7] = 9;    /* before '\r' */
 | |
|   expected[8] = 11;   /* before 'x' */
 | |
|   expected[9] = 12;   /* before 'y' */
 | |
|   expected[10] = 13;  /* before 'z' */
 | |
|   expected[11] = 14;  /* after 'z' (only matters going backward) */
 | |
|   expected_steps = 11;
 | |
|   
 | |
|   gtk_text_buffer_get_start_iter (buffer, &iter);
 | |
|   i = 0;
 | |
|   do
 | |
|     {
 | |
|       int pos;
 | |
| 
 | |
|       pos = gtk_text_iter_get_offset (&iter);
 | |
|       
 | |
|       if (pos != expected[i])
 | |
|         {
 | |
|           g_error ("Cursor position %d, expected %d",
 | |
|                    pos, expected[i]);
 | |
|         }
 | |
| 
 | |
|       ++i;      
 | |
|     }
 | |
|   while (gtk_text_iter_forward_cursor_position (&iter));
 | |
| 
 | |
|   if (!gtk_text_iter_is_end (&iter))
 | |
|     g_error ("Expected to stop at the end iterator\n");
 | |
| 
 | |
|   if (!gtk_text_iter_is_cursor_position (&iter))
 | |
|     g_error ("Should be a cursor position before the end iterator");
 | |
|   
 | |
|   if (i != expected_steps)
 | |
|     g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
 | |
| 
 | |
|   i = expected_steps;
 | |
|   do
 | |
|     {
 | |
|       int pos;
 | |
| 
 | |
|       pos = gtk_text_iter_get_offset (&iter);
 | |
|       
 | |
|       if (pos != expected[i])
 | |
|         {
 | |
|           g_error ("Moving backward, cursor position %d, expected %d",
 | |
|                    pos, expected[i]);
 | |
|         }
 | |
| 
 | |
|       /* g_print ("%d = %d\n", pos, expected[i]); */
 | |
|       
 | |
|       --i;
 | |
|     }
 | |
|   while (gtk_text_iter_backward_cursor_position (&iter));
 | |
| 
 | |
|   if (i != -1)
 | |
|     g_error ("Expected %d steps, there were actually %d\n", expected_steps - i, i);
 | |
| 
 | |
|   if (!gtk_text_iter_is_start (&iter))
 | |
|     g_error ("Expected to stop at the start iterator\n");
 | |
| 
 | |
| 
 | |
|   /* Check sentence boundaries */
 | |
|   
 | |
|   gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
 | |
| 
 | |
|   memset (expected, 0, sizeof (expected));
 | |
| 
 | |
|   expected[0] = 0;    /* before first Hi */
 | |
|   expected[1] = 3;    /* After first . */
 | |
|   expected[2] = 7;    /* After second . */
 | |
|   expected[3] = 12;   /* After ! */
 | |
|   expected[4] = 16;   /* After third . */
 | |
|   expected[5] = 20;   /* After ? */
 | |
|   
 | |
|   expected_steps = 6;
 | |
|   
 | |
|   gtk_text_buffer_get_start_iter (buffer, &iter);
 | |
|   i = 0;
 | |
|   do
 | |
|     {
 | |
|       int pos;
 | |
| 
 | |
|       pos = gtk_text_iter_get_offset (&iter);
 | |
| 
 | |
|       if (pos != expected[i])
 | |
|         {
 | |
|           g_error ("Sentence position %d, expected %d",
 | |
|                    pos, expected[i]);
 | |
|         }
 | |
| 
 | |
|       if (i != 0 &&
 | |
|           !gtk_text_iter_is_end (&iter) &&
 | |
|           !gtk_text_iter_ends_sentence (&iter))
 | |
|         g_error ("Iterator at %d should end a sentence", pos);
 | |
|       
 | |
|       ++i;
 | |
|     }
 | |
|   while (gtk_text_iter_forward_sentence_end (&iter));
 | |
| 
 | |
|   if (i != expected_steps)
 | |
|     g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
 | |
| 
 | |
|   if (!gtk_text_iter_is_end (&iter))
 | |
|     g_error ("Expected to stop at the end iterator\n");
 | |
|   
 | |
|   gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
 | |
| 
 | |
|   memset (expected, 0, sizeof (expected));
 | |
| 
 | |
|   expected[0] = 24;
 | |
|   expected[1] = 21;
 | |
|   expected[2] = 17;
 | |
|   expected[3] = 13;
 | |
|   expected[4] = 9;
 | |
|   expected[5] = 4;
 | |
|   expected[6] = 0;
 | |
|   
 | |
|   expected_steps = 7;
 | |
|   
 | |
|   gtk_text_buffer_get_end_iter (buffer, &iter);
 | |
|   i = 0;
 | |
|   do
 | |
|     {
 | |
|       int pos;
 | |
| 
 | |
|       pos = gtk_text_iter_get_offset (&iter);
 | |
| 
 | |
|       if (pos != expected[i])
 | |
|         {
 | |
|           g_error ("Sentence position %d, expected %d",
 | |
|                    pos, expected[i]);
 | |
|         }
 | |
| 
 | |
|       if (pos != 0 &&
 | |
|           !gtk_text_iter_is_end (&iter) &&
 | |
|           !gtk_text_iter_starts_sentence (&iter))
 | |
|         g_error ("Iterator at %d should start a sentence", pos);
 | |
|       
 | |
|       ++i;
 | |
|     }
 | |
|   while (gtk_text_iter_backward_sentence_start (&iter));
 | |
| 
 | |
|   if (i != expected_steps)
 | |
|     g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
 | |
| 
 | |
|   if (gtk_text_iter_get_offset (&iter) != 0)
 | |
|     g_error ("Expected to stop at the start iterator\n");
 | |
|   
 | |
|   g_print ("Logical motion tests passed\n");
 | |
| 
 | |
|   g_object_unref (G_OBJECT (buffer));
 | |
| }
 |