/usr/lib/python2.7/dist-packages/traits/tests/test_ui_notifiers.py is in python-traits 4.6.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | """ Tests for dynamic notifiers with `dispatch='ui'`.
Dynamic notifiers created with the `dispatch='ui'` option dispatch event
notifications on the UI thread. The class handling the dispatch,
`FastUITraitChangeNotifyWrapper`, is a subclass of `TraitChangeNotifyWrapper`.
Most of the functionality of the class is thus already covered by the
`TestDynamicNotifiers` test case, and we only need to test that the
notification really occurs on the UI thread.
At present, `dispatch='ui'` and `dispatch='fast_ui'` have the same effect.
"""
# Preamble: Try importing Qt, and set QT_FOUND to True on success.
try:
from pyface.util.guisupport import get_app_qt4, start_event_loop_qt4
# This import is necessary to set the `ui_handler` global variable in
# `traits.trait_notifiers`, which is responsible for dispatching the events
# to the UI thread.
from traitsui.qt4 import toolkit
qt4_app = get_app_qt4()
except Exception:
QT_FOUND = False
else:
QT_FOUND = True
import thread
from threading import Thread
import time
from traits.api import Callable, Float, HasTraits, on_trait_change
from traits.testing.unittest_tools import unittest
from traits import trait_notifiers
class CalledAsMethod(HasTraits):
foo = Float
class CalledAsDecorator(HasTraits):
foo = Float
callback = Callable
@on_trait_change('foo', dispatch='ui')
def on_foo_change(self, obj, name, old, new):
self.callback(obj, name, old, new)
class BaseTestUINotifiers(object):
""" Tests for dynamic notifiers with `dispatch='ui'`.
"""
#### 'TestCase' protocol ##################################################
def setUp(self):
self.notifications = []
#### 'TestUINotifiers' protocol ###########################################
def flush_event_loop(self):
""" Post and process the Qt events. """
qt4_app.sendPostedEvents()
qt4_app.processEvents()
def on_foo_notifications(self, obj, name, old, new):
thread_id = thread.get_ident()
event = (thread_id, (obj, name, old, new))
self.notifications.append(event)
#### Tests ################################################################
@unittest.skipIf(
not QT_FOUND, "Qt event loop not found, UI dispatch not possible.")
def test_notification_from_main_thread(self):
obj = self.obj_factory()
obj.foo = 3
self.flush_event_loop()
notifications = self.notifications
self.assertEqual(len(notifications), 1)
thread_id, event = notifications[0]
self.assertEqual(event, (obj, 'foo', 0, 3))
ui_thread = trait_notifiers.ui_thread
self.assertEqual(thread_id, ui_thread)
@unittest.skipIf(
not QT_FOUND, "Qt event loop not found, UI dispatch not possible.")
def test_notification_from_separate_thread(self):
obj = self.obj_factory()
# Set obj.foo to 3 on a separate thread.
def set_foo_to_3(obj):
obj.foo = 3
Thread(target=set_foo_to_3, args=(obj,)).start()
# Wait for a while to make sure the function has finished.
time.sleep(0.1)
self.flush_event_loop()
notifications = self.notifications
self.assertEqual(len(notifications), 1)
thread_id, event = notifications[0]
self.assertEqual(event, (obj, 'foo', 0, 3))
ui_thread = trait_notifiers.ui_thread
self.assertEqual(thread_id, ui_thread)
class TestMethodUINotifiers(BaseTestUINotifiers, unittest.TestCase):
""" Tests for dynamic notifiers with `dispatch='ui'` set by method call.
"""
def obj_factory(self):
obj = CalledAsMethod()
obj.on_trait_change(self.on_foo_notifications, 'foo', dispatch='ui')
return obj
class TestDecoratorUINotifiers(BaseTestUINotifiers, unittest.TestCase):
""" Tests for dynamic notifiers with `dispatch='ui'` set by decorator. """
def obj_factory(self):
return CalledAsDecorator(callback=self.on_foo_notifications)
if __name__ == '__main__':
unittest.main()
|