# -*- coding: utf-8 -*- # libavg - Media Playback Engine. # Copyright (C) 2003-2014 Ulrich von Zadow # # This library 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 2 of the License, or (at your option) any later version. # # This library 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 this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Current versions can be found at www.libavg.de # from libavg import avg, player from testcase import * def dumpMouseEvent(Event): print Event print " type: "+str(Event.type) print " leftbuttonstate: "+str(Event.leftbuttonstate) print " middlebuttonstate: "+str(Event.middlebuttonstate) print " rightbuttonstate: "+str(Event.rightbuttonstate) print " position: "+str(Event.x)+","+str(Event.y) print " node: "+Event.node.id mainMouseUpCalled = False mainMouseDownCalled = False def mainMouseUp(Event): global mainMouseUpCalled assert (Event.type == avg.Event.CURSOR_UP) mainMouseUpCalled = True def mainMouseDown(Event): global mainMouseDownCalled assert (Event.type == avg.Event.CURSOR_DOWN) mainMouseDownCalled = True class EventTestCase(AVGTestCase): def __init__(self, testFuncName): AVGTestCase.__init__(self, testFuncName) def testKeyEvents(self): def onKeyDown(event): if event.keystring == 'A' and event.keycode == 65 and event.unicode == 65: self.keyDownCalled = True def onKeyUp(event): if event.keystring == 'A' and event.keycode == 65 and event.unicode == 65: self.keyUpCalled = True def onSubscribeKeyDown(event): self.subscribeKeyDownCalled = True def onSubscribeKeyUp(event): self.subscribeKeyUpCalled = True root = self.loadEmptyScene() root.setEventHandler(avg.Event.KEY_DOWN, avg.Event.NONE, onKeyDown) root.setEventHandler(avg.Event.KEY_UP, avg.Event.NONE, onKeyUp) player.subscribe(avg.Player.KEY_DOWN, onSubscribeKeyDown) player.subscribe(avg.Player.KEY_UP, onSubscribeKeyUp) self.start(False, (lambda: Helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65, avg.KEYMOD_NONE), lambda: self.assert_(self.keyDownCalled and self.subscribeKeyDownCalled), lambda: Helper.fakeKeyEvent(avg.Event.KEY_UP, 65, 65, "A", 65, avg.KEYMOD_NONE), lambda: self.assert_(self.keyUpCalled and self.subscribeKeyUpCalled) )) def testSimpleEvents(self): def getMouseState(): Event = player.getMouseState() self.assertEqual(Event.pos, avg.Point2D(10,10)) root = self.loadEmptyScene() img1 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) handlerTester1 = NodeHandlerTester(self, img1) img2 = avg.ImageNode(pos=(64,0), href="rgb24-65x65.png", parent=root) handlerTester2 = NodeHandlerTester(self, img2) self.start(False, (# down, getMouseState(), move, up. # events are inside img1 but outside img2. lambda: self.assert_(not(player.isMultitouchAvailable())), lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: handlerTester1.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), lambda: handlerTester2.assertState(()), getMouseState, lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 12, 12), lambda: handlerTester1.assertState((avg.Node.CURSOR_MOTION,)), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 12, 12), lambda: handlerTester1.assertState((avg.Node.CURSOR_UP,)) )) def testTilted(self): root = self.loadEmptyScene() img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", angle=0.785, parent=root) handlerTester = NodeHandlerTester(self, img) self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 32, 32), lambda: handlerTester.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 0, 0), lambda: handlerTester.assertState((avg.Node.CURSOR_OUT,)), )) def testWordsClicks(self): root = self.loadEmptyScene() words = avg.WordsNode(pos=(40,40), alignment="right", text="test", parent=root) handlerTester = NodeHandlerTester(self, words) self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 45, 45), lambda: handlerTester.assertState(()), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 35, 45), lambda: handlerTester.assertState( (avg.Node.CURSOR_UP, avg.Node.CURSOR_OVER)), )) def testDivEvents(self): root = self.loadEmptyScene() div = avg.DivNode(pos=(0,0), parent=root) divHandlerTester = NodeHandlerTester(self, div) img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=div) imgHandlerTester = NodeHandlerTester(self, img) self.start(False, (# down, move, up. # events are inside img and therefore should bubble to div. lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: divHandlerTester.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), lambda: imgHandlerTester.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 12, 12), lambda: divHandlerTester.assertState((avg.Node.CURSOR_MOTION,)), lambda: imgHandlerTester.assertState((avg.Node.CURSOR_MOTION,)), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 12, 12), lambda: divHandlerTester.assertState((avg.Node.CURSOR_UP,)), lambda: imgHandlerTester.assertState((avg.Node.CURSOR_UP,)) )) def testDivNegativePos(self): root = self.loadEmptyScene() div = avg.DivNode(pos=(10,10), parent=root) divHandlerTester = NodeHandlerTester(self, div) img = avg.ImageNode(pos=(-10,-10), href="rgb24-65x65.png", parent=div) imgHandlerTester = NodeHandlerTester(self, img) self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 1, 1), lambda: divHandlerTester.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), lambda: imgHandlerTester.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), )) def testUnlinkInHandler(self): def onImgDown(event): self.__imgDownCalled = True self.div.unlink(True) def onDivDown(event): self.__divDownCalled = True def checkState(): self.assert_(self.__imgDownCalled and not(self.__divDownCalled)) self.__imgDownCalled = False self.__divDownCalled = False root = self.loadEmptyScene() self.div = avg.DivNode(pos=(0,0), parent=root) self.div.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self, onDivDown) img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=self.div) img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self, onImgDown) self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), checkState)) def testConnectHandler(self): def onDown1(event): self.down1Called = True def onDown2(event): self.down2Called = True def resetDownCalled(): self.down1Called = False self.down2Called = False def connectTwoHandlers(): self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self, onDown1) self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self, onDown2) def connectUnlinkHandler(): self.img.disconnectEventHandler(self) self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self, unlinkHandler) self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self, onDown2) def unlinkHandler(event): self.img.disconnectEventHandler(self) root = self.loadEmptyScene() self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) connectTwoHandlers() self.img.disconnectEventHandler(self, onDown1) self.img.disconnectEventHandler(self, onDown2) connectTwoHandlers() self.img.disconnectEventHandler(self) resetDownCalled() self.start(False, (connectTwoHandlers, lambda: self.fakeClick(10,10), lambda: self.assert_(self.down1Called and self.down2Called), resetDownCalled, lambda: self.img.disconnectEventHandler(self, onDown1), lambda: self.fakeClick(10,10), lambda: self.assert_(not(self.down1Called) and self.down2Called), connectUnlinkHandler, lambda: self.fakeClick(10,10), )) def testPublisher(self): def onDown(event): self.assert_(event.type == avg.Event.CURSOR_DOWN) curEvent = player.getCurrentEvent() self.assert_(curEvent.type == avg.Event.CURSOR_DOWN) self.assert_(curEvent.when == event.when) self.downCalled = True def unsubscribe(): self.assert_(self.img.isSubscribed(avg.Node.CURSOR_DOWN, onDown)) self.img.unsubscribe(avg.Node.CURSOR_DOWN, onDown) self.assert_(not(self.img.isSubscribed(avg.Node.CURSOR_DOWN, onDown))) self.assert_(self.img.getNumSubscribers(avg.Node.CURSOR_DOWN) == 0) self.downCalled = False self.assertException( lambda: self.img.unsubscribe(avg.Node.CURSOR_DOWN, onDown)) def initUnsubscribeInEvent(useMessageID): self.subscriberID = self.img.subscribe(avg.Node.CURSOR_DOWN, lambda event: onDownUnsubscribe(event, useMessageID)) def onDownUnsubscribe(event, useMessageID): if useMessageID: self.img.unsubscribe(avg.Node.CURSOR_DOWN, self.subscriberID) self.assertException(lambda: self.img.unsubscribe(avg.Node.CURSOR_DOWN, self.subscriberID)) else: self.img.unsubscribe(self.subscriberID) self.assertException(lambda: self.img.unsubscribe(self.subscriberID)) self.downCalled = True def onFrame(): self.onFrameCalled = True self.downCalled = False self.onFrameCalled = False root = self.loadEmptyScene() player.subscribe(player.ON_FRAME, onFrame) self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) self.img.subscribe(avg.Node.CURSOR_DOWN, onDown) self.assertException(lambda: self.img.subscribe(23, onDown)) self.assertException(lambda: self.img.unsubscribe(avg.Node.CURSOR_DOWN, 23)) self.start(False, (lambda: self.fakeClick(10,10), lambda: self.assert_(self.downCalled), lambda: self.assert_(self.onFrameCalled), unsubscribe, lambda: self.fakeClick(10,10), lambda: self.assert_(not(self.downCalled)), lambda: initUnsubscribeInEvent(True), lambda: self.fakeClick(10,10), lambda: self.assert_(self.downCalled), lambda: initUnsubscribeInEvent(False), lambda: self.fakeClick(10,10), lambda: self.assert_(self.downCalled), )) def testComplexPublisher(self): def setupUnsubscribe(): self.downCalled = [False, False] self.msgIDs = [] for i in range(0,2): self.msgIDs.append(self.img.subscribe(avg.Node.CURSOR_DOWN, lambda event, i=i: onUnsubscribeDown(i))) def onUnsubscribeDown(i): self.downCalled[i] = True for j in range(0,2): self.img.unsubscribe(avg.Node.CURSOR_DOWN, self.msgIDs[j]) def assertCorrectUnsubscribe(): # Exactly one of the two callbacks should have been invoked self.assert_(self.downCalled[0] != self.downCalled[1]) def setupSubscribe(): self.downCalled = [False, False] self.msgIDs = [] self.msgIDs.append(self.img.subscribe(avg.Node.CURSOR_DOWN, lambda event: onSubscribeDown())) def onSubscribeDown(): self.downCalled[0] = True self.msgIDs.append(self.img.subscribe(avg.Node.CURSOR_DOWN, lambda event: onSecondSubscribeDown())) def onSecondSubscribeDown(): self.downCalled[1] = True def assertDownsCalled(expectedState): self.assert_(self.downCalled == expectedState) root = self.loadEmptyScene() self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) self.start(False, (# Subscribe twice to an event, unsubscribe both during processing of the # first. Second shouldn't be called anymore. lambda: setupUnsubscribe(), lambda: self.fakeClick(10,10), assertCorrectUnsubscribe, # Subscribe to an event, subscribe again during event processing. # The second one shouldn't be called immediately. lambda: setupSubscribe(), lambda: self.fakeClick(10,10), lambda: assertDownsCalled([True, False]), lambda: self.fakeClick(10,10), lambda: assertDownsCalled([True, True]), )) def testPublisherAutoDelete(self): class TestSubscriber(): def __init__(self): self.__downCalled = False def subscribe(self, node): node.subscribe(avg.Node.CURSOR_DOWN, self.onDown) def subscribeLambda(self, node): node.subscribe(avg.Node.CURSOR_DOWN, lambda event: self.onDown(event)) def onDown(self, event): self.__downCalled = True def hasClicked(self): return self.__downCalled def removeSubscriber(): del self.subscriber; root = self.loadEmptyScene() self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) self.subscriber = TestSubscriber() self.subscriber.subscribe(self.img) self.start(False, (lambda: self.fakeClick(10,10), lambda: self.assert_(self.subscriber.hasClicked()), removeSubscriber, lambda: self.fakeClick(10,10), lambda: self.assert_( self.img.getNumSubscribers(avg.Node.CURSOR_DOWN) == 0) )) def testPublisherNestedUnsubscribe(self): class TestPublisher(avg.Publisher): OUTER_EVENT = avg.Publisher.genMessageID() INNER_EVENT = avg.Publisher.genMessageID() def __init__(self): super(TestPublisher, self).__init__() self.publish(TestPublisher.OUTER_EVENT) self.publish(TestPublisher.INNER_EVENT) def generateEvent(self): self.notifySubscribers(TestPublisher.OUTER_EVENT, []) def generateInnerEvent(self): self.notifySubscribers(TestPublisher.INNER_EVENT, []) def onEvent(): self.publisher.generateInnerEvent() def onEvent2(): self.event2Called = True; def onInnerEvent(): self.publisher.unsubscribe(TestPublisher.OUTER_EVENT, onEvent) self.publisher.unsubscribe(TestPublisher.OUTER_EVENT, onEvent2) self.loadEmptyScene() self.publisher = TestPublisher() self.publisher.subscribe(TestPublisher.OUTER_EVENT, onEvent2) self.publisher.subscribe(TestPublisher.OUTER_EVENT, onEvent) self.publisher.subscribe(TestPublisher.INNER_EVENT, onInnerEvent) self.event2Called = False self.start(False, (self.publisher.generateEvent, )) self.assert_(not(self.event2Called)) def testObscuringEvents(self): root = self.loadEmptyScene() img1 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) handlerTester1 = NodeHandlerTester(self, img1) img2 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) handlerTester2 = NodeHandlerTester(self, img2) self.start(False, (# down, move, up. # events should only arrive at img2 because img1 is obscured by img1. lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: handlerTester1.assertState(()), lambda: handlerTester2.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 12, 12), lambda: handlerTester1.assertState(()), lambda: handlerTester2.assertState((avg.Node.CURSOR_MOTION,)), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 12, 12), lambda: handlerTester1.assertState(()), lambda: handlerTester2.assertState((avg.Node.CURSOR_UP,)) )) def testSensitive(self): # Tests both sensitive and active attributes. def activateNode(node, useSensitiveAttr, b): if useSensitiveAttr: node.sensitive = b else: node.active = b def onNode2Down(event): self.__node2Down = True for useSensitiveAttr in (True, False): root = self.loadEmptyScene() self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) handlerTester = NodeHandlerTester(self, self.img) activateNode(self.img, useSensitiveAttr, False) self.start(False, (# Node is inactive -> no events. lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: handlerTester.assertState(()), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), # Activate the node -> events arrive. lambda: activateNode(self.img, useSensitiveAttr, True), lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: handlerTester.assertState( (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), )) self.img = None # Check if sensitive is deactivated immediately, not at the end of the frame. root = self.loadEmptyScene() self.img1 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) self.img2 = avg.ImageNode(pos=(64,0), href="rgb24-65x65.png", parent=root) self.img1.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.TOUCH, self, lambda event: activateNode(self.img2, useSensitiveAttr, False)) self.img2.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.TOUCH, self, onNode2Down) self.__node2Down = False self.start(False, (lambda: self._sendTouchEvents(( (1, avg.Event.CURSOR_DOWN, 10, 10), (2, avg.Event.CURSOR_DOWN, 80, 10),)), lambda: self.assert_(not(self.__node2Down)), )) def testChangingHandlers(self): root = self.loadEmptyScene() img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) handlerTester = NodeHandlerTester(self, img) self.start(False, (lambda: handlerTester.clearHandlers(), lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: handlerTester.assertState(()), lambda: handlerTester.setHandlers(), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), lambda: handlerTester.assertState((avg.Node.CURSOR_UP,)), )) def testEventCapture(self): def onMainMouseDown(Event): self.mainMouseDownCalled = True def onMouseDown(Event): self.mouseDownCalled = True def captureEvent(): self.mouseDownCalled = False self.mainMouseDownCalled = False self.img.setEventCapture() def noCaptureEvent(): self.mouseDownCalled = False self.mainMouseDownCalled = False self.img.releaseEventCapture() def doubleCaptureEvent(): self.mouseDownCalled = False self.mainMouseDownCalled = False self.img.setEventCapture() self.img.setEventCapture() self.img.releaseEventCapture() def releaseTooMuch(): self.img.releaseEventCapture() self.assertException(self.img.releaseEventCapture) self.mouseDownCalled = False self.mainMouseDownCalled = False root = self.loadEmptyScene() root.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, onMainMouseDown) self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) self.img.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, onMouseDown) self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: self.assert_(self.mouseDownCalled), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), captureEvent, lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10), lambda: self.assert_(self.mouseDownCalled and self.mainMouseDownCalled), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10), noCaptureEvent, lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10), lambda: self.assert_(not(self.mouseDownCalled) and self.mainMouseDownCalled), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10), doubleCaptureEvent, lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10), lambda: self.assert_(self.mouseDownCalled and self.mainMouseDownCalled), releaseTooMuch, lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10), )) self.img = None def testMouseOver(self): def onImg2MouseOver(Event): self.img2MouseOverCalled = True def onImg2MouseOut(Event): self.img2MouseOutCalled = True def onDivMouseOver(Event): self.divMouseOverCalled = True def onDivMouseOut(Event): self.divMouseOutCalled = True def onAVGMouseOver(Event): self.avgMouseOverCalled = True def onImg1MouseOver(Event): self.img1MouseOverCalled = True def printState(): print "----" print "img2MouseOverCalled=", self.img2MouseOverCalled print "img2MouseOutCalled=", self.img2MouseOutCalled print "divMouseOverCalled=", self.divMouseOverCalled print "divMouseOutCalled=", self.divMouseOutCalled print "avgMouseOverCalled=", self.avgMouseOverCalled print "img1MouseOverCalled=", self.img1MouseOverCalled def resetState(): self.img2MouseOverCalled = False self.img2MouseOutCalled = False self.divMouseOverCalled = False self.divMouseOutCalled = False self.avgMouseOverCalled = False self.img1MouseOverCalled = False def killNodeUnderCursor(): Parent = img1.parent Parent.removeChild(Parent.indexOf(img1)) root = self.loadEmptyScene() img1 = avg.ImageNode(href="rgb24-65x65.png", parent=root) div = avg.DivNode(pos=(65,0), parent=root) img3 = avg.ImageNode(href="rgb24-65x65.png", parent=div) img2 = avg.ImageNode(pos=(0,65), href="rgb24-65x65.png", parent=div) img2.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onImg2MouseOver) img2.setEventHandler(avg.Event.CURSOR_OUT, avg.Event.MOUSE, onImg2MouseOut) div.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onDivMouseOver) div.setEventHandler(avg.Event.CURSOR_OUT, avg.Event.MOUSE, onDivMouseOut) root.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onAVGMouseOver) img1.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onImg1MouseOver) self.start(False, (resetState, lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 70, 70), lambda: self.assert_( self.img2MouseOverCalled and self.divMouseOverCalled and self.avgMouseOverCalled and not(self.img2MouseOutCalled) and not(self.divMouseOutCalled) and not(self.img1MouseOverCalled)), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 70), resetState, lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 70, 10), lambda: self.assert_( not(self.img2MouseOverCalled) and not(self.divMouseOverCalled) and not(self.avgMouseOverCalled) and self.img2MouseOutCalled and not(self.divMouseOutCalled) and not(self.img1MouseOverCalled)), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 10), resetState, lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: self.assert_( not(self.img2MouseOverCalled) and not(self.divMouseOverCalled) and not(self.avgMouseOverCalled) and not(self.img2MouseOutCalled) and self.divMouseOutCalled and self.img1MouseOverCalled), resetState, killNodeUnderCursor, lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), lambda: self.assert_( not(self.img2MouseOverCalled) and not(self.divMouseOverCalled) and not(self.avgMouseOverCalled) and not(self.img2MouseOutCalled) and not(self.divMouseOutCalled) and not(self.img1MouseOverCalled)), lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), resetState, lambda: img2.setEventCapture(), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 70), lambda: self.assert_( self.img2MouseOverCalled and self.divMouseOverCalled and not(self.avgMouseOverCalled) and not(self.img2MouseOutCalled) and not(self.divMouseOutCalled) and not(self.img1MouseOverCalled)), lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 70, 70), resetState, lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), lambda: self.assert_( not(self.img2MouseOverCalled) and not(self.divMouseOverCalled) and not(self.avgMouseOverCalled) and self.img2MouseOutCalled and self.divMouseOutCalled and not(self.img1MouseOverCalled)) )) def testMouseDisable(self): def checkMouseWorking(working): if working: downTestEvents = (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER) upTestEvents = (avg.Node.CURSOR_UP,) else: downTestEvents = () upTestEvents = () return (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: handlerTester.assertState(downTestEvents), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), lambda: handlerTester.assertState(upTestEvents) ) root = self.loadEmptyScene() img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root) handlerTester = NodeHandlerTester(self, img) player.enableMouse(False) self.start(False, (checkMouseWorking(False), lambda: player.enableMouse(True), checkMouseWorking(True), lambda: player.enableMouse(False), checkMouseWorking(False), lambda: player.enableMouse(True), )) def testEventErr(self): def onErrMouseOver(Event): undefinedFunction() root = self.loadEmptyScene() root.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, onErrMouseOver) self.assertException(lambda: self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), ))) def testEventHook(self): def resetState(): self.ehookMouseEvent = False self.ehookKeyboardEvent = False def cleanup(): resetState() player.setEventHook(None) def handleEvent(event): if isinstance(event, avg.MouseEvent) and event.source == avg.Event.MOUSE: if event.type == avg.Event.CURSOR_DOWN: self.ehookMouseEvent = True elif isinstance(event, avg.KeyEvent): self.ehookKeyboardEvent = True else: self.fail() self.loadEmptyScene() resetState() player.setEventHook(handleEvent) self.start(False, (lambda: self.fakeClick(10, 10), lambda: self.assert_(self.ehookMouseEvent), lambda: Helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65, 0), lambda: self.assert_(self.ehookKeyboardEvent), cleanup, lambda: self.fakeClick(10, 10), lambda: self.assert_(not self.ehookMouseEvent), lambda: Helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65, 0), lambda: self.assert_(not self.ehookKeyboardEvent), )) def testException(self): class TestException(Exception): pass def throwException(event): raise TestException rect = avg.RectNode(size = (50, 50)) rect.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, throwException) root = self.loadEmptyScene() root.appendChild(rect) self.__exceptionThrown = False try: self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: None )) except TestException: self.__exceptionThrown = True self.assert_(self.__exceptionThrown) def testContacts(self): def onDown(event): contact = event.contact self.assertEqual(event.cursorid, contact.id) self.assertEqual(contact.age, 0) self.assertEqual(contact.distancefromstart, 0) self.assertEqual(contact.motionangle, 0) self.assertEqual(contact.motionvec, (0,0)) self.assertEqual(contact.distancetravelled, 0) self.assertEqual(contact.events[0].pos, event.pos) self.assertEqual(len(contact.events), 1) contact.connectListener(onMotion, onUp) contact.subscribe(avg.Contact.CURSOR_MOTION, onMotionSubscribe) contact.subscribe(avg.Contact.CURSOR_UP, onUpSubscribe) def onMotion(event): contact = event.contact self.assertEqual(event.cursorid, contact.id) self.assertEqual(contact.age, 40) self.assertEqual(contact.distancefromstart, 10) self.assertEqual(contact.motionangle, 0) self.assertEqual(contact.motionvec, (10,0)) self.assertEqual(contact.distancetravelled, 10) self.assertEqual(contact.events[-1].pos, event.pos) self.assert_(len(contact.events) > 1) self.numContactCallbacks += 1 def onUp(event): contact = event.contact self.assertEqual(event.cursorid, contact.id) self.assertEqual(contact.age, 80) self.assertEqual(contact.distancefromstart, 0) self.assertEqual(contact.motionangle, 0) self.assertEqual(contact.motionvec, (0,0)) self.assertEqual(contact.distancetravelled, 20) self.assertEqual(contact.events[-1].pos, event.pos) self.assert_(len(contact.events) > 1) self.numContactCallbacks += 1 def onMotionSubscribe(event): self.motionCalled = True def onUpSubscribe(event): self.upCalled = True def onOver(event): self.numOverCallbacks += 1 self.assertEqual(event.cursorid, event.contact.id) def onOut(event): self.numOutCallbacks += 1 self.assertEqual(event.cursorid, event.contact.id) root = self.loadEmptyScene() root.subscribe(avg.Node.CURSOR_DOWN, onDown) self.numContactCallbacks = 0 rect = avg.RectNode(pos=(5,5), size=(10,10), parent=root) rect.subscribe(avg.Node.CURSOR_OVER, onOver) self.numOverCallbacks = 0 rect.subscribe(avg.Node.CURSOR_OUT, onOut) self.numOutCallbacks = 0 player.setFakeFPS(25) self.motionCalled = False self.upCalled = False self.start(False, (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10), lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 10, 10), )) self.assertEqual(self.numContactCallbacks, 2) self.assertEqual(self.numOverCallbacks, 2) self.assertEqual(self.numOutCallbacks, 2) self.assert_(self.motionCalled and self.upCalled) root = self.loadEmptyScene() root.subscribe(avg.Node.CURSOR_DOWN, onDown) self.numContactCallbacks = 0 self.start(False, (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10), lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 20, 10), lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10), )) self.assertEqual(self.numContactCallbacks, 2) def testContactRegistration(self): def onDown(event): root.setEventCapture(event.cursorid) root.releaseEventCapture(event.cursorid) def onMotion(event): contact = event.contact self.contactID = contact.subscribe(avg.Contact.CURSOR_MOTION, onContactMotion) self.numMotionCallbacks += 1 root.unsubscribe(avg.Node.CURSOR_DOWN, onDown) root.unsubscribe(avg.Node.CURSOR_MOTION, onMotion) def onContactMotion(event): contact = event.contact contact.unsubscribe(self.contactID) self.assertException(lambda: contact.unsubscribe(self.contactID)) self.numContactCallbacks += 1 root = self.loadEmptyScene() root.subscribe(avg.Node.CURSOR_DOWN, onDown) self.numMotionCallbacks = 0 root.subscribe(avg.Node.CURSOR_MOTION, onMotion) self.numContactCallbacks = 0 player.setFakeFPS(25) self.start(False, (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10), lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 30, 10), lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 40, 10), )) self.assertEqual(self.numContactCallbacks, 1) self.assertEqual(self.numMotionCallbacks, 1) def testMultiContactRegistration(self): def onDown(event): contact = event.contact self.motionListenerID = contact.subscribe(avg.Contact.CURSOR_MOTION, onContact2) self.upListenerID = contact.subscribe(avg.Contact.CURSOR_UP, onContact2) contact.subscribe(avg.Contact.CURSOR_MOTION, onContact1) contact.subscribe(avg.Contact.CURSOR_UP, onContact1) def onContact1(event): if self.numContact1Callbacks == 0: event.contact.unsubscribe(self.motionListenerID) event.contact.unsubscribe(self.upListenerID) self.numContact1Callbacks += 1 def onContact2(event): self.assertEqual(self.numContact1Callbacks, 0) self.numContact2Callbacks += 1 root = self.loadEmptyScene() root.subscribe(avg.Node.CURSOR_DOWN, onDown) player.setFakeFPS(25) self.numContact1Callbacks = 0 self.numContact2Callbacks = 0 self.start(False, (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10), lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 10, 10), )) self.assertEqual(self.numContact1Callbacks, 2) # The order of callbacks is unspecified, so onContact2 might be called once. self.assert_(self.numContact2Callbacks <= 1) def testPlaybackMessages(self): self.loadEmptyScene() messageTester = MessageTester(player, [avg.Player.PLAYBACK_START, avg.Player.PLAYBACK_END], self) self.start(False, (lambda: messageTester.assertState([avg.Player.PLAYBACK_START]), )) messageTester.assertState([avg.Player.PLAYBACK_END]) def testImageSizeChanged(self): def onResize(newSize): self.assert_(newSize == self.sizeExpected) self.messageReceived = True def changeHref(): self.messageReceived = False self.sizeExpected = (32,32) self.image.href="rgb24-32x32.png" self.assert_(self.messageReceived) def explicitChangeSize(): self.messageReceived = False self.sizeExpected = (64,64) self.image.size = self.sizeExpected self.assert_(self.messageReceived) def changeWidth(): self.messageReceived = False self.sizeExpected = (32,64) self.image.width = 32 self.assert_(self.messageReceived) def move(): self.messageReceived = False self.image.x = 4 self.assert_(not(self.messageReceived)) root = self.loadEmptyScene() self.image = avg.ImageNode(href="rgb24-64x64.png", parent=root) self.image.subscribe(avg.AreaNode.SIZE_CHANGED, onResize) self.sizeExpected = (64, 64) self.start(False, (changeHref, explicitChangeSize, changeWidth, move, )) def testWordsSizeChanged(self): def onResize(newSize): self.messageReceived = True def checkMessageReceived(): self.assert_(self.messageReceived) self.messageReceived = False def changeText(): self.words.text="NewText" checkMessageReceived() self.messageReceived = False root = self.loadEmptyScene() self.words = avg.WordsNode(text="Test", parent=root) self.words.subscribe(self.words.SIZE_CHANGED, onResize) self.start(False, (checkMessageReceived, changeText, )) def testVideoSizeChanged(self): def onResize(newSize): self.messageReceived = True self.messageReceived = False root = self.loadEmptyScene() self.video = avg.VideoNode(href="mpeg1-48x48.mov", parent=root) self.video.subscribe(self.video.SIZE_CHANGED, onResize) self.video.play() self.assert_(self.messageReceived) def testRectSizeChanged(self): def onResize(newSize): self.messageReceived = True self.messageReceived = False root = self.loadEmptyScene() self.rect = avg.RectNode(size=(10,10), parent=root) self.rect.subscribe(self.rect.SIZE_CHANGED, onResize) self.rect.size=(100,100) self.assert_(self.messageReceived) def eventTestSuite(tests): availableTests = ( "testKeyEvents", "testSimpleEvents", "testTilted", "testWordsClicks", "testDivEvents", "testDivNegativePos", "testUnlinkInHandler", "testConnectHandler", "testPublisher", "testComplexPublisher", "testPublisherAutoDelete", "testPublisherNestedUnsubscribe", "testObscuringEvents", "testSensitive", "testChangingHandlers", "testEventCapture", "testMouseOver", "testMouseDisable", "testEventErr", "testEventHook", "testException", "testContacts", "testContactRegistration", "testMultiContactRegistration", "testPlaybackMessages", "testImageSizeChanged", "testWordsSizeChanged", "testVideoSizeChanged", "testRectSizeChanged", ) return createAVGTestSuite(availableTests, EventTestCase, tests) Helper = player.getTestHelper()