1 /* Simplistic test suite */
9 #include "../gtk/gtktexttypes.h" /* Private header, for UNKNOWN_CHAR */
12 gtk_text_iter_spew (const GtkTextIter *iter, const gchar *desc)
14 g_print (" %20s: line %d / char %d / line char %d / line byte %d\n",
16 gtk_text_iter_get_line (iter),
17 gtk_text_iter_get_offset (iter),
18 gtk_text_iter_get_line_offset (iter),
19 gtk_text_iter_get_line_index (iter));
22 static void fill_buffer (GtkTextBuffer *buffer);
24 static void run_tests (GtkTextBuffer *buffer);
26 static void check_get_set_text (GtkTextBuffer *buffer,
30 static void line_separator_tests (void);
32 static void logical_motion_tests (void);
35 main (int argc, char** argv)
37 GtkTextBuffer *buffer;
40 GtkTextIter start, end;
42 gtk_init (&argc, &argv);
44 /* Check UTF8 unknown char thing */
45 g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
46 ch = g_utf8_get_char (gtk_text_unknown_char_utf8);
47 g_assert (ch == GTK_TEXT_UNKNOWN_CHAR);
49 /* First, we turn on btree debugging. */
50 gtk_debug_flags |= GTK_DEBUG_TEXT;
52 /* Check some line separator stuff */
53 line_separator_tests ();
55 /* Check log attr motion */
56 logical_motion_tests ();
59 buffer = gtk_text_buffer_new (NULL);
61 /* Check that buffer starts with one empty line and zero chars */
63 n = gtk_text_buffer_get_line_count (buffer);
65 g_error ("%d lines, expected 1", n);
67 n = gtk_text_buffer_get_char_count (buffer);
69 g_error ("%d chars, expected 0", n);
71 /* empty first line contains 0 chars */
72 gtk_text_buffer_get_start_iter (buffer, &start);
73 n = gtk_text_iter_get_chars_in_line (&start);
75 g_error ("%d chars in first line, expected 0", n);
76 n = gtk_text_iter_get_bytes_in_line (&start);
78 g_error ("%d bytes in first line, expected 0", n);
80 /* Run gruesome alien test suite on buffer */
83 /* Check set/get text */
84 check_get_set_text (buffer, "Hello");
85 check_get_set_text (buffer, "Hello\n");
86 check_get_set_text (buffer, "Hello\r\n");
87 check_get_set_text (buffer, "Hello\r");
88 check_get_set_text (buffer, "Hello\nBar\nFoo");
89 check_get_set_text (buffer, "Hello\nBar\nFoo\n");
91 g_print ("get/set tests passed.\n");
93 /* Put stuff in the buffer */
97 /* Subject stuff-bloated buffer to further torment */
100 /* Delete all stuff from the buffer */
101 gtk_text_buffer_get_bounds (buffer, &start, &end);
102 gtk_text_buffer_delete (buffer, &start, &end);
104 /* Check buffer for emptiness (note that a single
105 empty line always remains in the buffer) */
106 n = gtk_text_buffer_get_line_count (buffer);
108 g_error ("%d lines, expected 1", n);
110 n = gtk_text_buffer_get_char_count (buffer);
112 g_error ("%d chars, expected 0", n);
116 gtk_text_buffer_set_text (buffer, "adcdef", -1);
117 gtk_text_buffer_get_iter_at_offset (buffer, &start, 1);
118 gtk_text_buffer_get_iter_at_offset (buffer, &end, 3);
119 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &start, &end);
123 g_object_unref (buffer);
125 g_print ("All tests passed.\n");
131 check_get_set_text (GtkTextBuffer *buffer,
134 GtkTextIter start, end, iter;
138 gtk_text_buffer_set_text (buffer, str, -1);
139 if (gtk_text_buffer_get_char_count (buffer) != g_utf8_strlen (str, -1))
140 g_error ("Wrong number of chars (%d not %d)",
141 gtk_text_buffer_get_char_count (buffer),
142 (int) g_utf8_strlen (str, -1));
143 gtk_text_buffer_get_bounds (buffer, &start, &end);
144 text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
145 if (strcmp (text, str) != 0)
146 g_error ("Got '%s' as buffer contents", text);
149 /* line char counts */
154 n += gtk_text_iter_get_chars_in_line (&iter);
156 while (gtk_text_iter_forward_line (&iter));
158 if (n != gtk_text_buffer_get_char_count (buffer))
159 g_error ("Sum of chars in lines is %d but buffer char count is %d",
160 n, gtk_text_buffer_get_char_count (buffer));
162 /* line byte counts */
167 n += gtk_text_iter_get_bytes_in_line (&iter);
169 while (gtk_text_iter_forward_line (&iter));
171 if (n != strlen (str))
172 g_error ("Sum of chars in lines is %d but buffer byte count is %d",
173 n, (int) strlen (str));
175 gtk_text_buffer_set_text (buffer, "", -1);
177 n = gtk_text_buffer_get_line_count (buffer);
179 g_error ("%d lines, expected 1", n);
181 n = gtk_text_buffer_get_char_count (buffer);
183 g_error ("%d chars, expected 0", n);
187 count_toggles_at_iter (GtkTextIter *iter,
194 /* get toggle-ons and toggle-offs */
195 tags = gtk_text_iter_get_toggled_tags (iter, TRUE);
196 tags = g_slist_concat (tags,
197 gtk_text_iter_get_toggled_tags (iter, FALSE));
204 else if (of_tag == tmp->data)
207 tmp = g_slist_next (tmp);
216 count_toggles_in_range_by_char (GtkTextBuffer *buffer,
218 const GtkTextIter *start,
219 const GtkTextIter *end)
227 count += count_toggles_at_iter (&iter, of_tag);
228 if (!gtk_text_iter_forward_char (&iter))
231 count += count_toggles_at_iter (&iter, of_tag);
235 while (gtk_text_iter_compare (&iter, end) <= 0);
241 count_toggles_in_buffer (GtkTextBuffer *buffer,
244 GtkTextIter start, end;
246 gtk_text_buffer_get_bounds (buffer, &start, &end);
248 return count_toggles_in_range_by_char (buffer, of_tag, &start, &end);
252 check_specific_tag_in_range (GtkTextBuffer *buffer,
253 const gchar *tag_name,
254 const GtkTextIter *start,
255 const GtkTextIter *end)
264 if (gtk_text_iter_compare (start, end) > 0)
266 g_print (" (inverted range for checking tags, skipping)\n");
270 tag = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer),
273 buffer_count = count_toggles_in_range_by_char (buffer, tag, start, end);
280 if (gtk_text_iter_toggles_tag (&iter, tag) ||
281 gtk_text_iter_forward_to_tag_toggle (&iter, tag))
289 this_offset = gtk_text_iter_get_offset (&iter);
291 if (this_offset <= last_offset)
292 g_error ("forward_to_tag_toggle moved in wrong direction");
294 last_offset = this_offset;
296 if (gtk_text_iter_begins_tag (&iter, tag))
299 g_error ("Tag %p is already on, and was toggled on?", tag);
302 else if (gtk_text_iter_ends_tag (&iter, tag))
305 g_error ("Tag %p toggled off, but wasn't toggled on?", tag);
309 g_error ("forward_to_tag_toggle went to a location without a toggle");
311 while (gtk_text_iter_forward_to_tag_toggle (&iter, tag) &&
312 gtk_text_iter_compare (&iter, end) <= 0);
315 if (count != buffer_count)
316 g_error ("Counted %d tags iterating by char, %d iterating forward by tag toggle\n",
317 buffer_count, count);
323 last_offset = gtk_text_iter_get_offset (&iter);
324 if (gtk_text_iter_toggles_tag (&iter, tag) ||
325 gtk_text_iter_backward_to_tag_toggle (&iter, tag))
333 this_offset = gtk_text_iter_get_offset (&iter);
335 if (this_offset >= last_offset)
336 g_error ("backward_to_tag_toggle moved in wrong direction");
338 last_offset = this_offset;
340 if (gtk_text_iter_begins_tag (&iter, tag))
343 g_error ("Tag %p wasn't on when we got to the on toggle going backward?", tag);
346 else if (gtk_text_iter_ends_tag (&iter, tag))
349 g_error ("Tag %p off toggle, but we were already inside a tag?", tag);
353 g_error ("backward_to_tag_toggle went to a location without a toggle");
355 while (gtk_text_iter_backward_to_tag_toggle (&iter, tag) &&
356 gtk_text_iter_compare (&iter, start) >= 0);
359 if (count != buffer_count)
360 g_error ("Counted %d tags iterating by char, %d iterating backward by tag toggle\n",
361 buffer_count, count);
365 check_specific_tag (GtkTextBuffer *buffer,
366 const gchar *tag_name)
368 GtkTextIter start, end;
370 gtk_text_buffer_get_bounds (buffer, &start, &end);
371 check_specific_tag_in_range (buffer, tag_name, &start, &end);
372 gtk_text_iter_forward_chars (&start, 2);
373 gtk_text_iter_backward_chars (&end, 2);
374 if (gtk_text_iter_compare (&start, &end) < 0)
375 check_specific_tag_in_range (buffer, tag_name, &start, &end);
379 run_tests (GtkTextBuffer *buffer)
387 GtkTextMark *bar_mark;
389 GHashTable *tag_states;
393 gtk_text_buffer_get_bounds (buffer, &start, &end);
395 /* Check that walking the tree via chars and via iterators produces
396 * the same number of indexable locations.
398 num_chars = gtk_text_buffer_get_char_count (buffer);
400 bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
402 while (i < num_chars)
405 GtkTextMark *foo_mark;
407 gtk_text_buffer_get_iter_at_offset (buffer, ¤t, i);
409 if (!gtk_text_iter_equal (&iter, ¤t))
411 g_error ("get_char_index didn't return current iter");
414 j = gtk_text_iter_get_offset (&iter);
418 g_error ("iter converted to %d not %d", j, i);
422 gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
424 if (!gtk_text_iter_equal (&iter, &mark))
426 gtk_text_iter_spew (&iter, "iter");
427 gtk_text_iter_spew (&mark, "mark");
428 g_error ("Mark not moved to the right place.");
431 foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
432 gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
433 gtk_text_buffer_delete_mark (buffer, foo_mark);
435 if (!gtk_text_iter_equal (&iter, &mark))
437 gtk_text_iter_spew (&iter, "iter");
438 gtk_text_iter_spew (&mark, "mark");
439 g_error ("Mark not created in the right place.");
442 if (gtk_text_iter_is_end (&iter))
443 g_error ("iterators ran out before chars (offset %d of %d)",
446 gtk_text_iter_forward_char (&iter);
448 gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
453 if (!gtk_text_iter_equal (&iter, &end))
454 g_error ("Iterating over all chars didn't end with the end iter");
456 /* Do the tree-walk backward
458 num_chars = gtk_text_buffer_get_char_count (buffer);
459 gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
461 gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
465 if (!gtk_text_iter_equal (&iter, &end))
466 g_error ("iter at char -1 is not equal to the end iterator");
471 GtkTextMark *foo_mark;
473 gtk_text_buffer_get_iter_at_offset (buffer, ¤t, i);
475 if (!gtk_text_iter_equal (&iter, ¤t))
477 g_error ("get_char_index didn't return current iter while going backward");
479 j = gtk_text_iter_get_offset (&iter);
483 g_error ("going backward, iter converted to %d not %d", j, i);
487 gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
489 if (!gtk_text_iter_equal (&iter, &mark))
491 gtk_text_iter_spew (&iter, "iter");
492 gtk_text_iter_spew (&mark, "mark");
493 g_error ("Mark not moved to the right place.");
496 foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
497 gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
498 gtk_text_buffer_delete_mark (buffer, foo_mark);
500 if (!gtk_text_iter_equal (&iter, &mark))
502 gtk_text_iter_spew (&iter, "iter");
503 gtk_text_iter_spew (&mark, "mark");
504 g_error ("Mark not created in the right place.");
509 if (!gtk_text_iter_backward_char (&iter))
510 g_error ("iterators ran out before char indexes");
512 gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
516 if (gtk_text_iter_backward_char (&iter))
517 g_error ("went backward from 0?");
523 if (!gtk_text_iter_equal (&iter, &start))
524 g_error ("Iterating backward over all chars didn't end with the start iter");
527 * Check that get_line_count returns the same number of lines
528 * as walking the tree by line
530 i = 1; /* include current (first) line */
531 gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
532 while (gtk_text_iter_forward_line (&iter))
535 if (i != gtk_text_buffer_get_line_count (buffer))
536 g_error ("Counted %d lines, buffer has %d", i,
537 gtk_text_buffer_get_line_count (buffer));
540 * Check that moving over tag toggles thinks about working.
543 buffer_count = count_toggles_in_buffer (buffer, NULL);
545 tag_states = g_hash_table_new (NULL, NULL);
548 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
549 if (gtk_text_iter_toggles_tag (&iter, NULL) ||
550 gtk_text_iter_forward_to_tag_toggle (&iter, NULL))
556 gboolean found_some = FALSE;
558 /* get toggled-on tags */
559 tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
571 if (g_hash_table_lookup (tag_states, tag))
572 g_error ("Tag %p is already on, and was toggled on?", tag);
574 g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
576 tmp = g_slist_next (tmp);
581 /* get toggled-off tags */
582 tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
594 if (!g_hash_table_lookup (tag_states, tag))
595 g_error ("Tag %p is already off, and was toggled off?", tag);
597 g_hash_table_remove (tag_states, tag);
599 tmp = g_slist_next (tmp);
605 g_error ("No tags found going forward to tag toggle.");
608 while (gtk_text_iter_forward_to_tag_toggle (&iter, NULL));
611 g_hash_table_destroy (tag_states);
613 if (count != buffer_count)
614 g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
615 buffer_count, count);
617 /* Go backward; here TRUE in the hash means we saw
618 * an off toggle last.
621 tag_states = g_hash_table_new (NULL, NULL);
624 gtk_text_buffer_get_end_iter (buffer, &iter);
625 if (gtk_text_iter_toggles_tag (&iter, NULL) ||
626 gtk_text_iter_backward_to_tag_toggle (&iter, NULL))
632 gboolean found_some = FALSE;
634 /* get toggled-off tags */
635 tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
647 if (g_hash_table_lookup (tag_states, tag))
648 g_error ("Tag %p has two off-toggles in a row?", tag);
650 g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
652 tmp = g_slist_next (tmp);
657 /* get toggled-on tags */
658 tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
670 if (!g_hash_table_lookup (tag_states, tag))
671 g_error ("Tag %p was toggled on, but saw no off-toggle?", tag);
673 g_hash_table_remove (tag_states, tag);
675 tmp = g_slist_next (tmp);
681 g_error ("No tags found going backward to tag toggle.");
683 while (gtk_text_iter_backward_to_tag_toggle (&iter, NULL));
686 g_hash_table_destroy (tag_states);
688 if (count != buffer_count)
689 g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
690 buffer_count, count);
692 check_specific_tag (buffer, "fg_red");
693 check_specific_tag (buffer, "bg_green");
694 check_specific_tag (buffer, "front_tag");
695 check_specific_tag (buffer, "center_tag");
696 check_specific_tag (buffer, "end_tag");
700 static const char *book_closed_xpm[] = {
726 fill_buffer (GtkTextBuffer *buffer)
729 GdkColor color, color2;
735 color.red = color.green = 0;
741 gtk_text_buffer_create_tag (buffer, "fg_blue",
742 "foreground_gdk", &color,
743 "background_gdk", &color2,
744 "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
747 color.blue = color.green = 0;
750 gtk_text_buffer_create_tag (buffer, "fg_red",
752 "foreground_gdk", &color,
755 color.blue = color.red = 0;
756 color.green = 0xffff;
758 gtk_text_buffer_create_tag (buffer, "bg_green",
759 "background_gdk", &color,
760 "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
763 pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
765 g_assert (pixbuf != NULL);
772 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
774 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
776 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
778 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
780 str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
783 gtk_text_buffer_insert (buffer, &iter, str, -1);
787 gtk_text_buffer_insert (buffer, &iter,
788 "(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"
789 /* This is UTF8 stuff, Emacs doesn't
790 really know how to display it */
791 "Spanish (Espa\303\261ol) \302\241Hola! / French (Fran\303\247ais) Bonjour, Salut / German (Deutsch S\303\274d) Gr\303\274\303\237 Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash) (\340\270\240\340\270\262\340\270\251\340\270\262\340\271\204\340\270\227\340\270\242) \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\270\243\340\270\261\340\270\232, \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\271\210\340\270\260\n",
794 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
795 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
797 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
799 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
801 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
803 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
805 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
807 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
809 gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
811 gtk_text_iter_forward_chars (&iter2, 10);
813 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
815 gtk_text_iter_forward_chars (&iter, 7);
816 gtk_text_iter_forward_chars (&iter2, 10);
818 gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
820 gtk_text_iter_forward_chars (&iter, 12);
821 gtk_text_iter_forward_chars (&iter2, 10);
823 gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
825 gtk_text_iter_forward_chars (&iter, 10);
826 gtk_text_iter_forward_chars (&iter2, 15);
828 gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
829 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
831 gtk_text_iter_forward_chars (&iter, 20);
832 gtk_text_iter_forward_chars (&iter2, 20);
834 gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
835 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
837 gtk_text_iter_backward_chars (&iter, 25);
838 gtk_text_iter_forward_chars (&iter2, 5);
840 gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
841 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
843 gtk_text_iter_forward_chars (&iter, 15);
844 gtk_text_iter_backward_chars (&iter2, 10);
846 gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
847 gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);
852 /* Put in tags that are just at the beginning, and just near the end,
853 * and just near the middle.
855 tag = gtk_text_buffer_create_tag (buffer, "front_tag", NULL);
856 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
857 gtk_text_buffer_get_iter_at_offset (buffer, &iter2, 300);
859 gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
861 tag = gtk_text_buffer_create_tag (buffer, "end_tag", NULL);
862 gtk_text_buffer_get_end_iter (buffer, &iter2);
863 gtk_text_iter_backward_chars (&iter2, 12);
865 gtk_text_iter_backward_chars (&iter, 157);
867 gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
869 tag = gtk_text_buffer_create_tag (buffer, "center_tag", NULL);
870 gtk_text_buffer_get_iter_at_offset (buffer, &iter,
871 gtk_text_buffer_get_char_count (buffer)/2);
872 gtk_text_iter_backward_chars (&iter, 37);
874 gtk_text_iter_forward_chars (&iter2, 57);
876 gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
878 g_object_unref (pixbuf);
883 * Line separator tests (initially to avoid regression on bugzilla #57428)
887 test_line_separation (const char* str,
888 gboolean expect_next_line,
889 gboolean expect_end_iter,
890 int expected_line_count,
891 int expected_line_break,
892 int expected_next_line_start)
895 GtkTextBuffer* buffer;
896 gboolean on_next_line;
897 gboolean on_end_iter;
900 buffer = gtk_text_buffer_new (NULL);
902 gtk_text_buffer_set_text (buffer, str, -1);
903 gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
905 g_assert (gtk_text_iter_ends_line (&iter) || gtk_text_iter_is_end (&iter));
907 g_assert (gtk_text_buffer_get_line_count (buffer) == expected_line_count);
909 on_next_line = gtk_text_iter_forward_line (&iter);
911 g_assert (expect_next_line == on_next_line);
913 on_end_iter = gtk_text_iter_is_end (&iter);
915 g_assert (on_end_iter == expect_end_iter);
917 new_pos = gtk_text_iter_get_offset (&iter);
920 g_assert (expected_next_line_start == new_pos);
922 ++expected_line_break;
923 while (expected_line_break < expected_next_line_start)
925 gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
927 g_assert (!gtk_text_iter_ends_line (&iter));
929 on_next_line = gtk_text_iter_forward_line (&iter);
931 g_assert (expect_next_line == on_next_line);
933 new_pos = gtk_text_iter_get_offset (&iter);
936 g_assert (expected_next_line_start == new_pos);
938 ++expected_line_break;
941 /* FIXME tests for backward line */
943 g_object_unref (buffer);
948 line_separator_tests (void)
951 char buf[7] = { '\0', };
953 /* Only one character has type G_UNICODE_PARAGRAPH_SEPARATOR in
954 * Unicode 3.0; update this if that changes.
956 #define PARAGRAPH_SEPARATOR 0x2029
958 test_line_separation ("line", FALSE, TRUE, 1, 4, 4);
959 test_line_separation ("line\r\n", FALSE, TRUE, 2, 4, 6);
960 test_line_separation ("line\r", FALSE, TRUE, 2, 4, 5);
961 test_line_separation ("line\n", FALSE, TRUE, 2, 4, 5);
962 test_line_separation ("line\rqw", TRUE, FALSE, 2, 4, 5);
963 test_line_separation ("line\nqw", TRUE, FALSE, 2, 4, 5);
964 test_line_separation ("line\r\nqw", TRUE, FALSE, 2, 4, 6);
966 g_unichar_to_utf8 (PARAGRAPH_SEPARATOR, buf);
968 str = g_strdup_printf ("line%s", buf);
969 test_line_separation (str, FALSE, TRUE, 2, 4, 5);
971 str = g_strdup_printf ("line%sqw", buf);
972 test_line_separation (str, TRUE, FALSE, 2, 4, 5);
975 g_print ("Line separator tests passed\n");
979 logical_motion_tests (void)
982 char buf1[7] = { '\0', };
983 char buf2[7] = { '\0', };
984 char buf3[7] = { '\0', };
988 GtkTextBuffer *buffer;
991 buffer = gtk_text_buffer_new (NULL);
993 #define LEADING_JAMO 0x1111
994 #define VOWEL_JAMO 0x1167
995 #define TRAILING_JAMO 0x11B9
997 g_unichar_to_utf8 (LEADING_JAMO, buf1);
998 g_unichar_to_utf8 (VOWEL_JAMO, buf2);
999 g_unichar_to_utf8 (TRAILING_JAMO, buf3);
1001 /* Build the string "abc<leading><vowel><trailing>def\r\nxyz" */
1002 str = g_strconcat ("abc", buf1, buf2, buf3, "def\r\nxyz", NULL);
1003 gtk_text_buffer_set_text (buffer, str, -1);
1006 /* Check cursor positions */
1007 memset (expected, 0, sizeof (expected));
1008 expected[0] = 0; /* before 'a' */
1009 expected[1] = 1; /* before 'b' */
1010 expected[2] = 2; /* before 'c' */
1011 expected[3] = 3; /* before jamo */
1012 expected[4] = 6; /* before 'd' */
1013 expected[5] = 7; /* before 'e' */
1014 expected[6] = 8; /* before 'f' */
1015 expected[7] = 9; /* before '\r' */
1016 expected[8] = 11; /* before 'x' */
1017 expected[9] = 12; /* before 'y' */
1018 expected[10] = 13; /* before 'z' */
1019 expected[11] = 14; /* after 'z' (only matters going backward) */
1020 expected_steps = 11;
1022 gtk_text_buffer_get_start_iter (buffer, &iter);
1028 pos = gtk_text_iter_get_offset (&iter);
1030 if (pos != expected[i])
1032 g_error ("Cursor position %d, expected %d",
1038 while (gtk_text_iter_forward_cursor_position (&iter));
1040 if (!gtk_text_iter_is_end (&iter))
1041 g_error ("Expected to stop at the end iterator\n");
1043 if (!gtk_text_iter_is_cursor_position (&iter))
1044 g_error ("Should be a cursor position before the end iterator");
1046 if (i != expected_steps)
1047 g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
1054 pos = gtk_text_iter_get_offset (&iter);
1056 if (pos != expected[i])
1058 g_error ("Moving backward, cursor position %d, expected %d",
1062 /* g_print ("%d = %d\n", pos, expected[i]); */
1066 while (gtk_text_iter_backward_cursor_position (&iter));
1069 g_error ("Expected %d steps, there were actually %d\n", expected_steps - i, i);
1071 if (!gtk_text_iter_is_start (&iter))
1072 g_error ("Expected to stop at the start iterator\n");
1075 /* Check sentence boundaries */
1077 gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
1079 memset (expected, 0, sizeof (expected));
1081 expected[0] = 0; /* before first Hi */
1082 expected[1] = 3; /* After first . */
1083 expected[2] = 7; /* After second . */
1084 expected[3] = 12; /* After ! */
1085 expected[4] = 16; /* After third . */
1086 expected[5] = 20; /* After ? */
1090 gtk_text_buffer_get_start_iter (buffer, &iter);
1096 pos = gtk_text_iter_get_offset (&iter);
1098 if (pos != expected[i])
1100 g_error ("Sentence position %d, expected %d",
1105 !gtk_text_iter_is_end (&iter) &&
1106 !gtk_text_iter_ends_sentence (&iter))
1107 g_error ("Iterator at %d should end a sentence", pos);
1111 while (gtk_text_iter_forward_sentence_end (&iter));
1113 if (i != expected_steps)
1114 g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
1116 if (!gtk_text_iter_is_end (&iter))
1117 g_error ("Expected to stop at the end iterator\n");
1119 gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
1121 memset (expected, 0, sizeof (expected));
1133 gtk_text_buffer_get_end_iter (buffer, &iter);
1139 pos = gtk_text_iter_get_offset (&iter);
1141 if (pos != expected[i])
1143 g_error ("Sentence position %d, expected %d",
1148 !gtk_text_iter_is_end (&iter) &&
1149 !gtk_text_iter_starts_sentence (&iter))
1150 g_error ("Iterator at %d should start a sentence", pos);
1154 while (gtk_text_iter_backward_sentence_start (&iter));
1156 if (i != expected_steps)
1157 g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
1159 if (gtk_text_iter_get_offset (&iter) != 0)
1160 g_error ("Expected to stop at the start iterator\n");
1162 g_print ("Logical motion tests passed\n");
1164 g_object_unref (buffer);