+ print '%s.notify() got the message "%s"' %(self.number, message)
+ def __str__(self):
+ return "SimpleListener_%s" % self.number
+
+ def testSubscribe():
+ publisher = Publisher()
+
+ topic1 = 'politics'
+ topic2 = ('history','middle age')
+ topic3 = ('politics','UN')
+ topic4 = ('politics','NATO')
+ topic5 = ('politics','NATO','US')
+
+ lisnr1 = SimpleListener(1)
+ lisnr2 = SimpleListener(2)
+ def func(message, a=1):
+ print 'Func received message "%s"' % message
+ lisnr3 = func
+ lisnr4 = lambda x: 'Lambda received message "%s"' % x
+
+ assert not publisher.isSubscribed(lisnr1)
+ assert not publisher.isSubscribed(lisnr2)
+ assert not publisher.isSubscribed(lisnr3)
+ assert not publisher.isSubscribed(lisnr4)
+
+ publisher.subscribe(lisnr1, topic1)
+ assert publisher.getAssociatedTopics(lisnr1) == [(topic1,)]
+ publisher.subscribe(lisnr1, topic2)
+ publisher.subscribe(lisnr1, topic1) # do it again, should be no-op
+ assert publisher.getAssociatedTopics(lisnr1) == [(topic1,),topic2]
+ publisher.subscribe(lisnr2.notify, topic3)
+ assert publisher.getAssociatedTopics(lisnr2.notify) == [topic3]
+ assert publisher.getAssociatedTopics(lisnr1) == [(topic1,),topic2]
+ publisher.subscribe(lisnr3, topic5)
+ assert publisher.getAssociatedTopics(lisnr3) == [topic5]
+ assert publisher.getAssociatedTopics(lisnr2.notify) == [topic3]
+ assert publisher.getAssociatedTopics(lisnr1) == [(topic1,),topic2]
+ publisher.subscribe(lisnr4)
+
+ print "Publisher tree: ", publisher
+ assert publisher.isSubscribed(lisnr1)
+ assert publisher.isSubscribed(lisnr1, topic1)
+ assert publisher.isSubscribed(lisnr1, topic2)
+ assert publisher.isSubscribed(lisnr2.notify)
+ assert publisher.isSubscribed(lisnr3, topic5)
+ assert publisher.isSubscribed(lisnr4, ALL_TOPICS)
+ expectTopicTree = 'all: <lambda> (politics: SimpleListener_1 (UN: SimpleListener_2.notify ) (NATO: (US: func ))) (history: (middle age: SimpleListener_1 ))'
+ print "Publisher tree: ", publisher
+ assert str(publisher) == expectTopicTree
+
+ publisher.unsubscribe(lisnr1, 'booboo') # should do nothing
+ assert publisher.getAssociatedTopics(lisnr1) == [(topic1,),topic2]
+ assert publisher.getAssociatedTopics(lisnr2.notify) == [topic3]
+ assert publisher.getAssociatedTopics(lisnr3) == [topic5]
+ publisher.unsubscribe(lisnr1, topic1)
+ assert publisher.getAssociatedTopics(lisnr1) == [topic2]
+ assert publisher.getAssociatedTopics(lisnr2.notify) == [topic3]
+ assert publisher.getAssociatedTopics(lisnr3) == [topic5]
+ publisher.unsubscribe(lisnr1, topic2)
+ publisher.unsubscribe(lisnr1, topic2)
+ publisher.unsubscribe(lisnr2.notify, topic3)
+ publisher.unsubscribe(lisnr3, topic5)
+ assert publisher.getAssociatedTopics(lisnr1) == []
+ assert publisher.getAssociatedTopics(lisnr2.notify) == []
+ assert publisher.getAssociatedTopics(lisnr3) == []
+ publisher.unsubscribe(lisnr4)
+
+ expectTopicTree = 'all: (politics: (UN: ) (NATO: (US: ))) (history: (middle age: ))'
+ print "Publisher tree: ", publisher
+ assert str(publisher) == expectTopicTree
+ assert publisher.getDeliveryCount() == 0
+ assert publisher.getMessageCount() == 0
+
+ publisher.unsubAll()
+ assert str(publisher) == 'all: '
+
+ done('testSubscribe')
+
+ testSubscribe()
+ #------------------------
+
+ def testUnsubAll():
+ publisher = Publisher()
+
+ topic1 = 'politics'
+ topic2 = ('history','middle age')
+ topic3 = ('politics','UN')
+ topic4 = ('politics','NATO')
+ topic5 = ('politics','NATO','US')
+
+ lisnr1 = SimpleListener(1)
+ lisnr2 = SimpleListener(2)
+ def func(message, a=1):
+ print 'Func received message "%s"' % message
+ lisnr3 = func
+ lisnr4 = lambda x: 'Lambda received message "%s"' % x
+
+ publisher.subscribe(lisnr1, topic1)
+ publisher.subscribe(lisnr1, topic2)
+ publisher.subscribe(lisnr2.notify, topic3)
+ publisher.subscribe(lisnr3, topic2)
+ publisher.subscribe(lisnr3, topic5)
+ publisher.subscribe(lisnr4)
+
+ expectTopicTree = 'all: <lambda> (politics: SimpleListener_1 (UN: SimpleListener_2.notify ) (NATO: (US: func ))) (history: (middle age: SimpleListener_1 func ))'
+ print "Publisher tree: ", publisher
+ assert str(publisher) == expectTopicTree
+
+ publisher.unsubAll(topic1)
+ assert publisher.getAssociatedTopics(lisnr1) == [topic2]
+ assert not publisher.isSubscribed(lisnr1, topic1)
+
+ publisher.unsubAll(topic2)
+ print publisher
+ assert publisher.getAssociatedTopics(lisnr1) == []
+ assert publisher.getAssociatedTopics(lisnr3) == [topic5]
+ assert not publisher.isSubscribed(lisnr1)
+ assert publisher.isSubscribed(lisnr3, topic5)
+
+ #print "Publisher tree: ", publisher
+ expectTopicTree = 'all: <lambda> (politics: (UN: SimpleListener_2.notify ) (NATO: (US: func ))) (history: (middle age: ))'
+ assert str(publisher) == expectTopicTree
+ publisher.unsubAll(ALL_TOPICS)
+ #print "Publisher tree: ", publisher
+ expectTopicTree = 'all: (politics: (UN: SimpleListener_2.notify ) (NATO: (US: func ))) (history: (middle age: ))'
+ assert str(publisher) == expectTopicTree
+
+ publisher.unsubAll()
+ done('testUnsubAll')
+
+ testUnsubAll()
+ #------------------------
+
+ def testSend():
+ publisher = Publisher()
+ called = []
+
+ class TestListener:
+ def __init__(self, num):
+ self.number = num
+ def __call__(self, b):
+ called.append( 'TL%scb' % self.number )
+ def notify(self, b):
+ called.append( 'TL%sm' % self.number )
+ def funcListener(b):
+ called.append('func')
+
+ lisnr1 = TestListener(1)
+ lisnr2 = TestListener(2)
+ lisnr3 = funcListener
+ lisnr4 = lambda x: called.append('lambda')
+
+ topic1 = 'politics'
+ topic2 = 'history'
+ topic3 = ('politics','UN')
+ topic4 = ('politics','NATO','US')
+ topic5 = ('politics','NATO')
+
+ publisher.subscribe(lisnr1, topic1)
+ publisher.subscribe(lisnr2, topic2)
+ publisher.subscribe(lisnr2.notify, topic2)
+ publisher.subscribe(lisnr3, topic4)
+ publisher.subscribe(lisnr4)
+
+ print publisher
+
+ # setup ok, now test send/receipt
+ publisher.sendMessage(topic1)
+ assert called == ['lambda','TL1cb']
+ called = []
+ publisher.sendMessage(topic2)
+ assert called == ['lambda','TL2cb','TL2m']
+ called = []
+ publisher.sendMessage(topic3)
+ assert called == ['lambda','TL1cb']
+ called = []
+ publisher.sendMessage(topic4)
+ assert called == ['lambda','TL1cb','func']
+ called = []
+ publisher.sendMessage(topic5)
+ assert called == ['lambda','TL1cb']
+ assert publisher.getDeliveryCount() == 12
+ assert publisher.getMessageCount() == 5
+
+ # test weak referencing works:
+ _NodeCallback.notified = 0
+ del lisnr2
+ called = []
+ publisher.sendMessage(topic2)
+ assert called == ['lambda']
+ assert _NodeCallback.notified == 2
+
+ done('testSend')
+
+ testSend()
+ assert _NodeCallback.notified == 5
+
+ def testDead():
+ # verify if weak references work as expected
+ print '------ Starting testDead ----------'
+ node = _TopicTreeNode('t1', None)
+ lisnr1 = SimpleListener(1)
+ lisnr2 = SimpleListener(2)
+ lisnr3 = SimpleListener(3)
+ lisnr4 = SimpleListener(4)
+
+ node.addCallable(lisnr1)
+ node.addCallable(lisnr2)
+ node.addCallable(lisnr3)
+ node.addCallable(lisnr4)
+
+ print 'Deleting listeners first'
+ _NodeCallback.notified = 0
+ del lisnr1
+ del lisnr2
+ assert _NodeCallback.notified == 2
+
+ print 'Deleting node first'
+ _NodeCallback.notified = 0
+ del node
+ del lisnr3
+ del lisnr4
+ assert _NodeCallback.notified == 0
+
+ lisnr1 = SimpleListener(1)
+ lisnr2 = SimpleListener(2)
+ lisnr3 = SimpleListener(3)
+ lisnr4 = SimpleListener(4)
+
+ # try same with root of tree
+ node = _TopicTreeRoot()
+ node.addTopic(('',), lisnr1)
+ node.addTopic(('',), lisnr2)
+ node.addTopic(('',), lisnr3)
+ node.addTopic(('',), lisnr4)
+ # add objects that will die immediately to see if cleanup occurs
+ # this must be done visually as it is a low-level detail
+ _NodeCallback.notified = 0
+ _TopicTreeRoot.callbackDeadLimit = 3
+ node.addTopic(('',), SimpleListener(5))
+ node.addTopic(('',), SimpleListener(6))
+ node.addTopic(('',), SimpleListener(7))
+ print node.numListeners()
+ assert node.numListeners() == (4, 3)
+ node.addTopic(('',), SimpleListener(8))
+ assert node.numListeners() == (4, 0)
+ assert _NodeCallback.notified == 4
+
+ print 'Deleting listeners first'
+ _NodeCallback.notified = 0
+ del lisnr1
+ del lisnr2
+ assert _NodeCallback.notified == 2
+ print 'Deleting node first'
+ _NodeCallback.notified = 0
+ del node
+ del lisnr3
+ del lisnr4
+ assert _NodeCallback.notified == 0
+
+ done('testDead')
+
+ testDead()
+
+ print 'Exiting tests'