build: Move gtk/tests to testsuite/gtk
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
|
||||
SUBDIRS = gdk
|
||||
SUBDIRS = gdk gtk
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
||||
|
||||
192
testsuite/gtk/Makefile.am
Normal file
192
testsuite/gtk/Makefile.am
Normal file
@ -0,0 +1,192 @@
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir)/gdk \
|
||||
-I$(top_srcdir)/gdk \
|
||||
-I$(top_builddir)/gtk \
|
||||
-I$(top_srcdir)/gtk \
|
||||
-DSRCDIR=\""$(abs_srcdir)"\" \
|
||||
$(GTK_DEBUG_FLAGS) \
|
||||
$(GTK_DEP_CFLAGS)
|
||||
|
||||
if OS_UNIX
|
||||
AM_CPPFLAGS += -DHAVE_UNIX_PRINT_WIDGETS
|
||||
endif
|
||||
|
||||
DEPS = \
|
||||
$(top_builddir)/gtk/libgtk-3.la
|
||||
|
||||
progs_ldadd = \
|
||||
$(top_builddir)/gtk/libgtk-3.la \
|
||||
$(top_builddir)/gdk/libgdk-3.la \
|
||||
$(GTK_DEP_LIBS)
|
||||
|
||||
noinst_PROGRAMS = $(TEST_PROGS)
|
||||
|
||||
|
||||
TEST_PROGS += testing
|
||||
testing_SOURCES = testing.c
|
||||
testing_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += treemodel
|
||||
treemodel_SOURCES = \
|
||||
treemodel.h \
|
||||
treemodel.c \
|
||||
liststore.c \
|
||||
treestore.c \
|
||||
filtermodel.c \
|
||||
sortmodel.c \
|
||||
modelrefcount.c \
|
||||
gtktreemodelrefcount.h \
|
||||
gtktreemodelrefcount.c
|
||||
treemodel_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += treeview
|
||||
treeview_SOURCES = treeview.c
|
||||
treeview_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += treeview-scrolling
|
||||
treeview_scrolling_SOURCES = treeview-scrolling.c
|
||||
treeview_scrolling_LDADD = $(progs_ldadd) -lm
|
||||
|
||||
TEST_PROGS += recentmanager
|
||||
recentmanager_SOURCES = recentmanager.c
|
||||
recentmanager_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += floating
|
||||
floating_SOURCES = floating.c
|
||||
floating_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += accel
|
||||
accel_SOURCES = accel.c
|
||||
accel_LDADD = $(progs_ldadd)
|
||||
|
||||
#TEST_PROGS += object
|
||||
#object_SOURCES = object.c
|
||||
#object_LDADD = $(progs_ldadd)
|
||||
|
||||
# this doesn't work in make distcheck, since running
|
||||
# on a naked X server creates slightly different event
|
||||
# sequences than running on a normal desktop
|
||||
# TEST_PROGS += crossingevents
|
||||
#crossingevents_SOURCES = crossingevents.c
|
||||
#crossingevents_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += filechooser
|
||||
filechooser_SOURCES = filechooser.c
|
||||
filechooser_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += builder
|
||||
builder_SOURCES = builder.c
|
||||
builder_LDADD = $(progs_ldadd)
|
||||
builder_LDFLAGS = -export-dynamic
|
||||
|
||||
TEST_PROGS += templates
|
||||
templates_SOURCES = templates.c
|
||||
templates_LDADD = $(progs_ldadd)
|
||||
|
||||
if OS_UNIX
|
||||
#TEST_PROGS += defaultvalue
|
||||
#defaultvalue_SOURCES = defaultvalue.c
|
||||
#defaultvalue_LDADD = $(progs_ldadd)
|
||||
endif
|
||||
|
||||
TEST_PROGS += textbuffer
|
||||
textbuffer_SOURCES = textbuffer.c
|
||||
textbuffer_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += textiter
|
||||
textiter_SOURCES = textiter.c
|
||||
textiter_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += expander
|
||||
expander_SOURCES = expander.c
|
||||
expander_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += action
|
||||
action_SOURCES = action.c
|
||||
action_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += stylecontext
|
||||
stylecontext_SOURCES = stylecontext.c
|
||||
stylecontext_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += papersize
|
||||
papersize_SOURCES = papersize.c
|
||||
papersize_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += cellarea
|
||||
cellarea_SOURCES = cellarea.c
|
||||
cellarea_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += treepath
|
||||
treepath_SOURCES = treepath.c
|
||||
treepath_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += accessible
|
||||
accessible_SOURCES = accessible.c
|
||||
accessible_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += entry
|
||||
entry_SOURCES = entry.c
|
||||
entry_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += grid
|
||||
grid_SOURCES = grid.c
|
||||
grid_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += rbtree
|
||||
rbtree_CFLAGS = -DGTK_COMPILATION -UG_ENABLE_DEBUG
|
||||
rbtree_SOURCES = rbtree.c \
|
||||
$(top_srcdir)/gtk/gtkrbtree.h \
|
||||
$(top_srcdir)/gtk/gtkrbtree.c
|
||||
rbtree_LDADD = $(GTK_DEP_LIBS)
|
||||
|
||||
TEST_PROGS += bitmask
|
||||
bitmask_CFLAGS = -DGTK_COMPILATION -UG_ENABLE_DEBUG
|
||||
bitmask_SOURCES = bitmask.c \
|
||||
$(top_srcdir)/gtk/gtkbitmaskprivate.h \
|
||||
$(top_srcdir)/gtk/gtkallocatedbitmaskprivate.h \
|
||||
$(top_srcdir)/gtk/gtkallocatedbitmask.c
|
||||
bitmask_LDADD = $(GTK_DEP_LIBS)
|
||||
|
||||
TEST_PROGS += regression-tests
|
||||
regression_tests_SOURCES = regression-tests.c
|
||||
regression_tests_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += keyhash
|
||||
keyhash_SOURCES = keyhash.c \
|
||||
$(top_srcdir)/gtk/gtkkeyhash.c \
|
||||
$(top_srcdir)/gtk/gtkkeyhash.h \
|
||||
$(top_srcdir)/gtk/gtkresources.c \
|
||||
$(top_srcdir)/gtk/gtkresources.h \
|
||||
$(top_srcdir)/gtk/gtkprivate.c \
|
||||
$(top_srcdir)/gtk/gtkprivate.h
|
||||
keyhash_LDADD = $(progs_ldadd)
|
||||
keyhash_CFLAGS = -DGTK_COMPILATION \
|
||||
-DGTK_LIBDIR=\"$(libdir)\" \
|
||||
-DGTK_DATADIR=\"$(datadir)\" \
|
||||
-DGTK_DATA_PREFIX=\"$(prefix)\" \
|
||||
-DGTK_SYSCONFDIR=\"$(sysconfdir)\"
|
||||
|
||||
TEST_PROGS += gtkmenu
|
||||
gtkmenu_SOURCES = gtkmenu.c
|
||||
gtkmenu_LDADD = $(progs_ldadd)
|
||||
|
||||
|
||||
TEST_PROGS += objects-finalize
|
||||
objects_finalize_SOURCES = objects-finalize.c
|
||||
objects_finalize_LDADD = $(progs_ldadd)
|
||||
|
||||
TEST_PROGS += window
|
||||
window_SOURCES = window.c
|
||||
window_LDADD = $(progs_ldadd)
|
||||
|
||||
EXTRA_DIST += \
|
||||
file-chooser-test-dir/empty \
|
||||
file-chooser-test-dir/text.txt
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
123
testsuite/gtk/accel.c
Normal file
123
testsuite/gtk/accel.c
Normal file
@ -0,0 +1,123 @@
|
||||
/* accel.c - test accel parsing
|
||||
* Copyright (C) 2011 Bastien Nocera <hadess@hadess.net>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
#include <locale.h>
|
||||
|
||||
static void
|
||||
test_one_accel (const char *accel,
|
||||
const char *exp_label,
|
||||
gboolean has_keysym)
|
||||
{
|
||||
guint accel_key;
|
||||
GdkModifierType mods;
|
||||
guint *keycodes;
|
||||
char *label, *name;
|
||||
|
||||
accel_key = 0;
|
||||
gtk_accelerator_parse_with_keycode (accel,
|
||||
&accel_key,
|
||||
&keycodes,
|
||||
&mods);
|
||||
|
||||
if (has_keysym)
|
||||
{
|
||||
guint accel_key_2;
|
||||
GdkModifierType mods_2;
|
||||
|
||||
gtk_accelerator_parse (accel,
|
||||
&accel_key_2,
|
||||
&mods_2);
|
||||
g_assert (accel_key == accel_key_2);
|
||||
g_assert (mods == mods_2);
|
||||
}
|
||||
|
||||
if (has_keysym)
|
||||
g_assert (accel_key != 0);
|
||||
g_assert (keycodes);
|
||||
g_assert (keycodes[0] != 0);
|
||||
|
||||
label = gtk_accelerator_get_label_with_keycode (NULL,
|
||||
accel_key,
|
||||
*keycodes,
|
||||
mods);
|
||||
|
||||
g_assert_cmpstr (label, ==, exp_label);
|
||||
|
||||
name = gtk_accelerator_name_with_keycode (NULL,
|
||||
accel_key,
|
||||
*keycodes,
|
||||
mods);
|
||||
g_assert_cmpstr (name, ==, accel);
|
||||
|
||||
g_free (keycodes);
|
||||
g_free (label);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
accel1 (void)
|
||||
{
|
||||
test_one_accel ("0xb3", "0xb3", FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
accel2 (void)
|
||||
{
|
||||
test_one_accel ("<Primary><Alt>z", "Ctrl+Alt+Z", TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
accel3 (void)
|
||||
{
|
||||
test_one_accel ("KP_7", "7", TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
accel4 (void)
|
||||
{
|
||||
test_one_accel ("<Primary>KP_7", "Ctrl+7", TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
accel5 (void)
|
||||
{
|
||||
test_one_accel ("<Shift>exclam", "Shift+!", TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
keysyms (void)
|
||||
{
|
||||
g_assert (gdk_keyval_from_name ("KP_7") == GDK_KEY_KP_7);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
setlocale (LC_ALL, "en_GB.UTF-8");
|
||||
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/keysyms", keysyms);
|
||||
|
||||
g_test_add_func ("/accel1", accel1);
|
||||
g_test_add_func ("/accel2", accel2);
|
||||
g_test_add_func ("/accel3", accel3);
|
||||
g_test_add_func ("/accel4", accel4);
|
||||
g_test_add_func ("/accel5", accel5);
|
||||
return g_test_run();
|
||||
}
|
||||
35
testsuite/gtk/accessible.c
Normal file
35
testsuite/gtk/accessible.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_type (GType t)
|
||||
{
|
||||
GtkWidget *w;
|
||||
AtkObject *a;
|
||||
|
||||
if (g_type_is_a (t, GTK_TYPE_WIDGET))
|
||||
{
|
||||
w = (GtkWidget *)g_object_new (t, NULL);
|
||||
a = gtk_widget_get_accessible (w);
|
||||
|
||||
g_assert (GTK_IS_ACCESSIBLE (a));
|
||||
g_assert (gtk_accessible_get_widget (GTK_ACCESSIBLE (a)) == w);
|
||||
|
||||
g_object_unref (w);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
const GType *tp;
|
||||
guint i, n;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
tp = gtk_test_list_all_types (&n);
|
||||
|
||||
for (i = 0; i < n; n++)
|
||||
test_type (tp[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
90
testsuite/gtk/action.c
Normal file
90
testsuite/gtk/action.c
Normal file
@ -0,0 +1,90 @@
|
||||
/* GtkAction tests.
|
||||
*
|
||||
* Authors: Jan Arne Petersen <jpetersen@openismus.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Fixture */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkAction *action;
|
||||
} ActionTest;
|
||||
|
||||
static void
|
||||
action_test_setup (ActionTest *fixture,
|
||||
gconstpointer test_data)
|
||||
{
|
||||
fixture->action = gtk_action_new ("name", "label", NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
action_test_teardown (ActionTest *fixture,
|
||||
gconstpointer test_data)
|
||||
{
|
||||
g_object_unref (fixture->action);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_count_emmisions (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
unsigned int *i = data;
|
||||
(*i)++;
|
||||
}
|
||||
|
||||
static void
|
||||
menu_item_label_notify_count (ActionTest *fixture,
|
||||
gconstpointer test_data)
|
||||
{
|
||||
GtkWidget *item = gtk_menu_item_new ();
|
||||
unsigned int emmisions = 0;
|
||||
|
||||
g_object_ref_sink (item);
|
||||
g_signal_connect (item, "notify::label",
|
||||
G_CALLBACK (notify_count_emmisions), &emmisions);
|
||||
|
||||
gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item),
|
||||
fixture->action);
|
||||
|
||||
g_assert_cmpuint (emmisions, ==, 1);
|
||||
|
||||
gtk_action_set_label (fixture->action, "new label");
|
||||
|
||||
g_assert_cmpuint (emmisions, ==, 2);
|
||||
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
/* main */
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add ("/Action/MenuItem/label-notify-count",
|
||||
ActionTest, NULL,
|
||||
action_test_setup,
|
||||
menu_item_label_notify_count,
|
||||
action_test_teardown);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
385
testsuite/gtk/bitmask.c
Normal file
385
testsuite/gtk/bitmask.c
Normal file
@ -0,0 +1,385 @@
|
||||
/* GtkRBTree tests.
|
||||
*
|
||||
* Copyright (C) 2011, Red Hat, Inc.
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include "../../gtk/gtkbitmaskprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* how often we run the random tests */
|
||||
#define N_RUNS 20
|
||||
|
||||
/* how many tries we do in our random tests */
|
||||
#define N_TRIES 100
|
||||
|
||||
/* the maximum index we use for bitmask values */
|
||||
#define MAX_INDEX 1000
|
||||
|
||||
/* UTILITIES */
|
||||
|
||||
static GtkBitmask *
|
||||
gtk_bitmask_new_parse (const char *string)
|
||||
{
|
||||
guint i, length;
|
||||
GtkBitmask *mask;
|
||||
|
||||
length = strlen (string);
|
||||
mask = _gtk_bitmask_new ();
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (string[i] == '0')
|
||||
mask = _gtk_bitmask_set (mask, length - i - 1, FALSE);
|
||||
else if (string[i] == '1')
|
||||
mask = _gtk_bitmask_set (mask, length - i - 1, TRUE);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
#define assert_cmpmasks(mask,other) G_STMT_START { \
|
||||
if (G_UNLIKELY (!_gtk_bitmask_equals (mask, other))) \
|
||||
{ \
|
||||
char *mask_string = _gtk_bitmask_to_string (mask); \
|
||||
char *other_string = _gtk_bitmask_to_string (other); \
|
||||
char *msg = g_strdup_printf ("%s (%s) != %s (%s)", \
|
||||
G_STRINGIFY (mask), mask_string, \
|
||||
G_STRINGIFY (other), other_string); \
|
||||
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); \
|
||||
g_free (msg); \
|
||||
g_free (mask_string); \
|
||||
g_free (other_string); \
|
||||
} \
|
||||
}G_STMT_END
|
||||
|
||||
static const char *tests[] = {
|
||||
"0",
|
||||
"1",
|
||||
"1000000000000000000000000000000",
|
||||
"10000000000000000000000000000000",
|
||||
"100000000000000000000000000000000000000000000000000000000000000",
|
||||
"1000000000000000000000000000000000000000000000000000000000000000",
|
||||
"10000000000000000000000000000000000000000000000000000000000000000",
|
||||
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010",
|
||||
"1000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000",
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
};
|
||||
|
||||
static GtkBitmask *masks[G_N_ELEMENTS (tests)];
|
||||
|
||||
/* TEST */
|
||||
|
||||
static void
|
||||
test_to_string (void)
|
||||
{
|
||||
guint i;
|
||||
char *to_string;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
to_string = _gtk_bitmask_to_string (masks[i]);
|
||||
g_assert_cmpstr (to_string, ==, tests[i]);
|
||||
g_free (to_string);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_is_empty (void)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
g_assert_cmpint (_gtk_bitmask_is_empty (masks[i]), ==, i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_equals (void)
|
||||
{
|
||||
guint i, j;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
for (j = 0; j < G_N_ELEMENTS (tests); j++)
|
||||
{
|
||||
g_assert_cmpint (_gtk_bitmask_equals (masks[i], masks[j]), ==, i == j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_set (void)
|
||||
{
|
||||
guint i, j;
|
||||
guint indexes[N_TRIES];
|
||||
GtkBitmask *copy;
|
||||
const GtkBitmask *mask;
|
||||
|
||||
for (i = 0; i < N_RUNS; i++)
|
||||
{
|
||||
mask = masks[g_test_rand_int_range (0, G_N_ELEMENTS (tests))];
|
||||
copy = _gtk_bitmask_copy (mask);
|
||||
|
||||
for (j = 0; j < N_TRIES; j++)
|
||||
{
|
||||
indexes[j] = g_test_rand_int_range (0, MAX_INDEX);
|
||||
copy = _gtk_bitmask_set (copy, indexes[j], g_test_rand_bit ());
|
||||
}
|
||||
|
||||
for (j = 0; j < N_TRIES; j++)
|
||||
{
|
||||
copy = _gtk_bitmask_set (copy, indexes[j], _gtk_bitmask_get (mask, indexes[j]));
|
||||
}
|
||||
|
||||
assert_cmpmasks (copy, mask);
|
||||
_gtk_bitmask_free (copy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_union (void)
|
||||
{
|
||||
GtkBitmask *left, *right, *expected;
|
||||
guint run, try, n_tries;
|
||||
|
||||
for (run = 0; run < N_RUNS; run++)
|
||||
{
|
||||
left = _gtk_bitmask_new ();
|
||||
right = _gtk_bitmask_new ();
|
||||
expected = _gtk_bitmask_new ();
|
||||
|
||||
n_tries = g_test_perf () ? N_TRIES : g_test_rand_int_range (0, N_TRIES);
|
||||
for (try = 0; try < n_tries; try++)
|
||||
{
|
||||
guint id = g_test_rand_int_range (0, MAX_INDEX);
|
||||
|
||||
if (g_test_rand_bit ())
|
||||
left = _gtk_bitmask_set (left, id, TRUE);
|
||||
else
|
||||
right = _gtk_bitmask_set (right, id, TRUE);
|
||||
|
||||
expected = _gtk_bitmask_set (expected, id, TRUE);
|
||||
}
|
||||
|
||||
left = _gtk_bitmask_union (left, right);
|
||||
right = _gtk_bitmask_union (right, left);
|
||||
|
||||
assert_cmpmasks (left, expected);
|
||||
assert_cmpmasks (right, expected);
|
||||
_gtk_bitmask_free (left);
|
||||
_gtk_bitmask_free (right);
|
||||
_gtk_bitmask_free (expected);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_intersect (void)
|
||||
{
|
||||
GtkBitmask *left, *right, *expected;
|
||||
guint run, try;
|
||||
gboolean intersects;
|
||||
|
||||
for (run = 0; run < N_RUNS; run++)
|
||||
{
|
||||
left = _gtk_bitmask_new ();
|
||||
right = _gtk_bitmask_new ();
|
||||
expected = _gtk_bitmask_new ();
|
||||
|
||||
for (try = 0; try < N_TRIES; try++)
|
||||
{
|
||||
guint id = g_test_rand_int_range (0, MAX_INDEX);
|
||||
gboolean set = g_test_rand_bit ();
|
||||
|
||||
if (g_test_rand_bit ())
|
||||
{
|
||||
left = _gtk_bitmask_set (left, id, set);
|
||||
expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (right, id) : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
right = _gtk_bitmask_set (right, id, set);
|
||||
expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (left, id) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
intersects = _gtk_bitmask_intersects (left, right);
|
||||
g_assert_cmpint (intersects, ==, _gtk_bitmask_intersects (right, left));
|
||||
g_assert_cmpint (intersects, !=, _gtk_bitmask_is_empty (expected));
|
||||
|
||||
left = _gtk_bitmask_intersect (left, right);
|
||||
right = _gtk_bitmask_intersect (right, left);
|
||||
|
||||
assert_cmpmasks (left, expected);
|
||||
assert_cmpmasks (right, expected);
|
||||
_gtk_bitmask_free (left);
|
||||
_gtk_bitmask_free (right);
|
||||
_gtk_bitmask_free (expected);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_intersect_hardcoded (void)
|
||||
{
|
||||
GtkBitmask *left, *right, *intersection, *expected;
|
||||
const char *left_str, *right_str;
|
||||
guint left_len, right_len;
|
||||
guint i, l, r;
|
||||
|
||||
for (l = 0; l < G_N_ELEMENTS (tests); l++)
|
||||
{
|
||||
for (r = 0; r < G_N_ELEMENTS (tests); r++)
|
||||
{
|
||||
left = masks[l];
|
||||
right = masks[r];
|
||||
left_str = tests[l];
|
||||
right_str = tests[r];
|
||||
left_len = strlen (tests[l]);
|
||||
right_len = strlen (tests[r]);
|
||||
|
||||
expected = _gtk_bitmask_new ();
|
||||
if (left_len > right_len)
|
||||
left_str += left_len - right_len;
|
||||
if (right_len > left_len)
|
||||
right_str += right_len - left_len;
|
||||
i = MIN (right_len, left_len);
|
||||
while (i--)
|
||||
{
|
||||
expected = _gtk_bitmask_set (expected, i, left_str[0] == '1' && right_str[0] == '1');
|
||||
right_str++;
|
||||
left_str++;
|
||||
}
|
||||
|
||||
intersection = _gtk_bitmask_intersect (_gtk_bitmask_copy (left), right);
|
||||
|
||||
assert_cmpmasks (intersection, expected);
|
||||
g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, !_gtk_bitmask_intersects (left, right));
|
||||
|
||||
_gtk_bitmask_free (intersection);
|
||||
_gtk_bitmask_free (expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SWAP(_a, _b) G_STMT_START{ \
|
||||
guint _tmp = _a; \
|
||||
_a = _b; \
|
||||
_b = _tmp; \
|
||||
}G_STMT_END
|
||||
|
||||
static void
|
||||
test_invert_range (void)
|
||||
{
|
||||
GtkBitmask *left, *right, *intersection, *expected;
|
||||
guint run;
|
||||
guint left_start, left_end, right_start, right_end, start, end;
|
||||
|
||||
for (run = 0; run < N_RUNS; run++)
|
||||
{
|
||||
left = _gtk_bitmask_new ();
|
||||
right = _gtk_bitmask_new ();
|
||||
expected = _gtk_bitmask_new ();
|
||||
|
||||
left_start = g_test_rand_int_range (0, MAX_INDEX);
|
||||
left_end = g_test_rand_int_range (0, MAX_INDEX);
|
||||
if (left_start > left_end)
|
||||
SWAP (left_start, left_end);
|
||||
right_start = g_test_rand_int_range (0, MAX_INDEX);
|
||||
right_end = g_test_rand_int_range (0, MAX_INDEX);
|
||||
if (right_start > right_end)
|
||||
SWAP (right_start, right_end);
|
||||
start = MAX (left_start, right_start);
|
||||
end = MIN (left_end, right_end);
|
||||
|
||||
if (left_start != left_end)
|
||||
left = _gtk_bitmask_invert_range (left, left_start, left_end);
|
||||
if (right_start != right_end)
|
||||
right = _gtk_bitmask_invert_range (right, right_start, right_end);
|
||||
if (start < end)
|
||||
expected = _gtk_bitmask_invert_range (expected, start, end);
|
||||
|
||||
intersection = _gtk_bitmask_copy (left);
|
||||
intersection = _gtk_bitmask_intersect (intersection, right);
|
||||
|
||||
assert_cmpmasks (intersection, expected);
|
||||
|
||||
if (start < end)
|
||||
expected = _gtk_bitmask_invert_range (expected, start, end);
|
||||
|
||||
g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, TRUE);
|
||||
|
||||
_gtk_bitmask_free (left);
|
||||
_gtk_bitmask_free (right);
|
||||
_gtk_bitmask_free (intersection);
|
||||
_gtk_bitmask_free (expected);
|
||||
}
|
||||
}
|
||||
|
||||
/* SETUP & RUNNING */
|
||||
|
||||
static void
|
||||
create_masks (void)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
masks[i] = gtk_bitmask_new_parse (tests[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
free_masks (void)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
_gtk_bitmask_free (masks[i]);
|
||||
masks[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int result;
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
create_masks ();
|
||||
|
||||
g_test_add_func ("/bitmask/to_string", test_to_string);
|
||||
g_test_add_func ("/bitmask/is_empty", test_is_empty);
|
||||
g_test_add_func ("/bitmask/equals", test_equals);
|
||||
g_test_add_func ("/bitmask/set", test_set);
|
||||
g_test_add_func ("/bitmask/union", test_union);
|
||||
g_test_add_func ("/bitmask/intersect", test_intersect);
|
||||
g_test_add_func ("/bitmask/intersect_hardcoded", test_intersect_hardcoded);
|
||||
g_test_add_func ("/bitmask/invert_range", test_invert_range);
|
||||
|
||||
result = g_test_run ();
|
||||
|
||||
free_masks ();
|
||||
|
||||
return result;
|
||||
}
|
||||
2776
testsuite/gtk/builder.c
Normal file
2776
testsuite/gtk/builder.c
Normal file
File diff suppressed because it is too large
Load Diff
863
testsuite/gtk/cellarea.c
Normal file
863
testsuite/gtk/cellarea.c
Normal file
@ -0,0 +1,863 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
* Author: Matthias Clasen
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/* tests related to handling of the cell-area property in
|
||||
* GtkCellLayout implementations
|
||||
*/
|
||||
|
||||
/* test that we have a cell area after new() */
|
||||
static void
|
||||
test_iconview_new (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
view = gtk_icon_view_new ();
|
||||
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == gtk_icon_view_get_item_orientation (GTK_ICON_VIEW (view)));
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that new_with_area() keeps the provided area */
|
||||
static void
|
||||
test_iconview_new_with_area (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = gtk_icon_view_new_with_area (area);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that g_object_new keeps the provided area */
|
||||
static void
|
||||
test_iconview_object_new (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
|
||||
view = g_object_new (GTK_TYPE_ICON_VIEW, "cell-area", area, NULL);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == gtk_icon_view_get_item_orientation (GTK_ICON_VIEW (view)));
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
typedef GtkIconView MyIconView;
|
||||
typedef GtkIconViewClass MyIconViewClass;
|
||||
|
||||
GType my_icon_view_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (MyIconView, my_icon_view, GTK_TYPE_ICON_VIEW)
|
||||
|
||||
static void
|
||||
my_icon_view_class_init (MyIconViewClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static gint subclass_init;
|
||||
|
||||
static void
|
||||
my_icon_view_init (MyIconView *view)
|
||||
{
|
||||
GtkCellArea *area;
|
||||
|
||||
if (subclass_init == 0)
|
||||
{
|
||||
/* do nothing to area */
|
||||
}
|
||||
else if (subclass_init == 1)
|
||||
{
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* test that an iconview subclass has an area */
|
||||
static void
|
||||
test_iconview_subclass0 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
view = g_object_new (my_icon_view_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that an iconview subclass keeps the provided area */
|
||||
static void
|
||||
test_iconview_subclass1 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = g_object_new (my_icon_view_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test we can access the area in subclass init */
|
||||
static void
|
||||
test_iconview_subclass2 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 1;
|
||||
|
||||
view = g_object_new (my_icon_view_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test we get a warning if an area is provided, but ignored */
|
||||
static void
|
||||
test_iconview_subclass3 (void)
|
||||
{
|
||||
subclass_init = 1;
|
||||
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = g_object_new (my_icon_view_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
g_test_trap_assert_stderr ("*ignoring construct property*");
|
||||
}
|
||||
|
||||
/* test that we have a cell area after new() */
|
||||
static void
|
||||
test_combobox_new (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
view = gtk_combo_box_new ();
|
||||
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that new_with_area() keeps the provided area */
|
||||
static void
|
||||
test_combobox_new_with_area (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = gtk_combo_box_new_with_area (area);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that g_object_new keeps the provided area */
|
||||
static void
|
||||
test_combobox_object_new (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
|
||||
view = g_object_new (GTK_TYPE_COMBO_BOX, "cell-area", area, NULL);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
typedef GtkComboBox MyComboBox;
|
||||
typedef GtkComboBoxClass MyComboBoxClass;
|
||||
|
||||
GType my_combo_box_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (MyComboBox, my_combo_box, GTK_TYPE_COMBO_BOX)
|
||||
|
||||
static void
|
||||
my_combo_box_class_init (MyComboBoxClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
my_combo_box_init (MyComboBox *view)
|
||||
{
|
||||
GtkCellArea *area;
|
||||
|
||||
if (subclass_init == 0)
|
||||
{
|
||||
/* do nothing to area */
|
||||
}
|
||||
else if (subclass_init == 1)
|
||||
{
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* test that a combobox subclass has an area */
|
||||
static void
|
||||
test_combobox_subclass0 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
view = g_object_new (my_combo_box_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that a combobox subclass keeps the provided area */
|
||||
static void
|
||||
test_combobox_subclass1 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = g_object_new (my_combo_box_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test we can access the area in subclass init */
|
||||
static void
|
||||
test_combobox_subclass2 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 1;
|
||||
|
||||
view = g_object_new (my_combo_box_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test we get a warning if an area is provided, but ignored */
|
||||
static void
|
||||
test_combobox_subclass3 (void)
|
||||
{
|
||||
subclass_init = 1;
|
||||
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = g_object_new (my_combo_box_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
g_test_trap_assert_stderr ("*ignoring construct property*");
|
||||
}
|
||||
|
||||
/* test that we have a cell area after new() */
|
||||
static void
|
||||
test_cellview_new (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
view = gtk_cell_view_new ();
|
||||
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that new_with_context() keeps the provided area */
|
||||
static void
|
||||
test_cellview_new_with_context (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
GtkCellAreaContext *context;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
context = gtk_cell_area_create_context (area);
|
||||
view = gtk_cell_view_new_with_context (area, context);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that g_object_new keeps the provided area */
|
||||
static void
|
||||
test_cellview_object_new (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
|
||||
view = g_object_new (GTK_TYPE_CELL_VIEW, "cell-area", area, NULL);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
typedef GtkCellView MyCellView;
|
||||
typedef GtkCellViewClass MyCellViewClass;
|
||||
|
||||
GType my_cell_view_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (MyCellView, my_cell_view, GTK_TYPE_CELL_VIEW)
|
||||
|
||||
static void
|
||||
my_cell_view_class_init (MyCellViewClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
my_cell_view_init (MyCellView *view)
|
||||
{
|
||||
GtkCellArea *area;
|
||||
|
||||
if (subclass_init == 0)
|
||||
{
|
||||
/* do nothing to area */
|
||||
}
|
||||
else if (subclass_init == 1)
|
||||
{
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* test that a cellview subclass has an area */
|
||||
static void
|
||||
test_cellview_subclass0 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
view = g_object_new (my_cell_view_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test that a cellview subclass keeps the provided area */
|
||||
static void
|
||||
test_cellview_subclass1 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = g_object_new (my_cell_view_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test we can access the area in subclass init */
|
||||
static void
|
||||
test_cellview_subclass2 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 1;
|
||||
|
||||
view = g_object_new (my_cell_view_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
/* test we get a warning if an area is provided, but ignored */
|
||||
static void
|
||||
test_cellview_subclass3 (void)
|
||||
{
|
||||
subclass_init = 1;
|
||||
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
view = g_object_new (my_cell_view_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (view);
|
||||
g_object_unref (view);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
g_test_trap_assert_stderr ("*ignoring construct property*");
|
||||
}
|
||||
|
||||
/* test that we have a cell area after new() */
|
||||
static void
|
||||
test_column_new (void)
|
||||
{
|
||||
GtkTreeViewColumn *col;
|
||||
GtkCellArea *area;
|
||||
|
||||
col = gtk_tree_view_column_new ();
|
||||
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
|
||||
g_object_ref_sink (col);
|
||||
g_object_unref (col);
|
||||
}
|
||||
|
||||
/* test that new_with_area() keeps the provided area */
|
||||
static void
|
||||
test_column_new_with_area (void)
|
||||
{
|
||||
GtkTreeViewColumn *col;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
col = gtk_tree_view_column_new_with_area (area);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)) == area);
|
||||
|
||||
g_object_ref_sink (col);
|
||||
g_object_unref (col);
|
||||
}
|
||||
|
||||
/* test that g_object_new keeps the provided area */
|
||||
static void
|
||||
test_column_object_new (void)
|
||||
{
|
||||
GtkTreeViewColumn *col;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
|
||||
col = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN, "cell-area", area, NULL);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)) == area);
|
||||
|
||||
g_object_ref_sink (col);
|
||||
g_object_unref (col);
|
||||
}
|
||||
|
||||
typedef GtkTreeViewColumn MyTreeViewColumn;
|
||||
typedef GtkTreeViewColumnClass MyTreeViewColumnClass;
|
||||
|
||||
GType my_tree_view_column_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (MyTreeViewColumn, my_tree_view_column, GTK_TYPE_TREE_VIEW_COLUMN)
|
||||
|
||||
static void
|
||||
my_tree_view_column_class_init (MyTreeViewColumnClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
my_tree_view_column_init (MyTreeViewColumn *col)
|
||||
{
|
||||
GtkCellArea *area;
|
||||
|
||||
if (subclass_init == 0)
|
||||
{
|
||||
/* do nothing to area */
|
||||
}
|
||||
else if (subclass_init == 1)
|
||||
{
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* test that a column subclass has an area */
|
||||
static void
|
||||
test_column_subclass0 (void)
|
||||
{
|
||||
GtkTreeViewColumn *col;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
col = g_object_new (my_tree_view_column_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (col);
|
||||
g_object_unref (col);
|
||||
}
|
||||
|
||||
/* test that a column subclass keeps the provided area */
|
||||
static void
|
||||
test_column_subclass1 (void)
|
||||
{
|
||||
GtkTreeViewColumn *col;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
col = g_object_new (my_tree_view_column_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (col);
|
||||
g_object_unref (col);
|
||||
}
|
||||
|
||||
/* test we can access the area in subclass init */
|
||||
static void
|
||||
test_column_subclass2 (void)
|
||||
{
|
||||
GtkTreeViewColumn *col;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 1;
|
||||
|
||||
col = g_object_new (my_tree_view_column_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (col);
|
||||
g_object_unref (col);
|
||||
}
|
||||
|
||||
/* test we get a warning if an area is provided, but ignored */
|
||||
static void
|
||||
test_column_subclass3 (void)
|
||||
{
|
||||
subclass_init = 1;
|
||||
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
GtkTreeViewColumn *col;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
col = g_object_new (my_tree_view_column_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (col);
|
||||
g_object_unref (col);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
g_test_trap_assert_stderr ("*ignoring construct property*");
|
||||
}
|
||||
|
||||
/* test that we have a cell area after new() */
|
||||
static void
|
||||
test_completion_new (void)
|
||||
{
|
||||
GtkEntryCompletion *c;
|
||||
GtkCellArea *area;
|
||||
|
||||
c = gtk_entry_completion_new ();
|
||||
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
|
||||
g_object_ref_sink (c);
|
||||
g_object_unref (c);
|
||||
}
|
||||
|
||||
/* test that new_with_area() keeps the provided area */
|
||||
static void
|
||||
test_completion_new_with_area (void)
|
||||
{
|
||||
GtkEntryCompletion *c;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
c = gtk_entry_completion_new_with_area (area);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
|
||||
|
||||
g_object_ref_sink (c);
|
||||
g_object_unref (c);
|
||||
}
|
||||
|
||||
/* test that g_object_new keeps the provided area */
|
||||
static void
|
||||
test_completion_object_new (void)
|
||||
{
|
||||
GtkEntryCompletion *c;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
|
||||
c = g_object_new (GTK_TYPE_ENTRY_COMPLETION, "cell-area", area, NULL);
|
||||
g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
|
||||
|
||||
g_object_ref_sink (c);
|
||||
g_object_unref (c);
|
||||
}
|
||||
|
||||
typedef GtkEntryCompletion MyEntryCompletion;
|
||||
typedef GtkEntryCompletionClass MyEntryCompletionClass;
|
||||
|
||||
GType my_entry_completion_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (MyEntryCompletion, my_entry_completion, GTK_TYPE_ENTRY_COMPLETION)
|
||||
|
||||
static void
|
||||
my_entry_completion_class_init (MyEntryCompletionClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
my_entry_completion_init (MyEntryCompletion *c)
|
||||
{
|
||||
GtkCellArea *area;
|
||||
|
||||
if (subclass_init == 0)
|
||||
{
|
||||
/* do nothing to area */
|
||||
}
|
||||
else if (subclass_init == 1)
|
||||
{
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* test that a completion subclass has an area */
|
||||
static void
|
||||
test_completion_subclass0 (void)
|
||||
{
|
||||
GtkEntryCompletion *c;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
c = g_object_new (my_entry_completion_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (c);
|
||||
g_object_unref (c);
|
||||
}
|
||||
|
||||
/* test that a completion subclass keeps the provided area */
|
||||
static void
|
||||
test_completion_subclass1 (void)
|
||||
{
|
||||
GtkEntryCompletion *c;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 0;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
c = g_object_new (my_entry_completion_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
g_object_ref_sink (c);
|
||||
g_object_unref (c);
|
||||
}
|
||||
|
||||
/* test we can access the area in subclass init */
|
||||
static void
|
||||
test_completion_subclass2 (void)
|
||||
{
|
||||
GtkEntryCompletion *c;
|
||||
GtkCellArea *area;
|
||||
|
||||
subclass_init = 1;
|
||||
|
||||
c = g_object_new (my_entry_completion_get_type (), NULL);
|
||||
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
|
||||
g_assert (GTK_IS_CELL_AREA_BOX (area));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (c);
|
||||
g_object_unref (c);
|
||||
}
|
||||
|
||||
/* test we get a warning if an area is provided, but ignored */
|
||||
static void
|
||||
test_completion_subclass3 (void)
|
||||
{
|
||||
subclass_init = 1;
|
||||
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
GtkEntryCompletion *c;
|
||||
GtkCellArea *area;
|
||||
|
||||
area = gtk_cell_area_box_new ();
|
||||
c = g_object_new (my_entry_completion_get_type (), "cell-area", area, NULL);
|
||||
g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)));
|
||||
g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_ref_sink (c);
|
||||
g_object_unref (c);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
g_test_trap_assert_stderr ("*ignoring construct property*");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
gtk_test_register_all_types();
|
||||
|
||||
g_test_add_func ("/tests/iconview-new", test_iconview_new);
|
||||
g_test_add_func ("/tests/iconview-new-with-area", test_iconview_new_with_area);
|
||||
g_test_add_func ("/tests/iconview-object-new", test_iconview_object_new);
|
||||
g_test_add_func ("/tests/iconview-subclass0", test_iconview_subclass0);
|
||||
g_test_add_func ("/tests/iconview-subclass1", test_iconview_subclass1);
|
||||
g_test_add_func ("/tests/iconview-subclass2", test_iconview_subclass2);
|
||||
g_test_add_func ("/tests/iconview-subclass3", test_iconview_subclass3);
|
||||
|
||||
g_test_add_func ("/tests/combobox-new", test_combobox_new);
|
||||
g_test_add_func ("/tests/combobox-new-with-area", test_combobox_new_with_area);
|
||||
g_test_add_func ("/tests/combobox-object-new", test_combobox_object_new);
|
||||
g_test_add_func ("/tests/combobox-subclass0", test_combobox_subclass0);
|
||||
g_test_add_func ("/tests/combobox-subclass1", test_combobox_subclass1);
|
||||
g_test_add_func ("/tests/combobox-subclass2", test_combobox_subclass2);
|
||||
g_test_add_func ("/tests/combobox-subclass3", test_combobox_subclass3);
|
||||
|
||||
g_test_add_func ("/tests/cellview-new", test_cellview_new);
|
||||
g_test_add_func ("/tests/cellview-new-with-context", test_cellview_new_with_context);
|
||||
g_test_add_func ("/tests/cellview-object-new", test_cellview_object_new);
|
||||
g_test_add_func ("/tests/cellview-subclass0", test_cellview_subclass0);
|
||||
g_test_add_func ("/tests/cellview-subclass1", test_cellview_subclass1);
|
||||
g_test_add_func ("/tests/cellview-subclass2", test_cellview_subclass2);
|
||||
g_test_add_func ("/tests/cellview-subclass3", test_cellview_subclass3);
|
||||
|
||||
g_test_add_func ("/tests/column-new", test_column_new);
|
||||
g_test_add_func ("/tests/column-new-with-area", test_column_new_with_area);
|
||||
g_test_add_func ("/tests/column-object-new", test_column_object_new);
|
||||
g_test_add_func ("/tests/column-subclass0", test_column_subclass0);
|
||||
g_test_add_func ("/tests/column-subclass1", test_column_subclass1);
|
||||
g_test_add_func ("/tests/column-subclass2", test_column_subclass2);
|
||||
g_test_add_func ("/tests/column-subclass3", test_column_subclass3);
|
||||
|
||||
g_test_add_func ("/tests/completion-new", test_completion_new);
|
||||
g_test_add_func ("/tests/completion-new-with-area", test_completion_new_with_area);
|
||||
g_test_add_func ("/tests/completion-object-new", test_completion_object_new);
|
||||
g_test_add_func ("/tests/completion-subclass0", test_completion_subclass0);
|
||||
g_test_add_func ("/tests/completion-subclass1", test_completion_subclass1);
|
||||
g_test_add_func ("/tests/completion-subclass2", test_completion_subclass2);
|
||||
g_test_add_func ("/tests/completion-subclass3", test_completion_subclass3);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
628
testsuite/gtk/crossingevents.c
Normal file
628
testsuite/gtk/crossingevents.c
Normal file
@ -0,0 +1,628 @@
|
||||
/*
|
||||
* crossingevents.c: A test for crossing events
|
||||
*
|
||||
* Copyright (C) 2008 Cody Russell
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *window;
|
||||
GtkWidget *eventbox;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *button;
|
||||
GtkWidget *check;
|
||||
gboolean events_connected;
|
||||
GQueue *queue;
|
||||
} CrossingTest;
|
||||
|
||||
typedef struct {
|
||||
gboolean entered;
|
||||
gchar *name;
|
||||
gboolean synthesized;
|
||||
GdkCrossingMode mode;
|
||||
GdkNotifyType detail;
|
||||
} CrossingEventData;
|
||||
|
||||
#define SLEEP_DURATION 100
|
||||
|
||||
void start_events (CrossingTest *test);
|
||||
void stop_events (CrossingTest *test);
|
||||
|
||||
static gboolean
|
||||
sleep_timeout_cb (gpointer data)
|
||||
{
|
||||
gtk_main_quit ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
sleep_in_main_loop (double fraction)
|
||||
{
|
||||
/* process all pending idles and events */
|
||||
while (g_main_context_pending (NULL))
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
/* sleeping probably isn't strictly necessary here */
|
||||
gdk_threads_add_timeout_full (G_MAXINT, fraction * SLEEP_DURATION, sleep_timeout_cb, NULL, NULL);
|
||||
gtk_main ();
|
||||
/* process any pending idles or events that arrived during sleep */
|
||||
while (g_main_context_pending (NULL))
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
set_cursor (GtkWidget *widget)
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
gdk_window_get_origin (widget->window, &x, &y);
|
||||
|
||||
x += widget->allocation.x;
|
||||
y += widget->allocation.y;
|
||||
w = widget->allocation.width;
|
||||
h = widget->allocation.height;
|
||||
|
||||
gdk_display_warp_pointer (gtk_widget_get_display (widget),
|
||||
gtk_widget_get_screen (widget),
|
||||
x + w / 2,
|
||||
y + h / 2);
|
||||
|
||||
sleep_in_main_loop (0.5);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_enter (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
|
||||
{
|
||||
CrossingTest *test = (CrossingTest*)user_data;
|
||||
|
||||
CrossingEventData *evt = g_slice_new0 (CrossingEventData);
|
||||
evt->entered = TRUE;
|
||||
evt->name = g_strdup (gtk_widget_get_name (widget));
|
||||
evt->synthesized = event->send_event;
|
||||
evt->mode = event->mode;
|
||||
evt->detail = event->detail;
|
||||
|
||||
if (!test->queue)
|
||||
test->queue = g_queue_new ();
|
||||
|
||||
g_queue_push_tail (test->queue, evt);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_leave (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
|
||||
{
|
||||
CrossingTest *test = (CrossingTest*)user_data;
|
||||
|
||||
CrossingEventData *evt = g_slice_new0 (CrossingEventData);
|
||||
evt->entered = FALSE;
|
||||
evt->name = g_strdup (gtk_widget_get_name (widget));
|
||||
evt->synthesized = event->send_event;
|
||||
evt->mode = event->mode;
|
||||
evt->detail = event->detail;
|
||||
|
||||
if (!test->queue)
|
||||
test->queue = g_queue_new ();
|
||||
|
||||
g_queue_push_tail (test->queue, evt);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_check_toggled (GtkWidget *toggle, GtkWidget *button)
|
||||
{
|
||||
gtk_widget_set_sensitive (button, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
|
||||
}
|
||||
|
||||
static void
|
||||
sensitivity_setup (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
|
||||
test->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_widget_set_name (test->window, "W");
|
||||
frame = gtk_frame_new ("Crossing Events");
|
||||
test->eventbox = gtk_event_box_new ();
|
||||
gtk_widget_set_name (test->eventbox, "E");
|
||||
|
||||
GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 10);
|
||||
gtk_container_add (GTK_CONTAINER (test->window), frame);
|
||||
gtk_container_add (GTK_CONTAINER (frame), test->eventbox);
|
||||
gtk_container_add (GTK_CONTAINER (test->eventbox), vbox);
|
||||
|
||||
test->button = gtk_button_new_with_label ("Click me!");
|
||||
gtk_widget_set_name (test->button, "B");
|
||||
gtk_box_pack_start (GTK_BOX (vbox), test->button, FALSE, TRUE, 0);
|
||||
|
||||
test->check = gtk_check_button_new_with_label ("Sensitive?");
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), TRUE);
|
||||
g_signal_connect (G_OBJECT (test->check),
|
||||
"toggled", G_CALLBACK (on_check_toggled), test->button);
|
||||
gtk_widget_set_name (test->check, "C");
|
||||
gtk_box_pack_start (GTK_BOX (vbox), test->check, FALSE, TRUE, 0);
|
||||
|
||||
gtk_widget_show_all (test->window);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (test->window), 0, 0);
|
||||
|
||||
sleep_in_main_loop (0.5);
|
||||
}
|
||||
|
||||
static void
|
||||
sensitivity_teardown (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
stop_events (test);
|
||||
gtk_widget_destroy (test->window);
|
||||
|
||||
if (test->queue != NULL)
|
||||
{
|
||||
g_queue_clear (test->queue);
|
||||
test->queue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
start_events (CrossingTest *test)
|
||||
{
|
||||
if (!test->events_connected)
|
||||
{
|
||||
g_object_connect (G_OBJECT (test->window),
|
||||
"signal::destroy", gtk_main_quit, NULL,
|
||||
"signal::enter-notify-event", on_enter, test,
|
||||
"signal::leave-notify-event", on_leave, test,
|
||||
NULL);
|
||||
g_object_connect (G_OBJECT (test->eventbox),
|
||||
"signal::enter-notify-event", on_enter, test,
|
||||
"signal::leave-notify-event", on_leave, test,
|
||||
NULL);
|
||||
g_object_connect (G_OBJECT (test->button),
|
||||
"signal::enter-notify-event", on_enter, test,
|
||||
"signal::leave-notify-event", on_leave, test,
|
||||
NULL);
|
||||
g_object_connect (G_OBJECT (test->check),
|
||||
"signal::enter-notify-event", on_enter, test,
|
||||
"signal::leave-notify-event", on_leave, test,
|
||||
NULL);
|
||||
test->events_connected = TRUE;
|
||||
}
|
||||
|
||||
sleep_in_main_loop (0.5);
|
||||
}
|
||||
|
||||
void
|
||||
stop_events (CrossingTest *test)
|
||||
{
|
||||
if (test->events_connected)
|
||||
{
|
||||
g_object_disconnect (G_OBJECT (test->window),
|
||||
"any_signal", gtk_main_quit, NULL,
|
||||
"any_signal", on_enter, test,
|
||||
"any_signal", on_leave, test,
|
||||
NULL);
|
||||
g_object_disconnect (G_OBJECT (test->eventbox),
|
||||
"any_signal", on_enter, test,
|
||||
"any_signal", on_leave, test,
|
||||
NULL);
|
||||
g_object_disconnect (G_OBJECT (test->button),
|
||||
"any_signal", on_enter, test,
|
||||
"any_signal", on_leave, test,
|
||||
NULL);
|
||||
g_object_disconnect (G_OBJECT (test->check),
|
||||
"any_signal", G_CALLBACK (on_check_toggled), test->button,
|
||||
"any_signal", on_enter, test,
|
||||
"any_signal", on_leave, test,
|
||||
NULL);
|
||||
test->events_connected = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
move_cursor_away (CrossingTest *test)
|
||||
{
|
||||
gdk_display_warp_pointer (gtk_widget_get_display (test->window),
|
||||
gtk_widget_get_screen (test->window),
|
||||
1000, -1000);
|
||||
|
||||
sleep_in_main_loop (0.5);
|
||||
}
|
||||
|
||||
void
|
||||
check_event (CrossingTest *test,
|
||||
const gchar *name,
|
||||
gboolean entered,
|
||||
gboolean synthesized,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail)
|
||||
{
|
||||
CrossingEventData *evt;
|
||||
|
||||
g_assert (test->queue != NULL);
|
||||
|
||||
evt = g_queue_pop_head (test->queue);
|
||||
|
||||
g_assert (evt->entered == entered);
|
||||
g_assert (strcmp (evt->name, name) == 0);
|
||||
g_assert (evt->synthesized == synthesized);
|
||||
g_assert (evt->mode == mode);
|
||||
|
||||
if (evt->detail != detail)
|
||||
g_print ("%s %s event, detail %d, expected detail %d\n",
|
||||
synthesized ? "synthesized" : "native",
|
||||
entered ? "enter" : "leave",
|
||||
evt->detail, detail);
|
||||
|
||||
g_assert (evt->detail == detail);
|
||||
}
|
||||
|
||||
/* Verify crossing events when moving into and out of a sensitive widget */
|
||||
static void
|
||||
cursor_on_sensitive (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
move_cursor_away (test);
|
||||
|
||||
start_events (test);
|
||||
|
||||
set_cursor (test->button);
|
||||
|
||||
check_event (test,
|
||||
"W",
|
||||
TRUE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR_VIRTUAL);
|
||||
|
||||
check_event (test,
|
||||
"E",
|
||||
TRUE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR_VIRTUAL);
|
||||
|
||||
check_event (test,
|
||||
"B",
|
||||
TRUE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
move_cursor_away (test);
|
||||
|
||||
check_event (test,
|
||||
"B",
|
||||
FALSE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
check_event (test,
|
||||
"E",
|
||||
FALSE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR_VIRTUAL);
|
||||
|
||||
check_event (test,
|
||||
"W",
|
||||
FALSE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR_VIRTUAL);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
change_sensitive_to_insensitive (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
move_cursor_away (test);
|
||||
set_cursor (test->button);
|
||||
|
||||
start_events (test);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
|
||||
|
||||
check_event (test,
|
||||
"B",
|
||||
FALSE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_STATE_CHANGED,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
check_event (test,
|
||||
"E",
|
||||
FALSE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_STATE_CHANGED,
|
||||
GDK_NOTIFY_VIRTUAL);
|
||||
|
||||
check_event (test,
|
||||
"W",
|
||||
FALSE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_STATE_CHANGED,
|
||||
GDK_NOTIFY_VIRTUAL);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
change_insensitive_to_sensitive (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
move_cursor_away (test);
|
||||
set_cursor (test->button);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
|
||||
|
||||
start_events (test);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), TRUE);
|
||||
|
||||
check_event (test,
|
||||
"W",
|
||||
TRUE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_STATE_CHANGED,
|
||||
GDK_NOTIFY_VIRTUAL);
|
||||
|
||||
check_event (test,
|
||||
"E",
|
||||
TRUE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_STATE_CHANGED,
|
||||
GDK_NOTIFY_VIRTUAL);
|
||||
|
||||
check_event (test,
|
||||
"B",
|
||||
TRUE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_STATE_CHANGED,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_from_insensitive_to_sensitive (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
set_cursor (test->button);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
|
||||
|
||||
start_events (test);
|
||||
|
||||
set_cursor (test->check);
|
||||
|
||||
check_event (test,
|
||||
"C",
|
||||
TRUE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_from_sensitive_to_insensitive (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
set_cursor (test->check);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
|
||||
|
||||
start_events (test);
|
||||
|
||||
set_cursor (test->button);
|
||||
|
||||
check_event (test,
|
||||
"C",
|
||||
FALSE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
add_gtk_grab (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
set_cursor (test->button);
|
||||
|
||||
start_events (test);
|
||||
|
||||
gtk_grab_add (test->check);
|
||||
|
||||
check_event (test,
|
||||
"B",
|
||||
FALSE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_GTK_GRAB,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
check_event (test,
|
||||
"E",
|
||||
FALSE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_GTK_GRAB,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
check_event (test,
|
||||
"W",
|
||||
FALSE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_GTK_GRAB,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_gtk_grab (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
set_cursor (test->button);
|
||||
|
||||
gtk_grab_add (test->check);
|
||||
|
||||
start_events (test);
|
||||
|
||||
gtk_grab_remove (test->check);
|
||||
|
||||
check_event (test,
|
||||
"B",
|
||||
TRUE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_GTK_UNGRAB,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
check_event (test,
|
||||
"E",
|
||||
TRUE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_GTK_UNGRAB,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
check_event (test,
|
||||
"W",
|
||||
TRUE,
|
||||
TRUE, /* synthesized */
|
||||
GDK_CROSSING_GTK_UNGRAB,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_from_shadowed_to_unshadowed (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
set_cursor (test->button);
|
||||
|
||||
gtk_grab_add (test->check);
|
||||
|
||||
start_events (test);
|
||||
|
||||
set_cursor (test->check);
|
||||
|
||||
check_event (test,
|
||||
"C",
|
||||
FALSE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
check_event (test,
|
||||
"C",
|
||||
TRUE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_from_unshadowed_to_shadowed (CrossingTest *test,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
set_cursor (test->check);
|
||||
|
||||
gtk_grab_add (test->check);
|
||||
|
||||
start_events (test);
|
||||
|
||||
set_cursor (test->button);
|
||||
|
||||
check_event (test,
|
||||
"C",
|
||||
FALSE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
check_event (test,
|
||||
"C",
|
||||
TRUE,
|
||||
FALSE, /* native */
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
g_assert (g_queue_is_empty (test->queue));
|
||||
|
||||
stop_events (test);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add ("/crossings/cursor-on-sensitive", CrossingTest, NULL,
|
||||
sensitivity_setup, cursor_on_sensitive, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/change-sensitive-to-insensitive", CrossingTest, NULL,
|
||||
sensitivity_setup, change_sensitive_to_insensitive, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/cursor-from-insensitive-to-sensitive", CrossingTest, NULL,
|
||||
sensitivity_setup, cursor_from_insensitive_to_sensitive, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/cursor-from-sensitive-to-insensitive", CrossingTest, NULL,
|
||||
sensitivity_setup, cursor_from_sensitive_to_insensitive, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/change-insensitive-to-sensitive", CrossingTest, NULL,
|
||||
sensitivity_setup, change_insensitive_to_sensitive, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/add-gtk-grab", CrossingTest, NULL,
|
||||
sensitivity_setup, add_gtk_grab, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/remove-gtk-grab", CrossingTest, NULL,
|
||||
sensitivity_setup, remove_gtk_grab, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/cursor-from-shadowed-to-unshadowed", CrossingTest, NULL,
|
||||
sensitivity_setup, cursor_from_shadowed_to_unshadowed, sensitivity_teardown);
|
||||
|
||||
g_test_add ("/crossings/cursor-from-unshadowed-to-shadowed", CrossingTest, NULL,
|
||||
sensitivity_setup, cursor_from_unshadowed_to_shadowed, sensitivity_teardown);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
347
testsuite/gtk/defaultvalue.c
Normal file
347
testsuite/gtk/defaultvalue.c
Normal file
@ -0,0 +1,347 @@
|
||||
/* Gtk+ default value tests
|
||||
* Copyright (C) 2007 Christian Persch
|
||||
* 2007 Johan Dahlin
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkunixprint.h>
|
||||
|
||||
static void
|
||||
check_property (const char *output,
|
||||
GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
GValue default_value = G_VALUE_INIT;
|
||||
char *v, *dv, *msg;
|
||||
|
||||
if (g_param_value_defaults (pspec, value))
|
||||
return;
|
||||
|
||||
g_value_init (&default_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
g_param_value_set_default (pspec, &default_value);
|
||||
|
||||
v = g_strdup_value_contents (value);
|
||||
dv = g_strdup_value_contents (&default_value);
|
||||
|
||||
msg = g_strdup_printf ("%s %s.%s: %s != %s\n",
|
||||
output,
|
||||
g_type_name (pspec->owner_type),
|
||||
pspec->name,
|
||||
dv, v);
|
||||
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__,
|
||||
G_STRFUNC, msg);
|
||||
g_free (msg);
|
||||
|
||||
g_free (v);
|
||||
g_free (dv);
|
||||
g_value_unset (&default_value);
|
||||
}
|
||||
|
||||
static void
|
||||
test_type (gconstpointer data)
|
||||
{
|
||||
GObjectClass *klass;
|
||||
GObject *instance;
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs, i;
|
||||
GType type;
|
||||
|
||||
type = * (GType *) data;
|
||||
|
||||
if (!G_TYPE_IS_CLASSED (type))
|
||||
return;
|
||||
|
||||
if (G_TYPE_IS_ABSTRACT (type))
|
||||
return;
|
||||
|
||||
if (!g_type_is_a (type, G_TYPE_OBJECT))
|
||||
return;
|
||||
|
||||
/* These can't be freely constructed/destroyed */
|
||||
if (g_type_is_a (type, GTK_TYPE_PRINT_JOB) ||
|
||||
g_type_is_a (type, GTK_TYPE_APPLICATION) ||
|
||||
g_type_is_a (type, GDK_TYPE_PIXBUF_LOADER) ||
|
||||
g_type_is_a (type, gdk_pixbuf_simple_anim_iter_get_type ()))
|
||||
return;
|
||||
|
||||
klass = g_type_class_ref (type);
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_SETTINGS))
|
||||
instance = g_object_ref (gtk_settings_get_default ());
|
||||
else if (g_type_is_a (type, GDK_TYPE_WINDOW))
|
||||
{
|
||||
GdkWindowAttr attributes;
|
||||
attributes.window_type = GDK_WINDOW_TEMP;
|
||||
attributes.event_mask = 0;
|
||||
attributes.width = 100;
|
||||
attributes.height = 100;
|
||||
instance = g_object_ref (gdk_window_new (NULL, &attributes, 0));
|
||||
}
|
||||
else
|
||||
instance = g_object_new (type, NULL);
|
||||
|
||||
if (g_type_is_a (type, G_TYPE_INITIALLY_UNOWNED))
|
||||
g_object_ref_sink (instance);
|
||||
|
||||
pspecs = g_object_class_list_properties (klass, &n_pspecs);
|
||||
for (i = 0; i < n_pspecs; ++i)
|
||||
{
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
if (pspec->owner_type != type)
|
||||
continue;
|
||||
|
||||
if ((pspec->flags & G_PARAM_READABLE) == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GDK_TYPE_DISPLAY_MANAGER) &&
|
||||
(strcmp (pspec->name, "default-display") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_ABOUT_DIALOG) &&
|
||||
(strcmp (pspec->name, "program-name") == 0))
|
||||
continue;
|
||||
|
||||
/* These are set to the current date */
|
||||
if (g_type_is_a (type, GTK_TYPE_CALENDAR) &&
|
||||
(strcmp (pspec->name, "year") == 0 ||
|
||||
strcmp (pspec->name, "month") == 0 ||
|
||||
strcmp (pspec->name, "day") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_CELL_RENDERER_TEXT) &&
|
||||
(strcmp (pspec->name, "background-gdk") == 0 ||
|
||||
strcmp (pspec->name, "foreground-gdk") == 0 ||
|
||||
strcmp (pspec->name, "font") == 0 ||
|
||||
strcmp (pspec->name, "font-desc") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_CELL_VIEW) &&
|
||||
(strcmp (pspec->name, "background-gdk") == 0 ||
|
||||
strcmp (pspec->name, "foreground-gdk") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_COLOR_BUTTON) &&
|
||||
strcmp (pspec->name, "color") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_COLOR_SELECTION) &&
|
||||
strcmp (pspec->name, "current-color") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_COLOR_SELECTION_DIALOG) &&
|
||||
(strcmp (pspec->name, "color-selection") == 0 ||
|
||||
strcmp (pspec->name, "ok-button") == 0 ||
|
||||
strcmp (pspec->name, "help-button") == 0 ||
|
||||
strcmp (pspec->name, "cancel-button") == 0))
|
||||
continue;
|
||||
|
||||
/* Default invisible char is determined at runtime */
|
||||
if (g_type_is_a (type, GTK_TYPE_ENTRY) &&
|
||||
(strcmp (pspec->name, "invisible-char") == 0 ||
|
||||
strcmp (pspec->name, "buffer") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_FONT_SELECTION) &&
|
||||
strcmp (pspec->name, "font") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_LAYOUT) &&
|
||||
(strcmp (pspec->name, "hadjustment") == 0 ||
|
||||
strcmp (pspec->name, "vadjustment") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_MESSAGE_DIALOG) &&
|
||||
(strcmp (pspec->name, "image") == 0 ||
|
||||
strcmp (pspec->name, "message-area") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_PANED) &&
|
||||
strcmp (pspec->name, "max-position") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_PRINT_OPERATION) &&
|
||||
strcmp (pspec->name, "job-name") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_PRINT_UNIX_DIALOG) &&
|
||||
(strcmp (pspec->name, "page-setup") == 0 ||
|
||||
strcmp (pspec->name, "print-settings") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_PROGRESS_BAR) &&
|
||||
strcmp (pspec->name, "adjustment") == 0)
|
||||
continue;
|
||||
|
||||
/* filename value depends on $HOME */
|
||||
if (g_type_is_a (type, GTK_TYPE_RECENT_MANAGER) &&
|
||||
(strcmp (pspec->name, "filename") == 0 ||
|
||||
strcmp (pspec->name, "size") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_SCALE_BUTTON) &&
|
||||
strcmp (pspec->name, "adjustment") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_SCROLLED_WINDOW) &&
|
||||
(strcmp (pspec->name, "hadjustment") == 0 ||
|
||||
strcmp (pspec->name, "vadjustment") == 0))
|
||||
continue;
|
||||
|
||||
/* these defaults come from XResources */
|
||||
if (g_type_is_a (type, GTK_TYPE_SETTINGS) &&
|
||||
strncmp (pspec->name, "gtk-xft-", 8) == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_SETTINGS) &&
|
||||
(strcmp (pspec->name, "color-hash") == 0 ||
|
||||
strcmp (pspec->name, "gtk-cursor-theme-name") == 0 ||
|
||||
strcmp (pspec->name, "gtk-cursor-theme-size") == 0 ||
|
||||
strcmp (pspec->name, "gtk-dnd-drag-threshold") == 0 ||
|
||||
strcmp (pspec->name, "gtk-double-click-time") == 0 ||
|
||||
strcmp (pspec->name, "gtk-fallback-icon-theme") == 0 ||
|
||||
strcmp (pspec->name, "gtk-file-chooser-backend") == 0 ||
|
||||
strcmp (pspec->name, "gtk-icon-theme-name") == 0 ||
|
||||
strcmp (pspec->name, "gtk-im-module") == 0 ||
|
||||
strcmp (pspec->name, "gtk-key-theme-name") == 0 ||
|
||||
strcmp (pspec->name, "gtk-theme-name") == 0 ||
|
||||
strcmp (pspec->name, "gtk-sound-theme-name") == 0 ||
|
||||
strcmp (pspec->name, "gtk-enable-input-feedback-sounds") == 0 ||
|
||||
strcmp (pspec->name, "gtk-enable-event-sounds") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_SPIN_BUTTON) &&
|
||||
(strcmp (pspec->name, "adjustment") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_STATUS_ICON) &&
|
||||
(strcmp (pspec->name, "size") == 0 ||
|
||||
strcmp (pspec->name, "screen") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_TEXT_BUFFER) &&
|
||||
(strcmp (pspec->name, "tag-table") == 0 ||
|
||||
strcmp (pspec->name, "copy-target-list") == 0 ||
|
||||
strcmp (pspec->name, "paste-target-list") == 0))
|
||||
continue;
|
||||
|
||||
/* language depends on the current locale */
|
||||
if (g_type_is_a (type, GTK_TYPE_TEXT_TAG) &&
|
||||
(strcmp (pspec->name, "background-gdk") == 0 ||
|
||||
strcmp (pspec->name, "foreground-gdk") == 0 ||
|
||||
strcmp (pspec->name, "language") == 0 ||
|
||||
strcmp (pspec->name, "font") == 0 ||
|
||||
strcmp (pspec->name, "font-desc") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_TEXT_VIEW) &&
|
||||
strcmp (pspec->name, "buffer") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_TOOL_ITEM_GROUP) &&
|
||||
strcmp (pspec->name, "label-widget") == 0)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_TREE_VIEW) &&
|
||||
(strcmp (pspec->name, "hadjustment") == 0 ||
|
||||
strcmp (pspec->name, "vadjustment") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_VIEWPORT) &&
|
||||
(strcmp (pspec->name, "hadjustment") == 0 ||
|
||||
strcmp (pspec->name, "vadjustment") == 0))
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_WIDGET) &&
|
||||
(strcmp (pspec->name, "name") == 0 ||
|
||||
strcmp (pspec->name, "screen") == 0 ||
|
||||
strcmp (pspec->name, "style") == 0))
|
||||
continue;
|
||||
|
||||
/* resize-grip-visible is determined at runtime */
|
||||
if (g_type_is_a (type, GTK_TYPE_WINDOW) &&
|
||||
(strcmp (pspec->name, "resize-grip-visible") == 0))
|
||||
continue;
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Property %s.%s\n",
|
||||
g_type_name (pspec->owner_type),
|
||||
pspec->name);
|
||||
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
g_object_get_property (instance, pspec->name, &value);
|
||||
check_property ("Property", pspec, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
g_free (pspecs);
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_WIDGET))
|
||||
{
|
||||
pspecs = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (klass), &n_pspecs);
|
||||
|
||||
for (i = 0; i < n_pspecs; ++i)
|
||||
{
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
if (pspec->owner_type != type)
|
||||
continue;
|
||||
|
||||
if ((pspec->flags & G_PARAM_READABLE) == 0)
|
||||
continue;
|
||||
|
||||
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
gtk_widget_style_get_property (GTK_WIDGET (instance), pspec->name, &value);
|
||||
check_property ("Style property", pspec, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
g_free (pspecs);
|
||||
}
|
||||
|
||||
if (g_type_is_a (type, GDK_TYPE_WINDOW))
|
||||
gdk_window_destroy (GDK_WINDOW (instance));
|
||||
else
|
||||
g_object_unref (instance);
|
||||
|
||||
g_type_class_unref (klass);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const GType *otypes;
|
||||
guint i;
|
||||
|
||||
gtk_test_init (&argc, &argv);
|
||||
gtk_test_register_all_types();
|
||||
|
||||
otypes = gtk_test_list_all_types (NULL);
|
||||
for (i = 0; otypes[i]; i++)
|
||||
{
|
||||
gchar *testname;
|
||||
|
||||
testname = g_strdup_printf ("/Default Values/%s",
|
||||
g_type_name (otypes[i]));
|
||||
g_test_add_data_func (testname,
|
||||
&otypes[i],
|
||||
test_type);
|
||||
g_free (testname);
|
||||
}
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
319
testsuite/gtk/entry.c
Normal file
319
testsuite/gtk/entry.c
Normal file
@ -0,0 +1,319 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static gint serial = 0;
|
||||
|
||||
typedef struct {
|
||||
gint serial;
|
||||
gint count;
|
||||
gint start;
|
||||
gint end;
|
||||
gchar *text;
|
||||
gchar *new_text;
|
||||
gint position;
|
||||
gint length;
|
||||
} EntryData;
|
||||
|
||||
static void
|
||||
notify (GtkEditable *editable, GParamSpec *pspec, EntryData *data)
|
||||
{
|
||||
data->serial = serial++;
|
||||
data->count++;
|
||||
data->text = gtk_editable_get_chars (editable, 0, -1);
|
||||
gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
|
||||
|
||||
#if 0
|
||||
g_print ("notify::%s\n", pspec->name);
|
||||
g_print ("\ttext: %s\n", data->text);
|
||||
g_print ("\tstart: %d\n", data->start);
|
||||
g_print ("\tend: %d\n", data->end);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
insert_text (GtkEditable *editable,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position,
|
||||
EntryData *data)
|
||||
{
|
||||
data->serial = serial++;
|
||||
data->count++;
|
||||
data->text = gtk_editable_get_chars (editable, 0, -1);
|
||||
gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
|
||||
data->new_text = g_strdup (new_text);
|
||||
data->position = *position;
|
||||
data->length = new_text_length;
|
||||
|
||||
#if 0
|
||||
g_print ("insert-text \"%s\", %d\n", new_text, *position);
|
||||
g_print ("\ttext: %s\n", data->text);
|
||||
g_print ("\tstart: %d\n", data->start);
|
||||
g_print ("\tend: %d\n", data->end);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
delete_text (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos,
|
||||
EntryData *data)
|
||||
{
|
||||
data->serial = serial++;
|
||||
data->count++;
|
||||
data->text = gtk_editable_get_chars (editable, 0, -1);
|
||||
gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
|
||||
data->position = start_pos;
|
||||
data->length = end_pos - start_pos;
|
||||
|
||||
#if 0
|
||||
g_print ("delete-text %d %d\n", start_pos, end_pos);
|
||||
g_print ("\ttext: %s\n", data->text);
|
||||
g_print ("\tstart: %d\n", data->start);
|
||||
g_print ("\tend: %d\n", data->end);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
changed (GtkEditable *editable,
|
||||
EntryData *data)
|
||||
{
|
||||
data->serial = serial++;
|
||||
data->count++;
|
||||
data->text = gtk_editable_get_chars (editable, 0, -1);
|
||||
gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
|
||||
|
||||
#if 0
|
||||
g_print ("changed\n");
|
||||
g_print ("\ttext: %s\n", data->text);
|
||||
g_print ("\tstart: %d\n", data->start);
|
||||
g_print ("\tend: %d\n", data->end);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
test_insert (void)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
gint pos;
|
||||
EntryData data1;
|
||||
EntryData data2;
|
||||
EntryData data3;
|
||||
EntryData data4;
|
||||
EntryData data5;
|
||||
EntryData data6;
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
g_object_ref_sink (entry);
|
||||
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), "bar");
|
||||
gtk_editable_set_position (GTK_EDITABLE (entry), -1);
|
||||
pos = gtk_editable_get_position (GTK_EDITABLE (entry));
|
||||
g_assert_cmpint (pos, ==, 3);
|
||||
|
||||
data1.count = 0;
|
||||
data2.count = 0;
|
||||
data3.count = 0;
|
||||
data4.count = 0;
|
||||
data5.count = 0;
|
||||
data6.count = 0;
|
||||
g_signal_connect (entry, "notify::cursor-position",
|
||||
G_CALLBACK (notify), &data1);
|
||||
g_signal_connect (entry, "notify::selection-bound",
|
||||
G_CALLBACK (notify), &data2);
|
||||
g_signal_connect (entry, "notify::text",
|
||||
G_CALLBACK (notify), &data3);
|
||||
g_signal_connect (entry, "insert-text",
|
||||
G_CALLBACK (insert_text), &data4);
|
||||
g_signal_connect (entry, "delete-text",
|
||||
G_CALLBACK (delete_text), &data5);
|
||||
g_signal_connect (entry, "changed",
|
||||
G_CALLBACK (changed), &data6);
|
||||
|
||||
pos = 0;
|
||||
gtk_editable_insert_text (GTK_EDITABLE (entry), "foo", -1, &pos);
|
||||
g_assert_cmpint (pos, ==, 3);
|
||||
|
||||
pos = gtk_editable_get_position (GTK_EDITABLE (entry));
|
||||
g_assert_cmpint (pos, ==, 6);
|
||||
|
||||
/* Check that notification for ::text, ::cursor-position and
|
||||
* ::selection-bound happens in a consistent state after the
|
||||
* change.
|
||||
*/
|
||||
g_assert_cmpint (data1.count, ==, 1);
|
||||
g_assert_cmpint (data1.start, ==, 6);
|
||||
g_assert_cmpint (data1.end, ==, 6);
|
||||
g_assert_cmpstr (data1.text, ==, "foobar");
|
||||
g_free (data1.text);
|
||||
|
||||
g_assert_cmpint (data2.count, ==, 1);
|
||||
g_assert_cmpint (data2.start, ==, 6);
|
||||
g_assert_cmpint (data2.end, ==, 6);
|
||||
g_assert_cmpstr (data2.text, ==, "foobar");
|
||||
g_free (data2.text);
|
||||
|
||||
g_assert_cmpint (data3.count, ==, 1);
|
||||
g_assert_cmpint (data3.start, ==, 6);
|
||||
g_assert_cmpint (data3.end, ==, 6);
|
||||
g_assert_cmpstr (data3.text, ==, "foobar");
|
||||
g_free (data3.text);
|
||||
|
||||
/* Check that ::insert-text sees the state _before_ the insertion */
|
||||
g_assert_cmpint (data4.count, ==, 1);
|
||||
g_assert_cmpint (data4.start, ==, 3);
|
||||
g_assert_cmpint (data4.end, ==, 3);
|
||||
g_assert_cmpstr (data4.text, ==, "bar");
|
||||
g_assert_cmpint (data4.position, ==, 0);
|
||||
g_assert_cmpint (data4.length, ==, 3);
|
||||
g_assert_cmpstr (data4.new_text, ==, "foo");
|
||||
g_free (data4.text);
|
||||
g_free (data4.new_text);
|
||||
|
||||
/* no deletion here */
|
||||
g_assert_cmpint (data5.count, ==, 0);
|
||||
|
||||
/* Check that ::changed sees the post-change state */
|
||||
g_assert_cmpint (data6.count, ==, 1);
|
||||
g_assert_cmpint (data6.start, ==, 6);
|
||||
g_assert_cmpint (data6.end, ==, 6);
|
||||
g_assert_cmpstr (data6.text, ==, "foobar");
|
||||
g_free (data6.text);
|
||||
|
||||
/* Now check ordering: ::insert-text comes before ::notify */
|
||||
g_assert_cmpint (data4.serial, <, data1.serial);
|
||||
g_assert_cmpint (data4.serial, <, data2.serial);
|
||||
g_assert_cmpint (data4.serial, <, data3.serial);
|
||||
|
||||
/* ... and ::changed comes after ::notify */
|
||||
g_assert_cmpint (data6.serial, >, data1.serial);
|
||||
g_assert_cmpint (data6.serial, >, data2.serial);
|
||||
g_assert_cmpint (data6.serial, >, data3.serial);
|
||||
|
||||
g_object_unref (entry);
|
||||
}
|
||||
|
||||
static void
|
||||
test_delete (void)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
gint pos;
|
||||
EntryData data1;
|
||||
EntryData data2;
|
||||
EntryData data3;
|
||||
EntryData data4;
|
||||
EntryData data5;
|
||||
EntryData data6;
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
g_object_ref_sink (entry);
|
||||
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), "foobar");
|
||||
gtk_editable_set_position (GTK_EDITABLE (entry), -1);
|
||||
pos = gtk_editable_get_position (GTK_EDITABLE (entry));
|
||||
g_assert_cmpint (pos, ==, 6);
|
||||
|
||||
data1.count = 0;
|
||||
data2.count = 0;
|
||||
data3.count = 0;
|
||||
data4.count = 0;
|
||||
data5.count = 0;
|
||||
data6.count = 0;
|
||||
g_signal_connect (entry, "notify::cursor-position",
|
||||
G_CALLBACK (notify), &data1);
|
||||
g_signal_connect (entry, "notify::selection-bound",
|
||||
G_CALLBACK (notify), &data2);
|
||||
g_signal_connect (entry, "notify::text",
|
||||
G_CALLBACK (notify), &data3);
|
||||
g_signal_connect (entry, "insert-text",
|
||||
G_CALLBACK (insert_text), &data4);
|
||||
g_signal_connect (entry, "delete-text",
|
||||
G_CALLBACK (delete_text), &data5);
|
||||
g_signal_connect (entry, "changed",
|
||||
G_CALLBACK (changed), &data6);
|
||||
|
||||
gtk_editable_delete_text (GTK_EDITABLE (entry), 0, 3);
|
||||
|
||||
pos = gtk_editable_get_position (GTK_EDITABLE (entry));
|
||||
g_assert_cmpint (pos, ==, 3);
|
||||
|
||||
/* Check that notification for ::text, ::cursor-position and
|
||||
* ::selection-bound happens in a consistent state after the
|
||||
* change.
|
||||
*/
|
||||
g_assert_cmpint (data1.count, ==, 1);
|
||||
g_assert_cmpint (data1.start, ==, 3);
|
||||
g_assert_cmpint (data1.end, ==, 3);
|
||||
g_assert_cmpstr (data1.text, ==, "bar");
|
||||
g_free (data1.text);
|
||||
|
||||
g_assert_cmpint (data2.count, ==, 1);
|
||||
g_assert_cmpint (data2.start, ==, 3);
|
||||
g_assert_cmpint (data2.end, ==, 3);
|
||||
g_assert_cmpstr (data2.text, ==, "bar");
|
||||
g_free (data2.text);
|
||||
|
||||
g_assert_cmpint (data3.count, ==, 1);
|
||||
g_assert_cmpint (data3.start, ==, 3);
|
||||
g_assert_cmpint (data3.end, ==, 3);
|
||||
g_assert_cmpstr (data3.text, ==, "bar");
|
||||
g_free (data3.text);
|
||||
|
||||
/* no insertion here */
|
||||
g_assert_cmpint (data4.count, ==, 0);
|
||||
|
||||
/* Check that ::delete-text sees the state _before_ the insertion */
|
||||
g_assert_cmpint (data5.count, ==, 1);
|
||||
g_assert_cmpint (data5.start, ==, 6);
|
||||
g_assert_cmpint (data5.end, ==, 6);
|
||||
g_assert_cmpstr (data5.text, ==, "foobar");
|
||||
g_assert_cmpint (data5.position, ==, 0);
|
||||
g_assert_cmpint (data5.length, ==, 3);
|
||||
g_free (data5.text);
|
||||
|
||||
/* Check that ::changed sees the post-change state */
|
||||
g_assert_cmpint (data6.count, ==, 1);
|
||||
g_assert_cmpint (data6.start, ==, 3);
|
||||
g_assert_cmpint (data6.end, ==, 3);
|
||||
g_assert_cmpstr (data6.text, ==, "bar");
|
||||
g_free (data6.text);
|
||||
|
||||
/* Now check ordering: ::delete-text comes before ::notify */
|
||||
g_assert_cmpint (data5.serial, <, data1.serial);
|
||||
g_assert_cmpint (data5.serial, <, data2.serial);
|
||||
g_assert_cmpint (data5.serial, <, data3.serial);
|
||||
|
||||
/* ... and ::changed comes after ::notify */
|
||||
g_assert_cmpint (data6.serial, >, data1.serial);
|
||||
g_assert_cmpint (data6.serial, >, data2.serial);
|
||||
g_assert_cmpint (data6.serial, >, data3.serial);
|
||||
g_object_unref (entry);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/entry/delete", test_delete);
|
||||
g_test_add_func ("/entry/insert", test_insert);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
92
testsuite/gtk/expander.c
Normal file
92
testsuite/gtk/expander.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_click_expander (void)
|
||||
{
|
||||
GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on expander");
|
||||
GtkWidget *expander = gtk_expander_new ("Test Expander");
|
||||
GtkWidget *label = gtk_label_new ("Test Label");
|
||||
gboolean expanded;
|
||||
gboolean simsuccess;
|
||||
gtk_container_add (GTK_CONTAINER (expander), label);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (window))), expander);
|
||||
gtk_widget_show (expander);
|
||||
gtk_widget_show (label);
|
||||
gtk_widget_show_now (window);
|
||||
/* check initial expander state */
|
||||
expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
|
||||
g_assert (!expanded);
|
||||
/* check expanding */
|
||||
simsuccess = gtk_test_widget_click (expander, 1, 0);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
|
||||
gtk_main_iteration ();
|
||||
expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
|
||||
g_assert (expanded);
|
||||
/* check collapsing */
|
||||
simsuccess = gtk_test_widget_click (expander, 1, 0);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
|
||||
gtk_main_iteration ();
|
||||
expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
|
||||
g_assert (!expanded);
|
||||
}
|
||||
|
||||
static void
|
||||
test_click_content_widget (void)
|
||||
{
|
||||
GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on content widget");
|
||||
GtkWidget *expander = gtk_expander_new ("Test Expander");
|
||||
GtkWidget *entry = gtk_entry_new ();
|
||||
gboolean expanded;
|
||||
gboolean simsuccess;
|
||||
gtk_container_add (GTK_CONTAINER (expander), entry);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (window))), expander);
|
||||
gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
|
||||
gtk_widget_show (expander);
|
||||
gtk_widget_show (entry);
|
||||
gtk_widget_show_now (window);
|
||||
|
||||
/* check click on content with expander open */
|
||||
expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
|
||||
g_assert (expanded);
|
||||
simsuccess = gtk_test_widget_click (entry, 1, 0);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
|
||||
gtk_main_iteration ();
|
||||
expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
|
||||
g_assert (expanded);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
g_test_add_func ("/expander/click-expander", test_click_expander);
|
||||
g_test_add_func ("/expander/click-content-widget", test_click_content_widget);
|
||||
return g_test_run();
|
||||
}
|
||||
0
testsuite/gtk/file-chooser-test-dir/empty
Normal file
0
testsuite/gtk/file-chooser-test-dir/empty
Normal file
1
testsuite/gtk/file-chooser-test-dir/text.txt
Normal file
1
testsuite/gtk/file-chooser-test-dir/text.txt
Normal file
@ -0,0 +1 @@
|
||||
Hello world!
|
||||
2492
testsuite/gtk/filechooser.c
Normal file
2492
testsuite/gtk/filechooser.c
Normal file
File diff suppressed because it is too large
Load Diff
7147
testsuite/gtk/filtermodel.c
Normal file
7147
testsuite/gtk/filtermodel.c
Normal file
File diff suppressed because it is too large
Load Diff
55
testsuite/gtk/floating.c
Normal file
55
testsuite/gtk/floating.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* floatingtest.c - test floating flag uses
|
||||
* Copyright (C) 2005 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static gboolean destroyed = FALSE;
|
||||
static void
|
||||
destroy (void)
|
||||
{
|
||||
destroyed = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
floating_tests (void)
|
||||
{
|
||||
GtkWidget *widget = g_object_new (GTK_TYPE_LABEL, NULL);
|
||||
g_object_connect (widget, "signal::destroy", destroy, NULL, NULL);
|
||||
|
||||
g_assert (g_object_is_floating (widget));
|
||||
|
||||
g_object_ref_sink (widget);
|
||||
g_assert (!g_object_is_floating (widget));
|
||||
|
||||
g_object_force_floating (G_OBJECT (widget));
|
||||
g_assert (g_object_is_floating (widget));
|
||||
|
||||
g_object_ref_sink (widget);
|
||||
g_assert (!g_object_is_floating (widget));
|
||||
|
||||
g_assert (!destroyed);
|
||||
g_object_unref (widget);
|
||||
g_assert (destroyed);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
g_test_add_func ("/floatingtest", floating_tests);
|
||||
return g_test_run();
|
||||
}
|
||||
236
testsuite/gtk/grid.c
Normal file
236
testsuite/gtk/grid.c
Normal file
@ -0,0 +1,236 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* test that attach_next_to picks the places
|
||||
* we expect it to pick, when there is any choice
|
||||
*/
|
||||
static void
|
||||
test_attach (void)
|
||||
{
|
||||
GtkGrid *g;
|
||||
GtkWidget *child, *sibling, *z, *A, *B;
|
||||
gint left, top, width, height;
|
||||
|
||||
g = (GtkGrid *)gtk_grid_new ();
|
||||
|
||||
child = gtk_label_new ("a");
|
||||
gtk_grid_attach_next_to (g, child, NULL, GTK_POS_LEFT, 1, 1);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, -1);
|
||||
g_assert_cmpint (top, ==, 0);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
|
||||
sibling = child;
|
||||
child = gtk_label_new ("b");
|
||||
gtk_grid_attach_next_to (g, child, sibling, GTK_POS_RIGHT, 2, 2);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 0);
|
||||
g_assert_cmpint (top, ==, 0);
|
||||
g_assert_cmpint (width, ==, 2);
|
||||
g_assert_cmpint (height, ==, 2);
|
||||
|
||||
/* this one should just be ignored */
|
||||
z = gtk_label_new ("z");
|
||||
gtk_grid_attach (g, z, 4, 4, 1, 1);
|
||||
|
||||
child = gtk_label_new ("c");
|
||||
gtk_grid_attach_next_to (g, child, sibling, GTK_POS_BOTTOM, 3, 1);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, -1);
|
||||
g_assert_cmpint (top, ==, 1);
|
||||
g_assert_cmpint (width, ==, 3);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
|
||||
child = gtk_label_new ("u");
|
||||
gtk_grid_attach_next_to (g, child, z, GTK_POS_LEFT, 2, 1);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 2);
|
||||
g_assert_cmpint (top, ==, 4);
|
||||
g_assert_cmpint (width, ==, 2);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
|
||||
child = gtk_label_new ("v");
|
||||
gtk_grid_attach_next_to (g, child, z, GTK_POS_RIGHT, 2, 1);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 5);
|
||||
g_assert_cmpint (top, ==, 4);
|
||||
g_assert_cmpint (width, ==, 2);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
|
||||
child = gtk_label_new ("x");
|
||||
gtk_grid_attach_next_to (g, child, z, GTK_POS_TOP, 1, 2);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 4);
|
||||
g_assert_cmpint (top, ==, 2);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 2);
|
||||
|
||||
child = gtk_label_new ("x");
|
||||
gtk_grid_attach_next_to (g, child, z, GTK_POS_TOP, 1, 2);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 4);
|
||||
g_assert_cmpint (top, ==, 2);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 2);
|
||||
|
||||
child = gtk_label_new ("y");
|
||||
gtk_grid_attach_next_to (g, child, z, GTK_POS_BOTTOM, 1, 2);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 4);
|
||||
g_assert_cmpint (top, ==, 5);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 2);
|
||||
|
||||
A = gtk_label_new ("A");
|
||||
gtk_grid_attach (g, A, 10, 10, 1, 1);
|
||||
B = gtk_label_new ("B");
|
||||
gtk_grid_attach (g, B, 10, 12, 1, 1);
|
||||
|
||||
child = gtk_label_new ("D");
|
||||
gtk_grid_attach_next_to (g, child, A, GTK_POS_RIGHT, 1, 3);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 11);
|
||||
g_assert_cmpint (top, ==, 10);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
test_add (void)
|
||||
{
|
||||
GtkGrid *g;
|
||||
GtkWidget *child;
|
||||
gint left, top, width, height;
|
||||
|
||||
g = (GtkGrid *)gtk_grid_new ();
|
||||
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (g), GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
child = gtk_label_new ("a");
|
||||
gtk_container_add (GTK_CONTAINER (g), child);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 0);
|
||||
g_assert_cmpint (top, ==, 0);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
|
||||
child = gtk_label_new ("b");
|
||||
gtk_container_add (GTK_CONTAINER (g), child);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 1);
|
||||
g_assert_cmpint (top, ==, 0);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
|
||||
child = gtk_label_new ("c");
|
||||
gtk_container_add (GTK_CONTAINER (g), child);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 2);
|
||||
g_assert_cmpint (top, ==, 0);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (g), GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
child = gtk_label_new ("d");
|
||||
gtk_container_add (GTK_CONTAINER (g), child);
|
||||
gtk_container_child_get (GTK_CONTAINER (g), child,
|
||||
"left-attach", &left,
|
||||
"top-attach", &top,
|
||||
"width", &width,
|
||||
"height", &height,
|
||||
NULL);
|
||||
g_assert_cmpint (left, ==, 0);
|
||||
g_assert_cmpint (top, ==, 1);
|
||||
g_assert_cmpint (width, ==, 1);
|
||||
g_assert_cmpint (height, ==, 1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/grid/attach", test_attach);
|
||||
g_test_add_func ("/grid/add", test_add);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
452
testsuite/gtk/gtkmenu.c
Normal file
452
testsuite/gtk/gtkmenu.c
Normal file
@ -0,0 +1,452 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* TestItem {{{1 */
|
||||
|
||||
/* This utility struct is used by both the RandomMenu and MirrorMenu
|
||||
* class implementations below.
|
||||
*/
|
||||
typedef struct {
|
||||
GHashTable *attributes;
|
||||
GHashTable *links;
|
||||
} TestItem;
|
||||
|
||||
static TestItem *
|
||||
test_item_new (GHashTable *attributes,
|
||||
GHashTable *links)
|
||||
{
|
||||
TestItem *item;
|
||||
|
||||
item = g_slice_new (TestItem);
|
||||
item->attributes = g_hash_table_ref (attributes);
|
||||
item->links = g_hash_table_ref (links);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static void
|
||||
test_item_free (gpointer data)
|
||||
{
|
||||
TestItem *item = data;
|
||||
|
||||
g_hash_table_unref (item->attributes);
|
||||
g_hash_table_unref (item->links);
|
||||
|
||||
g_slice_free (TestItem, item);
|
||||
}
|
||||
|
||||
/* RandomMenu {{{1 */
|
||||
#define MAX_ITEMS 10
|
||||
#define TOP_ORDER 4
|
||||
|
||||
typedef struct {
|
||||
GMenuModel parent_instance;
|
||||
|
||||
GSequence *items;
|
||||
gint order;
|
||||
} RandomMenu;
|
||||
|
||||
typedef GMenuModelClass RandomMenuClass;
|
||||
|
||||
static GType random_menu_get_type (void);
|
||||
G_DEFINE_TYPE (RandomMenu, random_menu, G_TYPE_MENU_MODEL);
|
||||
|
||||
static gboolean
|
||||
random_menu_is_mutable (GMenuModel *model)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
random_menu_get_n_items (GMenuModel *model)
|
||||
{
|
||||
RandomMenu *menu = (RandomMenu *) model;
|
||||
|
||||
return g_sequence_get_length (menu->items);
|
||||
}
|
||||
|
||||
static void
|
||||
random_menu_get_item_attributes (GMenuModel *model,
|
||||
gint position,
|
||||
GHashTable **table)
|
||||
{
|
||||
RandomMenu *menu = (RandomMenu *) model;
|
||||
TestItem *item;
|
||||
|
||||
item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
|
||||
*table = g_hash_table_ref (item->attributes);
|
||||
}
|
||||
|
||||
static void
|
||||
random_menu_get_item_links (GMenuModel *model,
|
||||
gint position,
|
||||
GHashTable **table)
|
||||
{
|
||||
RandomMenu *menu = (RandomMenu *) model;
|
||||
TestItem *item;
|
||||
|
||||
item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
|
||||
*table = g_hash_table_ref (item->links);
|
||||
}
|
||||
|
||||
static void
|
||||
random_menu_finalize (GObject *object)
|
||||
{
|
||||
RandomMenu *menu = (RandomMenu *) object;
|
||||
|
||||
g_sequence_free (menu->items);
|
||||
|
||||
G_OBJECT_CLASS (random_menu_parent_class)
|
||||
->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
random_menu_init (RandomMenu *menu)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
random_menu_class_init (GMenuModelClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
class->is_mutable = random_menu_is_mutable;
|
||||
class->get_n_items = random_menu_get_n_items;
|
||||
class->get_item_attributes = random_menu_get_item_attributes;
|
||||
class->get_item_links = random_menu_get_item_links;
|
||||
|
||||
object_class->finalize = random_menu_finalize;
|
||||
}
|
||||
|
||||
static RandomMenu * random_menu_new (GRand *rand, gint order);
|
||||
|
||||
static void
|
||||
random_menu_change (RandomMenu *menu,
|
||||
GRand *rand)
|
||||
{
|
||||
gint position, removes, adds;
|
||||
GSequenceIter *point;
|
||||
gint n_items;
|
||||
gint i;
|
||||
|
||||
n_items = g_sequence_get_length (menu->items);
|
||||
|
||||
do
|
||||
{
|
||||
position = g_rand_int_range (rand, 0, n_items + 1);
|
||||
removes = g_rand_int_range (rand, 0, n_items - position + 1);
|
||||
adds = g_rand_int_range (rand, 0, MAX_ITEMS - (n_items - removes) + 1);
|
||||
}
|
||||
while (removes == 0 && adds == 0);
|
||||
|
||||
point = g_sequence_get_iter_at_pos (menu->items, position + removes);
|
||||
|
||||
if (removes)
|
||||
{
|
||||
GSequenceIter *start;
|
||||
|
||||
start = g_sequence_get_iter_at_pos (menu->items, position);
|
||||
g_sequence_remove_range (start, point);
|
||||
}
|
||||
|
||||
for (i = 0; i < adds; i++)
|
||||
{
|
||||
const gchar *label;
|
||||
GHashTable *links;
|
||||
GHashTable *attributes;
|
||||
|
||||
attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
|
||||
links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
|
||||
|
||||
if (menu->order > 0 && g_rand_boolean (rand))
|
||||
{
|
||||
RandomMenu *child;
|
||||
const gchar *subtype;
|
||||
|
||||
child = random_menu_new (rand, menu->order - 1);
|
||||
|
||||
if (g_rand_boolean (rand))
|
||||
{
|
||||
subtype = G_MENU_LINK_SECTION;
|
||||
/* label some section headers */
|
||||
if (g_rand_boolean (rand))
|
||||
label = "Section";
|
||||
else
|
||||
label = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* label all submenus */
|
||||
subtype = G_MENU_LINK_SUBMENU;
|
||||
label = "Submenu";
|
||||
}
|
||||
|
||||
g_hash_table_insert (links, g_strdup (subtype), child);
|
||||
}
|
||||
else
|
||||
/* label all terminals */
|
||||
label = "Menu Item";
|
||||
|
||||
if (label)
|
||||
g_hash_table_insert (attributes, g_strdup ("label"), g_variant_ref_sink (g_variant_new_string (label)));
|
||||
|
||||
g_sequence_insert_before (point, test_item_new (attributes, links));
|
||||
g_hash_table_unref (links);
|
||||
g_hash_table_unref (attributes);
|
||||
}
|
||||
|
||||
g_menu_model_items_changed (G_MENU_MODEL (menu), position, removes, adds);
|
||||
}
|
||||
|
||||
static RandomMenu *
|
||||
random_menu_new (GRand *rand,
|
||||
gint order)
|
||||
{
|
||||
RandomMenu *menu;
|
||||
|
||||
menu = g_object_new (random_menu_get_type (), NULL);
|
||||
menu->items = g_sequence_new (test_item_free);
|
||||
menu->order = order;
|
||||
|
||||
random_menu_change (menu, rand);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
/* Test cases {{{1 */
|
||||
|
||||
static void assert_menu_equality (GtkContainer *container, GMenuModel *model);
|
||||
|
||||
static const gchar *
|
||||
get_label (GtkMenuItem *item)
|
||||
{
|
||||
GList *children = gtk_container_get_children (GTK_CONTAINER (item));
|
||||
const gchar *label = NULL;
|
||||
|
||||
while (children)
|
||||
{
|
||||
if (GTK_IS_CONTAINER (children->data))
|
||||
children = g_list_concat (children, gtk_container_get_children (children->data));
|
||||
else if (GTK_IS_LABEL (children->data))
|
||||
label = gtk_label_get_text (children->data);
|
||||
|
||||
children = g_list_delete_link (children, children);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/* a bit complicated with the separators...
|
||||
*
|
||||
* with_separators are if subsections of this GMenuModel should have
|
||||
* separators inserted between them (ie: in the same sense as the
|
||||
* 'with_separators' argument to gtk_menu_shell_bind_model().
|
||||
*
|
||||
* needs_separator is true if this particular section needs to have a
|
||||
* separator before it in the case that it is non-empty. this will be
|
||||
* defined for all subsections of a with_separators menu (except the
|
||||
* first) or in case section_header is non-%NULL.
|
||||
*
|
||||
* section_header is the label that must be inside that separator, if it
|
||||
* exists. section_header is only non-%NULL if needs_separator is also
|
||||
* TRUE.
|
||||
*/
|
||||
static void
|
||||
assert_section_equality (GSList **children,
|
||||
gboolean with_separators,
|
||||
gboolean needs_separator,
|
||||
const gchar *section_header,
|
||||
GMenuModel *model)
|
||||
{
|
||||
gboolean has_separator;
|
||||
GSList *our_children;
|
||||
gint i, n;
|
||||
|
||||
/* Assuming that we have the possibility of showing a separator, there
|
||||
* are two valid situations:
|
||||
*
|
||||
* - we have a separator and we have other children
|
||||
*
|
||||
* - we have no separator and no children
|
||||
*
|
||||
* If we see a separator, we suppose that it is ours and that we will
|
||||
* encounter children. In the case that we have no children, the
|
||||
* separator may not be ours but may rather belong to a later section.
|
||||
*
|
||||
* We therefore keep our own copy of the children GSList. If we
|
||||
* encounter children, we will delete the links that this section is
|
||||
* responsible for and update the pass-by-reference value. Otherwise,
|
||||
* we will leave everything alone and let the separator be accounted
|
||||
* for by a following section.
|
||||
*/
|
||||
our_children = *children;
|
||||
if (needs_separator && GTK_IS_SEPARATOR_MENU_ITEM (our_children->data))
|
||||
{
|
||||
/* We accounted for the separator, at least for now, so remove it
|
||||
* from the list.
|
||||
*
|
||||
* We will check later if we should have actually had a separator
|
||||
* and compare the result to has_separator.
|
||||
*/
|
||||
our_children = our_children->next;
|
||||
has_separator = TRUE;
|
||||
}
|
||||
else
|
||||
has_separator = FALSE;
|
||||
|
||||
/* Now, iterate the model checking that the items in the GSList line
|
||||
* up with our expectations. */
|
||||
n = g_menu_model_get_n_items (model);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
GMenuModel *subsection;
|
||||
GMenuModel *submenu;
|
||||
gchar *label = NULL;
|
||||
|
||||
subsection = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
|
||||
submenu = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
|
||||
g_menu_model_get_item_attribute (model, i, G_MENU_ATTRIBUTE_LABEL, "s", &label);
|
||||
|
||||
if (subsection)
|
||||
{
|
||||
g_assert (!submenu);
|
||||
assert_section_equality (&our_children,
|
||||
FALSE, /* with_separators */
|
||||
label || (with_separators && i > 0), /* needs_separator */
|
||||
label, /* section_header */
|
||||
subsection);
|
||||
g_object_unref (subsection);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWidget *submenu_widget;
|
||||
GtkMenuItem *item;
|
||||
|
||||
/* This is a normal item. Make sure the label is right. */
|
||||
item = our_children->data;
|
||||
our_children = g_slist_remove (our_children, item);
|
||||
|
||||
/* get_label() returns "" when it ought to return NULL */
|
||||
g_assert_cmpstr (get_label (item), ==, label ? label : "");
|
||||
submenu_widget = gtk_menu_item_get_submenu (item);
|
||||
|
||||
if (submenu)
|
||||
{
|
||||
g_assert (submenu_widget != NULL);
|
||||
assert_menu_equality (GTK_CONTAINER (submenu_widget), submenu);
|
||||
g_object_unref (submenu);
|
||||
}
|
||||
else
|
||||
g_assert (!submenu_widget);
|
||||
}
|
||||
|
||||
g_free (label);
|
||||
}
|
||||
|
||||
/* If we found a separator but visited no children then the separator
|
||||
* was not for us. Patch that up.
|
||||
*/
|
||||
if (has_separator && our_children == (*children)->next)
|
||||
{
|
||||
/* Rewind our_children to put the separator we tentatively
|
||||
* consumed back into the list.
|
||||
*/
|
||||
our_children = *children;
|
||||
has_separator = FALSE;
|
||||
}
|
||||
|
||||
if (our_children == *children)
|
||||
/* If we had no children then we didn't really need a separator. */
|
||||
needs_separator = FALSE;
|
||||
|
||||
g_assert (needs_separator == has_separator);
|
||||
|
||||
if (has_separator)
|
||||
{
|
||||
GtkWidget *contents;
|
||||
const gchar *label;
|
||||
|
||||
/* We needed and had a separator and we visited a child.
|
||||
*
|
||||
* Make sure that separator was valid.
|
||||
*/
|
||||
contents = gtk_bin_get_child ((*children)->data);
|
||||
if (GTK_IS_LABEL (contents))
|
||||
label = gtk_label_get_label (GTK_LABEL (contents));
|
||||
else
|
||||
label = "";
|
||||
|
||||
/* get_label() returns "" when it ought to return NULL */
|
||||
g_assert_cmpstr (label, ==, section_header ? section_header : "");
|
||||
|
||||
/* our_children has already gone (possibly far) past *children, so
|
||||
* we need to free up the link that we left behind for the
|
||||
* separator in case we wanted to rewind.
|
||||
*/
|
||||
g_slist_free_1 (*children);
|
||||
}
|
||||
|
||||
*children = our_children;
|
||||
}
|
||||
|
||||
/* We want to use a GSList here instead of a GList because the ->prev
|
||||
* pointer updates cause trouble with the way we speculatively deal with
|
||||
* separators by skipping over them and coming back to clean up later.
|
||||
*/
|
||||
static void
|
||||
get_children_into_slist (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSList **list_ptr = user_data;
|
||||
|
||||
*list_ptr = g_slist_prepend (*list_ptr, widget);
|
||||
}
|
||||
|
||||
static void
|
||||
assert_menu_equality (GtkContainer *container,
|
||||
GMenuModel *model)
|
||||
{
|
||||
GSList *children = NULL;
|
||||
|
||||
gtk_container_foreach (container, get_children_into_slist, &children);
|
||||
children = g_slist_reverse (children);
|
||||
|
||||
assert_section_equality (&children, TRUE, FALSE, NULL, model);
|
||||
g_assert (children == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_bind_menu (void)
|
||||
{
|
||||
RandomMenu *model;
|
||||
GtkWidget *menu;
|
||||
GRand *rand;
|
||||
gint i;
|
||||
|
||||
gtk_init (0, 0);
|
||||
|
||||
rand = g_rand_new_with_seed (g_test_rand_int ());
|
||||
model = random_menu_new (rand, TOP_ORDER);
|
||||
menu = gtk_menu_new_from_model (G_MENU_MODEL (model));
|
||||
g_object_ref_sink (menu);
|
||||
assert_menu_equality (GTK_CONTAINER (menu), G_MENU_MODEL (model));
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
random_menu_change (model, rand);
|
||||
while (g_main_context_iteration (NULL, FALSE));
|
||||
assert_menu_equality (GTK_CONTAINER (menu), G_MENU_MODEL (model));
|
||||
}
|
||||
g_object_unref (model);
|
||||
g_object_unref (menu);
|
||||
g_rand_free (rand);
|
||||
}
|
||||
/* Epilogue {{{1 */
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/gmenu/bind", test_bind_menu);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
/* vim:set foldmethod=marker: */
|
||||
313
testsuite/gtk/gtktreemodelrefcount.c
Normal file
313
testsuite/gtk/gtktreemodelrefcount.c
Normal file
@ -0,0 +1,313 @@
|
||||
/* gtktreemodelrefcount.c
|
||||
* Copyright (C) 2011 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gtktreemodelrefcount.h"
|
||||
|
||||
|
||||
/* The purpose of this GtkTreeModel is to keep record of the reference count
|
||||
* of each node. The reference count does not effect the functioning of
|
||||
* the model in any way. Because this model is a subclass of GtkTreeStore,
|
||||
* the GtkTreeStore API should be used to add to and remove nodes from
|
||||
* this model. We depend on the iter format of GtkTreeStore, which means
|
||||
* that this model needs to be revised in case the iter format of
|
||||
* GtkTreeStore is modified. Currently, we make use of the fact that
|
||||
* the value stored in the user_data field is unique for each node.
|
||||
*/
|
||||
|
||||
struct _GtkTreeModelRefCountPrivate
|
||||
{
|
||||
GHashTable *node_hash;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ref_count;
|
||||
}
|
||||
NodeInfo;
|
||||
|
||||
|
||||
static void gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface);
|
||||
static void gtk_tree_model_ref_count_finalize (GObject *object);
|
||||
|
||||
static NodeInfo *node_info_new (void);
|
||||
static void node_info_free (NodeInfo *info);
|
||||
|
||||
/* GtkTreeModel interface */
|
||||
static void gtk_tree_model_ref_count_ref_node (GtkTreeModel *model,
|
||||
GtkTreeIter *iter);
|
||||
static void gtk_tree_model_ref_count_unref_node (GtkTreeModel *model,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkTreeModelRefCount, gtk_tree_model_ref_count, GTK_TYPE_TREE_STORE,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
|
||||
gtk_tree_model_ref_count_tree_model_init))
|
||||
|
||||
static void
|
||||
row_removed (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GtkTreeIter tree_iter;
|
||||
|
||||
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ref_model), &tree_iter))
|
||||
{
|
||||
g_hash_table_remove_all (ref_model->priv->node_hash);
|
||||
return;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, ref_model->priv->node_hash);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &tree_iter.user_data, NULL))
|
||||
{
|
||||
if (!gtk_tree_store_iter_is_valid (GTK_TREE_STORE (ref_model), &tree_iter))
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_ref_count_init (GtkTreeModelRefCount *ref_model)
|
||||
{
|
||||
ref_model->priv = G_TYPE_INSTANCE_GET_PRIVATE (ref_model,
|
||||
GTK_TYPE_TREE_MODEL_REF_COUNT,
|
||||
GtkTreeModelRefCountPrivate);
|
||||
|
||||
ref_model->priv->node_hash = g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify)node_info_free);
|
||||
|
||||
g_signal_connect (ref_model, "row-deleted", G_CALLBACK (row_removed), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_ref_count_class_init (GtkTreeModelRefCountClass *ref_model_class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
object_class = (GObjectClass *) ref_model_class;
|
||||
|
||||
object_class->finalize = gtk_tree_model_ref_count_finalize;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkTreeModelRefCountPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface)
|
||||
{
|
||||
iface->ref_node = gtk_tree_model_ref_count_ref_node;
|
||||
iface->unref_node = gtk_tree_model_ref_count_unref_node;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_ref_count_finalize (GObject *object)
|
||||
{
|
||||
GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (object);
|
||||
|
||||
if (ref_model->priv->node_hash)
|
||||
{
|
||||
g_hash_table_destroy (ref_model->priv->node_hash);
|
||||
ref_model->priv->node_hash = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_tree_model_ref_count_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static NodeInfo *
|
||||
node_info_new (void)
|
||||
{
|
||||
NodeInfo *info = g_slice_new (NodeInfo);
|
||||
info->ref_count = 0;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
node_info_free (NodeInfo *info)
|
||||
{
|
||||
g_slice_free (NodeInfo, info);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_ref_count_ref_node (GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
NodeInfo *info;
|
||||
GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
|
||||
if (!info)
|
||||
{
|
||||
info = node_info_new ();
|
||||
|
||||
g_hash_table_insert (ref_model->priv->node_hash, iter->user_data, info);
|
||||
}
|
||||
|
||||
info->ref_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_ref_count_unref_node (GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
NodeInfo *info;
|
||||
GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
|
||||
g_assert (info != NULL);
|
||||
g_assert (info->ref_count > 0);
|
||||
|
||||
info->ref_count--;
|
||||
}
|
||||
|
||||
|
||||
GtkTreeModel *
|
||||
gtk_tree_model_ref_count_new (void)
|
||||
{
|
||||
GtkTreeModel *retval;
|
||||
|
||||
retval = g_object_new (gtk_tree_model_ref_count_get_type (), NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_iter (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gchar *path_str;
|
||||
NodeInfo *info;
|
||||
GtkTreePath *path;
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (ref_model), iter);
|
||||
path_str = gtk_tree_path_to_string (path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
|
||||
if (!info)
|
||||
g_print ("%-16s ref_count=0\n", path_str);
|
||||
else
|
||||
g_print ("%-16s ref_count=%d\n", path_str, info->ref_count);
|
||||
|
||||
g_free (path_str);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_ref_count_dump_recurse (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
do
|
||||
{
|
||||
GtkTreeIter child;
|
||||
|
||||
dump_iter (ref_model, iter);
|
||||
|
||||
if (gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
|
||||
&child, iter))
|
||||
gtk_tree_model_ref_count_dump_recurse (ref_model, &child);
|
||||
}
|
||||
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), iter));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tree_model_ref_count_dump (GtkTreeModelRefCount *ref_model)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ref_model), &iter))
|
||||
return;
|
||||
|
||||
gtk_tree_model_ref_count_dump_recurse (ref_model, &iter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_iter (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *iter,
|
||||
gint expected_ref_count,
|
||||
gboolean may_assert)
|
||||
{
|
||||
NodeInfo *info;
|
||||
|
||||
if (may_assert)
|
||||
g_assert (gtk_tree_store_iter_is_valid (GTK_TREE_STORE (ref_model), iter));
|
||||
|
||||
info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
|
||||
if (!info)
|
||||
{
|
||||
if (expected_ref_count == 0)
|
||||
return TRUE;
|
||||
else
|
||||
{
|
||||
if (may_assert)
|
||||
g_error ("Expected ref count %d, but node has never been referenced.\n", expected_ref_count);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (may_assert)
|
||||
{
|
||||
if (expected_ref_count == 0)
|
||||
g_assert_cmpint (expected_ref_count, ==, info->ref_count);
|
||||
else
|
||||
g_assert_cmpint (expected_ref_count, <=, info->ref_count);
|
||||
}
|
||||
|
||||
return expected_ref_count == info->ref_count;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *parent,
|
||||
gint expected_ref_count,
|
||||
gboolean recurse,
|
||||
gboolean may_assert)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (!gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
|
||||
&iter, parent))
|
||||
return TRUE;
|
||||
|
||||
do
|
||||
{
|
||||
if (!check_iter (ref_model, &iter, expected_ref_count, may_assert))
|
||||
return FALSE;
|
||||
|
||||
if (recurse &&
|
||||
gtk_tree_model_iter_has_child (GTK_TREE_MODEL (ref_model), &iter))
|
||||
{
|
||||
if (!gtk_tree_model_ref_count_check_level (ref_model, &iter,
|
||||
expected_ref_count,
|
||||
recurse, may_assert))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), &iter));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_tree_model_ref_count_check_node (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *iter,
|
||||
gint expected_ref_count,
|
||||
gboolean may_assert)
|
||||
{
|
||||
return check_iter (ref_model, iter, expected_ref_count, may_assert);
|
||||
}
|
||||
132
testsuite/gtk/gtktreemodelrefcount.h
Normal file
132
testsuite/gtk/gtktreemodelrefcount.h
Normal file
@ -0,0 +1,132 @@
|
||||
/* gtktreemodelrefcount.h
|
||||
* Copyright (C) 2011 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_TREE_MODEL_REF_COUNT_H__
|
||||
#define __GTK_TREE_MODEL_REF_COUNT_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_TREE_MODEL_REF_COUNT (gtk_tree_model_ref_count_get_type ())
|
||||
#define GTK_TREE_MODEL_REF_COUNT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCount))
|
||||
#define GTK_TREE_MODEL_REF_COUNT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
|
||||
#define GTK_IS_TREE_MODEL_REF_COUNT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT))
|
||||
#define GTK_IS_TREE_MODEL_REF_COUNT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT))
|
||||
#define GTK_TREE_MODEL_REF_COUNT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
|
||||
|
||||
|
||||
typedef struct _GtkTreeModelRefCount GtkTreeModelRefCount;
|
||||
typedef struct _GtkTreeModelRefCountClass GtkTreeModelRefCountClass;
|
||||
typedef struct _GtkTreeModelRefCountPrivate GtkTreeModelRefCountPrivate;
|
||||
|
||||
struct _GtkTreeModelRefCount
|
||||
{
|
||||
GtkTreeStore parent;
|
||||
|
||||
/* < private > */
|
||||
GtkTreeModelRefCountPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkTreeModelRefCountClass
|
||||
{
|
||||
GtkTreeStoreClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gtk_tree_model_ref_count_get_type (void) G_GNUC_CONST;
|
||||
GtkTreeModel *gtk_tree_model_ref_count_new (void);
|
||||
|
||||
void gtk_tree_model_ref_count_dump (GtkTreeModelRefCount *ref_model);
|
||||
gboolean gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *parent,
|
||||
gint expected_ref_count,
|
||||
gboolean recurse,
|
||||
gboolean may_assert);
|
||||
gboolean gtk_tree_model_ref_count_check_node (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *iter,
|
||||
gint expected_ref_count,
|
||||
gboolean may_assert);
|
||||
|
||||
/* A couple of helpers for the tests. Since this model will never be used
|
||||
* outside of unit tests anyway, it is probably fine to have these here
|
||||
* without namespacing.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
assert_entire_model_unreferenced (GtkTreeModelRefCount *ref_model)
|
||||
{
|
||||
gtk_tree_model_ref_count_check_level (ref_model, NULL, 0, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
assert_root_level_unreferenced (GtkTreeModelRefCount *ref_model)
|
||||
{
|
||||
gtk_tree_model_ref_count_check_level (ref_model, NULL, 0, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
assert_level_unreferenced (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gtk_tree_model_ref_count_check_level (ref_model, iter, 0, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
assert_entire_model_referenced (GtkTreeModelRefCount *ref_model,
|
||||
gint ref_count)
|
||||
{
|
||||
gtk_tree_model_ref_count_check_level (ref_model, NULL, ref_count, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
assert_not_entire_model_referenced (GtkTreeModelRefCount *ref_model,
|
||||
gint ref_count)
|
||||
{
|
||||
g_assert_cmpint (gtk_tree_model_ref_count_check_level (ref_model, NULL,
|
||||
ref_count,
|
||||
TRUE, FALSE),
|
||||
==, FALSE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
assert_root_level_referenced (GtkTreeModelRefCount *ref_model,
|
||||
gint ref_count)
|
||||
{
|
||||
gtk_tree_model_ref_count_check_level (ref_model, NULL, ref_count,
|
||||
FALSE, TRUE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
assert_level_referenced (GtkTreeModelRefCount *ref_model,
|
||||
gint ref_count,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gtk_tree_model_ref_count_check_level (ref_model, iter, ref_count,
|
||||
FALSE, TRUE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
assert_node_ref_count (GtkTreeModelRefCount *ref_model,
|
||||
GtkTreeIter *iter,
|
||||
gint ref_count)
|
||||
{
|
||||
gtk_tree_model_ref_count_check_node (ref_model, iter, ref_count, TRUE);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __GTK_TREE_MODEL_REF_COUNT_H__ */
|
||||
203
testsuite/gtk/keyhash.c
Normal file
203
testsuite/gtk/keyhash.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* keyhash.c
|
||||
* Copyright (C) 2012 Red Hat, Inc12 Red Hat, Inc
|
||||
* Authors: Matthias Clasen
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include "../../gtk/gtkkeyhash.h"
|
||||
#include "../../gtk/gtkprivate.h"
|
||||
|
||||
static gint count;
|
||||
|
||||
static void
|
||||
counting_destroy (gpointer data)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
static void
|
||||
test_basic (void)
|
||||
{
|
||||
GtkKeyHash *hash;
|
||||
GSList *keys;
|
||||
|
||||
count = 0;
|
||||
hash = _gtk_key_hash_new (gdk_keymap_get_default (), counting_destroy);
|
||||
|
||||
keys = _gtk_key_hash_lookup (hash, 0, 0, 0, 0);
|
||||
g_assert (keys == NULL);
|
||||
|
||||
_gtk_key_hash_add_entry (hash, 1, 0, NULL);
|
||||
_gtk_key_hash_add_entry (hash, 1, 1, NULL);
|
||||
_gtk_key_hash_add_entry (hash, 2, 0, NULL);
|
||||
_gtk_key_hash_add_entry (hash, 3, 0, NULL);
|
||||
_gtk_key_hash_add_entry (hash, 4, 0, NULL);
|
||||
|
||||
_gtk_key_hash_free (hash);
|
||||
|
||||
g_assert_cmpint (count, ==, 5);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
typedef struct
|
||||
{
|
||||
guint keyval;
|
||||
GdkModifierType modifiers;
|
||||
} Entry;
|
||||
|
||||
static void
|
||||
test_lookup (GtkKeyHash *hash,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
GdkModifierType mask,
|
||||
gint n_results,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
gint d;
|
||||
GSList *res, *l;
|
||||
gint i;
|
||||
GdkKeymapKey *keys;
|
||||
gint n_keys;
|
||||
|
||||
gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), keyval, &keys, &n_keys);
|
||||
if (n_keys == 0)
|
||||
return;
|
||||
|
||||
res = _gtk_key_hash_lookup (hash, keys[0].keycode, modifiers, mask, keys[0].group);
|
||||
g_free (keys);
|
||||
|
||||
g_assert_cmpint (g_slist_length (res), ==, n_results);
|
||||
|
||||
va_start (ap, n_results);
|
||||
for (i = 0, l = res; i < n_results; i++, l = l->next)
|
||||
{
|
||||
d = va_arg (ap, int);
|
||||
g_assert_cmpint (d, ==, GPOINTER_TO_INT (l->data));
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
g_slist_free (res);
|
||||
}
|
||||
|
||||
static void
|
||||
add_entries (GtkKeyHash *hash,
|
||||
Entry *entries)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; entries[i].keyval; i++)
|
||||
_gtk_key_hash_add_entry (hash, entries[i].keyval, entries[i].modifiers, GINT_TO_POINTER (i+1));
|
||||
}
|
||||
|
||||
#define DEFAULT_MASK (GDK_CONTROL_MASK \
|
||||
| GDK_SHIFT_MASK \
|
||||
| GDK_MOD1_MASK \
|
||||
| GDK_SUPER_MASK \
|
||||
| GDK_HYPER_MASK \
|
||||
| GDK_META_MASK)
|
||||
|
||||
static void
|
||||
test_match (void)
|
||||
{
|
||||
GtkKeyHash *hash;
|
||||
static Entry entries[] = {
|
||||
{ GDK_KEY_a, GDK_CONTROL_MASK },
|
||||
{ GDK_KEY_a, GDK_CONTROL_MASK|GDK_SHIFT_MASK } ,
|
||||
{ GDK_KEY_b, GDK_MOD1_MASK|GDK_CONTROL_MASK },
|
||||
{ GDK_KEY_F10, 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
hash = _gtk_key_hash_new (gdk_keymap_get_default (), NULL);
|
||||
add_entries (hash, entries);
|
||||
|
||||
test_lookup (hash, GDK_KEY_a, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2);
|
||||
test_lookup (hash, GDK_KEY_A, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2);
|
||||
test_lookup (hash, GDK_KEY_a, GDK_MOD1_MASK, DEFAULT_MASK, 0);
|
||||
test_lookup (hash, GDK_KEY_F10, 0, DEFAULT_MASK, 4, 4, 4, 4, 4);
|
||||
test_lookup (hash, GDK_KEY_F10, GDK_SHIFT_MASK, DEFAULT_MASK, 4, 4, 4, 4, 4);
|
||||
|
||||
_gtk_key_hash_free (hash);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
hyper_equals_super (void)
|
||||
{
|
||||
GdkModifierType mods1, mods2;
|
||||
|
||||
mods1 = GDK_HYPER_MASK;
|
||||
gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods1);
|
||||
mods1 = mods1 & ~GDK_HYPER_MASK;
|
||||
mods2 = GDK_SUPER_MASK;
|
||||
gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods2);
|
||||
mods2 = mods2 & ~GDK_SUPER_MASK;
|
||||
|
||||
return mods1 == mods2;
|
||||
}
|
||||
|
||||
static void
|
||||
test_virtual (void)
|
||||
{
|
||||
GtkKeyHash *hash;
|
||||
static Entry entries[] = {
|
||||
{ GDK_KEY_a, GDK_SUPER_MASK },
|
||||
{ GDK_KEY_b, GDK_HYPER_MASK } ,
|
||||
{ GDK_KEY_c, GDK_META_MASK },
|
||||
{ GDK_KEY_d, GDK_SUPER_MASK|GDK_HYPER_MASK },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
hash = _gtk_key_hash_new (gdk_keymap_get_default (), NULL);
|
||||
add_entries (hash, entries);
|
||||
|
||||
test_lookup (hash, GDK_KEY_a, GDK_SUPER_MASK, DEFAULT_MASK, 2, 1, 1);
|
||||
test_lookup (hash, GDK_KEY_a, GDK_HYPER_MASK, DEFAULT_MASK, 0);
|
||||
test_lookup (hash, GDK_KEY_b, GDK_HYPER_MASK, DEFAULT_MASK, 2, 2, 2);
|
||||
test_lookup (hash, GDK_KEY_c, GDK_META_MASK, DEFAULT_MASK, 2, 3, 3);
|
||||
if (hyper_equals_super ())
|
||||
{
|
||||
GdkModifierType mods;
|
||||
|
||||
/* test that colocated virtual modifiers don't count twice */
|
||||
test_lookup (hash, GDK_KEY_d, GDK_SUPER_MASK, DEFAULT_MASK, 0);
|
||||
test_lookup (hash, GDK_KEY_d, GDK_HYPER_MASK, DEFAULT_MASK, 0);
|
||||
|
||||
mods = GDK_HYPER_MASK;
|
||||
gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods);
|
||||
test_lookup (hash, GDK_KEY_d, mods, DEFAULT_MASK, 0);
|
||||
}
|
||||
|
||||
_gtk_key_hash_free (hash);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
/* initialize test program */
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/keyhash/basic", test_basic);
|
||||
#if 0
|
||||
/* FIXME: need to make these independent of xkb configuration */
|
||||
g_test_add_func ("/keyhash/match", test_match);
|
||||
g_test_add_func ("/keyhash/virtual", test_virtual);
|
||||
#endif
|
||||
return g_test_run();
|
||||
}
|
||||
1139
testsuite/gtk/liststore.c
Normal file
1139
testsuite/gtk/liststore.c
Normal file
File diff suppressed because it is too large
Load Diff
976
testsuite/gtk/modelrefcount.c
Normal file
976
testsuite/gtk/modelrefcount.c
Normal file
@ -0,0 +1,976 @@
|
||||
/* GtkTreeModel ref counting tests
|
||||
* Copyright (C) 2011 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gtktreemodelrefcount.h"
|
||||
#include "treemodel.h"
|
||||
|
||||
/* And the tests themselves */
|
||||
|
||||
static void
|
||||
test_list_no_reference (void)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_list_reference_during_creation (void)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_list_reference_after_creation (void)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_list_reference_reordered (void)
|
||||
{
|
||||
GtkTreeIter iter1, iter2, iter3, iter4, iter5;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, NULL);
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_store_move_after (GTK_TREE_STORE (model),
|
||||
&iter1, &iter5);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_store_move_after (GTK_TREE_STORE (model),
|
||||
&iter3, &iter4);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_tree_no_reference (void)
|
||||
{
|
||||
GtkTreeIter iter, child;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tree_reference_during_creation (void)
|
||||
{
|
||||
GtkTreeIter iter, child;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
assert_not_entire_model_referenced (ref_model, 1);
|
||||
assert_level_unreferenced (ref_model, &child);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tree_reference_after_creation (void)
|
||||
{
|
||||
GtkTreeIter iter, child;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
assert_not_entire_model_referenced (ref_model, 1);
|
||||
assert_level_unreferenced (ref_model, &child);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tree_reference_reordered (void)
|
||||
{
|
||||
GtkTreeIter parent;
|
||||
GtkTreeIter iter1, iter2, iter3, iter4, iter5;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &parent, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, &parent);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, &parent);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, &parent);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, &parent);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, &parent);
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
assert_entire_model_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_store_move_after (GTK_TREE_STORE (model),
|
||||
&iter1, &iter5);
|
||||
|
||||
assert_entire_model_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_store_move_after (GTK_TREE_STORE (model),
|
||||
&iter3, &iter4);
|
||||
|
||||
assert_entire_model_referenced (ref_model, 1);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tree_reference_expand_all (void)
|
||||
{
|
||||
GtkTreeIter iter, child;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
assert_not_entire_model_referenced (ref_model, 1);
|
||||
assert_level_unreferenced (ref_model, &child);
|
||||
|
||||
gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
assert_entire_model_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
assert_not_entire_model_referenced (ref_model, 1);
|
||||
assert_level_unreferenced (ref_model, &child);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tree_reference_collapse_all (void)
|
||||
{
|
||||
GtkTreeIter iter, child;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
assert_entire_model_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
assert_not_entire_model_referenced (ref_model, 1);
|
||||
assert_level_unreferenced (ref_model, &child);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tree_reference_expand_collapse (void)
|
||||
{
|
||||
GtkTreeIter parent1, parent2, child;
|
||||
GtkTreePath *path1, *path2;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
|
||||
|
||||
path1 = gtk_tree_model_get_path (model, &parent1);
|
||||
path2 = gtk_tree_model_get_path (model, &parent2);
|
||||
|
||||
assert_level_unreferenced (ref_model, &parent1);
|
||||
assert_level_unreferenced (ref_model, &parent2);
|
||||
|
||||
gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
|
||||
|
||||
assert_level_referenced (ref_model, 1, &parent1);
|
||||
assert_level_unreferenced (ref_model, &parent2);
|
||||
|
||||
gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path1);
|
||||
|
||||
assert_level_unreferenced (ref_model, &parent1);
|
||||
assert_level_unreferenced (ref_model, &parent2);
|
||||
|
||||
gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
|
||||
|
||||
assert_level_unreferenced (ref_model, &parent1);
|
||||
assert_level_referenced (ref_model, 1, &parent2);
|
||||
|
||||
gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path2);
|
||||
|
||||
assert_level_unreferenced (ref_model, &parent1);
|
||||
assert_level_unreferenced (ref_model, &parent2);
|
||||
|
||||
gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
|
||||
|
||||
assert_level_unreferenced (ref_model, &parent1);
|
||||
assert_level_referenced (ref_model, 1, &parent2);
|
||||
|
||||
gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
|
||||
|
||||
assert_level_referenced (ref_model, 1, &parent1);
|
||||
assert_level_referenced (ref_model, 1, &parent2);
|
||||
|
||||
gtk_tree_path_free (path1);
|
||||
gtk_tree_path_free (path2);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_row_reference_list (void)
|
||||
{
|
||||
GtkTreeIter iter0, iter1, iter2;
|
||||
GtkTreePath *path;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkTreeRowReference *row_ref;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
/* create and remove a row ref and check reference counts */
|
||||
path = gtk_tree_path_new_from_indices (1, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 0);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
/* the same, but then also with a tree view monitoring the model */
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &iter1, 2);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 0);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_row_reference_list_remove (void)
|
||||
{
|
||||
GtkTreeIter iter0, iter1, iter2;
|
||||
GtkTreePath *path;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkTreeRowReference *row_ref;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
/* test creating the row reference and then removing the node */
|
||||
path = gtk_tree_path_new_from_indices (1, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 0);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter1);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
/* test creating a row ref, removing another node and then removing
|
||||
* the row ref node.
|
||||
*/
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter0);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
|
||||
|
||||
g_assert (!gtk_tree_model_get_iter_first (model, &iter0));
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_row_reference_tree (void)
|
||||
{
|
||||
GtkTreeIter iter0, iter1, iter2;
|
||||
GtkTreeIter child0, child1, child2;
|
||||
GtkTreeIter grandchild0, grandchild1, grandchild2;
|
||||
GtkTreePath *path;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkTreeRowReference *row_ref, *row_ref1;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
/* create and remove a row ref and check reference counts */
|
||||
path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 0);
|
||||
assert_node_ref_count (ref_model, &child2, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
/* again, with path 1:1 */
|
||||
path = gtk_tree_path_new_from_indices (1, 0, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 0);
|
||||
assert_node_ref_count (ref_model, &child2, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
/* both row refs existent at once and also with a tree view monitoring
|
||||
* the model
|
||||
*/
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 2);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
assert_node_ref_count (ref_model, &child2, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (1, 0, -1);
|
||||
row_ref1 = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 3);
|
||||
assert_node_ref_count (ref_model, &child1, 2);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
assert_node_ref_count (ref_model, &child2, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 2);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
assert_node_ref_count (ref_model, &child2, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 0);
|
||||
assert_node_ref_count (ref_model, &child2, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref1);
|
||||
|
||||
assert_root_level_unreferenced (ref_model);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_row_reference_tree_remove (void)
|
||||
{
|
||||
GtkTreeIter iter0, iter1, iter2;
|
||||
GtkTreeIter child0, child1, child2;
|
||||
GtkTreeIter grandchild0, grandchild1, grandchild2;
|
||||
GtkTreePath *path;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (2, 0, -1);
|
||||
row_ref1 = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (2, -1);
|
||||
row_ref2 = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 2);
|
||||
assert_node_ref_count (ref_model, &child2, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 0);
|
||||
assert_node_ref_count (ref_model, &child1, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 2);
|
||||
assert_node_ref_count (ref_model, &child2, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 0);
|
||||
assert_node_ref_count (ref_model, &child1, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
gtk_tree_row_reference_free (row_ref1);
|
||||
gtk_tree_row_reference_free (row_ref2);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_row_reference_tree_remove_ancestor (void)
|
||||
{
|
||||
GtkTreeIter iter0, iter1, iter2;
|
||||
GtkTreeIter child0, child1, child2;
|
||||
GtkTreeIter grandchild0, grandchild1, grandchild2;
|
||||
GtkTreePath *path;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkTreeRowReference *row_ref, *row_ref1;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (2, 0, -1);
|
||||
row_ref1 = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
assert_node_ref_count (ref_model, &child2, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &child1);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 0);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 1);
|
||||
assert_node_ref_count (ref_model, &child2, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 0);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
|
||||
|
||||
assert_entire_model_unreferenced (ref_model);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
gtk_tree_row_reference_free (row_ref1);
|
||||
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
static void
|
||||
test_row_reference_tree_expand (void)
|
||||
{
|
||||
GtkTreeIter iter0, iter1, iter2;
|
||||
GtkTreeIter child0, child1, child2;
|
||||
GtkTreeIter grandchild0, grandchild1, grandchild2;
|
||||
GtkTreePath *path;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModelRefCount *ref_model;
|
||||
GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
|
||||
GtkWidget *tree_view;
|
||||
|
||||
model = gtk_tree_model_ref_count_new ();
|
||||
ref_model = GTK_TREE_MODEL_REF_COUNT (model);
|
||||
tree_view = gtk_tree_view_new_with_model (model);
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
|
||||
|
||||
assert_root_level_referenced (ref_model, 1);
|
||||
|
||||
gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
assert_entire_model_referenced (ref_model, 1);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
|
||||
row_ref = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (2, 0, -1);
|
||||
row_ref1 = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (2, -1);
|
||||
row_ref2 = gtk_tree_row_reference_new (model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 1);
|
||||
assert_node_ref_count (ref_model, &iter1, 2);
|
||||
assert_node_ref_count (ref_model, &child1, 2);
|
||||
assert_node_ref_count (ref_model, &grandchild1, 2);
|
||||
assert_node_ref_count (ref_model, &iter2, 3);
|
||||
assert_node_ref_count (ref_model, &child2, 2);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 1);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 1);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 3);
|
||||
assert_node_ref_count (ref_model, &child2, 2);
|
||||
assert_node_ref_count (ref_model, &grandchild2, 1);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 1);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 1);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 1);
|
||||
assert_node_ref_count (ref_model, &iter2, 2);
|
||||
|
||||
gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 0);
|
||||
assert_node_ref_count (ref_model, &iter2, 2);
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
|
||||
|
||||
assert_node_ref_count (ref_model, &iter0, 1);
|
||||
assert_node_ref_count (ref_model, &child0, 0);
|
||||
assert_node_ref_count (ref_model, &grandchild0, 0);
|
||||
assert_node_ref_count (ref_model, &iter1, 1);
|
||||
assert_node_ref_count (ref_model, &child1, 0);
|
||||
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
gtk_tree_row_reference_free (row_ref1);
|
||||
gtk_tree_row_reference_free (row_ref2);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
g_object_unref (ref_model);
|
||||
}
|
||||
|
||||
void
|
||||
register_model_ref_count_tests (void)
|
||||
{
|
||||
/* lists (though based on GtkTreeStore) */
|
||||
g_test_add_func ("/TreeModel/ref-count/list/no-reference",
|
||||
test_list_no_reference);
|
||||
g_test_add_func ("/TreeModel/ref-count/list/reference-during-creation",
|
||||
test_list_reference_during_creation);
|
||||
g_test_add_func ("/TreeModel/ref-count/list/reference-after-creation",
|
||||
test_list_reference_after_creation);
|
||||
g_test_add_func ("/TreeModel/ref-count/list/reference-reordered",
|
||||
test_list_reference_reordered);
|
||||
|
||||
/* trees */
|
||||
g_test_add_func ("/TreeModel/ref-count/tree/no-reference",
|
||||
test_tree_no_reference);
|
||||
g_test_add_func ("/TreeModel/ref-count/tree/reference-during-creation",
|
||||
test_tree_reference_during_creation);
|
||||
g_test_add_func ("/TreeModel/ref-count/tree/reference-after-creation",
|
||||
test_tree_reference_after_creation);
|
||||
g_test_add_func ("/TreeModel/ref-count/tree/expand-all",
|
||||
test_tree_reference_expand_all);
|
||||
g_test_add_func ("/TreeModel/ref-count/tree/collapse-all",
|
||||
test_tree_reference_collapse_all);
|
||||
g_test_add_func ("/TreeModel/ref-count/tree/expand-collapse",
|
||||
test_tree_reference_expand_collapse);
|
||||
g_test_add_func ("/TreeModel/ref-count/tree/reference-reordered",
|
||||
test_tree_reference_reordered);
|
||||
|
||||
/* row references */
|
||||
g_test_add_func ("/TreeModel/ref-count/row-reference/list",
|
||||
test_row_reference_list);
|
||||
g_test_add_func ("/TreeModel/ref-count/row-reference/list-remove",
|
||||
test_row_reference_list_remove);
|
||||
g_test_add_func ("/TreeModel/ref-count/row-reference/tree",
|
||||
test_row_reference_tree);
|
||||
g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove",
|
||||
test_row_reference_tree_remove);
|
||||
g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove-ancestor",
|
||||
test_row_reference_tree_remove_ancestor);
|
||||
g_test_add_func ("/TreeModel/ref-count/row-reference/tree-expand",
|
||||
test_row_reference_tree_expand);
|
||||
}
|
||||
329
testsuite/gtk/object.c
Normal file
329
testsuite/gtk/object.c
Normal file
@ -0,0 +1,329 @@
|
||||
/* Gtk+ object tests
|
||||
* Copyright (C) 2007 Imendio AB
|
||||
* Authors: 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
/* --- helper macros for property value generation --- */
|
||||
/* dvalue=+0: generate minimum value
|
||||
* dvalue=.x: generate value within value range proportional to x.
|
||||
* dvalue=+1: generate maximum value
|
||||
* dvalue=-1: generate random value within value range
|
||||
* dvalue=+2: initialize value from default_value
|
||||
*/
|
||||
#define ASSIGN_VALUE(__g_value_set_func, __value, PSPECTYPE, __pspec, __default_value, __minimum, __maximum, __dvalue) do { \
|
||||
PSPECTYPE __p = (PSPECTYPE) __pspec; \
|
||||
__g_value_set_func (__value, SELECT_VALUE (__dvalue, __p->__default_value, __p->__minimum, __p->__maximum)); \
|
||||
} while (0)
|
||||
#define SELECT_VALUE(__dvalue, __default_value, __minimum, __maximum) ( \
|
||||
__dvalue >= 0 && __dvalue <= 1 ? __minimum * (1 - __dvalue) + __dvalue * __maximum : \
|
||||
__dvalue <= -1 ? g_test_rand_double_range (__minimum, __maximum) : \
|
||||
__default_value)
|
||||
#define SELECT_NAME(__dvalue) ( \
|
||||
__dvalue == 0 ? "minimum" : \
|
||||
__dvalue == 1 ? "maximum" : \
|
||||
__dvalue >= +2 ? "default" : \
|
||||
__dvalue == 0.5 ? "medium" : \
|
||||
__dvalue > 0 && __dvalue < 1 ? "fractional" : \
|
||||
"random")
|
||||
#define MATCH_ANY_VALUE ((void*) 0xf1874c23)
|
||||
|
||||
/* --- property blacklists --- */
|
||||
typedef struct {
|
||||
const char *type_name;
|
||||
const char *name;
|
||||
gconstpointer value;
|
||||
} IgnoreProperty;
|
||||
static const IgnoreProperty*
|
||||
list_ignore_properties (gboolean buglist)
|
||||
{
|
||||
/* currently untestable properties */
|
||||
static const IgnoreProperty ignore_properties[] = {
|
||||
{ "GtkContainer", "child", NULL, }, /* needs working child widget */
|
||||
{ "GtkRadioMenuItem", "group", NULL, }, /* needs working sibling */
|
||||
{ "GtkWidget", "parent", NULL, }, /* needs working parent widget */
|
||||
{ "GtkCList", "selection-mode", (void*) GTK_SELECTION_NONE, },
|
||||
{ "GtkWidget", "has-default", (void*) TRUE, }, /* conflicts with toplevel-less widgets */
|
||||
{ "GtkWidget", "screen", NULL, },
|
||||
{ "GtkWindow", "type-hint", (void*) GDK_WINDOW_TYPE_HINT_DND, }, /* conflicts with ::visible=TRUE */
|
||||
{ "GtkCellView", "background", (void*) "", }, /* "" is not a valid background color */
|
||||
{ "GtkColorButton", "color", (void*) NULL, }, /* not a valid boxed color */
|
||||
{ "GtkInputDialog", "has-separator", (void*) MATCH_ANY_VALUE, }, /* property disabled */
|
||||
{ "GtkMessageDialog", "has-separator", (void*) MATCH_ANY_VALUE, }, /* property disabled */
|
||||
{ "GtkFontSelectionDialog", "has-separator", (void*) MATCH_ANY_VALUE, }, /* property disabled */
|
||||
{ "GtkColorSelectionDialog","has-separator", (void*) MATCH_ANY_VALUE, }, /* property disabled */
|
||||
{ "GtkColorSelection", "child", NULL, },
|
||||
{ "GtkColorSelection", "current-color", (void*) NULL, }, /* not a valid boxed color */
|
||||
{ "GtkComboBox", "row-span-column", (void*) MATCH_ANY_VALUE }, /* GtkComboBoxEntry needs a tree model for this */
|
||||
{ "GtkComboBox", "column-span-column", (void*) MATCH_ANY_VALUE }, /* GtkComboBoxEntry needs a tree model for this */
|
||||
{ "GtkFileChooserButton", "select-multiple", (void*) MATCH_ANY_VALUE }, /* property disabled */
|
||||
{ "GtkFileChooserButton", "action", (void*) GTK_FILE_CHOOSER_ACTION_SAVE },
|
||||
{ "GtkFileChooserButton", "action", (void*) GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER },
|
||||
{ "GtkFileChooserWidget", "select-multiple", (void*) 0x1 }, /* property conflicts */
|
||||
{ "GtkFileChooserDialog", "select-multiple", (void*) MATCH_ANY_VALUE }, /* property disabled */
|
||||
{ "GtkMenu", "accel-path", (void*) MATCH_ANY_VALUE }, /* has odd restrictions in the setter */
|
||||
{ "GtkMenuItem", "accel-path", (void*) MATCH_ANY_VALUE }, /* has odd restrictions in the setter */
|
||||
{ "GtkRecentChooserMenu", "select-multiple", (void*) MATCH_ANY_VALUE }, /* property disabled */
|
||||
{ "GtkTextView", "overwrite", (void*) MATCH_ANY_VALUE }, /* needs text buffer */
|
||||
{ "GtkToolbar", "icon-size", (void*) GTK_ICON_SIZE_INVALID },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
/* properties suspected to be Gdk/Gtk+ bugs */
|
||||
static const IgnoreProperty bug_properties[] = {
|
||||
{ "GtkComboBox", "active", (void*) MATCH_ANY_VALUE }, /* FIXME: triggers NULL model bug */
|
||||
{ "GtkCTree", "spacing", (void*) MATCH_ANY_VALUE }, /* FIXME: triggers signedness bug */
|
||||
{ "GtkFileChooserButton", "local-only", (void*) MATCH_ANY_VALUE }, /* FIXME: triggers NULL path assertion */
|
||||
{ "GtkFileChooserDialog", "local-only", (void*) MATCH_ANY_VALUE }, /* FIXME: triggers NULL path assertion */
|
||||
{ "GtkFileChooserWidget", "local-only", (void*) MATCH_ANY_VALUE }, /* FIXME: triggers NULL path assertion */
|
||||
{ "GtkMenu", "tearoff-state", (void*) MATCH_ANY_VALUE }, /* FIXME: triggers NULL widget cast */
|
||||
{ "GtkText", "text-position", (void*) MATCH_ANY_VALUE }, /* FIXME: segfaults, fix property minimum/maximum */
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
if (buglist)
|
||||
return bug_properties;
|
||||
else
|
||||
return ignore_properties;
|
||||
}
|
||||
|
||||
/* --- test functions --- */
|
||||
static void
|
||||
pspec_select_value (GParamSpec *pspec,
|
||||
GValue *value,
|
||||
double dvalue)
|
||||
{
|
||||
/* generate a value suitable for pspec */
|
||||
if (G_IS_PARAM_SPEC_CHAR (pspec))
|
||||
ASSIGN_VALUE (g_value_set_char, value, GParamSpecChar*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_UCHAR (pspec))
|
||||
ASSIGN_VALUE (g_value_set_uchar, value, GParamSpecUChar*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_INT (pspec))
|
||||
ASSIGN_VALUE (g_value_set_int, value, GParamSpecInt*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_UINT (pspec))
|
||||
ASSIGN_VALUE (g_value_set_uint, value, GParamSpecUInt*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_LONG (pspec))
|
||||
ASSIGN_VALUE (g_value_set_long, value, GParamSpecLong*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_ULONG (pspec))
|
||||
ASSIGN_VALUE (g_value_set_ulong, value, GParamSpecULong*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_INT64 (pspec))
|
||||
ASSIGN_VALUE (g_value_set_int64, value, GParamSpecInt64*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_UINT64 (pspec))
|
||||
ASSIGN_VALUE (g_value_set_uint64, value, GParamSpecUInt64*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_FLOAT (pspec))
|
||||
ASSIGN_VALUE (g_value_set_float, value, GParamSpecFloat*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
|
||||
ASSIGN_VALUE (g_value_set_double, value, GParamSpecDouble*, pspec, default_value, minimum, maximum, dvalue);
|
||||
else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
|
||||
g_value_set_boolean (value, SELECT_VALUE (dvalue, ((GParamSpecBoolean*) pspec)->default_value, FALSE, TRUE));
|
||||
else if (G_IS_PARAM_SPEC_UNICHAR (pspec))
|
||||
g_value_set_uint (value, SELECT_VALUE (dvalue, ((GParamSpecUnichar*) pspec)->default_value, FALSE, TRUE));
|
||||
else if (G_IS_PARAM_SPEC_GTYPE (pspec))
|
||||
g_value_set_gtype (value, SELECT_VALUE ((int) dvalue, ((GParamSpecGType*) pspec)->is_a_type, 0, GTK_TYPE_WIDGET));
|
||||
else if (G_IS_PARAM_SPEC_STRING (pspec))
|
||||
{
|
||||
GParamSpecString *sspec = (GParamSpecString*) pspec;
|
||||
if (dvalue >= +2)
|
||||
g_value_set_string (value, sspec->default_value);
|
||||
if (dvalue > 0 && sspec->cset_first && sspec->cset_nth)
|
||||
g_value_take_string (value, g_strdup_printf ("%c%c", sspec->cset_first[0], sspec->cset_nth[0]));
|
||||
else /* if (sspec->ensure_non_null) */
|
||||
g_value_set_string (value, "");
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_ENUM (pspec))
|
||||
{
|
||||
GParamSpecEnum *espec = (GParamSpecEnum*) pspec;
|
||||
if (dvalue >= +2)
|
||||
g_value_set_enum (value, espec->default_value);
|
||||
if (dvalue >= 0 && dvalue <= 1)
|
||||
g_value_set_enum (value, espec->enum_class->values[(int) ((espec->enum_class->n_values - 1) * dvalue)].value);
|
||||
else if (dvalue <= -1)
|
||||
g_value_set_enum (value, espec->enum_class->values[g_test_rand_int_range (0, espec->enum_class->n_values)].value);
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_FLAGS (pspec))
|
||||
{
|
||||
GParamSpecFlags *fspec = (GParamSpecFlags*) pspec;
|
||||
if (dvalue >= +2)
|
||||
g_value_set_flags (value, fspec->default_value);
|
||||
if (dvalue >= 0 && dvalue <= 1)
|
||||
g_value_set_flags (value, fspec->flags_class->values[(int) ((fspec->flags_class->n_values - 1) * dvalue)].value);
|
||||
else if (dvalue <= -1)
|
||||
g_value_set_flags (value, fspec->flags_class->values[g_test_rand_int_range (0, fspec->flags_class->n_values)].value);
|
||||
}
|
||||
/* unimplemented:
|
||||
* G_IS_PARAM_SPEC_PARAM
|
||||
* G_IS_PARAM_SPEC_BOXED
|
||||
* G_IS_PARAM_SPEC_POINTER
|
||||
* G_IS_PARAM_SPEC_VALUE_ARRAY
|
||||
* G_IS_PARAM_SPEC_OBJECT
|
||||
*/
|
||||
}
|
||||
|
||||
static gpointer
|
||||
value_as_pointer (GValue *value)
|
||||
{
|
||||
if (g_value_fits_pointer (value))
|
||||
return g_value_peek_pointer (value);
|
||||
if (G_VALUE_HOLDS_BOOLEAN (value))
|
||||
return GINT_TO_POINTER(g_value_get_boolean (value));
|
||||
if (G_VALUE_HOLDS_CHAR (value))
|
||||
return (void*) (gssize) g_value_get_char (value);
|
||||
if (G_VALUE_HOLDS_UCHAR (value))
|
||||
return (void*) (gsize) g_value_get_uchar (value);
|
||||
if (G_VALUE_HOLDS_INT (value))
|
||||
return GINT_TO_POINTER(g_value_get_int (value));
|
||||
if (G_VALUE_HOLDS_UINT (value))
|
||||
return GUINT_TO_POINTER(g_value_get_uint (value));
|
||||
if (G_VALUE_HOLDS_LONG (value))
|
||||
return (void*) g_value_get_long (value);
|
||||
if (G_VALUE_HOLDS_ULONG (value))
|
||||
return (void*) g_value_get_ulong (value);
|
||||
if (G_VALUE_HOLDS_FLOAT (value))
|
||||
return (void*) (gssize) g_value_get_float (value);
|
||||
if (G_VALUE_HOLDS_DOUBLE (value))
|
||||
return (void*) (gssize) g_value_get_double (value);
|
||||
if (G_VALUE_HOLDS_ENUM (value))
|
||||
return (void*) (gssize) g_value_get_enum (value);
|
||||
if (G_VALUE_HOLDS_FLAGS (value))
|
||||
return (void*) (gsize) g_value_get_flags (value);
|
||||
return (void*) 0x1373babe;
|
||||
}
|
||||
|
||||
static void
|
||||
object_test_property (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
double dvalue)
|
||||
{
|
||||
/* test setting of a normal writable property */
|
||||
if (pspec->flags & G_PARAM_WRITABLE &&
|
||||
!(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
guint i;
|
||||
const IgnoreProperty *ignore_properties;
|
||||
/* select value to set */
|
||||
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
pspec_select_value (pspec, &value, dvalue);
|
||||
/* ignore untestable properties */
|
||||
ignore_properties = list_ignore_properties (FALSE);
|
||||
for (i = 0; ignore_properties[i].name; i++)
|
||||
if (g_strcmp0 ("", ignore_properties[i].name) ||
|
||||
(g_type_is_a (G_OBJECT_TYPE (object), g_type_from_name (ignore_properties[i].type_name)) &&
|
||||
strcmp (pspec->name, ignore_properties[i].name) == 0 &&
|
||||
(MATCH_ANY_VALUE == ignore_properties[i].value ||
|
||||
value_as_pointer (&value) == ignore_properties[i].value ||
|
||||
(G_VALUE_HOLDS_STRING (&value) &&
|
||||
strcmp (g_value_get_string (&value), ignore_properties[i].value) == 0))))
|
||||
break;
|
||||
/* ignore known property bugs if not testing thoroughly */
|
||||
if (ignore_properties[i].name == NULL && !g_test_thorough ())
|
||||
{
|
||||
ignore_properties = list_ignore_properties (TRUE);
|
||||
for (i = 0; ignore_properties[i].name; i++)
|
||||
if (g_type_is_a (G_OBJECT_TYPE (object), g_type_from_name (ignore_properties[i].type_name)) &&
|
||||
strcmp (pspec->name, ignore_properties[i].name) == 0 &&
|
||||
(MATCH_ANY_VALUE == ignore_properties[i].value ||
|
||||
value_as_pointer (&value) == ignore_properties[i].value ||
|
||||
(G_VALUE_HOLDS_STRING (&value) &&
|
||||
strcmp (g_value_get_string (&value), ignore_properties[i].value) == 0)))
|
||||
break;
|
||||
}
|
||||
/* assign unignored properties */
|
||||
if (ignore_properties[i].name == NULL)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("PropertyTest: %s::%s := (%s value (%s): %p)\n",
|
||||
g_type_name (G_OBJECT_TYPE (object)), pspec->name,
|
||||
SELECT_NAME (dvalue), g_type_name (G_VALUE_TYPE (&value)),
|
||||
value_as_pointer (&value));
|
||||
g_object_set_property (object, pspec->name, &value);
|
||||
}
|
||||
/* cleanups */
|
||||
g_value_unset (&value);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
widget_test_properties (GtkWidget *widget,
|
||||
double dvalue)
|
||||
{
|
||||
/* try setting all possible properties, according to dvalue */
|
||||
guint i, n_pspecs = 0;
|
||||
GParamSpec **pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (widget), &n_pspecs);
|
||||
for (i = 0; i < n_pspecs; i++)
|
||||
{
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
if (pspec->flags & G_PARAM_WRITABLE &&
|
||||
!(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
|
||||
object_test_property (G_OBJECT (widget), pspecs[i], dvalue);
|
||||
}
|
||||
g_free (pspecs);
|
||||
}
|
||||
|
||||
static void
|
||||
widget_fixups (GtkWidget *widget)
|
||||
{
|
||||
/* post-constructor for widgets that need additional settings to work correctly */
|
||||
if (GTK_IS_COMBO_BOX (widget))
|
||||
{
|
||||
GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
g_object_set (widget, "model", store, NULL);
|
||||
g_object_unref (store);
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "test text");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
widget_property_tests (gconstpointer test_data)
|
||||
{
|
||||
GType wtype = (GType) test_data;
|
||||
/* create widget */
|
||||
GtkWidget *widget = gtk_widget_new (wtype, NULL);
|
||||
g_object_ref_sink (widget);
|
||||
widget_fixups (widget);
|
||||
/* test property values */
|
||||
widget_test_properties (widget, +2); /* test default_value */
|
||||
widget_test_properties (widget, 0); /* test minimum */
|
||||
widget_test_properties (widget, 0.5); /* test medium */
|
||||
widget_test_properties (widget, 1); /* test maximum */
|
||||
widget_test_properties (widget, -1); /* test random value */
|
||||
/* cleanup */
|
||||
gtk_widget_destroy (widget);
|
||||
g_object_unref (widget);
|
||||
}
|
||||
|
||||
/* --- main test program --- */
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
const GType *otypes;
|
||||
guint i;
|
||||
/* initialize test program */
|
||||
gtk_test_init (&argc, &argv);
|
||||
gtk_test_register_all_types ();
|
||||
/* install a property test for each widget type */
|
||||
otypes = gtk_test_list_all_types (NULL);
|
||||
for (i = 0; otypes[i]; i++)
|
||||
if (g_type_is_a (otypes[i], GTK_TYPE_WIDGET) &&
|
||||
G_TYPE_IS_OBJECT (otypes[i]) &&
|
||||
!G_TYPE_IS_ABSTRACT (otypes[i]))
|
||||
{
|
||||
gchar *testpath = g_strdup_printf ("/properties/%s", g_type_name (otypes[i]));
|
||||
g_test_add_data_func (testpath, (void*) otypes[i], widget_property_tests);
|
||||
g_free (testpath);
|
||||
}
|
||||
return g_test_run ();
|
||||
}
|
||||
114
testsuite/gtk/objects-finalize.c
Normal file
114
testsuite/gtk/objects-finalize.c
Normal file
@ -0,0 +1,114 @@
|
||||
/* objects-finalize.c
|
||||
* Copyright (C) 2013 Openismus GmbH
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Tristan Van Berkom <tristanvb@openismus.com>
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
# include <gdk/gdkx.h>
|
||||
#endif
|
||||
|
||||
|
||||
typedef GType (*GTypeGetFunc) (void);
|
||||
|
||||
static gboolean finalized = FALSE;
|
||||
|
||||
static gboolean
|
||||
main_loop_quit_cb (gpointer data)
|
||||
{
|
||||
gtk_main_quit ();
|
||||
|
||||
g_assert (finalized);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
check_finalized (gpointer data,
|
||||
GObject *where_the_object_was)
|
||||
{
|
||||
gboolean *did_finalize = (gboolean *)data;
|
||||
|
||||
*did_finalize = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_finalize_object (gconstpointer data)
|
||||
{
|
||||
GType test_type = GPOINTER_TO_SIZE (data);
|
||||
GObject *object;
|
||||
|
||||
object = g_object_new (test_type, NULL);
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
|
||||
/* Make sure we have the only reference */
|
||||
if (g_object_is_floating (object))
|
||||
g_object_ref_sink (object);
|
||||
|
||||
/* Assert that the object finalizes properly */
|
||||
g_object_weak_ref (object, check_finalized, &finalized);
|
||||
|
||||
/* Toplevels are owned by GTK+, just tell GTK+ to destroy it */
|
||||
if (GTK_IS_WINDOW (object) || GTK_IS_INVISIBLE (object))
|
||||
gtk_widget_destroy (GTK_WIDGET (object));
|
||||
else
|
||||
g_object_unref (object);
|
||||
|
||||
/* Even if the object did finalize, it may have left some dangerous stuff in the GMainContext */
|
||||
g_timeout_add (50, main_loop_quit_cb, NULL);
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const GType *all_types;
|
||||
guint n_types = 0, i;
|
||||
|
||||
/* initialize test program */
|
||||
gtk_test_init (&argc, &argv);
|
||||
gtk_test_register_all_types ();
|
||||
|
||||
all_types = gtk_test_list_all_types (&n_types);
|
||||
|
||||
for (i = 0; i < n_types; i++)
|
||||
{
|
||||
if (g_type_is_a (all_types[i], G_TYPE_OBJECT) &&
|
||||
G_TYPE_IS_INSTANTIATABLE (all_types[i]) &&
|
||||
!G_TYPE_IS_ABSTRACT (all_types[i]) &&
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
all_types[i] != GDK_TYPE_X11_WINDOW &&
|
||||
all_types[i] != GDK_TYPE_X11_CURSOR &&
|
||||
all_types[i] != GDK_TYPE_X11_SCREEN &&
|
||||
all_types[i] != GDK_TYPE_X11_DISPLAY &&
|
||||
all_types[i] != GDK_TYPE_X11_DEVICE_MANAGER_XI2 &&
|
||||
all_types[i] != GDK_TYPE_X11_DISPLAY_MANAGER &&
|
||||
#endif
|
||||
/* Not allowed to finalize a GdkPixbufLoader without calling gdk_pixbuf_loader_close() */
|
||||
all_types[i] != GDK_TYPE_PIXBUF_LOADER &&
|
||||
all_types[i] != gdk_pixbuf_simple_anim_iter_get_type())
|
||||
{
|
||||
gchar *test_path = g_strdup_printf ("/FinalizeObject/%s", g_type_name (all_types[i]));
|
||||
|
||||
g_test_add_data_func (test_path, GSIZE_TO_POINTER (all_types[i]), test_finalize_object);
|
||||
|
||||
g_free (test_path);
|
||||
}
|
||||
}
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
126
testsuite/gtk/papersize.c
Normal file
126
testsuite/gtk/papersize.c
Normal file
@ -0,0 +1,126 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_parse (void)
|
||||
{
|
||||
GtkPaperSize *p;
|
||||
|
||||
p = gtk_paper_size_new (GTK_PAPER_NAME_A4);
|
||||
g_assert (p != NULL);
|
||||
g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
|
||||
g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
|
||||
g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_a4");
|
||||
g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "A4");
|
||||
g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "A4");
|
||||
g_assert (!gtk_paper_size_is_custom (p));
|
||||
gtk_paper_size_free (p);
|
||||
|
||||
p = gtk_paper_size_new (GTK_PAPER_NAME_B5);
|
||||
g_assert (p != NULL);
|
||||
g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 176);
|
||||
g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 250);
|
||||
g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_b5");
|
||||
g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "B5");
|
||||
g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "ISOB5");
|
||||
g_assert (!gtk_paper_size_is_custom (p));
|
||||
gtk_paper_size_free (p);
|
||||
|
||||
p = gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE);
|
||||
g_assert (p != NULL);
|
||||
g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 184);
|
||||
g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 266);
|
||||
g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "na_executive");
|
||||
g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "Executive");
|
||||
g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "Executive");
|
||||
g_assert (!gtk_paper_size_is_custom (p));
|
||||
gtk_paper_size_free (p);
|
||||
|
||||
p = gtk_paper_size_new ("iso_a4_210x297mm");
|
||||
g_assert (p != NULL);
|
||||
g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
|
||||
g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
|
||||
g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_a4");
|
||||
g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "A4");
|
||||
g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "A4");
|
||||
g_assert (!gtk_paper_size_is_custom (p));
|
||||
gtk_paper_size_free (p);
|
||||
|
||||
p = gtk_paper_size_new ("custom_w1_20x30in");
|
||||
g_assert (p != NULL);
|
||||
g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_INCH), ==, 20);
|
||||
g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_INCH), ==, 30);
|
||||
g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "custom_w1");
|
||||
g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "custom_w1");
|
||||
g_assert (gtk_paper_size_is_custom (p));
|
||||
gtk_paper_size_free (p);
|
||||
}
|
||||
|
||||
static void
|
||||
test_compare (void)
|
||||
{
|
||||
GtkPaperSize *a1, *a2, *b, *c;
|
||||
|
||||
a1 = gtk_paper_size_new (GTK_PAPER_NAME_A4);
|
||||
a2 = gtk_paper_size_new ("iso_a4_210x297mm");
|
||||
b = gtk_paper_size_new (GTK_PAPER_NAME_B5);
|
||||
c = gtk_paper_size_new ("custom_w1_20x30in");
|
||||
|
||||
g_assert (gtk_paper_size_is_equal (a1, a2));
|
||||
g_assert (!gtk_paper_size_is_equal (a1, b));
|
||||
g_assert (!gtk_paper_size_is_equal (a1, c));
|
||||
g_assert (!gtk_paper_size_is_equal (b, c));
|
||||
|
||||
gtk_paper_size_free (a1);
|
||||
gtk_paper_size_free (a2);
|
||||
gtk_paper_size_free (b);
|
||||
gtk_paper_size_free (c);
|
||||
}
|
||||
|
||||
static void
|
||||
test_units (void)
|
||||
{
|
||||
GtkPaperSize *p;
|
||||
|
||||
p = gtk_paper_size_new (GTK_PAPER_NAME_A4);
|
||||
|
||||
g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
|
||||
g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
|
||||
|
||||
/* compare up to 2 decimals */
|
||||
g_assert_cmpint (100 * gtk_paper_size_get_width (p, GTK_UNIT_INCH), ==, 100 * 8.26);
|
||||
g_assert_cmpint (100 * gtk_paper_size_get_height (p, GTK_UNIT_INCH), ==, 100 * 11.69);
|
||||
|
||||
g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_POINTS), ==, 595);
|
||||
g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_POINTS), ==, 841);
|
||||
|
||||
gtk_paper_size_free (p);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/paper-size/parse", test_parse);
|
||||
g_test_add_func ("/paper-size/compare", test_compare);
|
||||
g_test_add_func ("/paper-size/units", test_units);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
525
testsuite/gtk/rbtree.c
Normal file
525
testsuite/gtk/rbtree.c
Normal file
@ -0,0 +1,525 @@
|
||||
/* GtkRBTree tests.
|
||||
*
|
||||
* Copyright (C) 2011, Red Hat, Inc.
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include "../../gtk/gtkrbtree.h"
|
||||
|
||||
/* _gtk_rbtree_test */
|
||||
|
||||
static guint
|
||||
get_total_count (GtkRBNode *node)
|
||||
{
|
||||
guint child_total = 0;
|
||||
|
||||
child_total += (guint) node->left->total_count;
|
||||
child_total += (guint) node->right->total_count;
|
||||
|
||||
if (node->children)
|
||||
child_total += (guint) node->children->root->total_count;
|
||||
|
||||
return child_total + 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
count_total (GtkRBTree *tree,
|
||||
GtkRBNode *node)
|
||||
{
|
||||
guint res;
|
||||
|
||||
if (_gtk_rbtree_is_nil (node))
|
||||
return 0;
|
||||
|
||||
res =
|
||||
count_total (tree, node->left) +
|
||||
count_total (tree, node->right) +
|
||||
(guint)1 +
|
||||
(node->children ? count_total (node->children, node->children->root) : 0);
|
||||
|
||||
if (res != node->total_count)
|
||||
g_print ("total count incorrect for node\n");
|
||||
|
||||
if (get_total_count (node) != node->total_count)
|
||||
g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gint
|
||||
_count_nodes (GtkRBTree *tree,
|
||||
GtkRBNode *node)
|
||||
{
|
||||
gint res;
|
||||
if (_gtk_rbtree_is_nil (node))
|
||||
return 0;
|
||||
|
||||
g_assert (node->left);
|
||||
g_assert (node->right);
|
||||
|
||||
res = (_count_nodes (tree, node->left) +
|
||||
_count_nodes (tree, node->right) + 1);
|
||||
|
||||
if (res != node->count)
|
||||
g_print ("Tree failed\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_rbtree_test_height (GtkRBTree *tree,
|
||||
GtkRBNode *node)
|
||||
{
|
||||
gint computed_offset = 0;
|
||||
|
||||
/* This whole test is sort of a useless truism. */
|
||||
|
||||
if (!_gtk_rbtree_is_nil (node->left))
|
||||
computed_offset += node->left->offset;
|
||||
|
||||
if (!_gtk_rbtree_is_nil (node->right))
|
||||
computed_offset += node->right->offset;
|
||||
|
||||
if (node->children && !_gtk_rbtree_is_nil (node->children->root))
|
||||
computed_offset += node->children->root->offset;
|
||||
|
||||
if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
|
||||
g_error ("node has broken offset\n");
|
||||
|
||||
if (!_gtk_rbtree_is_nil (node->left))
|
||||
_gtk_rbtree_test_height (tree, node->left);
|
||||
|
||||
if (!_gtk_rbtree_is_nil (node->right))
|
||||
_gtk_rbtree_test_height (tree, node->right);
|
||||
|
||||
if (node->children && !_gtk_rbtree_is_nil (node->children->root))
|
||||
_gtk_rbtree_test_height (node->children, node->children->root);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_rbtree_test_dirty (GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
gint expected_dirtyness)
|
||||
{
|
||||
|
||||
if (expected_dirtyness)
|
||||
{
|
||||
g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
|
||||
GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID) ||
|
||||
GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID) ||
|
||||
(node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) &&
|
||||
! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID));
|
||||
if (!_gtk_rbtree_is_nil (node->left))
|
||||
g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
|
||||
if (!_gtk_rbtree_is_nil (node->right))
|
||||
g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
|
||||
if (node->children != NULL)
|
||||
g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
|
||||
}
|
||||
|
||||
if (!_gtk_rbtree_is_nil (node->left))
|
||||
_gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
|
||||
if (!_gtk_rbtree_is_nil (node->right))
|
||||
_gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
|
||||
if (node->children != NULL && !_gtk_rbtree_is_nil (node->children->root))
|
||||
_gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
|
||||
}
|
||||
|
||||
static void _gtk_rbtree_test_structure (GtkRBTree *tree);
|
||||
|
||||
static guint
|
||||
_gtk_rbtree_test_structure_helper (GtkRBTree *tree,
|
||||
GtkRBNode *node)
|
||||
{
|
||||
guint left_blacks, right_blacks;
|
||||
|
||||
g_assert (!_gtk_rbtree_is_nil (node));
|
||||
|
||||
g_assert (node->left != NULL);
|
||||
g_assert (node->right != NULL);
|
||||
g_assert (node->parent != NULL);
|
||||
|
||||
if (!_gtk_rbtree_is_nil (node->left))
|
||||
{
|
||||
g_assert (node->left->parent == node);
|
||||
left_blacks = _gtk_rbtree_test_structure_helper (tree, node->left);
|
||||
}
|
||||
else
|
||||
left_blacks = 0;
|
||||
|
||||
if (!_gtk_rbtree_is_nil (node->right))
|
||||
{
|
||||
g_assert (node->right->parent == node);
|
||||
right_blacks = _gtk_rbtree_test_structure_helper (tree, node->right);
|
||||
}
|
||||
else
|
||||
right_blacks = 0;
|
||||
|
||||
if (node->children != NULL)
|
||||
{
|
||||
g_assert (node->children->parent_tree == tree);
|
||||
g_assert (node->children->parent_node == node);
|
||||
|
||||
_gtk_rbtree_test_structure (node->children);
|
||||
}
|
||||
|
||||
g_assert (left_blacks == right_blacks);
|
||||
|
||||
return left_blacks + (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_rbtree_test_structure (GtkRBTree *tree)
|
||||
{
|
||||
g_assert (tree->root);
|
||||
if (_gtk_rbtree_is_nil (tree->root))
|
||||
return;
|
||||
|
||||
g_assert (_gtk_rbtree_is_nil (tree->root->parent));
|
||||
_gtk_rbtree_test_structure_helper (tree, tree->root);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_rbtree_test (GtkRBTree *tree)
|
||||
{
|
||||
GtkRBTree *tmp_tree;
|
||||
|
||||
if (tree == NULL)
|
||||
return;
|
||||
|
||||
/* Test the entire tree */
|
||||
tmp_tree = tree;
|
||||
while (tmp_tree->parent_tree)
|
||||
tmp_tree = tmp_tree->parent_tree;
|
||||
|
||||
if (_gtk_rbtree_is_nil (tmp_tree->root))
|
||||
return;
|
||||
|
||||
_gtk_rbtree_test_structure (tmp_tree);
|
||||
|
||||
g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
|
||||
_count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
|
||||
|
||||
_gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
|
||||
_gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID));
|
||||
g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count);
|
||||
}
|
||||
|
||||
/* gtk_rbtree_print() - unused, for debugging only */
|
||||
|
||||
static void
|
||||
gtk_rbtree_print_node (GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
gint depth)
|
||||
{
|
||||
gint i;
|
||||
for (i = 0; i < depth; i++)
|
||||
g_print ("\t");
|
||||
|
||||
g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
|
||||
node,
|
||||
(GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
|
||||
node->offset,
|
||||
node->total_count,
|
||||
(GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0,
|
||||
(GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0,
|
||||
(GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0);
|
||||
if (node->children != NULL)
|
||||
{
|
||||
g_print ("Looking at child.\n");
|
||||
gtk_rbtree_print_node (node->children, node->children->root, depth + 1);
|
||||
g_print ("Done looking at child.\n");
|
||||
}
|
||||
if (!_gtk_rbtree_is_nil (node->left))
|
||||
{
|
||||
gtk_rbtree_print_node (tree, node->left, depth+1);
|
||||
}
|
||||
if (!_gtk_rbtree_is_nil (node->right))
|
||||
{
|
||||
gtk_rbtree_print_node (tree, node->right, depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* not static so the debugger finds it. */
|
||||
void gtk_rbtree_print (GtkRBTree *tree);
|
||||
|
||||
void
|
||||
gtk_rbtree_print (GtkRBTree *tree)
|
||||
{
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
if (_gtk_rbtree_is_nil (tree->root))
|
||||
g_print ("Empty tree...\n");
|
||||
else
|
||||
gtk_rbtree_print_node (tree, tree->root, 0);
|
||||
}
|
||||
|
||||
/* actual tests */
|
||||
|
||||
static guint
|
||||
append_elements (GtkRBTree *tree,
|
||||
guint depth,
|
||||
guint elements_per_depth,
|
||||
gboolean check,
|
||||
guint height)
|
||||
{
|
||||
GtkRBNode *node;
|
||||
guint i;
|
||||
|
||||
g_assert (depth > 0);
|
||||
|
||||
node = NULL;
|
||||
depth--;
|
||||
|
||||
for (i = 0; i < elements_per_depth; i++)
|
||||
{
|
||||
node = _gtk_rbtree_insert_after (tree, node, ++height, TRUE);
|
||||
if (depth)
|
||||
{
|
||||
node->children = _gtk_rbtree_new ();
|
||||
node->children->parent_tree = tree;
|
||||
node->children->parent_node = node;
|
||||
height = append_elements (node->children, depth, elements_per_depth, check, height);
|
||||
}
|
||||
if (check)
|
||||
_gtk_rbtree_test (tree);
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
static GtkRBTree *
|
||||
create_rbtree (guint depth,
|
||||
guint elements_per_depth,
|
||||
gboolean check)
|
||||
{
|
||||
GtkRBTree *tree;
|
||||
|
||||
tree = _gtk_rbtree_new ();
|
||||
|
||||
append_elements (tree, depth, elements_per_depth, check, 0);
|
||||
|
||||
_gtk_rbtree_test (tree);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
static void
|
||||
test_create (void)
|
||||
{
|
||||
GtkRBTree *tree;
|
||||
|
||||
tree = create_rbtree (5, 5, TRUE);
|
||||
|
||||
_gtk_rbtree_free (tree);
|
||||
}
|
||||
|
||||
static void
|
||||
test_insert_after (void)
|
||||
{
|
||||
guint i;
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
|
||||
tree = _gtk_rbtree_new ();
|
||||
node = NULL;
|
||||
|
||||
for (i = 1; i <= 100; i++)
|
||||
{
|
||||
node = _gtk_rbtree_insert_after (tree, node, i, TRUE);
|
||||
_gtk_rbtree_test (tree);
|
||||
g_assert (tree->root->count == i);
|
||||
g_assert (tree->root->total_count == i);
|
||||
g_assert (tree->root->offset == i * (i + 1) / 2);
|
||||
}
|
||||
|
||||
_gtk_rbtree_free (tree);
|
||||
}
|
||||
|
||||
static void
|
||||
test_insert_before (void)
|
||||
{
|
||||
guint i;
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
|
||||
tree = _gtk_rbtree_new ();
|
||||
node = NULL;
|
||||
|
||||
for (i = 1; i <= 100; i++)
|
||||
{
|
||||
node = _gtk_rbtree_insert_before (tree, node, i, TRUE);
|
||||
_gtk_rbtree_test (tree);
|
||||
g_assert (tree->root->count == i);
|
||||
g_assert (tree->root->total_count == i);
|
||||
g_assert (tree->root->offset == i * (i + 1) / 2);
|
||||
}
|
||||
|
||||
_gtk_rbtree_free (tree);
|
||||
}
|
||||
|
||||
static void
|
||||
test_remove_node (void)
|
||||
{
|
||||
GtkRBTree *tree;
|
||||
|
||||
tree = create_rbtree (3, 16, g_test_thorough ());
|
||||
|
||||
while (tree->root->count > 1)
|
||||
{
|
||||
GtkRBTree *find_tree;
|
||||
GtkRBNode *find_node;
|
||||
guint i;
|
||||
|
||||
i = g_test_rand_int_range (0, tree->root->total_count);
|
||||
if (!_gtk_rbtree_find_index (tree, i, &find_tree, &find_node))
|
||||
{
|
||||
/* We search an available index, so we mustn't fail. */
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
_gtk_rbtree_test (find_tree);
|
||||
|
||||
if (find_tree->root->count == 1)
|
||||
{
|
||||
_gtk_rbtree_remove (find_tree);
|
||||
}
|
||||
else
|
||||
_gtk_rbtree_remove_node (find_tree, find_node);
|
||||
_gtk_rbtree_test (tree);
|
||||
}
|
||||
|
||||
_gtk_rbtree_free (tree);
|
||||
}
|
||||
|
||||
static void
|
||||
test_remove_root (void)
|
||||
{
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
|
||||
tree = _gtk_rbtree_new ();
|
||||
|
||||
node = _gtk_rbtree_insert_after (tree, NULL, 1, TRUE);
|
||||
_gtk_rbtree_insert_after (tree, node, 2, TRUE);
|
||||
_gtk_rbtree_insert_before (tree, node, 3, TRUE);
|
||||
|
||||
_gtk_rbtree_remove_node (tree, node);
|
||||
|
||||
_gtk_rbtree_free (tree);
|
||||
}
|
||||
|
||||
static gint *
|
||||
fisher_yates_shuffle (guint n_items)
|
||||
{
|
||||
gint *list;
|
||||
guint i, j;
|
||||
|
||||
list = g_new (gint, n_items);
|
||||
|
||||
for (i = 0; i < n_items; i++)
|
||||
{
|
||||
j = g_random_int_range (0, i + 1);
|
||||
list[i] = list[j];
|
||||
list[j] = i;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static GtkRBTree *
|
||||
create_unsorted_tree (gint *order,
|
||||
guint n)
|
||||
{
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
guint i;
|
||||
|
||||
tree = _gtk_rbtree_new ();
|
||||
node = NULL;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
node = _gtk_rbtree_insert_after (tree, node, 0, TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
node = _gtk_rbtree_find_count (tree, order[i] + 1);
|
||||
_gtk_rbtree_node_set_height (tree, node, i);
|
||||
}
|
||||
|
||||
_gtk_rbtree_test (tree);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
static void
|
||||
test_reorder (void)
|
||||
{
|
||||
guint n = g_test_perf () ? 1000000 : 100;
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
gint *reorder;
|
||||
guint i;
|
||||
double elapsed;
|
||||
|
||||
reorder = fisher_yates_shuffle (n);
|
||||
tree = create_unsorted_tree (reorder, n);
|
||||
|
||||
g_test_timer_start ();
|
||||
|
||||
_gtk_rbtree_reorder (tree, reorder, n);
|
||||
|
||||
elapsed = g_test_timer_elapsed ();
|
||||
if (g_test_perf ())
|
||||
g_test_minimized_result (elapsed, "reordering rbtree with %u items: %gsec", n, elapsed);
|
||||
|
||||
_gtk_rbtree_test (tree);
|
||||
|
||||
for (node = _gtk_rbtree_first (tree), i = 0;
|
||||
node != NULL;
|
||||
node = _gtk_rbtree_next (tree, node), i++)
|
||||
{
|
||||
g_assert (GTK_RBNODE_GET_HEIGHT (node) == i);
|
||||
}
|
||||
g_assert (i == n);
|
||||
|
||||
_gtk_rbtree_free (tree);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
g_test_add_func ("/rbtree/create", test_create);
|
||||
g_test_add_func ("/rbtree/insert_after", test_insert_after);
|
||||
g_test_add_func ("/rbtree/insert_before", test_insert_before);
|
||||
g_test_add_func ("/rbtree/remove_node", test_remove_node);
|
||||
g_test_add_func ("/rbtree/remove_root", test_remove_root);
|
||||
g_test_add_func ("/rbtree/reorder", test_reorder);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
309
testsuite/gtk/recentmanager.c
Normal file
309
testsuite/gtk/recentmanager.c
Normal file
@ -0,0 +1,309 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkrecentmanager.c: a manager for the recently used resources
|
||||
*
|
||||
* Copyright (C) 2006 Emmanuele Bassi
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
const gchar *uri = "file:///tmp/testrecentchooser.txt";
|
||||
const gchar *uri2 = "file:///tmp/testrecentchooser2.txt";
|
||||
|
||||
static void
|
||||
recent_manager_get_default (void)
|
||||
{
|
||||
GtkRecentManager *manager;
|
||||
GtkRecentManager *manager2;
|
||||
|
||||
manager = gtk_recent_manager_get_default ();
|
||||
g_assert (manager != NULL);
|
||||
|
||||
manager2 = gtk_recent_manager_get_default ();
|
||||
g_assert (manager == manager2);
|
||||
}
|
||||
|
||||
static void
|
||||
recent_manager_add (void)
|
||||
{
|
||||
GtkRecentManager *manager;
|
||||
GtkRecentData *recent_data;
|
||||
gboolean res;
|
||||
|
||||
manager = gtk_recent_manager_get_default ();
|
||||
|
||||
recent_data = g_slice_new0 (GtkRecentData);
|
||||
|
||||
/* mime type is mandatory */
|
||||
recent_data->mime_type = NULL;
|
||||
recent_data->app_name = "testrecentchooser";
|
||||
recent_data->app_exec = "testrecentchooser %u";
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
res = gtk_recent_manager_add_full (manager,
|
||||
uri,
|
||||
recent_data);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
|
||||
/* app name is mandatory */
|
||||
recent_data->mime_type = "text/plain";
|
||||
recent_data->app_name = NULL;
|
||||
recent_data->app_exec = "testrecentchooser %u";
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
res = gtk_recent_manager_add_full (manager,
|
||||
uri,
|
||||
recent_data);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
|
||||
/* app exec is mandatory */
|
||||
recent_data->mime_type = "text/plain";
|
||||
recent_data->app_name = "testrecentchooser";
|
||||
recent_data->app_exec = NULL;
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
res = gtk_recent_manager_add_full (manager,
|
||||
uri,
|
||||
recent_data);
|
||||
}
|
||||
g_test_trap_assert_failed ();
|
||||
|
||||
recent_data->mime_type = "text/plain";
|
||||
recent_data->app_name = "testrecentchooser";
|
||||
recent_data->app_exec = "testrecentchooser %u";
|
||||
res = gtk_recent_manager_add_full (manager,
|
||||
uri,
|
||||
recent_data);
|
||||
g_assert (res == TRUE);
|
||||
|
||||
g_slice_free (GtkRecentData, recent_data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GMainLoop *main_loop;
|
||||
gint counter;
|
||||
} AddManyClosure;
|
||||
|
||||
static void
|
||||
check_bulk (GtkRecentManager *manager,
|
||||
gpointer data)
|
||||
{
|
||||
AddManyClosure *closure = data;
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print (G_STRLOC ": counter = %d\n", closure->counter);
|
||||
|
||||
g_assert_cmpint (closure->counter, ==, 100);
|
||||
|
||||
if (g_main_loop_is_running (closure->main_loop))
|
||||
g_main_loop_quit (closure->main_loop);
|
||||
}
|
||||
|
||||
static void
|
||||
recent_manager_add_many (void)
|
||||
{
|
||||
GtkRecentManager *manager = g_object_new (GTK_TYPE_RECENT_MANAGER,
|
||||
"filename", "recently-used.xbel",
|
||||
NULL);
|
||||
AddManyClosure *closure = g_new (AddManyClosure, 1);
|
||||
GtkRecentData *data = g_slice_new0 (GtkRecentData);
|
||||
gint i;
|
||||
|
||||
closure->main_loop = g_main_loop_new (NULL, FALSE);
|
||||
closure->counter = 0;
|
||||
|
||||
g_signal_connect (manager, "changed", G_CALLBACK (check_bulk), closure);
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
gchar *new_uri;
|
||||
|
||||
data->mime_type = "text/plain";
|
||||
data->app_name = "testrecentchooser";
|
||||
data->app_exec = "testrecentchooser %u";
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print (G_STRLOC ": adding item %d\n", i);
|
||||
|
||||
new_uri = g_strdup_printf ("file:///doesnotexist-%d.txt", i);
|
||||
gtk_recent_manager_add_full (manager, new_uri, data);
|
||||
g_free (new_uri);
|
||||
|
||||
closure->counter += 1;
|
||||
}
|
||||
|
||||
g_main_loop_run (closure->main_loop);
|
||||
|
||||
g_main_loop_unref (closure->main_loop);
|
||||
g_slice_free (GtkRecentData, data);
|
||||
g_free (closure);
|
||||
g_object_unref (manager);
|
||||
|
||||
g_assert_cmpint (g_unlink ("recently-used.xbel"), ==, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
recent_manager_has_item (void)
|
||||
{
|
||||
GtkRecentManager *manager;
|
||||
gboolean res;
|
||||
|
||||
manager = gtk_recent_manager_get_default ();
|
||||
|
||||
res = gtk_recent_manager_has_item (manager, "file:///tmp/testrecentdoesnotexist.txt");
|
||||
g_assert (res == FALSE);
|
||||
|
||||
res = gtk_recent_manager_has_item (manager, uri);
|
||||
g_assert (res == TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
recent_manager_move_item (void)
|
||||
{
|
||||
GtkRecentManager *manager;
|
||||
gboolean res;
|
||||
GError *error;
|
||||
|
||||
manager = gtk_recent_manager_get_default ();
|
||||
|
||||
error = NULL;
|
||||
res = gtk_recent_manager_move_item (manager,
|
||||
"file:///tmp/testrecentdoesnotexist.txt",
|
||||
uri2,
|
||||
&error);
|
||||
g_assert (res == FALSE);
|
||||
g_assert (error != NULL);
|
||||
g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
|
||||
g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
|
||||
g_error_free (error);
|
||||
|
||||
error = NULL;
|
||||
res = gtk_recent_manager_move_item (manager, uri, uri2, &error);
|
||||
g_assert (res == TRUE);
|
||||
g_assert (error == NULL);
|
||||
|
||||
res = gtk_recent_manager_has_item (manager, uri);
|
||||
g_assert (res == FALSE);
|
||||
|
||||
res = gtk_recent_manager_has_item (manager, uri2);
|
||||
g_assert (res == TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
recent_manager_lookup_item (void)
|
||||
{
|
||||
GtkRecentManager *manager;
|
||||
GtkRecentInfo *info;
|
||||
GError *error;
|
||||
|
||||
manager = gtk_recent_manager_get_default ();
|
||||
|
||||
error = NULL;
|
||||
info = gtk_recent_manager_lookup_item (manager,
|
||||
"file:///tmp/testrecentdoesnotexist.txt",
|
||||
&error);
|
||||
g_assert (info == NULL);
|
||||
g_assert (error != NULL);
|
||||
g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
|
||||
g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
|
||||
g_error_free (error);
|
||||
|
||||
error = NULL;
|
||||
info = gtk_recent_manager_lookup_item (manager, uri2, &error);
|
||||
g_assert (info != NULL);
|
||||
g_assert (error == NULL);
|
||||
|
||||
g_assert (gtk_recent_info_has_application (info, "testrecentchooser"));
|
||||
|
||||
gtk_recent_info_unref (info);
|
||||
}
|
||||
|
||||
static void
|
||||
recent_manager_remove_item (void)
|
||||
{
|
||||
GtkRecentManager *manager;
|
||||
gboolean res;
|
||||
GError *error;
|
||||
|
||||
manager = gtk_recent_manager_get_default ();
|
||||
|
||||
error = NULL;
|
||||
res = gtk_recent_manager_remove_item (manager,
|
||||
"file:///tmp/testrecentdoesnotexist.txt",
|
||||
&error);
|
||||
g_assert (res == FALSE);
|
||||
g_assert (error != NULL);
|
||||
g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
|
||||
g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
|
||||
g_error_free (error);
|
||||
|
||||
/* remove an item that's actually there */
|
||||
error = NULL;
|
||||
res = gtk_recent_manager_remove_item (manager, uri2, &error);
|
||||
g_assert (res == TRUE);
|
||||
g_assert (error == NULL);
|
||||
|
||||
res = gtk_recent_manager_has_item (manager, uri2);
|
||||
g_assert (res == FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
recent_manager_purge (void)
|
||||
{
|
||||
GtkRecentManager *manager;
|
||||
GtkRecentData *recent_data;
|
||||
gint n;
|
||||
GError *error;
|
||||
|
||||
manager = gtk_recent_manager_get_default ();
|
||||
|
||||
/* purge, add 1, purge again and check that 1 item has been purged */
|
||||
error = NULL;
|
||||
n = gtk_recent_manager_purge_items (manager, &error);
|
||||
g_assert (error == NULL);
|
||||
|
||||
recent_data = g_slice_new0 (GtkRecentData);
|
||||
recent_data->mime_type = "text/plain";
|
||||
recent_data->app_name = "testrecentchooser";
|
||||
recent_data->app_exec = "testrecentchooser %u";
|
||||
gtk_recent_manager_add_full (manager, uri, recent_data);
|
||||
g_slice_free (GtkRecentData, recent_data);
|
||||
|
||||
error = NULL;
|
||||
n = gtk_recent_manager_purge_items (manager, &error);
|
||||
g_assert (error == NULL);
|
||||
g_assert (n == 1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/recent-manager/get-default", recent_manager_get_default);
|
||||
g_test_add_func ("/recent-manager/add", recent_manager_add);
|
||||
g_test_add_func ("/recent-manager/add-many", recent_manager_add_many);
|
||||
g_test_add_func ("/recent-manager/has-item", recent_manager_has_item);
|
||||
g_test_add_func ("/recent-manager/move-item", recent_manager_move_item);
|
||||
g_test_add_func ("/recent-manager/lookup-item", recent_manager_lookup_item);
|
||||
g_test_add_func ("/recent-manager/remove-item", recent_manager_remove_item);
|
||||
g_test_add_func ("/recent-manager/purge", recent_manager_purge);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
68
testsuite/gtk/regression-tests.c
Normal file
68
testsuite/gtk/regression-tests.c
Normal file
@ -0,0 +1,68 @@
|
||||
/* Regression tests
|
||||
*
|
||||
* Copyright (C) 2011, Red Hat, Inc.
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_9d6da33ff5c5e41e3521e1afd63d2d67bc915753 (void)
|
||||
{
|
||||
GtkWidget *window, *label;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
label = gtk_label_new ("I am sensitive.");
|
||||
gtk_container_add (GTK_CONTAINER (window), label);
|
||||
|
||||
gtk_widget_set_sensitive (label, FALSE);
|
||||
gtk_widget_set_sensitive (window, FALSE);
|
||||
gtk_widget_set_sensitive (label, TRUE);
|
||||
gtk_widget_set_sensitive (window, TRUE);
|
||||
|
||||
g_assert (gtk_widget_get_sensitive (label));
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
static void
|
||||
test_94f00eb04dd1433cf1cc9a3341f485124e38abd1 (void)
|
||||
{
|
||||
GtkWidget *window, *label;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
label = gtk_label_new ("I am insensitive.");
|
||||
gtk_container_add (GTK_CONTAINER (window), label);
|
||||
|
||||
gtk_widget_set_sensitive (window, FALSE);
|
||||
gtk_widget_set_sensitive (label, FALSE);
|
||||
gtk_widget_set_sensitive (label, TRUE);
|
||||
|
||||
g_assert (!gtk_widget_is_sensitive (label));
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/regression/94f00eb04dd1433cf1cc9a3341f485124e38abd1", test_94f00eb04dd1433cf1cc9a3341f485124e38abd1);
|
||||
g_test_add_func ("/regression/9d6da33ff5c5e41e3521e1afd63d2d67bc915753", test_9d6da33ff5c5e41e3521e1afd63d2d67bc915753);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
1243
testsuite/gtk/sortmodel.c
Normal file
1243
testsuite/gtk/sortmodel.c
Normal file
File diff suppressed because it is too large
Load Diff
359
testsuite/gtk/stylecontext.c
Normal file
359
testsuite/gtk/stylecontext.c
Normal file
@ -0,0 +1,359 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_parse_selectors (void)
|
||||
{
|
||||
GtkCssProvider *provider;
|
||||
GError *error;
|
||||
gboolean res;
|
||||
gint i;
|
||||
const gchar *valid[] = {
|
||||
"* {}",
|
||||
"E {}",
|
||||
"E F {}",
|
||||
"E > F {}",
|
||||
"E#id {}",
|
||||
"#id {}",
|
||||
"tab:first-child {}",
|
||||
"tab:last-child {}",
|
||||
"tab:nth-child(first) {}",
|
||||
"tab:nth-child(last) {}",
|
||||
"tab:nth-child(even) {}",
|
||||
"tab:nth-child(odd) {}",
|
||||
"tab:sorted {}",
|
||||
".some-class {}",
|
||||
".some-class.another-class {}",
|
||||
".some-class .another-class {}",
|
||||
"E * {}",
|
||||
"E .class {}",
|
||||
"E > .foo {}",
|
||||
"E > #id {}",
|
||||
"E:active {}",
|
||||
"E:prelight {}",
|
||||
"E:hover {}",
|
||||
"E:selected {}",
|
||||
"E:insensitive {}",
|
||||
"E:inconsistent {}",
|
||||
"E:focused {}",
|
||||
"E:active:prelight {}",
|
||||
"* > .notebook tab:first-child .label:focused {}",
|
||||
"E, F {}",
|
||||
"E, F /* comment here */ {}",
|
||||
"E,/* comment here */ F {}",
|
||||
"E1.e1_2 #T3_4 {}",
|
||||
"E:first-child {}",
|
||||
"E:last-child {}",
|
||||
"E:nth-child(first) {}",
|
||||
"E:nth-child(last) {}",
|
||||
"E:nth-child(even) {}",
|
||||
"E:nth-child(odd) {}",
|
||||
"E:sorted {}",
|
||||
"E:focused tab {}",
|
||||
NULL
|
||||
};
|
||||
|
||||
error = NULL;
|
||||
for (i = 0; valid[i]; i++)
|
||||
{
|
||||
provider = gtk_css_provider_new ();
|
||||
res = gtk_css_provider_load_from_data (provider, valid[i], -1, &error);
|
||||
if (error)
|
||||
g_print ("parsing '%s': got unexpected error: %s\n", valid[i], error->message);
|
||||
g_assert_no_error (error);
|
||||
g_assert (res);
|
||||
|
||||
g_object_unref (provider);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_path (void)
|
||||
{
|
||||
GtkWidgetPath *path;
|
||||
GtkWidgetPath *path2;
|
||||
gint pos;
|
||||
GtkRegionFlags flags;
|
||||
|
||||
path = gtk_widget_path_new ();
|
||||
g_assert_cmpint (gtk_widget_path_length (path), ==, 0);
|
||||
|
||||
pos = gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
|
||||
g_assert_cmpint (pos, ==, 0);
|
||||
g_assert_cmpint (gtk_widget_path_length (path), ==, 1);
|
||||
g_assert (gtk_widget_path_iter_get_object_type (path, 0) == GTK_TYPE_WINDOW);
|
||||
g_assert (gtk_widget_path_is_type (path, GTK_TYPE_WIDGET));
|
||||
g_assert (gtk_widget_path_iter_get_name (path, 0) == NULL);
|
||||
|
||||
pos = gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
|
||||
g_assert_cmpint (pos, ==, 1);
|
||||
g_assert_cmpint (gtk_widget_path_length (path), ==, 2);
|
||||
gtk_widget_path_iter_set_object_type (path, pos, GTK_TYPE_BUTTON);
|
||||
g_assert (gtk_widget_path_is_type (path, GTK_TYPE_BUTTON));
|
||||
g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WIDGET));
|
||||
g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WINDOW));
|
||||
g_assert (!gtk_widget_path_has_parent (path, GTK_TYPE_DIALOG));
|
||||
g_assert (gtk_widget_path_iter_get_name (path, 1) == NULL);
|
||||
|
||||
gtk_widget_path_iter_set_name (path, 1, "name");
|
||||
g_assert (gtk_widget_path_iter_has_name (path, 1, "name"));
|
||||
|
||||
gtk_widget_path_iter_add_class (path, 1, "class1");
|
||||
gtk_widget_path_iter_add_class (path, 1, "class2");
|
||||
g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
|
||||
g_assert (gtk_widget_path_iter_has_class (path, 1, "class2"));
|
||||
g_assert (!gtk_widget_path_iter_has_class (path, 1, "class3"));
|
||||
|
||||
path2 = gtk_widget_path_copy (path);
|
||||
g_assert (gtk_widget_path_iter_has_class (path2, 1, "class1"));
|
||||
g_assert (gtk_widget_path_iter_has_class (path2, 1, "class2"));
|
||||
g_assert (!gtk_widget_path_iter_has_class (path2, 1, "class3"));
|
||||
gtk_widget_path_free (path2);
|
||||
|
||||
gtk_widget_path_iter_remove_class (path, 1, "class2");
|
||||
g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
|
||||
g_assert (!gtk_widget_path_iter_has_class (path, 1, "class2"));
|
||||
gtk_widget_path_iter_clear_classes (path, 1);
|
||||
g_assert (!gtk_widget_path_iter_has_class (path, 1, "class1"));
|
||||
|
||||
gtk_widget_path_iter_add_region (path, 1, "tab", 0);
|
||||
gtk_widget_path_iter_add_region (path, 1, "title", GTK_REGION_EVEN | GTK_REGION_FIRST);
|
||||
|
||||
g_assert (gtk_widget_path_iter_has_region (path, 1, "tab", &flags) &&
|
||||
flags == 0);
|
||||
g_assert (gtk_widget_path_iter_has_region (path, 1, "title", &flags) &&
|
||||
flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
|
||||
g_assert (!gtk_widget_path_iter_has_region (path, 1, "extension", NULL));
|
||||
|
||||
path2 = gtk_widget_path_copy (path);
|
||||
g_assert (gtk_widget_path_iter_has_region (path2, 1, "tab", &flags) &&
|
||||
flags == 0);
|
||||
g_assert (gtk_widget_path_iter_has_region (path2, 1, "title", &flags) &&
|
||||
flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
|
||||
g_assert (!gtk_widget_path_iter_has_region (path2, 1, "extension", NULL));
|
||||
gtk_widget_path_free (path2);
|
||||
|
||||
gtk_widget_path_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_match (void)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkWidgetPath *path;
|
||||
GtkCssProvider *provider;
|
||||
GError *error;
|
||||
const gchar *data;
|
||||
GdkRGBA color;
|
||||
GdkRGBA expected;
|
||||
|
||||
error = NULL;
|
||||
provider = gtk_css_provider_new ();
|
||||
|
||||
gdk_rgba_parse (&expected, "#fff");
|
||||
|
||||
context = gtk_style_context_new ();
|
||||
|
||||
path = gtk_widget_path_new ();
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_BOX);
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
|
||||
gtk_widget_path_iter_set_name (path, 0, "mywindow");
|
||||
gtk_widget_path_iter_add_class (path, 2, "button");
|
||||
gtk_style_context_set_path (context, path);
|
||||
gtk_widget_path_free (path);
|
||||
|
||||
gtk_style_context_add_provider (context,
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
data = "* { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
"GtkButton { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
"GtkButton { color: #fff }\n"
|
||||
"GtkWindow > GtkButton { color: #000 }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
".button { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
"GtkButton { color: #000 }\n"
|
||||
".button { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
"GtkButton { color: #000 }\n"
|
||||
"GtkWindow GtkButton { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
".button { color: #000 }\n"
|
||||
"GtkWindow .button { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
"* .button { color: #000 }\n"
|
||||
"#mywindow .button { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
"GtkWindow .button { color: #000 }\n"
|
||||
"GtkWindow#mywindow .button { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
data = "* { color: #f00 }\n"
|
||||
"GtkWindow .button { color: #000 }\n"
|
||||
"GObject .button { color: #fff }";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_invalidate (context);
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
g_object_unref (provider);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
test_style_property (void)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkWidgetPath *path;
|
||||
GtkCssProvider *provider;
|
||||
GError *error;
|
||||
const gchar *data;
|
||||
gint x;
|
||||
GdkRGBA color;
|
||||
GdkRGBA expected;
|
||||
|
||||
error = NULL;
|
||||
provider = gtk_css_provider_new ();
|
||||
|
||||
context = gtk_style_context_new ();
|
||||
|
||||
path = gtk_widget_path_new ();
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_BOX);
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
|
||||
gtk_style_context_set_path (context, path);
|
||||
gtk_widget_path_free (path);
|
||||
gtk_style_context_set_state (context, GTK_STATE_FLAG_PRELIGHT);
|
||||
|
||||
/* Since we set the prelight state on the context, we expect
|
||||
* only the third selector to match, even though the second one
|
||||
* has higher specificity, and the fourth one comes later.
|
||||
*
|
||||
* In particular, we want to verify that widget style properties and
|
||||
* CSS properties follow the same matching rules, ie we expect
|
||||
* color to be #003 and child-displacement-x to be 3.
|
||||
*/
|
||||
data = "GtkButton:insensitive { color: #001; -GtkButton-child-displacement-x: 1 }\n"
|
||||
"GtkBox GtkButton:selected { color: #002; -GtkButton-child-displacement-x: 2 }\n"
|
||||
"GtkButton:prelight { color: #003; -GtkButton-child-displacement-x: 3 }\n"
|
||||
"GtkButton:focused { color: #004; -GtkButton-child-displacement-x: 4 }\n";
|
||||
gtk_css_provider_load_from_data (provider, data, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_add_provider (context,
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
gtk_style_context_invalidate (context);
|
||||
|
||||
gtk_style_context_get_color (context, GTK_STATE_FLAG_PRELIGHT, &color);
|
||||
gdk_rgba_parse (&expected, "#003");
|
||||
g_assert (gdk_rgba_equal (&color, &expected));
|
||||
|
||||
gtk_style_context_get_style (context, "child-displacement-x", &x, NULL);
|
||||
|
||||
g_assert_cmpint (x, ==, 3);
|
||||
|
||||
g_object_unref (provider);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
test_basic_properties (void)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkWidgetPath *path;
|
||||
GdkRGBA *color;
|
||||
GdkRGBA *bg_color;
|
||||
PangoFontDescription *font;
|
||||
|
||||
context = gtk_style_context_new ();
|
||||
path = gtk_widget_path_new ();
|
||||
gtk_style_context_set_path (context, path);
|
||||
gtk_widget_path_free (path);
|
||||
|
||||
gtk_style_context_get (context, 0,
|
||||
"color", &color,
|
||||
"background-color", &bg_color,
|
||||
"font", &font,
|
||||
NULL);
|
||||
g_assert (color != NULL);
|
||||
g_assert (bg_color != NULL);
|
||||
g_assert (font != NULL);
|
||||
|
||||
gdk_rgba_free (color);
|
||||
gdk_rgba_free (bg_color);
|
||||
pango_font_description_free (font);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_init (NULL, NULL);
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/style/parse/selectors", test_parse_selectors);
|
||||
g_test_add_func ("/style/path", test_path);
|
||||
g_test_add_func ("/style/match", test_match);
|
||||
g_test_add_func ("/style/style-property", test_style_property);
|
||||
g_test_add_func ("/style/basic", test_basic_properties);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
359
testsuite/gtk/templates.c
Normal file
359
testsuite/gtk/templates.c
Normal file
@ -0,0 +1,359 @@
|
||||
/* templates.c
|
||||
* Copyright (C) 2013 Openismus GmbH
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Tristan Van Berkom <tristanvb@openismus.com>
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#ifdef HAVE_UNIX_PRINT_WIDGETS
|
||||
# include <gtk/gtkunixprint.h>
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
main_loop_quit_cb (gpointer data)
|
||||
{
|
||||
gtk_main_quit ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
g_assert (GTK_IS_DIALOG (dialog));
|
||||
g_assert (gtk_dialog_get_action_area (GTK_DIALOG (dialog)) != NULL);
|
||||
g_assert (gtk_dialog_get_content_area (GTK_DIALOG (dialog)) != NULL);
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dialog_override_property (void)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = g_object_new (GTK_TYPE_DIALOG,
|
||||
"type-hint", GDK_WINDOW_TYPE_HINT_UTILITY,
|
||||
NULL);
|
||||
g_assert (GTK_IS_DIALOG (dialog));
|
||||
g_assert (gtk_window_get_type_hint (GTK_WINDOW (dialog)) == GDK_WINDOW_TYPE_HINT_UTILITY);
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
test_message_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (NULL, 0,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"Do it hard !");
|
||||
g_assert (GTK_IS_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
test_about_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_about_dialog_new ();
|
||||
g_assert (GTK_IS_ABOUT_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
test_info_bar_basic (void)
|
||||
{
|
||||
GtkWidget *infobar;
|
||||
|
||||
infobar = gtk_info_bar_new ();
|
||||
g_assert (GTK_IS_INFO_BAR (infobar));
|
||||
gtk_widget_destroy (infobar);
|
||||
}
|
||||
|
||||
static void
|
||||
test_lock_button_basic (void)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GPermission *permission;
|
||||
|
||||
permission = g_simple_permission_new (TRUE);
|
||||
button = gtk_lock_button_new (permission);
|
||||
g_assert (GTK_IS_LOCK_BUTTON (button));
|
||||
gtk_widget_destroy (button);
|
||||
g_object_unref (permission);
|
||||
}
|
||||
|
||||
static void
|
||||
test_assistant_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_assistant_new ();
|
||||
g_assert (GTK_IS_ASSISTANT (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_scale_button_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_scale_button_new (GTK_ICON_SIZE_MENU,
|
||||
0, 100, 10, NULL);
|
||||
g_assert (GTK_IS_SCALE_BUTTON (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_volume_button_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_volume_button_new ();
|
||||
g_assert (GTK_IS_VOLUME_BUTTON (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_statusbar_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_statusbar_new ();
|
||||
g_assert (GTK_IS_STATUSBAR (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_app_chooser_widget_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_app_chooser_widget_new (NULL);
|
||||
g_assert (GTK_IS_APP_CHOOSER_WIDGET (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_app_chooser_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_app_chooser_dialog_new_for_content_type (NULL, 0, "text/plain");
|
||||
g_assert (GTK_IS_APP_CHOOSER_DIALOG (widget));
|
||||
|
||||
/* GtkAppChooserDialog bug, if destroyed before spinning
|
||||
* the main context then app_chooser_online_get_default_ready_cb()
|
||||
* will be eventually called and segfault.
|
||||
*/
|
||||
g_timeout_add (500, main_loop_quit_cb, NULL);
|
||||
gtk_main();
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_color_chooser_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
/* This test also tests the internal GtkColorEditor widget */
|
||||
widget = gtk_color_chooser_dialog_new (NULL, NULL);
|
||||
g_assert (GTK_IS_COLOR_CHOOSER_DIALOG (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
/* Avoid warnings from GVFS-RemoteVolumeMonitor */
|
||||
static gboolean
|
||||
ignore_gvfs_warning (const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (g_strcmp0 (log_domain, "GVFS-RemoteVolumeMonitor") == 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_file_chooser_widget_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
/* This test also tests the internal GtkPathBar widget */
|
||||
g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
|
||||
|
||||
widget = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
g_assert (GTK_IS_FILE_CHOOSER_WIDGET (widget));
|
||||
|
||||
/* XXX BUG:
|
||||
*
|
||||
* Spin the mainloop for a bit, this allows the file operations
|
||||
* to complete, GtkFileChooserDefault has a bug where it leaks
|
||||
* GtkTreeRowReferences to the internal shortcuts_model
|
||||
*
|
||||
* Since we assert all automated children are finalized we
|
||||
* can catch this
|
||||
*/
|
||||
g_timeout_add (100, main_loop_quit_cb, NULL);
|
||||
gtk_main();
|
||||
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_file_chooser_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
|
||||
|
||||
widget = gtk_file_chooser_dialog_new ("The Dialog", NULL,
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
|
||||
g_assert (GTK_IS_FILE_CHOOSER_DIALOG (widget));
|
||||
g_timeout_add (100, main_loop_quit_cb, NULL);
|
||||
gtk_main();
|
||||
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_file_chooser_button_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
|
||||
|
||||
widget = gtk_file_chooser_button_new ("Choose a file !", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
g_assert (GTK_IS_FILE_CHOOSER_BUTTON (widget));
|
||||
g_timeout_add (100, main_loop_quit_cb, NULL);
|
||||
gtk_main();
|
||||
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_font_button_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_font_button_new ();
|
||||
g_assert (GTK_IS_FONT_BUTTON (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_font_chooser_widget_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_font_chooser_widget_new ();
|
||||
g_assert (GTK_IS_FONT_CHOOSER_WIDGET (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_font_chooser_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_font_chooser_dialog_new ("Choose a font !", NULL);
|
||||
g_assert (GTK_IS_FONT_CHOOSER_DIALOG (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_recent_chooser_widget_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_recent_chooser_widget_new ();
|
||||
g_assert (GTK_IS_RECENT_CHOOSER_WIDGET (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
#ifdef HAVE_UNIX_PRINT_WIDGETS
|
||||
static void
|
||||
test_page_setup_unix_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_page_setup_unix_dialog_new ("Setup your Page !", NULL);
|
||||
g_assert (GTK_IS_PAGE_SETUP_UNIX_DIALOG (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
test_print_unix_dialog_basic (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_print_unix_dialog_new ("Go Print !", NULL);
|
||||
g_assert (GTK_IS_PRINT_UNIX_DIALOG (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
/* initialize test program */
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
/* This environment variable cooperates with gtk_widget_destroy()
|
||||
* to assert that all automated compoenents are properly finalized
|
||||
* when a given composite widget is destroyed.
|
||||
*/
|
||||
g_assert (g_setenv ("GTK_WIDGET_ASSERT_COMPONENTS", "1", TRUE));
|
||||
|
||||
g_test_add_func ("/Template/GtkDialog/Basic", test_dialog_basic);
|
||||
g_test_add_func ("/Template/GtkDialog/OverrideProperty", test_dialog_override_property);
|
||||
g_test_add_func ("/Template/GtkMessageDialog/Basic", test_message_dialog_basic);
|
||||
g_test_add_func ("/Template/GtkAboutDialog/Basic", test_about_dialog_basic);
|
||||
g_test_add_func ("/Template/GtkInfoBar/Basic", test_info_bar_basic);
|
||||
g_test_add_func ("/Template/GtkLockButton/Basic", test_lock_button_basic);
|
||||
g_test_add_func ("/Template/GtkAssistant/Basic", test_assistant_basic);
|
||||
g_test_add_func ("/Template/GtkScaleButton/Basic", test_scale_button_basic);
|
||||
g_test_add_func ("/Template/GtkVolumeButton/Basic", test_volume_button_basic);
|
||||
g_test_add_func ("/Template/GtkStatusBar/Basic", test_statusbar_basic);
|
||||
g_test_add_func ("/Template/GtkAppChooserWidget/Basic", test_app_chooser_widget_basic);
|
||||
g_test_add_func ("/Template/GtkAppChooserDialog/Basic", test_app_chooser_dialog_basic);
|
||||
g_test_add_func ("/Template/GtkColorChooserDialog/Basic", test_color_chooser_dialog_basic);
|
||||
g_test_add_func ("/Template/GtkFileChooserWidget/Basic", test_file_chooser_widget_basic);
|
||||
g_test_add_func ("/Template/GtkFileChooserDialog/Basic", test_file_chooser_dialog_basic);
|
||||
g_test_add_func ("/Template/GtkFileChooserButton/Basic", test_file_chooser_button_basic);
|
||||
g_test_add_func ("/Template/GtkFontButton/Basic", test_font_button_basic);
|
||||
g_test_add_func ("/Template/GtkFontChooserWidget/Basic", test_font_chooser_widget_basic);
|
||||
g_test_add_func ("/Template/GtkFontChooserDialog/Basic", test_font_chooser_dialog_basic);
|
||||
g_test_add_func ("/Template/GtkRecentChooserWidget/Basic", test_recent_chooser_widget_basic);
|
||||
|
||||
#ifdef HAVE_UNIX_PRINT_WIDGETS
|
||||
g_test_add_func ("/Template/UnixPrint/GtkPageSetupUnixDialog/Basic", test_page_setup_unix_dialog_basic);
|
||||
g_test_add_func ("/Template/UnixPrint/GtkPrintUnixDialog/Basic", test_print_unix_dialog_basic);
|
||||
#endif
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
306
testsuite/gtk/testing.c
Normal file
306
testsuite/gtk/testing.c
Normal file
@ -0,0 +1,306 @@
|
||||
/* Gtk+ testing utilities
|
||||
* Copyright (C) 2007 Imendio AB
|
||||
* Authors: 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Use a keyval that requires Shift to be active (in typical layouts)
|
||||
* like GDK_KEY_ampersand, which is '<shift>6'
|
||||
*/
|
||||
#define KEYVAL_THAT_REQUIRES_SHIFT GDK_KEY_ampersand
|
||||
|
||||
|
||||
/* --- test functions --- */
|
||||
static void
|
||||
test_button_clicks (void)
|
||||
{
|
||||
int a = 0, b = 0, c = 0;
|
||||
GtkWidget *window = gtk_test_display_button_window ("Test Window",
|
||||
"Test: gtk_test_widget_click",
|
||||
"IgnoreMe1", &a,
|
||||
"ClickMe", &b,
|
||||
"IgnoreMe2", &c,
|
||||
NULL);
|
||||
GtkWidget *button = gtk_test_find_widget (window, "*Click*", GTK_TYPE_BUTTON);
|
||||
gboolean simsuccess;
|
||||
g_assert (button != NULL);
|
||||
simsuccess = gtk_test_widget_click (button, 1, 0);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
g_assert (a == 0);
|
||||
g_assert (b > 0);
|
||||
g_assert (c == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_button_keys (void)
|
||||
{
|
||||
int a = 0, b = 0, c = 0;
|
||||
GtkWidget *window = gtk_test_display_button_window ("Test Window",
|
||||
"Test: gtk_test_widget_send_key",
|
||||
"IgnoreMe1", &a,
|
||||
"ClickMe", &b,
|
||||
"IgnoreMe2", &c,
|
||||
NULL);
|
||||
GtkWidget *button = gtk_test_find_widget (window, "*Click*", GTK_TYPE_BUTTON);
|
||||
gboolean simsuccess;
|
||||
g_assert (button != NULL);
|
||||
gtk_widget_grab_focus (button);
|
||||
g_assert (gtk_widget_has_focus (button));
|
||||
simsuccess = gtk_test_widget_send_key (button, GDK_KEY_Return, 0);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
g_assert (a == 0);
|
||||
g_assert (b > 0);
|
||||
g_assert (c == 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
store_last_key_release (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
*((gint *)user_data) = event->keyval;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_send_shift_key (void)
|
||||
{
|
||||
GtkWidget *window = gtk_test_display_button_window ("Test Window",
|
||||
"Test: test_send_shift_key()",
|
||||
"IgnoreMe1", NULL,
|
||||
"SendMeKeys", NULL,
|
||||
"IgnoreMe2", NULL,
|
||||
NULL);
|
||||
GtkWidget *button = gtk_test_find_widget (window, "SendMeKeys", GTK_TYPE_BUTTON);
|
||||
gint last_key_release = 0;
|
||||
gboolean simsuccess;
|
||||
g_assert (button != NULL);
|
||||
g_signal_connect (button, "key-release-event",
|
||||
G_CALLBACK (store_last_key_release),
|
||||
&last_key_release);
|
||||
gtk_widget_grab_focus (button);
|
||||
g_assert (gtk_widget_has_focus (button));
|
||||
simsuccess = gtk_test_widget_send_key (button, KEYVAL_THAT_REQUIRES_SHIFT, 0 /*modifiers*/);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
g_assert_cmpint (KEYVAL_THAT_REQUIRES_SHIFT, ==, last_key_release);
|
||||
}
|
||||
|
||||
static void
|
||||
test_slider_ranges (void)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: gtk_test_warp_slider");
|
||||
GtkWidget *hscale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
|
||||
-50, +50, 5);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (window));
|
||||
gtk_container_add (GTK_CONTAINER (child), hscale);
|
||||
gtk_widget_show (hscale);
|
||||
gtk_widget_show_now (window);
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
gtk_test_slider_set_perc (hscale, 0.0);
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
g_assert (gtk_test_slider_get_value (hscale) == -50);
|
||||
gtk_test_slider_set_perc (hscale, 50.0);
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
g_assert (fabs (gtk_test_slider_get_value (hscale)) < 0.0001);
|
||||
gtk_test_slider_set_perc (hscale, 100.0);
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
g_assert (gtk_test_slider_get_value (hscale) == +50.0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_text_access (void)
|
||||
{
|
||||
const int N_WIDGETS = 3;
|
||||
GtkWidget *widgets[N_WIDGETS];
|
||||
int i = 0;
|
||||
widgets[i++] = gtk_test_create_widget (GTK_TYPE_LABEL, NULL);
|
||||
widgets[i++] = gtk_test_create_widget (GTK_TYPE_ENTRY, NULL);
|
||||
widgets[i++] = gtk_test_create_widget (GTK_TYPE_TEXT_VIEW, NULL);
|
||||
g_assert (i == N_WIDGETS);
|
||||
for (i = 0; i < N_WIDGETS; i++)
|
||||
gtk_test_text_set (widgets[i], "foobar");
|
||||
for (i = 0; i < N_WIDGETS; i++)
|
||||
{
|
||||
gchar *text = gtk_test_text_get (widgets[i]);
|
||||
g_assert (strcmp (text, "foobar") == 0);
|
||||
g_free (text);
|
||||
}
|
||||
for (i = 0; i < N_WIDGETS; i++)
|
||||
gtk_test_text_set (widgets[i], "");
|
||||
for (i = 0; i < N_WIDGETS; i++)
|
||||
{
|
||||
gchar *text = gtk_test_text_get (widgets[i]);
|
||||
g_assert (strcmp (text, "") == 0);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_xserver_sync (void)
|
||||
{
|
||||
GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: test_xserver_sync");
|
||||
GtkWidget *darea = gtk_drawing_area_new ();
|
||||
GtkWidget *child;
|
||||
GdkWindow *gdk_window;
|
||||
GTimer *gtimer = g_timer_new();
|
||||
gint sync_is_slower = 0, repeat = 5;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (window));
|
||||
//gdk_window = gtk_widget_get_window (darea);
|
||||
|
||||
gtk_widget_set_size_request (darea, 320, 200);
|
||||
gtk_container_add (GTK_CONTAINER (child), darea);
|
||||
gtk_widget_show (darea);
|
||||
gtk_widget_show_now (window);
|
||||
|
||||
while (repeat--)
|
||||
{
|
||||
gint i, many = 200;
|
||||
double nosync_time, sync_time;
|
||||
cairo_t *cr;
|
||||
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
gdk_window = gtk_widget_get_window (darea);
|
||||
cr = gdk_cairo_create (gdk_window);
|
||||
cairo_set_source_rgba (cr, 0, 1, 0, 0.1);
|
||||
/* run a number of consecutive drawing requests, just using drawing queue */
|
||||
g_timer_start (gtimer);
|
||||
for (i = 0; i < many; i++)
|
||||
{
|
||||
cairo_paint (cr);
|
||||
}
|
||||
g_timer_stop (gtimer);
|
||||
nosync_time = g_timer_elapsed (gtimer, NULL);
|
||||
gdk_flush();
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
g_timer_start (gtimer);
|
||||
/* run a number of consecutive drawing requests with intermediate drawing syncs */
|
||||
for (i = 0; i < many; i++)
|
||||
{
|
||||
cairo_paint (cr);
|
||||
gdk_test_render_sync (gdk_window);
|
||||
}
|
||||
g_timer_stop (gtimer);
|
||||
sync_time = g_timer_elapsed (gtimer, NULL);
|
||||
sync_is_slower += sync_time > nosync_time * 1.5;
|
||||
}
|
||||
g_timer_destroy (gtimer);
|
||||
g_assert (sync_is_slower > 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_spin_button_arrows (void)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: test_spin_button_arrows");
|
||||
GtkWidget *spinner = gtk_spin_button_new_with_range (0, 100, 5);
|
||||
gboolean simsuccess;
|
||||
double oldval, newval;
|
||||
|
||||
gtk_window_set_has_resize_grip (GTK_WINDOW (window), FALSE);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (window));
|
||||
gtk_container_add (GTK_CONTAINER (child), spinner);
|
||||
gtk_widget_show (spinner);
|
||||
gtk_widget_show_now (window);
|
||||
gtk_test_slider_set_perc (spinner, 0);
|
||||
/* check initial spinner value */
|
||||
oldval = gtk_test_slider_get_value (spinner);
|
||||
g_assert (oldval == 0);
|
||||
/* check simple increment */
|
||||
simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 1, TRUE);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
|
||||
gtk_main_iteration ();
|
||||
newval = gtk_test_slider_get_value (spinner);
|
||||
g_assert (newval > oldval);
|
||||
/* check maximum warp */
|
||||
simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 3, TRUE);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
|
||||
gtk_main_iteration ();
|
||||
oldval = gtk_test_slider_get_value (spinner);
|
||||
g_assert (oldval == 100);
|
||||
/* check simple decrement */
|
||||
oldval = gtk_test_slider_get_value (spinner);
|
||||
simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 1, FALSE);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
|
||||
gtk_main_iteration ();
|
||||
newval = gtk_test_slider_get_value (spinner);
|
||||
g_assert (newval < oldval);
|
||||
/* check minimum warp */
|
||||
simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 3, FALSE);
|
||||
g_assert (simsuccess == TRUE);
|
||||
while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
|
||||
gtk_main_iteration ();
|
||||
oldval = gtk_test_slider_get_value (spinner);
|
||||
g_assert (oldval == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_statusbar_remove_all (void)
|
||||
{
|
||||
GtkWidget *statusbar;
|
||||
|
||||
g_test_bug ("640487");
|
||||
|
||||
statusbar = gtk_statusbar_new ();
|
||||
g_object_ref_sink (statusbar);
|
||||
|
||||
gtk_statusbar_push (GTK_STATUSBAR (statusbar), 1, "bla");
|
||||
gtk_statusbar_push (GTK_STATUSBAR (statusbar), 1, "bla");
|
||||
gtk_statusbar_remove_all (GTK_STATUSBAR (statusbar), 1);
|
||||
|
||||
g_object_unref (statusbar);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
gtk_test_register_all_types();
|
||||
|
||||
g_test_add_func ("/tests/statusbar-remove-all", test_statusbar_remove_all);
|
||||
g_test_add_func ("/ui-tests/text-access", test_text_access);
|
||||
g_test_add_func ("/ui-tests/button-clicks", test_button_clicks);
|
||||
g_test_add_func ("/ui-tests/keys-events", test_button_keys);
|
||||
g_test_add_func ("/ui-tests/send-shift-key", test_send_shift_key);
|
||||
g_test_add_func ("/ui-tests/slider-ranges", test_slider_ranges);
|
||||
g_test_add_func ("/ui-tests/xserver-sync", test_xserver_sync);
|
||||
g_test_add_func ("/ui-tests/spin-button-arrows", test_spin_button_arrows);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
1341
testsuite/gtk/textbuffer.c
Normal file
1341
testsuite/gtk/textbuffer.c
Normal file
File diff suppressed because it is too large
Load Diff
269
testsuite/gtk/textiter.c
Normal file
269
testsuite/gtk/textiter.c
Normal file
@ -0,0 +1,269 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_empty_search ()
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter it, s, e;
|
||||
gboolean res;
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, "This is some foo text", -1);
|
||||
|
||||
/* search from start forward */
|
||||
gtk_text_buffer_get_start_iter (buffer, &it);
|
||||
res = gtk_text_iter_forward_search (&it, "", 0, &s, &e, NULL);
|
||||
g_assert (res);
|
||||
g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
|
||||
g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 1);
|
||||
|
||||
/* search from end backward */
|
||||
gtk_text_buffer_get_end_iter (buffer, &it);
|
||||
res = gtk_text_iter_backward_search (&it, "", 0, &s, &e, NULL);
|
||||
g_assert (res);
|
||||
g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
|
||||
g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 20);
|
||||
}
|
||||
|
||||
static void
|
||||
check_found_forward (const gchar *haystack,
|
||||
const gchar *needle,
|
||||
GtkTextSearchFlags flags,
|
||||
int expected_start,
|
||||
int expected_end,
|
||||
const gchar *expected_string)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter i, s, e;
|
||||
gboolean res;
|
||||
gchar *text;
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
|
||||
gtk_text_buffer_set_text (buffer, haystack, -1);
|
||||
|
||||
/* TODO: add test with limit before, after and in the middle
|
||||
of expected start and end */
|
||||
|
||||
/* search from start forward */
|
||||
gtk_text_buffer_get_start_iter (buffer, &i);
|
||||
res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
|
||||
g_assert (res);
|
||||
g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
|
||||
g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
|
||||
text = gtk_text_iter_get_text (&s, &e);
|
||||
g_assert_cmpstr (expected_string, ==, text);
|
||||
g_free (text);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
check_found_backward (const gchar *haystack,
|
||||
const gchar *needle,
|
||||
GtkTextSearchFlags flags,
|
||||
int expected_start,
|
||||
int expected_end,
|
||||
const gchar *expected_string)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter i, s, e;
|
||||
gboolean res;
|
||||
gchar *text;
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
|
||||
gtk_text_buffer_set_text (buffer, haystack, -1);
|
||||
|
||||
/* search from end backward */
|
||||
gtk_text_buffer_get_end_iter (buffer, &i);
|
||||
res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
|
||||
g_assert (res);
|
||||
g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
|
||||
g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
|
||||
text = gtk_text_iter_get_text (&s, &e);
|
||||
g_assert_cmpstr (expected_string, ==, text);
|
||||
g_free (text);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
check_not_found (const gchar *haystack,
|
||||
const gchar *needle,
|
||||
GtkTextSearchFlags flags)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter i, s, e;
|
||||
gboolean res;
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
|
||||
gtk_text_buffer_set_text (buffer, haystack, -1);
|
||||
|
||||
/* search from start forward */
|
||||
gtk_text_buffer_get_start_iter (buffer, &i);
|
||||
res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
|
||||
g_assert (res == FALSE);
|
||||
|
||||
/* search from end backward */
|
||||
gtk_text_buffer_get_end_iter (buffer, &i);
|
||||
res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
|
||||
g_assert (res == FALSE);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
test_full_buffer (void)
|
||||
{
|
||||
check_found_forward ("foo", "foo", 0, 0, 3, "foo");
|
||||
check_found_backward ("foo", "foo", 0, 0, 3, "foo");
|
||||
check_found_forward ("foo", "foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
|
||||
check_found_backward ("foo", "foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
|
||||
check_found_forward ("foo", "Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
|
||||
check_found_backward ("foo", "Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
|
||||
}
|
||||
|
||||
static void
|
||||
test_search (void)
|
||||
{
|
||||
/* simple match */
|
||||
check_found_forward ("This is some foo text", "foo", 0, 13, 16, "foo");
|
||||
check_found_backward ("This is some foo text", "foo", 0, 13, 16, "foo");
|
||||
check_not_found ("This is some foo text", "Foo", 0);
|
||||
|
||||
/* different matches for forward and backward */
|
||||
check_found_forward ("This is some foo foo text", "foo", 0, 13, 16, "foo");
|
||||
check_found_backward ("This is some foo foo text", "foo", 0, 17, 20, "foo");
|
||||
|
||||
/* new lines in the haystack */
|
||||
check_found_forward ("This is some\nfoo text", "foo", 0, 13, 16, "foo");
|
||||
check_found_backward ("This is some\nfoo text", "foo", 0, 13, 16, "foo");
|
||||
check_found_forward ("This is some foo\nfoo text", "foo", 0, 13, 16, "foo");
|
||||
check_found_backward ("This is some foo\nfoo text", "foo", 0, 17, 20, "foo");
|
||||
check_not_found ("This is some\nfoo text", "Foo", 0);
|
||||
|
||||
/* end of buffer */
|
||||
check_found_forward ("This is some\ntext foo", "foo", 0, 18, 21, "foo");
|
||||
check_found_backward ("This is some\ntext foo", "foo", 0, 18, 21, "foo");
|
||||
check_not_found ("This is some\ntext foo", "Foo", 0);
|
||||
|
||||
/* multiple lines in the needle */
|
||||
check_found_forward ("This is some foo\nfoo text", "foo\nfoo", 0, 13, 20, "foo\nfoo");
|
||||
check_found_backward ("This is some foo\nfoo text", "foo\nfoo", 0, 13, 20, "foo\nfoo");
|
||||
check_not_found ("This is some foo\nfoo text", "Foo\nfoo", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_search_caseless (void)
|
||||
{
|
||||
GtkTextSearchFlags flags;
|
||||
|
||||
flags = GTK_TEXT_SEARCH_CASE_INSENSITIVE;
|
||||
|
||||
/* simple match */
|
||||
check_found_forward ("This is some foo text", "foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some foo text", "Foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some Foo text", "foo", flags, 13, 16, "Foo");
|
||||
check_found_backward ("This is some foo text", "foo", flags, 13, 16, "foo");
|
||||
check_found_backward ("This is some foo text", "Foo", flags, 13, 16, "foo");
|
||||
check_found_backward ("This is some Foo text", "foo", flags, 13, 16, "Foo");
|
||||
|
||||
/* check also that different composition of utf8 characters
|
||||
(e.g. accented letters) match */
|
||||
|
||||
/* different matches for forward and backward */
|
||||
check_found_forward ("This is some foo foo text", "foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some foo foo text", "Foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some Foo foo text", "foo", flags, 13, 16, "Foo");
|
||||
check_found_forward ("This is some \303\200 \303\240 text", "\303\240", flags, 13, 14, "\303\200");
|
||||
check_found_forward ("This is some \303\200 \303\240 text", "\303\200", flags, 13, 14, "\303\200");
|
||||
check_found_forward ("This is some \303\200 \303\240 text", "a\314\200", flags, 13, 14, "\303\200");
|
||||
check_found_backward ("This is some foo foo text", "foo", flags, 17, 20, "foo");
|
||||
check_found_backward ("This is some foo foo text", "Foo", flags, 17, 20, "foo");
|
||||
check_found_backward ("This is some foo Foo text", "foo", flags, 17, 20, "Foo");
|
||||
check_found_backward ("This is some \303\200 \303\240 text", "\303\240", flags, 15, 16, "\303\240");
|
||||
check_found_backward ("This is some \303\200 \303\240 text", "\303\200", flags, 15, 16, "\303\240");
|
||||
check_found_backward ("This is some \303\200 \303\240 text", "a\314\200", flags, 15, 16, "\303\240");
|
||||
|
||||
/* new lines in the haystack */
|
||||
check_found_forward ("This is some\nfoo text", "foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some\nfoo text", "Foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some\nFoo text", "foo", flags, 13, 16, "Foo");
|
||||
check_found_forward ("This is some\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
|
||||
check_found_forward ("This is some\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
|
||||
check_found_backward ("This is some\nfoo text", "foo", flags, 13, 16, "foo");
|
||||
check_found_backward ("This is some\nfoo text", "Foo", flags, 13, 16, "foo");
|
||||
check_found_backward ("This is some\nFoo text", "foo", flags, 13, 16, "Foo");
|
||||
check_found_backward ("This is some\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
|
||||
check_found_backward ("This is some\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
|
||||
check_found_forward ("This is some foo\nfoo text", "foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some foo\nfoo text", "Foo", flags, 13, 16, "foo");
|
||||
check_found_forward ("This is some Foo\nfoo text", "foo", flags, 13, 16, "Foo");
|
||||
check_found_forward ("This is some \303\200\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
|
||||
check_found_forward ("This is some \303\200\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
|
||||
check_found_backward ("This is some foo\nfoo text", "foo", flags, 17, 20, "foo");
|
||||
check_found_backward ("This is some foo\nfoo text", "Foo", flags, 17, 20, "foo");
|
||||
check_found_backward ("This is some foo\nFoo text", "foo", flags, 17, 20, "Foo");
|
||||
check_found_backward ("This is some \303\200\n\303\200 text", "\303\240", flags, 15, 16, "\303\200");
|
||||
check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200", flags, 15, 16, "\303\200");
|
||||
|
||||
/* end of buffer */
|
||||
check_found_forward ("This is some\ntext foo", "foo", flags, 18, 21, "foo");
|
||||
check_found_forward ("This is some\ntext foo", "Foo", flags, 18, 21, "foo");
|
||||
check_found_forward ("This is some\ntext Foo", "foo", flags, 18, 21, "Foo");
|
||||
check_found_forward ("This is some\ntext \303\200", "\303\240", flags, 18, 19, "\303\200");
|
||||
check_found_forward ("This is some\ntext \303\200", "a\314\200", flags, 18, 19, "\303\200");
|
||||
check_found_backward ("This is some\ntext foo", "foo", flags, 18, 21, "foo");
|
||||
check_found_backward ("This is some\ntext foo", "Foo", flags, 18, 21, "foo");
|
||||
check_found_backward ("This is some\ntext Foo", "foo", flags, 18, 21, "Foo");
|
||||
check_found_backward ("This is some\ntext \303\200", "\303\240", flags, 18, 19, "\303\200");
|
||||
check_found_backward ("This is some\ntext \303\200", "a\314\200", flags, 18, 19, "\303\200");
|
||||
|
||||
/* multiple lines in the needle */
|
||||
check_found_forward ("This is some foo\nfoo text", "foo\nfoo", flags, 13, 20, "foo\nfoo");
|
||||
check_found_forward ("This is some foo\nfoo text", "Foo\nFoo", flags, 13, 20, "foo\nfoo");
|
||||
check_found_forward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo");
|
||||
check_found_forward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, "\303\200\n\303\200");
|
||||
check_found_forward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, "\303\200\n\303\200");
|
||||
check_found_backward ("This is some foo\nfoo text", "foo\nfoo", flags, 13, 20, "foo\nfoo");
|
||||
check_found_backward ("This is some foo\nfoo text", "Foo\nFoo", flags, 13, 20, "foo\nfoo");
|
||||
check_found_backward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo");
|
||||
check_found_backward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, "\303\200\n\303\200");
|
||||
check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, "\303\200\n\303\200");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/TextIter/Search Empty", test_empty_search);
|
||||
g_test_add_func ("/TextIter/Search Full Buffer", test_full_buffer);
|
||||
g_test_add_func ("/TextIter/Search", test_search);
|
||||
g_test_add_func ("/TextIter/Search Caseless", test_search_caseless);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
345
testsuite/gtk/treemodel.c
Normal file
345
testsuite/gtk/treemodel.c
Normal file
@ -0,0 +1,345 @@
|
||||
/* Main wrapper for TreeModel test suite.
|
||||
* Copyright (C) 2011 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "treemodel.h"
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
register_list_store_tests ();
|
||||
register_tree_store_tests ();
|
||||
register_model_ref_count_tests ();
|
||||
register_sort_model_tests ();
|
||||
register_filter_model_tests ();
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal monitor
|
||||
*/
|
||||
|
||||
static const char *
|
||||
signal_name_to_string (SignalName signal)
|
||||
{
|
||||
switch (signal)
|
||||
{
|
||||
case ROW_INSERTED:
|
||||
return "row-inserted";
|
||||
|
||||
case ROW_DELETED:
|
||||
return "row-deleted";
|
||||
|
||||
case ROW_CHANGED:
|
||||
return "row-changed";
|
||||
|
||||
case ROW_HAS_CHILD_TOGGLED:
|
||||
return "row-has-child-toggled";
|
||||
|
||||
case ROWS_REORDERED:
|
||||
return "rows-reordered";
|
||||
|
||||
default:
|
||||
/* Fall through */
|
||||
break;
|
||||
}
|
||||
|
||||
return "(unknown)";
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SignalName signal;
|
||||
GtkTreePath *path;
|
||||
|
||||
/* For rows-reordered */
|
||||
int *new_order;
|
||||
int len;
|
||||
}
|
||||
Signal;
|
||||
|
||||
|
||||
static Signal *
|
||||
signal_new (SignalName signal, GtkTreePath *path)
|
||||
{
|
||||
Signal *s;
|
||||
|
||||
s = g_new0 (Signal, 1);
|
||||
s->signal = signal;
|
||||
s->path = gtk_tree_path_copy (path);
|
||||
s->new_order = NULL;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static Signal *
|
||||
signal_new_with_order (SignalName signal, GtkTreePath *path,
|
||||
int *new_order, int len)
|
||||
{
|
||||
Signal *s = signal_new (signal, path);
|
||||
|
||||
s->new_order = new_order;
|
||||
s->len = len;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
signal_free (Signal *s)
|
||||
{
|
||||
if (s->path)
|
||||
gtk_tree_path_free (s->path);
|
||||
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
|
||||
struct _SignalMonitor
|
||||
{
|
||||
GQueue *queue;
|
||||
GtkTreeModel *client;
|
||||
gulong signal_ids[LAST_SIGNAL];
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
signal_monitor_generic_handler (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreePath *path,
|
||||
int *new_order)
|
||||
{
|
||||
Signal *s;
|
||||
|
||||
if (g_queue_is_empty (m->queue))
|
||||
{
|
||||
gchar *path_str;
|
||||
|
||||
path_str = gtk_tree_path_to_string (path);
|
||||
g_error ("Signal queue empty, got signal %s path %s\n",
|
||||
signal_name_to_string (signal), path_str);
|
||||
g_free (path_str);
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (m->client != model)
|
||||
{
|
||||
g_error ("Model mismatch; expected %p, got %p\n",
|
||||
m->client, model);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
s = g_queue_peek_tail (m->queue);
|
||||
|
||||
#if 0
|
||||
/* For debugging: output signals that are coming in. Leaks memory. */
|
||||
g_print ("signal=%s path=%s\n", signal_name_to_string (signal),
|
||||
gtk_tree_path_to_string (path));
|
||||
#endif
|
||||
|
||||
if (s->signal != signal ||
|
||||
(gtk_tree_path_get_depth (s->path) == 0 &&
|
||||
gtk_tree_path_get_depth (path) != 0) ||
|
||||
(gtk_tree_path_get_depth (s->path) != 0 &&
|
||||
gtk_tree_path_compare (s->path, path) != 0))
|
||||
{
|
||||
gchar *path_str, *s_path_str;
|
||||
|
||||
s_path_str = gtk_tree_path_to_string (s->path);
|
||||
path_str = gtk_tree_path_to_string (path);
|
||||
|
||||
g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n",
|
||||
signal_name_to_string (s->signal), s_path_str,
|
||||
signal_name_to_string (signal), path_str);
|
||||
|
||||
g_free (s_path_str);
|
||||
g_free (path_str);
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (signal == ROWS_REORDERED && s->new_order != NULL)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
g_assert (new_order != NULL);
|
||||
|
||||
len = gtk_tree_model_iter_n_children (model, iter);
|
||||
g_assert (s->len == len);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
g_assert (s->new_order[i] == new_order[i]);
|
||||
}
|
||||
|
||||
s = g_queue_pop_tail (m->queue);
|
||||
|
||||
signal_free (s);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_monitor_row_inserted (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
signal_monitor_generic_handler (data, ROW_INSERTED,
|
||||
model, iter, path, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_monitor_row_deleted (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
gpointer data)
|
||||
{
|
||||
signal_monitor_generic_handler (data, ROW_DELETED,
|
||||
model, NULL, path, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_monitor_row_changed (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
signal_monitor_generic_handler (data, ROW_CHANGED,
|
||||
model, iter, path, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_monitor_row_has_child_toggled (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
|
||||
model, iter, path, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_monitor_rows_reordered (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gint *new_order,
|
||||
gpointer data)
|
||||
{
|
||||
signal_monitor_generic_handler (data, ROWS_REORDERED,
|
||||
model, iter, path, new_order);
|
||||
}
|
||||
|
||||
SignalMonitor *
|
||||
signal_monitor_new (GtkTreeModel *client)
|
||||
{
|
||||
SignalMonitor *m;
|
||||
|
||||
m = g_new0 (SignalMonitor, 1);
|
||||
m->client = g_object_ref (client);
|
||||
m->queue = g_queue_new ();
|
||||
|
||||
m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
|
||||
"row-inserted",
|
||||
G_CALLBACK (signal_monitor_row_inserted),
|
||||
m);
|
||||
m->signal_ids[ROW_DELETED] = g_signal_connect (client,
|
||||
"row-deleted",
|
||||
G_CALLBACK (signal_monitor_row_deleted),
|
||||
m);
|
||||
m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
|
||||
"row-changed",
|
||||
G_CALLBACK (signal_monitor_row_changed),
|
||||
m);
|
||||
m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
|
||||
"row-has-child-toggled",
|
||||
G_CALLBACK (signal_monitor_row_has_child_toggled),
|
||||
m);
|
||||
m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
|
||||
"rows-reordered",
|
||||
G_CALLBACK (signal_monitor_rows_reordered),
|
||||
m);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
signal_monitor_free (SignalMonitor *m)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < LAST_SIGNAL; i++)
|
||||
g_signal_handler_disconnect (m->client, m->signal_ids[i]);
|
||||
|
||||
g_object_unref (m->client);
|
||||
|
||||
if (m->queue)
|
||||
g_queue_free (m->queue);
|
||||
|
||||
g_free (m);
|
||||
}
|
||||
|
||||
void
|
||||
signal_monitor_assert_is_empty (SignalMonitor *m)
|
||||
{
|
||||
g_assert (g_queue_is_empty (m->queue));
|
||||
}
|
||||
|
||||
void
|
||||
signal_monitor_append_signal_path (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
Signal *s;
|
||||
|
||||
s = signal_new (signal, path);
|
||||
g_queue_push_head (m->queue, s);
|
||||
}
|
||||
|
||||
void
|
||||
signal_monitor_append_signal_reordered (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
GtkTreePath *path,
|
||||
int *new_order,
|
||||
int len)
|
||||
{
|
||||
Signal *s;
|
||||
|
||||
s = signal_new_with_order (signal, path, new_order, len);
|
||||
g_queue_push_head (m->queue, s);
|
||||
}
|
||||
|
||||
void
|
||||
signal_monitor_append_signal (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
const gchar *path_string)
|
||||
{
|
||||
Signal *s;
|
||||
GtkTreePath *path;
|
||||
|
||||
path = gtk_tree_path_new_from_string (path_string);
|
||||
|
||||
s = signal_new (signal, path);
|
||||
g_queue_push_head (m->queue, s);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
58
testsuite/gtk/treemodel.h
Normal file
58
testsuite/gtk/treemodel.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* Main wrapper for TreeModel test suite.
|
||||
* Copyright (C) 2011 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
void register_list_store_tests ();
|
||||
void register_tree_store_tests ();
|
||||
void register_sort_model_tests ();
|
||||
void register_filter_model_tests ();
|
||||
void register_model_ref_count_tests ();
|
||||
|
||||
/*
|
||||
* Signal monitor
|
||||
*/
|
||||
typedef struct _SignalMonitor SignalMonitor;
|
||||
typedef enum _SignalName SignalName;
|
||||
|
||||
enum _SignalName
|
||||
{
|
||||
ROW_INSERTED,
|
||||
ROW_DELETED,
|
||||
ROW_CHANGED,
|
||||
ROW_HAS_CHILD_TOGGLED,
|
||||
ROWS_REORDERED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
SignalMonitor *signal_monitor_new (GtkTreeModel *client);
|
||||
void signal_monitor_free (SignalMonitor *m);
|
||||
|
||||
void signal_monitor_assert_is_empty (SignalMonitor *m);
|
||||
|
||||
void signal_monitor_append_signal_reordered (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
GtkTreePath *path,
|
||||
int *new_order,
|
||||
int len);
|
||||
void signal_monitor_append_signal_path (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
GtkTreePath *path);
|
||||
void signal_monitor_append_signal (SignalMonitor *m,
|
||||
SignalName signal,
|
||||
const gchar *path_string);
|
||||
181
testsuite/gtk/treepath.c
Normal file
181
testsuite/gtk/treepath.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* GtkTrePath tests.
|
||||
*
|
||||
* Copyright (C) 2011, Red Hat, Inc.
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_append (void)
|
||||
{
|
||||
GtkTreePath *p;
|
||||
gint i;
|
||||
gint *indices;
|
||||
|
||||
p = gtk_tree_path_new ();
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
g_assert_cmpint (gtk_tree_path_get_depth (p), ==, i);
|
||||
gtk_tree_path_append_index (p, i);
|
||||
}
|
||||
|
||||
indices = gtk_tree_path_get_indices (p);
|
||||
for (i = 0; i < 100; i++)
|
||||
g_assert_cmpint (indices[i], ==, i);
|
||||
|
||||
gtk_tree_path_free (p);
|
||||
}
|
||||
|
||||
static void
|
||||
test_prepend (void)
|
||||
{
|
||||
GtkTreePath *p;
|
||||
gint i;
|
||||
gint *indices;
|
||||
|
||||
p = gtk_tree_path_new ();
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
g_assert_cmpint (gtk_tree_path_get_depth (p), ==, i);
|
||||
gtk_tree_path_prepend_index (p, i);
|
||||
}
|
||||
|
||||
indices = gtk_tree_path_get_indices (p);
|
||||
for (i = 0; i < 100; i++)
|
||||
g_assert_cmpint (indices[i], ==, 99 - i);
|
||||
|
||||
gtk_tree_path_free (p);
|
||||
}
|
||||
|
||||
static void
|
||||
test_to_string (void)
|
||||
{
|
||||
const gchar *str = "0:1:2:3:4:5:6:7:8:9:10";
|
||||
GtkTreePath *p;
|
||||
gint *indices;
|
||||
gchar *s;
|
||||
gint i;
|
||||
|
||||
p = gtk_tree_path_new_from_string (str);
|
||||
indices = gtk_tree_path_get_indices (p);
|
||||
for (i = 0; i < 10; i++)
|
||||
g_assert_cmpint (indices[i], ==, i);
|
||||
s = gtk_tree_path_to_string (p);
|
||||
g_assert_cmpstr (s, ==, str);
|
||||
|
||||
gtk_tree_path_free (p);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
static void
|
||||
test_from_indices (void)
|
||||
{
|
||||
GtkTreePath *p;
|
||||
gint *indices;
|
||||
gint i;
|
||||
|
||||
p = gtk_tree_path_new_from_indices (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
|
||||
g_assert_cmpint (gtk_tree_path_get_depth (p), ==, 10);
|
||||
indices = gtk_tree_path_get_indices (p);
|
||||
for (i = 0; i < 10; i++)
|
||||
g_assert_cmpint (indices[i], ==, i);
|
||||
gtk_tree_path_free (p);
|
||||
}
|
||||
|
||||
static void
|
||||
test_first (void)
|
||||
{
|
||||
GtkTreePath *p;
|
||||
p = gtk_tree_path_new_first ();
|
||||
g_assert_cmpint (gtk_tree_path_get_depth (p), ==, 1);
|
||||
g_assert_cmpint (gtk_tree_path_get_indices (p)[0], ==, 0);
|
||||
gtk_tree_path_free (p);
|
||||
}
|
||||
|
||||
static void
|
||||
test_navigation (void)
|
||||
{
|
||||
GtkTreePath *p;
|
||||
GtkTreePath *q;
|
||||
gint *pi;
|
||||
gint *qi;
|
||||
gint i;
|
||||
gboolean res;
|
||||
|
||||
p = gtk_tree_path_new_from_indices (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
|
||||
q = gtk_tree_path_copy (p);
|
||||
g_assert (gtk_tree_path_compare (p, q) == 0);
|
||||
gtk_tree_path_next (q);
|
||||
pi = gtk_tree_path_get_indices (p);
|
||||
qi = gtk_tree_path_get_indices (q);
|
||||
for (i = 0; i < 9; i++)
|
||||
g_assert_cmpint (pi[i], ==, qi[i]);
|
||||
g_assert_cmpint (qi[9], ==, pi[9] + 1);
|
||||
|
||||
g_assert (!gtk_tree_path_is_ancestor (p, q));
|
||||
g_assert (!gtk_tree_path_is_ancestor (q, p));
|
||||
g_assert (!gtk_tree_path_is_descendant (p, q));
|
||||
g_assert (!gtk_tree_path_is_descendant (q, p));
|
||||
|
||||
res = gtk_tree_path_prev (q);
|
||||
g_assert (res);
|
||||
g_assert (gtk_tree_path_compare (p, q) == 0);
|
||||
|
||||
g_assert (!gtk_tree_path_is_ancestor (p, q));
|
||||
g_assert (!gtk_tree_path_is_ancestor (q, p));
|
||||
g_assert (!gtk_tree_path_is_descendant (p, q));
|
||||
g_assert (!gtk_tree_path_is_descendant (q, p));
|
||||
|
||||
gtk_tree_path_down (q);
|
||||
|
||||
g_assert (gtk_tree_path_compare (p, q) < 0);
|
||||
|
||||
g_assert (gtk_tree_path_is_ancestor (p, q));
|
||||
g_assert (!gtk_tree_path_is_ancestor (q, p));
|
||||
g_assert (!gtk_tree_path_is_descendant (p, q));
|
||||
g_assert (gtk_tree_path_is_descendant (q, p));
|
||||
|
||||
res = gtk_tree_path_prev (q);
|
||||
g_assert (!res);
|
||||
|
||||
res = gtk_tree_path_up (q);
|
||||
g_assert (res);
|
||||
g_assert (gtk_tree_path_compare (p, q) == 0);
|
||||
|
||||
g_assert_cmpint (gtk_tree_path_get_depth (q), ==, 10);
|
||||
res = gtk_tree_path_up (q);
|
||||
g_assert (res);
|
||||
g_assert_cmpint (gtk_tree_path_get_depth (q), ==, 9);
|
||||
|
||||
gtk_tree_path_free (p);
|
||||
gtk_tree_path_free (q);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/tree-path/append", test_append);
|
||||
g_test_add_func ("/tree-path/prepend", test_prepend);
|
||||
g_test_add_func ("/tree-path/to-string", test_to_string);
|
||||
g_test_add_func ("/tree-path/from-indices", test_from_indices);
|
||||
g_test_add_func ("/tree-path/first", test_first);
|
||||
g_test_add_func ("/tree-path/navigation", test_navigation);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
1178
testsuite/gtk/treestore.c
Normal file
1178
testsuite/gtk/treestore.c
Normal file
File diff suppressed because it is too large
Load Diff
1494
testsuite/gtk/treeview-scrolling.c
Normal file
1494
testsuite/gtk/treeview-scrolling.c
Normal file
File diff suppressed because it is too large
Load Diff
243
testsuite/gtk/treeview.c
Normal file
243
testsuite/gtk/treeview.c
Normal file
@ -0,0 +1,243 @@
|
||||
/* Basic GtkTreeView unit tests.
|
||||
* Copyright (C) 2009 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_bug_546005 (void)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GtkTreePath *cursor_path;
|
||||
GtkListStore *list_store;
|
||||
GtkWidget *view;
|
||||
|
||||
/* Tests provided by Bjorn Lindqvist, Paul Pogonyshev */
|
||||
view = gtk_tree_view_new ();
|
||||
|
||||
/* Invalid path on tree view without model */
|
||||
path = gtk_tree_path_new_from_indices (1, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
|
||||
NULL, FALSE);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
list_store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (view),
|
||||
GTK_TREE_MODEL (list_store));
|
||||
|
||||
/* Invalid path on tree view with empty model */
|
||||
path = gtk_tree_path_new_from_indices (1, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
|
||||
NULL, FALSE);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
/* Valid path */
|
||||
gtk_list_store_insert_with_values (list_store, &iter, 0,
|
||||
0, "hi",
|
||||
-1);
|
||||
|
||||
path = gtk_tree_path_new_from_indices (0, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
|
||||
NULL, FALSE);
|
||||
|
||||
gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &cursor_path, NULL);
|
||||
//gtk_assert_cmptreepath (cursor_path, ==, path);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
gtk_tree_path_free (cursor_path);
|
||||
|
||||
/* Invalid path on tree view with model */
|
||||
path = gtk_tree_path_new_from_indices (1, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
|
||||
NULL, FALSE);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_bug_539377 (void)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkTreePath *path;
|
||||
GtkListStore *list_store;
|
||||
|
||||
/* Test provided by Bjorn Lindqvist */
|
||||
|
||||
/* Non-realized view, no model */
|
||||
view = gtk_tree_view_new ();
|
||||
g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path,
|
||||
NULL, NULL, NULL) == FALSE);
|
||||
g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10,
|
||||
&path, NULL) == FALSE);
|
||||
|
||||
/* Non-realized view, with model */
|
||||
list_store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (view),
|
||||
GTK_TREE_MODEL (list_store));
|
||||
|
||||
g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path,
|
||||
NULL, NULL, NULL) == FALSE);
|
||||
g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10,
|
||||
&path, NULL) == FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_select_collapsed_row (void)
|
||||
{
|
||||
GtkTreeIter child, parent;
|
||||
GtkTreePath *path;
|
||||
GtkTreeStore *tree_store;
|
||||
GtkTreeSelection *selection;
|
||||
GtkWidget *view;
|
||||
|
||||
/* Reported by Michael Natterer */
|
||||
tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
|
||||
|
||||
gtk_tree_store_insert_with_values (tree_store, &parent, NULL, 0,
|
||||
0, "Parent",
|
||||
-1);
|
||||
|
||||
gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0,
|
||||
0, "Child",
|
||||
-1);
|
||||
gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0,
|
||||
0, "Child",
|
||||
-1);
|
||||
|
||||
|
||||
/* Try to select a child path. */
|
||||
path = gtk_tree_path_new_from_indices (0, 1, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
|
||||
|
||||
/* Check that the parent is not selected. */
|
||||
gtk_tree_path_up (path);
|
||||
g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == FALSE);
|
||||
|
||||
/* Nothing should be selected at this point. */
|
||||
g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 0);
|
||||
|
||||
/* Check that selection really still works. */
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
|
||||
g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
|
||||
g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
|
||||
|
||||
/* Expand and select child node now. */
|
||||
gtk_tree_path_append_index (path, 1);
|
||||
gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
|
||||
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
|
||||
g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
|
||||
g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_row_separator_height_func (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GtkTreePath *path;
|
||||
|
||||
path = gtk_tree_model_get_path (model, iter);
|
||||
if (gtk_tree_path_get_indices (path)[0] == 2)
|
||||
ret = TRUE;
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
test_row_separator_height (void)
|
||||
{
|
||||
int focus_pad, separator_height, height;
|
||||
gboolean wide_separators;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GtkListStore *store;
|
||||
GtkWidget *window;
|
||||
GtkWidget *tree_view;
|
||||
GdkRectangle rect, cell_rect;
|
||||
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
gtk_list_store_insert_with_values (store, &iter, 0, 0, "Row content", -1);
|
||||
gtk_list_store_insert_with_values (store, &iter, 1, 0, "Row content", -1);
|
||||
gtk_list_store_insert_with_values (store, &iter, 2, 0, "Row content", -1);
|
||||
gtk_list_store_insert_with_values (store, &iter, 3, 0, "Row content", -1);
|
||||
gtk_list_store_insert_with_values (store, &iter, 4, 0, "Row content", -1);
|
||||
|
||||
window = gtk_offscreen_window_new ();
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
|
||||
gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (tree_view),
|
||||
test_row_separator_height_func,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
|
||||
0,
|
||||
"Test",
|
||||
gtk_cell_renderer_text_new (),
|
||||
"text", 0,
|
||||
NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), tree_view);
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
|
||||
path = gtk_tree_path_new_from_indices (2, -1);
|
||||
gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
|
||||
path, NULL, &rect);
|
||||
gtk_tree_view_get_cell_area (GTK_TREE_VIEW (tree_view),
|
||||
path, NULL, &cell_rect);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_widget_style_get (tree_view,
|
||||
"focus-padding", &focus_pad,
|
||||
"wide-separators", &wide_separators,
|
||||
"separator-height", &separator_height,
|
||||
NULL);
|
||||
|
||||
if (wide_separators)
|
||||
height = separator_height + 2 * focus_pad;
|
||||
else
|
||||
height = 2 + 2 * focus_pad;
|
||||
|
||||
g_assert_cmpint (rect.height, ==, height);
|
||||
g_assert_cmpint (cell_rect.height, ==, height);
|
||||
|
||||
gtk_widget_destroy (tree_view);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/TreeView/cursor/bug-546005", test_bug_546005);
|
||||
g_test_add_func ("/TreeView/cursor/bug-539377", test_bug_539377);
|
||||
g_test_add_func ("/TreeView/cursor/select-collapsed_row",
|
||||
test_select_collapsed_row);
|
||||
g_test_add_func ("/TreeView/sizing/row-separator-height",
|
||||
test_row_separator_height);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
361
testsuite/gtk/window.c
Normal file
361
testsuite/gtk/window.c
Normal file
@ -0,0 +1,361 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static gboolean interactive = FALSE;
|
||||
|
||||
static gboolean
|
||||
stop_main (gpointer data)
|
||||
{
|
||||
gtk_main_quit ();
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_draw (GtkWidget *widget, cairo_t *cr)
|
||||
{
|
||||
gint i, j;
|
||||
|
||||
for (i = 0; 20 * i < gtk_widget_get_allocated_width (widget); i++)
|
||||
{
|
||||
for (j = 0; 20 * j < gtk_widget_get_allocated_height (widget); j++)
|
||||
{
|
||||
if ((i + j) % 2 == 1)
|
||||
cairo_set_source_rgb (cr, 1., 1., 1.);
|
||||
else
|
||||
cairo_set_source_rgb (cr, 0., 0., 0.);
|
||||
|
||||
cairo_rectangle (cr, 20. * i, 20. *j, 20., 20.);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_keypress (GtkWidget *widget)
|
||||
{
|
||||
gtk_main_quit ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_default_size (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
gint w, h;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
g_signal_connect (window, "draw", G_CALLBACK (on_draw), NULL);
|
||||
if (interactive)
|
||||
g_signal_connect (window, "key-press-event", G_CALLBACK (on_keypress), NULL);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
/* check that default size is unset initially */
|
||||
gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, -1);
|
||||
g_assert_cmpint (h, ==, -1);
|
||||
|
||||
/* check that setting default size before realize works */
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
|
||||
|
||||
gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 300);
|
||||
g_assert_cmpint (h, ==, 300);
|
||||
|
||||
/* check that the window size is also reported accordingly */
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 300);
|
||||
g_assert_cmpint (h, ==, 300);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
if (!interactive)
|
||||
g_timeout_add (200, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
/* check that the window and its content actually gets the right size */
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 300);
|
||||
g_assert_cmpint (h, ==, 300);
|
||||
|
||||
g_assert_cmpint (gtk_widget_get_allocated_width (window), ==, 300);
|
||||
g_assert_cmpint (gtk_widget_get_allocated_height (window), ==, 300);
|
||||
|
||||
g_assert_cmpint (gtk_widget_get_allocated_width (box), ==, 300);
|
||||
g_assert_cmpint (gtk_widget_get_allocated_height (box), ==, 300);
|
||||
|
||||
/* check that setting default size after the fact does not change
|
||||
* window size
|
||||
*/
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 100, 600);
|
||||
gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 100);
|
||||
g_assert_cmpint (h, ==, 600);
|
||||
|
||||
if (!interactive)
|
||||
g_timeout_add (200, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 300);
|
||||
g_assert_cmpint (h, ==, 300);
|
||||
|
||||
/* check that even hide/show does not pull in the new default */
|
||||
gtk_widget_hide (window);
|
||||
gtk_widget_show (window);
|
||||
|
||||
if (!interactive)
|
||||
g_timeout_add (200, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 300);
|
||||
g_assert_cmpint (h, ==, 300);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
static void
|
||||
test_resize (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
gint w, h;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
g_signal_connect (window, "draw", G_CALLBACK (on_draw), NULL);
|
||||
if (interactive)
|
||||
g_signal_connect (window, "key-press-event", G_CALLBACK (on_keypress), NULL);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
/* test that resize before show overrides default size */
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 500, 500);
|
||||
|
||||
gtk_window_resize (GTK_WINDOW (window), 1, 1);
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 1);
|
||||
g_assert_cmpint (h, ==, 1);
|
||||
|
||||
gtk_window_resize (GTK_WINDOW (window), 400, 200);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
if (!interactive)
|
||||
g_timeout_add (200, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
/* test that resize before show works */
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 400);
|
||||
g_assert_cmpint (h, ==, 200);
|
||||
|
||||
/* test that resize after show works, both
|
||||
* for making things bigger and for making things
|
||||
* smaller
|
||||
*/
|
||||
gtk_window_resize (GTK_WINDOW (window), 200, 400);
|
||||
|
||||
if (!interactive)
|
||||
g_timeout_add (200, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (w, ==, 200);
|
||||
g_assert_cmpint (h, ==, 400);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
static void
|
||||
test_resize_popup (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
gint x, y, w, h;
|
||||
|
||||
/* testcase for the dnd window */
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_window_set_screen (GTK_WINDOW (window), gdk_screen_get_default ());
|
||||
gtk_window_resize (GTK_WINDOW (window), 1, 1);
|
||||
gtk_window_move (GTK_WINDOW (window), -99, -99);
|
||||
|
||||
gtk_window_get_position (GTK_WINDOW (window), &x, &y);
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (x, ==, -99);
|
||||
g_assert_cmpint (y, ==, -99);
|
||||
g_assert_cmpint (w, ==, 1);
|
||||
g_assert_cmpint (h, ==, 1);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (200, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_position (GTK_WINDOW (window), &x, &y);
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
g_assert_cmpint (x, ==, -99);
|
||||
g_assert_cmpint (y, ==, -99);
|
||||
g_assert_cmpint (w, ==, 1);
|
||||
g_assert_cmpint (h, ==, 1);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
static void
|
||||
test_show_hide (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
gint w, h, w1, h1;
|
||||
|
||||
g_test_bug ("696882");
|
||||
|
||||
/* test that hide/show does not affect the size */
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
|
||||
gtk_widget_hide (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
|
||||
g_assert_cmpint (w, ==, w1);
|
||||
g_assert_cmpint (h, ==, h1);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
|
||||
g_assert_cmpint (w, ==, w1);
|
||||
g_assert_cmpint (h, ==, h1);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
static void
|
||||
test_show_hide2 (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
gint x, y, w, h, w1, h1;
|
||||
|
||||
g_test_bug ("696882");
|
||||
|
||||
/* test that hide/show does not affect the size,
|
||||
* even when get_position/move is called
|
||||
*/
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_position (GTK_WINDOW (window), &x, &y);
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
gtk_widget_hide (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
|
||||
g_assert_cmpint (w, ==, w1);
|
||||
g_assert_cmpint (h, ==, h1);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (window), x, y);
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
|
||||
g_assert_cmpint (w, ==, w1);
|
||||
g_assert_cmpint (h, ==, h1);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
static void
|
||||
test_show_hide3 (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
gint x, y, w, h, w1, h1;
|
||||
|
||||
g_test_bug ("696882");
|
||||
|
||||
/* test that hide/show does not affect the size,
|
||||
* even when get_position/move is called and
|
||||
* a default size is set
|
||||
*/
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_position (GTK_WINDOW (window), &x, &y);
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
|
||||
gtk_widget_hide (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
|
||||
g_assert_cmpint (w, ==, w1);
|
||||
g_assert_cmpint (h, ==, h1);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (window), x, y);
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (100, stop_main, NULL);
|
||||
gtk_main ();
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
|
||||
g_assert_cmpint (w, ==, w1);
|
||||
g_assert_cmpint (h, ==, h1);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gint i;
|
||||
|
||||
gtk_test_init (&argc, &argv);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (g_strcmp0 (argv[i], "--interactive") == 0)
|
||||
interactive = TRUE;
|
||||
}
|
||||
|
||||
g_test_add_func ("/window/default-size", test_default_size);
|
||||
g_test_add_func ("/window/resize", test_resize);
|
||||
g_test_add_func ("/window/resize-popup", test_resize_popup);
|
||||
g_test_add_func ("/window/show-hide", test_show_hide);
|
||||
g_test_add_func ("/window/show-hide2", test_show_hide2);
|
||||
g_test_add_func ("/window/show-hide3", test_show_hide3);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
Reference in New Issue
Block a user