diff options
author | Dimitri John Ledkov <xnox@ubuntu.com> | 2014-06-24 20:05:13 +0100 |
---|---|---|
committer | Dimitri John Ledkov <xnox@ubuntu.com> | 2014-06-24 20:05:13 +0100 |
commit | dd22bd15f6ed3e5eb5c77ab427029be50fe20148 (patch) | |
tree | d9491ee40d80688b7f5b1f20504f022686827a57 /src/test |
libavg (1.8.1-1) unstable; urgency=medium
* New upstream release (Closes: #739664)
* Mark libdc1394-22-dev as linux-any build-dependency.
* Add libvdpau-dev build-dependency.
* Add libavresample-dev build-dependency.
# imported from the archive
Diffstat (limited to 'src/test')
660 files changed, 10984 insertions, 0 deletions
diff --git a/src/test/AVGAppTest.py b/src/test/AVGAppTest.py new file mode 100644 index 0000000..9178e4c --- /dev/null +++ b/src/test/AVGAppTest.py @@ -0,0 +1,187 @@ +#!/usr/bin/python +# -*- 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 +# + +import os +import time + +import libavg +from libavg import avg, Point2D, player +import testcase + +g_helper = player.getTestHelper() + +TEST_RESOLUTION = (160, 120) + +class TestAppBase(libavg.AVGApp): + @classmethod + def start(cls, **kwargs): + with testcase.SuppressOutput(): + super(TestAppBase, cls).start(**kwargs) + + def requestStop(self, timeout=0): + player.setTimeout(timeout, player.stop) + + def singleKeyPress(self, char): + g_helper.fakeKeyEvent(avg.Event.KEY_DOWN, ord(char), ord(char), char, ord(char), + avg.KEYMOD_NONE) + g_helper.fakeKeyEvent(avg.Event.KEY_UP, ord(char), ord(char), char, ord(char), + avg.KEYMOD_NONE) + + +class AVGAppTestCase(testcase.AVGTestCase): + def testMinimal(self): + class MinimalApp(TestAppBase): + testInstance = self + def init(self): + self.testInstance.assert_(not player.isFullscreen()) + self.requestStop() + + if 'AVG_DEPLOY' in os.environ: + del os.environ['AVG_DEPLOY'] + MinimalApp.start(resolution=TEST_RESOLUTION) + + def testAvgDeploy(self): + class FullscreenApp(TestAppBase): + testInstance = self + def init(self): + self.testInstance.assert_(player.isFullscreen()) + rootNodeSize = player.getRootNode().size + self.testInstance.assertEqual(rootNodeSize, resolution) + self.requestStop() + + resolution = player.getScreenResolution() + os.environ['AVG_DEPLOY'] = '1' + FullscreenApp.start(resolution=resolution) + del os.environ['AVG_DEPLOY'] + + def testDebugWindowSize(self): + class DebugwindowApp(TestAppBase): + testInstance = self + def init(self): + self.testInstance.assert_(not player.isFullscreen()) + rootNodeSize = player.getRootNode().size + self.testInstance.assertEqual(rootNodeSize, TEST_RESOLUTION) + + # windowSize = player.getWindowResolution() + # self.testInstance.assertEqual(windowSize, Point2D(TEST_RESOLUTION)/2) + self.requestStop() + + DebugwindowApp.start(resolution=TEST_RESOLUTION, + debugWindowSize=Point2D(TEST_RESOLUTION) / 2) + + def testScreenshot(self): + if not(self._isCurrentDirWriteable()): + self.skip("Current dir not writeable") + return + + expectedFiles = ['screenshot-000.png', 'screenshot-001.png'] + + def cleanup(): + for screenshotFile in expectedFiles[::-1]: + if os.path.exists(screenshotFile): + os.unlink(screenshotFile) + + def checkCallback(): + for screenshotFile in expectedFiles[::-1]: + if os.path.exists(screenshotFile): + avg.Bitmap(screenshotFile) + else: + raise RuntimeError('Cannot find the expected ' + 'screenshot file %s' % screenshotFile) + + player.stop() + + class ScreenshotApp(TestAppBase): + def init(self): + self.singleKeyPress('s') + self.singleKeyPress('s') + self.timeStarted = time.time() + self.timerId = player.subscribe(player.ON_FRAME, self.onFrame) + + def onFrame(self): + if (os.path.exists(expectedFiles[-1]) or + time.time() - self.timeStarted > 1): + player.clearInterval(self.timerId) + checkCallback() + + cleanup() + ScreenshotApp.start(resolution=TEST_RESOLUTION) + cleanup() + + def testGraphs(self): + class GraphsApp(TestAppBase): + def init(self): + self.enableGraphs() + + def enableGraphs(self): + self.singleKeyPress('f') + self.singleKeyPress('m') + player.setTimeout(500, self.disableGraphs) + + def disableGraphs(self): + self.singleKeyPress('m') + self.singleKeyPress('f') + self.requestStop() + + GraphsApp.start(resolution=TEST_RESOLUTION) + + def testToggleKeys(self): + TOGGLE_KEYS = ['?', 't', 'e'] + class ToggleKeysApp(TestAppBase): + def init(self): + self.keys = TOGGLE_KEYS[:] + player.setTimeout(0, self.nextKey) + + def nextKey(self): + if not self.keys: + player.stop() + else: + key = self.keys.pop() + self.singleKeyPress(key) + player.setTimeout(0, self.nextKey) + + ToggleKeysApp.start(resolution=TEST_RESOLUTION) + + def testFakeFullscreen(self): + class FakeFullscreenApp(TestAppBase): + fakeFullscreen = True + def init(self): + player.setTimeout(0, player.stop) + + resolution = player.getScreenResolution() + if os.name == 'nt': + FakeFullscreenApp.start(resolution=resolution) + else: + self.assertException( + lambda: FakeFullscreenApp.start(resolution=resolution)) + +def avgAppTestSuite(tests): + availableTests = ( + 'testMinimal', + 'testAvgDeploy', + 'testDebugWindowSize', + 'testScreenshot', + 'testGraphs', + 'testToggleKeys', + 'testFakeFullscreen', + ) + return testcase.createAVGTestSuite(availableTests, AVGAppTestCase, tests) diff --git a/src/test/AVTest.py b/src/test/AVTest.py new file mode 100644 index 0000000..04de91e --- /dev/null +++ b/src/test/AVTest.py @@ -0,0 +1,674 @@ +#!/usr/bin/python +# -*- 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 * + +class AVTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def setUp(self): + AVGTestCase.setUp(self) + + def testEOF(self, node): + def onEOF(): + player.stop() + + def onNoEOF(): + self.fail("No EOF") + + def onSubscribeEOF(): + self.eofCalled = True + + self.eofCalled = False + root = self.loadEmptyScene() + root.appendChild(node) + node.play() + node.setEOFCallback(onEOF) + node.subscribe(avg.Node.END_OF_FILE, onSubscribeEOF) + player.setTimeout(100000, onNoEOF) + player.play() + self.assert_(self.eofCalled) + + def testVideoInfo(self): + def checkInfo(): + node.pause() + self.assertEqual(node.getContainerFormat(), "avi") + self.assertEqual(node.getCurFrame(), 0) + self.assertEqual(node.getCurTime(), 0) + self.assertEqual(node.getDuration(), 1000) + self.assertEqual(node.getBitrate(), 224064) + self.assertEqual(node.getVideoCodec(), "mpeg4") + self.assertEqual(node.getStreamPixelFormat(), "yuv420p") + self.assertEqual(node.getVideoDuration(), 1000) + if isThreaded: + self.assertEqual(node.getAudioCodec(), "mp2") + self.assertEqual(node.getAudioSampleRate(), 44100) + self.assertEqual(node.getNumAudioChannels(), 2) + self.assert_(node.getVideoDuration() >= 1000) + + def checkEnableSound(): + node = avg.VideoNode(href="mpeg1-48x48-sound.avi", threaded=isThreaded, + enablesound=False, parent=root) + node.pause() + self.assertEqual(node.getVideoCodec(), "mpeg4") + self.assertException(node.getAudioCodec) + + def checkExceptions(): + node = avg.VideoNode(href="mpeg1-48x48.mov", threaded=isThreaded) + self.assertException(node.getDuration) + self.assertException(node.getBitrate) + self.assertException(node.getVideoCodec) + self.assertException(node.getStreamPixelFormat) + node.pause() + self.assertException(node.getAudioCodec) + self.assertException(node.getAudioSampleRate) + self.assertException(node.getNumAudioChannels) + root.appendChild(node) + + def checkAudioFile(): + node = avg.VideoNode(href="44.1kHz_16bit_stereo.wav", threaded=isThreaded, + parent=root) + self.assertException(node.pause) + + sys.stderr.write("\n") + for isThreaded in (False, True): + sys.stderr.write(" Threaded: " + str(isThreaded) + "\n") + root = self.loadEmptyScene() + node = avg.VideoNode(href="mpeg1-48x48-sound.avi", threaded=isThreaded, + parent=root) + checkInfo() + checkEnableSound() + checkExceptions() + self.start(False, + (checkInfo, + checkExceptions, + checkAudioFile, + )) + sys.stderr.write(" Nonstandard queue length\n") + root = self.loadEmptyScene() + node = avg.VideoNode(href="mpeg1-48x48-sound.avi", queuelength=23, parent=root) + self.assertEqual(node.queuelength, 23) + + def testVideoFiles(self): + def testVideoFile(filename, isThreaded): + def setVolume(volume): + node.volume = volume + + def testGetVolume(volume): + self.assertAlmostEqual(node.volume, volume) + + def checkImage(filename): + if not(isThreaded): + self.compareImage("testVideo-"+filename+"1") + + def testInfo(): + if filename == "mpeg1-48x48-sound.avi" and isThreaded: + self.assert_(node.hasAudio()) + else: + self.assert_(not(node.hasAudio())) + self.assert_((filename == "rgba-48x48.mov" or + filename == "vp6a-yuva-48x48.flv") == node.hasAlpha()) + + root = self.loadEmptyScene() + node = avg.VideoNode(href=filename, volume=0.8, size=(96,96), + threaded=isThreaded) + self.assertEqual(node.threaded, isThreaded) + setVolume(0.6) + root.appendChild(node) + self.assertException(node.hasAudio) + self.start(False, + (lambda: setVolume(0.5), + lambda: testGetVolume(0.5), + lambda: node.play(), + lambda: checkImage(filename), + lambda: setVolume(0.3), + lambda: testGetVolume(0.3), + testInfo, + lambda: node.stop() + )) + videoFiles = ["mjpeg-48x48.avi", "mpeg1-48x48.mov", #"mpeg1-48x48-sound.avi", + "rgba-48x48.mov", "h264-48x48.h264", "vp6a-yuva-48x48.flv"] + sys.stderr.write("\n") + for filename in videoFiles: + sys.stderr.write(" "+filename+"\n") + for isThreaded in [False, True]: + sys.stderr.write(" threaded: "+str(isThreaded)+"\n") + testVideoFile(filename, isThreaded) + + def testPlayBeforeConnect(self): + node = avg.VideoNode(href="media/mpeg1-48x48.mov", threaded=False) + node.play() + player.createMainCanvas(size=(160,120)) + root = player.getRootNode() + root.insertChild(node, 0) + player.setFakeFPS(25) + self.start(False, + (lambda: self.assertEqual(node.size, (48, 48)), + lambda: self.compareImage("testPlayBeforeConnect"), + )) + + def testVideoState(self): + for accelerated in [True, False]: + root = self.loadEmptyScene() + node = avg.VideoNode(href="mpeg1-48x48.mov", size=(96,96), threaded=False, + accelerated=accelerated, parent=root) + player.setFakeFPS(25) + self.start(False, + (lambda: node.play(), + lambda: self.compareImage("testVideoState1"), + lambda: node.pause(), + lambda: self.compareImage("testVideoState2"), + lambda: self.compareImage("testVideoState2"), + lambda: node.play(), + lambda: self.compareImage("testVideoState3"), + lambda: node.stop(), + lambda: self.compareImage("testVideoState4"), + lambda: node.pause(), + lambda: self.compareImage("testVideoState5"), + lambda: self.compareImage("testVideoState5"), + lambda: node.stop(), + lambda: self.compareImage("testVideoState4"), + )) + + def testVideoActive(self): + def deactivate(): + node.active=0 + + def activate(): + node.active=1 + + root = self.loadEmptyScene() + node = avg.VideoNode(href="mpeg1-48x48.mov", size=(96,96), threaded=False, + parent=root) + player.setFakeFPS(25) + self.start(False, + (lambda: node.play(), + deactivate, + lambda: self.compareImage("testVideoActive1"), + activate, + lambda: self.compareImage("testVideoActive2") + )) + + def testVideoHRef(self): + def testGetMediaSize(): + self.assertEqual(node.getMediaSize(), (48, 48)) + + def setHRefLoaded(): + node.href = "h264-48x48.h264" + + def setHRefUnloaded(): + node = avg.VideoNode() + node.href = "h264-48x48.h264" + node.play() + + def testVideoNotFound(): + # Missing file, but no play() or pause(): Should just work. + node = avg.VideoNode(href="MissingFile.mov") + node.href = "SecondMissingFile.mov" + # Now libavg notices the missing file. + self.assertException(node.play) + + def testVideoBroken(): + node = avg.VideoNode(href="rgb24-64x64.png") + self.assertException(node.play) + + root = self.loadEmptyScene() + node = avg.VideoNode(href="mpeg1-48x48.mov", threaded=False, parent=root) + player.setFakeFPS(25) + testVideoNotFound() + testVideoBroken() + setHRefUnloaded() + self.start(False, + (lambda: node.play(), + testGetMediaSize, + setHRefLoaded, + lambda: self.compareImage("testVideoHRef1"), + testGetMediaSize, + testVideoNotFound, + testVideoBroken + )) + + def testVideoOpacity(self): + def testWithFile(filename, testImgName): + def hide(): + self.videoNode.opacity=0 + + def show(): + self.videoNode.opacity=1 + + player.setFakeFPS(25) + root = self.loadEmptyScene() + self.videoNode = avg.VideoNode(href=filename, loop=True, threaded=False, + parent=root) + self.start(False, + (lambda: self.videoNode.play(), + None, + lambda: self.compareImage(testImgName+"1"), + hide, + None, + None, + show, + lambda: self.compareImage(testImgName+"2") + )) + testWithFile("rgba-48x48.mov", "testVideoOpacityRGBA") + testWithFile("mpeg1-48x48.mov", "testVideoOpacityYUV") + + def testVideoSeek(self): + def seek(frame): + videoNode.seekToFrame(frame) + + def checkCurFrame(): + self.assertEqual(videoNode.getCurFrame(), 26) + + player.setFakeFPS(25) + for useCustomFPS in [False, True]: + root = self.loadEmptyScene() + if useCustomFPS: + videoNode = avg.VideoNode(parent=root, loop=True, size=(96,96), fps=25, + threaded=False, href="mjpeg-48x48.avi") + else: + videoNode = avg.VideoNode(parent=root, loop=True, size=(96,96), + threaded=False, href="mjpeg-48x48.avi") + + videoNode.play() + seek(26) + self.start(False, + (checkCurFrame, + lambda: self.compareImage("testVideoSeek0"), + lambda: seek(100), + lambda: self.compareImage("testVideoSeek1"), + lambda: videoNode.pause(), + lambda: seek(26), + None, + lambda: self.compareImage("testVideoSeek2"), + lambda: videoNode.play(), + None, + lambda: self.compareImage("testVideoSeek3") + )) + + def checkSeek(): + seek(26) + self.assertNotEqual(videoNode.getCurFrame(), 0) + + def testVideoFPS(self): + player.setFakeFPS(25) + root = self.loadEmptyScene() + root = root + videoNode = avg.VideoNode(size=(80,80), loop=True, threaded=False, + href="mjpeg-48x48.avi", fps=250, parent=root) + self.start(False, + (lambda: videoNode.play(), + None, + lambda: self.compareImage("testVideoFPS") + )) + + def testVideoLoop(self): + def onEOF(): + self.eof = True + + def onFrame(): + if self.eof: + if not(threaded): + self.compareImage("testVideoLoop") + player.stop() + + for threaded in [False, True]: + self.eof = False + player.setFakeFPS(25) + root = self.loadEmptyScene() + videoNode = avg.VideoNode(parent=root, loop=True, fps=25, size=(96,96), + threaded=threaded, href="mpeg1-48x48.mov") + videoNode.subscribe(avg.Node.END_OF_FILE, onEOF) + videoNode.play() + player.subscribe(player.ON_FRAME, onFrame) + player.play() + + def testVideoMask(self): + def testWithFile(filename, testImgName): + def setMask(href): + video.maskhref = href + + def setOpacity(): + video.opacity = 0.5 + + player.setFakeFPS(25) + root = self.loadEmptyScene() + video = avg.VideoNode(href=filename, threaded=False, + parent=root) + video.play() + self.start(False, + (lambda: setMask("mask.png"), + lambda: self.compareImage(testImgName+"1"), + lambda: video.seekToFrame(10), + lambda: setMask(""), + lambda: self.compareImage(testImgName+"2"), + lambda: setMask("mask2.png"), + lambda: self.compareImage(testImgName+"3"), + setOpacity, + lambda: self.compareImage(testImgName+"4"), + )) + + testWithFile("mpeg1-48x48.mov", "testVideoMaskYUV") + testWithFile("mjpeg-48x48.avi", "testVideoMaskYUVJ") + testWithFile("rgba-48x48.mov", "testVideoMaskRGBA") + + def testException(self): + class TestException(Exception): + pass + + def throwException(): + raise TestException + + player.setFakeFPS(0.1) + videoNode = avg.VideoNode(threaded = False) + videoNode.href = "../testmediadir/mjpeg-48x48.avi" + videoNode.subscribe(avg.Node.END_OF_FILE, throwException) + + root = self.loadEmptyScene() + root.appendChild(videoNode) + + self.__exceptionThrown = False + try: + self.start(False, + (videoNode.pause, + lambda: videoNode.seekToFrame(videoNode.getNumFrames()), + videoNode.play, + lambda: None + )) + except TestException: + self.__exceptionThrown = True + + self.assert_(self.__exceptionThrown) + + def testVideoEOF(self): + player.setFakeFPS(25) + for filename in ["mpeg1-48x48.mov", "mpeg1-48x48-sound.avi"]: + node = avg.VideoNode(href=filename) + self.testEOF(node) + node = avg.VideoNode(href="mpeg1-48x48.mov", opacity=0) + self.testEOF(node) + + root = self.loadEmptyScene() + video = avg.VideoNode(href="mpeg1-48x48.mov", threaded=False, + parent=root) + player.setFakeFPS(0.1) + + # Should never be called + eofID = video.subscribe(avg.Node.END_OF_FILE, lambda: self.assert_(False)) + self.start(False, + (lambda: video.unsubscribe(avg.Node.END_OF_FILE, eofID), + video.play, + None + )) + + def testVideoSeekAfterEOF(self): + def onEOF(): + node.seekToTime(0) + player.subscribe(avg.Player.ON_FRAME, onFrame) + + def onFrame(): + if node.getCurTime() < 100: + self.compareImage("testSeekAfterEOF") + player.stop() + + def onNoEOF(): + self.fail("No EOF") + + player.setFakeFPS(25) + root = self.loadEmptyScene() + node = avg.VideoNode(href="mpeg1-48x48.mov", parent=root) + node.play() + node.subscribe(avg.VideoNode.END_OF_FILE, onEOF) + player.setTimeout(100000, onNoEOF) + player.play() + + def testSound(self): + def testSoundFile(filename): + def setVolume(volume): + node.volume = volume + + def testGetVolume(volume): + self.assertAlmostEqual(node.volume, volume) + + root = self.loadEmptyScene() + node = avg.SoundNode(href=filename, parent=root) + self.start(False, + (lambda: setVolume(0.5), + lambda: testGetVolume(0.5), + lambda: node.play(), + None, + lambda: node.stop(), + lambda: node.play(), + lambda: node.pause(), + lambda: node.play(), + lambda: setVolume(0.5), + lambda: testGetVolume(0.5), + lambda: node.pause(), + lambda: node.stop(), + lambda: setVolume(0.3), + lambda: testGetVolume(0.3), + lambda: node.pause() + )) + player.setFakeFPS(-1) + player.volume = 0 + # "44.1kHz_mono.ogg" not tested for now - broken under Windows. + # Assuming buggy ffmpeg version. + for filename in ["22.050Hz_16bit_mono.wav", "44.1kHz_16bit_stereo.aif", + "44.1kHz_16bit_stereo.wav", "44.1kHz_stereo.mp3", + "48kHz_24bit_stereo.wav"]: + testSoundFile(filename) + + def testSoundInfo(self): + def checkInfo(): + node.pause() + self.assertEqual(node.getAudioCodec(), "pcm_s16le") + self.assertEqual(node.getAudioSampleRate(), 44100) + self.assertEqual(node.getNumAudioChannels(), 2) + + def checkExceptions(): + node = avg.SoundNode(href="44.1kHz_16bit_stereo.wav") + self.assertException(node.getAudioCodec) + self.assertException(node.getAudioSampleRate) + self.assertException(node.getNumAudioChannels) + + def checkVideoFile(): + node = avg.SoundNode(href="mpeg1-48x48.mov", parent=root) + self.assertException(node.pause) + + root = self.loadEmptyScene() + node = avg.SoundNode(href="44.1kHz_16bit_stereo.wav", parent=root) + checkInfo() + checkExceptions() + self.start(False, + (checkInfo, + checkExceptions, + checkVideoFile, + )) + + def testSoundSeek(self): + player.setFakeFPS(-1) + player.volume = 0 + root = self.loadEmptyScene() + soundNode = avg.SoundNode(parent=root, href="44.1kHz_16bit_stereo.wav") + soundNode.play() + soundNode.seekToTime(500) + self.start(False, + (None, + lambda: soundNode.seekToTime(200), + )) + + + def testBrokenSound(self): + def openSound(): + node = avg.SoundNode(href="44.1kHz_16bit_6Chan.ogg", parent=root) + self.assertException(node.play) + + root = self.loadEmptyScene() + self.start(False, [openSound]) + + def testSoundEOF(self): + player.setFakeFPS(-1) + player.volume = 0 + node = avg.SoundNode(href="44.1kHz_16bit_mono.wav") + self.testEOF(node) + + def testVideoWriter(self): + + def startWriter(fps, syncToPlayback): + self.videoWriter = avg.VideoWriter(canvas, "test.mov", fps, 3, 5, + syncToPlayback) + + def stopWriter(): + self.videoWriter.stop() + + def killWriter(): + self.videoWriter = None + + def pauseWriter(): + self.videoWriter.pause() + + def playWriter(): + self.videoWriter.play() + + def hideVideo(): + videoNode.opacity = 0 + + def showVideo(): + videoNode.opacity = 1 + + def checkVideo(numFrames): + savedVideoNode = avg.VideoNode(href="../test.mov", pos=(48,0), + threaded=False, parent=root) + savedVideoNode.pause() + self.assertEqual(savedVideoNode.getVideoCodec(), "mjpeg") + self.assertEqual(savedVideoNode.getNumFrames(), numFrames) + self.assertEqual(savedVideoNode.getStreamPixelFormat(), "yuvj420p") + + def testCreateException(): + self.assertException(lambda: avg.VideoWriter(player.getMainCanvas(), + "nonexistentdir/test.mov", 30)) + + if not(self._isCurrentDirWriteable()): + self.skip("Current dir not writeable.") + return + if player.isUsingGLES(): + self.skip("VideoWriter not supported under GLES.") + return + + self.assertException(lambda: + avg.VideoWriter(player.getMainCanvas(), "test.mov", 30, 3, 5, False)) + + for useCanvas in (False, True): + player.setFakeFPS(30) + + root = self.loadEmptyScene() + videoNode = avg.VideoNode(href="mpeg1-48x48.mov", threaded=False) + if useCanvas: + canvas = player.createCanvas(id="canvas", size=(48,48), + mediadir="media") + canvas.getRootNode().appendChild(videoNode) + avg.ImageNode(parent=root, href="canvas:canvas") + testImageName = "testVideoWriterCanvas" + else: + root.appendChild(videoNode) + canvas = player.getMainCanvas() + testImageName = "testVideoWriter" + + self.start(False, + (videoNode.play, + lambda: startWriter(30, True), + lambda: self.delay(100), + stopWriter, + killWriter, + lambda: checkVideo(4), + hideVideo, + lambda: self.compareImage(testImageName+"1"), + showVideo, + testCreateException, + lambda: startWriter(15, False), + lambda: self.delay(150), + stopWriter, + killWriter, + lambda: checkVideo(2), + lambda: startWriter(30, False), + pauseWriter, + lambda: self.delay(200), + playWriter, + stopWriter, + killWriter, + lambda: checkVideo(1), + lambda: startWriter(30, False), + killWriter, + lambda: checkVideo(1), + )) + os.remove("test.mov") + + def test2VideosAtOnce(self): + player.setFakeFPS(25) + self.loadEmptyScene() + root = player.getRootNode() + for pos in ((0,0), (80,0)): + video = avg.VideoNode(pos=pos, threaded=False, href="mpeg1-48x48.mov", + parent=root) + video.play() + self.start(False, + [lambda: self.compareImage("test2VideosAtOnce1"),]) + + def testVideoAccel(self): + accelConfig = avg.VideoNode.getVideoAccelConfig() + video = avg.VideoNode(accelerated=False, href="media/mpeg1-48x48.mov") + video.play() + self.assertEqual(video.accelerated, False) + video = avg.VideoNode(accelerated=True, href="media/mpeg1-48x48.mov") + video.play() + self.assertEqual(video.accelerated, (accelConfig != avg.NO_ACCELERATION)) + + +def AVTestSuite(tests): + availableTests = [ + "testSound", + "testSoundInfo", + "testSoundSeek", + "testBrokenSound", + "testSoundEOF", + "testVideoInfo", + "testVideoFiles", + "testPlayBeforeConnect", + "testVideoState", + "testVideoActive", + "testVideoHRef", + "testVideoOpacity", + "testVideoSeek", + "testVideoFPS", + "testVideoLoop", + "testVideoMask", + "testVideoEOF", + "testVideoSeekAfterEOF", + "testException", + "testVideoWriter", + "test2VideosAtOnce", + "testVideoAccel", + ] + return createAVGTestSuite(availableTests, AVTestCase, tests) + diff --git a/src/test/AnimTest.py b/src/test/AnimTest.py new file mode 100644 index 0000000..4079b6a --- /dev/null +++ b/src/test/AnimTest.py @@ -0,0 +1,512 @@ +#!/usr/bin/python +# -*- 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 * + +class AnimTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def initScene(self): + root = self.loadEmptyScene() + self.__node = avg.ImageNode(id="test", pos=(64,30), href="rgb24-65x65.png", + parent=root) + player.setFakeFPS(10) + + def testAnimType(self, curAnim, imgBaseName): + def onStop(): + self.__onStopCalled = True + + def startAnim(): + self.__onStopCalled = False + self.__anim.start() + + def startKeepAttr(): + self.__node.x = 32 + self.__anim.start(True) + + def abortAnim(): + self.__anim.abort() + + self.__anim = curAnim + self.__anim.setStopCallback(onStop) + self.__onStopCalled = False + self.assertException(lambda: self.__anim.start()) + self.start(False, + (startAnim, + lambda: self.compareImage(imgBaseName+"1"), + lambda: self.compareImage(imgBaseName+"2"), + lambda: self.compareImage(imgBaseName+"3"), + lambda: self.assert_(self.__onStopCalled), + lambda: self.assert_(not(self.__anim.isRunning())), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0), + lambda: self.compareImage(imgBaseName+"4"), + lambda: self.assertEqual(self.__node.x, 100), + startAnim, + lambda: self.compareImage(imgBaseName+"1"), + lambda: self.assertEqual(avg.getNumRunningAnims(), 1), + abortAnim, + lambda: self.assertEqual(avg.getNumRunningAnims(), 0), + lambda: self.compareImage(imgBaseName+"5"), + lambda: self.assert_(not(self.__anim.isRunning())), + None, + lambda: self.assert_(self.__onStopCalled), + startKeepAttr, + lambda: self.compareImage(imgBaseName+"6"), + lambda: self.assertEqual(avg.getNumRunningAnims(), 1) + )) + self.__anim = None + + def testLinearAnim(self): + self.initScene() + curAnim = avg.LinearAnim(self.__node, "x", 300, 0, 100) + self.testAnimType(curAnim, "testLinearAnimC") + + def testAnimRegistry(self): + def on1Stop(): + self.__onStopCalled = True + + def on2Start(): + self.__onStopBeforeOnStart = self.__onStopCalled + + self.initScene() + sameNode = player.getElementByID("test") + anim1 = avg.LinearAnim(self.__node, "x", 500, 0, 100, + False, None, on1Stop) + anim2 = avg.LinearAnim(sameNode, "x", 300, 0, 100, + False, on2Start) + self.__onStopCalled = False + self.__onStopBeforeOnStart = False + self.start(False, + (lambda: anim1.start(), + lambda: self.assert_(not(self.__onStopCalled)), + lambda: anim2.start(), + lambda: self.assert_(self.__onStopBeforeOnStart), + lambda: self.assertEqual(avg.getNumRunningAnims(), 1) + )) + anim1 = None + anim2 = None + + def testFadeIn(self): + def onStop(): + self.__onStopCalled = True + + self.initScene() + self.__node.opacity=0.5 + self.__onStopCalled = False + self.start(False, + (lambda: avg.fadeIn(self.__node, 200, 1, onStop), + lambda: self.compareImage("testFadeIn1"), + lambda: self.compareImage("testFadeIn2"), + lambda: self.compareImage("testFadeIn3"), + lambda: self.assert_(self.__onStopCalled), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0) + )) + self.__anim = None + + def testFadeOut(self): + def onStop(): + self.__onStopCalled = True + + self.initScene() + self.__node.opacity=0.5 + self.__onStopCalled = False + self.start(False, + (lambda: avg.fadeOut(self.__node, 200, onStop), + lambda: self.compareImage("testFadeOut1"), + lambda: self.compareImage("testFadeOut2"), + lambda: self.compareImage("testFadeOut3"), + lambda: self.assert_(self.__onStopCalled), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0) + )) + self.__anim = None + + def testNonExistentAttributeAnim(self): + self.initScene() + self.assertException(lambda: avg.LinearAnim(self.__node, "foo", 0, 0, 0, False)) + self.assertException(lambda: avg.LinearAnim(None, "x", 0, 0, 0, False)) + + def testLinearAnimZeroDuration(self): + def onStop(): + self.__onStopCalled = True + + def startAnim(): + self.__onStopCalled = False + self.__anim.start() + + self.initScene() + self.__anim = avg.LinearAnim(self.__node, "x", 0, 0, 100, False, None, onStop) + self.__onStopCalled = False + self.start(False, + (startAnim, + lambda: self.compareImage("testLinearAnimZeroDurationC1"), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0), + lambda: self.assert_(self.__onStopCalled), + lambda: self.assert_(not(self.__anim.isRunning())) + )) + self.__anim = None + + def testPingPongStopAnim(self): + def forth(): + anim = avg.LinearAnim(self.__node, 'pos', 100, (50, 100), + (100, 100), False, None, back) + anim.start() + + def back(): + anim = avg.LinearAnim(self.__node, 'pos', 100, (100, 100), + (50, 100), False, None, forth) + anim.start() + + self.initScene() + self.start(False, + (forth, + lambda: self.delay(300), + )) + + def testPointAnim(self): + self._testPointAnim( + startPos=(0, 0), + endPos=(100, 40), + keepAttrPos=(50, 20), + startPosImgSrc="testPointAnim1", + endPosImgSrc="testPointAnim2", + keepAttrPosImgSrc="testPointAnim3") + + def testXPosPointAnim(self): + self._testPointAnim( + startPos=(0, 0), + endPos=(80, 0), + keepAttrPos=(40, 0), + startPosImgSrc="testXPosPointAnim1", + endPosImgSrc="testXPosPointAnim2", + keepAttrPosImgSrc="testXPosPointAnim3") + + def testYPosPointAnim(self): + self._testPointAnim( + startPos=(0, 0), + endPos=(0, 80), + keepAttrPos=(0, 40), + startPosImgSrc="testYPosPointAnim1", + endPosImgSrc="testYPosPointAnim2", + keepAttrPosImgSrc="testYPosPointAnim3") + + def testIntAnim(self): + self.initScene() + self.__doubleAnim = avg.LinearAnim(self.__node, "x", 300, 0, 100, True) + self.__pointAnim = avg.LinearAnim(self.__node, "pos", 200, avg.Point2D(0,0), + avg.Point2D(100,40), True) + self.start(False, + (self.__doubleAnim.start, + lambda: self.delay(100), + lambda: self.compareImage("testIntAnim1"), + self.__doubleAnim.abort, + self.__pointAnim.start, + lambda: self.delay(100), + lambda: self.compareImage("testIntAnim2"), + )) + + def testEaseInOutAnim(self): + self.initScene() + curAnim = avg.EaseInOutAnim(self.__node, "x", 300, 0, 100, 100, 100, False) + self.testAnimType(curAnim, "testEaseInOutAnimC") + + def testContinuousAnim(self): + def startAnim(): + self.__animStarted = True + + def stopAnim(): + self.__animStopped = True + + def reset(): + self.__animStarted = False + self.__animStopped = False + + self.initScene() + self.__anim = avg.ContinuousAnim(self.__node, "angle", 0, 2*math.pi, + False, startAnim, stopAnim) + self.__linearAnim = avg.LinearAnim(self.__node, "angle", 1000, math.pi, math.pi) + + self.__animStarted = False + self.__animStopped = False + self.start(False, + (self.__anim.start, + lambda: self.assert_(self.__animStarted), + lambda: self.compareImage("testContinuousAnim1"), + self.__anim.abort, + lambda: self.assert_(self.__animStopped), + reset, + self.__anim.start, + self.__linearAnim.start, + lambda: self.assert_(self.__animStopped), + lambda: self.compareImage("testContinuousAnim2"), + self.__linearAnim.abort, + )) + + def testWaitAnim(self): + def animStopped(): + self.__endCalled = True + + def startAnim(): + self.anim = avg.WaitAnim(200, animStopped, None) + self.anim.start() + + self.initScene() + self.__endCalled = False + self.start(False, + (startAnim, + lambda: self.assert_(self.anim.isRunning()), + lambda: self.delay(200), + lambda: self.assert_(not(self.anim.isRunning())), + lambda: self.assert_(self.__endCalled) + )) + + def testParallelAnim(self): + def animStopped(): + self.__endCalled = True + + def startFireForgetAnim(): + avg.ParallelAnim( + [ avg.LinearAnim(self.nodes[0], "x", 200, 0, 60), + avg.LinearAnim(self.nodes[1], "x", 200, 0, 120) + ]).start() + + def startAnim(): + self.anim = avg.ParallelAnim( + [ avg.LinearAnim(self.nodes[0], "x", 200, 0, 60), + avg.LinearAnim(self.nodes[1], "x", 400, 0, 120), + avg.EaseInOutAnim(self.nodes[2], "x", 400, 0, 120, 100, 100) + ], None, animStopped) + self.__endCalled = False + self.anim.start() + + def startTimedAnim(): + self.anim = avg.ParallelAnim( + [ avg.LinearAnim(self.nodes[0], "x", 200, 0, 60), + avg.LinearAnim(self.nodes[1], "x", 400, 0, 120), + ], None, animStopped, 200) + self.__endCalled = False + self.anim.start() + + def abortAnim(): + self.anim.abort() + + def deleteAnim(): + self.anim = None + + root = self.loadEmptyScene() + self.nodes = [] + for i in range(3): + node = avg.ImageNode(id=str(i), pos=(64, i*20), href="rgb24-64x64.png") + root.appendChild(node) + self.nodes.append(node) + player.setFakeFPS(10) + self.__endCalled = False + self.start(False, + (startFireForgetAnim, + lambda: self.assertEqual(avg.getNumRunningAnims(), 2), + None, + startAnim, + lambda: self.assertEqual(avg.getNumRunningAnims(), 3), + lambda: self.compareImage("testParallelAnimC1"), + lambda: self.assert_(self.anim.isRunning()), + lambda: self.delay(200), + lambda: self.assert_(not(self.anim.isRunning())), + lambda: self.compareImage("testParallelAnimC2"), + lambda: self.assert_(self.__endCalled), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0), + startAnim, + abortAnim, + lambda: self.compareImage("testParallelAnimC3"), + lambda: self.assert_(self.__endCalled), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0), + startTimedAnim, + lambda: self.delay(200), + lambda: self.assert_(self.__endCalled), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0), + startAnim + )) + self.nodes = [] + + def testParallelAnimRegistry(self): + def makeAnims(): + avg.ParallelAnim( + [ avg.LinearAnim(self.__node, "x", 200, 0, 60), + avg.LinearAnim(self.__node, "y", 200, 0, 120) + ]).start() + + avg.LinearAnim(self.__node, "x", 300, 0, 100, False, None).start() + + self.initScene() + self.start(False, + (makeAnims, + None + )) + + def testStateAnim(self): + def state1StopCallback(): + self.__state1StopCallbackCalled = True + + def state2StartCallback(): + if self.__state1StopCallbackCalled: + self.__stop1Start2CallbackOrder = True + self.__state2StartCallbackCalled = True + + def makeAnim(): + self.anim = avg.StateAnim( + [avg.AnimState("STATE1", avg.LinearAnim(self.__node, "x", 200, + 0, 100, False, None, state1StopCallback), "STATE2"), + avg.AnimState("STATE2", avg.LinearAnim(self.__node, "x", 200, + 100, 50, False, state2StartCallback), "STATE3"), + avg.AnimState("STATE3", avg.WaitAnim()) + ]) +# self.anim.setDebug(True) + + def killAnim(): + self.anim = None + + self.initScene() + self.__state1StopCallbackCalled = False + self.__state2StartCallbackCalled = False + self.__stop1Start2CallbackOrder = False + self.start(False, + (makeAnim, + lambda: self.compareImage("testStateAnimC1"), + lambda: self.anim.setState("STATE1"), + None, + lambda: self.compareImage("testStateAnimC2"), + lambda: self.assertEqual(self.anim.getState(), "STATE2"), + lambda: self.compareImage("testStateAnimC3"), + lambda: self.assert_(self.__state1StopCallbackCalled), + lambda: self.assert_(self.__state2StartCallbackCalled), + lambda: self.assert_(self.__stop1Start2CallbackOrder), + lambda: self.assertEqual(self.anim.getState(), "STATE3"), + lambda: self.compareImage("testStateAnimC4"), + lambda: self.anim.setState("STATE1"), + lambda: self.assertEqual(avg.getNumRunningAnims(), 1), + lambda: self.compareImage("testStateAnimC5"), + killAnim, +# lambda: player.getTestHelper().dumpObjects() + )) + + def testNonNodeAttrAnim(self): + class GenericClass(object): + def __init__(self): + self.numberValue = 0 + self.pointValue = avg.Point2D(0.0, 0.0) + + def on1Stop(): + self.__onStopCalled = True + + def on2Start(): + self.__onStopBeforeOnStart = self.__onStopCalled + + self.loadEmptyScene() + player.setFakeFPS(10) + genericObject1 = GenericClass() + genericObject2 = genericObject1 + genericObject3 = GenericClass() + anim1 = avg.LinearAnim(genericObject1, "numberValue", 1000, 0, 100, + False, None, on1Stop) + anim2 = avg.LinearAnim(genericObject2, "numberValue", 1200, 0, 200, + False, on2Start) + anim3 = avg.LinearAnim(genericObject1, "pointValue", 800, (0, 0), (100, 200)) + anim4 = avg.LinearAnim(genericObject3, "numberValue", 400, 0, 42) + self.__onStopCalled = False + self.__onStopBeforeOnStart = False + self.start(False, + (lambda: anim1.start(), + lambda: self.assert_(anim1.isRunning()), + lambda: self.assert_(not(self.__onStopCalled)), + lambda: anim2.start(), + lambda: self.assert_(self.__onStopBeforeOnStart), + lambda: self.assert_(not(anim1.isRunning())), + lambda: self.assert_(anim2.isRunning()), + lambda: self.assertEqual(avg.getNumRunningAnims(), 1), + lambda: anim3.start(), + lambda: self.assert_(anim2.isRunning()), + lambda: self.assert_(anim3.isRunning()), + lambda: self.assertEqual(avg.getNumRunningAnims(), 2), + lambda: anim4.start(), + lambda: self.assert_(anim4.isRunning()), + lambda: self.assertEqual(avg.getNumRunningAnims(), 3), + lambda: self.delay(200), + lambda: self.assertEqual(avg.getNumRunningAnims(), 0), + lambda: self.assert_(genericObject1.numberValue == 200), + lambda: self.assert_(genericObject2.pointValue == (100, 200)), + lambda: self.assert_(genericObject3.numberValue == 42) + )) + anim1 = None + anim2 = None + anim3 = None + anim4 = None + genericObject1 = None + genericObject2 = None + genericObject3 = None + + + def _testPointAnim(self, startPos, endPos, keepAttrPos, startPosImgSrc, endPosImgSrc, + keepAttrPosImgSrc): + def startAnim(): + self.__anim.start() + + def startKeepAttr(): + self.__node.pos = keepAttrPos + self.__anim.start(True) + + self.initScene() + self.__anim = avg.LinearAnim(self.__node, "pos", 200, avg.Point2D(startPos), + avg.Point2D(endPos), False) + self.start(False, + (startAnim, + lambda: self.compareImage(startPosImgSrc), + lambda: self.compareImage(endPosImgSrc), + None, + lambda: self.assert_(not(self.__anim.isRunning())), + startKeepAttr, + lambda: self.compareImage(keepAttrPosImgSrc), + )) + + +def animTestSuite(tests): + availableTests = ( + "testLinearAnim", + "testAnimRegistry", + "testFadeIn", + "testFadeOut", + "testNonExistentAttributeAnim", + "testLinearAnimZeroDuration", + "testPingPongStopAnim", + "testPointAnim", + "testXPosPointAnim", + "testYPosPointAnim", + "testEaseInOutAnim", + "testIntAnim", + "testContinuousAnim", + "testWaitAnim", + "testParallelAnim", + "testParallelAnimRegistry", + "testStateAnim", + "testNonNodeAttrAnim" + ) + return createAVGTestSuite(availableTests, AnimTestCase, tests) + diff --git a/src/test/AppTest.py b/src/test/AppTest.py new file mode 100644 index 0000000..e3b5463 --- /dev/null +++ b/src/test/AppTest.py @@ -0,0 +1,299 @@ +#!/usr/bin/python +# -*- 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 +# +# Original author of this file is OXullo Interecans <x at brainrapers dot org> + + +import os +import sys +import tempfile +import libavg +from libavg import player +from libavg.app import settings +from libavg.app import keyboardmanager +from libavg.app.settings import Option +import testcase + + +class TestApp(libavg.app.App): + CUSTOM_SETTINGS = {'app_resolution': '160x120', 'app_window_size': '160x120'} + + def testRun(self, onFrameHandlersList=[], mainDiv=None, runtimeOptions={}): + assert type(onFrameHandlersList) == list + self.__onFrameHandlersList = onFrameHandlersList + player.subscribe(player.ON_FRAME, self.__onFrame) + player.setFramerate(10000) + player.assumePixelsPerMM(1) + for k, v in self.CUSTOM_SETTINGS.iteritems(): + self.settings.set(k, v) + + if mainDiv is None: + mainDiv = libavg.app.MainDiv() + + self.run(mainDiv, **runtimeOptions) + + def __onFrame(self): + if self.__onFrameHandlersList: + todo = self.__onFrameHandlersList.pop(0) + todo() + else: + player.stop() + + +class AppTestCase(testcase.AVGTestCase): + def testSettingsOptions(self): + self.assertRaises(ValueError, lambda: settings.Option('test', 1)) + + self.assertRaises(RuntimeError, lambda: settings.Settings( + [Option('foo', 'bar'), Option('foo', 'bar')])) + + s = settings.Settings([Option('foo', 'bar')]) + self.assertRaises(RuntimeError, lambda: s.addOption(Option('foo', 'baz'))) + + def testSettingsTypes(self): + defaults = [ + Option('test_boolean', 'True', 'help'), + Option('test_string', 'string'), + Option('another_value_int', '1234'), + Option('test_2d', '1280x1024'), + Option('test_2d_alt','1280,1024'), + Option('test_float','12.345'), + Option('test_json','[1, null,3 , "string", 12.345]') + ] + + s = settings.Settings(defaults) + + self.assertEquals(s.getBoolean('test_boolean'), True) + + self.assertEquals(type(s.get('test_string')), str) + self.assertRaises(ValueError, lambda: s.getBoolean('test_string')) + + self.assertEquals(s.getInt('another_value_int'), 1234) + self.assertRaises(ValueError, lambda: s.getInt('test_string')) + self.assertEquals(s.get('another_value_int'), '1234') + + self.assertEquals(s.getPoint2D('test_2d'), libavg.Point2D(1280, 1024)) + self.assertEquals(s.getPoint2D('test_2d_alt'), libavg.Point2D(1280, 1024)) + self.assertRaises(ValueError, lambda: s.getInt('test_2d')) + + self.assertEquals(s.getFloat('test_float'), 12.345) + + self.assertEquals(s.getJson('test_json'), [1, None, 3, 'string', 12.345]) + + def testSettingsSet(self): + s = settings.Settings() + s.addOption(Option('test_value', '')) + self.assertRaises(ValueError, lambda: s.set('test_value', 1234)) + + s.set('test_value', '1234') + self.assertEquals(s.getInt('test_value'), 1234) + + def testSettingsHasOption(self): + s = settings.Settings() + s.addOption(Option('test_value', '')) + self.assertEquals(s.hasOption('test_value'), True) + self.assertEquals(s.hasOption('test_value_foo'), False) + + def testSettingsArgvExtender(self): + s = settings.Settings([Option('foo_bar', 'bar')]) + e = settings.ArgvExtender('', args=['foo', '--foo-bar', 'baz', '-c', 'baz2']) + e.parser.add_option('-c') + s.applyExtender(e) + self.assertEquals(s.get('foo_bar'), 'baz') + self.assertEquals(e.parsedArgs[0].c, 'baz2') + self.assertEquals(e.parsedArgs[1], ['foo']) + + e = settings.ArgvExtender('', args=['foo', '--foo-baxxx', 'baz']) + with testcase.SuppressOutput(): + self.assertRaises(SystemExit, lambda: s.applyExtender(e)) + + def testSettingsKargsExtender(self): + s = settings.Settings([Option('foo_bar', 'bar')]) + e = settings.KargsExtender({'foo_bar': 'baz'}) + s.applyExtender(e) + self.assertEquals(s.get('foo_bar'), 'baz') + + e = settings.KargsExtender({'foo_baxxx': 'baz'}) + self.assertRaises(RuntimeError, lambda: s.applyExtender(e)) + + def testAppAdditionalSettings(self): + app = TestApp() + app.settings.addOption(Option('foo_bar', 'baz')) + app.settings.addOption(Option('bar_foo', 'baz')) + self.assertEquals(app.settings.get('foo_bar'), 'baz') + + def testAppRuntimeSettings(self): + app = TestApp() + app.settings.addOption(Option('foo_bar', 'baz')) + app.testRun([ + lambda: self.assertEquals(libavg.app.instance.settings.get('foo_bar'), + 'bar'), + ], + runtimeOptions={'foo_bar':'bar'}) + + def testAppRuntimeSettingsFail(self): + app = TestApp() + self.assertRaises(RuntimeError, + lambda: app.testRun(runtimeOptions={'foo_bar':'bar'})) + + def testAppInstance(self): + app = TestApp() + self.assertEquals(app, libavg.app.instance) + + def testAppResolution(self): + app = TestApp() + app.testRun([ + lambda: self.assertEquals(player.getRootNode().size, (160, 120)), + lambda: self.assert_(not player.isFullscreen()), + ]) + + def testAppDefaultWindowSize(self): + app = TestApp() + app.CUSTOM_SETTINGS = {'app_resolution': '160x120'} + app.testRun() + + def testAppFullscreen(self): + app = TestApp() + app.settings.set('app_fullscreen', 'true') + app.testRun([ + lambda: self.assert_(player.isFullscreen()), + ]) + + def testAppRotation(self): + app = TestApp() + app.settings.set('app_rotation', 'left') + app.testRun([ + lambda: self.assertEquals(player.getRootNode().size, (120, 160)), + ]) + + def testScreenshot(self): + tempDir = tempfile.gettempdir() + expectedFiles = map(lambda v: os.path.join(tempDir, v), + ['TestApp-001.png', 'TestApp-002.png']) + + def removeFiles(): + for file in expectedFiles: + if os.path.exists(file): + os.unlink(file) + + def testScreenshots(): + for file in expectedFiles: + self.assert_(os.path.exists(file)) + + removeFiles() + app = TestApp() + app.testRun([ + lambda: app.takeScreenshot(tempDir), + lambda: app.takeScreenshot(tempDir), + testScreenshots, + removeFiles, + ]) + + def testKeyboardManagerPlain(self): + tester = lambda: self.__emuKeyPress(0, 97, 'a', 97, libavg.avg.KEYMOD_NONE) + self.__testKeyboardManager('a', libavg.avg.KEYMOD_NONE, tester) + + def testKeyboardManagerPlainMod(self): + tester = lambda: self.__emuKeyPress(0, 97, 'a', 97, libavg.avg.KEYMOD_LSHIFT) + self.__testKeyboardManager('a', libavg.avg.KEYMOD_SHIFT, tester) + + def testKeyboardManagerUnicodeBinary(self): + tester = lambda: self.__emuKeyPress(53, 164, 'ö', 246, libavg.avg.KEYMOD_NONE) + self.__testKeyboardManager('ö', libavg.avg.KEYMOD_NONE, tester) + + def testKeyboardManagerUnicodeExplicit(self): + tester = lambda: self.__emuKeyPress(53, 164, 'ö', 246, libavg.avg.KEYMOD_NONE) + self.__testKeyboardManager(u'ö', libavg.avg.KEYMOD_NONE, tester) + + def testKeyboardManagerUnicodeMod(self): + tester = lambda: self.__emuKeyPress(0, 65, 'A', 65, libavg.avg.KEYMOD_LSHIFT) + self.__testKeyboardManager(u'A', keyboardmanager.KEYMOD_ANY, tester) + self.tearDown() + self.__testKeyboardManager(u'A', libavg.avg.KEYMOD_SHIFT, tester) + + def tearDown(self): + libavg.app.instance = None + + def __testKeyboardManager(self, keyString, modifiers, tester): + self.statesRecords = [False, False] + def keyDownPressed(): + self.statesRecords[0] = True + + def keyUpPressed(): + self.statesRecords[1] = True + + def bindKeys(): + keyboardmanager.bindKeyDown(keyString, keyDownPressed, '', modifiers) + keyboardmanager.bindKeyUp(keyString, keyUpPressed, '', modifiers) + + def reset(): + keyboardmanager.unbindKeyDown(keyString, modifiers) + keyboardmanager.unbindKeyUp(keyString, modifiers) + self.statesRecords = [False, False] + + def cleanup(): + del self.statesRecords + + app = TestApp() + app.testRun([ + bindKeys, + tester, + lambda: self.assert_(all(self.statesRecords)), + reset, + tester, + lambda: self.assert_(not any(self.statesRecords)), + cleanup, + ]) + + def __emuKeyPress(self, scanCode, keyCode, keyString, unicode_, modifiers): + helper = libavg.player.getTestHelper() + helper.fakeKeyEvent(libavg.avg.Event.KEY_DOWN, scanCode, keyCode, keyString, + unicode_, modifiers) + # Note: on up, unicode is always 0 + helper.fakeKeyEvent(libavg.avg.Event.KEY_UP, scanCode, keyCode, keyString, + 0, modifiers) + + +def appTestSuite(tests): + availableTests = ( + 'testSettingsOptions', + 'testSettingsTypes', + 'testSettingsSet', + 'testSettingsHasOption', + 'testSettingsArgvExtender', + 'testSettingsKargsExtender', + 'testAppAdditionalSettings', + 'testAppRuntimeSettings', + 'testAppRuntimeSettingsFail', + 'testAppInstance', + 'testAppResolution', + 'testAppDefaultWindowSize', + 'testAppFullscreen', + 'testAppRotation', + 'testScreenshot', + 'testKeyboardManagerPlain', + 'testKeyboardManagerPlainMod', + 'testKeyboardManagerUnicodeBinary', + 'testKeyboardManagerUnicodeExplicit', + 'testKeyboardManagerUnicodeMod', + ) + return testcase.createAVGTestSuite(availableTests, AppTestCase, tests) + diff --git a/src/test/DynamicsTest.py b/src/test/DynamicsTest.py new file mode 100644 index 0000000..522c2f0 --- /dev/null +++ b/src/test/DynamicsTest.py @@ -0,0 +1,380 @@ +#!/usr/bin/python +# -*- 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 * + +class DynamicsTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def __runDynamicsTest(self, createFunc, testName, isVideo = False, + warnOnImageDiff = False): + + def createNode1(useXml): + + def setNodeID(): + node.id = "bork" + + node = createFunc(useXml) + node.id = "nodeid1" + node.x = 10 + node.y = 20 + self.root.appendChild(node) + self.assertException(setNodeID) + self.assertEqual(self.root.indexOf(player.getElementByID("nodeid1")), 0) + self.assertException(lambda: self.root.indexOf(self.root)) + + def createNode2(useXml): + node = createFunc(useXml) + node.id = "nodeid2" + oldNode = player.getElementByID("nodeid1") + self.root.insertChildBefore(node, oldNode) + + def reorderNode(): + self.root.reorderChild(0, 1) + node = player.getElementByID("nodeid1") + self.root.reorderChild(node, 0) + + def removeNodes(): + self.node = player.getElementByID("nodeid1") + self.root.removeChild(self.root.indexOf(self.node)) + node2 = player.getElementByID("nodeid2") + self.root.removeChild(node2) + self.assertEqual(player.getElementByID("nodeid1"), None) + + def reAddNode(): + self.root.appendChild(self.node) + if isVideo: + self.node.play() + self.node = None + + def killNode(): + self.node = player.getElementByID("nodeid1") + self.node.unlink(True) + gone = player.getElementByID("nodeid1") + self.assertEqual(gone, None) + + def removeAgain(): + node = player.getElementByID("nodeid1") + node.unlink() + gone = player.getElementByID("nodeid1") + self.assertEqual(gone, None) + + def runTest(useXml): + self.root = self.loadEmptyScene() + createNode1(useXml) + player.stop() + self.root = self.loadEmptyScene() + player.setFakeFPS(25) + self.start(warnOnImageDiff, + (lambda: createNode1(useXml), + lambda: self.compareImage(testName+"1"), + lambda: createNode2(useXml), + lambda: self.compareImage(testName+"2"), + reorderNode, + lambda: self.compareImage(testName+"3"), + removeNodes, + lambda: self.compareImage(testName+"4"), + reAddNode, + lambda: self.compareImage(testName+"5"), + killNode, + reAddNode, + removeAgain + )) + + runTest(True) + runTest(False) + + def testImgDynamics(self): + def createImg(useXml): + if useXml: + node = player.createNode("<image href='rgb24-64x64.png'/>") + else: + node = player.createNode("image", {"href":"rgb24-64x64.png"}) + return node + + self.__runDynamicsTest(createImg, "testImgDynamics") + + def testVideoDynamics(self): + def createVideo(useXml): + if useXml: + node = player.createNode( + "<video href='mpeg1-48x48.mov' threaded='false'/>") + else: + node = player.createNode("video", + {"href":"mpeg1-48x48.mov", "threaded":False}) + node.play() + return node + + self.__runDynamicsTest(createVideo, "testVideoDynamics", True) + + def testWordsDynamics(self): + def createWords(useXml): + if useXml: + node = player.createNode("<words text='test'/>") + else: + node = player.createNode("words", {"text":"test"}) + node.font="Bitstream Vera Sans" + node.fontsize=12 + node.width=200 + return node + + self.__runDynamicsTest(createWords, "testWordsDynamics", False, True) + + def testDivDynamics(self): + def createDiv(useXml): + if useXml: + node = player.createNode(""" + <div> + <image href='rgb24-64x64.png'/> + </div> + """) + else: + node = avg.DivNode() + avg.ImageNode(href="rgb24-64x64.png", parent=node) + return node + + self.__runDynamicsTest(createDiv, "testDivDynamics") + + def testDuplicateID(self): + root = self.loadEmptyScene() + avg.ImageNode(href="rgb24-64x64.png", id="testdup", parent=root) + self.assertException(lambda: avg.ImageNode(href="rgb24-64x64.png", + id="testdup", parent=root)) + self.start(False, + (self.assertException(lambda: avg.ImageNode(href="rgb24-64x64.png", + id="testdup", parent=root)), + )) + + def testChangeParentError(self): + def changeParent(): + div = avg.DivNode() + img = avg.ImageNode(href="additive/rgb24-64x64.png", parent=div) + root.appendChild(img) + + root = self.loadEmptyScene() + self.assertException(changeParent) + self.start(False, (self.assertException(changeParent),)) + + def testDynamicEventCapture(self): + # Tests if deleting a node that has events captured works. + def createImg(): + parentNode = root + node = player.createNode("image", {"id": "img", "href":"rgb24-64x64.png"}) + parentNode.appendChild(node) + node.subscribe(avg.Node.CURSOR_DOWN, captureMouseDown) + parentNode.subscribe(avg.Node.CURSOR_UP, mainMouseUp) + + def setEventCapture(): + player.getElementByID("img").setEventCapture() + + def deleteImg(): + parentNode = root + node = player.getElementByID("img") + parentNode.removeChild(parentNode.indexOf(node)) + + def captureMouseDown(event): + self.captureMouseDownCalled = True + + def mainMouseUp(event): + self.mainMouseUpCalled = True + + self.captureMouseDownCalled = False + self.mainMouseUpCalled = False + root = self.loadEmptyScene() + self.start(False, + (createImg, + setEventCapture, + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10), + lambda: self.assert_(self.captureMouseDownCalled), + deleteImg, + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10), + lambda: self.assert_(self.mainMouseUpCalled) + )) + + def testEventBubbling(self): + def click (x, y): + self.fakeClick(x, y) + + def createNodes(): + def appendEventString (s): + self.__eventString += s + return True + + def setHandler (node, s, swallow = False): + node.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, + lambda e: appendEventString(s) and swallow) + + parentNode = root + node = player.createNode("div", {'x':0,'y':0,'width':50, 'height':50}) + setHandler (node, 'a') + parentNode.appendChild(node) + node = player.createNode("div", {'x':0,'y':0,'width':100, 'height':100}) + setHandler (node, 'b') + parentNode.insertChild(node,0) + parentNode = node + node = player.createNode("div", {'x':40,'y':40,'width':30, 'height':30}) + setHandler (node, 'c') + parentNode.appendChild(node) + node = player.createNode("div", {'x':60,'y':40,'width':30, 'height':30}) + setHandler (node, 'd', True) + parentNode.appendChild(node) + + def resetEventString(): + self.__eventString = '' + + root = self.loadEmptyScene() + self.start(False, + (createNodes, + resetEventString, + lambda: click (10,10), + lambda: self.assertEqual(self.__eventString, 'a'), + resetEventString, + lambda: click (55,55), + lambda: self.assertEqual(self.__eventString, 'cb'), + resetEventString, + lambda: click (65,55), + lambda: self.assertEqual(self.__eventString, 'd'), + )) + + def testComplexDiv(self): + def setImageID(imgNode): + imgNode.id = "imageid" + + def createDiv(): + imgNode = player.createNode("image", + {"id":"imageid", "href":"rgb24-64x64.png"}) + node = player.createNode("div", {"id":"divid"}) + node.appendChild(imgNode) + imgNode.id = "imageid" + root.appendChild(node) + self.assertException(lambda: setImageID(imgNode)) + + def removeDiv(): + node = player.getElementByID("divid") + imgNode = player.getElementByID("imageid") + node.unlink() + imgNode.id = "imageid" + imgNode.unlink() + root.appendChild(node) + node.appendChild(imgNode) + self.assertException(lambda: setImageID(imgNode)) + + root = self.loadEmptyScene() + createDiv() + removeDiv() + player.stop() + root = self.loadEmptyScene() + player.setFakeFPS(25) + self.start(False, + (createDiv, + lambda: self.compareImage("testComplexDiv1"), + removeDiv, + lambda: self.compareImage("testComplexDiv1"), + )) + + def testNodeCustomization(self): + def testNodePythonAttribute(): + node1 = player.createNode("image", {"id":"foo", "pos":(23, 42)}) + root.appendChild(node1) + node1.customAttribute = "bbb" + node2 = player.getElementByID("foo") + self.assertEqual(node1, node2) + self.assertEqual(node2.customAttribute, "bbb") + node1.unlink(True) + + def testNodePythonSubclass(): + + class CustomImageNode(avg.ImageNode): + def __init__(self, p, parent=None, **kwargs): + avg.ImageNode.__init__(self, pos=p, href="rgb24-64x64.png", **kwargs) + self.registerInstance(self, parent) + + def customMethod(self): + pass + + class CustomDivNode(avg.DivNode): + def __init__(self, parent=None, **kwargs): + avg.DivNode.__init__(self, **kwargs) + self.registerInstance(self, parent) + CustomImageNode((23,42), parent=self) + + + customNode = CustomImageNode((23, 42), parent=root) + retrievedImage = root.getChild(0) + self.assertEqual(type(retrievedImage), CustomImageNode) + self.assertEqual(retrievedImage.pos, (23,42)) + self.assertEqual(retrievedImage.href, "rgb24-64x64.png") + retrievedImage.customMethod() + customNode.unlink(True) + + CustomDivNode(parent=player.getRootNode()) + retrievedDiv = player.getRootNode().getChild(0) + self.assertEqual(type(retrievedDiv), CustomDivNode) + retrievedImage = retrievedDiv.getChild(0) + self.assertEqual(type(retrievedImage), CustomImageNode) + retrievedDiv = retrievedImage.parent + self.assertEqual(type(retrievedDiv), CustomDivNode) + retrievedDiv.unlink(True) + + customNode = CustomImageNode((23,42)) + root.appendChild(customNode) + retrievedImage = root.getChild(0) + self.assertEqual(type(retrievedImage), CustomImageNode) + + root = self.loadEmptyScene() + testNodePythonAttribute() + testNodePythonSubclass() + + def testDynamicMediaDir(self): + def attachNode(): + root.appendChild(imageNode1) + + root = self.loadEmptyScene() + root.mediadir="testmediadir" + imageNode1 = player.createNode("image", {"href": "rgb24-64x64a.png"}) + imageNode2 = player.createNode("image", {"href": "rgb24-64x64a.png", "x":30}) + root.appendChild(imageNode2) + self.start(False, + (lambda: self.compareImage("testDynamicMediaDir1"), + attachNode, + lambda: self.compareImage("testDynamicMediaDir2") + )) + + +def dynamicsTestSuite(tests): + availableTests = ( + "testImgDynamics", + "testVideoDynamics", + "testWordsDynamics", + "testDivDynamics", + "testEventBubbling", + "testDuplicateID", + "testChangeParentError", + "testDynamicEventCapture", + "testComplexDiv", + "testNodeCustomization", + "testDynamicMediaDir", + ) + + return createAVGTestSuite(availableTests, DynamicsTestCase, tests) diff --git a/src/test/EventTest.py b/src/test/EventTest.py new file mode 100644 index 0000000..afdfe94 --- /dev/null +++ b/src/test/EventTest.py @@ -0,0 +1,1086 @@ +# -*- 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() diff --git a/src/test/FXTest.py b/src/test/FXTest.py new file mode 100644 index 0000000..de677a0 --- /dev/null +++ b/src/test/FXTest.py @@ -0,0 +1,483 @@ +#!/usr/bin/env python +# -*- 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, utils, player +from testcase import * + + +class FXTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testImageNullFX(self): + def activateFX(): + for node in self.nodes[0]: + node.setEffect(avg.NullFXNode()) + + def newNode(): + self.newNode = avg.ImageNode(parent=root, href="rgb24-32x32.png", pos=(64,0)) + self.newNode.setEffect(avg.NullFXNode()) + + def newFX(): + self.newNode.setEffect(avg.NullFXNode()) + + def addBgNode(): + node = avg.RectNode(pos=(0,0), size=(64,96), fillopacity=1, opacity=0, + fillcolor="FFFFFF") + root.insertChild(node, 0) + + def emptyImageFX(): + node = avg.ImageNode(parent=root, href="", pos=(64,0)) + node.setEffect(avg.NullFXNode()) + + # Initial setup is 3x2 images: + # rows: no alpha, alpha, alpha & opacity 0.6 + # cols: no FX, FX + # The two cols should look the same. + root = self.loadEmptyScene() + self.nodes = [] + for fx in (False, True): + curNodes = [] + self.nodes.append(curNodes) + def configureNode(node, fx): + curNodes.append(node) + if fx: + node.x = 32 + node.setEffect(avg.NullFXNode()) + + node = avg.ImageNode(parent=root, href="rgb24-32x32.png", pos=(0,0)) + configureNode(node, fx) + node = avg.ImageNode(parent=root, href="rgb24alpha-32x32.png", pos=(0,32)) + configureNode(node, fx) + node = avg.ImageNode(parent=root, href="rgb24alpha-32x32.png", pos=(0,64), + opacity=0.6) + configureNode(node, fx) + + self.start(False, + (lambda: self.compareImage("testImageNullFX1"), + addBgNode, + lambda: self.compareImage("testImageNullFX2"), + activateFX, + lambda: self.compareImage("testImageNullFX2"), + newNode, + lambda: self.compareImage("testImageNullFX3"), + newFX, + lambda: self.compareImage("testImageNullFX3"), + emptyImageFX, + lambda: utils.initFXCache(10), + )) + + def testVideoNullFX(self): + root = self.loadEmptyScene() + player.setFakeFPS(25) + node = avg.VideoNode(parent=root, href="mjpeg-48x48.avi", + threaded=False) + node.setEffect(avg.NullFXNode()) + node.play() + self.start(False, (lambda: self.compareImage("testVideoNullFX"),)) + + def testWordsNullFX(self): + root = self.loadEmptyScene() + node = avg.WordsNode(parent=root, text="testtext", font="Bitstream Vera Sans") + node.setEffect(avg.NullFXNode()) + node = avg.WordsNode(parent=root, text="testtext", pos=(0,20), + font="Bitstream Vera Sans") + self.start(True, + (lambda: self.compareImage("testWordsNullFX"), + )) + + def testCanvasNullFX(self): + def setOuterOpacity(): + node.opacity=0.6 + + def setInnerOpacity(): + innerNode = canvas.getElementByID("test") + innerNode.opacity = 0.0 + + root = self.loadEmptyScene() + canvas = self.__createOffscreenCanvas() + node = avg.ImageNode(parent=root, href="canvas:offscreen") + node.setEffect(avg.NullFXNode()) + self.start(False, + (lambda: self.compareImage("testCanvasNullFX1"), + setOuterOpacity, + lambda: self.compareImage("testCanvasNullFX2"), + setInnerOpacity, + lambda: self.compareImage("testCanvasNullFX3"), + )) + + def testNodeInCanvasNullFX(self): + root = self.loadEmptyScene() + canvas = self.__createOffscreenCanvas() + avg.ImageNode(parent=root, href="canvas:offscreen") + node = canvas.getElementByID("test") + node.setEffect(avg.NullFXNode()) + rect = avg.RectNode(size=(100,100), strokewidth=0, fillcolor="FF0000", + fillopacity=1) + canvas.getRootNode().insertChild(rect, 0) + + self.start(False, + (lambda: self.compareImage("testNodeInCanvasNullFX1"), + )) + + def testRenderPipeline(self): + sys.stderr.write("\n") + for useSrcCanvas in (False, True): + for useDestCanvas in (False, True): + for useFX in (False, True): + for useColorConv in (False, True): + sys.stderr.write(" "+str(useSrcCanvas)+" "+str(useDestCanvas)+ + " "+str(useFX)+" "+str(useColorConv)+"\n") + root = self.loadEmptyScene() + if useSrcCanvas: + srcCanvas = player.createCanvas(id="src", size=(160,120), + mediadir="media") + avg.ImageNode(href="rgb24alpha-64x64.png", + parent=srcCanvas.getRootNode()) + srcImg = avg.ImageNode(href="canvas:src") + else: + srcImg = avg.ImageNode(href="rgb24alpha-64x64.png") + if useFX: + srcImg.setEffect(avg.NullFXNode()) + if useColorConv: + srcImg.contrast = (1.01, 1.0, 1.0) + if useDestCanvas: + destCanvas = player.createCanvas(id="dest", + size=(160,120), mediadir="media") + destCanvas.getRootNode().appendChild(srcImg) + avg.ImageNode(href="canvas:dest", parent=root) + else: + root.appendChild(srcImg) + self.start(False, + (lambda: self.compareImage("testRenderPipeline"), + )) + + def testBlurFX(self): + + def setRadius(radius): + self.effect.radius = radius + + def removeFX(): + self.node.setEffect(None) + + def reAddFX(): + self.node.setEffect(self.effect) + + def addNewFX(): + effect = avg.BlurFXNode(8) + self.node.setEffect(effect) + + root = self.loadEmptyScene() + self.node = avg.ImageNode(parent=root, pos=(10,10), href="rgb24-64x64.png") + self.effect = avg.BlurFXNode() + self.start(False, + (self.skipIfMinimalShader, + lambda: self.node.setEffect(self.effect), + lambda: self.compareImage("testBlurFX1"), + lambda: setRadius(8), + lambda: self.compareImage("testBlurFX2"), + removeFX, + lambda: self.compareImage("testBlurFX3"), + reAddFX, + lambda: self.compareImage("testBlurFX2"), + removeFX, + addNewFX, + lambda: self.compareImage("testBlurFX2"), + lambda: setRadius(300), + )) + + def testHueSatFX(self): + + def resetFX(): + self.effect = avg.HueSatFXNode() + self.node.setEffect(self.effect) + + def setParam(param, value): + assert(hasattr(self.effect, param)) + setattr(self.effect, param, value) + + root = self.loadEmptyScene() + self.node = avg.ImageNode(parent=root, pos=(10,10), href="rgb24alpha-64x64.png") + resetFX() + self.start(False, + (self.skipIfMinimalShader, + lambda: self.compareImage("testHueSatFX1"), + lambda: setParam('saturation', -50), + lambda: self.compareImage("testHueSatFX2"), + lambda: setParam('saturation', -100), + lambda: self.compareImage("testHueSatFX3"), + lambda: setParam('saturation', -150), + lambda: self.compareImage("testHueSatFX3"), + resetFX, + lambda: setParam('hue', 180), + lambda: self.compareImage("testHueSatFX4"), + lambda: setParam('hue', -180), + lambda: self.compareImage("testHueSatFX4"), + )) + + def testInvertFX(self): + + def resetFX(): + self.effect = avg.InvertFXNode() + self.node.setEffect(self.effect) + + def redAlphaScene(): + self.redRect = avg.RectNode(parent=self.root, pos=(5, 5), fillcolor='FF0000', + fillopacity=1, opacity=0, size=(72, 72)) + self.node = avg.ImageNode(parent=self.root, pos=(10,10), + href="rgb24alpha-64x64.png") + resetFX() + + self.root = self.loadEmptyScene() + self.node = avg.ImageNode(parent=self.root, pos=(10,10), href="hsl.png") + resetFX() + self.start(False, + (self.skipIfMinimalShader, + lambda: self.compareImage("testInvertFX1"), + redAlphaScene, + lambda: self.compareImage("testInvertFX2"), + )) + + def testShadowFX(self): + + def setParams(offset, radius, opacity, color): + effect.offset = offset + effect.radius = radius + effect.opacity = opacity + effect.color = color + + root = self.loadEmptyScene() + rect = avg.RectNode(parent=root, pos=(9.5,9.5), color="0000FF") + node = avg.ImageNode(parent=root, pos=(10,10), href="shadow.png") + rect.size = node.size + (1, 1) + effect = avg.ShadowFXNode((0,0), 1, 1, "FFFFFF") + self.start(False, + (self.skipIfMinimalShader, + lambda: node.setEffect(effect), + lambda: self.compareImage("testShadowFX1"), + lambda: setParams((0,0), 3, 2, "00FFFF"), + lambda: self.compareImage("testShadowFX2"), + lambda: setParams((2,2), 0.1, 1, "FFFFFF"), + lambda: self.compareImage("testShadowFX3"), + lambda: setParams((-2,-2), 0.1, 1, "FFFFFF"), + lambda: self.compareImage("testShadowFX4"), + lambda: setParams((-2,-2), 3, 1, "FFFFFF"), + lambda: self.compareImage("testShadowFX5"), + lambda: setParams((0,0), 0, 1, "FFFFFF"), + lambda: self.compareImage("testShadowFX6"), + )) + + def testWordsShadowFX(self): + + def setParams(offset, radius, opacity, color): + effect.offset = offset + effect.radius = radius + effect.opacity = opacity + effect.color = color + + root = self.loadEmptyScene() + node = avg.WordsNode(parent=root, pos=(10,10), text="testtext", + font="Bitstream Vera Sans") + effect = avg.ShadowFXNode() + setParams((0,0), 1.5, 1.5, "FF0000") + self.start(True, + (self.skipIfMinimalShader, + lambda: node.setEffect(effect), + lambda: self.compareImage("testWordsShadowFX1"), + lambda: setParams((2,2), 2, 2, "00FFFF"), + lambda: self.compareImage("testWordsShadowFX2"), + )) + + def testGamma(self): + def setGamma(val): + node.gamma = val + + root = self.loadEmptyScene() + node = avg.ImageNode(parent=root, href="colorramp.png", gamma=(0.5,0.5,0.5)) + self.assertEqual(node.gamma, (0.5,0.5,0.5)) + self.start(False, + (lambda: self.compareImage("testGamma1"), + lambda: setGamma((1.5,2.0,2.5)), + lambda: self.assertEqual(node.gamma, (1.5,2.0,2.5)), + lambda: self.compareImage("testGamma2"), + )) + + def testIntensity(self): + def setIntensity(val): + node.intensity = val + + def showVideo(): + node.unlink(True) + self.videoNode = avg.VideoNode(parent=root, size=(96,96), threaded=False, + href="mpeg1-48x48.mov", intensity=(0.5,0.5,0.5)) + self.videoNode.play() + + root = self.loadEmptyScene() + node = avg.ImageNode(parent=root, href="colorramp.png", intensity=(0.5,0.5,0.5)) + self.assertEqual(node.intensity, (0.5,0.5,0.5)) + player.setFakeFPS(10) + self.start(False, + (lambda: self.compareImage("testIntensity1"), + lambda: setIntensity((1.5,2.0,2.5)), + lambda: self.assertEqual(node.intensity, (1.5,2.0,2.5)), + lambda: self.compareImage("testIntensity2"), + showVideo, + lambda: self.compareImage("testIntensity3"), + )) + player.setFakeFPS(-1) + self.videoNode = None + + def testWordsIntensity(self): + root = self.loadEmptyScene() + avg.WordsNode(parent=root, fontsize=24, font="Bitstream Vera Sans", + intensity=(0.5,0.5,0.5), text="brightness", + width=140) + self.start(True, + (lambda: self.compareImage("testWordsIntensity"), + )) + + + def testContrast(self): + def setContrast(val): + node.contrast = val + + def showVideo(): + node.unlink(True) + videoNode = avg.VideoNode(parent=root, size=(96,96), threaded=False, + href="mpeg1-48x48.mov", contrast=(0.5,0.5,0.5)) + videoNode.play() + + root = self.loadEmptyScene() + node = avg.ImageNode(parent=root, href="colorramp.png", contrast=(0.5,0.5,0.5)) + self.assertEqual(node.contrast, (0.5,0.5,0.5)) + player.setFakeFPS(10) + self.start(False, + (lambda: self.compareImage("testContrast1"), + lambda: setContrast((1.5,2.0,2.5)), + lambda: self.assertEqual(node.contrast, (1.5,2.0,2.5)), + lambda: self.compareImage("testContrast2"), + showVideo, + lambda: self.compareImage("testContrast3"), + )) + player.setFakeFPS(-1) + + def testFXUpdate(self): + # This tests if the FX render-on-demand functionality doesn't forget updates. + def changeTexture(): + node.href = "colorramp.png" + + def addMaskTex(): + node.maskhref = "mask.png" + + def changeMaskTex(): + node.maskhref = "mask2.png" + + def changeMaskPos(): + node.maskpos = (10, 10) + + def changeFX(): + effect.radius = 2 + + def addVideo(): + node.unlink(True) + videoNode = avg.VideoNode(parent=root, threaded=False, size=(96,96), + href="mpeg1-48x48.mov") + effect = avg.BlurFXNode() + effect.radius = 0 + videoNode.setEffect(effect) + videoNode.play() + + root = self.loadEmptyScene() + node = avg.ImageNode(parent=root, href="rgb24alpha-64x64.png") + effect = avg.BlurFXNode() + effect.radius = 0 + player.setFakeFPS(25) + self.start(False, + (self.skipIfMinimalShader, + lambda: node.setEffect(effect), + changeTexture, + lambda: self.compareImage("testFXUpdateTex"), + addMaskTex, + lambda: self.compareImage("testFXUpdateMaskTex1"), + changeMaskTex, + lambda: self.compareImage("testFXUpdateMaskTex2"), + changeMaskPos, + lambda: self.compareImage("testFXUpdateMaskPos"), + changeFX, + lambda: self.compareImage("testFXUpdateFX"), + addVideo, + None, + lambda: self.compareImage("testFXUpdateVideo"), + )) + + def testChromaKeyFX(self): + + def setParams(htol, ltol, stol): + effect.htolerance = htol + effect.ltolerance = ltol + effect.stolerance = stol + + root = self.loadEmptyScene() + node = avg.ImageNode(parent=root, href="rgb24-64x64.png") + effect = avg.ChromaKeyFXNode() + setParams(0.01, 0.01, 0.01) + self.start(False, + (self.skipIfMinimalShader, + lambda: node.setEffect(effect), + lambda: self.compareImage("testChromaKeyFX1"), + lambda: setParams(0.2, 0.2, 0.2), + lambda: self.compareImage("testChromaKeyFX2"), + lambda: effect.__setattr__("color", "FF0000"), + lambda: self.compareImage("testChromaKeyFX3"), + lambda: effect.__setattr__("spillthreshold", 1), + lambda: self.compareImage("testChromaKeyFX4"), + )) + + def __createOffscreenCanvas(self): + canvas = player.createCanvas(id="offscreen", size=(160,120), mediadir="media") + root = canvas.getRootNode() + avg.ImageNode(href="rgb24-32x32.png", parent=root) + avg.ImageNode(id="test", pos=(32,0), href="rgb24alpha-32x32.png", parent=root) + return canvas + + +def fxTestSuite(tests): + availableTests = [ + "testImageNullFX", + "testVideoNullFX", + "testWordsNullFX", + "testCanvasNullFX", + "testNodeInCanvasNullFX", + "testRenderPipeline", + "testBlurFX", + "testHueSatFX", + "testInvertFX", + "testShadowFX", + "testWordsShadowFX", + "testGamma", + "testIntensity", + "testWordsIntensity", + "testContrast", + "testFXUpdate", + "testChromaKeyFX", + ] + return createAVGTestSuite(availableTests, FXTestCase, tests) diff --git a/src/test/GestureTest.py b/src/test/GestureTest.py new file mode 100644 index 0000000..4c1a792 --- /dev/null +++ b/src/test/GestureTest.py @@ -0,0 +1,1048 @@ +# -*- 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, gesture, player + +import math +from testcase import * + +class GestureTestCase(AVGTestCase): + + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testTapRecognizer(self): + + def abort(): + self.__tapRecognizer.abort() + + def enable(isEnabled): + self.__tapRecognizer.enable(isEnabled) + + self.__initImageScene() + self.__tapRecognizer = gesture.TapRecognizer(self.image) + self.messageTester = MessageTester(self.__tapRecognizer, + [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED, + gesture.Recognizer.FAILED], self) + player.setFakeFPS(10) + self.start(False, + (# Down-up: recognized as tap. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + # Down-small move-up: recognized as tap. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 31, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + + # Down-small down-second up-second up-first: recognized as tap + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 31, 30, btn=2), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 31, 30, btn=2), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 31, 30, btn=2), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 31, 30, btn=2), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + + # Down-big move-up: fail + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 80, + [gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + # Down-Abort-Up: not recognized as tap + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + # Abort-Down-Up: recognized as tap + abort, + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + # Down-Abort-Up-Down-Up: recognized as tap + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + # Disable-Down-Up-Enable: not recognized as tap + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(True), + # Down-Disable-Enable-Up: not recognized as tap + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: enable(False), + lambda: enable(True), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + # Down-Disable-Up-Enable-Down-Up: recognized as tap + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(True), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + # Abort-Disable-Abort-Enable-Abort-Down-Up: recognized as tap + abort, + lambda: enable(False), + abort, + lambda: enable(True), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + + # Remove node while tap is in progress. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self.__killImageNode, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + )) + + def testHoldRecognizer(self): + + def abort(): + self.__holdRecognizer.abort() + + def enable(isEnabled): + self.__holdRecognizer.enable(isEnabled) + + player.setFakeFPS(20) + self.__initImageScene() + self.__holdRecognizer = gesture.HoldRecognizer(self.image, + delay=1000) + self.messageTester = MessageTester(self.__holdRecognizer, + [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED, + gesture.Recognizer.FAILED, gesture.Recognizer.END], self) + self.start(False, + (# Standard down-hold-up sequence. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: self.delay(1100), + lambda: self.messageTester.assertState([gesture.Recognizer.DETECTED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.END]), + + # down-up sequence, hold not long enough. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.FAILED]), + + # down-move-up sequence, should fail. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 1, 1, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 150, 50, + [gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + + # down-hold-abort-up, should be recognized, no end event. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: self.delay(1100), + lambda: self.messageTester.assertState([gesture.Recognizer.DETECTED]), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + + # down-abort-hold-up, should not be recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + abort, + lambda: self.delay(1100), + lambda: self.messageTester.assertState([]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + + # down-hold-disabled-up-enabled, should be recognized, no end event. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: self.delay(1100), + lambda: self.messageTester.assertState([gesture.Recognizer.DETECTED]), + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(True), + + # down-disabled-enabled-hold-up, should not be recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: enable(False), + lambda: enable(True), + lambda: self.delay(1100), + lambda: self.messageTester.assertState([]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + + # Remove node while hold is in progress. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self.__killImageNode, + lambda: self.delay(1100), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + )) + player.setFakeFPS(-1) + + + def testDoubletapRecognizer(self): + + def abort(): + self.__tapRecognizer.abort() + + def enable(isEnabled): + self.__tapRecognizer.enable(isEnabled) + + root = self.loadEmptyScene() + image = avg.ImageNode(parent=root, href="rgb24-64x64.png", size=(128,128)) + self.__tapRecognizer = gesture.DoubletapRecognizer(image) + self.messageTester = MessageTester(self.__tapRecognizer, + [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED, + gesture.Recognizer.FAILED, gesture.Recognizer.END], self) + player.setFakeFPS(20) + self.start(False, + (# Down, up, down, up: click + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + # Down, move: stop + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 30, + [gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []), + # Down, up, move: stop + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 80, 30, + [gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []), + # Down, up, down, move: stop + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 30, + [gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []), + # Down,delay: stop + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: self.delay(1000), + lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + []), + # Down, up, delay: stop + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: self.delay(1000), + lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]), + # Down, up, down, delay: stop + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + lambda: self.delay(1000), + lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + []), + # Down, abort, up, down, up, delay: just one click + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: self.delay(1000), + lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]), + # Down, up, abort, down, up, delay: two clicks but no double-click + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: self.delay(1000), + lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]), + # Down, up, down, abort, up: just one click + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + # Down, abort, up, down, up, down up: first aborted then recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + # Disabled, down, up, down, up, enabled: nothing + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(True), + # Down, disabled up, down, up, enabled: just one down + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(True), + # Down, up, disabled, down, up, enabled: just one click + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(True), + # Down, up, down, disabled, up, enabled: just one click + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + lambda: enable(True), + # Down, disabled, enabled, up, down, up, down, up: recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + lambda: enable(False), + lambda: enable(True), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.DETECTED]), + )) + + + def testSwipeRecognizer(self): + + # One finger + for direction, xdir in ( + (gesture.SwipeRecognizer.RIGHT, 1), (gesture.SwipeRecognizer.LEFT, -1)): + self.__initImageScene() + swipeRecognizer = gesture.SwipeRecognizer(self.image, minDist=20, + direction=direction) + self.messageTester = MessageTester(swipeRecognizer, + [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED, + gesture.Recognizer.FAILED], + self) + self.start(False, + (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 30, + [gesture.Recognizer.DETECTED]), + # Check angle tolerance + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 25, + [gesture.Recognizer.DETECTED]), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 35, + [gesture.Recognizer.DETECTED]), + # Not far enough -> fail + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*10, 30, + [gesture.Recognizer.FAILED]), + # Wrong direction -> fail + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 60, + [gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 5, + [gesture.Recognizer.FAILED]), + )) + + + def testSwipeRecognizerTwoFingers(self): + self.__initImageScene() + swipeRecognizer = gesture.SwipeRecognizer(self.image, minDist=20, numContacts=2, + maxContactDist=15, direction=gesture.SwipeRecognizer.RIGHT) + self.messageTester = MessageTester(swipeRecognizer, + [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED, + gesture.Recognizer.FAILED], + self) + self.start(False, + (self._genTouchEventFrames( + [(0, avg.Event.CURSOR_DOWN, 30, 30,),], + []), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_DOWN, 40, 30,),], + [gesture.Recognizer.POSSIBLE]), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_UP, 70, 30,),], + []), + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_UP, 60, 30,),], + [gesture.Recognizer.DETECTED]), + # Not enough fingers -> not recognized + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_DOWN, 30, 30,),], + []), + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_UP, 60, 30,),], + []), + # Fail first finger + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_DOWN, 30, 30,),], + []), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_DOWN, 40, 30,),], + [gesture.Recognizer.POSSIBLE]), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_UP, 35, 30,),], + [gesture.Recognizer.FAILED]), + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_UP, 60, 30,),], + []), + # Fail second finger + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_DOWN, 30, 30,),], + []), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_DOWN, 40, 30,),], + [gesture.Recognizer.POSSIBLE]), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_UP, 70, 30,),], + []), + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_UP, 35, 30,),], + [gesture.Recognizer.FAILED]), + # Fingers too far apart + self._genTouchEventFrames( + [(0, avg.Event.CURSOR_DOWN, 30, 30,),], + []), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_DOWN, 50, 30,),], + [gesture.Recognizer.FAILED]), + self._genTouchEventFrames( + [(1, avg.Event.CURSOR_UP, 70, 30,), + (0, avg.Event.CURSOR_UP, 60, 30,),], + []), + )) + + def testDragRecognizer(self): + + def onMove(offset): + if self.friction == -1: + self.assertEqual(offset, (40,40)) + self.messageTester.setMessageReceived(gesture.Recognizer.MOTION) + + def onUp(offset): + if self.friction == -1: + self.assertEqual(offset, (10,-10)) + self.messageTester.setMessageReceived(gesture.Recognizer.UP) + + def enable(isEnabled): + dragRecognizer.enable(isEnabled) + + def abort(): + dragRecognizer.abort() + + def setupRecognizer(friction, moveHandler=onMove, minDragDist=0, + direction=gesture.DragRecognizer.ANY_DIRECTION, **kargs): + self.__initImageScene() + dragRecognizer = gesture.DragRecognizer(self.image, moveHandler=moveHandler, + upHandler=onUp, friction=friction, minDragDist=minDragDist, + direction=direction, **kargs) + messageTester = MessageTester(dragRecognizer, [gesture.Recognizer.POSSIBLE, + gesture.Recognizer.DETECTED, gesture.Recognizer.FAILED, + gesture.Recognizer.END], + self) + return (dragRecognizer, messageTester) + + player.setFakeFPS(100) + sys.stderr.write("\n") + for self.friction in (-1, 100): + if self.friction == -1: + sys.stderr.write(" Simple drag, no inertia\n") + else: + sys.stderr.write(" Simple drag, inertia\n") + dragRecognizer, self.messageTester = setupRecognizer(friction=self.friction) + self.start(False, + (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.DETECTED]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 70, 70, + [gesture.Recognizer.MOTION]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, + [gesture.Recognizer.UP, gesture.Recognizer.END]), + lambda: enable(False), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []), + lambda: dragRecognizer.enable(True), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.DETECTED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, + [gesture.Recognizer.UP, gesture.Recognizer.END]), + + # Remove node during drag. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.DETECTED]), + self.__killImageNode, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []), + )) + + # Test with constraint. + def onVertMove(offset): + if self.friction == -1: + self.assertEqual(offset, (0,40)) + self.messageTester.setMessageReceived(gesture.Recognizer.MOTION) + + for self.friction in (-1, 100): + if self.friction == -1: + sys.stderr.write(" Drag with constraint, no inertia\n") + else: + sys.stderr.write(" Drag with constraint, inertia\n") + dragRecognizer, self.messageTester = setupRecognizer(moveHandler=onVertMove, + friction=self.friction, direction=gesture.DragRecognizer.VERTICAL, + minDragDist=5) + self.start(False, + (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, + [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, + [gesture.Recognizer.UP, gesture.Recognizer.END]), + # Wrong direction -> stop. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 70, 30, + [gesture.Recognizer.FAILED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 70, 30, []), + + # No movement -> stop. + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, + [gesture.Recognizer.FAILED]), + + # Down, Abort, Motion, Motion, Up -> not recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []), + + # Down, Motion, Abort, Motion, Up -> not Recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []), + + # Down, Motion, Motion, Abort, Up -> not recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, + [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []), + + # Down, Motion, Abort, Up, Down, Motion, Motion, Up -> Recognized + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []), + abort, + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []), + + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, + [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, + [gesture.Recognizer.UP, gesture.Recognizer.END]), + )) + + # Test second down during inertia. + sys.stderr.write(" Down during inertia\n") + dragRecognizer, self.messageTester = setupRecognizer(friction=0.01) + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 40, 20), + self.messageTester.reset, + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 40, 20, + [gesture.Recognizer.END, gesture.Recognizer.DETECTED, + gesture.Recognizer.MOTION]), + )) + + # Test node delete during inertia + sys.stderr.write(" Delete during inertia\n") + dragRecognizer, self.messageTester = setupRecognizer(friction=0.01) + self.start(False, + (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.DETECTED]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, + [gesture.Recognizer.MOTION, gesture.Recognizer.UP]), + self.__killImageNode, + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 40, 20, + [gesture.Recognizer.MOTION]), + )) + + # Test second down during inertia, constrained recognizer + sys.stderr.write(" Down during inertia, constrained recognizer\n") + dragRecognizer, self.messageTester = setupRecognizer(friction=0.01, + direction=gesture.DragRecognizer.VERTICAL, minDragDist=5) + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, + [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION, + gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 70, + [gesture.Recognizer.MOTION, gesture.Recognizer.UP]), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.END, gesture.Recognizer.POSSIBLE, + gesture.Recognizer.MOTION]), + )) + + # Test abort in possible handler + for self.friction in (-1, 100): + if self.friction == -1: + sys.stderr.write(" Abort in possible handler, no inertia\n") + else: + sys.stderr.write(" Abort in possible handler, inertia\n") + dragRecognizer, self.messageTester = setupRecognizer(friction=self.friction, + minDragDist=5, possibleHandler=abort) + self.start(False, + (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 70, 70, []), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 70, 70, []), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, + [gesture.Recognizer.POSSIBLE]), + )) + + player.setFakeFPS(-1) + + + def testDragRecognizerRelCoords(self): + + def onDrag(offset): + self.assertAlmostEqual(offset, (-40,-40)) + self.__onDragCalled = True + + player.setFakeFPS(100) + self.__onDragCalled = False + for self.friction in (-1, 100): + root = self.loadEmptyScene() + div = avg.DivNode(pos=(64,64), angle=math.pi, parent=root) + image = avg.ImageNode(parent=div, href="rgb24-64x64.png") + dragRecognizer = gesture.DragRecognizer(image, moveHandler=onDrag, + friction=self.friction) + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 70, 70), + )) + player.setFakeFPS(-1) + assert(self.__onDragCalled) + + + def testDragRecognizerInitialEvent(self): + + def onMotion(offset): + gesture.DragRecognizer(self.image, + detectedHandler=onDragStart, moveHandler=onDrag, + initialEvent=player.getCurrentEvent()) + self.image.unsubscribe(avg.Node.CURSOR_MOTION, onMotion) + + def onDragStart(): + self.__dragStartCalled = True + + def onDrag(offset): + self.assertEqual(offset, (10,0)) + + self.__initImageScene() + self.image.subscribe(avg.Node.CURSOR_MOTION, onMotion) + self.__dragStartCalled = False + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 40, 30), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 50, 30), + )) + assert(self.__dragStartCalled) + + + def testDragRecognizerCoordSysNode(self): + + def onDrag(offset): + self.assertEqual(offset, (40,40)) + self.__dragRecognizerCalled = True + + root = self.loadEmptyScene() + div = avg.DivNode(pos=(64,64), angle=math.pi, parent=root) + image = avg.ImageNode(parent=div, href="rgb24-64x64.png") + dragRecognizer = gesture.DragRecognizer(image, moveHandler=onDrag, + coordSysNode=div, friction=-1) + self.__dragRecognizerCalled = False + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 70, 70), + )) + assert(self.__dragRecognizerCalled) + + + def testDragRecognizerCoordSysNodeParentUnlink(self): + + def onDrag(offset): + self.assertEqual(offset, (40,40)) + self.__dragRecognizerCalled = True + + def onUp(offset): + self.__upRecognizerCalled = True + + root = self.loadEmptyScene() + div = avg.DivNode(pos=(64,64), angle=math.pi, parent=root) + image = avg.ImageNode(parent=div, href="rgb24-64x64.png") + dragRecognizer = gesture.DragRecognizer(image, moveHandler=onDrag, + coordSysNode=div, friction=-1) + self.__dragRecognizerCalled = False + self.__upRecognizerCalled = False + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 70, 70), + lambda: div.unlink(False), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 70), + )) + assert(self.__dragRecognizerCalled) + assert(not self.__upRecognizerCalled) + + + def testDragRecognizerMinDist(self): + + def onMove(offset): + self.messageTester.setMessageReceived(gesture.Recognizer.MOTION) + + self.__initImageScene() + dragRecognizer = gesture.DragRecognizer(self.image, moveHandler=onMove, + minDragDist=10, friction=-1) + self.messageTester = MessageTester(dragRecognizer, [gesture.Recognizer.DETECTED], + self) + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 35, + []), + self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 50, + [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]), + )) + + + def testTransformRecognizer(self): + + def onDetected(): + pass + + def onMove(transform): + self.transform = transform + + def onUp(transform): + self.transform = transform + + def checkTransform(expectedTransform): +# print self.transform +# print expectedTransform +# print + self.assertAlmostEqual(self.transform.trans, expectedTransform.trans) + self.assertAlmostEqual(self.transform.rot, expectedTransform.rot) + self.assertAlmostEqual(self.transform.scale, expectedTransform.scale) + if expectedTransform.rot != 0 or expectedTransform.scale != 1: + self.assertAlmostEqual(self.transform.pivot, expectedTransform.pivot) + + def createTransTestFrames(): + return ( + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10), + lambda: checkTransform(gesture.Transform((10,0))), + ) + + def createRotTestFrames(expectedTransform): + return ( + lambda: self._sendTouchEvents(( + (1, avg.Event.CURSOR_DOWN, 0, 10), + (2, avg.Event.CURSOR_DOWN, 0, 20))), + lambda: self._sendTouchEvents(( + (1, avg.Event.CURSOR_MOTION, 0, 20), + (2, avg.Event.CURSOR_MOTION, 0, 10))), + lambda: checkTransform(expectedTransform), + lambda: self._sendTouchEvents(( + (1, avg.Event.CURSOR_UP, 0, 20), + (2, avg.Event.CURSOR_UP, 0, 10))), + ) + + def createScaleTestFrames(expectedTransform): + return ( + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 0, 10), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 0, 20), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 0, 10), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_MOTION, 0, 30), + lambda: checkTransform(expectedTransform), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 0, 10), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 0, 30), + ) + + player.setFakeFPS(100) + self.__initImageScene() + # Turn off the jitter filter. + gesture.TransformRecognizer.FILTER_MIN_CUTOFF = None + gesture.TransformRecognizer.FILTER_BETA = None + + self.__transformRecognizer = gesture.TransformRecognizer(self.image, + friction=-1, + detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp) + self.start(False, + (# Check up/down handling + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: checkTransform(gesture.Transform((0,0))), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10), + lambda: checkTransform(gesture.Transform((10,0))), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 20, 20), + lambda: checkTransform(gesture.Transform((0,0))), + lambda: self._sendTouchEvents(( + (1, avg.Event.CURSOR_MOTION, 30, 10), + (2, avg.Event.CURSOR_MOTION, 30, 20))), + lambda: checkTransform(gesture.Transform((10,0))), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 20), + lambda: checkTransform(gesture.Transform((0,0))), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 40, 10), + lambda: checkTransform(gesture.Transform((10,0))), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 50, 10), + lambda: checkTransform(gesture.Transform((10,0))), + + createRotTestFrames(gesture.Transform((0,0), math.pi, 1, (0,15))), + + createScaleTestFrames(gesture.Transform((0,5), 0, 2, (0,20))), + + # Delete node during transform + lambda: self._sendTouchEvents(( + (1, avg.Event.CURSOR_DOWN, 30, 10), + (2, avg.Event.CURSOR_DOWN, 30, 20))), + self.__killImageNode, + lambda: self._sendTouchEvents(( + (1, avg.Event.CURSOR_UP, 30, 10), + (2, avg.Event.CURSOR_UP, 30, 20))), + )) + + # Test rel. coords. + root = self.loadEmptyScene() + div = avg.DivNode(parent=root, pos=(0,10)) + image = avg.ImageNode(parent=div, href="rgb24-64x64.png") + self.__transformRecognizer = gesture.TransformRecognizer(image, friction=-1, + detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp) + self.start(False, + (createTransTestFrames(), + createRotTestFrames(gesture.Transform((0,0), math.pi, 1, (0,5))), + createScaleTestFrames(gesture.Transform((0,5), 0, 2, (0,10))), + )) + + # Test coordSysNode. + root = self.loadEmptyScene() + div = avg.DivNode(parent=root, pos=(0,10)) + image = avg.ImageNode(parent=div, href="rgb24-64x64.png") + self.__transformRecognizer = gesture.TransformRecognizer(image, coordSysNode=div, + friction=-1, + detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp) + self.start(False, + (createTransTestFrames(), + createRotTestFrames(gesture.Transform((0,0), math.pi, 1, (0,15))), + createScaleTestFrames(gesture.Transform((0,5), 0, 2, (0,20))), + )) + + # Test friction + root = self.loadEmptyScene() + div = avg.DivNode(parent=root, pos=(0,10)) + image = avg.ImageNode(parent=div, href="rgb24-64x64.png") + self.__transformRecognizer = gesture.TransformRecognizer(image, friction=0.01, + detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp) + self.start(False, + (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10), + )) + + # Test abort + self.__initImageScene() + self.__transformRecognizer = gesture.TransformRecognizer(self.image, + detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp) + self.start(False, + (self.__transformRecognizer.abort, + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + self.__transformRecognizer.abort, + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 30, 10), + lambda: checkTransform(gesture.Transform((0,0))), + self.__transformRecognizer.abort, + )) + + # Test enable/disable + self.__initImageScene() + self.__transformRecognizer = gesture.TransformRecognizer(self.image, friction=-1, + detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp) + self.start(False, + (# Regular disable + lambda: self.__transformRecognizer.enable(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, 30, 10), + lambda: checkTransform(gesture.Transform((0,0))), + # Re-enable + lambda: self.__transformRecognizer.enable(True), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10), + lambda: checkTransform(gesture.Transform((10,0))), + # Disable during gesture + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: self.__transformRecognizer.enable(False), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10), + lambda: checkTransform(gesture.Transform((0,0))), + lambda: self.__transformRecognizer.enable(True), + )) + + # Test enable/disable, friction + def disableDuringEnd(): + self.__transformRecognizer.enable(False) + + self.__initImageScene() + self.__transformRecognizer = gesture.TransformRecognizer(self.image, friction=1, + detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp) + self.start(False, + (# Disable during end event + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: self.__transformRecognizer.subscribe(gesture.Recognizer.END, + disableDuringEnd), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 10, 10), + None, + )) + + # Test second down during inertia. + self.__initImageScene() + self.__transformRecognizer = gesture.TransformRecognizer(self.image, + friction=0.01, detectedHandler=onDetected, moveHandler=onMove, + upHandler=onUp) + self.start(False, + ( + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 30, 10), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 30, 10), + )) + player.setFakeFPS(-1) + + def testKMeans(self): + pts = [avg.Point2D(0,0), avg.Point2D(0,1)] + means = gesture.calcKMeans(pts) + self.assertEqual(means, ([0], [1])) + + pts.append (avg.Point2D(0,4)) + means = gesture.calcKMeans(pts) + self.assertEqual(means, ([0,1], [2])) + + + def testMat3x3(self): + t = gesture.Mat3x3.translate([1,0,1]) + v = [1,0,1] + self.assertEqual(t.applyVec(v), [2,0,1]) + r = gesture.Mat3x3.rotate(math.pi/2) + self.assertAlmostEqual(r.applyVec(v), [0,1,1]) + self.assertAlmostEqual(t.applyMat(t).m, gesture.Mat3x3.translate([2,0,1]).m) + self.assertAlmostEqual(t.applyMat(r).m, gesture.Mat3x3([0,-1,1],[1,0,0]).m) + self.assertAlmostEqual(r.applyMat(t).m, gesture.Mat3x3([0,-1,0],[1,0,1]).m) + self.assertAlmostEqual(gesture.Mat3x3().m, gesture.Mat3x3().inverse().m) + m = gesture.Mat3x3([-1, 3, -3], + [ 0, -6, 5], + [-5, -3, 1]) + im = gesture.Mat3x3([3./2, 1., -1./2], + [-25./6, -8./3, 5./6], + [-5., -3., 1.]) + self.assertAlmostEqual(m.inverse().m, im.m) + + image = avg.ImageNode(pos=(10,20), size=(30,40), angle=1.57, + href="rgb24alpha-64x64.png") + mat = gesture.Mat3x3.fromNode(image) + mat.setNodeTransform(image) + self.assertAlmostEqual(image.pos, (10,20)) + self.assertAlmostEqual(image.size, (30,40)) + self.assertAlmostEqual(image.angle, 1.57) + + def __initImageScene(self): + root = self.loadEmptyScene() + self.image = avg.ImageNode(parent=root, href="rgb24-64x64.png") + + def __killImageNode(self): + self.image.unlink(True) + self.image = None + + +def gestureTestSuite(tests): + availableTests = ( + "testTapRecognizer", + "testHoldRecognizer", + "testDoubletapRecognizer", + "testSwipeRecognizer", + "testSwipeRecognizerTwoFingers", + "testDragRecognizer", + "testDragRecognizerRelCoords", + "testDragRecognizerInitialEvent", + "testDragRecognizerCoordSysNode", + "testDragRecognizerCoordSysNodeParentUnlink", + "testDragRecognizerMinDist", + "testTransformRecognizer", + "testKMeans", + "testMat3x3", + ) + + return createAVGTestSuite(availableTests, GestureTestCase, tests) diff --git a/src/test/ImageTest.py b/src/test/ImageTest.py new file mode 100644 index 0000000..f59d4ad --- /dev/null +++ b/src/test/ImageTest.py @@ -0,0 +1,583 @@ +#!/usr/bin/env python +# -*- 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 +# + + +import shutil + +from libavg import avg, player +from testcase import * + +class ImageTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testImageHRef(self): + def createXmlNode(pos): + node = player.createNode( + """<image pos="%s" href="rgb24-32x32.png"/>"""%str(pos)) + self.assertEqual(node.getMediaSize(), avg.Point2D(32, 32)) + return node + + def createDictNode(root, p): + node = avg.ImageNode(pos=p, href="rgb24-32x32.png", parent=root) + self.assertEqual(node.getMediaSize(), avg.Point2D(32, 32)) + self.assertEqual(node.size, avg.Point2D(32, 32)) + return node + + def addNodes(y): + xmlNode = createXmlNode((16, y)) + root.appendChild(xmlNode) + + createDictNode(root, (48, y)) + + noAttachNode = createXmlNode((80, y)) + noAttachNode.href = "rgb24alpha-32x32.png" + self.assertEqual(noAttachNode.getMediaSize(), avg.Point2D(32, 32)) + self.assertEqual(noAttachNode.size, avg.Point2D(32,32)) + root.appendChild(noAttachNode) + + attachNode = createXmlNode((112, y)) + root.appendChild(attachNode) + attachNode.href = "rgb24alpha-32x32.png" + self.assertEqual(attachNode.getMediaSize(), avg.Point2D(32, 32)) + self.assertEqual(attachNode.size, avg.Point2D(32,32)) + + def setUnicodeHref(): + if self._isCurrentDirWriteable(): + # Can't check unicode filenames into svn or the windows client breaks. + # So we rename the file locally. + shutil.copyfile("media/oe.png", u"media/ö.png") + node = createXmlNode((16, 16)) + root.appendChild(node) + node.href = u"ö.png" + os.remove(u"media/ö.png") + + def compareUnicode(): + if self._isCurrentDirWriteable(): + self.compareImage("testImgHRef3") + + root = self.loadEmptyScene() + addNodes(16) + self.start(False, + (lambda: self.compareImage("testImgHRef1"), + lambda: addNodes(48), + lambda: self.compareImage("testImgHRef2"), + setUnicodeHref, + compareUnicode + )) + + def testImagePos(self): + def createXmlNode(pos): + return player.createNode( + """<image pos="%s" href="rgb24-32x32.png"/>"""%str(pos)) + + def createDictNode(root, p): + return avg.ImageNode(pos=p, href="rgb24-32x32.png", parent=root) + + def illegalMove(node): + self.assertException(node.pos.x == 23) + self.assertException(node.pos.y == 23) + + def addNodes(y): + xmlNode = createXmlNode((16, y)) + root.appendChild(xmlNode) + createDictNode(root, (48, y)) + noAttachNode = createXmlNode((0, 0)) + noAttachNode.pos = avg.Point2D(80, y) + illegalMove(noAttachNode) + root.appendChild(noAttachNode) + attachNode = createXmlNode((0, 0)) + root.appendChild(attachNode) + attachNode.pos = avg.Point2D(112, y) + illegalMove(attachNode) + + root = self.loadEmptyScene() + addNodes(16) + self.start(False, + (lambda: self.compareImage("testImgPos1"), + lambda: addNodes(48), + lambda: self.compareImage("testImgPos2"), + )) + + def testImageSize(self): + def createXmlNode(pos, size): + return player.createNode( + """<image pos="%s" size="%s" href="rgb24-64x64.png"/>""" + %(str(pos), str(size))) + + def createDictNode(p, s): + return avg.ImageNode(pos=p, size=s, href="rgb24-64x64.png") + + def addNodes(y): + xmlNode = createXmlNode((16, y), (32, 32)) + self.assertEqual(xmlNode.size, avg.Point2D(32, 32)) + root.appendChild(xmlNode) + dictNode = createDictNode((48, y), (32, 32)) + self.assertEqual(dictNode.size, avg.Point2D(32, 32)) + root.appendChild(dictNode) + noAttachNode = createXmlNode((80, y), (0, 0)) + noAttachNode.size = avg.Point2D(32, 32) + self.assertEqual(noAttachNode.size, avg.Point2D(32, 32)) + root.appendChild(noAttachNode) + attachNode = createXmlNode((112, y), (0, 0)) + root.appendChild(attachNode) + attachNode.size = avg.Point2D(32, 32) + self.assertEqual(attachNode.size, avg.Point2D(32, 32)) + + root = self.loadEmptyScene() + addNodes(16) + self.start(False, + (lambda: self.compareImage("testImgSize1"), + lambda: addNodes(48), + lambda: self.compareImage("testImgSize2"), + )) + + def testImageWarp(self): + def createNode(p): + return avg.ImageNode(pos=p, href="rgb24-32x32.png", + maxtilewidth=16, maxtileheight=8) + + def moveVertex(node): + grid = node.getWarpedVertexCoords() + grid[0][1] = (grid[0][1][0]+0.25, grid[0][1][1]+0.25) + node.setWarpedVertexCoords(grid) + + def testEarlyAccessException(): + node = createNode((16, 16)) + root.appendChild(node) + self.assertException(node.getWarpedVertexCoords) + node.unlink() + + def addNode(): + self.node = createNode((16, 16)) + root.appendChild(self.node) + moveVertex(self.node) + + def changeHref(): + self.node.href = "rgb24-65x65.png" + grid = self.node.getWarpedVertexCoords() + self.assert_(len(grid) == 10) + self.assert_(len(grid[0]) == 6) + + + root = self.loadEmptyScene() + testEarlyAccessException() + self.start(False, + (lambda: addNode(), + lambda: self.compareImage("testImgWarp1"), + lambda: changeHref(), + lambda: self.compareImage("testImgWarp2"), + )) + + def testBitmap(self): + def getBitmap(node): + bmp = node.getBitmap() + self.assertEqual(bmp.getSize(), (65,65)) + self.assert_(bmp.getFormat() == avg.R8G8B8X8 or + bmp.getFormat() == avg.B8G8R8X8) + node.setBitmap(bmp) + self.assertEqual(node.getMediaSize(), (65,65)) + + def loadFromBitmap(p, orighref): + node = avg.ImageNode(pos=p, size=(32, 32), href=orighref) + bmp = avg.Bitmap('media/rgb24-65x65.png') + self.assertEqual(bmp.getSize(), (65,65)) + node.setBitmap(bmp) + self.assertEqual(node.getMediaSize(), (65,65)) + root.appendChild(node) + + def testStringConversion(): + bmp = avg.Bitmap('media/rgb24-65x65.png') + s = bmp.getPixels() + bmp1 = avg.Bitmap(bmp.getSize(), bmp.getFormat(), "sample") + bmp1.setPixels(s) + self.assert_(self.areSimilarBmps(bmp, bmp1, 0.01, 0.01)) + + def testCropRect(): + bmp = avg.Bitmap('media/rgb24-65x65.png') + bmp1 = avg.Bitmap(bmp, (32,32), (64,64)) + self.assert_(bmp1.getSize() == (32,32)) + node = avg.ImageNode(pos=(96,0), parent=root) + node.setBitmap(bmp1) + + def testBlt(): + srcBmp = avg.Bitmap('media/rgb24-65x65.png') + destBmp = avg.Bitmap((65,65), srcBmp.getFormat(), "bmp") + destBmp.blt(srcBmp, (0,0)) + destBmp.blt(srcBmp, (32,32)) + node = avg.ImageNode(pos=(96,32), size=(32,32), parent=root) + node.setBitmap(destBmp) + + def testResize(): + srcBmp = avg.Bitmap('media/rgb24-32x32.png') + destBmp = srcBmp.getResized((64,64)) + self.assert_(destBmp.getSize() == (64,64)) + node = avg.ImageNode(pos=(128,0), size=(32,32), parent=root) + node.setBitmap(destBmp) + + def testUnicode(): + if self._isCurrentDirWriteable(): + # Can't check unicode filenames into svn or the windows client breaks. + # So we rename the file locally. + shutil.copyfile("media/oe.png", u"media/ö.png") + avg.Bitmap(u"media/ö.png") + os.remove(u"media/ö.png") + + def testGetPixel(): + bmp = avg.Bitmap('media/rgb24-65x65.png') + self.assertEqual(bmp.getPixel((1,1)), (255,0,0,255)) + self.assertEqual(bmp.getPixel((33,1)), (0,255,0,255)) + bmp = avg.Bitmap('media/rgb24alpha-64x64.png') + self.assertEqual(bmp.getPixel((1,1)), (0,0,0,0)) + self.assertEqual(bmp.getPixel((63,1)), (83,255,83,142)) + bmp = avg.Bitmap('media/greyscale.png') + self.assertEqual(bmp.getPixel((1,1)), (255,255,255,255)) + self.assertEqual(bmp.getPixel((1,63)), (0,0,0,255)) + self.assertException(lambda: bmp.getPixel((64,0))) + + def setNullBitmap(): + node.setBitmap(None) + + def testSubBitmap(): + srcBmp = avg.Bitmap('media/rgb24-32x32.png') + destBmp = avg.Bitmap(srcBmp, (16,16), (32,32)) + self.assertEqual(srcBmp.getPixel((16,16)), destBmp.getPixel((0,0))) + self.assertException(lambda: avg.Bitmap(srcBmp, (16,16), (16,32))) + + node = avg.ImageNode(href="media/rgb24-65x65.png", size=(32, 32)) + getBitmap(node) + + root = self.loadEmptyScene() + node = avg.ImageNode(pos=(0,0), size=(32, 32), href="rgb24-65x65.png") + root.appendChild(node) + getBitmap(node) + self.assertEqual(node.size, (32,32)) + loadFromBitmap((32,0), "") + loadFromBitmap((64,0), "rgb24alpha-64x64.png") + testStringConversion() + testUnicode() + self.start(False, + (lambda: getBitmap(node), + lambda: loadFromBitmap((32,32), ""), + lambda: loadFromBitmap((64,32), "rgb24alpha-64x64.png"), + lambda: self.compareImage("testBitmap1"), + testCropRect, + lambda: self.compareImage("testBitmap2"), + testBlt, + lambda: self.compareImage("testBitmap3"), + testResize, + lambda: self.compareImage("testBitmap4"), + testGetPixel, + lambda: self.assertException(setNullBitmap), + testSubBitmap, + )) + + def testBitmapManager(self): + WAIT_TIMEOUT = 2000 + def expectException(returnValue, nextAction): + if isinstance(returnValue, Exception): + nextAction() + else: + raise RuntimeError("Expected exception, got %s (%s)" % ( + returnValue, type(returnValue))) + + def loadValidBitmap(): + def validBitmapCb(bitmap): + self.assert_(not isinstance(bitmap, Exception)) + player.setTimeout(0, loadBitmapWithPixelFormat) + + avg.BitmapManager.get().loadBitmap("media/rgb24alpha-64x64.png", + validBitmapCb) + + def loadBitmapWithPixelFormat(): + def validBitmapCb(bitmap): + self.assert_(not isinstance(bitmap, Exception)) + self.assert_(bitmap.getFormat() == avg.B5G6R5) + player.setTimeout(0, loadUnexistentBitmap) + + avg.BitmapManager.get().loadBitmap("media/rgb24alpha-64x64.png", + validBitmapCb, avg.B5G6R5) + + def loadUnexistentBitmap(): + avg.BitmapManager.get().loadBitmap("nonexistent.png", + lambda bmp: expectException( + returnValue=bmp, + nextAction=lambda: player.setTimeout(0, loadBrokenBitmap))) + + def loadBrokenBitmap(): + import tempfile + tempFileName = os.path.join(tempfile.gettempdir(), + "broken.png") + open(tempFileName, "w") + + def cleanupAndTestReturnValue(returnValue): + os.unlink(tempFileName) + expectException(returnValue=returnValue, nextAction=player.stop) + + avg.BitmapManager.get().loadBitmap(tempFileName, + cleanupAndTestReturnValue) + + def reportStuck(): + raise RuntimeError("BitmapManager didn't reply " + "within %dms timeout" % WAIT_TIMEOUT) + player.stop() + + for multithread in [False, True]: + self.loadEmptyScene() + if multithread: + avg.BitmapManager.get().setNumThreads(2) + player.setTimeout(WAIT_TIMEOUT, reportStuck) + player.setResolution(0, 0, 0, 0) + loadValidBitmap() + player.play() + avg.BitmapManager.get().setNumThreads(1) + + def testBitmapManagerException(self): + def bitmapCb(bitmap): + raise RuntimeError + + self.loadEmptyScene() + avg.BitmapManager.get().loadBitmap("rgb24alpha-64x64.png", bitmapCb), + self.assertException(player.play) + + def testBlendMode(self): + def isBlendMinMaxSupported(): + def tryInsertNode(): + try: + avg.ImageNode(href="rgb24-65x65.png", blendmode="min", parent=root) + except RuntimeError: + self.supported = False + root = self.loadEmptyScene() + self.supported = True + self.start(False, + (tryInsertNode, + )) + return self.supported + + + def setBlendMode(): + blendNode.blendmode="add" + + if not(isBlendMinMaxSupported()): + self.skip("Blend modes min and max not supported.") + return + root = self.loadEmptyScene() + avg.ImageNode(href="freidrehen.jpg", parent=root) + blendNode = avg.ImageNode(opacity=0.6, href="rgb24-65x65.png", parent=root) + avg.ImageNode(pos=(0,48), opacity=0.6, href="rgb24-65x65.png", blendmode="add", + parent=root) + avg.ImageNode(pos=(48,0), opacity=1, href="rgb24-65x65.png", blendmode="min", + parent=root) + avg.ImageNode(pos=(48,48), opacity=1, href="rgb24-65x65.png", blendmode="max", + parent=root) + + self.start(False, + (lambda: self.compareImage("testBlend1"), + setBlendMode, + lambda: self.compareImage("testBlend2") + )) + + def testImageMask(self): + def createNode(p): + node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png", + pos=p, size=(32, 32)) + root.appendChild(node) + + def setNoAttach(p): + node = avg.ImageNode(href="rgb24-65x65.png", pos=p, size=(32, 32)) + node.maskhref = "mask.png" + root.appendChild(node) + + def setAttach(p): + node = avg.ImageNode(href="rgb24-65x65.png", pos=p, size=(32, 32)) + root.appendChild(node) + node.maskhref = "mask.png" + + def changeHRef(): + node.maskhref = "mask2.png" + + def changeBaseHRef(): + node.href = "greyscale.png" + + def setMaskNotFound(): + node.maskhref = "nonexistentmask.png" + + root = self.loadEmptyScene() + createNode((0,0)) + node = root.getChild(0) + setNoAttach((32,0)) + setAttach((64,0)) + self.start(False, + (lambda: createNode((0, 32)), + lambda: setNoAttach((32,32)), + lambda: setAttach((64,32)), + lambda: self.compareImage("testImgMask1"), + changeHRef, + lambda: self.compareImage("testImgMask2"), + changeBaseHRef, + lambda: self.compareImage("testImgMask3"), + setMaskNotFound + )) + + def testImageMaskCanvas(self): + root = self.loadEmptyScene() + canvas = player.createCanvas(id="testcanvas", size=(64,64), mediadir="media") + avg.ImageNode(href="rgb24-64x64.png", parent=canvas.getRootNode()) + avg.RectNode(size=(160,120), fillcolor="FFFFFF", fillopacity=1, parent=root) + avg.ImageNode(href="canvas:testcanvas", maskhref="mask.png", parent=root) + self.start(False, + (lambda: self.compareImage("testImgMaskCanvas"),)) + + def testImageMaskPos(self): + def createNode(p): + node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png", + pos=p, size=(32, 32), maskpos=(32, 32)) + root.appendChild(node) + + def setNoAttach(p): + node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png", + pos=p, size=(32, 32)) + node.maskpos = (32, 32) + root.appendChild(node) + + def setAttach(p): + node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png", + pos=p, size=(32, 32)) + root.appendChild(node) + node.maskpos = (32, 32) + + root = self.loadEmptyScene() + createNode((0,0)) + setNoAttach((32,0)) + setAttach((64,0)) + self.start(False, + (lambda: createNode((0, 32)), + lambda: setNoAttach((32,32)), + lambda: setAttach((64,32)), + lambda: self.compareImage("testImgMaskPos") + )) + + def testImageMaskSize(self): + def createNode(p): + avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png", + pos=p, size=(32, 32), masksize=(48, 48), parent=root) + + def setNoAttach(p): + node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png", + pos=p, size=(32, 32)) + node.masksize = (48, 48) + root.appendChild(node) + + def setAttach(p): + node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png", + pos=p, size=(32, 32), parent=root) + node.masksize = (48, 48) + + def setPos(): + node.maskpos = (16, 16) + + def resetPos(): + node.maskpos = (0, 0) + node.masksize = (0, 0) + + root = self.loadEmptyScene() + createNode((0,0)) + node = root.getChild(0) + setNoAttach((32,0)) + setAttach((64,0)) + self.start(False, + (lambda: createNode((0, 32)), + lambda: setNoAttach((32,32)), + lambda: setAttach((64,32)), + lambda: self.compareImage("testImgMaskSize1"), + setPos, + lambda: self.compareImage("testImgMaskSize2"), + resetPos, + lambda: self.compareImage("testImgMaskSize3") + )) + + def testImageMipmap(self): + root = self.loadEmptyScene() + avg.ImageNode(size=(64,64), href="checker.png", mipmap=True, parent=root) + self.start(False, + (lambda: self.compareImage("testMipmap"),)) + + def testImageCompression(self): + def loadBitmap(): + bmp = avg.Bitmap("media/colorramp.png") + self.image.setBitmap(bmp) + + def relink(): + self.image.unlink(False) + root.appendChild(self.image) + + def checkAlpha(): + self.image.href="rgb24alpha-64x64.png" + + root = self.loadEmptyScene() + self.image = avg.ImageNode(href="rgb24-64x64.png", compression="B5G6R5", + parent=root) + self.assertEqual(self.image.compression, "B5G6R5") + self.start(False, + [lambda: self.compareImage("testTexCompression1"), + loadBitmap, + lambda: self.compareImage("testTexCompression2"), + relink, + lambda: self.compareImage("testTexCompression2"), + checkAlpha, + ]) + + def testSpline(self): + spline = avg.CubicSpline([(0,3),(1,2),(2,1),(3,0)]) + self.assertAlmostEqual(spline.interpolate(0), 3) + self.assertAlmostEqual(spline.interpolate(0.5), 2.5) + self.assertAlmostEqual(spline.interpolate(1), 2) + self.assertAlmostEqual(spline.interpolate(-1), 4) + self.assertAlmostEqual(spline.interpolate(4), -1) + + spline = avg.CubicSpline([(2,0),(4,1),(6,3),(8,6)]) + self.assertAlmostEqual(spline.interpolate(2), 0) + self.assert_(spline.interpolate(3) < 0.5) + self.assert_(spline.interpolate(3) > 0.0) + self.assert_(spline.interpolate(7) < 4.5) + self.assert_(spline.interpolate(7) > 4) + + +def imageTestSuite(tests): + availableTests = ( + "testImageHRef", + "testImagePos", + "testImageSize", + "testImageWarp", + "testBitmap", + "testBitmapManager", + "testBitmapManagerException", + "testBlendMode", + "testImageMask", + "testImageMaskCanvas", + "testImageMaskPos", + "testImageMaskSize", + "testImageMipmap", + "testImageCompression", + "testSpline", + ) + return createAVGTestSuite(availableTests, ImageTestCase, tests) diff --git a/src/test/InputDeviceTest.py b/src/test/InputDeviceTest.py new file mode 100644 index 0000000..c6350cb --- /dev/null +++ b/src/test/InputDeviceTest.py @@ -0,0 +1,218 @@ +# -*- 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 * + + +class CustomMouseEvent(avg.TouchEvent): + def __init__(self, eventId, eventType, pos, source): + super(CustomMouseEvent, self).__init__(eventId, eventType, pos, source) + self.customAttribute = None + + def customMethod(self): + pass + + +class CustomInputDevice(avg.InputDevice): + def __init__(self, eventReceiverNode=None): + if eventReceiverNode: + super(CustomInputDevice, self).__init__(self.__class__.__name__, + eventReceiverNode) + else: + super(CustomInputDevice, self).__init__(self.__class__.__name__) + + self.__events = [] + + def pollEvents(self): + events = self.__events[:] + self.__events = [] + return events + + def feedEvent(self, event): + self.__events.append(event) + + +class AnonymousInputDevice(avg.InputDevice): + def __init__(self, eventReceiverNode=None): + if eventReceiverNode: + super(AnonymousInputDevice, self).__init__(self.__class__.__name__, + eventReceiverNode) + else: + super(AnonymousInputDevice, self).__init__(self.__class__.__name__) + + self.__isInitialized = False + + def pollEvents(self): + if self.__isInitialized: return [] + self.__isInitialized = True + return [ avg.Event(avg.Event.CUSTOM_EVENT, avg.Event.CUSTOM) ] + + +class EventTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testCustomInputDevice(self): + root = self.loadEmptyScene() + + class DerivedEvent(avg.Event): + def __init__(self): + super(DerivedEvent, self).__init__(avg.Event.CUSTOM_EVENT, avg.Event.NONE) + self.property = True + + class CustomMouseEvent(avg.TouchEvent): + def __init__(self): + super(CustomMouseEvent, self).__init__(42, avg.Event.CURSOR_DOWN, + (10, 10), avg.Event.TOUCH) + self.customAttribute = None + + self.hasEventHandlerBeenCalled = False + self.isCustomInputDeviceSet = False + self.isCustomInputDeviceNameSet = False + self.hasCustomEventProperty = False + self.customMouseEventHandlerCalled = False + + def eventHandler(event): + self.hasEventHandlerBeenCalled = True + self.isCustomInputDeviceSet = event.inputdevice == self.customInputDevice + self.isCustomInputDeviceNameSet = (event.inputdevicename == + self.customInputDevice.name) + + def customEventEventHandler(event): + self.hasCustomEventProperty = event.property + + def customMouseEventHandler(event): + self.customMouseEventHandlerCalled = True + self.assert_(hasattr(event, "customAttribute")) + + def checkAndResetResults(): + if not self.hasEventHandlerBeenCalled: return False + if not self.isCustomInputDeviceSet: return False + if not self.isCustomInputDeviceNameSet: return False + + self.hasEventHandlerBeenCalled = False + self.isCustomInputDeviceSet = False + self.isCustomInputDeviceNameSet = False + return True + + rectNode = avg.RectNode(parent=root, pos=(0, 0), size=(50, 50)) + rectNode.subscribe(avg.Node.CURSOR_DOWN, eventHandler) + + root.subscribe(avg.Node.CURSOR_DOWN, eventHandler) + root.setEventHandler(avg.Event.CUSTOM_EVENT, avg.Event.NONE, + customEventEventHandler) + + self.customInputDevice = CustomInputDevice() + player.addInputDevice(self.customInputDevice) + + self.start(False, + (lambda: self.customInputDevice.feedEvent( + avg.Event(avg.Event.CURSOR_DOWN, avg.Event.MOUSE)), + lambda: self.assert_(checkAndResetResults()), + + lambda: self.customInputDevice.feedEvent( + DerivedEvent()), + lambda: self.assert_(self.hasCustomEventProperty), + + lambda: self.customInputDevice.feedEvent( + avg.MouseEvent(avg.Event.CURSOR_DOWN, False, False, False, + (5, 5), 0)), + lambda: self.assert_(checkAndResetResults()), + + lambda: self.customInputDevice.feedEvent( + avg.TouchEvent(300, avg.Event.CURSOR_DOWN, (5, 5), + avg.Event.TOUCH, (10,10))), + lambda: self.assert_(checkAndResetResults()), + + lambda: root.subscribe(avg.Node.CURSOR_DOWN, customMouseEventHandler), + lambda: self.customInputDevice.feedEvent(CustomMouseEvent()), + lambda: self.assert_(self.customMouseEventHandlerCalled), + )) + + def testAnonymousInputDevice(self): + root = self.loadEmptyScene() + + self.hasEventHandlerBeenCalled = False + + def eventHandler(event): + self.hasEventHandlerBeenCalled = (event.inputdevicename == + AnonymousInputDevice.__name__) + + def checkAndResetResults(): + if not self.hasEventHandlerBeenCalled: + return False + + self.hasEventHandlerBeenCalled = False + return True + + root.setEventHandler(avg.Event.CUSTOM_EVENT, avg.Event.CUSTOM, eventHandler) + player.addInputDevice(AnonymousInputDevice()) + + self.start(False, + (lambda: None, + lambda: None, + lambda: self.assert_(checkAndResetResults()) + )) + + def testInputDeviceEventReceiverNode(self): + root = self.loadEmptyScene() + + divNode = avg.DivNode(id="div", size=(50, 50), parent=root) + rectNode = avg.RectNode(id="rect", size=(50, 50), parent=root) + + self.customInputDevice = CustomInputDevice(divNode) + player.addInputDevice(self.customInputDevice) + + handlerTester = NodeHandlerTester(self, divNode) + + self.start(False, + (lambda: self.customInputDevice.feedEvent( + avg.MouseEvent(avg.Event.CURSOR_DOWN, True, False, False, + (10, 10), 1)), + lambda: handlerTester.assertState( + (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)), + + lambda: self.customInputDevice.feedEvent(avg.MouseEvent( + avg.Event.CURSOR_MOTION, True, False, False, (12, 12), 1)), + lambda: handlerTester.assertState((avg.Node.CURSOR_MOTION,)), + + lambda: self.customInputDevice.feedEvent(avg.MouseEvent( + avg.Event.CURSOR_MOTION, True, False, False, (100, 100), 1)), + lambda: handlerTester.assertState((avg.Node.CURSOR_OUT,)), + + lambda: self.customInputDevice.feedEvent(avg.MouseEvent( + avg.Event.CURSOR_MOTION, True, False, False, (12, 12), 1)), + lambda: handlerTester.assertState( + (avg.Node.CURSOR_OVER, avg.Node.CURSOR_MOTION)), + + lambda: self.customInputDevice.feedEvent(avg.MouseEvent( + avg.Event.CURSOR_UP, False, False, False, (12, 12), 1)), + lambda: handlerTester.assertState((avg.Node.CURSOR_UP,)), + )) + +def inputDeviceTestSuite(tests): + availableTests = ( + "testCustomInputDevice", + "testAnonymousInputDevice", + "testInputDeviceEventReceiverNode" + ) + return createAVGTestSuite(availableTests, EventTestCase, tests) diff --git a/src/test/LoggerTest.py b/src/test/LoggerTest.py new file mode 100644 index 0000000..9848dcd --- /dev/null +++ b/src/test/LoggerTest.py @@ -0,0 +1,96 @@ +# -*- 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 +# + +import StringIO +import logging + +from libavg import logger + +from testcase import * + + +class LoggerTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + self.testMsg = u'福 means good fortune' + + def setUp(self): + self.stream = StringIO.StringIO() + self.hdlr = logging.StreamHandler(self.stream) + self.pyLogger = logging.getLogger(__name__) + self.pyLogger.addHandler(self.hdlr) + self.pyLogger.propagate = False + self.pyLogger.level = logging.DEBUG + logger.addSink(self.pyLogger) + logger.removeStdLogSink() + + def tearDown(self): + self.pyLogger.removeHandler(self.hdlr) + + def _assertMsg(self): + self.stream.flush() + self.assert_(self.stream.getvalue().decode('utf8').find(self.testMsg) != -1) + self.stream.close() + + def _assertNoMsg(self): + self.stream.flush() + self.assert_(self.stream.getvalue().decode('utf8').find(self.testMsg) == -1) + self.stream.close() + + def testRemoveSink(self): + logger.removeSink(self.pyLogger) + logger.info(self.testMsg) + self._assertNoMsg() + + def testConfigureCategory(self): + snowmanCategory = logger.configureCategory(u'☃ Category') + logger.warning(self.testMsg, snowmanCategory) + self._assertMsg() + + def testReconfigureCategory(self): + snowmanCategory = logger.configureCategory(u'☃ Category', logger.Severity.INFO) + logger.info(self.testMsg, snowmanCategory) + self._assertMsg() + + def testOmitCategory(self): + logger.configureCategory(logger.Category.APP, logger.Severity.CRIT) + logger.info(self.testMsg) + self._assertNoMsg() + + def testLogCategory(self): + logger.configureCategory(logger.Category.APP, logger.Severity.INFO) + logger.info(self.testMsg) + self._assertMsg() + + def testUnknownCategoryWarning(self): + self.assertException(lambda: logger.error("Foo", "Bar")) + + +def loggerTestSuite(tests): + availableTests = ( + "testRemoveSink", + "testConfigureCategory", + "testReconfigureCategory", + "testOmitCategory", + "testLogCategory", + "testUnknownCategoryWarning", + ) + return createAVGTestSuite(availableTests, LoggerTestCase, tests) diff --git a/src/test/Makefile.am b/src/test/Makefile.am new file mode 100644 index 0000000..27b0e90 --- /dev/null +++ b/src/test/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = plugin + +pkgpyexec_PYTHON = testcase.py testapp.py + +EXTRA_DIST = $(wildcard *.avg) $(wildcard *.png) $(wildcard *.jpg) $(wildcard *.tif) \ + $(wildcard *.py) $(wildcard baseline/*.png) $(wildcard testmediadir/*) \ + $(wildcard extrafonts) $(wildcard fonts) $(wildcard *.svg) $(wildcard media/*) + +TESTS = Test.py diff --git a/src/test/OffscreenTest.py b/src/test/OffscreenTest.py new file mode 100644 index 0000000..76bff52 --- /dev/null +++ b/src/test/OffscreenTest.py @@ -0,0 +1,472 @@ +# -*- 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 * +import gc + +class OffscreenTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testCanvasBasics(self): + def createCanvas(isFirst, canvasName, x): + canvas = self.__createOffscreenCanvas(canvasName, False) + canvas.getElementByID("test1").x = x + node = avg.ImageNode(parent=root, id="imagenode") + node.href="canvas:"+canvasName + if isFirst: + self.assertEqual(canvas.getNumDependentCanvases(), 0) + self.canvas1 = canvas + else: + self.assertEqual(canvas.getNumDependentCanvases(), 1) + self.canvas2 = canvas + + def unlink(): + self.node = player.getElementByID("imagenode") + self.node.unlink() + self.assertEqual(self.canvas1.getNumDependentCanvases(), 0) + gc.collect() + + def relink(): + root.appendChild(self.node) + self.node = None + self.assertEqual(self.canvas1.getNumDependentCanvases(), 1) + + def changeHRef(href): + player.getElementByID("imagenode").href = href + + def setBitmap(): + bitmap = avg.Bitmap("media/rgb24-65x65.png") + player.getElementByID("imagenode").setBitmap(bitmap) + + def deleteCanvases(): + changeHRef("") + firstNode.href = "" + player.deleteCanvas("testcanvas1") +# self.assertException(lambda: changeHRef("canvas:testcanvas1")) + changeHRef("canvas:testcanvas2") +# self.assertException(lambda: player.deleteCanvas("testcanvas2")) + changeHRef("") + player.deleteCanvas("testcanvas2") +# self.assertException(lambda: player.deleteCanvas("foo")) + + root = self.loadEmptyScene() + root.mediadir = "media" + createCanvas(True, "testcanvas1", 0) + firstNode = player.getElementByID("imagenode") + self.start(False, + (lambda: self.compareImage("testOffscreen1"), + unlink, + lambda: self.compareImage("testOffscreen2"), + relink, + lambda: self.compareImage("testOffscreen1"), + unlink, + lambda: createCanvas(False, "testcanvas2", 80), + lambda: self.compareImage("testOffscreen3"), + lambda: changeHRef("canvas:testcanvas1"), + lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 1), + lambda: self.assertEqual(self.canvas2.getNumDependentCanvases(), 0), + lambda: self.compareImage("testOffscreen1"), + lambda: changeHRef("rgb24-65x65.png"), + lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 0), + lambda: self.compareImage("testOffscreen4"), + lambda: changeHRef("canvas:testcanvas1"), + lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 1), + lambda: self.compareImage("testOffscreen1"), + setBitmap, + lambda: self.compareImage("testOffscreen4"), + deleteCanvases, + lambda: self.compareImage("testOffscreen5"), + )) + + def testCanvasLoadAfterPlay(self): + def createOffscreenCanvas(): + self.__createOffscreenCanvas("offscreencanvas", False) + self.node = avg.ImageNode(parent=root, href="canvas:offscreencanvas") + + root = self.loadEmptyScene() + self.start(False, + (createOffscreenCanvas, + lambda: self.compareImage("testOffscreen1"), + )) + + def testCanvasResize(self): + def setSize(): + self.node.size = (80, 60) + + mainCanvas, offscreenCanvas = self.__setupCanvas(False) + self.start(False, + (setSize, + lambda: self.compareImage("testCanvasResize") + )) + + def testCanvasErrors(self): + self.loadEmptyScene() + # Missing size + self.assertException( + lambda: player.createCanvas(id="foo")) + # Duplicate canvas id + player.createCanvas(id="foo", size=(160, 120)) + self.assertException( + lambda: player.createCanvas(id="foo", size=(160, 120))) + + def testCanvasAPI(self): + def checkMainScreenshot(): + bmp1 = player.screenshot() + bmp2 = mainCanvas.screenshot() + self.assert_(self.areSimilarBmps(bmp1, bmp2, 0.01, 0.01)) + + def checkCanvasScreenshot(): + bmp = offscreenCanvas.screenshot() + self.compareBitmapToFile(bmp, "testOffscreenScreenshot") + + def createCompressed(): + avg.ImageNode(href="canvas:offscreencanvas", compression="B5G6R5", + parent=root) + + root = self.loadEmptyScene() + mainCanvas = player.getMainCanvas() + self.assertEqual(mainCanvas.getRootNode(), root) + offscreenCanvas = self.__createOffscreenCanvas("offscreencanvas", False) + self.assertEqual(offscreenCanvas, player.getCanvas("offscreencanvas")) + self.assertEqual(offscreenCanvas.getElementByID("test1").href, "rgb24-65x65.png") + self.assertEqual(offscreenCanvas.getElementByID("missingnode"), None) + self.assertException(player.screenshot) + self.assertException(createCompressed) + self.start(False, + (checkMainScreenshot, + checkCanvasScreenshot)) + + def testCanvasEvents(self): + def onOffscreenImageDown(event): + self.__offscreenImageDownCalled = True + + def onMainDown(event): + self.__mainDownCalled = True + + def reset(): + self.__offscreenImageDownCalled = False + self.__mainDownCalled = False + + def setPos(): + self.node.pos = (80, 60) + self.node.size = (80, 60) + + mainCanvas, offscreenCanvas = self.__setupCanvas(True) + offscreenImage = offscreenCanvas.getElementByID("test1") + offscreenImage.subscribe(avg.Node.CURSOR_DOWN, onOffscreenImageDown) + player.getRootNode().subscribe(avg.Node.CURSOR_DOWN, onMainDown) + self.__offscreenImageDownCalled = False + self.__mainDownCalled = False + self.start(False, + (lambda: self.fakeClick(10, 10), + lambda: self.assert_(self.__offscreenImageDownCalled), + reset, + lambda: self.fakeClick(80, 10), + lambda: self.assert_(not(self.__offscreenImageDownCalled)), + reset, + setPos, + lambda: self.fakeClick(70, 65), + lambda: self.assert_(not(self.__offscreenImageDownCalled)), + lambda: self.fakeClick(120, 65), + lambda: self.assert_(not(self.__offscreenImageDownCalled)), + reset, + lambda: self.fakeClick(110, 65), + lambda: self.assert_(self.__offscreenImageDownCalled and + self.__mainDownCalled), + reset, + lambda: self.fakeClick(1, 1), + lambda: self.assert_(not(self.__offscreenImageDownCalled) and + self.__mainDownCalled), + )) + + def testCanvasEventCapture(self): + def onOffscreenImageDown(event): + self.__offscreenImageDownCalled = True + + mainCanvas, offscreenCanvas = self.__setupCanvas(True) + offscreenImage = offscreenCanvas.getElementByID("test1") + offscreenImage.subscribe(avg.Node.CURSOR_DOWN, onOffscreenImageDown); + self.__offscreenImageDownCalled = False + offscreenImage.setEventCapture() + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 80, 10), + lambda: self.assert_(self.__offscreenImageDownCalled), + )) + + def testCanvasRender(self): + def createCanvas(): + canvas = player.createCanvas(id="testcanvas", size=(160,120), + mediadir="media", autorender=False) + avg.ImageNode(id="test", href="rgb24-65x65.png", parent=canvas.getRootNode()) + return canvas + + def testEarlyScreenshotException(): + self.assertException(self.__offscreenCanvas.screenshot) + + def renderCanvas(): + self.__offscreenCanvas.render() + bmp = self.__offscreenCanvas.screenshot() + self.compareBitmapToFile(bmp, "testOffscreenScreenshot") + + def deleteCanvas(): + player.deleteCanvas("testcanvas") + self.__offscreenCanvas = None + + def recreateCanvas(): + self.__offscreenCanvas = createCanvas() + + self.loadEmptyScene() + self.__offscreenCanvas = createCanvas() + self.assertException(renderCanvas) + self.start(False, + (testEarlyScreenshotException, + renderCanvas, + deleteCanvas, + recreateCanvas, + renderCanvas + )) + + def testCanvasAutoRender(self): + def createCanvas(): + canvas = self.__createOffscreenCanvas("testcanvas", False) + avg.ImageNode(href="canvas:testcanvas", parent=root) + return canvas + + def disableAutoRender(): + self.__offscreenCanvas.autorender = False + + def enableAutoRender(): + self.__offscreenCanvas.autorender = True + + def changeContent(): + self.__offscreenCanvas.getElementByID("test1").x = 42 + + root = self.loadEmptyScene() + self.__offscreenCanvas = createCanvas() + self.start(False, + (lambda: self.assert_(self.__offscreenCanvas.autorender), + lambda: self.compareImage("testOffscreenAutoRender1"), + disableAutoRender, + lambda: self.assert_(not(self.__offscreenCanvas.autorender)), + changeContent, + lambda: self.compareImage("testOffscreenAutoRender1"), + enableAutoRender, + lambda: self.assert_(self.__offscreenCanvas.autorender), + lambda: self.compareImage("testOffscreenAutoRender2") + )) + + def testCanvasCrop(self): + root = self.loadEmptyScene() + canvas = player.createCanvas(id="testcanvas", size=(160,120), + mediadir="media") + div = avg.DivNode(pos=(40,30), size=(80,60), crop=True, + parent=canvas.getRootNode()) + avg.ImageNode(id="test1", pos=(-32, -32), href="rgb24-65x65.png", parent=div) + avg.ImageNode(parent=root, href="canvas:testcanvas") + self.start(False, (lambda: self.compareImage("testCanvasCrop"),)) + + def testCanvasAlpha(self): + root = self.loadEmptyScene() + canvas = player.createCanvas(id="testcanvas", size=(80,120), mediadir="media") + avg.ImageNode(id="test1", href="rgb24alpha-64x64.png", + parent=canvas.getRootNode()) + avg.RectNode(parent=root, fillcolor="FFFFFF", + pos=(0.5, 0.5), size=(160, 48), fillopacity=1) + avg.ImageNode(parent=root, href="canvas:testcanvas") + avg.ImageNode(parent=root, x=64, href="rgb24alpha-64x64.png") + self.start(False, (lambda: self.compareImage("testCanvasAlpha"),)) + + def testCanvasBlendModes(self): + def createBaseCanvas(): + canvas = player.createCanvas(id="testcanvas", size=(64,64), + mediadir="media") + avg.ImageNode(href="rgb24alpha-64x64.png", parent=canvas.getRootNode()) + return canvas + + root = self.loadEmptyScene() + createBaseCanvas() + avg.RectNode(parent=root, pos=(48,0), size=(32, 120), strokewidth=2, + fillopacity=1, fillcolor="808080") + avg.ImageNode(parent=root, href="canvas:testcanvas") + avg.ImageNode(parent=root, pos=(0,64), href="canvas:testcanvas", + opacity=0.6) + avg.ImageNode(parent=root, pos=(64,0), href="canvas:testcanvas", + blendmode="add") + avg.ImageNode(parent=root, pos=(64,64), href="canvas:testcanvas", + opacity=0.6, blendmode="add") + self.start(False, (lambda: self.compareImage("testCanvasBlendModes"),)) + + def testCanvasMultisampling(self): + def testIllegalSamples(numSamples): + self.canvas = player.createCanvas(id="brokencanvas", size=(160,120), + multisamplesamples=numSamples) + + def screenshot(): + bmp = self.canvas.screenshot() + self.compareBitmapToFile(bmp, "testOffscreenMultisampleScreenshot") + + def createCanvas(): + if not(avg.OffscreenCanvas.isMultisampleSupported()): + self.skip("Offscreen multisampling not supported") + player.stop() + return + try: + self.canvas = player.createCanvas(id="testcanvas", size=(160,120), + mediadir="media", multisamplesamples=2) + avg.ImageNode(id="test1", href="rgb24-65x65.png", angle=0.1, + parent=self.canvas.getRootNode()) + except RuntimeError: + self.skip("Offscreen multisampling init failed") + player.stop() + return + self.assertEqual(self.canvas.multisamplesamples, 2) + avg.ImageNode(parent=root, href="canvas:testcanvas") + + + root = self.loadEmptyScene() + self.start(False, + (createCanvas, + lambda: self.compareImage("testCanvasMultisample"), + screenshot, + lambda: self.assertException(lambda: testIllegalSamples(42)), + lambda: self.assertException(lambda: testIllegalSamples(0)), + )) + self.canvas = None + + def testCanvasMipmap(self): + root = self.loadEmptyScene() + + canvas = player.createCanvas(id="testcanvas", size=(80,120), mediadir="media", + mipmap=True) + avg.ImageNode(id="test1", href="rgb24alpha-64x64.png", + parent=canvas.getRootNode()) + avg.ImageNode(parent=root, size=(40, 30), href="canvas:testcanvas") + try: + self.start(False, (lambda: self.compareImage("testCanvasMipmap"),)) + except RuntimeError: + self.skip("Offscreen mipmap init failed.") + return + + def testCanvasDependencies(self): + def makeCircularRef(): + self.offscreen1.getElementByID("test1").href = "canvas:offscreencanvas2" + + def makeSelfRef1(): + avg.ImageNode(href="canvas:offscreencanvas1", + parent=self.offscreen1.getRootNode()) + + def makeSelfRef2(): + self.offscreen1.getElementByID("test1").href = "canvas:offscreencanvas1" + + def createTwoCanvases(): + self.offscreen1 = self.__createOffscreenCanvas("offscreencanvas1", False) + self.offscreen2 = self.__createOffscreenCanvas("offscreencanvas2", False) + self.node = avg.ImageNode(parent=root, + href="canvas:offscreencanvas1") + node = self.offscreen1.getElementByID("test1") + node.href = "canvas:offscreencanvas2" + node.size = (80, 60) + + def exchangeCanvases(): + self.offscreen1.getElementByID("test1").href = "rgb24-65x65.png" + self.offscreen2.getElementByID("test1").href = "canvas:offscreencanvas1" + self.node.href = "canvas:offscreencanvas2" + + def loadCanvasDepString(): + player.createCanvas(id="canvas1", size=(160, 120)) + canvas2 = player.createCanvas(id="canvas2", size=(160, 120)) + avg.ImageNode(href="canvas:canvas1", parent=canvas2.getRootNode()) + player.deleteCanvas('canvas2') + player.deleteCanvas('canvas1') + + root = self.loadEmptyScene() + createTwoCanvases() + self.offscreen1.getElementByID("test1").href = "" + self.offscreen1 = None + self.offscreen2 = None + self.node.href = "" + self.node = None + player.deleteCanvas("offscreencanvas1") + player.deleteCanvas("offscreencanvas2") + self.start(False, + (createTwoCanvases, + lambda: self.compareImage("testCanvasDependencies1"), + exchangeCanvases, + lambda: self.compareImage("testCanvasDependencies2"), + lambda: self.assertException(makeCircularRef), + lambda: self.assertException(makeSelfRef1), + lambda: self.assertException(makeSelfRef2), + loadCanvasDepString, + )) + + def __setupCanvas(self, handleEvents): + root = self.loadEmptyScene() + mainCanvas = player.getMainCanvas() + offscreenCanvas = self.__createOffscreenCanvas("offscreencanvas", handleEvents) + self.node = avg.ImageNode(parent=root, href="canvas:offscreencanvas") + return (mainCanvas, offscreenCanvas) + + def __createOffscreenCanvas(self, canvasName, handleEvents): + canvas = player.createCanvas(id=canvasName, size=(160,120), + handleevents=handleEvents) + canvas.getRootNode().mediadir = "media" + avg.ImageNode(id="test1", href="rgb24-65x65.png", parent=canvas.getRootNode()) + return canvas + +def isOffscreenSupported(): + + def testOffscreenSupported(): + global offscreenSupported + offscreenSupported = avg.OffscreenCanvas.isSupported() + player.stop() + + global offscreenSupported + sceneString = """<avg id="avg" width="160" height="120"/>""" + player.loadString(sceneString) + player.setTimeout(0, testOffscreenSupported) + player.play() + return offscreenSupported + +def offscreenTestSuite(tests): + if isOffscreenSupported(): + availableTests = ( + "testCanvasBasics", + "testCanvasLoadAfterPlay", + "testCanvasResize", + "testCanvasErrors", + "testCanvasAPI", + "testCanvasEvents", + "testCanvasEventCapture", + "testCanvasRender", + "testCanvasAutoRender", + "testCanvasCrop", + "testCanvasAlpha", + "testCanvasBlendModes", + "testCanvasMultisampling", + "testCanvasMipmap", + "testCanvasDependencies", + ) + return createAVGTestSuite(availableTests, OffscreenTestCase, tests) + else: + sys.stderr.write("Skipping offscreen tests - no canvas support with this graphics configuration.\n") + return unittest.TestSuite() diff --git a/src/test/PlayerTest.py b/src/test/PlayerTest.py new file mode 100644 index 0000000..2443759 --- /dev/null +++ b/src/test/PlayerTest.py @@ -0,0 +1,853 @@ +# -*- 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 +# + +import math +import threading + +from libavg import avg, player +from testcase import * + +class PlayerTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testPoint(self): + def testHash(): + ptMap = {} + ptMap[avg.Point2D(0,0)] = 0 + ptMap[avg.Point2D(1,0)] = 1 + ptMap[avg.Point2D(0,0)] = 2 + self.assertEqual(len(ptMap), 2) + self.assertEqual(ptMap[avg.Point2D(0,0)], 2) + + def testToTupleConversion(): + pt = avg.Point2D(10, 20) + tpl = tuple(pt) + self.assertEqual(pt.x, tpl[0]) + self.assertEqual(pt.y, tpl[1]) + + def testFromTupleConversion(): + tpl = (15, 20) + pt = avg.Point2D(tpl) + self.assertEqual(pt.x, tpl[0]) + self.assertEqual(pt.y, tpl[1]) + + pt = avg.Point2D() + self.assertEqual(pt, avg.Point2D(0,0)) + pt = avg.Point2D(10, 20) + self.assertEqual(pt[0], pt.x) + self.assertEqual(pt[1], pt.y) + pt = avg.Point2D(10, 10) + self.assertEqual(pt, avg.Point2D(10, 10)) + self.assertEqual(pt, (10, 10)) + self.assertEqual(pt, avg.Point2D([10, 10])) + self.assertNotEqual(pt, avg.Point2D(11, 10)) + self.assertEqual(str(pt), "(10,10)") + pt2 = eval(repr(pt)) + self.assertEqual(pt2, pt) + testHash() + testFromTupleConversion() + testToTupleConversion() + self.assertAlmostEqual(avg.Point2D(10,0).getNormalized(), avg.Point2D(1,0)) + self.assertAlmostEqual(pt.getRotated(math.pi, (5,5)), avg.Point2D(0,0)) + self.assertEqual(-pt, (-10, -10)) + self.assertEqual(pt-(10,0), (0,10)) + self.assertEqual(pt+(10,0), (20,10)) + self.assertEqual(pt*2, (20,20)) + self.assertEqual(2*pt, (20,20)) + pt.x = 21 + pt.y = 23 + self.assertEqual(pt, avg.Point2D(21, 23)) + pt.x -= 11 + pt.y -= 13 + pt += avg.Point2D(10, 10) + self.assertEqual(pt, avg.Point2D(20, 20)) + pt -= avg.Point2D(6, 6) + self.assertEqual(pt, avg.Point2D(14, 14)) + self.assertNotEqual(pt, avg.Point2D(13, 13)) + pt = pt/2. + self.assertEqual(pt, avg.Point2D(7, 7)) + pt = avg.Point2D((10, 10)) + self.assertEqual(pt, (10, 10)) + self.assertEqual(len(pt), 2) + self.assertEqual(pt[0], pt.x) + self.assertEqual(pt[1], pt.y) + self.assertException(lambda: pt[2]) + self.assertAlmostEqual(avg.Point2D(10,0), avg.Point2D.fromPolar(0,10)) + self.assertException(avg.Point2D(0,0).getNormalized) + self.assertException(lambda: avg.Point2D(0,)) + self.assertException(lambda: avg.Point2D(0,1,2)) + for point in ((10,0), (0,10), (-10,0), (0,-10)): + pt = avg.Point2D(point) + angle = pt.getAngle() + norm = pt.getNorm() + self.assertAlmostEqual(pt, avg.Point2D.fromPolar(angle,norm)) + + def testBasics(self): + def getFramerate(): + framerate = player.getEffectiveFramerate() + self.assert_(framerate > 0) + + def invalidCreateNode(): + avg.ImageNode(1, 2, 3) + + player.showCursor(0) + player.showCursor(1) + root = self.loadEmptyScene() + avg.ImageNode(href="rgb24-65x65.png", parent=root) + self.assertException(invalidCreateNode) + self.start(False, + (getFramerate, + lambda: self.compareImage("testbasics"), + lambda: player.setGamma(0.3, 0.3, 0.3), + lambda: player.showCursor(0), + lambda: player.showCursor(1), + )) + + def testColorParse(self): + def setColor(colorName): + node.color = colorName + + node = avg.LineNode(pos1=(0.5, 0), pos2=(0.5, 50), color="FF0000") + setColor("ff00ff") + self.assertException(lambda: setColor("foo")) + self.assertException(lambda: setColor("ff00f")) + self.assertException(lambda: setColor("ff00ffx")) + self.assertException(lambda: setColor("ff00fx")) + + def testFakeTime(self): + def checkTime(): + self.assertEqual(player.getFrameTime(), 50) + self.assertEqual(player.getFrameDuration(), 50) + self.assertEqual(player.getEffectiveFramerate(), 20) + + self.loadEmptyScene() + player.setFakeFPS(20) + self.start(False, + (checkTime, + )) + + def testDivResize(self): + def checkSize (w, h): + self.assertEqual(node.width, w) + self.assertEqual(node.height, h) + self.assertEqual(node.size, (w,h)) + + def setSize (size): + node.size = size + + def setWidth (w): + node.width = w + + def setHeight (h): + node.height = h + + self.__initDefaultScene() + node = player.getElementByID('nestedavg') + + self.start(False, + (lambda: checkSize(128, 32), + lambda: setSize((14,15)), + lambda: checkSize(14,15), + lambda: setWidth(23), + lambda: checkSize(23,15), + lambda: setHeight(22), + lambda: checkSize(23,22), + )) + + def testRotate(self): + def onOuterDown(Event): + self.onOuterDownCalled = True + + def fakeRotate(): + player.getElementByID("outer").angle += 0.1 + player.getElementByID("inner").angle -= 0.1 + + def testCoordConversions(): + innerNode = player.getElementByID("inner") + relPos = innerNode.getRelPos((90, 80)) + self.assertAlmostEqual(relPos, (10, 10)) + outerNode = player.getElementByID("outer") + relPos = outerNode.getRelPos((90, 80)) + self.assertAlmostEqual(relPos[0], 12.332806394528092) + self.assertAlmostEqual(relPos[1], 6.9211188716194592) + absPos = outerNode.getAbsPos(relPos) + self.assertAlmostEqual(absPos, (90, 80)) + self.assertEqual(outerNode.getElementByPos((10, 10)), innerNode) + self.assertEqual(outerNode.getElementByPos((0, 10)), outerNode) + self.assertEqual(outerNode.getElementByPos((-10, -110)), None) + + def disableCrop(): + player.getElementByID("outer").crop = False + player.getElementByID("inner").crop = False + + self.__initDefaultRotateScene() + player.getElementByID("outer").subscribe(avg.Node.CURSOR_DOWN, onOuterDown) + self.onOuterDownCalled = False + self.start(False, + (lambda: self.compareImage("testRotate1"), + testCoordConversions, + fakeRotate, + lambda: self.compareImage("testRotate1a"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 85, 70), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 85, 70), + lambda: self.assert_(not(self.onOuterDownCalled)), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 85, 75), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 85, 75), + lambda: self.assert_(self.onOuterDownCalled), + disableCrop, + lambda: self.compareImage("testRotate1b"), + )) + + def testRotate2(self): + root = self.loadEmptyScene() + + div1 = avg.DivNode(pos=(80,0), size=(160,120), pivot=(0,0), angle=1.57, + parent=root) + avg.ImageNode(size=(16,16), href="rgb24-65x65.png", parent=div1) + div2 = avg.DivNode(pos=(40,0), size=(110,80), pivot=(0,0), angle=1.57, + crop=True, parent=div1) + avg.ImageNode(pos=(0,0), size=(16,16), href="rgb24-65x65.png", parent=div2) + avg.ImageNode(pos=(30,-6), size=(16,16), href="rgb24-65x65.png", parent=div2) + self.start(False, [lambda: self.compareImage("testRotate2")]) + + def testRotatePivot(self): + def setPivot (pos): + node.pivot = pos + + def addPivot (offset): + node.pivot += offset + + root = self.loadEmptyScene() + node = avg.DivNode(pos=(80,0), size=(160,120), pivot=(0,0), angle=1.57, + crop=True, parent=root) + div = avg.DivNode(pos=(40,-20), size=(160,120), pivot=(0,0), angle=0.79, + crop=True, parent=node) + avg.ImageNode(pos=(-10,-10), size=(128,128), href="rgb24-65x65.png", parent=div) + avg.ImageNode(pos=(0,10), size=(32,32), href="rgb24-65x65.png", parent=node) + self.start(False, + (lambda: self.compareImage("testRotatePivot1"), + lambda: setPivot((10, 10)), + lambda: self.compareImage("testRotatePivot2"), + lambda: addPivot((-8, 0)), + lambda: self.compareImage("testRotatePivot3"), + )) + + def testOpacity(self): + root = self.loadEmptyScene() + avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", opacity=0.5, parent=root) + avg.RectNode(pos=(0,64), size=(64,64), opacity=0.5, fillopacity=0.5, + fillcolor="FF0000", strokewidth=2, parent=root) + div = avg.DivNode(pos=(80,0), opacity=0.5, parent=root) + avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=div) + avg.RectNode(pos=(0,64), size=(64,64), opacity=1, fillopacity=1, + fillcolor="FF0000", strokewidth=2, parent=div) + self.start(False, + (lambda: self.compareImage("testOpacity"), + )) + + def testOutlines(self): + root = self.__initDefaultRotateScene() + root.elementoutlinecolor = "FFFFFF" + innerDiv = player.getElementByID("inner") + innerDiv.size = (0, 0) + innerDiv.getChild(0).elementoutlinecolor = "00FF00" + self.start(False, [lambda: self.compareImage("testOutlines")]) + + def testWordsOutlines(self): + root = self.loadEmptyScene() + root.elementoutlinecolor = "FFFFFF" + avg.WordsNode(pos=(40,40), alignment="center", text="test", parent=root) + self.start(True, [lambda: self.compareImage("testWordsOutlines")]) + + def testError(self): + self.initDefaultImageScene() + player.setTimeout(1, lambda: undefinedFunction) + player.setTimeout(50, player.stop) + try: + player.play() + except NameError: + self.assert_(1) + else: + self.assert_(0) + + def testExceptionInTimeout(self): + def throwException(): + raise ZeroDivisionError + + try: + self.initDefaultImageScene() + self.start(False, [throwException]) + except ZeroDivisionError: + self.assert_(1) + else: + self.assert_(0) + + def testInvalidImageFilename(self): + def activateNode(): + div.active = 1 + + root = self.loadEmptyScene() + div = avg.DivNode(active=False, parent=root) + avg.ImageNode(href="filedoesntexist.png", parent=div) + self.start(False, [activateNode]) + + def testInvalidVideoFilename(self): + def tryplay(): + assertException(lambda: video.play()) + + root = self.loadEmptyScene() + video = avg.VideoNode(href="filedoesntexist.avi", parent=root) + self.start(False, + (lambda: tryplay, + lambda: video.stop() + )) + + def testTimeouts(self): + class TestException(Exception): + pass + + def timeout1(): + player.clearInterval(self.timeout1ID) + player.clearInterval(self.timeout2ID) + self.timeout1called = True + + def timeout2(): + self.timeout2called = True + + def onFrame(): + self.numOnFramesCalled += 1 + if self.numOnFramesCalled == 3: + player.clearInterval(self.intervalID) + + def wait(): + pass + + def throwException(): + raise TestException + + def initException(): + self.timeout3ID = player.setTimeout(0, throwException) + + def setupTimeouts(): + self.timeout1ID = player.setTimeout(0, timeout1) + self.timeout2ID = player.setTimeout(1, timeout2) + self.intervalID = player.setOnFrameHandler(onFrame) + + self.timeout1called = False + self.timeout2called = False + self.__exceptionThrown = False + self.numOnFramesCalled = 0 + try: + self.initDefaultImageScene() + self.start(False, + (setupTimeouts, + None, + lambda: self.assert_(self.timeout1called), + lambda: self.assert_(not(self.timeout2called)), + lambda: self.assert_(self.numOnFramesCalled == 3), + lambda: initException(), + lambda: self.delay(10), + )) + except TestException: + self.__exceptionThrown = True + + self.assert_(self.__exceptionThrown) + player.clearInterval(self.timeout3ID) + + def testCallFromThread(self): + + def onAsyncCall(): + self.asyncCalled = True + + def threadFunc(): + player.setTimeout(0, onAsyncCall) + + def startThread(): + self.thread = threading.Thread(target=threadFunc) + self.thread.start() + + self.initDefaultImageScene() + self.asyncCalled = False + player.setFakeFPS(-1) + self.start(False, + (startThread, + lambda: self.thread.join(), + None, + lambda: self.assert_(self.asyncCalled), + )) + + def testAVGFile(self): + player.loadFile("image.avg") + self.start(False, + (lambda: self.compareImage("testAVGFile"), + )) + self.assertException(lambda: player.loadFile("filedoesntexist.avg")) + + def testBroken(self): + def testBrokenString(string): + self.assertException(lambda: player.loadString(string)) + + # This isn't xml + testBrokenString(""" + xxx<avg width="400" height="300"> + </avg> + """) + # This isn't avg + testBrokenString(""" + <bla>hallo + </bla>""") + testBrokenString(""" + <avg width="640" height="480" invalidattribute="bla"> + </avg> + """) + + def testMove(self): + def moveit(): + node = player.getElementByID("nestedimg1") + node.x += 50 + node.opacity -= 0.7 + node = player.getElementByID("nestedavg") + node.x += 50 + + def checkRelPos(): + RelPos = player.getElementByID("obscured").getRelPos((50,52)) + self.assertEqual(RelPos, (0, 0)) + + self.__initDefaultScene() + self.start(False, + (lambda: self.compareImage("testMove1"), + moveit, + checkRelPos + )) + + def testCropImage(self): + def moveTLCrop(): + node = player.getElementByID("img") + node.x = -20 + node.y = -20 + + def moveBRCrop(): + node = player.getElementByID("img") + node.x = 60 + node.y = 40 + + def moveTLNegative(): + node = player.getElementByID("img") + node.x = -60 + node.y = -50 + + def moveBRGone(): + node = player.getElementByID("img") + node.x = 140 + node.y = 100 + + def rotate(): + node = player.getElementByID("img") + node.x = 10 + node.y = 10 + player.getElementByID("nestedavg").angle = 1.0 + player.getElementByID("bkgd").angle = 1.0 + + root = self.loadEmptyScene() + avg.ImageNode(id="bkgd", href="crop_bkgd.png", parent=root) + root.appendChild( + player.createNode(""" + <div id="nestedavg" x="40" y="30" width="80" height="60" crop="True"> + <div id="nestedavg2" crop="True"> + <div id="nestedavg3" crop="True"> + <image id="img" x="10" y="10" width="40" height="40" + href="rgb24-64x64.png"/> + </div> + </div> + </div> + """)) + self.start(False, + (lambda: self.compareImage("testCropImage1"), + moveTLCrop, + lambda: self.compareImage("testCropImage2"), + moveBRCrop, + lambda: self.compareImage("testCropImage3"), + moveTLNegative, + lambda: self.compareImage("testCropImage4"), + moveBRGone, + lambda: self.compareImage("testCropImage5"), + + rotate, + lambda: self.compareImage("testCropImage6"), + moveTLCrop, + lambda: self.compareImage("testCropImage7"), + moveBRCrop, + lambda: self.compareImage("testCropImage8"), + moveTLNegative, + lambda: self.compareImage("testCropImage9"), + moveBRGone, + lambda: self.compareImage("testCropImage10") + )) + + def testCropMovie(self): + def playMovie(): + node = player.getElementByID("movie") + node.play() + + def moveTLCrop(): + node = player.getElementByID("movie") + node.x = -20 + node.y = -20 + + def moveBRCrop(): + node = player.getElementByID("movie") + node.x = 60 + node.y = 40 + + def moveTLNegative(): + node = player.getElementByID("movie") + node.x = -60 + node.y = -50 + + def moveBRGone(): + node = player.getElementByID("movie") + node.x = 140 + node.y = 100 + + def rotate(): + node = player.getElementByID("movie") + node.x = 10 + node.y = 10 + player.getElementByID("nestedavg").angle = 1.0 + player.getElementByID("bkgd").angle = 1.0 + + player.setFakeFPS(30) + root = self.loadEmptyScene() + avg.ImageNode(id="bkgd", href="crop_bkgd.png", parent=root) + root.appendChild( + player.createNode(""" + <div id="nestedavg" x="40" y="30" width="80" height="60" crop="True"> + <video id="movie" x="10" y="10" width="40" height="40" + threaded="false" href="mpeg1-48x48.mov" + fps="30"/> + </div> + """)) + self.start(False, + (playMovie, + lambda: self.compareImage("testCropMovie1"), + moveTLCrop, + lambda: self.compareImage("testCropMovie2"), + moveBRCrop, + lambda: self.compareImage("testCropMovie3"), + moveTLNegative, + lambda: self.compareImage("testCropMovie4"), + moveBRGone, + lambda: self.compareImage("testCropMovie5"), + + rotate, + lambda: self.compareImage("testCropMovie6"), + moveTLCrop, + lambda: self.compareImage("testCropMovie7"), + moveBRCrop, + lambda: self.compareImage("testCropMovie8"), + moveTLNegative, + lambda: self.compareImage("testCropMovie9"), + moveBRGone, + lambda: self.compareImage("testCropMovie10") + )) + + def testWarp(self): + def moveVertex(): + grid = image.getWarpedVertexCoords() + grid[1][1] = (grid[1][1][0]+0.06, grid[1][1][1]+0.06) + image.setWarpedVertexCoords(grid) + grid = video.getWarpedVertexCoords() + grid[0][0] = (grid[0][0][0]+0.06, grid[0][0][1]+0.06) + grid[1][1] = (grid[1][1][0]-0.06, grid[1][1][1]-0.06) + video.setWarpedVertexCoords(grid) + + def flip(): + grid = image.getOrigVertexCoords() + grid = [ [ (1-pos[0], pos[1]) for pos in line ] for line in grid] + image.setWarpedVertexCoords(grid) + + root = self.loadEmptyScene() + image = avg.ImageNode(href="rgb24-64x64.png", + maxtilewidth=32, maxtileheight=16, parent=root) + video = avg.VideoNode(pos=(40,0), size=(80,80), opacity=0.5, loop=True, + href="mpeg1-48x48.mov", threaded=False, fps=30, parent=root) + + self.assertException(image.getOrigVertexCoords) + self.assertException(image.getWarpedVertexCoords) + player.setFakeFPS(30) + self.start(False, + (lambda: video.play(), + lambda: self.compareImage("testWarp1"), + moveVertex, + lambda: self.compareImage("testWarp2"), + flip, + lambda: self.compareImage("testWarp3") + )) + + def testMediaDir(self): + def createImageNode(): + # Node is not in tree; mediadir should be root node dir. + node = avg.ImageNode(href="rgb24-64x64a.png") + self.assertEqual(node.size, avg.Point2D(0,0)) # File not found + node.href = "rgb24-64x64.png" + self.assertEqual(node.size, avg.Point2D(64,64)) # File found + node = avg.ImageNode(href="rgb24-64x64a.png", width=23, height=42) + # File not found, but custom size + self.assertEqual(node.size, avg.Point2D(23,42)) + node.href = "rgb24-64x64.png" + # File found, custom size stays + self.assertEqual(node.size, avg.Point2D(23,42)) + node.size = (0,0) + # File found, custom size cleared. Media size should be used. + self.assertEqual(node.size, avg.Point2D(64,64)) + + def setDir(): + div.mediadir="" + + def setAbsDir(): + def absDir(): + # Should not find any media here... + div.mediadir="/testmediadir" + + self.assertException(absDir) + + def createNode(): + avg.VideoNode(href="mjpeg1-48x48.avi", fps=30) + + root = self.loadEmptyScene() + div = avg.DivNode(mediadir="../testmediadir", parent=root) + image = avg.ImageNode(pos=(0,30), href="rgb24-64x64a.png", parent=div) + video = avg.VideoNode(href="mjpeg-48x48.avi", threaded=False, parent=div) + self.start(False, + (createImageNode, + lambda: video.play(), + lambda: self.compareImage("testMediaDir1"), + setDir, + lambda: video.play(), + lambda: self.compareImage("testMediaDir2"), + lambda: self.assertEqual(image.width, 0), + createNode, + setAbsDir + )) + + def testMemoryQuery(self): + self.assertNotEqual(avg.getMemoryUsage(), 0) + + def testStopOnEscape(self): + def pressEscape(): + Helper = player.getTestHelper() + escape = 27 + Helper.fakeKeyEvent(avg.Event.KEY_DOWN, escape, escape, "escape", escape, + avg.KEYMOD_NONE), + Helper.fakeKeyEvent(avg.Event.KEY_UP, escape, escape, "escape", escape, + avg.KEYMOD_NONE), + + def testEscape1(): + player.stopOnEscape(False) + pressEscape() + + def testEscape2(): + player.stopOnEscape(True) + player.stopOnEscape(False) + pressEscape() + + def testEscape3(): + player.stopOnEscape(True) + pressEscape() + + def setAlive(): + self.testStopOnEscapeAlive = True + + self.testStopOnEscapeAlive = False + self.__initDefaultScene() + self.start(False, + (testEscape1, + testEscape2, + setAlive + )) + self.assert_(self.testStopOnEscapeAlive) + self.__initDefaultScene() + self.start(False, + (testEscape3, # this should exit the player + lambda: self.fail(), + )) + + def testScreenDimensions(self): + def queryDimensions(): + res = player.getScreenResolution() + self.assert_(res.x > 0 and res.y > 0 and res.x < 10000 and res.y < 10000) + ppmm = player.getPixelsPerMM() + self.assert_(ppmm > 0 and ppmm < 10000) + mm = player.getPhysicalScreenDimensions() + self.assert_(mm.x > 0 and mm.y > 0 and mm.x < 10000 and mm.y < 10000) + player.assumePixelsPerMM(ppmm) + newPPMM = player.getPixelsPerMM() + self.assertAlmostEqual(newPPMM, ppmm) + newMM = player.getPhysicalScreenDimensions() + self.assertEqual(newMM, mm) + + queryDimensions() + self.__initDefaultScene() + self.start(False, + (queryDimensions, + )) + + def testSVG(self): + svgFile = avg.SVG("media/rect.svg", False) + + # renderElement + bmp = svgFile.renderElement("rect") + self.compareBitmapToFile(bmp, "testSvgBmp") + self.assertEqual(svgFile.getElementSize("rect"), avg.Point2D(22,12)) + bmp = svgFile.renderElement("pos_rect") + self.compareBitmapToFile(bmp, "testSvgPosBmp") + bmp = svgFile.renderElement("rect", 5) + self.compareBitmapToFile(bmp, "testSvgScaleBmp1") + bmp = svgFile.renderElement("rect", (20,20)) + self.compareBitmapToFile(bmp, "testSvgScaleBmp2") + + # error handling + self.assertException(lambda: avg.SVG("filedoesntexist.svg", False)) + self.assertException(lambda: svgFile.renderElement("missing_id")) + + # unescapeIllustratorIDs + svgIllustratorFile = avg.SVG("illustratorRect.svg", True) + svgIllustratorFile.getElementSize("pos_rect") + + # createImageNode + root = self.loadEmptyScene() + self.start(False, + (lambda: svgFile.createImageNode("rect", {"pos":(10,10), "parent":root}), + lambda: self.compareImage("testSvgNode"), + lambda: svgFile.createImageNode("rect", {"pos":(5,5), "parent":root}, + 5), + lambda: self.compareImage("testSvgScaledNode1"), + lambda: svgFile.createImageNode("rect", {"pos":(1,1), "parent":root}, + (40,40)), + lambda: self.compareImage("testSvgScaledNode2") + )) + + def testGetConfigOption(self): + self.assert_(len(player.getConfigOption("scr", "bpp")) > 0) + self.assertException(lambda: player.getConfigOption("scr", "illegalOption")) + self.assertException(lambda: + player.getConfigOption("illegalGroup", "illegalOption")) + + def testValidateXml(self): + schema = """<?xml version="1.0" encoding="UTF-8"?> + <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:element name="shiporder"> + <xs:complexType> + <xs:sequence> + <xs:element name="orderperson" type="xs:string"/> + </xs:sequence> + <xs:attribute name="orderid" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> + + </xs:schema> + """ + xmlString = """<?xml version="1.0" encoding="UTF-8"?> + + <shiporder orderid="889923"> + <orderperson>John Smith</orderperson> + </shiporder> + """ + avg.validateXml(xmlString, schema, "shiporder.xml", "shiporder.xsd") + + brokenSchema = "ff"+schema + self.assertException(lambda: avg.validateXml(xmlString, brokenSchema, + "shiporder.xml", "shiporder.xsd")) + + brokenXml = xmlString+"ff" + self.assertException(lambda: avg.validateXml(brokenXml, schema, + "shiporder.xml", "shiporder.xsd")) + + # Not executed due to bug #145 - hangs with some window managers. + def testWindowFrame(self): + def revertWindowFrame(): + player.setWindowFrame(True) + + player.setWindowFrame(False) + self.__initDefaultScene() + self.start(False, [revertWindowFrame]) + + def __initDefaultScene(self): + root = self.loadEmptyScene() + avg.ImageNode(id="mainimg", size=(100, 75), href="rgb24-65x65.png", parent=root) + div = avg.DivNode(id="nestedavg", pos=(0,32), opacity=1, size=(128, 32), + crop=True, parent=root) + avg.ImageNode(id="obscured", pos=(0,20), size=(96,40), href="rgb24-65x65.png", + parent=div) + avg.ImageNode(id="nestedimg1", size=(96,48), href="rgb24-65x65.png", + parent=div) + avg.ImageNode(id="nestedimg2", pos=(65,0), href="rgb24alpha-64x64.png", + parent=div) + + def __initDefaultRotateScene(self): + root = self.loadEmptyScene() + div = avg.DivNode(pos=(80,10), size=(80,60), pivot=(0,0), angle=0.274, + crop=True, parent=root) + avg.ImageNode(pos=(10,10), size=(32,32), href="rgb24-65x65.png", parent=div) + outerDiv = avg.DivNode(id="outer", pos=(80,70), size=(80,60), + pivot=(0,0), angle=0.274, crop=True, parent=root) + innerDiv = avg.DivNode(id="inner", size=(80,60), pivot=(0,0), angle=-0.274, + crop=True, parent=outerDiv) + avg.ImageNode(pos=(10,10), size=(32,32), href="rgb24-65x65.png", parent=innerDiv) + return root + +def playerTestSuite(tests): + availableTests = ( + "testPoint", + "testBasics", + "testColorParse", + "testFakeTime", + "testDivResize", + "testRotate", + "testRotate2", + "testRotatePivot", + "testOpacity", + "testOutlines", + "testWordsOutlines", + "testError", + "testExceptionInTimeout", + "testInvalidImageFilename", + "testInvalidVideoFilename", + "testTimeouts", + "testCallFromThread", + "testAVGFile", + "testBroken", + "testMove", + "testCropImage", + "testCropMovie", + "testWarp", + "testMediaDir", + "testMemoryQuery", + "testStopOnEscape", + "testScreenDimensions", + "testSVG", + "testGetConfigOption", + "testValidateXml", +# "testWindowFrame", + ) + return createAVGTestSuite(availableTests, PlayerTestCase, tests) diff --git a/src/test/PluginTest.py b/src/test/PluginTest.py new file mode 100644 index 0000000..186f7e4 --- /dev/null +++ b/src/test/PluginTest.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# -*- 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 +# + +import platform + +from libavg import player +from testcase import * + +class PluginTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testColorNodePlugin(self): + def loadPlugin(): + if platform.system() != 'Windows': + if not(os.getenv('srcdir') in ('.', None)): + # make distcheck + player.pluginPath += ":../../_build/src/test/plugin/.libs" + player.loadPlugin("colorplugin") + + def usePlugin1(): + node = colorplugin.ColorNode(fillcolor="7f7f00", id="mynode1") + root.appendChild(node) + + mynode = player.getElementByID("mynode1") + self.assertEqual(mynode.fillcolor, "7f7f00") + + def usePlugin2(): + node = player.createNode('<colornode fillcolor="0f3f7f" id="mynode2" />') + root.appendChild(node) + + mynode = player.getElementByID("mynode2") + self.assertEqual(mynode.fillcolor, "0f3f7f") + + root = self.loadEmptyScene() + self.start(False, + (loadPlugin, + usePlugin1, + lambda: self.compareImage("testplugin1"), + usePlugin2, + lambda: self.compareImage("testplugin2"), + )) + +def pluginTestSuite (tests): + availableTests = ("testColorNodePlugin",) + return createAVGTestSuite(availableTests, PluginTestCase, tests) diff --git a/src/test/PythonTest.py b/src/test/PythonTest.py new file mode 100644 index 0000000..21dd68b --- /dev/null +++ b/src/test/PythonTest.py @@ -0,0 +1,239 @@ +# -*- 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 +# + +import os +import time +import tempfile + +from libavg import geom, statemachine, persist + +from testcase import * + +def getTempFileName(): + return os.path.join(tempfile.gettempdir(), 'libavg.%d' % time.time()) + + +class PythonTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testRoundedRect(self): + def setPos(): + self.rect.pos = (20.5, 3.5) + + def setSize(): + self.rect.size = (40, 20) + + def setRadius(r): + self.rect.radius = r + + def setFill(): + self.rect.fillcolor = "0000FF" + self.rect.fillopacity = 0.5 + + def createDegenRect(): + self.rect.unlink(True) + rect = geom.RoundedRect(parent=root, pos=(10.5,10.5), size=(10,10), radius=6, + fillopacity=0.5, color="FFFFFF") + self.assert_(rect.radius == 6) + + root = self.loadEmptyScene() + self.rect = geom.RoundedRect(parent=root, pos=(2.5,2.5), + size=(64,64), radius=5, color="FF0000") + self.start(False, + (lambda: self.compareImage("testRoundedRect1"), + setPos, + lambda: self.compareImage("testRoundedRect2"), + setSize, + lambda: self.compareImage("testRoundedRect3"), + lambda: setRadius(10), + lambda: self.compareImage("testRoundedRect4"), + setFill, + lambda: self.compareImage("testRoundedRect5"), + createDegenRect, + lambda: self.compareImage("testRoundedRect6"), + )) + + def testPieSlice(self): + def changeAttrs(): + self.pieSlice.startangle = -1 + self.pieSlice.endangle = 3.14 + self.pieSlice.radius = 50 + self.pieSlice.pos = (80.5, 60.5) + self.pieSlice.fillcolor = "00FFFF" + self.pieSlice.fillopacity = 0.5 + + def makeSmall(): + self.pieSlice.radius = 0.6 + + root = self.loadEmptyScene() + self.pieSlice = geom.PieSlice(parent=root, pos=(20.5,20.5), + radius=40, startangle=0, endangle=1.57, color="FF0000") + + self.start(False, + (lambda: self.compareImage("testPieSlice1"), + changeAttrs, + lambda: self.compareImage("testPieSlice2"), + makeSmall, + lambda: self.compareImage("testPieSlice3"), + )) + + def testArc(self): + def changeAttrs(): + self.arc.startangle = -1 + self.arc.endangle = 3.14 + self.arc.radius = 50 + self.arc.pos = (80.5, 60.5) + + root = self.loadEmptyScene() + self.arc = geom.Arc(parent=root, pos=(20.5,20.5), + radius=40, startangle=0, endangle=1.57, color="FF0000") + + self.start(False, + (lambda: self.compareImage("testArc1"), + changeAttrs, + lambda: self.compareImage("testArc2"), + )) + + def btoa(self): + # Test for member function handling in StateMachine. + self.btoaCalled = True + + def testStateMachine(self): + def atob(oldState, newState): + self.atobCalled = True + + def btoc(dummy): + # Dummy argument so we can test handling of lambda expressions. + self.btocCalled = True + + def aEntered(): + self.aEnteredCalled = True + + def aLeft(): + self.aLeftCalled = True + + self.atobCalled = False + self.btocCalled = False + self.btoaCalled = False + self.aLeftCalled = False + self.aEnteredCalled = False + machine = statemachine.StateMachine("testmachine", 'A') + machine.addState('A', {'B': atob, 'nostate': atob}, aEntered, aLeft) + machine.addState('B', {'C': lambda: btoc("dummy"), 'A': self.btoa}) + machine.addState('C', {'A': None}) + self.assertException(lambda: machine.addState('C', {'A': None})) + self.assertException(lambda: machine.changeState('C')) + self.assertException(lambda: machine.changeState('nostate')) + machine.changeState('B') + self.assert_(self.atobCalled) + self.assert_(self.aLeftCalled) + machine.changeState('A') + self.assert_(self.aEnteredCalled) + self.assert_(self.btoaCalled) + machine.changeState('B') + machine.changeState('C') + self.assert_(self.btocCalled) + machine.changeState('A') + self.assertEqual(machine.state, 'A') +# machine.dump() + + self.assertException(lambda: machine.addState('illegal', {})) + + # Create a machine without transition callbacks + machine = statemachine.StateMachine("testmachine", 'A') + machine.addState('A', ('B',), aEntered, aLeft) + machine.addState('B', ('C', 'A')) + machine.addState('C', ('A',)) + machine.changeState('B') + + # Make a machine with a transition to a nonexistent state. + kaputtMachine = statemachine.StateMachine("kaputt", 'A') + kaputtMachine.addState('A', {'B': None}) + self.assertException(lambda: kaputtMachine.changeState('B')) + + def testStateMachineDiagram(self): + def aEntered(): + pass + + if not(self._isCurrentDirWriteable()): + self.skip("Current dir not writeable") + return + + machine = statemachine.StateMachine("testmachine", 'A') + machine.addState('A', {'B': None, 'nostate': None}, aEntered) + machine.addState('B', {'C': None, 'A': self.btoa}) + machine.addState('C', {'A': None}) + + imageFName = AVGTestCase.imageResultDirectory + "/stateMachineGraphViz.png" + try: + machine.makeDiagram(imageFName) + except RuntimeError: + self.skip("graphviz not installed.") + + def testPersistStore(self): + testFile = getTempFileName() + p = persist.Persist(testFile, {}) + self.assertEqual(p.storeFile, testFile) + self.assertEqual(p.data, {}) + p.data['test'] = 1 + p.commit() + p = persist.Persist(testFile, {}) + self.assert_('test' in p.data) + self.assertEqual(p.data['test'], 1) + os.unlink(testFile) + + def testPersistCorrupted(self): + logger.configureCategory("APP", logger.Severity.ERR); + testFile = getTempFileName() + f = open(testFile, 'w') + f.write('garbage') + f.close() + p = persist.Persist(testFile, {}) + self.assertEqual(p.data, {}) + os.unlink(testFile) + logger.configureCategory("APP", logger.Severity.WARN); + + def testPersistValidation(self): + logger.configureCategory("APP", logger.Severity.ERR); + testFile = getTempFileName() + p = persist.Persist(testFile, {'test': 1}) + p.commit() + p = persist.Persist(testFile, [], validator=lambda v: isinstance(v, list)) + self.assertEqual(p.data, []) + os.unlink(testFile) + logger.configureCategory("APP", logger.Severity.WARN); + + +def pythonTestSuite(tests): + availableTests = ( + "testRoundedRect", + "testPieSlice", + "testArc", + "testStateMachine", + "testStateMachineDiagram", + "testPersistStore", + "testPersistCorrupted", + "testPersistValidation", + ) + + return createAVGTestSuite(availableTests, PythonTestCase, tests) + diff --git a/src/test/Test.py b/src/test/Test.py new file mode 100755 index 0000000..4c4de8f --- /dev/null +++ b/src/test/Test.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python +# -*- 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 +# + +''' +Runner for libavg unit tests + +On autotools-based systems, tests are performed on a local libavg package. +This package is created by symlinking all the relevant files in a local, temporary +directory, letting python find it as first instance. +On windows, instead, tests are always carried on after distutils installs the package. +''' + +import sys +import os +import shutil +import atexit + +def cleanup(folder): + if os.path.isdir(folder): + sys.stderr.write('Wiping out directory: %s\n' % folder) + shutil.rmtree(folder) + +def symtree(src, dest): + os.mkdir(dest) + for f in os.listdir(src): + fpath = os.path.join(src, f) + if (f and f[0] != '.' and + (os.path.isdir(fpath) or + (os.path.isfile(fpath) and os.path.splitext(f)[1] in ('.py', '.glsl')))): + os.symlink(os.path.join(os.pardir, src, f), os.path.join(dest, f)) + + +if sys.platform != 'win32': + tempPackageDir = os.path.join(os.getcwd(), 'libavg') + # Possible values for srcdir: + # '.': make check + # None: ./Test.py + # dir name: make distcheck + srcDir = os.getenv("srcdir",".") + if srcDir == '.': + # Running make check or ./Test.py + if os.path.basename(os.getcwd()) != 'test': + raise RuntimeError('Manual tests must be performed inside directory "test"') + + cleanup(tempPackageDir) + + try: + symtree('../python', 'libavg') + os.symlink('../../graphics/shaders', 'libavg/shaders') + except OSError: + pass + else: + # Running make distcheck + symtree('../../../../src/python', 'libavg') + os.symlink('../../../../../src/graphics/shaders', 'libavg/shaders') + + # distcheck doesn't want leftovers (.pyc files) + atexit.register(lambda tempPackageDir=tempPackageDir: cleanup(tempPackageDir)) + + if os.path.exists('../wrapper/.libs/avg.so'): + # Normal case: use the local version (not the installed one) + shutil.copy2('../wrapper/.libs/avg.so', 'libavg/avg.so') + elif os.path.exists('../../avg.so'): + # Mac version after installer dmg + pass + else: + raise RuntimeError('Compile libavg before running tests or use "make check"') + + # The following line prevents the test to be run + # with an unknown version of libavg, which can be hiding somewhere + # in the system + sys.path.insert(0, os.getcwd()) + + # Meaningful only for distcheck + os.chdir(srcDir) + +import libavg +libavg.logger.configureCategory(libavg.Logger.Category.APP, libavg.Logger.Severity.INFO) +libavg.logger.info("Using libavg from: "+ os.path.dirname(libavg.__file__), + libavg.Logger.Category.APP) +# Ensure mouse is activated +libavg.player.enableMouse(True) + +import testapp + +libavg.Player.get().keepWindowOpen() + +import PluginTest +import PlayerTest +import OffscreenTest +import ImageTest +import FXTest +import VectorTest +import WordsTest +import AVTest +import DynamicsTest +import PythonTest +import AnimTest +import EventTest +import InputDeviceTest +import AVGAppTest +import WidgetTest +import GestureTest +import LoggerTest +import AppTest + +app = testapp.TestApp() + +app.registerSuiteFactory('plugin', PluginTest.pluginTestSuite) +app.registerSuiteFactory('player', PlayerTest.playerTestSuite) +app.registerSuiteFactory('offscreen', OffscreenTest.offscreenTestSuite) +app.registerSuiteFactory('image', ImageTest.imageTestSuite) +app.registerSuiteFactory('fx', FXTest.fxTestSuite) +app.registerSuiteFactory('vector', VectorTest.vectorTestSuite) +app.registerSuiteFactory('words', WordsTest.wordsTestSuite) +app.registerSuiteFactory('av', AVTest.AVTestSuite) +app.registerSuiteFactory('dynamics', DynamicsTest.dynamicsTestSuite) +app.registerSuiteFactory('python', PythonTest.pythonTestSuite) +app.registerSuiteFactory('anim', AnimTest.animTestSuite) +app.registerSuiteFactory('event', EventTest.eventTestSuite) +app.registerSuiteFactory('inputdevice', InputDeviceTest.inputDeviceTestSuite) +app.registerSuiteFactory('widget', WidgetTest.widgetTestSuite) +app.registerSuiteFactory('gesture', GestureTest.gestureTestSuite) +app.registerSuiteFactory('avgapp', AVGAppTest.avgAppTestSuite) +app.registerSuiteFactory('logger', LoggerTest.loggerTestSuite) +app.registerSuiteFactory('app', AppTest.appTestSuite) + +app.run() + +sys.exit(app.exitCode()) + diff --git a/src/test/VectorTest.py b/src/test/VectorTest.py new file mode 100644 index 0000000..af0ddaf --- /dev/null +++ b/src/test/VectorTest.py @@ -0,0 +1,734 @@ +# -*- 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 * + +class VectorTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def makeEmptyCanvas(self): + root = self.loadEmptyScene() + canvas = avg.DivNode(id="canvas", size=(160,120), parent=root) + return canvas + + def testLine(self): + def addLines(): + def addLine(attribs): + line = player.createNode("line", attribs) + canvas.appendChild(line) + + addLine({"pos1":(2, 2.5), "pos2":(100, 2.5)}) + addLine({"pos1":(2, 5), "pos2":(100, 5), "strokewidth":2}) + addLine({"pos1":(2.5, 20), "pos2":(2.5, 100)}) + addLine({"pos1":(5, 20), "pos2":(5, 100), "strokewidth":2}) + addLine({"pos1":(2, 7.5), "pos2":(100, 7.5), "color":"FF0000"}) + addLine({"pos1":(2, 9.5), "pos2":(100, 9.5), "color":"00FF00"}) + addLine({"pos1":(2, 11.5), "pos2":(100, 11.5), "color":"0000FF"}) + + def changeLine(): + line.color="FF0000" + line.strokewidth=3 + + def moveLine(): + line.pos1 += (0, 30) + line.pos2 += (0, 30) + + def blendMode(): + line = canvas.getChild(6) + line.pos1 = (line.pos1.x, 7.9) + line.pos2 = (line.pos2.x, 7.9) + line.strokewidth = 10 + line.blendmode="add" + + canvas = self.makeEmptyCanvas() + addLines() + line = canvas.getChild(0) + self.start(False, + (lambda: self.compareImage("testline1"), + changeLine, + lambda: self.compareImage("testline2"), + moveLine, + lambda: self.compareImage("testline3"), + blendMode, + lambda: self.compareImage("testline4") + )) + + def testLotsOfLines(self): + def addLines(): + for i in xrange(500): + y = i+2.5 + line = avg.LineNode(pos1=(2, y), pos2=(10, y)) + canvas.appendChild(line) + + canvas = self.makeEmptyCanvas() + self.start(False, + (addLines, + lambda: self.compareImage("testlotsoflines"), + )) + + def testTexturedLine(self): + def addLine(): + line = avg.LineNode(pos1=(2, 20), pos2=(100, 20), texhref="rgb24-64x64.png", + strokewidth=30) + canvas.appendChild(line) + + def removeLine(): + self.line = canvas.getChild(0) + self.line.unlink() + + def reAddLine(): + canvas.appendChild(self.line) + + def moveTexture(): + self.line.texcoord1 = -0.5 + self.line.texcoord2 = 1.5 + + def bmpTexture(): + bmp = avg.Bitmap("media/rgb24alpha-64x64.png") + self.line.setBitmap(bmp) + + def bmpNoTexture(): + self.line.setBitmap(None) + + canvas = self.makeEmptyCanvas() + addLine() + self.start(False, + (lambda: self.compareImage("testtexturedline1"), + removeLine, + lambda: self.compareImage("testtexturedline2"), + addLine, + lambda: self.compareImage("testtexturedline1"), + removeLine, + lambda: self.compareImage("testtexturedline2"), + reAddLine, + lambda: self.compareImage("testtexturedline1"), + moveTexture, + lambda: self.compareImage("testtexturedline3"), + bmpTexture, + lambda: self.compareImage("testtexturedline4"), + bmpNoTexture, + lambda: self.compareImage("testtexturedline5"), + )) + + def testLineOpacity(self): + def addLine(): + line = avg.LineNode(pos1=(2, 2.5), pos2=(158, 2.5), opacity=0.5) + canvas.appendChild(line) + + def changeCanvasOpacity(): + canvas.opacity = 0.5 + canvas.getChild(0).opacity = 0.25 + + canvas = self.makeEmptyCanvas() + self.start(False, + (addLine, + lambda: self.compareImage("testlineopacity1"), + changeCanvasOpacity, + lambda: self.compareImage("testlineopacity2"), + )) + + def testRect(self): + def addRect(): + rect = avg.RectNode(pos=(2, 2), size=(50, 30), fillopacity=1, + strokewidth=0) + canvas.appendChild(rect) + rect.subscribe(avg.Node.CURSOR_DOWN, onMouseDown) + return rect + + def moveRect(): + rect.pos = (50, 50) + rect.size = (30, 10) + rect.fillcolor = "FF0000" + rect.fillopacity = 0.5 + rect.color = "FFFF00" + rect.strokewidth = 2 + + def rotateRect(): + rect.angle = 1.57 + + def addRect2(): + rect = avg.RectNode(pos=(60, 2), size=(50, 30), fillopacity=1, + strokewidth=2) + rect.color = "FFFF00" + canvas.insertChild(rect, 0) + + def onMouseDown(event): + self.__mouseDownCalled = True + + self.__mouseDownCalled = False + canvas = self.makeEmptyCanvas() + rect = addRect() + self.start(False, + (lambda: self.compareImage("testRect1"), + moveRect, + lambda: self.compareImage("testRect2"), + rotateRect, + lambda: self.compareImage("testRect3"), + addRect2, + lambda: self.compareImage("testRect4"), + lambda: self.fakeClick(100, 100), + lambda: self.assertEqual(self.__mouseDownCalled, False), + lambda: self.fakeClick(55, 50), + lambda: self.assertEqual(self.__mouseDownCalled, False), + lambda: self.fakeClick(65, 65), + lambda: self.assert_(self.__mouseDownCalled) + )) + + def testTexturedRect(self): + def addRect(): + self.rect = avg.RectNode(pos=(20, 20), size=(50, 40), fillopacity=1, + filltexcoord1=(1,1), filltexcoord2=(0,0), strokewidth=20, + texcoords=(1, 0.75, 0.5, 0.25, 0), texhref="rgb24-64x64.png") + canvas.appendChild(self.rect) + return self.rect + + def newRect(): + self.rect.unlink() + self.rect = player.createNode( + """<rect pos="(20, 20)" size="(50, 40)" fillopacity="1" + filltexcoord1="(1,1)" filltexcoord2="(0,0)" + texcoords="(0, 0.25, 0.5, 0.75, 1)" + strokewidth="20" texhref="rgb24-64x64.png"/>""") + canvas.appendChild(self.rect) + + def setTexCoords(): + self.rect.texcoords = [-1, 0, 1, 2, 3] + + def setFillTex(): + self.rect.strokewidth = 2 + self.rect.texhref = "" + self.rect.filltexhref="rgb24alpha-64x64.png" + + def setFillTexCoords(): + self.rect.filltexcoord1 = (0.5, 0.5) + self.rect.filltexcoord2 = (1.5, 1.5) + + def setFillBitmap(): + bmp = avg.Bitmap("media/rgb24-64x64.png") + self.rect.setFillBitmap(bmp) + + def clearFillBitmap(): + self.rect.fillcolor = "FF0000" + self.rect.setFillBitmap(None) + + def setTransparentBorder(): + self.rect.fillopacity = 0 + self.rect.texhref = "rectborder.png" + self.rect.strokewidth = 10 + + canvas = self.makeEmptyCanvas() + addRect() + self.start(False, + (lambda: self.compareImage("testTexturedRect1"), + newRect, + lambda: self.compareImage("testTexturedRect2"), + setTexCoords, + lambda: self.compareImage("testTexturedRect3"), + setFillTex, + lambda: self.compareImage("testTexturedRect4"), + setFillTexCoords, + lambda: self.compareImage("testTexturedRect5"), + setFillBitmap, + lambda: self.compareImage("testTexturedRect6"), + clearFillBitmap, + lambda: self.compareImage("testTexturedRect7"), + setFillBitmap, + lambda: self.compareImage("testTexturedRect6"), +# setTransparentBorder, +# lambda: self.compareImage("testTexturedRect8"), + )) + + def testCurve(self): + def addCurve(): + curve = avg.CurveNode(pos1=(10.5, 10), pos2=(10.5, 80), pos3=(80.5, 80), + pos4=(80.5, 10)) + canvas.appendChild(curve) + return curve + + def changeCurve(): + curve.strokewidth = 19 + curve.color="FFFF00" + + def moveCurve(): + curve.pos2 = (10.5, 120) + curve.pos3 = (80.5, 120) + + def addCurve2(): + curve = avg.CurveNode(pos1=(30.5, 10), pos2=(30.5, 120), pos3=(100.5, 120), + pos4=(100.5, 10)) + curve.color="FF0000" + canvas.appendChild(curve) + + canvas = self.makeEmptyCanvas() + curve = addCurve() + self.assertAlmostEqual(curve.length, 210) + self.assertAlmostEqual(curve.getPtOnCurve(0), (10.5,10)) + self.assertAlmostEqual(curve.getPtOnCurve(1), (80.5,10)) + self.assertAlmostEqual(curve.getPtOnCurve(0.5), (45.5,62.5)) + self.start(False, + (lambda: self.compareImage("testCurve1"), + changeCurve, + lambda: self.compareImage("testCurve2"), + moveCurve, + lambda: self.compareImage("testCurve3"), + addCurve2, + lambda: self.compareImage("testCurve4"), + )) + + def testTexturedCurve(self): + def addCurve(): + curve = avg.CurveNode(pos1=(10.5, 10), pos2=(10.5, 80), pos3=(80.5, 80), + pos4=(80.5, 10), strokewidth=19, texhref="rgb24-64x64.png") + canvas.appendChild(curve) + return curve + + def setTexCoords(): + curve.texcoord1=-1 + curve.texcoord2=2 + + canvas = self.makeEmptyCanvas() + curve = addCurve() + self.start(False, + (lambda: self.compareImage("testTexturedCurve1"), + setTexCoords, + lambda: self.compareImage("testTexturedCurve2") + )) + + def testPolyLine(self): + def addPolyLine(): + polyline = avg.PolyLineNode(strokewidth=2, color="FF00FF", + pos=[(10,10), (50,10), (90,50), (90, 90)]) + canvas.appendChild(polyline) + return polyline + + def changePolyLine(): + polyline.strokewidth = 16 + polyline.color="FFFF00" + pos = polyline.pos + pos.append((110, 90)) + polyline.pos = pos + + def miterPolyLine(): + polyline.linejoin = "miter" + + def addPolyLine2(): + polyline2 = player.createNode( + """<polyline strokewidth="2" color="FF00FF" + pos="((110,10), (100,50), (110,70))" />""") + canvas.insertChild(polyline2,0) + + def testEmptyPolyLine(): + polyline2 = canvas.getChild(0) + polyline2.pos=[] + + def testAlmostEmptyPolyLine(): + polyline2 = canvas.getChild(0) + polyline2.pos=[(10,10)] + + def testAcutePolyLine(): + polyline2 = canvas.getChild(0) + polyline2.strokewidth = 10 + polyline2.linejoin="bevel" + polyline2.pos = [(50,10), (60,10), (50,11)] + canvas.removeChild(1) + + canvas = self.makeEmptyCanvas() + polyline = addPolyLine() + self.start(False, + (lambda: self.compareImage("testPolyLine1"), + changePolyLine, + lambda: self.compareImage("testPolyLine2"), + miterPolyLine, + lambda: self.compareImage("testPolyLine3"), + addPolyLine2, + lambda: self.compareImage("testPolyLine4"), + testEmptyPolyLine, + lambda: self.compareImage("testPolyLine5"), + testAlmostEmptyPolyLine, + lambda: self.compareImage("testPolyLine5"), + testAcutePolyLine, + lambda: self.compareImage("testPolyLine6") + )) + + def testTexturedPolyLine(self): + def texturePolyLine(): + polyline = avg.PolyLineNode(strokewidth=20, color="FF00FF", + texhref="rgb24-64x64.png", pos=((10,10), (50,10), (90,50), (90, 90)), + texcoords=(0, 0.3, 0.7, 1)) + canvas.appendChild(polyline) + return polyline + + def miter(): + polyline.linejoin = "miter" + + def setTexCoords(): + polyline.texcoords = [-1, 0, 1, 2] + + def repeatTexCoords(): + polyline.pos = [(10,10), (30,10), (30,50), (50,50), (50,70), (70,70)] + polyline.texcoords = [1, 2, 3] + + canvas = self.makeEmptyCanvas() + polyline = texturePolyLine() + self.start(False, + (lambda: self.compareImage("testTexturedPolyLine1"), + miter, + lambda: self.compareImage("testTexturedPolyLine2"), + setTexCoords, + lambda: self.compareImage("testTexturedPolyLine3"), + repeatTexCoords, + lambda: self.compareImage("testTexturedPolyLine4") + )) + + def testPolygon(self): + def addPolygon(): + polygon = avg.PolygonNode(strokewidth=2, color="FF00FF", + pos=((10,10), (50,10), (90,50), (90, 90))) + polygon.subscribe(avg.Node.CURSOR_DOWN, onMouseDown) + canvas.appendChild(polygon) + return polygon + + def changePolygon(): + polygon.strokewidth = 12 + polygon.color="FFFF00" + pos = polygon.pos + pos.append((10, 90)) + polygon.pos = pos + + def fillPolygon(): + polygon.strokewidth = 4 + polygon.fillcolor = "00FFFF" + polygon.fillopacity = 0.5 + pos = polygon.pos + pos.append((80, 50)) + pos.append((50, 20)) + pos.append((40, 40)) + polygon.pos = pos + + def addEmptyPoint(): + pos = polygon.pos + pos.insert(1, (10, 10)) + pos.append((40, 40)) + polygon.pos = pos + + def addPolygon2(): + polygon = avg.PolygonNode(strokewidth=3, color="FF00FF", + pos=((100.5,10.5), (100.5,30.5), (120.5,30.5), (120.5, 10.5))) + canvas.insertChild(polygon, 0) + + def miterPolygons(): + polygon.linejoin = "miter" + polygon2 = canvas.getChild(0) + polygon2.linejoin = "miter" + + def onMouseDown(event): + self.__mouseDownCalled = True + + def addEmptyPolygon(): + avg.PolygonNode(parent=canvas, fillopacity=1) + + def createLeftOpenPolygon(): + polygon.pos = ( (15,0), (35,0), (55,10), (65,30), (55,50), (35,60), (15,60), + (5,50), (15,40), (35,40), (35,30), (35,20), (15,20), (5,10) ) + polygon.strokewidth = 2 + + def createUpOpenPolygon(): + polygon.pos = ( (15,0), (25,10), (25,30), (35,30), (45,30), (45,10), (55,0), + (65,10), (65,30), (55,50), (35,60), (15,50), (5,30), (5,10) ) + + def createBottomOpenPolygon(): + polygon.pos = ( (35,0), (55,10), (65,30), (65,50), (55,60), (45,50), (45,30), + (35,30), (25,30), (25,50), (15,60), (5,50), (5,30), (15,10) ) + + def createOneHole(): + polygon.holes = ( [(35,10), (40,15), (35,20), (30,15)], ) + + def createMoreHoles(): + newHoles = ( polygon.holes[0], [(20,35), (20,45), (10,40)], + [(50,35), (50,45), (60,40)], ) + polygon.holes = newHoles + + def clearCanvas(): + for i in xrange(canvas.getNumChildren()-1): + dell = canvas.getChild(i) + canvas.removeChild(dell) + + self.__mouseDownCalled = False + canvas = self.makeEmptyCanvas() + polygon = addPolygon() + self.start(False, + (lambda: self.compareImage("testPolygon1"), + changePolygon, + lambda: self.compareImage("testPolygon2"), + fillPolygon, + lambda: self.compareImage("testPolygon3"), + addEmptyPoint, + lambda: self.compareImage("testPolygon4"), + addPolygon2, + lambda: self.compareImage("testPolygon5"), + miterPolygons, + lambda: self.compareImage("testPolygon6"), + lambda: self.fakeClick(50, 50), + lambda: self.assertEqual(self.__mouseDownCalled, False), + lambda: self.fakeClick(20, 87), + lambda: self.assert_(self.__mouseDownCalled), + addEmptyPolygon, + clearCanvas, + createLeftOpenPolygon, + lambda: self.compareImage("testPolygon7"), + createUpOpenPolygon, + lambda: self.compareImage("testPolygon8"), + createBottomOpenPolygon, + lambda: self.compareImage("testPolygon9"), + createOneHole, + lambda: self.compareImage("testPolygonHole1"), + createMoreHoles, + lambda: self.compareImage("testPolygonHole2") + )) + + def testTexturedPolygon(self): + def texturePolygon(): + polygon = avg.PolygonNode(strokewidth=20, color="FF00FF", + texhref="rgb24-64x64.png", pos=((10,10), (50,10), (90,50), (90, 90))) + canvas.appendChild(polygon) + return polygon + + def miter(): + polygon.linejoin = "miter" + + def setTexCoords(): + polygon.texcoords = [-1, 0, 1, 2, 3] + + def repeatTexCoords(): + polygon.texcoords = [0, 1] + + def setFillTex(): + polygon.fillopacity=1 + polygon.texhref="" + polygon.strokewidth=2 + polygon.filltexhref="rgb24alpha-64x64.png" + + def setFillTexCoords(): + polygon.filltexcoord1=(0.5, 1) + polygon.filltexcoord2=(1.5, 3) + + canvas = self.makeEmptyCanvas() + polygon = texturePolygon() + self.start(False, + (lambda: self.compareImage("testTexturedPolygon1"), + miter, + lambda: self.compareImage("testTexturedPolygon2"), + setTexCoords, + lambda: self.compareImage("testTexturedPolygon3"), + repeatTexCoords, + lambda: self.compareImage("testTexturedPolygon4"), + setFillTex, + lambda: self.compareImage("testTexturedPolygon5"), + setFillTexCoords, + lambda: self.compareImage("testTexturedPolygon6") + )) + + def testPointInPolygon(self): + polygon_pos = [(10, 10), (50, 10), (90, 50), (90, 90)] + self.assert_(avg.pointInPolygon((50, 20), polygon_pos)) + self.assert_(avg.pointInPolygon((10, 20), polygon_pos) == False) + + def testCircle(self): + def addCircle(): + circle = avg.CircleNode(pos=(30, 30), r=20) + circle.subscribe(avg.Node.CURSOR_DOWN, onMouseDown) + canvas.appendChild(circle) + return circle + + def changeCircle(): + circle.color="FF0000" + circle.fillcolor=u"FFFFFF" + circle.fillopacity=0.5 + circle.strokewidth=3 + + def textureCircle(): + circle.texhref="rgb24-64x64.png" + circle.strokewidth=20 + circle.pos = (50, 50) + circle.texcoord1 = -1 + circle.texcoord2 = 1 + + def setFillTex(): + circle.strokewidth=1 + circle.fillopacity=1 + circle.texhref = "" + circle.filltexhref="rgb24alpha-64x64.png" + + def setFillTexCoords(): + circle.filltexcoord1 = (0.5, 0.5) + circle.filltexcoord2 = (1.5, 1.5) + + def onMouseDown(event): + self.__mouseDownCalled = True + + self.__mouseDownCalled = False + canvas = self.makeEmptyCanvas() + circle = addCircle() + self.start(False, + (lambda: self.compareImage("testCircle1"), + changeCircle, + lambda: self.compareImage("testCircle2"), + textureCircle, + lambda: self.compareImage("testCircle3"), + setFillTex, + lambda: self.compareImage("testCircle4"), + setFillTexCoords, + lambda: self.compareImage("testCircle5"), + lambda: self.fakeClick(32, 32), + lambda: self.assert_(self.__mouseDownCalled == False), + lambda: self.fakeClick(67, 50), + lambda: self.assert_(self.__mouseDownCalled) + )) + + def testMesh(self): + def addMesh(): + div = avg.DivNode() + mesh = avg.MeshNode( + texhref="rgb24-64x64.png", + vertexcoords=((0,0), (64,0), (0,64), (64, 64),(32, 32)), + texcoords=((0,0),(1,0),(0,1),(1,1),(0.5,0.5)), + triangles=((0,1,4),(1,3,4),(3,2,4),(2,0,4))) + div.appendChild(mesh) + div.x = 50 + div.y = 30 + canvas.appendChild(div) + return mesh + + def setVertexCoords(): + mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 64)) + + def setTexCoords(): + mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 32)) + mesh.texcoords = ((1,1),(1,1),(1,1),(1,1),(0.5,0.5)) + + def setTriangles(): + mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(31.5, 32)) + mesh.texcoords = ((0,0),(1,0),(0,1),(1,1),(0.5,0.5)) + mesh.triangles = ((3,1,4),(1,3,4),(1,2,4),(2,0,4)) + + def setTrianglesSameItem(): + mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 32)) + mesh.texcoords = ((0,0),(1,0),(0,1),(1,1),(0.5,0.5)) + mesh.triangles = ((1,1,1),(2,2,2),(3,3,3),(4,4,4)) + + def setHref(): + mesh.texhref = "rgb24alpha-64x64.png" + + def setBackfaceCullTrue(): + mesh.texhref="rgb24-64x64.png" + mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(31.5, 32)) + mesh.texcoords = ((0,0),(1,0),(0,1),(1,1),(0.5,0.5)) + mesh.triangles = ((3,1,4),(1,3,4),(1,2,4),(2,0,4)) + mesh.backfacecull = True + + def setBackfaceCullFalse(): + mesh.backfacecull = False + + def setIllegalVertexes(): + mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 32), (16,16)) + + def setIllegalTextures(): + mesh.texcoords = ((100,0),(1,0),(0,1),(1,1),(0.5,0.5), (1.0,1.0)) + + def setIllegalIndexes(): + mesh.triangles = ((27,1,1),(1,3,4),(3,2,4),(2,0,4)) + + canvas = self.makeEmptyCanvas() + mesh = addMesh() + self.assertException(setIllegalVertexes) + self.assertException(setIllegalTextures) + self.assertException(setIllegalIndexes) + self.start(False, + (lambda: self.compareImage("testMesh1"), + setVertexCoords, + lambda: self.compareImage("testMesh2"), + setTexCoords, + lambda: self.compareImage("testMesh3"), + setTriangles, + lambda: self.compareImage("testMesh4"), + setHref, + lambda: self.compareImage("testMesh5"), + setTrianglesSameItem, + lambda: self.compareImage("testMesh6"), + setBackfaceCullTrue, + lambda: self.compareImage("testMesh7"), + setBackfaceCullFalse, + lambda: self.compareImage("testMesh8") + )) + + def testInactiveVector(self): + def addVectorNode(): + node = avg.LineNode(pos1=(2, 2), pos2=(50, 2), strokewidth=2) + canvas.appendChild(node) + return node + + def addFilledVectorNode(): + node = avg.RectNode(pos=(2, 6), size=(50, 30), strokewidth=2) + node.subscribe(avg.Node.CURSOR_DOWN, onDown) + canvas.appendChild(node) + return node + + def onDown(Event): + vNode.active = False + fvNode.active = False + self.onDownCalled = not self.onDownCalled + + canvas = self.makeEmptyCanvas() + vNode = addVectorNode() + fvNode = addFilledVectorNode() + self.onDownCalled = False + self.start(False, + (lambda: self.compareImage("testInactiveVector1"), + lambda: self.fakeClick(20, 20), + lambda: self.assert_(self.onDownCalled), + lambda: self.compareImage("testInactiveVector2"), + lambda: self.fakeClick(20, 20), + lambda: self.assert_(self.onDownCalled) + )) + + +def vectorTestSuite(tests): + availableTests = ( + "testLine", + "testLotsOfLines", + "testLineOpacity", + "testTexturedLine", + "testRect", + "testTexturedRect", + "testCurve", + "testTexturedCurve", + "testPolyLine", + "testTexturedPolyLine", + "testPolygon", + "testTexturedPolygon", + "testPointInPolygon", + "testCircle", + "testMesh", + "testInactiveVector" + ) + return createAVGTestSuite(availableTests, VectorTestCase, tests) diff --git a/src/test/WidgetTest.py b/src/test/WidgetTest.py new file mode 100644 index 0000000..720171e --- /dev/null +++ b/src/test/WidgetTest.py @@ -0,0 +1,900 @@ +# -*- 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, textarea, widget, player + +from testcase import * + +class WidgetTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testKeyboard(self): + def createKbd(pos, shiftKey=None, feedbackImage=None): + keyDefs = [ + [("a", "A"), ( 5, 5), (30, 30), False], + [("1", ), (35, 5), (30, 30), False], + ["SHIFT", (65, 5), (50, 30), True]] + kbd = widget.Keyboard("keyboard_bg.png", "keyboard_down.png", keyDefs, + shiftKey, feedbackSrc=feedbackImage, pos=pos, parent=root) + + for msg in (widget.Keyboard.DOWN, widget.Keyboard.UP, widget.Keyboard.CHAR): + kbd.subscribe(msg, lambda keyCode, msg=msg: onMessage(msg, keyCode)) + return kbd + + def onMessage(msg, keyCode): + self.__messageTester.setMessageReceived(msg) + self.__keyCode = keyCode + + def assertState(msgs, keyCode, imageSrc): + self.__messageTester.assertState(msgs) + self.assert_(self.__keyCode == keyCode) + self.compareImage(imageSrc) + + root = self.loadEmptyScene() + self.__keyCode = "" + + # Keyboard without shift support, no feedback image. + kbNoShift = createKbd((10, 10)) + self.__messageTester = MessageTester(kbNoShift, [], self) + + self.start(False, + (lambda: self.compareImage("testUIKeyboard"), + # test character key + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30), + lambda: assertState((widget.Keyboard.DOWN,), "a", "testUIKeyboardA"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 30, 30), + lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP), + "a", "testUIKeyboard"), + # test command key + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 30), + lambda: assertState((widget.Keyboard.DOWN,), "SHIFT", "testUIKeyboardS"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 30), + lambda: assertState((widget.Keyboard.UP,), "SHIFT", "testUIKeyboard"), + # test multiple keys + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 100, 30), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 30, 30), + lambda: assertState((widget.Keyboard.DOWN,), "a", "testUIKeyboardAS"), + lambda: self._sendTouchEvent(3, avg.Event.CURSOR_DOWN, 60, 30), + lambda: assertState((widget.Keyboard.DOWN,), "1", "testUIKeyboardA1S"), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 30), + lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP), + "a", "testUIKeyboard1S"), + lambda: self._sendTouchEvent(3, avg.Event.CURSOR_UP, 60, 30), + lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP), + "1", "testUIKeyboardS"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 100, 30), + lambda: assertState((widget.Keyboard.UP,), "SHIFT", "testUIKeyboard"), + )) + + root = self.loadEmptyScene() + self.__keyCode = "" + + # Keyboard with shift support, feedback image. + kbd = createKbd((10, 60), "SHIFT", "keyboard_feedback.png") + self.__messageTester = MessageTester(kbd, [], self) + + self.start(False, + # test shift key + (lambda: self.compareImage("testUIKeyboardFB"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 100, 80), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 30, 80), + lambda: assertState((widget.Keyboard.DOWN,), "a", "testUIKeyboardFBAS"), + lambda: self._sendTouchEvent(3, avg.Event.CURSOR_DOWN, 60, 80), + lambda: assertState((widget.Keyboard.DOWN,), "1", "testUIKeyboardFBA1S"), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 80), + lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP), + "A", "testUIKeyboardNoFB1S"), + lambda: self._sendTouchEvent(3, avg.Event.CURSOR_UP, 60, 80), + lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP), + "1", "testUIKeyboardFBS"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 100, 80), + lambda: assertState((widget.Keyboard.UP,), "SHIFT", "testUIKeyboardFB"), + # test drag over keys + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 60, 80), + lambda: assertState((widget.Keyboard.DOWN,), "1", "testUIKeyboardFB1"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 60, 50), + lambda: assertState((widget.Keyboard.UP,), "1", "testUIKeyboardFB"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 100, 80), + lambda: assertState((widget.Keyboard.DOWN,), "SHIFT", + "testUIKeyboardFBS"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 60, 80), + lambda: assertState((widget.Keyboard.DOWN,widget.Keyboard.UP), + "1", "testUIKeyboardFB1"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 60, 80), + lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP), + "1", "testUIKeyboardFB"), + )) + + def testTextArea(self): + def setup(): + self.ta1 = textarea.TextArea(pos=(2,2), size=(156, 96), parent=root) + self.ta1.setStyle(font="Bitstream vera sans", variant="Roman", fontsize=16, + multiline=True, color='FFFFFF') + self.ta1.setText('Lorem ipsum') + self.ta1.setFocus(True) # TODO: REMOVE + + self.ta2 = textarea.TextArea(pos=(2,100), size=(156, 18), parent=root) + self.ta2.setStyle(font="Bitstream vera sans", variant="Roman", fontsize=14, + multiline=False, color='4b94ef', cursorColor='FF0000', + flashingCursor=False) + self.ta2.setText('sit dolor') + self.ta2.showCursor(False) + self.ta2.setFocus(True) # TODO: REMOVE + + def setAndCheck(ta, text): + ta.setText(text) + self.assertEqual(ta.getText(), text) + + def clear(ta): + ta.onKeyDown(textarea.KEYCODE_FORMFEED) + self.assertEqual(ta.getText(), '') + + def testUnicode(): + self.ta1.setText(u'some ùnìcöde') + self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[0]) + self.assertEqual(self.ta1.getText(), u'some ùnìcöd') + self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[1]) + self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[0]) + self.assertEqual(self.ta1.getText(), u'some ùnìc') + self.ta1.onKeyDown(ord(u'Ä')) + self.assertEqual(self.ta1.getText(), u'some ùnìcÄ') + + def testSpecialChars(): + clear(self.ta1) + self.ta1.onKeyDown(ord(u'&')) + self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[0]) + self.assertEqual(self.ta1.getText(), '') + + def checkSingleLine(): + text = '' + self.ta2.setText('') + while True: + self.assert_(len(text) < 20) + self.ta2.onKeyDown(ord(u'A')) + text = text + 'A' + if text != self.ta2.getText(): + break + + root = self.loadEmptyScene() + + player.setFakeFPS(20) + textarea.init(avg, False) + self.start(True, + (setup, + lambda: self.delay(200), + lambda: self.assertEqual(self.ta1.getText(), 'Lorem ipsum'), + lambda: setAndCheck(self.ta1, ''), + lambda: setAndCheck(self.ta2, 'Lorem Ipsum'), + testUnicode, + lambda: self.compareImage("testTextArea1"), + testSpecialChars, + checkSingleLine, + lambda: self.compareImage("testTextArea2"), + lambda: self.ta2.showCursor(True), + lambda: self.delay(200), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 30, 100), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 30, 100), + lambda: self.compareImage("testTextArea3"), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 130, 100), + lambda: self.delay(1100), + lambda: self.compareImage("testTextArea4"), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_MOTION, 30, 100), + lambda: self.compareImage("testTextArea5"), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 100), + lambda: self.compareImage("testTextArea3"), + )) + player.setFakeFPS(-1) + + def testFocusContext(self): + def setup(): + textarea.init(avg) + self.ctx1 = textarea.FocusContext() + self.ctx2 = textarea.FocusContext() + + self.ta1 = textarea.TextArea(self.ctx1, pos=(2,2), size=(156,54), parent=root) + self.ta1.setStyle(fontsize=16, multiline=True, color='FFFFFF') + self.ta1.setText('Lorem ipsum') + + self.ta2 = textarea.TextArea(self.ctx1, pos=(2,58), size=(76,54), parent=root) + self.ta2.setStyle(fontsize=14, multiline=False, color='FFFFFF') + self.ta2.setText('dolor') + + self.bgImage = avg.ImageNode(href="1x1_white.png", size=(76,54)) + self.ta3 = textarea.TextArea(self.ctx2, disableMouseFocus=True, pos=(80,58), + size=(76,54), textBackgroundNode=self.bgImage, parent=root) + self.ta3.setStyle(fontsize=14, multiline=True, color='FFFFFF') + self.ta3.setText('dolor sit amet') + + textarea.setActiveFocusContext(self.ctx1) + + def writeChar(): + helper = player.getTestHelper() + helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65, 0) + helper.fakeKeyEvent(avg.Event.KEY_UP, 65, 65, "A", 65, 0) + helper.fakeKeyEvent(avg.Event.KEY_DOWN, 66, 66, "B", 66, 0) + helper.fakeKeyEvent(avg.Event.KEY_UP, 66, 66, "B", 66, 0) + helper.fakeKeyEvent(avg.Event.KEY_DOWN, 67, 67, "C", 67, 0) + helper.fakeKeyEvent(avg.Event.KEY_UP, 67, 67, "C", 67, 0) + + def switchFocus(): + self.ctx1.cycleFocus() + + def clearFocused(): + self.ctx1.clear() + + def clickForFocus(): + self._sendMouseEvent(avg.Event.CURSOR_DOWN, 20, 70) + self._sendMouseEvent(avg.Event.CURSOR_UP, 20, 70) + + root = self.loadEmptyScene() + self.start(True, + (setup, + lambda: self.compareImage("testFocusContext1"), + writeChar, + lambda: self.compareImage("testFocusContext2"), + switchFocus, + writeChar, + lambda: self.compareImage("testFocusContext3"), + switchFocus, + clearFocused, + lambda: self.compareImage("testFocusContext4"), + clickForFocus, + clearFocused, + lambda: self.compareImage("testFocusContext5"), + )) + + + def testButton(self): + + def enable(enabled): + button.enabled = enabled + + def createScene(**kwargs): + root = self.loadEmptyScene() + button = widget.Button( + parent = root, + upNode = avg.ImageNode(href="button_up.png"), + downNode = avg.ImageNode(href="button_down.png"), + disabledNode = avg.ImageNode(href="button_disabled.png"), + **kwargs + ) + self.messageTester = MessageTester(button, + [widget.Button.CLICKED, widget.Button.PRESSED, + widget.Button.RELEASED], self) + return button + + def runTest(): + self.start(False, + (# Standard down->up + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0, + [widget.Button.PRESSED]), + lambda: self.compareImage("testUIButtonDown"), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0, + [widget.Button.CLICKED, widget.Button.RELEASED]), + lambda: self.compareImage("testUIButtonUp"), + + # Disable, down, up -> no click + lambda: self.assert_(button.enabled), + lambda: enable(False), + lambda: self.assert_(not(button.enabled)), + lambda: self.compareImage("testUIButtonDisabled"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0, []), + lambda: enable(True), + lambda: self.assert_(button.enabled), + + # Down, up further away -> no click + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 100, 0, + [widget.Button.PRESSED, widget.Button.RELEASED]), + lambda: self.compareImage("testUIButtonUp"), + + # Down, move further away, up -> no click + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 100, 0), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 100, 0, + [widget.Button.PRESSED, widget.Button.RELEASED]), + lambda: self.compareImage("testUIButtonUp"), + + # Test if button still reacts after abort + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0, + [widget.Button.PRESSED]), + lambda: self.compareImage("testUIButtonDown"), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0, + [widget.Button.CLICKED, widget.Button.RELEASED]), + lambda: self.compareImage("testUIButtonUp"), + )) + + button = createScene() + runTest() + + button = createScene(activeAreaNode=avg.CircleNode(r=5, opacity=0)) + runTest() + + button = createScene(fatFingerEnlarge=True) + runTest() + + root = self.loadEmptyScene() + button = widget.BmpButton( + parent = root, + upSrc = "button_up.png", + downSrc = "button_down.png", + disabledSrc = "button_disabled.png", + ) + self.messageTester = MessageTester(button, + [widget.Button.CLICKED, widget.Button.PRESSED, widget.Button.RELEASED], + self) + runTest() + + button = createScene(enabled=False) + self.start(False, + (lambda: self.compareImage("testUIButtonDisabled"), + )) + + def testTextButton(self): + root = self.loadEmptyScene() + button = widget.TextButton("text", parent=root, size=(50,42)) + self.messageTester = MessageTester(button, + [widget.Button.CLICKED, widget.Button.PRESSED, widget.Button.RELEASED], + self) + self.start(True, + (# Standard down->up + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0, + [widget.Button.PRESSED]), + lambda: self.compareImage("testTextButtonDown"), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0, + [widget.Button.CLICKED, widget.Button.RELEASED]), + lambda: self.compareImage("testTextButtonUp"), + + # Check disabled graphics + lambda: self.assert_(button.enabled), + lambda: button.setEnabled(False), + lambda: self.assert_(not(button.enabled)), + lambda: self.compareImage("testTextButtonDisabled"), + lambda: button.setEnabled(True), + + # Change text + lambda: button.setText("newText"), + lambda: self.compareImage("testTextButtonUpNewText"), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0, + [widget.Button.PRESSED]), + lambda: self.compareImage("testTextButtonDownNewText"), + )) + + + def testToggleButton(self): + + def onToggled(isToggled): + self.messageTester.setMessageReceived(widget.ToggleButton.TOGGLED) + self.toggled = isToggled + + def createScene(**kwargs): + root = self.loadEmptyScene() + button = widget.ToggleButton( + uncheckedUpNode = avg.ImageNode(href="toggle_unchecked_Up.png"), + uncheckedDownNode = avg.ImageNode(href="toggle_unchecked_Down.png"), + checkedUpNode = avg.ImageNode(href="toggle_checked_Up.png"), + checkedDownNode = avg.ImageNode(href="toggle_checked_Down.png"), + uncheckedDisabledNode = + avg.ImageNode(href="toggle_unchecked_Disabled.png"), + checkedDisabledNode = + avg.ImageNode(href="toggle_checked_Disabled.png"), + parent=root, + **kwargs + ) + self.messageTester = MessageTester(button, + [widget.ToggleButton.PRESSED, widget.ToggleButton.RELEASED], self) + + button.subscribe(widget.ToggleButton.TOGGLED, onToggled) + return button + + def testToggle(): + self.start(False, + (lambda: self.compareImage("testUIToggleUnchecked_Up"), + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0, + [widget.ToggleButton.PRESSED]), + lambda: self.assert_(not self.toggled), + lambda: self.compareImage("testUIToggleUnchecked_Down"), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0, + [widget.ToggleButton.RELEASED, widget.ToggleButton.TOGGLED]), + lambda: self.assert_(self.toggled), + lambda: self.compareImage("testUIToggleChecked_Up"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0), + lambda: self.compareImage("testUIToggleChecked_Down"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 0, 0), + lambda: self.assert_(not(self.toggled)), + lambda: self.compareImage("testUIToggleUnchecked_Up"), + )) + + def testToggleAbort(): + self.start(False, + (lambda: self.compareImage("testUIToggleUnchecked_Up"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0), + lambda: self.compareImage("testUIToggleUnchecked_Down"), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 100, 0, + [widget.ToggleButton.PRESSED, widget.ToggleButton.RELEASED]), + lambda: self.assert_(not self.toggled), + lambda: self.compareImage("testUIToggleUnchecked_Up"), + lambda: button.setChecked(True), + lambda: self.compareImage("testUIToggleChecked_Up"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0), + lambda: self.compareImage("testUIToggleChecked_Down"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 0), + lambda: self.assert_(not(self.toggled)), + lambda: self.compareImage("testUIToggleChecked_Up"), + )) + + def testToggleDisable(): + self.start(False, + (lambda: self.compareImage("testUIToggleUnchecked_Disabled"), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 0, 0), + lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 0, 0), + lambda: self.compareImage("testUIToggleUnchecked_Disabled"), + lambda: button.setEnabled(True), + lambda: self.compareImage("testUIToggleUnchecked_Up"), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 0, 0), + lambda: button.setEnabled(False), + lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 0, 0), + lambda: self.assert_(not(self.toggled)), + lambda: self.compareImage("testUIToggleUnchecked_Disabled"), + + lambda: button.setEnabled(True), + lambda: self.compareImage("testUIToggleUnchecked_Up"), + lambda: button.setChecked(True), + lambda: self.compareImage("testUIToggleChecked_Up"), + lambda: button.setEnabled(False), + lambda: self.compareImage("testUIToggleChecked_Disabled"), + lambda: self._sendTouchEvent(3, avg.Event.CURSOR_DOWN, 0, 0), + lambda: self._sendTouchEvent(3, avg.Event.CURSOR_UP, 0, 0), + lambda: self.compareImage("testUIToggleChecked_Disabled"), + lambda: button.setEnabled(True), + lambda: self.compareImage("testUIToggleChecked_Up"), + lambda: self._sendTouchEvent(4, avg.Event.CURSOR_DOWN, 0, 0), + lambda: button.setEnabled(False), + lambda: self._sendTouchEvent(4, avg.Event.CURSOR_UP, 0, 0), + lambda: self.assert_(not(self.toggled)), + lambda: self.compareImage("testUIToggleChecked_Disabled"), + )) + + def testFromSrc(): + root = self.loadEmptyScene() + button = widget.BmpToggleButton( + uncheckedUpSrc="toggle_unchecked_Up.png", + uncheckedDownSrc="toggle_unchecked_Down.png", + checkedUpSrc="toggle_checked_Up.png", + checkedDownSrc="toggle_checked_Down.png", + uncheckedDisabledSrc="toggle_unchecked_Disabled.png", + checkedDisabledSrc="toggle_checked_Disabled.png", + parent=root) + button.subscribe(widget.ToggleButton.TOGGLED, onToggled) + self.start(False, + (lambda: self.compareImage("testUIToggleUnchecked_Up"), + lambda: button.setChecked(True), + lambda: self.compareImage("testUIToggleChecked_Up"), + lambda: button.setChecked(False), + lambda: button.setEnabled(False), + lambda: self.compareImage("testUIToggleUnchecked_Disabled"), + lambda: button.setChecked(True), + lambda: self.compareImage("testUIToggleChecked_Disabled"), + )) + + self.toggled = False + button = createScene() + testToggle() + + button = createScene() + testToggleAbort() + + button = createScene(enabled = False) + testToggleDisable() + + button = createScene(activeAreaNode = avg.CircleNode(r=5, opacity=0)) + testToggle() + + button = createScene(fatFingerEnlarge = True) + testToggle() + + testFromSrc() + + + def testCheckBox(self): + + root = self.loadEmptyScene() + avg.RectNode(size=(160,120), fillcolor="FFFFFF", fillopacity=1, parent=root) + checkBox = widget.CheckBox(text="checkboxtext", pos=(10,10), parent=root) + + self.start(True, + (lambda: self.compareImage("testUICheckBoxUnchecked_Up"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 15, 15), + lambda: self.compareImage("testUICheckBoxUnchecked_Down"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 15, 15), + lambda: self.compareImage("testUICheckBoxChecked_Up"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 15, 15), + lambda: self.compareImage("testUICheckBoxChecked_Down"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 15, 15), + lambda: self.compareImage("testUICheckBoxUnchecked_Up"), + lambda: checkBox.setEnabled(False), + lambda: self.compareImage("testUICheckBoxUnchecked_Disabled"), + lambda: checkBox.setEnabled(True), + lambda: self.compareImage("testUICheckBoxUnchecked_Up"), + # Test click on text. + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 50, 15), + lambda: self.compareImage("testUICheckBoxUnchecked_Down"), + )) + + + def testScrollPane(self): + def scrollLarge(): + scrollPane.contentpos = (34, 34) + self.assertEqual(scrollPane.contentpos, (32,32)) + + def initSmallContent(): + scrollPane.size = (64, 64) + contentArea.size = (32, 32) + image.size = (32, 32) + scrollPane.contentpos = (0, 0) + self.assertEqual(scrollPane.getMaxContentPos(), (0,0)) + + def scrollSmall(): + scrollPane.contentpos = (32, 32) + + root = self.loadEmptyScene() + contentArea = avg.DivNode(size=(64,64)) + image = avg.ImageNode(href="rgb24-64x64.png", parent=contentArea) + scrollPane = widget.ScrollPane(contentNode=contentArea, size=(32,32), parent=root) + + self.start(False, + (lambda: self.compareImage("testScrollPane1"), + scrollLarge, + lambda: self.compareImage("testScrollPane2"), + initSmallContent, + lambda: self.compareImage("testScrollPane3"), + scrollSmall, + lambda: self.compareImage("testScrollPane3"), + )) + + def testStretchNode(self): + + def changeExtent(): + if orientation == widget.Orientation.HORIZONTAL: + self.node.width = 100 + else: + self.node.height = 100 + + def minExtent(): + if orientation == widget.Orientation.HORIZONTAL: + self.node.width = 3 + self.assert_(self.node.width == 31) + else: + self.node.height = 3 + self.assert_(self.node.height == 31) + + for orientation, orName in ( + (widget.Orientation.HORIZONTAL,"Horiz"), + (widget.Orientation.VERTICAL, "Vert"),): + root = self.loadEmptyScene() + if orientation == widget.Orientation.HORIZONTAL: + self.node = widget.HStretchNode(src="media/rgb24-32x32.png", + endsExtent=15, size=(31,31), parent=root) + else: + self.node = widget.VStretchNode(src="media/rgb24-32x32.png", + endsExtent=15, size=(31,31), parent=root) + self.start(False, + (lambda: self.compareImage("testStretchNode"+orName+"1"), + changeExtent, + lambda: self.compareImage("testStretchNode"+orName+"2"), + minExtent, + lambda: self.compareImage("testStretchNode"+orName+"1"), + )) + + + def testHVStretchNode(self): + + def changeSize(): + self.node.size = (64, 64) + self.assert_(self.node.size == (64,64)) + + root = self.loadEmptyScene() + self.node = widget.HVStretchNode(src="media/rgb24-32x32.png", endsExtent=(5,5), + size=(31,31), parent=root) + self.start(False, + (lambda: self.compareImage("testHVStretchNode1"), + changeSize, + lambda: self.compareImage("testHVStretchNode2"), + )) + + + def testSlider(self): + def onThumbPosChanged(pos): + self.thumbPos = pos + + def setSize(): + if orientation == widget.Orientation.HORIZONTAL: + self.node.width=140 + else: + self.node.height=60 + + sys.stderr.write("\n") + for orientation, orName in ( + (widget.Orientation.HORIZONTAL, "Horiz"), + (widget.Orientation.VERTICAL, "Vert")): + for widgetType in ("Slider", "TimeSlider"): + sys.stderr.write(" "+widgetType+", "+orName+"\n") + root = self.loadEmptyScene() + if widgetType == "Slider": + self.node = widget.Slider(orientation=orientation, pos=(20,20), + width=100, height=100, parent=root) + else: + self.node = widget.TimeSlider(orientation=orientation, pos=(20,20), + width=100, height=100, parent=root) + self.start(False, + (lambda: self.compareImage("test"+widgetType+orName+"1"), + lambda: self.node.setThumbPos(0.25), + lambda: self.compareImage("test"+widgetType+orName+"2"), + lambda: self.node.setThumbPos(1), + lambda: self.compareImage("test"+widgetType+orName+"3"), + lambda: self.node.setRange((1,10)), + lambda: self.compareImage("test"+widgetType+orName+"1"), + lambda: self.node.setRange((10,1)), + lambda: self.compareImage("test"+widgetType+orName+"3"), + setSize, + lambda: self.compareImage("test"+widgetType+orName+"4"), + lambda: self.node.setEnabled(False), + lambda: self.compareImage("test"+widgetType+orName+"5"), + lambda: self.node.setEnabled(True), + lambda: self.compareImage("test"+widgetType+orName+"4"), + )) + + + def testScrollBar(self): + + def onThumbPosChanged(pos): + self.thumbPos = pos + + for orientation, orName in ( + (widget.Orientation.HORIZONTAL, "Horiz"), + (widget.Orientation.VERTICAL, "Vert")): + root = self.loadEmptyScene() + self.node = widget.ScrollBar(orientation=orientation, pos=(20,20), + width=100, height=100, parent=root) + self.start(False, + (lambda: self.compareImage("testScrollBar"+orName+"1"), + lambda: self.node.setThumbExtent(0.5), + lambda: self.compareImage("testScrollBar"+orName+"2"), + lambda: self.node.setThumbPos(0.25), + lambda: self.compareImage("testScrollBar"+orName+"3"), + lambda: self.node.setThumbPos(5), + lambda: self.compareImage("testScrollBar"+orName+"4"), + lambda: self.node.setRange((0,10)), + lambda: self.node.setThumbPos(4.75), + lambda: self.compareImage("testScrollBar"+orName+"5"), + lambda: self.node.setRange((10,20)), + lambda: self.node.setThumbPos(14.75), + lambda: self.compareImage("testScrollBar"+orName+"5"), + lambda: self.node.setThumbExtent(10), + lambda: self.compareImage("testScrollBar"+orName+"6"), + lambda: self.node.setRange((10,0)), + lambda: self.node.setThumbExtent(0.5), + lambda: self.node.setThumbPos(4.75), + lambda: self.compareImage("testScrollBar"+orName+"5"), + )) + + # Horizontal + root = self.loadEmptyScene() + self.node = widget.ScrollBar(orientation=widget.Orientation.HORIZONTAL, + pos=(20,5), width=100, parent=root) + self.messageTester = MessageTester(self.node, + [widget.Slider.PRESSED, widget.Slider.RELEASED], self) + self.start(False, + (lambda: self.node.setThumbExtent(0.5), + # User input + self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 25, 10, + [widget.Slider.PRESSED]), + lambda: self.compareImage("testScrollBarHoriz7"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 50, 10), + lambda: self.compareImage("testScrollBarHoriz8"), + lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0.25), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 25, 10), + lambda: self.compareImage("testScrollBarHoriz9"), + lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0), + self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 10, + [widget.Slider.RELEASED]), + lambda: self.compareImage("testScrollBarHoriz10"), + lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0), + + # Publish/Subscribe interface + lambda: self.node.subscribe(widget.ScrollBar.THUMB_POS_CHANGED, + onThumbPosChanged), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 25, 10), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 50, 10), + lambda: self.assertAlmostEqual(self.thumbPos, 0.25), + + # Enable/disable + self.messageTester.reset, + lambda: self.node.setEnabled(False), + lambda: self.compareImage("testScrollBarHoriz11"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 50, 10), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 25, 10), + lambda: self.messageTester.assertState([]), + lambda: self.assertAlmostEqual(self.thumbPos, 0.25), + lambda: self.node.setEnabled(True), + lambda: self.compareImage("testScrollBarHoriz12"), + + # Disable after down: Drag aborted + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 50, 10), + lambda: self.node.setEnabled(False), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 25, 10), + lambda: self.assertAlmostEqual(self.thumbPos, 0.25), + lambda: self.node.setEnabled(True), + lambda: self.compareImage("testScrollBarHoriz12"), + )) + + # Vertical: Don't need to test everything again, just make sure coords are + # calculated correctly. + root = self.loadEmptyScene() + self.node = widget.ScrollBar(orientation=widget.Orientation.VERTICAL, pos=(5,5), + height=100, parent=root) + self.start(False, + (lambda: self.node.setThumbExtent(0.5), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 25), + lambda: self.compareImage("testScrollBarVert7"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 10, 50), + lambda: self.compareImage("testScrollBarVert8"), + lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0.25), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 0), + lambda: self.compareImage("testScrollBarVert9"), + lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0), + )) + + def testProgressBar(self): + + def setValue(value): + self.node.value = value + + def setRange(range): + self.node.range = range + + root = self.loadEmptyScene() + self.node = widget.ProgressBar(orientation=widget.Orientation.HORIZONTAL, + pos=(5,5), width=100, parent=root) + self.start(False, + (lambda: self.compareImage("testProgressBar1"), + lambda: setValue(0.5), + lambda: self.compareImage("testProgressBar2"), + lambda: setValue(1), + lambda: self.compareImage("testProgressBar3"), + lambda: setRange((23,42)), + lambda: self.compareImage("testProgressBar1"), + lambda: setValue(32.5), + lambda: self.compareImage("testProgressBar2"), + )) + + def testMediaControl(self): + + def onSeek(time): + self.messageTester.setMessageReceived(widget.MediaControl.SEEK_MOTION) + + root = self.loadEmptyScene() + self.node = widget.MediaControl(size=(160,30), parent=root) + self.messageTester = MessageTester(self.node, + [widget.MediaControl.PLAY_CLICKED, widget.MediaControl.PAUSE_CLICKED, + widget.MediaControl.SEEK_PRESSED, widget.MediaControl.SEEK_RELEASED], + self) + self.node.subscribe(widget.MediaControl.SEEK_MOTION, onSeek) + self.start(True, + (lambda: self.compareImage("testMediaControl1"), + lambda: self.node.setDuration(60*1000), + lambda: self.compareImage("testMediaControl2"), + lambda: self.node.setTime(30*1000), + lambda: self.compareImage("testMediaControl3"), + lambda: self.node.setTime(60*1000), + lambda: self.compareImage("testMediaControl4"), + lambda: self.node.play(), + lambda: self.compareImage("testMediaControl5"), + lambda: self.node.pause(), + lambda: self.compareImage("testMediaControl4"), + self.messageTester.reset, + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 1, 1), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 1, 1), + lambda: self.messageTester.assertState( + [widget.MediaControl.PLAY_CLICKED,]), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 1, 1), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 1, 1), + lambda: self.messageTester.assertState( + [widget.MediaControl.PAUSE_CLICKED,]), + lambda: self.node.setTime(0), + lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 56, 5), + lambda: self.messageTester.assertState( + [widget.MediaControl.SEEK_PRESSED]), + lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 150, 5), + lambda: self.messageTester.assertState( + [widget.MediaControl.SEEK_MOTION,]), + lambda: self.compareImage("testMediaControl4"), + lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 150, 5), + lambda: self.messageTester.assertState( + [widget.MediaControl.SEEK_RELEASED,]), + )) + + def testScrollArea(self): + def setSize(size): + self.node.size = size + + root = self.loadEmptyScene() + image = avg.ImageNode(href="rgb24-64x64.png", size=(200,400)) + self.node = widget.ScrollArea(contentNode=image, size=(80,80), parent=root) + self.start(False, + (lambda: self.compareImage("testScrollArea1"), + lambda: setSize((120,80)), + lambda: self.compareImage("testScrollArea2"), + )) + + def testScrollAreaCustomSkin(self): + root = self.loadEmptyScene() + image = avg.ImageNode(href="rgb24-64x64.png", size=(200, 400)) + pwdPath = os.path.dirname(os.path.realpath(__file__)) + mediaPath = os.path.join(pwdPath, "media") + skin = widget.Skin("CustomSkin.xml", mediaPath) + self.node = widget.ScrollArea(contentNode=image, size=(80, 80), skinObj=skin, + parent=root) + self.start(False, + (lambda: self.compareImage("testScrollArea3"),)) + + def testCustomMediaDir(self): + root = self.loadEmptyScene() + + pwdPath = os.path.dirname(os.path.realpath(__file__)) + mediaPath = os.path.join(pwdPath, "media") + skin = widget.Skin("SimpleSkin.xml", mediaPath) + downBmpPath = skin.textButtonCfg[None]['downBmp'].getName() + upBmpPath = skin.textButtonCfg[None]['upBmp'].getName() + self.assert_(downBmpPath == os.path.join(mediaPath, 'button_bg_down.png')) + self.assert_(upBmpPath == os.path.join(mediaPath, 'button_bg_up.png')) + + customSkinMediaPath = os.path.join(mediaPath, 'incompleteSkinMedia') + skin = widget.Skin("IncompleteSkin.xml", customSkinMediaPath) + self.node = widget.ScrollBar(orientation=widget.Orientation.HORIZONTAL, + pos=(20,5), width=100, parent=root, skinObj=skin) + self.start(False, ()) + + +def widgetTestSuite(tests): + availableTests = ( + "testKeyboard", + "testTextArea", + "testFocusContext", + "testButton", + "testTextButton", + "testToggleButton", + "testCheckBox", + "testScrollPane", + "testStretchNode", + "testHVStretchNode", + "testSlider", + "testScrollBar", + "testProgressBar", + "testMediaControl", + "testScrollArea", + "testScrollAreaCustomSkin", + "testCustomMediaDir", + ) + + return createAVGTestSuite(availableTests, WidgetTestCase, tests) diff --git a/src/test/WordsTest.py b/src/test/WordsTest.py new file mode 100644 index 0000000..a5e856e --- /dev/null +++ b/src/test/WordsTest.py @@ -0,0 +1,701 @@ +#!/usr/bin/python +# -*- 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 +# + +import platform + +from libavg import avg, player +from testcase import * + +class WordsTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testSimpleWords(self): + def checkFont(): + self.assertEqual(node.variant, "bold") + + def checkUnicodeText(): + node.text = u"föa" + avg.WordsNode(text=u"öäü", font="Bitstream Vera Sans") + + fontList = avg.WordsNode.getFontFamilies() + try: + fontList.index("Bitstream Vera Sans") + except ValueError: + self.fail("Font not found") + variantList = avg.WordsNode.getFontVariants("Bitstream Vera Sans") + self.assert_(len(variantList) >= 4) + root = self.loadEmptyScene() + avg.WordsNode (pos=(1,1), fontsize=12, font="Bitstream Vera Sans", + text="Bitstream Vera Sans", variant="roman", parent=root) + node = avg.WordsNode(pos=(1,16), fontsize=12, font="Bitstream Vera Sans", + text="Bold", variant="bold", parent=root) + self.assertNotEqual(node.size, (0,0)) + node.getGlyphPos(0) + self.start(True, + (lambda: self.compareImage("testSimpleWords"), + checkFont, + checkUnicodeText, + )) + + def testRedrawOnDemand(self): + + def changeText(newText): + size = node.size + node.text = newText + self.assertNotEqual(node.size, size) + + def changeFont(): + size = node.size + node.fontsize = 18 + self.assertNotEqual(node.size, size) + + root = self.loadEmptyScene() + node = avg.WordsNode(font="Bitstream Vera Sans", fontsize=12, text="foo", + parent=root) + changeText("foobar") + self.start(True, + (lambda: changeText("bar"), + changeFont, + )) + + def testFontStyle(self): + + def setStyle(node, style): + node.fontstyle = style + self.assert_(node.fontsize == 15) + + fontStyle = avg.FontStyle(font="Bitstream Vera Sans", variant="Roman", + fontsize=12) + self.assert_(fontStyle.font == "Bitstream Vera Sans") + root = self.loadEmptyScene() + words = avg.WordsNode(pos=(1,1), fontstyle=fontStyle, text="Bitstream Vera Sans", + parent=root) + avg.WordsNode (pos=(1,16), fontstyle=fontStyle, variant="bold", text="Bold", + parent=root) + otherFontStyle = fontStyle + otherFontStyle.fontsize = 15 + self.start(True, + (lambda: self.compareImage("testFontStyle1"), + lambda: setStyle(words, otherFontStyle), + lambda: self.compareImage("testFontStyle2"), + )) + + def testBaseStyle(self): + attrs = {"font": "Bitstream Vera Sans", + "variant": "Bold", + "color": "FF0000", + "aagamma": 0.5, + "fontsize": 20, + "indent": 1, + "linespacing": 2, + "alignment": "right", + "wrapmode": "char", + "justify": True, + "letterspacing": 3, + "hint": False} + defaultStyle = avg.FontStyle() + fontStyle1 = avg.FontStyle(basestyle=defaultStyle, **attrs) + for attrName in attrs.iterkeys(): + self.assert_(getattr(fontStyle1, attrName) != getattr(defaultStyle, attrName)) + self.assert_(getattr(fontStyle1, attrName) == attrs[attrName]) + fontStyle2 = avg.FontStyle(basestyle=fontStyle1) + for attrName in attrs.iterkeys(): + self.assert_(getattr(fontStyle2, attrName) == getattr(fontStyle1, attrName)) + + def testGlyphPos(self): + def posAlmostEqual(pos1, pos2): + return math.fabs(pos1[0]-pos2[0]) <= 2 and math.fabs(pos1[1]-pos2[1]) <= 2 + + node = avg.WordsNode(text="Bold", font="Bitstream Vera Sans") + self.assertEqual(node.getGlyphPos(0), (0,0)) + size = node.getGlyphSize(0) + self.assert_(posAlmostEqual(size, (10, 18))) + self.assert_(posAlmostEqual(node.getGlyphPos(3), (22,0))) + size = node.getGlyphSize(3) + self.assert_(posAlmostEqual(size, (8, 18))) + self.assertException(lambda: node.getGlyphPos(4)) + node.text=u"föa" + self.assert_(posAlmostEqual(node.getGlyphPos(1), (4,0))) +# print [ node.getGlyphPos(i) for i in range(3)] + self.assert_(posAlmostEqual(node.getGlyphPos(2), (12,0))) + self.assertException(lambda: node.getGlyphPos(3)) + + def testParaWords(self): + root = self.loadEmptyScene() + avg.LineNode(pos1=(0.5, 0), pos2=(0.5, 50), color="FF0000", parent=root) + avg.LineNode(pos1=(119.5, 0.5), pos2=(119.5, 50), color="FF0000", parent=root) + avg.LineNode(pos1=(74.5,60), pos2=(74.5, 110), color="FF0000", parent=root) + avg.WordsNode(id="para", pos=(1,1), fontsize=12, width=70, + font="Bitstream Vera Sans", text="Left-justified paragraph.", + parent=root) + avg.WordsNode(id="paracenter", pos=(120,1), fontsize=12, width=70, + font="Bitstream Vera Sans", text="Centered paragraph", + alignment="center", parent=root) + avg.WordsNode(id="pararight", pos=(75,60), fontsize=12, width=70, + font="Bitstream Vera Sans", alignment="right", + text="Right-justified paragraph.<i>l</i>", + parent=root) + avg.WordsNode(id="paralinespacing", pos=(80,60), fontsize=12, width=70, + font="Bitstream Vera Sans", linespacing=-4, + text="Paragraph with custom line spacing.", + parent=root) + self.start(True, [lambda: self.compareImage("testParaWords")]) + + def testJustify(self): + root = self.loadEmptyScene() + avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans", + variant="roman", justify=True, width=100, + text="Justified paragraph more than one line long.", parent=root) + self.start(True, [lambda: self.compareImage("testJustify")]) + + def testWrapMode(self): + def setCharMode(): + node.wrapmode = 'char' + + def setWordMode(): + node.wrapmode = 'word' + + def setWordCharMode(): + node.wrapmode = 'wordchar' + + root = self.loadEmptyScene() + node = avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans", + variant="roman", width=100, + text="""Wrapped paragraph more than one line long. + Withaverylongpackedlinewithnobreaks""", + parent=root) + self.start(True, + (lambda: self.compareImage("testWrapMode1"), + setCharMode, + lambda: self.compareImage("testWrapMode2"), + setWordMode, + lambda: self.compareImage("testWrapMode3"), + setWordCharMode, + lambda: self.compareImage("testWrapMode4"), + )) + + def testWordsMask(self): + def setMask(): + try: + node.maskhref = "mask1.png" + except RuntimeError: + self.skip("no shader support") + player.stop() + + def setColor(): + node.color = "FFFF00" + + def setOpacity(): + node.opacity = 0.5 + + def setSize(): + rect = avg.RectNode(pos=(39.5, 30.5), size=(80, 60)) + root.appendChild(rect) + node.masksize = (160, 120) + node.opacity = 1 + + def setPos(): + node.pos = (40, 20) + node.maskpos = (-40, -20) + + def setDefaultSize(): + node.masksize = (0,0) + + def setCentered(): + node.alignment = "center" + node.masksize = (160, 120) + node.pos = (80,20) + node.maskpos = (0, -20) + + root = self.loadEmptyScene() + node = avg.WordsNode(fontsize=8, linespacing=-4, font="Bitstream Vera Sans", + variant="roman", width=160, + text="Ich bin nur ein kleiner Blindtext. Wenn ich gross bin, will ich \ + Ulysses von James Joyce werden. Aber jetzt lohnt es sich noch nicht, \ + mich weiterzulesen. Denn vorerst bin ich nur ein kleiner Blindtext. \ + Ich bin nur ein kleiner Blindtext. Wenn ich gross bin, will ich \ + Ulysses von James Joyce werden. Aber jetzt lohnt es sich noch nicht, \ + mich weiterzulesen. Denn vorerst bin ich nur ein kleiner Blindtext. \ + Ich bin nur ein kleiner Blindtext. Wenn ich gross bin, will ich \ + Ulysses von James Joyce werden. Aber jetzt lohnt es sich noch nicht, \ + mich weiterzulesen. Denn vorerst bin ich nur ein kleiner Blindtext.", + parent=root) + self.start(True, + (setMask, + lambda: self.compareImage("testWordsMask1"), + setColor, + lambda: self.compareImage("testWordsMask2"), + setOpacity, + lambda: self.compareImage("testWordsMask3"), + setSize, + lambda: self.compareImage("testWordsMask4"), + setPos, + lambda: self.compareImage("testWordsMask5"), + setDefaultSize, + lambda: self.compareImage("testWordsMask6"), + setCentered, + lambda: self.compareImage("testWordsMask7"), + )) + + def testHinting(self): + def checkPositions(): +# node0 = root.getChild(0) +# for i in range(len(node0.text)): +# print node0.getGlyphPos(i) + noHint = root.getChild(0) + hint = root.getChild(1) + posNoHint = noHint.getGlyphPos(6) + posHint = hint.getGlyphPos(6) + self.assertNotEqual(posNoHint, posHint) + noHint.hint = True + hint.hint = False + self.assertEqual(posNoHint, hint.getGlyphPos(6)) + self.assertEqual(posHint, noHint.getGlyphPos(6)) + + if platform.system() == "Linux": + self.skip("Linux support requires modified font config") + else: + root = self.loadEmptyScene() + avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans", + variant="roman", hint=False, text="Lorem ipsum dolor (no hinting)", + parent=root) + avg.WordsNode(pos=(1,15), fontsize=12, font="Bitstream Vera Sans", + variant="roman", hint=True, text="Lorem ipsum dolor (hinting)", + parent=root) + self.start(True, [checkPositions]) + + + def testSpanWords(self): + def setTextAttrib(): + self.baselineBmp = player.screenshot() + player.getElementByID("words").text = self.text + + def checkSameImage(): + bmp = player.screenshot() + self.assert_(self.areSimilarBmps(bmp, self.baselineBmp, 0, 0)) + + def createUsingDict(): + player.getElementByID("words").unlink() + node = avg.WordsNode(id="words", pos=(1,1), fontsize=12, width=120, + font="Bitstream Vera Sans", variant="roman", text=self.text) + root.appendChild(node) + + self.text = """ + Markup: + <span size='14000' rise='5000' foreground='red'>span</span>, + <i>italics</i>, <b>bold</b> + """ + root = self.loadEmptyScene() + node = player.createNode(""" + <words id="words" x="1" y="1" fontsize="12" width="120" + font="Bitstream Vera Sans" variant="roman"> + """ + +self.text+ + """ + </words> + """) + root.appendChild(node) + self.start(True, + [lambda: self.compareImage("testSpanWords"), + setTextAttrib, + lambda: self.compareImage("testSpanWords"), + checkSameImage, + createUsingDict, + lambda: self.compareImage("testSpanWords"), + checkSameImage, + ]) + + def testDynamicWords(self): + def changeText(): + oldwidth = words.width + words.text = "blue" + self.assertNotEqual(words.width, oldwidth) + words.color = "404080" + words.x += 10 + + def changeHeight(): + words.height = 28 + + def activateText(): + words.active = True + + def deactivateText(): + words.active = False + + def changeFont(): + words.font = "Bitstream Vera Sans" + words.height = 0 + words.fontsize = 30 + + def changeFont2(): + words.fontsize = 18 + + def changeTextWithInvalidTag(): + try: + words.text = "This <invalid_tag/>bombs" + except: + words.text = "except" + self.assertEqual(words.text, "except") + + root = self.loadEmptyScene() + words = avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans", + text="foo", parent=root) + self.start(True, + (lambda: self.compareImage("testDynamicWords1"), + changeText, + changeHeight, + changeFont, + lambda: self.compareImage("testDynamicWords2"), + deactivateText, + lambda: self.compareImage("testDynamicWords3"), + activateText, + changeFont2, + lambda: self.compareImage("testDynamicWords4"), + changeTextWithInvalidTag + )) + + def testI18NWords(self): + def changeUnicodeText(): + words.text = "Arabic nonsense: ﯿﭗ" + + def setNBSP(): + words.width=100 + words.text=(u"blindtext1\u00A0blindtext2\u00Ablindtext3 "+ + u"blindtext4\u00A0blindtext\u00A0blindtext\u00A0") + + root = self.loadEmptyScene() + avg.WordsNode(pos=(1,1), fontsize=14, font="Bitstream Vera Sans", + text="一二三四五六七八九", parent=root) + words = avg.WordsNode(pos=(1,24), fontsize=12, font="Bitstream Vera Sans", + text="foo", parent=root) + root.appendChild( + player.createNode(""" + <words x="1" y="48" fontsize="12" font="Bitstream Vera Sans"> + & + </words> + """)) + avg.WordsNode(pos=(12,48), fontsize=12, font="Bitstream Vera Sans", text="&", + rawtextmode=True, parent=root) + + self.start(True, + (lambda: self.compareImage("testI18NWords1"), + changeUnicodeText, + lambda: self.compareImage("testI18NWords2"), + setNBSP, + lambda: self.compareImage("testI18NWords3"), + )) + + def testRawText(self): + def createDynNodes(): + self.dictdnode = avg.WordsNode(text='<test dyndict&', + rawtextmode=True, pos=(1,65), font='Bitstream Vera Sans', + variant='roman', fontsize=12) + root.appendChild(self.dictdnode) + + self.xmldnode = player.createNode(""" + <words text="<test dynattr&" fontsize="12" + font="Bitstream Vera Sans" variant="roman" rawtextmode="true" + x="1" y="85"/>""") + root.appendChild(self.xmldnode) + + def switchRawMode(): + self.dictdnode.rawtextmode = False + valNode.rawtextmode = True + attribNode.rawtextmode = True + + def bombIt(): + def cantRun(): + self.xmldnode.rawtextmode = False + self.assert_(0) + self.assertException(cantRun) + + def assignNewTexts(): + text = u'&ùùààxx>' + self.dictdnode.rawtextmode = True + self.dictdnode.text = text + self.xmldnode.text = text + valNode.text = text + attribNode.text = text + + root = self.loadEmptyScene() + attribNode = avg.WordsNode(text="ùnicòdé <b>bold</b>", + fontsize=12, pos=(1,5), font="Bitstream Vera Sans", parent=root) + valNode = player.createNode(""" + <words id="nodeval" fontsize="10" x="1" y="25" font="Bitstream Vera Sans"><b>bold</b> ùnicòdé <</words>""") + root.appendChild(valNode) + root.appendChild( + player.createNode(""" + <words x="1" y="45" fontsize="15" font="Bitstream Vera Sans"> + & + </words>""")) + + self.start(True, + (lambda: self.compareImage("testRawText1"), + createDynNodes, + lambda: self.compareImage("testRawText2"), + switchRawMode, + lambda: self.compareImage("testRawText3"), + bombIt, + assignNewTexts, + lambda: self.compareImage("testRawText4"), + )) + + def testWordsBR(self): + root = self.loadEmptyScene() + avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans", variant="roman", + text="paragraph 1<br/>paragraph 2", parent=root) + self.start(True, + [lambda: self.compareImage("testWordsBR")]) + + def testLetterSpacing(self): + def setSpacing(): + player.getElementByID("words1").letterspacing=-2 + player.getElementByID("words2").letterspacing=-2 + + root = self.loadEmptyScene() + avg.WordsNode(id="words1", pos=(1,1), fontsize=12, font="Bitstream Vera Sans", + variant="roman", + text="""normal + <span letter_spacing="-2048"> packed</span> + <span letter_spacing="2048"> spaced</span>""", + parent=root) + avg.WordsNode(id="words2", pos=(1,20), fontsize=12, font="Bitstream Vera Sans", + variant="roman", letterspacing=2, text="spaced", parent=root) + self.start(True, + (lambda: self.compareImage("testLetterSpacing1"), + setSpacing, + lambda: self.compareImage("testLetterSpacing2") + )) + + def testPositioning(self): + def click(pos): + self.fakeClick(int(pos[0]), int(pos[1])) + + def testInside(bInside): + ok = bInside == self.clicked + self.clicked = False + return ok + + def onMouse(event): + self.clicked = True + + root = self.loadEmptyScene() + avg.LineNode(pos1=(4, 20.5), pos2=(157, 20.5), color="FF0000", parent=root) + avg.LineNode(pos1=(4.5, 20.5), pos2=(4.5, 110), color="FF0000", parent=root) + avg.LineNode(pos1=(156.5, 20.5), pos2=(156.5, 110), color="FF0000", parent=root) + avg.LineNode(pos1=(80.5, 20.5), pos2=(80.5, 110), color="FF0000", parent=root) + avg.WordsNode(id="left", pos=(4,20), fontsize=12, font="Bitstream Vera Sans", + variant="roman", text="Norm", parent=root) + avg.WordsNode(pos=(45,20), fontsize=12, font="Bitstream Vera Sans", + variant="roman", text="orm", parent=root) + avg.WordsNode(pos=(75,20), fontsize=12, font="Bitstream Vera Sans", + variant="roman", text="ÖÄÜ", parent=root) + avg.WordsNode(pos=(4,40), fontsize=12, font="Bitstream Vera Sans", + variant="oblique", text="Jtalic", parent=root) + avg.WordsNode(id="right", pos=(156,60), fontsize=12, alignment="right", + font="Bitstream Vera Sans", variant="roman", text="Right-aligned", + parent=root) + avg.WordsNode(id="center", pos=(80,80), fontsize=12, alignment="center", + font="Bitstream Vera Sans", variant="roman", text="Centered", + parent=root) + for id in ["left", "center", "right"]: + player.getElementByID(id).subscribe(avg.Node.CURSOR_DOWN, onMouse) + self.clicked = False + leftWidth = player.getElementByID("left").getMediaSize()[0] + centerWidth = player.getElementByID("center").getMediaSize()[0] + rightWidth = player.getElementByID("right").getMediaSize()[0] + + self.start(True, + (lambda: self.compareImage("testPositioning"), + lambda: click((4,20)), + lambda: self.assert_(testInside(True)), + lambda: click((3,20)), + lambda: self.assert_(testInside(False)), + lambda: click((3+leftWidth,20)), + lambda: self.assert_(testInside(True)), + lambda: click((4+leftWidth,20)), + lambda: self.assert_(testInside(False)), + + lambda: click((81-centerWidth/2,80)), + lambda: self.assert_(testInside(True)), + lambda: click((80-centerWidth/2,80)), + lambda: self.assert_(testInside(False)), + lambda: click((80+centerWidth/2,80)), + lambda: self.assert_(testInside(True)), + lambda: click((81+centerWidth/2,80)), + lambda: self.assert_(testInside(False)), + + lambda: click((156-rightWidth,60)), + lambda: self.assert_(testInside(True)), + lambda: click((155-rightWidth,60)), + lambda: self.assert_(testInside(False)), + lambda: click((155,60)), + lambda: self.assert_(testInside(True)), + lambda: click((156,60)), + lambda: self.assert_(testInside(False)), + )) + + def testInvalidColor(self): + def testColor(col): + avg.WordsNode(color=col) + + def assignValidColor(): + testColor('123456') + + def assignInvalidColor1(): + testColor('1234567') + + def assignInvalidColor2(): + testColor('xxx') + + def assignInvalidColor3(): + testColor('xxxxxx') + + self.loadEmptyScene() + self.start(True, + (self.assertException(assignInvalidColor1), + self.assertException(assignInvalidColor2), + self.assertException(assignInvalidColor3), + )) + + def testFontDir(self): + avg.WordsNode.addFontDir('extrafonts') + root = self.loadEmptyScene() + avg.WordsNode(font="testaddfontdir", fontsize=50, text="ABAAA", parent=root) + self.start(True, + (lambda: self.compareImage("testFontDir"),)) + + def testGetNumLines(self): + textNode = avg.WordsNode(text="paragraph 1<br/>paragraph 2<br/>paragraph 3") + self.assertEqual(textNode.getNumLines(), 3) + textNode.text = "" + self.assertEqual(textNode.getNumLines(), 0) + + def testGetLineExtents(self): + textNode = avg.WordsNode(fontsize = 100, + font = "Bitstream Vera Sans", + text = "bla <br/> blabli <br/> blabliblabla") + self.assertEqual(textNode.getLineExtents(0), (184,117)) + self.assertEqual(textNode.getLineExtents(1), (303,117)) + + def testGetCharIndexFromPos(self): + textNode = avg.WordsNode(fontsize=30, + font = "Bitstream Vera Sans", + text = "A B C D E F G H Ä Ö Ü ? Ì Á Í Å Ø ∏ ~ ç Ç Å", + width = 300) + + for k in (1,2,3,23,42): + pos = textNode.getGlyphPos(k) + char = textNode.getCharIndexFromPos(pos) + self.assertEqual(char, k) + + def testGetTextAsDisplayed(self): + orgText = "A<br/>B C <b>D</b> E F G H <i>Ä</i> Ö Ü ? Ì Á<br/>Í Å Ø ∏ ~ ç Ç Å" + orgTextWithout = "A\nB C D E F G H Ä Ö Ü ? Ì Á\nÍ Å Ø ∏ ~ ç Ç Å" + textNode = avg.WordsNode(fontsize=30, + font = "Bitstream Vera Sans", + text = orgText, + width = 300) + self.assertEqual(orgTextWithout, textNode.getTextAsDisplayed()) + + def testSetWidth(self): + root = self.loadEmptyScene() + text = "42 " * 42 + textNode = avg.WordsNode( + parent=root, + fontsize = 10, + font = "Bitstream Vera Sans", + text = text) + + def testSize(p1, p2): + self.assert_(abs(p1.x - p2.x) < 5) + self.assert_(abs(p1.y - p2.y) < 50) + + testSize(textNode.size, avg.Point2D(630,13)) + testSize(textNode.getMediaSize(), avg.Point2D(630,13)) + mediaSize = textNode.getMediaSize() + + def changeSize(): + textNode.width = 50 + testSize(textNode.size, avg.Point2D(50,182)) + testSize(textNode.getMediaSize(), avg.Point2D(45,182)) + self.assertNotEqual(mediaSize, textNode.getMediaSize()) + + self.start(True, + [lambda: changeSize()]) + + def testTooWide(self): + root = self.loadEmptyScene() + text = "42 " * 42 * 20 + avg.WordsNode(parent=root, text=text) + self.assertException( + lambda: self.start((None, None)) + ) + + def testWordsGamma(self): + + def setGamma(): + node.aagamma = 4 + + root = self.loadEmptyScene() + for i, gamma in enumerate((2, 1.5, 1)): + node = avg.WordsNode(pos=(1,i*20), fontsize=12, font="Bitstream Vera Sans", + variant="roman", aagamma=gamma, text="lorem ipsum dolor", + parent=root) + self.start(True, + (lambda: self.compareImage("testWordsGamma1"), + setGamma, + lambda: self.compareImage("testWordsGamma2"), + )) + + +def wordsTestSuite(tests): + availableTests = ( + "testSimpleWords", + "testRedrawOnDemand", + "testFontStyle", + "testBaseStyle", + "testGlyphPos", + "testParaWords", + "testJustify", + "testWrapMode", + "testWordsMask", + "testHinting", + "testSpanWords", + "testDynamicWords", + "testI18NWords", + "testRawText", + "testWordsBR", + "testLetterSpacing", + "testPositioning", + "testInvalidColor", + "testFontDir", + "testGetNumLines", + "testGetLineExtents", + "testGetCharIndexFromPos", + "testGetTextAsDisplayed", + "testSetWidth", + "testTooWide", + "testWordsGamma", + ) + return createAVGTestSuite(availableTests, WordsTestCase, tests) diff --git a/src/test/baseline/test2VideosAtOnce1.png b/src/test/baseline/test2VideosAtOnce1.png Binary files differnew file mode 100644 index 0000000..f561888 --- /dev/null +++ b/src/test/baseline/test2VideosAtOnce1.png diff --git a/src/test/baseline/testAVGFile.png b/src/test/baseline/testAVGFile.png Binary files differnew file mode 100644 index 0000000..375582b --- /dev/null +++ b/src/test/baseline/testAVGFile.png diff --git a/src/test/baseline/testAnim1.png b/src/test/baseline/testAnim1.png Binary files differnew file mode 100644 index 0000000..6651fc3 --- /dev/null +++ b/src/test/baseline/testAnim1.png diff --git a/src/test/baseline/testAnim2.png b/src/test/baseline/testAnim2.png Binary files differnew file mode 100644 index 0000000..d8553de --- /dev/null +++ b/src/test/baseline/testAnim2.png diff --git a/src/test/baseline/testAnim3.png b/src/test/baseline/testAnim3.png Binary files differnew file mode 100644 index 0000000..4d6dbd7 --- /dev/null +++ b/src/test/baseline/testAnim3.png diff --git a/src/test/baseline/testArc1.png b/src/test/baseline/testArc1.png Binary files differnew file mode 100644 index 0000000..9c4a2f0 --- /dev/null +++ b/src/test/baseline/testArc1.png diff --git a/src/test/baseline/testArc2.png b/src/test/baseline/testArc2.png Binary files differnew file mode 100644 index 0000000..1e321a3 --- /dev/null +++ b/src/test/baseline/testArc2.png diff --git a/src/test/baseline/testBitmap1.png b/src/test/baseline/testBitmap1.png Binary files differnew file mode 100644 index 0000000..c5b06a0 --- /dev/null +++ b/src/test/baseline/testBitmap1.png diff --git a/src/test/baseline/testBitmap2.png b/src/test/baseline/testBitmap2.png Binary files differnew file mode 100644 index 0000000..f94b54e --- /dev/null +++ b/src/test/baseline/testBitmap2.png diff --git a/src/test/baseline/testBitmap3.png b/src/test/baseline/testBitmap3.png Binary files differnew file mode 100644 index 0000000..7d0898d --- /dev/null +++ b/src/test/baseline/testBitmap3.png diff --git a/src/test/baseline/testBitmap4.png b/src/test/baseline/testBitmap4.png Binary files differnew file mode 100644 index 0000000..5569133 --- /dev/null +++ b/src/test/baseline/testBitmap4.png diff --git a/src/test/baseline/testBlend1.png b/src/test/baseline/testBlend1.png Binary files differnew file mode 100644 index 0000000..29e4a11 --- /dev/null +++ b/src/test/baseline/testBlend1.png diff --git a/src/test/baseline/testBlend2.png b/src/test/baseline/testBlend2.png Binary files differnew file mode 100644 index 0000000..8b2ae59 --- /dev/null +++ b/src/test/baseline/testBlend2.png diff --git a/src/test/baseline/testBlurFX1.png b/src/test/baseline/testBlurFX1.png Binary files differnew file mode 100644 index 0000000..9564d6f --- /dev/null +++ b/src/test/baseline/testBlurFX1.png diff --git a/src/test/baseline/testBlurFX2.png b/src/test/baseline/testBlurFX2.png Binary files differnew file mode 100644 index 0000000..0147846 --- /dev/null +++ b/src/test/baseline/testBlurFX2.png diff --git a/src/test/baseline/testBlurFX3.png b/src/test/baseline/testBlurFX3.png Binary files differnew file mode 100644 index 0000000..b50decf --- /dev/null +++ b/src/test/baseline/testBlurFX3.png diff --git a/src/test/baseline/testButtonDisabled.png b/src/test/baseline/testButtonDisabled.png Binary files differnew file mode 100644 index 0000000..6b7eea4 --- /dev/null +++ b/src/test/baseline/testButtonDisabled.png diff --git a/src/test/baseline/testButtonDown.png b/src/test/baseline/testButtonDown.png Binary files differnew file mode 100644 index 0000000..96e6e40 --- /dev/null +++ b/src/test/baseline/testButtonDown.png diff --git a/src/test/baseline/testButtonOver.png b/src/test/baseline/testButtonOver.png Binary files differnew file mode 100644 index 0000000..f3d5a0e --- /dev/null +++ b/src/test/baseline/testButtonOver.png diff --git a/src/test/baseline/testButtonUp.png b/src/test/baseline/testButtonUp.png Binary files differnew file mode 100644 index 0000000..a9adeb5 --- /dev/null +++ b/src/test/baseline/testButtonUp.png diff --git a/src/test/baseline/testCanvasAlpha.png b/src/test/baseline/testCanvasAlpha.png Binary files differnew file mode 100644 index 0000000..63fb052 --- /dev/null +++ b/src/test/baseline/testCanvasAlpha.png diff --git a/src/test/baseline/testCanvasBlendModes.png b/src/test/baseline/testCanvasBlendModes.png Binary files differnew file mode 100644 index 0000000..f0feba3 --- /dev/null +++ b/src/test/baseline/testCanvasBlendModes.png diff --git a/src/test/baseline/testCanvasCrop.png b/src/test/baseline/testCanvasCrop.png Binary files differnew file mode 100644 index 0000000..ffcdcfa --- /dev/null +++ b/src/test/baseline/testCanvasCrop.png diff --git a/src/test/baseline/testCanvasDependencies1.png b/src/test/baseline/testCanvasDependencies1.png Binary files differnew file mode 100644 index 0000000..5821855 --- /dev/null +++ b/src/test/baseline/testCanvasDependencies1.png diff --git a/src/test/baseline/testCanvasDependencies2.png b/src/test/baseline/testCanvasDependencies2.png Binary files differnew file mode 100644 index 0000000..d38ac6a --- /dev/null +++ b/src/test/baseline/testCanvasDependencies2.png diff --git a/src/test/baseline/testCanvasMipmap.png b/src/test/baseline/testCanvasMipmap.png Binary files differnew file mode 100644 index 0000000..ecc51f0 --- /dev/null +++ b/src/test/baseline/testCanvasMipmap.png diff --git a/src/test/baseline/testCanvasMultisample.png b/src/test/baseline/testCanvasMultisample.png Binary files differnew file mode 100644 index 0000000..1f30aad --- /dev/null +++ b/src/test/baseline/testCanvasMultisample.png diff --git a/src/test/baseline/testCanvasNullFX1.png b/src/test/baseline/testCanvasNullFX1.png Binary files differnew file mode 100644 index 0000000..c877bdf --- /dev/null +++ b/src/test/baseline/testCanvasNullFX1.png diff --git a/src/test/baseline/testCanvasNullFX2.png b/src/test/baseline/testCanvasNullFX2.png Binary files differnew file mode 100644 index 0000000..8e485f7 --- /dev/null +++ b/src/test/baseline/testCanvasNullFX2.png diff --git a/src/test/baseline/testCanvasNullFX3.png b/src/test/baseline/testCanvasNullFX3.png Binary files differnew file mode 100644 index 0000000..56571a2 --- /dev/null +++ b/src/test/baseline/testCanvasNullFX3.png diff --git a/src/test/baseline/testCanvasResize.png b/src/test/baseline/testCanvasResize.png Binary files differnew file mode 100644 index 0000000..5821855 --- /dev/null +++ b/src/test/baseline/testCanvasResize.png diff --git a/src/test/baseline/testCheckboxClickedDown.png b/src/test/baseline/testCheckboxClickedDown.png Binary files differnew file mode 100644 index 0000000..2065be3 --- /dev/null +++ b/src/test/baseline/testCheckboxClickedDown.png diff --git a/src/test/baseline/testCheckboxClickedOut.png b/src/test/baseline/testCheckboxClickedOut.png Binary files differnew file mode 100644 index 0000000..a17d5b2 --- /dev/null +++ b/src/test/baseline/testCheckboxClickedOut.png diff --git a/src/test/baseline/testCheckboxClickedOver.png b/src/test/baseline/testCheckboxClickedOver.png Binary files differnew file mode 100644 index 0000000..b94c9d9 --- /dev/null +++ b/src/test/baseline/testCheckboxClickedOver.png diff --git a/src/test/baseline/testCheckboxDown.png b/src/test/baseline/testCheckboxDown.png Binary files differnew file mode 100644 index 0000000..96e6e40 --- /dev/null +++ b/src/test/baseline/testCheckboxDown.png diff --git a/src/test/baseline/testCheckboxOver.png b/src/test/baseline/testCheckboxOver.png Binary files differnew file mode 100644 index 0000000..f3d5a0e --- /dev/null +++ b/src/test/baseline/testCheckboxOver.png diff --git a/src/test/baseline/testCheckboxUp.png b/src/test/baseline/testCheckboxUp.png Binary files differnew file mode 100644 index 0000000..a9adeb5 --- /dev/null +++ b/src/test/baseline/testCheckboxUp.png diff --git a/src/test/baseline/testChromaKeyFX1.png b/src/test/baseline/testChromaKeyFX1.png Binary files differnew file mode 100644 index 0000000..9f63ce5 --- /dev/null +++ b/src/test/baseline/testChromaKeyFX1.png diff --git a/src/test/baseline/testChromaKeyFX2.png b/src/test/baseline/testChromaKeyFX2.png Binary files differnew file mode 100644 index 0000000..65df5ea --- /dev/null +++ b/src/test/baseline/testChromaKeyFX2.png diff --git a/src/test/baseline/testChromaKeyFX3.png b/src/test/baseline/testChromaKeyFX3.png Binary files differnew file mode 100644 index 0000000..1ab1b59 --- /dev/null +++ b/src/test/baseline/testChromaKeyFX3.png diff --git a/src/test/baseline/testChromaKeyFX4.png b/src/test/baseline/testChromaKeyFX4.png Binary files differnew file mode 100644 index 0000000..86efc70 --- /dev/null +++ b/src/test/baseline/testChromaKeyFX4.png diff --git a/src/test/baseline/testCircle1.png b/src/test/baseline/testCircle1.png Binary files differnew file mode 100644 index 0000000..45f2c58 --- /dev/null +++ b/src/test/baseline/testCircle1.png diff --git a/src/test/baseline/testCircle2.png b/src/test/baseline/testCircle2.png Binary files differnew file mode 100644 index 0000000..26ca01c --- /dev/null +++ b/src/test/baseline/testCircle2.png diff --git a/src/test/baseline/testCircle3.png b/src/test/baseline/testCircle3.png Binary files differnew file mode 100644 index 0000000..4824bcf --- /dev/null +++ b/src/test/baseline/testCircle3.png diff --git a/src/test/baseline/testCircle4.png b/src/test/baseline/testCircle4.png Binary files differnew file mode 100644 index 0000000..be36e58 --- /dev/null +++ b/src/test/baseline/testCircle4.png diff --git a/src/test/baseline/testCircle5.png b/src/test/baseline/testCircle5.png Binary files differnew file mode 100644 index 0000000..f70b3eb --- /dev/null +++ b/src/test/baseline/testCircle5.png diff --git a/src/test/baseline/testColorFX1.png b/src/test/baseline/testColorFX1.png Binary files differnew file mode 100644 index 0000000..1a225e9 --- /dev/null +++ b/src/test/baseline/testColorFX1.png diff --git a/src/test/baseline/testColorFX2.png b/src/test/baseline/testColorFX2.png Binary files differnew file mode 100644 index 0000000..dc708c6 --- /dev/null +++ b/src/test/baseline/testColorFX2.png diff --git a/src/test/baseline/testColorFX3.png b/src/test/baseline/testColorFX3.png Binary files differnew file mode 100644 index 0000000..b82c72d --- /dev/null +++ b/src/test/baseline/testColorFX3.png diff --git a/src/test/baseline/testColorFX4.png b/src/test/baseline/testColorFX4.png Binary files differnew file mode 100644 index 0000000..5722a24 --- /dev/null +++ b/src/test/baseline/testColorFX4.png diff --git a/src/test/baseline/testColorFX5.png b/src/test/baseline/testColorFX5.png Binary files differnew file mode 100644 index 0000000..dbcec1c --- /dev/null +++ b/src/test/baseline/testColorFX5.png diff --git a/src/test/baseline/testColorFX6.png b/src/test/baseline/testColorFX6.png Binary files differnew file mode 100644 index 0000000..ab46da3 --- /dev/null +++ b/src/test/baseline/testColorFX6.png diff --git a/src/test/baseline/testColorFX7.png b/src/test/baseline/testColorFX7.png Binary files differnew file mode 100644 index 0000000..5fb43b8 --- /dev/null +++ b/src/test/baseline/testColorFX7.png diff --git a/src/test/baseline/testComplexDiv1.png b/src/test/baseline/testComplexDiv1.png Binary files differnew file mode 100644 index 0000000..bde774d --- /dev/null +++ b/src/test/baseline/testComplexDiv1.png diff --git a/src/test/baseline/testContAnim1.png b/src/test/baseline/testContAnim1.png Binary files differnew file mode 100644 index 0000000..f337d2f --- /dev/null +++ b/src/test/baseline/testContAnim1.png diff --git a/src/test/baseline/testContAnim2.png b/src/test/baseline/testContAnim2.png Binary files differnew file mode 100644 index 0000000..1e2b4fd --- /dev/null +++ b/src/test/baseline/testContAnim2.png diff --git a/src/test/baseline/testContAnim3.png b/src/test/baseline/testContAnim3.png Binary files differnew file mode 100644 index 0000000..cdf6b45 --- /dev/null +++ b/src/test/baseline/testContAnim3.png diff --git a/src/test/baseline/testContAnim4.png b/src/test/baseline/testContAnim4.png Binary files differnew file mode 100644 index 0000000..3a16eeb --- /dev/null +++ b/src/test/baseline/testContAnim4.png diff --git a/src/test/baseline/testContinuousAnim1.png b/src/test/baseline/testContinuousAnim1.png Binary files differnew file mode 100644 index 0000000..4f8a5be --- /dev/null +++ b/src/test/baseline/testContinuousAnim1.png diff --git a/src/test/baseline/testContinuousAnim2.png b/src/test/baseline/testContinuousAnim2.png Binary files differnew file mode 100644 index 0000000..34a9e24 --- /dev/null +++ b/src/test/baseline/testContinuousAnim2.png diff --git a/src/test/baseline/testContrast1.png b/src/test/baseline/testContrast1.png Binary files differnew file mode 100644 index 0000000..06bf3d0 --- /dev/null +++ b/src/test/baseline/testContrast1.png diff --git a/src/test/baseline/testContrast2.png b/src/test/baseline/testContrast2.png Binary files differnew file mode 100644 index 0000000..fc1e0e6 --- /dev/null +++ b/src/test/baseline/testContrast2.png diff --git a/src/test/baseline/testContrast3.png b/src/test/baseline/testContrast3.png Binary files differnew file mode 100644 index 0000000..e979473 --- /dev/null +++ b/src/test/baseline/testContrast3.png diff --git a/src/test/baseline/testCropImage1.png b/src/test/baseline/testCropImage1.png Binary files differnew file mode 100644 index 0000000..40bdcfe --- /dev/null +++ b/src/test/baseline/testCropImage1.png diff --git a/src/test/baseline/testCropImage10.png b/src/test/baseline/testCropImage10.png Binary files differnew file mode 100644 index 0000000..f05723a --- /dev/null +++ b/src/test/baseline/testCropImage10.png diff --git a/src/test/baseline/testCropImage2.png b/src/test/baseline/testCropImage2.png Binary files differnew file mode 100644 index 0000000..e0706ea --- /dev/null +++ b/src/test/baseline/testCropImage2.png diff --git a/src/test/baseline/testCropImage3.png b/src/test/baseline/testCropImage3.png Binary files differnew file mode 100644 index 0000000..33078f2 --- /dev/null +++ b/src/test/baseline/testCropImage3.png diff --git a/src/test/baseline/testCropImage4.png b/src/test/baseline/testCropImage4.png Binary files differnew file mode 100644 index 0000000..e230b9a --- /dev/null +++ b/src/test/baseline/testCropImage4.png diff --git a/src/test/baseline/testCropImage5.png b/src/test/baseline/testCropImage5.png Binary files differnew file mode 100644 index 0000000..0636df4 --- /dev/null +++ b/src/test/baseline/testCropImage5.png diff --git a/src/test/baseline/testCropImage6.png b/src/test/baseline/testCropImage6.png Binary files differnew file mode 100644 index 0000000..566f599 --- /dev/null +++ b/src/test/baseline/testCropImage6.png diff --git a/src/test/baseline/testCropImage7.png b/src/test/baseline/testCropImage7.png Binary files differnew file mode 100644 index 0000000..632a158 --- /dev/null +++ b/src/test/baseline/testCropImage7.png diff --git a/src/test/baseline/testCropImage8.png b/src/test/baseline/testCropImage8.png Binary files differnew file mode 100644 index 0000000..017faca --- /dev/null +++ b/src/test/baseline/testCropImage8.png diff --git a/src/test/baseline/testCropImage9.png b/src/test/baseline/testCropImage9.png Binary files differnew file mode 100644 index 0000000..2f013fc --- /dev/null +++ b/src/test/baseline/testCropImage9.png diff --git a/src/test/baseline/testCropMovie1.png b/src/test/baseline/testCropMovie1.png Binary files differnew file mode 100644 index 0000000..aaff2c3 --- /dev/null +++ b/src/test/baseline/testCropMovie1.png diff --git a/src/test/baseline/testCropMovie10.png b/src/test/baseline/testCropMovie10.png Binary files differnew file mode 100644 index 0000000..1ef3ca3 --- /dev/null +++ b/src/test/baseline/testCropMovie10.png diff --git a/src/test/baseline/testCropMovie2.png b/src/test/baseline/testCropMovie2.png Binary files differnew file mode 100644 index 0000000..1345610 --- /dev/null +++ b/src/test/baseline/testCropMovie2.png diff --git a/src/test/baseline/testCropMovie3.png b/src/test/baseline/testCropMovie3.png Binary files differnew file mode 100644 index 0000000..a2aef90 --- /dev/null +++ b/src/test/baseline/testCropMovie3.png diff --git a/src/test/baseline/testCropMovie4.png b/src/test/baseline/testCropMovie4.png Binary files differnew file mode 100644 index 0000000..72a5ae2 --- /dev/null +++ b/src/test/baseline/testCropMovie4.png diff --git a/src/test/baseline/testCropMovie5.png b/src/test/baseline/testCropMovie5.png Binary files differnew file mode 100644 index 0000000..8e663fc --- /dev/null +++ b/src/test/baseline/testCropMovie5.png diff --git a/src/test/baseline/testCropMovie6.png b/src/test/baseline/testCropMovie6.png Binary files differnew file mode 100644 index 0000000..ff47430 --- /dev/null +++ b/src/test/baseline/testCropMovie6.png diff --git a/src/test/baseline/testCropMovie7.png b/src/test/baseline/testCropMovie7.png Binary files differnew file mode 100644 index 0000000..60941e4 --- /dev/null +++ b/src/test/baseline/testCropMovie7.png diff --git a/src/test/baseline/testCropMovie8.png b/src/test/baseline/testCropMovie8.png Binary files differnew file mode 100644 index 0000000..e12b702 --- /dev/null +++ b/src/test/baseline/testCropMovie8.png diff --git a/src/test/baseline/testCropMovie9.png b/src/test/baseline/testCropMovie9.png Binary files differnew file mode 100644 index 0000000..f0ede3e --- /dev/null +++ b/src/test/baseline/testCropMovie9.png diff --git a/src/test/baseline/testCurve1.png b/src/test/baseline/testCurve1.png Binary files differnew file mode 100644 index 0000000..70127bc --- /dev/null +++ b/src/test/baseline/testCurve1.png diff --git a/src/test/baseline/testCurve2.png b/src/test/baseline/testCurve2.png Binary files differnew file mode 100644 index 0000000..6046c98 --- /dev/null +++ b/src/test/baseline/testCurve2.png diff --git a/src/test/baseline/testCurve3.png b/src/test/baseline/testCurve3.png Binary files differnew file mode 100644 index 0000000..9545904 --- /dev/null +++ b/src/test/baseline/testCurve3.png diff --git a/src/test/baseline/testCurve4.png b/src/test/baseline/testCurve4.png Binary files differnew file mode 100644 index 0000000..1472c2f --- /dev/null +++ b/src/test/baseline/testCurve4.png diff --git a/src/test/baseline/testDivDynamics1.png b/src/test/baseline/testDivDynamics1.png Binary files differnew file mode 100644 index 0000000..d05741d --- /dev/null +++ b/src/test/baseline/testDivDynamics1.png diff --git a/src/test/baseline/testDivDynamics2.png b/src/test/baseline/testDivDynamics2.png Binary files differnew file mode 100644 index 0000000..b3f308f --- /dev/null +++ b/src/test/baseline/testDivDynamics2.png diff --git a/src/test/baseline/testDivDynamics3.png b/src/test/baseline/testDivDynamics3.png Binary files differnew file mode 100644 index 0000000..72a9acf --- /dev/null +++ b/src/test/baseline/testDivDynamics3.png diff --git a/src/test/baseline/testDivDynamics4.png b/src/test/baseline/testDivDynamics4.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testDivDynamics4.png diff --git a/src/test/baseline/testDivDynamics5.png b/src/test/baseline/testDivDynamics5.png Binary files differnew file mode 100644 index 0000000..d05741d --- /dev/null +++ b/src/test/baseline/testDivDynamics5.png diff --git a/src/test/baseline/testDraggable1.png b/src/test/baseline/testDraggable1.png Binary files differnew file mode 100644 index 0000000..d60276f --- /dev/null +++ b/src/test/baseline/testDraggable1.png diff --git a/src/test/baseline/testDraggable2.png b/src/test/baseline/testDraggable2.png Binary files differnew file mode 100644 index 0000000..19ad729 --- /dev/null +++ b/src/test/baseline/testDraggable2.png diff --git a/src/test/baseline/testDynamicMediaDir1.png b/src/test/baseline/testDynamicMediaDir1.png Binary files differnew file mode 100644 index 0000000..71c0100 --- /dev/null +++ b/src/test/baseline/testDynamicMediaDir1.png diff --git a/src/test/baseline/testDynamicMediaDir2.png b/src/test/baseline/testDynamicMediaDir2.png Binary files differnew file mode 100644 index 0000000..392e2a8 --- /dev/null +++ b/src/test/baseline/testDynamicMediaDir2.png diff --git a/src/test/baseline/testDynamicWords1.png b/src/test/baseline/testDynamicWords1.png Binary files differnew file mode 100644 index 0000000..9b37b72 --- /dev/null +++ b/src/test/baseline/testDynamicWords1.png diff --git a/src/test/baseline/testDynamicWords2.png b/src/test/baseline/testDynamicWords2.png Binary files differnew file mode 100644 index 0000000..390d0f3 --- /dev/null +++ b/src/test/baseline/testDynamicWords2.png diff --git a/src/test/baseline/testDynamicWords3.png b/src/test/baseline/testDynamicWords3.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testDynamicWords3.png diff --git a/src/test/baseline/testDynamicWords4.png b/src/test/baseline/testDynamicWords4.png Binary files differnew file mode 100644 index 0000000..789c2c8 --- /dev/null +++ b/src/test/baseline/testDynamicWords4.png diff --git a/src/test/baseline/testEaseInOutAnim1.png b/src/test/baseline/testEaseInOutAnim1.png Binary files differnew file mode 100644 index 0000000..82abf89 --- /dev/null +++ b/src/test/baseline/testEaseInOutAnim1.png diff --git a/src/test/baseline/testEaseInOutAnim2.png b/src/test/baseline/testEaseInOutAnim2.png Binary files differnew file mode 100644 index 0000000..e299221 --- /dev/null +++ b/src/test/baseline/testEaseInOutAnim2.png diff --git a/src/test/baseline/testEaseInOutAnim3.png b/src/test/baseline/testEaseInOutAnim3.png Binary files differnew file mode 100644 index 0000000..03311b5 --- /dev/null +++ b/src/test/baseline/testEaseInOutAnim3.png diff --git a/src/test/baseline/testEaseInOutAnimC1.png b/src/test/baseline/testEaseInOutAnimC1.png Binary files differnew file mode 100644 index 0000000..fbe5b29 --- /dev/null +++ b/src/test/baseline/testEaseInOutAnimC1.png diff --git a/src/test/baseline/testEaseInOutAnimC2.png b/src/test/baseline/testEaseInOutAnimC2.png Binary files differnew file mode 100644 index 0000000..1e889df --- /dev/null +++ b/src/test/baseline/testEaseInOutAnimC2.png diff --git a/src/test/baseline/testEaseInOutAnimC3.png b/src/test/baseline/testEaseInOutAnimC3.png Binary files differnew file mode 100644 index 0000000..40d820a --- /dev/null +++ b/src/test/baseline/testEaseInOutAnimC3.png diff --git a/src/test/baseline/testEaseInOutAnimC4.png b/src/test/baseline/testEaseInOutAnimC4.png Binary files differnew file mode 100644 index 0000000..9703e09 --- /dev/null +++ b/src/test/baseline/testEaseInOutAnimC4.png diff --git a/src/test/baseline/testEaseInOutAnimC5.png b/src/test/baseline/testEaseInOutAnimC5.png Binary files differnew file mode 100644 index 0000000..40d820a --- /dev/null +++ b/src/test/baseline/testEaseInOutAnimC5.png diff --git a/src/test/baseline/testEaseInOutAnimC6.png b/src/test/baseline/testEaseInOutAnimC6.png Binary files differnew file mode 100644 index 0000000..60da2b1 --- /dev/null +++ b/src/test/baseline/testEaseInOutAnimC6.png diff --git a/src/test/baseline/testEvents.png b/src/test/baseline/testEvents.png Binary files differnew file mode 100644 index 0000000..bdd9280 --- /dev/null +++ b/src/test/baseline/testEvents.png diff --git a/src/test/baseline/testFXUpdateFX.png b/src/test/baseline/testFXUpdateFX.png Binary files differnew file mode 100644 index 0000000..a2d1a44 --- /dev/null +++ b/src/test/baseline/testFXUpdateFX.png diff --git a/src/test/baseline/testFXUpdateMaskPos.png b/src/test/baseline/testFXUpdateMaskPos.png Binary files differnew file mode 100644 index 0000000..150ebd2 --- /dev/null +++ b/src/test/baseline/testFXUpdateMaskPos.png diff --git a/src/test/baseline/testFXUpdateMaskTex1.png b/src/test/baseline/testFXUpdateMaskTex1.png Binary files differnew file mode 100644 index 0000000..18588ff --- /dev/null +++ b/src/test/baseline/testFXUpdateMaskTex1.png diff --git a/src/test/baseline/testFXUpdateMaskTex2.png b/src/test/baseline/testFXUpdateMaskTex2.png Binary files differnew file mode 100644 index 0000000..4790154 --- /dev/null +++ b/src/test/baseline/testFXUpdateMaskTex2.png diff --git a/src/test/baseline/testFXUpdateTex.png b/src/test/baseline/testFXUpdateTex.png Binary files differnew file mode 100644 index 0000000..3111780 --- /dev/null +++ b/src/test/baseline/testFXUpdateTex.png diff --git a/src/test/baseline/testFXUpdateVideo.png b/src/test/baseline/testFXUpdateVideo.png Binary files differnew file mode 100644 index 0000000..fed9567 --- /dev/null +++ b/src/test/baseline/testFXUpdateVideo.png diff --git a/src/test/baseline/testFadeIn1.png b/src/test/baseline/testFadeIn1.png Binary files differnew file mode 100644 index 0000000..e4a332a --- /dev/null +++ b/src/test/baseline/testFadeIn1.png diff --git a/src/test/baseline/testFadeIn2.png b/src/test/baseline/testFadeIn2.png Binary files differnew file mode 100644 index 0000000..b1c6746 --- /dev/null +++ b/src/test/baseline/testFadeIn2.png diff --git a/src/test/baseline/testFadeIn3.png b/src/test/baseline/testFadeIn3.png Binary files differnew file mode 100644 index 0000000..02f0389 --- /dev/null +++ b/src/test/baseline/testFadeIn3.png diff --git a/src/test/baseline/testFadeOut1.png b/src/test/baseline/testFadeOut1.png Binary files differnew file mode 100644 index 0000000..e4a332a --- /dev/null +++ b/src/test/baseline/testFadeOut1.png diff --git a/src/test/baseline/testFadeOut2.png b/src/test/baseline/testFadeOut2.png Binary files differnew file mode 100644 index 0000000..f7bcf5b --- /dev/null +++ b/src/test/baseline/testFadeOut2.png diff --git a/src/test/baseline/testFadeOut3.png b/src/test/baseline/testFadeOut3.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testFadeOut3.png diff --git a/src/test/baseline/testFocusContext1.png b/src/test/baseline/testFocusContext1.png Binary files differnew file mode 100644 index 0000000..380902e --- /dev/null +++ b/src/test/baseline/testFocusContext1.png diff --git a/src/test/baseline/testFocusContext2.png b/src/test/baseline/testFocusContext2.png Binary files differnew file mode 100644 index 0000000..5ecbcf4 --- /dev/null +++ b/src/test/baseline/testFocusContext2.png diff --git a/src/test/baseline/testFocusContext3.png b/src/test/baseline/testFocusContext3.png Binary files differnew file mode 100644 index 0000000..0606d81 --- /dev/null +++ b/src/test/baseline/testFocusContext3.png diff --git a/src/test/baseline/testFocusContext4.png b/src/test/baseline/testFocusContext4.png Binary files differnew file mode 100644 index 0000000..9629e81 --- /dev/null +++ b/src/test/baseline/testFocusContext4.png diff --git a/src/test/baseline/testFocusContext5.png b/src/test/baseline/testFocusContext5.png Binary files differnew file mode 100644 index 0000000..2ae68e0 --- /dev/null +++ b/src/test/baseline/testFocusContext5.png diff --git a/src/test/baseline/testFontDir.png b/src/test/baseline/testFontDir.png Binary files differnew file mode 100644 index 0000000..5dc4858 --- /dev/null +++ b/src/test/baseline/testFontDir.png diff --git a/src/test/baseline/testFontStyle1.png b/src/test/baseline/testFontStyle1.png Binary files differnew file mode 100644 index 0000000..3d773d6 --- /dev/null +++ b/src/test/baseline/testFontStyle1.png diff --git a/src/test/baseline/testFontStyle2.png b/src/test/baseline/testFontStyle2.png Binary files differnew file mode 100644 index 0000000..e67cfa4 --- /dev/null +++ b/src/test/baseline/testFontStyle2.png diff --git a/src/test/baseline/testGamma1.png b/src/test/baseline/testGamma1.png Binary files differnew file mode 100644 index 0000000..a713a13 --- /dev/null +++ b/src/test/baseline/testGamma1.png diff --git a/src/test/baseline/testGamma2.png b/src/test/baseline/testGamma2.png Binary files differnew file mode 100644 index 0000000..18d0479 --- /dev/null +++ b/src/test/baseline/testGamma2.png diff --git a/src/test/baseline/testHVStretchNode1.png b/src/test/baseline/testHVStretchNode1.png Binary files differnew file mode 100644 index 0000000..304c23e --- /dev/null +++ b/src/test/baseline/testHVStretchNode1.png diff --git a/src/test/baseline/testHVStretchNode2.png b/src/test/baseline/testHVStretchNode2.png Binary files differnew file mode 100644 index 0000000..ca1f0f2 --- /dev/null +++ b/src/test/baseline/testHVStretchNode2.png diff --git a/src/test/baseline/testHinting1.png b/src/test/baseline/testHinting1.png Binary files differnew file mode 100644 index 0000000..4657e71 --- /dev/null +++ b/src/test/baseline/testHinting1.png diff --git a/src/test/baseline/testHueSatFX1.png b/src/test/baseline/testHueSatFX1.png Binary files differnew file mode 100644 index 0000000..abe4582 --- /dev/null +++ b/src/test/baseline/testHueSatFX1.png diff --git a/src/test/baseline/testHueSatFX2.png b/src/test/baseline/testHueSatFX2.png Binary files differnew file mode 100644 index 0000000..736bfbd --- /dev/null +++ b/src/test/baseline/testHueSatFX2.png diff --git a/src/test/baseline/testHueSatFX3.png b/src/test/baseline/testHueSatFX3.png Binary files differnew file mode 100644 index 0000000..96e7744 --- /dev/null +++ b/src/test/baseline/testHueSatFX3.png diff --git a/src/test/baseline/testHueSatFX4.png b/src/test/baseline/testHueSatFX4.png Binary files differnew file mode 100644 index 0000000..7aff060 --- /dev/null +++ b/src/test/baseline/testHueSatFX4.png diff --git a/src/test/baseline/testHugeImage0.png b/src/test/baseline/testHugeImage0.png Binary files differnew file mode 100644 index 0000000..eb59ae0 --- /dev/null +++ b/src/test/baseline/testHugeImage0.png diff --git a/src/test/baseline/testHugeImage1.png b/src/test/baseline/testHugeImage1.png Binary files differnew file mode 100644 index 0000000..241b52f --- /dev/null +++ b/src/test/baseline/testHugeImage1.png diff --git a/src/test/baseline/testI18NWords1.png b/src/test/baseline/testI18NWords1.png Binary files differnew file mode 100644 index 0000000..b9b8808 --- /dev/null +++ b/src/test/baseline/testI18NWords1.png diff --git a/src/test/baseline/testI18NWords2.png b/src/test/baseline/testI18NWords2.png Binary files differnew file mode 100644 index 0000000..e3f649b --- /dev/null +++ b/src/test/baseline/testI18NWords2.png diff --git a/src/test/baseline/testI18NWords3.png b/src/test/baseline/testI18NWords3.png Binary files differnew file mode 100644 index 0000000..ace8433 --- /dev/null +++ b/src/test/baseline/testI18NWords3.png diff --git a/src/test/baseline/testImageNullFX1.png b/src/test/baseline/testImageNullFX1.png Binary files differnew file mode 100644 index 0000000..cdbf3fb --- /dev/null +++ b/src/test/baseline/testImageNullFX1.png diff --git a/src/test/baseline/testImageNullFX2.png b/src/test/baseline/testImageNullFX2.png Binary files differnew file mode 100644 index 0000000..a5dd14b --- /dev/null +++ b/src/test/baseline/testImageNullFX2.png diff --git a/src/test/baseline/testImageNullFX3.png b/src/test/baseline/testImageNullFX3.png Binary files differnew file mode 100644 index 0000000..f9b00d9 --- /dev/null +++ b/src/test/baseline/testImageNullFX3.png diff --git a/src/test/baseline/testImgDynamics1.png b/src/test/baseline/testImgDynamics1.png Binary files differnew file mode 100644 index 0000000..d05741d --- /dev/null +++ b/src/test/baseline/testImgDynamics1.png diff --git a/src/test/baseline/testImgDynamics2.png b/src/test/baseline/testImgDynamics2.png Binary files differnew file mode 100644 index 0000000..b3f308f --- /dev/null +++ b/src/test/baseline/testImgDynamics2.png diff --git a/src/test/baseline/testImgDynamics3.png b/src/test/baseline/testImgDynamics3.png Binary files differnew file mode 100644 index 0000000..72a9acf --- /dev/null +++ b/src/test/baseline/testImgDynamics3.png diff --git a/src/test/baseline/testImgDynamics4.png b/src/test/baseline/testImgDynamics4.png Binary files differnew file mode 100644 index 0000000..21c01f2 --- /dev/null +++ b/src/test/baseline/testImgDynamics4.png diff --git a/src/test/baseline/testImgDynamics5.png b/src/test/baseline/testImgDynamics5.png Binary files differnew file mode 100644 index 0000000..d05741d --- /dev/null +++ b/src/test/baseline/testImgDynamics5.png diff --git a/src/test/baseline/testImgHRef1.png b/src/test/baseline/testImgHRef1.png Binary files differnew file mode 100644 index 0000000..a1df968 --- /dev/null +++ b/src/test/baseline/testImgHRef1.png diff --git a/src/test/baseline/testImgHRef2.png b/src/test/baseline/testImgHRef2.png Binary files differnew file mode 100644 index 0000000..03c8e41 --- /dev/null +++ b/src/test/baseline/testImgHRef2.png diff --git a/src/test/baseline/testImgHRef3.png b/src/test/baseline/testImgHRef3.png Binary files differnew file mode 100644 index 0000000..b18ec93 --- /dev/null +++ b/src/test/baseline/testImgHRef3.png diff --git a/src/test/baseline/testImgMask1.png b/src/test/baseline/testImgMask1.png Binary files differnew file mode 100644 index 0000000..2fe736a --- /dev/null +++ b/src/test/baseline/testImgMask1.png diff --git a/src/test/baseline/testImgMask2.png b/src/test/baseline/testImgMask2.png Binary files differnew file mode 100644 index 0000000..9d1f486 --- /dev/null +++ b/src/test/baseline/testImgMask2.png diff --git a/src/test/baseline/testImgMask3.png b/src/test/baseline/testImgMask3.png Binary files differnew file mode 100644 index 0000000..70f58ff --- /dev/null +++ b/src/test/baseline/testImgMask3.png diff --git a/src/test/baseline/testImgMaskCanvas.png b/src/test/baseline/testImgMaskCanvas.png Binary files differnew file mode 100644 index 0000000..1faa5d5 --- /dev/null +++ b/src/test/baseline/testImgMaskCanvas.png diff --git a/src/test/baseline/testImgMaskPos.png b/src/test/baseline/testImgMaskPos.png Binary files differnew file mode 100644 index 0000000..16176eb --- /dev/null +++ b/src/test/baseline/testImgMaskPos.png diff --git a/src/test/baseline/testImgMaskSize1.png b/src/test/baseline/testImgMaskSize1.png Binary files differnew file mode 100644 index 0000000..41ac537 --- /dev/null +++ b/src/test/baseline/testImgMaskSize1.png diff --git a/src/test/baseline/testImgMaskSize2.png b/src/test/baseline/testImgMaskSize2.png Binary files differnew file mode 100644 index 0000000..de6549d --- /dev/null +++ b/src/test/baseline/testImgMaskSize2.png diff --git a/src/test/baseline/testImgMaskSize3.png b/src/test/baseline/testImgMaskSize3.png Binary files differnew file mode 100644 index 0000000..d452f98 --- /dev/null +++ b/src/test/baseline/testImgMaskSize3.png diff --git a/src/test/baseline/testImgPos1.png b/src/test/baseline/testImgPos1.png Binary files differnew file mode 100644 index 0000000..5bb376d --- /dev/null +++ b/src/test/baseline/testImgPos1.png diff --git a/src/test/baseline/testImgPos2.png b/src/test/baseline/testImgPos2.png Binary files differnew file mode 100644 index 0000000..017609d --- /dev/null +++ b/src/test/baseline/testImgPos2.png diff --git a/src/test/baseline/testImgSize1.png b/src/test/baseline/testImgSize1.png Binary files differnew file mode 100644 index 0000000..5a5a7d6 --- /dev/null +++ b/src/test/baseline/testImgSize1.png diff --git a/src/test/baseline/testImgSize2.png b/src/test/baseline/testImgSize2.png Binary files differnew file mode 100644 index 0000000..df562d3 --- /dev/null +++ b/src/test/baseline/testImgSize2.png diff --git a/src/test/baseline/testImgWarp1.png b/src/test/baseline/testImgWarp1.png Binary files differnew file mode 100644 index 0000000..a5ee5c0 --- /dev/null +++ b/src/test/baseline/testImgWarp1.png diff --git a/src/test/baseline/testImgWarp2.png b/src/test/baseline/testImgWarp2.png Binary files differnew file mode 100644 index 0000000..514e6f4 --- /dev/null +++ b/src/test/baseline/testImgWarp2.png diff --git a/src/test/baseline/testInactiveVector1.png b/src/test/baseline/testInactiveVector1.png Binary files differnew file mode 100644 index 0000000..be0f350 --- /dev/null +++ b/src/test/baseline/testInactiveVector1.png diff --git a/src/test/baseline/testInactiveVector2.png b/src/test/baseline/testInactiveVector2.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testInactiveVector2.png diff --git a/src/test/baseline/testIntAnim1.png b/src/test/baseline/testIntAnim1.png Binary files differnew file mode 100644 index 0000000..904a872 --- /dev/null +++ b/src/test/baseline/testIntAnim1.png diff --git a/src/test/baseline/testIntAnim2.png b/src/test/baseline/testIntAnim2.png Binary files differnew file mode 100644 index 0000000..c2df44a --- /dev/null +++ b/src/test/baseline/testIntAnim2.png diff --git a/src/test/baseline/testIntensity1.png b/src/test/baseline/testIntensity1.png Binary files differnew file mode 100644 index 0000000..cf19285 --- /dev/null +++ b/src/test/baseline/testIntensity1.png diff --git a/src/test/baseline/testIntensity2.png b/src/test/baseline/testIntensity2.png Binary files differnew file mode 100644 index 0000000..c8bb26a --- /dev/null +++ b/src/test/baseline/testIntensity2.png diff --git a/src/test/baseline/testIntensity3.png b/src/test/baseline/testIntensity3.png Binary files differnew file mode 100644 index 0000000..450327c --- /dev/null +++ b/src/test/baseline/testIntensity3.png diff --git a/src/test/baseline/testIntensity4.png b/src/test/baseline/testIntensity4.png Binary files differnew file mode 100644 index 0000000..649cd82 --- /dev/null +++ b/src/test/baseline/testIntensity4.png diff --git a/src/test/baseline/testInvertFX1.png b/src/test/baseline/testInvertFX1.png Binary files differnew file mode 100644 index 0000000..cbce0de --- /dev/null +++ b/src/test/baseline/testInvertFX1.png diff --git a/src/test/baseline/testInvertFX2.png b/src/test/baseline/testInvertFX2.png Binary files differnew file mode 100644 index 0000000..2c5a673 --- /dev/null +++ b/src/test/baseline/testInvertFX2.png diff --git a/src/test/baseline/testJustify.png b/src/test/baseline/testJustify.png Binary files differnew file mode 100644 index 0000000..4d5affc --- /dev/null +++ b/src/test/baseline/testJustify.png diff --git a/src/test/baseline/testLetterSpacing1.png b/src/test/baseline/testLetterSpacing1.png Binary files differnew file mode 100644 index 0000000..3b04e0e --- /dev/null +++ b/src/test/baseline/testLetterSpacing1.png diff --git a/src/test/baseline/testLetterSpacing2.png b/src/test/baseline/testLetterSpacing2.png Binary files differnew file mode 100644 index 0000000..8385a22 --- /dev/null +++ b/src/test/baseline/testLetterSpacing2.png diff --git a/src/test/baseline/testLinearAnim1.png b/src/test/baseline/testLinearAnim1.png Binary files differnew file mode 100644 index 0000000..82abf89 --- /dev/null +++ b/src/test/baseline/testLinearAnim1.png diff --git a/src/test/baseline/testLinearAnim2.png b/src/test/baseline/testLinearAnim2.png Binary files differnew file mode 100644 index 0000000..e299221 --- /dev/null +++ b/src/test/baseline/testLinearAnim2.png diff --git a/src/test/baseline/testLinearAnim3.png b/src/test/baseline/testLinearAnim3.png Binary files differnew file mode 100644 index 0000000..e299221 --- /dev/null +++ b/src/test/baseline/testLinearAnim3.png diff --git a/src/test/baseline/testLinearAnimC1.png b/src/test/baseline/testLinearAnimC1.png Binary files differnew file mode 100644 index 0000000..fbe5b29 --- /dev/null +++ b/src/test/baseline/testLinearAnimC1.png diff --git a/src/test/baseline/testLinearAnimC2.png b/src/test/baseline/testLinearAnimC2.png Binary files differnew file mode 100644 index 0000000..b6403be --- /dev/null +++ b/src/test/baseline/testLinearAnimC2.png diff --git a/src/test/baseline/testLinearAnimC3.png b/src/test/baseline/testLinearAnimC3.png Binary files differnew file mode 100644 index 0000000..b5e695e --- /dev/null +++ b/src/test/baseline/testLinearAnimC3.png diff --git a/src/test/baseline/testLinearAnimC4.png b/src/test/baseline/testLinearAnimC4.png Binary files differnew file mode 100644 index 0000000..9703e09 --- /dev/null +++ b/src/test/baseline/testLinearAnimC4.png diff --git a/src/test/baseline/testLinearAnimC5.png b/src/test/baseline/testLinearAnimC5.png Binary files differnew file mode 100644 index 0000000..b5e695e --- /dev/null +++ b/src/test/baseline/testLinearAnimC5.png diff --git a/src/test/baseline/testLinearAnimC6.png b/src/test/baseline/testLinearAnimC6.png Binary files differnew file mode 100644 index 0000000..f1fbb13 --- /dev/null +++ b/src/test/baseline/testLinearAnimC6.png diff --git a/src/test/baseline/testLinearAnimZeroDuration1.png b/src/test/baseline/testLinearAnimZeroDuration1.png Binary files differnew file mode 100644 index 0000000..e299221 --- /dev/null +++ b/src/test/baseline/testLinearAnimZeroDuration1.png diff --git a/src/test/baseline/testLinearAnimZeroDuration2.png b/src/test/baseline/testLinearAnimZeroDuration2.png Binary files differnew file mode 100644 index 0000000..ef346f8 --- /dev/null +++ b/src/test/baseline/testLinearAnimZeroDuration2.png diff --git a/src/test/baseline/testLinearAnimZeroDuration3.png b/src/test/baseline/testLinearAnimZeroDuration3.png Binary files differnew file mode 100644 index 0000000..ef346f8 --- /dev/null +++ b/src/test/baseline/testLinearAnimZeroDuration3.png diff --git a/src/test/baseline/testLinearAnimZeroDurationC1.png b/src/test/baseline/testLinearAnimZeroDurationC1.png Binary files differnew file mode 100644 index 0000000..9703e09 --- /dev/null +++ b/src/test/baseline/testLinearAnimZeroDurationC1.png diff --git a/src/test/baseline/testLinearAnimZeroDurationC2.png b/src/test/baseline/testLinearAnimZeroDurationC2.png Binary files differnew file mode 100644 index 0000000..ef346f8 --- /dev/null +++ b/src/test/baseline/testLinearAnimZeroDurationC2.png diff --git a/src/test/baseline/testLinearAnimZeroDurationC3.png b/src/test/baseline/testLinearAnimZeroDurationC3.png Binary files differnew file mode 100644 index 0000000..ef346f8 --- /dev/null +++ b/src/test/baseline/testLinearAnimZeroDurationC3.png diff --git a/src/test/baseline/testMediaControl1.png b/src/test/baseline/testMediaControl1.png Binary files differnew file mode 100644 index 0000000..fd36c50 --- /dev/null +++ b/src/test/baseline/testMediaControl1.png diff --git a/src/test/baseline/testMediaControl2.png b/src/test/baseline/testMediaControl2.png Binary files differnew file mode 100644 index 0000000..fd01c50 --- /dev/null +++ b/src/test/baseline/testMediaControl2.png diff --git a/src/test/baseline/testMediaControl3.png b/src/test/baseline/testMediaControl3.png Binary files differnew file mode 100644 index 0000000..9f9c0ee --- /dev/null +++ b/src/test/baseline/testMediaControl3.png diff --git a/src/test/baseline/testMediaControl4.png b/src/test/baseline/testMediaControl4.png Binary files differnew file mode 100644 index 0000000..53adc06 --- /dev/null +++ b/src/test/baseline/testMediaControl4.png diff --git a/src/test/baseline/testMediaControl5.png b/src/test/baseline/testMediaControl5.png Binary files differnew file mode 100644 index 0000000..37d7bf4 --- /dev/null +++ b/src/test/baseline/testMediaControl5.png diff --git a/src/test/baseline/testMediaDir1.png b/src/test/baseline/testMediaDir1.png Binary files differnew file mode 100644 index 0000000..d566076 --- /dev/null +++ b/src/test/baseline/testMediaDir1.png diff --git a/src/test/baseline/testMediaDir2.png b/src/test/baseline/testMediaDir2.png Binary files differnew file mode 100644 index 0000000..e46ab2c --- /dev/null +++ b/src/test/baseline/testMediaDir2.png diff --git a/src/test/baseline/testMesh1.png b/src/test/baseline/testMesh1.png Binary files differnew file mode 100644 index 0000000..533ea09 --- /dev/null +++ b/src/test/baseline/testMesh1.png diff --git a/src/test/baseline/testMesh2.png b/src/test/baseline/testMesh2.png Binary files differnew file mode 100644 index 0000000..d81ddbd --- /dev/null +++ b/src/test/baseline/testMesh2.png diff --git a/src/test/baseline/testMesh3.png b/src/test/baseline/testMesh3.png Binary files differnew file mode 100644 index 0000000..4e3dab2 --- /dev/null +++ b/src/test/baseline/testMesh3.png diff --git a/src/test/baseline/testMesh4.png b/src/test/baseline/testMesh4.png Binary files differnew file mode 100644 index 0000000..f325b53 --- /dev/null +++ b/src/test/baseline/testMesh4.png diff --git a/src/test/baseline/testMesh5.png b/src/test/baseline/testMesh5.png Binary files differnew file mode 100644 index 0000000..86c0a24 --- /dev/null +++ b/src/test/baseline/testMesh5.png diff --git a/src/test/baseline/testMesh6.png b/src/test/baseline/testMesh6.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testMesh6.png diff --git a/src/test/baseline/testMesh7.png b/src/test/baseline/testMesh7.png Binary files differnew file mode 100644 index 0000000..a7e2493 --- /dev/null +++ b/src/test/baseline/testMesh7.png diff --git a/src/test/baseline/testMesh8.png b/src/test/baseline/testMesh8.png Binary files differnew file mode 100644 index 0000000..20e4fb1 --- /dev/null +++ b/src/test/baseline/testMesh8.png diff --git a/src/test/baseline/testMipmap.png b/src/test/baseline/testMipmap.png Binary files differnew file mode 100644 index 0000000..eb6185e --- /dev/null +++ b/src/test/baseline/testMipmap.png diff --git a/src/test/baseline/testMove1.png b/src/test/baseline/testMove1.png Binary files differnew file mode 100644 index 0000000..4d0bdec --- /dev/null +++ b/src/test/baseline/testMove1.png diff --git a/src/test/baseline/testNodeInCanvasNullFX1.png b/src/test/baseline/testNodeInCanvasNullFX1.png Binary files differnew file mode 100644 index 0000000..00767fb --- /dev/null +++ b/src/test/baseline/testNodeInCanvasNullFX1.png diff --git a/src/test/baseline/testOffscreen1.png b/src/test/baseline/testOffscreen1.png Binary files differnew file mode 100644 index 0000000..4c1afa7 --- /dev/null +++ b/src/test/baseline/testOffscreen1.png diff --git a/src/test/baseline/testOffscreen2.png b/src/test/baseline/testOffscreen2.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testOffscreen2.png diff --git a/src/test/baseline/testOffscreen3.png b/src/test/baseline/testOffscreen3.png Binary files differnew file mode 100644 index 0000000..f274a2b --- /dev/null +++ b/src/test/baseline/testOffscreen3.png diff --git a/src/test/baseline/testOffscreen4.png b/src/test/baseline/testOffscreen4.png Binary files differnew file mode 100644 index 0000000..4c1afa7 --- /dev/null +++ b/src/test/baseline/testOffscreen4.png diff --git a/src/test/baseline/testOffscreen5.png b/src/test/baseline/testOffscreen5.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testOffscreen5.png diff --git a/src/test/baseline/testOffscreenAutoRender1.png b/src/test/baseline/testOffscreenAutoRender1.png Binary files differnew file mode 100644 index 0000000..4c1afa7 --- /dev/null +++ b/src/test/baseline/testOffscreenAutoRender1.png diff --git a/src/test/baseline/testOffscreenAutoRender2.png b/src/test/baseline/testOffscreenAutoRender2.png Binary files differnew file mode 100644 index 0000000..0d508a9 --- /dev/null +++ b/src/test/baseline/testOffscreenAutoRender2.png diff --git a/src/test/baseline/testOffscreenMultisampleScreenshot.png b/src/test/baseline/testOffscreenMultisampleScreenshot.png Binary files differnew file mode 100644 index 0000000..1a04a20 --- /dev/null +++ b/src/test/baseline/testOffscreenMultisampleScreenshot.png diff --git a/src/test/baseline/testOffscreenScreenshot.png b/src/test/baseline/testOffscreenScreenshot.png Binary files differnew file mode 100644 index 0000000..31fcc27 --- /dev/null +++ b/src/test/baseline/testOffscreenScreenshot.png diff --git a/src/test/baseline/testOpacity.png b/src/test/baseline/testOpacity.png Binary files differnew file mode 100644 index 0000000..aab7cdb --- /dev/null +++ b/src/test/baseline/testOpacity.png diff --git a/src/test/baseline/testOutlines.png b/src/test/baseline/testOutlines.png Binary files differnew file mode 100644 index 0000000..36a7c14 --- /dev/null +++ b/src/test/baseline/testOutlines.png diff --git a/src/test/baseline/testPanoDynamics1.png b/src/test/baseline/testPanoDynamics1.png Binary files differnew file mode 100644 index 0000000..8cac76c --- /dev/null +++ b/src/test/baseline/testPanoDynamics1.png diff --git a/src/test/baseline/testPanoDynamics2.png b/src/test/baseline/testPanoDynamics2.png Binary files differnew file mode 100644 index 0000000..21c01f2 --- /dev/null +++ b/src/test/baseline/testPanoDynamics2.png diff --git a/src/test/baseline/testPanoDynamics3.png b/src/test/baseline/testPanoDynamics3.png Binary files differnew file mode 100644 index 0000000..e52d01b --- /dev/null +++ b/src/test/baseline/testPanoDynamics3.png diff --git a/src/test/baseline/testPanoImage.png b/src/test/baseline/testPanoImage.png Binary files differnew file mode 100644 index 0000000..6ce1008 --- /dev/null +++ b/src/test/baseline/testPanoImage.png diff --git a/src/test/baseline/testPanoImagewNOP.png b/src/test/baseline/testPanoImagewNOP.png Binary files differnew file mode 100644 index 0000000..6ce1008 --- /dev/null +++ b/src/test/baseline/testPanoImagewNOP.png diff --git a/src/test/baseline/testParaWords.png b/src/test/baseline/testParaWords.png Binary files differnew file mode 100644 index 0000000..4709a3b --- /dev/null +++ b/src/test/baseline/testParaWords.png diff --git a/src/test/baseline/testParallelAnimC1.png b/src/test/baseline/testParallelAnimC1.png Binary files differnew file mode 100644 index 0000000..69aa068 --- /dev/null +++ b/src/test/baseline/testParallelAnimC1.png diff --git a/src/test/baseline/testParallelAnimC2.png b/src/test/baseline/testParallelAnimC2.png Binary files differnew file mode 100644 index 0000000..80a7f81 --- /dev/null +++ b/src/test/baseline/testParallelAnimC2.png diff --git a/src/test/baseline/testParallelAnimC3.png b/src/test/baseline/testParallelAnimC3.png Binary files differnew file mode 100644 index 0000000..ec591f3 --- /dev/null +++ b/src/test/baseline/testParallelAnimC3.png diff --git a/src/test/baseline/testParallelAnims1.png b/src/test/baseline/testParallelAnims1.png Binary files differnew file mode 100644 index 0000000..4d189b7 --- /dev/null +++ b/src/test/baseline/testParallelAnims1.png diff --git a/src/test/baseline/testParallelAnims2.png b/src/test/baseline/testParallelAnims2.png Binary files differnew file mode 100644 index 0000000..64f85d1 --- /dev/null +++ b/src/test/baseline/testParallelAnims2.png diff --git a/src/test/baseline/testPieSlice1.png b/src/test/baseline/testPieSlice1.png Binary files differnew file mode 100644 index 0000000..9d5bc4d --- /dev/null +++ b/src/test/baseline/testPieSlice1.png diff --git a/src/test/baseline/testPieSlice2.png b/src/test/baseline/testPieSlice2.png Binary files differnew file mode 100644 index 0000000..5d62891 --- /dev/null +++ b/src/test/baseline/testPieSlice2.png diff --git a/src/test/baseline/testPieSlice3.png b/src/test/baseline/testPieSlice3.png Binary files differnew file mode 100644 index 0000000..c011af3 --- /dev/null +++ b/src/test/baseline/testPieSlice3.png diff --git a/src/test/baseline/testPlayBeforeConnect.png b/src/test/baseline/testPlayBeforeConnect.png Binary files differnew file mode 100644 index 0000000..d27fda0 --- /dev/null +++ b/src/test/baseline/testPlayBeforeConnect.png diff --git a/src/test/baseline/testPointAnim1.png b/src/test/baseline/testPointAnim1.png Binary files differnew file mode 100644 index 0000000..4c1afa7 --- /dev/null +++ b/src/test/baseline/testPointAnim1.png diff --git a/src/test/baseline/testPointAnim2.png b/src/test/baseline/testPointAnim2.png Binary files differnew file mode 100644 index 0000000..1d46750 --- /dev/null +++ b/src/test/baseline/testPointAnim2.png diff --git a/src/test/baseline/testPointAnim3.png b/src/test/baseline/testPointAnim3.png Binary files differnew file mode 100644 index 0000000..1d46750 --- /dev/null +++ b/src/test/baseline/testPointAnim3.png diff --git a/src/test/baseline/testPolyLine1.png b/src/test/baseline/testPolyLine1.png Binary files differnew file mode 100644 index 0000000..e2843f6 --- /dev/null +++ b/src/test/baseline/testPolyLine1.png diff --git a/src/test/baseline/testPolyLine2.png b/src/test/baseline/testPolyLine2.png Binary files differnew file mode 100644 index 0000000..4b26092 --- /dev/null +++ b/src/test/baseline/testPolyLine2.png diff --git a/src/test/baseline/testPolyLine3.png b/src/test/baseline/testPolyLine3.png Binary files differnew file mode 100644 index 0000000..80df8a0 --- /dev/null +++ b/src/test/baseline/testPolyLine3.png diff --git a/src/test/baseline/testPolyLine4.png b/src/test/baseline/testPolyLine4.png Binary files differnew file mode 100644 index 0000000..e37c026 --- /dev/null +++ b/src/test/baseline/testPolyLine4.png diff --git a/src/test/baseline/testPolyLine5.png b/src/test/baseline/testPolyLine5.png Binary files differnew file mode 100644 index 0000000..80df8a0 --- /dev/null +++ b/src/test/baseline/testPolyLine5.png diff --git a/src/test/baseline/testPolyLine6.png b/src/test/baseline/testPolyLine6.png Binary files differnew file mode 100644 index 0000000..2607d53 --- /dev/null +++ b/src/test/baseline/testPolyLine6.png diff --git a/src/test/baseline/testPolygon1.png b/src/test/baseline/testPolygon1.png Binary files differnew file mode 100644 index 0000000..441ed9b --- /dev/null +++ b/src/test/baseline/testPolygon1.png diff --git a/src/test/baseline/testPolygon2.png b/src/test/baseline/testPolygon2.png Binary files differnew file mode 100644 index 0000000..858bf40 --- /dev/null +++ b/src/test/baseline/testPolygon2.png diff --git a/src/test/baseline/testPolygon3.png b/src/test/baseline/testPolygon3.png Binary files differnew file mode 100644 index 0000000..636ada8 --- /dev/null +++ b/src/test/baseline/testPolygon3.png diff --git a/src/test/baseline/testPolygon4.png b/src/test/baseline/testPolygon4.png Binary files differnew file mode 100644 index 0000000..636ada8 --- /dev/null +++ b/src/test/baseline/testPolygon4.png diff --git a/src/test/baseline/testPolygon5.png b/src/test/baseline/testPolygon5.png Binary files differnew file mode 100644 index 0000000..964a01b --- /dev/null +++ b/src/test/baseline/testPolygon5.png diff --git a/src/test/baseline/testPolygon6.png b/src/test/baseline/testPolygon6.png Binary files differnew file mode 100644 index 0000000..45ee95d --- /dev/null +++ b/src/test/baseline/testPolygon6.png diff --git a/src/test/baseline/testPolygon7.png b/src/test/baseline/testPolygon7.png Binary files differnew file mode 100644 index 0000000..5cb45e6 --- /dev/null +++ b/src/test/baseline/testPolygon7.png diff --git a/src/test/baseline/testPolygon8.png b/src/test/baseline/testPolygon8.png Binary files differnew file mode 100644 index 0000000..f926687 --- /dev/null +++ b/src/test/baseline/testPolygon8.png diff --git a/src/test/baseline/testPolygon9.png b/src/test/baseline/testPolygon9.png Binary files differnew file mode 100644 index 0000000..3e00de4 --- /dev/null +++ b/src/test/baseline/testPolygon9.png diff --git a/src/test/baseline/testPolygonHole1.png b/src/test/baseline/testPolygonHole1.png Binary files differnew file mode 100644 index 0000000..9c18ad1 --- /dev/null +++ b/src/test/baseline/testPolygonHole1.png diff --git a/src/test/baseline/testPolygonHole2.png b/src/test/baseline/testPolygonHole2.png Binary files differnew file mode 100644 index 0000000..d8199da --- /dev/null +++ b/src/test/baseline/testPolygonHole2.png diff --git a/src/test/baseline/testPositioning.png b/src/test/baseline/testPositioning.png Binary files differnew file mode 100644 index 0000000..1b174b0 --- /dev/null +++ b/src/test/baseline/testPositioning.png diff --git a/src/test/baseline/testProgressBar1.png b/src/test/baseline/testProgressBar1.png Binary files differnew file mode 100644 index 0000000..2b2c752 --- /dev/null +++ b/src/test/baseline/testProgressBar1.png diff --git a/src/test/baseline/testProgressBar2.png b/src/test/baseline/testProgressBar2.png Binary files differnew file mode 100644 index 0000000..6c1f56b --- /dev/null +++ b/src/test/baseline/testProgressBar2.png diff --git a/src/test/baseline/testProgressBar3.png b/src/test/baseline/testProgressBar3.png Binary files differnew file mode 100644 index 0000000..d788f76 --- /dev/null +++ b/src/test/baseline/testProgressBar3.png diff --git a/src/test/baseline/testRawText1.png b/src/test/baseline/testRawText1.png Binary files differnew file mode 100644 index 0000000..4733e87 --- /dev/null +++ b/src/test/baseline/testRawText1.png diff --git a/src/test/baseline/testRawText2.png b/src/test/baseline/testRawText2.png Binary files differnew file mode 100644 index 0000000..cedb8bb --- /dev/null +++ b/src/test/baseline/testRawText2.png diff --git a/src/test/baseline/testRawText3.png b/src/test/baseline/testRawText3.png Binary files differnew file mode 100644 index 0000000..e91b743 --- /dev/null +++ b/src/test/baseline/testRawText3.png diff --git a/src/test/baseline/testRawText4.png b/src/test/baseline/testRawText4.png Binary files differnew file mode 100644 index 0000000..cd1c0dc --- /dev/null +++ b/src/test/baseline/testRawText4.png diff --git a/src/test/baseline/testRect1.png b/src/test/baseline/testRect1.png Binary files differnew file mode 100644 index 0000000..c2f4c5e --- /dev/null +++ b/src/test/baseline/testRect1.png diff --git a/src/test/baseline/testRect2.png b/src/test/baseline/testRect2.png Binary files differnew file mode 100644 index 0000000..9d9ec9d --- /dev/null +++ b/src/test/baseline/testRect2.png diff --git a/src/test/baseline/testRect3.png b/src/test/baseline/testRect3.png Binary files differnew file mode 100644 index 0000000..aabb540 --- /dev/null +++ b/src/test/baseline/testRect3.png diff --git a/src/test/baseline/testRect4.png b/src/test/baseline/testRect4.png Binary files differnew file mode 100644 index 0000000..c549747 --- /dev/null +++ b/src/test/baseline/testRect4.png diff --git a/src/test/baseline/testRenderPipeline.png b/src/test/baseline/testRenderPipeline.png Binary files differnew file mode 100644 index 0000000..f9603fd --- /dev/null +++ b/src/test/baseline/testRenderPipeline.png diff --git a/src/test/baseline/testRotate1.png b/src/test/baseline/testRotate1.png Binary files differnew file mode 100644 index 0000000..7c8aa25 --- /dev/null +++ b/src/test/baseline/testRotate1.png diff --git a/src/test/baseline/testRotate1a.png b/src/test/baseline/testRotate1a.png Binary files differnew file mode 100644 index 0000000..4e71a64 --- /dev/null +++ b/src/test/baseline/testRotate1a.png diff --git a/src/test/baseline/testRotate1b.png b/src/test/baseline/testRotate1b.png Binary files differnew file mode 100644 index 0000000..d1b5321 --- /dev/null +++ b/src/test/baseline/testRotate1b.png diff --git a/src/test/baseline/testRotate2.png b/src/test/baseline/testRotate2.png Binary files differnew file mode 100644 index 0000000..5db6d09 --- /dev/null +++ b/src/test/baseline/testRotate2.png diff --git a/src/test/baseline/testRotatePivot1.png b/src/test/baseline/testRotatePivot1.png Binary files differnew file mode 100644 index 0000000..6b4d6ef --- /dev/null +++ b/src/test/baseline/testRotatePivot1.png diff --git a/src/test/baseline/testRotatePivot2.png b/src/test/baseline/testRotatePivot2.png Binary files differnew file mode 100644 index 0000000..d5122c7 --- /dev/null +++ b/src/test/baseline/testRotatePivot2.png diff --git a/src/test/baseline/testRotatePivot3.png b/src/test/baseline/testRotatePivot3.png Binary files differnew file mode 100644 index 0000000..8237df6 --- /dev/null +++ b/src/test/baseline/testRotatePivot3.png diff --git a/src/test/baseline/testRoundedRect1.png b/src/test/baseline/testRoundedRect1.png Binary files differnew file mode 100644 index 0000000..44e5013 --- /dev/null +++ b/src/test/baseline/testRoundedRect1.png diff --git a/src/test/baseline/testRoundedRect2.png b/src/test/baseline/testRoundedRect2.png Binary files differnew file mode 100644 index 0000000..b50d434 --- /dev/null +++ b/src/test/baseline/testRoundedRect2.png diff --git a/src/test/baseline/testRoundedRect3.png b/src/test/baseline/testRoundedRect3.png Binary files differnew file mode 100644 index 0000000..b35eb14 --- /dev/null +++ b/src/test/baseline/testRoundedRect3.png diff --git a/src/test/baseline/testRoundedRect4.png b/src/test/baseline/testRoundedRect4.png Binary files differnew file mode 100644 index 0000000..a6e5d6e --- /dev/null +++ b/src/test/baseline/testRoundedRect4.png diff --git a/src/test/baseline/testRoundedRect5.png b/src/test/baseline/testRoundedRect5.png Binary files differnew file mode 100644 index 0000000..c6da32c --- /dev/null +++ b/src/test/baseline/testRoundedRect5.png diff --git a/src/test/baseline/testRoundedRect6.png b/src/test/baseline/testRoundedRect6.png Binary files differnew file mode 100644 index 0000000..a9e76a8 --- /dev/null +++ b/src/test/baseline/testRoundedRect6.png diff --git a/src/test/baseline/testScrollArea1.png b/src/test/baseline/testScrollArea1.png Binary files differnew file mode 100644 index 0000000..4cb67e2 --- /dev/null +++ b/src/test/baseline/testScrollArea1.png diff --git a/src/test/baseline/testScrollArea2.png b/src/test/baseline/testScrollArea2.png Binary files differnew file mode 100644 index 0000000..7939cae --- /dev/null +++ b/src/test/baseline/testScrollArea2.png diff --git a/src/test/baseline/testScrollArea3.png b/src/test/baseline/testScrollArea3.png Binary files differnew file mode 100644 index 0000000..1fc62df --- /dev/null +++ b/src/test/baseline/testScrollArea3.png diff --git a/src/test/baseline/testScrollBarHoriz1.png b/src/test/baseline/testScrollBarHoriz1.png Binary files differnew file mode 100644 index 0000000..aedcb12 --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz1.png diff --git a/src/test/baseline/testScrollBarHoriz10.png b/src/test/baseline/testScrollBarHoriz10.png Binary files differnew file mode 100644 index 0000000..0c8a5af --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz10.png diff --git a/src/test/baseline/testScrollBarHoriz11.png b/src/test/baseline/testScrollBarHoriz11.png Binary files differnew file mode 100644 index 0000000..da84ebc --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz11.png diff --git a/src/test/baseline/testScrollBarHoriz12.png b/src/test/baseline/testScrollBarHoriz12.png Binary files differnew file mode 100644 index 0000000..5e2f013 --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz12.png diff --git a/src/test/baseline/testScrollBarHoriz2.png b/src/test/baseline/testScrollBarHoriz2.png Binary files differnew file mode 100644 index 0000000..b8a2dcd --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz2.png diff --git a/src/test/baseline/testScrollBarHoriz3.png b/src/test/baseline/testScrollBarHoriz3.png Binary files differnew file mode 100644 index 0000000..885b429 --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz3.png diff --git a/src/test/baseline/testScrollBarHoriz4.png b/src/test/baseline/testScrollBarHoriz4.png Binary files differnew file mode 100644 index 0000000..8ceea4f --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz4.png diff --git a/src/test/baseline/testScrollBarHoriz5.png b/src/test/baseline/testScrollBarHoriz5.png Binary files differnew file mode 100644 index 0000000..4278825 --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz5.png diff --git a/src/test/baseline/testScrollBarHoriz6.png b/src/test/baseline/testScrollBarHoriz6.png Binary files differnew file mode 100644 index 0000000..ee270d3 --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz6.png diff --git a/src/test/baseline/testScrollBarHoriz7.png b/src/test/baseline/testScrollBarHoriz7.png Binary files differnew file mode 100644 index 0000000..0fefd7b --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz7.png diff --git a/src/test/baseline/testScrollBarHoriz8.png b/src/test/baseline/testScrollBarHoriz8.png Binary files differnew file mode 100644 index 0000000..138ec3a --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz8.png diff --git a/src/test/baseline/testScrollBarHoriz9.png b/src/test/baseline/testScrollBarHoriz9.png Binary files differnew file mode 100644 index 0000000..0fefd7b --- /dev/null +++ b/src/test/baseline/testScrollBarHoriz9.png diff --git a/src/test/baseline/testScrollBarVert1.png b/src/test/baseline/testScrollBarVert1.png Binary files differnew file mode 100644 index 0000000..25c3098 --- /dev/null +++ b/src/test/baseline/testScrollBarVert1.png diff --git a/src/test/baseline/testScrollBarVert2.png b/src/test/baseline/testScrollBarVert2.png Binary files differnew file mode 100644 index 0000000..572fac9 --- /dev/null +++ b/src/test/baseline/testScrollBarVert2.png diff --git a/src/test/baseline/testScrollBarVert3.png b/src/test/baseline/testScrollBarVert3.png Binary files differnew file mode 100644 index 0000000..d1a893c --- /dev/null +++ b/src/test/baseline/testScrollBarVert3.png diff --git a/src/test/baseline/testScrollBarVert4.png b/src/test/baseline/testScrollBarVert4.png Binary files differnew file mode 100644 index 0000000..a29849f --- /dev/null +++ b/src/test/baseline/testScrollBarVert4.png diff --git a/src/test/baseline/testScrollBarVert5.png b/src/test/baseline/testScrollBarVert5.png Binary files differnew file mode 100644 index 0000000..ff40ef7 --- /dev/null +++ b/src/test/baseline/testScrollBarVert5.png diff --git a/src/test/baseline/testScrollBarVert6.png b/src/test/baseline/testScrollBarVert6.png Binary files differnew file mode 100644 index 0000000..edb3196 --- /dev/null +++ b/src/test/baseline/testScrollBarVert6.png diff --git a/src/test/baseline/testScrollBarVert7.png b/src/test/baseline/testScrollBarVert7.png Binary files differnew file mode 100644 index 0000000..115d8ca --- /dev/null +++ b/src/test/baseline/testScrollBarVert7.png diff --git a/src/test/baseline/testScrollBarVert8.png b/src/test/baseline/testScrollBarVert8.png Binary files differnew file mode 100644 index 0000000..5e1e08b --- /dev/null +++ b/src/test/baseline/testScrollBarVert8.png diff --git a/src/test/baseline/testScrollBarVert9.png b/src/test/baseline/testScrollBarVert9.png Binary files differnew file mode 100644 index 0000000..3a7ff70 --- /dev/null +++ b/src/test/baseline/testScrollBarVert9.png diff --git a/src/test/baseline/testScrollPane1.png b/src/test/baseline/testScrollPane1.png Binary files differnew file mode 100644 index 0000000..68fcad1 --- /dev/null +++ b/src/test/baseline/testScrollPane1.png diff --git a/src/test/baseline/testScrollPane2.png b/src/test/baseline/testScrollPane2.png Binary files differnew file mode 100644 index 0000000..3e58737 --- /dev/null +++ b/src/test/baseline/testScrollPane2.png diff --git a/src/test/baseline/testScrollPane3.png b/src/test/baseline/testScrollPane3.png Binary files differnew file mode 100644 index 0000000..834a091 --- /dev/null +++ b/src/test/baseline/testScrollPane3.png diff --git a/src/test/baseline/testSeekAfterEOF.png b/src/test/baseline/testSeekAfterEOF.png Binary files differnew file mode 100644 index 0000000..76e79c1 --- /dev/null +++ b/src/test/baseline/testSeekAfterEOF.png diff --git a/src/test/baseline/testShadowFX1.png b/src/test/baseline/testShadowFX1.png Binary files differnew file mode 100644 index 0000000..7d1d5d7 --- /dev/null +++ b/src/test/baseline/testShadowFX1.png diff --git a/src/test/baseline/testShadowFX2.png b/src/test/baseline/testShadowFX2.png Binary files differnew file mode 100644 index 0000000..0d9b1ee --- /dev/null +++ b/src/test/baseline/testShadowFX2.png diff --git a/src/test/baseline/testShadowFX3.png b/src/test/baseline/testShadowFX3.png Binary files differnew file mode 100644 index 0000000..3a3a678 --- /dev/null +++ b/src/test/baseline/testShadowFX3.png diff --git a/src/test/baseline/testShadowFX4.png b/src/test/baseline/testShadowFX4.png Binary files differnew file mode 100644 index 0000000..13da229 --- /dev/null +++ b/src/test/baseline/testShadowFX4.png diff --git a/src/test/baseline/testShadowFX5.png b/src/test/baseline/testShadowFX5.png Binary files differnew file mode 100644 index 0000000..b1ed885 --- /dev/null +++ b/src/test/baseline/testShadowFX5.png diff --git a/src/test/baseline/testShadowFX6.png b/src/test/baseline/testShadowFX6.png Binary files differnew file mode 100644 index 0000000..52e8c14 --- /dev/null +++ b/src/test/baseline/testShadowFX6.png diff --git a/src/test/baseline/testSimpleWords.png b/src/test/baseline/testSimpleWords.png Binary files differnew file mode 100644 index 0000000..21e1a1b --- /dev/null +++ b/src/test/baseline/testSimpleWords.png diff --git a/src/test/baseline/testSliderHoriz1.png b/src/test/baseline/testSliderHoriz1.png Binary files differnew file mode 100644 index 0000000..c30040d --- /dev/null +++ b/src/test/baseline/testSliderHoriz1.png diff --git a/src/test/baseline/testSliderHoriz2.png b/src/test/baseline/testSliderHoriz2.png Binary files differnew file mode 100644 index 0000000..e22a32f --- /dev/null +++ b/src/test/baseline/testSliderHoriz2.png diff --git a/src/test/baseline/testSliderHoriz3.png b/src/test/baseline/testSliderHoriz3.png Binary files differnew file mode 100644 index 0000000..bcf1690 --- /dev/null +++ b/src/test/baseline/testSliderHoriz3.png diff --git a/src/test/baseline/testSliderHoriz4.png b/src/test/baseline/testSliderHoriz4.png Binary files differnew file mode 100644 index 0000000..7c48e5a --- /dev/null +++ b/src/test/baseline/testSliderHoriz4.png diff --git a/src/test/baseline/testSliderHoriz5.png b/src/test/baseline/testSliderHoriz5.png Binary files differnew file mode 100644 index 0000000..2b6534a --- /dev/null +++ b/src/test/baseline/testSliderHoriz5.png diff --git a/src/test/baseline/testSliderVert1.png b/src/test/baseline/testSliderVert1.png Binary files differnew file mode 100644 index 0000000..d82d467 --- /dev/null +++ b/src/test/baseline/testSliderVert1.png diff --git a/src/test/baseline/testSliderVert2.png b/src/test/baseline/testSliderVert2.png Binary files differnew file mode 100644 index 0000000..294dae9 --- /dev/null +++ b/src/test/baseline/testSliderVert2.png diff --git a/src/test/baseline/testSliderVert3.png b/src/test/baseline/testSliderVert3.png Binary files differnew file mode 100644 index 0000000..4a00a8f --- /dev/null +++ b/src/test/baseline/testSliderVert3.png diff --git a/src/test/baseline/testSliderVert4.png b/src/test/baseline/testSliderVert4.png Binary files differnew file mode 100644 index 0000000..f13d278 --- /dev/null +++ b/src/test/baseline/testSliderVert4.png diff --git a/src/test/baseline/testSliderVert5.png b/src/test/baseline/testSliderVert5.png Binary files differnew file mode 100644 index 0000000..a939fe0 --- /dev/null +++ b/src/test/baseline/testSliderVert5.png diff --git a/src/test/baseline/testSpanWords.png b/src/test/baseline/testSpanWords.png Binary files differnew file mode 100644 index 0000000..c206d60 --- /dev/null +++ b/src/test/baseline/testSpanWords.png diff --git a/src/test/baseline/testSplineAnim1.png b/src/test/baseline/testSplineAnim1.png Binary files differnew file mode 100644 index 0000000..82abf89 --- /dev/null +++ b/src/test/baseline/testSplineAnim1.png diff --git a/src/test/baseline/testSplineAnim2.png b/src/test/baseline/testSplineAnim2.png Binary files differnew file mode 100644 index 0000000..e299221 --- /dev/null +++ b/src/test/baseline/testSplineAnim2.png diff --git a/src/test/baseline/testSplineAnim3.png b/src/test/baseline/testSplineAnim3.png Binary files differnew file mode 100644 index 0000000..36a6afc --- /dev/null +++ b/src/test/baseline/testSplineAnim3.png diff --git a/src/test/baseline/testStateAnim1.png b/src/test/baseline/testStateAnim1.png Binary files differnew file mode 100644 index 0000000..19ad729 --- /dev/null +++ b/src/test/baseline/testStateAnim1.png diff --git a/src/test/baseline/testStateAnim2.png b/src/test/baseline/testStateAnim2.png Binary files differnew file mode 100644 index 0000000..92a98a5 --- /dev/null +++ b/src/test/baseline/testStateAnim2.png diff --git a/src/test/baseline/testStateAnim3.png b/src/test/baseline/testStateAnim3.png Binary files differnew file mode 100644 index 0000000..92a98a5 --- /dev/null +++ b/src/test/baseline/testStateAnim3.png diff --git a/src/test/baseline/testStateAnim4.png b/src/test/baseline/testStateAnim4.png Binary files differnew file mode 100644 index 0000000..19ad729 --- /dev/null +++ b/src/test/baseline/testStateAnim4.png diff --git a/src/test/baseline/testStateAnim5.png b/src/test/baseline/testStateAnim5.png Binary files differnew file mode 100644 index 0000000..92a98a5 --- /dev/null +++ b/src/test/baseline/testStateAnim5.png diff --git a/src/test/baseline/testStateAnimC1.png b/src/test/baseline/testStateAnimC1.png Binary files differnew file mode 100644 index 0000000..02f0389 --- /dev/null +++ b/src/test/baseline/testStateAnimC1.png diff --git a/src/test/baseline/testStateAnimC2.png b/src/test/baseline/testStateAnimC2.png Binary files differnew file mode 100644 index 0000000..2126c02 --- /dev/null +++ b/src/test/baseline/testStateAnimC2.png diff --git a/src/test/baseline/testStateAnimC3.png b/src/test/baseline/testStateAnimC3.png Binary files differnew file mode 100644 index 0000000..dc43edc --- /dev/null +++ b/src/test/baseline/testStateAnimC3.png diff --git a/src/test/baseline/testStateAnimC4.png b/src/test/baseline/testStateAnimC4.png Binary files differnew file mode 100644 index 0000000..2126c02 --- /dev/null +++ b/src/test/baseline/testStateAnimC4.png diff --git a/src/test/baseline/testStateAnimC5.png b/src/test/baseline/testStateAnimC5.png Binary files differnew file mode 100644 index 0000000..2126c02 --- /dev/null +++ b/src/test/baseline/testStateAnimC5.png diff --git a/src/test/baseline/testStretchNodeHoriz1.png b/src/test/baseline/testStretchNodeHoriz1.png Binary files differnew file mode 100644 index 0000000..652ada8 --- /dev/null +++ b/src/test/baseline/testStretchNodeHoriz1.png diff --git a/src/test/baseline/testStretchNodeHoriz2.png b/src/test/baseline/testStretchNodeHoriz2.png Binary files differnew file mode 100644 index 0000000..fe123b0 --- /dev/null +++ b/src/test/baseline/testStretchNodeHoriz2.png diff --git a/src/test/baseline/testStretchNodeVert1.png b/src/test/baseline/testStretchNodeVert1.png Binary files differnew file mode 100644 index 0000000..a0e6fe3 --- /dev/null +++ b/src/test/baseline/testStretchNodeVert1.png diff --git a/src/test/baseline/testStretchNodeVert2.png b/src/test/baseline/testStretchNodeVert2.png Binary files differnew file mode 100644 index 0000000..ac7d496 --- /dev/null +++ b/src/test/baseline/testStretchNodeVert2.png diff --git a/src/test/baseline/testSvgBmp.png b/src/test/baseline/testSvgBmp.png Binary files differnew file mode 100644 index 0000000..8020a67 --- /dev/null +++ b/src/test/baseline/testSvgBmp.png diff --git a/src/test/baseline/testSvgNode.png b/src/test/baseline/testSvgNode.png Binary files differnew file mode 100644 index 0000000..76d1632 --- /dev/null +++ b/src/test/baseline/testSvgNode.png diff --git a/src/test/baseline/testSvgPosBmp.png b/src/test/baseline/testSvgPosBmp.png Binary files differnew file mode 100644 index 0000000..6eb83fe --- /dev/null +++ b/src/test/baseline/testSvgPosBmp.png diff --git a/src/test/baseline/testSvgScaleBmp1.png b/src/test/baseline/testSvgScaleBmp1.png Binary files differnew file mode 100644 index 0000000..ba46499 --- /dev/null +++ b/src/test/baseline/testSvgScaleBmp1.png diff --git a/src/test/baseline/testSvgScaleBmp2.png b/src/test/baseline/testSvgScaleBmp2.png Binary files differnew file mode 100644 index 0000000..eb038d5 --- /dev/null +++ b/src/test/baseline/testSvgScaleBmp2.png diff --git a/src/test/baseline/testSvgScaledNode1.png b/src/test/baseline/testSvgScaledNode1.png Binary files differnew file mode 100644 index 0000000..7c78fb5 --- /dev/null +++ b/src/test/baseline/testSvgScaledNode1.png diff --git a/src/test/baseline/testSvgScaledNode2.png b/src/test/baseline/testSvgScaledNode2.png Binary files differnew file mode 100644 index 0000000..3cdff7f --- /dev/null +++ b/src/test/baseline/testSvgScaledNode2.png diff --git a/src/test/baseline/testTexCompression1.png b/src/test/baseline/testTexCompression1.png Binary files differnew file mode 100644 index 0000000..8629a85 --- /dev/null +++ b/src/test/baseline/testTexCompression1.png diff --git a/src/test/baseline/testTexCompression2.png b/src/test/baseline/testTexCompression2.png Binary files differnew file mode 100644 index 0000000..51acdba --- /dev/null +++ b/src/test/baseline/testTexCompression2.png diff --git a/src/test/baseline/testTextArea1.png b/src/test/baseline/testTextArea1.png Binary files differnew file mode 100644 index 0000000..7cf8ac1 --- /dev/null +++ b/src/test/baseline/testTextArea1.png diff --git a/src/test/baseline/testTextArea2.png b/src/test/baseline/testTextArea2.png Binary files differnew file mode 100644 index 0000000..6fe4c64 --- /dev/null +++ b/src/test/baseline/testTextArea2.png diff --git a/src/test/baseline/testTextArea3.png b/src/test/baseline/testTextArea3.png Binary files differnew file mode 100644 index 0000000..6577cf2 --- /dev/null +++ b/src/test/baseline/testTextArea3.png diff --git a/src/test/baseline/testTextArea4.png b/src/test/baseline/testTextArea4.png Binary files differnew file mode 100644 index 0000000..2fc48fe --- /dev/null +++ b/src/test/baseline/testTextArea4.png diff --git a/src/test/baseline/testTextArea5.png b/src/test/baseline/testTextArea5.png Binary files differnew file mode 100644 index 0000000..a7c53e2 --- /dev/null +++ b/src/test/baseline/testTextArea5.png diff --git a/src/test/baseline/testTextButtonDisabled.png b/src/test/baseline/testTextButtonDisabled.png Binary files differnew file mode 100644 index 0000000..c859bfa --- /dev/null +++ b/src/test/baseline/testTextButtonDisabled.png diff --git a/src/test/baseline/testTextButtonDown.png b/src/test/baseline/testTextButtonDown.png Binary files differnew file mode 100644 index 0000000..9122c33 --- /dev/null +++ b/src/test/baseline/testTextButtonDown.png diff --git a/src/test/baseline/testTextButtonDownNewText.png b/src/test/baseline/testTextButtonDownNewText.png Binary files differnew file mode 100644 index 0000000..9592a86 --- /dev/null +++ b/src/test/baseline/testTextButtonDownNewText.png diff --git a/src/test/baseline/testTextButtonUp.png b/src/test/baseline/testTextButtonUp.png Binary files differnew file mode 100644 index 0000000..c859bfa --- /dev/null +++ b/src/test/baseline/testTextButtonUp.png diff --git a/src/test/baseline/testTextButtonUpNewText.png b/src/test/baseline/testTextButtonUpNewText.png Binary files differnew file mode 100644 index 0000000..ebb66bc --- /dev/null +++ b/src/test/baseline/testTextButtonUpNewText.png diff --git a/src/test/baseline/testTexturedCurve1.png b/src/test/baseline/testTexturedCurve1.png Binary files differnew file mode 100644 index 0000000..dc626fd --- /dev/null +++ b/src/test/baseline/testTexturedCurve1.png diff --git a/src/test/baseline/testTexturedCurve2.png b/src/test/baseline/testTexturedCurve2.png Binary files differnew file mode 100644 index 0000000..f75a670 --- /dev/null +++ b/src/test/baseline/testTexturedCurve2.png diff --git a/src/test/baseline/testTexturedPolyLine1.png b/src/test/baseline/testTexturedPolyLine1.png Binary files differnew file mode 100644 index 0000000..1fd2e84 --- /dev/null +++ b/src/test/baseline/testTexturedPolyLine1.png diff --git a/src/test/baseline/testTexturedPolyLine2.png b/src/test/baseline/testTexturedPolyLine2.png Binary files differnew file mode 100644 index 0000000..ccbe01d --- /dev/null +++ b/src/test/baseline/testTexturedPolyLine2.png diff --git a/src/test/baseline/testTexturedPolyLine3.png b/src/test/baseline/testTexturedPolyLine3.png Binary files differnew file mode 100644 index 0000000..65c59eb --- /dev/null +++ b/src/test/baseline/testTexturedPolyLine3.png diff --git a/src/test/baseline/testTexturedPolyLine4.png b/src/test/baseline/testTexturedPolyLine4.png Binary files differnew file mode 100644 index 0000000..f063a2f --- /dev/null +++ b/src/test/baseline/testTexturedPolyLine4.png diff --git a/src/test/baseline/testTexturedPolygon1.png b/src/test/baseline/testTexturedPolygon1.png Binary files differnew file mode 100644 index 0000000..7064f8d --- /dev/null +++ b/src/test/baseline/testTexturedPolygon1.png diff --git a/src/test/baseline/testTexturedPolygon2.png b/src/test/baseline/testTexturedPolygon2.png Binary files differnew file mode 100644 index 0000000..05f67c2 --- /dev/null +++ b/src/test/baseline/testTexturedPolygon2.png diff --git a/src/test/baseline/testTexturedPolygon3.png b/src/test/baseline/testTexturedPolygon3.png Binary files differnew file mode 100644 index 0000000..31730e0 --- /dev/null +++ b/src/test/baseline/testTexturedPolygon3.png diff --git a/src/test/baseline/testTexturedPolygon4.png b/src/test/baseline/testTexturedPolygon4.png Binary files differnew file mode 100644 index 0000000..333ada7 --- /dev/null +++ b/src/test/baseline/testTexturedPolygon4.png diff --git a/src/test/baseline/testTexturedPolygon5.png b/src/test/baseline/testTexturedPolygon5.png Binary files differnew file mode 100644 index 0000000..e7f7cc4 --- /dev/null +++ b/src/test/baseline/testTexturedPolygon5.png diff --git a/src/test/baseline/testTexturedPolygon6.png b/src/test/baseline/testTexturedPolygon6.png Binary files differnew file mode 100644 index 0000000..1222a19 --- /dev/null +++ b/src/test/baseline/testTexturedPolygon6.png diff --git a/src/test/baseline/testTexturedRect1.png b/src/test/baseline/testTexturedRect1.png Binary files differnew file mode 100644 index 0000000..35edac3 --- /dev/null +++ b/src/test/baseline/testTexturedRect1.png diff --git a/src/test/baseline/testTexturedRect2.png b/src/test/baseline/testTexturedRect2.png Binary files differnew file mode 100644 index 0000000..5d2a0ba --- /dev/null +++ b/src/test/baseline/testTexturedRect2.png diff --git a/src/test/baseline/testTexturedRect3.png b/src/test/baseline/testTexturedRect3.png Binary files differnew file mode 100644 index 0000000..f5f2b77 --- /dev/null +++ b/src/test/baseline/testTexturedRect3.png diff --git a/src/test/baseline/testTexturedRect4.png b/src/test/baseline/testTexturedRect4.png Binary files differnew file mode 100644 index 0000000..795a7ad --- /dev/null +++ b/src/test/baseline/testTexturedRect4.png diff --git a/src/test/baseline/testTexturedRect5.png b/src/test/baseline/testTexturedRect5.png Binary files differnew file mode 100644 index 0000000..38d6e56 --- /dev/null +++ b/src/test/baseline/testTexturedRect5.png diff --git a/src/test/baseline/testTexturedRect6.png b/src/test/baseline/testTexturedRect6.png Binary files differnew file mode 100644 index 0000000..b124377 --- /dev/null +++ b/src/test/baseline/testTexturedRect6.png diff --git a/src/test/baseline/testTexturedRect7.png b/src/test/baseline/testTexturedRect7.png Binary files differnew file mode 100644 index 0000000..ed51fa1 --- /dev/null +++ b/src/test/baseline/testTexturedRect7.png diff --git a/src/test/baseline/testTexturedRect8.png b/src/test/baseline/testTexturedRect8.png Binary files differnew file mode 100644 index 0000000..ddf74a2 --- /dev/null +++ b/src/test/baseline/testTexturedRect8.png diff --git a/src/test/baseline/testTimeSliderHoriz1.png b/src/test/baseline/testTimeSliderHoriz1.png Binary files differnew file mode 100644 index 0000000..42c0eca --- /dev/null +++ b/src/test/baseline/testTimeSliderHoriz1.png diff --git a/src/test/baseline/testTimeSliderHoriz2.png b/src/test/baseline/testTimeSliderHoriz2.png Binary files differnew file mode 100644 index 0000000..a42b8ca --- /dev/null +++ b/src/test/baseline/testTimeSliderHoriz2.png diff --git a/src/test/baseline/testTimeSliderHoriz3.png b/src/test/baseline/testTimeSliderHoriz3.png Binary files differnew file mode 100644 index 0000000..4908be5 --- /dev/null +++ b/src/test/baseline/testTimeSliderHoriz3.png diff --git a/src/test/baseline/testTimeSliderHoriz4.png b/src/test/baseline/testTimeSliderHoriz4.png Binary files differnew file mode 100644 index 0000000..1371480 --- /dev/null +++ b/src/test/baseline/testTimeSliderHoriz4.png diff --git a/src/test/baseline/testTimeSliderHoriz5.png b/src/test/baseline/testTimeSliderHoriz5.png Binary files differnew file mode 100644 index 0000000..1371480 --- /dev/null +++ b/src/test/baseline/testTimeSliderHoriz5.png diff --git a/src/test/baseline/testTimeSliderVert1.png b/src/test/baseline/testTimeSliderVert1.png Binary files differnew file mode 100644 index 0000000..8b31bac --- /dev/null +++ b/src/test/baseline/testTimeSliderVert1.png diff --git a/src/test/baseline/testTimeSliderVert2.png b/src/test/baseline/testTimeSliderVert2.png Binary files differnew file mode 100644 index 0000000..79be7d1 --- /dev/null +++ b/src/test/baseline/testTimeSliderVert2.png diff --git a/src/test/baseline/testTimeSliderVert3.png b/src/test/baseline/testTimeSliderVert3.png Binary files differnew file mode 100644 index 0000000..a3a8718 --- /dev/null +++ b/src/test/baseline/testTimeSliderVert3.png diff --git a/src/test/baseline/testTimeSliderVert4.png b/src/test/baseline/testTimeSliderVert4.png Binary files differnew file mode 100644 index 0000000..f64996b --- /dev/null +++ b/src/test/baseline/testTimeSliderVert4.png diff --git a/src/test/baseline/testTimeSliderVert5.png b/src/test/baseline/testTimeSliderVert5.png Binary files differnew file mode 100644 index 0000000..f64996b --- /dev/null +++ b/src/test/baseline/testTimeSliderVert5.png diff --git a/src/test/baseline/testUIButtonDisabled.png b/src/test/baseline/testUIButtonDisabled.png Binary files differnew file mode 100644 index 0000000..9e00094 --- /dev/null +++ b/src/test/baseline/testUIButtonDisabled.png diff --git a/src/test/baseline/testUIButtonDown.png b/src/test/baseline/testUIButtonDown.png Binary files differnew file mode 100644 index 0000000..c9e3369 --- /dev/null +++ b/src/test/baseline/testUIButtonDown.png diff --git a/src/test/baseline/testUIButtonUp.png b/src/test/baseline/testUIButtonUp.png Binary files differnew file mode 100644 index 0000000..f385f38 --- /dev/null +++ b/src/test/baseline/testUIButtonUp.png diff --git a/src/test/baseline/testUICheckBoxChecked_Down.png b/src/test/baseline/testUICheckBoxChecked_Down.png Binary files differnew file mode 100644 index 0000000..73818b9 --- /dev/null +++ b/src/test/baseline/testUICheckBoxChecked_Down.png diff --git a/src/test/baseline/testUICheckBoxChecked_Up.png b/src/test/baseline/testUICheckBoxChecked_Up.png Binary files differnew file mode 100644 index 0000000..a4af8c9 --- /dev/null +++ b/src/test/baseline/testUICheckBoxChecked_Up.png diff --git a/src/test/baseline/testUICheckBoxUnchecked_Disabled.png b/src/test/baseline/testUICheckBoxUnchecked_Disabled.png Binary files differnew file mode 100644 index 0000000..ebcb3ef --- /dev/null +++ b/src/test/baseline/testUICheckBoxUnchecked_Disabled.png diff --git a/src/test/baseline/testUICheckBoxUnchecked_Down.png b/src/test/baseline/testUICheckBoxUnchecked_Down.png Binary files differnew file mode 100644 index 0000000..4967f44 --- /dev/null +++ b/src/test/baseline/testUICheckBoxUnchecked_Down.png diff --git a/src/test/baseline/testUICheckBoxUnchecked_Up.png b/src/test/baseline/testUICheckBoxUnchecked_Up.png Binary files differnew file mode 100644 index 0000000..1c102e7 --- /dev/null +++ b/src/test/baseline/testUICheckBoxUnchecked_Up.png diff --git a/src/test/baseline/testUIKeyboard.png b/src/test/baseline/testUIKeyboard.png Binary files differnew file mode 100644 index 0000000..87d23a2 --- /dev/null +++ b/src/test/baseline/testUIKeyboard.png diff --git a/src/test/baseline/testUIKeyboard1S.png b/src/test/baseline/testUIKeyboard1S.png Binary files differnew file mode 100644 index 0000000..d7f0606 --- /dev/null +++ b/src/test/baseline/testUIKeyboard1S.png diff --git a/src/test/baseline/testUIKeyboardA.png b/src/test/baseline/testUIKeyboardA.png Binary files differnew file mode 100644 index 0000000..0012b33 --- /dev/null +++ b/src/test/baseline/testUIKeyboardA.png diff --git a/src/test/baseline/testUIKeyboardA1S.png b/src/test/baseline/testUIKeyboardA1S.png Binary files differnew file mode 100644 index 0000000..f2ccd3a --- /dev/null +++ b/src/test/baseline/testUIKeyboardA1S.png diff --git a/src/test/baseline/testUIKeyboardAS.png b/src/test/baseline/testUIKeyboardAS.png Binary files differnew file mode 100644 index 0000000..cd76aad --- /dev/null +++ b/src/test/baseline/testUIKeyboardAS.png diff --git a/src/test/baseline/testUIKeyboardDown11.png b/src/test/baseline/testUIKeyboardDown11.png Binary files differnew file mode 100644 index 0000000..bfc8a50 --- /dev/null +++ b/src/test/baseline/testUIKeyboardDown11.png diff --git a/src/test/baseline/testUIKeyboardDownA212S2.png b/src/test/baseline/testUIKeyboardDownA212S2.png Binary files differnew file mode 100644 index 0000000..cd79feb --- /dev/null +++ b/src/test/baseline/testUIKeyboardDownA212S2.png diff --git a/src/test/baseline/testUIKeyboardDownA2S1.png b/src/test/baseline/testUIKeyboardDownA2S1.png Binary files differnew file mode 100644 index 0000000..6c07214 --- /dev/null +++ b/src/test/baseline/testUIKeyboardDownA2S1.png diff --git a/src/test/baseline/testUIKeyboardFB.png b/src/test/baseline/testUIKeyboardFB.png Binary files differnew file mode 100644 index 0000000..f4836a1 --- /dev/null +++ b/src/test/baseline/testUIKeyboardFB.png diff --git a/src/test/baseline/testUIKeyboardFB1.png b/src/test/baseline/testUIKeyboardFB1.png Binary files differnew file mode 100644 index 0000000..13a56aa --- /dev/null +++ b/src/test/baseline/testUIKeyboardFB1.png diff --git a/src/test/baseline/testUIKeyboardFBA1S.png b/src/test/baseline/testUIKeyboardFBA1S.png Binary files differnew file mode 100644 index 0000000..e9e5534 --- /dev/null +++ b/src/test/baseline/testUIKeyboardFBA1S.png diff --git a/src/test/baseline/testUIKeyboardFBAS.png b/src/test/baseline/testUIKeyboardFBAS.png Binary files differnew file mode 100644 index 0000000..0e10aaf --- /dev/null +++ b/src/test/baseline/testUIKeyboardFBAS.png diff --git a/src/test/baseline/testUIKeyboardFBS.png b/src/test/baseline/testUIKeyboardFBS.png Binary files differnew file mode 100644 index 0000000..9e0964a --- /dev/null +++ b/src/test/baseline/testUIKeyboardFBS.png diff --git a/src/test/baseline/testUIKeyboardNoFB1S.png b/src/test/baseline/testUIKeyboardNoFB1S.png Binary files differnew file mode 100644 index 0000000..4c91d91 --- /dev/null +++ b/src/test/baseline/testUIKeyboardNoFB1S.png diff --git a/src/test/baseline/testUIKeyboardS.png b/src/test/baseline/testUIKeyboardS.png Binary files differnew file mode 100644 index 0000000..12a6c9f --- /dev/null +++ b/src/test/baseline/testUIKeyboardS.png diff --git a/src/test/baseline/testUIToggleChecked_Disabled.png b/src/test/baseline/testUIToggleChecked_Disabled.png Binary files differnew file mode 100644 index 0000000..6a23dda --- /dev/null +++ b/src/test/baseline/testUIToggleChecked_Disabled.png diff --git a/src/test/baseline/testUIToggleChecked_Down.png b/src/test/baseline/testUIToggleChecked_Down.png Binary files differnew file mode 100644 index 0000000..a17041f --- /dev/null +++ b/src/test/baseline/testUIToggleChecked_Down.png diff --git a/src/test/baseline/testUIToggleChecked_Up.png b/src/test/baseline/testUIToggleChecked_Up.png Binary files differnew file mode 100644 index 0000000..03f2f41 --- /dev/null +++ b/src/test/baseline/testUIToggleChecked_Up.png diff --git a/src/test/baseline/testUIToggleUnchecked_Disabled.png b/src/test/baseline/testUIToggleUnchecked_Disabled.png Binary files differnew file mode 100644 index 0000000..8fccaa6 --- /dev/null +++ b/src/test/baseline/testUIToggleUnchecked_Disabled.png diff --git a/src/test/baseline/testUIToggleUnchecked_Down.png b/src/test/baseline/testUIToggleUnchecked_Down.png Binary files differnew file mode 100644 index 0000000..bbad224 --- /dev/null +++ b/src/test/baseline/testUIToggleUnchecked_Down.png diff --git a/src/test/baseline/testUIToggleUnchecked_Up.png b/src/test/baseline/testUIToggleUnchecked_Up.png Binary files differnew file mode 100644 index 0000000..a6f08f0 --- /dev/null +++ b/src/test/baseline/testUIToggleUnchecked_Up.png diff --git a/src/test/baseline/testVideo-h264-48x48.h2641.png b/src/test/baseline/testVideo-h264-48x48.h2641.png Binary files differnew file mode 100644 index 0000000..5adc733 --- /dev/null +++ b/src/test/baseline/testVideo-h264-48x48.h2641.png diff --git a/src/test/baseline/testVideo-mjpeg-48x48.avi1.png b/src/test/baseline/testVideo-mjpeg-48x48.avi1.png Binary files differnew file mode 100644 index 0000000..a16beec --- /dev/null +++ b/src/test/baseline/testVideo-mjpeg-48x48.avi1.png diff --git a/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png b/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png Binary files differnew file mode 100644 index 0000000..043fa46 --- /dev/null +++ b/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png diff --git a/src/test/baseline/testVideo-mpeg1-48x48.mov1.png b/src/test/baseline/testVideo-mpeg1-48x48.mov1.png Binary files differnew file mode 100644 index 0000000..ad9dcf8 --- /dev/null +++ b/src/test/baseline/testVideo-mpeg1-48x48.mov1.png diff --git a/src/test/baseline/testVideo-rgba-48x48.mov1.png b/src/test/baseline/testVideo-rgba-48x48.mov1.png Binary files differnew file mode 100644 index 0000000..700b042 --- /dev/null +++ b/src/test/baseline/testVideo-rgba-48x48.mov1.png diff --git a/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png b/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png Binary files differnew file mode 100644 index 0000000..970e6a4 --- /dev/null +++ b/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png diff --git a/src/test/baseline/testVideoActive1.png b/src/test/baseline/testVideoActive1.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testVideoActive1.png diff --git a/src/test/baseline/testVideoActive2.png b/src/test/baseline/testVideoActive2.png Binary files differnew file mode 100644 index 0000000..0f1b555 --- /dev/null +++ b/src/test/baseline/testVideoActive2.png diff --git a/src/test/baseline/testVideoDynamics1.png b/src/test/baseline/testVideoDynamics1.png Binary files differnew file mode 100644 index 0000000..3eca9a4 --- /dev/null +++ b/src/test/baseline/testVideoDynamics1.png diff --git a/src/test/baseline/testVideoDynamics2.png b/src/test/baseline/testVideoDynamics2.png Binary files differnew file mode 100644 index 0000000..8e8716c --- /dev/null +++ b/src/test/baseline/testVideoDynamics2.png diff --git a/src/test/baseline/testVideoDynamics3.png b/src/test/baseline/testVideoDynamics3.png Binary files differnew file mode 100644 index 0000000..90bde83 --- /dev/null +++ b/src/test/baseline/testVideoDynamics3.png diff --git a/src/test/baseline/testVideoDynamics4.png b/src/test/baseline/testVideoDynamics4.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testVideoDynamics4.png diff --git a/src/test/baseline/testVideoDynamics5.png b/src/test/baseline/testVideoDynamics5.png Binary files differnew file mode 100644 index 0000000..3eca9a4 --- /dev/null +++ b/src/test/baseline/testVideoDynamics5.png diff --git a/src/test/baseline/testVideoFPS.png b/src/test/baseline/testVideoFPS.png Binary files differnew file mode 100644 index 0000000..70e60fd --- /dev/null +++ b/src/test/baseline/testVideoFPS.png diff --git a/src/test/baseline/testVideoHRef1.png b/src/test/baseline/testVideoHRef1.png Binary files differnew file mode 100644 index 0000000..c463313 --- /dev/null +++ b/src/test/baseline/testVideoHRef1.png diff --git a/src/test/baseline/testVideoLoop.png b/src/test/baseline/testVideoLoop.png Binary files differnew file mode 100644 index 0000000..ad9dcf8 --- /dev/null +++ b/src/test/baseline/testVideoLoop.png diff --git a/src/test/baseline/testVideoMaskRGBA1.png b/src/test/baseline/testVideoMaskRGBA1.png Binary files differnew file mode 100644 index 0000000..2ddf341 --- /dev/null +++ b/src/test/baseline/testVideoMaskRGBA1.png diff --git a/src/test/baseline/testVideoMaskRGBA2.png b/src/test/baseline/testVideoMaskRGBA2.png Binary files differnew file mode 100644 index 0000000..12fccc3 --- /dev/null +++ b/src/test/baseline/testVideoMaskRGBA2.png diff --git a/src/test/baseline/testVideoMaskRGBA3.png b/src/test/baseline/testVideoMaskRGBA3.png Binary files differnew file mode 100644 index 0000000..9241d08 --- /dev/null +++ b/src/test/baseline/testVideoMaskRGBA3.png diff --git a/src/test/baseline/testVideoMaskRGBA4.png b/src/test/baseline/testVideoMaskRGBA4.png Binary files differnew file mode 100644 index 0000000..2b00886 --- /dev/null +++ b/src/test/baseline/testVideoMaskRGBA4.png diff --git a/src/test/baseline/testVideoMaskYUV1.png b/src/test/baseline/testVideoMaskYUV1.png Binary files differnew file mode 100644 index 0000000..9b3cb7b --- /dev/null +++ b/src/test/baseline/testVideoMaskYUV1.png diff --git a/src/test/baseline/testVideoMaskYUV2.png b/src/test/baseline/testVideoMaskYUV2.png Binary files differnew file mode 100644 index 0000000..978f3a6 --- /dev/null +++ b/src/test/baseline/testVideoMaskYUV2.png diff --git a/src/test/baseline/testVideoMaskYUV3.png b/src/test/baseline/testVideoMaskYUV3.png Binary files differnew file mode 100644 index 0000000..238edc4 --- /dev/null +++ b/src/test/baseline/testVideoMaskYUV3.png diff --git a/src/test/baseline/testVideoMaskYUV4.png b/src/test/baseline/testVideoMaskYUV4.png Binary files differnew file mode 100644 index 0000000..e4379a3 --- /dev/null +++ b/src/test/baseline/testVideoMaskYUV4.png diff --git a/src/test/baseline/testVideoMaskYUVJ1.png b/src/test/baseline/testVideoMaskYUVJ1.png Binary files differnew file mode 100644 index 0000000..ccb7e0d --- /dev/null +++ b/src/test/baseline/testVideoMaskYUVJ1.png diff --git a/src/test/baseline/testVideoMaskYUVJ2.png b/src/test/baseline/testVideoMaskYUVJ2.png Binary files differnew file mode 100644 index 0000000..bfbd99c --- /dev/null +++ b/src/test/baseline/testVideoMaskYUVJ2.png diff --git a/src/test/baseline/testVideoMaskYUVJ3.png b/src/test/baseline/testVideoMaskYUVJ3.png Binary files differnew file mode 100644 index 0000000..bf95a39 --- /dev/null +++ b/src/test/baseline/testVideoMaskYUVJ3.png diff --git a/src/test/baseline/testVideoMaskYUVJ4.png b/src/test/baseline/testVideoMaskYUVJ4.png Binary files differnew file mode 100644 index 0000000..b0f6e66 --- /dev/null +++ b/src/test/baseline/testVideoMaskYUVJ4.png diff --git a/src/test/baseline/testVideoNullFX.png b/src/test/baseline/testVideoNullFX.png Binary files differnew file mode 100644 index 0000000..9c1a999 --- /dev/null +++ b/src/test/baseline/testVideoNullFX.png diff --git a/src/test/baseline/testVideoOpacityRGBA1.png b/src/test/baseline/testVideoOpacityRGBA1.png Binary files differnew file mode 100644 index 0000000..e98478f --- /dev/null +++ b/src/test/baseline/testVideoOpacityRGBA1.png diff --git a/src/test/baseline/testVideoOpacityRGBA2.png b/src/test/baseline/testVideoOpacityRGBA2.png Binary files differnew file mode 100644 index 0000000..00cf166 --- /dev/null +++ b/src/test/baseline/testVideoOpacityRGBA2.png diff --git a/src/test/baseline/testVideoOpacityYUV1.png b/src/test/baseline/testVideoOpacityYUV1.png Binary files differnew file mode 100644 index 0000000..d27fda0 --- /dev/null +++ b/src/test/baseline/testVideoOpacityYUV1.png diff --git a/src/test/baseline/testVideoOpacityYUV2.png b/src/test/baseline/testVideoOpacityYUV2.png Binary files differnew file mode 100644 index 0000000..152df47 --- /dev/null +++ b/src/test/baseline/testVideoOpacityYUV2.png diff --git a/src/test/baseline/testVideoSeek0.png b/src/test/baseline/testVideoSeek0.png Binary files differnew file mode 100644 index 0000000..e0046ba --- /dev/null +++ b/src/test/baseline/testVideoSeek0.png diff --git a/src/test/baseline/testVideoSeek1.png b/src/test/baseline/testVideoSeek1.png Binary files differnew file mode 100644 index 0000000..6f658da --- /dev/null +++ b/src/test/baseline/testVideoSeek1.png diff --git a/src/test/baseline/testVideoSeek2.png b/src/test/baseline/testVideoSeek2.png Binary files differnew file mode 100644 index 0000000..6a48ed4 --- /dev/null +++ b/src/test/baseline/testVideoSeek2.png diff --git a/src/test/baseline/testVideoSeek3.png b/src/test/baseline/testVideoSeek3.png Binary files differnew file mode 100644 index 0000000..c436802 --- /dev/null +++ b/src/test/baseline/testVideoSeek3.png diff --git a/src/test/baseline/testVideoState1.png b/src/test/baseline/testVideoState1.png Binary files differnew file mode 100644 index 0000000..ad9dcf8 --- /dev/null +++ b/src/test/baseline/testVideoState1.png diff --git a/src/test/baseline/testVideoState2.png b/src/test/baseline/testVideoState2.png Binary files differnew file mode 100644 index 0000000..fed9567 --- /dev/null +++ b/src/test/baseline/testVideoState2.png diff --git a/src/test/baseline/testVideoState3.png b/src/test/baseline/testVideoState3.png Binary files differnew file mode 100644 index 0000000..b7bc073 --- /dev/null +++ b/src/test/baseline/testVideoState3.png diff --git a/src/test/baseline/testVideoState4.png b/src/test/baseline/testVideoState4.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testVideoState4.png diff --git a/src/test/baseline/testVideoState5.png b/src/test/baseline/testVideoState5.png Binary files differnew file mode 100644 index 0000000..ad9dcf8 --- /dev/null +++ b/src/test/baseline/testVideoState5.png diff --git a/src/test/baseline/testVideoWriter1.png b/src/test/baseline/testVideoWriter1.png Binary files differnew file mode 100644 index 0000000..6a9f728 --- /dev/null +++ b/src/test/baseline/testVideoWriter1.png diff --git a/src/test/baseline/testVideoWriterCanvas1.png b/src/test/baseline/testVideoWriterCanvas1.png Binary files differnew file mode 100644 index 0000000..b319da2 --- /dev/null +++ b/src/test/baseline/testVideoWriterCanvas1.png diff --git a/src/test/baseline/testWarp1.png b/src/test/baseline/testWarp1.png Binary files differnew file mode 100644 index 0000000..99ddc2f --- /dev/null +++ b/src/test/baseline/testWarp1.png diff --git a/src/test/baseline/testWarp2.png b/src/test/baseline/testWarp2.png Binary files differnew file mode 100644 index 0000000..0dca03a --- /dev/null +++ b/src/test/baseline/testWarp2.png diff --git a/src/test/baseline/testWarp3.png b/src/test/baseline/testWarp3.png Binary files differnew file mode 100644 index 0000000..357a1b3 --- /dev/null +++ b/src/test/baseline/testWarp3.png diff --git a/src/test/baseline/testWordsBR.png b/src/test/baseline/testWordsBR.png Binary files differnew file mode 100644 index 0000000..82df070 --- /dev/null +++ b/src/test/baseline/testWordsBR.png diff --git a/src/test/baseline/testWordsDynamics1.png b/src/test/baseline/testWordsDynamics1.png Binary files differnew file mode 100644 index 0000000..c68081b --- /dev/null +++ b/src/test/baseline/testWordsDynamics1.png diff --git a/src/test/baseline/testWordsDynamics2.png b/src/test/baseline/testWordsDynamics2.png Binary files differnew file mode 100644 index 0000000..ff6c80f --- /dev/null +++ b/src/test/baseline/testWordsDynamics2.png diff --git a/src/test/baseline/testWordsDynamics3.png b/src/test/baseline/testWordsDynamics3.png Binary files differnew file mode 100644 index 0000000..ff6c80f --- /dev/null +++ b/src/test/baseline/testWordsDynamics3.png diff --git a/src/test/baseline/testWordsDynamics4.png b/src/test/baseline/testWordsDynamics4.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testWordsDynamics4.png diff --git a/src/test/baseline/testWordsDynamics5.png b/src/test/baseline/testWordsDynamics5.png Binary files differnew file mode 100644 index 0000000..c68081b --- /dev/null +++ b/src/test/baseline/testWordsDynamics5.png diff --git a/src/test/baseline/testWordsGamma1.png b/src/test/baseline/testWordsGamma1.png Binary files differnew file mode 100644 index 0000000..9586c80 --- /dev/null +++ b/src/test/baseline/testWordsGamma1.png diff --git a/src/test/baseline/testWordsGamma2.png b/src/test/baseline/testWordsGamma2.png Binary files differnew file mode 100644 index 0000000..f5c2367 --- /dev/null +++ b/src/test/baseline/testWordsGamma2.png diff --git a/src/test/baseline/testWordsIntensity.png b/src/test/baseline/testWordsIntensity.png Binary files differnew file mode 100644 index 0000000..c49904e --- /dev/null +++ b/src/test/baseline/testWordsIntensity.png diff --git a/src/test/baseline/testWordsMask1.png b/src/test/baseline/testWordsMask1.png Binary files differnew file mode 100644 index 0000000..10affb2 --- /dev/null +++ b/src/test/baseline/testWordsMask1.png diff --git a/src/test/baseline/testWordsMask2.png b/src/test/baseline/testWordsMask2.png Binary files differnew file mode 100644 index 0000000..093b6a3 --- /dev/null +++ b/src/test/baseline/testWordsMask2.png diff --git a/src/test/baseline/testWordsMask3.png b/src/test/baseline/testWordsMask3.png Binary files differnew file mode 100644 index 0000000..2a6e464 --- /dev/null +++ b/src/test/baseline/testWordsMask3.png diff --git a/src/test/baseline/testWordsMask4.png b/src/test/baseline/testWordsMask4.png Binary files differnew file mode 100644 index 0000000..a65df77 --- /dev/null +++ b/src/test/baseline/testWordsMask4.png diff --git a/src/test/baseline/testWordsMask5.png b/src/test/baseline/testWordsMask5.png Binary files differnew file mode 100644 index 0000000..3df07d1 --- /dev/null +++ b/src/test/baseline/testWordsMask5.png diff --git a/src/test/baseline/testWordsMask6.png b/src/test/baseline/testWordsMask6.png Binary files differnew file mode 100644 index 0000000..7c592c6 --- /dev/null +++ b/src/test/baseline/testWordsMask6.png diff --git a/src/test/baseline/testWordsMask7.png b/src/test/baseline/testWordsMask7.png Binary files differnew file mode 100644 index 0000000..6be97bc --- /dev/null +++ b/src/test/baseline/testWordsMask7.png diff --git a/src/test/baseline/testWordsNullFX.png b/src/test/baseline/testWordsNullFX.png Binary files differnew file mode 100644 index 0000000..3197c3d --- /dev/null +++ b/src/test/baseline/testWordsNullFX.png diff --git a/src/test/baseline/testWordsOutlines.png b/src/test/baseline/testWordsOutlines.png Binary files differnew file mode 100644 index 0000000..6187147 --- /dev/null +++ b/src/test/baseline/testWordsOutlines.png diff --git a/src/test/baseline/testWordsShadowFX1.png b/src/test/baseline/testWordsShadowFX1.png Binary files differnew file mode 100644 index 0000000..bd50822 --- /dev/null +++ b/src/test/baseline/testWordsShadowFX1.png diff --git a/src/test/baseline/testWordsShadowFX2.png b/src/test/baseline/testWordsShadowFX2.png Binary files differnew file mode 100644 index 0000000..84b503c --- /dev/null +++ b/src/test/baseline/testWordsShadowFX2.png diff --git a/src/test/baseline/testWrapMode1.png b/src/test/baseline/testWrapMode1.png Binary files differnew file mode 100644 index 0000000..cff05d0 --- /dev/null +++ b/src/test/baseline/testWrapMode1.png diff --git a/src/test/baseline/testWrapMode2.png b/src/test/baseline/testWrapMode2.png Binary files differnew file mode 100644 index 0000000..596cdb6 --- /dev/null +++ b/src/test/baseline/testWrapMode2.png diff --git a/src/test/baseline/testWrapMode3.png b/src/test/baseline/testWrapMode3.png Binary files differnew file mode 100644 index 0000000..cff05d0 --- /dev/null +++ b/src/test/baseline/testWrapMode3.png diff --git a/src/test/baseline/testWrapMode4.png b/src/test/baseline/testWrapMode4.png Binary files differnew file mode 100644 index 0000000..6d17b93 --- /dev/null +++ b/src/test/baseline/testWrapMode4.png diff --git a/src/test/baseline/testXPosPointAnim1.png b/src/test/baseline/testXPosPointAnim1.png Binary files differnew file mode 100644 index 0000000..ce2f589 --- /dev/null +++ b/src/test/baseline/testXPosPointAnim1.png diff --git a/src/test/baseline/testXPosPointAnim2.png b/src/test/baseline/testXPosPointAnim2.png Binary files differnew file mode 100644 index 0000000..84eca4f --- /dev/null +++ b/src/test/baseline/testXPosPointAnim2.png diff --git a/src/test/baseline/testXPosPointAnim3.png b/src/test/baseline/testXPosPointAnim3.png Binary files differnew file mode 100644 index 0000000..84eca4f --- /dev/null +++ b/src/test/baseline/testXPosPointAnim3.png diff --git a/src/test/baseline/testYPosPointAnim1.png b/src/test/baseline/testYPosPointAnim1.png Binary files differnew file mode 100644 index 0000000..ce2f589 --- /dev/null +++ b/src/test/baseline/testYPosPointAnim1.png diff --git a/src/test/baseline/testYPosPointAnim2.png b/src/test/baseline/testYPosPointAnim2.png Binary files differnew file mode 100644 index 0000000..39d093e --- /dev/null +++ b/src/test/baseline/testYPosPointAnim2.png diff --git a/src/test/baseline/testYPosPointAnim3.png b/src/test/baseline/testYPosPointAnim3.png Binary files differnew file mode 100644 index 0000000..39d093e --- /dev/null +++ b/src/test/baseline/testYPosPointAnim3.png diff --git a/src/test/baseline/testbasics.png b/src/test/baseline/testbasics.png Binary files differnew file mode 100644 index 0000000..4c1afa7 --- /dev/null +++ b/src/test/baseline/testbasics.png diff --git a/src/test/baseline/testline1.png b/src/test/baseline/testline1.png Binary files differnew file mode 100644 index 0000000..b499abd --- /dev/null +++ b/src/test/baseline/testline1.png diff --git a/src/test/baseline/testline2.png b/src/test/baseline/testline2.png Binary files differnew file mode 100644 index 0000000..c307bd7 --- /dev/null +++ b/src/test/baseline/testline2.png diff --git a/src/test/baseline/testline3.png b/src/test/baseline/testline3.png Binary files differnew file mode 100644 index 0000000..c1a7795 --- /dev/null +++ b/src/test/baseline/testline3.png diff --git a/src/test/baseline/testline4.png b/src/test/baseline/testline4.png Binary files differnew file mode 100644 index 0000000..b086840 --- /dev/null +++ b/src/test/baseline/testline4.png diff --git a/src/test/baseline/testlineopacity1.png b/src/test/baseline/testlineopacity1.png Binary files differnew file mode 100644 index 0000000..0c11d1c --- /dev/null +++ b/src/test/baseline/testlineopacity1.png diff --git a/src/test/baseline/testlineopacity2.png b/src/test/baseline/testlineopacity2.png Binary files differnew file mode 100644 index 0000000..ee9b3e7 --- /dev/null +++ b/src/test/baseline/testlineopacity2.png diff --git a/src/test/baseline/testlotsoflines.png b/src/test/baseline/testlotsoflines.png Binary files differnew file mode 100644 index 0000000..485d9c5 --- /dev/null +++ b/src/test/baseline/testlotsoflines.png diff --git a/src/test/baseline/testplugin1.png b/src/test/baseline/testplugin1.png Binary files differnew file mode 100644 index 0000000..fd07f6c --- /dev/null +++ b/src/test/baseline/testplugin1.png diff --git a/src/test/baseline/testplugin2.png b/src/test/baseline/testplugin2.png Binary files differnew file mode 100644 index 0000000..2ec2e11 --- /dev/null +++ b/src/test/baseline/testplugin2.png diff --git a/src/test/baseline/testtexturedline1.png b/src/test/baseline/testtexturedline1.png Binary files differnew file mode 100644 index 0000000..d4b3719 --- /dev/null +++ b/src/test/baseline/testtexturedline1.png diff --git a/src/test/baseline/testtexturedline2.png b/src/test/baseline/testtexturedline2.png Binary files differnew file mode 100644 index 0000000..174636b --- /dev/null +++ b/src/test/baseline/testtexturedline2.png diff --git a/src/test/baseline/testtexturedline3.png b/src/test/baseline/testtexturedline3.png Binary files differnew file mode 100644 index 0000000..7ac3757 --- /dev/null +++ b/src/test/baseline/testtexturedline3.png diff --git a/src/test/baseline/testtexturedline4.png b/src/test/baseline/testtexturedline4.png Binary files differnew file mode 100644 index 0000000..07b7750 --- /dev/null +++ b/src/test/baseline/testtexturedline4.png diff --git a/src/test/baseline/testtexturedline5.png b/src/test/baseline/testtexturedline5.png Binary files differnew file mode 100644 index 0000000..7ffeed2 --- /dev/null +++ b/src/test/baseline/testtexturedline5.png diff --git a/src/test/camcfgs.py b/src/test/camcfgs.py new file mode 100644 index 0000000..5c65229 --- /dev/null +++ b/src/test/camcfgs.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# -*- 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 +# + +class CameraTestCfg: + def __init__(self, driver, device, unit, fw800, formats, illegalFormat, paramTests, + defaultParams): + self.driver = driver + self.device = device + self.unit = unit + self.fw800 = fw800 + + self.formats = formats + self.illegalFormat = illegalFormat + self.paramTests = paramTests + self.defaultParams = defaultParams + +class CameraFormatCfg: + def __init__(self, size, pixelformat, framerate): + self.size = size + self.pixelformat = pixelformat + self.framerate = framerate + +class ParamTestCfg: + def __init__(self, name, testValues, minMedDiff, medMaxDiff): + self.name = name + self.testValues = testValues + self.minMedDiff = minMedDiff + self.medMaxDiff = medMaxDiff + +DFx31BF03Cfg = CameraTestCfg('firewire', '', -1, False, + [CameraFormatCfg((1024,768), 'BAYER8', 30), + CameraFormatCfg((1024,768), 'I8', 30), + CameraFormatCfg((1024,768), 'YUV422', 15), + CameraFormatCfg((1024,768), 'YUV422', 7.5)], + CameraFormatCfg((320,240), 'BAYER8', 30), + [ParamTestCfg('gain', (180, 800, 1023), 6, 6), + ParamTestCfg('camgamma', (10, 16, 22), 15, 15), + ParamTestCfg('brightness', (0, 127, 254), 8, 8)], + {'gain':300, 'shutter':220, 'saturation':1200, 'camgamma':16, + 'brightness':120, 'setWhitebalance':[450, 450]} + ) + +FireflyMV = CameraTestCfg('firewire', '', -1, False, + [CameraFormatCfg((640, 480), 'I8', 7.5), + CameraFormatCfg((640, 480), 'I8', 15), + CameraFormatCfg((640, 480), 'I8', 60), + CameraFormatCfg((640, 480), 'I16', 7.5), + CameraFormatCfg((640, 480), 'I16', 15), + CameraFormatCfg((640, 480), 'I16', 30)], + CameraFormatCfg((640, 480), 'I8', 30), + [ParamTestCfg('gain', (16, 30, 64), 15, 15), + ParamTestCfg('shutter', (1, 150, 531), 50, 20), + ParamTestCfg('brightness', (1, 130, 255), 10, 10)], + {'gain':16, 'shutter':100, 'brightness':130} + ) + +Dragonfly2 = CameraTestCfg('firewire', '', -1, False, + [CameraFormatCfg((640,480), 'RGB', 30), + CameraFormatCfg((1024,768), 'I8', 15), + CameraFormatCfg((1024,768), 'I16', 15), + CameraFormatCfg((1024,768), 'BAYER8', 30), + CameraFormatCfg((1024,768), 'YUV422', 7.5)], + CameraFormatCfg((123,456), 'RGB', 30), + [ParamTestCfg('gain', (0, 346, 683), 10, 30), + ParamTestCfg('camgamma', (0, 1278, 4095), 30, 50), + ParamTestCfg('brightness', (0, 127, 254), 8, 8)], + {'gain':300, 'shutter':220, 'saturation':1200, 'camgamma':1200, + 'brightness':120, 'setWhitebalance':[450, 450]} + ) + +Firei = CameraTestCfg('firewire', '', -1, False, + [CameraFormatCfg((640,480), 'YUV411', 30), + CameraFormatCfg((640,480), 'RGB', 15), + CameraFormatCfg((640,480), 'YUV422', 15), + CameraFormatCfg((640,480), 'I8', 30), + CameraFormatCfg((320,240), 'YUV422', 7.5)], + CameraFormatCfg((123,456), 'RGB', 30), + #To check: there is something strange with shutter and gain in this camera. + [ParamTestCfg('gain', (1, 100, 255), 10, 30), + ParamTestCfg('brightness', (128, 255, 383), 8, 8), + ParamTestCfg('shutter', (4, 4, 4), 8, 8)], + {'gain':87, 'shutter':6, 'brightness':304, 'setWhitebalance':[95, 87]} + ) + +QuickCamProLinux = CameraTestCfg('video4linux', '', -1, False, + [CameraFormatCfg((352,288), 'YUYV422', 30), + CameraFormatCfg((320,240), 'YUYV422', 15), + CameraFormatCfg((176,144), 'YUYV422', 30), + CameraFormatCfg((640,480), 'YUYV422', 30)], + CameraFormatCfg((123,456), 'I16', 30), + [ParamTestCfg('brightness', (0, 127, 254), 40, 50)], + {'brightness':-1} + ) + +QuickCamPro9Win = CameraTestCfg('directshow', '', -1, False, + [CameraFormatCfg((352,288), 'YUYV422', 30), + CameraFormatCfg((320,240), 'YUYV422', 15), + CameraFormatCfg((640,480), 'YUYV422', 30), + CameraFormatCfg((176,144), 'YUYV422', 30)], + CameraFormatCfg((123,456), 'RGB', 30), + [ParamTestCfg('brightness', (0, 127, 254), 40, 50)], + {'brightness': 60} + ) + +QuickCamProBGRWin = CameraTestCfg('directshow', '', -1, False, + [CameraFormatCfg((352,288), 'BGR', 30), + CameraFormatCfg((320,240), 'BGR', 15), + CameraFormatCfg((640,480), 'BGR', 30), + CameraFormatCfg((176,144), 'BGR', 30)], + CameraFormatCfg((123,456), 'YUYV422', 30), + [ParamTestCfg('brightness', (0, 127, 254), 40, 50)], + {'brightness': 60} + ) + diff --git a/src/test/checkcamera.py b/src/test/checkcamera.py new file mode 100755 index 0000000..1146679 --- /dev/null +++ b/src/test/checkcamera.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python +# -*- 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 +# +# Original author of this file is Robert Parcus <betoparcus@gmail.com> +# + +from libavg import * +import camcfgs +import optparse + +from testcase import * + +def parseCmdLine(): + global g_TestParams + + validCameras = ('Dragonfly', 'FireflyMV', 'Firei', 'DFx31BF03', 'QuickCamProLinux', + 'QuickCamProBGRWin', 'QuickCamPro9Win') + parser = optparse.OptionParser(usage= +"""%prog cameraname [option]. +A test to check camera features support by libavg. Supported cameras are """ ++ str(validCameras)) +# parser.add_argument(dest='camera', action='store', type=str, +# choices=validCameras, help = 'Select which camera model to test.') + parser.add_option('--test-params', '-p', dest='testParams', action='store_true', + default=False, + help='Execute optional tests for camera params like gain, shutter, etc.') + (options, args) = parser.parse_args() + g_TestParams = options.testParams + if len(args) != 1: + parser.error("Must be invoked with camera name as argument") + cameraName = args[0] + if cameraName == 'Dragonfly': + return camcfgs.Dragonfly2 + elif cameraName == 'FireflyMV': + return camcfgs.FireflyMV + elif cameraName == 'Firei': + return camcfgs.Firei + elif cameraName == 'DFx31BF03': + return camcfgs.DFx31BF03Cfg + elif cameraName == 'QuickCamProLinux': + return camcfgs.QuickCamProLinux + elif cameraName == 'QuickCamPro9Win': + return camcfgs.QuickCamPro9Win + elif cameraName == 'QuickCamProBGRWin': + return camcfgs.QuickCamProBGRWin + else: + parser.error("Unknown camera name '" + cameraName + "'.") + +class CameraTestCase(AVGTestCase): + def __init__(self, cameraCfg, fmt, testFuncName, *testFuncArgs): + self.cameraCfg = cameraCfg + self.fmt = fmt + self.testFuncArgs = testFuncArgs + AVGTestCase.__init__(self, testFuncName) + + def testFormat(self): + self.__dumpFormat() + self.loadEmptyScene() + self.__openCamera() + self.actions = [None, None] + avg.player.setOnFrameHandler(self.__onFrame) + avg.player.play() + self.assertEqual(self.cam.framenum, 2) + self.cam = None + + def testIllegalFormat(self): + self.loadEmptyScene() + self.assertException(lambda: self.__openCamera()) + + def testCreateDelete(self): + # Create and delete without ever calling play. + self.__openCamera() + self.cam.unlink(True) + + def testParams(self): + def buildParamActionList(testCfg): + actions = [] + actions.append(setDefaultParams) + actions.append(None) + for val in testCfg.testValues: + actions.append(lambda paramName=testCfg.name, val=val: + setCamParam(paramName, val)) + actions.append(None) + actions.append(None) + actions.append(None) + actions.append(lambda name=testCfg.name: calcCamImgAverage(name)) + actions.append(lambda testCfg=testCfg: checkCamImageChange(testCfg)) + return actions + + def setDefaultParams(): + for (paramName, val) in cameraCfg.defaultParams.iteritems(): + if paramName == "setWhitebalance": + self.cam.setWhitebalance(*val) + else: + setattr(self.cam, paramName, val) + + def setCamParam(paramName, val): + if paramName == 'setwhitebalance': + self.cam.setWhitebalance(*val) + else: + setattr(self.cam, paramName, val) + + def calcCamImgAverage(param): + bmp = self.cam.getBitmap() + self.camBmps.append(bmp) + if isColorParam(param): + colour = [] + colour.append(bmp.getChannelAvg(0)) + colour.append(bmp.getChannelAvg(1)) + colour.append(bmp.getChannelAvg(2)) + self.averages.append(colour) + else: + self.averages.append(bmp.getAvg()) + + def checkCamImageChange(testCfg): + + def saveCamImages(): +# print +# print "Average image brightnesses: ",minAverages, medAverages, maxAverages + dir = AVGTestCase.getImageResultDir() + for (i, category) in enumerate(("min", "med", "max")): + self.camBmps[i].save(dir+"/cam"+testCfg.name+category+".png") + + minAverages = self.averages[0] + medAverages = self.averages[1] + maxAverages = self.averages[2] + ok = False + if isColorParam(testCfg.name): + pass + else: + if minAverages+testCfg.minMedDiff > medAverages: + saveCamImages() + self.fail() + if medAverages+testCfg.medMaxDiff > maxAverages: + saveCamImages() + self.fail() + self.averages = [] + self.camBmps = [] + + def isColorParam(paramName): + return paramName in ['saturation', 'setwhitebalance'] + + testCfg = self.testFuncArgs[0] + print >>sys.stderr, testCfg.name, " ", + self.loadEmptyScene() + self.__openCamera() + self.actions = buildParamActionList(testCfg) + avg.player.setOnFrameHandler(self.__onFrame) + self.averages = [] + self.camBmps = [] + avg.player.play() + self.cam = None + + def __openCamera(self): + self.cam = avg.CameraNode(driver=self.cameraCfg.driver, + device=self.cameraCfg.device, unit=self.cameraCfg.unit, + fw800=self.cameraCfg.fw800, framerate=self.fmt.framerate, + capturewidth=self.fmt.size[0], captureheight=self.fmt.size[1], + pixelformat=self.fmt.pixelformat, + parent=avg.player.getRootNode()) + self.cam.play() + self.lastCameraFrame = -1 + self.assert_(self.cam.isAvailable()) + + def __onFrame(self): + # We execute one action per camera frame. +# print self.cam.framenum + if self.cam.framenum != self.lastCameraFrame: + self.lastCameraFrame += 1 + if len(self.actions) == self.lastCameraFrame: + avg.player.stop() + else: + action = self.actions[self.lastCameraFrame] + if action != None: + action() + + def __dumpFormat(self): + print >>sys.stderr, str(self.fmt.size)+", "+str(self.fmt.pixelformat)+ \ + ", "+str(self.fmt.framerate)+" ", + +def dumpCameraCfg(cfg): + print >>sys.stderr, "Camera config: driver="+cfg.driver+", device="+cfg.device+ \ + ", unit="+str(cfg.unit) + + +cameraCfg = parseCmdLine() +AVGTestCase.cleanResultDir() +suite = unittest.TestSuite() +dumpCameraCfg(cameraCfg) +for fmt in cameraCfg.formats: + suite.addTest(CameraTestCase(cameraCfg, fmt, "testFormat")) +suite.addTest(CameraTestCase(cameraCfg, cameraCfg.illegalFormat, "testIllegalFormat")) +suite.addTest(CameraTestCase(cameraCfg, cameraCfg.formats[0], "testCreateDelete")) +if g_TestParams: + for testCfg in cameraCfg.paramTests: + suite.addTest(CameraTestCase(cameraCfg, cameraCfg.formats[0], "testParams", + testCfg)) +testRunner = unittest.TextTestRunner(verbosity = 2) +testResult = testRunner.run(suite) + +if testResult.wasSuccessful(): + exitCode = 0 +else: + exitCode = 1 +sys.exit(exitCode) + + diff --git a/src/test/extrafonts/testaddfontdir.ttf b/src/test/extrafonts/testaddfontdir.ttf Binary files differnew file mode 100644 index 0000000..d57eda6 --- /dev/null +++ b/src/test/extrafonts/testaddfontdir.ttf diff --git a/src/test/fonts/Vera.ttf b/src/test/fonts/Vera.ttf Binary files differnew file mode 100644 index 0000000..58cd6b5 --- /dev/null +++ b/src/test/fonts/Vera.ttf diff --git a/src/test/fonts/VeraBI.ttf b/src/test/fonts/VeraBI.ttf Binary files differnew file mode 100644 index 0000000..b55eee3 --- /dev/null +++ b/src/test/fonts/VeraBI.ttf diff --git a/src/test/fonts/VeraBd.ttf b/src/test/fonts/VeraBd.ttf Binary files differnew file mode 100644 index 0000000..51d6111 --- /dev/null +++ b/src/test/fonts/VeraBd.ttf diff --git a/src/test/fonts/VeraIt.ttf b/src/test/fonts/VeraIt.ttf Binary files differnew file mode 100644 index 0000000..cc23c9e --- /dev/null +++ b/src/test/fonts/VeraIt.ttf diff --git a/src/test/illustratorRect.svg b/src/test/illustratorRect.svg new file mode 100644 index 0000000..37a4a6d --- /dev/null +++ b/src/test/illustratorRect.svg @@ -0,0 +1,7 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> + +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect id="pos_x5F_rect" x="5" y="15" width="8" height="12" style="fill:rgb(255,0,0);stroke-width:1; stroke:rgb(0,0,255)"/> +</svg> + diff --git a/src/test/image.avg b/src/test/image.avg new file mode 100644 index 0000000..7fc4c13 --- /dev/null +++ b/src/test/image.avg @@ -0,0 +1,8 @@ +<avg id="imageavg" width="160" height="120" mediadir="media"> + <image id="testtiles" pos="(0, 30)" size=" ( 65 , 65 ) " + opacity="1" href="rgb24-65x65.png" maxtilewidth="16" maxtileheight="32"/> + <image id="test" x="64" y="30" + opacity="1" href="rgb24-65x65.png" pivot="(0, 0)" angle="0.274"/> + <image id="test1" x="129" y="30" + opacity="1" href="rgb24-65x65.png"/> +</avg> diff --git a/src/test/media/1x1_white.png b/src/test/media/1x1_white.png Binary files differnew file mode 100644 index 0000000..5800230 --- /dev/null +++ b/src/test/media/1x1_white.png diff --git a/src/test/media/22.050Hz_16bit_mono.wav b/src/test/media/22.050Hz_16bit_mono.wav Binary files differnew file mode 100755 index 0000000..1f86e64 --- /dev/null +++ b/src/test/media/22.050Hz_16bit_mono.wav diff --git a/src/test/media/44.1kHz_16bit_6Chan.ogg b/src/test/media/44.1kHz_16bit_6Chan.ogg Binary files differnew file mode 100644 index 0000000..7d190d1 --- /dev/null +++ b/src/test/media/44.1kHz_16bit_6Chan.ogg diff --git a/src/test/media/44.1kHz_16bit_mono.wav b/src/test/media/44.1kHz_16bit_mono.wav Binary files differnew file mode 100755 index 0000000..8676a75 --- /dev/null +++ b/src/test/media/44.1kHz_16bit_mono.wav diff --git a/src/test/media/44.1kHz_16bit_stereo.aif b/src/test/media/44.1kHz_16bit_stereo.aif Binary files differnew file mode 100755 index 0000000..0c9b5c7 --- /dev/null +++ b/src/test/media/44.1kHz_16bit_stereo.aif diff --git a/src/test/media/44.1kHz_16bit_stereo.wav b/src/test/media/44.1kHz_16bit_stereo.wav Binary files differnew file mode 100755 index 0000000..af5c2ee --- /dev/null +++ b/src/test/media/44.1kHz_16bit_stereo.wav diff --git a/src/test/media/44.1kHz_24bit_mono.wav b/src/test/media/44.1kHz_24bit_mono.wav Binary files differnew file mode 100755 index 0000000..fd2deed --- /dev/null +++ b/src/test/media/44.1kHz_24bit_mono.wav diff --git a/src/test/media/44.1kHz_24bit_stereo.aif b/src/test/media/44.1kHz_24bit_stereo.aif Binary files differnew file mode 100755 index 0000000..f569ded --- /dev/null +++ b/src/test/media/44.1kHz_24bit_stereo.aif diff --git a/src/test/media/44.1kHz_24bit_stereo.wav b/src/test/media/44.1kHz_24bit_stereo.wav Binary files differnew file mode 100755 index 0000000..36c6aa7 --- /dev/null +++ b/src/test/media/44.1kHz_24bit_stereo.wav diff --git a/src/test/media/44.1kHz_mono.ogg b/src/test/media/44.1kHz_mono.ogg Binary files differnew file mode 100755 index 0000000..7bcb866 --- /dev/null +++ b/src/test/media/44.1kHz_mono.ogg diff --git a/src/test/media/44.1kHz_stereo.mp3 b/src/test/media/44.1kHz_stereo.mp3 Binary files differnew file mode 100644 index 0000000..cbefc63 --- /dev/null +++ b/src/test/media/44.1kHz_stereo.mp3 diff --git a/src/test/media/44.1kHz_stereo.ogg b/src/test/media/44.1kHz_stereo.ogg Binary files differnew file mode 100644 index 0000000..f5ed4d0 --- /dev/null +++ b/src/test/media/44.1kHz_stereo.ogg diff --git a/src/test/media/48kHz_16bit_mono.wav b/src/test/media/48kHz_16bit_mono.wav Binary files differnew file mode 100755 index 0000000..0f817c9 --- /dev/null +++ b/src/test/media/48kHz_16bit_mono.wav diff --git a/src/test/media/48kHz_16bit_stereo.aif b/src/test/media/48kHz_16bit_stereo.aif Binary files differnew file mode 100755 index 0000000..db3a381 --- /dev/null +++ b/src/test/media/48kHz_16bit_stereo.aif diff --git a/src/test/media/48kHz_16bit_stereo.wav b/src/test/media/48kHz_16bit_stereo.wav Binary files differnew file mode 100755 index 0000000..9fc52f1 --- /dev/null +++ b/src/test/media/48kHz_16bit_stereo.wav diff --git a/src/test/media/48kHz_24bit_mono.wav b/src/test/media/48kHz_24bit_mono.wav Binary files differnew file mode 100755 index 0000000..296ca11 --- /dev/null +++ b/src/test/media/48kHz_24bit_mono.wav diff --git a/src/test/media/48kHz_24bit_stereo.aif b/src/test/media/48kHz_24bit_stereo.aif Binary files differnew file mode 100755 index 0000000..3ab7cf1 --- /dev/null +++ b/src/test/media/48kHz_24bit_stereo.aif diff --git a/src/test/media/48kHz_24bit_stereo.wav b/src/test/media/48kHz_24bit_stereo.wav Binary files differnew file mode 100755 index 0000000..af2c977 --- /dev/null +++ b/src/test/media/48kHz_24bit_stereo.wav diff --git a/src/test/media/48kHz_stereo.mp3 b/src/test/media/48kHz_stereo.mp3 Binary files differnew file mode 100644 index 0000000..0eaa0f5 --- /dev/null +++ b/src/test/media/48kHz_stereo.mp3 diff --git a/src/test/media/48kHz_stereo.ogg b/src/test/media/48kHz_stereo.ogg Binary files differnew file mode 100644 index 0000000..92d7b7b --- /dev/null +++ b/src/test/media/48kHz_stereo.ogg diff --git a/src/test/media/CustomSkin.xml b/src/test/media/CustomSkin.xml new file mode 100644 index 0000000..3f21274 --- /dev/null +++ b/src/test/media/CustomSkin.xml @@ -0,0 +1,83 @@ +<skin> + <fontdef id="stdFont" font="Bitstream Vera Sans" variant="Roman" fontsize="12" + color="000000" letterspacing="0" linespacing="-1"/> + <fontdef id="downFont" baseid="stdFont" color="CCCCCC"/> + <fontdef id="disabledFont" baseid="stdFont" color="444444"/> + <textbutton + upSrc="button_bg_up.png" + downSrc="button_bg_down.png" + font="stdFont" + downFont="downFont" + disabledFont="disabledFont" + endsExtent="(7,7)"/> + <slider> + <horizontal + trackSrc="slider_horiz_track.png" + trackDisabledSrc="slider_horiz_track_disabled.png" + trackEndsExtent="6" + thumbUpSrc="slider_thumb_up.png" + thumbDownSrc="slider_thumb_down.png"/> + <vertical + trackSrc="slider_vert_track.png" + trackDisabledSrc="slider_vert_track_disabled.png" + trackEndsExtent="6" + thumbUpSrc="slider_thumb_up.png" + thumbDownSrc="slider_thumb_down.png"/> + </slider> + <scrollbar> + <horizontal + trackSrc="scrollbar_horiz_track.png" + trackDisabledSrc="scrollbar_horiz_track_disabled.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_horiz_thumb_up.png" + thumbDownSrc="scrollbar_horiz_thumb_down.png" + thumbEndsExtent="4"/> + <vertical + trackSrc="scrollbar_vert_track.png" + trackDisabledSrc="scrollbar_vert_track_disabled.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_vert_thumb_up.png" + thumbDownSrc="scrollbar_vert_thumb_down.png" + thumbEndsExtent="4"/> + </scrollbar> + <progressbar> + <horizontal + trackSrc="scrollbar_horiz_track.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_horiz_thumb_up.png" + thumbDisabledSrc="scrollbar_vert_thumb_down.png" + thumbEndsExtent="4"/> + <vertical + trackSrc="scrollbar_vert_track.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_vert_thumb_up.png" + thumbDisabledSrc="scrollbar_vert_thumb_down.png" + thumbEndsExtent="4"/> + </progressbar> + <scrollarea + borderSrc="scrollarea_border.png" + borderEndsExtent="(8,8)" + margins="(1,1,8,8)" + friction="-1" + sensitiveScrollBars="True"/> + <checkbox + uncheckedUpSrc="checkbox_unchecked_up.png" + uncheckedDownSrc="checkbox_unchecked_down.png" + uncheckedDisabledSrc="checkbox_unchecked_disabled.png" + checkedUpSrc="checkbox_checked_up.png" + checkedDownSrc="checkbox_checked_down.png" + checkedDisabledSrc="checkbox_checked_disabled.png" + font="stdFont" + downFont="stdFont" + disabledFont="disabledFont"/> + <mediacontrol + playUpSrc="play_button_up.png" + playDownSrc="play_button_down.png" + pauseUpSrc="pause_button_up.png" + pauseDownSrc="pause_button_down.png" + font="stdFont" + timePos="(15,0)" + timeLeftPos="(-42,0)" + barPos="(55,2)" + barRight="-45"/> +</skin> diff --git a/src/test/media/SimpleSkin.xml b/src/test/media/SimpleSkin.xml new file mode 100644 index 0000000..3f21274 --- /dev/null +++ b/src/test/media/SimpleSkin.xml @@ -0,0 +1,83 @@ +<skin> + <fontdef id="stdFont" font="Bitstream Vera Sans" variant="Roman" fontsize="12" + color="000000" letterspacing="0" linespacing="-1"/> + <fontdef id="downFont" baseid="stdFont" color="CCCCCC"/> + <fontdef id="disabledFont" baseid="stdFont" color="444444"/> + <textbutton + upSrc="button_bg_up.png" + downSrc="button_bg_down.png" + font="stdFont" + downFont="downFont" + disabledFont="disabledFont" + endsExtent="(7,7)"/> + <slider> + <horizontal + trackSrc="slider_horiz_track.png" + trackDisabledSrc="slider_horiz_track_disabled.png" + trackEndsExtent="6" + thumbUpSrc="slider_thumb_up.png" + thumbDownSrc="slider_thumb_down.png"/> + <vertical + trackSrc="slider_vert_track.png" + trackDisabledSrc="slider_vert_track_disabled.png" + trackEndsExtent="6" + thumbUpSrc="slider_thumb_up.png" + thumbDownSrc="slider_thumb_down.png"/> + </slider> + <scrollbar> + <horizontal + trackSrc="scrollbar_horiz_track.png" + trackDisabledSrc="scrollbar_horiz_track_disabled.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_horiz_thumb_up.png" + thumbDownSrc="scrollbar_horiz_thumb_down.png" + thumbEndsExtent="4"/> + <vertical + trackSrc="scrollbar_vert_track.png" + trackDisabledSrc="scrollbar_vert_track_disabled.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_vert_thumb_up.png" + thumbDownSrc="scrollbar_vert_thumb_down.png" + thumbEndsExtent="4"/> + </scrollbar> + <progressbar> + <horizontal + trackSrc="scrollbar_horiz_track.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_horiz_thumb_up.png" + thumbDisabledSrc="scrollbar_vert_thumb_down.png" + thumbEndsExtent="4"/> + <vertical + trackSrc="scrollbar_vert_track.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_vert_thumb_up.png" + thumbDisabledSrc="scrollbar_vert_thumb_down.png" + thumbEndsExtent="4"/> + </progressbar> + <scrollarea + borderSrc="scrollarea_border.png" + borderEndsExtent="(8,8)" + margins="(1,1,8,8)" + friction="-1" + sensitiveScrollBars="True"/> + <checkbox + uncheckedUpSrc="checkbox_unchecked_up.png" + uncheckedDownSrc="checkbox_unchecked_down.png" + uncheckedDisabledSrc="checkbox_unchecked_disabled.png" + checkedUpSrc="checkbox_checked_up.png" + checkedDownSrc="checkbox_checked_down.png" + checkedDisabledSrc="checkbox_checked_disabled.png" + font="stdFont" + downFont="stdFont" + disabledFont="disabledFont"/> + <mediacontrol + playUpSrc="play_button_up.png" + playDownSrc="play_button_down.png" + pauseUpSrc="pause_button_up.png" + pauseDownSrc="pause_button_down.png" + font="stdFont" + timePos="(15,0)" + timeLeftPos="(-42,0)" + barPos="(55,2)" + barRight="-45"/> +</skin> diff --git a/src/test/media/button_bg_down.png b/src/test/media/button_bg_down.png Binary files differnew file mode 100644 index 0000000..81cbb0f --- /dev/null +++ b/src/test/media/button_bg_down.png diff --git a/src/test/media/button_bg_up.png b/src/test/media/button_bg_up.png Binary files differnew file mode 100644 index 0000000..91cfe04 --- /dev/null +++ b/src/test/media/button_bg_up.png diff --git a/src/test/media/button_check.png b/src/test/media/button_check.png Binary files differnew file mode 100644 index 0000000..b0aa4a9 --- /dev/null +++ b/src/test/media/button_check.png diff --git a/src/test/media/button_disabled.png b/src/test/media/button_disabled.png Binary files differnew file mode 100644 index 0000000..dbf1309 --- /dev/null +++ b/src/test/media/button_disabled.png diff --git a/src/test/media/button_down.png b/src/test/media/button_down.png Binary files differnew file mode 100644 index 0000000..88ee5f5 --- /dev/null +++ b/src/test/media/button_down.png diff --git a/src/test/media/button_over.png b/src/test/media/button_over.png Binary files differnew file mode 100644 index 0000000..0837e8e --- /dev/null +++ b/src/test/media/button_over.png diff --git a/src/test/media/button_up.png b/src/test/media/button_up.png Binary files differnew file mode 100644 index 0000000..aa7d33a --- /dev/null +++ b/src/test/media/button_up.png diff --git a/src/test/media/checkbox_checked_disabled.png b/src/test/media/checkbox_checked_disabled.png Binary files differnew file mode 100644 index 0000000..da58829 --- /dev/null +++ b/src/test/media/checkbox_checked_disabled.png diff --git a/src/test/media/checkbox_checked_down.png b/src/test/media/checkbox_checked_down.png Binary files differnew file mode 100644 index 0000000..4fbbd83 --- /dev/null +++ b/src/test/media/checkbox_checked_down.png diff --git a/src/test/media/checkbox_checked_up.png b/src/test/media/checkbox_checked_up.png Binary files differnew file mode 100644 index 0000000..ca901f4 --- /dev/null +++ b/src/test/media/checkbox_checked_up.png diff --git a/src/test/media/checkbox_unchecked_disabled.png b/src/test/media/checkbox_unchecked_disabled.png Binary files differnew file mode 100644 index 0000000..e8c2116 --- /dev/null +++ b/src/test/media/checkbox_unchecked_disabled.png diff --git a/src/test/media/checkbox_unchecked_down.png b/src/test/media/checkbox_unchecked_down.png Binary files differnew file mode 100644 index 0000000..69f8282 --- /dev/null +++ b/src/test/media/checkbox_unchecked_down.png diff --git a/src/test/media/checkbox_unchecked_up.png b/src/test/media/checkbox_unchecked_up.png Binary files differnew file mode 100644 index 0000000..e354492 --- /dev/null +++ b/src/test/media/checkbox_unchecked_up.png diff --git a/src/test/media/checker.png b/src/test/media/checker.png Binary files differnew file mode 100644 index 0000000..4f100c5 --- /dev/null +++ b/src/test/media/checker.png diff --git a/src/test/media/chromakey-median.png b/src/test/media/chromakey-median.png Binary files differnew file mode 100644 index 0000000..5858c4b --- /dev/null +++ b/src/test/media/chromakey-median.png diff --git a/src/test/media/chromakey.png b/src/test/media/chromakey.png Binary files differnew file mode 100644 index 0000000..b2cfc2e --- /dev/null +++ b/src/test/media/chromakey.png diff --git a/src/test/media/colorramp.png b/src/test/media/colorramp.png Binary files differnew file mode 100644 index 0000000..da12725 --- /dev/null +++ b/src/test/media/colorramp.png diff --git a/src/test/media/crop_bkgd.png b/src/test/media/crop_bkgd.png Binary files differnew file mode 100644 index 0000000..89f9e95 --- /dev/null +++ b/src/test/media/crop_bkgd.png diff --git a/src/test/media/dilation.png b/src/test/media/dilation.png Binary files differnew file mode 100644 index 0000000..7981594 --- /dev/null +++ b/src/test/media/dilation.png diff --git a/src/test/media/erosion.png b/src/test/media/erosion.png Binary files differnew file mode 100644 index 0000000..899e2c4 --- /dev/null +++ b/src/test/media/erosion.png diff --git a/src/test/media/filterwipeborder.png b/src/test/media/filterwipeborder.png Binary files differnew file mode 100644 index 0000000..58ac84d --- /dev/null +++ b/src/test/media/filterwipeborder.png diff --git a/src/test/media/flat.png b/src/test/media/flat.png Binary files differnew file mode 100644 index 0000000..51d2c55 --- /dev/null +++ b/src/test/media/flat.png diff --git a/src/test/media/floodfill.png b/src/test/media/floodfill.png Binary files differnew file mode 100644 index 0000000..6a9e5b5 --- /dev/null +++ b/src/test/media/floodfill.png diff --git a/src/test/media/freidrehen.jpg b/src/test/media/freidrehen.jpg Binary files differnew file mode 100644 index 0000000..7f93bf0 --- /dev/null +++ b/src/test/media/freidrehen.jpg diff --git a/src/test/media/greyscale.png b/src/test/media/greyscale.png Binary files differnew file mode 100644 index 0000000..f86a18b --- /dev/null +++ b/src/test/media/greyscale.png diff --git a/src/test/media/h264-48x48.h264 b/src/test/media/h264-48x48.h264 Binary files differnew file mode 100644 index 0000000..d650960 --- /dev/null +++ b/src/test/media/h264-48x48.h264 diff --git a/src/test/media/hsl.png b/src/test/media/hsl.png Binary files differnew file mode 100644 index 0000000..9621451 --- /dev/null +++ b/src/test/media/hsl.png diff --git a/src/test/media/i8-64x64.png b/src/test/media/i8-64x64.png Binary files differnew file mode 100644 index 0000000..ec88c8c --- /dev/null +++ b/src/test/media/i8-64x64.png diff --git a/src/test/media/incompleteSkinMedia/IncompleteSkin.xml b/src/test/media/incompleteSkinMedia/IncompleteSkin.xml new file mode 100644 index 0000000..019d702 --- /dev/null +++ b/src/test/media/incompleteSkinMedia/IncompleteSkin.xml @@ -0,0 +1,11 @@ +<skin> +<scrollbar> + <horizontal + trackSrc="scrollbar_horiz_track.png" + trackDisabledSrc="scrollbar_horiz_track_disabled.png" + trackEndsExtent="2" + thumbUpSrc="scrollbar_horiz_thumb_up.png" + thumbDownSrc="scrollbar_horiz_thumb_down.png" + thumbEndsExtent="4"/> +</scrollbar> +</skin> diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.png Binary files differnew file mode 100644 index 0000000..6dc6fd1 --- /dev/null +++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.png diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png Binary files differnew file mode 100644 index 0000000..eb6b005 --- /dev/null +++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png Binary files differnew file mode 100644 index 0000000..d2f393b --- /dev/null +++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png Binary files differnew file mode 100644 index 0000000..7ac86fe --- /dev/null +++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png diff --git a/src/test/media/keyboard_bg.png b/src/test/media/keyboard_bg.png Binary files differnew file mode 100644 index 0000000..a767d06 --- /dev/null +++ b/src/test/media/keyboard_bg.png diff --git a/src/test/media/keyboard_down.png b/src/test/media/keyboard_down.png Binary files differnew file mode 100644 index 0000000..f3ead71 --- /dev/null +++ b/src/test/media/keyboard_down.png diff --git a/src/test/media/keyboard_feedback.png b/src/test/media/keyboard_feedback.png Binary files differnew file mode 100644 index 0000000..e519594 --- /dev/null +++ b/src/test/media/keyboard_feedback.png diff --git a/src/test/media/mask.png b/src/test/media/mask.png Binary files differnew file mode 100644 index 0000000..031b39a --- /dev/null +++ b/src/test/media/mask.png diff --git a/src/test/media/mask1.png b/src/test/media/mask1.png Binary files differnew file mode 100644 index 0000000..ffe5618 --- /dev/null +++ b/src/test/media/mask1.png diff --git a/src/test/media/mask2.png b/src/test/media/mask2.png Binary files differnew file mode 100644 index 0000000..92975df --- /dev/null +++ b/src/test/media/mask2.png diff --git a/src/test/media/mjpeg-48x48.avi b/src/test/media/mjpeg-48x48.avi Binary files differnew file mode 100644 index 0000000..337df16 --- /dev/null +++ b/src/test/media/mjpeg-48x48.avi diff --git a/src/test/media/mpeg1-48x48-sound.avi b/src/test/media/mpeg1-48x48-sound.avi Binary files differnew file mode 100644 index 0000000..be415db --- /dev/null +++ b/src/test/media/mpeg1-48x48-sound.avi diff --git a/src/test/media/mpeg1-48x48.mov b/src/test/media/mpeg1-48x48.mov Binary files differnew file mode 100644 index 0000000..16ab499 --- /dev/null +++ b/src/test/media/mpeg1-48x48.mov diff --git a/src/test/media/oe.png b/src/test/media/oe.png Binary files differnew file mode 100644 index 0000000..3527967 --- /dev/null +++ b/src/test/media/oe.png diff --git a/src/test/media/pause_button_down.png b/src/test/media/pause_button_down.png Binary files differnew file mode 100644 index 0000000..c06b34a --- /dev/null +++ b/src/test/media/pause_button_down.png diff --git a/src/test/media/pause_button_up.png b/src/test/media/pause_button_up.png Binary files differnew file mode 100644 index 0000000..1a923b9 --- /dev/null +++ b/src/test/media/pause_button_up.png diff --git a/src/test/media/play_button_down.png b/src/test/media/play_button_down.png Binary files differnew file mode 100644 index 0000000..07b167b --- /dev/null +++ b/src/test/media/play_button_down.png diff --git a/src/test/media/play_button_up.png b/src/test/media/play_button_up.png Binary files differnew file mode 100644 index 0000000..e16ec9e --- /dev/null +++ b/src/test/media/play_button_up.png diff --git a/src/test/media/rect.svg b/src/test/media/rect.svg new file mode 100644 index 0000000..136b061 --- /dev/null +++ b/src/test/media/rect.svg @@ -0,0 +1,8 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> + +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect id="rect" x="1" y="1" width="20" height="10" style="fill:rgb(255,0,0);stroke-width:1; stroke:rgb(0,0,255)"/> + <rect id="pos_rect" x="5" y="15" width="8" height="12" style="fill:rgb(255,0,0);stroke-width:1; stroke:rgb(0,0,255)"/> +</svg> + diff --git a/src/test/media/rectborder.png b/src/test/media/rectborder.png Binary files differnew file mode 100644 index 0000000..1675688 --- /dev/null +++ b/src/test/media/rectborder.png diff --git a/src/test/media/rgb24-32x32.png b/src/test/media/rgb24-32x32.png Binary files differnew file mode 100644 index 0000000..c5d6711 --- /dev/null +++ b/src/test/media/rgb24-32x32.png diff --git a/src/test/media/rgb24-64x64.png b/src/test/media/rgb24-64x64.png Binary files differnew file mode 100644 index 0000000..cca71fe --- /dev/null +++ b/src/test/media/rgb24-64x64.png diff --git a/src/test/media/rgb24-65x65.png b/src/test/media/rgb24-65x65.png Binary files differnew file mode 100644 index 0000000..ada2689 --- /dev/null +++ b/src/test/media/rgb24-65x65.png diff --git a/src/test/media/rgb24alpha-32x32.png b/src/test/media/rgb24alpha-32x32.png Binary files differnew file mode 100644 index 0000000..2e9e6af --- /dev/null +++ b/src/test/media/rgb24alpha-32x32.png diff --git a/src/test/media/rgb24alpha-64x64.png b/src/test/media/rgb24alpha-64x64.png Binary files differnew file mode 100644 index 0000000..41b69c3 --- /dev/null +++ b/src/test/media/rgb24alpha-64x64.png diff --git a/src/test/media/rgba-48x48.mov b/src/test/media/rgba-48x48.mov Binary files differnew file mode 100644 index 0000000..7e311cc --- /dev/null +++ b/src/test/media/rgba-48x48.mov diff --git a/src/test/media/scrollarea_border.png b/src/test/media/scrollarea_border.png Binary files differnew file mode 100644 index 0000000..2e95f57 --- /dev/null +++ b/src/test/media/scrollarea_border.png diff --git a/src/test/media/scrollbar_horiz_thumb_disabled.png b/src/test/media/scrollbar_horiz_thumb_disabled.png Binary files differnew file mode 100644 index 0000000..4645372 --- /dev/null +++ b/src/test/media/scrollbar_horiz_thumb_disabled.png diff --git a/src/test/media/scrollbar_horiz_thumb_down.png b/src/test/media/scrollbar_horiz_thumb_down.png Binary files differnew file mode 100644 index 0000000..6dc6fd1 --- /dev/null +++ b/src/test/media/scrollbar_horiz_thumb_down.png diff --git a/src/test/media/scrollbar_horiz_thumb_up.png b/src/test/media/scrollbar_horiz_thumb_up.png Binary files differnew file mode 100644 index 0000000..eb6b005 --- /dev/null +++ b/src/test/media/scrollbar_horiz_thumb_up.png diff --git a/src/test/media/scrollbar_horiz_track.png b/src/test/media/scrollbar_horiz_track.png Binary files differnew file mode 100644 index 0000000..d2f393b --- /dev/null +++ b/src/test/media/scrollbar_horiz_track.png diff --git a/src/test/media/scrollbar_horiz_track_disabled.png b/src/test/media/scrollbar_horiz_track_disabled.png Binary files differnew file mode 100644 index 0000000..7ac86fe --- /dev/null +++ b/src/test/media/scrollbar_horiz_track_disabled.png diff --git a/src/test/media/scrollbar_vert_thumb_disabled.png b/src/test/media/scrollbar_vert_thumb_disabled.png Binary files differnew file mode 100644 index 0000000..f375a2b --- /dev/null +++ b/src/test/media/scrollbar_vert_thumb_disabled.png diff --git a/src/test/media/scrollbar_vert_thumb_down.png b/src/test/media/scrollbar_vert_thumb_down.png Binary files differnew file mode 100644 index 0000000..c7b09d1 --- /dev/null +++ b/src/test/media/scrollbar_vert_thumb_down.png diff --git a/src/test/media/scrollbar_vert_thumb_up.png b/src/test/media/scrollbar_vert_thumb_up.png Binary files differnew file mode 100644 index 0000000..f6c2f88 --- /dev/null +++ b/src/test/media/scrollbar_vert_thumb_up.png diff --git a/src/test/media/scrollbar_vert_track.png b/src/test/media/scrollbar_vert_track.png Binary files differnew file mode 100644 index 0000000..58af284 --- /dev/null +++ b/src/test/media/scrollbar_vert_track.png diff --git a/src/test/media/scrollbar_vert_track_disabled.png b/src/test/media/scrollbar_vert_track_disabled.png Binary files differnew file mode 100644 index 0000000..695b112 --- /dev/null +++ b/src/test/media/scrollbar_vert_track_disabled.png diff --git a/src/test/media/shadow.png b/src/test/media/shadow.png Binary files differnew file mode 100644 index 0000000..0a4563f --- /dev/null +++ b/src/test/media/shadow.png diff --git a/src/test/media/slider_horiz_track.png b/src/test/media/slider_horiz_track.png Binary files differnew file mode 100644 index 0000000..6e233a5 --- /dev/null +++ b/src/test/media/slider_horiz_track.png diff --git a/src/test/media/slider_horiz_track_disabled.png b/src/test/media/slider_horiz_track_disabled.png Binary files differnew file mode 100644 index 0000000..01c880d --- /dev/null +++ b/src/test/media/slider_horiz_track_disabled.png diff --git a/src/test/media/slider_thumb_down.png b/src/test/media/slider_thumb_down.png Binary files differnew file mode 100644 index 0000000..1f2acc2 --- /dev/null +++ b/src/test/media/slider_thumb_down.png diff --git a/src/test/media/slider_thumb_up.png b/src/test/media/slider_thumb_up.png Binary files differnew file mode 100644 index 0000000..885506d --- /dev/null +++ b/src/test/media/slider_thumb_up.png diff --git a/src/test/media/slider_vert_track.png b/src/test/media/slider_vert_track.png Binary files differnew file mode 100644 index 0000000..51bac37 --- /dev/null +++ b/src/test/media/slider_vert_track.png diff --git a/src/test/media/slider_vert_track_disabled.png b/src/test/media/slider_vert_track_disabled.png Binary files differnew file mode 100644 index 0000000..bc8d7b6 --- /dev/null +++ b/src/test/media/slider_vert_track_disabled.png diff --git a/src/test/media/spike.png b/src/test/media/spike.png Binary files differnew file mode 100644 index 0000000..958e95d --- /dev/null +++ b/src/test/media/spike.png diff --git a/src/test/media/toggle_checked_Disabled.png b/src/test/media/toggle_checked_Disabled.png Binary files differnew file mode 100644 index 0000000..31372c0 --- /dev/null +++ b/src/test/media/toggle_checked_Disabled.png diff --git a/src/test/media/toggle_checked_Down.png b/src/test/media/toggle_checked_Down.png Binary files differnew file mode 100644 index 0000000..8c4afd2 --- /dev/null +++ b/src/test/media/toggle_checked_Down.png diff --git a/src/test/media/toggle_checked_Up.png b/src/test/media/toggle_checked_Up.png Binary files differnew file mode 100644 index 0000000..8214fcf --- /dev/null +++ b/src/test/media/toggle_checked_Up.png diff --git a/src/test/media/toggle_unchecked_Disabled.png b/src/test/media/toggle_unchecked_Disabled.png Binary files differnew file mode 100644 index 0000000..6b90e0b --- /dev/null +++ b/src/test/media/toggle_unchecked_Disabled.png diff --git a/src/test/media/toggle_unchecked_Down.png b/src/test/media/toggle_unchecked_Down.png Binary files differnew file mode 100644 index 0000000..f2e4272 --- /dev/null +++ b/src/test/media/toggle_unchecked_Down.png diff --git a/src/test/media/toggle_unchecked_Up.png b/src/test/media/toggle_unchecked_Up.png Binary files differnew file mode 100644 index 0000000..3a006ea --- /dev/null +++ b/src/test/media/toggle_unchecked_Up.png diff --git a/src/test/media/vp6a-yuva-48x48.flv b/src/test/media/vp6a-yuva-48x48.flv Binary files differnew file mode 100644 index 0000000..21866fe --- /dev/null +++ b/src/test/media/vp6a-yuva-48x48.flv diff --git a/src/test/media/widebmp.jpg b/src/test/media/widebmp.jpg Binary files differnew file mode 100644 index 0000000..8304e3d --- /dev/null +++ b/src/test/media/widebmp.jpg diff --git a/src/test/plugin/ColorNode.cpp b/src/test/plugin/ColorNode.cpp new file mode 100644 index 0000000..b98c98b --- /dev/null +++ b/src/test/plugin/ColorNode.cpp @@ -0,0 +1,153 @@ +// +// 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 +// +// Original author of this file is Jan Boelsche (regular.gonzales@googlemail.com). +// + +#define AVG_PLUGIN +#include "../../api.h" + +#include "../../player/Player.h" +#include "../../player/AreaNode.h" +#include "../../player/TypeDefinition.h" + +#include "../../base/Logger.h" +#include "../../graphics/OGLHelper.h" +#include "../../wrapper/WrapHelper.h" +#include "../../wrapper/raw_constructor.hpp" + +#include <string> +#include <iostream> +#include <sstream> +#include <iomanip> + +using namespace std; +using namespace boost::python; + +namespace avg { + +class ColorNode : public AreaNode +{ +public: + static void registerType(); + + ColorNode(const ArgList& Args); + + void setFillColor(const std::string& sColor); + const std::string& getFillColor() const; + + float getFloat() const; + void setFloat(float f); + + virtual void maybeRender(const glm::mat4& parentTransform); + virtual void render(); + +private: + std::string m_sFillColorName; + Pixel32 m_Color; + float m_FloatParam; +}; + +ColorNode::ColorNode(const ArgList& Args) + : m_sFillColorName("FFFFFF") +{ + AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO, + "ColorNode c'tor gets Argument fillcolor= " << + Args.getArgVal<string>("fillcolor")); + + Args.setMembers(this); + AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO, + "ColorNode constructed with " << m_sFillColorName); + m_Color = colorStringToColor(m_sFillColorName); +} + +void ColorNode::setFillColor(const string& sFillColor) +{ + AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO, + "setFillColor called with " << sFillColor); + m_sFillColorName = sFillColor; + m_Color = colorStringToColor(m_sFillColorName); +} + +const std::string& ColorNode::getFillColor() const +{ + return m_sFillColorName; +} + +float ColorNode::getFloat() const +{ + return m_FloatParam; +} + +void ColorNode::setFloat(float f) +{ + m_FloatParam = f; +} + + +void ColorNode::maybeRender(const glm::mat4& parentTransform) +{ + render(); +} + +void ColorNode::render() +{ + glClearColor(m_Color.getR()/255., m_Color.getG()/255., m_Color.getB()/255., 1.0); + glClear(GL_COLOR_BUFFER_BIT); +} + +char colorNodeName[] = "colornode"; + +void ColorNode::registerType() +{ + avg::TypeDefinition def = avg::TypeDefinition("colornode", "areanode", + ExportedObject::buildObject<ColorNode>) + .addArg(Arg<float>("floatparam", 0.0f, false, + offsetof(ColorNode, m_FloatParam))) + .addArg(Arg<string>("fillcolor", "0F0F0F", false, + offsetof(ColorNode, m_sFillColorName))); + const char* allowedParentNodeNames[] = {"avg", 0}; + avg::TypeRegistry::get()->registerType(def, allowedParentNodeNames); +} + +} + +using namespace avg; + +BOOST_PYTHON_MODULE(colorplugin) +{ + class_<ColorNode, bases<AreaNode>, boost::noncopyable>("ColorNode", no_init) + .def("__init__", raw_constructor(createNode<colorNodeName>)) + .add_property("floatparam", &ColorNode::getFloat, &ColorNode::setFloat) + .add_property("fillcolor", make_function(&ColorNode::getFillColor, + return_value_policy<copy_const_reference>()), &ColorNode::setFillColor); +} + +AVG_PLUGIN_API void registerPlugin() +{ + initcolorplugin(); + object mainModule(handle<>(borrowed(PyImport_AddModule("__builtin__")))); + object colorModule(handle<>(PyImport_ImportModule("colorplugin"))); + mainModule.attr("colorplugin") = colorModule; + + avg::ColorNode::registerType(); + +} + diff --git a/src/test/plugin/Makefile.am b/src/test/plugin/Makefile.am new file mode 100644 index 0000000..9aa10b1 --- /dev/null +++ b/src/test/plugin/Makefile.am @@ -0,0 +1,19 @@ +AM_CPPFLAGS = -I. -I../player \ + @XML2_CFLAGS@ @PTHREAD_CFLAGS@ @PANGOFT2_CFLAGS@ \ + @PYTHON_CPPFLAGS@ @DC1394_2_CFLAGS@ + +ALL_H = + +if APPLE + XGL_LIBS = + EXTRA_LDFLAGS = -read_only_relocs suppress +else + XGL_LIBS = -lXxf86vm + EXTRA_LDFLAGS = -XCClinker ../../wrapper/.libs/avg.so +endif + +ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS) + +pkgpyexec_LTLIBRARIES = colorplugin.la +colorplugin_la_SOURCES = ColorNode.cpp +colorplugin_la_LDFLAGS = $(EXTRA_LDFLAGS) -module diff --git a/src/test/plugin/test.sh b/src/test/plugin/test.sh new file mode 100755 index 0000000..9af205f --- /dev/null +++ b/src/test/plugin/test.sh @@ -0,0 +1,5 @@ +#!/bin/bash +pushd .. +./PluginTest.py +popd + diff --git a/src/test/testapp.py b/src/test/testapp.py new file mode 100644 index 0000000..251ab47 --- /dev/null +++ b/src/test/testapp.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# -*- 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 +# + +import unittest + +import optparse +import os +import sys + +from libavg import avg, player +import testcase + + +class TestApp(object): + EXIT_OK = 0 + EXIT_FAILURE = 1 + + def __init__(self): + self.__exitOk = TestApp.EXIT_FAILURE + + self.__registeredSuiteFactories = [] + self.__registerdSuiteFactoriesDict = {} + + self.__suitesToRun = [] + self.__suitesTestSubsets = [] + + self.__testSuite = unittest.TestSuite() + self.__optionParser = None + self.__commandlineOptions = None + player.keepWindowOpen() + + def getSuiteFactory(self, name): + return self.__registerdSuiteFactoriesDict[name] + + def isSuiteFactoryRegistered(self, name): + return name in self.__registeredSuiteFactories + + def getSuiteFactoryNames(self): + return list(self.__registeredSuiteFactories) + + def getSuiteFactories(self): + return [ self.__registerdSuiteFactoriesDict[name] + for name in self.__registeredSuiteFactories ] + + def registerSuiteFactory(self, name, suite): + self.__registeredSuiteFactories.append(name) + self.__registerdSuiteFactoriesDict[name] = suite + + def run(self): + hasAVGConsoleTest = os.getenv("AVG_CONSOLE_TEST") + if hasAVGConsoleTest: + self.__runVideoTest() + else: + self.__setupTestApp() + self.__run() + + def exitCode(self): + return self.__exitOk + + def __iter__(self): + for name in self.__registeredSuiteFactories: + yield self.__RegisterdSuitesDict[name] + + def __runVideoTest(self): + player.loadFile("image.avg") + + def __run(self): + testRunner = unittest.TextTestRunner(verbosity = 2) + testcase.AVGTestCase.cleanResultDir() + testResult = testRunner.run(self.__testSuite) + + numSkipped = 0 + for suite in self.__testSuite: + for test in suite: + if test.skipped(): + numSkipped += 1 + if numSkipped > 0: + sys.stderr.write("Skipped "+str(numSkipped)+" tests:\n") + for suite in self.__testSuite: + for test in suite: + if test.skipped(): + print " " + str(test) + ": " + test.skipReason() + + if testResult.wasSuccessful(): + self.__exitOk = TestApp.EXIT_OK + + def __setupTestApp(self): + self.__setupCommandlineParser() + self.__parseCommandline() + self.__setupGlobalPlayerOptions() + self.__dumpConfig() + self.__populateTestSuite() + + def __setupGlobalPlayerOptions(self): + if self.__commandlineOptions.shaderusage == "FULL": + shaderUsage = avg.SHADERUSAGE_FULL + elif self.__commandlineOptions.shaderusage == "MINIMAL": + shaderUsage = avg.SHADERUSAGE_MINIMAL + elif self.__commandlineOptions.shaderusage == "FRAGMENT_ONLY": + shaderUsage = avg.SHADERUSAGE_FRAGMENT_ONLY + elif self.__commandlineOptions.shaderusage == "AUTO": + shaderUsage = avg.SHADERUSAGE_AUTO + else: + sys.stderr.write("\nUnknown value for --shaderusage command-line parameter.\n") + self.__optionParser.print_help() + sys.exit(-1) + + player.setOGLOptions(self.__commandlineOptions.usepow2textures, + self.__commandlineOptions.usepixelbuffers, 1, shaderUsage, True) + + def __setupCommandlineParser(self): + self.__optionParser = optparse.OptionParser( + usage = '%prog [options] [<suite> [testcase] [testcase] [...]]') + + self.__optionParser.add_option("--usepow2textures", + dest = "usepow2textures", + action = 'store_true', + default = False, + help = "Use power of 2 textures") + + self.__optionParser.add_option("--nopixelbuffers", + dest = "usepixelbuffers", + action = 'store_false', + default = True, + help = "Use pixel buffers") + + self.__optionParser.add_option("--shaderusage", + dest = "shaderusage", + default = "AUTO", + help = "Configure usage of shaders. Valid values are FULL, MINIMAL, FRAGMENT_ONLY and AUTO.") + + def __parseCommandline(self): + self.__commandlineOptions, args = self.__optionParser.parse_args() + + # MFX 2013-11-10: cleanup argv consuming testapp args to avoid clashes + # with libavg.app.App ArgvExtender + sys.argv = [sys.argv[0]] + + if len(args): # suite + suiteFactory = args.pop(0) + if not(self.isSuiteFactoryRegistered(suiteFactory)): + sys.stderr.write("Unknown test suite, registered suites:\n") + for factory in self.getSuiteFactoryNames(): + sys.stderr.write(factory+"\n") + sys.stderr.write("\n") + self.__optionParser.print_usage() + + self.__suitesToRun.append(self.getSuiteFactory(suiteFactory)) + self.__suitesTestSubsets = args + + else: + self.__suitesToRun = self.getSuiteFactories() + + def __populateTestSuite(self): + for suite in self.__suitesToRun: + self.__testSuite.addTest(suite(self.__suitesTestSubsets)) + + def __dumpConfig(self): + player.enableGLErrorChecks(True) + cats = avg.logger.getCategories() + for cat in [avg.logger.Category.APP, avg.logger.Category.CONFIG, + avg.logger.Category.DEPREC]: + avg.logger.configureCategory(cat, avg.logger.Severity.INFO) + player.loadString(""" + <avg id="avg" width="160" height="120"> + </avg> + """) + player.setTimeout(0, player.stop) + player.setFramerate(10000) + player.play() + for cat, severity in cats.iteritems(): + avg.logger.configureCategory(cat, severity) diff --git a/src/test/testcase.py b/src/test/testcase.py new file mode 100644 index 0000000..95f271e --- /dev/null +++ b/src/test/testcase.py @@ -0,0 +1,369 @@ +#!/usr/bin/python +# -*- 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 +# + +import unittest + +import sys +import os +import math + +from libavg import avg, player, logger + +def almostEqual(a, b, epsilon): + try: + bOk = True + for i in range(len(a)): + if not(almostEqual(a[i], b[i], epsilon)): + bOk = False + return bOk + except: + return math.fabs(a-b) < epsilon + +def flatten(l): + ltype = type(l) + l = list(l) + i = 0 + while i < len(l): + while isinstance(l[i], (list, tuple)): + if not l[i]: + l.pop(i) + i -= 1 + break + else: + l[i:i + 1] = l[i] + i += 1 + return ltype(l) + + +class SuppressOutput(object): + class Blackhole(object): + def write(self, *args): + pass + + def __init__(self): + self.__savedStreams = [sys.stdout, sys.stderr] + + def __enter__(self): + sys.stdout = self.Blackhole() + sys.stderr = self.Blackhole() + + def __exit__(self, *args): + sys.stdout, sys.stderr = self.__savedStreams + + +class MouseEmulator(object): + def __init__(self): + self.btnStates = [False, False, False] + + def sendMouseEvent(self, type_, x, y, btn=1): + helper = player.getTestHelper() + index = btn-1 + if type_ == avg.Event.CURSOR_UP: + self.btnStates[index] = False + if type_ == avg.Event.CURSOR_DOWN: + self.btnStates[index] = True + + helper.fakeMouseEvent(type_, self.btnStates[0], self.btnStates[1], + self.btnStates[2], x, y, btn) + + +class AVGTestCase(unittest.TestCase): + imageResultDirectory = "resultimages" + baselineImageResultDirectory = "baseline" + + def __init__(self, testFuncName): + unittest.TestCase.__init__(self, testFuncName) + + player.enableGLErrorChecks(True) + logger.configureCategory("MEMORY", logger.Severity.ERR); + logger.configureCategory("DEPREC", logger.Severity.ERR); + self.__testFuncName = testFuncName + self.__logger = avg.logger + self.__skipped = False + self.__warnOnImageDiff = False + self.__mouseEmulator = None + + def __setupPlayer(self): + player.setMultiSampleSamples(1) + player.setResolution(0, 0, 0, 0) + + @staticmethod + def setImageResultDirectory(name): + AVGTestCase.imageResultDirectory = name + + @staticmethod + def getImageResultDir(): + return AVGTestCase.imageResultDirectory + + @staticmethod + def cleanResultDir(): + dir = AVGTestCase.getImageResultDir() + try: + files = os.listdir(dir) + for file in files: + os.remove(dir+"/"+file) + except OSError: + try: + os.mkdir(dir) + except OSError: + pass + + def start(self, warnOnImageDiff, actions): + self.__setupPlayer() + self.__dumpTestFrames = (os.getenv("AVG_DUMP_TEST_FRAMES") != None) + self.__delaying = False + self.__warnOnImageDiff = warnOnImageDiff + + self.assert_(player.isPlaying() == 0) + self.actions = flatten(actions) + self.curFrame = 0 + player.subscribe(player.ON_FRAME, self.__nextAction) + player.setFramerate(10000) + player.assumePixelsPerMM(1) + player.play() + self.assert_(player.isPlaying() == 0) + + def delay(self, time): + def timeout(): + self.__delaying = False + self.__delaying = True + player.setTimeout(time, timeout) + + def compareImage(self, fileName): + bmp = player.screenshot() + self.compareBitmapToFile(bmp, fileName) + + def compareBitmapToFile(self, bmp, fileName): + try: + baselineBmp = avg.Bitmap(AVGTestCase.baselineImageResultDirectory + "/" + + fileName + ".png") + except RuntimeError: + bmp.save(AVGTestCase.getImageResultDir()+"/"+fileName+".png") + self.__logger.warning("Could not load image "+fileName+".png") + raise + diffBmp = bmp.subtract(baselineBmp) + average = diffBmp.getAvg() + stdDev = diffBmp.getStdDev() + if (average > 0.1 or stdDev > 0.5): + if self._isCurrentDirWriteable(): + bmp.save(AVGTestCase.getImageResultDir() + "/" + fileName + ".png") + baselineBmp.save(AVGTestCase.getImageResultDir() + "/" + fileName + + "_baseline.png") + diffBmp.save(AVGTestCase.getImageResultDir() + "/" + fileName + + "_diff.png") + if (average > 2 or stdDev > 6): + msg = (" "+fileName+ + ": Difference image has avg=%(avg).2f, std dev=%(stddev).2f"% + {'avg':average, 'stddev':stdDev}) + if self.__warnOnImageDiff: + sys.stderr.write("\n"+msg+"\n") + else: + self.fail(msg) + + def areSimilarBmps(self, bmp1, bmp2, maxAvg, maxStdDev): + diffBmp = bmp1.subtract(bmp2) + avg = diffBmp.getAvg() + stdDev = diffBmp.getStdDev() + return avg <= maxAvg and stdDev <= maxStdDev + + def assertException(self, code): + exceptionRaised = False + try: + code() + except: + exceptionRaised = True + + self.assert_(exceptionRaised) + + def assertAlmostEqual(self, a, b, epsilon=0.00001): + if not(almostEqual(a, b, epsilon)): + msg = "almostEqual: " + str(a) + " != " + str(b) + self.fail(msg) + + def loadEmptyScene(self, resolution=(160,120)): + player.createMainCanvas(size=resolution) + root = player.getRootNode() + root.mediadir = "media" + return root + + def initDefaultImageScene(self): + root = self.loadEmptyScene() + avg.ImageNode(id="testtiles", pos=(0,30), size=(65,65), href="rgb24-65x65.png", + maxtilewidth=16, maxtileheight=32, parent=root) + avg.ImageNode(id="test", pos=(64,30), href="rgb24-65x65.png", pivot=(0,0), + angle=0.274, parent=root) + avg.ImageNode(id="test1", pos=(129,30), href="rgb24-65x65.png", parent=root) + + def fakeClick(self, x, y): + helper = player.getTestHelper() + helper.fakeMouseEvent(avg.Event.CURSOR_DOWN, True, False, False, x, y, 1) + helper.fakeMouseEvent(avg.Event.CURSOR_UP, False, False, False, x, y, 1) + + def skip(self, message): + self.__skipReason = str(message) + sys.stderr.write("skipping: " + str(message) + " ... ") + self.__skipped = True + + def skipped(self): + return self.__skipped + + def skipReason(self): + return self.__skipReason + + def skipIfMinimalShader(self): + if not(player.areFullShadersSupported()): + self.skip("Not supported if ShaderUsage == MINIMAL") + player.stop() + return + + def _sendMouseEvent(self, type, x, y, btn=1): + if not self.__mouseEmulator: + self.__mouseEmulator = MouseEmulator() + self.__mouseEmulator.sendMouseEvent(type, x, y, btn) + + def _sendTouchEvent(self, id, type, x, y): + helper = player.getTestHelper() + helper.fakeTouchEvent(id, type, avg.Event.TOUCH, avg.Point2D(x, y)) + + def _sendTouchEvents(self, eventData): + helper = player.getTestHelper() + for (id, type, x, y) in eventData: + helper.fakeTouchEvent(id, type, avg.Event.TOUCH, avg.Point2D(x, y)) + + def _genMouseEventFrames(self, type, x, y, expectedEvents): + return [ + lambda: self._sendMouseEvent(type, x, y), + lambda: self.messageTester.assertState(expectedEvents), + ] + + def _genTouchEventFrames(self, eventData, expectedEvents): + return [ + lambda: self._sendTouchEvents(eventData), + lambda: self.messageTester.assertState(expectedEvents), + ] + + def _isCurrentDirWriteable(self): + return bool(os.access('.', os.W_OK)) + + def __nextAction(self): + if not(self.__delaying): + if self.__dumpTestFrames: + self.__logger.log("Frame "+str(self.curFrame)) + if len(self.actions) == self.curFrame: + player.stop() + else: + action = self.actions[self.curFrame] + if action != None: + action() + self.curFrame += 1 + + +def createAVGTestSuite(availableTests, AVGTestCaseClass, testSubset): + testNames = [] + if testSubset: + for testName in testSubset: + if testName in availableTests: + testNames.append(testName) + else: + sys.stderr.write(("No test named %s"%testName) + "\n") + sys.exit(1) + else: + testNames = availableTests + + suite = unittest.TestSuite() + for testName in testNames: + suite.addTest(AVGTestCaseClass(testName)) + + return suite + + +class NodeHandlerTester(object): + def __init__(self, testCase, node): + self.__testCase = testCase + self.reset() + self.__node = node + self.__subscriberIDs = set() + self.setHandlers() + self.__messagesReceived = set() + + def assertState(self, expectedMessages): + self.__testCase.assert_(self.isState(expectedMessages)) + self.reset() + + def isState(self, expectedMessages): + expectedMessages = set(expectedMessages) + if expectedMessages != self.__messagesReceived: + sys.stderr.write("\nState expected: "+str(expectedMessages)+"\n") + sys.stderr.write("Actual state: "+str(self.__messagesReceived)+"\n") + return False + else: + return True + + def reset(self): + self.__messagesReceived = set() + + def setHandlers(self): + messageIDs = [avg.Node.CURSOR_DOWN, avg.Node.CURSOR_UP, avg.Node.CURSOR_OVER, + avg.Node.CURSOR_OUT, avg.Node.CURSOR_MOTION] + for messageID in messageIDs: + subscriberID = self.__node.subscribe(messageID, + lambda event, messageID=messageID: + self.setMessageReceived(messageID, event)) + self.__subscriberIDs.add(subscriberID) + + def clearHandlers(self): + for subscriber in self.__subscriberIDs: + self.__node.unsubscribe(subscriber) + self.__subscriberIDs = set() + + def setMessageReceived(self, messageID, event): + self.__messagesReceived.add(messageID) + + +class MessageTester(object): + + def __init__(self, publisher, messageIDs, testCase=None): + for messageID in messageIDs: + publisher.subscribe(messageID, + lambda messageID=messageID: self.setMessageReceived(messageID)) + self.__messagesReceived = set() + self.__testCase = testCase + + def assertState(self, expectedMessages): + self.__testCase.assert_(self.isState(expectedMessages)) + self.reset() + + def isState(self, expectedMessages): + expectedMessages = set(expectedMessages) + if expectedMessages != self.__messagesReceived: + sys.stderr.write("\nState expected: "+str(expectedMessages)+"\n") + sys.stderr.write("Actual state: "+str(self.__messagesReceived)+"\n") + return False + else: + return True + + def setMessageReceived(self, messageID): + self.__messagesReceived.add(messageID) + + def reset(self): + self.__messagesReceived = set() + diff --git a/src/test/testmediadir/mjpeg-48x48.avi b/src/test/testmediadir/mjpeg-48x48.avi Binary files differnew file mode 100644 index 0000000..d62180a --- /dev/null +++ b/src/test/testmediadir/mjpeg-48x48.avi diff --git a/src/test/testmediadir/rgb24-64x64a.png b/src/test/testmediadir/rgb24-64x64a.png Binary files differnew file mode 100644 index 0000000..41b69c3 --- /dev/null +++ b/src/test/testmediadir/rgb24-64x64a.png |