diff options
author | Paul Pogonyshev <pogonyshev@gmx.net> | 2008-08-09 11:58:21 +0000 |
---|---|---|
committer | Paul Pogonyshev <paulp@src.gnome.org> | 2008-08-09 11:58:21 +0000 |
commit | 1a20d6e43a3cc24feb7d4d5573face04b6d2492a (patch) | |
tree | 288e20c51f8c05f3098274e9ef62514bce6437fc | |
parent | efed0743ab6e395e3d689455e7897240ec8b0e45 (diff) | |
download | pygobject-1a20d6e43a3cc24feb7d4d5573face04b6d2492a.tar.gz pygobject-1a20d6e43a3cc24feb7d4d5573face04b6d2492a.tar.xz pygobject-1a20d6e43a3cc24feb7d4d5573face04b6d2492a.zip |
Bug 546135 – GIcon and implementations improvements
2008-08-09 Paul Pogonyshev <pogonyshev@gmx.net>
Bug 546135 – GIcon and implementations improvements
* gio/gio.defs (gio.LoadableIcon.load)
(gio.LoadableIcon.load_async, gio.LoadableIcon.load_finish):
Document.
* gio/Makefile.am:
* gio/gicon.override: New file: parts of 'gio.override', three
methods of gio.LoadableIcon and gio.ThemedIcon constructor.
* gio/gio.override: Move over all icon-related overrides to
'gicon.override'.
* tests/Makefile.am:
* tests/test_gicon.py: New file: parts of 'test_gio.py' and
several new gio.Icon tests.
* tests/test_gio.py (TestThemedIcon): Move over to
'test_gicon.py'.
svn path=/trunk/; revision=931
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | gio/Makefile.am | 1 | ||||
-rw-r--r-- | gio/gicon.override | 341 | ||||
-rw-r--r-- | gio/gio.defs | 30 | ||||
-rw-r--r-- | gio/gio.override | 149 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/test_gicon.py | 94 | ||||
-rw-r--r-- | tests/test_gio.py | 13 |
8 files changed, 490 insertions, 161 deletions
@@ -1,3 +1,25 @@ +2008-08-09 Paul Pogonyshev <pogonyshev@gmx.net> + + Bug 546135 – GIcon and implementations improvements + + * gio/gio.defs (gio.LoadableIcon.load) + (gio.LoadableIcon.load_async, gio.LoadableIcon.load_finish): + Document. + + * gio/Makefile.am: + * gio/gicon.override: New file: parts of 'gio.override', three + methods of gio.LoadableIcon and gio.ThemedIcon constructor. + + * gio/gio.override: Move over all icon-related overrides to + 'gicon.override'. + + * tests/Makefile.am: + * tests/test_gicon.py: New file: parts of 'test_gio.py' and + several new gio.Icon tests. + + * tests/test_gio.py (TestThemedIcon): Move over to + 'test_gicon.py'. + 2008-08-07 Jonathan Matthew <jonathan@d14n.org> Bug 546734 – Missing Py_INCREFs for some file async methods diff --git a/gio/Makefile.am b/gio/Makefile.am index af0cda1..3748214 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -42,6 +42,7 @@ GIO_OVERRIDES = \ gfileattribute.override \ gfileenumerator.override \ gfileinfo.override \ + gicon.override \ ginputstream.override \ goutputstream.override \ gvolume.override \ diff --git a/gio/gicon.override b/gio/gicon.override new file mode 100644 index 0000000..8da8d74 --- /dev/null +++ b/gio/gicon.override @@ -0,0 +1,341 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 2008 Johan Dahlin + * + * gicon.override: module overrides for GIcon and related types + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ +%% +headers + +static PyObject * pygio_do_icon_richcompare(PyGObject *self, PyGObject *other, int op); + +%% +ignore-glob + g_icon_hash + g_themed_icon_new_from_names + g_themed_icon_new_with_default_fallbacks +%% +override-slot GIcon.tp_richcompare +static PyObject * +pygio_do_icon_richcompare(PyGObject *self, PyGObject *other, int op) +{ + PyObject *result; + + if (PyObject_TypeCheck(self, &PyGIcon_Type) + && PyObject_TypeCheck(other, &PyGIcon_Type)) { + GIcon *icon1 = G_ICON(self->obj); + GIcon *icon2 = G_ICON(other->obj); + + switch (op) { + case Py_EQ: + result = (g_icon_equal(icon1, icon2) + ? Py_True : Py_False); + break; + case Py_NE: + result = (!g_icon_equal(icon1, icon2) + ? Py_True : Py_False); + break; + default: + result = Py_NotImplemented; + } + } + else + result = Py_NotImplemented; + + Py_INCREF(result); + return result; +} +static PyObject * +_wrap_g_icon_tp_richcompare(PyGObject *self, PyGObject *other, int op) +{ + return pygio_do_icon_richcompare(self, other, op); +} +%% +override-slot GIcon.tp_hash +static long +_wrap_g_icon_tp_hash(PyGObject *self) +{ + return g_icon_hash(G_ICON(self->obj)); +} +%% +override g_loadable_icon_load kwargs +static PyObject * +_wrap_g_loadable_icon_load(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "size", "cancellable", NULL }; + int size = 0; + char *type = NULL; + PyGObject *pycancellable = NULL; + GCancellable *cancellable; + GError *error = NULL; + GInputStream *stream; + PyObject *result; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|iO:gio.LoadableIcon.load", + kwlist, + &size, &pycancellable)) + return NULL; + + if (!pygio_check_cancellable(pycancellable, &cancellable)) + return NULL; + + stream = g_loadable_icon_load(G_LOADABLE_ICON(self->obj), size, &type, + cancellable, &error); + if (pyg_error_check(&error)) + return NULL; + + result = Py_BuildValue("Ns", pygobject_new((GObject *) stream), type); + g_free(type); + return result; +} +%% +override g_loadable_icon_load_async kwargs +static PyObject * +_wrap_g_loadable_icon_load_async(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "callback", "size", "cancellable", "user_data", NULL }; + int size = 0; + PyGObject *pycancellable = NULL; + GCancellable *cancellable; + PyGIONotify *notify; + + notify = g_slice_new0(PyGIONotify); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|iOO:gio.LoadableIcon.load_async", + kwlist, + ¬ify->callback, &size, &pycancellable, ¬ify->data)) + goto error; + + if (!PyCallable_Check(notify->callback)) { + PyErr_SetString(PyExc_TypeError, "callback argument not callable"); + goto error; + } + + if (!pygio_check_cancellable(pycancellable, &cancellable)) + goto error; + + Py_INCREF(notify->callback); + Py_XINCREF(notify->data); + + g_loadable_icon_load_async(G_LOADABLE_ICON(self->obj), + size, + cancellable, + (GAsyncReadyCallback) async_result_callback_marshal, + notify); + Py_INCREF(Py_None); + return Py_None; + + error: + g_slice_free(PyGIONotify, notify); + return NULL; +} +%% +override g_loadable_icon_load_finish kwargs +static PyObject * +_wrap_g_loadable_icon_load_finish(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "res", NULL }; + PyGObject *res; + char *type = NULL; + GError *error = NULL; + GInputStream *stream; + PyObject *result; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!:gio.LoadableIcon.load_finish", + kwlist, + &PyGAsyncResult_Type, &res)) + return NULL; + + stream = g_loadable_icon_load_finish(G_LOADABLE_ICON(self->obj), + G_ASYNC_RESULT(res->obj), &type, &error); + if (pyg_error_check(&error)) + return NULL; + + result = Py_BuildValue("Ns", pygobject_new((GObject *) stream), type); + g_free(type); + return result; +} +%% +override-slot GFileIcon.tp_richcompare +/* We need to duplicate, because GIcon is an interface, not a class. */ +static PyObject * +_wrap_g_file_icon_tp_richcompare(PyGObject *self, PyGObject *other, int op) +{ + return pygio_do_icon_richcompare(self, other, op); +} +%% +override-slot GFileIcon.tp_hash +/* We need to duplicate, because GIcon is an interface, not a class. */ +static long +_wrap_g_file_icon_tp_hash(PyGObject *self) +{ + return g_icon_hash(G_ICON(self->obj)); +} +%% +override-slot GFileIcon.tp_repr +static PyObject * +_wrap_g_file_icon_tp_repr(PyGObject *self) +{ + GFile *file = g_file_icon_get_file(G_FILE_ICON(self->obj)); + char *uri = (file ? g_file_get_uri(file) : NULL); + gchar *representation; + PyObject *result; + + if (uri) { + representation = g_strdup_printf("<%s at %p: %s>", self->ob_type->tp_name, self, uri); + g_free(uri); + } + else + representation = g_strdup_printf("<%s at %p: UNKNOWN URI>", self->ob_type->tp_name, self); + + result = PyString_FromString(representation); + g_free(representation); + return result; +} +%% +new-constructor G_TYPE_THEMED_ICON +%% +override g_themed_icon_new kwargs +static int +_wrap_g_themed_icon_new(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", "use_default_fallbacks", NULL }; + PyObject *name; + gboolean use_default_fallbacks = FALSE; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:gio.ThemedIcon.__init__", + kwlist, &name, &use_default_fallbacks)) + return -1; + + if (PyString_Check(name)) { + pygobject_construct(self, + "name", PyString_AsString(name), + "use-default-fallbacks", use_default_fallbacks, NULL); + return 0; + } + else if (PySequence_Check(name)) { + PyObject *tuple = PySequence_Tuple(name); + + if (tuple) { + int k; + int length = PyTuple_Size(tuple); + char **names = g_new(char *, length + 1); + + for (k = 0; k < length; k++) { + PyObject *str = PyTuple_GetItem(tuple, k); + if (str && PyString_Check(str)) + names[k] = PyString_AsString(str); + else { + Py_DECREF(tuple); + g_free(names); + goto error; + } + } + + names[length] = NULL; + pygobject_construct(self, + "names", names, + "use-default-fallbacks", use_default_fallbacks, NULL); + Py_DECREF(tuple); + g_free(names); + return 0; + } + } + + error: + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "argument 1 of gio.ThemedIcon.__init__ " + "must be either a string or a sequence of strings"); + } + return -1; +} +%% +override g_themed_icon_get_names noargs +static PyObject * +_wrap_g_themed_icon_get_names(PyGObject *self) +{ + const char * const *names; + PyObject *ret; + + names = g_themed_icon_get_names(G_THEMED_ICON(self->obj)); + + ret = PyList_New(0); + while (names && *names) { + PyObject *item = PyString_FromString(names[0]); + PyList_Append(ret, item); + Py_DECREF(item); + + names++; + } + + return ret; +} +%% +override-slot GThemedIcon.tp_richcompare +/* We need to duplicate, because GIcon is an interface, not a class. */ +static PyObject * +_wrap_g_themed_icon_tp_richcompare(PyGObject *self, PyGObject *other, int op) +{ + return pygio_do_icon_richcompare(self, other, op); +} +%% +override-slot GThemedIcon.tp_hash +/* We need to duplicate, because GIcon is an interface, not a class. */ +static long +_wrap_g_themed_icon_tp_hash(PyGObject *self) +{ + return g_icon_hash(G_ICON(self->obj)); +} +%% +override-slot GThemedIcon.tp_repr +static PyObject * +_wrap_g_themed_icon_tp_repr(PyGObject *self) +{ + const char * const *names = g_themed_icon_get_names(G_THEMED_ICON(self->obj)); + GString *representation = g_string_new(NULL); + PyObject *result; + + g_string_append_printf(representation, "<%s at %p: ", self->ob_type->tp_name, self); + + if (names) { + gboolean first_name = TRUE; + while (*names) { + if (!first_name) + g_string_append(representation, ", "); + else + first_name = FALSE; + + g_string_append(representation, *names++); + } + } + + g_string_append(representation, ">"); + result = PyString_FromString(representation->str); + g_string_free(representation, TRUE); + return result; +} diff --git a/gio/gio.defs b/gio/gio.defs index d11eeb5..0396d65 100644 --- a/gio/gio.defs +++ b/gio/gio.defs @@ -3448,6 +3448,20 @@ (define-method load (of-object "GLoadableIcon") + (docstring + "ICON.load([size, [cancellable]]) -> input stream, type\n" + "\n" + "Opens a stream of icon data for reading. The result is a tuple of\n" + "gio.InputStream and type (either a string or None). The stream can\n" + "be read to retrieve icon data.\n" + "\n" + ;; Note: this is just a guess, GIO docs say nothing at the moment. + "Optional size is a hint at desired icon size. Not all implementations\n" + "support it and the hint will be just ignored in such cases.\n" + "If cancellable is specified, then the operation can be cancelled\n" + "by triggering the cancellable object from another thread. See\n" + "gio.File.read for details." + ) (c-name "g_loadable_icon_load") (return-type "GInputStream*") (parameters @@ -3460,6 +3474,15 @@ (define-method load_async (of-object "GLoadableIcon") + (docstring + "ICON.load_async(callback, [size, [cancellable, [user_data]]]) -> start loading\n" + "\n" + "For more information, see gio.LoadableIcon.load() which is the\n" + "synchronous version of this call. Asynchronously opens icon data for\n" + "reading. When the operation is finished, callback will be called.\n" + "You can then call gio.LoadableIcon.load_finish() to get the result of\n" + "the operation.\n" + ) (c-name "g_loadable_icon_load_async") (return-type "none") (parameters @@ -3471,6 +3494,13 @@ ) (define-method load_finish + (docstring + "F.load_finish(res) -> start loading\n" + "\n" + "Finish asynchronous icon loading operation. Must be called from callback\n" + "as specified to gio.LoadableIcon.load_async. Returns a tuple of\n" + "gio.InputStream and type, just as gio.LoadableIcon.load." + ) (of-object "GLoadableIcon") (c-name "g_loadable_icon_load_finish") (return-type "GInputStream*") diff --git a/gio/gio.override b/gio/gio.override index 32a8a5f..16c796a 100644 --- a/gio/gio.override +++ b/gio/gio.override @@ -38,8 +38,6 @@ typedef struct { PyObject *data; } PyGIONotify; -static PyObject * pygio_do_icon_richcompare(PyGObject *self, PyGObject *other, int op); - static void py_decref_callback (gpointer data) { @@ -88,6 +86,7 @@ include gfileattribute.override gfileenumerator.override gfileinfo.override + gicon.override ginputstream.override goutputstream.override gvolume.override @@ -101,7 +100,6 @@ ignore-glob g_file_new_from_path g_file_new_from_uri g_file_hash - g_icon_hash g_input_stream_read_all g_io_error_quark g_simple_async_result_new_error @@ -181,151 +179,6 @@ _wrap_g_app_info_get_all_for_type (PyGObject *self, PyObject *args) return ret; } %% -override-slot GIcon.tp_richcompare -static PyObject * -pygio_do_icon_richcompare(PyGObject *self, PyGObject *other, int op) -{ - PyObject *result; - - if (PyObject_TypeCheck(self, &PyGIcon_Type) - && PyObject_TypeCheck(other, &PyGIcon_Type)) { - GIcon *icon1 = G_ICON(self->obj); - GIcon *icon2 = G_ICON(other->obj); - - switch (op) { - case Py_EQ: - result = (g_icon_equal(icon1, icon2) - ? Py_True : Py_False); - break; - case Py_NE: - result = (!g_icon_equal(icon1, icon2) - ? Py_True : Py_False); - break; - default: - result = Py_NotImplemented; - } - } - else - result = Py_NotImplemented; - - Py_INCREF(result); - return result; -} -static PyObject * -_wrap_g_icon_tp_richcompare(PyGObject *self, PyGObject *other, int op) -{ - return pygio_do_icon_richcompare(self, other, op); -} -%% -override-slot GIcon.tp_hash -static long -_wrap_g_icon_tp_hash(PyGObject *self) -{ - return g_icon_hash(G_ICON(self->obj)); -} -%% -override-slot GFileIcon.tp_richcompare -/* We need to duplicate, because GIcon is an interface, not a class. */ -static PyObject * -_wrap_g_file_icon_tp_richcompare(PyGObject *self, PyGObject *other, int op) -{ - return pygio_do_icon_richcompare(self, other, op); -} -%% -override-slot GFileIcon.tp_hash -/* We need to duplicate, because GIcon is an interface, not a class. */ -static long -_wrap_g_file_icon_tp_hash(PyGObject *self) -{ - return g_icon_hash(G_ICON(self->obj)); -} -%% -override-slot GFileIcon.tp_repr -static PyObject * -_wrap_g_file_icon_tp_repr(PyGObject *self) -{ - GFile *file = g_file_icon_get_file(G_FILE_ICON(self->obj)); - char *uri = (file ? g_file_get_uri(file) : NULL); - gchar *representation; - PyObject *result; - - if (uri) { - representation = g_strdup_printf("<%s at %p: %s>", self->ob_type->tp_name, self, uri); - g_free(uri); - } - else - representation = g_strdup_printf("<%s at %p: UNKNOWN URI>", self->ob_type->tp_name, self); - - result = PyString_FromString(representation); - g_free(representation); - return result; -} -%% -override g_themed_icon_get_names noargs -static PyObject * -_wrap_g_themed_icon_get_names(PyGObject *self) -{ - const char * const *names; - PyObject *ret; - - names = g_themed_icon_get_names(G_THEMED_ICON(self->obj)); - - ret = PyList_New(0); - while (names && *names) { - PyObject *item = PyString_FromString(names[0]); - PyList_Append(ret, item); - Py_DECREF(item); - - names++; - } - - return ret; -} -%% -override-slot GThemedIcon.tp_richcompare -/* We need to duplicate, because GIcon is an interface, not a class. */ -static PyObject * -_wrap_g_themed_icon_tp_richcompare(PyGObject *self, PyGObject *other, int op) -{ - return pygio_do_icon_richcompare(self, other, op); -} -%% -override-slot GThemedIcon.tp_hash -/* We need to duplicate, because GIcon is an interface, not a class. */ -static long -_wrap_g_themed_icon_tp_hash(PyGObject *self) -{ - return g_icon_hash(G_ICON(self->obj)); -} -%% -override-slot GThemedIcon.tp_repr -static PyObject * -_wrap_g_themed_icon_tp_repr(PyGObject *self) -{ - const char * const *names = g_themed_icon_get_names(G_THEMED_ICON(self->obj)); - GString *representation = g_string_new(NULL); - PyObject *result; - - g_string_append_printf(representation, "<%s at %p: ", self->ob_type->tp_name, self); - - if (names) { - gboolean first_name = TRUE; - while (*names) { - if (!first_name) - g_string_append(representation, ", "); - else - first_name = FALSE; - - g_string_append(representation, *names++); - } - } - - g_string_append(representation, ">"); - result = PyString_FromString(representation->str); - g_string_free(representation, TRUE); - return result; -} -%% override g_content_type_guess kwargs static PyObject * _wrap_g_content_type_guess(PyGObject *self, PyObject *args, PyObject *kwargs) diff --git a/tests/Makefile.am b/tests/Makefile.am index 9f9ba6f..667506c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,6 +24,7 @@ testhelper_la_SOURCES = \ tests = \ test_conversion.py \ test_enum.py \ + test_gicon.py \ test_gio.py \ test_gobject.py \ test_gtype.py \ diff --git a/tests/test_gicon.py b/tests/test_gicon.py new file mode 100644 index 0000000..0a66c9e --- /dev/null +++ b/tests/test_gicon.py @@ -0,0 +1,94 @@ +# -*- Mode: Python -*- + +import os +import unittest + +from common import gio, glib + + +class TestIcon(unittest.TestCase): + def test_eq(self): + self.assertEquals(gio.File('foo.png').icon_new(), + gio.File('foo.png').icon_new()) + self.assertEquals(gio.ThemedIcon('foo'), + gio.ThemedIcon('foo')) + + self.assertNotEqual(gio.File('foo.png').icon_new(), + gio.File('bar.png').icon_new()) + self.assertNotEquals(gio.ThemedIcon('foo'), + gio.ThemedIcon('bar')) + self.assertNotEquals(gio.File('foo.png').icon_new(), + gio.ThemedIcon('foo')) + + def test_hash(self): + self.assertEquals(hash(gio.File('foo.png').icon_new()), + hash(gio.File('foo.png').icon_new())) + 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.File('temp.svg').icon_new() + + 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 TestThemedIcon(unittest.TestCase): + def setUp(self): + self.icon = gio.ThemedIcon("open") + + def test_constructor(self): + icon = gio.ThemedIcon('foo') + self.assertEquals(['foo'], icon.props.names) + self.assert_(not icon.props.use_default_fallbacks) + + icon = gio.ThemedIcon(['foo', 'bar', 'baz']) + self.assertEquals(['foo', 'bar', 'baz'], icon.props.names) + self.assert_(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_(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']) diff --git a/tests/test_gio.py b/tests/test_gio.py index c321076..930d8fb 100644 --- a/tests/test_gio.py +++ b/tests/test_gio.py @@ -568,19 +568,6 @@ class TestVolumeMonitor(unittest.TestCase): self.failUnless(isinstance(icon, gio.Icon)) -class TestThemedIcon(unittest.TestCase): - def setUp(self): - self.icon = gio.ThemedIcon("open") - - def testGetNames(self): - self.assertEquals(self.icon.get_names(), ['open']) - - def testAppendName(self): - self.assertEquals(self.icon.get_names(), ['open']) - self.icon.append_name('close') - self.assertEquals(self.icon.get_names(), ['open', 'close']) - - class TestContentTypeGuess(unittest.TestCase): def testFromName(self): mime_type = gio.content_type_guess('diagram.svg') |