Some error handling/reporting fixes.
[pygobject.git] / tests / test_gio.py
blob05ab008ea83cdb976cb9a0ce42e477c38dac418b
1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
4 import unittest
6 import gi.overrides
7 from gi.repository import GLib, Gio
9 from helper import ignore_gi_deprecation_warnings
12 class TestGio(unittest.TestCase):
13 def test_file_enumerator(self):
14 self.assertEqual(Gio.FileEnumerator, gi.overrides.Gio.FileEnumerator)
15 f = Gio.file_new_for_path("./")
17 iter_info = []
18 for info in f.enumerate_children("standard::*", 0, None):
19 iter_info.append(info.get_name())
21 next_info = []
22 enumerator = f.enumerate_children("standard::*", 0, None)
23 while True:
24 info = enumerator.next_file(None)
25 if info is None:
26 break
27 next_info.append(info.get_name())
29 self.assertEqual(iter_info, next_info)
31 def test_menu_item(self):
32 menu = Gio.Menu()
33 item = Gio.MenuItem()
34 item.set_attribute([("label", "s", "Test"),
35 ("action", "s", "app.test")])
36 menu.append_item(item)
37 value = menu.get_item_attribute_value(0, "label", GLib.VariantType.new("s"))
38 self.assertEqual("Test", value.unpack())
39 value = menu.get_item_attribute_value(0, "action", GLib.VariantType.new("s"))
40 self.assertEqual("app.test", value.unpack())
43 class TestGSettings(unittest.TestCase):
44 def setUp(self):
45 self.settings = Gio.Settings.new('org.gnome.test')
46 # we change the values in the tests, so set them to predictable start
47 # value
48 self.settings.reset('test-string')
49 self.settings.reset('test-array')
50 self.settings.reset('test-boolean')
51 self.settings.reset('test-enum')
53 def test_native(self):
54 self.assertTrue('test-array' in self.settings.list_keys())
56 # get various types
57 v = self.settings.get_value('test-boolean')
58 self.assertEqual(v.get_boolean(), True)
59 self.assertEqual(self.settings.get_boolean('test-boolean'), True)
61 v = self.settings.get_value('test-string')
62 self.assertEqual(v.get_string(), 'Hello')
63 self.assertEqual(self.settings.get_string('test-string'), 'Hello')
65 v = self.settings.get_value('test-array')
66 self.assertEqual(v.unpack(), [1, 2])
68 v = self.settings.get_value('test-tuple')
69 self.assertEqual(v.unpack(), (1, 2))
71 # set a value
72 self.settings.set_string('test-string', 'World')
73 self.assertEqual(self.settings.get_string('test-string'), 'World')
75 self.settings.set_value('test-string', GLib.Variant('s', 'Goodbye'))
76 self.assertEqual(self.settings.get_string('test-string'), 'Goodbye')
78 def test_constructor(self):
79 # default constructor uses path from schema
80 self.assertEqual(self.settings.get_property('path'), '/tests/')
82 # optional constructor arguments
83 with_path = Gio.Settings.new_with_path('org.gnome.nopathtest', '/mypath/')
84 self.assertEqual(with_path.get_property('path'), '/mypath/')
85 self.assertEqual(with_path['np-int'], 42)
87 def test_dictionary_api(self):
88 self.assertEqual(len(self.settings), 5)
89 self.assertTrue('test-array' in self.settings)
90 self.assertTrue('test-array' in self.settings.keys())
91 self.assertFalse('nonexisting' in self.settings)
92 self.assertFalse(4 in self.settings)
93 self.assertEqual(bool(self.settings), True)
95 def test_get(self):
96 self.assertEqual(self.settings['test-boolean'], True)
97 self.assertEqual(self.settings['test-string'], 'Hello')
98 self.assertEqual(self.settings['test-enum'], 'banana')
99 self.assertEqual(self.settings['test-array'], [1, 2])
100 self.assertEqual(self.settings['test-tuple'], (1, 2))
102 self.assertRaises(KeyError, self.settings.__getitem__, 'unknown')
103 self.assertRaises(KeyError, self.settings.__getitem__, 2)
105 def test_set(self):
106 self.settings['test-boolean'] = False
107 self.assertEqual(self.settings['test-boolean'], False)
108 self.settings['test-string'] = 'Goodbye'
109 self.assertEqual(self.settings['test-string'], 'Goodbye')
110 self.settings['test-array'] = [3, 4, 5]
111 self.assertEqual(self.settings['test-array'], [3, 4, 5])
112 self.settings['test-enum'] = 'pear'
113 self.assertEqual(self.settings['test-enum'], 'pear')
115 self.assertRaises(TypeError, self.settings.__setitem__, 'test-string', 1)
116 self.assertRaises(ValueError, self.settings.__setitem__, 'test-enum', 'plum')
117 self.assertRaises(KeyError, self.settings.__setitem__, 'unknown', 'moo')
119 def test_empty(self):
120 empty = Gio.Settings.new_with_path('org.gnome.empty', '/tests/')
121 self.assertEqual(len(empty), 0)
122 self.assertEqual(bool(empty), True)
123 self.assertEqual(empty.keys(), [])
125 @ignore_gi_deprecation_warnings
126 def test_change_event(self):
127 changed_log = []
128 change_event_log = []
130 def on_changed(settings, key):
131 changed_log.append((settings, key))
133 def on_change_event(settings, keys, n_keys):
134 change_event_log.append((settings, keys, n_keys))
136 self.settings.connect('changed', on_changed)
137 self.settings.connect('change-event', on_change_event)
138 self.settings['test-string'] = 'Moo'
139 self.assertEqual(changed_log, [(self.settings, 'test-string')])
140 self.assertEqual(change_event_log, [(self.settings,
141 [GLib.quark_from_static_string('test-string')],
142 1)])
145 class TestGFile(unittest.TestCase):
146 def setUp(self):
147 self.file, self.io_stream = Gio.File.new_tmp('TestGFile.XXXXXX')
149 def tearDown(self):
150 try:
151 self.file.delete(None)
152 # test_delete and test_delete_async already remove it
153 except GLib.GError:
154 pass
156 def test_replace_contents(self):
157 content = b'hello\0world\x7F!'
158 succ, etag = self.file.replace_contents(content, None, False,
159 Gio.FileCreateFlags.NONE, None)
160 new_succ, new_content, new_etag = self.file.load_contents(None)
162 self.assertTrue(succ)
163 self.assertTrue(new_succ)
164 self.assertEqual(etag, new_etag)
165 self.assertEqual(content, new_content)
167 # https://bugzilla.gnome.org/show_bug.cgi?id=690525
168 def disabled_test_replace_contents_async(self):
169 content = b''.join(bytes(chr(i), 'utf-8') for i in range(128))
171 def callback(f, result, d):
172 # Quit so in case of failed assertations loop doesn't keep running.
173 main_loop.quit()
174 succ, etag = self.file.replace_contents_finish(result)
175 new_succ, new_content, new_etag = self.file.load_contents(None)
176 d['succ'], d['etag'] = self.file.replace_contents_finish(result)
177 load = self.file.load_contents(None)
178 d['new_succ'], d['new_content'], d['new_etag'] = load
180 data = {}
181 self.file.replace_contents_async(content, None, False,
182 Gio.FileCreateFlags.NONE, None,
183 callback, data)
184 main_loop = GLib.MainLoop()
185 main_loop.run()
186 self.assertTrue(data['succ'])
187 self.assertTrue(data['new_succ'])
188 self.assertEqual(data['etag'], data['new_etag'])
189 self.assertEqual(content, data['new_content'])
191 def test_tmp_exists(self):
192 # A simple test to check if Gio.File.new_tmp is working correctly.
193 self.assertTrue(self.file.query_exists(None))
195 def test_delete(self):
196 self.file.delete(None)
197 self.assertFalse(self.file.query_exists(None))
199 def test_delete_async(self):
200 def callback(f, result, data):
201 main_loop.quit()
203 self.file.delete_async(0, None, callback, None)
204 main_loop = GLib.MainLoop()
205 main_loop.run()
206 self.assertFalse(self.file.query_exists(None))
209 class TestGApplication(unittest.TestCase):
210 def test_command_line(self):
211 class App(Gio.Application):
212 args = None
214 def __init__(self):
215 super(App, self).__init__(flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
217 def do_command_line(self, cmdline):
218 self.args = cmdline.get_arguments()
219 return 42
221 app = App()
222 res = app.run(['spam', 'eggs'])
224 self.assertEqual(res, 42)
225 self.assertSequenceEqual(app.args, ['spam', 'eggs'])
227 def test_local_command_line(self):
228 class App(Gio.Application):
229 local_args = None
231 def __init__(self):
232 super(App, self).__init__(flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
234 def do_local_command_line(self, args):
235 self.local_args = args[:] # copy
236 args.remove('eggs')
238 # True skips do_command_line being called.
239 return True, args, 42
241 app = App()
242 res = app.run(['spam', 'eggs'])
244 self.assertEqual(res, 42)
245 self.assertSequenceEqual(app.local_args, ['spam', 'eggs'])
247 def test_local_and_remote_command_line(self):
248 class App(Gio.Application):
249 args = None
250 local_args = None
252 def __init__(self):
253 super(App, self).__init__(flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
255 def do_command_line(self, cmdline):
256 self.args = cmdline.get_arguments()
257 return 42
259 def do_local_command_line(self, args):
260 self.local_args = args[:] # copy
261 args.remove('eggs')
263 # False causes do_command_line to be called with args.
264 return False, args, 0
266 app = App()
267 res = app.run(['spam', 'eggs'])
269 self.assertEqual(res, 42)
270 self.assertSequenceEqual(app.args, ['spam'])
271 self.assertSequenceEqual(app.local_args, ['spam', 'eggs'])
273 @unittest.skipUnless(hasattr(Gio.Application, 'add_main_option'),
274 'Requires newer version of GLib')
275 def test_add_main_option(self):
276 stored_options = []
278 def on_handle_local_options(app, options):
279 stored_options.append(options)
280 return 0 # Return 0 if options have been handled
282 def on_activate(app):
283 pass
285 app = Gio.Application()
286 app.add_main_option(long_name='string',
287 short_name=b's',
288 flags=0,
289 arg=GLib.OptionArg.STRING,
290 description='some string')
292 app.connect('activate', on_activate)
293 app.connect('handle-local-options', on_handle_local_options)
294 app.run(['app', '-s', 'test string'])
296 self.assertEqual(len(stored_options), 1)
297 options = stored_options[0]
298 self.assertTrue(options.contains('string'))
299 self.assertEqual(options.lookup_value('string').unpack(),
300 'test string')