2
from twisted.trial import unittest
3
from twisted.internet import defer
4
from coherence.dispatcher import Dispatcher, UnknownSignal, Receiver, \
5
SignalingProperty, ChangedSignalingProperty, CustomSignalingProperty
7
class TestDispatcher(Dispatcher):
8
__signals__ = {'test': 'Test signal'}
10
class SimpleTarget(object):
22
def updater(self, arg1, arg2, value, arg4, key_a='p', variable=None):
23
setattr(self, variable, value)
24
setattr(self, "%s_%s" % (variable, arg2), key_a)
26
def plus(self, plus, variable=False):
27
setattr(self, variable, getattr(self, variable) + plus)
29
def fail_before(self, plus, variable=False):
31
self.update(plus, variable=variable)
33
class TestDispatching(unittest.TestCase):
36
self.called_counter = 0
37
self.dispatcher = TestDispatcher()
38
self.target = SimpleTarget()
40
def test_simple_emit(self):
42
receiver = self.dispatcher.connect('test', self.target.callback)
43
self.dispatcher.emit('test')
44
self.assertEquals(self.target.called, 1)
46
self.dispatcher.emit('test')
47
self.assertEquals(self.target.called, 2)
49
self.dispatcher.disconnect(receiver)
50
self.dispatcher.emit('test')
51
self.assertEquals(self.target.called, 2)
53
def test_simple_deferred_emit(self):
55
receiver = self.dispatcher.connect('test', self.target.callback)
56
self.dispatcher.deferred_emit('test')
57
self.assertEquals(self.target.called, 1)
59
self.dispatcher.deferred_emit('test')
60
self.assertEquals(self.target.called, 2)
62
self.dispatcher.disconnect(receiver)
63
self.dispatcher.deferred_emit('test')
64
self.assertEquals(self.target.called, 2)
66
def test_simple_save_emit(self):
69
return self.dispatcher.save_emit('test')
72
self.assertEquals(self.target.called, val)
75
receiver = self.dispatcher.connect('test', self.target.callback)
77
dfr = defer.succeed(None)
79
dfr.addCallback(test, 1)
81
dfr.addCallback(test, 2)
82
dfr.addCallback(lambda x: self.dispatcher.disconnect(receiver))
84
dfr.addCallback(test, 2)
87
def test_connect_typo(self):
88
self.assertRaises(UnknownSignal, self.dispatcher.connect, 'Test', None)
90
def test_disconnect_none_receiver(self):
92
trying to disconnect with None shouldn't fail, it is a valid use case
94
self.dispatcher.disconnect(None)
96
def test_disconnect_false_receiver(self):
98
this receiver isn't coming from this dispatcher
100
# this is REALLY constructed. you may *not* instantiate a Receiver yourself anyway
101
rec = Receiver('test', None, None, None)
102
self.dispatcher.disconnect(rec)
104
def test_disconnect_wrong_signal_receiver(self):
105
rec = Receiver('Test', None, None, None)
106
self.assertRaises(UnknownSignal, self.dispatcher.disconnect, rec)
108
def test_disconnect_not_receiver(self):
109
self.assertRaises(TypeError, self.dispatcher.disconnect, 'test')
111
def test_emit_false_signal(self):
112
self.assertRaises(UnknownSignal, self.dispatcher.emit, False)
114
def test_emit_without_receivers(self):
115
self.dispatcher.emit('test')
116
self.assertEquals(self.target.called, 0)
118
def test_emit_with_multiple_receiver(self):
119
rc1 = self.dispatcher.connect('test', self.target.updater,
120
1, 2, variable='va1')
121
rc2 = self.dispatcher.connect('test', self.target.updater,
122
'value', 2, variable='variable')
123
rc3 = self.dispatcher.connect('test', self.target.updater,
124
'other', 2, variable='one')
126
self.dispatcher.emit('test', self, 'other', key_a='q')
128
self.assertEquals(self.target.va1, 1)
129
self.assertEquals(self.target.va1_other, 'q')
131
self.assertEquals(self.target.variable, 'value')
132
self.assertEquals(self.target.variable_other, 'q')
134
self.assertEquals(self.target.one, 'other')
135
self.assertEquals(self.target.one_other, 'q')
137
# now removing the one in the middel
138
self.dispatcher.disconnect(rc2)
140
# and try again with other data
141
self.dispatcher.emit('test', self, 'other', key_a='thistime')
143
self.assertEquals(self.target.va1, 1)
144
self.assertEquals(self.target.va1_other, 'thistime')
146
self.assertEquals(self.target.variable, 'value')
147
self.assertEquals(self.target.variable_other, 'q')
149
self.assertEquals(self.target.one, 'other')
150
self.assertEquals(self.target.one_other, 'thistime')
153
self.dispatcher.emit('test', self, 'a')
154
# worked for rc1 and rc3 with the default value
155
self.assertEquals(self.target.va1_a, 'p')
156
self.assertEquals(self.target.one_a, 'p')
158
self.assertFalse(hasattr(self.target, 'variable_a'))
160
self.dispatcher.disconnect(rc1)
161
self.dispatcher.disconnect(rc3)
163
def test_emit_multiple_with_failing_in_between(self):
166
rc1 = self.dispatcher.connect('test', self.target.plus,
167
1, variable='called_a')
168
rc2 = self.dispatcher.connect('test', self.target.plus,
169
2, variable='called_b')
170
rc3 = self.dispatcher.connect('test', self.target.fail_before,
171
3, variable='called_c')
172
rc4 = self.dispatcher.connect('test', self.target.plus,
173
4, variable='called_d')
175
self.dispatcher.emit('test')
176
self.assertEquals(self.target.called_a, 1)
177
self.assertEquals(self.target.called_b, 2)
178
self.assertEquals(self.target.called_c, 0)
179
self.assertEquals(self.target.called_d, 4)
181
self.dispatcher.emit('test')
182
self.assertEquals(self.target.called_a, 2)
183
self.assertEquals(self.target.called_b, 4)
184
self.assertEquals(self.target.called_c, 0)
185
self.assertEquals(self.target.called_d, 8)
187
self.dispatcher.disconnect(rc1)
188
self.dispatcher.disconnect(rc2)
189
self.dispatcher.disconnect(rc3)
190
self.dispatcher.disconnect(rc4)
194
class TestReceiver(unittest.TestCase):
199
def _callback(self, *args, **kw):
204
def test_simple_calling(self):
205
rec = Receiver('test', self._callback, (), {})
206
self.assertEquals(rec.signal, 'test')
208
self.assertEquals(self.called, 1)
209
self.assertEquals(self.args, ())
210
self.assertEquals(self.kw, {})
213
self.assertEquals(self.called, 2)
214
self.assertEquals(self.args, ())
215
self.assertEquals(self.kw, {})
218
self.assertEquals(self.called, 3)
219
self.assertEquals(self.args, ())
220
self.assertEquals(self.kw, {})
222
def test_calling_with_args(self):
223
rec = Receiver('test', self._callback, (1, 2, 3), {'test': 'a'})
224
self.assertEquals(rec.signal, 'test')
226
self.assertEquals(self.called, 1)
227
self.assertEquals(self.args, (0, 1, 2, 3))
228
self.assertEquals(self.kw, {'test': 'a'})
231
self.assertEquals(self.called, 2)
232
self.assertEquals(self.args, (-1, 1, 2, 3))
233
self.assertEquals(self.kw, {'test': 'a'})
236
self.assertEquals(self.called, 3)
237
self.assertEquals(self.args, (-2, 1, 2, 3))
238
self.assertEquals(self.kw, {'test': 'a'})
240
def test_calling_with_kw(self):
241
rec = Receiver('test', self._callback, (1, 2, 3), {'test': 'a'})
242
self.assertEquals(rec.signal, 'test')
244
self.assertEquals(self.called, 1)
245
self.assertEquals(self.args, (1, 2, 3))
246
self.assertEquals(self.kw, {'test': 'a', 'p': 'q'})
249
self.assertEquals(self.called, 2)
250
self.assertEquals(self.args, (1, 2, 3))
251
self.assertEquals(self.kw, {'test': 'a', 'other': 'wise'})
254
self.assertEquals(self.called, 3)
255
self.assertEquals(self.args, (1, 2, 3))
256
self.assertEquals(self.kw, {'test': 'a', 'and_one': 'more'})
258
def test_calling_with_clashing_kw(self):
259
rec = Receiver('test', self._callback, (1, 2, 3), {'test': 'a', 'p': 'a'})
260
self.assertEquals(rec.signal, 'test')
262
self.assertEquals(self.called, 1)
263
self.assertEquals(self.args, (1, 2, 3))
264
self.assertEquals(self.kw, {'test': 'a', 'p': 'q'})
267
self.assertEquals(self.called, 2)
268
self.assertEquals(self.args, (1, 2, 3))
269
self.assertEquals(self.kw, {'test': 'a', 'other': 'wise', 'p': 'a'})
271
def test_calling_with_clashing_kw_and_args(self):
272
rec = Receiver('test', self._callback, (1, 2, 3), {'test': 'a', 'p': 'a'})
273
self.assertEquals(rec.signal, 'test')
276
self.assertEquals(self.called, 1)
277
self.assertEquals(self.args, (1, 2, 3))
278
self.assertEquals(self.kw, {'test': 'a', 'p': 'a'})
280
rec(1, 2, 7, test='True', o='p')
281
self.assertEquals(self.called, 2)
282
self.assertEquals(self.args, (1, 2, 7, 1, 2, 3))
283
self.assertEquals(self.kw, {'test': 'True', 'o': 'p', 'p': 'a'})
287
rec = Receiver('test', 'callback', (0, 1, 2), {})
288
self.assertIn('%s' % id(rec), '%r' % rec)
289
self.assertIn('test', '%r' % rec)
290
self.assertIn('callback', '%r' % rec)
291
self.assertIn('0, 1, 2', '%r' % rec)
293
# Signal Descriptor test
295
class SimpleSignaler(object):
296
simple = SignalingProperty('simple')
301
def emit(self, signal, *values, **kw):
302
self.emitted.append((signal, values, kw))
304
class DummySignaler(SimpleSignaler):
306
simple_with_default = SignalingProperty('simple2', default=0)
308
double_a = SignalingProperty('same-signal')
309
double_b = SignalingProperty('same-signal')
311
double_c = SignalingProperty('dif-var', var_name='_a')
312
double_d = SignalingProperty('dif-var', var_name='_b')
314
changer = ChangedSignalingProperty('state')
315
changer_with_default = ChangedSignalingProperty('state2', default='off')
327
def xset(self, value):
331
def xsq(self, value):
333
self._x = value * value
335
x = CustomSignalingProperty('x-changed', xget, xset)
336
x_square = CustomSignalingProperty('x-square', xget, xsq)
338
class TestSignalingDescriptors(unittest.TestCase):
341
self.signaler = DummySignaler()
343
def test_simple(self):
344
self.signaler.simple = 'A'
345
self._check(values=[('simple', ('A',), {})])
348
self.signaler.emitted = []
349
self.signaler.simple = 'A'
353
def test_simple_with_default(self):
354
self.signaler.simple_with_default = 'B'
355
self._check(values=[('simple2', ('B',), {})])
358
self.signaler.emitted = []
359
self.signaler.simple_with_default = 'B'
363
def test_changer(self):
364
self.signaler.changer = 'Yes'
365
self._check(values=[('state', ('Yes', None), {})])
368
self.signaler.emitted = []
369
self.signaler.changer = 'Yes'
373
def test_changer_with_default(self):
374
self.signaler.changer_with_default = 'another'
375
self._check(values=[('state2', ('another', 'off'), {})])
378
self.signaler.emitted = []
379
self.signaler.changer_with_default = 'another'
383
def test_double_same_var(self):
384
self.signaler.double_a = 'A1'
385
self.signaler.double_b = 'B2'
386
self._check(values=[('same-signal', ('A1',), {}),
387
('same-signal', ('B2',), {})])
390
self.signaler.emitted = []
391
# sending B2 over double a even thought it was changed by b
392
self.signaler.double_a = 'B2'
393
self.signaler.double_b = 'B2'
397
# but changing them different works
398
self.signaler.double_a = 'B1'
399
self.signaler.double_b = 'A2'
400
self._check(values=[('same-signal', ('B1',), {}),
401
('same-signal', ('A2',), {})])
403
def test_double_differnt_var(self):
404
self.signaler.double_c = 'A1'
405
self.signaler.double_d = 'B2'
406
self._check(values=[('dif-var', ('A1',), {}),
407
('dif-var', ('B2',), {})])
410
self.signaler.emitted = []
411
self.signaler.double_c = 'A1'
412
self.signaler.double_d = 'B2'
416
# but they still allow changes
417
self.signaler.double_c = 'B1'
418
self.signaler.double_d = 'A2'
419
self._check(values=[('dif-var', ('B1',), {}),
420
('dif-var', ('A2',), {})])
422
def test_custom(self):
423
self.signaler.x = 'Pocahontas'
424
self._check(values=[('x-changed', ('Pocahontas',), {})],
425
x='Pocahontas', x_get=2, x_set=1)
426
self.assertEquals(self.signaler.x, 'Pocahontas')
428
# settings again to the same value is boring me
429
self.signaler.emitted = []
430
self.signaler.x_get = 0
431
self.signaler.x_set = 0
433
self.signaler.x = 'Pocahontas'
434
self.assertEquals(self.signaler.emitted, [])
435
self.assertEquals(self.signaler.x, 'Pocahontas')
437
def test_custom_square(self):
438
self.signaler.x_square = 10
439
self._check(values=[('x-square', (100,), {})],
440
x=100, x_get=2, x_set=1)
441
self.assertEquals(self.signaler.x, 100)
443
def test_custom_square_nearly_the_same(self):
444
self.signaler._x = 10
445
self.signaler.x_square = 10
446
self._check(values=[('x-square', (100,), {})],
447
x=100, x_get=2, x_set=1)
448
self.assertEquals(self.signaler.x, 100)
450
def _check(self, values=[], x=0, x_set=0, x_get=0):
451
self.assertEquals(self.signaler._x, x)
452
self.assertEquals(self.signaler.x_set, x_set)
453
self.assertEquals(self.signaler.x_get, x_get)
454
self.assertEquals(self.signaler.emitted, values)
456
class TestStayInObjectSignaling(unittest.TestCase):
459
self.foo = SimpleSignaler()
460
self.bar = SimpleSignaler()
462
def test_double_different_values(self):
463
self.foo.simple = 'A'
464
self.bar.simple = 'B'
465
self.assertEquals(self.foo.simple, 'A')
466
self.assertEquals(self.bar.simple, 'B')
467
self.assertEquals(len(self.foo.emitted), 1)
468
self.assertEquals(len(self.bar.emitted), 1)
470
self.assertEquals(self.foo.emitted[0][1][0], 'A')
471
self.assertEquals(self.bar.emitted[0][1][0], 'B')