diff options
Diffstat (limited to 'tests/test_glib.py')
-rw-r--r-- | tests/test_glib.py | 157 |
1 files changed, 123 insertions, 34 deletions
diff --git a/tests/test_glib.py b/tests/test_glib.py index 3cde168..19eff7f 100644 --- a/tests/test_glib.py +++ b/tests/test_glib.py @@ -1,31 +1,45 @@ # -*- Mode: Python -*- -# encoding: UTF-8 +import os +import sys import unittest import os.path import warnings import subprocess +import pytest from gi.repository import GLib from gi import PyGIDeprecationWarning -from compathelper import _unicode, _bytes - class TestGLib(unittest.TestCase): + + @pytest.mark.xfail() + def test_pytest_capture_error_in_closure(self): + # this test is supposed to fail + ml = GLib.MainLoop() + + def callback(): + ml.quit() + raise Exception("expected") + + GLib.idle_add(callback) + ml.run() + + @unittest.skipIf(os.name == "nt", "no bash on Windows") def test_find_program_in_path(self): bash_path = GLib.find_program_in_path('bash') - self.assertTrue(bash_path.endswith('/bash')) + self.assertTrue(bash_path.endswith(os.path.sep + 'bash')) self.assertTrue(os.path.exists(bash_path)) self.assertEqual(GLib.find_program_in_path('non existing'), None) def test_markup_escape_text(self): - self.assertEqual(GLib.markup_escape_text(_unicode('a&bä')), 'a&bä') - self.assertEqual(GLib.markup_escape_text(_bytes('a&b\x05')), 'a&b') + self.assertEqual(GLib.markup_escape_text(u'a&bä'), 'a&bä') + self.assertEqual(GLib.markup_escape_text(b'a&b\x05'), 'a&b') # with explicit length argument - self.assertEqual(GLib.markup_escape_text(_bytes('a\x05\x01\x02'), 2), 'a') + self.assertEqual(GLib.markup_escape_text(b'a\x05\x01\x02', 2), 'a') def test_progname(self): GLib.set_prgname('moo') @@ -37,15 +51,18 @@ class TestGLib(unittest.TestCase): def test_xdg_dirs(self): d = GLib.get_user_data_dir() - self.assertTrue('/' in d, d) - d = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP) - self.assertTrue('/' in d, d) - # also works with backwards compatible enum names - self.assertEqual(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC), - GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)) + self.assertTrue(os.path.sep in d, d) + d = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP) + self.assertTrue(os.path.sep in d, d) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', PyGIDeprecationWarning) + + # also works with backwards compatible enum names + self.assertEqual(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC), + GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)) for d in GLib.get_system_config_dirs(): - self.assertTrue('/' in d, d) + self.assertTrue(os.path.sep in d, d) for d in GLib.get_system_data_dirs(): self.assertTrue(isinstance(d, str), d) @@ -56,13 +73,26 @@ class TestGLib(unittest.TestCase): self.assertEqual(GLib.filename_display_name('foo'), 'foo') self.assertEqual(GLib.filename_display_basename('bar/foo'), 'foo') + def glibfsencode(f): + # the annotations of filename_from_utf8() was changed in + # https://bugzilla.gnome.org/show_bug.cgi?id=756128 + if isinstance(f, bytes): + return f + if os.name == "nt": + return f.encode("utf-8", "surrogatepass") + else: + return os.fsencode(f) + # this is locale dependent, so we cannot completely verify the result - res = GLib.filename_from_utf8(_unicode('aäb')) + res = GLib.filename_from_utf8(u'aäb') + res = glibfsencode(res) self.assertTrue(isinstance(res, bytes)) self.assertGreaterEqual(len(res), 3) # with explicit length argument - self.assertEqual(GLib.filename_from_utf8(_unicode('aäb'), 1), b'a') + res = GLib.filename_from_utf8(u'aäb', 1) + res = glibfsencode(res) + self.assertEqual(res, b'a') def test_uri_extract(self): res = GLib.uri_list_extract_uris('''# some comment @@ -82,6 +112,7 @@ https://my.org/q?x=1&y=2 self.assertTrue(isinstance(tm, float)) self.assertGreater(tm, 1350000000.0) + @unittest.skipIf(sys.platform == "darwin", "fails on OSX") def test_main_loop(self): # note we do not test run() here, as we use this in countless other # tests @@ -119,57 +150,96 @@ https://my.org/q?x=1&y=2 self.assertTrue(context.pending() in [True, False]) self.assertTrue(context.iteration(False) in [True, False]) + @unittest.skipIf(os.name == "nt", "hangs") def test_io_add_watch_no_data(self): (r, w) = os.pipe() call_data = [] def cb(fd, condition): call_data.append((fd, condition, os.read(fd, 1))) + if len(call_data) == 2: + ml.quit() return True # io_add_watch() takes an IOChannel, calling with an fd is deprecated with warnings.catch_warnings(record=True) as warn: warnings.simplefilter('always') - GLib.io_add_watch(r, GLib.IOCondition.IN, cb) + GLib.io_add_watch(r, GLib.IOCondition.IN, cb, + priority=GLib.PRIORITY_HIGH) self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning)) + def write(): + os.write(w, b'a') + GLib.idle_add(lambda: os.write(w, b'b') and False) + ml = GLib.MainLoop() - GLib.timeout_add(10, lambda: os.write(w, b'a') and False) - GLib.timeout_add(100, lambda: os.write(w, b'b') and False) - GLib.timeout_add(200, ml.quit) + GLib.idle_add(write) + GLib.timeout_add(2000, ml.quit) ml.run() self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a'), (r, GLib.IOCondition.IN, b'b')]) + @unittest.skipIf(os.name == "nt", "hangs") def test_io_add_watch_with_data(self): (r, w) = os.pipe() call_data = [] def cb(fd, condition, data): call_data.append((fd, condition, os.read(fd, 1), data)) + if len(call_data) == 2: + ml.quit() return True # io_add_watch() takes an IOChannel, calling with an fd is deprecated with warnings.catch_warnings(record=True) as warn: warnings.simplefilter('always') - GLib.io_add_watch(r, GLib.IOCondition.IN, cb, 'moo') + GLib.io_add_watch(r, GLib.IOCondition.IN, cb, 'moo', + priority=GLib.PRIORITY_HIGH) self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning)) + def write(): + os.write(w, b'a') + GLib.idle_add(lambda: os.write(w, b'b') and False) + ml = GLib.MainLoop() - GLib.timeout_add(10, lambda: os.write(w, b'a') and False) - GLib.timeout_add(100, lambda: os.write(w, b'b') and False) - GLib.timeout_add(200, ml.quit) + GLib.idle_add(write) + GLib.timeout_add(2000, ml.quit) ml.run() self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a', 'moo'), (r, GLib.IOCondition.IN, b'b', 'moo')]) + @unittest.skipIf(os.name == "nt", "hangs") + def test_io_add_watch_with_multiple_data(self): + (r, w) = os.pipe() + call_data = [] + + def cb(fd, condition, *user_data): + call_data.append((fd, condition, os.read(fd, 1), user_data)) + ml.quit() + return True + + # io_add_watch() takes an IOChannel, calling with an fd is deprecated + with warnings.catch_warnings(record=True) as warn: + warnings.simplefilter('always') + GLib.io_add_watch(r, GLib.IOCondition.IN, cb, 'moo', 'foo') + self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning)) + + ml = GLib.MainLoop() + GLib.idle_add(lambda: os.write(w, b'a') and False) + GLib.timeout_add(2000, ml.quit) + ml.run() + + self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a', ('moo', 'foo'))]) + + @unittest.skipIf(sys.platform == "darwin", "fails") + @unittest.skipIf(os.name == "nt", "no shell on Windows") def test_io_add_watch_pyfile(self): call_data = [] - cmd = subprocess.Popen('sleep 0.1; echo hello; sleep 0.2; echo world', - shell=True, stdout=subprocess.PIPE) + cmd = subprocess.Popen('echo hello; echo world', + shell=True, bufsize=0, stdout=subprocess.PIPE) def cb(file, condition): call_data.append((file, condition, file.readline())) @@ -194,13 +264,32 @@ https://my.org/q?x=1&y=2 (cmd.stdout, GLib.IOCondition.IN, b'world\n')]) def test_glib_version(self): - (major, minor, micro) = GLib.glib_version - self.assertGreaterEqual(major, 2) - self.assertGreaterEqual(minor, 0) - self.assertGreaterEqual(micro, 0) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', PyGIDeprecationWarning) + + (major, minor, micro) = GLib.glib_version + self.assertGreaterEqual(major, 2) + self.assertGreaterEqual(minor, 0) + self.assertGreaterEqual(micro, 0) def test_pyglib_version(self): - (major, minor, micro) = GLib.pyglib_version - self.assertGreaterEqual(major, 3) - self.assertGreaterEqual(minor, 0) - self.assertGreaterEqual(micro, 0) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', PyGIDeprecationWarning) + + (major, minor, micro) = GLib.pyglib_version + self.assertGreaterEqual(major, 3) + self.assertGreaterEqual(minor, 0) + self.assertGreaterEqual(micro, 0) + + def test_timezone_constructor(self): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + timezone = GLib.TimeZone("+05:21") + self.assertEqual(timezone.get_offset(0), ((5 * 60) + 21) * 60) + + def test_source_attach_implicit_context(self): + context = GLib.MainContext.default() + source = GLib.Idle() + source_id = source.attach() + self.assertEqual(context, source.get_context()) + self.assertTrue(GLib.Source.remove(source_id)) |