##// END OF EJS Templates
fixed None for type/sender
Barry Wark -
Show More
@@ -20,6 +20,12 b' class NotificationCenter(object):'
20 """Synchronous notification center"""
20 """Synchronous notification center"""
21 def __init__(self):
21 def __init__(self):
22 super(NotificationCenter, self).__init__()
22 super(NotificationCenter, self).__init__()
23 self._init_observers()
24
25
26 def _init_observers(self):
27 """Initialize observer storage"""
28
23 self.registeredTypes = set() #set of types that are observed
29 self.registeredTypes = set() #set of types that are observed
24 self.registeredSenders = set() #set of senders that are observed
30 self.registeredSenders = set() #set of senders that are observed
25 self.observers = {} #map (type,sender) => callback (callable)
31 self.observers = {} #map (type,sender) => callback (callable)
@@ -41,20 +47,34 b' class NotificationCenter(object):'
41 type and sender.")
47 type and sender.")
42
48
43 # If there are no registered observers for the type/sender pair
49 # If there are no registered observers for the type/sender pair
44 if((theType not in self.registeredTypes) or
50 if((theType not in self.registeredTypes and None not in self.registeredTypes) or
45 (sender not in self.registeredSenders)):
51 (sender not in self.registeredSenders and None not in self.registeredSenders)):
52 print theType,sender,self.registeredTypes,self.registeredSenders
46 return
53 return
47
54
48 keys = ((theType,sender), (None, sender), (theType, None), (None,None))
55 for o in self._observers_for_notification(theType, sender):
49 observers = set()
56 o(theType, sender, args=kwargs)
57
58
59 def _observers_for_notification(self, theType, sender):
60 """Find all registered observers that should recieve notification"""
61
62 keys = (
63 (theType,sender),
64 (theType, None),
65 (None, sender),
66 (None,None)
67 )
68
69
70 obs = set()
50 for k in keys:
71 for k in keys:
51 observers.update(self.observers.get(k, set()))
72 obs.update(self.observers.get(k, set()))
52
73
53 for o in observers:
74 return obs
54 o(theType, sender, args=kwargs)
55
75
56
76
57 def add_observer(self, observerCallback, theType, sender):
77 def add_observer(self, callback, theType, sender):
58 """Add an observer callback to this notification center.
78 """Add an observer callback to this notification center.
59
79
60 The given callback will be called upon posting of notifications of
80 The given callback will be called upon posting of notifications of
@@ -75,10 +95,15 b' class NotificationCenter(object):'
75 The notification sender. If None, all notifications of theType
95 The notification sender. If None, all notifications of theType
76 will be posted.
96 will be posted.
77 """
97 """
78 assert(observerCallback != None)
98 assert(callback != None)
79 self.registeredTypes.add(theType)
99 self.registeredTypes.add(theType)
80 self.registeredSenders.add(sender)
100 self.registeredSenders.add(sender)
81 self.observers.setdefault((theType,sender), set()).add(observerCallback)
101 self.observers.setdefault((theType,sender), set()).add(callback)
102
103 def remove_all_observers(self):
104 """Removes all observers from this notification center"""
105
106 self._init_observers()
82
107
83
108
84
109
@@ -15,8 +15,9 b' __docformat__ = "restructuredtext en"'
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 from IPython.kernel.core.notification import NotificationCenter,\
18 import unittest
19 sharedCenter
19 import IPython.kernel.core.notification as notification
20 from nose.tools import timed
20
21
21 #
22 #
22 # Supporting test classes
23 # Supporting test classes
@@ -24,13 +25,14 b' from IPython.kernel.core.notification import NotificationCenter,\\'
24
25
25 class Observer(object):
26 class Observer(object):
26 """docstring for Observer"""
27 """docstring for Observer"""
27 def __init__(self, expectedType, expectedSender, **kwargs):
28 def __init__(self, expectedType, expectedSender,
29 center=notification.sharedCenter, **kwargs):
28 super(Observer, self).__init__()
30 super(Observer, self).__init__()
29 self.expectedType = expectedType
31 self.expectedType = expectedType
30 self.expectedSender = expectedSender
32 self.expectedSender = expectedSender
31 self.expectedKwArgs = kwargs
33 self.expectedKwArgs = kwargs
32 self.recieved = False
34 self.recieved = False
33 sharedCenter.add_observer(self.callback,
35 center.add_observer(self.callback,
34 self.expectedType,
36 self.expectedType,
35 self.expectedSender)
37 self.expectedSender)
36
38
@@ -38,8 +40,10 b' class Observer(object):'
38 def callback(self, theType, sender, args={}):
40 def callback(self, theType, sender, args={}):
39 """callback"""
41 """callback"""
40
42
41 assert(theType == self.expectedType)
43 assert(theType == self.expectedType or
42 assert(sender == self.expectedSender)
44 self.expectedType == None)
45 assert(sender == self.expectedSender or
46 self.expectedSender == None)
43 assert(args == self.expectedKwArgs)
47 assert(args == self.expectedKwArgs)
44 self.recieved = True
48 self.recieved = True
45
49
@@ -49,6 +53,11 b' class Observer(object):'
49
53
50 assert(self.recieved)
54 assert(self.recieved)
51
55
56 def reset(self):
57 """reset"""
58
59 self.recieved = False
60
52
61
53
62
54 class Notifier(object):
63 class Notifier(object):
@@ -58,7 +67,7 b' class Notifier(object):'
58 self.theType = theType
67 self.theType = theType
59 self.kwargs = kwargs
68 self.kwargs = kwargs
60
69
61 def post(self, center=sharedCenter):
70 def post(self, center=notification.sharedCenter):
62 """fire"""
71 """fire"""
63
72
64 center.post_notification(self.theType, self,
73 center.post_notification(self.theType, self,
@@ -69,8 +78,13 b' class Notifier(object):'
69 # Test Cases
78 # Test Cases
70 #
79 #
71
80
81 class NotificationTests(unittest.TestCase):
82 """docstring for NotificationTests"""
83
84 def tearDown(self):
85 notification.sharedCenter.remove_all_observers()
72
86
73 def test_notification_delivered():
87 def test_notification_delivered(self):
74 """Test that notifications are delivered"""
88 """Test that notifications are delivered"""
75 expectedType = 'EXPECTED_TYPE'
89 expectedType = 'EXPECTED_TYPE'
76 sender = Notifier(expectedType)
90 sender = Notifier(expectedType)
@@ -81,7 +95,7 b' def test_notification_delivered():'
81 observer.verify()
95 observer.verify()
82
96
83
97
84 def test_type_specificity():
98 def test_type_specificity(self):
85 """Test that observers are registered by type"""
99 """Test that observers are registered by type"""
86
100
87 expectedType = 1
101 expectedType = 1
@@ -96,7 +110,7 b' def test_type_specificity():'
96 observer.verify()
110 observer.verify()
97
111
98
112
99 def test_sender_specificity():
113 def test_sender_specificity(self):
100 """Test that observers are registered by sender"""
114 """Test that observers are registered by sender"""
101
115
102 expectedType = "EXPECTED_TYPE"
116 expectedType = "EXPECTED_TYPE"
@@ -110,9 +124,56 b' def test_sender_specificity():'
110 observer.verify()
124 observer.verify()
111
125
112
126
113 def test_complexity_with_no_observers():
127 def test_remove_all_observers(self):
128 """White-box test for remove_all_observers"""
129
130 for i in xrange(10):
131 Observer('TYPE', None, center=notification.sharedCenter)
132
133 self.assert_(len(notification.sharedCenter.observers[('TYPE',None)]) >= 10,
134 "observers registered")
135
136 notification.sharedCenter.remove_all_observers()
137
138 self.assert_(len(notification.sharedCenter.observers) == 0, "observers removed")
139
140
141 def test_any_sender(self):
142 """test_any_sender"""
143
144 expectedType = "EXPECTED_TYPE"
145 sender1 = Notifier(expectedType)
146 sender2 = Notifier(expectedType)
147 observer = Observer(expectedType, None)
148
149
150 sender1.post()
151 observer.verify()
152
153 observer.reset()
154 sender2.post()
155 observer.verify()
156
157
158 @timed(.01)
159 def test_post_performance(self):
160 """Test that post_notification, even with many registered irrelevant
161 observers is fast"""
162
163 for i in xrange(10):
164 Observer("UNRELATED_TYPE", None)
165
166 o = Observer('EXPECTED_TYPE', None)
167
168 notification.sharedCenter.post_notification('EXPECTED_TYPE', self)
169
170 o.verify()
171
172
173 def test_complexity_with_no_observers(self):
114 """Test that the notification center's algorithmic complexity is O(1)
174 """Test that the notification center's algorithmic complexity is O(1)
115 with no registered observers (for the given notification type)
175 with no registered observers (for the given notification type)
116 """
176 """
117
177
118 assert(False) #I'm not sure how to test this yet
178 self.fail("I'm not sure how to test this.")
179
General Comments 0
You need to be logged in to leave comments. Login now