diff options
author | Michael Natterer <mitch@imendio.com> | 2006-08-28 16:14:42 +0000 |
---|---|---|
committer | Michael Natterer <mitch@src.gnome.org> | 2006-08-28 16:14:42 +0000 |
commit | 0fa6144940197ff150e232a53c2da515296e12b0 (patch) | |
tree | da6f63e9be0c6925e3515d3f1c0e364422ee7c39 /tests | |
parent | 21ac0b0b4045ebedfcf1c6a8dc527a3f5d20c372 (diff) | |
download | gtk+-0fa6144940197ff150e232a53c2da515296e12b0.tar.gz |
don't write out </apply_tag> for tags that have already been closed by the
2006-08-28 Michael Natterer <mitch@imendio.com>
* gtk/gtktextbufferserialize.c (serialize_text): don't write out
</apply_tag> for tags that have already been closed by the logic
which turns overlapping spans into XML-able trees. Fixes broken
XML when there are overlapping tags in the buffer. Also free two
leaked GLists and did some cleanup.
* tests/Makefile.am
* tests/testrichtext.c: new test which creates randomly tagged
GtkTextBuffers and serializes/deserializes them.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/testrichtext.c | 185 |
2 files changed, 188 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 32bac901e4..d9458dfd95 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -57,6 +57,7 @@ noinst_PROGRAMS = \ testprint \ testrgb \ testrecentchooser \ + testrichtext \ testselection \ $(testsocket_programs) \ testspinbutton \ @@ -113,6 +114,7 @@ testnouiprint_DEPENDENCIES = $(TEST_DEPS) testprint_DEPENDENCIES = $(TEST_DEPS) testrecentchooser_DEPENDENCIES = $(TEST_DEPS) testrgb_DEPENDENCIES = $(TEST_DEPS) +testrichtext_DEPENDENCIES = $(TEST_DEPS) testselection_DEPENDENCIES = $(TEST_DEPS) testsocket_DEPENDENCIES = $(DEPS) testsocket_child_DEPENDENCIES = $(DEPS) @@ -163,6 +165,7 @@ testnouiprint_LDADD = $(LDADDS) testprint_LDADD = $(LDADDS) testrecentchooser_LDADD = $(LDADDS) testrgb_LDADD = $(LDADDS) +testrichtext_LDADD = $(LDADDS) testselection_LDADD = $(LDADDS) testsocket_LDADD = $(LDADDS) testsocket_child_LDADD = $(LDADDS) diff --git a/tests/testrichtext.c b/tests/testrichtext.c new file mode 100644 index 0000000000..2a64cf7b93 --- /dev/null +++ b/tests/testrichtext.c @@ -0,0 +1,185 @@ +/* testrichtext.c + * Copyright (C) 2006 Imendio AB + * Authors: Michael Natterer, Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <string.h> +#include <gtk/gtk.h> + +static guint32 quick_rand32_accu = 2147483563; + +static inline guint32 +quick_rand32 (void) +{ + quick_rand32_accu = 1664525 * quick_rand32_accu + 1013904223; + return quick_rand32_accu; +} + +static gboolean +delete_event (GtkWidget *widget, + GdkEventAny *event, + gpointer user_data) +{ + gtk_main_quit (); + + return TRUE; +} + +static void +text_tag_enqueue (GtkTextTag *tag, + gpointer data) +{ + GSList **slist_p = data; + *slist_p = g_slist_prepend (*slist_p, tag); +} + +static const gchar *example_text = +"vkndsk vfds vkfds vkdsv fdlksnvkfdvnkfdvnkdsnvs\n" +"kmvofdmvfdsvkv fdskvnkfdv nnd.mckfdvnknsknvdnvs" +"fdlvmfdsvlkfdsmvnskdnvfdsnvf sbskjnvlknfd cvdvnd" +"mvlfdsv vfdkjv m, ds vkfdks v df,v j kfds v d\n" +"vnfdskv kjvnfv cfdkvndfnvcm fd,vk kdsf vj d\n" +"KLJHkjh kjh klhjKLJH Kjh kjl h34kj h34kj3h klj 23 " +"kjlkjlhsdjk 34kljh klj hklj 23k4jkjkjh234kjh 52kj " +"2h34 sdaf ukklj kjl32l jkkjl 23j jkl ljk23 jkl\n" +"hjhjhj2hj23jh jh jk jk2h3 hj kjj jk jh21 jhhj32."; + +static GdkAtom +setup_buffer (GtkTextBuffer *buffer) +{ + const guint tlen = strlen (example_text); + const guint tcount = 17; + GtkTextTag *tags[tcount]; + GtkTextTagTable *ttable = gtk_text_buffer_get_tag_table (buffer); + GSList *node, *slist = NULL; + GdkAtom atom; + guint i; + + /* cleanup */ + gtk_text_buffer_set_text (buffer, "", 0); + gtk_text_tag_table_foreach (ttable, text_tag_enqueue, &slist); + for (node = slist; node; node = node->next) + gtk_text_tag_table_remove (ttable, node->data); + g_slist_free (slist); + + /* create new tags */ + for (i = 0; i < tcount; i++) + { + char *s = g_strdup_printf ("tag%u", i); + tags[i] = gtk_text_buffer_create_tag (buffer, s, + "weight", quick_rand32() >> 31 ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, + "style", quick_rand32() >> 31 ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL, + "underline", quick_rand32() >> 31, + NULL); + g_free (s); + } + + /* assign text and tags */ + gtk_text_buffer_set_text (buffer, example_text, -1); + for (i = 0; i < tcount * 5; i++) + { + gint a = quick_rand32() % tlen, b = quick_rand32() % tlen; + GtkTextIter start, end; + gtk_text_buffer_get_iter_at_offset (buffer, &start, MIN (a, b)); + gtk_text_buffer_get_iter_at_offset (buffer, &end, MAX (a, b)); + gtk_text_buffer_apply_tag (buffer, tags[i % tcount], &start, &end); + } + + /* return serialization format */ + atom = gtk_text_buffer_register_deserialize_tagset (buffer, NULL); + gtk_text_buffer_deserialize_set_can_create_tags (buffer, atom, TRUE); + + return atom; +} + +static gboolean +test_serialize_deserialize (GtkTextBuffer *buffer, + GdkAtom atom, + GError **error) +{ + GtkTextIter start, end; + guint8 *spew; + gsize spew_length; + gboolean success; + + gtk_text_buffer_get_bounds (buffer, &start, &end); + + spew = gtk_text_buffer_serialize (buffer, buffer, atom, + &start, &end, &spew_length); + + success = gtk_text_buffer_deserialize (buffer, buffer, atom, &end, + spew, spew_length, error); + + g_free (spew); + + return success; +} + +gint +main (gint argc, + gchar *argv[]) +{ + GtkWidget *window; + GtkWidget *sw; + GtkWidget *view; + GtkTextBuffer *buffer; + GdkAtom atom; + guint i, broken = 0; + + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request (window, 400, 300); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), + GTK_SHADOW_IN); + gtk_container_set_border_width (GTK_CONTAINER (sw), 12); + gtk_container_add (GTK_CONTAINER (window), sw); + + g_signal_connect (window, "delete-event", + G_CALLBACK (delete_event), + NULL); + + buffer = gtk_text_buffer_new (NULL); + view = gtk_text_view_new_with_buffer (buffer); + g_object_unref (buffer); + + gtk_container_add (GTK_CONTAINER (sw), view); + + gtk_widget_show_all (window); + if (0) + gtk_main (); + + for (i = 0; i < 250; i++) + { + GError *error = NULL; + g_printerr ("creating randomly tagged text buffer with accu=0x%x...\n", quick_rand32_accu); + atom = setup_buffer (buffer); + if (test_serialize_deserialize (buffer, atom, &error)) + g_printerr ("ok.\n"); + else + { + g_printerr ("FAIL: serialization/deserialization failed:\n %s\n", error->message); + broken += 1; + } + g_clear_error (&error); + } + + return broken > 0; +} |