diff options
Diffstat (limited to 'tests/test_glib.py')
-rw-r--r-- | tests/test_glib.py | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/tests/test_glib.py b/tests/test_glib.py new file mode 100644 index 0000000..3cde168 --- /dev/null +++ b/tests/test_glib.py @@ -0,0 +1,206 @@ +# -*- Mode: Python -*- +# encoding: UTF-8 + +import unittest +import os.path +import warnings +import subprocess + +from gi.repository import GLib +from gi import PyGIDeprecationWarning + +from compathelper import _unicode, _bytes + + +class TestGLib(unittest.TestCase): + def test_find_program_in_path(self): + bash_path = GLib.find_program_in_path('bash') + self.assertTrue(bash_path.endswith('/bash')) + self.assertTrue(os.path.exists(bash_path)) + + self.assertEqual(GLib.find_program_in_path('non existing'), None) + + def test_markup_escape_text(self): + self.assertEqual(GLib.markup_escape_text(_unicode('a&bä')), 'a&bä') + self.assertEqual(GLib.markup_escape_text(_bytes('a&b\x05')), 'a&b') + + # with explicit length argument + self.assertEqual(GLib.markup_escape_text(_bytes('a\x05\x01\x02'), 2), 'a') + + def test_progname(self): + GLib.set_prgname('moo') + self.assertEqual(GLib.get_prgname(), 'moo') + + def test_appname(self): + GLib.set_application_name('moo') + self.assertEqual(GLib.get_application_name(), 'moo') + + def test_xdg_dirs(self): + d = GLib.get_user_data_dir() + self.assertTrue('/' in d, d) + d = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP) + self.assertTrue('/' in d, d) + # also works with backwards compatible enum names + self.assertEqual(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC), + GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)) + + for d in GLib.get_system_config_dirs(): + self.assertTrue('/' in d, d) + for d in GLib.get_system_data_dirs(): + self.assertTrue(isinstance(d, str), d) + + def test_main_depth(self): + self.assertEqual(GLib.main_depth(), 0) + + def test_filenames(self): + self.assertEqual(GLib.filename_display_name('foo'), 'foo') + self.assertEqual(GLib.filename_display_basename('bar/foo'), 'foo') + + # this is locale dependent, so we cannot completely verify the result + res = GLib.filename_from_utf8(_unicode('aäb')) + self.assertTrue(isinstance(res, bytes)) + self.assertGreaterEqual(len(res), 3) + + # with explicit length argument + self.assertEqual(GLib.filename_from_utf8(_unicode('aäb'), 1), b'a') + + def test_uri_extract(self): + res = GLib.uri_list_extract_uris('''# some comment +http://example.com +https://my.org/q?x=1&y=2 + http://gnome.org/new''') + self.assertEqual(res, ['http://example.com', + 'https://my.org/q?x=1&y=2', + 'http://gnome.org/new']) + + def test_current_time(self): + with warnings.catch_warnings(record=True) as warn: + warnings.simplefilter('always') + tm = GLib.get_current_time() + self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning)) + + self.assertTrue(isinstance(tm, float)) + self.assertGreater(tm, 1350000000.0) + + def test_main_loop(self): + # note we do not test run() here, as we use this in countless other + # tests + ml = GLib.MainLoop() + self.assertFalse(ml.is_running()) + + context = ml.get_context() + self.assertEqual(context, GLib.MainContext.default()) + self.assertTrue(context.is_owner() in [True, False]) + self.assertTrue(context.pending() in [True, False]) + self.assertFalse(context.iteration(False)) + + def test_main_loop_with_context(self): + context = GLib.MainContext() + ml = GLib.MainLoop(context) + self.assertFalse(ml.is_running()) + self.assertEqual(ml.get_context(), context) + + def test_main_context(self): + # constructor + context = GLib.MainContext() + self.assertTrue(context.is_owner() in [True, False]) + self.assertFalse(context.pending()) + self.assertFalse(context.iteration(False)) + + # GLib API + context = GLib.MainContext.default() + self.assertTrue(context.is_owner() in [True, False]) + self.assertTrue(context.pending() in [True, False]) + self.assertTrue(context.iteration(False) in [True, False]) + + # backwards compatible API + context = GLib.main_context_default() + self.assertTrue(context.is_owner() in [True, False]) + self.assertTrue(context.pending() in [True, False]) + self.assertTrue(context.iteration(False) in [True, False]) + + def test_io_add_watch_no_data(self): + (r, w) = os.pipe() + call_data = [] + + def cb(fd, condition): + call_data.append((fd, condition, os.read(fd, 1))) + return True + + # io_add_watch() takes an IOChannel, calling with an fd is deprecated + with warnings.catch_warnings(record=True) as warn: + warnings.simplefilter('always') + GLib.io_add_watch(r, GLib.IOCondition.IN, cb) + self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning)) + + ml = GLib.MainLoop() + GLib.timeout_add(10, lambda: os.write(w, b'a') and False) + GLib.timeout_add(100, lambda: os.write(w, b'b') and False) + GLib.timeout_add(200, ml.quit) + ml.run() + + self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a'), + (r, GLib.IOCondition.IN, b'b')]) + + def test_io_add_watch_with_data(self): + (r, w) = os.pipe() + call_data = [] + + def cb(fd, condition, data): + call_data.append((fd, condition, os.read(fd, 1), data)) + return True + + # io_add_watch() takes an IOChannel, calling with an fd is deprecated + with warnings.catch_warnings(record=True) as warn: + warnings.simplefilter('always') + GLib.io_add_watch(r, GLib.IOCondition.IN, cb, 'moo') + self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning)) + + ml = GLib.MainLoop() + GLib.timeout_add(10, lambda: os.write(w, b'a') and False) + GLib.timeout_add(100, lambda: os.write(w, b'b') and False) + GLib.timeout_add(200, ml.quit) + ml.run() + + self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a', 'moo'), + (r, GLib.IOCondition.IN, b'b', 'moo')]) + + def test_io_add_watch_pyfile(self): + call_data = [] + + cmd = subprocess.Popen('sleep 0.1; echo hello; sleep 0.2; echo world', + shell=True, stdout=subprocess.PIPE) + + def cb(file, condition): + call_data.append((file, condition, file.readline())) + if len(call_data) == 2: + # avoid having to wait for the full timeout + ml.quit() + return True + + # io_add_watch() takes an IOChannel, calling with a Python file is deprecated + with warnings.catch_warnings(record=True) as warn: + warnings.simplefilter('always') + GLib.io_add_watch(cmd.stdout, GLib.IOCondition.IN, cb) + self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning)) + + ml = GLib.MainLoop() + GLib.timeout_add(2000, ml.quit) + ml.run() + + cmd.wait() + + self.assertEqual(call_data, [(cmd.stdout, GLib.IOCondition.IN, b'hello\n'), + (cmd.stdout, GLib.IOCondition.IN, b'world\n')]) + + def test_glib_version(self): + (major, minor, micro) = GLib.glib_version + self.assertGreaterEqual(major, 2) + self.assertGreaterEqual(minor, 0) + self.assertGreaterEqual(micro, 0) + + def test_pyglib_version(self): + (major, minor, micro) = GLib.pyglib_version + self.assertGreaterEqual(major, 3) + self.assertGreaterEqual(minor, 0) + self.assertGreaterEqual(micro, 0) |