build: Move gtk/tests to testsuite/gtk

This commit is contained in:
Benjamin Otte
2013-05-15 01:48:18 +02:00
parent 6ea4c144dd
commit bdfb55c945
45 changed files with 3 additions and 3 deletions

View File

@ -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
View 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
View 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();
}

View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

863
testsuite/gtk/cellarea.c Normal file
View 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();
}

View 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 ();
}

View 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
View 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
View 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();
}

View File

@ -0,0 +1 @@
Hello world!

2492
testsuite/gtk/filechooser.c Normal file

File diff suppressed because it is too large Load Diff

7147
testsuite/gtk/filtermodel.c Normal file

File diff suppressed because it is too large Load Diff

55
testsuite/gtk/floating.c Normal file
View 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
View 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
View 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: */

View 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);
}

View 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
View 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

File diff suppressed because it is too large Load Diff

View 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
View 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 ();
}

View 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
View 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
View 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 ();
}

View 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 ();
}

View 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

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

269
testsuite/gtk/textiter.c Normal file
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

243
testsuite/gtk/treeview.c Normal file
View 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
View 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 ();
}