diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 63 | ||||
-rw-r--r-- | tests/Makefile.in | 569 | ||||
-rw-r--r-- | tests/common.py | 48 | ||||
-rw-r--r-- | tests/runtests.py | 44 | ||||
-rw-r--r-- | tests/test-floating.c | 95 | ||||
-rw-r--r-- | tests/test-floating.h | 60 | ||||
-rw-r--r-- | tests/test-thread.c | 64 | ||||
-rw-r--r-- | tests/test-thread.h | 22 | ||||
-rw-r--r-- | tests/test-unknown.c | 113 | ||||
-rw-r--r-- | tests/test-unknown.h | 40 | ||||
-rw-r--r-- | tests/test_gicon.py | 111 | ||||
-rw-r--r-- | tests/test_gio.py | 1137 | ||||
-rw-r--r-- | tests/test_gobject.py | 29 | ||||
-rw-r--r-- | tests/test_interface.py | 45 | ||||
-rw-r--r-- | tests/test_mainloop.py | 53 | ||||
-rw-r--r-- | tests/test_properties.py | 376 | ||||
-rw-r--r-- | tests/test_signal.py | 393 | ||||
-rw-r--r-- | tests/test_source.py | 100 | ||||
-rw-r--r-- | tests/test_subprocess.py | 27 | ||||
-rw-r--r-- | tests/test_unknown.py | 15 | ||||
-rw-r--r-- | tests/testhelpermodule.c | 679 | ||||
-rw-r--r-- | tests/testmodule.py | 21 |
22 files changed, 4104 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..fcdffe1 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,63 @@ +INCLUDES = \ + -I$(top_srcdir)/gobject \ + $(PYTHON_INCLUDES) \ + $(GLIB_CFLAGS) + +EXTRA_DIST = \ + $(tests) \ + common.py \ + runtests.py \ + testmodule.py \ + test-floating.h \ + test-thread.h \ + test-unknown.h + +noinst_LTLIBRARIES = testhelper.la +linked_LIBS = testhelper.la + +testhelper_la_LDFLAGS = -module -avoid-version +testhelper_la_LIBADD = $(GLIB_LIBS) +testhelper_la_SOURCES = \ + testhelpermodule.c \ + test-floating.c \ + test-thread.c \ + test-unknown.c + +tests = \ + test_gicon.py \ + test_gio.py \ + test_gobject.py \ + test_interface.py \ + test_mainloop.py \ + test_properties.py \ + test_signal.py \ + test_subprocess.py \ + test_unknown.py \ + test_source.py + +# 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) + +check-local: $(top_srcdir)/glib/__init__.py $(top_srcdir)/gobject/__init__.py $(top_srcdir)/gio/__init__.py + @if test "$(top_builddir)" != "$(top_srcdir)"; then \ + cp $(top_srcdir)/glib/*.py $(top_builddir)/glib; \ + cp $(top_srcdir)/gobject/*.py $(top_builddir)/gobject; \ + cp $(top_srcdir)/gio/*.py $(top_builddir)/gio; \ + fi + @$(PYTHON) $(srcdir)/runtests.py $(top_builddir) $(top_srcdir) + @if test "$(top_builddir)" != "$(top_srcdir)"; then \ + rm -f $(top_builddir)/glib/*.py; \ + rm -f $(top_builddir)/gobject/*.py; \ + rm -f $(top_builddir)/gio/*.py; \ + fi + @rm -fr $(top_builddir)/glib/*.pyc + @rm -fr $(top_builddir)/gobject/*.pyc + @rm -fr $(top_builddir)/gio/*.pyc + + +all: $(LTLIBRARIES:.la=.so) +clean-local: + rm -f $(LTLIBRARIES:.la=.so) +.la.so: + $(LN_S) .libs/$@ $@ || true diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 0000000..7e77581 --- /dev/null +++ b/tests/Makefile.in @@ -0,0 +1,569 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +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 +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) +am__DEPENDENCIES_1 = +testhelper_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_testhelper_la_OBJECTS = testhelpermodule.lo test-floating.lo \ + test-thread.lo test-unknown.lo +testhelper_la_OBJECTS = $(am_testhelper_la_OBJECTS) +testhelper_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(testhelper_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(testhelper_la_SOURCES) +DIST_SOURCES = $(testhelper_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FFI_CFLAGS = @FFI_CFLAGS@ +FFI_LIBS = @FFI_LIBS@ +FGREP = @FGREP@ +GIOUNIX_CFLAGS = @GIOUNIX_CFLAGS@ +GIOUNIX_LIBS = @GIOUNIX_LIBS@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBFFI_PC = @LIBFFI_PC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PLATFORM = @PLATFORM@ +PYGOBJECT_MAJOR_VERSION = @PYGOBJECT_MAJOR_VERSION@ +PYGOBJECT_MICRO_VERSION = @PYGOBJECT_MICRO_VERSION@ +PYGOBJECT_MINOR_VERSION = @PYGOBJECT_MINOR_VERSION@ +PYTHON = @PYTHON@ +PYTHON_BASENAME = @PYTHON_BASENAME@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +THREADING_CFLAGS = @THREADING_CFLAGS@ +VERSION = @VERSION@ +XSLTPROC = @XSLTPROC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pygobject_CODEGEN_DEFINES = @pygobject_CODEGEN_DEFINES@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_srcdir)/gobject \ + $(PYTHON_INCLUDES) \ + $(GLIB_CFLAGS) + +EXTRA_DIST = \ + $(tests) \ + common.py \ + runtests.py \ + testmodule.py \ + test-floating.h \ + test-thread.h \ + test-unknown.h + +noinst_LTLIBRARIES = testhelper.la +linked_LIBS = testhelper.la +testhelper_la_LDFLAGS = -module -avoid-version +testhelper_la_LIBADD = $(GLIB_LIBS) +testhelper_la_SOURCES = \ + testhelpermodule.c \ + test-floating.c \ + test-thread.c \ + test-unknown.c + +tests = \ + test_gicon.py \ + test_gio.py \ + test_gobject.py \ + test_interface.py \ + test_mainloop.py \ + test_properties.py \ + test_signal.py \ + test_subprocess.py \ + test_unknown.py \ + test_source.py + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .la .lo .o .obj .so +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(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 \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-floating.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-thread.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-unknown.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testhelpermodule.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @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 + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +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 \ + 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 +testhelper.la: $(testhelper_la_OBJECTS) $(testhelper_la_DEPENDENCIES) + $(LINK) -rpath $(pkgpyexecdir) $(testhelper_la_LDFLAGS) $(testhelper_la_OBJECTS) $(testhelper_la_LIBADD) $(LIBS) + +check-local: $(top_srcdir)/glib/__init__.py $(top_srcdir)/gobject/__init__.py $(top_srcdir)/gio/__init__.py + @if test "$(top_builddir)" != "$(top_srcdir)"; then \ + cp $(top_srcdir)/glib/*.py $(top_builddir)/glib; \ + cp $(top_srcdir)/gobject/*.py $(top_builddir)/gobject; \ + cp $(top_srcdir)/gio/*.py $(top_builddir)/gio; \ + fi + @$(PYTHON) $(srcdir)/runtests.py $(top_builddir) $(top_srcdir) + @if test "$(top_builddir)" != "$(top_srcdir)"; then \ + rm -f $(top_builddir)/glib/*.py; \ + rm -f $(top_builddir)/gobject/*.py; \ + rm -f $(top_builddir)/gio/*.py; \ + fi + @rm -fr $(top_builddir)/glib/*.pyc + @rm -fr $(top_builddir)/gobject/*.pyc + @rm -fr $(top_builddir)/gio/*.pyc + +all: $(LTLIBRARIES:.la=.so) +clean-local: + rm -f $(LTLIBRARIES:.la=.so) +.la.so: + $(LN_S) .libs/$@ $@ || true + +# 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. +.NOEXPORT: diff --git a/tests/common.py b/tests/common.py new file mode 100644 index 0000000..a6fa73d --- /dev/null +++ b/tests/common.py @@ -0,0 +1,48 @@ +import os +import sys + +def importModules(buildDir, srcDir): + # Be very careful when you change this code, it's + # fragile and the order is really significant + + sys.path.insert(0, srcDir) + sys.path.insert(0, buildDir) + sys.path.insert(0, os.path.join(buildDir, 'glib')) + sys.path.insert(0, os.path.join(buildDir, 'gobject')) + sys.path.insert(0, os.path.join(buildDir, 'gio')) + + # testhelper + sys.path.insert(0, os.path.join(buildDir, 'tests')) + sys.argv.append('--g-fatal-warnings') + + testhelper = importModule('testhelper', '.') + glib = importModule('glib', buildDir, 'glib') + gobject = importModule('gobject', buildDir, 'gobject') + gio = importModule('gio', buildDir, 'gio') + + globals().update(locals()) + + os.environ['PYGTK_USE_GIL_STATE_API'] = '' + gobject.threads_init() + +def importModule(module, directory, name=None): + global isDistCheck + + origName = module + if not name: + name = module + '.la' + + try: + obj = __import__(module, {}, {}, '') + except ImportError, e: + raise SystemExit('%s could not be imported: %s' % (origName, e)) + + location = obj.__file__ + + current = os.getcwd() + expected = os.path.abspath(os.path.join(current, location)) + current = os.path.abspath(location) + if current != expected: + raise AssertionError('module %s imported from wrong location. Expected %s, got %s' % ( + module, expected, current)) + return obj diff --git a/tests/runtests.py b/tests/runtests.py new file mode 100644 index 0000000..da5ade0 --- /dev/null +++ b/tests/runtests.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +import glob +import os +import sys +import unittest + +import common + +program = None +if len(sys.argv) == 3: + buildDir = sys.argv[1] + srcDir = sys.argv[2] +else: + if len(sys.argv) == 2: + program = sys.argv[1] + if program.endswith('.py'): + program = program[:-3] + buildDir = '..' + srcDir = '.' + +common.importModules(buildDir=buildDir, + srcDir=srcDir) + +SKIP_FILES = ['common', 'runtests'] + +dir = os.path.split(os.path.abspath(__file__))[0] +os.chdir(dir) + +def gettestnames(): + files = glob.glob('*.py') + names = map(lambda x: x[:-3], files) + map(names.remove, SKIP_FILES) + return names + +suite = unittest.TestSuite() +loader = unittest.TestLoader() + +for name in gettestnames(): + if program and program not in name: + continue + suite.addTest(loader.loadTestsFromName(name)) + +testRunner = unittest.TextTestRunner() +testRunner.run(suite) diff --git a/tests/test-floating.c b/tests/test-floating.c new file mode 100644 index 0000000..918a42d --- /dev/null +++ b/tests/test-floating.c @@ -0,0 +1,95 @@ +/* + * test-floating.c - Source for TestFloatingWithSinkFunc and TestFloatingWithoutSinkFunc + * Copyright (C) 2010 Collabora Ltd. + * + * 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 + */ + +#include "test-floating.h" + +/* TestFloatingWithSinkFunc */ + +G_DEFINE_TYPE(TestFloatingWithSinkFunc, test_floating_with_sink_func, G_TYPE_INITIALLY_UNOWNED) + +static void +test_floating_with_sink_func_finalize (GObject *gobject) +{ + TestFloatingWithSinkFunc *object = TEST_FLOATING_WITH_SINK_FUNC (gobject); + + if (g_object_is_floating (object)) + { + g_warning ("A floating object was finalized. This means that someone\n" + "called g_object_unref() on an object that had only a floating\n" + "reference; the initial floating reference is not owned by anyone\n" + "and must be removed with g_object_ref_sink()."); + } + + G_OBJECT_CLASS (test_floating_with_sink_func_parent_class)->finalize (gobject); +} + +static void +test_floating_with_sink_func_class_init (TestFloatingWithSinkFuncClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = test_floating_with_sink_func_finalize; +} + +static void +test_floating_with_sink_func_init (TestFloatingWithSinkFunc *self) +{ +} + +void +sink_test_floating_with_sink_func (GObject *object) +{ + if (g_object_is_floating(object)) { + g_object_ref_sink(object); + } +} + +/* TestFloatingWithoutSinkFunc */ + +G_DEFINE_TYPE(TestFloatingWithoutSinkFunc, test_floating_without_sink_func, G_TYPE_INITIALLY_UNOWNED) + +static void +test_floating_without_sink_func_finalize (GObject *gobject) +{ + TestFloatingWithoutSinkFunc *object = TEST_FLOATING_WITHOUT_SINK_FUNC (gobject); + + if (g_object_is_floating (object)) + { + g_warning ("A floating object was finalized. This means that someone\n" + "called g_object_unref() on an object that had only a floating\n" + "reference; the initial floating reference is not owned by anyone\n" + "and must be removed without g_object_ref_sink()."); + } + + G_OBJECT_CLASS (test_floating_without_sink_func_parent_class)->finalize (gobject); +} + +static void +test_floating_without_sink_func_class_init (TestFloatingWithoutSinkFuncClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = test_floating_without_sink_func_finalize; +} + +static void +test_floating_without_sink_func_init (TestFloatingWithoutSinkFunc *self) +{ +} + diff --git a/tests/test-floating.h b/tests/test-floating.h new file mode 100644 index 0000000..e53df32 --- /dev/null +++ b/tests/test-floating.h @@ -0,0 +1,60 @@ +/* + * test-floating.h - Header for TestFloatingWithSinkFunc and TestFloatingWithoutSinkFunc + * Copyright (C) 2010 Collabora Ltd. + * + * 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 + */ + +#include <glib-object.h> + +/* TestFloatingWithSinkFunc */ + +typedef struct { + GInitiallyUnowned parent; +} TestFloatingWithSinkFunc; + +typedef struct { + GInitiallyUnownedClass parent_class; +} TestFloatingWithSinkFuncClass; + +#define TEST_TYPE_FLOATING_WITH_SINK_FUNC (test_floating_with_sink_func_get_type()) +#define TEST_FLOATING_WITH_SINK_FUNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_FLOATING_WITH_SINK_FUNC, TestFloatingWithSinkFunc)) +#define TEST_FLOATING_WITH_SINK_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_FLOATING_WITH_SINK_FUNC, TestFloatingWithSinkFuncClass)) +#define TEST_IS_FLOATING_WITH_SINK_FUNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_FLOATING_WITH_SINK_FUNC)) +#define TEST_IS_FLOATING_WITH_SINK_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TEST_TYPE_FLOATING_WITH_SINK_FUNC)) +#define TEST_FLOATING_WITH_SINK_FUNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_FLOATING_WITH_SINK_FUNC, TestFloatingWithSinkFuncClass)) + +GType test_floating_with_sink_func_get_type (void); +void sink_test_floating_with_sink_func (GObject *object); + +/* TestFloatingWithoutSinkFunc */ + +typedef struct { + GInitiallyUnowned parent; +} TestFloatingWithoutSinkFunc; + +typedef struct { + GInitiallyUnownedClass parent_class; +} TestFloatingWithoutSinkFuncClass; + +#define TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC (test_floating_without_sink_func_get_type()) +#define TEST_FLOATING_WITHOUT_SINK_FUNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC, TestFloatingWithoutSinkFunc)) +#define TEST_FLOATING_WITHOUT_SINK_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC, TestFloatingWithoutSinkFuncClass)) +#define TEST_IS_FLOATING_WITHOUT_SINK_FUNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC)) +#define TEST_IS_FLOATING_WITHOUT_SINK_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC)) +#define TEST_FLOATING_WITHOUT_SINK_FUNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC, TestFloatingWithoutSinkFuncClass)) + +GType test_floating_without_sink_func_get_type (void); + diff --git a/tests/test-thread.c b/tests/test-thread.c new file mode 100644 index 0000000..0f5b909 --- /dev/null +++ b/tests/test-thread.c @@ -0,0 +1,64 @@ +#include "test-thread.h" + +enum +{ + /* methods */ + SIGNAL_EMIT_SIGNAL, + SIGNAL_FROM_THREAD, + LAST_SIGNAL +}; + +static guint test_thread_signals[LAST_SIGNAL] = { 0 }; + +typedef enum { + TEST_THREAD_A, + TEST_THREAD_B +} ThreadEnumType; + +static GType +test_thread_enum_get_type (void) +{ + static GType enum_type = 0; + static GEnumValue enum_values[] = { + {TEST_THREAD_A, "TEST_THREAD_A", "a as in apple"}, + {0, NULL, NULL}, + }; + + if (!enum_type) { + enum_type = + g_enum_register_static ("TestThreadEnum", enum_values); + } + return enum_type; +} + +G_DEFINE_TYPE(TestThread, test_thread, G_TYPE_OBJECT); + +static void +other_thread_cb (TestThread *self) +{ + g_signal_emit_by_name (self, "from-thread", 0, NULL); + g_thread_exit (0); +} + +static void +test_thread_emit_signal (TestThread *self) +{ + self->thread = g_thread_create ((GThreadFunc)other_thread_cb, + self, TRUE, NULL); +} + +static void test_thread_init (TestThread *self) {} +static void test_thread_class_init (TestThreadClass *klass) +{ + test_thread_signals[SIGNAL_EMIT_SIGNAL] = + g_signal_new ("emit-signal", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestThreadClass, emit_signal), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + test_thread_signals[SIGNAL_FROM_THREAD] = + g_signal_new ("from-thread", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestThreadClass, from_thread), + NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, + test_thread_enum_get_type ()); + + klass->emit_signal = test_thread_emit_signal; +} diff --git a/tests/test-thread.h b/tests/test-thread.h new file mode 100644 index 0000000..db12fe4 --- /dev/null +++ b/tests/test-thread.h @@ -0,0 +1,22 @@ +#include <glib-object.h> + +typedef struct { + GObject parent; + GThread *thread; +} TestThread; + +typedef struct { + GObjectClass parent_class; + void (*emit_signal) (TestThread *sink); + void (*from_thread) (TestThread *sink); +} TestThreadClass; + +GType test_thread_get_type (void); + +#define TEST_TYPE_THREAD (test_thread_get_type()) +#define TEST_THREAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_THREAD, TestTHREAD)) +#define TEST_THREAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_THREAD, TestTHREADClass)) +#define TEST_IS_THREAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_THREAD)) +#define TEST_IS_THREAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TEST_TYPE_THREAD)) +#define TEST_THREAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_THREAD, TestTHREADClass)) + diff --git a/tests/test-unknown.c b/tests/test-unknown.c new file mode 100644 index 0000000..85aba73 --- /dev/null +++ b/tests/test-unknown.c @@ -0,0 +1,113 @@ +#include "test-unknown.h" + +enum { + PROP_SOME_PROPERTY = 1, +}; + + +static void +test_interface_base_init (gpointer g_iface) +{ + static gboolean initialized = FALSE; + + if (!initialized) + { + g_object_interface_install_property (g_iface, + g_param_spec_string ("some-property", + "some-property", + "A simple test property", + NULL, + G_PARAM_READWRITE)); + initialized = TRUE; + } +} + + +GType +test_interface_get_type (void) +{ + static GType gtype = 0; + + if (!gtype) + { + static const GTypeInfo info = + { + sizeof (TestInterfaceIface), /* class_size */ + test_interface_base_init, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + gtype = + g_type_register_static (G_TYPE_INTERFACE, "TestInterface", + &info, 0); + + g_type_interface_add_prerequisite (gtype, G_TYPE_OBJECT); + } + + return gtype; +} + +void test_unknown_iface_method (TestInterface *iface) +{ +} + +static void +test_unknown_test_interface_init (TestInterfaceIface *iface) +{ + iface->iface_method = test_unknown_iface_method; +} + +G_DEFINE_TYPE_WITH_CODE (TestUnknown, test_unknown, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TEST_TYPE_INTERFACE, + test_unknown_test_interface_init)); + +static void test_unknown_init (TestUnknown *self) {} + + +static void +test_unknown_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + +} + +static void +test_unknown_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + +} + +static void test_unknown_class_init (TestUnknownClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + + gobject_class->get_property = test_unknown_get_property; + gobject_class->set_property = test_unknown_set_property; + + + g_object_class_install_property (G_OBJECT_CLASS (klass), + PROP_SOME_PROPERTY, + g_param_spec_string ("some-property", + "some-property", + "A simple test property", + NULL, + G_PARAM_READWRITE)); +} + +void test_interface_iface_method (TestInterface *instance) +{ + TestInterfaceIface *iface = TEST_INTERFACE_GET_IFACE (instance); + + (* iface->iface_method) (instance); +} diff --git a/tests/test-unknown.h b/tests/test-unknown.h new file mode 100644 index 0000000..e0f51a2 --- /dev/null +++ b/tests/test-unknown.h @@ -0,0 +1,40 @@ +#include <glib-object.h> + +/* TestUnknown */ + +typedef struct { + GObject parent; +} TestUnknown; + +typedef struct { + GObjectClass parent_class; +} TestUnknownClass; + +#define TEST_TYPE_UNKNOWN (test_unknown_get_type()) +#define TEST_UNKNOWN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_UNKNOWN, TestUnknown)) +#define TEST_UNKNOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_UNKNOWN, TestUnknownClass)) +#define TEST_IS_UNKNOWN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_UNKNOWN)) +#define TEST_IS_UNKNOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TEST_TYPE_UNKNOWN)) +#define TEST_UNKNOWN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_UNKNOWN, TestUnknownClass)) + +GType test_unknown_get_type (void); + +/* TestInterface */ +typedef struct _TestInterface TestInterface; +typedef struct _TestInterfaceIface TestInterfaceIface; + +struct _TestInterfaceIface +{ + GTypeInterface g_iface; + /* VTable */ + void (* iface_method) (TestInterface *iface); +}; + +#define TEST_TYPE_INTERFACE (test_interface_get_type ()) +#define TEST_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_INTERFACE, TestInterface)) +#define TEST_IS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_INTERFACE)) +#define TEST_INTERFACE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_INTERFACE, TestInterfaceIface)) + +GType test_interface_get_type (void); + +void test_interface_iface_method (TestInterface *iface); diff --git a/tests/test_gicon.py b/tests/test_gicon.py new file mode 100644 index 0000000..5ce7ece --- /dev/null +++ b/tests/test_gicon.py @@ -0,0 +1,111 @@ +# -*- Mode: Python -*- + +import os +import unittest + +from common import gio, glib + + +class TestIcon(unittest.TestCase): + def test_eq(self): + self.assertEquals(gio.FileIcon(gio.File('foo.png')), + gio.FileIcon(gio.File('foo.png'))) + self.assertEquals(gio.ThemedIcon('foo'), + gio.ThemedIcon('foo')) + + self.assertNotEqual(gio.FileIcon(gio.File('foo.png')), + gio.FileIcon(gio.File('bar.png'))) + self.assertNotEquals(gio.ThemedIcon('foo'), + gio.ThemedIcon('bar')) + self.assertNotEquals(gio.FileIcon(gio.File('foo.png')), + gio.ThemedIcon('foo')) + + def test_hash(self): + self.assertEquals(hash(gio.FileIcon(gio.File('foo.png'))), + hash(gio.FileIcon(gio.File('foo.png')))) + self.assertEquals(hash(gio.ThemedIcon('foo')), + hash(gio.ThemedIcon('foo'))) + +class TestLoadableIcon(unittest.TestCase): + def setUp(self): + self.file = open('temp.svg', 'w') + self.svg = ('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" ' + '"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">' + '<svg width="32" height="32"/>') + self.file.write(self.svg) + self.file.close() + self.icon = gio.FileIcon(gio.File('temp.svg')) + + def tearDown(self): + if os.path.exists('temp.svg'): + os.unlink('temp.svg') + + def test_load(self): + stream, type = self.icon.load() + try: + self.assert_(isinstance(stream, gio.InputStream)) + self.assertEquals(self.svg, stream.read()) + finally: + stream.close() + + def test_load_async(self): + def callback(icon, result): + try: + stream, type = icon.load_finish(result) + self.assert_(isinstance(stream, gio.InputStream)) + self.assertEquals(self.svg, stream.read()) + finally: + loop.quit() + stream.close() + + self.icon.load_async(callback) + + loop = glib.MainLoop() + loop.run() + +class TestFileIcon(unittest.TestCase): + def test_constructor(self): + file = gio.File('foo.png') + self.assert_(file is gio.FileIcon(file).get_file()) + +class TestThemedIcon(unittest.TestCase): + def setUp(self): + self.icon = gio.ThemedIcon("open") + + def test_constructor(self): + have_use_default_fallbacks = ('use_default_fallbacks' + in gio.ThemedIcon.props.__members__) + icon = gio.ThemedIcon('foo') + self.assertEquals(['foo'], icon.props.names) + self.assert_(not have_use_default_fallbacks + or not icon.props.use_default_fallbacks) + + icon = gio.ThemedIcon(['foo', 'bar', 'baz']) + self.assertEquals(['foo', 'bar', 'baz'], icon.props.names) + self.assert_(not have_use_default_fallbacks + or not icon.props.use_default_fallbacks) + + icon = gio.ThemedIcon('xxx-yyy-zzz', True) + self.assertEquals(['xxx-yyy-zzz', 'xxx-yyy', 'xxx'], icon.props.names) + self.assert_(not have_use_default_fallbacks + or icon.props.use_default_fallbacks) + + def test_constructor_illegals(self): + self.assertRaises(TypeError, lambda: gio.ThemedIcon(42)) + self.assertRaises(TypeError, lambda: gio.ThemedIcon(['foo', 42, 'bar'])) + + def test_get_names(self): + self.assertEquals(self.icon.get_names(), ['open']) + + def test_append_name(self): + self.assertEquals(self.icon.get_names(), ['open']) + self.icon.append_name('close') + self.assertEquals(self.icon.get_names(), ['open', 'close']) + +class TestEmblemedIcon(unittest.TestCase): + def test_emblemed_icon(self): + icon = gio.FileIcon(gio.File('foo.png')) + emblem = gio.Emblem(icon) + emblemed = gio.EmblemedIcon(icon, emblem) + self.assertEquals(emblemed.get_emblems()[0], emblem) diff --git a/tests/test_gio.py b/tests/test_gio.py new file mode 100644 index 0000000..feafc70 --- /dev/null +++ b/tests/test_gio.py @@ -0,0 +1,1137 @@ +# -*- Mode: Python -*- + +import os +import unittest + +from common import gio, glib + + +class TestFile(unittest.TestCase): + def setUp(self): + self._f = open("file.txt", "w+") + self.file = gio.File("file.txt") + + def tearDown(self): + self._f.close() + if os.path.exists('file.txt'): + os.unlink("file.txt") + + def testReadAsync(self): + self._f.write("testing") + self._f.seek(0) + + def callback(file, result): + try: + stream = file.read_finish(result) + self.failUnless(isinstance(stream, gio.InputStream)) + self.assertEquals(stream.read(), "testing") + finally: + loop.quit() + + self.file.read_async(callback) + + loop = glib.MainLoop() + loop.run() + + def testAppendToAsync(self): + self._f.write("append_to ") + self._f.close() + + def callback(file, result): + try: + stream = file.append_to_finish(result) + self.failUnless(isinstance(stream, gio.OutputStream)) + w = stream.write("testing") + cont, leng, etag = self.file.load_contents() + self.assertEqual(cont, "append_to testing") + finally: + loop.quit() + + self.file.append_to_async(callback, gio.FILE_CREATE_NONE, + glib.PRIORITY_HIGH) + + loop = glib.MainLoop() + loop.run() + + def testAppendToAsyncNoargs(self): + self._f.write("append_to ") + self._f.close() + + def callback(file, result): + try: + stream = file.append_to_finish(result) + self.failUnless(isinstance(stream, gio.OutputStream)) + w = stream.write("testing") + cont, leng, etag = self.file.load_contents() + self.assertEqual(cont, "append_to testing") + finally: + loop.quit() + + self.file.append_to_async(callback) + + loop = glib.MainLoop() + loop.run() + + def testCreateAsync(self): + def callback(file, result): + try: + stream = file.create_finish(result) + self.failUnless(isinstance(stream, gio.OutputStream)) + w = stream.write("testing") + cont, leng, etag = file.load_contents() + self.assertEqual(cont, "testing") + finally: + if os.path.exists('temp.txt'): + os.unlink("temp.txt") + loop.quit() + + gfile = gio.File("temp.txt") + gfile.create_async(callback, gio.FILE_CREATE_NONE, + glib.PRIORITY_HIGH) + + loop = glib.MainLoop() + loop.run() + + def testCreateReadWriteAsync(self): + def callback(file, result): + try: + iostream = file.create_readwrite_finish(result) + self.failUnless(isinstance(iostream, gio.FileIOStream)) + + ostream = iostream.get_output_stream() + self.failUnless(isinstance(ostream, gio.OutputStream)) + + w = ostream.write("testing") + cont, leng, etag = file.load_contents() + self.assertEqual(cont, "testing") + finally: + if os.path.exists('temp.txt'): + os.unlink("temp.txt") + loop.quit() + + gfile = gio.File("temp.txt") + gfile.create_readwrite_async(callback, gio.FILE_CREATE_NONE, + glib.PRIORITY_HIGH) + + loop = glib.MainLoop() + loop.run() + + def testCreateAsyncNoargs(self): + def callback(file, result): + try: + stream = file.create_finish(result) + self.failUnless(isinstance(stream, gio.OutputStream)) + w = stream.write("testing") + cont, leng, etag = file.load_contents() + self.assertEqual(cont, "testing") + finally: + if os.path.exists('temp.txt'): + os.unlink("temp.txt") + loop.quit() + + gfile = gio.File("temp.txt") + gfile.create_async(callback) + + loop = glib.MainLoop() + loop.run() + + def testReplaceAsync(self): + self._f.write("testing") + self._f.close() + + def callback(file, result): + try: + stream = file.replace_finish(result) + self.failUnless(isinstance(stream, gio.OutputStream)) + stream.write("some new string") + stream.close() + cont, leng, etag = file.load_contents() + self.assertEqual(cont, "some new string") + finally: + loop.quit() + + + self.file.replace_async(callback, None, True, gio.FILE_CREATE_NONE, + glib.PRIORITY_HIGH) + + loop = glib.MainLoop() + loop.run() + + def testReplaceAsyncNoargs(self): + self._f.write("testing") + self._f.close() + + def callback(file, result): + try: + stream = file.replace_finish(result) + self.failUnless(isinstance(stream, gio.OutputStream)) + stream.write("some new string") + stream.close() + cont, leng, etag = file.load_contents() + self.assertEqual(cont, "some new string") + finally: + loop.quit() + + + self.file.replace_async(callback) + + loop = glib.MainLoop() + loop.run() + + def testReadAsyncError(self): + self.assertRaises(TypeError, self.file.read_async) + self.assertRaises(TypeError, self.file.read_async, "foo", "bar") + self.assertRaises(TypeError, self.file.read_async, "foo", + priority="bar") + self.assertRaises(TypeError, self.file.read_async, "foo", + priority="bar") + self.assertRaises(TypeError, self.file.read_async, "foo", + priority=1, cancellable="bar") + self.assertRaises(TypeError, self.file.read_async, "foo", 1, "bar") + + def testConstructor(self): + for gfile in [gio.File("/"), + gio.File("file:///"), + gio.File(uri="file:///"), + gio.File(path="/"), + gio.File(u"/"), + gio.File(path=u"/")]: + self.failUnless(isinstance(gfile, gio.File)) + self.assertEquals(gfile.get_path(), "/") + self.assertEquals(gfile.get_uri(), "file:///") + + def testConstructorError(self): + self.assertRaises(TypeError, gio.File) + self.assertRaises(TypeError, gio.File, 1) + self.assertRaises(TypeError, gio.File, "foo", "bar") + self.assertRaises(TypeError, gio.File, foo="bar") + self.assertRaises(TypeError, gio.File, uri=1) + self.assertRaises(TypeError, gio.File, path=1) + + def testLoadContents(self): + self._f.write("testing load_contents") + self._f.seek(0) + c = gio.Cancellable() + cont, leng, etag = self.file.load_contents(cancellable=c) + self.assertEqual(cont, "testing load_contents") + self.assertEqual(leng, 21) + self.assertNotEqual(etag, '') + + def testLoadContentsAsync(self): + self._f.write("testing load_contents_async") + self._f.seek(0) + + def callback(contents, result): + try: + cont, leng, etag = contents.load_contents_finish(result) + self.assertEqual(cont, "testing load_contents_async") + self.assertEqual(leng, 27) + self.assertNotEqual(etag, '') + finally: + loop.quit() + + canc = gio.Cancellable() + self.file.load_contents_async(callback, cancellable=canc) + + loop = glib.MainLoop() + loop.run() + + def testQueryInfoAsync(self): + def callback(file, result): + try: + info = file.query_info_finish(result) + self.failUnless(isinstance(info, gio.FileInfo)) + self.failUnless(info.get_name(), "file.txt") + finally: + loop.quit() + + self.file.query_info_async("standard", callback) + + loop = glib.MainLoop() + loop.run() + + def testMountMountable(self): + gfile = gio.File('localtest:') + def unmount_done(mount, result): + try: + retval = mount.unmount_finish(result) + self.failUnless(retval) + finally: + loop.quit() + + def mount_enclosing_volume_done(gfile, result): + try: + try: + retval = gfile.mount_enclosing_volume_finish(result) + except gio.Error, e: + # If we run the tests too fast + if e.code == gio.ERROR_ALREADY_MOUNTED: + print ('WARNING: testfile is already mounted, ' + 'skipping test') + loop.quit() + return + raise + self.failUnless(retval) + finally: + try: + mount = gfile.find_enclosing_mount() + except gio.Error: + loop.quit() + return + mount.unmount(unmount_done) + + mount_operation = gio.MountOperation() + gfile.mount_enclosing_volume(mount_operation, + mount_enclosing_volume_done) + + loop = glib.MainLoop() + loop.run() + + def testCopy(self): + if os.path.exists('copy.txt'): + os.unlink("copy.txt") + + source = gio.File('file.txt') + destination = gio.File('copy.txt') + try: + retval = source.copy(destination) + self.failUnless(retval) + + self.failUnless(os.path.exists('copy.txt')) + self.assertEqual(open('file.txt').read(), + open('copy.txt').read()) + finally: + os.unlink("copy.txt") + + self.called = False + def callback(current, total): + self.called = True + source = gio.File('file.txt') + destination = gio.File('copy.txt') + try: + retval = source.copy(destination, callback) + self.failUnless(retval) + + self.failUnless(os.path.exists('copy.txt')) + self.assertEqual(open('file.txt').read(), + open('copy.txt').read()) + self.failUnless(self.called) + finally: + os.unlink("copy.txt") + + def test_copy_async(self): + if os.path.exists('copy.txt'): + os.unlink("copy.txt") + + source = gio.File('file.txt') + destination = gio.File('copy.txt') + + def copied(source_, result): + try: + self.assert_(source_ is source) + self.failUnless(source_.copy_finish(result)) + finally: + loop.quit() + + def progress(current, total): + self.assert_(isinstance(current, long)) + self.assert_(isinstance(total, long)) + self.assert_(0 <= current <= total) + + try: + loop = glib.MainLoop() + source.copy_async(destination, copied, progress_callback = progress) + loop.run() + + self.failUnless(os.path.exists('copy.txt')) + self.assertEqual(open('file.txt').read(), + open('copy.txt').read()) + finally: + os.unlink("copy.txt") + + # See bug 546591. + def test_copy_progress(self): + source = gio.File('file.txt') + destination = gio.File('copy.txt') + + def progress(current, total): + self.assert_(isinstance(current, long)) + self.assert_(isinstance(total, long)) + self.assert_(0 <= current <= total) + + try: + retval = source.copy(destination, + flags=gio.FILE_COPY_OVERWRITE, + progress_callback=progress) + self.failUnless(retval) + + self.failUnless(os.path.exists('copy.txt')) + self.assertEqual(open('file.txt').read(), + open('copy.txt').read()) + finally: + os.unlink("copy.txt") + + def testMove(self): + if os.path.exists('move.txt'): + os.unlink("move.txt") + + source = gio.File('file.txt') + destination = gio.File('move.txt') + retval = source.move(destination) + self.failUnless(retval) + + self.failIf(os.path.exists('file.txt')) + self.failUnless(os.path.exists('move.txt')) + + self.called = False + def callback(current, total): + self.called = True + source = gio.File('move.txt') + destination = gio.File('move-2.txt') + try: + retval = source.move(destination, callback) + self.failUnless(retval) + + self.failIf(os.path.exists('move.txt')) + self.failUnless(os.path.exists('move-2.txt')) + self.failUnless(self.called) + finally: + os.unlink("move-2.txt") + + def testInfoList(self): + infolist = self.file.query_settable_attributes() + for info in infolist: + if info.name == "time::modified": + self.assertEqual(info.type, gio.FILE_ATTRIBUTE_TYPE_UINT64) + self.assertEqual(info.name, "time::modified") + self.assertEqual(info.flags, + gio.FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED | + gio.FILE_ATTRIBUTE_INFO_COPY_WITH_FILE) + + def testQueryWritableNamespaces(self): + infolist = self.file.query_writable_namespaces() + for info in infolist: + if info.name == "xattr": + self.assertEqual(info.type, gio.FILE_ATTRIBUTE_TYPE_STRING) + + def testSetAttribute(self): + self._f.write("testing attributes") + self._f.seek(0) + infolist = self.file.query_settable_attributes() + + self.assertNotEqual(len(infolist), 0) + + for info in infolist: + if info.name == "time::modified-usec": + ret = self.file.set_attribute("time::modified-usec", + gio.FILE_ATTRIBUTE_TYPE_UINT32, + 10, gio.FILE_QUERY_INFO_NONE) + self.assertEqual(ret, True) + + def testSetAttributesAsync(self): + def callback(gfile, result): + try: + info = gfile.set_attributes_finish(result) + usec = info.get_attribute_uint32("time::modified-usec") + self.assertEqual(usec, 10) + finally: + loop.quit() + + info = gio.FileInfo() + info.set_attribute_uint32("time::modified-usec", 10) + + canc = gio.Cancellable() + self.file.set_attributes_async(info, callback) + + loop = glib.MainLoop() + loop.run() + + def testReplaceContents(self): + self.file.replace_contents("testing replace_contents") + cont, leng, etag = self.file.load_contents() + self.assertEqual(cont, "testing replace_contents") + + caught = False + try: + self.file.replace_contents("this won't work", etag="wrong") + except gio.Error, e: + self.assertEqual(e.code, gio.ERROR_WRONG_ETAG) + caught = True + self.failUnless(caught) + + self.file.replace_contents("testing replace_contents again", etag=etag) + cont, leng, etag = self.file.load_contents() + self.assertEqual(cont, "testing replace_contents again") + + self.file.replace_contents("testing replace_contents yet again", etag=None) + cont, leng, etag = self.file.load_contents() + self.assertEqual(cont, "testing replace_contents yet again") + + def testReplaceContentsAsync(self): + + def callback(contents, result): + try: + newetag = contents.replace_contents_finish(result) + cont, leng, etag = self.file.load_contents() + self.assertEqual(cont, "testing replace_contents_async") + self.assertEqual(leng, 30) + self.assertEqual(etag, newetag) + self.assertNotEqual(newetag, '') + finally: + loop.quit() + + canc = gio.Cancellable() + self.file.replace_contents_async("testing replace_contents_async", callback, cancellable=canc) + + loop = glib.MainLoop() + loop.run() + + def test_eq(self): + self.assertEqual(gio.File('foo'), + gio.File('foo')) + self.assertNotEqual(gio.File('foo'), + gio.File('bar')) + + def test_hash(self): + self.assertEquals(hash(gio.File('foo')), + hash(gio.File('foo'))) + + def testSetDisplayNameAsync(self): + def callback(gfile, result): + try: + new_gfile = gfile.set_display_name_finish(result) + new_name = new_gfile.get_basename() + self.assertEqual(new_name, "new.txt") + deleted = new_gfile.delete() + self.assertEqual(deleted, True) + finally: + loop.quit() + + canc = gio.Cancellable() + self.file.set_display_name_async("new.txt", callback, cancellable=canc) + + loop = glib.MainLoop() + loop.run() + +class TestGFileEnumerator(unittest.TestCase): + def setUp(self): + self.file = gio.File(".") + + def testEnumerateChildren(self): + enumerator = self.file.enumerate_children( + "standard::*", gio.FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) + for file_info in enumerator: + if file_info.get_name() == 'test_gio.py': + break + else: + raise AssertionError + + def testEnumerateChildrenAsync(self): + def callback(gfile, result): + try: + for file_info in gfile.enumerate_children_finish(result): + if file_info.get_name() == 'test_gio.py': + break + else: + raise AssertionError + finally: + loop.quit() + + self.file.enumerate_children_async( + "standard::*", callback) + loop = glib.MainLoop() + loop.run() + + def testNextFilesAsync(self): + def callback(enumerator, result): + try: + for file_info in enumerator.next_files_finish(result): + if file_info.get_name() == 'test_gio.py': + break + else: + raise AssertionError + finally: + loop.quit() + + enumerator = self.file.enumerate_children( + "standard::*", gio.FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) + enumerator.next_files_async(1000, callback) + loop = glib.MainLoop() + loop.run() + + def testCloseFilesAsync(self): + def callback(enumerator, result): + try: + enumerator.close_finish(result) + finally: + loop.quit() + + enumerator = self.file.enumerate_children( + "standard::*", gio.FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) + + enumerator.close_async(callback) + + loop = glib.MainLoop() + loop.run() + + +class TestInputStream(unittest.TestCase): + def setUp(self): + self._f = open("inputstream.txt", "w+") + self._f.write("testing") + self._f.seek(0) + self.stream = gio.unix.InputStream(self._f.fileno(), False) + + def tearDown(self): + self._f.close() + os.unlink("inputstream.txt") + + def testRead(self): + self.assertEquals(self.stream.read(), "testing") + + self.stream = gio.MemoryInputStream() + self.assertEquals(self.stream.read(), '') + + self.stream = gio.MemoryInputStream() + some_data = open("test_gio.py", "rb").read() + self.stream.add_data(some_data) + self.assertEquals(self.stream.read(), some_data) + + stream = gio.MemoryInputStream() + stream.add_data(some_data) + self.assertEquals(self._read_in_loop(stream, + lambda: stream.read(50), + 50), + some_data) + + def testSkip(self): + self.stream.skip(2) + res = self.stream.read() + self.assertEqual(res, "sting") + + def testSkipAsync(self): + def callback(stream, result): + try: + size = stream.skip_finish(result) + self.assertEqual(size, 2) + res = stream.read() + self.assertEqual(res, "sting") + finally: + loop.quit() + + self.stream.skip_async(2, callback) + + loop = glib.MainLoop() + loop.run() + + def test_read_part(self): + self.assertEquals(self._read_in_loop(self.stream, + lambda: self.stream.read_part()), + 'testing') + + stream = gio.MemoryInputStream() + some_data = open('test_gio.py', 'rb').read() + stream.add_data(some_data) + self.assertEquals(self._read_in_loop(stream, + lambda: stream.read_part(50), + 50), + some_data) + + def _read_in_loop(self, stream, reader, size_limit=0): + read_data = '' + while True: + read_part = reader() + if read_part: + read_data += read_part + if size_limit > 0: + self.assert_(len(read_part) <= size_limit, + '%d <= %d' % (len(read_part), size_limit)) + else: + return read_data + + def testReadAsync(self): + def callback(stream, result): + self.assertEquals(result.get_op_res_gssize(), 7) + try: + data = stream.read_finish(result) + self.assertEquals(data, "testing") + stream.close() + finally: + loop.quit() + + self.stream.read_async(7, callback) + + loop = glib.MainLoop() + loop.run() + + def testReadAsyncError(self): + self.count = 0 + def callback(stream, result): + try: + self.count += 1 + if self.count == 1: + return + self.assertRaises(gio.Error, stream.read_finish, result) + finally: + loop.quit() + + self.stream.read_async(10240, callback) + self.stream.read_async(10240, callback) + + loop = glib.MainLoop() + loop.run() + + self.assertEquals(self.count, 2) + + self.assertRaises(TypeError, self.stream.read_async) + self.assertRaises(TypeError, self.stream.read_async, "foo") + self.assertRaises(TypeError, self.stream.read_async, 1024, "bar") + self.assertRaises(TypeError, self.stream.read_async, 1024, + priority="bar") + self.assertRaises(TypeError, self.stream.read_async, 1024, + priority="bar") + self.assertRaises(TypeError, self.stream.read_async, 1024, + priority=1, cancellable="bar") + self.assertRaises(TypeError, self.stream.read_async, 1024, 1, "bar") + + + # FIXME: this makes 'make check' freeze + def _testCloseAsync(self): + def callback(stream, result): + try: + self.failUnless(stream.close_finish(result)) + finally: + loop.quit() + + self.stream.close_async(callback) + + loop = glib.MainLoop() + loop.run() + + +class TestDataInputStream(unittest.TestCase): + def setUp(self): + self.base_stream = gio.MemoryInputStream() + self.data_stream = gio.DataInputStream(self.base_stream) + + def test_read_line(self): + self.base_stream.add_data('foo\nbar\n\nbaz') + self.assertEquals('foo', self.data_stream.read_line()) + self.assertEquals('bar', self.data_stream.read_line()) + self.assertEquals('', self.data_stream.read_line()) + self.assertEquals('baz', self.data_stream.read_line()) + + def test_read_line_async(self): + def do_read_line_async(): + loop = glib.MainLoop() + line = [] + + def callback(stream, result): + try: + line.append(stream.read_line_finish(result)) + finally: + loop.quit() + + self.data_stream.read_line_async(callback) + loop.run() + return line[0] + + self.base_stream.add_data('foo\nbar\n\nbaz') + self.assertEquals('foo', do_read_line_async()) + self.assertEquals('bar', do_read_line_async()) + self.assertEquals('', do_read_line_async()) + self.assertEquals('baz', do_read_line_async()) + + def test_read_until(self): + self.base_stream.add_data('sentence.end of line\nthe rest') + self.assertEquals('sentence', self.data_stream.read_until('.!?')) + self.assertEquals('end of line', self.data_stream.read_until('\n\r')) + self.assertEquals('the rest', self.data_stream.read_until('#$%^&')) + + def test_read_until_async(self): + def do_read_until_async(stop_chars): + loop = glib.MainLoop() + data = [] + + def callback(stream, result): + try: + data.append(stream.read_until_finish(result)) + finally: + loop.quit() + + self.data_stream.read_until_async(stop_chars, callback) + loop.run() + return data[0] + + # Note the weird difference between synchronous and + # asynchronous version. See bug #584284. + self.base_stream.add_data('sentence.end of line\nthe rest') + self.assertEquals('sentence', do_read_until_async('.!?')) + self.assertEquals('.end of line', do_read_until_async('\n\r')) + self.assertEquals('\nthe rest', do_read_until_async('#$%^&')) + + +class TestMemoryInputStream(unittest.TestCase): + def setUp(self): + self.stream = gio.MemoryInputStream() + + def test_add_data(self): + self.stream.add_data('foobar') + self.assertEquals('foobar', self.stream.read()) + + self.stream.add_data('ham ') + self.stream.add_data(None) + self.stream.add_data('spam') + self.assertEquals('ham spam', self.stream.read()) + + def test_new_from_data(self): + stream = gio.memory_input_stream_new_from_data('spam') + self.assertEquals('spam', stream.read()) + + +class TestOutputStream(unittest.TestCase): + def setUp(self): + self._f = open("outputstream.txt", "w") + self.stream = gio.unix.OutputStream(self._f.fileno(), False) + + def tearDown(self): + self._f.close() + os.unlink("outputstream.txt") + + def testWrite(self): + self.stream.write("testing") + self.stream.close() + self.failUnless(os.path.exists("outputstream.txt")) + self.assertEquals(open("outputstream.txt").read(), "testing") + + def test_write_part(self): + stream = gio.MemoryOutputStream() + some_data = open('test_gio.py', 'rb').read() + buffer = some_data + + # In fact this makes only one looping (memory stream is fast, + # write_part behaves just like write), but let's still be + # complete. + while buffer: + written = stream.write_part(buffer) + if written == len(buffer): + break + else: + buffer = buffer[written:] + + self.assertEquals(stream.get_contents(), some_data) + + def testWriteAsync(self): + def callback(stream, result): + self.assertEquals(result.get_op_res_gssize(), 7) + try: + self.assertEquals(stream.write_finish(result), 7) + self.failUnless(os.path.exists("outputstream.txt")) + self.assertEquals(open("outputstream.txt").read(), "testing") + finally: + loop.quit() + + self.stream.write_async("testing", callback) + + loop = glib.MainLoop() + loop.run() + + def testWriteAsyncError(self): + def callback(stream, result): + self.assertEquals(result.get_op_res_gssize(), 0) + try: + self.assertRaises(gio.Error, stream.write_finish, result) + finally: + loop.quit() + + self.stream.close() + self.stream.write_async("testing", callback) + + loop = glib.MainLoop() + loop.run() + + self.assertRaises(TypeError, self.stream.write_async) + self.assertRaises(TypeError, self.stream.write_async, 1138) + self.assertRaises(TypeError, self.stream.write_async, "foo", "bar") + self.assertRaises(TypeError, self.stream.write_async, "foo", + priority="bar") + self.assertRaises(TypeError, self.stream.write_async, "foo", + priority="bar") + self.assertRaises(TypeError, self.stream.write_async, "foo", + priority=1, cancellable="bar") + self.assertRaises(TypeError, self.stream.write_async, "foo", 1, "bar") + + # FIXME: this makes 'make check' freeze + def _testCloseAsync(self): + def callback(stream, result): + try: + self.failUnless(stream.close_finish(result)) + finally: + loop.quit() + + self.stream.close_async(callback) + + loop = glib.MainLoop() + loop.run() + + def testFlushAsync(self): + def callback(stream, result): + try: + self.failUnless(stream.flush_finish(result)) + finally: + loop.quit() + + self.stream.flush_async(callback) + + loop = glib.MainLoop() + loop.run() + + def testSpliceAsync(self): + _f = open("stream.txt", "w+") + _f.write("testing") + _f.seek(0) + instream = gio.unix.InputStream(_f.fileno(), False) + + def callback(stream, result): + try: + size = stream.splice_finish(result) + self.assertEqual(size, 7) + + finally: + os.unlink("stream.txt") + loop.quit() + + self.stream.splice_async(instream, callback) + + loop = glib.MainLoop() + loop.run() + +class TestMemoryOutputStream(unittest.TestCase): + def setUp(self): + self.stream = gio.MemoryOutputStream() + + def test_get_contents(self): + self.stream.write('foobar') + self.assertEquals('foobar', self.stream.get_contents()) + + self.stream.write('baz') + self.assertEquals('foobarbaz', self.stream.get_contents()) + + +class TestVolumeMonitor(unittest.TestCase): + def setUp(self): + self.monitor = gio.volume_monitor_get() + + def testGetConnectedDrives(self): + drives = self.monitor.get_connected_drives() + self.failUnless(isinstance(drives, list)) + + def testGetVolumes(self): + volumes = self.monitor.get_volumes() + self.failUnless(isinstance(volumes, list)) + + def testGetMounts(self): + mounts = self.monitor.get_mounts() + self.failUnless(isinstance(mounts, list)) + if not mounts: + return + + self.failUnless(isinstance(mounts[0], gio.Mount)) + # Bug 538601 + icon = mounts[0].get_icon() + if not icon: + return + self.failUnless(isinstance(icon, gio.Icon)) + + +class TestContentTypeGuess(unittest.TestCase): + def testFromName(self): + mime_type = gio.content_type_guess('diagram.svg') + self.assertEquals('image/svg+xml', mime_type) + + def testFromContents(self): + mime_type = gio.content_type_guess(data='<html></html>') + self.assertEquals('text/html', mime_type) + + def testFromContentsUncertain(self): + mime_type, result_uncertain = gio.content_type_guess( + data='<html></html>', want_uncertain=True) + self.assertEquals('text/html', mime_type) + self.assertEquals(bool, type(result_uncertain)) + + +class TestFileInfo(unittest.TestCase): + def setUp(self): + self.fileinfo = gio.File("test_gio.py").query_info("*") + + def testListAttributes(self): + attributes = self.fileinfo.list_attributes("standard") + self.failUnless(attributes) + self.failUnless('standard::name' in attributes) + + def testGetModificationTime(self): + mtime = self.fileinfo.get_modification_time() + self.assertEqual(type(mtime), float) + + def testSetModificationTime(self): + self.fileinfo.set_modification_time(1000) + mtime = self.fileinfo.get_modification_time() + self.assertEqual(mtime, 1000) + + +class TestAppInfo(unittest.TestCase): + def setUp(self): + self.appinfo = gio.AppInfo("does-not-exist") + + def testSimple(self): + self.assertEquals(self.appinfo.get_description(), + "Custom definition for does-not-exist") + + def test_eq(self): + info1 = gio.app_info_get_all()[0] + info2 = info1.dup() + self.assert_(info1 is not info2) + self.assertEquals(info1, info2) + + self.assertNotEqual(gio.app_info_get_all()[0], gio.app_info_get_all()[1]) + +class TestVfs(unittest.TestCase): + def setUp(self): + self.vfs = gio.vfs_get_default() + + def testGetSupportedURISchemes(self): + result = self.vfs.get_supported_uri_schemes() + self.failUnless(type(result), []) + +class TestVolume(unittest.TestCase): + def setUp(self): + self.monitor = gio.volume_monitor_get() + + def testVolumeEnumerate(self): + volumes = self.monitor.get_volumes() + self.failUnless(isinstance(volumes, list)) + for v in volumes: + if v is not None: + ids = v.enumerate_identifiers() + self.failUnless(isinstance(ids, list)) + for id in ids: + if id is not None: + self.failUnless(isinstance(id, str)) + +class TestFileInputStream(unittest.TestCase): + def setUp(self): + self._f = open("file.txt", "w+") + self._f.write("testing") + self._f.seek(0) + self.file = gio.File("file.txt") + + def tearDown(self): + self._f.close() + if os.path.exists('file.txt'): + os.unlink("file.txt") + + def testQueryInfoAsync(self): + def callback(stream, result): + try: + info = stream.query_info_finish(result) + self.failUnless(isinstance(info, gio.FileInfo)) + self.failUnless(info.get_attribute_uint64("standard::size"), 7) + finally: + loop.quit() + + inputstream = self.file.read() + inputstream.query_info_async("standard", callback) + + loop = glib.MainLoop() + loop.run() + +class TestFileOutputStream(unittest.TestCase): + def setUp(self): + self._f = open("file.txt", "w+") + self._f.write("testing") + self._f.seek(0) + self.file = gio.File("file.txt") + + def tearDown(self): + self._f.close() + if os.path.exists('file.txt'): + os.unlink("file.txt") + + def testQueryInfoAsync(self): + def callback(stream, result): + try: + info = stream.query_info_finish(result) + self.failUnless(isinstance(info, gio.FileInfo)) + self.failUnless(info.get_attribute_uint64("standard::size"), 7) + finally: + loop.quit() + + outputstream = self.file.append_to() + outputstream.query_info_async("standard", callback) + + loop = glib.MainLoop() + loop.run() + +class TestBufferedInputStream(unittest.TestCase): + def setUp(self): + self._f = open("buffer.txt", "w+") + self._f.write("testing") + self._f.seek(0) + stream = gio.unix.InputStream(self._f.fileno(), False) + self.buffered = gio.BufferedInputStream(stream) + + def tearDown(self): + self._f.close() + os.unlink("buffer.txt") + + def test_fill_async(self): + def callback(stream, result): + try: + size = stream.fill_finish(result) + self.failUnlessEqual(size, 4) + finally: + loop.quit() + + self.buffered.fill_async(4, callback) + + loop = glib.MainLoop() + loop.run() + +class TestIOStream(unittest.TestCase): + def setUp(self): + self.file = gio.File("file.txt") + self.iofile = self.file.create_readwrite(gio.FILE_CREATE_NONE) + + def tearDown(self): + if os.path.exists('file.txt'): + os.unlink("file.txt") + + def testIOStreamCloseAsync(self): + def callback(stream, result): + try: + self.failUnless(stream.close_finish(result)) + finally: + loop.quit() + + self.iofile.close_async(callback) + + loop = glib.MainLoop() + loop.run() + + + def testQueryInfoAsync(self): + def callback(stream, result): + try: + info = stream.query_info_finish(result) + self.failUnless(isinstance(info, gio.FileInfo)) + self.failUnless(info.get_attribute_uint64("standard::size"), 7) + finally: + loop.quit() + + ostream = self.iofile.get_output_stream() + ostream.write("testing") + + self.iofile.query_info_async("standard", callback) + + loop = glib.MainLoop() + loop.run() diff --git a/tests/test_gobject.py b/tests/test_gobject.py new file mode 100644 index 0000000..d91f3ad --- /dev/null +++ b/tests/test_gobject.py @@ -0,0 +1,29 @@ +# -*- Mode: Python -*- + +import unittest + +from common import gobject, testhelper + + +class TestGObjectAPI(unittest.TestCase): + def testGObjectModule(self): + obj = gobject.GObject() + self.assertEquals(obj.__module__, + 'gobject._gobject') + self.assertEquals(obj.__grefcount__, 1) + + +class TestFloating(unittest.TestCase): + def testFloatingWithSinkFunc(self): + obj = testhelper.FloatingWithSinkFunc() + self.assertEquals(obj.__grefcount__, 1) + + obj = gobject.new(testhelper.FloatingWithSinkFunc) + self.assertEquals(obj.__grefcount__, 1) + + def testFloatingWithoutSinkFunc(self): + obj = testhelper.FloatingWithoutSinkFunc() + self.assertEquals(obj.__grefcount__, 1) + + obj = gobject.new(testhelper.FloatingWithoutSinkFunc) + self.assertEquals(obj.__grefcount__, 1) diff --git a/tests/test_interface.py b/tests/test_interface.py new file mode 100644 index 0000000..d959791 --- /dev/null +++ b/tests/test_interface.py @@ -0,0 +1,45 @@ +import unittest + +from common import gobject, testhelper + +GUnknown = gobject.type_from_name("TestUnknown") +Unknown = GUnknown.pytype + + +class MyUnknown(Unknown, testhelper.Interface): + some_property = gobject.property(type=str) + + def __init__(self): + Unknown.__init__(self) + self.called = False + + def do_iface_method(self): + self.called = True + Unknown.do_iface_method(self) +gobject.type_register(MyUnknown) + + +class MyObject(gobject.GObject, testhelper.Interface): + some_property = gobject.property(type=str) + + def __init__(self): + gobject.GObject.__init__(self) + self.called = False + + def do_iface_method(self): + self.called = True +gobject.type_register(MyObject) + + +class TestIfaceImpl(unittest.TestCase): + + def testReImplementInterface(self): + m = MyUnknown() + m.iface_method() + self.assertEqual(m.called, True) + + def testImplementInterface(self): + m = MyObject() + m.iface_method() + self.assertEqual(m.called, True) + diff --git a/tests/test_mainloop.py b/tests/test_mainloop.py new file mode 100644 index 0000000..95e5f78 --- /dev/null +++ b/tests/test_mainloop.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +import exceptions +import os +import sys +import select +import unittest + +from common import glib + +class TestMainLoop(unittest.TestCase): + def testExceptionHandling(self): + pipe_r, pipe_w = os.pipe() + + pid = os.fork() + if pid == 0: + os.close(pipe_w) + select.select([pipe_r], [], []) + os.close(pipe_r) + os._exit(1) + + def child_died(pid, status, loop): + loop.quit() + raise Exception("deadbabe") + + loop = glib.MainLoop() + glib.child_watch_add(pid, child_died, loop) + + os.close(pipe_r) + os.write(pipe_w, "Y") + os.close(pipe_w) + + def excepthook(type, value, traceback): + assert type is exceptions.Exception + assert value.args[0] == "deadbabe" + sys.excepthook = excepthook + + got_exception = False + try: + loop.run() + except: + got_exception = True + + # + # 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 + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_properties.py b/tests/test_properties.py new file mode 100644 index 0000000..ccfcb34 --- /dev/null +++ b/tests/test_properties.py @@ -0,0 +1,376 @@ + +import struct +import unittest + +import gobject +from gobject import GObject, GType, GEnum, new, PARAM_READWRITE, \ + PARAM_CONSTRUCT, PARAM_READABLE, PARAM_WRITABLE, PARAM_CONSTRUCT_ONLY +from gobject.constants import \ + TYPE_INT, TYPE_UINT, TYPE_LONG, \ + TYPE_ULONG, TYPE_INT64, TYPE_UINT64 +from gobject.constants import \ + G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, \ + G_MAXULONG + +class PropertyObject(GObject): + normal = gobject.property(type=str) + construct = gobject.property( + type=str, + flags=PARAM_READWRITE|PARAM_CONSTRUCT, default='default') + construct_only = gobject.property( + type=str, + flags=PARAM_READWRITE|PARAM_CONSTRUCT_ONLY) + uint64 = gobject.property( + type=TYPE_UINT64, flags=PARAM_READWRITE|PARAM_CONSTRUCT) + +class TestProperties(unittest.TestCase): + def testGetSet(self): + obj = PropertyObject() + obj.props.normal = "value" + self.assertEqual(obj.props.normal, "value") + + def testListWithInstance(self): + obj = PropertyObject() + self.failUnless(hasattr(obj.props, "normal")) + + def testListWithoutInstance(self): + self.failUnless(hasattr(PropertyObject.props, "normal")) + + def testSetNoInstance(self): + def set(obj): + obj.props.normal = "foobar" + + self.assertRaises(TypeError, set, PropertyObject) + + def testIterator(self): + for obj in (PropertyObject.props, PropertyObject().props): + for pspec in obj: + gtype = GType(pspec) + self.assertEqual(gtype.parent.name, 'GParam') + self.failUnless(pspec.name in ['normal', + 'construct', + 'construct-only', + 'uint64']) + self.assertEqual(len(obj), 4) + + def testNormal(self): + obj = new(PropertyObject, normal="123") + self.assertEqual(obj.props.normal, "123") + obj.set_property('normal', '456') + self.assertEqual(obj.props.normal, "456") + obj.props.normal = '789' + self.assertEqual(obj.props.normal, "789") + + def testConstruct(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 testConstructOnly(self): + obj = new(PropertyObject, construct_only="123") + self.assertEqual(obj.props.construct_only, "123") + self.assertRaises(TypeError, + setattr, obj.props, 'construct_only', '456') + self.assertRaises(TypeError, + obj.set_property, 'construct-only', '456') + + def testUint64(self): + obj = new(PropertyObject) + self.assertEqual(obj.props.uint64, 0) + obj.props.uint64 = 1L + self.assertEqual(obj.props.uint64, 1L) + obj.props.uint64 = 1 + self.assertEqual(obj.props.uint64, 1L) + + self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", -1L) + self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", -1) + + def testUInt64DefaultValue(self): + try: + class TimeControl(GObject): + __gproperties__ = { + 'time': (TYPE_UINT64, 'Time', 'Time', + 0L, (1<<64) - 1, 0L, + PARAM_READABLE) + } + except OverflowError, ex: + self.fail(str(ex)) + + def testRange(self): + # kiwi code + def max(c): + return 2 ** ((8 * struct.calcsize(c)) - 1) - 1 + def umax(c): + return 2 ** (8 * struct.calcsize(c)) - 1 + + maxint = max('i') + minint = -maxint - 1 + maxuint = umax('I') + maxlong = max('l') + minlong = -maxlong - 1 + maxulong = umax('L') + maxint64 = max('q') + 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)) + + def build_gproperties(types): + d = {} + 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): + __gproperties__ = build_gproperties(types) + + def __init__(self): + self.values = {} + GObject.__init__(self) + + def do_set_property(self, pspec, value): + self.values[pspec.name] = value + + def do_get_property(self, pspec): + return self.values.get(pspec.name, pspec.default_value) + + self.assertEqual(RangeCheck.props.int.minimum, minint) + self.assertEqual(RangeCheck.props.int.maximum, maxint) + self.assertEqual(RangeCheck.props.uint.minimum, 0) + self.assertEqual(RangeCheck.props.uint.maximum, maxuint) + self.assertEqual(RangeCheck.props.long.minimum, minlong) + self.assertEqual(RangeCheck.props.long.maximum, maxlong) + self.assertEqual(RangeCheck.props.ulong.minimum, 0) + self.assertEqual(RangeCheck.props.ulong.maximum, maxulong) + self.assertEqual(RangeCheck.props.int64.minimum, minint64) + self.assertEqual(RangeCheck.props.int64.maximum, maxint64) + self.assertEqual(RangeCheck.props.uint64.minimum, 0) + self.assertEqual(RangeCheck.props.uint64.maximum, maxuint64) + + obj = RangeCheck() + for key, (gtype, min, max) in types.items(): + self.assertEqual(obj.get_property(key), + getattr(RangeCheck.props, key).default_value) + + obj.set_property(key, min) + self.assertEqual(obj.get_property(key), min) + + obj.set_property(key, max) + self.assertEqual(obj.get_property(key), max) + + + def testMulti(self): + obj = PropertyObject() + obj.set_properties(normal="foo", + uint64=7) + normal, uint64 = obj.get_properties("normal", "uint64") + self.assertEqual(normal, "foo") + self.assertEqual(uint64, 7) + +class TestProperty(unittest.TestCase): + def testSimple(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')) + + o = C() + self.assertEqual(o.str, '') + o.str = 'str' + self.assertEqual(o.str, 'str') + + self.assertEqual(o.int, 0) + o.int = 1138 + self.assertEqual(o.int, 1138) + + self.assertEqual(o.float, 0.0) + o.float = 3.14 + self.assertEqual(o.float, 3.14) + + self.assertEqual(o.long, 0L) + o.long = 100L + self.assertEqual(o.long, 100L) + + def testCustomGetter(self): + class C(gobject.GObject): + def get_prop(self): + return 'value' + prop = gobject.property(getter=get_prop) + + o = C() + self.assertEqual(o.prop, 'value') + self.assertRaises(TypeError, setattr, o, 'prop', 'xxx') + + def testCustomSetter(self): + class C(gobject.GObject): + def set_prop(self, value): + self._value = value + prop = gobject.property(setter=set_prop) + + def __init__(self): + self._value = None + gobject.GObject.__init__(self) + + o = C() + self.assertEquals(o._value, None) + o.prop = 'bar' + self.assertEquals(o._value, 'bar') + self.assertRaises(TypeError, getattr, o, 'prop') + + def testErrors(self): + self.assertRaises(TypeError, gobject.property, type='str') + self.assertRaises(TypeError, gobject.property, nick=False) + self.assertRaises(TypeError, gobject.property, blurb=False) + # this never fail while bool is a subclass of int + # >>> bool.__bases__ + # (<type 'int'>,) + # self.assertRaises(TypeError, gobject.property, type=bool, default=0) + self.assertRaises(TypeError, gobject.property, type=bool, default='ciao mamma') + self.assertRaises(TypeError, gobject.property, type=bool) + self.assertRaises(TypeError, gobject.property, type=GEnum) + self.assertRaises(TypeError, gobject.property, type=GEnum, default=0) + 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 testNameWithUnderscore(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 = [ + (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), + ] + + 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)) + 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, + maximum=max) + + # Higher than maximum + self.assertRaises(TypeError, + gobject.property, type=gtype, minimum=min, + maximum=max+1) + + def testMultipleInstances(self): + class C(gobject.GObject): + prop = gobject.property(type=str, default='default') + + o1 = C() + o2 = C() + self.assertEqual(o1.prop, 'default') + self.assertEqual(o2.prop, 'default') + o1.prop = 'value' + self.assertEqual(o1.prop, 'value') + self.assertEqual(o2.prop, 'default') + + def testObjectProperty(self): + class PropertyObject(GObject): + obj = gobject.property(type=GObject) + + pobj1 = PropertyObject() + obj1_hash = hash(pobj1) + pobj2 = PropertyObject() + + pobj2.obj = pobj1 + del pobj1 + pobj1 = pobj2.obj + self.assertEqual(hash(pobj1), obj1_hash) + + def testPropertySubclass(self): + # test for #470718 + class A(GObject): + prop1 = gobject.property(type=int) + + class B(A): + prop2 = gobject.property(type=int) + + b = B() + b.prop2 = 10 + self.assertEquals(b.prop2, 10) + b.prop1 = 20 + self.assertEquals(b.prop1, 20) + + def testPropertySubclassCustomSetter(self): + # test for #523352 + class A(GObject): + def get_first(self): + return 'first' + first = gobject.property(type=str, getter=get_first) + + class B(A): + def get_second(self): + return 'second' + second = gobject.property(type=str, getter=get_second) + + a = A() + self.assertEquals(a.first, 'first') + self.assertRaises(TypeError, setattr, a, 'first', 'foo') + + b = B() + self.assertEquals(b.first, 'first') + self.assertRaises(TypeError, setattr, b, 'first', 'foo') + self.assertEquals(b.second, 'second') + self.assertRaises(TypeError, setattr, b, 'second', 'foo') + + def testPropertySubclassCustomSetterError(self): + try: + class A(GObject): + def get_first(self): + return 'first' + first = gobject.property(type=str, getter=get_first) + + def do_get_property(self, pspec): + pass + except TypeError: + pass + else: + 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) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_signal.py b/tests/test_signal.py new file mode 100644 index 0000000..96e0731 --- /dev/null +++ b/tests/test_signal.py @@ -0,0 +1,393 @@ +# -*- Mode: Python -*- + +import gc +import unittest +import sys + +from common import gobject, testhelper + +class C(gobject.GObject): + __gsignals__ = { 'my_signal': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_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): + self.assertRaises(TypeError, lambda: gobject.signal_new('test', + None, + 0, + gobject.TYPE_NONE, + (gobject.TYPE_LONG,))) + + +class TestChaining(unittest.TestCase): + def setUp(self): + self.inst = C() + self.inst.connect("my_signal", self.my_signal_handler_cb, 1, 2, 3) + + def my_signal_handler_cb(self, *args): + assert len(args) == 5 + assert isinstance(args[0], C) + assert args[0] == self.inst + + assert isinstance(args[1], int) + assert args[1] == 42 + + assert args[2:] == (1, 2, 3) + + def testChaining(self): + self.inst.emit("my_signal", 42) + assert self.inst.arg == 42 + + def testChaining(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 foo(): + class Foo(gobject.GObject): + __gsignals__ = None + self.assertRaises(TypeError, foo) + gc.collect() + + def testInvalidName(self, *args): + def foo(): + class Foo(gobject.GObject): + __gsignals__ = {'not-exists' : 'override'} + self.assertRaises(TypeError, foo) + gc.collect() + +class TestGPropertyError(unittest.TestCase): + def testInvalidType(self, *args): + def foo(): + class Foo(gobject.GObject): + __gproperties__ = None + self.assertRaises(TypeError, foo) + gc.collect() + + def testInvalidName(self, *args): + def foo(): + class Foo(gobject.GObject): + __gproperties__ = { None: None } + + self.assertRaises(TypeError, foo) + gc.collect() + +class TestList(unittest.TestCase): + def testListObject(self): + self.assertEqual(gobject.signal_list_names(C), ('my-signal',)) + + +def my_accumulator(ihint, return_accu, handler_return, user_data): + """An accumulator that stops emission when the sum of handler + returned values reaches 3""" + assert user_data == "accum data" + if return_accu >= 3: + return False, return_accu + return True, return_accu + handler_return + +class Foo(gobject.GObject): + __gsignals__ = { + 'my-acc-signal': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_INT, + (), my_accumulator, "accum data"), + 'my-other-acc-signal': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, + (), gobject.signal_accumulator_true_handled) + } + +class TestAccumulator(unittest.TestCase): + + def testAccumulator(self): + inst = Foo() + inst.connect("my-acc-signal", lambda obj: 1) + inst.connect("my-acc-signal", 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") + self.assertEqual(retval, 3) + + def testAccumulatorTrueHandled(self): + inst = Foo() + inst.connect("my-other-acc-signal", self._true_handler1) + inst.connect("my-other-acc-signal", 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) + self.__true_val = None + inst.emit("my-other-acc-signal") + self.assertEqual(self.__true_val, 2) + + 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.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ()) } + def __init__(self): + gobject.GObject.__init__(self) + self.status = 0 + + def do_signal(self): + assert self.status == 0 + self.status = 1 + +class F(gobject.GObject): + __gsignals__ = { 'signal': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ()) } + def __init__(self): + gobject.GObject.__init__(self) + self.status = 0 + + def do_signal(self): + self.status += 1 + +class TestEmissionHook(unittest.TestCase): + def testAdd(self): + self.hook = True + e = E() + e.connect('signal', self._callback) + gobject.add_emission_hook(E, "signal", self._emission_hook) + e.emit('signal') + self.assertEqual(e.status, 3) + + def testRemove(self): + self.hook = False + e = E() + e.connect('signal', self._callback) + hook_id = gobject.add_emission_hook(E, "signal", self._emission_hook) + gobject.remove_emission_hook(E, "signal", hook_id) + e.emit('signal') + self.assertEqual(e.status, 3) + + def _emission_hook(self, e): + self.assertEqual(e.status, 1) + e.status = 2 + + def _callback(self, e): + if self.hook: + self.assertEqual(e.status, 2) + else: + self.assertEqual(e.status, 1) + e.status = 3 + + def testCallbackReturnFalse(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) + obj.emit('signal') + obj.emit('signal') + self.assertEqual(obj.status, 3) + + def testCallbackReturnTrue(self): + self.hook = False + obj = F() + def _emission_hook(obj): + obj.status += 1 + return True + hook_id = gobject.add_emission_hook(obj, "signal", _emission_hook) + obj.emit('signal') + obj.emit('signal') + gobject.remove_emission_hook(obj, "signal", hook_id) + self.assertEqual(obj.status, 4) + + def testCallbackReturnTrueButRemove(self): + self.hook = False + obj = F() + def _emission_hook(obj): + obj.status += 1 + return True + hook_id = gobject.add_emission_hook(obj, "signal", _emission_hook) + obj.emit('signal') + gobject.remove_emission_hook(obj, "signal", hook_id) + obj.emit('signal') + self.assertEqual(obj.status, 3) + +class TestClosures(unittest.TestCase): + def setUp(self): + self.count = 0 + + def _callback(self, e): + self.count += 1 + + def testDisconnect(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): + 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): + e = E() + signal_id = e.connect('signal', self._callback) + e.handler_block(signal_id) + e.handler_unblock_by_func(self._callback) + e.emit('signal') + self.assertEqual(self.count, 1) + + def testHandlerBlockMethod(self): + # Filed as #375589 + class A: + def __init__(self): + self.a = 0 + + def callback(self, o): + self.a = 1 + o.handler_block_by_func(self.callback) + + inst = A() + e = E() + e.connect("signal", inst.callback) + e.emit('signal') + self.assertEqual(inst.a, 1) + gc.collect() + + def testGString(self): + class C(gobject.GObject): + __gsignals__ = { 'my_signal': (gobject.SIGNAL_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) + return ''.join([data[2], data[1], data[0]]) + c = C(self) + data = c.emit("my_signal", "\01\00\02") + self.assertEqual(data, "\02\00\01") + +class SigPropClass(gobject.GObject): + __gsignals__ = { 'my_signal': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + (gobject.TYPE_INT,)) } + + __gproperties__ = { + 'foo': (str, None, None, '', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT), + } + + signal_emission_failed = False + + def do_my_signal(self, arg): + self.arg = arg + + def do_set_property(self, pspec, value): + if pspec.name == 'foo': + self._foo = value + else: + raise AttributeError, 'unknown property %s' % pspec.name + try: + self.emit("my-signal", 1) + except TypeError: + self.signal_emission_failed = True + + +class TestSigProp(unittest.TestCase): + def testEmitInPropertySetter(self): + obj = SigPropClass() + self.failIf(obj.signal_emission_failed) + +f = gobject.SIGNAL_RUN_FIRST +l = gobject.SIGNAL_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, )), + ) + +class _TestCMarshaller: + def setUp(self): + self.obj = CM() + testhelper.connectcallbacks(self.obj) + + def testTest1(self): + self.obj.emit("test1") + + def testTest2(self): + self.obj.emit("test2", "string") + + def testTest3(self): + rv = self.obj.emit("test3", 42.0) + self.assertEqual(rv, 20) + + def testTest4(self): + self.obj.emit("test4", True, 10L, 3.14, 1.78, 20, 30L, 31L) + + def testTestReturnFloat(self): + rv = self.obj.emit("test-float", 1.234) + self.failUnless(rv >= 1.233999 and rv <= 1.2400001, rv) + + def testTestReturnDouble(self): + rv = self.obj.emit("test-double", 1.234) + self.assertEqual(rv, 1.234) + + def testTestReturnString(self): + rv = self.obj.emit("test-string", "str") + self.assertEqual(rv, "str") + + def testTestReturnObject(self): + rv = self.obj.emit("test-object", self) + self.assertEqual(rv, self) + +if 'generic-c-marshaller' in gobject.features: + class TestCMarshaller(_TestCMarshaller, unittest.TestCase): + pass +else: + print + print '** WARNING: LIBFFI disabled, not testing' + print + +# Test for 374653 +class TestPyGValue(unittest.TestCase): + def testNoneNULLBoxedConversion(self): + class C(gobject.GObject): + __gsignals__ = dict(my_boxed_signal=( + gobject.SIGNAL_RUN_LAST, + gobject.type_from_name('GStrv'), ())) + + obj = C() + obj.connect('my-boxed-signal', lambda obj: None) + sys.last_type = None + obj.emit('my-boxed-signal') + assert not sys.last_type + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_source.py b/tests/test_source.py new file mode 100644 index 0000000..abe2f69 --- /dev/null +++ b/tests/test_source.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +import unittest + +from common import glib + + +class Idle(glib.Idle): + def __init__(self, loop): + glib.Idle.__init__(self) + self.count = 0 + self.set_callback(self.callback, loop) + + def callback(self, loop): + self.count += 1 + return True + + +class MySource(glib.Source): + def __init__(self): + glib.Source.__init__(self) + + def prepare(self): + return True, 0 + + def check(self): + return True + + def dispatch(self, callback, args): + return callback(*args) + + +class TestSource(unittest.TestCase): + def timeout_callback(self, loop): + loop.quit() + + def my_callback(self, loop): + self.pos += 1 + return True + + def setup_timeout(self, loop): + timeout = glib.Timeout(500) + timeout.set_callback(self.timeout_callback, loop) + timeout.attach() + + def testSources(self): + loop = glib.MainLoop() + + self.setup_timeout(loop) + + idle = Idle(loop) + idle.attach() + + self.pos = 0 + + m = MySource() + m.set_callback(self.my_callback, loop) + m.attach() + + loop.run() + + assert self.pos >= 0 and idle.count >= 0 + + def testSourcePrepare(self): + # this test may not terminate if prepare() is wrapped incorrectly + dispatched = [False] + loop = glib.MainLoop() + + class CustomTimeout(glib.Source): + def prepare(self): + return (False, 10) + + def check(self): + return True + + def dispatch(self, callback, args): + dispatched[0] = True + + loop.quit() + + return False + + source = CustomTimeout() + + source.attach() + source.set_callback(dir) + + loop.run() + + assert dispatched[0] + + +class TestTimeout(unittest.TestCase): + def test504337(self): + timeout_source = glib.Timeout(20) + idle_source = glib.Idle() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_subprocess.py b/tests/test_subprocess.py new file mode 100644 index 0000000..1522edb --- /dev/null +++ b/tests/test_subprocess.py @@ -0,0 +1,27 @@ +# -*- Mode: Python -*- + +import sys +import unittest + +from common import glib + + +class TestProcess(unittest.TestCase): + + def _child_watch_cb(self, pid, condition, data): + self.data = data + self.loop.quit() + + def testChildWatch(self): + self.data = 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) + pid.close() + glib.child_watch_add(pid, self._child_watch_cb, 12345) + self.loop.run() + self.assertEqual(self.data, 12345) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_unknown.py b/tests/test_unknown.py new file mode 100644 index 0000000..d65bb89 --- /dev/null +++ b/tests/test_unknown.py @@ -0,0 +1,15 @@ + +import unittest + +from common import gobject, testhelper + +TestInterface = gobject.GType.from_name('TestInterface') + + +class TestUnknown(unittest.TestCase): + def testFoo(self): + obj = testhelper.get_unknown() + TestUnknownGType = gobject.GType.from_name('TestUnknown') + TestUnknown = gobject.new(TestUnknownGType).__class__ + assert isinstance(obj, testhelper.Interface) + assert isinstance(obj, TestUnknown) diff --git a/tests/testhelpermodule.c b/tests/testhelpermodule.c new file mode 100644 index 0000000..21679bc --- /dev/null +++ b/tests/testhelpermodule.c @@ -0,0 +1,679 @@ +#include "pygobject.h" +#include <gobject/gmarshal.h> + +#include "test-thread.h" +#include "test-unknown.h" +#include "test-floating.h" + +static PyTypeObject *_PyGObject_Type; +#define PyGObject_Type (*_PyGObject_Type) + +static PyObject * _wrap_TestInterface__do_iface_method(PyObject *cls, + PyObject *args, + PyObject *kwargs); + +GType +test_type_get_type(void) +{ + static GType gtype = 0; + GType parent_type; + + if (gtype == 0) + { + GTypeInfo *type_info; + GTypeQuery query; + + parent_type = g_type_from_name("PyGObject"); + if (parent_type == 0) + g_error("could not get PyGObject from testmodule"); + + type_info = (GTypeInfo *)g_new0(GTypeInfo, 1); + + g_type_query(parent_type, &query); + type_info->class_size = query.class_size; + type_info->instance_size = query.instance_size; + + gtype = g_type_register_static(parent_type, + "TestType", type_info, 0); + if (!gtype) + g_error("Could not register TestType"); + } + + return gtype; +} + +#define TYPE_TEST (test_type_get_type()) + +static PyObject * +_wrap_get_test_thread (PyObject * self) +{ + GObject *obj; + + test_thread_get_type(); + g_assert (g_type_is_a (TEST_TYPE_THREAD, G_TYPE_OBJECT)); + obj = g_object_new (TEST_TYPE_THREAD, NULL); + g_assert (obj != NULL); + + return pygobject_new(obj); +} + +static PyObject * +_wrap_get_unknown (PyObject * self) +{ + GObject *obj; + obj = g_object_new (TEST_TYPE_UNKNOWN, NULL); + return pygobject_new(obj); +} + +static PyObject * +_wrap_create_test_type (PyObject * self) +{ + GObject *obj; + PyObject *rv; + obj = g_object_new(TYPE_TEST, NULL); + rv = pygobject_new(obj); + g_object_unref(obj); + return rv; +} + +static PyObject * +_wrap_test_g_object_new (PyObject * self) +{ + GObject *obj; + PyObject *rv; + + obj = g_object_new(g_type_from_name("PyGObject"), NULL); + rv = PyInt_FromLong(obj->ref_count); /* should be == 2 at this point */ + g_object_unref(obj); + return rv; +} + +/* TestUnknown */ +static PyObject * +_wrap_test_interface_iface_method(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,":", kwlist)) + return NULL; + + test_interface_iface_method(TEST_INTERFACE(self->obj)); + + Py_INCREF(Py_None); + return Py_None; +} + +static const PyMethodDef _PyTestInterface_methods[] = { + { "iface_method", (PyCFunction)_wrap_test_interface_iface_method, METH_VARARGS|METH_KEYWORDS, + NULL }, + { "do_iface_method", (PyCFunction)_wrap_TestInterface__do_iface_method, METH_VARARGS|METH_KEYWORDS|METH_CLASS, + NULL }, + { NULL, NULL, 0, NULL } +}; + +/* TestInterface */ +PyTypeObject PyTestInterface_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "test.Interface", /* tp_name */ + sizeof(PyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + (PyNumberMethods*)0, /* tp_as_number */ + (PySequenceMethods*)0, /* tp_as_sequence */ + (PyMappingMethods*)0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + (PyBufferProcs*)0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + NULL, /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + (struct PyMethodDef*)_PyTestInterface_methods, /* tp_methods */ + (struct PyMemberDef*)0, /* tp_members */ + (struct PyGetSetDef*)0, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + (descrgetfunc)0, /* tp_descr_get */ + (descrsetfunc)0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)0, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)0, /* tp_free */ + (inquiry)0 /* tp_is_gc */ + + + +}; + +static PyObject * +_wrap_TestInterface__do_iface_method(PyObject *cls, PyObject *args, PyObject *kwargs) +{ + TestInterfaceIface *iface; + static char *kwlist[] = { "self", NULL }; + PyGObject *self; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:TestInterface.iface_method", kwlist, &PyTestInterface_Type, &self)) + return NULL; + + iface = g_type_interface_peek(g_type_class_peek(pyg_type_from_object(cls)), + TEST_TYPE_INTERFACE); + if (iface->iface_method) + iface->iface_method(TEST_INTERFACE(self->obj)); + else { + PyErr_SetString(PyExc_NotImplementedError, + "interface method TestInterface.iface_method not implemented"); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + +PyTypeObject PyTestUnknown_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "testhelper.Unknown", /* tp_name */ + sizeof(PyGObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + (PyNumberMethods*)0, /* tp_as_number */ + (PySequenceMethods*)0, /* tp_as_sequence */ + (PyMappingMethods*)0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + (PyBufferProcs*)0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + NULL, /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + (struct PyMethodDef*)0, /* tp_methods */ + (struct PyMemberDef*)0, /* tp_members */ + (struct PyGetSetDef*)0, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + (descrgetfunc)0, /* tp_descr_get */ + (descrsetfunc)0, /* tp_descr_set */ + offsetof(PyGObject, inst_dict), /* tp_dictoffset */ + (initproc)0, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)0, /* tp_free */ + (inquiry)0 /* tp_is_gc */ +}; + + +static void +_wrap_TestInterface__proxy_do_iface_method(TestInterface *self) +{ + PyGILState_STATE __py_state; + PyObject *py_self; + PyObject *py_retval; + PyObject *py_args; + PyObject *py_method; + + __py_state = pyg_gil_state_ensure(); + py_self = pygobject_new((GObject *) self); + if (!py_self) { + if (PyErr_Occurred()) + PyErr_Print(); + pyg_gil_state_release(__py_state); + return; + } + py_args = PyTuple_New(0); + py_method = PyObject_GetAttrString(py_self, "do_iface_method"); + if (!py_method) { + if (PyErr_Occurred()) + PyErr_Print(); + Py_DECREF(py_args); + Py_DECREF(py_self); + pyg_gil_state_release(__py_state); + return; + } + py_retval = PyObject_CallObject(py_method, py_args); + if (!py_retval) { + if (PyErr_Occurred()) + PyErr_Print(); + Py_DECREF(py_method); + Py_DECREF(py_args); + Py_DECREF(py_self); + pyg_gil_state_release(__py_state); + return; + } + if (py_retval != Py_None) { + if (PyErr_Occurred()) + PyErr_Print(); + PyErr_SetString(PyExc_TypeError, "retval should be None"); + Py_DECREF(py_retval); + Py_DECREF(py_method); + Py_DECREF(py_args); + Py_DECREF(py_self); + pyg_gil_state_release(__py_state); + return; + } + + Py_DECREF(py_retval); + Py_DECREF(py_method); + Py_DECREF(py_args); + Py_DECREF(py_self); + pyg_gil_state_release(__py_state); +} + +static void +__TestInterface__interface_init(TestInterfaceIface *iface, + PyTypeObject *pytype) +{ + TestInterfaceIface *parent_iface = g_type_interface_peek_parent(iface); + PyObject *py_method; + + py_method = pytype ? PyObject_GetAttrString((PyObject *) pytype, + "do_iface_method") : NULL; + + if (py_method && !PyObject_TypeCheck(py_method, &PyCFunction_Type)) { + iface->iface_method = _wrap_TestInterface__proxy_do_iface_method; + } else { + PyErr_Clear(); + if (parent_iface) { + iface->iface_method = parent_iface->iface_method; + } + Py_XDECREF(py_method); + } +} + +static const GInterfaceInfo __TestInterface__iinfo = { + (GInterfaceInitFunc) __TestInterface__interface_init, + NULL, + NULL +}; + +/* TestFloatingWithSinkFunc */ + +PyTypeObject PyTestFloatingWithSinkFunc_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "testhelper.FloatingWithSinkFunc", /* tp_name */ + sizeof(PyGObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + (PyNumberMethods*)0, /* tp_as_number */ + (PySequenceMethods*)0, /* tp_as_sequence */ + (PyMappingMethods*)0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + (PyBufferProcs*)0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + NULL, /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + (struct PyMethodDef*)0, /* tp_methods */ + (struct PyMemberDef*)0, /* tp_members */ + (struct PyGetSetDef*)0, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + (descrgetfunc)0, /* tp_descr_get */ + (descrsetfunc)0, /* tp_descr_set */ + offsetof(PyGObject, inst_dict), /* tp_dictoffset */ + (initproc)0, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)0, /* tp_free */ + (inquiry)0 /* tp_is_gc */ +}; + +/* TestFloatingWithoutSinkFunc */ + +PyTypeObject PyTestFloatingWithoutSinkFunc_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "testhelper.FloatingWithoutSinkFunc", /* tp_name */ + sizeof(PyGObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + (PyNumberMethods*)0, /* tp_as_number */ + (PySequenceMethods*)0, /* tp_as_sequence */ + (PyMappingMethods*)0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + (PyBufferProcs*)0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + NULL, /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + (struct PyMethodDef*)0, /* tp_methods */ + (struct PyMemberDef*)0, /* tp_members */ + (struct PyGetSetDef*)0, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + (descrgetfunc)0, /* tp_descr_get */ + (descrsetfunc)0, /* tp_descr_set */ + offsetof(PyGObject, inst_dict), /* tp_dictoffset */ + (initproc)0, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)0, /* tp_free */ + (inquiry)0 /* tp_is_gc */ +}; + +#include <string.h> +#include <glib-object.h> + +static void +test1_callback (GObject *object, char *data) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (!strcmp (data, "user-data")); +} + +static void +test1_callback_swapped (char *data, GObject *object) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (!strcmp (data, "user-data")); +} + +static void +test2_callback (GObject *object, char *string) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (!strcmp (string, "string")); +} + +static int +test3_callback (GObject *object, double d) +{ + g_return_val_if_fail (G_IS_OBJECT (object), -1); + g_return_val_if_fail (d == 42.0, -1); + + return 20; +} + +static void +test4_callback (GObject *object, + gboolean b, long l, float f, double d, guint uint, gulong ulong, + gpointer user_data) +{ + g_return_if_fail (b == TRUE); + g_return_if_fail (l == 10L); + g_return_if_fail (f <= 3.14001 && f >= 3.13999); + g_return_if_fail (d == 1.78); + g_return_if_fail (uint == 20); + g_return_if_fail (ulong == 30L); +} + +static float +test_float_callback (GObject *object, float f) +{ + g_return_val_if_fail (G_IS_OBJECT (object), -1); + g_return_val_if_fail (f <= 1.234001 && f >= 1.123999, -1); + + return f; +} + +static double +test_double_callback (GObject *object, double d) +{ + g_return_val_if_fail (G_IS_OBJECT (object), -1); + g_return_val_if_fail (d <= 1.234001 && d >= 1.123999, -1); + + return d; +} + +static char * +test_string_callback (GObject *object, char *s) +{ + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (!strcmp(s, "str"), NULL); + + return g_strdup (s); +} + +static GObject * +test_object_callback (GObject *object, GObject *o) +{ + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + + return o; +} + +void +connectcallbacks (GObject *object) +{ + + gchar *data = "user-data"; + + g_signal_connect (G_OBJECT (object), + "test1", + G_CALLBACK (test1_callback), + data); + g_signal_connect_swapped (G_OBJECT (object), + "test1", + G_CALLBACK (test1_callback_swapped), + data); + g_signal_connect (G_OBJECT (object), + "test2", + G_CALLBACK (test2_callback), + NULL); + g_signal_connect (G_OBJECT (object), + "test3", + G_CALLBACK (test3_callback), + NULL); + g_signal_connect (G_OBJECT (object), + "test4", + G_CALLBACK (test4_callback), + NULL); + g_signal_connect (G_OBJECT (object), + "test_float", + G_CALLBACK (test_float_callback), + NULL); + g_signal_connect (G_OBJECT (object), + "test_double", + G_CALLBACK (test_double_callback), + NULL); + g_signal_connect (G_OBJECT (object), + "test_string", + G_CALLBACK (test_string_callback), + NULL); + g_signal_connect (G_OBJECT (object), + "test_object", + G_CALLBACK (test_object_callback), + NULL); +} + +static PyObject * +_wrap_connectcallbacks(PyObject * self, PyObject *args) +{ + PyGObject *obj; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + + connectcallbacks (G_OBJECT (obj->obj)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_test_value(PyObject *self, PyObject *args) +{ + GValue tvalue = {0,}, *value = &tvalue; + PyObject *obj; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + + g_value_init(value, G_TYPE_VALUE); + if (pyg_value_from_pyobject(value, obj)) { + PyErr_SetString(PyExc_TypeError, "Could not convert to GValue"); + return NULL; + } + + return pyg_value_as_pyobject(value, FALSE); +} + +static PyObject * +_wrap_test_value_array(PyObject *self, PyObject *args) +{ + GValue tvalue = {0,}, *value = &tvalue; + PyObject *obj; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + + g_value_init(value, G_TYPE_VALUE_ARRAY); + if (pyg_value_from_pyobject(value, obj)) { + PyErr_SetString(PyExc_TypeError, "Could not convert to GValueArray"); + return NULL; + } + + return pyg_value_as_pyobject(value, FALSE); +} + +static PyObject * +_wrap_test_gerror_exception(PyObject *self, PyObject *args) +{ + PyObject *py_method; + PyObject *py_args; + PyObject *py_ret; + GError *err = NULL; + + if (!PyArg_ParseTuple(args, "O", &py_method)) + return NULL; + + py_args = PyTuple_New(0); + py_ret = PyObject_CallObject(py_method, py_args); + if (pyg_gerror_exception_check(&err)) { + pyg_error_check(&err); + return NULL; + } + + Py_DECREF(py_method); + Py_DECREF(py_args); + Py_DECREF(py_ret); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef testhelper_functions[] = { + { "get_test_thread", (PyCFunction)_wrap_get_test_thread, METH_NOARGS }, + { "get_unknown", (PyCFunction)_wrap_get_unknown, METH_NOARGS }, + { "create_test_type", (PyCFunction)_wrap_create_test_type, METH_NOARGS }, + { "test_g_object_new", (PyCFunction)_wrap_test_g_object_new, METH_NOARGS }, + { "connectcallbacks", (PyCFunction)_wrap_connectcallbacks, METH_VARARGS }, + { "test_value", (PyCFunction)_wrap_test_value, METH_VARARGS }, + { "test_value_array", (PyCFunction)_wrap_test_value_array, METH_VARARGS }, + { "test_gerror_exception", (PyCFunction)_wrap_test_gerror_exception, METH_VARARGS }, + { NULL, NULL } +}; + +void +inittesthelper () +{ + PyObject *m, *d; + PyObject *module; + + g_thread_init(NULL); + init_pygobject(); + m = Py_InitModule ("testhelper", testhelper_functions); + + d = PyModule_GetDict(m); + + if ((module = PyImport_ImportModule("gobject")) != NULL) { + PyObject *moddict = PyModule_GetDict(module); + + _PyGObject_Type = (PyTypeObject *)PyDict_GetItemString(moddict, "GObject"); + if (_PyGObject_Type == NULL) { + PyErr_SetString(PyExc_ImportError, + "cannot import name GObject from gobject"); + return ; + } + } else { + PyErr_SetString(PyExc_ImportError, + "could not import gobject"); + return ; + } + + /* TestInterface */ + pyg_register_interface(d, "Interface", TEST_TYPE_INTERFACE, + &PyTestInterface_Type); + pyg_register_interface_info(TEST_TYPE_INTERFACE, &__TestInterface__iinfo); + + + /* TestUnknown */ + pygobject_register_class(d, "Unknown", TEST_TYPE_UNKNOWN, + &PyTestUnknown_Type, + Py_BuildValue("(O)", + &PyGObject_Type, + &PyTestInterface_Type)); + pyg_set_object_has_new_constructor(TEST_TYPE_UNKNOWN); + //pyg_register_class_init(TEST_TYPE_UNKNOWN, __GtkUIManager_class_init); + + /* TestFloatingWithSinkFunc */ + pygobject_register_class(d, "FloatingWithSinkFunc", TEST_TYPE_FLOATING_WITH_SINK_FUNC, + &PyTestFloatingWithSinkFunc_Type, + Py_BuildValue("(O)", + &PyGObject_Type)); + pyg_set_object_has_new_constructor(TEST_TYPE_FLOATING_WITH_SINK_FUNC); + pygobject_register_sinkfunc(TEST_TYPE_FLOATING_WITH_SINK_FUNC, sink_test_floating_with_sink_func); + + /* TestFloatingWithoutSinkFunc */ + pygobject_register_class(d, "FloatingWithoutSinkFunc", TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC, + &PyTestFloatingWithoutSinkFunc_Type, + Py_BuildValue("(O)", + &PyGObject_Type)); + pyg_set_object_has_new_constructor(TEST_TYPE_FLOATING_WITHOUT_SINK_FUNC); +} + diff --git a/tests/testmodule.py b/tests/testmodule.py new file mode 100644 index 0000000..5fc29b3 --- /dev/null +++ b/tests/testmodule.py @@ -0,0 +1,21 @@ +import gobject + +class PyGObject(gobject.GObject): + __gtype_name__ = 'PyGObject' + __gproperties__ = { + 'label': (gobject.TYPE_STRING, + 'label property', + 'the label of the object', + 'default', gobject.PARAM_READWRITE), + } + + def __init__(self): + self._props = {} + gobject.GObject.__init__(self) + self.set_property('label', 'hello') + + def do_set_property(self, name, value): + self._props[name] = value + + def do_get_property(self, name): + return self._props[name] |