/usr/lib/python3/dist-packages/plainbox/vendor/morris/test_morris.py is in python3-plainbox 0.25-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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | # Copyright 2012-2015 Canonical Ltd.
# Written by:
# Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
#
# This file is part of Morris.
#
# Morris 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 3 of the License
#
# Morris 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 Morris. If not, see <http://www.gnu.org/licenses/>.
"""
morris.tests
============
Test definitions for Morris
"""
from __future__ import print_function, absolute_import, unicode_literals
from unittest import TestCase
from doctest import DocTestSuite
from plainbox.vendor.morris import Signal
from plainbox.vendor.morris import SignalTestCase
from plainbox.vendor.morris import boundmethod
from plainbox.vendor.morris import remove_signals_listeners
from plainbox.vendor.morris import signal
from plainbox.vendor.morris import signaldescriptor
def load_tests(loader, tests, ignore):
from plainbox.vendor import morris
tests.addTests(DocTestSuite(morris))
return tests
class FakeSignalTestCase(SignalTestCase):
"""
A subclass of :class:`morris.SignalTestCase` that defines :meth:`runTest()`
"""
def runTest(self):
"""
An empty test method
"""
class SignalTestCaseTest(TestCase):
"""
Test definitions for the :class:`morris.SignalTestCase` class.
"""
def setUp(self):
self.signal = Signal('signal')
self.case = FakeSignalTestCase()
def test_watchSignal(self):
"""
Ensure that calling watchSignal() actually connects a signal listener
"""
self.assertEqual(len(self.signal.listeners), 0)
self.case.watchSignal(self.signal)
self.assertEqual(len(self.signal.listeners), 1)
def test_assertSignalFired(self):
"""
Ensure that assertSignalFired works correctly
"""
self.case.watchSignal(self.signal)
self.signal.fire((), {})
sig = self.case.assertSignalFired(self.signal)
self.assertEqual(sig, (self.signal, (), {}))
def test_assertSignalNotFired(self):
"""
Ensure that assertSignalNotFired works correctly
"""
self.case.watchSignal(self.signal)
self.case.assertSignalNotFired(self.signal)
def test_assertSignalOrdering(self):
"""
Ensure that assertSignalOrdering works correctly
"""
self.case.watchSignal(self.signal)
self.signal('first')
self.signal('second')
self.signal('third')
first = self.case.assertSignalFired(self.signal, 'first')
second = self.case.assertSignalFired(self.signal, 'second')
third = self.case.assertSignalFired(self.signal, 'third')
self.case.assertSignalOrdering(first, second, third)
class C1(object):
"""
Helper class with two signals defined using :meth:`Signal.define`
"""
def on_foo(self, *args, **kwargs):
"""
A signal accepting (ignoring) arbitrary arguments
"""
on_foo_func = on_foo
on_foo = Signal.define(on_foo)
@Signal.define
def on_bar(self):
"""
A signal accepting no arguments
"""
class C2(object):
"""
Helper class with two signals defined using :class:`morris.signal`
"""
def on_foo(self, *args, **kwargs):
"""
A signal accepting (ignoring) arbitrary arguments
"""
on_foo_func = on_foo
on_foo = signal(on_foo)
@signal
def on_bar(self):
"""
A signal accepting no arguments
"""
class NS(object):
"""
Helper namespace-like class
"""
def get_foo_bar():
"""
Helper function that returns two functions, on_foo() and on_bar(), similar
to what :class:`C1` and :class:`C2` define internally.
"""
def on_foo(*args, **kwargs):
"""
A signal accepting (ignoring) arbitrary arguments
"""
def on_bar():
"""
A signal accepting no arguments
"""
return on_foo, on_bar
def M1():
"""
Helper function that returns a module-like thing with two signals defined
using :meth:`Signal.define`
"""
on_foo, on_bar = get_foo_bar()
ns = NS()
ns.on_foo_func = on_foo
ns.on_foo = Signal.define(on_foo)
ns.on_bar = Signal.define(on_bar)
return ns
def M2():
"""
Helper function that returns a module-like thing with two signals defined
using :class:`signal`
"""
on_foo, on_bar = get_foo_bar()
ns = NS()
ns.on_foo_func = on_foo
ns.on_foo = signal(on_foo)
ns.on_bar = signal(on_bar)
return ns
class R(object):
"""
Helper class that collaborates with either :class:`C1` or :class:`C2`
"""
def __init__(self, c):
c.on_foo.connect(self._foo)
c.on_bar.connect(self._bar)
c.on_bar.connect(self._baz)
def _foo(self):
pass
def _bar(self):
pass
def _baz(self):
pass
class SignalTestsBase(object):
"""
Set of base test definitions for :class:`morris.Signal` class.
"""
def setUp(self):
self.c = self.get_c()
def test_sanity(self):
"""
Ensure that :meth:`get_c()` is not faulty
"""
self.assertIsInstance(self.c.on_foo, Signal)
self.assertNotIsInstance(self.c.on_foo_func, Signal)
self.assertNotIsInstance(self.c.on_foo_func, signaldescriptor)
self.assertEqual(len(self.c.on_foo.listeners), 1)
self.assertIsInstance(self.c.on_bar, Signal)
self.assertEqual(len(self.c.on_bar.listeners), 1)
def get_c(self):
raise NotImplementedError
def test_connect(self):
"""
Ensure that connecting signals works
"""
def handler():
pass
self.c.on_foo.connect(handler)
self.assertIn(
handler, (info.listener for info in self.c.on_foo.listeners))
def test_disconnect(self):
"""
Ensure that disconnecting signals works
"""
def handler():
pass
self.c.on_foo.connect(handler)
self.c.on_foo.disconnect(handler)
self.assertNotIn(
handler, (info.listener for info in self.c.on_foo.listeners))
def test_calling_signal_fires_them(self):
"""
Ensure that calling signals fires them
"""
self.watchSignal(self.c.on_foo)
self.c.on_foo()
self.assertSignalFired(self.c.on_foo)
def test_calling_signals_passes_positional_arguments(self):
"""
Ensure that calling the signal object with positional arguments works
"""
self.watchSignal(self.c.on_foo)
self.c.on_foo(1, 2, 3)
self.assertSignalFired(self.c.on_foo, 1, 2, 3)
def test_calling_signals_passes_keyword_arguments(self):
"""
Ensure that calling the signal object with keyword arguments works
"""
self.watchSignal(self.c.on_foo)
self.c.on_foo(one=1, two=2, three=3)
self.assertSignalFired(self.c.on_foo, one=1, two=2, three=3)
def test_remove_signals_listeners(self):
"""
Ensure that calling :func:`remove_signal_listeners()` works
"""
a = R(self.c)
b = R(self.c)
self.assertEqual(len(a.__listeners__), 3)
self.assertEqual(len(b.__listeners__), 3)
remove_signals_listeners(a)
self.assertEqual(len(a.__listeners__), 0)
self.assertEqual(len(b.__listeners__), 3)
class SignalsOnMethods(object):
"""
Mix-in for C1 and C2-based tests
"""
def test_first_responder(self):
"""
Ensure that using the decorator syntax connects the decorated object
as the first responder
"""
self.assertEqual(len(self.c.on_foo.listeners), 1)
# NOTE: this is a bit hairy. The ``signal`` decorator is always called
# on the bare function object (so on the ``on_foo`` function, before
# it becomes a method.
#
# To test that we need to extract the bare function (using the __func__
# property) from the (real) boundmethod that we see as
# self.c.on_foo_func.
#
# Then on top of that, the first responder is treated specially
# by ``signal.__get__()`` so that it creates a fake boundmethod
# (implemented in morris, not by python built-in) that stores the
# signal and the instance manually.
first_info = self.c.on_foo.listeners[0]
first_listener = first_info.listener
self.assertIsInstance(first_listener, boundmethod)
self.assertEqual(first_listener.instance, self.c)
self.assertEqual(first_listener.func, self.c.on_foo_func.__func__)
self.assertEqual(first_info.pass_signal, False)
class SignalsOnFunctions(object):
"""
Mix-in for M1 and M2-based tests
"""
def test_first_responder(self):
"""
Ensure that using the decorator syntax connects the decorated object as
the first responder
"""
self.assertEqual(len(self.c.on_foo.listeners), 1)
first_info = self.c.on_foo.listeners[0]
first_listener = first_info.listener
self.assertEqual(first_listener, self.c.on_foo_func)
self.assertEqual(first_info.pass_signal, False)
class SignalTestsC1(SignalTestsBase, SignalsOnMethods, SignalTestCase):
"""
Test definitions for :class:`morris.Signal` class that use :class:`C1`
"""
def get_c(self):
return C1()
class SignalTestsC2(SignalTestsBase, SignalsOnMethods, SignalTestCase):
"""
Test definitions for :class:`morris.Signal` class that use :class:`C2`
"""
def get_c(self):
return C2()
class SignalTestsM1(SignalTestsBase, SignalsOnFunctions, SignalTestCase):
"""
Test definitions for :class:`morris.Signal` class that use :func:`M1`
"""
def get_c(self):
return M1()
class SignalTestsM2(SignalTestsBase, SignalsOnFunctions, SignalTestCase):
"""
Test definitions for :class:`morris.Signal` class that use :func:`M2`
"""
def get_c(self):
return M2()
|