summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am128
-rw-r--r--tests/Makefile.in203
-rw-r--r--tests/compat_test_pygtk.py147
-rw-r--r--tests/compathelper.py2
-rw-r--r--tests/gi/__init__.py2
-rw-r--r--tests/gi/overrides/Regress.py26
-rw-r--r--tests/gi/overrides/__init__.py2
-rw-r--r--tests/org.gnome.test.gschema.xml9
-rw-r--r--tests/runtests-windows.py10
-rwxr-xr-xtests/runtests.py38
-rw-r--r--tests/test-thread.c3
-rw-r--r--tests/test-unknown.c2
-rw-r--r--tests/test_atoms.py77
-rw-r--r--tests/test_docstring.py49
-rw-r--r--tests/test_everything.py989
-rw-r--r--tests/test_gdbus.py89
-rw-r--r--tests/test_generictreemodel.py411
-rw-r--r--tests/test_gi.py1731
-rw-r--r--tests/test_gio.py203
-rw-r--r--tests/test_glib.py206
-rw-r--r--tests/test_gobject.py579
-rw-r--r--tests/test_gtype.py51
-rw-r--r--tests/test_interface.py5
-rw-r--r--tests/test_internal_api.py73
-rw-r--r--tests/test_iochannel.py424
-rw-r--r--tests/test_mainloop.py68
-rw-r--r--tests/test_object_marshaling.py603
-rw-r--r--tests/test_option.py82
-rw-r--r--tests/test_overrides.py1983
-rw-r--r--tests/test_overrides_gdk.py141
-rw-r--r--tests/test_overrides_glib.py489
-rw-r--r--tests/test_overrides_gtk.py1748
-rw-r--r--tests/test_overrides_pango.py37
-rw-r--r--tests/test_properties.py604
-rw-r--r--tests/test_pygtkcompat.py83
-rw-r--r--tests/test_signal.py746
-rw-r--r--tests/test_source.py290
-rw-r--r--tests/test_subprocess.py135
-rw-r--r--tests/test_thread.py3
-rw-r--r--tests/test_uris.py15
-rw-r--r--tests/testhelpermodule.c112
-rw-r--r--tests/testmodule.py1
42 files changed, 9486 insertions, 3113 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e666696..b845e4b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,19 +1,36 @@
CLEANFILES =
-noinst_LTLIBRARIES = libregress.la libgimarshallingtests.la
+check_LTLIBRARIES = libgimarshallingtests.la
+test_typelibs = GIMarshallingTests-1.0.typelib
-nodist_libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h
-libregress_la_CFLAGS = $(GIO_CFLAGS) $(PYCAIRO_CFLAGS)
-libregress_la_LDFLAGS = -module -avoid-version $(GIO_LIBS) $(PYCAIRO_LIBS)
nodist_libgimarshallingtests_la_SOURCES = $(GI_DATADIR)/tests/gimarshallingtests.c $(GI_DATADIR)/tests/gimarshallingtests.h
libgimarshallingtests_la_CFLAGS = $(GLIB_CFLAGS)
libgimarshallingtests_la_LDFLAGS = -module -avoid-version $(GLIB_LIBS)
# This is a hack to make sure a shared library is built
-libregress.la: $(libregress_la_OBJECTS) $(libregress_la_DEPENDENCIES)
- $(LINK) -rpath $(pkgpyexecdir) $(libregress_la_LDFLAGS) $(libregress_la_OBJECTS) $(libregress_la_LIBADD) $(LIBS)
-
libgimarshallingtests.la: $(libgimarshallingtests_la_OBJECTS) $(libgimarshallingtests_la_DEPENDENCIES)
- $(LINK) -rpath $(pkgpyexecdir) $(libgimarshallingtests_la_LDFLAGS) $(libgimarshallingtests_la_OBJECTS) $(libgimarhallingtests_la_LIBADD) $(LIBS)
+ $(AM_V_GEN) $(LINK) -rpath $(pkgpyexecdir) $(libgimarshallingtests_la_LDFLAGS) $(libgimarshallingtests_la_OBJECTS) $(libgimarhallingtests_la_LIBADD) $(LIBS)
+
+GIMarshallingTests-1.0.gir: libgimarshallingtests.la Makefile
+ $(AM_V_GEN) g-ir-scanner --include=Gio-2.0 \
+ --namespace=GIMarshallingTests --nsversion=1.0 --symbol-prefix=gi_marshalling_tests \
+ --warn-all --warn-error \
+ --library=libgimarshallingtests.la \
+ --libtool="$(top_builddir)/libtool" \
+ --output $@ \
+ $(nodist_libgimarshallingtests_la_SOURCES)
+GIMarshallingTests-1.0.typelib: GIMarshallingTests-1.0.gir Makefile
+ $(AM_V_GEN) g-ir-compiler $< -o $@
+
+# regress.c needs cairo
+if ENABLE_CAIRO
+check_LTLIBRARIES += libregress.la
+test_typelibs += Regress-1.0.typelib
+nodist_libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h
+libregress_la_CFLAGS = $(GIO_CFLAGS) $(CAIRO_CFLAGS)
+libregress_la_LDFLAGS = -module -avoid-version $(GIO_LIBS) $(CAIRO_LIBS)
+
+libregress.la: $(libregress_la_OBJECTS) $(libregress_la_DEPENDENCIES)
+ $(AM_V_GEN) $(LINK) -rpath $(pkgpyexecdir) $(libregress_la_LDFLAGS) $(libregress_la_OBJECTS) $(libregress_la_LIBADD) $(LIBS)
# g-i doesn't ship these as shared libraries anymore; we build them here
Regress-1.0.gir: libregress.la Makefile
@@ -27,23 +44,15 @@ Regress-1.0.gir: libregress.la Makefile
Regress-1.0.typelib: Regress-1.0.gir Makefile
$(AM_V_GEN) g-ir-compiler $< -o $@
-GIMarshallingTests-1.0.gir: libgimarshallingtests.la Makefile
- $(AM_V_GEN) g-ir-scanner --include=Gio-2.0 \
- --namespace=GIMarshallingTests --nsversion=1.0 --symbol-prefix=gi_marshalling_tests \
- --warn-all --warn-error \
- --library=libgimarshallingtests.la \
- --libtool="$(top_builddir)/libtool" \
- --output $@ \
- $(nodist_libgimarshallingtests_la_SOURCES)
-GIMarshallingTests-1.0.typelib: GIMarshallingTests-1.0.gir Makefile
- $(AM_V_GEN) g-ir-compiler $< -o $@
+endif # ENABLE_CAIRO
+
gschemas.compiled: org.gnome.test.gschema.xml
glib-compile-schemas --targetdir=. --schema-file=$<
CLEANFILES += Regress-1.0.gir Regress-1.0.typelib GIMarshallingTests-1.0.gir GIMarshallingTests-1.0.typelib gschemas.compiled
-noinst_LTLIBRARIES += testhelper.la
+check_LTLIBRARIES += testhelper.la
testhelper_la_CFLAGS = -I$(top_srcdir)/gi/_gobject -I$(top_srcdir)/gi/_glib $(PYTHON_INCLUDES) $(GLIB_CFLAGS)
testhelper_la_LDFLAGS = -module -avoid-version
@@ -56,50 +65,59 @@ testhelper_la_SOURCES = \
# This is a hack to make sure a shared library is built
testhelper.la: $(testhelper_la_OBJECTS) $(testhelper_la_DEPENDENCIES)
- $(LINK) -rpath $(pkgpyexecdir) $(testhelper_la_LDFLAGS) $(testhelper_la_OBJECTS) $(testhelper_la_LIBADD) $(LIBS)
+ $(AM_V_GEN) $(LINK) -rpath $(pkgpyexecdir) $(testhelper_la_LDFLAGS) $(testhelper_la_OBJECTS) $(testhelper_la_LIBADD) $(LIBS)
.la.so:
test -L $@ || $(LN_S) .libs/$@ $@
-all: $(LTLIBRARIES:.la=.so)
+all: $(check_LTLIBRARIES:.la=.so)
-TEST_FILES_STATIC = \
+EXTRA_DIST = \
+ compathelper.py \
+ runtests.py \
+ runtests-windows.py \
+ testmodule.py \
+ test-floating.h \
+ test-thread.h \
+ test-unknown.h \
+ te_ST@nouppera \
+ org.gnome.test.gschema.xml \
+ test_gio.py \
+ test_glib.py \
test_gobject.py \
+ test_gtype.py \
test_interface.py \
+ test_internal_api.py \
+ test_iochannel.py \
test_mainloop.py \
+ test_object_marshaling.py \
test_option.py \
test_properties.py \
test_signal.py \
test_source.py \
test_subprocess.py \
test_thread.py \
- test_uris.py
-
-
-TEST_FILES_GI = \
test_everything.py \
test_gi.py \
test_gdbus.py \
test_overrides.py \
- test_pygtkcompat.py
-
-EXTRA_DIST = \
- compathelper.py \
- runtests.py \
- runtests-windows.py \
- testmodule.py \
- test-floating.h \
- test-thread.h \
- test-unknown.h \
- te_ST@nouppera \
- org.gnome.test.gschema.xml
-
-EXTRA_DIST += $(TEST_FILES_STATIC) $(TEST_FILES_GI)
+ test_overrides_glib.py \
+ test_overrides_pango.py \
+ test_overrides_gdk.py \
+ test_overrides_gtk.py \
+ test_atoms.py \
+ test_generictreemodel.py \
+ test_docstring.py \
+ compat_test_pygtk.py \
+ gi/__init__.py \
+ gi/overrides/__init__.py \
+ gi/overrides/Regress.py \
+ $(NULL)
clean-local:
- rm -f $(LTLIBRARIES:.la=.so) file.txt~
+ rm -f $(check_LTLIBRARIES:.la=.so) file.txt~
DBUS_LAUNCH=$(shell which dbus-launch)
RUN_TESTS_ENV_VARS= \
@@ -107,17 +125,31 @@ RUN_TESTS_ENV_VARS= \
LD_LIBRARY_PATH=$(builddir)/.libs:$$LD_LIBRARY_PATH \
GI_TYPELIB_PATH=$(builddir):$$GI_TYPELIB_PATH \
XDG_DATA_DIRS=$$XDG_DATA_DIRS:/usr/share \
+ MALLOC_PERTURB_=85 \
+ MALLOC_CHECK_=3 \
+ G_SLICE=debug-blocks \
TESTS_BUILDDIR=$(builddir)
-RUN_TESTS_LAUNCH=$(RUN_TESTS_ENV_VARS) $(DBUS_LAUNCH) $(EXEC_NAME) $(PYTHON) $(srcdir)/runtests.py
-check-local: $(LTLIBRARIES:.la=.so) Regress-1.0.typelib GIMarshallingTests-1.0.typelib gschemas.compiled
- TEST_FILES="$(TEST_FILES_STATIC)" $(RUN_TESTS_LAUNCH)
- TEST_FILES="$(TEST_FILES_GI)" $(RUN_TESTS_LAUNCH)
+# pygtkcompat tests need to be run in a separate process as they
+# clobber global name space
+check-local: $(check_LTLIBRARIES:.la=.so) $(test_typelibs) gschemas.compiled
+ @echo " CHECK Pyflakes"
+ @if type pyflakes >/dev/null 2>&1; then pyflakes $(top_srcdir); else echo "skipped, pyflakes not installed"; fi
+ @if test -z "$$SKIP_PEP8"; then \
+ echo " CHECK PEP8"; \
+ if type pep8 >/dev/null 2>&1; then pep8 --ignore=E501,E123,E124 --repeat --show-source $(top_srcdir); else echo "skipped, pep8 not installed"; fi; \
+ fi
+ export `$(DBUS_LAUNCH)` && \
+ $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd $(srcdir)/runtests.py; rc=$$?; \
+ [ "$$rc" -ne 0 ] || [ -n "$$TEST_NAMES" ] || { TEST_NAMES=compat_test_pygtk $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd -Werror::PendingDeprecationWarning -Werror::DeprecationWarning -Werror::RuntimeWarning $(srcdir)/runtests.py; rc=$$?; }; \
+ kill $$DBUS_SESSION_BUS_PID; \
+ exit $$rc
check.gdb:
EXEC_NAME="gdb --args" $(MAKE) check
-check.valgrind:
- EXEC_NAME="valgrind --suppressions=python.supp" G_SLICE=always-malloc G_DEBUG=gc-friendly $(MAKE) check
+check.nemiver:
+ EXEC_NAME="nemiver" $(MAKE) check
--include $(top_srcdir)/git.mk
+check.valgrind:
+ EXEC_NAME="valgrind --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 5744e30..c88e320 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -14,8 +14,24 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
-
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -34,21 +50,22 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+
+# regress.c needs cairo
+@ENABLE_CAIRO_TRUE@am__append_1 = libregress.la
+@ENABLE_CAIRO_TRUE@am__append_2 = Regress-1.0.typelib
subdir = tests
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
- $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/python.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/python.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
libgimarshallingtests_la_LIBADD =
nodist_libgimarshallingtests_la_OBJECTS = \
libgimarshallingtests_la-gimarshallingtests.lo
@@ -62,11 +79,13 @@ libgimarshallingtests_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(libgimarshallingtests_la_CFLAGS) $(CFLAGS) \
$(libgimarshallingtests_la_LDFLAGS) $(LDFLAGS) -o $@
libregress_la_LIBADD =
-nodist_libregress_la_OBJECTS = libregress_la-regress.lo
+@ENABLE_CAIRO_TRUE@nodist_libregress_la_OBJECTS = \
+@ENABLE_CAIRO_TRUE@ libregress_la-regress.lo
libregress_la_OBJECTS = $(nodist_libregress_la_OBJECTS)
libregress_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libregress_la_CFLAGS) \
$(CFLAGS) $(libregress_la_LDFLAGS) $(LDFLAGS) -o $@
+@ENABLE_CAIRO_TRUE@am_libregress_la_rpath =
am__DEPENDENCIES_1 =
testhelper_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_testhelper_la_OBJECTS = testhelper_la-testhelpermodule.lo \
@@ -105,6 +124,11 @@ am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(nodist_libgimarshallingtests_la_SOURCES) \
$(nodist_libregress_la_SOURCES) $(testhelper_la_SOURCES)
DIST_SOURCES = $(testhelper_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -118,9 +142,14 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
+CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
+CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -138,6 +167,7 @@ EXEEXT = @EXEEXT@
FFI_CFLAGS = @FFI_CFLAGS@
FFI_LIBS = @FFI_LIBS@
FGREP = @FGREP@
+GENHTML = @GENHTML@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
GI_CFLAGS = @GI_CFLAGS@
@@ -157,6 +187,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+LCOV = @LCOV@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBFFI_PC = @LIBFFI_PC@
@@ -166,7 +197,6 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
@@ -201,6 +231,7 @@ PYTHON_LIBS = @PYTHON_LIBS@
PYTHON_LIB_LOC = @PYTHON_LIB_LOC@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SO = @PYTHON_SO@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
@@ -209,6 +240,7 @@ SHELL = @SHELL@
STRIP = @STRIP@
THREADING_CFLAGS = @THREADING_CFLAGS@
VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -268,14 +300,15 @@ top_srcdir = @top_srcdir@
CLEANFILES = Regress-1.0.gir Regress-1.0.typelib \
GIMarshallingTests-1.0.gir GIMarshallingTests-1.0.typelib \
gschemas.compiled
-noinst_LTLIBRARIES = libregress.la libgimarshallingtests.la \
+check_LTLIBRARIES = libgimarshallingtests.la $(am__append_1) \
testhelper.la
-nodist_libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h
-libregress_la_CFLAGS = $(GIO_CFLAGS) $(PYCAIRO_CFLAGS)
-libregress_la_LDFLAGS = -module -avoid-version $(GIO_LIBS) $(PYCAIRO_LIBS)
+test_typelibs = GIMarshallingTests-1.0.typelib $(am__append_2)
nodist_libgimarshallingtests_la_SOURCES = $(GI_DATADIR)/tests/gimarshallingtests.c $(GI_DATADIR)/tests/gimarshallingtests.h
libgimarshallingtests_la_CFLAGS = $(GLIB_CFLAGS)
libgimarshallingtests_la_LDFLAGS = -module -avoid-version $(GLIB_LIBS)
+@ENABLE_CAIRO_TRUE@nodist_libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h
+@ENABLE_CAIRO_TRUE@libregress_la_CFLAGS = $(GIO_CFLAGS) $(CAIRO_CFLAGS)
+@ENABLE_CAIRO_TRUE@libregress_la_LDFLAGS = -module -avoid-version $(GIO_LIBS) $(CAIRO_LIBS)
testhelper_la_CFLAGS = -I$(top_srcdir)/gi/_gobject -I$(top_srcdir)/gi/_glib $(PYTHON_INCLUDES) $(GLIB_CFLAGS)
testhelper_la_LDFLAGS = -module -avoid-version
testhelper_la_LIBADD = $(GLIB_LIBS)
@@ -285,43 +318,64 @@ testhelper_la_SOURCES = \
test-thread.c \
test-unknown.c
-TEST_FILES_STATIC = \
+EXTRA_DIST = \
+ compathelper.py \
+ runtests.py \
+ runtests-windows.py \
+ testmodule.py \
+ test-floating.h \
+ test-thread.h \
+ test-unknown.h \
+ te_ST@nouppera \
+ org.gnome.test.gschema.xml \
+ test_gio.py \
+ test_glib.py \
test_gobject.py \
+ test_gtype.py \
test_interface.py \
+ test_internal_api.py \
+ test_iochannel.py \
test_mainloop.py \
+ test_object_marshaling.py \
test_option.py \
test_properties.py \
test_signal.py \
test_source.py \
test_subprocess.py \
test_thread.py \
- test_uris.py
-
-TEST_FILES_GI = \
test_everything.py \
test_gi.py \
test_gdbus.py \
test_overrides.py \
- test_pygtkcompat.py
+ test_overrides_glib.py \
+ test_overrides_pango.py \
+ test_overrides_gdk.py \
+ test_overrides_gtk.py \
+ test_atoms.py \
+ test_generictreemodel.py \
+ test_docstring.py \
+ compat_test_pygtk.py \
+ gi/__init__.py \
+ gi/overrides/__init__.py \
+ gi/overrides/Regress.py \
+ $(NULL)
-EXTRA_DIST = compathelper.py runtests.py runtests-windows.py \
- testmodule.py test-floating.h test-thread.h test-unknown.h \
- te_ST@nouppera org.gnome.test.gschema.xml $(TEST_FILES_STATIC) \
- $(TEST_FILES_GI)
DBUS_LAUNCH = $(shell which dbus-launch)
RUN_TESTS_ENV_VARS = \
PYTHONPATH=$(top_builddir):$(top_builddir)/tests:$${PYTHONPATH:+:$$PYTHONPATH} \
LD_LIBRARY_PATH=$(builddir)/.libs:$$LD_LIBRARY_PATH \
GI_TYPELIB_PATH=$(builddir):$$GI_TYPELIB_PATH \
XDG_DATA_DIRS=$$XDG_DATA_DIRS:/usr/share \
+ MALLOC_PERTURB_=85 \
+ MALLOC_CHECK_=3 \
+ G_SLICE=debug-blocks \
TESTS_BUILDDIR=$(builddir)
-RUN_TESTS_LAUNCH = $(RUN_TESTS_ENV_VARS) $(DBUS_LAUNCH) $(EXEC_NAME) $(PYTHON) $(srcdir)/runtests.py
all: all-am
.SUFFIXES:
.SUFFIXES: .c .la .lo .o .obj .so
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -346,20 +400,22 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-clean-noinstLTLIBRARIES:
- -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+clean-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
+@ENABLE_CAIRO_FALSE@libregress.la: $(libregress_la_OBJECTS) $(libregress_la_DEPENDENCIES) $(EXTRA_libregress_la_DEPENDENCIES)
+@ENABLE_CAIRO_FALSE@ $(AM_V_CCLD)$(libregress_la_LINK) $(am_libregress_la_rpath) $(libregress_la_OBJECTS) $(libregress_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -526,9 +582,10 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES)
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
-all-am: Makefile $(LTLIBRARIES)
+all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
@@ -563,8 +620,8 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libtool clean-local \
- clean-noinstLTLIBRARIES mostlyclean-am
+clean-am: clean-checkLTLIBRARIES clean-generic clean-libtool \
+ clean-local mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
@@ -635,38 +692,23 @@ uninstall-am:
.MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \
- clean-generic clean-libtool clean-local \
- clean-noinstLTLIBRARIES ctags distclean distclean-compile \
- distclean-generic distclean-libtool distclean-tags distdir dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
+ clean-checkLTLIBRARIES clean-generic clean-libtool clean-local \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am
# This is a hack to make sure a shared library is built
-libregress.la: $(libregress_la_OBJECTS) $(libregress_la_DEPENDENCIES)
- $(LINK) -rpath $(pkgpyexecdir) $(libregress_la_LDFLAGS) $(libregress_la_OBJECTS) $(libregress_la_LIBADD) $(LIBS)
-
libgimarshallingtests.la: $(libgimarshallingtests_la_OBJECTS) $(libgimarshallingtests_la_DEPENDENCIES)
- $(LINK) -rpath $(pkgpyexecdir) $(libgimarshallingtests_la_LDFLAGS) $(libgimarshallingtests_la_OBJECTS) $(libgimarhallingtests_la_LIBADD) $(LIBS)
-
-# g-i doesn't ship these as shared libraries anymore; we build them here
-Regress-1.0.gir: libregress.la Makefile
- $(AM_V_GEN) g-ir-scanner --include=cairo-1.0 --include=Gio-2.0 \
- --namespace=Regress --nsversion=1.0 \
- --warn-all --warn-error \
- --library=libregress.la \
- --libtool="$(top_builddir)/libtool" \
- --output $@ \
- $(nodist_libregress_la_SOURCES)
-Regress-1.0.typelib: Regress-1.0.gir Makefile
- $(AM_V_GEN) g-ir-compiler $< -o $@
+ $(AM_V_GEN) $(LINK) -rpath $(pkgpyexecdir) $(libgimarshallingtests_la_LDFLAGS) $(libgimarshallingtests_la_OBJECTS) $(libgimarhallingtests_la_LIBADD) $(LIBS)
GIMarshallingTests-1.0.gir: libgimarshallingtests.la Makefile
$(AM_V_GEN) g-ir-scanner --include=Gio-2.0 \
@@ -679,32 +721,59 @@ GIMarshallingTests-1.0.gir: libgimarshallingtests.la Makefile
GIMarshallingTests-1.0.typelib: GIMarshallingTests-1.0.gir Makefile
$(AM_V_GEN) g-ir-compiler $< -o $@
+@ENABLE_CAIRO_TRUE@libregress.la: $(libregress_la_OBJECTS) $(libregress_la_DEPENDENCIES)
+@ENABLE_CAIRO_TRUE@ $(AM_V_GEN) $(LINK) -rpath $(pkgpyexecdir) $(libregress_la_LDFLAGS) $(libregress_la_OBJECTS) $(libregress_la_LIBADD) $(LIBS)
+
+# g-i doesn't ship these as shared libraries anymore; we build them here
+@ENABLE_CAIRO_TRUE@Regress-1.0.gir: libregress.la Makefile
+@ENABLE_CAIRO_TRUE@ $(AM_V_GEN) g-ir-scanner --include=cairo-1.0 --include=Gio-2.0 \
+@ENABLE_CAIRO_TRUE@ --namespace=Regress --nsversion=1.0 \
+@ENABLE_CAIRO_TRUE@ --warn-all --warn-error \
+@ENABLE_CAIRO_TRUE@ --library=libregress.la \
+@ENABLE_CAIRO_TRUE@ --libtool="$(top_builddir)/libtool" \
+@ENABLE_CAIRO_TRUE@ --output $@ \
+@ENABLE_CAIRO_TRUE@ $(nodist_libregress_la_SOURCES)
+@ENABLE_CAIRO_TRUE@Regress-1.0.typelib: Regress-1.0.gir Makefile
+@ENABLE_CAIRO_TRUE@ $(AM_V_GEN) g-ir-compiler $< -o $@
+
gschemas.compiled: org.gnome.test.gschema.xml
glib-compile-schemas --targetdir=. --schema-file=$<
# This is a hack to make sure a shared library is built
testhelper.la: $(testhelper_la_OBJECTS) $(testhelper_la_DEPENDENCIES)
- $(LINK) -rpath $(pkgpyexecdir) $(testhelper_la_LDFLAGS) $(testhelper_la_OBJECTS) $(testhelper_la_LIBADD) $(LIBS)
+ $(AM_V_GEN) $(LINK) -rpath $(pkgpyexecdir) $(testhelper_la_LDFLAGS) $(testhelper_la_OBJECTS) $(testhelper_la_LIBADD) $(LIBS)
.la.so:
test -L $@ || $(LN_S) .libs/$@ $@
-all: $(LTLIBRARIES:.la=.so)
+all: $(check_LTLIBRARIES:.la=.so)
clean-local:
- rm -f $(LTLIBRARIES:.la=.so) file.txt~
-
-check-local: $(LTLIBRARIES:.la=.so) Regress-1.0.typelib GIMarshallingTests-1.0.typelib gschemas.compiled
- TEST_FILES="$(TEST_FILES_STATIC)" $(RUN_TESTS_LAUNCH)
- TEST_FILES="$(TEST_FILES_GI)" $(RUN_TESTS_LAUNCH)
+ rm -f $(check_LTLIBRARIES:.la=.so) file.txt~
+
+# pygtkcompat tests need to be run in a separate process as they
+# clobber global name space
+check-local: $(check_LTLIBRARIES:.la=.so) $(test_typelibs) gschemas.compiled
+ @echo " CHECK Pyflakes"
+ @if type pyflakes >/dev/null 2>&1; then pyflakes $(top_srcdir); else echo "skipped, pyflakes not installed"; fi
+ @if test -z "$$SKIP_PEP8"; then \
+ echo " CHECK PEP8"; \
+ if type pep8 >/dev/null 2>&1; then pep8 --ignore=E501,E123,E124 --repeat --show-source $(top_srcdir); else echo "skipped, pep8 not installed"; fi; \
+ fi
+ export `$(DBUS_LAUNCH)` && \
+ $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd $(srcdir)/runtests.py; rc=$$?; \
+ [ "$$rc" -ne 0 ] || [ -n "$$TEST_NAMES" ] || { TEST_NAMES=compat_test_pygtk $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd -Werror::PendingDeprecationWarning -Werror::DeprecationWarning -Werror::RuntimeWarning $(srcdir)/runtests.py; rc=$$?; }; \
+ kill $$DBUS_SESSION_BUS_PID; \
+ exit $$rc
check.gdb:
EXEC_NAME="gdb --args" $(MAKE) check
-check.valgrind:
- EXEC_NAME="valgrind --suppressions=python.supp" G_SLICE=always-malloc G_DEBUG=gc-friendly $(MAKE) check
+check.nemiver:
+ EXEC_NAME="nemiver" $(MAKE) check
--include $(top_srcdir)/git.mk
+check.valgrind:
+ EXEC_NAME="valgrind --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tests/compat_test_pygtk.py b/tests/compat_test_pygtk.py
new file mode 100644
index 0000000..10be6a3
--- /dev/null
+++ b/tests/compat_test_pygtk.py
@@ -0,0 +1,147 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+
+from gi.repository import GLib
+
+try:
+ from gi.repository import Pango
+ from gi.repository import Atk
+ from gi.repository import Gdk
+ from gi.repository import Gtk
+ (Atk, Gtk, Pango) # pyflakes
+
+ import pygtkcompat
+
+ pygtkcompat.enable()
+ pygtkcompat.enable_gtk(version='3.0')
+
+ import atk
+ import pango
+ import pangocairo
+ import gtk
+ import gtk.gdk
+except ImportError:
+ Gtk = None
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestATKCompat(unittest.TestCase):
+ def test_object(self):
+ self.assertTrue(hasattr(atk, 'Object'))
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestPangoCompat(unittest.TestCase):
+ def test_layout(self):
+ self.assertTrue(hasattr(pango, 'Layout'))
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestPangoCairoCompat(unittest.TestCase):
+ def test_error_underline_path(self):
+ self.assertTrue(hasattr(pangocairo, 'error_underline_path'))
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestGTKCompat(unittest.TestCase):
+ def test_buttons(self):
+ self.assertEqual(Gdk._2BUTTON_PRESS, 5)
+ self.assertEqual(Gdk.BUTTON_PRESS, 4)
+
+ def test_enums(self):
+ self.assertEqual(gtk.WINDOW_TOPLEVEL, Gtk.WindowType.TOPLEVEL)
+ self.assertEqual(gtk.PACK_START, Gtk.PackType.START)
+
+ def test_flags(self):
+ self.assertEqual(gtk.EXPAND, Gtk.AttachOptions.EXPAND)
+ self.assertEqual(gtk.gdk.SHIFT_MASK, Gdk.ModifierType.SHIFT_MASK)
+
+ def test_keysyms(self):
+ import gtk.keysyms
+ self.assertEqual(gtk.keysyms.Escape, Gdk.KEY_Escape)
+ self.assertTrue(gtk.keysyms._0, Gdk.KEY_0)
+
+ def test_style(self):
+ widget = gtk.Button()
+ self.assertTrue(isinstance(widget.style.base[gtk.STATE_NORMAL],
+ gtk.gdk.Color))
+
+ def test_alignment(self):
+ a = gtk.Alignment()
+ self.assertEqual(a.props.xalign, 0.0)
+ self.assertEqual(a.props.yalign, 0.0)
+ self.assertEqual(a.props.xscale, 0.0)
+ self.assertEqual(a.props.yscale, 0.0)
+
+ def test_box(self):
+ box = gtk.Box()
+ child = gtk.Button()
+
+ box.pack_start(child)
+ expand, fill, padding, pack_type = box.query_child_packing(child)
+ self.assertTrue(expand)
+ self.assertTrue(fill)
+ self.assertEqual(padding, 0)
+ self.assertEqual(pack_type, gtk.PACK_START)
+
+ child = gtk.Button()
+ box.pack_end(child)
+ expand, fill, padding, pack_type = box.query_child_packing(child)
+ self.assertTrue(expand)
+ self.assertTrue(fill)
+ self.assertEqual(padding, 0)
+ self.assertEqual(pack_type, gtk.PACK_END)
+
+ def test_combobox_entry(self):
+ liststore = gtk.ListStore(int, str)
+ liststore.append((1, 'One'))
+ liststore.append((2, 'Two'))
+ liststore.append((3, 'Three'))
+ # might cause a Pango warning, do not break on this
+ old_mask = GLib.log_set_always_fatal(
+ GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
+ try:
+ combo = gtk.ComboBoxEntry(model=liststore)
+ finally:
+ GLib.log_set_always_fatal(old_mask)
+ combo.set_text_column(1)
+ combo.set_active(0)
+ self.assertEqual(combo.get_text_column(), 1)
+ self.assertEqual(combo.get_child().get_text(), 'One')
+ combo = gtk.combo_box_entry_new()
+ combo.set_model(liststore)
+ combo.set_text_column(1)
+ combo.set_active(0)
+ self.assertEqual(combo.get_text_column(), 1)
+ self.assertEqual(combo.get_child().get_text(), 'One')
+ combo = gtk.combo_box_entry_new_with_model(liststore)
+ combo.set_text_column(1)
+ combo.set_active(0)
+ self.assertEqual(combo.get_text_column(), 1)
+ self.assertEqual(combo.get_child().get_text(), 'One')
+
+ def test_size_request(self):
+ box = gtk.Box()
+ self.assertEqual(box.size_request(), [0, 0])
+
+ def test_pixbuf(self):
+ gtk.gdk.Pixbuf()
+
+ def test_pixbuf_loader(self):
+ loader = gtk.gdk.PixbufLoader('png')
+ loader.close()
+
+ def test_pixbuf_formats(self):
+ formats = gtk.gdk.pixbuf_get_formats()
+ self.assertEqual(type(formats[0]), dict)
+ self.assertTrue('name' in formats[0])
+ self.assertTrue('description' in formats[0])
+ self.assertTrue('mime_types' in formats[0])
+ self.assertEqual(type(formats[0]['extensions']), list)
+
+ def test_gdk_window(self):
+ w = gtk.Window()
+ w.realize()
+ self.assertEqual(w.get_window().get_origin(), (0, 0))
diff --git a/tests/compathelper.py b/tests/compathelper.py
index 2465747..668e60a 100644
--- a/tests/compathelper.py
+++ b/tests/compathelper.py
@@ -49,7 +49,7 @@ if sys.version_info >= (3, 0):
for tests that need to write to intefaces that take unicode in
python 2
- python 3 strings are unicode encoded as UTF-8 so the unicode object
+ python 3 strings are unicode encoded as UTF-8 so the unicode object
doesn't exist
python 2 differs between a string an unicode string and you must specify
diff --git a/tests/gi/__init__.py b/tests/gi/__init__.py
new file mode 100644
index 0000000..3ad9513
--- /dev/null
+++ b/tests/gi/__init__.py
@@ -0,0 +1,2 @@
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
diff --git a/tests/gi/overrides/Regress.py b/tests/gi/overrides/Regress.py
new file mode 100644
index 0000000..cb38631
--- /dev/null
+++ b/tests/gi/overrides/Regress.py
@@ -0,0 +1,26 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2012 Martin Pitt <martinpitt@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.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+from ..importer import modules
+
+Regress = modules['Regress']._introspection_module
+
+REGRESS_OVERRIDE = 42
+__all__ = ['REGRESS_OVERRIDE']
diff --git a/tests/gi/overrides/__init__.py b/tests/gi/overrides/__init__.py
new file mode 100644
index 0000000..3ad9513
--- /dev/null
+++ b/tests/gi/overrides/__init__.py
@@ -0,0 +1,2 @@
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
diff --git a/tests/org.gnome.test.gschema.xml b/tests/org.gnome.test.gschema.xml
index 221b87a..eb9aab8 100644
--- a/tests/org.gnome.test.gschema.xml
+++ b/tests/org.gnome.test.gschema.xml
@@ -1,4 +1,10 @@
<schemalist>
+ <enum id="org.gnome.test.FruitType">
+ <value nick="banana" value="0"/>
+ <value nick="apple" value="1"/>
+ <value nick="pear" value="2"/>
+ </enum>
+
<schema id="org.gnome.test" path="/tests/">
<key name="test-boolean" type="b">
<default>true</default>
@@ -12,6 +18,9 @@
<key name="test-array" type="ai">
<default>[1,2]</default>
</key>
+ <key name="test-enum" enum="org.gnome.test.FruitType">
+ <default>'banana'</default>
+ </key>
</schema>
<schema id="org.gnome.nopathtest">
diff --git a/tests/runtests-windows.py b/tests/runtests-windows.py
index ae81202..36ab9e1 100644
--- a/tests/runtests-windows.py
+++ b/tests/runtests-windows.py
@@ -7,8 +7,16 @@ import sys
import glob
import unittest
+mydir = os.path.dirname(os.path.abspath(__file__))
+tests_builddir = os.path.abspath(os.environ.get('TESTS_BUILDDIR', os.path.dirname(__file__)))
+builddir = os.path.dirname(tests_builddir)
+
+# we have to do this here instead of Makefile.am so that the implicitly added
+# directory for the source file comes after the builddir
+sys.path.insert(0, tests_builddir)
+sys.path.insert(0, builddir)
+
os.environ['PYGTK_USE_GIL_STATE_API'] = ''
-sys.path.insert(0, os.path.dirname(__file__))
sys.argv.append('--g-fatal-warnings')
from gi.repository import GObject
diff --git a/tests/runtests.py b/tests/runtests.py
index 2a8ecf4..6085ff9 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -7,28 +7,49 @@ import sys
import unittest
+# this was renamed in Python 3, provide backwards compatible name
+if sys.version_info[:2] == (2, 7):
+ unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
+
if '--help' in sys.argv:
print("Usage: ./runtests.py <testfiles>")
sys.exit(0)
+mydir = os.path.dirname(os.path.abspath(__file__))
+tests_builddir = os.path.abspath(os.environ.get('TESTS_BUILDDIR', os.path.dirname(__file__)))
+builddir = os.path.dirname(tests_builddir)
+
+# we have to do this here instead of Makefile.am so that the implicitly added
+# directory for the source file comes after the builddir
+sys.path.insert(0, tests_builddir)
+sys.path.insert(0, builddir)
+
# force untranslated messages, as we check for them in some tests
os.environ['LC_MESSAGES'] = 'C'
+os.environ['G_DEBUG'] = 'fatal-warnings fatal-criticals'
+
+# make Gio able to find our gschemas.compiled in tests/. This needs to be set
+# before importing Gio. Support a separate build tree, so look in build dir
+# first.
+os.environ['GSETTINGS_BACKEND'] = 'memory'
+os.environ['GSETTINGS_SCHEMA_DIR'] = tests_builddir
+os.environ['G_FILENAME_ENCODING'] = 'UTF-8'
# Load tests.
if 'TEST_NAMES' in os.environ:
- names = os.environ['TEST_NAMES'].split()
+ names = os.environ['TEST_NAMES'].split()
elif 'TEST_FILES' in os.environ:
- names = []
- for filename in os.environ['TEST_FILES'].split():
- names.append(filename[:-3])
+ names = []
+ for filename in os.environ['TEST_FILES'].split():
+ names.append(filename[:-3])
elif len(sys.argv) > 1:
names = []
for filename in sys.argv[1:]:
names.append(filename.replace('.py', ''))
else:
- names = []
- for filename in glob.iglob("test_*.py"):
- names.append(filename[:-3])
+ names = []
+ for filename in glob.iglob(os.path.join(mydir, 'test_*.py')):
+ names.append(os.path.basename(filename)[:-3])
loader = unittest.TestLoader()
suite = loader.loadTestsFromNames(names)
@@ -38,5 +59,4 @@ suite = loader.loadTestsFromNames(names)
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
if not result.wasSuccessful():
- sys.exit(1) # exit code so "make check" reports error
-
+ sys.exit(1) # exit code so "make check" reports error
diff --git a/tests/test-thread.c b/tests/test-thread.c
index 0f5b909..438cb97 100644
--- a/tests/test-thread.c
+++ b/tests/test-thread.c
@@ -43,8 +43,7 @@ other_thread_cb (TestThread *self)
static void
test_thread_emit_signal (TestThread *self)
{
- self->thread = g_thread_create ((GThreadFunc)other_thread_cb,
- self, TRUE, NULL);
+ self->thread = g_thread_new ("t", (GThreadFunc)other_thread_cb, self);
}
static void test_thread_init (TestThread *self) {}
diff --git a/tests/test-unknown.c b/tests/test-unknown.c
index 85aba73..f1c3139 100644
--- a/tests/test-unknown.c
+++ b/tests/test-unknown.c
@@ -53,7 +53,7 @@ test_interface_get_type (void)
return gtype;
}
-void test_unknown_iface_method (TestInterface *iface)
+static void test_unknown_iface_method (TestInterface *iface)
{
}
diff --git a/tests/test_atoms.py b/tests/test_atoms.py
new file mode 100644
index 0000000..1561dbd
--- /dev/null
+++ b/tests/test_atoms.py
@@ -0,0 +1,77 @@
+import unittest
+
+try:
+ from gi.repository import Atk, Gdk, Gtk
+ (Atk, Gdk) # pyflakes
+except:
+ Gdk = None
+
+
+@unittest.skipUnless(Gdk, 'Gdk not available')
+class TestGdkAtom(unittest.TestCase):
+ def test_create(self):
+ atom = Gdk.Atom.intern('my_string', False)
+ self.assertEqual(atom.name(), 'my_string')
+
+ def test_str(self):
+ atom = Gdk.Atom.intern('my_string', False)
+ self.assertEqual(str(atom), 'my_string')
+
+ self.assertEqual(str(Gdk.SELECTION_CLIPBOARD), 'CLIPBOARD')
+
+ def test_repr(self):
+ atom = Gdk.Atom.intern('my_string', False)
+ self.assertEqual(repr(atom), 'Gdk.Atom<my_string>')
+
+ self.assertEqual(repr(Gdk.SELECTION_CLIPBOARD), 'Gdk.Atom<CLIPBOARD>')
+
+ def test_in_single(self):
+ a_selection = Gdk.Atom.intern('test_clipboard', False)
+ clipboard = Gtk.Clipboard.get(a_selection)
+ clipboard.set_text('hello', 5)
+
+ # needs a Gdk.Atom, not a string
+ self.assertRaises(TypeError, Gtk.Clipboard.get, 'CLIPBOARD')
+
+ def test_in_array(self):
+ a_plain = Gdk.Atom.intern('text/plain', False)
+ a_html = Gdk.Atom.intern('text/html', False)
+ a_jpeg = Gdk.Atom.intern('image/jpeg', False)
+
+ self.assertFalse(Gtk.targets_include_text([]))
+ self.assertTrue(Gtk.targets_include_text([a_plain, a_html]))
+ self.assertFalse(Gtk.targets_include_text([a_jpeg]))
+ self.assertTrue(Gtk.targets_include_text([a_jpeg, a_plain]))
+
+ self.assertFalse(Gtk.targets_include_image([], False))
+ self.assertFalse(Gtk.targets_include_image([a_plain, a_html], False))
+ self.assertTrue(Gtk.targets_include_image([a_jpeg], False))
+ self.assertTrue(Gtk.targets_include_image([a_jpeg, a_plain], False))
+
+ def test_out_array(self):
+ a_selection = Gdk.Atom.intern('my_clipboard', False)
+ clipboard = Gtk.Clipboard.get(a_selection)
+
+ # empty
+ (res, targets) = clipboard.wait_for_targets()
+ self.assertEqual(res, False)
+ self.assertEqual(targets, [])
+
+ # text
+ clipboard.set_text('hello', 5)
+ (res, targets) = clipboard.wait_for_targets()
+ self.assertEqual(res, True)
+ self.assertNotEqual(targets, [])
+ self.assertEqual(type(targets[0]), Gdk.Atom)
+ names = [t.name() for t in targets]
+ self.assertFalse(None in names, names)
+ self.assertTrue('TEXT' in names, names)
+
+ def test_out_glist(self):
+ display = Gdk.Display.get_default()
+ dm = display.get_device_manager()
+ device = dm.get_client_pointer()
+ axes = device.list_axes()
+ axes_names = [atom.name() for atom in axes]
+ self.assertNotEqual(axes_names, [])
+ self.assertTrue('Rel X' in axes_names)
diff --git a/tests/test_docstring.py b/tests/test_docstring.py
new file mode 100644
index 0000000..1628295
--- /dev/null
+++ b/tests/test_docstring.py
@@ -0,0 +1,49 @@
+import unittest
+
+import gi.docstring
+from gi.repository import GIMarshallingTests
+
+
+class Test(unittest.TestCase):
+ def test_api(self):
+ new_func = lambda info: 'docstring test'
+ old_func = gi.docstring.get_doc_string_generator()
+
+ gi.docstring.set_doc_string_generator(new_func)
+ self.assertEqual(gi.docstring.get_doc_string_generator(),
+ new_func)
+ self.assertEqual(gi.docstring.generate_doc_string(None),
+ 'docstring test')
+
+ # Set back to original generator
+ gi.docstring.set_doc_string_generator(old_func)
+ self.assertEqual(gi.docstring.get_doc_string_generator(),
+ old_func)
+
+ def test_split_args_multi_out(self):
+ in_args, out_args = gi.docstring.split_function_info_args(GIMarshallingTests.int_out_out)
+ self.assertEqual(len(in_args), 0)
+ self.assertEqual(len(out_args), 2)
+ self.assertEqual(out_args[0].get_pytype_hint(), 'int')
+ self.assertEqual(out_args[1].get_pytype_hint(), 'int')
+
+ def test_split_args_inout(self):
+ in_args, out_args = gi.docstring.split_function_info_args(GIMarshallingTests.long_inout_max_min)
+ self.assertEqual(len(in_args), 1)
+ self.assertEqual(len(out_args), 1)
+ self.assertEqual(in_args[0].get_name(), out_args[0].get_name())
+ self.assertEqual(in_args[0].get_pytype_hint(), out_args[0].get_pytype_hint())
+
+ def test_split_args_none(self):
+ obj = GIMarshallingTests.Object(int=33)
+ in_args, out_args = gi.docstring.split_function_info_args(obj.none_inout)
+ self.assertEqual(len(in_args), 1)
+ self.assertEqual(len(out_args), 1)
+
+ def test_final_signature_with_full_inout(self):
+ self.assertEqual(GIMarshallingTests.Object.full_inout.__doc__,
+ 'full_inout(object:GIMarshallingTests.Object) -> object:GIMarshallingTests.Object')
+
+ def test_overridden_doc_is_not_clobbered(self):
+ self.assertEqual(GIMarshallingTests.OverridesObject.method.__doc__,
+ 'Overridden doc string.')
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 86ddb42..b2f0528 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -3,18 +3,28 @@
# vim: tabstop=4 shiftwidth=4 expandtab
import unittest
-
+import traceback
+import ctypes
+import warnings
import sys
-sys.path.insert(0, "../")
-from sys import getrefcount
-import copy
-import cairo
+try:
+ import cairo
+ has_cairo = True
+ from gi.repository import Regress as Everything
+except ImportError:
+ has_cairo = False
+#import gi
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio
-from gi.repository import Regress as Everything
+
+try:
+ from gi.repository import Gtk
+ Gtk # pyflakes
+except:
+ Gtk = None
if sys.version_info < (3, 0):
UNICHAR = "\xe2\x99\xa5"
@@ -23,6 +33,18 @@ else:
UNICHAR = "♥"
+class RawGList(ctypes.Structure):
+ _fields_ = [('data', ctypes.c_void_p),
+ ('next', ctypes.c_void_p),
+ ('prev', ctypes.c_void_p)]
+
+ @classmethod
+ def from_wrapped(cls, obj):
+ offset = sys.getsizeof(object()) # size of PyObject_HEAD
+ return ctypes.POINTER(cls).from_address(id(obj) + offset)
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestEverything(unittest.TestCase):
def test_cairo_context(self):
@@ -37,16 +59,16 @@ class TestEverything(unittest.TestCase):
surface = Everything.test_cairo_surface_none_return()
self.assertTrue(isinstance(surface, cairo.ImageSurface))
self.assertTrue(isinstance(surface, cairo.Surface))
- self.assertEquals(surface.get_format(), cairo.FORMAT_ARGB32)
- self.assertEquals(surface.get_width(), 10)
- self.assertEquals(surface.get_height(), 10)
+ self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
+ self.assertEqual(surface.get_width(), 10)
+ self.assertEqual(surface.get_height(), 10)
surface = Everything.test_cairo_surface_full_return()
self.assertTrue(isinstance(surface, cairo.ImageSurface))
self.assertTrue(isinstance(surface, cairo.Surface))
- self.assertEquals(surface.get_format(), cairo.FORMAT_ARGB32)
- self.assertEquals(surface.get_width(), 10)
- self.assertEquals(surface.get_height(), 10)
+ self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
+ self.assertEqual(surface.get_width(), 10)
+ self.assertEqual(surface.get_height(), 10)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
Everything.test_cairo_surface_none_in(surface)
@@ -54,29 +76,234 @@ class TestEverything(unittest.TestCase):
surface = Everything.test_cairo_surface_full_out()
self.assertTrue(isinstance(surface, cairo.ImageSurface))
self.assertTrue(isinstance(surface, cairo.Surface))
- self.assertEquals(surface.get_format(), cairo.FORMAT_ARGB32)
- self.assertEquals(surface.get_width(), 10)
- self.assertEquals(surface.get_height(), 10)
+ self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
+ self.assertEqual(surface.get_width(), 10)
+ self.assertEqual(surface.get_height(), 10)
+
+ def test_bool(self):
+ self.assertEqual(Everything.test_boolean(False), False)
+ self.assertEqual(Everything.test_boolean(True), True)
+ self.assertEqual(Everything.test_boolean('hello'), True)
+ self.assertEqual(Everything.test_boolean(''), False)
+
+ self.assertEqual(Everything.test_boolean_true(True), True)
+ self.assertEqual(Everything.test_boolean_false(False), False)
+
+ def test_int8(self):
+ self.assertEqual(Everything.test_int8(GObject.G_MAXINT8),
+ GObject.G_MAXINT8)
+ self.assertEqual(Everything.test_int8(GObject.G_MININT8),
+ GObject.G_MININT8)
+ self.assertRaises(OverflowError, Everything.test_int8, GObject.G_MAXINT8 + 1)
+
+ self.assertEqual(Everything.test_uint8(GObject.G_MAXUINT8),
+ GObject.G_MAXUINT8)
+ self.assertEqual(Everything.test_uint8(0), 0)
+ self.assertRaises(OverflowError, Everything.test_uint8, -1)
+ self.assertRaises(OverflowError, Everything.test_uint8, GObject.G_MAXUINT8 + 1)
+
+ def test_int16(self):
+ self.assertEqual(Everything.test_int16(GObject.G_MAXINT16),
+ GObject.G_MAXINT16)
+ self.assertEqual(Everything.test_int16(GObject.G_MININT16),
+ GObject.G_MININT16)
+ self.assertRaises(OverflowError, Everything.test_int16, GObject.G_MAXINT16 + 1)
+
+ self.assertEqual(Everything.test_uint16(GObject.G_MAXUINT16),
+ GObject.G_MAXUINT16)
+ self.assertEqual(Everything.test_uint16(0), 0)
+ self.assertRaises(OverflowError, Everything.test_uint16, -1)
+ self.assertRaises(OverflowError, Everything.test_uint16, GObject.G_MAXUINT16 + 1)
+
+ def test_int32(self):
+ self.assertEqual(Everything.test_int32(GObject.G_MAXINT32),
+ GObject.G_MAXINT32)
+ self.assertEqual(Everything.test_int32(GObject.G_MININT32),
+ GObject.G_MININT32)
+ self.assertRaises(OverflowError, Everything.test_int32, GObject.G_MAXINT32 + 1)
+
+ self.assertEqual(Everything.test_uint32(GObject.G_MAXUINT32),
+ GObject.G_MAXUINT32)
+ self.assertEqual(Everything.test_uint32(0), 0)
+ self.assertRaises(OverflowError, Everything.test_uint32, -1)
+ self.assertRaises(OverflowError, Everything.test_uint32, GObject.G_MAXUINT32 + 1)
+
+ def test_int64(self):
+ self.assertEqual(Everything.test_int64(GObject.G_MAXINT64),
+ GObject.G_MAXINT64)
+ self.assertEqual(Everything.test_int64(GObject.G_MININT64),
+ GObject.G_MININT64)
+ self.assertRaises(OverflowError, Everything.test_int64, GObject.G_MAXINT64 + 1)
+
+ self.assertEqual(Everything.test_uint64(GObject.G_MAXUINT64),
+ GObject.G_MAXUINT64)
+ self.assertEqual(Everything.test_uint64(0), 0)
+ self.assertRaises(OverflowError, Everything.test_uint64, -1)
+ self.assertRaises(OverflowError, Everything.test_uint64, GObject.G_MAXUINT64 + 1)
+
+ def test_int(self):
+ self.assertEqual(Everything.test_int(GObject.G_MAXINT),
+ GObject.G_MAXINT)
+ self.assertEqual(Everything.test_int(GObject.G_MININT),
+ GObject.G_MININT)
+ self.assertRaises(OverflowError, Everything.test_int, GObject.G_MAXINT + 1)
+
+ self.assertEqual(Everything.test_uint(GObject.G_MAXUINT),
+ GObject.G_MAXUINT)
+ self.assertEqual(Everything.test_uint(0), 0)
+ self.assertRaises(OverflowError, Everything.test_uint, -1)
+ self.assertRaises(OverflowError, Everything.test_uint, GObject.G_MAXUINT + 1)
+
+ def test_short(self):
+ self.assertEqual(Everything.test_short(GObject.G_MAXSHORT),
+ GObject.G_MAXSHORT)
+ self.assertEqual(Everything.test_short(GObject.G_MINSHORT),
+ GObject.G_MINSHORT)
+ self.assertRaises(OverflowError, Everything.test_short, GObject.G_MAXSHORT + 1)
+
+ self.assertEqual(Everything.test_ushort(GObject.G_MAXUSHORT),
+ GObject.G_MAXUSHORT)
+ self.assertEqual(Everything.test_ushort(0), 0)
+ self.assertRaises(OverflowError, Everything.test_ushort, -1)
+ self.assertRaises(OverflowError, Everything.test_ushort, GObject.G_MAXUSHORT + 1)
+
+ def test_long(self):
+ self.assertEqual(Everything.test_long(GObject.G_MAXLONG),
+ GObject.G_MAXLONG)
+ self.assertEqual(Everything.test_long(GObject.G_MINLONG),
+ GObject.G_MINLONG)
+ self.assertRaises(OverflowError, Everything.test_long, GObject.G_MAXLONG + 1)
+
+ self.assertEqual(Everything.test_ulong(GObject.G_MAXULONG),
+ GObject.G_MAXULONG)
+ self.assertEqual(Everything.test_ulong(0), 0)
+ self.assertRaises(OverflowError, Everything.test_ulong, -1)
+ self.assertRaises(OverflowError, Everything.test_ulong, GObject.G_MAXULONG + 1)
+
+ def test_size(self):
+ self.assertEqual(Everything.test_ssize(GObject.G_MAXSSIZE),
+ GObject.G_MAXSSIZE)
+ self.assertEqual(Everything.test_ssize(GObject.G_MINSSIZE),
+ GObject.G_MINSSIZE)
+ self.assertRaises(OverflowError, Everything.test_ssize, GObject.G_MAXSSIZE + 1)
+
+ self.assertEqual(Everything.test_size(GObject.G_MAXSIZE),
+ GObject.G_MAXSIZE)
+ self.assertEqual(Everything.test_size(0), 0)
+ self.assertRaises(OverflowError, Everything.test_size, -1)
+ self.assertRaises(OverflowError, Everything.test_size, GObject.G_MAXSIZE + 1)
+
+ def test_timet(self):
+ self.assertEqual(Everything.test_timet(42), 42)
+ self.assertRaises(OverflowError, Everything.test_timet, GObject.G_MAXUINT64 + 1)
def test_unichar(self):
- self.assertEquals("c", Everything.test_unichar("c"))
+ self.assertEqual("c", Everything.test_unichar("c"))
if sys.version_info < (3, 0):
- self.assertEquals(UNICHAR, Everything.test_unichar(PY2_UNICODE_UNICHAR))
- self.assertEquals(UNICHAR, Everything.test_unichar(UNICHAR))
+ self.assertEqual(UNICHAR, Everything.test_unichar(PY2_UNICODE_UNICHAR))
+ self.assertEqual(UNICHAR, Everything.test_unichar(UNICHAR))
self.assertRaises(TypeError, Everything.test_unichar, "")
self.assertRaises(TypeError, Everything.test_unichar, "morethanonechar")
-
+
+ def test_float(self):
+ self.assertEqual(Everything.test_float(GObject.G_MAXFLOAT),
+ GObject.G_MAXFLOAT)
+ self.assertEqual(Everything.test_float(GObject.G_MINFLOAT),
+ GObject.G_MINFLOAT)
+ self.assertRaises(OverflowError, Everything.test_float, GObject.G_MAXFLOAT * 2)
+
+ def test_double(self):
+ self.assertEqual(Everything.test_double(GObject.G_MAXDOUBLE),
+ GObject.G_MAXDOUBLE)
+ self.assertEqual(Everything.test_double(GObject.G_MINDOUBLE),
+ GObject.G_MINDOUBLE)
+
+ (two, three) = Everything.test_multi_double_args(2.5)
+ self.assertAlmostEqual(two, 5.0)
+ self.assertAlmostEqual(three, 7.5)
+
+ def test_value(self):
+ self.assertEqual(Everything.test_int_value_arg(GObject.G_MAXINT), GObject.G_MAXINT)
+ self.assertEqual(Everything.test_value_return(GObject.G_MAXINT), GObject.G_MAXINT)
+
+ def test_variant(self):
+ v = Everything.test_gvariant_i()
+ self.assertEqual(v.get_type_string(), 'i')
+ self.assertEqual(v.get_int32(), 1)
+
+ v = Everything.test_gvariant_s()
+ self.assertEqual(v.get_type_string(), 's')
+ self.assertEqual(v.get_string(), 'one')
+
+ v = Everything.test_gvariant_v()
+ self.assertEqual(v.get_type_string(), 'v')
+ vi = v.get_variant()
+ self.assertEqual(vi.get_type_string(), 's')
+ self.assertEqual(vi.get_string(), 'contents')
+
+ v = Everything.test_gvariant_as()
+ self.assertEqual(v.get_type_string(), 'as')
+ self.assertEqual(v.get_strv(), ['one', 'two', 'three'])
+
+ v = Everything.test_gvariant_asv()
+ self.assertEqual(v.get_type_string(), 'a{sv}')
+ self.assertEqual(v.lookup_value('nosuchkey', None), None)
+ name = v.lookup_value('name', None)
+ self.assertEqual(name.get_string(), 'foo')
+ timeout = v.lookup_value('timeout', None)
+ self.assertEqual(timeout.get_int32(), 10)
+
+ def test_string(self):
+ const_str = b'const \xe2\x99\xa5 utf8'
+ if sys.version_info >= (3, 0):
+ const_str = const_str.decode('UTF-8')
+ noconst_str = 'non' + const_str
+
+ self.assertEqual(Everything.test_utf8_const_return(), const_str)
+ self.assertEqual(Everything.test_utf8_nonconst_return(), noconst_str)
+ self.assertEqual(Everything.test_utf8_out(), noconst_str)
+
+ Everything.test_utf8_const_in(const_str)
+ self.assertEqual(Everything.test_utf8_inout(const_str), noconst_str)
+
+ self.assertEqual(Everything.test_filename_return(), ['åäö', '/etc/fstab'])
+
+ # returns g_utf8_strlen() in out argument
+ self.assertEqual(Everything.test_int_out_utf8(''), 0)
+ self.assertEqual(Everything.test_int_out_utf8('hello world'), 11)
+ self.assertEqual(Everything.test_int_out_utf8('åäö'), 3)
+
+ self.assertEqual(Everything.test_utf8_out_out(), ('first', 'second'))
+ self.assertEqual(Everything.test_utf8_out_nonconst_return(), ('first', 'second'))
+
+ def test_enum(self):
+ self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE1), 'value1')
+ self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE3), 'value3')
+ self.assertRaises(TypeError, Everything.test_enum_param, 'hello')
+
+ # FIXME: ValueError: invalid enum value: 2147483648
+ @unittest.expectedFailure
+ def test_enum_unsigned(self):
+ self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE1), 'value1')
+ self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE3), 'value3')
+ self.assertRaises(TypeError, Everything.test_unsigned_enum_param, 'hello')
+
+ def test_flags(self):
+ result = Everything.global_get_flags_out()
+ # assert that it's not an int
+ self.assertEqual(type(result), Everything.TestFlags)
+ self.assertEqual(result, Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3)
def test_floating(self):
e = Everything.TestFloating()
- self.assertEquals(e.__grefcount__, 1)
+ self.assertEqual(e.__grefcount__, 1)
e = GObject.new(Everything.TestFloating)
- self.assertEquals(e.__grefcount__, 1)
+ self.assertEqual(e.__grefcount__, 1)
e = Everything.TestFloating.new()
- self.assertEquals(e.__grefcount__, 1)
+ self.assertEqual(e.__grefcount__, 1)
def test_caller_allocates(self):
struct_a = Everything.TestStructA()
@@ -87,10 +314,10 @@ class TestEverything(unittest.TestCase):
struct_a_clone = struct_a.clone()
self.assertTrue(struct_a != struct_a_clone)
- self.assertEquals(struct_a.some_int, struct_a_clone.some_int)
- self.assertEquals(struct_a.some_int8, struct_a_clone.some_int8)
- self.assertEquals(struct_a.some_double, struct_a_clone.some_double)
- self.assertEquals(struct_a.some_enum, struct_a_clone.some_enum)
+ self.assertEqual(struct_a.some_int, struct_a_clone.some_int)
+ self.assertEqual(struct_a.some_int8, struct_a_clone.some_int8)
+ self.assertEqual(struct_a.some_double, struct_a_clone.some_double)
+ self.assertEqual(struct_a.some_enum, struct_a_clone.some_enum)
struct_b = Everything.TestStructB()
struct_b.some_int8 = 8
@@ -101,30 +328,33 @@ class TestEverything(unittest.TestCase):
struct_b_clone = struct_b.clone()
self.assertTrue(struct_b != struct_b_clone)
- self.assertEquals(struct_b.some_int8, struct_b_clone.some_int8)
- self.assertEquals(struct_b.nested_a.some_int, struct_b_clone.nested_a.some_int)
- self.assertEquals(struct_b.nested_a.some_int8, struct_b_clone.nested_a.some_int8)
- self.assertEquals(struct_b.nested_a.some_double, struct_b_clone.nested_a.some_double)
- self.assertEquals(struct_b.nested_a.some_enum, struct_b_clone.nested_a.some_enum)
+ self.assertEqual(struct_b.some_int8, struct_b_clone.some_int8)
+ self.assertEqual(struct_b.nested_a.some_int, struct_b_clone.nested_a.some_int)
+ self.assertEqual(struct_b.nested_a.some_int8, struct_b_clone.nested_a.some_int8)
+ self.assertEqual(struct_b.nested_a.some_double, struct_b_clone.nested_a.some_double)
+ self.assertEqual(struct_b.nested_a.some_enum, struct_b_clone.nested_a.some_enum)
+
+ struct_a = Everything.test_struct_a_parse('ignored')
+ self.assertEqual(struct_a.some_int, 23)
def test_wrong_type_of_arguments(self):
try:
Everything.test_int8()
except TypeError:
(e_type, e) = sys.exc_info()[:2]
- self.assertEquals(e.args, ("test_int8() takes exactly 1 argument (0 given)",))
+ self.assertEqual(e.args, ("test_int8() takes exactly 1 argument (0 given)",))
def test_gtypes(self):
gchararray_gtype = GObject.type_from_name('gchararray')
gtype = Everything.test_gtype(str)
- self.assertEquals(gchararray_gtype, gtype)
+ self.assertEqual(gchararray_gtype, gtype)
gtype = Everything.test_gtype('gchararray')
- self.assertEquals(gchararray_gtype, gtype)
+ self.assertEqual(gchararray_gtype, gtype)
gobject_gtype = GObject.GObject.__gtype__
gtype = Everything.test_gtype(GObject.GObject)
- self.assertEquals(gobject_gtype, gtype)
+ self.assertEqual(gobject_gtype, gtype)
gtype = Everything.test_gtype('GObject')
- self.assertEquals(gobject_gtype, gtype)
+ self.assertEqual(gobject_gtype, gtype)
self.assertRaises(TypeError, Everything.test_gtype, 'invalidgtype')
class NotARegisteredClass(object):
@@ -136,60 +366,187 @@ class TestEverything(unittest.TestCase):
__gtype_name__ = 'EverythingTestsARegisteredClass'
gtype = Everything.test_gtype('EverythingTestsARegisteredClass')
- self.assertEquals(ARegisteredClass.__gtype__, gtype)
+ self.assertEqual(ARegisteredClass.__gtype__, gtype)
gtype = Everything.test_gtype(ARegisteredClass)
- self.assertEquals(ARegisteredClass.__gtype__, gtype)
+ self.assertEqual(ARegisteredClass.__gtype__, gtype)
self.assertRaises(TypeError, Everything.test_gtype, 'ARegisteredClass')
-
+
def test_dir(self):
attr_list = dir(Everything)
-
+
# test that typelib attributes are listed
self.assertTrue('TestStructA' in attr_list)
-
+
# test that class attributes and methods are listed
self.assertTrue('__class__' in attr_list)
self.assertTrue('__dir__' in attr_list)
self.assertTrue('__repr__' in attr_list)
-
+
# test that instance members are listed
self.assertTrue('_namespace' in attr_list)
self.assertTrue('_version' in attr_list)
-
+
# test that there are no duplicates returned
self.assertEqual(len(attr_list), len(set(attr_list)))
+ def test_array(self):
+ self.assertEqual(Everything.test_array_int_in([]), 0)
+ self.assertEqual(Everything.test_array_int_in([1, 5, -2]), 4)
+ self.assertEqual(Everything.test_array_int_out(), [0, 1, 2, 3, 4])
+ self.assertEqual(Everything.test_array_int_full_out(), [0, 1, 2, 3, 4])
+ self.assertEqual(Everything.test_array_int_none_out(), [1, 2, 3, 4, 5])
+ self.assertEqual(Everything.test_array_int_inout([1, 5, 42, -8]), [6, 43, -7])
+
+ if sys.version_info >= (3, 0):
+ self.assertEqual(Everything.test_array_gint8_in(b'\x01\x03\x05'), 9)
+ self.assertEqual(Everything.test_array_gint8_in([1, 3, 5, -50]), -41)
+ self.assertEqual(Everything.test_array_gint16_in([256, 257, -1000, 10000]), 9513)
+ self.assertEqual(Everything.test_array_gint32_in([30000, 1, -2]), 29999)
+ self.assertEqual(Everything.test_array_gint64_in([2 ** 33, 2 ** 34]), 2 ** 33 + 2 ** 34)
+
+ self.assertEqual(Everything.test_array_gtype_in(
+ [GObject.TYPE_STRING, GObject.TYPE_UINT64, GObject.TYPE_VARIANT]),
+ '[gchararray,guint64,GVariant,]')
+
+ def test_array_fixed_size(self):
+ # fixed length of 5
+ self.assertEqual(Everything.test_array_fixed_size_int_in([1, 2, -10, 5, 3]), 1)
+ self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4])
+ self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4, 5, 6])
+
+ self.assertEqual(Everything.test_array_fixed_size_int_out(), [0, 1, 2, 3, 4])
+ self.assertEqual(Everything.test_array_fixed_size_int_return(), [0, 1, 2, 3, 4])
+
def test_ptrarray(self):
# transfer container
result = Everything.test_garray_container_return()
- self.assertEquals (result, ['regress'])
+ self.assertEqual(result, ['regress'])
result = None
# transfer full
result = Everything.test_garray_full_return()
- self.assertEquals (result, ['regress'])
+ self.assertEqual(result, ['regress'])
+ result = None
+
+ def test_strv(self):
+ self.assertEqual(Everything.test_strv_out(), ['thanks', 'for', 'all', 'the', 'fish'])
+ self.assertEqual(Everything.test_strv_out_c(), ['thanks', 'for', 'all', 'the', 'fish'])
+ self.assertEqual(Everything.test_strv_out_container(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_strv_outarg(), ['1', '2', '3'])
+
+ self.assertEqual(Everything.test_strv_in_gvalue(), ['one', 'two', 'three'])
+
+ Everything.test_strv_in(['1', '2', '3'])
+
+ def test_glist(self):
+ self.assertEqual(Everything.test_glist_nothing_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_glist_nothing_return2(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_glist_container_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_glist_everything_return(), ['1', '2', '3'])
+
+ Everything.test_glist_nothing_in(['1', '2', '3'])
+ Everything.test_glist_nothing_in2(['1', '2', '3'])
+
+ def test_gslist(self):
+ self.assertEqual(Everything.test_gslist_nothing_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_gslist_nothing_return2(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_gslist_container_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_gslist_everything_return(), ['1', '2', '3'])
+
+ Everything.test_gslist_nothing_in(['1', '2', '3'])
+ Everything.test_gslist_nothing_in2(['1', '2', '3'])
+
+ def test_hash_return(self):
+ expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'}
+
+ self.assertEqual(Everything.test_ghash_null_return(), None)
+ self.assertEqual(Everything.test_ghash_nothing_return(), expected)
+ self.assertEqual(Everything.test_ghash_nothing_return(), expected)
+ self.assertEqual(Everything.test_ghash_container_return(), expected)
+ self.assertEqual(Everything.test_ghash_everything_return(), expected)
+
+ result = Everything.test_ghash_gvalue_return()
+ self.assertEqual(result['integer'], 12)
+ self.assertEqual(result['boolean'], True)
+ self.assertEqual(result['string'], 'some text')
+ self.assertEqual(result['strings'], ['first', 'second', 'third'])
+ self.assertEqual(result['flags'], Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3)
+ self.assertEqual(result['enum'], Everything.TestEnum.VALUE2)
result = None
+ # FIXME: CRITICAL **: Unsupported type ghash
+ def disabled_test_hash_return_nested(self):
+ self.assertEqual(Everything.test_ghash_nested_everything_return(), {})
+ self.assertEqual(Everything.test_ghash_nested_everything_return2(), {})
+
+ def test_hash_in(self):
+ expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'}
+
+ Everything.test_ghash_nothing_in(expected)
+ Everything.test_ghash_nothing_in2(expected)
+
+ def test_hash_in_with_typed_strv(self):
+ class GStrv(list):
+ __gtype__ = GObject.TYPE_STRV
+
+ data = {'integer': 12,
+ 'boolean': True,
+ 'string': 'some text',
+ 'strings': GStrv(['first', 'second', 'third']),
+ 'flags': Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3,
+ 'enum': Everything.TestEnum.VALUE2,
+ }
+ Everything.test_ghash_gvalue_in(data)
+ data = None
+
+ def test_hash_in_with_gvalue_strv(self):
+ data = {'integer': 12,
+ 'boolean': True,
+ 'string': 'some text',
+ 'strings': GObject.Value(GObject.TYPE_STRV, ['first', 'second', 'third']),
+ 'flags': Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3,
+ 'enum': Everything.TestEnum.VALUE2,
+ }
+ Everything.test_ghash_gvalue_in(data)
+ data = None
+
def test_struct_gpointer(self):
- l1 = GLib.List()
- self.assertEqual(l1.data, None)
- init_refcount = getrefcount(l1)
+ glist = GLib.List()
+ raw = RawGList.from_wrapped(glist)
+
+ # Note that pointer fields use 0 for NULL in PyGObject and None in ctypes
+ self.assertEqual(glist.data, 0)
+ self.assertEqual(raw.contents.data, None)
- l1.data = 'foo'
- self.assertEqual(l1.data, 'foo')
+ glist.data = 123
+ self.assertEqual(glist.data, 123)
+ self.assertEqual(raw.contents.data, 123)
- l2 = l1
- self.assertEqual(l1.data, l2.data)
- self.assertEquals(getrefcount(l1), init_refcount+1)
+ glist.data = None
+ self.assertEqual(glist.data, 0)
+ self.assertEqual(raw.contents.data, None)
- l3 = copy.copy(l1)
- l3.data = 'bar'
- self.assertEqual(l1.data, 'foo')
- self.assertEqual(l2.data, 'foo')
- self.assertEqual(l3.data, 'bar')
- self.assertEquals(getrefcount(l1), init_refcount+1)
- self.assertEquals(getrefcount(l3), init_refcount)
+ # Setting to anything other than an int should raise
+ self.assertRaises(TypeError, setattr, glist.data, 'nan')
+ self.assertRaises(TypeError, setattr, glist.data, object())
+ self.assertRaises(TypeError, setattr, glist.data, 123.321)
+ def test_struct_opaque(self):
+ # we should get a sensible error message
+ try:
+ Everything.TestBoxedPrivate()
+ self.fail('allocating disguised struct without default constructor unexpectedly succeeded')
+ except TypeError:
+ (e_type, e_value, e_tb) = sys.exc_info()
+ self.assertEqual(e_type, TypeError)
+ self.assertTrue('TestBoxedPrivate' in str(e_value), str(e_value))
+ self.assertTrue('override' in str(e_value), str(e_value))
+ self.assertTrue('constructor' in str(e_value), str(e_value))
+ tb = ''.join(traceback.format_exception(e_type, e_value, e_tb))
+ self.assertTrue('tests/test_everything.py", line' in tb, tb)
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestNullableArgs(unittest.TestCase):
def test_in_nullable_hash(self):
Everything.test_ghash_null_in(None)
@@ -227,15 +584,17 @@ class TestNullableArgs(unittest.TestCase):
self.assertEqual(None, Everything.TestObj.null_out())
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestCallbacks(unittest.TestCase):
called = False
- main_loop = GObject.MainLoop()
+ main_loop = GLib.MainLoop()
def test_callback(self):
TestCallbacks.called = False
+
def callback():
TestCallbacks.called = True
-
+
Everything.test_simple_callback(callback)
self.assertTrue(TestCallbacks.called)
@@ -246,11 +605,12 @@ class TestCallbacks(unittest.TestCase):
"""
def callback():
x = 1 / 0
-
- try:
- Everything.test_simple_callback(callback)
- except ZeroDivisionError:
- pass
+ self.fail('unexpected surviving zero divsion:' + str(x))
+
+ # note that we do NOT expect the ZeroDivisionError to be propagated
+ # through from the callback, as it crosses the Python<->C boundary
+ # twice. (See GNOME #616279)
+ Everything.test_simple_callback(callback)
def test_double_callback_exception(self):
"""
@@ -259,79 +619,107 @@ class TestCallbacks(unittest.TestCase):
"""
def badcallback():
x = 1 / 0
+ self.fail('unexpected surviving zero divsion:' + str(x))
def callback():
Everything.test_boolean(True)
Everything.test_boolean(False)
Everything.test_simple_callback(badcallback())
- try:
- Everything.test_simple_callback(callback)
- except ZeroDivisionError:
- pass
+ # note that we do NOT expect the ZeroDivisionError to be propagated
+ # through from the callback, as it crosses the Python<->C boundary
+ # twice. (See GNOME #616279)
+ Everything.test_simple_callback(callback)
def test_return_value_callback(self):
TestCallbacks.called = False
+
def callback():
TestCallbacks.called = True
return 44
- self.assertEquals(Everything.test_callback(callback), 44)
+ self.assertEqual(Everything.test_callback(callback), 44)
self.assertTrue(TestCallbacks.called)
-
- def test_callback_async(self):
+
+ def test_callback_scope_async(self):
TestCallbacks.called = False
- def callback(foo):
+ ud = 'Test Value 44'
+
+ def callback(user_data):
+ self.assertEqual(user_data, ud)
TestCallbacks.called = True
- return foo
+ return 44
+
+ ud_refcount = sys.getrefcount(ud)
+ callback_refcount = sys.getrefcount(callback)
- Everything.test_callback_async(callback, 44);
- i = Everything.test_callback_thaw_async();
- self.assertEquals(44, i);
+ self.assertEqual(Everything.test_callback_async(callback, ud), None)
+ # Callback should not have run and the ref count is increased by 1
+ self.assertEqual(TestCallbacks.called, False)
+ self.assertEqual(sys.getrefcount(callback), callback_refcount + 1)
+ self.assertEqual(sys.getrefcount(ud), ud_refcount + 1)
+
+ # test_callback_thaw_async will run the callback previously supplied.
+ # references should be auto decremented after this call.
+ self.assertEqual(Everything.test_callback_thaw_async(), 44)
self.assertTrue(TestCallbacks.called)
- def test_callback_scope_call(self):
+ # Make sure refcounts are returned to normal
+ self.assertEqual(sys.getrefcount(callback), callback_refcount)
+ self.assertEqual(sys.getrefcount(ud), ud_refcount)
+
+ def test_callback_scope_call_multi(self):
+ # This tests a callback that gets called multiple times from a
+ # single scope call in python.
TestCallbacks.called = 0
+
def callback():
TestCallbacks.called += 1
- return 0
+ return TestCallbacks.called
- Everything.test_multi_callback(callback)
- self.assertEquals(TestCallbacks.called, 2)
+ refcount = sys.getrefcount(callback)
+ result = Everything.test_multi_callback(callback)
+ # first callback should give 1, second 2, and the function sums them up
+ self.assertEqual(result, 3)
+ self.assertEqual(TestCallbacks.called, 2)
+ self.assertEqual(sys.getrefcount(callback), refcount)
+
+ def test_callback_scope_call_array(self):
+ # This tests a callback that gets called multiple times from a
+ # single scope call in python with array arguments
+ TestCallbacks.callargs = []
+
+ # FIXME: would be cleaner without the explicit length args:
+ # def callback(one, two):
+ def callback(one, one_length, two, two_length):
+ TestCallbacks.callargs.append((one, two))
+ return len(TestCallbacks.callargs)
+
+ refcount = sys.getrefcount(callback)
+ result = Everything.test_array_callback(callback)
+ # first callback should give 1, second 2, and the function sums them up
+ self.assertEqual(result, 3)
+ self.assertEqual(TestCallbacks.callargs,
+ [([-1, 0, 1, 2], ['one', 'two', 'three'])] * 2)
+ self.assertEqual(sys.getrefcount(callback), refcount)
def test_callback_userdata(self):
TestCallbacks.called = 0
+
def callback(userdata):
- self.assertEquals(userdata, "Test%d" % TestCallbacks.called)
+ self.assertEqual(userdata, "Test%d" % TestCallbacks.called)
TestCallbacks.called += 1
return TestCallbacks.called
-
- for i in range(100):
- val = Everything.test_callback_user_data(callback, "Test%d" % i)
- self.assertEquals(val, i+1)
-
- self.assertEquals(TestCallbacks.called, 100)
- def test_callback_userdata_refcount(self):
- TestCallbacks.called = False
- def callback(userdata):
- TestCallbacks.called = True
- return 1
-
- ud = "Test User Data"
-
- start_ref_count = getrefcount(ud)
for i in range(100):
- Everything.test_callback_destroy_notify(callback, ud)
-
- Everything.test_callback_thaw_notifications()
- end_ref_count = getrefcount(ud)
+ val = Everything.test_callback_user_data(callback, "Test%d" % i)
+ self.assertEqual(val, i + 1)
- self.assertEquals(start_ref_count, end_ref_count)
+ self.assertEqual(TestCallbacks.called, 100)
def test_async_ready_callback(self):
TestCallbacks.called = False
- TestCallbacks.main_loop = GObject.MainLoop()
+ TestCallbacks.main_loop = GLib.MainLoop()
def callback(obj, result, user_data):
TestCallbacks.main_loop.quit()
@@ -343,15 +731,73 @@ class TestCallbacks(unittest.TestCase):
self.assertTrue(TestCallbacks.called)
- def test_callback_destroy_notify(self):
+ def test_callback_scope_notified_with_destroy(self):
+ TestCallbacks.called = 0
+ ud = 'Test scope notified data 33'
+
def callback(user_data):
- TestCallbacks.called = True
- return 42
+ self.assertEqual(user_data, ud)
+ TestCallbacks.called += 1
+ return 33
- TestCallbacks.called = False
- self.assertEquals(Everything.test_callback_destroy_notify(callback, 42), 42)
- self.assertTrue(TestCallbacks.called)
- self.assertEquals(Everything.test_callback_thaw_notifications(), 42)
+ value_refcount = sys.getrefcount(ud)
+ callback_refcount = sys.getrefcount(callback)
+
+ # Callback is immediately called.
+ for i in range(100):
+ res = Everything.test_callback_destroy_notify(callback, ud)
+ self.assertEqual(res, 33)
+
+ self.assertEqual(TestCallbacks.called, 100)
+ self.assertEqual(sys.getrefcount(callback), callback_refcount + 100)
+ self.assertEqual(sys.getrefcount(ud), value_refcount + 100)
+
+ # thaw will call the callback again, this time resources should be freed
+ self.assertEqual(Everything.test_callback_thaw_notifications(), 33 * 100)
+ self.assertEqual(TestCallbacks.called, 200)
+ self.assertEqual(sys.getrefcount(callback), callback_refcount)
+ self.assertEqual(sys.getrefcount(ud), value_refcount)
+
+ def test_callback_scope_notified_with_destroy_no_user_data(self):
+ TestCallbacks.called = 0
+
+ def callback(user_data):
+ self.assertEqual(user_data, None)
+ TestCallbacks.called += 1
+ return 34
+
+ callback_refcount = sys.getrefcount(callback)
+
+ # Run with warning as exception
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("error")
+ self.assertRaises(RuntimeWarning,
+ Everything.test_callback_destroy_notify_no_user_data,
+ callback)
+
+ self.assertEqual(TestCallbacks.called, 0)
+ self.assertEqual(sys.getrefcount(callback), callback_refcount)
+
+ # Run with warning as warning
+ with warnings.catch_warnings(record=True) as w:
+ # Cause all warnings to always be triggered.
+ warnings.simplefilter("default")
+ # Trigger a warning.
+ res = Everything.test_callback_destroy_notify_no_user_data(callback)
+ # Verify some things
+ self.assertEqual(len(w), 1)
+ self.assertTrue(issubclass(w[-1].category, RuntimeWarning))
+ self.assertTrue('Callables passed to' in str(w[-1].message))
+
+ self.assertEqual(res, 34)
+ self.assertEqual(TestCallbacks.called, 1)
+ self.assertEqual(sys.getrefcount(callback), callback_refcount + 1)
+
+ # thaw will call the callback again,
+ # refcount will not go down without user_data parameter
+ self.assertEqual(Everything.test_callback_thaw_notifications(), 34)
+ self.assertEqual(TestCallbacks.called, 2)
+ self.assertEqual(sys.getrefcount(callback), callback_refcount + 1)
def test_callback_in_methods(self):
object_ = Everything.TestObj()
@@ -369,12 +815,17 @@ class TestCallbacks(unittest.TestCase):
self.assertTrue(TestCallbacks.called)
def callbackWithUserData(user_data):
- TestCallbacks.called = True
+ TestCallbacks.called += 1
return 42
- TestCallbacks.called = False
- obj_ = Everything.TestObj.new_callback(callbackWithUserData, None)
- self.assertTrue(TestCallbacks.called)
+ TestCallbacks.called = 0
+ Everything.TestObj.new_callback(callbackWithUserData, None)
+ self.assertEqual(TestCallbacks.called, 1)
+ # Note: using "new_callback" adds the notification to the same global
+ # list as Everything.test_callback_destroy_notify, so thaw the list
+ # so we don't get confusion between tests.
+ self.assertEqual(Everything.test_callback_thaw_notifications(), 42)
+ self.assertEqual(TestCallbacks.called, 2)
def test_callback_none(self):
# make sure this doesn't assert or crash
@@ -417,29 +868,41 @@ class TestCallbacks(unittest.TestCase):
mydict['new'] = 42
TestCallbacks.called = True
- mydict = { 'foo': 1, 'bar': 2 }
+ mydict = {'foo': 1, 'bar': 2}
TestCallbacks.called = False
Everything.test_hash_table_callback(mydict, callback)
self.assertTrue(TestCallbacks.called)
- self.assertEqual(mydict, { 'foo': 1, 'bar': 2, 'new': 42 })
+ self.assertEqual(mydict, {'foo': 1, 'bar': 2, 'new': 42})
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestClosures(unittest.TestCase):
+ def test_no_arg(self):
+ def callback():
+ self.called = True
+ return 42
+
+ self.called = False
+ result = Everything.test_closure(callback)
+ self.assertTrue(self.called)
+ self.assertEqual(result, 42)
+
def test_int_arg(self):
def callback(num):
self.called = True
- return num+1
+ return num + 1
self.called = False
result = Everything.test_closure_one_arg(callback, 42)
self.assertTrue(self.called)
self.assertEqual(result, 43)
- # https://bugzilla.gnome.org/show_bug.cgi?id=656554
- @unittest.expectedFailure
def test_variant(self):
def callback(variant):
- self.assertEqual(variant.get_type_string(), 'i')
self.called = True
+ if variant is None:
+ return None
+ self.assertEqual(variant.get_type_string(), 'i')
return GLib.Variant('i', variant.get_int32() + 1)
self.called = False
@@ -448,58 +911,142 @@ class TestClosures(unittest.TestCase):
self.assertEqual(result.get_type_string(), 'i')
self.assertEqual(result.get_int32(), 43)
+ self.called = False
+ result = Everything.test_closure_variant(callback, None)
+ self.assertTrue(self.called)
+ self.assertEqual(result, None)
+
+ self.called = False
+ self.assertRaises(TypeError, Everything.test_closure_variant, callback, 'foo')
+ self.assertFalse(self.called)
+
+ def test_variant_wrong_return_type(self):
+ def callback(variant):
+ return 'no_variant'
+
+ # reset last error
+ sys.last_type = None
+
+ # this does not directly raise an exception (see
+ # https://bugzilla.gnome.org/show_bug.cgi?id=616279)
+ result = Everything.test_closure_variant(callback, GLib.Variant('i', 42))
+ # ... but the result shouldn't be a string
+ self.assertEqual(result, None)
+ # and the error should be shown
+ self.assertEqual(sys.last_type, TypeError)
+ self.assertTrue('return value' in str(sys.last_value), sys.last_value)
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestProperties(unittest.TestCase):
def test_basic(self):
object_ = Everything.TestObj()
- self.assertEquals(object_.props.int, 0)
+ self.assertEqual(object_.props.int, 0)
object_.props.int = 42
self.assertTrue(isinstance(object_.props.int, int))
- self.assertEquals(object_.props.int, 42)
+ self.assertEqual(object_.props.int, 42)
- self.assertEquals(object_.props.float, 0.0)
+ self.assertEqual(object_.props.float, 0.0)
object_.props.float = 42.42
self.assertTrue(isinstance(object_.props.float, float))
- self.assertAlmostEquals(object_.props.float, 42.42, places=5)
+ self.assertAlmostEqual(object_.props.float, 42.42, places=5)
- self.assertEquals(object_.props.double, 0.0)
+ self.assertEqual(object_.props.double, 0.0)
object_.props.double = 42.42
self.assertTrue(isinstance(object_.props.double, float))
- self.assertAlmostEquals(object_.props.double, 42.42, places=5)
+ self.assertAlmostEqual(object_.props.double, 42.42, places=5)
- self.assertEquals(object_.props.string, None)
+ self.assertEqual(object_.props.string, None)
object_.props.string = 'mec'
self.assertTrue(isinstance(object_.props.string, str))
- self.assertEquals(object_.props.string, 'mec')
+ self.assertEqual(object_.props.string, 'mec')
+
+ self.assertEqual(object_.props.gtype, GObject.TYPE_INVALID)
+ object_.props.gtype = int
+ self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
def test_hash_table(self):
object_ = Everything.TestObj()
- self.assertEquals(object_.props.hash_table, None)
+ self.assertEqual(object_.props.hash_table, None)
object_.props.hash_table = {'mec': 56}
self.assertTrue(isinstance(object_.props.hash_table, dict))
- self.assertEquals(list(object_.props.hash_table.items())[0], ('mec', 56))
+ self.assertEqual(list(object_.props.hash_table.items())[0], ('mec', 56))
def test_list(self):
object_ = Everything.TestObj()
- self.assertEquals(object_.props.list, [])
+ self.assertEqual(object_.props.list, [])
object_.props.list = ['1', '2', '3']
self.assertTrue(isinstance(object_.props.list, list))
- self.assertEquals(object_.props.list, ['1', '2', '3'])
+ self.assertEqual(object_.props.list, ['1', '2', '3'])
def test_boxed(self):
object_ = Everything.TestObj()
- self.assertEquals(object_.props.boxed, None)
+ self.assertEqual(object_.props.boxed, None)
boxed = Everything.TestBoxed()
boxed.some_int8 = 42
object_.props.boxed = boxed
self.assertTrue(isinstance(object_.props.boxed, Everything.TestBoxed))
- self.assertEquals(object_.props.boxed.some_int8, 42)
+ self.assertEqual(object_.props.boxed.some_int8, 42)
+
+ def test_boxed_alternative_constructor(self):
+ boxed = Everything.TestBoxed.new_alternative_constructor1(5)
+ self.assertEqual(boxed.some_int8, 5)
+
+ boxed = Everything.TestBoxed.new_alternative_constructor2(5, 3)
+ self.assertEqual(boxed.some_int8, 8)
+
+ boxed = Everything.TestBoxed.new_alternative_constructor3("-3")
+ self.assertEqual(boxed.some_int8, -3)
+
+ def test_boxed_equality(self):
+ boxed42 = Everything.TestBoxed.new_alternative_constructor1(42)
+ boxed5 = Everything.TestBoxed.new_alternative_constructor1(5)
+ boxed42_2 = Everything.TestBoxed.new_alternative_constructor2(41, 1)
+
+ self.assertFalse(boxed42.equals(boxed5))
+ self.assertTrue(boxed42.equals(boxed42_2))
+ self.assertTrue(boxed42_2.equals(boxed42))
+ self.assertTrue(boxed42.equals(boxed42))
+ def test_boxed_c_equality(self):
+ boxed = Everything.TestBoxedC()
+ # TestBoxedC uses refcounting, so we know that
+ # the pointer is the same when copied
+ copy = boxed.copy()
+ self.assertEqual(boxed, copy)
+ self.assertNotEqual(id(boxed), id(copy))
+
+ def test_gtype(self):
+ object_ = Everything.TestObj()
+ self.assertEqual(object_.props.gtype, GObject.TYPE_INVALID)
+ object_.props.gtype = int
+ self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
+
+ object_ = Everything.TestObj(gtype=int)
+ self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
+ object_.props.gtype = str
+ self.assertEqual(object_.props.gtype, GObject.TYPE_STRING)
+
+ def test_parent_class(self):
+ class A(Everything.TestObj):
+ prop1 = GObject.Property(type=int)
+
+ a = A()
+ a.props.int = 20
+ self.assertEqual(a.props.int, 20)
+
+ # test parent property which needs introspection
+ a.props.list = ("str1", "str2")
+ self.assertEqual(a.props.list, ["str1", "str2"])
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestTortureProfile(unittest.TestCase):
def test_torture_profile(self):
import time
@@ -510,9 +1057,9 @@ class TestTortureProfile(unittest.TestCase):
start_time = time.clock()
for i in range(10000):
- (y,z,q) = object_.torture_signature_0(5000,
- "Torture Test 1",
- 12345)
+ (y, z, q) = object_.torture_signature_0(5000,
+ "Torture Test 1",
+ 12345)
end_time = time.clock()
delta_time = end_time - start_time
@@ -523,23 +1070,20 @@ class TestTortureProfile(unittest.TestCase):
start_time = time.clock()
for i in range(10000):
- (y,z,q) = Everything.TestObj().torture_signature_0(5000,
- "Torture Test 2",
- 12345)
+ (y, z, q) = Everything.TestObj().torture_signature_0(
+ 5000, "Torture Test 2", 12345)
end_time = time.clock()
delta_time = end_time - start_time
total_time += delta_time
print("%f secs" % delta_time)
-
sys.stdout.write("\ttorture test 3 (10000 iterations): ")
start_time = time.clock()
for i in range(10000):
try:
- (y,z,q) = object_.torture_signature_1(5000,
- "Torture Test 3",
- 12345)
+ (y, z, q) = object_.torture_signature_1(
+ 5000, "Torture Test 3", 12345)
except:
pass
end_time = time.clock()
@@ -548,17 +1092,15 @@ class TestTortureProfile(unittest.TestCase):
print("%f secs" % delta_time)
sys.stdout.write("\ttorture test 4 (10000 iterations): ")
+
def callback(userdata):
pass
- userdata = [1,2,3,4]
+ userdata = [1, 2, 3, 4]
start_time = time.clock()
for i in range(10000):
- (y,z,q) = Everything.test_torture_signature_2(5000,
- callback,
- userdata,
- "Torture Test 4",
- 12345)
+ (y, z, q) = Everything.test_torture_signature_2(
+ 5000, callback, userdata, "Torture Test 4", 12345)
end_time = time.clock()
delta_time = end_time - start_time
total_time += delta_time
@@ -566,6 +1108,8 @@ class TestTortureProfile(unittest.TestCase):
print("\t====")
print("\tTotal: %f sec" % total_time)
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestAdvancedInterfaces(unittest.TestCase):
def test_array_objs(self):
obj1, obj2 = Everything.test_array_fixed_out_objects()
@@ -574,28 +1118,149 @@ class TestAdvancedInterfaces(unittest.TestCase):
self.assertNotEqual(obj1, obj2)
def test_obj_skip_return_val(self):
- obj = Everything.TestObj();
- ret = obj.skip_return_val(50, 42.0, 60, 2, 3);
- self.assertEquals(len(ret), 3);
- self.assertEquals(ret[0], 51);
- self.assertEquals(ret[1], 61);
- self.assertEquals(ret[2], 32);
+ obj = Everything.TestObj()
+ ret = obj.skip_return_val(50, 42.0, 60, 2, 3)
+ self.assertEqual(len(ret), 3)
+ self.assertEqual(ret[0], 51)
+ self.assertEqual(ret[1], 61)
+ self.assertEqual(ret[2], 32)
def test_obj_skip_return_val_no_out(self):
- obj = Everything.TestObj();
+ obj = Everything.TestObj()
# raises an error for 0, succeeds for any other value
self.assertRaises(GLib.GError, obj.skip_return_val_no_out, 0)
ret = obj.skip_return_val_no_out(1)
- self.assertEquals(ret, None)
+ self.assertEqual(ret, None)
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestSignals(unittest.TestCase):
def test_object_param_signal(self):
- obj = Everything.TestObj();
+ obj = Everything.TestObj()
def callback(obj, obj_param):
- self.assertEquals(obj_param.props.int, 3)
+ self.assertEqual(obj_param.props.int, 3)
self.assertGreater(obj_param.__grefcount__, 1)
+ obj.called = True
+ obj.called = False
obj.connect('sig-with-obj', callback)
obj.emit_sig_with_obj()
+ self.assertTrue(obj.called)
+
+ def test_connect_after(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, obj_param):
+ obj.called = True
+
+ obj.called = False
+ obj.connect_after('sig-with-obj', callback)
+ obj.emit_sig_with_obj()
+ self.assertTrue(obj.called)
+
+ def test_connect_object(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, obj_param):
+ obj.called = True
+
+ obj.called = False
+ obj.connect_object('sig-with-obj', callback, obj)
+ obj.emit_sig_with_obj()
+ self.assertTrue(obj.called)
+
+ def test_connect_object_after(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, obj_param):
+ obj.called = True
+
+ obj.called = False
+ obj.connect_object_after('sig-with-obj', callback, obj)
+ obj.emit_sig_with_obj()
+ self.assertTrue(obj.called)
+
+ def test_int64_param_from_py(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, i):
+ obj.callback_i = i
+ return i
+
+ obj.callback_i = None
+ obj.connect('sig-with-int64-prop', callback)
+ rv = obj.emit('sig-with-int64-prop', GObject.G_MAXINT64)
+ self.assertEqual(rv, GObject.G_MAXINT64)
+ self.assertEqual(obj.callback_i, GObject.G_MAXINT64)
+
+ def test_uint64_param_from_py(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, i):
+ obj.callback_i = i
+ return i
+
+ obj.callback_i = None
+ obj.connect('sig-with-uint64-prop', callback)
+ rv = obj.emit('sig-with-uint64-prop', GObject.G_MAXUINT64)
+ self.assertEqual(rv, GObject.G_MAXUINT64)
+ self.assertEqual(obj.callback_i, GObject.G_MAXUINT64)
+
+ def test_int64_param_from_c(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, i):
+ obj.callback_i = i
+ return i
+
+ obj.callback_i = None
+
+ obj.connect('sig-with-int64-prop', callback)
+ obj.emit_sig_with_int64()
+ self.assertEqual(obj.callback_i, GObject.G_MAXINT64)
+
+ def test_uint64_param_from_c(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, i):
+ obj.callback_i = i
+ return i
+
+ obj.callback_i = None
+
+ obj.connect('sig-with-uint64-prop', callback)
+ obj.emit_sig_with_uint64()
+ self.assertEqual(obj.callback_i, GObject.G_MAXUINT64)
+
+ def test_intarray_ret(self):
+ obj = Everything.TestObj()
+
+ def callback(obj, i):
+ obj.callback_i = i
+ return [i, i + 1]
+
+ obj.callback_i = None
+
+ try:
+ obj.connect('sig-with-intarray-ret', callback)
+ except TypeError as e:
+ # compat with g-i 1.34.x
+ if 'unknown signal' in str(e):
+ return
+ raise
+
+ rv = obj.emit('sig-with-intarray-ret', 42)
+ self.assertEqual(obj.callback_i, 42)
+ self.assertEqual(type(rv), GLib.Array)
+ self.assertEqual(rv.len, 2)
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestPango(unittest.TestCase):
+ def test_cairo_font_options(self):
+ screen = Gtk.Window().get_screen()
+ font_opts = screen.get_font_options()
+ self.assertEqual(type(font_opts.get_subpixel_order()), int)
diff --git a/tests/test_gdbus.py b/tests/test_gdbus.py
index 5db5d93..805633a 100644
--- a/tests/test_gdbus.py
+++ b/tests/test_gdbus.py
@@ -3,34 +3,34 @@
import unittest
-import sys
-sys.path.insert(0, "../")
-
-from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio
+
class TestGDBusClient(unittest.TestCase):
def setUp(self):
self.bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
self.dbus_proxy = Gio.DBusProxy.new_sync(self.bus,
- Gio.DBusProxyFlags.NONE, None,
- 'org.freedesktop.DBus',
- '/org/freedesktop/DBus',
- 'org.freedesktop.DBus', None)
+ Gio.DBusProxyFlags.NONE,
+ None,
+ 'org.freedesktop.DBus',
+ '/org/freedesktop/DBus',
+ 'org.freedesktop.DBus',
+ None)
def test_native_calls_sync(self):
- result = self.dbus_proxy.call_sync('ListNames', None,
- Gio.DBusCallFlags.NO_AUTO_START, 500, None)
+ result = self.dbus_proxy.call_sync('ListNames', None,
+ Gio.DBusCallFlags.NO_AUTO_START,
+ 500, None)
self.assertTrue(isinstance(result, GLib.Variant))
- result = result.unpack()[0] # result is always a tuple
+ result = result.unpack()[0] # result is always a tuple
self.assertTrue(len(result) > 1)
self.assertTrue('org.freedesktop.DBus' in result)
- result = self.dbus_proxy.call_sync('GetNameOwner',
- GLib.Variant('(s)', ('org.freedesktop.DBus',)),
- Gio.DBusCallFlags.NO_AUTO_START, 500, None)
+ result = self.dbus_proxy.call_sync('GetNameOwner',
+ GLib.Variant('(s)', ('org.freedesktop.DBus',)),
+ Gio.DBusCallFlags.NO_AUTO_START, 500, None)
self.assertTrue(isinstance(result, GLib.Variant))
self.assertEqual(type(result.unpack()[0]), type(''))
@@ -38,16 +38,16 @@ class TestGDBusClient(unittest.TestCase):
# error case: invalid argument types
try:
self.dbus_proxy.call_sync('GetConnectionUnixProcessID', None,
- Gio.DBusCallFlags.NO_AUTO_START, 500, None)
+ Gio.DBusCallFlags.NO_AUTO_START, 500, None)
self.fail('call with invalid arguments should raise an exception')
except Exception as e:
self.assertTrue('InvalidArgs' in str(e))
# error case: invalid argument
try:
- self.dbus_proxy.call_sync('GetConnectionUnixProcessID',
- GLib.Variant('(s)', (' unknown',)),
- Gio.DBusCallFlags.NO_AUTO_START, 500, None)
+ self.dbus_proxy.call_sync('GetConnectionUnixProcessID',
+ GLib.Variant('(s)', (' unknown',)),
+ Gio.DBusCallFlags.NO_AUTO_START, 500, None)
self.fail('call with invalid arguments should raise an exception')
except Exception as e:
self.assertTrue('NameHasNoOwner' in str(e))
@@ -55,7 +55,7 @@ class TestGDBusClient(unittest.TestCase):
# error case: unknown method
try:
self.dbus_proxy.call_sync('UnknownMethod', None,
- Gio.DBusCallFlags.NO_AUTO_START, 500, None)
+ Gio.DBusCallFlags.NO_AUTO_START, 500, None)
self.fail('call for unknown method should raise an exception')
except Exception as e:
self.assertTrue('UnknownMethod' in str(e))
@@ -67,15 +67,15 @@ class TestGDBusClient(unittest.TestCase):
finally:
user_data['main_loop'].quit()
- main_loop = GObject.MainLoop()
+ main_loop = GLib.MainLoop()
data = {'main_loop': main_loop}
- self.dbus_proxy.call('ListNames', None,
- Gio.DBusCallFlags.NO_AUTO_START, 500, None,
- call_done, data)
+ self.dbus_proxy.call('ListNames', None,
+ Gio.DBusCallFlags.NO_AUTO_START, 500, None,
+ call_done, data)
main_loop.run()
self.assertTrue(isinstance(data['result'], GLib.Variant))
- result = data['result'].unpack()[0] # result is always a tuple
+ result = data['result'].unpack()[0] # result is always a tuple
self.assertTrue(len(result) > 1)
self.assertTrue('org.freedesktop.DBus' in result)
@@ -89,10 +89,11 @@ class TestGDBusClient(unittest.TestCase):
finally:
user_data['main_loop'].quit()
- main_loop = GObject.MainLoop()
+ main_loop = GLib.MainLoop()
data = {'main_loop': main_loop}
self.dbus_proxy.call('UnknownMethod', None,
- Gio.DBusCallFlags.NO_AUTO_START, 500, None, call_done, data)
+ Gio.DBusCallFlags.NO_AUTO_START, 500, None,
+ call_done, data)
main_loop.run()
def test_python_calls_sync(self):
@@ -112,12 +113,13 @@ class TestGDBusClient(unittest.TestCase):
# does not have any method returning multiple results, so try talking
# to notification-daemon (and don't fail the test if it does not exist)
try:
- notification_daemon = Gio.DBusProxy.new_sync(self.bus,
- Gio.DBusProxyFlags.NONE, None,
- 'org.freedesktop.Notifications',
- '/org/freedesktop/Notifications',
- 'org.freedesktop.Notifications', None)
- result = notification_daemon.GetServerInformation('()')
+ nd = Gio.DBusProxy.new_sync(self.bus,
+ Gio.DBusProxyFlags.NONE, None,
+ 'org.freedesktop.Notifications',
+ '/org/freedesktop/Notifications',
+ 'org.freedesktop.Notifications',
+ None)
+ result = nd.GetServerInformation('()')
self.assertTrue(isinstance(result, tuple))
self.assertEqual(len(result), 4)
for i in result:
@@ -128,10 +130,12 @@ class TestGDBusClient(unittest.TestCase):
# test keyword argument; timeout=0 will fail immediately
try:
- self.dbus_proxy.GetConnectionUnixProcessID('()', timeout=0)
+ self.dbus_proxy.GetConnectionUnixProcessID('(s)', '1', timeout=0)
self.fail('call with timeout=0 should raise an exception')
except Exception as e:
- self.assertTrue('Timeout' in str(e), str(e))
+ # FIXME: this is not very precise, but in some environments we
+ # do not always get an actual timeout
+ self.assertTrue(isinstance(e, GLib.GError), str(e))
def test_python_calls_sync_noargs(self):
# methods without arguments don't need an explicit signature
@@ -159,10 +163,9 @@ class TestGDBusClient(unittest.TestCase):
user_data['result'] = result
user_data['main_loop'].quit()
- main_loop = GObject.MainLoop()
+ main_loop = GLib.MainLoop()
data = {'main_loop': main_loop}
- self.dbus_proxy.ListNames('()', result_handler=call_done,
- user_data=data)
+ self.dbus_proxy.ListNames('()', result_handler=call_done, user_data=data)
main_loop.run()
result = data['result']
@@ -176,10 +179,10 @@ class TestGDBusClient(unittest.TestCase):
user_data['result'] = result
user_data['main_loop'].quit()
- main_loop = GObject.MainLoop()
+ main_loop = GLib.MainLoop()
data = {'main_loop': main_loop}
self.dbus_proxy.ListNames('(s)', 'invalid_argument',
- result_handler=call_done, user_data=data)
+ result_handler=call_done, user_data=data)
main_loop.run()
self.assertTrue(isinstance(data['result'], Exception))
@@ -195,13 +198,13 @@ class TestGDBusClient(unittest.TestCase):
user_data['error'] = error
user_data['main_loop'].quit()
- main_loop = GObject.MainLoop()
+ main_loop = GLib.MainLoop()
data = {'main_loop': main_loop}
self.dbus_proxy.ListNames('(s)', 'invalid_argument',
- result_handler=call_done, error_handler=call_error,
- user_data=data)
+ result_handler=call_done,
+ error_handler=call_error,
+ user_data=data)
main_loop.run()
self.assertTrue(isinstance(data['error'], Exception))
self.assertTrue('InvalidArgs' in str(data['error']), str(data['error']))
-
diff --git a/tests/test_generictreemodel.py b/tests/test_generictreemodel.py
new file mode 100644
index 0000000..9fa89ff
--- /dev/null
+++ b/tests/test_generictreemodel.py
@@ -0,0 +1,411 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# test_generictreemodel - Tests for GenericTreeModel
+# Copyright (C) 2013 Simon Feltman
+#
+# test_generictreemodel.py: Tests for GenericTreeModel
+#
+# 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.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+
+# system
+import gc
+import sys
+import weakref
+import unittest
+
+# pygobject
+from gi.repository import GObject
+from gi.repository import Gtk
+from pygtkcompat.generictreemodel import GenericTreeModel
+from pygtkcompat.generictreemodel import _get_user_data_as_pyobject
+
+
+class Node(object):
+ """Represents a generic node with name, value, and children."""
+ def __init__(self, name, value, *children):
+ self.name = name
+ self.value = value
+ self.children = list(children)
+ self.parent = None
+ self.next = None
+
+ for i, child in enumerate(children):
+ child.parent = weakref.ref(self)
+ if i < len(children) - 1:
+ child.next = weakref.ref(children[i + 1])
+
+ def __repr__(self):
+ return 'Node("%s", %s)' % (self.name, self.value)
+
+
+class TesterModel(GenericTreeModel):
+ def __init__(self):
+ super(TesterModel, self).__init__()
+ self.root = Node('root', 0,
+ Node('spam', 1,
+ Node('sushi', 2),
+ Node('bread', 3)
+ ),
+ Node('eggs', 4)
+ )
+
+ def on_get_flags(self):
+ return 0
+
+ def on_get_n_columns(self):
+ return 2
+
+ def on_get_column_type(self, n):
+ return (str, int)[n]
+
+ def on_get_iter(self, path):
+ node = self.root
+ path = list(path)
+ idx = path.pop(0)
+ while path:
+ idx = path.pop(0)
+ node = node.children[idx]
+ return node
+
+ def on_get_path(self, node):
+ def rec_get_path(n):
+ for i, child in enumerate(n.children):
+ if child == node:
+ return [i]
+ else:
+ res = rec_get_path(child)
+ if res:
+ res.insert(0, i)
+
+ return rec_get_path(self.root)
+
+ def on_get_value(self, node, column):
+ if column == 0:
+ return node.name
+ elif column == 1:
+ return node.value
+
+ def on_iter_has_child(self, node):
+ return bool(node.children)
+
+ def on_iter_next(self, node):
+ if node.next:
+ return node.next()
+
+ def on_iter_children(self, node):
+ if node:
+ return node.children[0]
+ else:
+ return self.root
+
+ def on_iter_n_children(self, node):
+ if node is None:
+ return 1
+ return len(node.children)
+
+ def on_iter_nth_child(self, node, n):
+ if node is None:
+ assert n == 0
+ return self.root
+ return node.children[n]
+
+ def on_iter_parent(self, child):
+ if child.parent:
+ return child.parent()
+
+
+class TestReferences(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_c_tree_iter_user_data_as_pyobject(self):
+ obj = object()
+ obj_id = id(obj)
+ ref_count = sys.getrefcount(obj)
+
+ # This is essentially a stolen ref in the context of _CTreeIter.get_user_data_as_pyobject
+ it = Gtk.TreeIter()
+ it.user_data = obj_id
+
+ obj2 = _get_user_data_as_pyobject(it)
+ self.assertEqual(obj, obj2)
+ self.assertEqual(sys.getrefcount(obj), ref_count + 1)
+
+ def test_leak_references_on(self):
+ model = TesterModel()
+ obj_ref = weakref.ref(model.root)
+ # Initial refcount is 1 for model.root + the temporary
+ self.assertEqual(sys.getrefcount(model.root), 2)
+
+ # Iter increases by 1 do to assignment to iter.user_data
+ res, it = model.do_get_iter([0])
+ self.assertEqual(id(model.root), it.user_data)
+ self.assertEqual(sys.getrefcount(model.root), 3)
+
+ # Verify getting a TreeIter more then once does not further increase
+ # the ref count.
+ res2, it2 = model.do_get_iter([0])
+ self.assertEqual(id(model.root), it2.user_data)
+ self.assertEqual(sys.getrefcount(model.root), 3)
+
+ # Deleting the iter does not decrease refcount because references
+ # leak by default (they are stored in the held_refs pool)
+ del it
+ gc.collect()
+ self.assertEqual(sys.getrefcount(model.root), 3)
+
+ # Deleting a model should free all held references to user data
+ # stored by TreeIters
+ del model
+ gc.collect()
+ self.assertEqual(obj_ref(), None)
+
+ def test_row_deleted_frees_refs(self):
+ model = TesterModel()
+ obj_ref = weakref.ref(model.root)
+ # Initial refcount is 1 for model.root + the temporary
+ self.assertEqual(sys.getrefcount(model.root), 2)
+
+ # Iter increases by 1 do to assignment to iter.user_data
+ res, it = model.do_get_iter([0])
+ self.assertEqual(id(model.root), it.user_data)
+ self.assertEqual(sys.getrefcount(model.root), 3)
+
+ # Notifying the underlying model of a row_deleted should decrease the
+ # ref count.
+ model.row_deleted(Gtk.TreePath('0'), model.root)
+ self.assertEqual(sys.getrefcount(model.root), 2)
+
+ # Finally deleting the actual object should collect it completely
+ del model.root
+ gc.collect()
+ self.assertEqual(obj_ref(), None)
+
+ def test_leak_references_off(self):
+ model = TesterModel()
+ model.leak_references = False
+
+ obj_ref = weakref.ref(model.root)
+ # Initial refcount is 1 for model.root + the temporary
+ self.assertEqual(sys.getrefcount(model.root), 2)
+
+ # Iter does not increas count by 1 when leak_references is false
+ res, it = model.do_get_iter([0])
+ self.assertEqual(id(model.root), it.user_data)
+ self.assertEqual(sys.getrefcount(model.root), 2)
+
+ # Deleting the iter does not decrease refcount because assigning user_data
+ # eats references and does not release them.
+ del it
+ gc.collect()
+ self.assertEqual(sys.getrefcount(model.root), 2)
+
+ # Deleting the model decreases the final ref, and the object is collected
+ del model
+ gc.collect()
+ self.assertEqual(obj_ref(), None)
+
+ def test_iteration_refs(self):
+ # Pull iterators off the model using the wrapped C API which will
+ # then call back into the python overrides.
+ model = TesterModel()
+ nodes = [node for node in model.iter_depth_first()]
+ values = [node.value for node in nodes]
+
+ # Verify depth first ordering
+ self.assertEqual(values, [0, 1, 2, 3, 4])
+
+ # Verify ref counts for each of the nodes.
+ # 5 refs for each node at this point:
+ # 1 - ref held in getrefcount function
+ # 2 - ref held by "node" var during iteration
+ # 3 - ref held by local "nodes" var
+ # 4 - ref held by the root/children graph itself
+ # 5 - ref held by the model "held_refs" instance var
+ for node in nodes:
+ self.assertEqual(sys.getrefcount(node), 5)
+
+ # A second iteration and storage of the nodes in a new list
+ # should only increase refcounts by 1 even though new
+ # iterators are created and assigned.
+ nodes2 = [node for node in model.iter_depth_first()]
+ for node in nodes2:
+ self.assertEqual(sys.getrefcount(node), 6)
+
+ # Hold weak refs and start verifying ref collection.
+ node_refs = [weakref.ref(node) for node in nodes]
+
+ # First round of collection
+ del nodes2
+ gc.collect()
+ for node in nodes:
+ self.assertEqual(sys.getrefcount(node), 5)
+
+ # Second round of collection, no more local lists of nodes.
+ del nodes
+ gc.collect()
+ for ref in node_refs:
+ node = ref()
+ self.assertEqual(sys.getrefcount(node), 4)
+
+ # Using invalidate_iters or row_deleted(path, node) will clear out
+ # the pooled refs held internal to the GenericTreeModel implementation.
+ model.invalidate_iters()
+ self.assertEqual(len(model._held_refs), 0)
+ gc.collect()
+ for ref in node_refs:
+ node = ref()
+ self.assertEqual(sys.getrefcount(node), 3)
+
+ # Deleting the root node at this point should allow all nodes to be collected
+ # as there is no longer a way to reach the children
+ del node # node still in locals() from last iteration
+ del model.root
+ gc.collect()
+ for ref in node_refs:
+ self.assertEqual(ref(), None)
+
+
+class TestIteration(unittest.TestCase):
+ def test_iter_next_root(self):
+ model = TesterModel()
+ it = model.get_iter([0])
+ self.assertEqual(it.user_data, id(model.root))
+ self.assertEqual(model.root.next, None)
+
+ it = model.iter_next(it)
+ self.assertEqual(it, None)
+
+ def test_iter_next_multiple(self):
+ model = TesterModel()
+ it = model.get_iter([0, 0])
+ self.assertEqual(it.user_data, id(model.root.children[0]))
+
+ it = model.iter_next(it)
+ self.assertEqual(it.user_data, id(model.root.children[1]))
+
+ it = model.iter_next(it)
+ self.assertEqual(it, None)
+
+
+class ErrorModel(GenericTreeModel):
+ # All on_* methods will raise a NotImplementedError by default
+ pass
+
+
+class ExceptHook(object):
+ """
+ Temporarily installs an exception hook in a context which
+ expects the given exc_type to be raised. This allows verification
+ of exceptions that occur within python gi callbacks but
+ are never bubbled through from python to C back to python.
+ This works because exception hooks are called in PyErr_Print.
+ """
+ def __init__(self, *expected_exc_types):
+ self._expected_exc_types = expected_exc_types
+ self._exceptions = []
+
+ def _excepthook(self, exc_type, value, traceback):
+ self._exceptions.append((exc_type, value))
+
+ def __enter__(self):
+ self._oldhook = sys.excepthook
+ sys.excepthook = self._excepthook
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ sys.excepthook = self._oldhook
+ error_message = 'Expecting the following exceptions: %s, got: %s' % \
+ (str(self._expected_exc_types), '\n'.join([str(item) for item in self._exceptions]))
+
+ assert len(self._expected_exc_types) == len(self._exceptions), error_message
+
+ for expected, got in zip(self._expected_exc_types, [exc[0] for exc in self._exceptions]):
+ assert issubclass(got, expected), error_message
+
+
+class TestReturnsAfterError(unittest.TestCase):
+ def setUp(self):
+ self.model = ErrorModel()
+
+ def test_get_flags(self):
+ with ExceptHook(NotImplementedError):
+ flags = self.model.get_flags()
+ self.assertEqual(flags, 0)
+
+ def test_get_n_columns(self):
+ with ExceptHook(NotImplementedError):
+ count = self.model.get_n_columns()
+ self.assertEqual(count, 0)
+
+ def test_get_column_type(self):
+ with ExceptHook(NotImplementedError, TypeError):
+ col_type = self.model.get_column_type(0)
+ self.assertEqual(col_type, GObject.TYPE_INVALID)
+
+ def test_get_iter(self):
+ with ExceptHook(NotImplementedError):
+ self.assertRaises(ValueError, self.model.get_iter, Gtk.TreePath(0))
+
+ def test_get_path(self):
+ it = self.model.create_tree_iter('foo')
+ with ExceptHook(NotImplementedError):
+ path = self.model.get_path(it)
+ self.assertEqual(path, None)
+
+ def test_get_value(self):
+ it = self.model.create_tree_iter('foo')
+ with ExceptHook(NotImplementedError):
+ try:
+ self.model.get_value(it, 0)
+ except TypeError:
+ pass # silence TypeError converting None to GValue
+
+ def test_iter_has_child(self):
+ it = self.model.create_tree_iter('foo')
+ with ExceptHook(NotImplementedError):
+ res = self.model.iter_has_child(it)
+ self.assertEqual(res, False)
+
+ def test_iter_next(self):
+ it = self.model.create_tree_iter('foo')
+ with ExceptHook(NotImplementedError):
+ res = self.model.iter_next(it)
+ self.assertEqual(res, None)
+
+ def test_iter_children(self):
+ with ExceptHook(NotImplementedError):
+ res = self.model.iter_children(None)
+ self.assertEqual(res, None)
+
+ def test_iter_n_children(self):
+ with ExceptHook(NotImplementedError):
+ res = self.model.iter_n_children(None)
+ self.assertEqual(res, 0)
+
+ def test_iter_nth_child(self):
+ with ExceptHook(NotImplementedError):
+ res = self.model.iter_nth_child(None, 0)
+ self.assertEqual(res, None)
+
+ def test_iter_parent(self):
+ child = self.model.create_tree_iter('foo')
+ with ExceptHook(NotImplementedError):
+ res = self.model.iter_parent(child)
+ self.assertEqual(res, None)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_gi.py b/tests/test_gi.py
index edbe461..da55187 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -10,19 +10,25 @@ import shutil
import os
import locale
import subprocess
-from gi.repository import GObject, GLib
+import gc
+import weakref
+import warnings
+from io import StringIO, BytesIO
+
+import gi
+from gi.repository import GObject, GLib, Gio
from gi.repository import GIMarshallingTests
-from compathelper import _bytes
+from compathelper import _bytes, _unicode
if sys.version_info < (3, 0):
CONSTANT_UTF8 = "const \xe2\x99\xa5 utf8"
PY2_UNICODE_UTF8 = unicode(CONSTANT_UTF8, 'UTF-8')
- CHAR_255='\xff'
+ CHAR_255 = '\xff'
else:
CONSTANT_UTF8 = "const ♥ utf8"
- CHAR_255=bytes([255])
+ CHAR_255 = bytes([255])
CONSTANT_NUMBER = 42
@@ -55,17 +61,26 @@ class TestConstant(unittest.TestCase):
# Blocked by https://bugzilla.gnome.org/show_bug.cgi?id=595773
# def test_constant_utf8(self):
-# self.assertEquals(CONSTANT_UTF8, GIMarshallingTests.CONSTANT_UTF8)
+# self.assertEqual(CONSTANT_UTF8, GIMarshallingTests.CONSTANT_UTF8)
def test_constant_number(self):
- self.assertEquals(CONSTANT_NUMBER, GIMarshallingTests.CONSTANT_NUMBER)
+ self.assertEqual(CONSTANT_NUMBER, GIMarshallingTests.CONSTANT_NUMBER)
+
+ def test_min_max_int(self):
+ self.assertEqual(GLib.MAXINT32, 2 ** 31 - 1)
+ self.assertEqual(GLib.MININT32, -2 ** 31)
+ self.assertEqual(GLib.MAXUINT32, 2 ** 32 - 1)
+
+ self.assertEqual(GLib.MAXINT64, 2 ** 63 - 1)
+ self.assertEqual(GLib.MININT64, -2 ** 63)
+ self.assertEqual(GLib.MAXUINT64, 2 ** 64 - 1)
class TestBoolean(unittest.TestCase):
def test_boolean_return(self):
- self.assertEquals(True, GIMarshallingTests.boolean_return_true())
- self.assertEquals(False, GIMarshallingTests.boolean_return_false())
+ self.assertEqual(True, GIMarshallingTests.boolean_return_true())
+ self.assertEqual(False, GIMarshallingTests.boolean_return_false())
def test_boolean_in(self):
GIMarshallingTests.boolean_in_true(True)
@@ -75,12 +90,12 @@ class TestBoolean(unittest.TestCase):
GIMarshallingTests.boolean_in_false(0)
def test_boolean_out(self):
- self.assertEquals(True, GIMarshallingTests.boolean_out_true())
- self.assertEquals(False, GIMarshallingTests.boolean_out_false())
+ self.assertEqual(True, GIMarshallingTests.boolean_out_true())
+ self.assertEqual(False, GIMarshallingTests.boolean_out_false())
def test_boolean_inout(self):
- self.assertEquals(False, GIMarshallingTests.boolean_inout_true_false(True))
- self.assertEquals(True, GIMarshallingTests.boolean_inout_false_true(False))
+ self.assertEqual(False, GIMarshallingTests.boolean_inout_true_false(True))
+ self.assertEqual(True, GIMarshallingTests.boolean_inout_false_true(False))
class TestInt8(unittest.TestCase):
@@ -89,8 +104,8 @@ class TestInt8(unittest.TestCase):
MIN = GObject.G_MININT8
def test_int8_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int8_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int8_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int8_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int8_return_min())
def test_int8_in(self):
max = Number(self.MAX)
@@ -102,18 +117,18 @@ class TestInt8(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.int8_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.int8_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.int8_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.int8_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.int8_in_max, "self.MAX")
def test_int8_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int8_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int8_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int8_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int8_out_min())
def test_int8_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.int8_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.int8_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.int8_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.int8_inout_min_max(Number(self.MIN)))
class TestUInt8(unittest.TestCase):
@@ -121,7 +136,7 @@ class TestUInt8(unittest.TestCase):
MAX = GObject.G_MAXUINT8
def test_uint8_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint8_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint8_return())
def test_uint8_in(self):
number = Number(self.MAX)
@@ -130,16 +145,16 @@ class TestUInt8(unittest.TestCase):
GIMarshallingTests.uint8_in(CHAR_255)
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.uint8_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.uint8_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.uint8_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.uint8_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.uint8_in, "self.MAX")
def test_uint8_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint8_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint8_out())
def test_uint8_inout(self):
- self.assertEquals(0, GIMarshallingTests.uint8_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.uint8_inout(Number(self.MAX)))
class TestInt16(unittest.TestCase):
@@ -148,8 +163,8 @@ class TestInt16(unittest.TestCase):
MIN = GObject.G_MININT16
def test_int16_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int16_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int16_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int16_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int16_return_min())
def test_int16_in(self):
max = Number(self.MAX)
@@ -161,18 +176,18 @@ class TestInt16(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.int16_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.int16_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.int16_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.int16_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.int16_in_max, "self.MAX")
def test_int16_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int16_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int16_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int16_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int16_out_min())
def test_int16_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.int16_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.int16_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.int16_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.int16_inout_min_max(Number(self.MIN)))
class TestUInt16(unittest.TestCase):
@@ -180,7 +195,7 @@ class TestUInt16(unittest.TestCase):
MAX = GObject.G_MAXUINT16
def test_uint16_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint16_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint16_return())
def test_uint16_in(self):
number = Number(self.MAX)
@@ -189,16 +204,16 @@ class TestUInt16(unittest.TestCase):
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.uint16_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.uint16_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.uint16_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.uint16_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.uint16_in, "self.MAX")
def test_uint16_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint16_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint16_out())
def test_uint16_inout(self):
- self.assertEquals(0, GIMarshallingTests.uint16_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.uint16_inout(Number(self.MAX)))
class TestInt32(unittest.TestCase):
@@ -207,8 +222,8 @@ class TestInt32(unittest.TestCase):
MIN = GObject.G_MININT32
def test_int32_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int32_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int32_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int32_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int32_return_min())
def test_int32_in(self):
max = Number(self.MAX)
@@ -220,18 +235,18 @@ class TestInt32(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.int32_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.int32_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.int32_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.int32_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.int32_in_max, "self.MAX")
def test_int32_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int32_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int32_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int32_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int32_out_min())
def test_int32_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.int32_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.int32_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.int32_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.int32_inout_min_max(Number(self.MIN)))
class TestUInt32(unittest.TestCase):
@@ -239,7 +254,7 @@ class TestUInt32(unittest.TestCase):
MAX = GObject.G_MAXUINT32
def test_uint32_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint32_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint32_return())
def test_uint32_in(self):
number = Number(self.MAX)
@@ -248,16 +263,16 @@ class TestUInt32(unittest.TestCase):
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.uint32_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.uint32_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.uint32_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.uint32_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.uint32_in, "self.MAX")
def test_uint32_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint32_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint32_out())
def test_uint32_inout(self):
- self.assertEquals(0, GIMarshallingTests.uint32_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.uint32_inout(Number(self.MAX)))
class TestInt64(unittest.TestCase):
@@ -266,8 +281,8 @@ class TestInt64(unittest.TestCase):
MIN = - (2 ** 63)
def test_int64_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int64_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int64_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int64_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int64_return_min())
def test_int64_in(self):
max = Number(self.MAX)
@@ -279,18 +294,18 @@ class TestInt64(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.int64_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.int64_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.int64_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.int64_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.int64_in_max, "self.MAX")
def test_int64_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int64_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int64_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int64_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int64_out_min())
def test_int64_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.int64_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.int64_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.int64_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.int64_inout_min_max(Number(self.MIN)))
class TestUInt64(unittest.TestCase):
@@ -298,7 +313,7 @@ class TestUInt64(unittest.TestCase):
MAX = 2 ** 64 - 1
def test_uint64_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint64_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint64_return())
def test_uint64_in(self):
number = Number(self.MAX)
@@ -307,26 +322,26 @@ class TestUInt64(unittest.TestCase):
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.uint64_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.uint64_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.uint64_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.uint64_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.uint64_in, "self.MAX")
def test_uint64_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint64_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint64_out())
def test_uint64_inout(self):
- self.assertEquals(0, GIMarshallingTests.uint64_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.uint64_inout(Number(self.MAX)))
class TestShort(unittest.TestCase):
- MAX = GObject.constants.G_MAXSHORT
- MIN = GObject.constants.G_MINSHORT
+ MAX = GObject.G_MAXSHORT
+ MIN = GObject.G_MINSHORT
def test_short_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.short_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.short_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.short_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.short_return_min())
def test_short_in(self):
max = Number(self.MAX)
@@ -338,26 +353,26 @@ class TestShort(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.short_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.short_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.short_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.short_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.short_in_max, "self.MAX")
def test_short_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.short_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.short_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.short_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.short_out_min())
def test_short_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.short_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.short_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.short_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.short_inout_min_max(Number(self.MIN)))
class TestUShort(unittest.TestCase):
- MAX = GObject.constants.G_MAXUSHORT
+ MAX = GObject.G_MAXUSHORT
def test_ushort_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.ushort_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.ushort_return())
def test_ushort_in(self):
number = Number(self.MAX)
@@ -366,26 +381,26 @@ class TestUShort(unittest.TestCase):
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.ushort_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.ushort_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.ushort_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.ushort_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.ushort_in, "self.MAX")
def test_ushort_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.ushort_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.ushort_out())
def test_ushort_inout(self):
- self.assertEquals(0, GIMarshallingTests.ushort_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.ushort_inout(Number(self.MAX)))
class TestInt(unittest.TestCase):
- MAX = GObject.constants.G_MAXINT
- MIN = GObject.constants.G_MININT
+ MAX = GObject.G_MAXINT
+ MIN = GObject.G_MININT
def test_int_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int_return_min())
def test_int_in(self):
max = Number(self.MAX)
@@ -397,27 +412,27 @@ class TestInt(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.int_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.int_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.int_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.int_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.int_in_max, "self.MAX")
def test_int_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.int_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.int_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.int_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.int_out_min())
def test_int_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.int_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.int_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.int_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.int_inout_min_max(Number(self.MIN)))
self.assertRaises(TypeError, GIMarshallingTests.int_inout_min_max, Number(self.MIN), CONSTANT_NUMBER)
class TestUInt(unittest.TestCase):
- MAX = GObject.constants.G_MAXUINT
+ MAX = GObject.G_MAXUINT
def test_uint_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint_return())
def test_uint_in(self):
number = Number(self.MAX)
@@ -426,26 +441,26 @@ class TestUInt(unittest.TestCase):
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.uint_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.uint_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.uint_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.uint_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.uint_in, "self.MAX")
def test_uint_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.uint_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.uint_out())
def test_uint_inout(self):
- self.assertEquals(0, GIMarshallingTests.uint_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.uint_inout(Number(self.MAX)))
class TestLong(unittest.TestCase):
- MAX = GObject.constants.G_MAXLONG
- MIN = GObject.constants.G_MINLONG
+ MAX = GObject.G_MAXLONG
+ MIN = GObject.G_MINLONG
def test_long_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.long_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.long_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.long_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.long_return_min())
def test_long_in(self):
max = Number(self.MAX)
@@ -457,26 +472,26 @@ class TestLong(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.long_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.long_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.long_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.long_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.long_in_max, "self.MAX")
def test_long_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.long_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.long_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.long_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.long_out_min())
def test_long_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.long_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.long_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.long_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.long_inout_min_max(Number(self.MIN)))
class TestULong(unittest.TestCase):
- MAX = GObject.constants.G_MAXULONG
+ MAX = GObject.G_MAXULONG
def test_ulong_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.ulong_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.ulong_return())
def test_ulong_in(self):
number = Number(self.MAX)
@@ -485,26 +500,26 @@ class TestULong(unittest.TestCase):
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.ulong_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.ulong_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.ulong_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.ulong_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.ulong_in, "self.MAX")
def test_ulong_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.ulong_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.ulong_out())
def test_ulong_inout(self):
- self.assertEquals(0, GIMarshallingTests.ulong_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.ulong_inout(Number(self.MAX)))
class TestSSize(unittest.TestCase):
- MAX = GObject.constants.G_MAXLONG
- MIN = GObject.constants.G_MINLONG
+ MAX = GObject.G_MAXLONG
+ MIN = GObject.G_MINLONG
def test_ssize_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.ssize_return_max())
- self.assertEquals(self.MIN, GIMarshallingTests.ssize_return_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.ssize_return_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.ssize_return_min())
def test_ssize_in(self):
max = Number(self.MAX)
@@ -516,26 +531,26 @@ class TestSSize(unittest.TestCase):
max.value += 1
min.value -= 1
- self.assertRaises(ValueError, GIMarshallingTests.ssize_in_max, max)
- self.assertRaises(ValueError, GIMarshallingTests.ssize_in_min, min)
+ self.assertRaises(OverflowError, GIMarshallingTests.ssize_in_max, max)
+ self.assertRaises(OverflowError, GIMarshallingTests.ssize_in_min, min)
self.assertRaises(TypeError, GIMarshallingTests.ssize_in_max, "self.MAX")
def test_ssize_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.ssize_out_max())
- self.assertEquals(self.MIN, GIMarshallingTests.ssize_out_min())
+ self.assertEqual(self.MAX, GIMarshallingTests.ssize_out_max())
+ self.assertEqual(self.MIN, GIMarshallingTests.ssize_out_min())
def test_ssize_inout(self):
- self.assertEquals(self.MIN, GIMarshallingTests.ssize_inout_max_min(Number(self.MAX)))
- self.assertEquals(self.MAX, GIMarshallingTests.ssize_inout_min_max(Number(self.MIN)))
+ self.assertEqual(self.MIN, GIMarshallingTests.ssize_inout_max_min(Number(self.MAX)))
+ self.assertEqual(self.MAX, GIMarshallingTests.ssize_inout_min_max(Number(self.MIN)))
class TestSize(unittest.TestCase):
- MAX = GObject.constants.G_MAXULONG
+ MAX = GObject.G_MAXULONG
def test_size_return(self):
- self.assertEquals(self.MAX, GIMarshallingTests.size_return())
+ self.assertEqual(self.MAX, GIMarshallingTests.size_return())
def test_size_in(self):
number = Number(self.MAX)
@@ -544,25 +559,41 @@ class TestSize(unittest.TestCase):
number.value += 1
- self.assertRaises(ValueError, GIMarshallingTests.size_in, number)
- self.assertRaises(ValueError, GIMarshallingTests.size_in, Number(-1))
+ self.assertRaises(OverflowError, GIMarshallingTests.size_in, number)
+ self.assertRaises(OverflowError, GIMarshallingTests.size_in, Number(-1))
self.assertRaises(TypeError, GIMarshallingTests.size_in, "self.MAX")
def test_size_out(self):
- self.assertEquals(self.MAX, GIMarshallingTests.size_out())
+ self.assertEqual(self.MAX, GIMarshallingTests.size_out())
def test_size_inout(self):
- self.assertEquals(0, GIMarshallingTests.size_inout(Number(self.MAX)))
+ self.assertEqual(0, GIMarshallingTests.size_inout(Number(self.MAX)))
+
+
+class TestTimet(unittest.TestCase):
+
+ def test_time_t_return(self):
+ self.assertEqual(1234567890, GIMarshallingTests.time_t_return())
+
+ def test_time_t_in(self):
+ GIMarshallingTests.time_t_in(1234567890)
+ self.assertRaises(TypeError, GIMarshallingTests.time_t_in, "hello")
+
+ def test_time_t_out(self):
+ self.assertEqual(1234567890, GIMarshallingTests.time_t_out())
+
+ def test_time_t_inout(self):
+ self.assertEqual(0, GIMarshallingTests.time_t_inout(1234567890))
class TestFloat(unittest.TestCase):
- MAX = GObject.constants.G_MAXFLOAT
- MIN = GObject.constants.G_MINFLOAT
+ MAX = GObject.G_MAXFLOAT
+ MIN = GObject.G_MINFLOAT
def test_float_return(self):
- self.assertAlmostEquals(self.MAX, GIMarshallingTests.float_return())
+ self.assertAlmostEqual(self.MAX, GIMarshallingTests.float_return())
def test_float_in(self):
GIMarshallingTests.float_in(Number(self.MAX))
@@ -570,19 +601,19 @@ class TestFloat(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.float_in, "self.MAX")
def test_float_out(self):
- self.assertAlmostEquals(self.MAX, GIMarshallingTests.float_out())
+ self.assertAlmostEqual(self.MAX, GIMarshallingTests.float_out())
def test_float_inout(self):
- self.assertAlmostEquals(self.MIN, GIMarshallingTests.float_inout(Number(self.MAX)))
+ self.assertAlmostEqual(self.MIN, GIMarshallingTests.float_inout(Number(self.MAX)))
class TestDouble(unittest.TestCase):
- MAX = GObject.constants.G_MAXDOUBLE
- MIN = GObject.constants.G_MINDOUBLE
+ MAX = GObject.G_MAXDOUBLE
+ MIN = GObject.G_MINDOUBLE
def test_double_return(self):
- self.assertAlmostEquals(self.MAX, GIMarshallingTests.double_return())
+ self.assertAlmostEqual(self.MAX, GIMarshallingTests.double_return())
def test_double_in(self):
GIMarshallingTests.double_in(Number(self.MAX))
@@ -590,17 +621,17 @@ class TestDouble(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.double_in, "self.MAX")
def test_double_out(self):
- self.assertAlmostEquals(self.MAX, GIMarshallingTests.double_out())
+ self.assertAlmostEqual(self.MAX, GIMarshallingTests.double_out())
def test_double_inout(self):
- self.assertAlmostEquals(self.MIN, GIMarshallingTests.double_inout(Number(self.MAX)))
+ self.assertAlmostEqual(self.MIN, GIMarshallingTests.double_inout(Number(self.MAX)))
class TestGType(unittest.TestCase):
def test_gtype_name(self):
- self.assertEquals("void", GObject.TYPE_NONE.name)
- self.assertEquals("gchararray", GObject.TYPE_STRING.name)
+ self.assertEqual("void", GObject.TYPE_NONE.name)
+ self.assertEqual("gchararray", GObject.TYPE_STRING.name)
def check_readonly(gtype):
gtype.name = "foo"
@@ -609,8 +640,8 @@ class TestGType(unittest.TestCase):
self.assertRaises(AttributeError, check_readonly, GObject.TYPE_STRING)
def test_gtype_return(self):
- self.assertEquals(GObject.TYPE_NONE, GIMarshallingTests.gtype_return())
- self.assertEquals(GObject.TYPE_STRING, GIMarshallingTests.gtype_string_return())
+ self.assertEqual(GObject.TYPE_NONE, GIMarshallingTests.gtype_return())
+ self.assertEqual(GObject.TYPE_STRING, GIMarshallingTests.gtype_string_return())
def test_gtype_in(self):
GIMarshallingTests.gtype_in(GObject.TYPE_NONE)
@@ -619,20 +650,20 @@ class TestGType(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.gtype_string_in, "foo")
def test_gtype_out(self):
- self.assertEquals(GObject.TYPE_NONE, GIMarshallingTests.gtype_out())
- self.assertEquals(GObject.TYPE_STRING, GIMarshallingTests.gtype_string_out())
+ self.assertEqual(GObject.TYPE_NONE, GIMarshallingTests.gtype_out())
+ self.assertEqual(GObject.TYPE_STRING, GIMarshallingTests.gtype_string_out())
def test_gtype_inout(self):
- self.assertEquals(GObject.TYPE_INT, GIMarshallingTests.gtype_inout(GObject.TYPE_NONE))
+ self.assertEqual(GObject.TYPE_INT, GIMarshallingTests.gtype_inout(GObject.TYPE_NONE))
class TestUtf8(unittest.TestCase):
def test_utf8_none_return(self):
- self.assertEquals(CONSTANT_UTF8, GIMarshallingTests.utf8_none_return())
+ self.assertEqual(CONSTANT_UTF8, GIMarshallingTests.utf8_none_return())
def test_utf8_full_return(self):
- self.assertEquals(CONSTANT_UTF8, GIMarshallingTests.utf8_full_return())
+ self.assertEqual(CONSTANT_UTF8, GIMarshallingTests.utf8_full_return())
def test_utf8_none_in(self):
GIMarshallingTests.utf8_none_in(CONSTANT_UTF8)
@@ -643,28 +674,59 @@ class TestUtf8(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.utf8_none_in, None)
def test_utf8_none_out(self):
- self.assertEquals(CONSTANT_UTF8, GIMarshallingTests.utf8_none_out())
+ self.assertEqual(CONSTANT_UTF8, GIMarshallingTests.utf8_none_out())
def test_utf8_full_out(self):
- self.assertEquals(CONSTANT_UTF8, GIMarshallingTests.utf8_full_out())
+ self.assertEqual(CONSTANT_UTF8, GIMarshallingTests.utf8_full_out())
def test_utf8_dangling_out(self):
GIMarshallingTests.utf8_dangling_out()
def test_utf8_none_inout(self):
- self.assertEquals("", GIMarshallingTests.utf8_none_inout(CONSTANT_UTF8))
+ self.assertEqual("", GIMarshallingTests.utf8_none_inout(CONSTANT_UTF8))
def test_utf8_full_inout(self):
- self.assertEquals("", GIMarshallingTests.utf8_full_inout(CONSTANT_UTF8))
+ self.assertEqual("", GIMarshallingTests.utf8_full_inout(CONSTANT_UTF8))
+
+
+class TestFilename(unittest.TestCase):
+ def setUp(self):
+ self.workdir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.workdir)
+
+ def test_filename_in(self):
+ fname = os.path.join(self.workdir, _unicode('testäø.txt'))
+ self.assertRaises(GLib.GError, GLib.file_get_contents, fname)
+
+ with open(fname.encode('UTF-8'), 'wb') as f:
+ f.write(b'hello world!\n\x01\x02')
+
+ (result, contents) = GLib.file_get_contents(fname)
+ self.assertEqual(result, True)
+ self.assertEqual(contents, b'hello world!\n\x01\x02')
+
+ def test_filename_out(self):
+ self.assertRaises(GLib.GError, GLib.Dir.make_tmp, 'test')
+
+ dirname = GLib.Dir.make_tmp('testäø.XXXXXX')
+ self.assertTrue('/testäø.' in dirname, dirname)
+ dirname = _bytes(dirname)
+ self.assertTrue(os.path.isdir(dirname))
+ os.rmdir(dirname)
+
+ def test_filename_type_error(self):
+ self.assertRaises(TypeError, GLib.file_get_contents, 23)
class TestArray(unittest.TestCase):
def test_array_fixed_int_return(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.array_fixed_int_return())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.array_fixed_int_return())
def test_array_fixed_short_return(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.array_fixed_short_return())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.array_fixed_short_return())
def test_array_fixed_int_in(self):
GIMarshallingTests.array_fixed_int_in(Sequence([-1, 0, 1, 2]))
@@ -678,26 +740,47 @@ class TestArray(unittest.TestCase):
GIMarshallingTests.array_fixed_short_in(Sequence([-1, 0, 1, 2]))
def test_array_fixed_out(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.array_fixed_out())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.array_fixed_out())
def test_array_fixed_inout(self):
- self.assertEquals([2, 1, 0, -1], GIMarshallingTests.array_fixed_inout([-1, 0, 1, 2]))
+ self.assertEqual([2, 1, 0, -1], GIMarshallingTests.array_fixed_inout([-1, 0, 1, 2]))
def test_array_return(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.array_return())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.array_return())
+
+ def test_array_return_etc(self):
+ self.assertEqual(([5, 0, 1, 9], 14), GIMarshallingTests.array_return_etc(5, 9))
def test_array_in(self):
GIMarshallingTests.array_in(Sequence([-1, 0, 1, 2]))
+ GIMarshallingTests.array_in_guint64_len(Sequence([-1, 0, 1, 2]))
+ GIMarshallingTests.array_in_guint8_len(Sequence([-1, 0, 1, 2]))
+
+ def test_array_in_len_before(self):
+ GIMarshallingTests.array_in_len_before(Sequence([-1, 0, 1, 2]))
+
+ def test_array_in_len_zero_terminated(self):
+ GIMarshallingTests.array_in_len_zero_terminated(Sequence([-1, 0, 1, 2]))
def test_array_uint8_in(self):
GIMarshallingTests.array_uint8_in(Sequence([97, 98, 99, 100]))
GIMarshallingTests.array_uint8_in(_bytes("abcd"))
+ def test_array_string_in(self):
+ GIMarshallingTests.array_string_in(['foo', 'bar'])
+
def test_array_out(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.array_out())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.array_out())
+
+ def test_array_out_etc(self):
+ self.assertEqual(([-5, 0, 1, 9], 4), GIMarshallingTests.array_out_etc(-5, 9))
def test_array_inout(self):
- self.assertEquals([-2, -1, 0, 1, 2], GIMarshallingTests.array_inout(Sequence([-1, 0, 1, 2])))
+ self.assertEqual([-2, -1, 0, 1, 2], GIMarshallingTests.array_inout(Sequence([-1, 0, 1, 2])))
+
+ def test_array_inout_etc(self):
+ self.assertEqual(([-5, -1, 0, 1, 9], 4),
+ GIMarshallingTests.array_inout_etc(-5, Sequence([-1, 0, 1, 2]), 9))
def test_method_array_in(self):
object_ = GIMarshallingTests.Object()
@@ -705,88 +788,122 @@ class TestArray(unittest.TestCase):
def test_method_array_out(self):
object_ = GIMarshallingTests.Object()
- self.assertEquals([-1, 0, 1, 2], object_.method_array_out())
+ self.assertEqual([-1, 0, 1, 2], object_.method_array_out())
def test_method_array_inout(self):
object_ = GIMarshallingTests.Object()
- self.assertEquals([-2, -1, 0, 1, 2], object_.method_array_inout(Sequence([-1, 0, 1, 2])))
+ self.assertEqual([-2, -1, 0, 1, 2], object_.method_array_inout(Sequence([-1, 0, 1, 2])))
def test_method_array_return(self):
object_ = GIMarshallingTests.Object()
- self.assertEquals([-1, 0, 1, 2], object_.method_array_return())
+ self.assertEqual([-1, 0, 1, 2], object_.method_array_return())
def test_array_enum_in(self):
- GIMarshallingTests.array_enum_in([GIMarshallingTests.Enum.VALUE1,
- GIMarshallingTests.Enum.VALUE2,
- GIMarshallingTests.Enum.VALUE3])
+ GIMarshallingTests.array_enum_in([GIMarshallingTests.Enum.VALUE1,
+ GIMarshallingTests.Enum.VALUE2,
+ GIMarshallingTests.Enum.VALUE3])
def test_array_boxed_struct_in(self):
- struct1 = GIMarshallingTests.BoxedStruct()
- struct1.long_ = 1
- struct2 = GIMarshallingTests.BoxedStruct()
- struct2.long_ = 2
- struct3 = GIMarshallingTests.BoxedStruct()
- struct3.long_ = 3
-
- GIMarshallingTests.array_struct_in([struct1, struct2, struct3])
+ struct1 = GIMarshallingTests.BoxedStruct()
+ struct1.long_ = 1
+ struct2 = GIMarshallingTests.BoxedStruct()
+ struct2.long_ = 2
+ struct3 = GIMarshallingTests.BoxedStruct()
+ struct3.long_ = 3
+
+ GIMarshallingTests.array_struct_in([struct1, struct2, struct3])
+
+ def test_array_boxed_struct_value_in(self):
+ struct1 = GIMarshallingTests.BoxedStruct()
+ struct1.long_ = 1
+ struct2 = GIMarshallingTests.BoxedStruct()
+ struct2.long_ = 2
+ struct3 = GIMarshallingTests.BoxedStruct()
+ struct3.long_ = 3
+
+ GIMarshallingTests.array_struct_value_in([struct1, struct2, struct3])
+
+ def test_array_boxed_struct_take_in(self):
+ struct1 = GIMarshallingTests.BoxedStruct()
+ struct1.long_ = 1
+ struct2 = GIMarshallingTests.BoxedStruct()
+ struct2.long_ = 2
+ struct3 = GIMarshallingTests.BoxedStruct()
+ struct3.long_ = 3
+
+ GIMarshallingTests.array_struct_take_in([struct1, struct2, struct3])
+
+ self.assertEqual(1, struct1.long_)
+
+ def test_array_boxed_struct_return(self):
+ (struct1, struct2, struct3) = GIMarshallingTests.array_zero_terminated_return_struct()
+ self.assertEqual(GIMarshallingTests.BoxedStruct, type(struct1))
+ self.assertEqual(GIMarshallingTests.BoxedStruct, type(struct2))
+ self.assertEqual(GIMarshallingTests.BoxedStruct, type(struct3))
+ self.assertEqual(42, struct1.long_)
+ self.assertEqual(43, struct2.long_)
+ self.assertEqual(44, struct3.long_)
def test_array_simple_struct_in(self):
- struct1 = GIMarshallingTests.SimpleStruct()
- struct1.long_ = 1
- struct2 = GIMarshallingTests.SimpleStruct()
- struct2.long_ = 2
- struct3 = GIMarshallingTests.SimpleStruct()
- struct3.long_ = 3
+ struct1 = GIMarshallingTests.SimpleStruct()
+ struct1.long_ = 1
+ struct2 = GIMarshallingTests.SimpleStruct()
+ struct2.long_ = 2
+ struct3 = GIMarshallingTests.SimpleStruct()
+ struct3.long_ = 3
- GIMarshallingTests.array_simple_struct_in([struct1, struct2, struct3])
+ GIMarshallingTests.array_simple_struct_in([struct1, struct2, struct3])
def test_array_multi_array_key_value_in(self):
- GIMarshallingTests.multi_array_key_value_in(["one", "two", "three"],
- [1, 2, 3])
+ GIMarshallingTests.multi_array_key_value_in(["one", "two", "three"],
+ [1, 2, 3])
+
+ def test_array_in_nonzero_nonlen(self):
+ GIMarshallingTests.array_in_nonzero_nonlen(1, b'abcd')
def test_array_fixed_out_struct(self):
struct1, struct2 = GIMarshallingTests.array_fixed_out_struct()
- self.assertEquals(7, struct1.long_)
- self.assertEquals(6, struct1.int8)
- self.assertEquals(6, struct2.long_)
- self.assertEquals(7, struct2.int8)
+ self.assertEqual(7, struct1.long_)
+ self.assertEqual(6, struct1.int8)
+ self.assertEqual(6, struct2.long_)
+ self.assertEqual(7, struct2.int8)
def test_array_zero_terminated_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.array_zero_terminated_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.array_zero_terminated_return())
def test_array_zero_terminated_return_null(self):
- self.assertEquals([], GIMarshallingTests.array_zero_terminated_return_null())
+ self.assertEqual([], GIMarshallingTests.array_zero_terminated_return_null())
def test_array_zero_terminated_in(self):
GIMarshallingTests.array_zero_terminated_in(Sequence(['0', '1', '2']))
def test_array_zero_terminated_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.array_zero_terminated_out())
-
- def test_array_zero_terminated_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.array_zero_terminated_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.array_zero_terminated_out())
def test_array_zero_terminated_inout(self):
- self.assertEquals(['-1', '0', '1', '2'], GIMarshallingTests.array_zero_terminated_inout(['0', '1', '2']))
+ self.assertEqual(['-1', '0', '1', '2'], GIMarshallingTests.array_zero_terminated_inout(['0', '1', '2']))
+
+ def test_init_function(self):
+ self.assertEqual((True, []), GIMarshallingTests.init_function([]))
+ self.assertEqual((True, []), GIMarshallingTests.init_function(['hello']))
+ self.assertEqual((True, ['hello']),
+ GIMarshallingTests.init_function(['hello', 'world']))
class TestGStrv(unittest.TestCase):
def test_gstrv_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gstrv_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gstrv_return())
def test_gstrv_in(self):
GIMarshallingTests.gstrv_in(Sequence(['0', '1', '2']))
def test_gstrv_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gstrv_out())
-
- def test_gstrv_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gstrv_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gstrv_out())
def test_gstrv_inout(self):
- self.assertEquals(['-1', '0', '1', '2'], GIMarshallingTests.gstrv_inout(['0', '1', '2']))
+ self.assertEqual(['-1', '0', '1', '2'], GIMarshallingTests.gstrv_inout(['0', '1', '2']))
class TestArrayGVariant(unittest.TestCase):
@@ -794,36 +911,39 @@ class TestArrayGVariant(unittest.TestCase):
def test_array_gvariant_none_in(self):
v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_none_in(v)]
- self.assertEquals([27, "Hello"], returned)
+ self.assertEqual([27, "Hello"], returned)
def test_array_gvariant_container_in(self):
v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
- returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_none_in(v)]
- self.assertEquals([27, "Hello"], returned)
+ returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_container_in(v)]
+ self.assertEqual([27, "Hello"], returned)
def test_array_gvariant_full_in(self):
v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
- returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_none_in(v)]
- self.assertEquals([27, "Hello"], returned)
+ returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_full_in(v)]
+ self.assertEqual([27, "Hello"], returned)
def test_bytearray_gvariant(self):
v = GLib.Variant.new_bytestring(b"foo")
- self.assertEquals(v.get_bytestring(), b"foo")
+ self.assertEqual(v.get_bytestring(), b"foo")
class TestGArray(unittest.TestCase):
def test_garray_int_none_return(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.garray_int_none_return())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.garray_int_none_return())
+
+ def test_garray_uint64_none_return(self):
+ self.assertEqual([0, GObject.G_MAXUINT64], GIMarshallingTests.garray_uint64_none_return())
def test_garray_utf8_none_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.garray_utf8_none_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_none_return())
def test_garray_utf8_container_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.garray_utf8_container_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_container_return())
def test_garray_utf8_full_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.garray_utf8_full_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_full_return())
def test_garray_int_none_in(self):
GIMarshallingTests.garray_int_none_in(Sequence([-1, 0, 1, 2]))
@@ -833,74 +953,133 @@ class TestGArray(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.garray_int_none_in, 42)
self.assertRaises(TypeError, GIMarshallingTests.garray_int_none_in, None)
+ def test_garray_uint64_none_in(self):
+ GIMarshallingTests.garray_uint64_none_in(Sequence([0, GObject.G_MAXUINT64]))
+
def test_garray_utf8_none_in(self):
GIMarshallingTests.garray_utf8_none_in(Sequence(['0', '1', '2']))
def test_garray_utf8_none_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.garray_utf8_none_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_none_out())
def test_garray_utf8_container_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.garray_utf8_container_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_container_out())
def test_garray_utf8_full_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.garray_utf8_full_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_full_out())
+
+ def test_garray_utf8_full_out_caller_allocated(self):
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_full_out_caller_allocated())
def test_garray_utf8_none_inout(self):
- self.assertEquals(['-2', '-1', '0', '1'], GIMarshallingTests.garray_utf8_none_inout(Sequence(('0', '1', '2'))))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.garray_utf8_none_inout(Sequence(('0', '1', '2'))))
def test_garray_utf8_container_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.garray_utf8_container_inout(['0', '1', '2']))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.garray_utf8_container_inout(['0', '1', '2']))
def test_garray_utf8_full_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.garray_utf8_full_inout(['0', '1', '2']))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.garray_utf8_full_inout(['0', '1', '2']))
class TestGPtrArray(unittest.TestCase):
def test_gptrarray_utf8_none_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_none_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_none_return())
def test_gptrarray_utf8_container_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_container_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_container_return())
def test_gptrarray_utf8_full_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_full_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_full_return())
def test_gptrarray_utf8_none_in(self):
GIMarshallingTests.gptrarray_utf8_none_in(Sequence(['0', '1', '2']))
def test_gptrarray_utf8_none_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_none_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_none_out())
def test_gptrarray_utf8_container_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_container_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_container_out())
def test_gptrarray_utf8_full_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_full_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gptrarray_utf8_full_out())
def test_gptrarray_utf8_none_inout(self):
- self.assertEquals(['-2', '-1', '0', '1'], GIMarshallingTests.gptrarray_utf8_none_inout(Sequence(('0', '1', '2'))))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.gptrarray_utf8_none_inout(Sequence(('0', '1', '2'))))
def test_gptrarray_utf8_container_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.gptrarray_utf8_container_inout(['0', '1', '2']))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.gptrarray_utf8_container_inout(['0', '1', '2']))
def test_gptrarray_utf8_full_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.gptrarray_utf8_full_inout(['0', '1', '2']))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.gptrarray_utf8_full_inout(['0', '1', '2']))
+
+
+class TestGBytes(unittest.TestCase):
+ def test_gbytes_create(self):
+ b = GLib.Bytes.new(b'\x00\x01\xFF')
+ self.assertEqual(3, b.get_size())
+ self.assertEqual(b'\x00\x01\xFF', b.get_data())
+
+ def test_gbytes_create_take(self):
+ b = GLib.Bytes.new_take(b'\x00\x01\xFF')
+ self.assertEqual(3, b.get_size())
+ self.assertEqual(b'\x00\x01\xFF', b.get_data())
+
+ def test_gbytes_full_return(self):
+ b = GIMarshallingTests.gbytes_full_return()
+ self.assertEqual(4, b.get_size())
+ self.assertEqual(b'\x00\x31\xFF\x33', b.get_data())
+
+ def test_gbytes_none_in(self):
+ b = GIMarshallingTests.gbytes_full_return()
+ GIMarshallingTests.gbytes_none_in(b)
+
+ def test_compare(self):
+ a1 = GLib.Bytes.new(b'\x00\x01\xFF')
+ a2 = GLib.Bytes.new(b'\x00\x01\xFF')
+ b = GLib.Bytes.new(b'\x00\x01\xFE')
+
+ self.assertTrue(a1.equal(a2))
+ self.assertTrue(a2.equal(a1))
+ self.assertFalse(a1.equal(b))
+ self.assertFalse(b.equal(a2))
+
+ self.assertEqual(0, a1.compare(a2))
+ self.assertLess(0, a1.compare(b))
+ self.assertGreater(0, b.compare(a1))
+
+
+class TestGByteArray(unittest.TestCase):
+ def test_new(self):
+ ba = GLib.ByteArray.new()
+ self.assertEqual(b'', ba)
+
+ ba = GLib.ByteArray.new_take(b'\x01\x02\xFF')
+ self.assertEqual(b'\x01\x02\xFF', ba)
+
+ def test_bytearray_full_return(self):
+ self.assertEqual(b'\x001\xFF3', GIMarshallingTests.bytearray_full_return())
+
+ def test_bytearray_none_in(self):
+ GIMarshallingTests.bytearray_none_in(b'\x00\x31\xFF\x33')
class TestGList(unittest.TestCase):
def test_glist_int_none_return(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.glist_int_none_return())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.glist_int_none_return())
+
+ def test_glist_uint32_none_return(self):
+ self.assertEqual([0, GObject.G_MAXUINT32], GIMarshallingTests.glist_uint32_none_return())
def test_glist_utf8_none_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.glist_utf8_none_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.glist_utf8_none_return())
def test_glist_utf8_container_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.glist_utf8_container_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.glist_utf8_container_return())
def test_glist_utf8_full_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.glist_utf8_full_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.glist_utf8_full_return())
def test_glist_int_none_in(self):
GIMarshallingTests.glist_int_none_in(Sequence((-1, 0, 1, 2)))
@@ -910,41 +1089,44 @@ class TestGList(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.glist_int_none_in, 42)
self.assertRaises(TypeError, GIMarshallingTests.glist_int_none_in, None)
+ def test_glist_uint32_none_in(self):
+ GIMarshallingTests.glist_uint32_none_in(Sequence((0, GObject.G_MAXUINT32)))
+
def test_glist_utf8_none_in(self):
GIMarshallingTests.glist_utf8_none_in(Sequence(('0', '1', '2')))
def test_glist_utf8_none_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.glist_utf8_none_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.glist_utf8_none_out())
def test_glist_utf8_container_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.glist_utf8_container_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.glist_utf8_container_out())
def test_glist_utf8_full_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.glist_utf8_full_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.glist_utf8_full_out())
def test_glist_utf8_none_inout(self):
- self.assertEquals(['-2', '-1', '0', '1'], GIMarshallingTests.glist_utf8_none_inout(Sequence(('0', '1', '2'))))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.glist_utf8_none_inout(Sequence(('0', '1', '2'))))
def test_glist_utf8_container_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.glist_utf8_container_inout(('0', '1', '2')))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.glist_utf8_container_inout(('0', '1', '2')))
def test_glist_utf8_full_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.glist_utf8_full_inout(('0', '1', '2')))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.glist_utf8_full_inout(('0', '1', '2')))
class TestGSList(unittest.TestCase):
def test_gslist_int_none_return(self):
- self.assertEquals([-1, 0, 1, 2], GIMarshallingTests.gslist_int_none_return())
+ self.assertEqual([-1, 0, 1, 2], GIMarshallingTests.gslist_int_none_return())
def test_gslist_utf8_none_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gslist_utf8_none_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gslist_utf8_none_return())
def test_gslist_utf8_container_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gslist_utf8_container_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gslist_utf8_container_return())
def test_gslist_utf8_full_return(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gslist_utf8_full_return())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gslist_utf8_full_return())
def test_gslist_int_none_in(self):
GIMarshallingTests.gslist_int_none_in(Sequence((-1, 0, 1, 2)))
@@ -958,37 +1140,37 @@ class TestGSList(unittest.TestCase):
GIMarshallingTests.gslist_utf8_none_in(Sequence(('0', '1', '2')))
def test_gslist_utf8_none_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gslist_utf8_none_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gslist_utf8_none_out())
def test_gslist_utf8_container_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gslist_utf8_container_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gslist_utf8_container_out())
def test_gslist_utf8_full_out(self):
- self.assertEquals(['0', '1', '2'], GIMarshallingTests.gslist_utf8_full_out())
+ self.assertEqual(['0', '1', '2'], GIMarshallingTests.gslist_utf8_full_out())
def test_gslist_utf8_none_inout(self):
- self.assertEquals(['-2', '-1', '0', '1'], GIMarshallingTests.gslist_utf8_none_inout(Sequence(('0', '1', '2'))))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.gslist_utf8_none_inout(Sequence(('0', '1', '2'))))
def test_gslist_utf8_container_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.gslist_utf8_container_inout(('0', '1', '2')))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.gslist_utf8_container_inout(('0', '1', '2')))
def test_gslist_utf8_full_inout(self):
- self.assertEquals(['-2', '-1','0', '1'], GIMarshallingTests.gslist_utf8_full_inout(('0', '1', '2')))
+ self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.gslist_utf8_full_inout(('0', '1', '2')))
class TestGHashTable(unittest.TestCase):
def test_ghashtable_int_none_return(self):
- self.assertEquals({-1: 1, 0: 0, 1: -1, 2: -2}, GIMarshallingTests.ghashtable_int_none_return())
+ self.assertEqual({-1: 1, 0: 0, 1: -1, 2: -2}, GIMarshallingTests.ghashtable_int_none_return())
- def test_ghashtable_int_none_return(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_none_return())
+ def test_ghashtable_int_none_return2(self):
+ self.assertEqual({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_none_return())
def test_ghashtable_int_container_return(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_container_return())
+ self.assertEqual({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_container_return())
def test_ghashtable_int_full_return(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_full_return())
+ self.assertEqual({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_full_return())
def test_ghashtable_int_none_in(self):
GIMarshallingTests.ghashtable_int_none_in({-1: 1, 0: 0, 1: -1, 2: -2})
@@ -1003,48 +1185,77 @@ class TestGHashTable(unittest.TestCase):
GIMarshallingTests.ghashtable_utf8_none_in({'-1': '1', '0': '0', '1': '-1', '2': '-2'})
def test_ghashtable_utf8_none_out(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_none_out())
+ self.assertEqual({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_none_out())
def test_ghashtable_utf8_container_out(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_container_out())
+ self.assertEqual({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_container_out())
def test_ghashtable_utf8_full_out(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_full_out())
+ self.assertEqual({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, GIMarshallingTests.ghashtable_utf8_full_out())
def test_ghashtable_utf8_none_inout(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '1'},
- GIMarshallingTests.ghashtable_utf8_none_inout({'-1': '1', '0': '0', '1': '-1', '2': '-2'}))
+ i = {'-1': '1', '0': '0', '1': '-1', '2': '-2'}
+ self.assertEqual({'-1': '1', '0': '0', '1': '1'},
+ GIMarshallingTests.ghashtable_utf8_none_inout(i))
def test_ghashtable_utf8_container_inout(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '1'},
- GIMarshallingTests.ghashtable_utf8_container_inout({'-1': '1', '0': '0', '1': '-1', '2': '-2'}))
+ i = {'-1': '1', '0': '0', '1': '-1', '2': '-2'}
+ self.assertEqual({'-1': '1', '0': '0', '1': '1'},
+ GIMarshallingTests.ghashtable_utf8_container_inout(i))
def test_ghashtable_utf8_full_inout(self):
- self.assertEquals({'-1': '1', '0': '0', '1': '1'},
- GIMarshallingTests.ghashtable_utf8_full_inout({'-1': '1', '0': '0', '1': '-1', '2': '-2'}))
+ i = {'-1': '1', '0': '0', '1': '-1', '2': '-2'}
+ self.assertEqual({'-1': '1', '0': '0', '1': '1'},
+ GIMarshallingTests.ghashtable_utf8_full_inout(i))
class TestGValue(unittest.TestCase):
def test_gvalue_return(self):
- self.assertEquals(42, GIMarshallingTests.gvalue_return())
+ self.assertEqual(42, GIMarshallingTests.gvalue_return())
def test_gvalue_in(self):
GIMarshallingTests.gvalue_in(42)
- value = GObject.Value()
- value.init(GObject.TYPE_INT)
- value.set_int(42)
+ value = GObject.Value(GObject.TYPE_INT, 42)
GIMarshallingTests.gvalue_in(value)
+ @unittest.skipUnless(hasattr(GIMarshallingTests, 'gvalue_in_with_modification'),
+ 'Newer version of gi needed.')
+ def test_gvalue_in_with_modification(self):
+ value = GObject.Value(GObject.TYPE_INT, 42)
+ GIMarshallingTests.gvalue_in_with_modification(value)
+ self.assertEqual(value.get_int(), 24)
+
+ def test_gvalue_int64_in(self):
+ value = GObject.Value(GObject.TYPE_INT64, GObject.G_MAXINT64)
+ GIMarshallingTests.gvalue_int64_in(value)
+
+ def test_gvalue_in_with_type(self):
+ value = GObject.Value(GObject.TYPE_STRING, 'foo')
+ GIMarshallingTests.gvalue_in_with_type(value, GObject.TYPE_STRING)
+
+ value = GObject.Value(GIMarshallingTests.Flags.__gtype__,
+ GIMarshallingTests.Flags.VALUE1)
+ GIMarshallingTests.gvalue_in_with_type(value, GObject.TYPE_FLAGS)
+
+ def test_gvalue_in_enum(self):
+ value = GObject.Value(GIMarshallingTests.Enum.__gtype__,
+ GIMarshallingTests.Enum.VALUE3)
+ GIMarshallingTests.gvalue_in_enum(value)
+
def test_gvalue_out(self):
- self.assertEquals(42, GIMarshallingTests.gvalue_out())
+ self.assertEqual(42, GIMarshallingTests.gvalue_out())
+
+ def test_gvalue_int64_out(self):
+ self.assertEqual(GObject.G_MAXINT64, GIMarshallingTests.gvalue_int64_out())
+
+ def test_gvalue_out_caller_allocates(self):
+ self.assertEqual(42, GIMarshallingTests.gvalue_out_caller_allocates())
def test_gvalue_inout(self):
- self.assertEquals('42', GIMarshallingTests.gvalue_inout(42))
- value = GObject.Value()
- value.init(GObject.TYPE_INT)
- value.set_int(42)
- self.assertEquals('42', GIMarshallingTests.gvalue_inout(value))
+ self.assertEqual('42', GIMarshallingTests.gvalue_inout(42))
+ value = GObject.Value(int, 42)
+ self.assertEqual('42', GIMarshallingTests.gvalue_inout(value))
def test_gvalue_flat_array_in(self):
# the function already asserts the correct values
@@ -1054,23 +1265,139 @@ class TestGValue(unittest.TestCase):
values = GIMarshallingTests.return_gvalue_flat_array()
self.assertEqual(values, [42, '42', True])
+ def test_gvalue_gobject_ref_counts(self):
+ # Tests a GObject held by a GValue
+ obj = GObject.Object()
+ ref = weakref.ref(obj)
+ grefcount = obj.__grefcount__
+
+ value = GObject.Value()
+ value.init(GObject.TYPE_OBJECT)
+
+ # TYPE_OBJECT will inc ref count as it should
+ value.set_object(obj)
+ self.assertEqual(obj.__grefcount__, grefcount + 1)
+
+ # multiple set_object should not inc ref count
+ value.set_object(obj)
+ self.assertEqual(obj.__grefcount__, grefcount + 1)
+
+ # get_object will re-use the same wrapper as obj
+ res = value.get_object()
+ self.assertEqual(obj, res)
+ self.assertEqual(obj.__grefcount__, grefcount + 1)
+
+ # multiple get_object should not inc ref count
+ res = value.get_object()
+ self.assertEqual(obj.__grefcount__, grefcount + 1)
+
+ # deletion of the result and value holder should bring the
+ # refcount back to where we started
+ del res
+ del value
+ gc.collect()
+ self.assertEqual(obj.__grefcount__, grefcount)
+
+ del obj
+ gc.collect()
+ self.assertEqual(ref(), None)
+
+ def test_gvalue_boxed_ref_counts(self):
+ # Tests a boxed type wrapping a python object pointer (TYPE_PYOBJECT)
+ # held by a GValue
+ class Obj(object):
+ pass
+
+ obj = Obj()
+ ref = weakref.ref(obj)
+ refcount = sys.getrefcount(obj)
+
+ value = GObject.Value()
+ value.init(GObject.TYPE_PYOBJECT)
+
+ # boxed TYPE_PYOBJECT will inc ref count as it should
+ value.set_boxed(obj)
+ self.assertEqual(sys.getrefcount(obj), refcount + 1)
+
+ # multiple set_boxed should not inc ref count
+ value.set_boxed(obj)
+ self.assertEqual(sys.getrefcount(obj), refcount + 1)
+
+ res = value.get_boxed()
+ self.assertEqual(obj, res)
+ self.assertEqual(sys.getrefcount(obj), refcount + 2)
+
+ # multiple get_boxed should not inc ref count
+ res = value.get_boxed()
+ self.assertEqual(sys.getrefcount(obj), refcount + 2)
+
+ # deletion of the result and value holder should bring the
+ # refcount back to where we started
+ del res
+ del value
+ gc.collect()
+ self.assertEqual(sys.getrefcount(obj), refcount)
+
+ del obj
+ gc.collect()
+ self.assertEqual(ref(), None)
+
+ # FIXME: crashes
+ def disabled_test_gvalue_flat_array_round_trip(self):
+ self.assertEqual([42, '42', True],
+ GIMarshallingTests.gvalue_flat_array_round_trip(42, '42', True))
+
class TestGClosure(unittest.TestCase):
- def test_gclosure_in(self):
+ def test_in(self):
GIMarshallingTests.gclosure_in(lambda: 42)
+ def test_pass(self):
# test passing a closure between two C calls
closure = GIMarshallingTests.gclosure_return()
GIMarshallingTests.gclosure_in(closure)
+ def test_type_error(self):
self.assertRaises(TypeError, GIMarshallingTests.gclosure_in, 42)
self.assertRaises(TypeError, GIMarshallingTests.gclosure_in, None)
+class TestCallbacks(unittest.TestCase):
+ def test_return_value_only(self):
+ def cb():
+ return 5
+ self.assertEqual(GIMarshallingTests.callback_return_value_only(cb), 5)
+
+ def test_one_out_arg(self):
+ def cb():
+ return 5.5
+ self.assertAlmostEqual(GIMarshallingTests.callback_one_out_parameter(cb), 5.5)
+
+ def test_multiple_out_args(self):
+ def cb():
+ return (5.5, 42.0)
+ res = GIMarshallingTests.callback_multiple_out_parameters(cb)
+ self.assertAlmostEqual(res[0], 5.5)
+ self.assertAlmostEqual(res[1], 42.0)
+
+ def test_return_and_one_out_arg(self):
+ def cb():
+ return (5, 42.0)
+ res = GIMarshallingTests.callback_return_value_and_one_out_parameter(cb)
+ self.assertEqual(res[0], 5)
+ self.assertAlmostEqual(res[1], 42.0)
+
+ def test_return_and_multiple_out_arg(self):
+ def cb():
+ return (5, 42, -1000)
+ self.assertEqual(GIMarshallingTests.callback_return_value_and_multiple_out_parameters(cb),
+ (5, 42, -1000))
+
+
class TestPointer(unittest.TestCase):
def test_pointer_in_return(self):
- self.assertEquals(GIMarshallingTests.pointer_in_return(42), 42)
+ self.assertEqual(GIMarshallingTests.pointer_in_return(42), 42)
class TestEnum(unittest.TestCase):
@@ -1079,15 +1406,15 @@ class TestEnum(unittest.TestCase):
def setUpClass(cls):
'''Run tests under a test locale.
- Upper case conversion of member names should not be locale specific;
+ Upper case conversion of member names should not be locale specific
e. g. in Turkish, "i".upper() == "i", which gives results like "iNVALiD"
Run test under a locale which defines toupper('a') == 'a'
'''
cls.locale_dir = tempfile.mkdtemp()
- subprocess.check_call(['localedef', '-i',
- os.path.join(os.path.dirname(os.path.realpath(__file__)), 'te_ST@nouppera'),
- '-c', '-f', 'UTF-8', os.path.join(cls.locale_dir, 'te_ST.UTF-8@nouppera')])
+ src = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'te_ST@nouppera')
+ dest = os.path.join(cls.locale_dir, 'te_ST.UTF-8@nouppera')
+ subprocess.check_call(['localedef', '-i', src, '-c', '-f', 'UTF-8', dest])
os.environ['LOCPATH'] = cls.locale_dir
locale.setlocale(locale.LC_ALL, 'te_ST.UTF-8@nouppera')
@@ -1105,7 +1432,7 @@ class TestEnum(unittest.TestCase):
self.assertTrue(isinstance(GIMarshallingTests.Enum.VALUE1, GIMarshallingTests.Enum))
self.assertTrue(isinstance(GIMarshallingTests.Enum.VALUE2, GIMarshallingTests.Enum))
self.assertTrue(isinstance(GIMarshallingTests.Enum.VALUE3, GIMarshallingTests.Enum))
- self.assertEquals(42, GIMarshallingTests.Enum.VALUE3)
+ self.assertEqual(42, GIMarshallingTests.Enum.VALUE3)
def test_value_nick_and_name(self):
self.assertEqual(GIMarshallingTests.Enum.VALUE1.value_nick, 'value1')
@@ -1123,15 +1450,20 @@ class TestEnum(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.enum_in, 43)
self.assertRaises(TypeError, GIMarshallingTests.enum_in, 'GIMarshallingTests.Enum.VALUE3')
+ def test_enum_return(self):
+ enum = GIMarshallingTests.enum_returnv()
+ self.assertTrue(isinstance(enum, GIMarshallingTests.Enum))
+ self.assertEqual(enum, GIMarshallingTests.Enum.VALUE3)
+
def test_enum_out(self):
enum = GIMarshallingTests.enum_out()
self.assertTrue(isinstance(enum, GIMarshallingTests.Enum))
- self.assertEquals(enum, GIMarshallingTests.Enum.VALUE3)
+ self.assertEqual(enum, GIMarshallingTests.Enum.VALUE3)
def test_enum_inout(self):
enum = GIMarshallingTests.enum_inout(GIMarshallingTests.Enum.VALUE3)
self.assertTrue(isinstance(enum, GIMarshallingTests.Enum))
- self.assertEquals(enum, GIMarshallingTests.Enum.VALUE1)
+ self.assertEqual(enum, GIMarshallingTests.Enum.VALUE1)
def test_enum_second(self):
# check for the bug where different non-gtype enums share the same class
@@ -1143,6 +1475,43 @@ class TestEnum(unittest.TestCase):
self.assertTrue(hasattr(GIMarshallingTests.Enum, "VALUE1"))
self.assertRaises(AttributeError, getattr, GIMarshallingTests.SecondEnum, "VALUE1")
+ def test_enum_gtype_name_is_namespaced(self):
+ self.assertEqual(GIMarshallingTests.Enum.__gtype__.name,
+ 'PyGIMarshallingTestsEnum')
+
+ def test_enum_double_registration_error(self):
+ # a warning is printed for double registration and pygobject will
+ # also raise a RuntimeError.
+ old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_ERROR)
+ try:
+ self.assertRaises(RuntimeError,
+ gi._gi.enum_register_new_gtype_and_add,
+ GIMarshallingTests.Enum.__info__)
+ finally:
+ GLib.log_set_always_fatal(old_mask)
+
+ def test_enum_add_type_error(self):
+ self.assertRaises(TypeError,
+ gi._gi.enum_add,
+ GIMarshallingTests.NoTypeFlags.__gtype__)
+
+
+class TestEnumVFuncResults(unittest.TestCase):
+ class EnumTester(GIMarshallingTests.Object):
+ def do_vfunc_return_enum(self):
+ return GIMarshallingTests.Enum.VALUE2
+
+ def do_vfunc_out_enum(self):
+ return GIMarshallingTests.Enum.VALUE3
+
+ def test_vfunc_return_enum(self):
+ tester = self.EnumTester()
+ self.assertEqual(tester.vfunc_return_enum(), GIMarshallingTests.Enum.VALUE2)
+
+ def test_vfunc_out_enum(self):
+ tester = self.EnumTester()
+ self.assertEqual(tester.vfunc_out_enum(), GIMarshallingTests.Enum.VALUE3)
+
class TestGEnum(unittest.TestCase):
@@ -1151,7 +1520,7 @@ class TestGEnum(unittest.TestCase):
self.assertTrue(isinstance(GIMarshallingTests.GEnum.VALUE1, GIMarshallingTests.GEnum))
self.assertTrue(isinstance(GIMarshallingTests.GEnum.VALUE2, GIMarshallingTests.GEnum))
self.assertTrue(isinstance(GIMarshallingTests.GEnum.VALUE3, GIMarshallingTests.GEnum))
- self.assertEquals(42, GIMarshallingTests.GEnum.VALUE3)
+ self.assertEqual(42, GIMarshallingTests.GEnum.VALUE3)
def test_value_nick_and_name(self):
self.assertEqual(GIMarshallingTests.GEnum.VALUE1.value_nick, 'value1')
@@ -1169,15 +1538,20 @@ class TestGEnum(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.genum_in, 43)
self.assertRaises(TypeError, GIMarshallingTests.genum_in, 'GIMarshallingTests.GEnum.VALUE3')
+ def test_genum_return(self):
+ genum = GIMarshallingTests.genum_returnv()
+ self.assertTrue(isinstance(genum, GIMarshallingTests.GEnum))
+ self.assertEqual(genum, GIMarshallingTests.GEnum.VALUE3)
+
def test_genum_out(self):
genum = GIMarshallingTests.genum_out()
self.assertTrue(isinstance(genum, GIMarshallingTests.GEnum))
- self.assertEquals(genum, GIMarshallingTests.GEnum.VALUE3)
+ self.assertEqual(genum, GIMarshallingTests.GEnum.VALUE3)
def test_genum_inout(self):
genum = GIMarshallingTests.genum_inout(GIMarshallingTests.GEnum.VALUE3)
self.assertTrue(isinstance(genum, GIMarshallingTests.GEnum))
- self.assertEquals(genum, GIMarshallingTests.GEnum.VALUE1)
+ self.assertEqual(genum, GIMarshallingTests.GEnum.VALUE1)
class TestGFlags(unittest.TestCase):
@@ -1190,7 +1564,7 @@ class TestGFlags(unittest.TestCase):
# __or__() operation should still return an instance, not an int.
self.assertTrue(isinstance(GIMarshallingTests.Flags.VALUE1 | GIMarshallingTests.Flags.VALUE2,
GIMarshallingTests.Flags))
- self.assertEquals(1 << 1, GIMarshallingTests.Flags.VALUE2)
+ self.assertEqual(1 << 1, GIMarshallingTests.Flags.VALUE2)
def test_value_nick_and_name(self):
self.assertEqual(GIMarshallingTests.Flags.VALUE1.first_value_nick, 'value1')
@@ -1210,15 +1584,20 @@ class TestGFlags(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.flags_in, 1 << 1)
self.assertRaises(TypeError, GIMarshallingTests.flags_in, 'GIMarshallingTests.Flags.VALUE2')
+ def test_flags_return(self):
+ flags = GIMarshallingTests.flags_returnv()
+ self.assertTrue(isinstance(flags, GIMarshallingTests.Flags))
+ self.assertEqual(flags, GIMarshallingTests.Flags.VALUE2)
+
def test_flags_out(self):
flags = GIMarshallingTests.flags_out()
self.assertTrue(isinstance(flags, GIMarshallingTests.Flags))
- self.assertEquals(flags, GIMarshallingTests.Flags.VALUE2)
+ self.assertEqual(flags, GIMarshallingTests.Flags.VALUE2)
def test_flags_inout(self):
flags = GIMarshallingTests.flags_inout(GIMarshallingTests.Flags.VALUE2)
self.assertTrue(isinstance(flags, GIMarshallingTests.Flags))
- self.assertEquals(flags, GIMarshallingTests.Flags.VALUE1)
+ self.assertEqual(flags, GIMarshallingTests.Flags.VALUE1)
class TestNoTypeFlags(unittest.TestCase):
@@ -1231,7 +1610,7 @@ class TestNoTypeFlags(unittest.TestCase):
# __or__() operation should still return an instance, not an int.
self.assertTrue(isinstance(GIMarshallingTests.NoTypeFlags.VALUE1 | GIMarshallingTests.NoTypeFlags.VALUE2,
GIMarshallingTests.NoTypeFlags))
- self.assertEquals(1 << 1, GIMarshallingTests.NoTypeFlags.VALUE2)
+ self.assertEqual(1 << 1, GIMarshallingTests.NoTypeFlags.VALUE2)
def test_value_nick_and_name(self):
self.assertEqual(GIMarshallingTests.NoTypeFlags.VALUE1.first_value_nick, 'value1')
@@ -1250,15 +1629,35 @@ class TestNoTypeFlags(unittest.TestCase):
self.assertRaises(TypeError, GIMarshallingTests.no_type_flags_in, 1 << 1)
self.assertRaises(TypeError, GIMarshallingTests.no_type_flags_in, 'GIMarshallingTests.NoTypeFlags.VALUE2')
+ def test_flags_return(self):
+ flags = GIMarshallingTests.no_type_flags_returnv()
+ self.assertTrue(isinstance(flags, GIMarshallingTests.NoTypeFlags))
+ self.assertEqual(flags, GIMarshallingTests.NoTypeFlags.VALUE2)
+
def test_flags_out(self):
flags = GIMarshallingTests.no_type_flags_out()
self.assertTrue(isinstance(flags, GIMarshallingTests.NoTypeFlags))
- self.assertEquals(flags, GIMarshallingTests.NoTypeFlags.VALUE2)
+ self.assertEqual(flags, GIMarshallingTests.NoTypeFlags.VALUE2)
def test_flags_inout(self):
flags = GIMarshallingTests.no_type_flags_inout(GIMarshallingTests.NoTypeFlags.VALUE2)
self.assertTrue(isinstance(flags, GIMarshallingTests.NoTypeFlags))
- self.assertEquals(flags, GIMarshallingTests.NoTypeFlags.VALUE1)
+ self.assertEqual(flags, GIMarshallingTests.NoTypeFlags.VALUE1)
+
+ def test_flags_gtype_name_is_namespaced(self):
+ self.assertEqual(GIMarshallingTests.NoTypeFlags.__gtype__.name,
+ 'PyGIMarshallingTestsNoTypeFlags')
+
+ def test_flags_double_registration_error(self):
+ # a warning is printed for double registration and pygobject will
+ # also raise a RuntimeError.
+ old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_ERROR)
+ try:
+ self.assertRaises(RuntimeError,
+ gi._gi.flags_register_new_gtype_and_add,
+ GIMarshallingTests.NoTypeFlags.__info__)
+ finally:
+ GLib.log_set_always_fatal(old_mask)
class TestStructure(unittest.TestCase):
@@ -1269,14 +1668,14 @@ class TestStructure(unittest.TestCase):
struct = GIMarshallingTests.SimpleStruct()
self.assertTrue(isinstance(struct, GIMarshallingTests.SimpleStruct))
- self.assertEquals(0, struct.long_)
- self.assertEquals(0, struct.int8)
+ self.assertEqual(0, struct.long_)
+ self.assertEqual(0, struct.int8)
struct.long_ = 6
struct.int8 = 7
- self.assertEquals(6, struct.long_)
- self.assertEquals(7, struct.int8)
+ self.assertEqual(6, struct.long_)
+ self.assertEqual(7, struct.int8)
del struct
@@ -1286,20 +1685,20 @@ class TestStructure(unittest.TestCase):
self.assertTrue(isinstance(struct.simple_struct, GIMarshallingTests.SimpleStruct))
struct.simple_struct.long_ = 42
- self.assertEquals(42, struct.simple_struct.long_)
+ self.assertEqual(42, struct.simple_struct.long_)
del struct
def test_not_simple_struct(self):
struct = GIMarshallingTests.NotSimpleStruct()
- self.assertEquals(None, struct.pointer)
+ self.assertEqual(None, struct.pointer)
def test_simple_struct_return(self):
struct = GIMarshallingTests.simple_struct_returnv()
self.assertTrue(isinstance(struct, GIMarshallingTests.SimpleStruct))
- self.assertEquals(6, struct.long_)
- self.assertEquals(7, struct.int8)
+ self.assertEqual(6, struct.long_)
+ self.assertEqual(7, struct.int8)
del struct
@@ -1343,7 +1742,7 @@ class TestStructure(unittest.TestCase):
struct = GIMarshallingTests.pointer_struct_returnv()
self.assertTrue(isinstance(struct, GIMarshallingTests.PointerStruct))
- self.assertEquals(42, struct.long_)
+ self.assertEqual(42, struct.long_)
del struct
@@ -1361,22 +1760,29 @@ class TestStructure(unittest.TestCase):
struct = GIMarshallingTests.BoxedStruct()
self.assertTrue(isinstance(struct, GIMarshallingTests.BoxedStruct))
- self.assertEquals(0, struct.long_)
- self.assertEquals([], struct.g_strv)
+ self.assertEqual(0, struct.long_)
+ self.assertEqual(None, struct.string_)
+ self.assertEqual([], struct.g_strv)
del struct
def test_boxed_struct_new(self):
struct = GIMarshallingTests.BoxedStruct.new()
self.assertTrue(isinstance(struct, GIMarshallingTests.BoxedStruct))
+ self.assertEqual(struct.long_, 0)
+ self.assertEqual(struct.string_, None)
del struct
def test_boxed_struct_copy(self):
struct = GIMarshallingTests.BoxedStruct()
+ struct.long_ = 42
+ struct.string_ = 'hello'
new_struct = struct.copy()
self.assertTrue(isinstance(new_struct, GIMarshallingTests.BoxedStruct))
+ self.assertEqual(new_struct.long_, 42)
+ self.assertEqual(new_struct.string_, 'hello')
del new_struct
del struct
@@ -1385,8 +1791,9 @@ class TestStructure(unittest.TestCase):
struct = GIMarshallingTests.boxed_struct_returnv()
self.assertTrue(isinstance(struct, GIMarshallingTests.BoxedStruct))
- self.assertEquals(42, struct.long_)
- self.assertEquals(['0', '1', '2'], struct.g_strv)
+ self.assertEqual(42, struct.long_)
+ self.assertEqual('hello', struct.string_)
+ self.assertEqual(['0', '1', '2'], struct.g_strv)
del struct
@@ -1402,7 +1809,7 @@ class TestStructure(unittest.TestCase):
struct = GIMarshallingTests.boxed_struct_out()
self.assertTrue(isinstance(struct, GIMarshallingTests.BoxedStruct))
- self.assertEquals(42, struct.long_)
+ self.assertEqual(42, struct.long_)
del struct
@@ -1413,11 +1820,19 @@ class TestStructure(unittest.TestCase):
out_struct = GIMarshallingTests.boxed_struct_inout(in_struct)
self.assertTrue(isinstance(out_struct, GIMarshallingTests.BoxedStruct))
- self.assertEquals(0, out_struct.long_)
+ self.assertEqual(0, out_struct.long_)
del in_struct
del out_struct
+ def test_struct_field_assignment(self):
+ struct = GIMarshallingTests.BoxedStruct()
+
+ struct.long_ = 42
+ struct.string_ = 'hello'
+ self.assertEqual(struct.long_, 42)
+ self.assertEqual(struct.string_, 'hello')
+
def test_union(self):
union = GIMarshallingTests.Union()
@@ -1433,7 +1848,7 @@ class TestStructure(unittest.TestCase):
union = GIMarshallingTests.union_returnv()
self.assertTrue(isinstance(union, GIMarshallingTests.Union))
- self.assertEquals(42, union.long_)
+ self.assertEqual(42, union.long_)
del union
@@ -1463,25 +1878,25 @@ class TestGObject(unittest.TestCase):
object_ = GIMarshallingTests.Object()
self.assertTrue(isinstance(object_, GIMarshallingTests.Object))
- self.assertEquals(object_.__grefcount__, 1)
+ self.assertEqual(object_.__grefcount__, 1)
def test_object_new(self):
object_ = GIMarshallingTests.Object.new(42)
self.assertTrue(isinstance(object_, GIMarshallingTests.Object))
- self.assertEquals(object_.__grefcount__, 1)
+ self.assertEqual(object_.__grefcount__, 1)
def test_object_int(self):
- object_ = GIMarshallingTests.Object(int = 42)
- self.assertEquals(object_.int_, 42)
+ object_ = GIMarshallingTests.Object(int=42)
+ self.assertEqual(object_.int_, 42)
# FIXME: Don't work yet.
# object_.int_ = 0
-# self.assertEquals(object_.int_, 0)
+# self.assertEqual(object_.int_, 0)
def test_object_static_method(self):
GIMarshallingTests.Object.static_method()
def test_object_method(self):
- GIMarshallingTests.Object(int = 42).method()
+ GIMarshallingTests.Object(int=42).method()
self.assertRaises(TypeError, GIMarshallingTests.Object.method, GObject.GObject())
self.assertRaises(TypeError, GIMarshallingTests.Object.method)
@@ -1499,7 +1914,7 @@ class TestGObject(unittest.TestCase):
object_.static_method()
def test_sub_object_method(self):
- object_ = GIMarshallingTests.SubObject(int = 42)
+ object_ = GIMarshallingTests.SubObject(int=42)
object_.method()
def test_sub_object_sub_method(self):
@@ -1514,27 +1929,27 @@ class TestGObject(unittest.TestCase):
def test_sub_object_int(self):
object_ = GIMarshallingTests.SubObject()
- self.assertEquals(object_.int_, 0)
+ self.assertEqual(object_.int_, 0)
# FIXME: Don't work yet.
# object_.int_ = 42
-# self.assertEquals(object_.int_, 42)
+# self.assertEqual(object_.int_, 42)
def test_object_none_return(self):
object_ = GIMarshallingTests.Object.none_return()
self.assertTrue(isinstance(object_, GIMarshallingTests.Object))
- self.assertEquals(object_.__grefcount__, 2)
+ self.assertEqual(object_.__grefcount__, 2)
def test_object_full_return(self):
object_ = GIMarshallingTests.Object.full_return()
self.assertTrue(isinstance(object_, GIMarshallingTests.Object))
- self.assertEquals(object_.__grefcount__, 1)
+ self.assertEqual(object_.__grefcount__, 1)
def test_object_none_in(self):
- object_ = GIMarshallingTests.Object(int = 42)
+ object_ = GIMarshallingTests.Object(int=42)
GIMarshallingTests.Object.none_in(object_)
- self.assertEquals(object_.__grefcount__, 1)
+ self.assertEqual(object_.__grefcount__, 1)
- object_ = GIMarshallingTests.SubObject(int = 42)
+ object_ = GIMarshallingTests.SubObject(int=42)
GIMarshallingTests.Object.none_in(object_)
object_ = GObject.GObject()
@@ -1545,7 +1960,7 @@ class TestGObject(unittest.TestCase):
def test_object_none_out(self):
object_ = GIMarshallingTests.Object.none_out()
self.assertTrue(isinstance(object_, GIMarshallingTests.Object))
- self.assertEquals(object_.__grefcount__, 2)
+ self.assertEqual(object_.__grefcount__, 2)
new_object = GIMarshallingTests.Object.none_out()
self.assertTrue(new_object is object_)
@@ -1553,46 +1968,48 @@ class TestGObject(unittest.TestCase):
def test_object_full_out(self):
object_ = GIMarshallingTests.Object.full_out()
self.assertTrue(isinstance(object_, GIMarshallingTests.Object))
- self.assertEquals(object_.__grefcount__, 1)
+ self.assertEqual(object_.__grefcount__, 1)
def test_object_none_inout(self):
- object_ = GIMarshallingTests.Object(int = 42)
+ object_ = GIMarshallingTests.Object(int=42)
new_object = GIMarshallingTests.Object.none_inout(object_)
self.assertTrue(isinstance(new_object, GIMarshallingTests.Object))
self.assertFalse(object_ is new_object)
- self.assertEquals(object_.__grefcount__, 1)
- self.assertEquals(new_object.__grefcount__, 2)
+ self.assertEqual(object_.__grefcount__, 1)
+ self.assertEqual(new_object.__grefcount__, 2)
new_new_object = GIMarshallingTests.Object.none_inout(object_)
self.assertTrue(new_new_object is new_object)
- GIMarshallingTests.Object.none_inout(GIMarshallingTests.SubObject(int = 42))
+ GIMarshallingTests.Object.none_inout(GIMarshallingTests.SubObject(int=42))
def test_object_full_inout(self):
- object_ = GIMarshallingTests.Object(int = 42)
+ object_ = GIMarshallingTests.Object(int=42)
new_object = GIMarshallingTests.Object.full_inout(object_)
self.assertTrue(isinstance(new_object, GIMarshallingTests.Object))
self.assertFalse(object_ is new_object)
- self.assertEquals(object_.__grefcount__, 2)
- self.assertEquals(new_object.__grefcount__, 1)
+ self.assertEqual(object_.__grefcount__, 2)
+ self.assertEqual(new_object.__grefcount__, 1)
# FIXME: Doesn't actually return the same object.
# def test_object_inout_same(self):
# object_ = GIMarshallingTests.Object()
# new_object = GIMarshallingTests.object_full_inout(object_)
# self.assertTrue(object_ is new_object)
-# self.assertEquals(object_.__grefcount__, 1)
+# self.assertEqual(object_.__grefcount__, 1)
class TestPythonGObject(unittest.TestCase):
class Object(GIMarshallingTests.Object):
+ return_for_caller_allocated_out_parameter = 'test caller alloc return'
+
def __init__(self, int):
GIMarshallingTests.Object.__init__(self)
self.val = None
@@ -1607,10 +2024,37 @@ class TestPythonGObject(unittest.TestCase):
def do_method_int8_out(self):
return 42
+ def do_method_int8_arg_and_out_caller(self, arg):
+ return arg + 1
+
+ def do_method_int8_arg_and_out_callee(self, arg):
+ return arg + 1
+
+ def do_method_str_arg_out_ret(self, arg):
+ return (arg.upper(), len(arg))
+
def do_method_with_default_implementation(self, int8):
GIMarshallingTests.Object.do_method_with_default_implementation(self, int8)
self.props.int += int8
+ def do_vfunc_return_value_only(self):
+ return 4242
+
+ def do_vfunc_one_out_parameter(self):
+ return 42.42
+
+ def do_vfunc_multiple_out_parameters(self):
+ return (42.42, 3.14)
+
+ def do_vfunc_return_value_and_one_out_parameter(self):
+ return (5, 42)
+
+ def do_vfunc_return_value_and_multiple_out_parameters(self):
+ return (5, 42, 99)
+
+ def do_vfunc_caller_allocated_out_parameter(self):
+ return self.return_for_caller_allocated_out_parameter
+
class SubObject(GIMarshallingTests.SubObject):
def __init__(self, int):
GIMarshallingTests.SubObject.__init__(self)
@@ -1619,48 +2063,96 @@ class TestPythonGObject(unittest.TestCase):
def do_method_with_default_implementation(self, int8):
self.val = int8
+ def do_vfunc_return_value_only(self):
+ return 2121
+
+ class Interface3Impl(GObject.Object, GIMarshallingTests.Interface3):
+ def __init__(self):
+ GObject.Object.__init__(self)
+ self.variants = None
+ self.n_variants = None
+
+ def do_test_variant_array_in(self, variants, n_variants):
+ self.variants = variants
+ self.n_variants = n_variants
+
+ class ErrorObject(GIMarshallingTests.Object):
+ def do_vfunc_return_value_only(self):
+ raise ValueError('Return value should be 0')
+
def test_object(self):
self.assertTrue(issubclass(self.Object, GIMarshallingTests.Object))
- object_ = self.Object(int = 42)
+ object_ = self.Object(int=42)
self.assertTrue(isinstance(object_, self.Object))
def test_object_method(self):
- self.Object(int = 0).method()
+ self.Object(int=0).method()
def test_object_vfuncs(self):
- object_ = self.Object(int = 42)
+ object_ = self.Object(int=42)
object_.method_int8_in(84)
self.assertEqual(object_.val, 84)
self.assertEqual(object_.method_int8_out(), 42)
+ # can be dropped when bumping g-i dependencies to >= 1.35.2
+ if hasattr(object_, 'method_int8_arg_and_out_caller'):
+ self.assertEqual(object_.method_int8_arg_and_out_caller(42), 43)
+ self.assertEqual(object_.method_int8_arg_and_out_callee(42), 43)
+ self.assertEqual(object_.method_str_arg_out_ret('hello'), ('HELLO', 5))
+
object_.method_with_default_implementation(42)
self.assertEqual(object_.props.int, 84)
+ self.assertEqual(object_.vfunc_return_value_only(), 4242)
+ self.assertAlmostEqual(object_.vfunc_one_out_parameter(), 42.42, places=5)
+
+ (a, b) = object_.vfunc_multiple_out_parameters()
+ self.assertAlmostEqual(a, 42.42, places=5)
+ self.assertAlmostEqual(b, 3.14, places=5)
+
+ self.assertEqual(object_.vfunc_return_value_and_one_out_parameter(), (5, 42))
+ self.assertEqual(object_.vfunc_return_value_and_multiple_out_parameters(), (5, 42, 99))
+
+ self.assertEqual(object_.vfunc_caller_allocated_out_parameter(),
+ object_.return_for_caller_allocated_out_parameter)
+
class ObjectWithoutVFunc(GIMarshallingTests.Object):
def __init__(self, int):
GIMarshallingTests.Object.__init__(self)
- object_ = ObjectWithoutVFunc(int = 42)
+ object_ = ObjectWithoutVFunc(int=42)
object_.method_with_default_implementation(84)
self.assertEqual(object_.props.int, 84)
+ def test_vfunc_return_ref_count(self):
+ obj = self.Object(int=42)
+ ref_count = sys.getrefcount(obj.return_for_caller_allocated_out_parameter)
+ ret = obj.vfunc_caller_allocated_out_parameter()
+ gc.collect()
+
+ # Make sure the return and what the vfunc returned
+ # are equal but not the same object.
+ self.assertEqual(ret, obj.return_for_caller_allocated_out_parameter)
+ self.assertFalse(ret is obj.return_for_caller_allocated_out_parameter)
+ self.assertEqual(sys.getrefcount(obj.return_for_caller_allocated_out_parameter),
+ ref_count)
+
def test_subobject_parent_vfunc(self):
- object_ = self.SubObject(int = 81)
+ object_ = self.SubObject(int=81)
object_.method_with_default_implementation(87)
- self.assertEquals(object_.val, 87)
+ self.assertEqual(object_.val, 87)
+
+ def test_subobject_child_vfunc(self):
+ object_ = self.SubObject(int=1)
+ self.assertEqual(object_.vfunc_return_value_only(), 2121)
def test_dynamic_module(self):
- from gi.module import DynamicGObjectModule
- self.assertTrue(isinstance(GObject, DynamicGObjectModule))
- # compare the same enum from both the pygobject attrs and gi GObject attrs
- self.assertEquals(GObject.SIGNAL_ACTION, GObject.SignalFlags.ACTION)
- # compare a static gobject attr with a dynamic GObject attr
- import gi._gobject
- self.assertEquals(GObject.GObject, gi._gobject.GObject)
+ from gi.module import DynamicModule
+ self.assertTrue(isinstance(GObject, DynamicModule))
def test_subobject_non_vfunc_do_method(self):
- class PythonObjectWithNonVFuncDoMethod:
+ class PythonObjectWithNonVFuncDoMethod(object):
def do_not_a_vfunc(self):
return 5
@@ -1670,7 +2162,7 @@ class TestPythonGObject(unittest.TestCase):
return 13 + value
object_ = ObjectOverrideNonVFuncDoMethod()
- self.assertEquals(18, object_.do_not_a_vfunc())
+ self.assertEqual(18, object_.do_not_a_vfunc())
def test_native_function_not_set_in_subclass_dict(self):
# Previously, GI was setting virtual functions on the class as well
@@ -1696,25 +2188,69 @@ class TestPythonGObject(unittest.TestCase):
GIMarshallingTests.SubSubObject.do_method_deep_hierarchy(sub_sub_sub_object, 5)
self.assertEqual(sub_sub_sub_object.props.int, 5)
+ def test_interface3impl(self):
+ iface3 = self.Interface3Impl()
+ variants = [GLib.Variant('i', 27), GLib.Variant('s', 'Hello')]
+ iface3.test_variant_array_in(variants)
+ self.assertEqual(iface3.n_variants, 2)
+ self.assertEqual(iface3.variants[0].unpack(), 27)
+ self.assertEqual(iface3.variants[1].unpack(), 'Hello')
+
+ def test_python_subsubobject_vfunc(self):
+ class PySubObject(GIMarshallingTests.Object):
+ def __init__(self):
+ GIMarshallingTests.Object.__init__(self)
+ self.sub_method_int8_called = 0
+
+ def do_method_int8_in(self, int8):
+ self.sub_method_int8_called += 1
+
+ class PySubSubObject(PySubObject):
+ def __init__(self):
+ PySubObject.__init__(self)
+ self.subsub_method_int8_called = 0
+
+ def do_method_int8_in(self, int8):
+ self.subsub_method_int8_called += 1
+
+ so = PySubObject()
+ so.method_int8_in(1)
+ self.assertEqual(so.sub_method_int8_called, 1)
+
+ # it should call the method on the SubSub object only
+ sso = PySubSubObject()
+ sso.method_int8_in(1)
+ self.assertEqual(sso.subsub_method_int8_called, 1)
+ self.assertEqual(sso.sub_method_int8_called, 0)
+
+ def test_callback_in_vfunc(self):
+ class SubObject(GIMarshallingTests.Object):
+ def __init__(self):
+ GObject.GObject.__init__(self)
+ self.worked = False
+
+ def do_vfunc_with_callback(self, callback):
+ self.worked = callback(42) == 42
+
+ _object = SubObject()
+ _object.call_vfunc_with_callback()
+ self.assertTrue(_object.worked)
+ _object.worked = False
+ _object.call_vfunc_with_callback()
+ self.assertTrue(_object.worked)
+
+ def test_exception_in_vfunc_return_value(self):
+ obj = self.ErrorObject()
+ self.assertEqual(obj.vfunc_return_value_only(), 0)
+
class TestMultiOutputArgs(unittest.TestCase):
def test_int_out_out(self):
- self.assertEquals((6, 7), GIMarshallingTests.int_out_out())
+ self.assertEqual((6, 7), GIMarshallingTests.int_out_out())
def test_int_return_out(self):
- self.assertEquals((6, 7), GIMarshallingTests.int_return_out())
-
-class TestGErrorException(unittest.TestCase):
- def test_gerror_exception(self):
- self.assertRaises(GObject.GError, GIMarshallingTests.gerror)
- try:
- GIMarshallingTests.gerror()
- except Exception:
- etype, e = sys.exc_info()[:2]
- self.assertEquals(e.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
- self.assertEquals(e.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
- self.assertEquals(e.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+ self.assertEqual((6, 7), GIMarshallingTests.int_return_out())
# Interface
@@ -1734,7 +2270,7 @@ class TestInterfaces(unittest.TestCase):
def test_wrapper(self):
self.assertTrue(issubclass(GIMarshallingTests.Interface, GObject.GInterface))
- self.assertEquals(GIMarshallingTests.Interface.__gtype__.name, 'GIMarshallingTestsInterface')
+ self.assertEqual(GIMarshallingTests.Interface.__gtype__.name, 'GIMarshallingTestsInterface')
self.assertRaises(NotImplementedError, GIMarshallingTests.Interface)
def test_implementation(self):
@@ -1743,7 +2279,7 @@ class TestInterfaces(unittest.TestCase):
def test_int8_int(self):
GIMarshallingTests.test_interface_test_int8_in(self.instance, 42)
- self.assertEquals(self.instance.val, 42)
+ self.assertEqual(self.instance.val, 42)
def test_subclass(self):
class TestInterfaceImplA(self.TestInterfaceImpl):
@@ -1754,9 +2290,104 @@ class TestInterfaces(unittest.TestCase):
instance = TestInterfaceImplA()
GIMarshallingTests.test_interface_test_int8_in(instance, 42)
- self.assertEquals(instance.val, 42)
+ self.assertEqual(instance.val, 42)
+
+ def test_subclass_override(self):
+ class TestInterfaceImplD(TestInterfaces.TestInterfaceImpl):
+ val2 = None
+
+ def do_test_int8_in(self, int8):
+ self.val2 = int8
+
+ instance = TestInterfaceImplD()
+ self.assertEqual(instance.val, None)
+ self.assertEqual(instance.val2, None)
+
+ GIMarshallingTests.test_interface_test_int8_in(instance, 42)
+ self.assertEqual(instance.val, None)
+ self.assertEqual(instance.val2, 42)
+
+ def test_type_mismatch(self):
+ obj = GIMarshallingTests.Object()
+ # wrong type for first argument: interface
+ enum = Gio.File.new_for_path('.').enumerate_children(
+ '', Gio.FileQueryInfoFlags.NONE, None)
+ try:
+ enum.next_file(obj)
+ self.fail('call with wrong type argument unexpectedly succeeded')
+ except TypeError as e:
+ # should have argument name
+ self.assertTrue('cancellable' in str(e), e)
+ # should have expected type
+ self.assertTrue('xpected Gio.Cancellable' in str(e), e)
+ # should have actual type
+ self.assertTrue('GIMarshallingTests.Object' in str(e), e)
+
+ # wrong type for self argument: interface
+ try:
+ Gio.FileEnumerator.next_file(obj, None)
+ self.fail('call with wrong type argument unexpectedly succeeded')
+ except TypeError as e:
+ # should have argument name
+ self.assertTrue('self' in str(e), e)
+ # should have expected type
+ self.assertTrue('xpected Gio.FileEnumerator' in str(e), e)
+ # should have actual type
+ self.assertTrue('GIMarshallingTests.Object' in str(e), e)
+
+ # wrong type for first argument: GObject
+ var = GLib.Variant('s', 'mystring')
+ action = Gio.SimpleAction.new('foo', var.get_type())
+ try:
+ action.activate(obj)
+ self.fail('call with wrong type argument unexpectedly succeeded')
+ except TypeError as e:
+ # should have argument name
+ self.assertTrue('parameter' in str(e), e)
+ # should have expected type
+ self.assertTrue('xpected GLib.Variant' in str(e), e)
+ # should have actual type
+ self.assertTrue('GIMarshallingTests.Object' in str(e), e)
+
+ # wrong type for self argument: GObject
+ try:
+ Gio.SimpleAction.activate(obj, obj)
+ self.fail('call with wrong type argument unexpectedly succeeded')
+ except TypeError as e:
+ # should have argument name
+ self.assertTrue('self' in str(e), e)
+ # should have expected type
+ self.assertTrue('xpected Gio.Action' in str(e), e)
+ # should have actual type
+ self.assertTrue('GIMarshallingTests.Object' in str(e), e)
+
+
+class TestMRO(unittest.TestCase):
def test_mro(self):
+ # check that our own MRO calculation matches what we would expect
+ # from Python's own C3 calculations
+ class A(object):
+ pass
+
+ class B(A):
+ pass
+
+ class C(A):
+ pass
+
+ class D(B, C):
+ pass
+
+ class E(D, GIMarshallingTests.Object):
+ pass
+
+ expected = (E, D, B, C, A, GIMarshallingTests.Object,
+ GObject.Object, GObject.Object.__base__, gi._gobject.GObject,
+ object)
+ self.assertEqual(expected, E.__mro__)
+
+ def test_interface_collision(self):
# there was a problem with Python bailing out because of
# http://en.wikipedia.org/wiki/Diamond_problem with interfaces,
# which shouldn't really be a problem.
@@ -1768,10 +2399,27 @@ class TestInterfaces(unittest.TestCase):
TestInterfaceImpl):
pass
- class TestInterfaceImpl3(self.TestInterfaceImpl,
+ class TestInterfaceImpl3(TestInterfaceImpl,
GIMarshallingTests.Interface2):
pass
+ def test_old_style_mixin(self):
+ # Note: Old style classes don't exist in Python 3
+ class Mixin:
+ pass
+
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+
+ # Dynamically create a new gi based class with an old
+ # style mixin.
+ type('GIWithOldStyleMixin', (GIMarshallingTests.Object, Mixin), {})
+
+ if sys.version_info < (3, 0):
+ self.assertTrue(issubclass(warn[0].category, RuntimeWarning))
+ else:
+ self.assertEqual(len(warn), 0)
+
class TestInterfaceClash(unittest.TestCase):
@@ -1788,7 +2436,7 @@ class TestInterfaceClash(unittest.TestCase):
class TestOverrides(unittest.TestCase):
def test_constant(self):
- self.assertEquals(GIMarshallingTests.OVERRIDES_CONSTANT, 7)
+ self.assertEqual(GIMarshallingTests.OVERRIDES_CONSTANT, 7)
def test_struct(self):
# Test that the constructor has been overridden.
@@ -1797,7 +2445,7 @@ class TestOverrides(unittest.TestCase):
self.assertTrue(isinstance(struct, GIMarshallingTests.OverridesStruct))
# Test that the method has been overridden.
- self.assertEquals(6, struct.method())
+ self.assertEqual(6, struct.method())
del struct
@@ -1820,7 +2468,7 @@ class TestOverrides(unittest.TestCase):
self.assertTrue(isinstance(object_, GIMarshallingTests.OverridesObject))
# Test that the method has been overridden.
- self.assertEquals(6, object_.method())
+ self.assertEqual(6, object_.method())
# Test that the overrides wrapper has been registered.
object_ = GIMarshallingTests.OverridesObject.returnv()
@@ -1828,8 +2476,16 @@ class TestOverrides(unittest.TestCase):
self.assertTrue(isinstance(object_, GIMarshallingTests.OverridesObject))
def test_module_name(self):
- self.assertEquals(GIMarshallingTests.OverridesStruct.__module__, 'gi.overrides.GIMarshallingTests')
- self.assertEquals(GObject.InitiallyUnowned.__module__, 'gi.repository.GObject')
+ # overridden types
+ self.assertEqual(GIMarshallingTests.OverridesStruct.__module__, 'gi.overrides.GIMarshallingTests')
+ self.assertEqual(GIMarshallingTests.OverridesObject.__module__, 'gi.overrides.GIMarshallingTests')
+ self.assertEqual(GObject.Object.__module__, 'gi.overrides.GObject')
+
+ # not overridden
+ self.assertEqual(GIMarshallingTests.SubObject.__module__, 'gi.repository.GIMarshallingTests')
+ # FIXME: does not work with TEST_NAMES='test_thread test_gi.TestOverrides',
+ # it is importlib._bootstrap then
+ #self.assertEqual(GObject.InitiallyUnowned.__module__, 'gi.repository.GObject')
class TestDir(unittest.TestCase):
@@ -1857,49 +2513,74 @@ class TestDir(unittest.TestCase):
# self.assertTrue('DoNotImportDummyTests' in list)
-class TestGErrorArrayInCrash(unittest.TestCase):
- # Previously there was a bug in invoke, in which C arrays were unwrapped
- # from inside GArrays to be passed to the C function. But when a GError was
- # set, invoke would attempt to free the C array as if it were a GArray.
- # This crash is only for C arrays. It does not happen for C functions which
- # take in GArrays. See https://bugzilla.gnome.org/show_bug.cgi?id=642708
- def test_gerror_array_in_crash(self):
+class TestGError(unittest.TestCase):
+ def test_array_in_crash(self):
+ # Previously there was a bug in invoke, in which C arrays were unwrapped
+ # from inside GArrays to be passed to the C function. But when a GError was
+ # set, invoke would attempt to free the C array as if it were a GArray.
+ # This crash is only for C arrays. It does not happen for C functions which
+ # take in GArrays. See https://bugzilla.gnome.org/show_bug.cgi?id=642708
self.assertRaises(GObject.GError, GIMarshallingTests.gerror_array_in, [1, 2, 3])
-
-class TestGErrorOut(unittest.TestCase):
- # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
- def test_gerror_out(self):
+ def test_out(self):
+ # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
error, debug = GIMarshallingTests.gerror_out()
self.assertIsInstance(error, GObject.GError)
- self.assertEquals(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
- self.assertEquals(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
- self.assertEquals(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
- self.assertEquals(debug, GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE)
+ self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+ self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+ self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+ self.assertEqual(debug, GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE)
-
-class TestGErrorOutTransferNone(unittest.TestCase):
- # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
- def test_gerror_out_transfer_none(self):
+ def test_out_transfer_none(self):
+ # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
error, debug = GIMarshallingTests.gerror_out_transfer_none()
self.assertIsInstance(error, GObject.GError)
- self.assertEquals(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
- self.assertEquals(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
- self.assertEquals(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
- self.assertEquals(GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE, debug)
-
+ self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+ self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+ self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+ self.assertEqual(GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE, debug)
-class TestGErrorReturn(unittest.TestCase):
- # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
- def test_return_gerror(self):
+ def test_return(self):
+ # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
error = GIMarshallingTests.gerror_return()
self.assertIsInstance(error, GObject.GError)
- self.assertEquals(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
- self.assertEquals(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
- self.assertEquals(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+ self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+ self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+ self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+
+ def test_exception(self):
+ self.assertRaises(GObject.GError, GIMarshallingTests.gerror)
+ try:
+ GIMarshallingTests.gerror()
+ except Exception:
+ etype, e = sys.exc_info()[:2]
+ self.assertEqual(e.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+ self.assertEqual(e.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+ self.assertEqual(e.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+
+
+class TestParamSpec(unittest.TestCase):
+ # https://bugzilla.gnome.org/show_bug.cgi?id=682355
+ @unittest.expectedFailure
+ def test_param_spec_in_bool(self):
+ ps = GObject.param_spec_boolean('mybool', 'test-bool', 'boolblurb',
+ True, GObject.ParamFlags.READABLE)
+ GIMarshallingTests.param_spec_in_bool(ps)
+
+ def test_param_spec_return(self):
+ obj = GIMarshallingTests.param_spec_return()
+ self.assertEqual(obj.name, 'test-param')
+ self.assertEqual(obj.nick, 'test')
+ self.assertEqual(obj.value_type, GObject.TYPE_STRING)
+
+ def test_param_spec_out(self):
+ obj = GIMarshallingTests.param_spec_out()
+ self.assertEqual(obj.name, 'test-param')
+ self.assertEqual(obj.nick, 'test')
+ self.assertEqual(obj.value_type, GObject.TYPE_STRING)
class TestKeywordArgs(unittest.TestCase):
@@ -1907,13 +2588,13 @@ class TestKeywordArgs(unittest.TestCase):
def test_calling(self):
kw_func = GIMarshallingTests.int_three_in_three_out
- self.assertEquals(kw_func(1, 2, 3), (1, 2, 3))
- self.assertEquals(kw_func(**{'a':4, 'b':5, 'c':6}), (4, 5, 6))
- self.assertEquals(kw_func(1, **{'b':7, 'c':8}), (1, 7, 8))
- self.assertEquals(kw_func(1, 7, **{'c':8}), (1, 7, 8))
- self.assertEquals(kw_func(1, c=8, **{'b':7}), (1, 7, 8))
- self.assertEquals(kw_func(2, c=4, b=3), (2, 3, 4))
- self.assertEquals(kw_func(a=2, c=4, b=3), (2, 3, 4))
+ self.assertEqual(kw_func(1, 2, 3), (1, 2, 3))
+ self.assertEqual(kw_func(**{'a': 4, 'b': 5, 'c': 6}), (4, 5, 6))
+ self.assertEqual(kw_func(1, **{'b': 7, 'c': 8}), (1, 7, 8))
+ self.assertEqual(kw_func(1, 7, **{'c': 8}), (1, 7, 8))
+ self.assertEqual(kw_func(1, c=8, **{'b': 7}), (1, 7, 8))
+ self.assertEqual(kw_func(2, c=4, b=3), (2, 3, 4))
+ self.assertEqual(kw_func(a=2, c=4, b=3), (2, 3, 4))
def assertRaisesMessage(self, exception, message, func, *args, **kwargs):
try:
@@ -1939,7 +2620,7 @@ class TestKeywordArgs(unittest.TestCase):
self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 arguments (0 given)",
GIMarshallingTests.int_three_in_three_out, *(), **{})
self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 non-keyword arguments (0 given)",
- GIMarshallingTests.int_three_in_three_out, *(), **{'c':4})
+ GIMarshallingTests.int_three_in_three_out, *(), **{'c': 4})
# test too many args
self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 arguments (4 given)",
@@ -1972,54 +2653,300 @@ class TestPropertiesObject(unittest.TestCase):
self.obj.props.some_boolean = True
self.assertEqual(self.obj.props.some_boolean, True)
- @unittest.expectedFailure
+ obj = GIMarshallingTests.PropertiesObject(some_boolean=True)
+ self.assertEqual(obj.props.some_boolean, True)
+
def test_char(self):
- # gobject-introspection thinks it has a guint8 type tag, which is wrong
self.assertEqual(self.obj.props.some_char, 0)
self.obj.props.some_char = GObject.G_MAXINT8
self.assertEqual(self.obj.props.some_char, GObject.G_MAXINT8)
+ obj = GIMarshallingTests.PropertiesObject(some_char=-42)
+ self.assertEqual(obj.props.some_char, -42)
+
def test_uchar(self):
self.assertEqual(self.obj.props.some_uchar, 0)
self.obj.props.some_uchar = GObject.G_MAXUINT8
self.assertEqual(self.obj.props.some_uchar, GObject.G_MAXUINT8)
+ obj = GIMarshallingTests.PropertiesObject(some_uchar=42)
+ self.assertEqual(obj.props.some_uchar, 42)
+
def test_int(self):
self.assertEqual(self.obj.props.some_int, 0)
self.obj.props.some_int = GObject.G_MAXINT
self.assertEqual(self.obj.props.some_int, GObject.G_MAXINT)
+ obj = GIMarshallingTests.PropertiesObject(some_int=-42)
+ self.assertEqual(obj.props.some_int, -42)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_int', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_int', None)
+
+ self.assertEqual(obj.props.some_int, -42)
+
def test_uint(self):
self.assertEqual(self.obj.props.some_uint, 0)
self.obj.props.some_uint = GObject.G_MAXUINT
self.assertEqual(self.obj.props.some_uint, GObject.G_MAXUINT)
+ obj = GIMarshallingTests.PropertiesObject(some_uint=42)
+ self.assertEqual(obj.props.some_uint, 42)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_uint', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_uint', None)
+
+ self.assertEqual(obj.props.some_uint, 42)
+
def test_long(self):
self.assertEqual(self.obj.props.some_long, 0)
self.obj.props.some_long = GObject.G_MAXLONG
self.assertEqual(self.obj.props.some_long, GObject.G_MAXLONG)
+ obj = GIMarshallingTests.PropertiesObject(some_long=-42)
+ self.assertEqual(obj.props.some_long, -42)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_long', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_long', None)
+
+ self.assertEqual(obj.props.some_long, -42)
+
def test_ulong(self):
self.assertEqual(self.obj.props.some_ulong, 0)
self.obj.props.some_ulong = GObject.G_MAXULONG
self.assertEqual(self.obj.props.some_ulong, GObject.G_MAXULONG)
+ obj = GIMarshallingTests.PropertiesObject(some_ulong=42)
+ self.assertEqual(obj.props.some_ulong, 42)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_ulong', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_ulong', None)
+
+ self.assertEqual(obj.props.some_ulong, 42)
+
def test_int64(self):
self.assertEqual(self.obj.props.some_int64, 0)
self.obj.props.some_int64 = GObject.G_MAXINT64
self.assertEqual(self.obj.props.some_int64, GObject.G_MAXINT64)
+ obj = GIMarshallingTests.PropertiesObject(some_int64=-4200000000000000)
+ self.assertEqual(obj.props.some_int64, -4200000000000000)
+
def test_uint64(self):
self.assertEqual(self.obj.props.some_uint64, 0)
self.obj.props.some_uint64 = GObject.G_MAXUINT64
self.assertEqual(self.obj.props.some_uint64, GObject.G_MAXUINT64)
+ obj = GIMarshallingTests.PropertiesObject(some_uint64=4200000000000000)
+ self.assertEqual(obj.props.some_uint64, 4200000000000000)
+
def test_float(self):
self.assertEqual(self.obj.props.some_float, 0)
self.obj.props.some_float = GObject.G_MAXFLOAT
self.assertEqual(self.obj.props.some_float, GObject.G_MAXFLOAT)
+ obj = GIMarshallingTests.PropertiesObject(some_float=42.42)
+ self.assertAlmostEqual(obj.props.some_float, 42.42, 4)
+
+ obj = GIMarshallingTests.PropertiesObject(some_float=42)
+ self.assertAlmostEqual(obj.props.some_float, 42.0, 4)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_float', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_float', None)
+
+ self.assertAlmostEqual(obj.props.some_float, 42.0, 4)
+
def test_double(self):
self.assertEqual(self.obj.props.some_double, 0)
self.obj.props.some_double = GObject.G_MAXDOUBLE
self.assertEqual(self.obj.props.some_double, GObject.G_MAXDOUBLE)
+
+ obj = GIMarshallingTests.PropertiesObject(some_double=42.42)
+ self.assertAlmostEqual(obj.props.some_double, 42.42)
+
+ obj = GIMarshallingTests.PropertiesObject(some_double=42)
+ self.assertAlmostEqual(obj.props.some_double, 42.0)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_double', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_double', None)
+
+ self.assertAlmostEqual(obj.props.some_double, 42.0)
+
+ def test_strv(self):
+ self.assertEqual(self.obj.props.some_strv, [])
+ self.obj.props.some_strv = ['hello', 'world']
+ self.assertEqual(self.obj.props.some_strv, ['hello', 'world'])
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', 1)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', [1, 2])
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', ['foo', 1])
+
+ self.assertEqual(self.obj.props.some_strv, ['hello', 'world'])
+
+ obj = GIMarshallingTests.PropertiesObject(some_strv=['hello', 'world'])
+ self.assertEqual(obj.props.some_strv, ['hello', 'world'])
+
+ def test_boxed_struct(self):
+ self.assertEqual(self.obj.props.some_boxed_struct, None)
+
+ class GStrv(list):
+ __gtype__ = GObject.TYPE_STRV
+
+ struct1 = GIMarshallingTests.BoxedStruct()
+ struct1.long_ = 1
+
+ self.obj.props.some_boxed_struct = struct1
+ self.assertEqual(self.obj.props.some_boxed_struct.long_, 1)
+ self.assertEqual(self.obj.some_boxed_struct.long_, 1)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_struct', 1)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_struct', 'foo')
+
+ obj = GIMarshallingTests.PropertiesObject(some_boxed_struct=struct1)
+ self.assertEqual(obj.props.some_boxed_struct.long_, 1)
+
+ def test_boxed_glist(self):
+ self.assertEqual(self.obj.props.some_boxed_glist, [])
+
+ l = [GObject.G_MININT, 42, GObject.G_MAXINT]
+ self.obj.props.some_boxed_glist = l
+ self.assertEqual(self.obj.props.some_boxed_glist, l)
+ self.obj.props.some_boxed_glist = []
+ self.assertEqual(self.obj.props.some_boxed_glist, [])
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_glist', 1)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_glist', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_glist', ['a'])
+
+ @unittest.expectedFailure
+ def test_boxed_glist_ctor(self):
+ l = [GObject.G_MININT, 42, GObject.G_MAXINT]
+ obj = GIMarshallingTests.PropertiesObject(some_boxed_glist=l)
+ self.assertEqual(obj.props.some_boxed_glist, l)
+
+ def test_variant(self):
+ self.assertEqual(self.obj.props.some_variant, None)
+
+ self.obj.props.some_variant = GLib.Variant('o', '/myobj')
+ self.assertEqual(self.obj.props.some_variant.get_type_string(), 'o')
+ self.assertEqual(self.obj.props.some_variant.print_(False), "'/myobj'")
+
+ self.obj.props.some_variant = None
+ self.assertEqual(self.obj.props.some_variant, None)
+
+ obj = GIMarshallingTests.PropertiesObject(some_variant=GLib.Variant('b', True))
+ self.assertEqual(obj.props.some_variant.get_type_string(), 'b')
+ self.assertEqual(obj.props.some_variant.get_boolean(), True)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_variant', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_variant', 23)
+
+ self.assertEqual(obj.props.some_variant.get_type_string(), 'b')
+ self.assertEqual(obj.props.some_variant.get_boolean(), True)
+
+ def test_setting_several_properties(self):
+ obj = GIMarshallingTests.PropertiesObject()
+ obj.set_properties(some_uchar=54, some_int=42)
+ self.assertEqual(42, obj.props.some_int)
+ self.assertEqual(54, obj.props.some_uchar)
+
+
+class TestKeywords(unittest.TestCase):
+ def test_method(self):
+ # g_variant_print()
+ v = GLib.Variant('i', 1)
+ self.assertEqual(v.print_(False), '1')
+
+ def test_function(self):
+ # g_thread_yield()
+ self.assertEqual(GLib.Thread.yield_(), None)
+
+ def test_struct_method(self):
+ # g_timer_continue()
+ # we cannot currently instantiate GLib.Timer objects, so just ensure
+ # the method exists
+ self.assertTrue(callable(GLib.Timer.continue_))
+
+ def test_uppercase(self):
+ self.assertEqual(GLib.IOCondition.IN.value_nicks, ['in'])
+
+
+class TestModule(unittest.TestCase):
+ def test_path(self):
+ self.assertTrue(GIMarshallingTests.__path__.endswith('GIMarshallingTests-1.0.typelib'),
+ GIMarshallingTests.__path__)
+
+ def test_str(self):
+ self.assertTrue("'GIMarshallingTests' from '" in str(GIMarshallingTests),
+ str(GIMarshallingTests))
+
+ def test_dir(self):
+ _dir = dir(GIMarshallingTests)
+ self.assertGreater(len(_dir), 10)
+
+ self.assertTrue('SimpleStruct' in _dir)
+ self.assertTrue('Interface2' in _dir)
+ self.assertTrue('CONSTANT_GERROR_CODE' in _dir)
+ self.assertTrue('array_zero_terminated_inout' in _dir)
+
+ # assert that dir() does not contain garbage
+ for item_name in _dir:
+ item = getattr(GIMarshallingTests, item_name)
+ self.assertTrue(hasattr(item, '__class__'))
+
+ def test_help(self):
+ orig_stdout = sys.stdout
+ try:
+ if sys.version_info < (3, 0):
+ sys.stdout = BytesIO()
+ else:
+ sys.stdout = StringIO()
+ help(GIMarshallingTests)
+ output = sys.stdout.getvalue()
+ finally:
+ sys.stdout = orig_stdout
+
+ self.assertTrue('SimpleStruct' in output, output)
+ self.assertTrue('Interface2' in output, output)
+ self.assertTrue('method_array_inout' in output, output)
+
+
+class TestProjectVersion(unittest.TestCase):
+ def test_version_str(self):
+ self.assertGreater(gi.__version__, "3.")
+
+ def test_version_info(self):
+ self.assertEqual(len(gi.version_info), 3)
+ self.assertGreaterEqual(gi.version_info, (3, 3, 5))
+
+ def test_check_version(self):
+ self.assertRaises(ValueError, gi.check_version, (99, 0, 0))
+ self.assertRaises(ValueError, gi.check_version, "99.0.0")
+ gi.check_version((3, 3, 5))
+ gi.check_version("3.3.5")
+
+
+class TestObjectInfo(unittest.TestCase):
+ def test_get_abstract_with_abstract(self):
+ repo = gi.gi.Repository.get_default()
+ info = repo.find_by_name('GObject', 'TypeModule')
+ self.assertTrue(info.get_abstract())
+
+ def test_get_abstract_with_concrete(self):
+ repo = gi.gi.Repository.get_default()
+ info = repo.find_by_name('GObject', 'Object')
+ self.assertFalse(info.get_abstract())
+
+ def test_get_class_struct(self):
+ self.assertEqual(GObject.Object.__info__.get_class_struct(),
+ GObject.ObjectClass.__info__)
+
+
+class TestDeprecation(unittest.TestCase):
+ def test_method(self):
+ d = GLib.Date.new()
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ d.set_time(1)
+ self.assertTrue(issubclass(warn[0].category, DeprecationWarning))
diff --git a/tests/test_gio.py b/tests/test_gio.py
new file mode 100644
index 0000000..57ab013
--- /dev/null
+++ b/tests/test_gio.py
@@ -0,0 +1,203 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+
+import gi.overrides
+from gi.repository import GLib, Gio
+
+
+class TestGio(unittest.TestCase):
+ def test_file_enumerator(self):
+ self.assertEqual(Gio.FileEnumerator, gi.overrides.Gio.FileEnumerator)
+ f = Gio.file_new_for_path("./")
+
+ iter_info = []
+ for info in f.enumerate_children("standard::*", 0, None):
+ iter_info.append(info.get_name())
+
+ next_info = []
+ enumerator = f.enumerate_children("standard::*", 0, None)
+ while True:
+ info = enumerator.next_file(None)
+ if info is None:
+ break
+ next_info.append(info.get_name())
+
+ self.assertEqual(iter_info, next_info)
+
+ def test_menu_item(self):
+ menu = Gio.Menu()
+ item = Gio.MenuItem()
+ item.set_attribute([("label", "s", "Test"),
+ ("action", "s", "app.test")])
+ menu.append_item(item)
+ value = menu.get_item_attribute_value(0, "label", GLib.VariantType.new("s"))
+ self.assertEqual("Test", value.unpack())
+ value = menu.get_item_attribute_value(0, "action", GLib.VariantType.new("s"))
+ self.assertEqual("app.test", value.unpack())
+
+
+class TestGSettings(unittest.TestCase):
+ def setUp(self):
+ self.settings = Gio.Settings('org.gnome.test')
+ # we change the values in the tests, so set them to predictable start
+ # value
+ self.settings.reset('test-string')
+ self.settings.reset('test-array')
+ self.settings.reset('test-boolean')
+ self.settings.reset('test-enum')
+
+ def test_native(self):
+ self.assertTrue('test-array' in self.settings.list_keys())
+
+ # get various types
+ v = self.settings.get_value('test-boolean')
+ self.assertEqual(v.get_boolean(), True)
+ self.assertEqual(self.settings.get_boolean('test-boolean'), True)
+
+ v = self.settings.get_value('test-string')
+ self.assertEqual(v.get_string(), 'Hello')
+ self.assertEqual(self.settings.get_string('test-string'), 'Hello')
+
+ v = self.settings.get_value('test-array')
+ self.assertEqual(v.unpack(), [1, 2])
+
+ v = self.settings.get_value('test-tuple')
+ self.assertEqual(v.unpack(), (1, 2))
+
+ # set a value
+ self.settings.set_string('test-string', 'World')
+ self.assertEqual(self.settings.get_string('test-string'), 'World')
+
+ self.settings.set_value('test-string', GLib.Variant('s', 'Goodbye'))
+ self.assertEqual(self.settings.get_string('test-string'), 'Goodbye')
+
+ def test_constructor(self):
+ # default constructor uses path from schema
+ self.assertEqual(self.settings.get_property('path'), '/tests/')
+
+ # optional constructor arguments
+ with_path = Gio.Settings('org.gnome.nopathtest', path='/mypath/')
+ self.assertEqual(with_path.get_property('path'), '/mypath/')
+ self.assertEqual(with_path['np-int'], 42)
+
+ def test_dictionary_api(self):
+ self.assertEqual(len(self.settings), 5)
+ self.assertTrue('test-array' in self.settings)
+ self.assertTrue('test-array' in self.settings.keys())
+ self.assertFalse('nonexisting' in self.settings)
+ self.assertFalse(4 in self.settings)
+ self.assertEqual(bool(self.settings), True)
+
+ def test_get(self):
+ self.assertEqual(self.settings['test-boolean'], True)
+ self.assertEqual(self.settings['test-string'], 'Hello')
+ self.assertEqual(self.settings['test-enum'], 'banana')
+ self.assertEqual(self.settings['test-array'], [1, 2])
+ self.assertEqual(self.settings['test-tuple'], (1, 2))
+
+ self.assertRaises(KeyError, self.settings.__getitem__, 'unknown')
+ self.assertRaises(KeyError, self.settings.__getitem__, 2)
+
+ def test_set(self):
+ self.settings['test-boolean'] = False
+ self.assertEqual(self.settings['test-boolean'], False)
+ self.settings['test-string'] = 'Goodbye'
+ self.assertEqual(self.settings['test-string'], 'Goodbye')
+ self.settings['test-array'] = [3, 4, 5]
+ self.assertEqual(self.settings['test-array'], [3, 4, 5])
+ self.settings['test-enum'] = 'pear'
+ self.assertEqual(self.settings['test-enum'], 'pear')
+
+ self.assertRaises(TypeError, self.settings.__setitem__, 'test-string', 1)
+ self.assertRaises(ValueError, self.settings.__setitem__, 'test-enum', 'plum')
+ self.assertRaises(KeyError, self.settings.__setitem__, 'unknown', 'moo')
+
+ def test_empty(self):
+ empty = Gio.Settings('org.gnome.empty', path='/tests/')
+ self.assertEqual(len(empty), 0)
+ self.assertEqual(bool(empty), True)
+ self.assertEqual(empty.keys(), [])
+
+ def test_change_event(self):
+ changed_log = []
+ change_event_log = []
+
+ def on_changed(settings, key):
+ changed_log.append((settings, key))
+
+ def on_change_event(settings, keys, n_keys):
+ change_event_log.append((settings, keys, n_keys))
+
+ self.settings.connect('changed', on_changed)
+ self.settings.connect('change-event', on_change_event)
+ self.settings['test-string'] = 'Moo'
+ self.assertEqual(changed_log, [(self.settings, 'test-string')])
+ self.assertEqual(change_event_log, [(self.settings,
+ [GLib.quark_from_static_string('test-string')],
+ 1)])
+
+
+class TestGFile(unittest.TestCase):
+ def setUp(self):
+ self.file, self.io_stream = Gio.File.new_tmp('TestGFile.XXXXXX')
+
+ def tearDown(self):
+ try:
+ self.file.delete(None)
+ # test_delete and test_delete_async already remove it
+ except GLib.GError:
+ pass
+
+ def test_replace_contents(self):
+ content = b'hello\0world\x7F!'
+ succ, etag = self.file.replace_contents(content, None, False,
+ Gio.FileCreateFlags.NONE, None)
+ new_succ, new_content, new_etag = self.file.load_contents(None)
+
+ self.assertTrue(succ)
+ self.assertTrue(new_succ)
+ self.assertEqual(etag, new_etag)
+ self.assertEqual(content, new_content)
+
+ # https://bugzilla.gnome.org/show_bug.cgi?id=690525
+ def disabled_test_replace_contents_async(self):
+ content = b''.join(bytes(chr(i), 'utf-8') for i in range(128))
+
+ def callback(f, result, d):
+ # Quit so in case of failed assertations loop doesn't keep running.
+ main_loop.quit()
+ succ, etag = self.file.replace_contents_finish(result)
+ new_succ, new_content, new_etag = self.file.load_contents(None)
+ d['succ'], d['etag'] = self.file.replace_contents_finish(result)
+ load = self.file.load_contents(None)
+ d['new_succ'], d['new_content'], d['new_etag'] = load
+
+ data = {}
+ self.file.replace_contents_async(content, None, False,
+ Gio.FileCreateFlags.NONE, None,
+ callback, data)
+ main_loop = GLib.MainLoop()
+ main_loop.run()
+ self.assertTrue(data['succ'])
+ self.assertTrue(data['new_succ'])
+ self.assertEqual(data['etag'], data['new_etag'])
+ self.assertEqual(content, data['new_content'])
+
+ def test_tmp_exists(self):
+ # A simple test to check if Gio.File.new_tmp is working correctly.
+ self.assertTrue(self.file.query_exists(None))
+
+ def test_delete(self):
+ self.file.delete(None)
+ self.assertFalse(self.file.query_exists(None))
+
+ def test_delete_async(self):
+ def callback(f, result, data):
+ main_loop.quit()
+
+ self.file.delete_async(0, None, callback, None)
+ main_loop = GLib.MainLoop()
+ main_loop.run()
+ self.assertFalse(self.file.query_exists(None))
diff --git a/tests/test_glib.py b/tests/test_glib.py
new file mode 100644
index 0000000..3cde168
--- /dev/null
+++ b/tests/test_glib.py
@@ -0,0 +1,206 @@
+# -*- Mode: Python -*-
+# encoding: UTF-8
+
+import unittest
+import os.path
+import warnings
+import subprocess
+
+from gi.repository import GLib
+from gi import PyGIDeprecationWarning
+
+from compathelper import _unicode, _bytes
+
+
+class TestGLib(unittest.TestCase):
+ def test_find_program_in_path(self):
+ bash_path = GLib.find_program_in_path('bash')
+ self.assertTrue(bash_path.endswith('/bash'))
+ self.assertTrue(os.path.exists(bash_path))
+
+ self.assertEqual(GLib.find_program_in_path('non existing'), None)
+
+ def test_markup_escape_text(self):
+ self.assertEqual(GLib.markup_escape_text(_unicode('a&bä')), 'a&amp;bä')
+ self.assertEqual(GLib.markup_escape_text(_bytes('a&b\x05')), 'a&amp;b&#x5;')
+
+ # with explicit length argument
+ self.assertEqual(GLib.markup_escape_text(_bytes('a\x05\x01\x02'), 2), 'a&#x5;')
+
+ def test_progname(self):
+ GLib.set_prgname('moo')
+ self.assertEqual(GLib.get_prgname(), 'moo')
+
+ def test_appname(self):
+ GLib.set_application_name('moo')
+ self.assertEqual(GLib.get_application_name(), 'moo')
+
+ def test_xdg_dirs(self):
+ d = GLib.get_user_data_dir()
+ self.assertTrue('/' in d, d)
+ d = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)
+ self.assertTrue('/' in d, d)
+ # also works with backwards compatible enum names
+ self.assertEqual(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC),
+ GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC))
+
+ for d in GLib.get_system_config_dirs():
+ self.assertTrue('/' in d, d)
+ for d in GLib.get_system_data_dirs():
+ self.assertTrue(isinstance(d, str), d)
+
+ def test_main_depth(self):
+ self.assertEqual(GLib.main_depth(), 0)
+
+ def test_filenames(self):
+ self.assertEqual(GLib.filename_display_name('foo'), 'foo')
+ self.assertEqual(GLib.filename_display_basename('bar/foo'), 'foo')
+
+ # this is locale dependent, so we cannot completely verify the result
+ res = GLib.filename_from_utf8(_unicode('aäb'))
+ self.assertTrue(isinstance(res, bytes))
+ self.assertGreaterEqual(len(res), 3)
+
+ # with explicit length argument
+ self.assertEqual(GLib.filename_from_utf8(_unicode('aäb'), 1), b'a')
+
+ def test_uri_extract(self):
+ res = GLib.uri_list_extract_uris('''# some comment
+http://example.com
+https://my.org/q?x=1&y=2
+ http://gnome.org/new''')
+ self.assertEqual(res, ['http://example.com',
+ 'https://my.org/q?x=1&y=2',
+ 'http://gnome.org/new'])
+
+ def test_current_time(self):
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ tm = GLib.get_current_time()
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ self.assertTrue(isinstance(tm, float))
+ self.assertGreater(tm, 1350000000.0)
+
+ def test_main_loop(self):
+ # note we do not test run() here, as we use this in countless other
+ # tests
+ ml = GLib.MainLoop()
+ self.assertFalse(ml.is_running())
+
+ context = ml.get_context()
+ self.assertEqual(context, GLib.MainContext.default())
+ self.assertTrue(context.is_owner() in [True, False])
+ self.assertTrue(context.pending() in [True, False])
+ self.assertFalse(context.iteration(False))
+
+ def test_main_loop_with_context(self):
+ context = GLib.MainContext()
+ ml = GLib.MainLoop(context)
+ self.assertFalse(ml.is_running())
+ self.assertEqual(ml.get_context(), context)
+
+ def test_main_context(self):
+ # constructor
+ context = GLib.MainContext()
+ self.assertTrue(context.is_owner() in [True, False])
+ self.assertFalse(context.pending())
+ self.assertFalse(context.iteration(False))
+
+ # GLib API
+ context = GLib.MainContext.default()
+ self.assertTrue(context.is_owner() in [True, False])
+ self.assertTrue(context.pending() in [True, False])
+ self.assertTrue(context.iteration(False) in [True, False])
+
+ # backwards compatible API
+ context = GLib.main_context_default()
+ self.assertTrue(context.is_owner() in [True, False])
+ self.assertTrue(context.pending() in [True, False])
+ self.assertTrue(context.iteration(False) in [True, False])
+
+ def test_io_add_watch_no_data(self):
+ (r, w) = os.pipe()
+ call_data = []
+
+ def cb(fd, condition):
+ call_data.append((fd, condition, os.read(fd, 1)))
+ return True
+
+ # io_add_watch() takes an IOChannel, calling with an fd is deprecated
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ GLib.io_add_watch(r, GLib.IOCondition.IN, cb)
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ ml = GLib.MainLoop()
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a'),
+ (r, GLib.IOCondition.IN, b'b')])
+
+ def test_io_add_watch_with_data(self):
+ (r, w) = os.pipe()
+ call_data = []
+
+ def cb(fd, condition, data):
+ call_data.append((fd, condition, os.read(fd, 1), data))
+ return True
+
+ # io_add_watch() takes an IOChannel, calling with an fd is deprecated
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ GLib.io_add_watch(r, GLib.IOCondition.IN, cb, 'moo')
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ ml = GLib.MainLoop()
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a', 'moo'),
+ (r, GLib.IOCondition.IN, b'b', 'moo')])
+
+ def test_io_add_watch_pyfile(self):
+ call_data = []
+
+ cmd = subprocess.Popen('sleep 0.1; echo hello; sleep 0.2; echo world',
+ shell=True, stdout=subprocess.PIPE)
+
+ def cb(file, condition):
+ call_data.append((file, condition, file.readline()))
+ if len(call_data) == 2:
+ # avoid having to wait for the full timeout
+ ml.quit()
+ return True
+
+ # io_add_watch() takes an IOChannel, calling with a Python file is deprecated
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ GLib.io_add_watch(cmd.stdout, GLib.IOCondition.IN, cb)
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ ml = GLib.MainLoop()
+ GLib.timeout_add(2000, ml.quit)
+ ml.run()
+
+ cmd.wait()
+
+ self.assertEqual(call_data, [(cmd.stdout, GLib.IOCondition.IN, b'hello\n'),
+ (cmd.stdout, GLib.IOCondition.IN, b'world\n')])
+
+ def test_glib_version(self):
+ (major, minor, micro) = GLib.glib_version
+ self.assertGreaterEqual(major, 2)
+ self.assertGreaterEqual(minor, 0)
+ self.assertGreaterEqual(micro, 0)
+
+ def test_pyglib_version(self):
+ (major, minor, micro) = GLib.pyglib_version
+ self.assertGreaterEqual(major, 3)
+ self.assertGreaterEqual(minor, 0)
+ self.assertGreaterEqual(micro, 0)
diff --git a/tests/test_gobject.py b/tests/test_gobject.py
index eef9cf6..57d3822 100644
--- a/tests/test_gobject.py
+++ b/tests/test_gobject.py
@@ -1,51 +1,107 @@
# -*- Mode: Python -*-
+import sys
+import gc
import unittest
+import warnings
+
+from gi.repository import GObject, GLib
+from gi import PyGIDeprecationWarning
+from gi.module import get_introspection_module
+from gi._gobject import _gobject
-from gi.repository import GObject
-import sys
import testhelper
class TestGObjectAPI(unittest.TestCase):
- def testGObjectModule(self):
- obj = GObject.GObject()
+ def test_gobject_inheritance(self):
+ # GObject.Object is a class hierarchy as follows:
+ # overrides.Object -> introspection.Object -> static.GObject
+ GIObjectModule = get_introspection_module('GObject')
+ self.assertTrue(issubclass(GObject.Object, GIObjectModule.Object))
+ self.assertTrue(issubclass(GIObjectModule.Object, _gobject.GObject))
+
+ self.assertEqual(_gobject.GObject.__gtype__, GObject.TYPE_OBJECT)
+ self.assertEqual(GIObjectModule.Object.__gtype__, GObject.TYPE_OBJECT)
+ self.assertEqual(GObject.Object.__gtype__, GObject.TYPE_OBJECT)
+
+ # The pytype wrapper should hold the outer most Object class from overrides.
+ self.assertEqual(GObject.TYPE_OBJECT.pytype, GObject.Object)
+
+ def test_gobject_unsupported_overrides(self):
+ obj = GObject.Object()
+
+ with self.assertRaisesRegex(RuntimeError, 'Data access methods are unsupported.*'):
+ obj.get_data()
+
+ with self.assertRaisesRegex(RuntimeError, 'This method is currently unsupported.*'):
+ obj.force_floating()
+
+ def test_compat_api(self):
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+ # GObject formerly exposed a lot of GLib's functions
+ self.assertEqual(GObject.markup_escape_text('foo'), 'foo')
+
+ ml = GObject.MainLoop()
+ self.assertFalse(ml.is_running())
- self.assertEquals(obj.__module__,
- 'gi._gobject._gobject')
+ context = GObject.main_context_default()
+ self.assertTrue(context.pending() in [False, True])
+
+ context = GObject.MainContext()
+ self.assertFalse(context.pending())
+
+ self.assertTrue(issubclass(w[0].category, PyGIDeprecationWarning))
+ self.assertTrue('GLib.markup_escape_text' in str(w[0]), str(w[0]))
+
+ self.assertLess(GObject.PRIORITY_HIGH, GObject.PRIORITY_DEFAULT)
+
+ def test_min_max_int(self):
+ self.assertEqual(GObject.G_MAXINT16, 2 ** 15 - 1)
+ self.assertEqual(GObject.G_MININT16, -2 ** 15)
+ self.assertEqual(GObject.G_MAXUINT16, 2 ** 16 - 1)
+
+ self.assertEqual(GObject.G_MAXINT32, 2 ** 31 - 1)
+ self.assertEqual(GObject.G_MININT32, -2 ** 31)
+ self.assertEqual(GObject.G_MAXUINT32, 2 ** 32 - 1)
+
+ self.assertEqual(GObject.G_MAXINT64, 2 ** 63 - 1)
+ self.assertEqual(GObject.G_MININT64, -2 ** 63)
+ self.assertEqual(GObject.G_MAXUINT64, 2 ** 64 - 1)
class TestReferenceCounting(unittest.TestCase):
- def testRegularObject(self):
+ def test_regular_object(self):
obj = GObject.GObject()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
obj = GObject.new(GObject.GObject)
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testFloating(self):
+ def test_floating(self):
obj = testhelper.Floating()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
obj = GObject.new(testhelper.Floating)
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testOwnedByLibrary(self):
+ def test_owned_by_library(self):
# Upon creation, the refcount of the object should be 2:
# - someone already has a reference on the new object.
# - the python wrapper should hold its own reference.
obj = testhelper.OwnedByLibrary()
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We ask the library to release its reference, so the only
# remaining ref should be our wrapper's. Once the wrapper
# will run out of scope, the object will get finalized.
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testOwnedByLibraryOutOfScope(self):
+ def test_owned_by_library_out_of_scope(self):
obj = testhelper.OwnedByLibrary()
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We are manually taking the object out of scope. This means
# that our wrapper has been freed, and its reference dropped. We
@@ -56,27 +112,27 @@ class TestReferenceCounting(unittest.TestCase):
# When we get the object back from the lib, the wrapper is
# re-created, so our refcount will be 2 once again.
obj = testhelper.owned_by_library_get_instance_list()[0]
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testOwnedByLibraryUsingGObjectNew(self):
+ def test_owned_by_library_using_gobject_new(self):
# Upon creation, the refcount of the object should be 2:
# - someone already has a reference on the new object.
# - the python wrapper should hold its own reference.
obj = GObject.new(testhelper.OwnedByLibrary)
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We ask the library to release its reference, so the only
# remaining ref should be our wrapper's. Once the wrapper
# will run out of scope, the object will get finalized.
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testOwnedByLibraryOutOfScopeUsingGobjectNew(self):
+ def test_owned_by_library_out_of_scope_using_gobject_new(self):
obj = GObject.new(testhelper.OwnedByLibrary)
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We are manually taking the object out of scope. This means
# that our wrapper has been freed, and its reference dropped. We
@@ -87,27 +143,27 @@ class TestReferenceCounting(unittest.TestCase):
# When we get the object back from the lib, the wrapper is
# re-created, so our refcount will be 2 once again.
obj = testhelper.owned_by_library_get_instance_list()[0]
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testFloatingAndSunk(self):
+ def test_floating_and_sunk(self):
# Upon creation, the refcount of the object should be 2:
# - someone already has a reference on the new object.
# - the python wrapper should hold its own reference.
obj = testhelper.FloatingAndSunk()
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We ask the library to release its reference, so the only
# remaining ref should be our wrapper's. Once the wrapper
# will run out of scope, the object will get finalized.
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testFloatingAndSunkOutOfScope(self):
+ def test_floating_and_sunk_out_of_scope(self):
obj = testhelper.FloatingAndSunk()
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We are manually taking the object out of scope. This means
# that our wrapper has been freed, and its reference dropped. We
@@ -118,28 +174,27 @@ class TestReferenceCounting(unittest.TestCase):
# When we get the object back from the lib, the wrapper is
# re-created, so our refcount will be 2 once again.
obj = testhelper.floating_and_sunk_get_instance_list()[0]
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
-
- def testFloatingAndSunkUsingGObjectNew(self):
+ def test_floating_and_sunk_using_gobject_new(self):
# Upon creation, the refcount of the object should be 2:
# - someone already has a reference on the new object.
# - the python wrapper should hold its own reference.
obj = GObject.new(testhelper.FloatingAndSunk)
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We ask the library to release its reference, so the only
# remaining ref should be our wrapper's. Once the wrapper
# will run out of scope, the object will get finalized.
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
- def testFloatingAndSunkOutOfScopeUsingGObjectNew(self):
+ def test_floating_and_sunk_out_of_scope_using_gobject_new(self):
obj = GObject.new(testhelper.FloatingAndSunk)
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
# We are manually taking the object out of scope. This means
# that our wrapper has been freed, and its reference dropped. We
@@ -150,31 +205,457 @@ class TestReferenceCounting(unittest.TestCase):
# When we get the object back from the lib, the wrapper is
# re-created, so our refcount will be 2 once again.
obj = testhelper.floating_and_sunk_get_instance_list()[0]
- self.assertEquals(obj.__grefcount__, 2)
+ self.assertEqual(obj.__grefcount__, 2)
obj.release()
- self.assertEquals(obj.__grefcount__, 1)
+ self.assertEqual(obj.__grefcount__, 1)
+
+ def test_uninitialized_object(self):
+ class Obj(GObject.GObject):
+ def __init__(self):
+ x = self.__grefcount__
+ super(Obj, self).__init__()
+ assert x >= 0 # quiesce pyflakes
+
+ # Accessing __grefcount__ before the object is initialized is wrong.
+ # Ensure we get a proper exception instead of a crash.
+ self.assertRaises(TypeError, Obj)
+
class A(GObject.GObject):
def __init__(self):
super(A, self).__init__()
+
class TestPythonReferenceCounting(unittest.TestCase):
# Newly created instances should alwayshave two references: one for
# the GC, and one for the bound variable in the local scope.
- def testNewInstanceHasTwoRefs(self):
+ def test_new_instance_has_two_refs(self):
obj = GObject.GObject()
- self.assertEquals(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(obj), 2)
- def testNewInstanceHasTwoRefsUsingGObjectNew(self):
+ def test_new_instance_has_two_refs_using_gobject_new(self):
obj = GObject.new(GObject.GObject)
- self.assertEquals(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(obj), 2)
- def testNewSubclassInstanceHasTwoRefs(self):
+ def test_new_subclass_instance_has_two_refs(self):
obj = A()
- self.assertEquals(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(obj), 2)
- def testNewSubclassInstanceHasTwoRefsUsingGObjectNew(self):
+ def test_new_subclass_instance_has_two_refs_using_gobject_new(self):
obj = GObject.new(A)
- self.assertEquals(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(obj), 2)
+
+
+class TestContextManagers(unittest.TestCase):
+ class ContextTestObject(GObject.GObject):
+ prop = GObject.Property(default=0, type=int)
+
+ def on_prop_set(self, obj, prop):
+ # Handler which tracks property changed notifications.
+ self.tracking.append(obj.get_property(prop.name))
+
+ def setUp(self):
+ self.tracking = []
+ self.obj = self.ContextTestObject()
+ self.handler = self.obj.connect('notify::prop', self.on_prop_set)
+
+ def test_freeze_notify_context(self):
+ # Verify prop tracking list
+ self.assertEqual(self.tracking, [])
+ self.obj.props.prop = 1
+ self.assertEqual(self.tracking, [1])
+ self.obj.props.prop = 2
+ self.assertEqual(self.tracking, [1, 2])
+ self.assertEqual(self.obj.__grefcount__, 1)
+
+ pyref_count = sys.getrefcount(self.obj)
+
+ # Using the context manager the tracking list should not be affected.
+ # The GObject reference count should stay the same and the python
+ # object ref-count should go up.
+ with self.obj.freeze_notify():
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.assertEqual(sys.getrefcount(self.obj), pyref_count + 1)
+ self.obj.props.prop = 3
+ self.assertEqual(self.obj.props.prop, 3)
+ self.assertEqual(self.tracking, [1, 2])
+
+ # After the context manager, the prop should have been modified,
+ # the tracking list will be modified, and the python object ref
+ # count goes back down.
+ gc.collect()
+ self.assertEqual(self.obj.props.prop, 3)
+ self.assertEqual(self.tracking, [1, 2, 3])
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.assertEqual(sys.getrefcount(self.obj), pyref_count)
+
+ def test_handler_block_context(self):
+ # Verify prop tracking list
+ self.assertEqual(self.tracking, [])
+ self.obj.props.prop = 1
+ self.assertEqual(self.tracking, [1])
+ self.obj.props.prop = 2
+ self.assertEqual(self.tracking, [1, 2])
+ self.assertEqual(self.obj.__grefcount__, 1)
+
+ pyref_count = sys.getrefcount(self.obj)
+
+ # Using the context manager the tracking list should not be affected.
+ # The GObject reference count should stay the same and the python
+ # object ref-count should go up.
+ with self.obj.handler_block(self.handler):
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.assertEqual(sys.getrefcount(self.obj), pyref_count + 1)
+ self.obj.props.prop = 3
+ self.assertEqual(self.obj.props.prop, 3)
+ self.assertEqual(self.tracking, [1, 2])
+
+ # After the context manager, the prop should have been modified
+ # the tracking list should have stayed the same and the GObject ref
+ # count goes back down.
+ gc.collect()
+ self.assertEqual(self.obj.props.prop, 3)
+ self.assertEqual(self.tracking, [1, 2])
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.assertEqual(sys.getrefcount(self.obj), pyref_count)
+
+ def test_freeze_notify_context_nested(self):
+ self.assertEqual(self.tracking, [])
+ with self.obj.freeze_notify():
+ self.obj.props.prop = 1
+ self.assertEqual(self.tracking, [])
+
+ with self.obj.freeze_notify():
+ self.obj.props.prop = 2
+ self.assertEqual(self.tracking, [])
+
+ with self.obj.freeze_notify():
+ self.obj.props.prop = 3
+ self.assertEqual(self.tracking, [])
+ self.assertEqual(self.tracking, [])
+ self.assertEqual(self.tracking, [])
+
+ # Finally after last context, the notifications should have collapsed
+ # and the last one sent.
+ self.assertEqual(self.tracking, [3])
+
+ def test_handler_block_context_nested(self):
+ self.assertEqual(self.tracking, [])
+ with self.obj.handler_block(self.handler):
+ self.obj.props.prop = 1
+ self.assertEqual(self.tracking, [])
+
+ with self.obj.handler_block(self.handler):
+ self.obj.props.prop = 2
+ self.assertEqual(self.tracking, [])
+
+ with self.obj.handler_block(self.handler):
+ self.obj.props.prop = 3
+ self.assertEqual(self.tracking, [])
+ self.assertEqual(self.tracking, [])
+ self.assertEqual(self.tracking, [])
+
+ # Finally after last context, the notifications should have collapsed
+ # and the last one sent.
+ self.assertEqual(self.obj.props.prop, 3)
+ self.assertEqual(self.tracking, [])
+
+ def test_freeze_notify_normal_usage_ref_counts(self):
+ # Ensure ref counts without using methods as context managers
+ # maintain the same count.
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.obj.freeze_notify()
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.obj.thaw_notify()
+ self.assertEqual(self.obj.__grefcount__, 1)
+
+ def test_handler_block_normal_usage_ref_counts(self):
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.obj.handler_block(self.handler)
+ self.assertEqual(self.obj.__grefcount__, 1)
+ self.obj.handler_unblock(self.handler)
+ self.assertEqual(self.obj.__grefcount__, 1)
+
+ def test_freeze_notify_context_error(self):
+ # Test an exception occurring within a freeze context exits the context
+ try:
+ with self.obj.freeze_notify():
+ self.obj.props.prop = 1
+ self.assertEqual(self.tracking, [])
+ raise ValueError('Simulation')
+ except ValueError:
+ pass
+
+ # Verify the property set within the context called notify.
+ self.assertEqual(self.obj.props.prop, 1)
+ self.assertEqual(self.tracking, [1])
+
+ # Verify we are still not in a frozen context.
+ self.obj.props.prop = 2
+ self.assertEqual(self.tracking, [1, 2])
+
+ def test_handler_block_context_error(self):
+ # Test an exception occurring within a handler block exits the context
+ try:
+ with self.obj.handler_block(self.handler):
+ self.obj.props.prop = 1
+ self.assertEqual(self.tracking, [])
+ raise ValueError('Simulation')
+ except ValueError:
+ pass
+
+ # Verify the property set within the context didn't call notify.
+ self.assertEqual(self.obj.props.prop, 1)
+ self.assertEqual(self.tracking, [])
+
+ # Verify we are still not in a handler block context.
+ self.obj.props.prop = 2
+ self.assertEqual(self.tracking, [2])
+
+
+class TestPropertyBindings(unittest.TestCase):
+ class TestObject(GObject.GObject):
+ int_prop = GObject.Property(default=0, type=int)
+
+ def setUp(self):
+ self.source = self.TestObject()
+ self.target = self.TestObject()
+
+ def test_default_binding(self):
+ binding = self.source.bind_property('int_prop', self.target, 'int_prop',
+ GObject.BindingFlags.DEFAULT)
+ binding = binding # PyFlakes
+
+ # Test setting value on source gets pushed to target
+ self.source.int_prop = 1
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 1)
+
+ # Test setting value on target does not change source
+ self.target.props.int_prop = 2
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 2)
+
+ def test_bidirectional_binding(self):
+ binding = self.source.bind_property('int_prop', self.target, 'int_prop',
+ GObject.BindingFlags.BIDIRECTIONAL)
+ binding = binding # PyFlakes
+
+ # Test setting value on source gets pushed to target
+ self.source.int_prop = 1
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 1)
+
+ # Test setting value on target also changes source
+ self.target.props.int_prop = 2
+ self.assertEqual(self.source.int_prop, 2)
+ self.assertEqual(self.target.int_prop, 2)
+
+ def test_transform_to_only(self):
+ def transform_to(binding, value, user_data=None):
+ self.assertEqual(user_data, 'test-data')
+ return value * 2
+
+ binding = self.source.bind_property('int_prop', self.target, 'int_prop',
+ GObject.BindingFlags.DEFAULT,
+ transform_to, None, 'test-data')
+ binding = binding # PyFlakes
+
+ self.source.int_prop = 1
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 2)
+
+ self.target.props.int_prop = 1
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 1)
+
+ def test_transform_from_only(self):
+ def transform_from(binding, value, user_data=None):
+ self.assertEqual(user_data, None)
+ return value * 2
+
+ binding = self.source.bind_property('int_prop', self.target, 'int_prop',
+ GObject.BindingFlags.BIDIRECTIONAL,
+ None, transform_from)
+ binding = binding # PyFlakes
+
+ self.source.int_prop = 1
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 1)
+
+ self.target.props.int_prop = 1
+ self.assertEqual(self.source.int_prop, 2)
+ self.assertEqual(self.target.int_prop, 1)
+
+ def test_transform_bidirectional(self):
+ test_data = object()
+
+ def transform_to(binding, value, user_data=None):
+ self.assertEqual(user_data, test_data)
+ return value * 2
+
+ def transform_from(binding, value, user_data=None):
+ self.assertEqual(user_data, test_data)
+ return value // 2
+
+ test_data_ref_count = sys.getrefcount(test_data)
+ transform_to_ref_count = sys.getrefcount(transform_to)
+ transform_from_ref_count = sys.getrefcount(transform_from)
+
+ # bidirectional bindings
+ binding = self.source.bind_property('int_prop', self.target, 'int_prop',
+ GObject.BindingFlags.BIDIRECTIONAL,
+ transform_to, transform_from, test_data)
+ binding = binding # PyFlakes
+ binding_ref_count = sys.getrefcount(binding())
+ binding_gref_count = binding().__grefcount__
+
+ self.source.int_prop = 1
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 2)
+
+ self.target.props.int_prop = 4
+ self.assertEqual(self.source.int_prop, 2)
+ self.assertEqual(self.target.int_prop, 4)
+
+ self.assertEqual(sys.getrefcount(binding()), binding_ref_count)
+ self.assertEqual(binding().__grefcount__, binding_gref_count)
+
+ # test_data ref count increases by 2, once for each callback.
+ self.assertEqual(sys.getrefcount(test_data), test_data_ref_count + 2)
+ self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count + 1)
+ self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count + 1)
+
+ # Unbind should clear out the binding and its transforms
+ binding.unbind()
+ self.assertEqual(binding(), None)
+ del binding
+ gc.collect()
+
+ # Setting source or target should not change the other.
+ self.target.int_prop = 3
+ self.source.int_prop = 5
+ self.assertEqual(self.target.int_prop, 3)
+ self.assertEqual(self.source.int_prop, 5)
+
+ self.assertEqual(sys.getrefcount(test_data), test_data_ref_count)
+ self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count)
+ self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count)
+
+ def test_explicit_unbind_clears_connection(self):
+ self.assertEqual(self.source.int_prop, 0)
+ self.assertEqual(self.target.int_prop, 0)
+
+ # Test deleting binding reference removes binding.
+ binding = self.source.bind_property('int_prop', self.target, 'int_prop')
+ self.source.int_prop = 1
+ self.assertEqual(self.source.int_prop, 1)
+ self.assertEqual(self.target.int_prop, 1)
+
+ binding.unbind()
+ self.assertEqual(binding(), None)
+
+ self.source.int_prop = 10
+ self.assertEqual(self.source.int_prop, 10)
+ self.assertEqual(self.target.int_prop, 1)
+
+ # An already unbound BindingWeakRef will raise if unbind is attempted a second time.
+ self.assertRaises(ValueError, binding.unbind)
+
+ def test_reference_counts(self):
+ self.assertEqual(self.source.__grefcount__, 1)
+ self.assertEqual(self.target.__grefcount__, 1)
+
+ # Binding ref count will be 2 do to the initial ref implicitly held by
+ # the act of binding and the ref incurred by using __call__ to generate
+ # a wrapper from the weak binding ref within python.
+ binding = self.source.bind_property('int_prop', self.target, 'int_prop')
+ self.assertEqual(binding().__grefcount__, 2)
+
+ # Creating a binding does not inc refs on source and target (they are weak
+ # on the binding object itself)
+ self.assertEqual(self.source.__grefcount__, 1)
+ self.assertEqual(self.target.__grefcount__, 1)
+
+ # Use GObject.get_property because the "props" accessor leaks.
+ # Note property names are canonicalized.
+ self.assertEqual(binding().get_property('source'), self.source)
+ self.assertEqual(binding().get_property('source_property'), 'int-prop')
+ self.assertEqual(binding().get_property('target'), self.target)
+ self.assertEqual(binding().get_property('target_property'), 'int-prop')
+ self.assertEqual(binding().get_property('flags'), GObject.BindingFlags.DEFAULT)
+
+ # Delete reference to source or target and the binding should listen.
+ ref = self.source.weak_ref()
+ del self.source
+ gc.collect()
+ self.assertEqual(ref(), None)
+ self.assertEqual(binding(), None)
+
+
+class TestGValue(unittest.TestCase):
+ def test_type_constant(self):
+ self.assertEqual(GObject.TYPE_VALUE, GObject.Value.__gtype__)
+ self.assertEqual(GObject.type_name(GObject.TYPE_VALUE), 'GValue')
+
+ def test_no_type(self):
+ value = GObject.Value()
+ self.assertEqual(value.g_type, GObject.TYPE_INVALID)
+ self.assertRaises(TypeError, value.set_value, 23)
+ self.assertEqual(value.get_value(), None)
+
+ def test_int(self):
+ value = GObject.Value(GObject.TYPE_UINT)
+ self.assertEqual(value.g_type, GObject.TYPE_UINT)
+ value.set_value(23)
+ self.assertEqual(value.get_value(), 23)
+ value.set_value(42.0)
+ self.assertEqual(value.get_value(), 42)
+
+ def test_string(self):
+ value = GObject.Value(str, 'foo_bar')
+ self.assertEqual(value.g_type, GObject.TYPE_STRING)
+ self.assertEqual(value.get_value(), 'foo_bar')
+
+ def test_float(self):
+ # python float is G_TYPE_DOUBLE
+ value = GObject.Value(float, 23.4)
+ self.assertEqual(value.g_type, GObject.TYPE_DOUBLE)
+ value.set_value(1e50)
+ self.assertAlmostEqual(value.get_value(), 1e50)
+
+ value = GObject.Value(GObject.TYPE_FLOAT, 23.4)
+ self.assertEqual(value.g_type, GObject.TYPE_FLOAT)
+ self.assertRaises(TypeError, value.set_value, 'string')
+ self.assertRaises(OverflowError, value.set_value, 1e50)
+
+ def test_float_inf_nan(self):
+ nan = float('nan')
+ for type_ in [GObject.TYPE_FLOAT, GObject.TYPE_DOUBLE]:
+ for x in [float('inf'), float('-inf'), nan]:
+ value = GObject.Value(type_, x)
+ # assertEqual() is False for (nan, nan)
+ if x is nan:
+ self.assertEqual(str(value.get_value()), 'nan')
+ else:
+ self.assertEqual(value.get_value(), x)
+
+ def test_enum(self):
+ value = GObject.Value(GLib.FileError, GLib.FileError.FAILED)
+ self.assertEqual(value.get_value(), GLib.FileError.FAILED)
+
+ def test_flags(self):
+ value = GObject.Value(GLib.IOFlags, GLib.IOFlags.IS_READABLE)
+ self.assertEqual(value.get_value(), GLib.IOFlags.IS_READABLE)
+
+ def test_object(self):
+ class TestObject(GObject.Object):
+ pass
+ obj = TestObject()
+ value = GObject.Value(GObject.TYPE_OBJECT, obj)
+ self.assertEqual(value.get_value(), obj)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_gtype.py b/tests/test_gtype.py
new file mode 100644
index 0000000..8099101
--- /dev/null
+++ b/tests/test_gtype.py
@@ -0,0 +1,51 @@
+import unittest
+
+from gi.repository import GObject
+from gi.repository import GIMarshallingTests
+
+
+class CustomBase(GObject.GObject):
+ pass
+
+
+class CustomChild(CustomBase, GIMarshallingTests.Interface):
+ pass
+
+
+class TestTypeModuleLevelFunctions(unittest.TestCase):
+ def test_type_name(self):
+ self.assertEqual(GObject.type_name(GObject.TYPE_NONE), 'void')
+ self.assertEqual(GObject.type_name(GObject.TYPE_OBJECT), 'GObject')
+ self.assertEqual(GObject.type_name(GObject.TYPE_PYOBJECT), 'PyObject')
+
+ def test_type_from_name(self):
+ # A complete test is not needed here since the TYPE_* defines are created
+ # using this method.
+ self.assertRaises(RuntimeError, GObject.type_from_name, '!NOT_A_REAL_TYPE!')
+ self.assertEqual(GObject.type_from_name('GObject'), GObject.TYPE_OBJECT)
+ self.assertEqual(GObject.type_from_name('GObject'), GObject.GObject.__gtype__)
+
+ def test_type_is_a(self):
+ self.assertTrue(GObject.type_is_a(CustomBase, GObject.TYPE_OBJECT))
+ self.assertTrue(GObject.type_is_a(CustomChild, CustomBase))
+ self.assertTrue(GObject.type_is_a(CustomBase, GObject.GObject))
+ self.assertTrue(GObject.type_is_a(CustomBase.__gtype__, GObject.TYPE_OBJECT))
+ self.assertFalse(GObject.type_is_a(GObject.TYPE_OBJECT, CustomBase))
+ self.assertFalse(GObject.type_is_a(CustomBase, int)) # invalid type
+ self.assertRaises(TypeError, GObject.type_is_a, CustomBase, 1)
+ self.assertRaises(TypeError, GObject.type_is_a, 2, GObject.TYPE_OBJECT)
+ self.assertRaises(TypeError, GObject.type_is_a, 1, 2)
+
+ def test_type_children(self):
+ self.assertEqual(GObject.type_children(CustomBase), [CustomChild.__gtype__])
+ self.assertEqual(len(GObject.type_children(CustomChild)), 0)
+
+ def test_type_interfaces(self):
+ self.assertEqual(len(GObject.type_interfaces(CustomBase)), 0)
+ self.assertEqual(len(GObject.type_interfaces(CustomChild)), 1)
+ self.assertEqual(GObject.type_interfaces(CustomChild), [GIMarshallingTests.Interface.__gtype__])
+
+ def test_type_parent(self):
+ self.assertEqual(GObject.type_parent(CustomChild), CustomBase.__gtype__)
+ self.assertEqual(GObject.type_parent(CustomBase), GObject.TYPE_OBJECT)
+ self.assertRaises(RuntimeError, GObject.type_parent, GObject.GObject)
diff --git a/tests/test_interface.py b/tests/test_interface.py
index f60a25c..dd01af8 100644
--- a/tests/test_interface.py
+++ b/tests/test_interface.py
@@ -37,13 +37,12 @@ GObject.type_register(MyObject)
class TestIfaceImpl(unittest.TestCase):
- def testReImplementInterface(self):
+ def test_reimplement_interface(self):
m = MyUnknown()
m.iface_method()
self.assertEqual(m.called, True)
- def testImplementInterface(self):
+ def test_implement_interface(self):
m = MyObject()
m.iface_method()
self.assertEqual(m.called, True)
-
diff --git a/tests/test_internal_api.py b/tests/test_internal_api.py
new file mode 100644
index 0000000..ca50f6b
--- /dev/null
+++ b/tests/test_internal_api.py
@@ -0,0 +1,73 @@
+# -*- Mode: Python -*-
+
+import unittest
+
+from gi.repository import GLib, GObject
+
+import testhelper
+import testmodule
+
+
+class TestObject(unittest.TestCase):
+ def test_create_ctor(self):
+ o = testmodule.PyGObject()
+ self.assertTrue(isinstance(o, GObject.Object))
+ self.assertTrue(isinstance(o, testmodule.PyGObject))
+
+ # has expected property
+ self.assertEqual(o.props.label, 'hello')
+ o.props.label = 'goodbye'
+ self.assertEqual(o.props.label, 'goodbye')
+ self.assertRaises(AttributeError, getattr, o.props, 'nosuchprop')
+
+ def test_pyobject_new_test_type(self):
+ o = testhelper.create_test_type()
+ self.assertTrue(isinstance(o, testmodule.PyGObject))
+
+ # has expected property
+ self.assertEqual(o.props.label, 'hello')
+ o.props.label = 'goodbye'
+ self.assertEqual(o.props.label, 'goodbye')
+ self.assertRaises(AttributeError, getattr, o.props, 'nosuchprop')
+
+ def test_new_refcount(self):
+ # TODO: justify why this should be 2
+ self.assertEqual(testhelper.test_g_object_new(), 2)
+
+
+class TestGValueConversion(unittest.TestCase):
+ def test_int(self):
+ self.assertEqual(testhelper.test_value(0), 0)
+ self.assertEqual(testhelper.test_value(5), 5)
+ self.assertEqual(testhelper.test_value(-5), -5)
+ self.assertEqual(testhelper.test_value(GObject.G_MAXINT32), GObject.G_MAXINT32)
+ self.assertEqual(testhelper.test_value(GObject.G_MININT32), GObject.G_MININT32)
+
+ def test_str(self):
+ self.assertEqual(testhelper.test_value('hello'), 'hello')
+
+ def test_int_array(self):
+ self.assertEqual(testhelper.test_value_array([]), [])
+ self.assertEqual(testhelper.test_value_array([0]), [0])
+ ar = list(range(100))
+ self.assertEqual(testhelper.test_value_array(ar), ar)
+
+ def test_str_array(self):
+ self.assertEqual(testhelper.test_value_array([]), [])
+ self.assertEqual(testhelper.test_value_array(['a']), ['a'])
+ ar = ('aa ' * 1000).split()
+ self.assertEqual(testhelper.test_value_array(ar), ar)
+
+
+class TestErrors(unittest.TestCase):
+ def test_gerror(self):
+ callable_ = lambda: GLib.file_get_contents('/nonexisting ')
+ self.assertRaises(GLib.GError, testhelper.test_gerror_exception, callable_)
+
+ def test_no_gerror(self):
+ callable_ = lambda: GLib.file_get_contents(__file__)
+ self.assertEqual(testhelper.test_gerror_exception(callable_), None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_iochannel.py b/tests/test_iochannel.py
new file mode 100644
index 0000000..0cc1b4b
--- /dev/null
+++ b/tests/test_iochannel.py
@@ -0,0 +1,424 @@
+# -*- Mode: Python -*-
+# encoding: UTF-8
+from __future__ import unicode_literals
+
+import unittest
+import tempfile
+import os.path
+import fcntl
+import shutil
+import warnings
+
+from gi.repository import GLib
+from gi import PyGIDeprecationWarning
+
+from compathelper import _unicode
+
+
+class IOChannel(unittest.TestCase):
+ def setUp(self):
+ self.workdir = tempfile.mkdtemp()
+
+ self.testutf8 = os.path.join(self.workdir, 'testutf8.txt')
+ with open(self.testutf8, 'wb') as f:
+ f.write('''hello ♥ world
+second line
+
+À demain!'''.encode('UTF-8'))
+
+ self.testlatin1 = os.path.join(self.workdir, 'testlatin1.txt')
+ with open(self.testlatin1, 'wb') as f:
+ f.write(b'''hell\xf8 world
+second line
+
+\xc0 demain!''')
+
+ self.testout = os.path.join(self.workdir, 'testout.txt')
+
+ def tearDown(self):
+ shutil.rmtree(self.workdir)
+
+ def test_file_readline_utf8(self):
+ ch = GLib.IOChannel(filename=self.testutf8)
+ self.assertEqual(ch.get_encoding(), 'UTF-8')
+ self.assertTrue(ch.get_close_on_unref())
+ self.assertEqual(_unicode(ch.readline()), 'hello ♥ world\n')
+ self.assertEqual(ch.get_buffer_condition(), GLib.IOCondition.IN)
+ self.assertEqual(ch.readline(), 'second line\n')
+ self.assertEqual(ch.readline(), '\n')
+ self.assertEqual(_unicode(ch.readline()), 'À demain!')
+ self.assertEqual(ch.get_buffer_condition(), 0)
+ self.assertEqual(ch.readline(), '')
+ ch.close()
+
+ def test_file_readline_latin1(self):
+ ch = GLib.IOChannel(filename=self.testlatin1, mode='r')
+ ch.set_encoding('latin1')
+ self.assertEqual(ch.get_encoding(), 'latin1')
+ self.assertEqual(_unicode(ch.readline()), 'hellø world\n')
+ self.assertEqual(ch.readline(), 'second line\n')
+ self.assertEqual(ch.readline(), '\n')
+ self.assertEqual(_unicode(ch.readline()), 'À demain!')
+ ch.close()
+
+ def test_file_iter(self):
+ items = []
+ ch = GLib.IOChannel(filename=self.testutf8)
+ for item in ch:
+ items.append(item)
+ self.assertEqual(len(items), 4)
+ self.assertEqual(_unicode(items[0]), 'hello ♥ world\n')
+ ch.close()
+
+ def test_file_readlines(self):
+ ch = GLib.IOChannel(filename=self.testutf8)
+ lines = ch.readlines()
+ # Note, this really ought to be 4, but the static bindings add an extra
+ # empty one
+ self.assertGreaterEqual(len(lines), 4)
+ self.assertLessEqual(len(lines), 5)
+ self.assertEqual(_unicode(lines[0]), 'hello ♥ world\n')
+ self.assertEqual(_unicode(lines[3]), 'À demain!')
+ if len(lines) == 4:
+ self.assertEqual(lines[4], '')
+
+ def test_file_read(self):
+ ch = GLib.IOChannel(filename=self.testutf8)
+ with open(self.testutf8, 'rb') as f:
+ self.assertEqual(ch.read(), f.read())
+
+ ch = GLib.IOChannel(filename=self.testutf8)
+ with open(self.testutf8, 'rb') as f:
+ self.assertEqual(ch.read(10), f.read(10))
+
+ ch = GLib.IOChannel(filename=self.testutf8)
+ with open(self.testutf8, 'rb') as f:
+ self.assertEqual(ch.read(max_count=15), f.read(15))
+
+ def test_seek(self):
+ ch = GLib.IOChannel(filename=self.testutf8)
+ ch.seek(2)
+ self.assertEqual(ch.read(3), b'llo')
+
+ ch.seek(2, 0) # SEEK_SET
+ self.assertEqual(ch.read(3), b'llo')
+
+ ch.seek(1, 1) # SEEK_CUR, skip the space
+ self.assertEqual(ch.read(3), b'\xe2\x99\xa5')
+
+ ch.seek(2, 2) # SEEK_END
+ # FIXME: does not work currently
+ #self.assertEqual(ch.read(2), b'n!')
+
+ # invalid whence value
+ self.assertRaises(ValueError, ch.seek, 0, 3)
+
+ def test_file_write(self):
+ ch = GLib.IOChannel(filename=self.testout, mode='w')
+ ch.set_encoding('latin1')
+ ch.write('hellø world\n')
+ ch.close()
+ ch = GLib.IOChannel(filename=self.testout, mode='a')
+ ch.set_encoding('latin1')
+ ch.write('À demain!')
+ ch.close()
+
+ with open(self.testout, 'rb') as f:
+ self.assertEqual(f.read().decode('latin1'), 'hellø world\nÀ demain!')
+
+ def test_file_writelines(self):
+ ch = GLib.IOChannel(filename=self.testout, mode='w')
+ ch.writelines(['foo', 'bar\n', 'baz\n', 'end'])
+ ch.close()
+
+ with open(self.testout, 'r') as f:
+ self.assertEqual(f.read(), 'foobar\nbaz\nend')
+
+ def test_buffering(self):
+ writer = GLib.IOChannel(filename=self.testout, mode='w')
+ writer.set_encoding(None)
+ self.assertTrue(writer.get_buffered())
+ self.assertGreater(writer.get_buffer_size(), 10)
+
+ reader = GLib.IOChannel(filename=self.testout, mode='r')
+
+ # does not get written immediately on buffering
+ writer.write('abc')
+ self.assertEqual(reader.read(), b'')
+ writer.flush()
+ self.assertEqual(reader.read(), b'abc')
+
+ # does get written immediately without buffering
+ writer.set_buffered(False)
+ writer.write('def')
+ self.assertEqual(reader.read(), b'def')
+
+ # writes after buffer overflow
+ writer.set_buffer_size(10)
+ writer.write('0123456789012')
+ self.assertTrue(reader.read().startswith(b'012'))
+ writer.flush()
+ reader.read() # ignore bits written after flushing
+
+ # closing flushes
+ writer.set_buffered(True)
+ writer.write('ghi')
+ writer.close()
+ self.assertEqual(reader.read(), b'ghi')
+ reader.close()
+
+ def test_fd_read(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+ self.assertNotEqual(ch.get_flags() | GLib.IOFlags.NONBLOCK, 0)
+ self.assertEqual(ch.read(), b'')
+ os.write(w, b'\x01\x02')
+ self.assertEqual(ch.read(), b'\x01\x02')
+
+ # now test blocking case, after closing the write end
+ ch.set_flags(GLib.IOFlags(ch.get_flags() & ~GLib.IOFlags.NONBLOCK))
+ os.write(w, b'\x03\x04')
+ os.close(w)
+ self.assertEqual(ch.read(), b'\x03\x04')
+
+ ch.close()
+
+ def test_fd_write(self):
+ (r, w) = os.pipe()
+ fcntl.fcntl(r, fcntl.F_SETFL, fcntl.fcntl(r, fcntl.F_GETFL) | os.O_NONBLOCK)
+
+ ch = GLib.IOChannel(filedes=w, mode='w')
+ ch.set_encoding(None)
+ ch.set_buffered(False)
+ ch.write(b'\x01\x02')
+ self.assertEqual(os.read(r, 10), b'\x01\x02')
+
+ # now test blocking case, after closing the write end
+ fcntl.fcntl(r, fcntl.F_SETFL, fcntl.fcntl(r, fcntl.F_GETFL) & ~os.O_NONBLOCK)
+ ch.write(b'\x03\x04')
+ ch.close()
+ self.assertEqual(os.read(r, 10), b'\x03\x04')
+ os.close(r)
+
+ def test_deprecated_method_add_watch_no_data(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+
+ cb_reads = []
+
+ def cb(channel, condition):
+ self.assertEqual(channel, ch)
+ self.assertEqual(condition, GLib.IOCondition.IN)
+ cb_reads.append(channel.read())
+ return True
+
+ # io_add_watch() method is deprecated, use GLib.io_add_watch
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ ch.add_watch(GLib.IOCondition.IN, cb)
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ ml = GLib.MainLoop()
+
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(cb_reads, [b'a', b'b'])
+
+ def test_deprecated_method_add_watch_data_priority(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+
+ cb_reads = []
+
+ def cb(channel, condition, data):
+ self.assertEqual(channel, ch)
+ self.assertEqual(condition, GLib.IOCondition.IN)
+ self.assertEqual(data, 'hello')
+ cb_reads.append(channel.read())
+ return True
+
+ ml = GLib.MainLoop()
+ # io_add_watch() method is deprecated, use GLib.io_add_watch
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ id = ch.add_watch(GLib.IOCondition.IN, cb, 'hello', priority=GLib.PRIORITY_HIGH)
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(cb_reads, [b'a', b'b'])
+
+ def test_add_watch_no_data(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+
+ cb_reads = []
+
+ def cb(channel, condition):
+ self.assertEqual(channel, ch)
+ self.assertEqual(condition, GLib.IOCondition.IN)
+ cb_reads.append(channel.read())
+ return True
+
+ id = GLib.io_add_watch(ch, GLib.PRIORITY_HIGH, GLib.IOCondition.IN, cb)
+
+ ml = GLib.MainLoop()
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(cb_reads, [b'a', b'b'])
+
+ def test_add_watch_with_data(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+
+ cb_reads = []
+
+ def cb(channel, condition, data):
+ self.assertEqual(channel, ch)
+ self.assertEqual(condition, GLib.IOCondition.IN)
+ self.assertEqual(data, 'hello')
+ cb_reads.append(channel.read())
+ return True
+
+ id = GLib.io_add_watch(ch, GLib.PRIORITY_HIGH, GLib.IOCondition.IN, cb, 'hello')
+
+ ml = GLib.MainLoop()
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(cb_reads, [b'a', b'b'])
+
+ def test_add_watch_with_multi_data(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+
+ cb_reads = []
+
+ def cb(channel, condition, data1, data2, data3):
+ self.assertEqual(channel, ch)
+ self.assertEqual(condition, GLib.IOCondition.IN)
+ self.assertEqual(data1, 'a')
+ self.assertEqual(data2, 'b')
+ self.assertEqual(data3, 'c')
+ cb_reads.append(channel.read())
+ return True
+
+ id = GLib.io_add_watch(ch, GLib.PRIORITY_HIGH, GLib.IOCondition.IN, cb,
+ 'a', 'b', 'c')
+
+ ml = GLib.MainLoop()
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(cb_reads, [b'a', b'b'])
+
+ def test_deprecated_add_watch_no_data(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+
+ cb_reads = []
+
+ def cb(channel, condition):
+ self.assertEqual(channel, ch)
+ self.assertEqual(condition, GLib.IOCondition.IN)
+ cb_reads.append(channel.read())
+ return True
+
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ id = GLib.io_add_watch(ch, GLib.IOCondition.IN, cb, priority=GLib.PRIORITY_HIGH)
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ ml = GLib.MainLoop()
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(cb_reads, [b'a', b'b'])
+
+ def test_deprecated_add_watch_with_data(self):
+ (r, w) = os.pipe()
+
+ ch = GLib.IOChannel(filedes=r)
+ ch.set_encoding(None)
+ ch.set_flags(ch.get_flags() | GLib.IOFlags.NONBLOCK)
+
+ cb_reads = []
+
+ def cb(channel, condition, data):
+ self.assertEqual(channel, ch)
+ self.assertEqual(condition, GLib.IOCondition.IN)
+ self.assertEqual(data, 'hello')
+ cb_reads.append(channel.read())
+ return True
+
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ id = GLib.io_add_watch(ch, GLib.IOCondition.IN, cb, 'hello',
+ priority=GLib.PRIORITY_HIGH)
+ self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+ ml = GLib.MainLoop()
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
+ GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
+ GLib.timeout_add(200, ml.quit)
+ ml.run()
+
+ self.assertEqual(cb_reads, [b'a', b'b'])
+
+ def test_backwards_compat_flags(self):
+ self.assertEqual(GLib.IOCondition.IN, GLib.IO_IN)
+ self.assertEqual(GLib.IOFlags.NONBLOCK, GLib.IO_FLAG_NONBLOCK)
+ self.assertEqual(GLib.IOFlags.IS_SEEKABLE, GLib.IO_FLAG_IS_SEEKABLE)
+ self.assertEqual(GLib.IOStatus.NORMAL, GLib.IO_STATUS_NORMAL)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_mainloop.py b/tests/test_mainloop.py
index 937ecaf..44197b3 100644
--- a/tests/test_mainloop.py
+++ b/tests/test_mainloop.py
@@ -3,14 +3,23 @@
import os
import sys
import select
+import signal
+import time
import unittest
+try:
+ from _thread import start_new_thread
+ start_new_thread # pyflakes
+except ImportError:
+ # Python 2
+ from thread import start_new_thread
from gi.repository import GLib
from compathelper import _bytes
+
class TestMainLoop(unittest.TestCase):
- def testExceptionHandling(self):
+ def test_exception_handling(self):
pipe_r, pipe_w = os.pipe()
pid = os.fork()
@@ -25,27 +34,64 @@ class TestMainLoop(unittest.TestCase):
raise Exception("deadbabe")
loop = GLib.MainLoop()
- GLib.child_watch_add(pid, child_died, loop)
+ GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, child_died, loop)
os.close(pipe_r)
os.write(pipe_w, _bytes("Y"))
os.close(pipe_w)
def excepthook(type, value, traceback):
- assert type is Exception
- assert value.args[0] == "deadbabe"
+ self.assertTrue(type is Exception)
+ self.assertEqual(value.args[0], "deadbabe")
sys.excepthook = excepthook
-
- got_exception = False
try:
- loop.run()
- except:
- got_exception = True
+ got_exception = False
+ try:
+ loop.run()
+ except:
+ got_exception = True
+ finally:
+ sys.excepthook = sys.__excepthook__
#
# The exception should be handled (by printing it)
# immediately on return from child_died() rather
# than here. See bug #303573
#
- sys.excepthook = sys.__excepthook__
- assert not got_exception
+ self.assertFalse(got_exception)
+
+ def test_concurrency(self):
+ def on_usr1(signum, frame):
+ pass
+
+ try:
+ # create a thread which will terminate upon SIGUSR1 by way of
+ # interrupting sleep()
+ orig_handler = signal.signal(signal.SIGUSR1, on_usr1)
+ start_new_thread(time.sleep, (10,))
+
+ # now create two main loops
+ loop1 = GLib.MainLoop()
+ loop2 = GLib.MainLoop()
+ GLib.timeout_add(100, lambda: os.kill(os.getpid(), signal.SIGUSR1))
+ GLib.timeout_add(500, loop1.quit)
+ loop1.run()
+ loop2.quit()
+ finally:
+ signal.signal(signal.SIGUSR1, orig_handler)
+
+ def test_sigint(self):
+ pid = os.fork()
+ if pid == 0:
+ time.sleep(0.5)
+ os.kill(os.getppid(), signal.SIGINT)
+ os._exit(0)
+
+ loop = GLib.MainLoop()
+ try:
+ loop.run()
+ self.fail('expected KeyboardInterrupt exception')
+ except KeyboardInterrupt:
+ pass
+ self.assertFalse(loop.is_running())
+ os.waitpid(pid, 0)
diff --git a/tests/test_object_marshaling.py b/tests/test_object_marshaling.py
new file mode 100644
index 0000000..624ed9d
--- /dev/null
+++ b/tests/test_object_marshaling.py
@@ -0,0 +1,603 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+import weakref
+import gc
+import sys
+import warnings
+
+from gi.repository import GObject
+from gi.repository import GIMarshallingTests
+
+
+class StrongRef(object):
+ # A class that behaves like weakref.ref but holds a strong reference.
+ # This allows re-use of the VFuncsBase by swapping out the ObjectRef
+ # class var with either weakref.ref or StrongRef.
+
+ def __init__(self, obj):
+ self.obj = obj
+
+ def __call__(self):
+ return self.obj
+
+
+class VFuncsBase(GIMarshallingTests.Object):
+ # Class which generically implements the vfuncs used for reference counting tests
+ # in a way that can be easily sub-classed and modified.
+
+ #: Object type used by this class for testing
+ #: This can be GObject.Object or GObject.InitiallyUnowned
+ Object = GObject.Object
+
+ #: Reference type used by this class for holding refs to in/out objects.
+ #: This can be set to weakref.ref or StrongRef
+ ObjectRef = weakref.ref
+
+ def __init__(self):
+ super(VFuncsBase, self).__init__()
+
+ #: Hold ref of input or output python wrappers
+ self.object_ref = None
+
+ #: store grefcount of input object
+ self.in_object_grefcount = None
+ self.in_object_is_floating = None
+
+ def do_vfunc_return_object_transfer_none(self):
+ # Return an object but keep a python reference to it.
+ obj = self.Object()
+ self.object_ref = self.ObjectRef(obj)
+ return obj
+
+ def do_vfunc_return_object_transfer_full(self):
+ # Return an object and hand off the reference to the caller.
+ obj = self.Object()
+ self.object_ref = self.ObjectRef(obj)
+ return obj
+
+ def do_vfunc_out_object_transfer_none(self):
+ # Same as do_vfunc_return_object_transfer_none but the pygi
+ # internals convert the return here into an out arg.
+ obj = self.Object()
+ self.object_ref = self.ObjectRef(obj)
+ return obj
+
+ def do_vfunc_out_object_transfer_full(self):
+ # Same as do_vfunc_return_object_transfer_full but the pygi
+ # internals convert the return here into an out arg.
+ obj = self.Object()
+ self.object_ref = self.ObjectRef(obj)
+ return obj
+
+ def do_vfunc_in_object_transfer_none(self, obj):
+ # 'obj' will have a python wrapper as well as still held
+ # by the caller.
+ self.object_ref = self.ObjectRef(obj)
+ self.in_object_grefcount = obj.__grefcount__
+ self.in_object_is_floating = obj.is_floating()
+
+ def do_vfunc_in_object_transfer_full(self, obj):
+ # 'obj' will now be owned by the Python GObject wrapper.
+ # When obj goes out of scope and is collected, the GObject
+ # should also be fully released.
+ self.object_ref = self.ObjectRef(obj)
+ self.in_object_grefcount = obj.__grefcount__
+ self.in_object_is_floating = obj.is_floating()
+
+
+class TestVFuncsWithObjectArg(unittest.TestCase):
+ # Basic set of tests which work on non-floating objects which python does
+ # not keep an additional reference of.
+
+ class VFuncs(VFuncsBase):
+ # Object for testing non-floating objects without holding any refs.
+ Object = GObject.Object
+ ObjectRef = weakref.ref
+
+ def test_vfunc_self_arg_ref_count(self):
+ # Check to make sure vfunc "self" arguments don't leak.
+ vfuncs = self.VFuncs()
+ vfuncs_ref = weakref.ref(vfuncs)
+ vfuncs.get_ref_info_for_vfunc_return_object_transfer_full() # Use any vfunc to test this.
+
+ gc.collect()
+ self.assertEqual(sys.getrefcount(vfuncs), 2)
+ self.assertEqual(vfuncs.__grefcount__, 1)
+
+ del vfuncs
+ gc.collect()
+ self.assertTrue(vfuncs_ref() is None)
+
+ def test_vfunc_return_object_transfer_none(self):
+ # This tests a problem case where the vfunc returns a GObject owned solely by Python
+ # but the argument is marked as transfer-none.
+ # In this case pygobject marshaling adds an additional ref and gives a warning
+ # of a potential leak. If this occures it is really a bug in the underlying library
+ # but pygobject tries to react to this in a reasonable way.
+ vfuncs = self.VFuncs()
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_none()
+ self.assertTrue(issubclass(warn[0].category, RuntimeWarning))
+
+ # The ref count of the GObject returned to the caller (get_ref_info_for_vfunc_return_object_transfer_none)
+ # should be a single floating ref
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_out_object_transfer_none(self):
+ # Same as above except uses out arg instead of return
+ vfuncs = self.VFuncs()
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_none()
+ self.assertTrue(issubclass(warn[0].category, RuntimeWarning))
+
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_return_object_transfer_full(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_return_object_transfer_full()
+
+ # The vfunc caller receives full ownership of a single ref which should not
+ # be floating.
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_out_object_transfer_full(self):
+ # Same as above except uses out arg instead of return
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_full()
+
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_in_object_transfer_none(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_none(self.VFuncs.Object)
+
+ gc.collect()
+ self.assertEqual(vfuncs.in_object_grefcount, 2) # initial + python wrapper
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ self.assertEqual(ref_count, 1) # ensure python wrapper released
+ self.assertFalse(is_floating)
+
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_in_object_transfer_full(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_full(self.VFuncs.Object)
+
+ gc.collect()
+
+ # python wrapper should take sole ownership of the gobject
+ self.assertEqual(vfuncs.in_object_grefcount, 1)
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ # ensure python wrapper took ownership and released, after vfunc was complete
+ self.assertEqual(ref_count, 0)
+ self.assertFalse(is_floating)
+
+ self.assertTrue(vfuncs.object_ref() is None)
+
+
+class TestVFuncsWithFloatingArg(unittest.TestCase):
+ # All tests here work with a floating object by using InitiallyUnowned as the argument
+
+ class VFuncs(VFuncsBase):
+ # Object for testing non-floating objects without holding any refs.
+ Object = GObject.InitiallyUnowned
+ ObjectRef = weakref.ref
+
+ def test_vfunc_return_object_transfer_none_with_floating(self):
+ # Python is expected to return a single floating reference without warning.
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_return_object_transfer_none()
+
+ # The ref count of the GObject returned to the caller (get_ref_info_for_vfunc_return_object_transfer_none)
+ # should be a single floating ref
+ self.assertEqual(ref_count, 1)
+ self.assertTrue(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_out_object_transfer_none_with_floating(self):
+ # Same as above except uses out arg instead of return
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_none()
+
+ self.assertEqual(ref_count, 1)
+ self.assertTrue(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_return_object_transfer_full_with_floating(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_return_object_transfer_full()
+
+ # The vfunc caller receives full ownership of a single ref.
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_out_object_transfer_full_with_floating(self):
+ # Same as above except uses out arg instead of return
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_full()
+
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ gc.collect()
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_in_object_transfer_none_with_floating(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_none(self.VFuncs.Object)
+
+ gc.collect()
+
+ # python wrapper should maintain the object as floating and add an additional ref
+ self.assertEqual(vfuncs.in_object_grefcount, 2)
+ self.assertTrue(vfuncs.in_object_is_floating)
+
+ # vfunc caller should only have a single floating ref after the vfunc finishes
+ self.assertEqual(ref_count, 1)
+ self.assertTrue(is_floating)
+
+ self.assertTrue(vfuncs.object_ref() is None)
+
+ def test_vfunc_in_object_transfer_full_with_floating(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_full(self.VFuncs.Object)
+
+ gc.collect()
+
+ # python wrapper sinks and owns the gobject
+ self.assertEqual(vfuncs.in_object_grefcount, 1)
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ # ensure python wrapper took ownership and released
+ self.assertEqual(ref_count, 0)
+ self.assertFalse(is_floating)
+
+ self.assertTrue(vfuncs.object_ref() is None)
+
+
+class TestVFuncsWithHeldObjectArg(unittest.TestCase):
+ # Same tests as TestVFuncsWithObjectArg except we hold
+ # onto the python object reference in all cases.
+
+ class VFuncs(VFuncsBase):
+ # Object for testing non-floating objects with a held ref.
+ Object = GObject.Object
+ ObjectRef = StrongRef
+
+ def test_vfunc_return_object_transfer_none_with_held_object(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_return_object_transfer_none()
+
+ # Python holds the single gobject ref in 'vfuncs.object_ref'
+ # Because of this, we do not expect a floating ref or a ref increase.
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ # The actual grefcount should stay at 1 even after the vfunc return.
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref)
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_out_object_transfer_none_with_held_object(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_none()
+
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref)
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_return_object_transfer_full_with_held_object(self):
+ # The vfunc caller receives full ownership which should not
+ # be floating. However, the held python wrapper also has a ref.
+
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_return_object_transfer_full()
+
+ # Ref count from the perspective of C after the vfunc is called
+ # The vfunc caller receives a new reference which should not
+ # be floating. However, the held python wrapper also has a ref.
+ self.assertEqual(ref_count, 2)
+ self.assertFalse(is_floating)
+
+ # Current ref count
+ # The vfunc caller should have decremented its reference.
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref)
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_out_object_transfer_full_with_held_object(self):
+ # Same test as above except uses out arg instead of return
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_full()
+
+ # Ref count from the perspective of C after the vfunc is called
+ # The vfunc caller receives a new reference which should not
+ # be floating. However, the held python wrapper also has a ref.
+ self.assertEqual(ref_count, 2)
+ self.assertFalse(is_floating)
+
+ # Current ref count
+ # The vfunc caller should have decremented its reference.
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref())
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_in_object_transfer_none_with_held_object(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_none(self.VFuncs.Object)
+
+ gc.collect()
+
+ # Ref count inside vfunc from the perspective of Python
+ self.assertEqual(vfuncs.in_object_grefcount, 2) # initial + python wrapper
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ # Ref count from the perspective of C after the vfunc is called
+ self.assertEqual(ref_count, 2) # kept after vfunc + held python wrapper
+ self.assertFalse(is_floating)
+
+ # Current ref count after C cleans up its reference
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref())
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_in_object_transfer_full_with_held_object(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_full(self.VFuncs.Object)
+
+ gc.collect()
+
+ # Ref count inside vfunc from the perspective of Python
+ self.assertEqual(vfuncs.in_object_grefcount, 1) # python wrapper takes ownership of the gobject
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ # Ref count from the perspective of C after the vfunc is called
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ # Current ref count
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref())
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+
+class TestVFuncsWithHeldFloatingArg(unittest.TestCase):
+ # Tests for a floating object which we hold a reference to the python wrapper
+ # on the VFuncs test class.
+
+ class VFuncs(VFuncsBase):
+ # Object for testing floating objects with a held ref.
+ Object = GObject.InitiallyUnowned
+ ObjectRef = StrongRef
+
+ def test_vfunc_return_object_transfer_none_with_held_floating(self):
+ # Python holds onto the wrapper which basically means the floating ref
+ # should also be owned by python.
+
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_return_object_transfer_none()
+
+ # This is a borrowed ref from what is held in python.
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ # The actual grefcount should stay at 1 even after the vfunc return.
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref)
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_out_object_transfer_none_with_held_floating(self):
+ # Same as above
+
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_none()
+
+ self.assertEqual(ref_count, 1)
+ self.assertFalse(is_floating)
+
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref)
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_return_object_transfer_full_with_held_floating(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_return_object_transfer_full()
+
+ # Ref count from the perspective of C after the vfunc is called
+ self.assertEqual(ref_count, 2)
+ self.assertFalse(is_floating)
+
+ # Current ref count
+ # vfunc wrapper destroyes ref it was given
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref)
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_out_object_transfer_full_with_held_floating(self):
+ # Same test as above except uses out arg instead of return
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_out_object_transfer_full()
+
+ # Ref count from the perspective of C after the vfunc is called
+ self.assertEqual(ref_count, 2)
+ self.assertFalse(is_floating)
+
+ # Current ref count
+ # vfunc wrapper destroyes ref it was given
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref())
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_in_floating_transfer_none_with_held_floating(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_none(self.VFuncs.Object)
+ gc.collect()
+
+ # Ref count inside vfunc from the perspective of Python
+ self.assertTrue(vfuncs.in_object_is_floating)
+ self.assertEqual(vfuncs.in_object_grefcount, 2) # python wrapper sinks and owns the gobject
+
+ # Ref count from the perspective of C after the vfunc is called
+ self.assertTrue(is_floating)
+ self.assertEqual(ref_count, 2) # floating + held by wrapper
+
+ # Current ref count after C cleans up its reference
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref())
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+ def test_vfunc_in_floating_transfer_full_with_held_floating(self):
+ vfuncs = self.VFuncs()
+ ref_count, is_floating = vfuncs.get_ref_info_for_vfunc_in_object_transfer_full(self.VFuncs.Object)
+ gc.collect()
+
+ # Ref count from the perspective of C after the vfunc is called
+ self.assertEqual(vfuncs.in_object_grefcount, 1) # python wrapper sinks and owns the gobject
+ self.assertFalse(vfuncs.in_object_is_floating)
+
+ # Ref count from the perspective of C after the vfunc is called
+ self.assertEqual(ref_count, 1) # held by wrapper
+ self.assertFalse(is_floating)
+
+ # Current ref count
+ self.assertEqual(vfuncs.object_ref().__grefcount__, 1)
+
+ held_object_ref = weakref.ref(vfuncs.object_ref())
+ del vfuncs.object_ref
+ gc.collect()
+ self.assertTrue(held_object_ref() is None)
+
+
+class TestPropertyHoldingObject(unittest.TestCase):
+ def test_props_getter_holding_object_ref_count(self):
+ holder = GIMarshallingTests.PropertiesObject()
+ held = GObject.Object()
+
+ self.assertEqual(holder.__grefcount__, 1)
+ self.assertEqual(held.__grefcount__, 1)
+
+ holder.set_property('some-object', held)
+ self.assertEqual(holder.__grefcount__, 1)
+
+ initial_ref_count = held.__grefcount__
+ holder.props.some_object
+ gc.collect()
+ self.assertEqual(held.__grefcount__, initial_ref_count)
+
+ def test_get_property_holding_object_ref_count(self):
+ holder = GIMarshallingTests.PropertiesObject()
+ held = GObject.Object()
+
+ self.assertEqual(holder.__grefcount__, 1)
+ self.assertEqual(held.__grefcount__, 1)
+
+ holder.set_property('some-object', held)
+ self.assertEqual(holder.__grefcount__, 1)
+
+ initial_ref_count = held.__grefcount__
+ holder.get_property('some-object')
+ gc.collect()
+ self.assertEqual(held.__grefcount__, initial_ref_count)
+
+ def test_props_setter_holding_object_ref_count(self):
+ holder = GIMarshallingTests.PropertiesObject()
+ held = GObject.Object()
+
+ self.assertEqual(holder.__grefcount__, 1)
+ self.assertEqual(held.__grefcount__, 1)
+
+ # Setting property should only increase ref count by 1
+ holder.props.some_object = held
+ self.assertEqual(holder.__grefcount__, 1)
+ self.assertEqual(held.__grefcount__, 2)
+
+ # Clearing should pull it back down
+ holder.props.some_object = None
+ self.assertEqual(held.__grefcount__, 1)
+
+ def test_set_property_holding_object_ref_count(self):
+ holder = GIMarshallingTests.PropertiesObject()
+ held = GObject.Object()
+
+ self.assertEqual(holder.__grefcount__, 1)
+ self.assertEqual(held.__grefcount__, 1)
+
+ # Setting property should only increase ref count by 1
+ holder.set_property('some-object', held)
+ self.assertEqual(holder.__grefcount__, 1)
+ self.assertEqual(held.__grefcount__, 2)
+
+ # Clearing should pull it back down
+ holder.set_property('some-object', None)
+ self.assertEqual(held.__grefcount__, 1)
+
+ def test_set_object_property_to_invalid_type(self):
+ obj = GIMarshallingTests.PropertiesObject()
+ self.assertRaises(TypeError, obj.set_property, 'some-object', 'not_an_object')
diff --git a/tests/test_option.py b/tests/test_option.py
index 9233eed..2900edd 100644
--- a/tests/test_option.py
+++ b/tests/test_option.py
@@ -6,23 +6,21 @@ import sys
# py3k has StringIO in a different module
try:
from StringIO import StringIO
+ StringIO # pyflakes
except ImportError:
from io import StringIO
-# FIXME: we need a way to import the options module from a public module
-from gi._glib.option import OptionParser, OptionGroup, OptionValueError, \
- make_option, BadOptionError
+from gi.repository import GLib
-from compathelper import _bytes
class TestOption(unittest.TestCase):
EXCEPTION_MESSAGE = "This callback fails"
def setUp(self):
- self.parser = OptionParser("NAMES...",
- description="Option unit test")
+ self.parser = GLib.option.OptionParser("NAMES...",
+ description="Option unit test")
self.parser.add_option("-t", "--test", help="Unit test option",
- action="store_false", dest="test", default=True)
+ action="store_false", dest="test", default=True)
self.parser.add_option("--g-fatal-warnings",
action="store_true",
dest="fatal_warnings",
@@ -32,22 +30,22 @@ class TestOption(unittest.TestCase):
def option_callback(option, opt, value, parser):
raise Exception(self.EXCEPTION_MESSAGE)
- group = OptionGroup(
+ group = GLib.option.OptionGroup(
"unittest", "Unit test options", "Show all unittest options",
- option_list = [
- make_option("-f", "-u", "--file", "--unit-file",
- type="filename",
- dest="unit_file",
- help="Unit test option"),
- make_option("--test-integer",
- type="int",
- dest="test_integer",
- help="Unit integer option"),
- make_option("--callback-failure-test",
- action="callback",
- callback=option_callback,
- dest="test_integer",
- help="Unit integer option"),
+ option_list=[
+ GLib.option.make_option("-f", "-u", "--file", "--unit-file",
+ type="filename",
+ dest="unit_file",
+ help="Unit test option"),
+ GLib.option.make_option("--test-integer",
+ type="int",
+ dest="test_integer",
+ help="Unit integer option"),
+ GLib.option.make_option("--callback-failure-test",
+ action="callback",
+ callback=option_callback,
+ dest="test_integer",
+ help="Unit integer option"),
])
group.add_option("-t", "--test",
action="store_false",
@@ -57,55 +55,52 @@ class TestOption(unittest.TestCase):
self.parser.add_option_group(group)
return group
- def testParseArgs(self):
+ def test_parse_args(self):
options, args = self.parser.parse_args(
["test_option.py"])
- self.failIf(args)
+ self.assertFalse(args)
options, args = self.parser.parse_args(
["test_option.py", "foo"])
- self.assertEquals(args, ["foo"])
+ self.assertEqual(args, [])
options, args = self.parser.parse_args(
["test_option.py", "foo", "bar"])
- self.assertEquals(args, ["foo", "bar"])
+ self.assertEqual(args, [])
- def testParseArgsDoubleDash(self):
+ def test_parse_args_double_dash(self):
options, args = self.parser.parse_args(
["test_option.py", "--", "-xxx"])
- #self.assertEquals(args, ["-xxx"])
+ #self.assertEqual(args, ["-xxx"])
- def testParseArgs(self):
- options, args = self.parser.parse_args()
-
- def testParseArgsGroup(self):
+ def test_parse_args_group(self):
group = self._create_group()
options, args = self.parser.parse_args(
["test_option.py", "--test", "-f", "test"])
- self.failIf(options.test)
+ self.assertFalse(options.test)
self.assertEqual(options.unit_file, "test")
- self.failUnless(group.values.test)
- self.failIf(self.parser.values.test)
+ self.assertTrue(group.values.test)
+ self.assertFalse(self.parser.values.test)
self.assertEqual(group.values.unit_file, "test")
- self.failIf(args)
+ self.assertFalse(args)
- def testOptionValueError(self):
+ def test_option_value_error(self):
self._create_group()
- self.assertRaises(OptionValueError, self.parser.parse_args,
+ self.assertRaises(GLib.option.OptionValueError, self.parser.parse_args,
["test_option.py", "--test-integer=text"])
- def testBadOptionError(self):
- self.assertRaises(BadOptionError,
+ def test_bad_option_error(self):
+ self.assertRaises(GLib.option.BadOptionError,
self.parser.parse_args,
["test_option.py", "--unknwon-option"])
- def testOptionGroupConstructor(self):
- self.assertRaises(TypeError, OptionGroup)
+ def test_option_group_constructor(self):
+ self.assertRaises(TypeError, GLib.option.OptionGroup)
- def testStandardError(self):
+ def test_standard_error(self):
self._create_group()
sio = StringIO()
old_stderr = sys.stderr
@@ -118,4 +113,3 @@ class TestOption(unittest.TestCase):
assert (sio.getvalue().split('\n')[-2] ==
"Exception: " + self.EXCEPTION_MESSAGE)
-
diff --git a/tests/test_overrides.py b/tests/test_overrides.py
index 78e589f..e1af1f1 100644
--- a/tests/test_overrides.py
+++ b/tests/test_overrides.py
@@ -3,1959 +3,56 @@
import unittest
-import sys
-import os
-sys.path.insert(0, "../")
+import gi.overrides
+import gi.module
-from compathelper import _long, _unicode, _bytes
+try:
+ from gi.repository import Regress
+ Regress # pyflakes
+except ImportError:
+ Regress = None
-os.environ['GSETTINGS_BACKEND'] = 'memory'
-# support a separate build tree, so look in build dir first
-os.environ['GSETTINGS_SCHEMA_DIR'] = os.environ.get('TESTS_BUILDDIR',
- os.path.dirname(__file__))
-from gi.repository import GLib
-from gi.repository import GObject
-from gi.repository import Gdk
-from gi.repository import Gtk
-from gi.repository import Gio
-from gi.repository import Pango
-from gi.repository import GdkPixbuf
-import gi.overrides as overrides
-import gi.types
-
-# in general we don't want tests to raise warnings, except when explicitly
-# testing with bad values; in those cases it will temporarily be set back to
-# ERROR
-GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_WARNING)
-
-class TestGLib(unittest.TestCase):
-
- def test_gvariant_create(self):
- # simple values
-
- variant = GLib.Variant('i', 42)
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertEquals(variant.get_int32(), 42)
-
- variant = GLib.Variant('s', '')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertEquals(variant.get_string(), '')
-
- variant = GLib.Variant('s', 'hello')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertEquals(variant.get_string(), 'hello')
-
- # boxed variant
- variant = GLib.Variant('v', GLib.Variant('i', 42))
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertTrue(isinstance(variant.get_variant(), GLib.Variant))
- self.assertEqual(variant.get_type_string(), 'v')
- self.assertEqual(variant.get_variant().get_type_string(), 'i')
- self.assertEquals(variant.get_variant().get_int32(), 42)
-
- variant = GLib.Variant('v', GLib.Variant('v', GLib.Variant('i', 42)))
- self.assertEqual(variant.get_type_string(), 'v')
- self.assertEqual(variant.get_variant().get_type_string(), 'v')
- self.assertEqual(variant.get_variant().get_variant().get_type_string(), 'i')
- self.assertEquals(variant.get_variant().get_variant().get_int32(), 42)
-
- # tuples
-
- variant = GLib.Variant('()', ())
- self.assertEqual(variant.get_type_string(), '()')
- self.assertEquals(variant.n_children(), 0)
-
- variant = GLib.Variant('(i)', (3,))
- self.assertEqual(variant.get_type_string(), '(i)')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertEquals(variant.n_children(), 1)
- self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
- self.assertEquals(variant.get_child_value(0).get_int32(), 3)
-
- variant = GLib.Variant('(ss)', ('mec', 'mac'))
- self.assertEqual(variant.get_type_string(), '(ss)')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
- self.assertEquals(variant.get_child_value(0).get_string(), 'mec')
- self.assertEquals(variant.get_child_value(1).get_string(), 'mac')
-
- # nested tuples
- variant = GLib.Variant('((si)(ub))', (('hello', -1), (42, True)))
- self.assertEqual(variant.get_type_string(), '((si)(ub))')
- self.assertEqual(variant.unpack(), (('hello', -1), (_long(42), True)))
-
- # dictionaries
-
- variant = GLib.Variant('a{si}', {})
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertEqual(variant.get_type_string(), 'a{si}')
- self.assertEquals(variant.n_children(), 0)
-
- variant = GLib.Variant('a{si}', {'': 1, 'key1': 2, 'key2': 3})
- self.assertEqual(variant.get_type_string(), 'a{si}')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(2), GLib.Variant))
- self.assertEqual(variant.unpack(), {'': 1, 'key1': 2, 'key2': 3})
-
- # nested dictionaries
- variant = GLib.Variant('a{sa{si}}', {})
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertEqual(variant.get_type_string(), 'a{sa{si}}')
- self.assertEquals(variant.n_children(), 0)
-
- d = {'': {'': 1, 'keyn1': 2},
- 'key1': {'key11': 11, 'key12': 12}}
- variant = GLib.Variant('a{sa{si}}', d)
- self.assertEqual(variant.get_type_string(), 'a{sa{si}}')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertEqual(variant.unpack(), d)
-
- # arrays
-
- variant = GLib.Variant('ai', [])
- self.assertEqual(variant.get_type_string(), 'ai')
- self.assertEquals(variant.n_children(), 0)
-
- variant = GLib.Variant('ai', [1, 2])
- self.assertEqual(variant.get_type_string(), 'ai')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
- self.assertEquals(variant.get_child_value(0).get_int32(), 1)
- self.assertEquals(variant.get_child_value(1).get_int32(), 2)
-
- variant = GLib.Variant('as', [])
- self.assertEqual(variant.get_type_string(), 'as')
- self.assertEquals(variant.n_children(), 0)
-
- variant = GLib.Variant('as', [''])
- self.assertEqual(variant.get_type_string(), 'as')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
- self.assertEquals(variant.get_child_value(0).get_string(), '')
-
- variant = GLib.Variant('as', ['hello', 'world'])
- self.assertEqual(variant.get_type_string(), 'as')
- self.assertTrue(isinstance(variant, GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
- self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
- self.assertEquals(variant.get_child_value(0).get_string(), 'hello')
- self.assertEquals(variant.get_child_value(1).get_string(), 'world')
-
- # nested arrays
- variant = GLib.Variant('aai', [])
- self.assertEqual(variant.get_type_string(), 'aai')
- self.assertEquals(variant.n_children(), 0)
-
- variant = GLib.Variant('aai', [[]])
- self.assertEqual(variant.get_type_string(), 'aai')
- self.assertEquals(variant.n_children(), 1)
- self.assertEquals(variant.get_child_value(0).n_children(), 0)
-
- variant = GLib.Variant('aai', [[1, 2], [3, 4, 5]])
- self.assertEqual(variant.get_type_string(), 'aai')
- self.assertEquals(variant.unpack(), [[1, 2], [3, 4, 5]])
-
- #
- # complex types
- #
-
- variant = GLib.Variant('(as)', ([],))
- self.assertEqual(variant.get_type_string(), '(as)')
- self.assertEquals(variant.n_children(), 1)
- self.assertEquals(variant.get_child_value(0).n_children(), 0)
-
- variant = GLib.Variant('(as)', ([''],))
- self.assertEqual(variant.get_type_string(), '(as)')
- self.assertEquals(variant.n_children(), 1)
- self.assertEquals(variant.get_child_value(0).n_children(), 1)
- self.assertEquals(variant.get_child_value(0).get_child_value(0).get_string(), '')
-
- variant = GLib.Variant('(as)', (['hello'],))
- self.assertEqual(variant.get_type_string(), '(as)')
- self.assertEquals(variant.n_children(), 1)
- self.assertEquals(variant.get_child_value(0).n_children(), 1)
- self.assertEquals(variant.get_child_value(0).get_child_value(0).get_string(), 'hello')
-
- obj = {'a1': (1, True), 'a2': (2, False)}
- variant = GLib.Variant('a{s(ib)}', obj)
- self.assertEqual(variant.get_type_string(), 'a{s(ib)}')
- self.assertEqual(variant.unpack(), obj)
-
- obj = {'a1': (1, GLib.Variant('b', True)), 'a2': (2, GLib.Variant('y', 255))}
- variant = GLib.Variant('a{s(iv)}', obj)
- self.assertEqual(variant.get_type_string(), 'a{s(iv)}')
- self.assertEqual(variant.unpack(), {'a1': (1, True), 'a2': (2, 255)})
-
- obj = (1, {'a': {'a1': True, 'a2': False},
- 'b': {'b1': False},
- 'c': {}
- },
- 'foo')
- variant = GLib.Variant('(ia{sa{sb}}s)', obj)
- self.assertEqual(variant.get_type_string(), '(ia{sa{sb}}s)')
- self.assertEqual(variant.unpack(), obj)
-
- obj = {"frequency": GLib.Variant('t', 738000000),
- "hierarchy": GLib.Variant('i', 0),
- "bandwidth": GLib.Variant('x', 8),
- "code-rate-hp": GLib.Variant('d', 2.0/3.0),
- "constellation": GLib.Variant('s', "QAM16"),
- "guard-interval": GLib.Variant('u', 4),}
- variant = GLib.Variant('a{sv}', obj)
- self.assertEqual(variant.get_type_string(), 'a{sv}')
- self.assertEqual(variant.unpack(), {"frequency": 738000000,
- "hierarchy": 0,
- "bandwidth": 8,
- "code-rate-hp": 2.0/3.0,
- "constellation": "QAM16",
- "guard-interval": 4})
-
- def test_gvariant_create_errors(self):
- # excess arguments
- self.assertRaises(TypeError, GLib.Variant, 'i', 42, 3)
- self.assertRaises(TypeError, GLib.Variant, '(i)', (42, 3))
-
- # not enough arguments
- self.assertRaises(TypeError, GLib.Variant, '(ii)', (42,))
-
- # data type mismatch
- self.assertRaises(TypeError, GLib.Variant, 'i', 'hello')
- self.assertRaises(TypeError, GLib.Variant, 's', 42)
- self.assertRaises(TypeError, GLib.Variant, '(ss)', 'mec', 'mac')
-
- # unimplemented data type
- self.assertRaises(NotImplementedError, GLib.Variant, 'Q', 1)
-
- def test_gvariant_unpack(self):
- # simple values
- res = GLib.Variant.new_int32(-42).unpack()
- self.assertEqual(res, -42)
-
- res = GLib.Variant.new_uint64(34359738368).unpack()
- self.assertEqual(res, 34359738368)
-
- res = GLib.Variant.new_boolean(True).unpack()
- self.assertEqual(res, True)
-
- res = GLib.Variant.new_object_path('/foo/Bar').unpack()
- self.assertEqual(res, '/foo/Bar')
-
- # variant
- res = GLib.Variant('v', GLib.Variant.new_int32(-42)).unpack()
- self.assertEqual(res, -42)
-
- variant = GLib.Variant('v', GLib.Variant('v', GLib.Variant('i', 42)))
- self.assertEqual(res, -42)
-
- # tuple
- res = GLib.Variant.new_tuple(GLib.Variant.new_int32(-1),
- GLib.Variant.new_string('hello')).unpack()
- self.assertEqual(res, (-1, 'hello'))
-
- # array
- vb = GLib.VariantBuilder.new(gi._gi.variant_type_from_string('ai'))
- vb.add_value(GLib.Variant.new_int32(-1))
- vb.add_value(GLib.Variant.new_int32(3))
- res = vb.end().unpack()
- self.assertEqual(res, [-1, 3])
-
- # dictionary
- res = GLib.Variant('a{si}', {'key1': 1, 'key2': 2}).unpack()
- self.assertEqual(res, {'key1': 1, 'key2': 2})
-
- def test_gvariant_iteration(self):
- # array index access
- vb = GLib.VariantBuilder.new(gi._gi.variant_type_from_string('ai'))
- vb.add_value(GLib.Variant.new_int32(-1))
- vb.add_value(GLib.Variant.new_int32(3))
- v = vb.end()
-
- self.assertEqual(len(v), 2)
- self.assertEqual(v[0], -1)
- self.assertEqual(v[1], 3)
- self.assertEqual(v[-1], 3)
- self.assertEqual(v[-2], -1)
- self.assertRaises(IndexError, v.__getitem__, 2)
- self.assertRaises(IndexError, v.__getitem__, -3)
- self.assertRaises(ValueError, v.__getitem__, 'a')
-
- # array iteration
- self.assertEqual([x for x in v], [-1, 3])
- self.assertEqual(list(v), [-1, 3])
-
- # tuple index access
- v = GLib.Variant.new_tuple(GLib.Variant.new_int32(-1),
- GLib.Variant.new_string('hello'))
- self.assertEqual(len(v), 2)
- self.assertEqual(v[0], -1)
- self.assertEqual(v[1], 'hello')
- self.assertEqual(v[-1], 'hello')
- self.assertEqual(v[-2], -1)
- self.assertRaises(IndexError, v.__getitem__, 2)
- self.assertRaises(IndexError, v.__getitem__, -3)
- self.assertRaises(ValueError, v.__getitem__, 'a')
-
- # tuple iteration
- self.assertEqual([x for x in v], [-1, 'hello'])
- self.assertEqual(tuple(v), (-1, 'hello'))
-
- # dictionary index access
- vsi = GLib.Variant('a{si}', {'key1': 1, 'key2': 2})
- vis = GLib.Variant('a{is}', {1: 'val1', 5: 'val2'})
-
- self.assertEqual(len(vsi), 2)
- self.assertEqual(vsi['key1'], 1)
- self.assertEqual(vsi['key2'], 2)
- self.assertRaises(KeyError, vsi.__getitem__, 'unknown')
-
- self.assertEqual(len(vis), 2)
- self.assertEqual(vis[1], 'val1')
- self.assertEqual(vis[5], 'val2')
- self.assertRaises(KeyError, vsi.__getitem__, 3)
-
- # dictionary iteration
- self.assertEqual(set(vsi.keys()), set(['key1', 'key2']))
- self.assertEqual(set(vis.keys()), set([1, 5]))
-
- # string index access
- v = GLib.Variant('s', 'hello')
- self.assertEqual(len(v), 5)
- self.assertEqual(v[0], 'h')
- self.assertEqual(v[4], 'o')
- self.assertEqual(v[-1], 'o')
- self.assertEqual(v[-5], 'h')
- self.assertRaises(IndexError, v.__getitem__, 5)
- self.assertRaises(IndexError, v.__getitem__, -6)
-
- # string iteration
- self.assertEqual([x for x in v], ['h', 'e', 'l', 'l', 'o'])
-
- def test_variant_split_signature(self):
- self.assertEqual(GLib.Variant.split_signature('()'), [])
-
- self.assertEqual(GLib.Variant.split_signature('s'), ['s'])
-
- self.assertEqual(GLib.Variant.split_signature('as'), ['as'])
-
- self.assertEqual(GLib.Variant.split_signature('(s)'), ['s'])
-
- self.assertEqual(GLib.Variant.split_signature('(iso)'), ['i', 's', 'o'])
-
- self.assertEqual(GLib.Variant.split_signature('(s(ss)i(ii))'),
- ['s', '(ss)', 'i', '(ii)'])
-
- self.assertEqual(GLib.Variant.split_signature('(as)'), ['as'])
-
- self.assertEqual(GLib.Variant.split_signature('(s(ss)iaiaasa(ii))'),
- ['s', '(ss)', 'i', 'ai', 'aas', 'a(ii)'])
-
- self.assertEqual(GLib.Variant.split_signature('(a{iv}(ii)((ss)a{s(ss)}))'),
- ['a{iv}', '(ii)', '((ss)a{s(ss)})'])
-
- def test_variant_hash(self):
- v1 = GLib.Variant('s', 'somestring')
- v2 = GLib.Variant('s', 'somestring')
- v3 = GLib.Variant('s', 'somestring2')
-
- self.assertTrue(v2 in set([v1, v3]))
- self.assertTrue(v2 in frozenset([v1, v3]))
- self.assertTrue(v2 in {v1: '1', v3:'2' })
-
- def test_variant_compare(self):
- # Check if identical GVariant are equal
-
- def assert_equal(vtype, value):
- self.assertEqual(GLib.Variant(vtype, value), GLib.Variant(vtype, value))
-
- def assert_not_equal(vtype1, value1, vtype2, value2):
- self.assertNotEqual(GLib.Variant(vtype1, value1), GLib.Variant(vtype2, value2))
-
- numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
- for num in numbers:
- assert_equal(num, 42)
- assert_not_equal(num, 42, num, 41)
- assert_not_equal(num, 42, 's', '42')
-
- assert_equal('s', 'something')
- assert_not_equal('s', 'something', 's', 'somethingelse')
- assert_not_equal('s', 'something', 'i', 1234)
-
- assert_equal('g', 'dustybinqhogx')
- assert_not_equal('g', 'dustybinqhogx', 'g', 'dustybin')
- assert_not_equal('g', 'dustybinqhogx', 'i', 1234)
-
- assert_equal('o', '/dev/null')
- assert_not_equal('o', '/dev/null', 'o', '/dev/zero')
- assert_not_equal('o', '/dev/null', 'i', 1234)
-
- assert_equal('(s)', ('strtuple',))
- assert_not_equal('(s)', ('strtuple',), '(s)', ('strtuple2',))
-
- assert_equal('a{si}', {'str': 42})
- assert_not_equal('a{si}', {'str': 42}, 'a{si}', {'str': 43})
-
- assert_equal('v', GLib.Variant('i', 42))
- assert_not_equal('v', GLib.Variant('i', 42), 'v', GLib.Variant('i', 43))
-
- def test_variant_bool(self):
- # Check if the GVariant bool matches the unpacked Pythonic bool
-
- def assert_equals_bool(vtype, value):
- self.assertEqual(bool(GLib.Variant(vtype, value)), bool(value))
-
- # simple values
- assert_equals_bool('b', True)
- assert_equals_bool('b', False)
-
- numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
- for number in numbers:
- assert_equals_bool(number, 0)
- assert_equals_bool(number, 1)
-
- assert_equals_bool('s', '')
- assert_equals_bool('g', '')
- assert_equals_bool('s', 'something')
- assert_equals_bool('o', '/dev/null')
- assert_equals_bool('g', 'dustybinqhogx')
-
- # arrays
- assert_equals_bool('ab', [True])
- assert_equals_bool('ab', [False])
- for number in numbers:
- assert_equals_bool('a'+number, [])
- assert_equals_bool('a'+number, [0])
- assert_equals_bool('as', [])
- assert_equals_bool('as', [''])
- assert_equals_bool('ao', [])
- assert_equals_bool('ao', ['/'])
- assert_equals_bool('ag', [])
- assert_equals_bool('ag', [''])
- assert_equals_bool('aai', [[]])
-
- # tuples
- assert_equals_bool('()', ())
- for number in numbers:
- assert_equals_bool('('+number+')', (0,))
- assert_equals_bool('(s)', ('',))
- assert_equals_bool('(o)', ('/',))
- assert_equals_bool('(g)', ('',))
- assert_equals_bool('(())', ((),))
-
- # dictionaries
- assert_equals_bool('a{si}', {})
- assert_equals_bool('a{si}', {'': 0})
-
- # complex types, always True
- assert_equals_bool('(as)', ([],))
- assert_equals_bool('a{s(i)}', {'': (0,)})
-
- # variant types, recursive unpacking
- assert_equals_bool('v', GLib.Variant('i', 0))
- assert_equals_bool('v', GLib.Variant('i', 1))
-
-class TestPango(unittest.TestCase):
-
- def test_default_font_description(self):
- desc = Pango.FontDescription()
- self.assertEquals(desc.get_variant(), Pango.Variant.NORMAL)
-
- def test_font_description(self):
- desc = Pango.FontDescription('monospace')
- self.assertEquals(desc.get_family(), 'monospace')
- self.assertEquals(desc.get_variant(), Pango.Variant.NORMAL)
-
- def test_layout(self):
- self.assertRaises(TypeError, Pango.Layout)
- context = Pango.Context()
- layout = Pango.Layout(context)
- self.assertEquals(layout.get_context(), context)
-
- layout.set_markup("Foobar")
- self.assertEquals(layout.get_text(), "Foobar")
-
-
-class TestGdk(unittest.TestCase):
-
- def test_constructor(self):
- attribute = Gdk.WindowAttr()
- attribute.window_type = Gdk.WindowType.CHILD
- attributes_mask = Gdk.WindowAttributesType.X | \
- Gdk.WindowAttributesType.Y
- window = Gdk.Window(None, attribute, attributes_mask)
- self.assertEquals(window.get_window_type(), Gdk.WindowType.CHILD)
-
- def test_color(self):
- color = Gdk.Color(100, 200, 300)
- self.assertEquals(color.red, 100)
- self.assertEquals(color.green, 200)
- self.assertEquals(color.blue, 300)
- self.assertEquals(color, Gdk.Color(100, 200, 300))
- self.assertNotEquals(color, Gdk.Color(1, 2, 3))
-
- def test_rgba(self):
- self.assertEquals(Gdk.RGBA, overrides.Gdk.RGBA)
- rgba = Gdk.RGBA(0.1, 0.2, 0.3, 0.4)
- self.assertEquals(rgba, Gdk.RGBA(0.1, 0.2, 0.3, 0.4))
- self.assertNotEquals(rgba, Gdk.RGBA(0.0, 0.2, 0.3, 0.4))
- self.assertEquals(rgba.red, 0.1)
- self.assertEquals(rgba.green, 0.2)
- self.assertEquals(rgba.blue, 0.3)
- self.assertEquals(rgba.alpha, 0.4)
- rgba.green = 0.9
- self.assertEquals(rgba.green, 0.9)
-
- def test_event(self):
- event = Gdk.Event.new(Gdk.EventType.CONFIGURE)
- self.assertEquals(event.type, Gdk.EventType.CONFIGURE)
- self.assertEquals(event.send_event, 0)
-
- event = Gdk.Event.new(Gdk.EventType.DRAG_MOTION)
- event.x_root, event.y_root = 0, 5
- self.assertEquals(event.x_root, 0)
- self.assertEquals(event.y_root, 5)
-
- event = Gdk.Event()
- event.type = Gdk.EventType.SCROLL
- self.assertRaises(AttributeError, lambda: getattr(event, 'foo_bar'))
-
- def test_event_structures(self):
- def button_press_cb(button, event):
- self.assertTrue(isinstance(event, Gdk.EventButton))
- self.assertTrue(event.type == Gdk.EventType.BUTTON_PRESS)
- self.assertEquals(event.send_event, 0)
- self.assertEquals(event.get_state(), Gdk.ModifierType.CONTROL_MASK)
- self.assertEquals(event.get_root_coords(), (2, 5))
-
- event.time = 12345
- self.assertEquals(event.get_time(), 12345)
-
- w = Gtk.Window()
- b = Gtk.Button()
- b.connect('button-press-event', button_press_cb)
- w.add(b)
- w.show_all()
- Gdk.test_simulate_button(b.get_window(),
- 2, 5,
- 0,
- Gdk.ModifierType.CONTROL_MASK,
- Gdk.EventType.BUTTON_PRESS)
-
- def test_cursor(self):
- self.assertEquals(Gdk.Cursor, overrides.Gdk.Cursor)
- c = Gdk.Cursor(Gdk.CursorType.WATCH)
- self.assertNotEqual(c, None)
- c = Gdk.Cursor(cursor_type = Gdk.CursorType.WATCH)
- self.assertNotEqual(c, None)
-
- display_manager = Gdk.DisplayManager.get()
- display = display_manager.get_default_display()
-
- test_pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB,
- False,
- 8,
- 5,
- 10)
-
- c = Gdk.Cursor(display,
- test_pixbuf,
- y=0, x=0)
-
- self.assertNotEqual(c, None)
- self.assertRaises(ValueError, Gdk.Cursor, 1, 2, 3)
-
-class TestGtk(unittest.TestCase):
-
- def test_container(self):
- box = Gtk.Box()
- self.failUnless(isinstance(box, Gtk.Box))
- self.failUnless(isinstance(box, Gtk.Container))
- self.failUnless(isinstance(box, Gtk.Widget))
- self.assertTrue(box)
- label = Gtk.Label()
- label2 = Gtk.Label()
- box.add(label)
- box.add(label2)
- self.assertTrue(label in box)
- self.assertTrue(label2 in box)
- self.assertEqual(len(box), 2)
- self.assertTrue(box)
- l = [x for x in box]
- self.assertEqual(l, [label, label2])
-
- def test_actions(self):
- self.assertEquals(Gtk.Action, overrides.Gtk.Action)
- self.assertRaises(TypeError, Gtk.Action)
- action = Gtk.Action("test", "Test", "Test Action", Gtk.STOCK_COPY)
- self.assertEquals(action.get_name(), "test")
- self.assertEquals(action.get_label(), "Test")
- self.assertEquals(action.get_tooltip(), "Test Action")
- self.assertEquals(action.get_stock_id(), Gtk.STOCK_COPY)
-
- self.assertEquals(Gtk.RadioAction, overrides.Gtk.RadioAction)
- self.assertRaises(TypeError, Gtk.RadioAction)
- action = Gtk.RadioAction("test", "Test", "Test Action", Gtk.STOCK_COPY, 1)
- self.assertEquals(action.get_name(), "test")
- self.assertEquals(action.get_label(), "Test")
- self.assertEquals(action.get_tooltip(), "Test Action")
- self.assertEquals(action.get_stock_id(), Gtk.STOCK_COPY)
- self.assertEquals(action.get_current_value(), 1)
-
- def test_actiongroup(self):
- self.assertEquals(Gtk.ActionGroup, overrides.Gtk.ActionGroup)
- self.assertRaises(TypeError, Gtk.ActionGroup)
-
- action_group = Gtk.ActionGroup (name = 'TestActionGroup')
- callback_data = "callback data"
-
- def test_action_callback_data(action, user_data):
- self.assertEquals(user_data, callback_data);
-
- def test_radio_action_callback_data(action, current, user_data):
- self.assertEquals(user_data, callback_data);
-
- action_group.add_actions ([
- ('test-action1', None, 'Test Action 1',
- None, None, test_action_callback_data),
- ('test-action2', Gtk.STOCK_COPY, 'Test Action 2',
- None, None, test_action_callback_data)], callback_data)
- action_group.add_toggle_actions([
- ('test-toggle-action1', None, 'Test Toggle Action 1',
- None, None, test_action_callback_data, False),
- ('test-toggle-action2', Gtk.STOCK_COPY, 'Test Toggle Action 2',
- None, None, test_action_callback_data, True)], callback_data)
- action_group.add_radio_actions([
- ('test-radio-action1', None, 'Test Radio Action 1'),
- ('test-radio-action2', Gtk.STOCK_COPY, 'Test Radio Action 2')], 1,
- test_radio_action_callback_data,
- callback_data)
-
- expected_results = [('test-action1', Gtk.Action),
- ('test-action2', Gtk.Action),
- ('test-toggle-action1', Gtk.ToggleAction),
- ('test-toggle-action2', Gtk.ToggleAction),
- ('test-radio-action1', Gtk.RadioAction),
- ('test-radio-action2', Gtk.RadioAction)]
-
- for action in action_group.list_actions():
- a = (action.get_name(), type(action))
- self.assertTrue(a in expected_results)
- expected_results.remove(a)
- action.activate()
-
- def test_uimanager(self):
- self.assertEquals(Gtk.UIManager, overrides.Gtk.UIManager)
- ui = Gtk.UIManager()
- ui.add_ui_from_string(
-"""
-<ui>
- <menubar name="menubar1"></menubar>
-</ui>
-"""
-)
- menubar = ui.get_widget("/menubar1")
- self.assertEquals(type(menubar), Gtk.MenuBar)
-
- ag = Gtk.ActionGroup (name="ag1")
- ui.insert_action_group(ag)
- ag2 = Gtk.ActionGroup (name="ag2")
- ui.insert_action_group(ag2)
- groups = ui.get_action_groups()
- self.assertEquals(ag, groups[-2])
- self.assertEquals(ag2, groups[-1])
-
- def test_builder(self):
- self.assertEquals(Gtk.Builder, overrides.Gtk.Builder)
-
- class SignalTest(GObject.GObject):
- __gtype_name__ = "GIOverrideSignalTest"
- __gsignals__ = {
- "test-signal": (GObject.SignalFlags.RUN_FIRST,
- None,
- []),
- }
-
-
- class SignalCheck:
- def __init__(self):
- self.sentinel = 0
- self.after_sentinel = 0;
-
- def on_signal_1(self, *args):
- self.sentinel += 1
- self.after_sentinel += 1
-
- def on_signal_3(self, *args):
- self.sentinel += 3
-
- def on_signal_after(self, *args):
- if self.after_sentinel == 1:
- self.after_sentinel += 1
-
- signal_checker = SignalCheck()
- builder = Gtk.Builder()
-
- # add object1 to the builder
- builder.add_from_string(
-"""
-<interface>
- <object class="GIOverrideSignalTest" id="object1">
- <signal name="test-signal" after="yes" handler="on_signal_after" />
- <signal name="test-signal" handler="on_signal_1" />
- </object>
-</interface>
-""")
-
- # only add object3 to the builder
- builder.add_objects_from_string(
-"""
-<interface>
- <object class="GIOverrideSignalTest" id="object2">
- <signal name="test-signal" handler="on_signal_2" />
- </object>
- <object class="GIOverrideSignalTest" id="object3">
- <signal name="test-signal" handler="on_signal_3" />
- </object>
- <object class="GIOverrideSignalTest" id="object4">
- <signal name="test-signal" handler="on_signal_4" />
- </object>
-</interface>
-
-""",
- ['object3'])
-
- # hook up signals
- builder.connect_signals(signal_checker)
-
- # call their notify signals and check sentinel
- objects = builder.get_objects()
- self.assertEquals(len(objects), 2)
- for obj in objects:
- obj.emit('test-signal')
-
- self.assertEquals(signal_checker.sentinel, 4)
- self.assertEquals(signal_checker.after_sentinel, 2)
-
- def test_dialogs(self):
- self.assertEquals(Gtk.Dialog, overrides.Gtk.Dialog)
- self.assertEquals(Gtk.AboutDialog, overrides.Gtk.AboutDialog)
- self.assertEquals(Gtk.MessageDialog, overrides.Gtk.MessageDialog)
- self.assertEquals(Gtk.ColorSelectionDialog, overrides.Gtk.ColorSelectionDialog)
- self.assertEquals(Gtk.FileChooserDialog, overrides.Gtk.FileChooserDialog)
- self.assertEquals(Gtk.FontSelectionDialog, overrides.Gtk.FontSelectionDialog)
- self.assertEquals(Gtk.RecentChooserDialog, overrides.Gtk.RecentChooserDialog)
-
- # Gtk.Dialog
- dialog = Gtk.Dialog (title='Foo',
- flags=Gtk.DialogFlags.MODAL,
- buttons=('test-button1', 1))
- self.failUnless(isinstance(dialog, Gtk.Dialog))
- self.failUnless(isinstance(dialog, Gtk.Window))
-
- dialog.add_buttons ('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
-
- self.assertEquals('Foo', dialog.get_title())
- self.assertTrue(dialog.get_modal())
- button = dialog.get_widget_for_response (1)
- self.assertEquals('test-button1', button.get_label())
- button = dialog.get_widget_for_response (2)
- self.assertEquals('test-button2', button.get_label())
- button = dialog.get_widget_for_response (Gtk.ResponseType.CLOSE)
- self.assertEquals(Gtk.STOCK_CLOSE, button.get_label())
-
- # Gtk.AboutDialog
- dialog = Gtk.AboutDialog()
- self.failUnless(isinstance(dialog, Gtk.Dialog))
- self.failUnless(isinstance(dialog, Gtk.Window))
-
- # Gtk.MessageDialog
- dialog = Gtk.MessageDialog (title='message dialog test',
- flags=Gtk.DialogFlags.MODAL,
- buttons=Gtk.ButtonsType.OK,
- message_format='dude!')
- self.failUnless(isinstance(dialog, Gtk.Dialog))
- self.failUnless(isinstance(dialog, Gtk.Window))
-
- self.assertEquals('message dialog test', dialog.get_title())
- self.assertTrue(dialog.get_modal())
- text = dialog.get_property('text')
- self.assertEquals('dude!', text)
-
- dialog.format_secondary_text('2nd text')
- self.assertEqual(dialog.get_property('secondary-text'), '2nd text')
- self.assertFalse(dialog.get_property('secondary-use-markup'))
-
- dialog.format_secondary_markup('2nd markup')
- self.assertEqual(dialog.get_property('secondary-text'), '2nd markup')
- self.assertTrue(dialog.get_property('secondary-use-markup'))
-
- # Gtk.ColorSelectionDialog
- dialog = Gtk.ColorSelectionDialog("color selection dialog test")
- self.failUnless(isinstance(dialog, Gtk.Dialog))
- self.failUnless(isinstance(dialog, Gtk.Window))
- self.assertEquals('color selection dialog test', dialog.get_title())
-
- # Gtk.FileChooserDialog
- dialog = Gtk.FileChooserDialog (title='file chooser dialog test',
- buttons=('test-button1', 1),
- action=Gtk.FileChooserAction.SAVE)
- self.failUnless(isinstance(dialog, Gtk.Dialog))
- self.failUnless(isinstance(dialog, Gtk.Window))
-
- dialog.add_buttons ('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
- self.assertEquals('file chooser dialog test', dialog.get_title())
- button = dialog.get_widget_for_response (1)
- self.assertEquals('test-button1', button.get_label())
- button = dialog.get_widget_for_response (2)
- self.assertEquals('test-button2', button.get_label())
- button = dialog.get_widget_for_response (Gtk.ResponseType.CLOSE)
- self.assertEquals(Gtk.STOCK_CLOSE, button.get_label())
- action = dialog.get_property('action')
- self.assertEquals(Gtk.FileChooserAction.SAVE, action)
-
-
- # Gtk.FontSelectionDialog
- dialog = Gtk.ColorSelectionDialog("font selection dialog test")
- self.failUnless(isinstance(dialog, Gtk.Dialog))
- self.failUnless(isinstance(dialog, Gtk.Window))
- self.assertEquals('font selection dialog test', dialog.get_title())
-
- # Gtk.RecentChooserDialog
- test_manager = Gtk.RecentManager()
- dialog = Gtk.RecentChooserDialog (title='recent chooser dialog test',
- buttons=('test-button1', 1),
- manager=test_manager)
- self.failUnless(isinstance(dialog, Gtk.Dialog))
- self.failUnless(isinstance(dialog, Gtk.Window))
-
- dialog.add_buttons ('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
- self.assertEquals('recent chooser dialog test', dialog.get_title())
- button = dialog.get_widget_for_response (1)
- self.assertEquals('test-button1', button.get_label())
- button = dialog.get_widget_for_response (2)
- self.assertEquals('test-button2', button.get_label())
- button = dialog.get_widget_for_response (Gtk.ResponseType.CLOSE)
- self.assertEquals(Gtk.STOCK_CLOSE, button.get_label())
-
- class TestClass(GObject.GObject):
- __gtype_name__ = "GIOverrideTreeAPITest"
-
- def __init__(self, tester, int_value, string_value):
- super(TestGtk.TestClass, self).__init__()
- self.tester = tester
- self.int_value = int_value
- self.string_value = string_value
-
- def check(self, int_value, string_value):
- self.tester.assertEquals(int_value, self.int_value)
- self.tester.assertEquals(string_value, self.string_value)
-
- def test_tree_store(self):
- self.assertEquals(Gtk.TreeStore, overrides.Gtk.TreeStore)
- self.assertEquals(Gtk.ListStore, overrides.Gtk.ListStore)
- self.assertEquals(Gtk.TreeModel, overrides.Gtk.TreeModel)
- self.assertEquals(Gtk.TreeViewColumn, overrides.Gtk.TreeViewColumn)
-
- class TestPyObject(object):
- pass
-
- test_pyobj = TestPyObject()
- test_pydict = {1:1, "2":2, "3":"3"}
- test_pylist = [1,"2", "3"]
- tree_store = Gtk.TreeStore(int,
- 'gchararray',
- TestGtk.TestClass,
- GObject.TYPE_PYOBJECT,
- object,
- object,
- object,
- bool,
- bool,
- GObject.TYPE_UINT,
- GObject.TYPE_ULONG,
- GObject.TYPE_INT64,
- GObject.TYPE_UINT64,
- GObject.TYPE_UCHAR,
- GObject.TYPE_CHAR)
-
- parent = None
- for i in range(97):
- label = 'this is child #%d' % i
- testobj = TestGtk.TestClass(self, i, label)
- parent = tree_store.append(parent, (i,
- label,
- testobj,
- testobj,
- test_pyobj,
- test_pydict,
- test_pylist,
- i % 2,
- bool(i % 2),
- i,
- GObject.G_MAXULONG,
- GObject.G_MININT64,
- 0xffffffffffffffff,
- 254,
- _bytes('a')
- ))
- # test set
- parent = tree_store.append(parent)
- i = 97
- label = 'this is child #%d' % i
- testobj = TestGtk.TestClass(self, i, label)
- tree_store.set(parent, 0, i,
- 2, testobj,
- 1, label,
- 3, testobj,
- 4, test_pyobj,
- 5, test_pydict,
- 6, test_pylist,
- 7, i % 2,
- 8, bool(i % 2),
- 9, i,
- 10, GObject.G_MAXULONG,
- 11, GObject.G_MININT64,
- 12, 0xffffffffffffffff,
- 13, 254,
- 14, _bytes('a'))
-
- parent = tree_store.append(parent)
- i = 98
- label = 'this is child #%d' % i
- testobj = TestGtk.TestClass(self, i, label)
- tree_store.set(parent, {0: i,
- 2: testobj,
- 1: label,
- 3: testobj,
- 4: test_pyobj,
- 5: test_pydict,
- 6: test_pylist,
- 7: i % 2,
- 8: bool(i % 2),
- 9: i,
- 10: GObject.G_MAXULONG,
- 11: GObject.G_MININT64,
- 12: 0xffffffffffffffff,
- 13: 254,
- 14: _bytes('a')})
-
- parent = tree_store.append(parent)
- i = 99
- label = 'this is child #%d' % i
- testobj = TestGtk.TestClass(self, i, label)
- tree_store.set(parent, (0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
- (i,
- testobj,
- label,
- testobj,
- test_pyobj,
- test_pydict,
- test_pylist,
- i % 2,
- bool(i % 2),
- i,
- GObject.G_MAXULONG,
- GObject.G_MININT64,
- 0xffffffffffffffff,
- 254,
- _bytes('a')))
-
- # len gets the number of children in the root node
- # since we kept appending to the previous node
- # there should only be one child of the root
- self.assertEquals(len(tree_store), 1)
-
- # walk the tree to see if the values were stored correctly
- parent = None
- i = 0
-
- treeiter = tree_store.iter_children(parent)
- while treeiter:
- i = tree_store.get_value(treeiter, 0)
- s = tree_store.get_value(treeiter, 1)
- obj = tree_store.get_value(treeiter, 2)
- obj.check(i, s)
- obj2 = tree_store.get_value(treeiter, 3)
- self.assertEquals(obj, obj2);
-
- pyobj = tree_store.get_value(treeiter, 4)
- self.assertEquals(pyobj, test_pyobj)
- pydict = tree_store.get_value(treeiter, 5)
- self.assertEquals(pydict, test_pydict)
- pylist = tree_store.get_value(treeiter, 6)
- self.assertEquals(pylist, test_pylist)
-
- bool_1 = tree_store.get_value(treeiter, 7)
- bool_2 = tree_store.get_value(treeiter, 8)
- self.assertEquals(bool_1, bool_2)
- self.assertTrue(isinstance(bool_1, bool))
- self.assertTrue(isinstance(bool_2, bool))
-
- uint_ = tree_store.get_value(treeiter, 9)
- self.assertEquals(uint_, i)
- ulong_ = tree_store.get_value(treeiter, 10)
- self.assertEquals(ulong_, GObject.G_MAXULONG)
- int64_ = tree_store.get_value(treeiter, 11)
- self.assertEquals(int64_, GObject.G_MININT64)
- uint64_ = tree_store.get_value(treeiter, 12)
- self.assertEquals(uint64_, 0xffffffffffffffff)
- uchar_ = tree_store.get_value(treeiter, 13)
- self.assertEquals(ord(uchar_), 254)
- char_ = tree_store.get_value(treeiter, 14)
- self.assertEquals(char_, 'a')
-
- parent = treeiter
- treeiter = tree_store.iter_children(parent)
-
- self.assertEquals(i, 99)
-
- def test_tree_store_signals(self):
- tree_store = Gtk.TreeStore(int, bool)
-
- def on_row_inserted(tree_store, tree_path, tree_iter, signal_list):
- signal_list.append('row-inserted')
-
- def on_row_changed(tree_store, tree_path, tree_iter, signal_list):
- signal_list.append('row-changed')
-
- signals = []
- tree_store.connect('row-inserted', on_row_inserted, signals)
- tree_store.connect('row-changed', on_row_changed, signals)
-
- # adding rows with and without data should only call one signal
- tree_store.append(None, (0, False))
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- tree_store.append(None)
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- tree_store.prepend(None, (0, False))
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- tree_store.prepend(None)
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- tree_store.insert(None, 1, (0, False))
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- tree_store.insert(None, 1)
- self.assertEqual(signals, ['row-inserted'])
-
- def test_list_store(self):
- class TestPyObject(object):
- pass
-
- test_pyobj = TestPyObject()
- test_pydict = {1:1, "2":2, "3":"3"}
- test_pylist = [1,"2", "3"]
-
- list_store = Gtk.ListStore(int, str, 'GIOverrideTreeAPITest', object, object, object, bool, bool)
- for i in range(1, 93):
- label = 'this is row #%d' % i
- testobj = TestGtk.TestClass(self, i, label)
- parent = list_store.append((i,
- label,
- testobj,
- test_pyobj,
- test_pydict,
- test_pylist,
- i % 2,
- bool(i % 2)))
-
- i = 93
- label = _unicode('this is row #93')
- treeiter = list_store.append()
- list_store.set_value(treeiter, 0, i)
- list_store.set_value(treeiter, 1, label)
- list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
- list_store.set_value(treeiter, 3, test_pyobj)
- list_store.set_value(treeiter, 4, test_pydict)
- list_store.set_value(treeiter, 5, test_pylist)
- list_store.set_value(treeiter, 6, 1)
- list_store.set_value(treeiter, 7, True)
-
- # test prepend
- label = 'this is row #0'
- list_store.prepend((0,
- label,
- TestGtk.TestClass(self, 0, label),
- test_pyobj,
- test_pydict,
- test_pylist,
- 0,
- False))
-
- # test automatic unicode->str conversion
- i = 94
- label = _unicode('this is row #94')
- treeiter = list_store.append((i,
- label,
- TestGtk.TestClass(self, i, label),
- test_pyobj,
- test_pydict,
- test_pylist,
- 0,
- False))
-
- # add sorted items out of order to test insert* apis
- # also test sending in None to not set a column
- i = 97
- label = 'this is row #97'
- treeiter = list_store.append((None,
- None,
- None,
- test_pyobj,
- None,
- test_pylist,
- 1,
- None))
-
- list_store.set_value(treeiter, 0, i)
- list_store.set_value(treeiter, 1, label)
- list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
- list_store.set_value(treeiter, 4, test_pydict)
- list_store.set_value(treeiter, 7, True)
-
- # this should append
- i = 99
- label = 'this is row #99'
- list_store.insert(9999, (i,
- label,
- TestGtk.TestClass(self, i, label),
- test_pyobj,
- test_pydict,
- test_pylist,
- 1,
- True))
-
- i = 96
- label = 'this is row #96'
- list_store.insert_before(treeiter, (i,
- label,
- TestGtk.TestClass(self, i, label),
- test_pyobj,
- test_pydict,
- test_pylist,
- 0,
- False))
-
- i = 98
- label = 'this is row #98'
- list_store.insert_after(treeiter, (i,
- label,
- TestGtk.TestClass(self, i, label),
- test_pyobj,
- test_pydict,
- test_pylist,
- 0,
- False))
-
-
- i = 95
- label = 'this is row #95'
- list_store.insert(95, (i,
- label,
- TestGtk.TestClass(self, i, label),
- test_pyobj,
- test_pydict,
- test_pylist,
- 1,
- True))
-
- i = 100
- label = 'this is row #100'
- treeiter = list_store.append()
- list_store.set(treeiter, 1, label,
- 0, i,
- 2, TestGtk.TestClass(self, i, label),
- 3, test_pyobj,
- 4, test_pydict,
- 5, test_pylist,
- 6, 0,
- 7, False)
- i = 101
- label = 'this is row #101'
- treeiter = list_store.append()
- list_store.set(treeiter, {1: label,
- 0: i,
- 2: TestGtk.TestClass(self, i, label),
- 3: test_pyobj,
- 4: test_pydict,
- 5: test_pylist,
- 6: 1,
- 7: True})
- i = 102
- label = 'this is row #102'
- treeiter = list_store.append()
- list_store.set(treeiter, (1, 0, 2, 3, 4, 5, 6, 7),
- (label,
- i,
- TestGtk.TestClass(self, i, label),
- test_pyobj,
- test_pydict,
- test_pylist,
- 0,
- False))
-
- self.assertEquals(len(list_store), 103)
-
- # walk the list to see if the values were stored correctly
- i = 0
- treeiter = list_store.get_iter_first()
-
- counter = 0
- while treeiter:
- i = list_store.get_value(treeiter, 0)
- self.assertEquals(i, counter)
- s = list_store.get_value(treeiter, 1)
- obj = list_store.get_value(treeiter, 2)
- obj.check(i, s)
-
- pyobj = list_store.get_value(treeiter, 3)
- self.assertEquals(pyobj, test_pyobj)
- pydict = list_store.get_value(treeiter, 4)
- self.assertEquals(pydict, test_pydict)
- pylist = list_store.get_value(treeiter, 5)
- self.assertEquals(pylist, test_pylist)
-
- bool_1 = list_store.get_value(treeiter, 6)
- bool_2 = list_store.get_value(treeiter, 7)
- self.assertEquals(bool_1, bool_2)
- self.assertTrue(isinstance(bool_1, bool))
- self.assertTrue(isinstance(bool_2, bool))
-
- treeiter = list_store.iter_next(treeiter)
-
- counter += 1
-
- self.assertEquals(i, 102)
-
- def test_list_store_signals(self):
- list_store = Gtk.ListStore(int, bool)
-
- def on_row_inserted(list_store, tree_path, tree_iter, signal_list):
- signal_list.append('row-inserted')
-
- def on_row_changed(list_store, tree_path, tree_iter, signal_list):
- signal_list.append('row-changed')
-
- signals = []
- list_store.connect('row-inserted', on_row_inserted, signals)
- list_store.connect('row-changed', on_row_changed, signals)
-
- # adding rows with and without data should only call one signal
- list_store.append((0, False))
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- list_store.append()
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- list_store.prepend((0, False))
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- list_store.prepend()
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- list_store.insert(1, (0, False))
- self.assertEqual(signals, ['row-inserted'])
-
- signals.pop()
- list_store.insert(1)
- self.assertEqual(signals, ['row-inserted'])
-
- def test_tree_path(self):
- p1 = Gtk.TreePath()
- p2 = Gtk.TreePath.new_first()
- self.assertEqual(p1, p2)
- self.assertEqual(str(p1), '0')
- p1 = Gtk.TreePath(2)
- p2 = Gtk.TreePath.new_from_string('2')
- self.assertEqual(p1, p2)
- self.assertEqual(str(p1), '2')
- p1 = Gtk.TreePath('1:2:3')
- p2 = Gtk.TreePath.new_from_string('1:2:3')
- self.assertEqual(p1, p2)
- self.assertEqual(str(p1), '1:2:3')
- p1 = Gtk.TreePath((1,2,3))
- p2 = Gtk.TreePath.new_from_string('1:2:3')
- self.assertEqual(p1, p2)
- self.assertEqual(str(p1), '1:2:3')
- self.assertTrue(p1 != None)
- self.assertFalse(p1 == None)
- self.assertTrue(p1 > None)
- self.assertTrue(p1 >= None)
- self.assertFalse(p1 < None)
- self.assertFalse(p1 <= None)
-
- self.assertEquals(tuple(p1), (1, 2, 3))
-
- def test_tree_model(self):
- tree_store = Gtk.TreeStore(int, str)
-
- self.assertTrue(tree_store)
- self.assertEqual(len(tree_store), 0)
- self.assertEqual(tree_store.get_iter_first(), None)
-
- def get_by_index(row, col=None):
- if col:
- return tree_store[row][col]
- else:
- return tree_store[row]
-
- self.assertRaises(TypeError, get_by_index, None)
- self.assertRaises(TypeError, get_by_index, "")
- self.assertRaises(TypeError, get_by_index, ())
-
- self.assertRaises(IndexError, get_by_index, "0")
- self.assertRaises(IndexError, get_by_index, 0)
- self.assertRaises(IndexError, get_by_index, (0,))
-
- self.assertRaises(ValueError, tree_store.get_iter, "0")
- self.assertRaises(ValueError, tree_store.get_iter, 0)
- self.assertRaises(ValueError, tree_store.get_iter, (0,))
-
- self.assertRaises(ValueError, tree_store.get_iter_from_string, "0")
-
- for row in tree_store:
- self.fail("Should not be reached")
-
- class DerivedIntType(int):
+class TestRegistry(unittest.TestCase):
+ def test_non_gi(self):
+ class MyClass:
pass
- class DerivedStrType(str):
- pass
-
- for i in range(100):
- label = 'this is row #%d' % i
- parent = tree_store.append(None, (DerivedIntType(i), DerivedStrType(label),))
- self.assertNotEquals(parent, None)
- for j in range(20):
- label = 'this is child #%d of node #%d' % (j, i)
- child = tree_store.append(parent, (j, label,))
- self.assertNotEqual(child, None)
-
- self.assertTrue(tree_store)
- self.assertEqual(len(tree_store), 100)
-
- for i,row in enumerate(tree_store):
- self.assertEqual(row.model, tree_store)
- self.assertEqual(row.parent, None)
-
- self.assertEqual(tree_store[i].path, row.path)
- self.assertEqual(tree_store[str(i)].path, row.path)
- self.assertEqual(tree_store[(i,)].path, row.path)
-
- self.assertEqual(tree_store[i][0], i)
- self.assertEqual(tree_store[i][1], "this is row #%d" % i)
-
- aiter = tree_store.get_iter(i)
- self.assertEqual(tree_store.get_path(aiter), row.path)
-
- aiter = tree_store.get_iter(str(i))
- self.assertEqual(tree_store.get_path(aiter), row.path)
-
- aiter = tree_store.get_iter((i,))
- self.assertEqual(tree_store.get_path(aiter), row.path)
-
- self.assertEqual(tree_store.iter_parent(aiter), row.parent)
-
- next = tree_store.iter_next(aiter)
- if i < len(tree_store) - 1:
- self.assertEqual(tree_store.get_path(next), row.next.path)
- else:
- self.assertEqual(next, None)
-
- self.assertEqual(tree_store.iter_n_children(row.iter), 20)
-
- child = tree_store.iter_children(row.iter)
- for j,childrow in enumerate(row.iterchildren()):
- child_path = tree_store.get_path(child)
- self.assertEqual(childrow.path, child_path)
- self.assertEqual(childrow.parent.path, row.path)
- self.assertEqual(childrow.path, tree_store[child].path)
- self.assertEqual(childrow.path, tree_store[child_path].path)
-
- self.assertEqual(childrow[0], tree_store[child][0])
- self.assertEqual(childrow[0], j)
- self.assertEqual(childrow[1], tree_store[child][1])
- self.assertEqual(childrow[1], 'this is child #%d of node #%d' % (j, i))
-
- self.assertRaises(IndexError, get_by_index, child, 2)
-
- tree_store[child][1] = 'this was child #%d of node #%d' % (j, i)
- self.assertEqual(childrow[1], 'this was child #%d of node #%d' % (j, i))
-
- nth_child = tree_store.iter_nth_child(row.iter, j)
- self.assertEqual(childrow.path, tree_store.get_path(nth_child))
-
- childrow2 = tree_store["%d:%d" % (i, j)]
- self.assertEqual(childrow.path, childrow2.path)
-
- childrow2 = tree_store[(i, j,)]
- self.assertEqual(childrow.path, childrow2.path)
-
- child = tree_store.iter_next(child)
- if j < 19:
- self.assertEqual(childrow.next.path, tree_store.get_path(child))
- else:
- self.assertEqual(child, childrow.next)
- self.assertEqual(child, None)
-
- self.assertEqual(j, 19)
-
- self.assertEqual(i, 99)
-
- # negative indices
- for i in range(-1,-100,-1):
- i_real = i + 100
- self.assertEqual(tree_store[i][0], i_real)
-
- row = tree_store[i]
- for j in range(-1, -20, -1):
- j_real = j + 20
- path = (i_real, j_real,)
-
- self.assertEqual(tree_store[path][-2], j_real)
-
- label = 'this was child #%d of node #%d' % (j_real, i_real)
- self.assertEqual(tree_store[path][-1], label)
-
- new_label = 'this still is child #%d of node #%d' % (j_real, i_real)
- tree_store[path][-1] = new_label
- self.assertEqual(tree_store[path][-1], new_label)
-
- self.assertRaises(IndexError, get_by_index, path, -3)
-
- self.assertRaises(IndexError, get_by_index, -101)
-
- last_row = tree_store[99]
- self.assertNotEqual(last_row, None)
-
- for i,childrow in enumerate(last_row.iterchildren()):
- if i < 19:
- self.assertTrue(tree_store.remove(childrow.iter))
- else:
- self.assertFalse(tree_store.remove(childrow.iter))
-
- self.assertEqual(i, 19)
-
- self.assertEqual(tree_store.iter_n_children(last_row.iter), 0)
- for childrow in last_row.iterchildren():
- self.fail("Should not be reached")
-
- aiter = tree_store.get_iter(10)
- self.assertRaises(TypeError, tree_store.get, aiter, 1, 'a')
- self.assertRaises(ValueError, tree_store.get, aiter, 1, -1)
- self.assertRaises(ValueError, tree_store.get, aiter, 1, 100)
- self.assertEqual(tree_store.get(aiter, 0, 1), (10, 'this is row #10'))
-
- def test_tree_model_edit(self):
- model = Gtk.ListStore(int, str, float)
- model.append([1, "one", -0.1])
- model.append([2, "two", -0.2])
-
- def set_row(value):
- model[1] = value
-
- self.assertRaises(TypeError, set_row, 3)
- self.assertRaises(TypeError, set_row, "three")
- self.assertRaises(ValueError, set_row, [])
- self.assertRaises(ValueError, set_row, [3, "three"])
-
- model[0] = (3, "three", -0.3)
-
- def test_tree_row_slice(self):
- model = Gtk.ListStore(int, str, float)
- model.append([1, "one", -0.1])
-
- self.assertEqual([1, "one", -0.1], model[0][:])
- self.assertEqual([1, "one"], model[0][:2])
- self.assertEqual(["one", -0.1], model[0][1:])
- self.assertEqual(["one"], model[0][1:-1])
- self.assertEqual([1], model[0][:-2])
- self.assertEqual([], model[0][5:])
- self.assertEqual([1, -0.1], model[0][0:3:2])
-
- model[0][:] = (2, "two", -0.2)
- self.assertEqual([2, "two", -0.2], model[0][:])
-
- model[0][:2] = (3, "three")
- self.assertEqual([3, "three", -0.2], model[0][:])
-
- model[0][1:] = ("four", -0.4)
- self.assertEqual([3, "four", -0.4], model[0][:])
-
- model[0][1:-1] = ("five",)
- self.assertEqual([3, "five", -0.4], model[0][:])
-
- model[0][0:3:2] = (6, -0.6)
- self.assertEqual([6, "five", -0.6], model[0][:])
-
- def set_row1():
- model[0][5:] = ("doesn't", "matter",)
-
- self.assertRaises(ValueError, set_row1)
-
- def set_row2():
- model[0][:1] = (0, "zero", 0)
-
- self.assertRaises(ValueError, set_row2)
-
- def set_row3():
- model[0][:2] = ("0", 0)
-
- self.assertRaises(ValueError, set_row3)
-
- def test_tree_view(self):
- store = Gtk.ListStore(int, str)
- store.append((0, "foo"))
- store.append((1, "bar"))
- view = Gtk.TreeView()
- # We can't easily call get_cursor() to make sure this works as
- # expected as we need to realize and focus the column
- view.set_cursor(store[1].path)
- view.set_cursor(str(store[1].path))
-
- view.get_cell_area(store[1].path)
- view.get_cell_area(str(store[1].path))
-
- def test_tree_view_column(self):
- cell = Gtk.CellRendererText()
- column = Gtk.TreeViewColumn(title='This is just a test',
- cell_renderer=cell,
- text=0,
- style=2)
-
- def test_tree_selection(self):
- store = Gtk.ListStore(int, str)
- for i in range(10):
- store.append((i, "foo"))
- view = Gtk.TreeView()
- view.set_model(store)
- firstpath = store.get_path(store.get_iter_first())
- sel = view.get_selection()
-
- sel.select_path(firstpath)
- (m, s) = sel.get_selected()
- self.assertEqual(m, store)
- self.assertEqual(store.get_path(s), firstpath)
-
- sel.select_path(0)
- (m, s) = sel.get_selected()
- self.assertEqual(m, store)
- self.assertEqual(store.get_path(s), firstpath)
-
- sel.select_path("0:0")
- (m, s) = sel.get_selected()
- self.assertEqual(m, store)
- self.assertEqual(store.get_path(s), firstpath)
-
- sel.select_path((0,0))
- (m, s) = sel.get_selected()
- self.assertEqual(m, store)
- self.assertEqual(store.get_path(s), firstpath)
-
- def test_text_buffer(self):
- self.assertEquals(Gtk.TextBuffer, overrides.Gtk.TextBuffer)
- buffer = Gtk.TextBuffer()
- tag = buffer.create_tag ('title', font = 'Sans 18')
-
- self.assertEquals(tag.props.name, 'title')
- self.assertEquals(tag.props.font, 'Sans 18')
-
- (start, end) = buffer.get_bounds()
-
- mark = buffer.create_mark(None, start)
- self.assertFalse(mark.get_left_gravity())
-
- buffer.set_text('Hello Jane Hello Bob')
- (start, end) = buffer.get_bounds()
- text = buffer.get_text(start, end, False)
- self.assertEquals(text, 'Hello Jane Hello Bob')
-
- buffer.set_text('')
- (start, end) = buffer.get_bounds()
- text = buffer.get_text(start, end, False)
- self.assertEquals(text, '')
-
- buffer.insert(end, 'HelloHello')
- buffer.insert(end, ' Bob')
-
- cursor_iter = end.copy()
- cursor_iter.backward_chars(9)
- buffer.place_cursor(cursor_iter)
- buffer.insert_at_cursor(' Jane ')
-
- (start, end) = buffer.get_bounds()
- text = buffer.get_text(start, end, False)
- self.assertEquals(text, 'Hello Jane Hello Bob')
-
- sel = buffer.get_selection_bounds()
- self.assertEquals(sel, ())
- buffer.select_range(start, end)
- sel = buffer.get_selection_bounds()
- self.assertTrue(sel[0].equal(start))
- self.assertTrue(sel[1].equal(end))
-
- buffer.set_text('')
- buffer.insert_with_tags(buffer.get_start_iter(), 'HelloHello', tag)
- (start, end) = buffer.get_bounds()
- self.assertTrue(start.begins_tag(tag))
- self.assertTrue(start.has_tag(tag))
-
- buffer.set_text('')
- buffer.insert_with_tags_by_name(buffer.get_start_iter(), 'HelloHello', 'title')
- (start, end) = buffer.get_bounds()
- self.assertTrue(start.begins_tag(tag))
- self.assertTrue(start.has_tag(tag))
-
- self.assertRaises(ValueError, buffer.insert_with_tags_by_name,
- buffer.get_start_iter(), 'HelloHello', 'unknowntag')
-
- def test_text_iter(self):
- self.assertEquals(Gtk.TextIter, overrides.Gtk.TextIter)
- buffer = Gtk.TextBuffer()
- buffer.set_text('Hello Jane Hello Bob')
- tag = buffer.create_tag ('title', font = 'Sans 18')
- (start, end) = buffer.get_bounds()
- start.forward_chars(10)
- buffer.apply_tag(tag, start, end)
- self.assertTrue(start.begins_tag())
- self.assertTrue(end.ends_tag())
- self.assertTrue(start.toggles_tag())
- self.assertTrue(end.toggles_tag())
- start.backward_chars(1)
- self.assertFalse(start.begins_tag())
- self.assertFalse(start.ends_tag())
- self.assertFalse(start.toggles_tag())
-
- def test_buttons(self):
- self.assertEquals(Gtk.Button, overrides.Gtk.Button)
-
- # test Gtk.Button
- button = Gtk.Button()
- self.failUnless(isinstance(button, Gtk.Button))
- self.failUnless(isinstance(button, Gtk.Container))
- self.failUnless(isinstance(button, Gtk.Widget))
- button = Gtk.Button(stock=Gtk.STOCK_CLOSE)
- self.assertEquals(Gtk.STOCK_CLOSE, button.get_label())
- self.assertTrue(button.get_use_stock())
- self.assertTrue(button.get_use_underline())
-
- # test Gtk.Button use_stock
- button = Gtk.Button(label=Gtk.STOCK_CLOSE, use_stock=True, use_underline=True)
- self.assertEquals(Gtk.STOCK_CLOSE, button.get_label())
- self.assertTrue(button.get_use_stock())
- self.assertTrue(button.get_use_underline())
-
- # test Gtk.LinkButton
- self.assertRaises(TypeError, Gtk.LinkButton)
- button = Gtk.LinkButton('http://www.Gtk.org', 'Gtk')
- self.failUnless(isinstance(button, Gtk.Button))
- self.failUnless(isinstance(button, Gtk.Container))
- self.failUnless(isinstance(button, Gtk.Widget))
- self.assertEquals('http://www.Gtk.org', button.get_uri())
- self.assertEquals('Gtk', button.get_label())
-
- def test_inheritance(self):
- for name in overrides.Gtk.__all__:
- over = getattr(overrides.Gtk, name)
- for element in dir(Gtk):
- try:
- klass = getattr(Gtk, element)
- info = klass.__info__
- except (NotImplementedError, AttributeError):
- continue
-
- # Get all parent classes and interfaces klass inherits from
- if isinstance(info, gi.types.ObjectInfo):
- classes = list(info.get_interfaces())
- parent = info.get_parent()
- while parent.get_name() != "Object":
- classes.append(parent)
- parent = parent.get_parent()
- classes = [kl for kl in classes if kl.get_namespace() == "Gtk"]
- else:
- continue
-
- for kl in classes:
- if kl.get_name() == name:
- self.assertTrue(issubclass(klass, over,),
- "%r does not inherit from override %r" % (klass, over,))
-
- def test_editable(self):
- self.assertEquals(Gtk.Editable, overrides.Gtk.Editable)
-
- # need to use Gtk.Entry because Editable is an interface
- entry=Gtk.Entry()
- pos = entry.insert_text('HeWorld', 0)
- self.assertEquals(pos, 7)
- pos = entry.insert_text('llo ', 2)
- self.assertEquals(pos, 6)
- text = entry.get_chars(0, 11)
- self.assertEquals('Hello World', text)
-
- def test_label(self):
- label = Gtk.Label(label='Hello')
- self.failUnless(isinstance(label, Gtk.Widget))
- self.assertEquals(label.get_text(), 'Hello')
-
- def adjustment_check(self, adjustment, value=0.0, lower=0.0, upper=0.0,
- step_increment=0.0, page_increment=0.0, page_size=0.0):
- self.assertEquals(adjustment.get_value(), value)
- self.assertEquals(adjustment.get_lower(), lower)
- self.assertEquals(adjustment.get_upper(), upper)
- self.assertEquals(adjustment.get_step_increment(), step_increment)
- self.assertEquals(adjustment.get_page_increment(), page_increment)
- self.assertEquals(adjustment.get_page_size(), page_size)
-
- def test_adjustment(self):
- adjustment = Gtk.Adjustment(1, 0, 6, 4, 5, 3)
- self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
-
- adjustment = Gtk.Adjustment(1, 0, 6, 4, 5)
- self.adjustment_check(adjustment, 1, 0, 6, 4, 5)
-
- adjustment = Gtk.Adjustment(1, 0, 6, 4)
- self.adjustment_check(adjustment, 1, 0, 6, 4)
-
- adjustment = Gtk.Adjustment(1, 0, 6)
- self.adjustment_check(adjustment, 1, 0, 6)
-
- adjustment = Gtk.Adjustment()
- self.adjustment_check(adjustment)
-
- adjustment = Gtk.Adjustment(value=1, lower=0, upper=6,
- step_increment=4, page_increment=5, page_size=3)
- self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
-
- def test_table(self):
- table = Gtk.Table()
- self.failUnless(isinstance(table, Gtk.Table))
- self.failUnless(isinstance(table, Gtk.Container))
- self.failUnless(isinstance(table, Gtk.Widget))
- self.assertEquals(table.get_size(), (1,1))
- self.assertEquals(table.get_homogeneous(), False)
- table = Gtk.Table(2, 3)
- self.assertEquals(table.get_size(), (2,3))
- self.assertEquals(table.get_homogeneous(), False)
- table = Gtk.Table(2, 3, True)
- self.assertEquals(table.get_size(), (2,3))
- self.assertEquals(table.get_homogeneous(), True)
-
- # Test PyGTK interface
- table = Gtk.Table(rows=3, columns=2)
- self.assertEquals(table.get_size(), (3,2))
- # Test using the actual property names
- table = Gtk.Table(n_rows=2, n_columns=3, homogeneous=True)
- self.assertEquals(table.get_size(), (2,3))
- self.assertEquals(table.get_homogeneous(), True)
-
- label = Gtk.Label(label='Hello')
- self.failUnless(isinstance(label, Gtk.Widget))
- table.attach(label, 0, 1, 0, 1)
- self.assertEquals(label, table.get_children()[0])
-
- def test_scrolledwindow(self):
- sw = Gtk.ScrolledWindow()
- self.failUnless(isinstance(sw, Gtk.ScrolledWindow))
- self.failUnless(isinstance(sw, Gtk.Container))
- self.failUnless(isinstance(sw, Gtk.Widget))
- sb = sw.get_hscrollbar()
- self.assertEquals(sw.get_hadjustment(), sb.get_adjustment())
- sb = sw.get_vscrollbar()
- self.assertEquals(sw.get_vadjustment(), sb.get_adjustment())
-
- def test_widget_drag_methods(self):
- widget = Gtk.Button()
-
- # here we are not checking functionality, only that the methods exist
- # and except the right number of arguments
-
- widget.drag_check_threshold(0, 0, 0, 0)
-
- # drag_dest_ methods
- widget.drag_dest_set(Gtk.DestDefaults.DROP, None, Gdk.DragAction.COPY)
- widget.drag_dest_add_image_targets()
- widget.drag_dest_add_text_targets()
- widget.drag_dest_add_uri_targets()
- widget.drag_dest_get_track_motion()
- widget.drag_dest_set_track_motion(True)
- widget.drag_dest_get_target_list()
- widget.drag_dest_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test',0, 0)]))
- widget.drag_dest_unset()
-
- widget.drag_highlight()
- widget.drag_unhighlight()
-
- # drag_source_ methods
- widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, None, Gdk.DragAction.MOVE)
- widget.drag_source_add_image_targets()
- widget.drag_source_add_text_targets()
- widget.drag_source_add_uri_targets()
- widget.drag_source_set_icon_name("")
- widget.drag_source_set_icon_pixbuf(GdkPixbuf.Pixbuf())
- widget.drag_source_set_icon_stock("")
- widget.drag_source_get_target_list()
- widget.drag_source_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
- widget.drag_source_unset()
-
- # these methods cannot be called because they require a valid drag on
- # a real GdkWindow. So we only check that they exist and are callable.
- self.assertTrue(hasattr(widget.drag_dest_set_proxy, '__call__'))
- self.assertTrue(hasattr(widget.drag_get_data, '__call__'))
-
- def test_scrollbar(self):
- # PyGTK compat
- adjustment = Gtk.Adjustment()
-
- hscrollbar = Gtk.HScrollbar()
- vscrollbar = Gtk.VScrollbar()
- self.assertNotEquals(hscrollbar.props.adjustment, adjustment)
- self.assertNotEquals(vscrollbar.props.adjustment, adjustment)
-
- hscrollbar = Gtk.HScrollbar(adjustment)
- vscrollbar = Gtk.VScrollbar(adjustment)
- self.assertEquals(hscrollbar.props.adjustment, adjustment)
- self.assertEquals(vscrollbar.props.adjustment, adjustment)
-
- def test_iconview(self):
- # PyGTK compat
- iconview = Gtk.IconView()
- self.assertEquals(iconview.props.model, None)
-
- model = Gtk.ListStore(str)
- iconview = Gtk.IconView(model)
- self.assertEquals(iconview.props.model, model)
-
- def test_toolbutton(self):
- # PyGTK compat
- button = Gtk.ToolButton()
- self.assertEquals(button.props.stock_id, None)
-
- button = Gtk.ToolButton('gtk-new')
- self.assertEquals(button.props.stock_id, 'gtk-new')
-
- def test_iconset(self):
- # PyGTK compat
- iconset = Gtk.IconSet()
- pixbuf = GdkPixbuf.Pixbuf()
- iconset = Gtk.IconSet(pixbuf)
-
- def test_viewport(self):
- # PyGTK compat
- vadjustment = Gtk.Adjustment()
- hadjustment = Gtk.Adjustment()
-
- viewport = Gtk.Viewport(hadjustment=hadjustment,
- vadjustment=vadjustment)
-
- self.assertEquals(viewport.props.vadjustment, vadjustment)
- self.assertEquals(viewport.props.hadjustment, hadjustment)
-
-
-class TestGio(unittest.TestCase):
- def setUp(self):
- self.settings = Gio.Settings('org.gnome.test')
- # we change the values in the tests, so set them to predictable start
- # value
- self.settings.reset('test-string')
- self.settings.reset('test-array')
-
- def test_file_enumerator(self):
- self.assertEquals(Gio.FileEnumerator, overrides.Gio.FileEnumerator)
- f = Gio.file_new_for_path("./")
-
- iter_info = []
- for info in f.enumerate_children("standard::*", 0, None):
- iter_info.append(info.get_name())
-
- next_info = []
- enumerator = f.enumerate_children("standard::*", 0, None)
- while True:
- info = enumerator.next_file(None)
- if info is None:
- break
- next_info.append(info.get_name())
-
- self.assertEquals(iter_info, next_info)
-
- def test_gsettings_native(self):
- self.assertTrue('test-array' in self.settings.list_keys())
-
- # get various types
- v = self.settings.get_value('test-boolean')
- self.assertEqual(v.get_boolean(), True)
- self.assertEqual(self.settings.get_boolean('test-boolean'), True)
-
- v = self.settings.get_value('test-string')
- self.assertEqual(v.get_string(), 'Hello')
- self.assertEqual(self.settings.get_string('test-string'), 'Hello')
-
- v = self.settings.get_value('test-array')
- self.assertEqual(v.unpack(), [1, 2])
-
- v = self.settings.get_value('test-tuple')
- self.assertEqual(v.unpack(), (1, 2))
-
- # set a value
- self.settings.set_string('test-string', 'World')
- self.assertEqual(self.settings.get_string('test-string'), 'World')
-
- self.settings.set_value('test-string', GLib.Variant('s', 'Goodbye'))
- self.assertEqual(self.settings.get_string('test-string'), 'Goodbye')
+ try:
+ gi.overrides.override(MyClass)
+ self.fail('unexpected success of overriding non-GI class')
+ except TypeError as e:
+ self.assertTrue('Can not override a type MyClass' in str(e))
- def test_gsettings_constructor(self):
- # default constructor uses path from schema
- self.assertEqual(self.settings.get_property('path'), '/tests/')
+ @unittest.skipUnless(Regress, 'built without cairo support')
+ def test_separate_path(self):
+ # Regress override is in tests/gi/overrides, separate from gi/overrides
+ # https://bugzilla.gnome.org/show_bug.cgi?id=680913
+ self.assertEqual(Regress.REGRESS_OVERRIDE, 42)
- # optional constructor arguments
- with_path = Gio.Settings('org.gnome.nopathtest', path='/mypath/')
- self.assertEqual(with_path.get_property('path'), '/mypath/')
- self.assertEqual(with_path['np-int'], 42)
- def test_gsettings_override(self):
- # dictionary interface
- self.assertEqual(len(self.settings), 4)
- self.assertTrue('test-array' in self.settings)
- self.assertTrue('test-array' in self.settings.keys())
- self.failIf('nonexisting' in self.settings)
- self.failIf(4 in self.settings)
- self.assertEqual(bool(self.settings), True)
+class TestModule(unittest.TestCase):
+ # Tests for gi.module
- # get various types
- self.assertEqual(self.settings['test-boolean'], True)
- self.assertEqual(self.settings['test-string'], 'Hello')
- self.assertEqual(self.settings['test-array'], [1, 2])
- self.assertEqual(self.settings['test-tuple'], (1, 2))
+ def test_get_introspection_module_caching(self):
+ # This test attempts to minimize side effects by
+ # using a DynamicModule directly instead of going though:
+ # from gi.repository import Foo
- self.assertRaises(KeyError, self.settings.__getitem__, 'unknown')
- self.assertRaises(KeyError, self.settings.__getitem__, 2)
+ # Clear out introspection module cache before running this test.
+ old_modules = gi.module._introspection_modules
+ gi.module._introspection_modules = {}
- # set a value
- self.settings['test-string'] = 'Goodbye'
- self.assertEqual(self.settings['test-string'], 'Goodbye')
- self.settings['test-array'] = [3, 4, 5]
- self.assertEqual(self.settings['test-array'], [3, 4, 5])
+ mod_name = 'GIMarshallingTests'
+ mod1 = gi.module.get_introspection_module(mod_name)
+ mod2 = gi.module.get_introspection_module(mod_name)
+ self.assertTrue(mod1 is mod2)
- self.assertRaises(TypeError, self.settings.__setitem__, 'test-string', 1)
- self.assertRaises(KeyError, self.settings.__setitem__, 'unknown', 'moo')
+ # Using a DynamicModule will use get_introspection_module internally
+ # in its _load method.
+ mod_overridden = gi.module.DynamicModule(mod_name)
+ mod_overridden._load()
+ self.assertTrue(mod1 is mod_overridden._introspection_module)
- def test_gsettings_empty(self):
- empty = Gio.Settings('org.gnome.empty', path='/tests/')
- self.assertEqual(len(empty), 0)
- self.assertEqual(bool(empty), True)
- self.assertEqual(empty.keys(), [])
+ # Restore the previous cache
+ gi.module._introspection_modules = old_modules
diff --git a/tests/test_overrides_gdk.py b/tests/test_overrides_gdk.py
new file mode 100644
index 0000000..46f0a38
--- /dev/null
+++ b/tests/test_overrides_gdk.py
@@ -0,0 +1,141 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+
+import gi.overrides
+
+try:
+ from gi.repository import Gdk, GdkPixbuf, Gtk
+ Gdk # pyflakes
+except ImportError:
+ Gdk = None
+
+
+@unittest.skipUnless(Gdk, 'Gdk not available')
+class TestGdk(unittest.TestCase):
+ def test_constructor(self):
+ attribute = Gdk.WindowAttr()
+ attribute.window_type = Gdk.WindowType.CHILD
+ attributes_mask = Gdk.WindowAttributesType.X | \
+ Gdk.WindowAttributesType.Y
+ window = Gdk.Window(None, attribute, attributes_mask)
+ self.assertEqual(window.get_window_type(), Gdk.WindowType.CHILD)
+
+ def test_color(self):
+ color = Gdk.Color(100, 200, 300)
+ self.assertEqual(color.red, 100)
+ self.assertEqual(color.green, 200)
+ self.assertEqual(color.blue, 300)
+ self.assertEqual(color, Gdk.Color(100, 200, 300))
+ self.assertNotEqual(color, Gdk.Color(1, 2, 3))
+
+ def test_color_floats(self):
+ self.assertEqual(Gdk.Color(13107, 21845, 65535),
+ Gdk.Color.from_floats(0.2, 1.0 / 3.0, 1.0))
+
+ self.assertEqual(Gdk.Color(13107, 21845, 65535).to_floats(),
+ (0.2, 1.0 / 3.0, 1.0))
+
+ self.assertEqual(Gdk.RGBA(0.2, 1.0 / 3.0, 1.0, 0.5).to_color(),
+ Gdk.Color.from_floats(0.2, 1.0 / 3.0, 1.0))
+
+ self.assertEqual(Gdk.RGBA.from_color(Gdk.Color(13107, 21845, 65535)),
+ Gdk.RGBA(0.2, 1.0 / 3.0, 1.0, 1.0))
+
+ def test_rgba(self):
+ self.assertEqual(Gdk.RGBA, gi.overrides.Gdk.RGBA)
+ rgba = Gdk.RGBA(0.1, 0.2, 0.3, 0.4)
+ self.assertEqual(rgba, Gdk.RGBA(0.1, 0.2, 0.3, 0.4))
+ self.assertNotEqual(rgba, Gdk.RGBA(0.0, 0.2, 0.3, 0.4))
+ self.assertEqual(rgba.red, 0.1)
+ self.assertEqual(rgba.green, 0.2)
+ self.assertEqual(rgba.blue, 0.3)
+ self.assertEqual(rgba.alpha, 0.4)
+ rgba.green = 0.9
+ self.assertEqual(rgba.green, 0.9)
+
+ # Iterator/tuple convsersion
+ self.assertEqual(tuple(Gdk.RGBA(0.1, 0.2, 0.3, 0.4)),
+ (0.1, 0.2, 0.3, 0.4))
+
+ def test_event(self):
+ event = Gdk.Event.new(Gdk.EventType.CONFIGURE)
+ self.assertEqual(event.type, Gdk.EventType.CONFIGURE)
+ self.assertEqual(event.send_event, 0)
+
+ event = Gdk.Event.new(Gdk.EventType.DRAG_MOTION)
+ event.x_root, event.y_root = 0, 5
+ self.assertEqual(event.x_root, 0)
+ self.assertEqual(event.y_root, 5)
+
+ event = Gdk.Event()
+ event.type = Gdk.EventType.SCROLL
+ self.assertRaises(AttributeError, lambda: getattr(event, 'foo_bar'))
+
+ def test_event_structures(self):
+ def button_press_cb(button, event):
+ self.assertTrue(isinstance(event, Gdk.EventButton))
+ self.assertTrue(event.type == Gdk.EventType.BUTTON_PRESS)
+ self.assertEqual(event.send_event, 0)
+ self.assertEqual(event.get_state(), Gdk.ModifierType.CONTROL_MASK)
+ self.assertEqual(event.get_root_coords(), (2, 5))
+
+ event.time = 12345
+ self.assertEqual(event.get_time(), 12345)
+
+ w = Gtk.Window()
+ b = Gtk.Button()
+ b.connect('button-press-event', button_press_cb)
+ w.add(b)
+ w.show_all()
+ Gdk.test_simulate_button(b.get_window(),
+ 2, 5,
+ 0,
+ Gdk.ModifierType.CONTROL_MASK,
+ Gdk.EventType.BUTTON_PRESS)
+
+ def test_cursor(self):
+ self.assertEqual(Gdk.Cursor, gi.overrides.Gdk.Cursor)
+ c = Gdk.Cursor(Gdk.CursorType.WATCH)
+ self.assertNotEqual(c, None)
+ c = Gdk.Cursor(cursor_type=Gdk.CursorType.WATCH)
+ self.assertNotEqual(c, None)
+
+ display_manager = Gdk.DisplayManager.get()
+ display = display_manager.get_default_display()
+
+ test_pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB,
+ False,
+ 8,
+ 5,
+ 10)
+
+ c = Gdk.Cursor(display,
+ test_pixbuf,
+ y=0, x=0)
+
+ self.assertNotEqual(c, None)
+ self.assertRaises(ValueError, Gdk.Cursor, 1, 2, 3)
+
+ def test_flags(self):
+ self.assertEqual(Gdk.ModifierType.META_MASK | 0, 0x10000000)
+ self.assertEqual(hex(Gdk.ModifierType.META_MASK), '0x10000000')
+ self.assertEqual(str(Gdk.ModifierType.META_MASK),
+ '<flags GDK_META_MASK of type GdkModifierType>')
+
+ self.assertEqual(Gdk.ModifierType.RELEASE_MASK | 0, 0x40000000)
+ self.assertEqual(hex(Gdk.ModifierType.RELEASE_MASK), '0x40000000')
+ self.assertEqual(str(Gdk.ModifierType.RELEASE_MASK),
+ '<flags GDK_RELEASE_MASK of type GdkModifierType>')
+
+ self.assertEqual(Gdk.ModifierType.RELEASE_MASK | Gdk.ModifierType.META_MASK, 0x50000000)
+ self.assertEqual(str(Gdk.ModifierType.RELEASE_MASK | Gdk.ModifierType.META_MASK),
+ '<flags GDK_META_MASK | GDK_RELEASE_MASK of type GdkModifierType>')
+
+ def test_color_parse(self):
+ c = Gdk.color_parse('#00FF80')
+ self.assertEqual(c.red, 0)
+ self.assertEqual(c.green, 65535)
+ self.assertEqual(c.blue, 32896)
+ self.assertEqual(Gdk.color_parse('bogus'), None)
diff --git a/tests/test_overrides_glib.py b/tests/test_overrides_glib.py
new file mode 100644
index 0000000..4d7e63a
--- /dev/null
+++ b/tests/test_overrides_glib.py
@@ -0,0 +1,489 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+
+import gi
+from gi.repository import GLib
+from compathelper import _long
+
+
+class TestGVariant(unittest.TestCase):
+ def test_create_simple(self):
+ variant = GLib.Variant('i', 42)
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertEqual(variant.get_int32(), 42)
+
+ variant = GLib.Variant('s', '')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertEqual(variant.get_string(), '')
+
+ variant = GLib.Variant('s', 'hello')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertEqual(variant.get_string(), 'hello')
+
+ def test_create_variant(self):
+ variant = GLib.Variant('v', GLib.Variant('i', 42))
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertTrue(isinstance(variant.get_variant(), GLib.Variant))
+ self.assertEqual(variant.get_type_string(), 'v')
+ self.assertEqual(variant.get_variant().get_type_string(), 'i')
+ self.assertEqual(variant.get_variant().get_int32(), 42)
+
+ variant = GLib.Variant('v', GLib.Variant('v', GLib.Variant('i', 42)))
+ self.assertEqual(variant.get_type_string(), 'v')
+ self.assertEqual(variant.get_variant().get_type_string(), 'v')
+ self.assertEqual(variant.get_variant().get_variant().get_type_string(), 'i')
+ self.assertEqual(variant.get_variant().get_variant().get_int32(), 42)
+
+ def test_create_tuple(self):
+ variant = GLib.Variant('()', ())
+ self.assertEqual(variant.get_type_string(), '()')
+ self.assertEqual(variant.n_children(), 0)
+
+ variant = GLib.Variant('(i)', (3,))
+ self.assertEqual(variant.get_type_string(), '(i)')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertEqual(variant.n_children(), 1)
+ self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
+ self.assertEqual(variant.get_child_value(0).get_int32(), 3)
+
+ variant = GLib.Variant('(ss)', ('mec', 'mac'))
+ self.assertEqual(variant.get_type_string(), '(ss)')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
+ self.assertEqual(variant.get_child_value(0).get_string(), 'mec')
+ self.assertEqual(variant.get_child_value(1).get_string(), 'mac')
+
+ # nested tuples
+ variant = GLib.Variant('((si)(ub))', (('hello', -1), (42, True)))
+ self.assertEqual(variant.get_type_string(), '((si)(ub))')
+ self.assertEqual(variant.unpack(), (('hello', -1), (_long(42), True)))
+
+ def test_create_dictionary(self):
+ variant = GLib.Variant('a{si}', {})
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertEqual(variant.get_type_string(), 'a{si}')
+ self.assertEqual(variant.n_children(), 0)
+
+ variant = GLib.Variant('a{si}', {'': 1, 'key1': 2, 'key2': 3})
+ self.assertEqual(variant.get_type_string(), 'a{si}')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(2), GLib.Variant))
+ self.assertEqual(variant.unpack(), {'': 1, 'key1': 2, 'key2': 3})
+
+ # nested dictionaries
+ variant = GLib.Variant('a{sa{si}}', {})
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertEqual(variant.get_type_string(), 'a{sa{si}}')
+ self.assertEqual(variant.n_children(), 0)
+
+ d = {'': {'': 1, 'keyn1': 2},
+ 'key1': {'key11': 11, 'key12': 12}}
+ variant = GLib.Variant('a{sa{si}}', d)
+ self.assertEqual(variant.get_type_string(), 'a{sa{si}}')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertEqual(variant.unpack(), d)
+
+ def test_create_array(self):
+ variant = GLib.Variant('ai', [])
+ self.assertEqual(variant.get_type_string(), 'ai')
+ self.assertEqual(variant.n_children(), 0)
+
+ variant = GLib.Variant('ai', [1, 2])
+ self.assertEqual(variant.get_type_string(), 'ai')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
+ self.assertEqual(variant.get_child_value(0).get_int32(), 1)
+ self.assertEqual(variant.get_child_value(1).get_int32(), 2)
+
+ variant = GLib.Variant('as', [])
+ self.assertEqual(variant.get_type_string(), 'as')
+ self.assertEqual(variant.n_children(), 0)
+
+ variant = GLib.Variant('as', [''])
+ self.assertEqual(variant.get_type_string(), 'as')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
+ self.assertEqual(variant.get_child_value(0).get_string(), '')
+
+ variant = GLib.Variant('as', ['hello', 'world'])
+ self.assertEqual(variant.get_type_string(), 'as')
+ self.assertTrue(isinstance(variant, GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
+ self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
+ self.assertEqual(variant.get_child_value(0).get_string(), 'hello')
+ self.assertEqual(variant.get_child_value(1).get_string(), 'world')
+
+ # nested arrays
+ variant = GLib.Variant('aai', [])
+ self.assertEqual(variant.get_type_string(), 'aai')
+ self.assertEqual(variant.n_children(), 0)
+
+ variant = GLib.Variant('aai', [[]])
+ self.assertEqual(variant.get_type_string(), 'aai')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 0)
+
+ variant = GLib.Variant('aai', [[1, 2], [3, 4, 5]])
+ self.assertEqual(variant.get_type_string(), 'aai')
+ self.assertEqual(variant.unpack(), [[1, 2], [3, 4, 5]])
+
+ def test_create_complex(self):
+ variant = GLib.Variant('(as)', ([],))
+ self.assertEqual(variant.get_type_string(), '(as)')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 0)
+
+ variant = GLib.Variant('(as)', ([''],))
+ self.assertEqual(variant.get_type_string(), '(as)')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_string(), '')
+
+ variant = GLib.Variant('(as)', (['hello'],))
+ self.assertEqual(variant.get_type_string(), '(as)')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_string(), 'hello')
+
+ variant = GLib.Variant('a(ii)', [])
+ self.assertEqual(variant.get_type_string(), 'a(ii)')
+ self.assertEqual(variant.n_children(), 0)
+
+ variant = GLib.Variant('a(ii)', [(5, 6)])
+ self.assertEqual(variant.get_type_string(), 'a(ii)')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 2)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_int32(), 5)
+ self.assertEqual(variant.get_child_value(0).get_child_value(1).get_int32(), 6)
+
+ variant = GLib.Variant('(a(ii))', ([],))
+ self.assertEqual(variant.get_type_string(), '(a(ii))')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 0)
+
+ variant = GLib.Variant('(a(ii))', ([(5, 6)],))
+ self.assertEqual(variant.get_type_string(), '(a(ii))')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).n_children(), 2)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_child_value(0).get_int32(), 5)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_child_value(1).get_int32(), 6)
+
+ obj = {'a1': (1, True), 'a2': (2, False)}
+ variant = GLib.Variant('a{s(ib)}', obj)
+ self.assertEqual(variant.get_type_string(), 'a{s(ib)}')
+ self.assertEqual(variant.unpack(), obj)
+
+ obj = {'a1': (1, GLib.Variant('b', True)), 'a2': (2, GLib.Variant('y', 255))}
+ variant = GLib.Variant('a{s(iv)}', obj)
+ self.assertEqual(variant.get_type_string(), 'a{s(iv)}')
+ self.assertEqual(variant.unpack(), {'a1': (1, True), 'a2': (2, 255)})
+
+ obj = (1, {'a': {'a1': True, 'a2': False},
+ 'b': {'b1': False},
+ 'c': {}
+ },
+ 'foo')
+ variant = GLib.Variant('(ia{sa{sb}}s)', obj)
+ self.assertEqual(variant.get_type_string(), '(ia{sa{sb}}s)')
+ self.assertEqual(variant.unpack(), obj)
+
+ obj = {"frequency": GLib.Variant('t', 738000000),
+ "hierarchy": GLib.Variant('i', 0),
+ "bandwidth": GLib.Variant('x', 8),
+ "code-rate-hp": GLib.Variant('d', 2.0 / 3.0),
+ "constellation": GLib.Variant('s', "QAM16"),
+ "guard-interval": GLib.Variant('u', 4)}
+ variant = GLib.Variant('a{sv}', obj)
+ self.assertEqual(variant.get_type_string(), 'a{sv}')
+ self.assertEqual(variant.unpack(),
+ {"frequency": 738000000,
+ "hierarchy": 0,
+ "bandwidth": 8,
+ "code-rate-hp": 2.0 / 3.0,
+ "constellation": "QAM16",
+ "guard-interval": 4
+ })
+
+ def test_create_errors(self):
+ # excess arguments
+ self.assertRaises(TypeError, GLib.Variant, 'i', 42, 3)
+ self.assertRaises(TypeError, GLib.Variant, '(i)', (42, 3))
+
+ # not enough arguments
+ self.assertRaises(TypeError, GLib.Variant, '(ii)', (42,))
+
+ # data type mismatch
+ self.assertRaises(TypeError, GLib.Variant, 'i', 'hello')
+ self.assertRaises(TypeError, GLib.Variant, 's', 42)
+ self.assertRaises(TypeError, GLib.Variant, '(ss)', 'mec', 'mac')
+ self.assertRaises(TypeError, GLib.Variant, '(s)', 'hello')
+
+ # unimplemented data type
+ self.assertRaises(NotImplementedError, GLib.Variant, 'Q', 1)
+
+ # invalid types
+ self.assertRaises(TypeError, GLib.Variant, '(ii', (42, 3))
+ self.assertRaises(TypeError, GLib.Variant, '(ii))', (42, 3))
+ self.assertRaises(TypeError, GLib.Variant, 'a{si', {})
+ self.assertRaises(TypeError, GLib.Variant, 'a{si}}', {})
+ self.assertRaises(TypeError, GLib.Variant, 'a{iii}', {})
+
+ def test_unpack(self):
+ # simple values
+ res = GLib.Variant.new_int32(-42).unpack()
+ self.assertEqual(res, -42)
+
+ res = GLib.Variant.new_uint64(34359738368).unpack()
+ self.assertEqual(res, 34359738368)
+
+ res = GLib.Variant.new_boolean(True).unpack()
+ self.assertEqual(res, True)
+
+ res = GLib.Variant.new_object_path('/foo/Bar').unpack()
+ self.assertEqual(res, '/foo/Bar')
+
+ # variant
+ res = GLib.Variant('v', GLib.Variant.new_int32(-42)).unpack()
+ self.assertEqual(res, -42)
+
+ GLib.Variant('v', GLib.Variant('v', GLib.Variant('i', 42)))
+ self.assertEqual(res, -42)
+
+ # tuple
+ res = GLib.Variant.new_tuple(GLib.Variant.new_int32(-1),
+ GLib.Variant.new_string('hello')).unpack()
+ self.assertEqual(res, (-1, 'hello'))
+
+ # array
+ vb = GLib.VariantBuilder.new(gi._gi.variant_type_from_string('ai'))
+ vb.add_value(GLib.Variant.new_int32(-1))
+ vb.add_value(GLib.Variant.new_int32(3))
+ res = vb.end().unpack()
+ self.assertEqual(res, [-1, 3])
+
+ # dictionary
+ res = GLib.Variant('a{si}', {'key1': 1, 'key2': 2}).unpack()
+ self.assertEqual(res, {'key1': 1, 'key2': 2})
+
+ # maybe
+ v = GLib.Variant.new_maybe(GLib.VariantType.new('i'), GLib.Variant('i', 1))
+ res = v.unpack()
+ self.assertEqual(res, 1)
+ v = GLib.Variant.new_maybe(GLib.VariantType.new('i'), None)
+ res = v.unpack()
+ self.assertEqual(res, None)
+
+ def test_iteration(self):
+ # array index access
+ vb = GLib.VariantBuilder.new(gi._gi.variant_type_from_string('ai'))
+ vb.add_value(GLib.Variant.new_int32(-1))
+ vb.add_value(GLib.Variant.new_int32(3))
+ v = vb.end()
+
+ self.assertEqual(len(v), 2)
+ self.assertEqual(v[0], -1)
+ self.assertEqual(v[1], 3)
+ self.assertEqual(v[-1], 3)
+ self.assertEqual(v[-2], -1)
+ self.assertRaises(IndexError, v.__getitem__, 2)
+ self.assertRaises(IndexError, v.__getitem__, -3)
+ self.assertRaises(ValueError, v.__getitem__, 'a')
+
+ # array iteration
+ self.assertEqual([x for x in v], [-1, 3])
+ self.assertEqual(list(v), [-1, 3])
+
+ # tuple index access
+ v = GLib.Variant.new_tuple(GLib.Variant.new_int32(-1),
+ GLib.Variant.new_string('hello'))
+ self.assertEqual(len(v), 2)
+ self.assertEqual(v[0], -1)
+ self.assertEqual(v[1], 'hello')
+ self.assertEqual(v[-1], 'hello')
+ self.assertEqual(v[-2], -1)
+ self.assertRaises(IndexError, v.__getitem__, 2)
+ self.assertRaises(IndexError, v.__getitem__, -3)
+ self.assertRaises(ValueError, v.__getitem__, 'a')
+
+ # tuple iteration
+ self.assertEqual([x for x in v], [-1, 'hello'])
+ self.assertEqual(tuple(v), (-1, 'hello'))
+
+ # dictionary index access
+ vsi = GLib.Variant('a{si}', {'key1': 1, 'key2': 2})
+ vis = GLib.Variant('a{is}', {1: 'val1', 5: 'val2'})
+
+ self.assertEqual(len(vsi), 2)
+ self.assertEqual(vsi['key1'], 1)
+ self.assertEqual(vsi['key2'], 2)
+ self.assertRaises(KeyError, vsi.__getitem__, 'unknown')
+
+ self.assertEqual(len(vis), 2)
+ self.assertEqual(vis[1], 'val1')
+ self.assertEqual(vis[5], 'val2')
+ self.assertRaises(KeyError, vsi.__getitem__, 3)
+
+ # dictionary iteration
+ self.assertEqual(set(vsi.keys()), set(['key1', 'key2']))
+ self.assertEqual(set(vis.keys()), set([1, 5]))
+
+ # string index access
+ v = GLib.Variant('s', 'hello')
+ self.assertEqual(len(v), 5)
+ self.assertEqual(v[0], 'h')
+ self.assertEqual(v[4], 'o')
+ self.assertEqual(v[-1], 'o')
+ self.assertEqual(v[-5], 'h')
+ self.assertRaises(IndexError, v.__getitem__, 5)
+ self.assertRaises(IndexError, v.__getitem__, -6)
+
+ # string iteration
+ self.assertEqual([x for x in v], ['h', 'e', 'l', 'l', 'o'])
+
+ def test_split_signature(self):
+ self.assertEqual(GLib.Variant.split_signature('()'), [])
+
+ self.assertEqual(GLib.Variant.split_signature('s'), ['s'])
+
+ self.assertEqual(GLib.Variant.split_signature('as'), ['as'])
+
+ self.assertEqual(GLib.Variant.split_signature('(s)'), ['s'])
+
+ self.assertEqual(GLib.Variant.split_signature('(iso)'), ['i', 's', 'o'])
+
+ self.assertEqual(GLib.Variant.split_signature('(s(ss)i(ii))'),
+ ['s', '(ss)', 'i', '(ii)'])
+
+ self.assertEqual(GLib.Variant.split_signature('(as)'), ['as'])
+
+ self.assertEqual(GLib.Variant.split_signature('(s(ss)iaiaasa(ii))'),
+ ['s', '(ss)', 'i', 'ai', 'aas', 'a(ii)'])
+
+ self.assertEqual(GLib.Variant.split_signature('(a{iv}(ii)((ss)a{s(ss)}))'),
+ ['a{iv}', '(ii)', '((ss)a{s(ss)})'])
+
+ def test_hash(self):
+ v1 = GLib.Variant('s', 'somestring')
+ v2 = GLib.Variant('s', 'somestring')
+ v3 = GLib.Variant('s', 'somestring2')
+
+ self.assertTrue(v2 in set([v1, v3]))
+ self.assertTrue(v2 in frozenset([v1, v3]))
+ self.assertTrue(v2 in {v1: '1', v3: '2'})
+
+ def test_compare(self):
+ # Check if identical GVariant are equal
+
+ def assert_equal(vtype, value):
+ self.assertEqual(GLib.Variant(vtype, value), GLib.Variant(vtype, value))
+
+ def assert_not_equal(vtype1, value1, vtype2, value2):
+ self.assertNotEqual(GLib.Variant(vtype1, value1), GLib.Variant(vtype2, value2))
+
+ numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
+ for num in numbers:
+ assert_equal(num, 42)
+ assert_not_equal(num, 42, num, 41)
+ assert_not_equal(num, 42, 's', '42')
+
+ assert_equal('s', 'something')
+ assert_not_equal('s', 'something', 's', 'somethingelse')
+ assert_not_equal('s', 'something', 'i', 1234)
+
+ assert_equal('g', 'dustybinqhogx')
+ assert_not_equal('g', 'dustybinqhogx', 'g', 'dustybin')
+ assert_not_equal('g', 'dustybinqhogx', 'i', 1234)
+
+ assert_equal('o', '/dev/null')
+ assert_not_equal('o', '/dev/null', 'o', '/dev/zero')
+ assert_not_equal('o', '/dev/null', 'i', 1234)
+
+ assert_equal('(s)', ('strtuple',))
+ assert_not_equal('(s)', ('strtuple',), '(s)', ('strtuple2',))
+
+ assert_equal('a{si}', {'str': 42})
+ assert_not_equal('a{si}', {'str': 42}, 'a{si}', {'str': 43})
+
+ assert_equal('v', GLib.Variant('i', 42))
+ assert_not_equal('v', GLib.Variant('i', 42), 'v', GLib.Variant('i', 43))
+
+ def test_bool(self):
+ # Check if the GVariant bool matches the unpacked Pythonic bool
+
+ def assert_equals_bool(vtype, value):
+ self.assertEqual(bool(GLib.Variant(vtype, value)), bool(value))
+
+ # simple values
+ assert_equals_bool('b', True)
+ assert_equals_bool('b', False)
+
+ numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
+ for number in numbers:
+ assert_equals_bool(number, 0)
+ assert_equals_bool(number, 1)
+
+ assert_equals_bool('s', '')
+ assert_equals_bool('g', '')
+ assert_equals_bool('s', 'something')
+ assert_equals_bool('o', '/dev/null')
+ assert_equals_bool('g', 'dustybinqhogx')
+
+ # arrays
+ assert_equals_bool('ab', [True])
+ assert_equals_bool('ab', [False])
+ for number in numbers:
+ assert_equals_bool('a' + number, [])
+ assert_equals_bool('a' + number, [0])
+ assert_equals_bool('as', [])
+ assert_equals_bool('as', [''])
+ assert_equals_bool('ao', [])
+ assert_equals_bool('ao', ['/'])
+ assert_equals_bool('ag', [])
+ assert_equals_bool('ag', [''])
+ assert_equals_bool('aai', [[]])
+
+ # tuples
+ assert_equals_bool('()', ())
+ for number in numbers:
+ assert_equals_bool('(' + number + ')', (0,))
+ assert_equals_bool('(s)', ('',))
+ assert_equals_bool('(o)', ('/',))
+ assert_equals_bool('(g)', ('',))
+ assert_equals_bool('(())', ((),))
+
+ # dictionaries
+ assert_equals_bool('a{si}', {})
+ assert_equals_bool('a{si}', {'': 0})
+
+ # complex types, always True
+ assert_equals_bool('(as)', ([],))
+ assert_equals_bool('a{s(i)}', {'': (0,)})
+
+ # variant types, recursive unpacking
+ assert_equals_bool('v', GLib.Variant('i', 0))
+ assert_equals_bool('v', GLib.Variant('i', 1))
+
+ def test_repr(self):
+ # with C constructor
+ v = GLib.Variant.new_uint32(42)
+ self.assertEqual(repr(v), "GLib.Variant('u', 42)")
+
+ # with override constructor
+ v = GLib.Variant('(is)', (1, 'somestring'))
+ self.assertEqual(repr(v), "GLib.Variant('(is)', (1, 'somestring'))")
+
+ def test_str(self):
+ # with C constructor
+ v = GLib.Variant.new_uint32(42)
+ self.assertEqual(str(v), 'uint32 42')
+
+ # with override constructor
+ v = GLib.Variant('(is)', (1, 'somestring'))
+ self.assertEqual(str(v), "(1, 'somestring')")
diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py
new file mode 100644
index 0000000..fbe51ec
--- /dev/null
+++ b/tests/test_overrides_gtk.py
@@ -0,0 +1,1748 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# coding: UTF-8
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import contextlib
+import unittest
+import time
+import sys
+
+from compathelper import _unicode, _bytes
+
+import gi.overrides
+import gi.types
+from gi.repository import GLib, GObject
+
+try:
+ from gi.repository import GdkPixbuf, Gdk, Gtk
+ Gtk # pyflakes
+except ImportError:
+ Gtk = None
+
+
+@contextlib.contextmanager
+def realized(widget):
+ """Makes sure the widget is realized.
+
+ view = Gtk.TreeView()
+ with realized(view):
+ do_something(view)
+ """
+
+ if isinstance(widget, Gtk.Window):
+ toplevel = widget
+ else:
+ toplevel = widget.get_parent_window()
+
+ if toplevel is None:
+ window = Gtk.Window()
+ window.add(widget)
+
+ widget.realize()
+ while Gtk.events_pending():
+ Gtk.main_iteration()
+ assert widget.get_realized()
+ yield widget
+
+ if toplevel is None:
+ window.remove(widget)
+ window.destroy()
+
+ while Gtk.events_pending():
+ Gtk.main_iteration()
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestGtk(unittest.TestCase):
+ def test_container(self):
+ box = Gtk.Box()
+ self.assertTrue(isinstance(box, Gtk.Box))
+ self.assertTrue(isinstance(box, Gtk.Container))
+ self.assertTrue(isinstance(box, Gtk.Widget))
+ self.assertTrue(box)
+ label = Gtk.Label()
+ label2 = Gtk.Label()
+ box.add(label)
+ box.add(label2)
+ self.assertTrue(label in box)
+ self.assertTrue(label2 in box)
+ self.assertEqual(len(box), 2)
+ self.assertTrue(box)
+ l = [x for x in box]
+ self.assertEqual(l, [label, label2])
+
+ def test_actions(self):
+ self.assertEqual(Gtk.Action, gi.overrides.Gtk.Action)
+ self.assertRaises(TypeError, Gtk.Action)
+ action = Gtk.Action("test", "Test", "Test Action", Gtk.STOCK_COPY)
+ self.assertEqual(action.get_name(), "test")
+ self.assertEqual(action.get_label(), "Test")
+ self.assertEqual(action.get_tooltip(), "Test Action")
+ self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
+
+ self.assertEqual(Gtk.RadioAction, gi.overrides.Gtk.RadioAction)
+ self.assertRaises(TypeError, Gtk.RadioAction)
+ action = Gtk.RadioAction("test", "Test", "Test Action", Gtk.STOCK_COPY, 1)
+ self.assertEqual(action.get_name(), "test")
+ self.assertEqual(action.get_label(), "Test")
+ self.assertEqual(action.get_tooltip(), "Test Action")
+ self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
+ self.assertEqual(action.get_current_value(), 1)
+
+ def test_actiongroup(self):
+ self.assertEqual(Gtk.ActionGroup, gi.overrides.Gtk.ActionGroup)
+ self.assertRaises(TypeError, Gtk.ActionGroup)
+
+ action_group = Gtk.ActionGroup(name='TestActionGroup')
+ callback_data = "callback data"
+
+ def test_action_callback_data(action, user_data):
+ self.assertEqual(user_data, callback_data)
+
+ def test_radio_action_callback_data(action, current, user_data):
+ self.assertEqual(user_data, callback_data)
+
+ action_group.add_actions([
+ ('test-action1', None, 'Test Action 1',
+ None, None, test_action_callback_data),
+ ('test-action2', Gtk.STOCK_COPY, 'Test Action 2',
+ None, None, test_action_callback_data)], callback_data)
+ action_group.add_toggle_actions([
+ ('test-toggle-action1', None, 'Test Toggle Action 1',
+ None, None, test_action_callback_data, False),
+ ('test-toggle-action2', Gtk.STOCK_COPY, 'Test Toggle Action 2',
+ None, None, test_action_callback_data, True)], callback_data)
+ action_group.add_radio_actions([
+ ('test-radio-action1', None, 'Test Radio Action 1'),
+ ('test-radio-action2', Gtk.STOCK_COPY, 'Test Radio Action 2')], 1,
+ test_radio_action_callback_data,
+ callback_data)
+
+ expected_results = [('test-action1', Gtk.Action),
+ ('test-action2', Gtk.Action),
+ ('test-toggle-action1', Gtk.ToggleAction),
+ ('test-toggle-action2', Gtk.ToggleAction),
+ ('test-radio-action1', Gtk.RadioAction),
+ ('test-radio-action2', Gtk.RadioAction)]
+
+ for action in action_group.list_actions():
+ a = (action.get_name(), type(action))
+ self.assertTrue(a in expected_results)
+ expected_results.remove(a)
+ action.activate()
+
+ def test_uimanager(self):
+ self.assertEqual(Gtk.UIManager, gi.overrides.Gtk.UIManager)
+ ui = Gtk.UIManager()
+ ui.add_ui_from_string("""<ui>
+ <menubar name="menubar1"></menubar>
+</ui>
+"""
+)
+ menubar = ui.get_widget("/menubar1")
+ self.assertEqual(type(menubar), Gtk.MenuBar)
+
+ ag = Gtk.ActionGroup(name="ag1")
+ ui.insert_action_group(ag)
+ ag2 = Gtk.ActionGroup(name="ag2")
+ ui.insert_action_group(ag2)
+ groups = ui.get_action_groups()
+ self.assertEqual(ag, groups[-2])
+ self.assertEqual(ag2, groups[-1])
+
+ def test_uimanager_nonascii(self):
+ ui = Gtk.UIManager()
+ ui.add_ui_from_string(b'<ui><menubar name="menub\xc3\xa6r1" /></ui>'.decode('UTF-8'))
+ mi = ui.get_widget("/menubær1")
+ self.assertEqual(type(mi), Gtk.MenuBar)
+
+ def test_window(self):
+ # standard Window
+ w = Gtk.Window()
+ self.assertEqual(w.get_property('type'), Gtk.WindowType.TOPLEVEL)
+
+ # type works as keyword argument
+ w = Gtk.Window(type=Gtk.WindowType.POPUP)
+ self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
+
+ # pygtk compatible positional argument
+ w = Gtk.Window(Gtk.WindowType.POPUP)
+ self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
+
+ class TestWindow(Gtk.Window):
+ __gtype_name__ = "TestWindow"
+
+ # works from builder
+ builder = Gtk.Builder()
+ builder.add_from_string('''
+<interface>
+ <object class="GtkWindow" id="win">
+ <property name="type">popup</property>
+ </object>
+ <object class="TestWindow" id="testwin">
+ </object>
+ <object class="TestWindow" id="testpop">
+ <property name="type">popup</property>
+ </object>
+</interface>''')
+ self.assertEqual(builder.get_object('win').get_property('type'),
+ Gtk.WindowType.POPUP)
+ self.assertEqual(builder.get_object('testwin').get_property('type'),
+ Gtk.WindowType.TOPLEVEL)
+ self.assertEqual(builder.get_object('testpop').get_property('type'),
+ Gtk.WindowType.POPUP)
+
+ def test_dialogs(self):
+ self.assertEqual(Gtk.Dialog, gi.overrides.Gtk.Dialog)
+ self.assertEqual(Gtk.AboutDialog, gi.overrides.Gtk.AboutDialog)
+ self.assertEqual(Gtk.MessageDialog, gi.overrides.Gtk.MessageDialog)
+ self.assertEqual(Gtk.ColorSelectionDialog, gi.overrides.Gtk.ColorSelectionDialog)
+ self.assertEqual(Gtk.FileChooserDialog, gi.overrides.Gtk.FileChooserDialog)
+ self.assertEqual(Gtk.FontSelectionDialog, gi.overrides.Gtk.FontSelectionDialog)
+ self.assertEqual(Gtk.RecentChooserDialog, gi.overrides.Gtk.RecentChooserDialog)
+
+ # Gtk.Dialog
+ dialog = Gtk.Dialog(title='Foo',
+ flags=Gtk.DialogFlags.MODAL,
+ buttons=('test-button1', 1))
+ self.assertTrue(isinstance(dialog, Gtk.Dialog))
+ self.assertTrue(isinstance(dialog, Gtk.Window))
+
+ dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
+
+ self.assertEqual('Foo', dialog.get_title())
+ self.assertTrue(dialog.get_modal())
+ button = dialog.get_widget_for_response(1)
+ self.assertEqual('test-button1', button.get_label())
+ button = dialog.get_widget_for_response(2)
+ self.assertEqual('test-button2', button.get_label())
+ button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
+ self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
+
+ # Gtk.AboutDialog
+ dialog = Gtk.AboutDialog()
+ self.assertTrue(isinstance(dialog, Gtk.Dialog))
+ self.assertTrue(isinstance(dialog, Gtk.Window))
+
+ # Gtk.MessageDialog
+ dialog = Gtk.MessageDialog(title='message dialog test',
+ flags=Gtk.DialogFlags.MODAL,
+ buttons=Gtk.ButtonsType.OK,
+ message_format='dude!')
+ self.assertTrue(isinstance(dialog, Gtk.Dialog))
+ self.assertTrue(isinstance(dialog, Gtk.Window))
+
+ self.assertEqual('message dialog test', dialog.get_title())
+ self.assertTrue(dialog.get_modal())
+ text = dialog.get_property('text')
+ self.assertEqual('dude!', text)
+
+ dialog.format_secondary_text('2nd text')
+ self.assertEqual(dialog.get_property('secondary-text'), '2nd text')
+ self.assertFalse(dialog.get_property('secondary-use-markup'))
+
+ dialog.format_secondary_markup('2nd markup')
+ self.assertEqual(dialog.get_property('secondary-text'), '2nd markup')
+ self.assertTrue(dialog.get_property('secondary-use-markup'))
+
+ # Gtk.ColorSelectionDialog
+ dialog = Gtk.ColorSelectionDialog("color selection dialog test")
+ self.assertTrue(isinstance(dialog, Gtk.Dialog))
+ self.assertTrue(isinstance(dialog, Gtk.Window))
+ self.assertEqual('color selection dialog test', dialog.get_title())
+
+ # Gtk.FileChooserDialog
+ # might cause a GVFS warning, do not break on this
+ old_mask = GLib.log_set_always_fatal(
+ GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
+ try:
+ dialog = Gtk.FileChooserDialog(title='file chooser dialog test',
+ buttons=('test-button1', 1),
+ action=Gtk.FileChooserAction.SAVE)
+ finally:
+ GLib.log_set_always_fatal(old_mask)
+ self.assertTrue(isinstance(dialog, Gtk.Dialog))
+ self.assertTrue(isinstance(dialog, Gtk.Window))
+
+ dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
+ self.assertEqual('file chooser dialog test', dialog.get_title())
+ button = dialog.get_widget_for_response(1)
+ self.assertEqual('test-button1', button.get_label())
+ button = dialog.get_widget_for_response(2)
+ self.assertEqual('test-button2', button.get_label())
+ button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
+ self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
+ action = dialog.get_property('action')
+ self.assertEqual(Gtk.FileChooserAction.SAVE, action)
+
+ # Gtk.FontSelectionDialog
+ dialog = Gtk.ColorSelectionDialog("font selection dialog test")
+ self.assertTrue(isinstance(dialog, Gtk.Dialog))
+ self.assertTrue(isinstance(dialog, Gtk.Window))
+ self.assertEqual('font selection dialog test', dialog.get_title())
+
+ # Gtk.RecentChooserDialog
+ test_manager = Gtk.RecentManager()
+ dialog = Gtk.RecentChooserDialog(title='recent chooser dialog test',
+ buttons=('test-button1', 1),
+ manager=test_manager)
+ self.assertTrue(isinstance(dialog, Gtk.Dialog))
+ self.assertTrue(isinstance(dialog, Gtk.Window))
+
+ dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
+ self.assertEqual('recent chooser dialog test', dialog.get_title())
+ button = dialog.get_widget_for_response(1)
+ self.assertEqual('test-button1', button.get_label())
+ button = dialog.get_widget_for_response(2)
+ self.assertEqual('test-button2', button.get_label())
+ button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
+ self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
+
+ class TestClass(GObject.GObject):
+ __gtype_name__ = "GIOverrideTreeAPITest"
+
+ def __init__(self, tester, int_value, string_value):
+ super(TestGtk.TestClass, self).__init__()
+ self.tester = tester
+ self.int_value = int_value
+ self.string_value = string_value
+
+ def check(self, int_value, string_value):
+ self.tester.assertEqual(int_value, self.int_value)
+ self.tester.assertEqual(string_value, self.string_value)
+
+ def test_buttons(self):
+ self.assertEqual(Gtk.Button, gi.overrides.Gtk.Button)
+
+ # test Gtk.Button
+ button = Gtk.Button()
+ self.assertTrue(isinstance(button, Gtk.Button))
+ self.assertTrue(isinstance(button, Gtk.Container))
+ self.assertTrue(isinstance(button, Gtk.Widget))
+ button = Gtk.Button(stock=Gtk.STOCK_CLOSE)
+ self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
+ self.assertTrue(button.get_use_stock())
+ self.assertTrue(button.get_use_underline())
+
+ # test Gtk.Button use_stock
+ button = Gtk.Button(label=Gtk.STOCK_CLOSE, use_stock=True, use_underline=True)
+ self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
+ self.assertTrue(button.get_use_stock())
+ self.assertTrue(button.get_use_underline())
+
+ # test Gtk.LinkButton
+ self.assertRaises(TypeError, Gtk.LinkButton)
+ button = Gtk.LinkButton('http://www.Gtk.org', 'Gtk')
+ self.assertTrue(isinstance(button, Gtk.Button))
+ self.assertTrue(isinstance(button, Gtk.Container))
+ self.assertTrue(isinstance(button, Gtk.Widget))
+ self.assertEqual('http://www.Gtk.org', button.get_uri())
+ self.assertEqual('Gtk', button.get_label())
+
+ def test_inheritance(self):
+ for name in gi.overrides.Gtk.__all__:
+ over = getattr(gi.overrides.Gtk, name)
+ for element in dir(Gtk):
+ try:
+ klass = getattr(Gtk, element)
+ info = klass.__info__
+ except (NotImplementedError, AttributeError):
+ continue
+
+ # Get all parent classes and interfaces klass inherits from
+ if isinstance(info, gi.types.ObjectInfo):
+ classes = list(info.get_interfaces())
+ parent = info.get_parent()
+ while parent.get_name() != "Object":
+ classes.append(parent)
+ parent = parent.get_parent()
+ classes = [kl for kl in classes if kl.get_namespace() == "Gtk"]
+ else:
+ continue
+
+ for kl in classes:
+ if kl.get_name() == name:
+ self.assertTrue(issubclass(klass, over,),
+ "%r does not inherit from override %r" % (klass, over,))
+
+ def test_editable(self):
+ self.assertEqual(Gtk.Editable, gi.overrides.Gtk.Editable)
+
+ # need to use Gtk.Entry because Editable is an interface
+ entry = Gtk.Entry()
+ pos = entry.insert_text('HeWorld', 0)
+ self.assertEqual(pos, 7)
+ pos = entry.insert_text('llo ', 2)
+ self.assertEqual(pos, 6)
+ text = entry.get_chars(0, 11)
+ self.assertEqual('Hello World', text)
+
+ def test_label(self):
+ label = Gtk.Label(label='Hello')
+ self.assertTrue(isinstance(label, Gtk.Widget))
+ self.assertEqual(label.get_text(), 'Hello')
+
+ def adjustment_check(self, adjustment, value=0.0, lower=0.0, upper=0.0,
+ step_increment=0.0, page_increment=0.0, page_size=0.0):
+ self.assertEqual(adjustment.get_value(), value)
+ self.assertEqual(adjustment.get_lower(), lower)
+ self.assertEqual(adjustment.get_upper(), upper)
+ self.assertEqual(adjustment.get_step_increment(), step_increment)
+ self.assertEqual(adjustment.get_page_increment(), page_increment)
+ self.assertEqual(adjustment.get_page_size(), page_size)
+
+ def test_adjustment(self):
+ adjustment = Gtk.Adjustment(1, 0, 6, 4, 5, 3)
+ self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
+
+ adjustment = Gtk.Adjustment(1, 0, 6, 4, 5)
+ self.adjustment_check(adjustment, 1, 0, 6, 4, 5)
+
+ adjustment = Gtk.Adjustment(1, 0, 6, 4)
+ self.adjustment_check(adjustment, 1, 0, 6, 4)
+
+ adjustment = Gtk.Adjustment(1, 0, 6)
+ self.adjustment_check(adjustment, 1, 0, 6)
+
+ adjustment = Gtk.Adjustment()
+ self.adjustment_check(adjustment)
+
+ adjustment = Gtk.Adjustment(value=1, lower=0, upper=6,
+ step_increment=4, page_increment=5, page_size=3)
+ self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
+
+ def test_table(self):
+ table = Gtk.Table()
+ self.assertTrue(isinstance(table, Gtk.Table))
+ self.assertTrue(isinstance(table, Gtk.Container))
+ self.assertTrue(isinstance(table, Gtk.Widget))
+ self.assertEqual(table.get_size(), (1, 1))
+ self.assertEqual(table.get_homogeneous(), False)
+ table = Gtk.Table(2, 3)
+ self.assertEqual(table.get_size(), (2, 3))
+ self.assertEqual(table.get_homogeneous(), False)
+ table = Gtk.Table(2, 3, True)
+ self.assertEqual(table.get_size(), (2, 3))
+ self.assertEqual(table.get_homogeneous(), True)
+
+ # Test PyGTK interface
+ table = Gtk.Table(rows=3, columns=2)
+ self.assertEqual(table.get_size(), (3, 2))
+ # Test using the actual property names
+ table = Gtk.Table(n_rows=2, n_columns=3, homogeneous=True)
+ self.assertEqual(table.get_size(), (2, 3))
+ self.assertEqual(table.get_homogeneous(), True)
+
+ label = Gtk.Label(label='Hello')
+ self.assertTrue(isinstance(label, Gtk.Widget))
+ table.attach(label, 0, 1, 0, 1)
+ self.assertEqual(label, table.get_children()[0])
+
+ def test_scrolledwindow(self):
+ sw = Gtk.ScrolledWindow()
+ self.assertTrue(isinstance(sw, Gtk.ScrolledWindow))
+ self.assertTrue(isinstance(sw, Gtk.Container))
+ self.assertTrue(isinstance(sw, Gtk.Widget))
+ sb = sw.get_hscrollbar()
+ self.assertEqual(sw.get_hadjustment(), sb.get_adjustment())
+ sb = sw.get_vscrollbar()
+ self.assertEqual(sw.get_vadjustment(), sb.get_adjustment())
+
+ def test_widget_drag_methods(self):
+ widget = Gtk.Button()
+
+ # here we are not checking functionality, only that the methods exist
+ # and except the right number of arguments
+
+ widget.drag_check_threshold(0, 0, 0, 0)
+
+ # drag_dest_ methods
+ widget.drag_dest_set(Gtk.DestDefaults.DROP, None, Gdk.DragAction.COPY)
+ widget.drag_dest_add_image_targets()
+ widget.drag_dest_add_text_targets()
+ widget.drag_dest_add_uri_targets()
+ widget.drag_dest_get_track_motion()
+ widget.drag_dest_set_track_motion(True)
+ widget.drag_dest_get_target_list()
+ widget.drag_dest_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
+ widget.drag_dest_unset()
+
+ widget.drag_highlight()
+ widget.drag_unhighlight()
+
+ # drag_source_ methods
+ widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, None, Gdk.DragAction.MOVE)
+ widget.drag_source_add_image_targets()
+ widget.drag_source_add_text_targets()
+ widget.drag_source_add_uri_targets()
+ widget.drag_source_set_icon_name("")
+ widget.drag_source_set_icon_pixbuf(GdkPixbuf.Pixbuf())
+ widget.drag_source_set_icon_stock("")
+ widget.drag_source_get_target_list()
+ widget.drag_source_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
+ widget.drag_source_unset()
+
+ # these methods cannot be called because they require a valid drag on
+ # a real GdkWindow. So we only check that they exist and are callable.
+ self.assertTrue(hasattr(widget, 'drag_dest_set_proxy'))
+ self.assertTrue(hasattr(widget, 'drag_get_data'))
+
+ def test_drag_target_list(self):
+ mixed_target_list = [Gtk.TargetEntry.new('test0', 0, 0),
+ ('test1', 1, 1),
+ Gtk.TargetEntry.new('test2', 2, 2),
+ ('test3', 3, 3)]
+
+ def _test_target_list(targets):
+ for i, target in enumerate(targets):
+ self.assertTrue(isinstance(target, Gtk.TargetEntry))
+ self.assertEqual(target.target, 'test' + str(i))
+ self.assertEqual(target.flags, i)
+ self.assertEqual(target.info, i)
+
+ _test_target_list(Gtk._construct_target_list(mixed_target_list))
+
+ widget = Gtk.Button()
+ widget.drag_dest_set(Gtk.DestDefaults.DROP, None, Gdk.DragAction.COPY)
+ widget.drag_dest_set_target_list(mixed_target_list)
+ widget.drag_dest_get_target_list()
+
+ widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, None, Gdk.DragAction.MOVE)
+ widget.drag_source_set_target_list(mixed_target_list)
+ widget.drag_source_get_target_list()
+
+ treeview = Gtk.TreeView()
+ treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK,
+ mixed_target_list,
+ Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE)
+
+ treeview.enable_model_drag_dest(mixed_target_list,
+ Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE)
+
+ def test_scrollbar(self):
+ # PyGTK compat
+ adjustment = Gtk.Adjustment()
+
+ hscrollbar = Gtk.HScrollbar()
+ vscrollbar = Gtk.VScrollbar()
+ self.assertNotEqual(hscrollbar.props.adjustment, adjustment)
+ self.assertNotEqual(vscrollbar.props.adjustment, adjustment)
+
+ hscrollbar = Gtk.HScrollbar(adjustment)
+ vscrollbar = Gtk.VScrollbar(adjustment)
+ self.assertEqual(hscrollbar.props.adjustment, adjustment)
+ self.assertEqual(vscrollbar.props.adjustment, adjustment)
+
+ def test_iconview(self):
+ # PyGTK compat
+ iconview = Gtk.IconView()
+ self.assertEqual(iconview.props.model, None)
+
+ model = Gtk.ListStore(str)
+ iconview = Gtk.IconView(model)
+ self.assertEqual(iconview.props.model, model)
+
+ def test_toolbutton(self):
+ # PyGTK compat
+ button = Gtk.ToolButton()
+ self.assertEqual(button.props.stock_id, None)
+
+ button = Gtk.ToolButton('gtk-new')
+ self.assertEqual(button.props.stock_id, 'gtk-new')
+
+ icon = Gtk.Image.new_from_stock(Gtk.STOCK_OPEN, Gtk.IconSize.SMALL_TOOLBAR)
+
+ button = Gtk.ToolButton(label='mylabel', icon_widget=icon)
+ self.assertEqual(button.props.label, 'mylabel')
+ self.assertEqual(button.props.icon_widget, icon)
+
+ def test_iconset(self):
+ # PyGTK compat
+ Gtk.IconSet()
+ pixbuf = GdkPixbuf.Pixbuf()
+ Gtk.IconSet(pixbuf)
+
+ def test_viewport(self):
+ # PyGTK compat
+ vadjustment = Gtk.Adjustment()
+ hadjustment = Gtk.Adjustment()
+
+ viewport = Gtk.Viewport(hadjustment=hadjustment,
+ vadjustment=vadjustment)
+
+ self.assertEqual(viewport.props.vadjustment, vadjustment)
+ self.assertEqual(viewport.props.hadjustment, hadjustment)
+
+ def test_stock_lookup(self):
+ l = Gtk.stock_lookup('gtk-ok')
+ self.assertEqual(type(l), Gtk.StockItem)
+ self.assertEqual(l.stock_id, 'gtk-ok')
+ self.assertEqual(Gtk.stock_lookup('nosuchthing'), None)
+
+ def test_gtk_main(self):
+ # with no arguments
+ GLib.timeout_add(100, Gtk.main_quit)
+ Gtk.main()
+
+ # overridden function ignores its arguments
+ GLib.timeout_add(100, Gtk.main_quit, 'hello')
+ Gtk.main()
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestSignals(unittest.TestCase):
+ class WindowWithSizeAllocOverride(Gtk.ScrolledWindow):
+ __gsignals__ = {'size-allocate': 'override'}
+
+ def __init__(self):
+ Gtk.ScrolledWindow.__init__(self)
+ self._alloc_called = False
+ self._alloc_value = None
+ self._alloc_error = None
+
+ def do_size_allocate(self, alloc):
+ self._alloc_called = True
+ self._alloc_value = alloc
+
+ try:
+ Gtk.ScrolledWindow.do_size_allocate(self, alloc)
+ except Exception as e:
+ self._alloc_error = e
+
+ def test_class_closure_override_with_aliased_type(self):
+ win = self.WindowWithSizeAllocOverride()
+ rect = Gdk.Rectangle()
+ rect.width = 100
+ rect.height = 100
+
+ with realized(win):
+ win.show()
+ win.size_allocate(rect)
+ self.assertTrue(win._alloc_called)
+ self.assertIsInstance(win._alloc_value, Gdk.Rectangle)
+ self.assertTrue(win._alloc_error is None, win._alloc_error)
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestBuilder(unittest.TestCase):
+ class SignalTest(GObject.GObject):
+ __gtype_name__ = "GIOverrideSignalTest"
+ __gsignals__ = {
+ "test-signal": (GObject.SignalFlags.RUN_FIRST,
+ None,
+ []),
+ }
+
+ def test_extract_handler_and_args_object(self):
+ class Obj():
+ pass
+
+ obj = Obj()
+ obj.foo = lambda: None
+
+ handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
+ self.assertEqual(handler, obj.foo)
+ self.assertEqual(len(args), 0)
+
+ def test_extract_handler_and_args_dict(self):
+ obj = {'foo': lambda: None}
+
+ handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
+ self.assertEqual(handler, obj['foo'])
+ self.assertEqual(len(args), 0)
+
+ def test_extract_handler_and_args_with_seq(self):
+ obj = {'foo': (lambda: None, 1, 2)}
+
+ handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
+ self.assertEqual(handler, obj['foo'][0])
+ self.assertSequenceEqual(args, [1, 2])
+
+ def test_extract_handler_and_args_no_handler_error(self):
+ obj = dict(foo=lambda: None)
+ self.assertRaises(AttributeError,
+ Gtk.Builder._extract_handler_and_args,
+ obj, 'not_a_handler')
+
+ def test_builder_with_handler_and_args(self):
+ builder = Gtk.Builder()
+ builder.add_from_string("""
+ <interface>
+ <object class="GIOverrideSignalTest" id="object_sig_test">
+ <signal name="test-signal" handler="on_signal1" />
+ <signal name="test-signal" handler="on_signal2" after="yes" />
+ </object>
+ </interface>
+ """)
+
+ args_collector = []
+
+ def on_signal(*args):
+ args_collector.append(args)
+
+ builder.connect_signals({'on_signal1': (on_signal, 1, 2),
+ 'on_signal2': on_signal})
+
+ objects = builder.get_objects()
+ self.assertEqual(len(objects), 1)
+ obj, = objects
+ obj.emit('test-signal')
+
+ self.assertEqual(len(args_collector), 2)
+ self.assertSequenceEqual(args_collector[0], (obj, 1, 2))
+ self.assertSequenceEqual(args_collector[1], (obj, ))
+
+ def test_builder(self):
+ self.assertEqual(Gtk.Builder, gi.overrides.Gtk.Builder)
+
+ class SignalCheck:
+ def __init__(self):
+ self.sentinel = 0
+ self.after_sentinel = 0
+
+ def on_signal_1(self, *args):
+ self.sentinel += 1
+ self.after_sentinel += 1
+
+ def on_signal_3(self, *args):
+ self.sentinel += 3
+
+ def on_signal_after(self, *args):
+ if self.after_sentinel == 1:
+ self.after_sentinel += 1
+
+ signal_checker = SignalCheck()
+ builder = Gtk.Builder()
+
+ # add object1 to the builder
+ builder.add_from_string("""
+<interface>
+ <object class="GIOverrideSignalTest" id="object1">
+ <signal name="test-signal" after="yes" handler="on_signal_after" />
+ <signal name="test-signal" handler="on_signal_1" />
+ </object>
+</interface>
+""")
+
+ # only add object3 to the builder
+ builder.add_objects_from_string("""
+<interface>
+ <object class="GIOverrideSignalTest" id="object2">
+ <signal name="test-signal" handler="on_signal_2" />
+ </object>
+ <object class="GIOverrideSignalTest" id="object3">
+ <signal name="test-signal" handler="on_signal_3" />
+ </object>
+ <object class="GIOverrideSignalTest" id="object4">
+ <signal name="test-signal" handler="on_signal_4" />
+ </object>
+</interface>
+""", ['object3'])
+
+ # hook up signals
+ builder.connect_signals(signal_checker)
+
+ # call their notify signals and check sentinel
+ objects = builder.get_objects()
+ self.assertEqual(len(objects), 2)
+ for obj in objects:
+ obj.emit('test-signal')
+
+ self.assertEqual(signal_checker.sentinel, 4)
+ self.assertEqual(signal_checker.after_sentinel, 2)
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestTreeModel(unittest.TestCase):
+ def test_tree_model_sort(self):
+ self.assertEqual(Gtk.TreeModelSort, gi.overrides.Gtk.TreeModelSort)
+ self.assertRaises(TypeError, Gtk.TreeModelSort)
+ model = Gtk.TreeStore(int, bool)
+ model_sort = Gtk.TreeModelSort(model)
+ self.assertEqual(model_sort.get_model(), model)
+
+ def test_tree_store(self):
+ self.assertEqual(Gtk.TreeStore, gi.overrides.Gtk.TreeStore)
+ self.assertEqual(Gtk.ListStore, gi.overrides.Gtk.ListStore)
+ self.assertEqual(Gtk.TreeModel, gi.overrides.Gtk.TreeModel)
+ self.assertEqual(Gtk.TreeViewColumn, gi.overrides.Gtk.TreeViewColumn)
+
+ class TestPyObject(object):
+ pass
+
+ test_pyobj = TestPyObject()
+ test_pydict = {1: 1, "2": 2, "3": "3"}
+ test_pylist = [1, "2", "3"]
+ tree_store = Gtk.TreeStore(int,
+ 'gchararray',
+ TestGtk.TestClass,
+ GObject.TYPE_PYOBJECT,
+ object,
+ object,
+ object,
+ bool,
+ bool,
+ GObject.TYPE_UINT,
+ GObject.TYPE_ULONG,
+ GObject.TYPE_INT64,
+ GObject.TYPE_UINT64,
+ GObject.TYPE_UCHAR,
+ GObject.TYPE_CHAR)
+
+ parent = None
+ for i in range(97):
+ label = 'this is child #%d' % i
+ testobj = TestGtk.TestClass(self, i, label)
+ parent = tree_store.append(parent, (i,
+ label,
+ testobj,
+ testobj,
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ i % 2,
+ bool(i % 2),
+ i,
+ GObject.G_MAXULONG,
+ GObject.G_MININT64,
+ 0xffffffffffffffff,
+ 254,
+ _bytes('a')
+ ))
+ # test set
+ parent = tree_store.append(parent)
+ i = 97
+ label = 'this is child #%d' % i
+ testobj = TestGtk.TestClass(self, i, label)
+ tree_store.set(parent,
+ 0, i,
+ 2, testobj,
+ 1, label,
+ 3, testobj,
+ 4, test_pyobj,
+ 5, test_pydict,
+ 6, test_pylist,
+ 7, i % 2,
+ 8, bool(i % 2),
+ 9, i,
+ 10, GObject.G_MAXULONG,
+ 11, GObject.G_MININT64,
+ 12, 0xffffffffffffffff,
+ 13, 254,
+ 14, _bytes('a'))
+
+ parent = tree_store.append(parent)
+ i = 98
+ label = 'this is child #%d' % i
+ testobj = TestGtk.TestClass(self, i, label)
+ tree_store.set(parent, {0: i,
+ 2: testobj,
+ 1: label,
+ 3: testobj,
+ 4: test_pyobj,
+ 5: test_pydict,
+ 6: test_pylist,
+ 7: i % 2,
+ 8: bool(i % 2),
+ 9: i,
+ 10: GObject.G_MAXULONG,
+ 11: GObject.G_MININT64,
+ 12: 0xffffffffffffffff,
+ 13: 254,
+ 14: _bytes('a')})
+
+ parent = tree_store.append(parent)
+ i = 99
+ label = 'this is child #%d' % i
+ testobj = TestGtk.TestClass(self, i, label)
+ tree_store.set(parent, (0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
+ (i,
+ testobj,
+ label,
+ testobj,
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ i % 2,
+ bool(i % 2),
+ i,
+ GObject.G_MAXULONG,
+ GObject.G_MININT64,
+ 0xffffffffffffffff,
+ 254,
+ _bytes('a')))
+
+ # len gets the number of children in the root node
+ # since we kept appending to the previous node
+ # there should only be one child of the root
+ self.assertEqual(len(tree_store), 1)
+
+ # walk the tree to see if the values were stored correctly
+ parent = None
+ i = 0
+
+ treeiter = tree_store.iter_children(parent)
+ while treeiter:
+ i = tree_store.get_value(treeiter, 0)
+ s = tree_store.get_value(treeiter, 1)
+ obj = tree_store.get_value(treeiter, 2)
+ obj.check(i, s)
+ obj2 = tree_store.get_value(treeiter, 3)
+ self.assertEqual(obj, obj2)
+
+ pyobj = tree_store.get_value(treeiter, 4)
+ self.assertEqual(pyobj, test_pyobj)
+ pydict = tree_store.get_value(treeiter, 5)
+ self.assertEqual(pydict, test_pydict)
+ pylist = tree_store.get_value(treeiter, 6)
+ self.assertEqual(pylist, test_pylist)
+
+ bool_1 = tree_store.get_value(treeiter, 7)
+ bool_2 = tree_store.get_value(treeiter, 8)
+ self.assertEqual(bool_1, bool_2)
+ self.assertTrue(isinstance(bool_1, bool))
+ self.assertTrue(isinstance(bool_2, bool))
+
+ uint_ = tree_store.get_value(treeiter, 9)
+ self.assertEqual(uint_, i)
+ ulong_ = tree_store.get_value(treeiter, 10)
+ self.assertEqual(ulong_, GObject.G_MAXULONG)
+ int64_ = tree_store.get_value(treeiter, 11)
+ self.assertEqual(int64_, GObject.G_MININT64)
+ uint64_ = tree_store.get_value(treeiter, 12)
+ self.assertEqual(uint64_, 0xffffffffffffffff)
+ uchar_ = tree_store.get_value(treeiter, 13)
+ self.assertEqual(ord(uchar_), 254)
+ char_ = tree_store.get_value(treeiter, 14)
+ self.assertEqual(char_, 'a')
+
+ parent = treeiter
+ treeiter = tree_store.iter_children(parent)
+
+ self.assertEqual(i, 99)
+
+ def test_tree_store_signals(self):
+ tree_store = Gtk.TreeStore(int, bool)
+
+ def on_row_inserted(tree_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-inserted')
+
+ def on_row_changed(tree_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-changed')
+
+ signals = []
+ tree_store.connect('row-inserted', on_row_inserted, signals)
+ tree_store.connect('row-changed', on_row_changed, signals)
+
+ # adding rows with and without data should only call one signal
+ tree_store.append(None, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.append(None)
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.prepend(None, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.prepend(None)
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.insert(None, 1, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.insert(None, 1)
+ self.assertEqual(signals, ['row-inserted'])
+
+ def test_list_store(self):
+ class TestPyObject(object):
+ pass
+
+ test_pyobj = TestPyObject()
+ test_pydict = {1: 1, "2": 2, "3": "3"}
+ test_pylist = [1, "2", "3"]
+
+ list_store = Gtk.ListStore(int, str, 'GIOverrideTreeAPITest', object, object, object, bool, bool)
+ for i in range(1, 93):
+ label = 'this is row #%d' % i
+ testobj = TestGtk.TestClass(self, i, label)
+ list_store.append((i,
+ label,
+ testobj,
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ i % 2,
+ bool(i % 2)))
+
+ i = 93
+ label = _unicode('this is row #93')
+ treeiter = list_store.append()
+ list_store.set_value(treeiter, 0, i)
+ list_store.set_value(treeiter, 1, label)
+ list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
+ list_store.set_value(treeiter, 3, test_pyobj)
+ list_store.set_value(treeiter, 4, test_pydict)
+ list_store.set_value(treeiter, 5, test_pylist)
+ list_store.set_value(treeiter, 6, 1)
+ list_store.set_value(treeiter, 7, True)
+
+ # test prepend
+ label = 'this is row #0'
+ list_store.prepend((0,
+ label,
+ TestGtk.TestClass(self, 0, label),
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ 0,
+ False))
+
+ # test automatic unicode->str conversion
+ i = 94
+ label = _unicode('this is row #94')
+ treeiter = list_store.append((i,
+ label,
+ TestGtk.TestClass(self, i, label),
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ 0,
+ False))
+
+ # add sorted items out of order to test insert* apis
+ # also test sending in None to not set a column
+ i = 97
+ label = 'this is row #97'
+ treeiter = list_store.append((None,
+ None,
+ None,
+ test_pyobj,
+ None,
+ test_pylist,
+ 1,
+ None))
+
+ list_store.set_value(treeiter, 0, i)
+ list_store.set_value(treeiter, 1, label)
+ list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
+ list_store.set_value(treeiter, 4, test_pydict)
+ list_store.set_value(treeiter, 7, True)
+
+ # this should append
+ i = 99
+ label = 'this is row #99'
+ list_store.insert(9999, (i,
+ label,
+ TestGtk.TestClass(self, i, label),
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ 1,
+ True))
+
+ i = 96
+ label = 'this is row #96'
+ list_store.insert_before(treeiter, (i,
+ label,
+ TestGtk.TestClass(self, i, label),
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ 0,
+ False))
+
+ i = 98
+ label = 'this is row #98'
+ list_store.insert_after(treeiter, (i,
+ label,
+ TestGtk.TestClass(self, i, label),
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ 0,
+ False))
+
+ i = 95
+ label = 'this is row #95'
+ list_store.insert(95, (i,
+ label,
+ TestGtk.TestClass(self, i, label),
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ 1,
+ True))
+
+ i = 100
+ label = 'this is row #100'
+ treeiter = list_store.append()
+ list_store.set(treeiter,
+ 1, label,
+ 0, i,
+ 2, TestGtk.TestClass(self, i, label),
+ 3, test_pyobj,
+ 4, test_pydict,
+ 5, test_pylist,
+ 6, 0,
+ 7, False)
+ i = 101
+ label = 'this is row #101'
+ treeiter = list_store.append()
+ list_store.set(treeiter, {1: label,
+ 0: i,
+ 2: TestGtk.TestClass(self, i, label),
+ 3: test_pyobj,
+ 4: test_pydict,
+ 5: test_pylist,
+ 6: 1,
+ 7: True})
+ i = 102
+ label = 'this is row #102'
+ treeiter = list_store.append()
+ list_store.set(treeiter, (1, 0, 2, 3, 4, 5, 6, 7),
+ (label,
+ i,
+ TestGtk.TestClass(self, i, label),
+ test_pyobj,
+ test_pydict,
+ test_pylist,
+ 0,
+ False))
+
+ self.assertEqual(len(list_store), 103)
+
+ # walk the list to see if the values were stored correctly
+ i = 0
+ treeiter = list_store.get_iter_first()
+
+ counter = 0
+ while treeiter:
+ i = list_store.get_value(treeiter, 0)
+ self.assertEqual(i, counter)
+ s = list_store.get_value(treeiter, 1)
+ obj = list_store.get_value(treeiter, 2)
+ obj.check(i, s)
+
+ pyobj = list_store.get_value(treeiter, 3)
+ self.assertEqual(pyobj, test_pyobj)
+ pydict = list_store.get_value(treeiter, 4)
+ self.assertEqual(pydict, test_pydict)
+ pylist = list_store.get_value(treeiter, 5)
+ self.assertEqual(pylist, test_pylist)
+
+ bool_1 = list_store.get_value(treeiter, 6)
+ bool_2 = list_store.get_value(treeiter, 7)
+ self.assertEqual(bool_1, bool_2)
+ self.assertTrue(isinstance(bool_1, bool))
+ self.assertTrue(isinstance(bool_2, bool))
+
+ treeiter = list_store.iter_next(treeiter)
+
+ counter += 1
+
+ self.assertEqual(i, 102)
+
+ def test_list_store_sort(self):
+ def comp1(model, row1, row2, user_data):
+ v1 = model[row1][1]
+ v2 = model[row2][1]
+
+ # make "m" smaller than anything else
+ if v1.startswith('m') and not v2.startswith('m'):
+ return -1
+ if v2.startswith('m') and not v1.startswith('m'):
+ return 1
+ return (v1 > v2) - (v1 < v2)
+
+ list_store = Gtk.ListStore(int, str)
+ list_store.set_sort_func(2, comp1, None)
+ list_store.append((1, 'apples'))
+ list_store.append((3, 'oranges'))
+ list_store.append((2, 'mango'))
+
+ # not sorted yet, should be original order
+ self.assertEqual([list(i) for i in list_store],
+ [[1, 'apples'], [3, 'oranges'], [2, 'mango']])
+
+ # sort with our custom function
+ list_store.set_sort_column_id(2, Gtk.SortType.ASCENDING)
+ self.assertEqual([list(i) for i in list_store],
+ [[2, 'mango'], [1, 'apples'], [3, 'oranges']])
+
+ list_store.set_sort_column_id(2, Gtk.SortType.DESCENDING)
+ self.assertEqual([list(i) for i in list_store],
+ [[3, 'oranges'], [1, 'apples'], [2, 'mango']])
+
+ def test_list_store_signals(self):
+ list_store = Gtk.ListStore(int, bool)
+
+ def on_row_inserted(list_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-inserted')
+
+ def on_row_changed(list_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-changed')
+
+ signals = []
+ list_store.connect('row-inserted', on_row_inserted, signals)
+ list_store.connect('row-changed', on_row_changed, signals)
+
+ # adding rows with and without data should only call one signal
+ list_store.append((0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.append()
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.prepend((0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.prepend()
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.insert(1, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.insert(1)
+ self.assertEqual(signals, ['row-inserted'])
+
+ def test_tree_path(self):
+ p1 = Gtk.TreePath()
+ p2 = Gtk.TreePath.new_first()
+ self.assertEqual(p1, p2)
+ self.assertEqual(str(p1), '0')
+ self.assertEqual(len(p1), 1)
+ p1 = Gtk.TreePath(2)
+ p2 = Gtk.TreePath.new_from_string('2')
+ self.assertEqual(p1, p2)
+ self.assertEqual(str(p1), '2')
+ self.assertEqual(len(p1), 1)
+ p1 = Gtk.TreePath('1:2:3')
+ p2 = Gtk.TreePath.new_from_string('1:2:3')
+ self.assertEqual(p1, p2)
+ self.assertEqual(str(p1), '1:2:3')
+ self.assertEqual(len(p1), 3)
+ p1 = Gtk.TreePath((1, 2, 3))
+ p2 = Gtk.TreePath.new_from_string('1:2:3')
+ self.assertEqual(p1, p2)
+ self.assertEqual(str(p1), '1:2:3')
+ self.assertEqual(len(p1), 3)
+ self.assertNotEqual(p1, None)
+ self.assertTrue(p1 > None)
+ self.assertTrue(p1 >= None)
+ self.assertFalse(p1 < None)
+ self.assertFalse(p1 <= None)
+
+ self.assertEqual(tuple(p1), (1, 2, 3))
+ self.assertEqual(p1[0], 1)
+ self.assertEqual(p1[1], 2)
+ self.assertEqual(p1[2], 3)
+ self.assertRaises(IndexError, p1.__getitem__, 3)
+
+ def test_tree_model(self):
+ tree_store = Gtk.TreeStore(int, str)
+
+ self.assertTrue(tree_store)
+ self.assertEqual(len(tree_store), 0)
+ self.assertEqual(tree_store.get_iter_first(), None)
+
+ def get_by_index(row, col=None):
+ if col:
+ return tree_store[row][col]
+ else:
+ return tree_store[row]
+
+ self.assertRaises(TypeError, get_by_index, None)
+ self.assertRaises(TypeError, get_by_index, "")
+ self.assertRaises(TypeError, get_by_index, ())
+
+ self.assertRaises(IndexError, get_by_index, "0")
+ self.assertRaises(IndexError, get_by_index, 0)
+ self.assertRaises(IndexError, get_by_index, (0,))
+
+ self.assertRaises(ValueError, tree_store.get_iter, "0")
+ self.assertRaises(ValueError, tree_store.get_iter, 0)
+ self.assertRaises(ValueError, tree_store.get_iter, (0,))
+
+ self.assertRaises(ValueError, tree_store.get_iter_from_string, "0")
+
+ for row in tree_store:
+ self.fail("Should not be reached")
+
+ class DerivedIntType(int):
+ pass
+
+ class DerivedStrType(str):
+ pass
+
+ for i in range(100):
+ label = 'this is row #%d' % i
+ parent = tree_store.append(None, (DerivedIntType(i), DerivedStrType(label),))
+ self.assertNotEqual(parent, None)
+ for j in range(20):
+ label = 'this is child #%d of node #%d' % (j, i)
+ child = tree_store.append(parent, (j, label,))
+ self.assertNotEqual(child, None)
+
+ self.assertTrue(tree_store)
+ self.assertEqual(len(tree_store), 100)
+
+ self.assertEqual(tree_store.iter_previous(tree_store.get_iter(0)), None)
+
+ for i, row in enumerate(tree_store):
+ self.assertEqual(row.model, tree_store)
+ self.assertEqual(row.parent, None)
+
+ self.assertEqual(tree_store[i].path, row.path)
+ self.assertEqual(tree_store[str(i)].path, row.path)
+ self.assertEqual(tree_store[(i,)].path, row.path)
+
+ self.assertEqual(tree_store[i][0], i)
+ self.assertEqual(tree_store[i][1], "this is row #%d" % i)
+
+ aiter = tree_store.get_iter(i)
+ self.assertEqual(tree_store.get_path(aiter), row.path)
+
+ aiter = tree_store.get_iter(str(i))
+ self.assertEqual(tree_store.get_path(aiter), row.path)
+
+ aiter = tree_store.get_iter((i,))
+ self.assertEqual(tree_store.get_path(aiter), row.path)
+
+ self.assertEqual(tree_store.iter_parent(aiter), row.parent)
+
+ next = tree_store.iter_next(aiter)
+ if i < len(tree_store) - 1:
+ self.assertEqual(tree_store.get_path(next), row.next.path)
+ self.assertEqual(tree_store.get_path(tree_store.iter_previous(next)),
+ tree_store.get_path(aiter))
+ else:
+ self.assertEqual(next, None)
+
+ self.assertEqual(tree_store.iter_n_children(row.iter), 20)
+
+ child = tree_store.iter_children(row.iter)
+ for j, childrow in enumerate(row.iterchildren()):
+ child_path = tree_store.get_path(child)
+ self.assertEqual(childrow.path, child_path)
+ self.assertEqual(childrow.parent.path, row.path)
+ self.assertEqual(childrow.path, tree_store[child].path)
+ self.assertEqual(childrow.path, tree_store[child_path].path)
+
+ self.assertEqual(childrow[0], tree_store[child][0])
+ self.assertEqual(childrow[0], j)
+ self.assertEqual(childrow[1], tree_store[child][1])
+ self.assertEqual(childrow[1], 'this is child #%d of node #%d' % (j, i))
+
+ self.assertRaises(IndexError, get_by_index, child, 2)
+
+ tree_store[child][1] = 'this was child #%d of node #%d' % (j, i)
+ self.assertEqual(childrow[1], 'this was child #%d of node #%d' % (j, i))
+
+ nth_child = tree_store.iter_nth_child(row.iter, j)
+ self.assertEqual(childrow.path, tree_store.get_path(nth_child))
+
+ childrow2 = tree_store["%d:%d" % (i, j)]
+ self.assertEqual(childrow.path, childrow2.path)
+
+ childrow2 = tree_store[(i, j,)]
+ self.assertEqual(childrow.path, childrow2.path)
+
+ child = tree_store.iter_next(child)
+ if j < 19:
+ self.assertEqual(childrow.next.path, tree_store.get_path(child))
+ else:
+ self.assertEqual(child, childrow.next)
+ self.assertEqual(child, None)
+
+ self.assertEqual(j, 19)
+
+ self.assertEqual(i, 99)
+
+ # negative indices
+ for i in range(-1, -100, -1):
+ i_real = i + 100
+ self.assertEqual(tree_store[i][0], i_real)
+
+ row = tree_store[i]
+ for j in range(-1, -20, -1):
+ j_real = j + 20
+ path = (i_real, j_real,)
+
+ self.assertEqual(tree_store[path][-2], j_real)
+
+ label = 'this was child #%d of node #%d' % (j_real, i_real)
+ self.assertEqual(tree_store[path][-1], label)
+
+ new_label = 'this still is child #%d of node #%d' % (j_real, i_real)
+ tree_store[path][-1] = new_label
+ self.assertEqual(tree_store[path][-1], new_label)
+
+ self.assertRaises(IndexError, get_by_index, path, -3)
+
+ self.assertRaises(IndexError, get_by_index, -101)
+
+ last_row = tree_store[99]
+ self.assertNotEqual(last_row, None)
+
+ for i, childrow in enumerate(last_row.iterchildren()):
+ if i < 19:
+ self.assertTrue(tree_store.remove(childrow.iter))
+ else:
+ self.assertFalse(tree_store.remove(childrow.iter))
+
+ self.assertEqual(i, 19)
+
+ self.assertEqual(tree_store.iter_n_children(last_row.iter), 0)
+ for childrow in last_row.iterchildren():
+ self.fail("Should not be reached")
+
+ aiter = tree_store.get_iter(10)
+ self.assertRaises(TypeError, tree_store.get, aiter, 1, 'a')
+ self.assertRaises(ValueError, tree_store.get, aiter, 1, -1)
+ self.assertRaises(ValueError, tree_store.get, aiter, 1, 100)
+ self.assertEqual(tree_store.get(aiter, 0, 1), (10, 'this is row #10'))
+
+ # check __delitem__
+ self.assertEqual(len(tree_store), 100)
+ aiter = tree_store.get_iter(10)
+ del tree_store[aiter]
+ self.assertEqual(len(tree_store), 99)
+ self.assertRaises(TypeError, tree_store.__delitem__, None)
+ self.assertRaises(IndexError, tree_store.__delitem__, -101)
+ self.assertRaises(IndexError, tree_store.__delitem__, 101)
+
+ def test_tree_model_get_iter_fail(self):
+ # TreeModel class with a failing get_iter()
+ class MyTreeModel(GObject.GObject, Gtk.TreeModel):
+ def do_get_iter(self, iter):
+ return (False, None)
+
+ tm = MyTreeModel()
+ self.assertEqual(tm.get_iter_first(), None)
+
+ def test_tree_model_edit(self):
+ model = Gtk.ListStore(int, str, float)
+ model.append([1, "one", -0.1])
+ model.append([2, "two", -0.2])
+
+ def set_row(value):
+ model[1] = value
+
+ self.assertRaises(TypeError, set_row, 3)
+ self.assertRaises(TypeError, set_row, "three")
+ self.assertRaises(ValueError, set_row, [])
+ self.assertRaises(ValueError, set_row, [3, "three"])
+
+ model[0] = (3, "three", -0.3)
+
+ def test_tree_row_slice(self):
+ model = Gtk.ListStore(int, str, float)
+ model.append([1, "one", -0.1])
+
+ self.assertEqual([1, "one", -0.1], model[0][:])
+ self.assertEqual([1, "one"], model[0][:2])
+ self.assertEqual(["one", -0.1], model[0][1:])
+ self.assertEqual(["one"], model[0][1:-1])
+ self.assertEqual([1], model[0][:-2])
+ self.assertEqual([], model[0][5:])
+ self.assertEqual([1, -0.1], model[0][0:3:2])
+
+ model[0][:] = (2, "two", -0.2)
+ self.assertEqual([2, "two", -0.2], model[0][:])
+
+ model[0][:2] = (3, "three")
+ self.assertEqual([3, "three", -0.2], model[0][:])
+
+ model[0][1:] = ("four", -0.4)
+ self.assertEqual([3, "four", -0.4], model[0][:])
+
+ model[0][1:-1] = ("five",)
+ self.assertEqual([3, "five", -0.4], model[0][:])
+
+ model[0][0:3:2] = (6, -0.6)
+ self.assertEqual([6, "five", -0.6], model[0][:])
+
+ def set_row1():
+ model[0][5:] = ("doesn't", "matter",)
+
+ self.assertRaises(ValueError, set_row1)
+
+ def set_row2():
+ model[0][:1] = (0, "zero", 0)
+
+ self.assertRaises(ValueError, set_row2)
+
+ def set_row3():
+ model[0][:2] = ("0", 0)
+
+ self.assertRaises(TypeError, set_row3)
+
+ def test_tree_model_set_value_to_none(self):
+ # Tests allowing the usage of None to set an empty value on a model.
+ store = Gtk.ListStore(str)
+ row = store.append(['test'])
+ self.assertSequenceEqual(store[0][:], ['test'])
+ store.set_value(row, 0, None)
+ self.assertSequenceEqual(store[0][:], [None])
+
+ def test_signal_emission_tree_path_coerce(self):
+ class Model(GObject.Object, Gtk.TreeModel):
+ pass
+
+ model = Model()
+ tree_paths = []
+
+ def on_any_signal(model, path, *args):
+ tree_paths.append(path.to_string())
+
+ model.connect('row-changed', on_any_signal)
+ model.connect('row-deleted', on_any_signal)
+ model.connect('row-has-child-toggled', on_any_signal)
+ model.connect('row-inserted', on_any_signal)
+
+ model.row_changed('0', Gtk.TreeIter())
+ self.assertEqual(tree_paths[-1], '0')
+
+ model.row_deleted('1')
+ self.assertEqual(tree_paths[-1], '1')
+
+ model.row_has_child_toggled('2', Gtk.TreeIter())
+ self.assertEqual(tree_paths[-1], '2')
+
+ model.row_inserted('3', Gtk.TreeIter())
+ self.assertEqual(tree_paths[-1], '3')
+
+ def test_tree_model_filter(self):
+ model = Gtk.ListStore(int, str, float)
+ model.append([1, "one", -0.1])
+ model.append([2, "two", -0.2])
+
+ filtered = Gtk.TreeModelFilter(child_model=model)
+
+ self.assertEqual(filtered[0][1], 'one')
+ filtered[0][1] = 'ONE'
+ self.assertEqual(filtered[0][1], 'ONE')
+
+ def test_list_store_performance(self):
+ model = Gtk.ListStore(int, str)
+
+ iterations = 2000
+ start = time.clock()
+ i = iterations
+ while i > 0:
+ model.append([1, 'hello'])
+ i -= 1
+ end = time.clock()
+ sys.stderr.write('[%.0f µs/append] ' % ((end - start) * 1000000 / iterations))
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestTreeView(unittest.TestCase):
+ def test_tree_view(self):
+ store = Gtk.ListStore(int, str)
+ store.append((0, "foo"))
+ store.append((1, "bar"))
+ view = Gtk.TreeView()
+
+ with realized(view):
+ view.set_cursor(store[1].path)
+ view.set_cursor(str(store[1].path))
+
+ view.get_cell_area(store[1].path)
+ view.get_cell_area(str(store[1].path))
+
+ def test_tree_view_column(self):
+ cell = Gtk.CellRendererText()
+ Gtk.TreeViewColumn(title='This is just a test',
+ cell_renderer=cell,
+ text=0,
+ style=2)
+
+ def test_tree_view_add_column_with_attributes(self):
+ model = Gtk.ListStore(str, str, str)
+ # deliberately use out-of-order sorting here; we assign column 0 to
+ # model index 2, etc.
+ model.append(['cell13', 'cell11', 'cell12'])
+ model.append(['cell23', 'cell21', 'cell22'])
+
+ tree = Gtk.TreeView(model)
+ cell1 = Gtk.CellRendererText()
+ cell2 = Gtk.CellRendererText()
+ cell3 = Gtk.CellRendererText()
+ cell4 = Gtk.CellRendererText()
+
+ tree.insert_column_with_attributes(0, 'Head2', cell2, text=2)
+ tree.insert_column_with_attributes(0, 'Head1', cell1, text=1)
+ tree.insert_column_with_attributes(-1, 'Head3', cell3, text=0)
+ # unconnected
+ tree.insert_column_with_attributes(-1, 'Head4', cell4)
+
+ with realized(tree):
+ tree.set_cursor(model[0].path)
+ while Gtk.events_pending():
+ Gtk.main_iteration()
+
+ self.assertEqual(tree.get_column(0).get_title(), 'Head1')
+ self.assertEqual(tree.get_column(1).get_title(), 'Head2')
+ self.assertEqual(tree.get_column(2).get_title(), 'Head3')
+ self.assertEqual(tree.get_column(3).get_title(), 'Head4')
+
+ # cursor should be at the first row
+ self.assertEqual(cell1.props.text, 'cell11')
+ self.assertEqual(cell2.props.text, 'cell12')
+ self.assertEqual(cell3.props.text, 'cell13')
+ self.assertEqual(cell4.props.text, None)
+
+ def test_tree_view_column_set_attributes(self):
+ store = Gtk.ListStore(int, str)
+ directors = ['Fellini', 'Tarantino', 'Tarkovskiy']
+ for i, director in enumerate(directors):
+ store.append([i, director])
+
+ treeview = Gtk.TreeView()
+ treeview.set_model(store)
+
+ column = Gtk.TreeViewColumn()
+ treeview.append_column(column)
+
+ cell = Gtk.CellRendererText()
+ column.pack_start(cell, expand=True)
+ column.set_attributes(cell, text=1)
+
+ with realized(treeview):
+ self.assertTrue(cell.props.text in directors)
+
+ def test_tree_selection(self):
+ store = Gtk.ListStore(int, str)
+ for i in range(10):
+ store.append((i, "foo"))
+ view = Gtk.TreeView()
+ view.set_model(store)
+ firstpath = store.get_path(store.get_iter_first())
+ sel = view.get_selection()
+
+ sel.select_path(firstpath)
+ (m, s) = sel.get_selected()
+ self.assertEqual(m, store)
+ self.assertEqual(store.get_path(s), firstpath)
+
+ sel.select_path(0)
+ (m, s) = sel.get_selected()
+ self.assertEqual(m, store)
+ self.assertEqual(store.get_path(s), firstpath)
+
+ sel.select_path("0:0")
+ (m, s) = sel.get_selected()
+ self.assertEqual(m, store)
+ self.assertEqual(store.get_path(s), firstpath)
+
+ sel.select_path((0, 0))
+ (m, s) = sel.get_selected()
+ self.assertEqual(m, store)
+ self.assertEqual(store.get_path(s), firstpath)
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestTextBuffer(unittest.TestCase):
+ def test_text_buffer(self):
+ self.assertEqual(Gtk.TextBuffer, gi.overrides.Gtk.TextBuffer)
+ buffer = Gtk.TextBuffer()
+ tag = buffer.create_tag('title', font='Sans 18')
+
+ self.assertEqual(tag.props.name, 'title')
+ self.assertEqual(tag.props.font, 'Sans 18')
+
+ (start, end) = buffer.get_bounds()
+
+ mark = buffer.create_mark(None, start)
+ self.assertFalse(mark.get_left_gravity())
+
+ buffer.set_text('Hello Jane Hello Bob')
+ (start, end) = buffer.get_bounds()
+ text = buffer.get_text(start, end, False)
+ self.assertEqual(text, 'Hello Jane Hello Bob')
+
+ buffer.set_text('')
+ (start, end) = buffer.get_bounds()
+ text = buffer.get_text(start, end, False)
+ self.assertEqual(text, '')
+
+ buffer.insert(end, 'HelloHello')
+ buffer.insert(end, ' Bob')
+
+ cursor_iter = end.copy()
+ cursor_iter.backward_chars(9)
+ buffer.place_cursor(cursor_iter)
+ buffer.insert_at_cursor(' Jane ')
+
+ (start, end) = buffer.get_bounds()
+ text = buffer.get_text(start, end, False)
+ self.assertEqual(text, 'Hello Jane Hello Bob')
+
+ sel = buffer.get_selection_bounds()
+ self.assertEqual(sel, ())
+ buffer.select_range(start, end)
+ sel = buffer.get_selection_bounds()
+ self.assertTrue(sel[0].equal(start))
+ self.assertTrue(sel[1].equal(end))
+
+ buffer.set_text('')
+ buffer.insert_with_tags(buffer.get_start_iter(), 'HelloHello', tag)
+ (start, end) = buffer.get_bounds()
+ self.assertTrue(start.begins_tag(tag))
+ self.assertTrue(start.has_tag(tag))
+
+ buffer.set_text('')
+ buffer.insert_with_tags_by_name(buffer.get_start_iter(), 'HelloHello', 'title')
+ (start, end) = buffer.get_bounds()
+ self.assertTrue(start.begins_tag(tag))
+ self.assertTrue(start.has_tag(tag))
+
+ self.assertRaises(ValueError, buffer.insert_with_tags_by_name,
+ buffer.get_start_iter(), 'HelloHello', 'unknowntag')
+
+ def test_text_iter(self):
+ self.assertEqual(Gtk.TextIter, gi.overrides.Gtk.TextIter)
+ buffer = Gtk.TextBuffer()
+ buffer.set_text('Hello Jane Hello Bob')
+ tag = buffer.create_tag('title', font='Sans 18')
+ (start, end) = buffer.get_bounds()
+ start.forward_chars(10)
+ buffer.apply_tag(tag, start, end)
+ self.assertTrue(start.begins_tag())
+ self.assertTrue(end.ends_tag())
+ self.assertTrue(start.toggles_tag())
+ self.assertTrue(end.toggles_tag())
+ start.backward_chars(1)
+ self.assertFalse(start.begins_tag())
+ self.assertFalse(start.ends_tag())
+ self.assertFalse(start.toggles_tag())
+
+ def test_text_buffer_search(self):
+ buffer = Gtk.TextBuffer()
+ buffer.set_text('Hello World Hello GNOME')
+
+ i = buffer.get_iter_at_offset(0)
+ self.assertTrue(isinstance(i, Gtk.TextIter))
+
+ self.assertEqual(i.forward_search('world', 0, None), None)
+
+ (start, end) = i.forward_search('World', 0, None)
+ self.assertEqual(start.get_offset(), 6)
+ self.assertEqual(end.get_offset(), 11)
+
+ (start, end) = i.forward_search('world',
+ Gtk.TextSearchFlags.CASE_INSENSITIVE,
+ None)
+ self.assertEqual(start.get_offset(), 6)
+ self.assertEqual(end.get_offset(), 11)
diff --git a/tests/test_overrides_pango.py b/tests/test_overrides_pango.py
new file mode 100644
index 0000000..42d4de9
--- /dev/null
+++ b/tests/test_overrides_pango.py
@@ -0,0 +1,37 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+
+try:
+ from gi.repository import Pango
+ Pango
+except ImportError:
+ Pango = None
+
+
+@unittest.skipUnless(Pango, 'Pango not available')
+class TestPango(unittest.TestCase):
+
+ def test_default_font_description(self):
+ desc = Pango.FontDescription()
+ self.assertEqual(desc.get_variant(), Pango.Variant.NORMAL)
+
+ def test_font_description(self):
+ desc = Pango.FontDescription('monospace')
+ self.assertEqual(desc.get_family(), 'monospace')
+ self.assertEqual(desc.get_variant(), Pango.Variant.NORMAL)
+
+ def test_layout(self):
+ self.assertRaises(TypeError, Pango.Layout)
+ context = Pango.Context()
+ layout = Pango.Layout(context)
+ self.assertEqual(layout.get_context(), context)
+
+ layout.set_markup("Foobar")
+ self.assertEqual(layout.get_text(), "Foobar")
+
+ def test_break_keyword_escape(self):
+ # https://bugzilla.gnome.org/show_bug.cgi?id=697363
+ self.assertTrue(hasattr(Pango, 'break_'))
+ self.assertTrue(Pango.break_ is not None)
diff --git a/tests/test_properties.py b/tests/test_properties.py
index f7f8e25..ef6b867 100644
--- a/tests/test_properties.py
+++ b/tests/test_properties.py
@@ -2,20 +2,28 @@
import sys
import struct
+import types
import unittest
from gi.repository import GObject
-from gi.repository.GObject import GType, GEnum, new, PARAM_READWRITE, \
- PARAM_CONSTRUCT, PARAM_READABLE, PARAM_WRITABLE, PARAM_CONSTRUCT_ONLY
+from gi.repository.GObject import GType, new, PARAM_READWRITE, \
+ PARAM_CONSTRUCT, PARAM_READABLE, PARAM_WRITABLE, PARAM_CONSTRUCT_ONLY
from gi.repository.GObject import \
- TYPE_INT, TYPE_UINT, TYPE_LONG, \
- TYPE_ULONG, TYPE_INT64, TYPE_UINT64
+ TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_INT64, \
+ TYPE_UINT64, TYPE_GTYPE, TYPE_INVALID, TYPE_NONE, TYPE_STRV, \
+ TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, TYPE_BOOLEAN, TYPE_FLOAT, \
+ TYPE_DOUBLE, TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
+ TYPE_STRING, TYPE_PYOBJECT, TYPE_VARIANT
+
from gi.repository.GObject import \
- G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, \
- G_MAXULONG
+ G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, G_MAXULONG, \
+ G_MAXUINT64, G_MAXINT64, G_MININT64
from gi.repository import Gio
from gi.repository import GLib
+from gi.repository import Regress
+from gi.repository import GIMarshallingTests
+from gi._gobject import propertyhelper
if sys.version_info < (3, 0):
TEST_UTF8 = "\xe2\x99\xa5"
@@ -26,56 +34,116 @@ else:
from compathelper import _long
+
class PropertyObject(GObject.GObject):
normal = GObject.Property(type=str)
construct = GObject.Property(
type=str,
- flags=PARAM_READWRITE|PARAM_CONSTRUCT, default='default')
+ flags=PARAM_READWRITE | PARAM_CONSTRUCT, default='default')
construct_only = GObject.Property(
type=str,
- flags=PARAM_READWRITE|PARAM_CONSTRUCT_ONLY)
+ flags=PARAM_READWRITE | PARAM_CONSTRUCT_ONLY)
uint64 = GObject.Property(
- type=TYPE_UINT64, flags=PARAM_READWRITE|PARAM_CONSTRUCT)
+ type=TYPE_UINT64, flags=PARAM_READWRITE | PARAM_CONSTRUCT)
enum = GObject.Property(
type=Gio.SocketType, default=Gio.SocketType.STREAM)
boxed = GObject.Property(
- type=GLib.Regex, flags=PARAM_READWRITE|PARAM_CONSTRUCT)
+ type=GLib.Regex, flags=PARAM_READWRITE | PARAM_CONSTRUCT)
+
+ flags = GObject.Property(
+ type=GIMarshallingTests.Flags, flags=PARAM_READWRITE | PARAM_CONSTRUCT,
+ default=GIMarshallingTests.Flags.VALUE1)
+
+ gtype = GObject.Property(
+ type=TYPE_GTYPE, flags=PARAM_READWRITE | PARAM_CONSTRUCT)
+
+ strings = GObject.Property(
+ type=TYPE_STRV, flags=PARAM_READWRITE | PARAM_CONSTRUCT)
+
+ variant = GObject.Property(
+ type=TYPE_VARIANT, flags=PARAM_READWRITE | PARAM_CONSTRUCT)
+
+ variant_def = GObject.Property(
+ type=TYPE_VARIANT, flags=PARAM_READWRITE | PARAM_CONSTRUCT,
+ default=GLib.Variant('i', 42))
+
+ interface = GObject.Property(
+ type=Gio.File, flags=PARAM_READWRITE | PARAM_CONSTRUCT)
+
+
+class PropertyInheritanceObject(Regress.TestObj):
+ # override property from the base class, with a different type
+ string = GObject.Property(type=int)
+
+ # a property entirely defined at the Python level
+ python_prop = GObject.Property(type=str)
+
-class TestProperties(unittest.TestCase):
- def testGetSet(self):
+class PropertySubClassObject(PropertyInheritanceObject):
+ # override property from the base class, with a different type
+ python_prop = GObject.Property(type=int)
+
+
+class TestPropertyInheritanceObject(unittest.TestCase):
+ def test_override_gi_property(self):
+ self.assertNotEqual(Regress.TestObj.props.string.value_type,
+ PropertyInheritanceObject.props.string.value_type)
+ obj = PropertyInheritanceObject()
+ self.assertEqual(type(obj.props.string), int)
+ obj.props.string = 4
+ self.assertEqual(obj.props.string, 4)
+
+ def test_override_python_property(self):
+ obj = PropertySubClassObject()
+ self.assertEqual(type(obj.props.python_prop), int)
+ obj.props.python_prop = 5
+ self.assertEqual(obj.props.python_prop, 5)
+
+
+class TestPropertyObject(unittest.TestCase):
+ def test_get_set(self):
obj = PropertyObject()
obj.props.normal = "value"
self.assertEqual(obj.props.normal, "value")
- def testListWithInstance(self):
+ def test_hasattr_on_object(self):
obj = PropertyObject()
- self.failUnless(hasattr(obj.props, "normal"))
+ self.assertTrue(hasattr(obj.props, "normal"))
- def testListWithoutInstance(self):
- self.failUnless(hasattr(PropertyObject.props, "normal"))
+ def test_hasattr_on_class(self):
+ self.assertTrue(hasattr(PropertyObject.props, "normal"))
- def testSetNoInstance(self):
+ def test_set_on_class(self):
def set(obj):
obj.props.normal = "foobar"
self.assertRaises(TypeError, set, PropertyObject)
- def testIterator(self):
+ def test_iteration(self):
for obj in (PropertyObject.props, PropertyObject().props):
+ names = []
for pspec in obj:
gtype = GType(pspec)
self.assertEqual(gtype.parent.name, 'GParam')
- self.failUnless(pspec.name in ['normal',
- 'construct',
- 'construct-only',
- 'uint64',
- 'enum',
- 'boxed'])
- self.assertEqual(len(obj), 6)
-
- def testNormal(self):
+ names.append(pspec.name)
+
+ names.sort()
+ self.assertEqual(names, ['boxed',
+ 'construct',
+ 'construct-only',
+ 'enum',
+ 'flags',
+ 'gtype',
+ 'interface',
+ 'normal',
+ 'strings',
+ 'uint64',
+ 'variant',
+ 'variant-def'])
+
+ def test_normal(self):
obj = new(PropertyObject, normal="123")
self.assertEqual(obj.props.normal, "123")
obj.set_property('normal', '456')
@@ -83,15 +151,15 @@ class TestProperties(unittest.TestCase):
obj.props.normal = '789'
self.assertEqual(obj.props.normal, "789")
- def testConstruct(self):
+ def test_construct(self):
obj = new(PropertyObject, construct="123")
self.assertEqual(obj.props.construct, "123")
obj.set_property('construct', '456')
self.assertEqual(obj.props.construct, "456")
obj.props.construct = '789'
self.assertEqual(obj.props.construct, "789")
-
- def testUTF8(self):
+
+ def test_utf8(self):
obj = new(PropertyObject, construct_only=UNICODE_UTF8)
self.assertEqual(obj.props.construct_only, TEST_UTF8)
obj.set_property('construct', UNICODE_UTF8)
@@ -99,7 +167,7 @@ class TestProperties(unittest.TestCase):
obj.props.normal = UNICODE_UTF8
self.assertEqual(obj.props.normal, TEST_UTF8)
- def testIntToStr(self):
+ def test_int_to_str(self):
obj = new(PropertyObject, construct_only=1)
self.assertEqual(obj.props.construct_only, '1')
obj.set_property('construct', '2')
@@ -107,7 +175,7 @@ class TestProperties(unittest.TestCase):
obj.props.normal = 3
self.assertEqual(obj.props.normal, '3')
- def testConstructOnly(self):
+ def test_construct_only(self):
obj = new(PropertyObject, construct_only="123")
self.assertEqual(obj.props.construct_only, "123")
self.assertRaises(TypeError,
@@ -115,7 +183,7 @@ class TestProperties(unittest.TestCase):
self.assertRaises(TypeError,
obj.set_property, 'construct-only', '456')
- def testUint64(self):
+ def test_uint64(self):
obj = new(PropertyObject)
self.assertEqual(obj.props.uint64, 0)
obj.props.uint64 = _long(1)
@@ -126,19 +194,19 @@ class TestProperties(unittest.TestCase):
self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", _long(-1))
self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", -1)
- def testUInt64DefaultValue(self):
+ def test_uint64_default_value(self):
try:
class TimeControl(GObject.GObject):
__gproperties__ = {
'time': (TYPE_UINT64, 'Time', 'Time',
- _long(0), (1<<64) - 1, _long(0),
+ _long(0), (1 << 64) - 1, _long(0),
PARAM_READABLE)
}
except OverflowError:
(etype, ex) = sys.exc_info()[2:]
self.fail(str(ex))
- def testEnum(self):
+ def test_enum(self):
obj = new(PropertyObject)
self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
self.assertEqual(obj.enum, Gio.SocketType.STREAM)
@@ -166,21 +234,181 @@ class TestProperties(unittest.TestCase):
self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
default=1)
- def textBoxed(self):
+ def test_flags(self):
+ obj = new(PropertyObject)
+ self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE1)
+ self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE1)
+
+ obj.flags = GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3
+ self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
+ self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
+
+ self.assertRaises(TypeError, setattr, obj, 'flags', 'foo')
+ self.assertRaises(TypeError, setattr, obj, 'flags', object())
+ self.assertRaises(TypeError, setattr, obj, 'flags', None)
+
+ self.assertRaises(TypeError, GObject.Property,
+ type=GIMarshallingTests.Flags, default='foo')
+ self.assertRaises(TypeError, GObject.Property,
+ type=GIMarshallingTests.Flags, default=object())
+ self.assertRaises(TypeError, GObject.Property,
+ type=GIMarshallingTests.Flags, default=None)
+
+ def test_gtype(self):
+ obj = new(PropertyObject)
+
+ self.assertEqual(obj.props.gtype, TYPE_NONE)
+ self.assertEqual(obj.gtype, TYPE_NONE)
+
+ obj.gtype = TYPE_UINT64
+ self.assertEqual(obj.props.gtype, TYPE_UINT64)
+ self.assertEqual(obj.gtype, TYPE_UINT64)
+
+ obj.gtype = TYPE_INVALID
+ self.assertEqual(obj.props.gtype, TYPE_INVALID)
+ self.assertEqual(obj.gtype, TYPE_INVALID)
+
+ # GType parameters do not support defaults in GLib
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
+ default=TYPE_INT)
+
+ # incompatible type
+ self.assertRaises(TypeError, setattr, obj, 'gtype', 'foo')
+ self.assertRaises(TypeError, setattr, obj, 'gtype', object())
+
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
+ default='foo')
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
+ default=object())
+
+ # set in constructor
+ obj = new(PropertyObject, gtype=TYPE_UINT)
+ self.assertEqual(obj.props.gtype, TYPE_UINT)
+ self.assertEqual(obj.gtype, TYPE_UINT)
+
+ def test_boxed(self):
obj = new(PropertyObject)
regex = GLib.Regex.new('[a-z]*', 0, 0)
obj.props.boxed = regex
self.assertEqual(obj.props.boxed.get_pattern(), '[a-z]*')
- self.assertEqual(obj.boxed.get_patttern(), '[a-z]*')
+ self.assertEqual(obj.boxed.get_pattern(), '[a-z]*')
self.assertRaises(TypeError, setattr, obj, 'boxed', 'foo')
self.assertRaises(TypeError, setattr, obj, 'boxed', object())
- def testRange(self):
+ def test_strings(self):
+ obj = new(PropertyObject)
+
+ # Should work with actual GStrv objects as well as
+ # Python string lists
+ class GStrv(list):
+ __gtype__ = GObject.TYPE_STRV
+
+ self.assertEqual(obj.props.strings, GStrv([]))
+ self.assertEqual(obj.strings, GStrv([]))
+ self.assertEqual(obj.props.strings, [])
+ self.assertEqual(obj.strings, [])
+
+ obj.strings = ['hello', 'world']
+ self.assertEqual(obj.props.strings, ['hello', 'world'])
+ self.assertEqual(obj.strings, ['hello', 'world'])
+
+ obj.strings = GStrv(['hello', 'world'])
+ self.assertEqual(obj.props.strings, GStrv(['hello', 'world']))
+ self.assertEqual(obj.strings, GStrv(['hello', 'world']))
+
+ obj.strings = []
+ self.assertEqual(obj.strings, [])
+ obj.strings = GStrv([])
+ self.assertEqual(obj.strings, GStrv([]))
+
+ p = GObject.Property(type=TYPE_STRV, default=['hello', '1'])
+ self.assertEqual(p.default, ['hello', '1'])
+ self.assertEqual(p.type, TYPE_STRV)
+ p = GObject.Property(type=TYPE_STRV, default=GStrv(['hello', '1']))
+ self.assertEqual(p.default, ['hello', '1'])
+ self.assertEqual(p.type, TYPE_STRV)
+
+ # set in constructor
+ obj = new(PropertyObject, strings=['hello', 'world'])
+ self.assertEqual(obj.props.strings, ['hello', 'world'])
+ self.assertEqual(obj.strings, ['hello', 'world'])
+
+ # wrong types
+ self.assertRaises(TypeError, setattr, obj, 'strings', 1)
+ self.assertRaises(TypeError, setattr, obj, 'strings', 'foo')
+ self.assertRaises(TypeError, setattr, obj, 'strings', ['foo', 1])
+
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
+ default=1)
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
+ default='foo')
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
+ default=['hello', 1])
+
+ def test_variant(self):
+ obj = new(PropertyObject)
+
+ self.assertEqual(obj.props.variant, None)
+ self.assertEqual(obj.variant, None)
+
+ obj.variant = GLib.Variant('s', 'hello')
+ self.assertEqual(obj.variant.print_(True), "'hello'")
+
+ obj.variant = GLib.Variant('b', True)
+ self.assertEqual(obj.variant.print_(True), "true")
+
+ obj.props.variant = GLib.Variant('y', 2)
+ self.assertEqual(obj.variant.print_(True), "byte 0x02")
+
+ obj.variant = None
+ self.assertEqual(obj.variant, None)
+
+ # set in constructor
+ obj = new(PropertyObject, variant=GLib.Variant('u', 5))
+ self.assertEqual(obj.props.variant.print_(True), 'uint32 5')
+
+ GObject.Property(type=TYPE_VARIANT, default=GLib.Variant('i', 1))
+
+ # incompatible types
+ self.assertRaises(TypeError, setattr, obj, 'variant', 'foo')
+ self.assertRaises(TypeError, setattr, obj, 'variant', 42)
+
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
+ default='foo')
+ self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
+ default=object())
+
+ def test_variant_default(self):
+ obj = new(PropertyObject)
+
+ self.assertEqual(obj.props.variant_def.print_(True), '42')
+ self.assertEqual(obj.variant_def.print_(True), '42')
+
+ obj.props.variant_def = GLib.Variant('y', 2)
+ self.assertEqual(obj.variant_def.print_(True), "byte 0x02")
+
+ # set in constructor
+ obj = new(PropertyObject, variant_def=GLib.Variant('u', 5))
+ self.assertEqual(obj.props.variant_def.print_(True), 'uint32 5')
+
+ def test_interface(self):
+ obj = new(PropertyObject)
+
+ file = Gio.File.new_for_path('/some/path')
+ obj.props.interface = file
+ self.assertEqual(obj.props.interface.get_path(), '/some/path')
+ self.assertEqual(obj.interface.get_path(), '/some/path')
+
+ self.assertRaises(TypeError, setattr, obj, 'interface', 'foo')
+ self.assertRaises(TypeError, setattr, obj, 'interface', object())
+
+ def test_range(self):
# kiwi code
def max(c):
return 2 ** ((8 * struct.calcsize(c)) - 1) - 1
+
def umax(c):
return 2 ** (8 * struct.calcsize(c)) - 1
@@ -194,22 +422,22 @@ class TestProperties(unittest.TestCase):
minint64 = -maxint64 - 1
maxuint64 = umax('Q')
- types = dict(int=(TYPE_INT, minint, maxint),
- uint=(TYPE_UINT, 0, maxuint),
- long=(TYPE_LONG, minlong, maxlong),
- ulong=(TYPE_ULONG, 0, maxulong),
- int64=(TYPE_INT64, minint64, maxint64),
- uint64=(TYPE_UINT64, 0, maxuint64))
+ types_ = dict(int=(TYPE_INT, minint, maxint),
+ uint=(TYPE_UINT, 0, maxuint),
+ long=(TYPE_LONG, minlong, maxlong),
+ ulong=(TYPE_ULONG, 0, maxulong),
+ int64=(TYPE_INT64, minint64, maxint64),
+ uint64=(TYPE_UINT64, 0, maxuint64))
- def build_gproperties(types):
+ def build_gproperties(types_):
d = {}
- for key, (gtype, min, max) in types.items():
+ for key, (gtype, min, max) in types_.items():
d[key] = (gtype, 'blurb', 'desc', min, max, 0,
PARAM_READABLE | PARAM_WRITABLE)
return d
class RangeCheck(GObject.GObject):
- __gproperties__ = build_gproperties(types)
+ __gproperties__ = build_gproperties(types_)
def __init__(self):
self.values = {}
@@ -235,7 +463,7 @@ class TestProperties(unittest.TestCase):
self.assertEqual(RangeCheck.props.uint64.maximum, maxuint64)
obj = RangeCheck()
- for key, (gtype, min, max) in types.items():
+ for key, (gtype, min, max) in types_.items():
self.assertEqual(obj.get_property(key),
getattr(RangeCheck.props, key).default_value)
@@ -245,8 +473,7 @@ class TestProperties(unittest.TestCase):
obj.set_property(key, max)
self.assertEqual(obj.get_property(key), max)
-
- def testMulti(self):
+ def test_multi(self):
obj = PropertyObject()
obj.set_properties(normal="foo",
uint64=7)
@@ -254,18 +481,19 @@ class TestProperties(unittest.TestCase):
self.assertEqual(normal, "foo")
self.assertEqual(uint64, 7)
+
class TestProperty(unittest.TestCase):
- def testSimple(self):
+ def test_simple(self):
class C(GObject.GObject):
str = GObject.Property(type=str)
int = GObject.Property(type=int)
float = GObject.Property(type=float)
long = GObject.Property(type=_long)
- self.failUnless(hasattr(C.props, 'str'))
- self.failUnless(hasattr(C.props, 'int'))
- self.failUnless(hasattr(C.props, 'float'))
- self.failUnless(hasattr(C.props, 'long'))
+ self.assertTrue(hasattr(C.props, 'str'))
+ self.assertTrue(hasattr(C.props, 'int'))
+ self.assertTrue(hasattr(C.props, 'float'))
+ self.assertTrue(hasattr(C.props, 'long'))
o = C()
self.assertEqual(o.str, '')
@@ -284,7 +512,7 @@ class TestProperty(unittest.TestCase):
o.long = _long(100)
self.assertEqual(o.long, _long(100))
- def testCustomGetter(self):
+ def test_custom_getter(self):
class C(GObject.GObject):
def get_prop(self):
return 'value'
@@ -294,7 +522,7 @@ class TestProperty(unittest.TestCase):
self.assertEqual(o.prop, 'value')
self.assertRaises(TypeError, setattr, o, 'prop', 'xxx')
- def testCustomSetter(self):
+ def test_custom_setter(self):
class C(GObject.GObject):
def set_prop(self, value):
self._value = value
@@ -305,19 +533,21 @@ class TestProperty(unittest.TestCase):
GObject.GObject.__init__(self)
o = C()
- self.assertEquals(o._value, None)
+ self.assertEqual(o._value, None)
o.prop = 'bar'
- self.assertEquals(o._value, 'bar')
+ self.assertEqual(o._value, 'bar')
self.assertRaises(TypeError, getattr, o, 'prop')
- def testDecoratorDefault(self):
+ def test_decorator_default(self):
class C(GObject.GObject):
_value = 'value'
+
@GObject.Property
def value(self):
return self._value
+
@value.setter
- def value(self, value):
+ def value_setter(self, value):
self._value = value
o = C()
@@ -326,14 +556,34 @@ class TestProperty(unittest.TestCase):
self.assertEqual(o.value, 'blah')
self.assertEqual(o.props.value, 'blah')
- def testDecoratorWithCall(self):
+ def test_decorator_private_setter(self):
+ class C(GObject.GObject):
+ _value = 'value'
+
+ @GObject.Property
+ def value(self):
+ return self._value
+
+ @value.setter
+ def _set_value(self, value):
+ self._value = value
+
+ o = C()
+ self.assertEqual(o.value, 'value')
+ o.value = 'blah'
+ self.assertEqual(o.value, 'blah')
+ self.assertEqual(o.props.value, 'blah')
+
+ def test_decorator_with_call(self):
class C(GObject.GObject):
_value = 1
+
@GObject.Property(type=int, default=1, minimum=1, maximum=10)
def typedValue(self):
return self._value
+
@typedValue.setter
- def typedValue(self, value):
+ def typedValue_setter(self, value):
self._value = value
o = C()
@@ -342,7 +592,7 @@ class TestProperty(unittest.TestCase):
self.assertEqual(o.typedValue, 5)
self.assertEqual(o.props.typedValue, 5)
- def testErrors(self):
+ def test_errors(self):
self.assertRaises(TypeError, GObject.Property, type='str')
self.assertRaises(TypeError, GObject.Property, nick=False)
self.assertRaises(TypeError, GObject.Property, blurb=False)
@@ -354,52 +604,46 @@ class TestProperty(unittest.TestCase):
self.assertRaises(TypeError, GObject.Property, type=bool)
self.assertRaises(TypeError, GObject.Property, type=object, default=0)
self.assertRaises(TypeError, GObject.Property, type=complex)
- self.assertRaises(TypeError, GObject.Property, flags=-10)
- def testDefaults(self):
- p1 = GObject.Property(type=bool, default=True)
- p2 = GObject.Property(type=bool, default=False)
+ def test_defaults(self):
+ GObject.Property(type=bool, default=True)
+ GObject.Property(type=bool, default=False)
- def testNameWithUnderscore(self):
+ def test_name_with_underscore(self):
class C(GObject.GObject):
prop_name = GObject.Property(type=int)
o = C()
o.prop_name = 10
self.assertEqual(o.prop_name, 10)
- def testRange(self):
- maxint64 = 2 ** 62 - 1
- minint64 = -2 ** 62 - 1
- maxuint64 = 2 ** 63 - 1
-
- types = [
+ def test_range(self):
+ types_ = [
(TYPE_INT, G_MININT, G_MAXINT),
(TYPE_UINT, 0, G_MAXUINT),
(TYPE_LONG, G_MINLONG, G_MAXLONG),
(TYPE_ULONG, 0, G_MAXULONG),
- (TYPE_INT64, minint64, maxint64),
- (TYPE_UINT64, 0, maxuint64),
+ (TYPE_INT64, G_MININT64, G_MAXINT64),
+ (TYPE_UINT64, 0, G_MAXUINT64),
]
- for gtype, min, max in types:
+ for gtype, min, max in types_:
# Normal, everything is alright
prop = GObject.Property(type=gtype, minimum=min, maximum=max)
- subtype = type('', (GObject.GObject,),
- dict(prop=prop))
+ subtype = type('', (GObject.GObject,), dict(prop=prop))
self.assertEqual(subtype.props.prop.minimum, min)
self.assertEqual(subtype.props.prop.maximum, max)
# Lower than minimum
self.assertRaises(TypeError,
- GObject.Property, type=gtype, minimum=min-1,
+ GObject.Property, type=gtype, minimum=min - 1,
maximum=max)
# Higher than maximum
self.assertRaises(TypeError,
GObject.Property, type=gtype, minimum=min,
- maximum=max+1)
+ maximum=max + 1)
- def testMinMax(self):
+ def test_min_max(self):
class C(GObject.GObject):
prop_int = GObject.Property(type=int, minimum=1, maximum=100, default=1)
prop_float = GObject.Property(type=float, minimum=0.1, maximum=10.5, default=1.1)
@@ -407,30 +651,36 @@ class TestProperty(unittest.TestCase):
def __init__(self):
GObject.GObject.__init__(self)
- o = C()
- self.assertEqual(o.prop_int, 1)
+ # we test known-bad values here which cause Gtk-WARNING logs.
+ # Explicitly allow these for this test.
+ old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_CRITICAL)
+ try:
+ o = C()
+ self.assertEqual(o.prop_int, 1)
- o.prop_int = 5
- self.assertEqual(o.prop_int, 5)
+ o.prop_int = 5
+ self.assertEqual(o.prop_int, 5)
- o.prop_int = 0
- self.assertEqual(o.prop_int, 5)
+ o.prop_int = 0
+ self.assertEqual(o.prop_int, 5)
- o.prop_int = 101
- self.assertEqual(o.prop_int, 5)
+ o.prop_int = 101
+ self.assertEqual(o.prop_int, 5)
- self.assertEqual(o.prop_float, 1.1)
+ self.assertEqual(o.prop_float, 1.1)
- o.prop_float = 7.75
- self.assertEqual(o.prop_float, 7.75)
+ o.prop_float = 7.75
+ self.assertEqual(o.prop_float, 7.75)
- o.prop_float = 0.09
- self.assertEqual(o.prop_float, 7.75)
+ o.prop_float = 0.09
+ self.assertEqual(o.prop_float, 7.75)
- o.prop_float = 10.51
- self.assertEqual(o.prop_float, 7.75)
+ o.prop_float = 10.51
+ self.assertEqual(o.prop_float, 7.75)
+ finally:
+ GLib.log_set_always_fatal(old_mask)
- def testMultipleInstances(self):
+ def test_multiple_instances(self):
class C(GObject.GObject):
prop = GObject.Property(type=str, default='default')
@@ -442,7 +692,7 @@ class TestProperty(unittest.TestCase):
self.assertEqual(o1.prop, 'value')
self.assertEqual(o2.prop, 'default')
- def testObjectProperty(self):
+ def test_object_property(self):
class PropertyObject(GObject.GObject):
obj = GObject.Property(type=GObject.GObject)
@@ -455,16 +705,16 @@ class TestProperty(unittest.TestCase):
pobj1 = pobj2.obj
self.assertEqual(hash(pobj1), obj1_hash)
- def testObjectSubclassProperty(self):
+ def test_object_subclass_property(self):
class ObjectSubclass(GObject.GObject):
__gtype_name__ = 'ObjectSubclass'
class PropertyObjectSubclass(GObject.GObject):
obj = GObject.Property(type=ObjectSubclass)
- obj1 = PropertyObjectSubclass(obj=ObjectSubclass())
+ PropertyObjectSubclass(obj=ObjectSubclass())
- def testPropertySubclass(self):
+ def test_property_subclass(self):
# test for #470718
class A(GObject.GObject):
prop1 = GObject.Property(type=int)
@@ -474,11 +724,30 @@ class TestProperty(unittest.TestCase):
b = B()
b.prop2 = 10
- self.assertEquals(b.prop2, 10)
+ self.assertEqual(b.prop2, 10)
b.prop1 = 20
- self.assertEquals(b.prop1, 20)
+ self.assertEqual(b.prop1, 20)
- def testPropertySubclassCustomSetter(self):
+ def test_property_subclass_c(self):
+ class A(Regress.TestSubObj):
+ prop1 = GObject.Property(type=int)
+
+ a = A()
+ a.prop1 = 10
+ self.assertEqual(a.prop1, 10)
+
+ # also has parent properties
+ a.props.int = 20
+ self.assertEqual(a.props.int, 20)
+
+ # Some of which are unusable without introspection
+ a.props.list = ("str1", "str2")
+ self.assertEqual(a.props.list, ["str1", "str2"])
+
+ a.set_property("list", ("str3", "str4"))
+ self.assertEqual(a.props.list, ["str3", "str4"])
+
+ def test_property_subclass_custom_setter(self):
# test for #523352
class A(GObject.GObject):
def get_first(self):
@@ -491,16 +760,16 @@ class TestProperty(unittest.TestCase):
second = GObject.Property(type=str, getter=get_second)
a = A()
- self.assertEquals(a.first, 'first')
+ self.assertEqual(a.first, 'first')
self.assertRaises(TypeError, setattr, a, 'first', 'foo')
b = B()
- self.assertEquals(b.first, 'first')
+ self.assertEqual(b.first, 'first')
self.assertRaises(TypeError, setattr, b, 'first', 'foo')
- self.assertEquals(b.second, 'second')
+ self.assertEqual(b.second, 'second')
self.assertRaises(TypeError, setattr, b, 'second', 'foo')
- def testPropertySubclassCustomSetterError(self):
+ def test_property_subclass_custom_setter_error(self):
try:
class A(GObject.GObject):
def get_first(self):
@@ -515,13 +784,15 @@ class TestProperty(unittest.TestCase):
raise AssertionError
# Bug 587637.
+
def test_float_min(self):
GObject.Property(type=float, minimum=-1)
GObject.Property(type=GObject.TYPE_FLOAT, minimum=-1)
GObject.Property(type=GObject.TYPE_DOUBLE, minimum=-1)
# Bug 644039
- def testReferenceCount(self):
+
+ def test_reference_count(self):
# We can check directly if an object gets finalized, so we will
# observe it indirectly through the refcount of a member object.
@@ -533,24 +804,119 @@ class TestProperty(unittest.TestCase):
# want to observe. Its refcount is increased by one.
t = PropertyObject(normal="test")
t.o = o
- self.assertEquals(sys.getrefcount(o), rc + 1)
+ self.assertEqual(sys.getrefcount(o), rc + 1)
# Now we want to ensure we do not leak any references to our
# object with properties. If no ref is leaked, then when deleting
# the local reference to this object, its reference count shoud
# drop to zero, and our dummy object should loose one reference.
del t
- self.assertEquals(sys.getrefcount(o), rc)
+ self.assertEqual(sys.getrefcount(o), rc)
- def testDocStringAsBlurb(self):
+ def test_doc_strings(self):
class C(GObject.GObject):
+ foo_blurbed = GObject.Property(type=int, blurb='foo_blurbed doc string')
+
@GObject.Property
- def blurbed(self):
- """blurbed doc string"""
+ def foo_getter(self):
+ """foo_getter doc string"""
return 0
- self.assertEqual(C.blurbed.blurb, 'blurbed doc string')
-
+ self.assertEqual(C.foo_blurbed.blurb, 'foo_blurbed doc string')
+ self.assertEqual(C.foo_blurbed.__doc__, 'foo_blurbed doc string')
+
+ self.assertEqual(C.foo_getter.blurb, 'foo_getter doc string')
+ self.assertEqual(C.foo_getter.__doc__, 'foo_getter doc string')
+
+ def test_python_to_glib_type_mapping(self):
+ tester = GObject.Property()
+ self.assertEqual(tester._type_from_python(int), GObject.TYPE_INT)
+ if sys.version_info < (3, 0):
+ self.assertEqual(tester._type_from_python(long), GObject.TYPE_LONG)
+ self.assertEqual(tester._type_from_python(bool), GObject.TYPE_BOOLEAN)
+ self.assertEqual(tester._type_from_python(float), GObject.TYPE_DOUBLE)
+ self.assertEqual(tester._type_from_python(str), GObject.TYPE_STRING)
+ self.assertEqual(tester._type_from_python(object), GObject.TYPE_PYOBJECT)
+
+ self.assertEqual(tester._type_from_python(GObject.GObject), GObject.GObject.__gtype__)
+ self.assertEqual(tester._type_from_python(GObject.GEnum), GObject.GEnum.__gtype__)
+ self.assertEqual(tester._type_from_python(GObject.GFlags), GObject.GFlags.__gtype__)
+ self.assertEqual(tester._type_from_python(GObject.GBoxed), GObject.GBoxed.__gtype__)
+ self.assertEqual(tester._type_from_python(GObject.GInterface), GObject.GInterface.__gtype__)
+
+ for type_ in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
+ TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
+ TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
+ TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
+ TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
+ TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV]:
+ self.assertEqual(tester._type_from_python(type_), type_)
+
+ self.assertRaises(TypeError, tester._type_from_python, types.CodeType)
+
+
+class TestInstallProperties(unittest.TestCase):
+ # These tests only test how signalhelper.install_signals works
+ # with the __gsignals__ dict and therefore does not need to use
+ # GObject as a base class because that would automatically call
+ # install_signals within the meta-class.
+ class Base(object):
+ __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
+
+ class Sub1(Base):
+ pass
+
+ class Sub2(Base):
+ @GObject.Property(type=int)
+ def sub2test(self):
+ return 123
+
+ class ClassWithPropertyAndGetterVFunc(object):
+ @GObject.Property(type=int)
+ def sub2test(self):
+ return 123
+
+ def do_get_property(self, name):
+ return 321
+
+ class ClassWithPropertyRedefined(object):
+ __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
+ test = GObject.Property(type=int)
+
+ def setUp(self):
+ self.assertEqual(len(self.Base.__gproperties__), 1)
+ propertyhelper.install_properties(self.Base)
+ self.assertEqual(len(self.Base.__gproperties__), 1)
+
+ def test_subclass_without_properties_is_not_modified(self):
+ self.assertFalse('__gproperties__' in self.Sub1.__dict__)
+ propertyhelper.install_properties(self.Sub1)
+ self.assertFalse('__gproperties__' in self.Sub1.__dict__)
+
+ def test_subclass_with_decorator_gets_gproperties_dict(self):
+ # Sub2 has Property instances but will not have a __gproperties__
+ # until install_properties is called
+ self.assertFalse('__gproperties__' in self.Sub2.__dict__)
+ self.assertFalse('do_get_property' in self.Sub2.__dict__)
+ self.assertFalse('do_set_property' in self.Sub2.__dict__)
+
+ propertyhelper.install_properties(self.Sub2)
+ self.assertTrue('__gproperties__' in self.Sub2.__dict__)
+ self.assertEqual(len(self.Base.__gproperties__), 1)
+ self.assertEqual(len(self.Sub2.__gproperties__), 1)
+ self.assertTrue('sub2test' in self.Sub2.__gproperties__)
+
+ # get/set vfuncs should have been added
+ self.assertTrue('do_get_property' in self.Sub2.__dict__)
+ self.assertTrue('do_set_property' in self.Sub2.__dict__)
+
+ def test_object_with_property_and_do_get_property_vfunc_raises(self):
+ self.assertRaises(TypeError, propertyhelper.install_properties,
+ self.ClassWithPropertyAndGetterVFunc)
+
+ def test_same_name_property_definitions_raises(self):
+ self.assertRaises(ValueError, propertyhelper.install_properties,
+ self.ClassWithPropertyRedefined)
if __name__ == '__main__':
unittest.main()
diff --git a/tests/test_pygtkcompat.py b/tests/test_pygtkcompat.py
deleted file mode 100644
index b9765c3..0000000
--- a/tests/test_pygtkcompat.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# -*- Mode: Python; py-indent-offset: 4 -*-
-# vim: tabstop=4 shiftwidth=4 expandtab
-
-import unittest
-
-import sys
-import os
-sys.path.insert(0, "../")
-
-from gi.repository import Gdk
-from gi.repository import Gtk
-
-import gi.pygtkcompat
-
-gi.pygtkcompat.enable()
-gi.pygtkcompat.enable_gtk(version='3.0')
-
-import atk
-import pango
-import pangocairo
-import gtk
-import gtk.gdk
-
-
-class TestGTKCompat(unittest.TestCase):
- def testButtons(self):
- self.assertEquals(Gdk._2BUTTON_PRESS, 5)
- self.assertEquals(Gdk.BUTTON_PRESS, 4)
-
- def testEnums(self):
- self.assertEquals(gtk.WINDOW_TOPLEVEL, Gtk.WindowType.TOPLEVEL)
- self.assertEquals(gtk.PACK_START, Gtk.PackType.START)
-
- def testFlags(self):
- self.assertEquals(gtk.EXPAND, Gtk.AttachOptions.EXPAND)
-
- def testKeysyms(self):
- import gtk.keysyms
- self.assertEquals(gtk.keysyms.Escape, Gdk.KEY_Escape)
- self.failUnless(gtk.keysyms._0, Gdk.KEY_0)
-
- def testStyle(self):
- widget = gtk.Button()
- self.failUnless(isinstance(widget.style.base[gtk.STATE_NORMAL],
- gtk.gdk.Color))
-
- def testAlignment(self):
- a = gtk.Alignment()
- self.assertEquals(a.props.xalign, 0.0)
- self.assertEquals(a.props.yalign, 0.0)
- self.assertEquals(a.props.xscale, 0.0)
- self.assertEquals(a.props.yscale, 0.0)
-
- def testBox(self):
- box = gtk.Box()
- child = gtk.Button()
-
- box.pack_start(child)
- expand, fill, padding, pack_type = box.query_child_packing(child)
- self.failUnless(expand)
- self.failUnless(fill)
- self.assertEquals(padding, 0)
- self.assertEquals(pack_type, gtk.PACK_START)
-
- child = gtk.Button()
- box.pack_end(child)
- expand, fill, padding, pack_type = box.query_child_packing(child)
- self.failUnless(expand)
- self.failUnless(fill)
- self.assertEquals(padding, 0)
- self.assertEquals(pack_type, gtk.PACK_END)
-
- def testPixbuf(self):
- gtk.gdk.Pixbuf()
-
- def testPixbufLoader(self):
- loader = gtk.gdk.PixbufLoader('png')
- loader.close()
-
- def testGdkWindow(self):
- w = gtk.Window()
- w.realize()
- self.assertEquals(w.get_window().get_origin(), (0, 0))
diff --git a/tests/test_signal.py b/tests/test_signal.py
index 8486adb..ec13896 100644
--- a/tests/test_signal.py
+++ b/tests/test_signal.py
@@ -4,21 +4,26 @@ import gc
import unittest
import sys
-from gi.repository import GObject
+from gi.repository import GObject, GLib
+from gi._gobject import signalhelper
import testhelper
from compathelper import _long
+
class C(GObject.GObject):
- __gsignals__ = { 'my_signal': (GObject.SignalFlags.RUN_FIRST, None,
- (GObject.TYPE_INT,)) }
+ __gsignals__ = {'my_signal': (GObject.SignalFlags.RUN_FIRST, None,
+ (GObject.TYPE_INT,))}
+
def do_my_signal(self, arg):
self.arg = arg
+
class D(C):
def do_my_signal(self, arg2):
self.arg2 = arg2
C.do_my_signal(self, arg2)
+
class TestSignalCreation(unittest.TestCase):
# Bug 540376.
def test_illegals(self):
@@ -44,50 +49,60 @@ class TestChaining(unittest.TestCase):
assert args[2:] == (1, 2, 3)
- def testChaining(self):
+ def test_chaining(self):
self.inst.emit("my_signal", 42)
assert self.inst.arg == 42
- def testChaining(self):
+ def test_chaining2(self):
inst2 = D()
inst2.emit("my_signal", 44)
assert inst2.arg == 44
assert inst2.arg2 == 44
# This is for bug 153718
+
+
class TestGSignalsError(unittest.TestCase):
- def testInvalidType(self, *args):
+ def test_invalid_type(self, *args):
def foo():
class Foo(GObject.GObject):
__gsignals__ = None
self.assertRaises(TypeError, foo)
gc.collect()
- def testInvalidName(self, *args):
+ def test_invalid_name(self, *args):
def foo():
class Foo(GObject.GObject):
- __gsignals__ = {'not-exists' : 'override'}
- self.assertRaises(TypeError, foo)
+ __gsignals__ = {'not-exists': 'override'}
+ # do not stumble over the warning thrown by GLib
+ old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_CRITICAL |
+ GLib.LogLevelFlags.LEVEL_ERROR)
+ try:
+ self.assertRaises(TypeError, foo)
+ finally:
+ GLib.log_set_always_fatal(old_mask)
gc.collect()
+
class TestGPropertyError(unittest.TestCase):
- def testInvalidType(self, *args):
+ def test_invalid_type(self, *args):
def foo():
class Foo(GObject.GObject):
__gproperties__ = None
self.assertRaises(TypeError, foo)
gc.collect()
- def testInvalidName(self, *args):
+ def test_invalid_name(self, *args):
def foo():
class Foo(GObject.GObject):
- __gproperties__ = { None: None }
+ __gproperties__ = {None: None}
self.assertRaises(TypeError, foo)
gc.collect()
+
class TestList(unittest.TestCase):
- def testListObject(self):
+ def test_list_names(self):
self.assertEqual(GObject.signal_list_names(C), ('my-signal',))
@@ -99,51 +114,76 @@ def my_accumulator(ihint, return_accu, handler_return, user_data):
return False, return_accu
return True, return_accu + handler_return
+
class Foo(GObject.GObject):
- __gsignals__ = {
- 'my-acc-signal': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_INT,
- (), my_accumulator, "accum data"),
- 'my-other-acc-signal': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN,
- (), GObject.signal_accumulator_true_handled)
- }
+ my_acc_signal = GObject.Signal(return_type=GObject.TYPE_INT,
+ flags=GObject.SignalFlags.RUN_LAST,
+ accumulator=my_accumulator,
+ accu_data="accum data")
+
+ my_other_acc_signal = GObject.Signal(return_type=GObject.TYPE_BOOLEAN,
+ flags=GObject.SignalFlags.RUN_LAST,
+ accumulator=GObject.signal_accumulator_true_handled)
+
+ my_acc_first_wins = GObject.Signal(return_type=GObject.TYPE_BOOLEAN,
+ flags=GObject.SignalFlags.RUN_LAST,
+ accumulator=GObject.signal_accumulator_first_wins)
+
class TestAccumulator(unittest.TestCase):
- def testAccumulator(self):
+ def test_accumulator(self):
inst = Foo()
- inst.connect("my-acc-signal", lambda obj: 1)
- inst.connect("my-acc-signal", lambda obj: 2)
+ inst.my_acc_signal.connect(lambda obj: 1)
+ inst.my_acc_signal.connect(lambda obj: 2)
## the value returned in the following handler will not be
## considered, because at this point the accumulator already
## reached its limit.
- inst.connect("my-acc-signal", lambda obj: 3)
- retval = inst.emit("my-acc-signal")
+ inst.my_acc_signal.connect(lambda obj: 3)
+ retval = inst.my_acc_signal.emit()
self.assertEqual(retval, 3)
- def testAccumulatorTrueHandled(self):
+ def test_accumulator_true_handled(self):
inst = Foo()
- inst.connect("my-other-acc-signal", self._true_handler1)
- inst.connect("my-other-acc-signal", self._true_handler2)
+ inst.my_other_acc_signal.connect(self._true_handler1)
+ inst.my_other_acc_signal.connect(self._true_handler2)
## the following handler will not be called because handler2
## returns True, so it should stop the emission.
- inst.connect("my-other-acc-signal", self._true_handler3)
+ inst.my_other_acc_signal.connect(self._true_handler3)
self.__true_val = None
- inst.emit("my-other-acc-signal")
+ inst.my_other_acc_signal.emit()
self.assertEqual(self.__true_val, 2)
+ def test_accumulator_first_wins(self):
+ # First signal hit will always win
+ inst = Foo()
+ inst.my_acc_first_wins.connect(self._true_handler3)
+ inst.my_acc_first_wins.connect(self._true_handler1)
+ inst.my_acc_first_wins.connect(self._true_handler2)
+ self.__true_val = None
+ inst.my_acc_first_wins.emit()
+ self.assertEqual(self.__true_val, 3)
+
def _true_handler1(self, obj):
self.__true_val = 1
return False
+
def _true_handler2(self, obj):
self.__true_val = 2
return True
+
def _true_handler3(self, obj):
self.__true_val = 3
return False
+
class E(GObject.GObject):
- __gsignals__ = { 'signal': (GObject.SignalFlags.RUN_FIRST, None,
- ()) }
+ __gsignals__ = {'signal': (GObject.SignalFlags.RUN_FIRST, None,
+ ())}
+
+ # Property used to test detailed signal
+ prop = GObject.Property(type=int, default=0)
+
def __init__(self):
GObject.GObject.__init__(self)
self.status = 0
@@ -152,9 +192,11 @@ class E(GObject.GObject):
assert self.status == 0
self.status = 1
+
class F(GObject.GObject):
- __gsignals__ = { 'signal': (GObject.SignalFlags.RUN_FIRST, None,
- ()) }
+ __gsignals__ = {'signal': (GObject.SignalFlags.RUN_FIRST, None,
+ ())}
+
def __init__(self):
GObject.GObject.__init__(self)
self.status = 0
@@ -162,8 +204,9 @@ class F(GObject.GObject):
def do_signal(self):
self.status += 1
+
class TestEmissionHook(unittest.TestCase):
- def testAdd(self):
+ def test_add(self):
self.hook = True
e = E()
e.connect('signal', self._callback)
@@ -171,7 +214,7 @@ class TestEmissionHook(unittest.TestCase):
e.emit('signal')
self.assertEqual(e.status, 3)
- def testRemove(self):
+ def test_remove(self):
self.hook = False
e = E()
e.connect('signal', self._callback)
@@ -191,20 +234,22 @@ class TestEmissionHook(unittest.TestCase):
self.assertEqual(e.status, 1)
e.status = 3
- def testCallbackReturnFalse(self):
+ def test_callback_return_false(self):
self.hook = False
obj = F()
+
def _emission_hook(obj):
obj.status += 1
return False
- hook_id = GObject.add_emission_hook(obj, "signal", _emission_hook)
+ GObject.add_emission_hook(obj, "signal", _emission_hook)
obj.emit('signal')
obj.emit('signal')
self.assertEqual(obj.status, 3)
- def testCallbackReturnTrue(self):
+ def test_callback_return_true(self):
self.hook = False
obj = F()
+
def _emission_hook(obj):
obj.status += 1
return True
@@ -214,9 +259,10 @@ class TestEmissionHook(unittest.TestCase):
GObject.remove_emission_hook(obj, "signal", hook_id)
self.assertEqual(obj.status, 4)
- def testCallbackReturnTrueButRemove(self):
+ def test_callback_return_true_but_remove(self):
self.hook = False
obj = F()
+
def _emission_hook(obj):
obj.status += 1
return True
@@ -226,36 +272,163 @@ class TestEmissionHook(unittest.TestCase):
obj.emit('signal')
self.assertEqual(obj.status, 3)
+
+class TestMatching(unittest.TestCase):
+ class Object(GObject.Object):
+ status = 0
+ prop = GObject.Property(type=int, default=0)
+
+ @GObject.Signal()
+ def my_signal(self):
+ pass
+
+ @unittest.expectedFailure # https://bugzilla.gnome.org/show_bug.cgi?id=692918
+ def test_signal_handler_block_matching(self):
+ def dummy(*args):
+ "Hack to work around: "
+
+ def foo(obj):
+ obj.status += 1
+
+ obj = self.Object()
+ handler_id = GObject.signal_connect_closure(obj, 'my-signal', foo, after=False)
+ handler_id
+
+ self.assertEqual(obj.status, 0)
+ obj.emit('my-signal')
+ self.assertEqual(obj.status, 1)
+
+ # Blocking by match criteria disables the foo callback
+ signal_id, detail = GObject.signal_parse_name('my-signal', obj, True)
+ count = GObject.signal_handlers_block_matched(obj,
+ GObject.SignalMatchType.ID | GObject.SignalMatchType.CLOSURE,
+ signal_id=signal_id, detail=detail,
+ closure=foo, func=dummy, data=dummy)
+ self.assertEqual(count, 1)
+ obj.emit('my-signal')
+ self.assertEqual(obj.status, 1)
+
+ # Unblocking by the same match criteria allows callback to work again
+ count = GObject.signal_handlers_unblock_matched(obj,
+ GObject.SignalMatchType.ID | GObject.SignalMatchType.CLOSURE,
+ signal_id=signal_id, detail=detail,
+ closure=foo, func=dummy, data=dummy)
+ self.assertEqual(count, 1)
+ obj.emit('my-signal')
+ self.assertEqual(obj.status, 2)
+
+ # Disconnecting by match criteria completely removes the handler
+ count = GObject.signal_handlers_disconnect_matched(obj,
+ GObject.SignalMatchType.ID | GObject.SignalMatchType.CLOSURE,
+ signal_id=signal_id, detail=detail,
+ closure=foo, func=dummy, data=dummy)
+ self.assertEqual(count, 1)
+ obj.emit('my-signal')
+ self.assertEqual(obj.status, 2)
+
+ def test_signal_handler_find(self):
+ def dummy(*args):
+ "Hack to work around: "
+
+ def foo(obj):
+ obj.status += 1
+
+ obj = self.Object()
+ handler_id = GObject.signal_connect_closure(obj, 'my-signal', foo, after=False)
+
+ signal_id, detail = GObject.signal_parse_name('my-signal', obj, True)
+ found_id = GObject.signal_handler_find(obj,
+ GObject.SignalMatchType.ID,
+ signal_id=signal_id, detail=detail,
+ closure=None, func=dummy, data=dummy)
+ self.assertEqual(handler_id, found_id)
+
+
class TestClosures(unittest.TestCase):
def setUp(self):
self.count = 0
+ self.emission_stopped = False
+ self.emission_error = False
+ self.handler_pending = False
+
+ def _callback_handler_pending(self, e):
+ signal_id, detail = GObject.signal_parse_name('signal', e, True)
+ self.handler_pending = GObject.signal_has_handler_pending(e, signal_id, detail,
+ may_be_blocked=False)
def _callback(self, e):
self.count += 1
- def testDisconnect(self):
+ def _callback_stop_emission(self, obj, prop, stop_it):
+ if stop_it:
+ obj.stop_emission_by_name('notify::prop')
+ self.emission_stopped = True
+ else:
+ self.count += 1
+
+ def _callback_invalid_stop_emission_name(self, obj, prop):
+ # We expect a GLib warning but there currently is no way to test that
+ # This can at least make sure we don't crash
+ old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_CRITICAL |
+ GLib.LogLevelFlags.LEVEL_ERROR)
+ try:
+ obj.stop_emission_by_name('notasignal::baddetail')
+ finally:
+ GLib.log_set_always_fatal(old_mask)
+ self.emission_error = True
+
+ def test_disconnect_by_func(self):
e = E()
e.connect('signal', self._callback)
e.disconnect_by_func(self._callback)
e.emit('signal')
self.assertEqual(self.count, 0)
- def testHandlerBlock(self):
+ def test_disconnect(self):
+ e = E()
+ handler_id = e.connect('signal', self._callback)
+ self.assertTrue(e.handler_is_connected(handler_id))
+ e.disconnect(handler_id)
+ e.emit('signal')
+ self.assertEqual(self.count, 0)
+ self.assertFalse(e.handler_is_connected(handler_id))
+
+ def test_stop_emission_by_name(self):
+ e = E()
+
+ # Sandwich a callback that stops emission in between a callback that increments
+ e.connect('notify::prop', self._callback_stop_emission, False)
+ e.connect('notify::prop', self._callback_stop_emission, True)
+ e.connect('notify::prop', self._callback_stop_emission, False)
+
+ e.set_property('prop', 1234)
+ self.assertEqual(e.get_property('prop'), 1234)
+ self.assertEqual(self.count, 1)
+ self.assertTrue(self.emission_stopped)
+
+ def test_stop_emission_by_name_error(self):
+ e = E()
+
+ e.connect('notify::prop', self._callback_invalid_stop_emission_name)
+ e.set_property('prop', 1234)
+ self.assertTrue(self.emission_error)
+
+ def test_handler_block(self):
e = E()
e.connect('signal', self._callback)
e.handler_block_by_func(self._callback)
e.emit('signal')
self.assertEqual(self.count, 0)
- def testHandlerUnBlock(self):
+ def test_handler_unblock(self):
e = E()
- signal_id = e.connect('signal', self._callback)
- e.handler_block(signal_id)
+ handler_id = e.connect('signal', self._callback)
+ e.handler_block(handler_id)
e.handler_unblock_by_func(self._callback)
e.emit('signal')
self.assertEqual(self.count, 1)
- def testHandlerBlockMethod(self):
+ def test_handler_block_method(self):
# Filed as #375589
class A:
def __init__(self):
@@ -272,13 +445,15 @@ class TestClosures(unittest.TestCase):
self.assertEqual(inst.a, 1)
gc.collect()
- def testGString(self):
+ def test_gstring(self):
class C(GObject.GObject):
- __gsignals__ = { 'my_signal': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_GSTRING,
- (GObject.TYPE_GSTRING,)) }
+ __gsignals__ = {'my_signal': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_GSTRING,
+ (GObject.TYPE_GSTRING,))}
+
def __init__(self, test):
GObject.GObject.__init__(self)
self.test = test
+
def do_my_signal(self, data):
self.data = data
self.test.assertEqual(len(data), 3)
@@ -287,12 +462,39 @@ class TestClosures(unittest.TestCase):
data = c.emit("my_signal", "\01\00\02")
self.assertEqual(data, "\02\00\01")
+ def test_handler_pending(self):
+ obj = F()
+ obj.connect('signal', self._callback_handler_pending)
+ obj.connect('signal', self._callback)
+
+ self.assertEqual(self.count, 0)
+ self.assertEqual(self.handler_pending, False)
+
+ obj.emit('signal')
+ self.assertEqual(self.count, 1)
+ self.assertEqual(self.handler_pending, True)
+
+ def test_signal_handlers_destroy(self):
+ obj = F()
+ obj.connect('signal', self._callback)
+ obj.connect('signal', self._callback)
+ obj.connect('signal', self._callback)
+
+ obj.emit('signal')
+ self.assertEqual(self.count, 3)
+
+ # count should remain at 3 after all handlers are destroyed
+ GObject.signal_handlers_destroy(obj)
+ obj.emit('signal')
+ self.assertEqual(self.count, 3)
+
+
class SigPropClass(GObject.GObject):
- __gsignals__ = { 'my_signal': (GObject.SignalFlags.RUN_FIRST, None,
- (GObject.TYPE_INT,)) }
+ __gsignals__ = {'my_signal': (GObject.SignalFlags.RUN_FIRST, None,
+ (GObject.TYPE_INT,))}
__gproperties__ = {
- 'foo': (str, None, None, '', GObject.PARAM_WRITABLE|GObject.PARAM_CONSTRUCT),
+ 'foo': (str, None, None, '', GObject.PARAM_WRITABLE | GObject.PARAM_CONSTRUCT),
}
signal_emission_failed = False
@@ -312,63 +514,151 @@ class SigPropClass(GObject.GObject):
class TestSigProp(unittest.TestCase):
- def testEmitInPropertySetter(self):
+ def test_emit_in_property_setter(self):
obj = SigPropClass()
- self.failIf(obj.signal_emission_failed)
+ self.assertFalse(obj.signal_emission_failed)
-f = GObject.SignalFlags.RUN_FIRST
-l = GObject.SignalFlags.RUN_LAST
-float = GObject.TYPE_FLOAT
-double = GObject.TYPE_DOUBLE
-uint = GObject.TYPE_UINT
-ulong = GObject.TYPE_ULONG
class CM(GObject.GObject):
__gsignals__ = dict(
- test1=(f, None, ()),
- test2=(l, None, (str,)),
- test3=(l, int, (double,)),
- test4=(f, None, (bool, _long, float, double, int, uint, ulong)),
- test_float=(l, float, (float,)),
- test_double=(l, double, (double, )),
- test_string=(l, str, (str, )),
- test_object=(l, object, (object, )),
+ test1=(GObject.SignalFlags.RUN_FIRST, None, ()),
+ test2=(GObject.SignalFlags.RUN_LAST, None, (str,)),
+ test3=(GObject.SignalFlags.RUN_LAST, int, (GObject.TYPE_DOUBLE,)),
+ test4=(GObject.SignalFlags.RUN_FIRST, None,
+ (bool, _long, GObject.TYPE_FLOAT, GObject.TYPE_DOUBLE, int,
+ GObject.TYPE_UINT, GObject.TYPE_ULONG)),
+ test_float=(GObject.SignalFlags.RUN_LAST, GObject.TYPE_FLOAT, (GObject.TYPE_FLOAT,)),
+ test_double=(GObject.SignalFlags.RUN_LAST, GObject.TYPE_DOUBLE, (GObject.TYPE_DOUBLE,)),
+ test_int64=(GObject.SignalFlags.RUN_LAST, GObject.TYPE_INT64, (GObject.TYPE_INT64,)),
+ test_string=(GObject.SignalFlags.RUN_LAST, str, (str,)),
+ test_object=(GObject.SignalFlags.RUN_LAST, object, (object,)),
+ test_paramspec=(GObject.SignalFlags.RUN_LAST, GObject.ParamSpec, ()),
+ test_paramspec_in=(GObject.SignalFlags.RUN_LAST, GObject.ParamSpec, (GObject.ParamSpec, )),
+ test_gvalue=(GObject.SignalFlags.RUN_LAST, GObject.Value, (GObject.Value,)),
+ test_gvalue_ret=(GObject.SignalFlags.RUN_LAST, GObject.Value, (GObject.TYPE_GTYPE,)),
)
+ testprop = GObject.Property(type=int)
+
+
class _TestCMarshaller:
def setUp(self):
self.obj = CM()
testhelper.connectcallbacks(self.obj)
- def testTest1(self):
+ def test_test1(self):
self.obj.emit("test1")
- def testTest2(self):
+ def test_test2(self):
self.obj.emit("test2", "string")
- def testTest3(self):
+ def test_test3(self):
rv = self.obj.emit("test3", 42.0)
self.assertEqual(rv, 20)
- def testTest4(self):
+ def test_test4(self):
self.obj.emit("test4", True, _long(10), 3.14, 1.78, 20, _long(30), _long(31))
- def testTestReturnFloat(self):
+ def test_float(self):
rv = self.obj.emit("test-float", 1.234)
- self.failUnless(rv >= 1.233999 and rv <= 1.2400001, rv)
+ self.assertTrue(rv >= 1.233999 and rv <= 1.2400001, rv)
- def testTestReturnDouble(self):
+ def test_double(self):
rv = self.obj.emit("test-double", 1.234)
self.assertEqual(rv, 1.234)
- def testTestReturnString(self):
+ def test_int64(self):
+ rv = self.obj.emit("test-int64", 102030405)
+ self.assertEqual(rv, 102030405)
+
+ rv = self.obj.emit("test-int64", GObject.G_MAXINT64)
+ self.assertEqual(rv, GObject.G_MAXINT64 - 1)
+
+ rv = self.obj.emit("test-int64", GObject.G_MININT64)
+ self.assertEqual(rv, GObject.G_MININT64)
+
+ def test_string(self):
rv = self.obj.emit("test-string", "str")
self.assertEqual(rv, "str")
- def testTestReturnObject(self):
+ def test_object(self):
rv = self.obj.emit("test-object", self)
self.assertEqual(rv, self)
+ def test_paramspec(self):
+ rv = self.obj.emit("test-paramspec")
+ self.assertEqual(rv.name, "test-param")
+ self.assertEqual(rv.nick, "test")
+
+ @unittest.skipUnless(hasattr(GObject, 'param_spec_boolean'),
+ 'too old gobject-introspection')
+ def test_paramspec_in(self):
+ rv = GObject.param_spec_boolean('mybool', 'test-bool', 'do something',
+ True, GObject.ParamFlags.READABLE)
+
+ rv2 = self.obj.emit("test-paramspec-in", rv)
+ self.assertEqual(type(rv), type(rv2))
+ self.assertEqual(rv2.name, "mybool")
+ self.assertEqual(rv2.nick, "test-bool")
+
+ def test_C_paramspec(self):
+ self.notify_called = False
+
+ def cb_notify(obj, prop):
+ self.notify_called = True
+ self.assertEqual(obj, self.obj)
+ self.assertEqual(prop.name, "testprop")
+
+ self.obj.connect("notify", cb_notify)
+ self.obj.set_property("testprop", 42)
+ self.assertTrue(self.notify_called)
+
+ def test_gvalue(self):
+ # implicit int
+ rv = self.obj.emit("test-gvalue", 42)
+ self.assertEqual(rv, 42)
+
+ # explicit float
+ v = GObject.Value(GObject.TYPE_FLOAT, 1.234)
+ rv = self.obj.emit("test-gvalue", v)
+ self.assertAlmostEqual(rv, 1.234, 4)
+
+ # implicit float
+ rv = self.obj.emit("test-gvalue", 1.234)
+ self.assertAlmostEqual(rv, 1.234, 4)
+
+ # explicit int64
+ v = GObject.Value(GObject.TYPE_INT64, GObject.G_MAXINT64)
+ rv = self.obj.emit("test-gvalue", v)
+ self.assertEqual(rv, GObject.G_MAXINT64)
+
+ # implicit int64
+ # does not work, see https://bugzilla.gnome.org/show_bug.cgi?id=683775
+ #rv = self.obj.emit("test-gvalue", GObject.G_MAXINT64)
+ #self.assertEqual(rv, GObject.G_MAXINT64)
+
+ # explicit uint64
+ v = GObject.Value(GObject.TYPE_UINT64, GObject.G_MAXUINT64)
+ rv = self.obj.emit("test-gvalue", v)
+ self.assertEqual(rv, GObject.G_MAXUINT64)
+
+ # implicit uint64
+ # does not work, see https://bugzilla.gnome.org/show_bug.cgi?id=683775
+ #rv = self.obj.emit("test-gvalue", GObject.G_MAXUINT64)
+ #self.assertEqual(rv, GObject.G_MAXUINT64)
+
+ def test_gvalue_ret(self):
+ self.assertEqual(self.obj.emit("test-gvalue-ret", GObject.TYPE_INT),
+ GObject.G_MAXINT)
+ self.assertEqual(self.obj.emit("test-gvalue-ret", GObject.TYPE_UINT),
+ GObject.G_MAXUINT)
+ self.assertEqual(self.obj.emit("test-gvalue-ret", GObject.TYPE_INT64),
+ GObject.G_MAXINT64)
+ self.assertEqual(self.obj.emit("test-gvalue-ret", GObject.TYPE_UINT64),
+ GObject.G_MAXUINT64)
+ self.assertEqual(self.obj.emit("test-gvalue-ret", GObject.TYPE_STRING),
+ "hello")
+
if 'generic-c-marshaller' in GObject.features:
class TestCMarshaller(_TestCMarshaller, unittest.TestCase):
pass
@@ -378,12 +668,14 @@ else:
print()
# Test for 374653
+
+
class TestPyGValue(unittest.TestCase):
- def testNoneNULLBoxedConversion(self):
+ def test_none_null_boxed_conversion(self):
class C(GObject.GObject):
__gsignals__ = dict(my_boxed_signal=(
GObject.SignalFlags.RUN_LAST,
- GObject.type_from_name('GStrv'), ()))
+ GObject.TYPE_STRV, ()))
obj = C()
obj.connect('my-boxed-signal', lambda obj: None)
@@ -391,5 +683,303 @@ class TestPyGValue(unittest.TestCase):
obj.emit('my-boxed-signal')
assert not sys.last_type
+
+class TestSignalDecorator(unittest.TestCase):
+ class Decorated(GObject.GObject):
+ value = 0
+
+ @GObject.Signal
+ def pushed(self):
+ """this will push"""
+ self.value += 1
+
+ @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST)
+ def pulled(self):
+ self.value -= 1
+
+ stomped = GObject.Signal('stomped', arg_types=(int,), doc='this will stomp')
+ unnamed = GObject.Signal()
+
+ class DecoratedOverride(GObject.GObject):
+ overridden_closure_called = False
+ notify_called = False
+ value = GObject.Property(type=int, default=0)
+
+ @GObject.SignalOverride
+ def notify(self, *args, **kargs):
+ self.overridden_closure_called = True
+ #GObject.GObject.notify(self, *args, **kargs)
+
+ def on_notify(self, obj, prop):
+ self.notify_called = True
+
+ def setUp(self):
+ self.unnamedCalled = False
+
+ def onUnnamed(self, obj):
+ self.unnamedCalled = True
+
+ def test_get_signal_args(self):
+ self.assertEqual(self.Decorated.pushed.get_signal_args(),
+ (GObject.SignalFlags.RUN_FIRST, None, tuple(), None, None))
+ self.assertEqual(self.Decorated.pulled.get_signal_args(),
+ (GObject.SignalFlags.RUN_LAST, None, tuple(), None, None))
+ self.assertEqual(self.Decorated.stomped.get_signal_args(),
+ (GObject.SignalFlags.RUN_FIRST, None, (int,), None, None))
+
+ def test_closures_called(self):
+ decorated = self.Decorated()
+ self.assertEqual(decorated.value, 0)
+ decorated.pushed.emit()
+ self.assertEqual(decorated.value, 1)
+ decorated.pulled.emit()
+ self.assertEqual(decorated.value, 0)
+
+ def test_signal_copy(self):
+ blah = self.Decorated.stomped.copy('blah')
+ self.assertEqual(str(blah), blah)
+ self.assertEqual(blah.func, self.Decorated.stomped.func)
+ self.assertEqual(blah.flags, self.Decorated.stomped.flags)
+ self.assertEqual(blah.return_type, self.Decorated.stomped.return_type)
+ self.assertEqual(blah.arg_types, self.Decorated.stomped.arg_types)
+ self.assertEqual(blah.__doc__, self.Decorated.stomped.__doc__)
+
+ def test_doc_string(self):
+ # Test the two techniques for setting doc strings on the signals
+ # class variables, through the "doc" keyword or as the getter doc string.
+ self.assertEqual(self.Decorated.stomped.__doc__, 'this will stomp')
+ self.assertEqual(self.Decorated.pushed.__doc__, 'this will push')
+
+ def test_unnamed_signal_gets_named(self):
+ self.assertEqual(str(self.Decorated.unnamed), 'unnamed')
+
+ def test_unnamed_signal_gets_called(self):
+ obj = self.Decorated()
+ obj.connect('unnamed', self.onUnnamed)
+ self.assertEqual(self.unnamedCalled, False)
+ obj.emit('unnamed')
+ self.assertEqual(self.unnamedCalled, True)
+
+ def NOtest_overridden_signal(self):
+ # Test that the pushed signal is called in with super and the override
+ # which should both increment the "value" to 3
+ obj = self.DecoratedOverride()
+ obj.connect("notify", obj.on_notify)
+ self.assertEqual(obj.value, 0)
+ #obj.notify.emit()
+ obj.value = 1
+ self.assertEqual(obj.value, 1)
+ self.assertTrue(obj.overridden_closure_called)
+ self.assertTrue(obj.notify_called)
+
+
+class TestSignalConnectors(unittest.TestCase):
+ class CustomButton(GObject.GObject):
+ on_notify_called = False
+ value = GObject.Property(type=int)
+
+ @GObject.Signal(arg_types=(int,))
+ def clicked(self, value):
+ self.value = value
+
+ def setUp(self):
+ self.obj = None
+ self.value = None
+
+ def on_clicked(self, obj, value):
+ self.obj = obj
+ self.value = value
+
+ def test_signal_notify(self):
+ def on_notify(obj, param):
+ obj.on_notify_called = True
+
+ obj = self.CustomButton()
+ obj.connect('notify', on_notify)
+ self.assertFalse(obj.on_notify_called)
+ obj.notify('value')
+ self.assertTrue(obj.on_notify_called)
+
+ def test_signal_emit(self):
+ # standard callback connection with different forms of emit.
+ obj = self.CustomButton()
+ obj.connect('clicked', self.on_clicked)
+
+ # vanilla
+ obj.emit('clicked', 1)
+ self.assertEqual(obj.value, 1)
+ self.assertEqual(obj, self.obj)
+ self.assertEqual(self.value, 1)
+
+ # using class signal as param
+ self.obj = None
+ self.value = None
+ obj.emit(self.CustomButton.clicked, 1)
+ self.assertEqual(obj, self.obj)
+ self.assertEqual(self.value, 1)
+
+ # using bound signal as param
+ self.obj = None
+ self.value = None
+ obj.emit(obj.clicked, 1)
+ self.assertEqual(obj, self.obj)
+ self.assertEqual(self.value, 1)
+
+ # using bound signal with emit
+ self.obj = None
+ self.value = None
+ obj.clicked.emit(1)
+ self.assertEqual(obj, self.obj)
+ self.assertEqual(self.value, 1)
+
+ def test_signal_class_connect(self):
+ obj = self.CustomButton()
+ obj.connect(self.CustomButton.clicked, self.on_clicked)
+ obj.emit('clicked', 2)
+ self.assertEqual(obj, self.obj)
+ self.assertEqual(self.value, 2)
+
+ def test_signal_bound_connect(self):
+ obj = self.CustomButton()
+ obj.clicked.connect(self.on_clicked)
+ obj.emit('clicked', 3)
+ self.assertEqual(obj, self.obj)
+ self.assertEqual(self.value, 3)
+
+
+class TestInstallSignals(unittest.TestCase):
+ # These tests only test how signalhelper.install_signals works
+ # with the __gsignals__ dict and therefore does not need to use
+ # GObject as a base class because that would automatically call
+ # install_signals within the meta-class.
+ class Base(object):
+ __gsignals__ = {'test': (0, None, tuple())}
+
+ class Sub1(Base):
+ pass
+
+ class Sub2(Base):
+ @GObject.Signal
+ def sub2test(self):
+ pass
+
+ def setUp(self):
+ self.assertEqual(len(self.Base.__gsignals__), 1)
+ signalhelper.install_signals(self.Base)
+ self.assertEqual(len(self.Base.__gsignals__), 1)
+
+ def test_subclass_gets_empty_gsignals_dict(self):
+ # Installing signals will add the __gsignals__ dict to a class
+ # if it doesn't already exists.
+ self.assertFalse('__gsignals__' in self.Sub1.__dict__)
+ signalhelper.install_signals(self.Sub1)
+ self.assertTrue('__gsignals__' in self.Sub1.__dict__)
+ # Sub1 should only contain an empty signals dict, this tests:
+ # https://bugzilla.gnome.org/show_bug.cgi?id=686496
+ self.assertEqual(self.Sub1.__dict__['__gsignals__'], {})
+
+ def test_subclass_with_decorator_gets_gsignals_dict(self):
+ self.assertFalse('__gsignals__' in self.Sub2.__dict__)
+ signalhelper.install_signals(self.Sub2)
+ self.assertTrue('__gsignals__' in self.Sub2.__dict__)
+ self.assertEqual(len(self.Base.__gsignals__), 1)
+ self.assertEqual(len(self.Sub2.__gsignals__), 1)
+ self.assertTrue('sub2test' in self.Sub2.__gsignals__)
+
+ # Make sure the vfunc was added
+ self.assertTrue(hasattr(self.Sub2, 'do_sub2test'))
+
+
+# For this test to work with both python2 and 3 we need to dynamically
+# exec the given code due to the new syntax causing an error in python 2.
+annotated_class_code = """
+class AnnotatedSignalClass(GObject.GObject):
+ @GObject.Signal
+ def sig1(self, a:int, b:float):
+ pass
+
+ @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST)
+ def sig2_with_return(self, a:int, b:float) -> str:
+ return "test"
+"""
+
+
+@unittest.skipUnless(sys.version_info >= (3, 0),
+ 'Argument annotations require Python 3')
+class TestPython3Signals(unittest.TestCase):
+ AnnotatedClass = None
+
+ def setUp(self):
+ exec(annotated_class_code, globals(), globals())
+ self.assertTrue('AnnotatedSignalClass' in globals())
+ self.AnnotatedClass = globals()['AnnotatedSignalClass']
+
+ def test_annotations(self):
+ self.assertEqual(signalhelper.get_signal_annotations(self.AnnotatedClass.sig1.func),
+ (None, (int, float)))
+ self.assertEqual(signalhelper.get_signal_annotations(self.AnnotatedClass.sig2_with_return.func),
+ (str, (int, float)))
+
+ self.assertEqual(self.AnnotatedClass.sig2_with_return.get_signal_args(),
+ (GObject.SignalFlags.RUN_LAST, str, (int, float), None, None))
+ self.assertEqual(self.AnnotatedClass.sig2_with_return.arg_types,
+ (int, float))
+ self.assertEqual(self.AnnotatedClass.sig2_with_return.return_type,
+ str)
+
+ def test_emit_return(self):
+ obj = self.AnnotatedClass()
+ self.assertEqual(obj.sig2_with_return.emit(1, 2.0),
+ 'test')
+
+
+class TestSignalModuleLevelFunctions(unittest.TestCase):
+ def test_signal_list_ids_with_invalid_type(self):
+ with self.assertRaisesRegex(TypeError, 'type must be instantiable or an interface.*'):
+ GObject.signal_list_ids(GObject.TYPE_INVALID)
+
+ def test_signal_list_ids(self):
+ with self.assertRaisesRegex(TypeError, 'type must be instantiable or an interface.*'):
+ GObject.signal_list_ids(GObject.TYPE_INT)
+
+ ids = GObject.signal_list_ids(C)
+ self.assertEqual(len(ids), 1)
+ # Note canonicalized names
+ self.assertEqual(GObject.signal_name(ids[0]), 'my-signal')
+ # There is no signal 0 in gobject
+ self.assertEqual(GObject.signal_name(0), None)
+
+ def test_signal_lookup_with_invalid_type(self):
+ with self.assertRaisesRegex(TypeError, 'type must be instantiable or an interface.*'):
+ GObject.signal_lookup('NOT_A_SIGNAL_NAME', GObject.TYPE_INVALID)
+
+ def test_signal_lookup(self):
+ ids = GObject.signal_list_ids(C)
+ self.assertEqual(ids[0], GObject.signal_lookup('my_signal', C))
+ self.assertEqual(ids[0], GObject.signal_lookup('my-signal', C))
+
+ with self.assertRaisesRegex(TypeError, 'type must be instantiable or an interface.*'):
+ GObject.signal_lookup('NOT_A_SIGNAL_NAME', GObject.TYPE_INT)
+
+ # Invalid signal names return 0 instead of raising
+ self.assertEqual(GObject.signal_lookup('NOT_A_SIGNAL_NAME', C),
+ 0)
+
+ def test_signal_query(self):
+ my_signal_id, = GObject.signal_list_ids(C)
+
+ # Form is: (id, name, gtype, arg_count, return_type, (arg_type1, ...))
+ my_signal_expected_query_result = [my_signal_id, 'my-signal', C.__gtype__,
+ 1, GObject.TYPE_NONE, (GObject.TYPE_INT,)]
+ # signal_query(name, type)
+ self.assertEqual(list(GObject.signal_query('my-signal', C)), my_signal_expected_query_result)
+ # signal_query(signal_id)
+ self.assertEqual(list(GObject.signal_query(my_signal_id)), my_signal_expected_query_result)
+ # invalid query returns None instead of raising
+ self.assertEqual(GObject.signal_query(0), None)
+ self.assertEqual(GObject.signal_query('NOT_A_SIGNAL', C),
+ None)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/test_source.py b/tests/test_source.py
index ad052cc..d0e28e4 100644
--- a/tests/test_source.py
+++ b/tests/test_source.py
@@ -1,8 +1,11 @@
# -*- Mode: Python -*-
import unittest
+import warnings
+
+from gi.repository import GLib, GObject
+from gi import PyGIDeprecationWarning
-from gi.repository import GLib
class Idle(GLib.Idle):
def __init__(self, loop):
@@ -42,25 +45,35 @@ class TestSource(unittest.TestCase):
timeout.set_callback(self.timeout_callback, loop)
timeout.attach()
- def testSources(self):
+ def test_sources(self):
loop = GLib.MainLoop()
self.setup_timeout(loop)
idle = Idle(loop)
+ self.assertEqual(idle.get_context(), None)
idle.attach()
+ self.assertEqual(idle.get_context(), GLib.main_context_default())
self.pos = 0
m = MySource()
+ self.assertEqual(m.get_context(), None)
m.set_callback(self.my_callback, loop)
m.attach()
+ self.assertEqual(m.get_context(), GLib.main_context_default())
loop.run()
- assert self.pos >= 0 and idle.count >= 0
+ m.destroy()
+ idle.destroy()
+
+ self.assertGreater(self.pos, 0)
+ self.assertGreaterEqual(idle.count, 0)
+ self.assertTrue(m.is_destroyed())
+ self.assertTrue(idle.is_destroyed())
- def testSourcePrepare(self):
+ def test_source_prepare(self):
# this test may not terminate if prepare() is wrapped incorrectly
dispatched = [False]
loop = GLib.MainLoop()
@@ -88,11 +101,272 @@ class TestSource(unittest.TestCase):
assert dispatched[0]
+ def test_is_destroyed_simple(self):
+ s = GLib.Source()
+
+ self.assertFalse(s.is_destroyed())
+ s.destroy()
+ self.assertTrue(s.is_destroyed())
+
+ c = GLib.MainContext()
+ s = GLib.Source()
+ s.attach(c)
+ self.assertFalse(s.is_destroyed())
+ s.destroy()
+ self.assertTrue(s.is_destroyed())
+
+ def test_is_destroyed_context(self):
+ def f():
+ c = GLib.MainContext()
+ s = GLib.Source()
+ s.attach(c)
+ return s
+
+ s = f()
+ self.assertTrue(s.is_destroyed())
+
+ def test_remove(self):
+ s = GLib.idle_add(dir)
+ self.assertEqual(GLib.source_remove(s), True)
+ # s is now removed, should fail now
+ self.assertEqual(GLib.source_remove(s), False)
+
+ # accepts large source IDs (they are unsigned)
+ self.assertEqual(GLib.source_remove(GObject.G_MAXINT32), False)
+ self.assertEqual(GLib.source_remove(GObject.G_MAXINT32 + 1), False)
+ self.assertEqual(GLib.source_remove(GObject.G_MAXUINT32), False)
+
+ def test_recurse_property(self):
+ s = GLib.Idle()
+ self.assertTrue(s.can_recurse in [False, True])
+ s.can_recurse = False
+ self.assertFalse(s.can_recurse)
+
+ def test_priority(self):
+ s = GLib.Idle()
+ self.assertEqual(s.priority, GLib.PRIORITY_DEFAULT_IDLE)
+ s.priority = GLib.PRIORITY_HIGH
+ self.assertEqual(s.priority, GLib.PRIORITY_HIGH)
+
+ s = GLib.Idle(GLib.PRIORITY_LOW)
+ self.assertEqual(s.priority, GLib.PRIORITY_LOW)
+
+ s = GLib.Timeout(1, GLib.PRIORITY_LOW)
+ self.assertEqual(s.priority, GLib.PRIORITY_LOW)
+
+ s = GLib.Source()
+ self.assertEqual(s.priority, GLib.PRIORITY_DEFAULT)
+
+ def test_get_current_time(self):
+ # Note, deprecated API
+ s = GLib.Idle()
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+ time = s.get_current_time()
+ self.assertTrue(issubclass(w[0].category, PyGIDeprecationWarning))
+
+ self.assertTrue(isinstance(time, float))
+ # plausibility check, and check magnitude of result
+ self.assertGreater(time, 1300000000.0)
+ self.assertLess(time, 2000000000.0)
+
+ def test_add_remove_poll(self):
+ # FIXME: very shallow test, only verifies the API signature
+ pollfd = GLib.PollFD(99, GLib.IOCondition.IN | GLib.IOCondition.HUP)
+ self.assertEqual(pollfd.fd, 99)
+ source = GLib.Source()
+ source.add_poll(pollfd)
+ source.remove_poll(pollfd)
+
+ def test_out_of_scope_before_dispatch(self):
+ # https://bugzilla.gnome.org/show_bug.cgi?id=504337
+ GLib.Timeout(20)
+ GLib.Idle()
+
+ def test_finalize(self):
+ self.dispatched = False
+ self.finalized = False
+
+ class S(GLib.Source):
+ def prepare(s):
+ return (True, 1)
+
+ def dispatch(s, callback, args):
+ self.dispatched = True
+ return False
-class TestTimeout(unittest.TestCase):
- def test504337(self):
- timeout_source = GLib.Timeout(20)
- idle_source = GLib.Idle()
+ def finalize(s):
+ self.finalized = True
+
+ source = S()
+ id = source.attach()
+ print('source id:', id)
+ self.assertFalse(self.finalized)
+ self.assertFalse(source.is_destroyed())
+
+ while source.get_context().iteration(False):
+ pass
+
+ source.destroy()
+ self.assertTrue(self.dispatched)
+ self.assertFalse(self.finalized)
+ self.assertTrue(source.is_destroyed())
+ del source
+ self.assertTrue(self.finalized)
+
+ def test_extra_init_args(self):
+ class SourceWithInitArgs(GLib.Source):
+ def __init__(self, arg, kwarg=None):
+ super(SourceWithInitArgs, self).__init__()
+ self.arg = arg
+ self.kwarg = kwarg
+
+ source = SourceWithInitArgs(1, kwarg=2)
+ self.assertEqual(source.arg, 1)
+ self.assertEqual(source.kwarg, 2)
+
+
+class TestUserData(unittest.TestCase):
+ def test_idle_no_data(self):
+ ml = GLib.MainLoop()
+
+ def cb():
+ ml.quit()
+ id = GLib.idle_add(cb)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_DEFAULT_IDLE)
+ ml.run()
+
+ def test_timeout_no_data(self):
+ ml = GLib.MainLoop()
+
+ def cb():
+ ml.quit()
+ id = GLib.timeout_add(50, cb)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_DEFAULT)
+ ml.run()
+
+ def test_idle_data(self):
+ ml = GLib.MainLoop()
+
+ def cb(data):
+ data['called'] = True
+ ml.quit()
+ data = {}
+ id = GLib.idle_add(cb, data)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_DEFAULT_IDLE)
+ ml.run()
+ self.assertTrue(data['called'])
+
+ def test_idle_multidata(self):
+ ml = GLib.MainLoop()
+
+ def cb(data, data2):
+ data['called'] = True
+ data['data2'] = data2
+ ml.quit()
+ data = {}
+ id = GLib.idle_add(cb, data, 'hello')
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_DEFAULT_IDLE)
+ ml.run()
+ self.assertTrue(data['called'])
+ self.assertEqual(data['data2'], 'hello')
+
+ def test_timeout_data(self):
+ ml = GLib.MainLoop()
+
+ def cb(data):
+ data['called'] = True
+ ml.quit()
+ data = {}
+ id = GLib.timeout_add(50, cb, data)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_DEFAULT)
+ ml.run()
+ self.assertTrue(data['called'])
+
+ def test_timeout_multidata(self):
+ ml = GLib.MainLoop()
+
+ def cb(data, data2):
+ data['called'] = True
+ data['data2'] = data2
+ ml.quit()
+ data = {}
+ id = GLib.timeout_add(50, cb, data, 'hello')
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_DEFAULT)
+ ml.run()
+ self.assertTrue(data['called'])
+ self.assertEqual(data['data2'], 'hello')
+
+ def test_idle_no_data_priority(self):
+ ml = GLib.MainLoop()
+
+ def cb():
+ ml.quit()
+ id = GLib.idle_add(cb, priority=GLib.PRIORITY_HIGH)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ ml.run()
+
+ def test_timeout_no_data_priority(self):
+ ml = GLib.MainLoop()
+
+ def cb():
+ ml.quit()
+ id = GLib.timeout_add(50, cb, priority=GLib.PRIORITY_HIGH)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ ml.run()
+
+ def test_idle_data_priority(self):
+ ml = GLib.MainLoop()
+
+ def cb(data):
+ data['called'] = True
+ ml.quit()
+ data = {}
+ id = GLib.idle_add(cb, data, priority=GLib.PRIORITY_HIGH)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ ml.run()
+ self.assertTrue(data['called'])
+
+ def test_timeout_data_priority(self):
+ ml = GLib.MainLoop()
+
+ def cb(data):
+ data['called'] = True
+ ml.quit()
+ data = {}
+ id = GLib.timeout_add(50, cb, data, priority=GLib.PRIORITY_HIGH)
+ self.assertEqual(ml.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ ml.run()
+ self.assertTrue(data['called'])
+
+ def cb_no_data(self):
+ self.loop.quit()
+
+ def test_idle_method_callback_no_data(self):
+ self.loop = GLib.MainLoop()
+ GLib.idle_add(self.cb_no_data)
+ self.loop.run()
+
+ def cb_with_data(self, data):
+ data['called'] = True
+ self.loop.quit()
+
+ def test_idle_method_callback_with_data(self):
+ self.loop = GLib.MainLoop()
+ data = {}
+ GLib.idle_add(self.cb_with_data, data)
+ self.loop.run()
+ self.assertTrue(data['called'])
if __name__ == '__main__':
diff --git a/tests/test_subprocess.py b/tests/test_subprocess.py
index 14c6283..ef4c35e 100644
--- a/tests/test_subprocess.py
+++ b/tests/test_subprocess.py
@@ -1,23 +1,146 @@
# -*- Mode: Python -*-
import sys
+import os
import unittest
+import warnings
from gi.repository import GLib
+from gi import PyGIDeprecationWarning
+
class TestProcess(unittest.TestCase):
- def _child_watch_cb(self, pid, condition, data):
- self.data = data
- self.loop.quit()
+ def test_deprecated_child_watch_no_data(self):
+ def cb(pid, status):
+ self.status = status
+ self.loop.quit()
+
+ self.status = None
+ self.loop = GLib.MainLoop()
+ argv = [sys.executable, '-c', 'import sys']
+ pid, stdin, stdout, stderr = GLib.spawn_async(
+ argv, flags=GLib.SpawnFlags.DO_NOT_REAP_CHILD)
+ pid.close()
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+ GLib.child_watch_add(pid, cb)
+ self.assertTrue(issubclass(w[0].category, PyGIDeprecationWarning))
+ self.loop.run()
+ self.assertEqual(self.status, 0)
+
+ def test_deprecated_child_watch_data_priority(self):
+ def cb(pid, status, data):
+ self.data = data
+ self.status = status
+ self.loop.quit()
+
+ self.status = None
+ self.data = None
+ self.loop = GLib.MainLoop()
+ argv = [sys.executable, '-c', 'import sys']
+ pid, stdin, stdout, stderr = GLib.spawn_async(
+ argv, flags=GLib.SpawnFlags.DO_NOT_REAP_CHILD)
+ pid.close()
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+ id = GLib.child_watch_add(pid, cb, 12345, GLib.PRIORITY_HIGH)
+ self.assertTrue(issubclass(w[0].category, PyGIDeprecationWarning))
+ self.assertEqual(self.loop.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ self.loop.run()
+ self.assertEqual(self.data, 12345)
+ self.assertEqual(self.status, 0)
+
+ def test_deprecated_child_watch_data_priority_kwargs(self):
+ def cb(pid, status, data):
+ self.data = data
+ self.status = status
+ self.loop.quit()
+
+ self.status = None
+ self.data = None
+ self.loop = GLib.MainLoop()
+ argv = [sys.executable, '-c', 'import sys']
+ pid, stdin, stdout, stderr = GLib.spawn_async(
+ argv, flags=GLib.SpawnFlags.DO_NOT_REAP_CHILD)
+ pid.close()
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+ id = GLib.child_watch_add(pid, cb, priority=GLib.PRIORITY_HIGH, data=12345)
+ self.assertTrue(issubclass(w[0].category, PyGIDeprecationWarning))
+ self.assertEqual(self.loop.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ self.loop.run()
+ self.assertEqual(self.data, 12345)
+ self.assertEqual(self.status, 0)
+
+ def test_child_watch_no_data(self):
+ def cb(pid, status):
+ self.status = status
+ self.loop.quit()
+
+ self.status = None
+ self.loop = GLib.MainLoop()
+ argv = [sys.executable, '-c', 'import sys']
+ pid, stdin, stdout, stderr = GLib.spawn_async(
+ argv, flags=GLib.SpawnFlags.DO_NOT_REAP_CHILD)
+ pid.close()
+ id = GLib.child_watch_add(GLib.PRIORITY_HIGH, pid, cb)
+ self.assertEqual(self.loop.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
+ self.loop.run()
+ self.assertEqual(self.status, 0)
+
+ def test_child_watch_with_data(self):
+ def cb(pid, status, data):
+ self.status = status
+ self.data = data
+ self.loop.quit()
- def testChildWatch(self):
self.data = None
+ self.status = None
self.loop = GLib.MainLoop()
argv = [sys.executable, '-c', 'import sys']
pid, stdin, stdout, stderr = GLib.spawn_async(
- argv, flags=GLib.SPAWN_DO_NOT_REAP_CHILD)
+ argv, flags=GLib.SpawnFlags.DO_NOT_REAP_CHILD)
+ self.assertEqual(stdin, None)
+ self.assertEqual(stdout, None)
+ self.assertEqual(stderr, None)
+ self.assertNotEqual(pid, 0)
pid.close()
- GLib.child_watch_add(pid, self._child_watch_cb, 12345)
+ id = GLib.child_watch_add(GLib.PRIORITY_HIGH, pid, cb, 12345)
+ self.assertEqual(self.loop.get_context().find_source_by_id(id).priority,
+ GLib.PRIORITY_HIGH)
self.loop.run()
self.assertEqual(self.data, 12345)
+ self.assertEqual(self.status, 0)
+
+ def test_spawn_async_fds(self):
+ pid, stdin, stdout, stderr = GLib.spawn_async(
+ ['cat'], flags=GLib.SpawnFlags.SEARCH_PATH, standard_input=True,
+ standard_output=True, standard_error=True)
+ os.write(stdin, b'hello world!\n')
+ os.close(stdin)
+ out = os.read(stdout, 50)
+ os.close(stdout)
+ err = os.read(stderr, 50)
+ os.close(stderr)
+ pid.close()
+ self.assertEqual(out, b'hello world!\n')
+ self.assertEqual(err, b'')
+
+ def test_spawn_async_envp(self):
+ pid, stdin, stdout, stderr = GLib.spawn_async(
+ ['sh', '-c', 'echo $TEST_VAR'], ['TEST_VAR=moo!'],
+ flags=GLib.SpawnFlags.SEARCH_PATH, standard_output=True)
+ self.assertEqual(stdin, None)
+ self.assertEqual(stderr, None)
+ out = os.read(stdout, 50)
+ os.close(stdout)
+ pid.close()
+ self.assertEqual(out, b'moo!\n')
+
+ def test_backwards_compat_flags(self):
+ self.assertEqual(GLib.SpawnFlags.DO_NOT_REAP_CHILD,
+ GLib.SPAWN_DO_NOT_REAP_CHILD)
diff --git a/tests/test_thread.py b/tests/test_thread.py
index fa52dfa..3d0557e 100644
--- a/tests/test_thread.py
+++ b/tests/test_thread.py
@@ -5,6 +5,7 @@ import testhelper
from gi.repository import GLib
+
class TestThread(unittest.TestCase):
def setUp(self):
self.main = GLib.MainLoop()
@@ -19,7 +20,7 @@ class TestThread(unittest.TestCase):
self.obj.connect('from-thread', self.from_thread_cb)
self.obj.emit('emit-signal')
- def testExtensionModule(self):
+ def test_extension_module(self):
GLib.idle_add(self.idle_cb)
GLib.timeout_add(50, self.timeout_cb)
self.main.run()
diff --git a/tests/test_uris.py b/tests/test_uris.py
deleted file mode 100644
index 8174324..0000000
--- a/tests/test_uris.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import unittest
-
-from gi.repository import GLib
-
-class TestUris(unittest.TestCase):
- def testExtractUris(self):
- uri_list_text = "# urn:isbn:0-201-08372-8\n" + \
- "http://www.huh.org/books/foo.html\n" + \
- "http://www.huh.org/books/foo.pdf\n" + \
- "ftp://ftp.foo.org/books/foo.txt\n"
- uri_list = GLib.uri_list_extract_uris(uri_list_text)
- assert uri_list[0] == "http://www.huh.org/books/foo.html"
- assert uri_list[1] == "http://www.huh.org/books/foo.pdf"
- assert uri_list[2] == "ftp://ftp.foo.org/books/foo.txt"
-
diff --git a/tests/testhelpermodule.c b/tests/testhelpermodule.c
index 592c503..9b198c3 100644
--- a/tests/testhelpermodule.c
+++ b/tests/testhelpermodule.c
@@ -7,14 +7,11 @@
#include <pyglib-python-compat.h>
-static PyTypeObject *_PyGObject_Type;
-#define PyGObject_Type (*_PyGObject_Type)
-
static PyObject * _wrap_TestInterface__do_iface_method(PyObject *cls,
PyObject *args,
PyObject *kwargs);
-GType
+static GType
test_type_get_type(void)
{
static GType gtype = 0;
@@ -322,6 +319,16 @@ test_double_callback (GObject *object, double d)
return d;
}
+static gint64
+test_int64_callback (GObject *object, gint64 i)
+{
+ g_return_val_if_fail (G_IS_OBJECT (object), -1);
+
+ if (i == G_MAXINT64)
+ return i-1;
+ return i;
+}
+
static char *
test_string_callback (GObject *object, char *s)
{
@@ -339,7 +346,69 @@ test_object_callback (GObject *object, GObject *o)
return o;
}
-void
+static GParamSpec *
+test_paramspec_callback (GObject *object)
+{
+ g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+
+ return g_param_spec_boolean ("test-param", "test", "test boolean", TRUE, G_PARAM_READABLE);
+}
+
+static GValue *
+test_gvalue_callback (GObject *object, const GValue *v)
+{
+ GValue *ret = g_malloc0 (sizeof (GValue));
+
+ g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+ g_return_val_if_fail (G_IS_VALUE (v), NULL);
+
+ g_value_init (ret, G_VALUE_TYPE (v));
+ g_value_copy (v, ret);
+ return ret;
+}
+
+static GValue *
+test_gvalue_ret_callback (GObject *object, GType type)
+{
+ GValue *ret = g_malloc0 (sizeof (GValue));
+
+ g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+
+ g_value_init (ret, type);
+
+ switch (type) {
+ case G_TYPE_INT:
+ g_value_set_int(ret, G_MAXINT);
+ break;
+ case G_TYPE_INT64:
+ g_value_set_int64(ret, G_MAXINT64);
+ break;
+ case G_TYPE_UINT:
+ g_value_set_uint(ret, G_MAXUINT);
+ break;
+ case G_TYPE_UINT64:
+ g_value_set_uint64(ret, G_MAXUINT64);
+ break;
+ case G_TYPE_STRING:
+ g_value_set_string(ret, "hello");
+ break;
+ default:
+ g_critical ("test_gvalue_ret_callback() does not support type %s", g_type_name (type));
+ }
+
+ return ret;
+}
+
+static GParamSpec *
+test_paramspec_in_callback (GObject *object, GParamSpec *p)
+{
+ g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+ g_return_val_if_fail (G_IS_PARAM_SPEC (p), NULL);
+
+ return p;
+}
+
+static void
connectcallbacks (GObject *object)
{
@@ -374,6 +443,10 @@ connectcallbacks (GObject *object)
G_CALLBACK (test_double_callback),
NULL);
g_signal_connect (G_OBJECT (object),
+ "test_int64",
+ G_CALLBACK (test_int64_callback),
+ NULL);
+ g_signal_connect (G_OBJECT (object),
"test_string",
G_CALLBACK (test_string_callback),
NULL);
@@ -381,6 +454,22 @@ connectcallbacks (GObject *object)
"test_object",
G_CALLBACK (test_object_callback),
NULL);
+ g_signal_connect (G_OBJECT (object),
+ "test_paramspec",
+ G_CALLBACK (test_paramspec_callback),
+ NULL);
+ g_signal_connect (G_OBJECT (object),
+ "test_gvalue",
+ G_CALLBACK (test_gvalue_callback),
+ NULL);
+ g_signal_connect (G_OBJECT (object),
+ "test_gvalue_ret",
+ G_CALLBACK (test_gvalue_ret_callback),
+ NULL);
+ g_signal_connect (G_OBJECT (object),
+ "test_paramspec_in",
+ G_CALLBACK (test_paramspec_in_callback),
+ NULL);
}
static PyObject *
@@ -451,7 +540,6 @@ _wrap_test_gerror_exception(PyObject *self, PyObject *args)
return NULL;
}
- Py_DECREF(py_method);
Py_DECREF(py_args);
Py_DECREF(py_ret);
@@ -523,21 +611,11 @@ PYGLIB_MODULE_START(testhelper, "testhelper")
{
PyObject *m, *d;
- g_thread_init(NULL);
pygobject_init(-1, -1, -1);
d = PyModule_GetDict(module);
- if ((m = PyImport_ImportModule("gi._gobject")) != NULL) {
- PyObject *moddict = PyModule_GetDict(m);
-
- _PyGObject_Type = (PyTypeObject *)PyDict_GetItemString(moddict, "GObject");
- if (_PyGObject_Type == NULL) {
- PyErr_SetString(PyExc_ImportError,
- "cannot import name GObject from gobject");
- return PYGLIB_MODULE_ERROR_RETURN;
- }
- } else {
+ if ((m = PyImport_ImportModule("gi.repository.GObject")) == NULL) {
PyErr_SetString(PyExc_ImportError,
"could not import gobject");
return PYGLIB_MODULE_ERROR_RETURN;
diff --git a/tests/testmodule.py b/tests/testmodule.py
index c4132c5..3da8ed5 100644
--- a/tests/testmodule.py
+++ b/tests/testmodule.py
@@ -1,5 +1,6 @@
from gi.repository import GObject
+
class PyGObject(GObject.GObject):
__gtype_name__ = 'PyGObject'
__gproperties__ = {