1 /* Simplistic test suite */
7 #include "../gtk/gtktexttypes.h" /* Private header, for UNKNOWN_CHAR */
9 static void fill_buffer (GtkTextBuffer *buffer);
11 static void run_tests (GtkTextBuffer *buffer);
14 main (int argc, char** argv)
16 GtkTextBuffer *buffer;
19 GtkTextIter start, end;
21 gtk_init (&argc, &argv);
23 /* Check UTF8 unknown char thing */
24 g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
25 ch = g_utf8_get_char (gtk_text_unknown_char_utf8);
26 g_assert (ch == GTK_TEXT_UNKNOWN_CHAR);
28 /* First, we turn on btree debugging. */
29 gtk_debug_flags |= GTK_DEBUG_TEXT;
32 buffer = gtk_text_buffer_new (NULL);
34 /* Check that buffer starts with one empty line and zero chars */
36 n = gtk_text_buffer_get_line_count (buffer);
38 g_error ("%d lines, expected 1", n);
40 n = gtk_text_buffer_get_char_count (buffer);
42 g_error ("%d chars, expected 1", n);
44 /* Run gruesome alien test suite on buffer */
47 /* Put stuff in the buffer */
51 /* Subject stuff-bloated buffer to further torment */
54 /* Delete all stuff from the buffer */
55 gtk_text_buffer_get_bounds (buffer, &start, &end);
56 gtk_text_buffer_delete (buffer, &start, &end);
58 /* Check buffer for emptiness (note that a single
59 empty line always remains in the buffer) */
60 n = gtk_text_buffer_get_line_count (buffer);
62 g_error ("%d lines, expected 1", n);
64 n = gtk_text_buffer_get_char_count (buffer);
66 g_error ("%d chars, expected 1", n);
70 g_object_unref (G_OBJECT (buffer));
72 g_print ("All tests passed.\n");
78 count_toggles_at_iter (GtkTextIter *iter,
85 /* get toggle-ons and toggle-offs */
86 tags = gtk_text_iter_get_toggled_tags (iter, TRUE);
87 tags = g_slist_concat (tags,
88 gtk_text_iter_get_toggled_tags (iter, FALSE));
95 else if (of_tag == tmp->data)
98 tmp = g_slist_next (tmp);
107 count_toggles_in_buffer (GtkTextBuffer *buffer,
113 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
116 count += count_toggles_at_iter (&iter, of_tag);
118 while (gtk_text_iter_forward_char (&iter));
120 /* Do the end iterator, because forward_char won't return TRUE
123 count += count_toggles_at_iter (&iter, of_tag);
129 check_specific_tag (GtkTextBuffer *buffer,
130 const gchar *tag_name)
139 tag = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer),
142 buffer_count = count_toggles_in_buffer (buffer, tag);
148 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
149 if (gtk_text_iter_toggles_tag (&iter, tag) ||
150 gtk_text_iter_forward_to_tag_toggle (&iter, tag))
158 this_offset = gtk_text_iter_get_offset (&iter);
160 if (this_offset <= last_offset)
161 g_error ("forward_to_tag_toggle moved in wrong direction");
163 last_offset = this_offset;
165 if (gtk_text_iter_begins_tag (&iter, tag))
168 g_error ("Tag %p is already on, and was toggled on?", tag);
171 else if (gtk_text_iter_ends_tag (&iter, tag))
174 g_error ("Tag %p toggled off, but wasn't toggled on?", tag);
178 g_error ("forward_to_tag_toggle went to a location without a toggle");
180 while (gtk_text_iter_forward_to_tag_toggle (&iter, tag));
183 if (count != buffer_count)
184 g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
185 buffer_count, count);
190 gtk_text_buffer_get_end_iter (buffer, &iter);
191 last_offset = gtk_text_iter_get_offset (&iter);
192 if (gtk_text_iter_toggles_tag (&iter, tag) ||
193 gtk_text_iter_backward_to_tag_toggle (&iter, tag))
201 this_offset = gtk_text_iter_get_offset (&iter);
203 if (this_offset >= last_offset)
204 g_error ("backward_to_tag_toggle moved in wrong direction");
206 last_offset = this_offset;
208 if (gtk_text_iter_begins_tag (&iter, tag))
211 g_error ("Tag %p wasn't on when we got to the on toggle going backward?", tag);
214 else if (gtk_text_iter_ends_tag (&iter, tag))
217 g_error ("Tag %p off toggle, but we were already inside a tag?", tag);
221 g_error ("backward_to_tag_toggle went to a location without a toggle");
223 while (gtk_text_iter_backward_to_tag_toggle (&iter, tag));
226 if (count != buffer_count)
227 g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
228 buffer_count, count);
233 run_tests (GtkTextBuffer *buffer)
241 GtkTextMark *bar_mark;
243 GHashTable *tag_states;
247 gtk_text_buffer_get_bounds (buffer, &start, &end);
249 /* Check that walking the tree via chars and via iterators produces
250 * the same number of indexable locations.
252 num_chars = gtk_text_buffer_get_char_count (buffer);
254 bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
256 while (i < num_chars)
259 GtkTextMark *foo_mark;
261 gtk_text_buffer_get_iter_at_offset (buffer, ¤t, i);
263 if (!gtk_text_iter_equal (&iter, ¤t))
265 g_error ("get_char_index didn't return current iter");
268 j = gtk_text_iter_get_offset (&iter);
272 g_error ("iter converted to %d not %d", j, i);
276 gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
278 if (!gtk_text_iter_equal (&iter, &mark))
280 gtk_text_iter_spew (&iter, "iter");
281 gtk_text_iter_spew (&mark, "mark");
282 g_error ("Mark not moved to the right place.");
285 foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
286 gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
287 gtk_text_buffer_delete_mark (buffer, foo_mark);
289 if (!gtk_text_iter_equal (&iter, &mark))
291 gtk_text_iter_spew (&iter, "iter");
292 gtk_text_iter_spew (&mark, "mark");
293 g_error ("Mark not created in the right place.");
296 if (gtk_text_iter_is_end (&iter))
297 g_error ("iterators ran out before chars (offset %d of %d)",
300 gtk_text_iter_forward_char (&iter);
302 gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
307 if (!gtk_text_iter_equal (&iter, &end))
308 g_error ("Iterating over all chars didn't end with the end iter");
310 /* Do the tree-walk backward
312 num_chars = gtk_text_buffer_get_char_count (buffer);
313 gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
315 gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
319 if (!gtk_text_iter_equal (&iter, &end))
320 g_error ("iter at char -1 is not equal to the end iterator");
325 GtkTextMark *foo_mark;
327 gtk_text_buffer_get_iter_at_offset (buffer, ¤t, i);
329 if (!gtk_text_iter_equal (&iter, ¤t))
331 g_error ("get_char_index didn't return current iter while going backward");
333 j = gtk_text_iter_get_offset (&iter);
337 g_error ("going backward, iter converted to %d not %d", j, i);
341 gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
343 if (!gtk_text_iter_equal (&iter, &mark))
345 gtk_text_iter_spew (&iter, "iter");
346 gtk_text_iter_spew (&mark, "mark");
347 g_error ("Mark not moved to the right place.");
350 foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
351 gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
352 gtk_text_buffer_delete_mark (buffer, foo_mark);
354 if (!gtk_text_iter_equal (&iter, &mark))
356 gtk_text_iter_spew (&iter, "iter");
357 gtk_text_iter_spew (&mark, "mark");
358 g_error ("Mark not created in the right place.");
363 if (!gtk_text_iter_backward_char (&iter))
364 g_error ("iterators ran out before char indexes");
366 gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
370 if (gtk_text_iter_backward_char (&iter))
371 g_error ("went backward from 0?");
377 if (!gtk_text_iter_equal (&iter, &start))
378 g_error ("Iterating backward over all chars didn't end with the start iter");
381 * Check that get_line_count returns the same number of lines
382 * as walking the tree by line
384 i = 1; /* include current (first) line */
385 gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
386 while (gtk_text_iter_forward_line (&iter))
389 if (i != gtk_text_buffer_get_line_count (buffer))
390 g_error ("Counted %d lines, buffer has %d", i,
391 gtk_text_buffer_get_line_count (buffer));
394 * Check that moving over tag toggles thinks about working.
397 buffer_count = count_toggles_in_buffer (buffer, NULL);
399 tag_states = g_hash_table_new (NULL, NULL);
402 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
403 if (gtk_text_iter_toggles_tag (&iter, NULL) ||
404 gtk_text_iter_forward_to_tag_toggle (&iter, NULL))
410 gboolean found_some = FALSE;
412 /* get toggled-on tags */
413 tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
425 if (g_hash_table_lookup (tag_states, tag))
426 g_error ("Tag %p is already on, and was toggled on?", tag);
428 g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
430 tmp = g_slist_next (tmp);
435 /* get toggled-off tags */
436 tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
448 if (!g_hash_table_lookup (tag_states, tag))
449 g_error ("Tag %p is already off, and was toggled off?", tag);
451 g_hash_table_remove (tag_states, tag);
453 tmp = g_slist_next (tmp);
459 g_error ("No tags found going forward to tag toggle.");
462 while (gtk_text_iter_forward_to_tag_toggle (&iter, NULL));
465 g_hash_table_destroy (tag_states);
467 if (count != buffer_count)
468 g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
469 buffer_count, count);
471 /* Go backward; here TRUE in the hash means we saw
472 * an off toggle last.
475 tag_states = g_hash_table_new (NULL, NULL);
478 gtk_text_buffer_get_end_iter (buffer, &iter);
479 if (gtk_text_iter_toggles_tag (&iter, NULL) ||
480 gtk_text_iter_backward_to_tag_toggle (&iter, NULL))
486 gboolean found_some = FALSE;
488 /* get toggled-off tags */
489 tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
501 if (g_hash_table_lookup (tag_states, tag))
502 g_error ("Tag %p has two off-toggles in a row?", tag);
504 g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
506 tmp = g_slist_next (tmp);
511 /* get toggled-on tags */
512 tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
524 if (!g_hash_table_lookup (tag_states, tag))
525 g_error ("Tag %p was toggled on, but saw no off-toggle?", tag);
527 g_hash_table_remove (tag_states, tag);
529 tmp = g_slist_next (tmp);
535 g_error ("No tags found going backward to tag toggle.");
537 while (gtk_text_iter_backward_to_tag_toggle (&iter, NULL));
540 g_hash_table_destroy (tag_states);
542 if (count != buffer_count)
543 g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
544 buffer_count, count);
546 check_specific_tag (buffer, "fg_red");
547 check_specific_tag (buffer, "bg_green");
548 check_specific_tag (buffer, "front_tag");
549 check_specific_tag (buffer, "center_tag");
550 check_specific_tag (buffer, "end_tag");
554 static char *book_closed_xpm[] = {
580 fill_buffer (GtkTextBuffer *buffer)
583 GdkColor color, color2;
589 color.red = color.green = 0;
595 gtk_text_buffer_create_tag (buffer, "fg_blue",
596 "foreground_gdk", &color,
597 "background_gdk", &color2,
598 "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
601 color.blue = color.green = 0;
604 gtk_text_buffer_create_tag (buffer, "fg_red",
606 "foreground_gdk", &color,
609 color.blue = color.red = 0;
610 color.green = 0xffff;
612 gtk_text_buffer_create_tag (buffer, "bg_green",
613 "background_gdk", &color,
614 "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
617 pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
619 g_assert (pixbuf != NULL);
626 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
628 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
630 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
632 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
634 str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
637 gtk_text_buffer_insert (buffer, &iter, str, -1);
641 gtk_text_buffer_insert (buffer, &iter,
642 "(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"
643 /* This is UTF8 stuff, Emacs doesn't
644 really know how to display it */
645 "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",
648 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
649 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
651 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
653 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
655 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
657 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
659 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
661 gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
663 gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
665 gtk_text_iter_forward_chars (&iter2, 10);
667 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
669 gtk_text_iter_forward_chars (&iter, 7);
670 gtk_text_iter_forward_chars (&iter2, 10);
672 gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
674 gtk_text_iter_forward_chars (&iter, 12);
675 gtk_text_iter_forward_chars (&iter2, 10);
677 gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
679 gtk_text_iter_forward_chars (&iter, 10);
680 gtk_text_iter_forward_chars (&iter2, 15);
682 gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
683 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
685 gtk_text_iter_forward_chars (&iter, 20);
686 gtk_text_iter_forward_chars (&iter2, 20);
688 gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
689 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
691 gtk_text_iter_backward_chars (&iter, 25);
692 gtk_text_iter_forward_chars (&iter2, 5);
694 gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
695 gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
697 gtk_text_iter_forward_chars (&iter, 15);
698 gtk_text_iter_backward_chars (&iter2, 10);
700 gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
701 gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);
706 /* Put in tags that are just at the beginning, and just near the end,
707 * and just near the middle.
709 tag = gtk_text_buffer_create_tag (buffer, "front_tag", NULL);
710 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
711 gtk_text_buffer_get_iter_at_offset (buffer, &iter2, 300);
713 gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
715 tag = gtk_text_buffer_create_tag (buffer, "end_tag", NULL);
716 gtk_text_buffer_get_end_iter (buffer, &iter2);
717 gtk_text_iter_backward_chars (&iter2, 12);
719 gtk_text_iter_backward_chars (&iter, 157);
721 gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
723 tag = gtk_text_buffer_create_tag (buffer, "center_tag", NULL);
724 gtk_text_buffer_get_iter_at_offset (buffer, &iter,
725 gtk_text_buffer_get_char_count (buffer)/2);
726 gtk_text_iter_backward_chars (&iter, 37);
728 gtk_text_iter_forward_chars (&iter2, 57);
730 gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
732 gdk_pixbuf_unref (pixbuf);