summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorDimitri John Ledkov <xnox@ubuntu.com>2014-06-24 20:05:13 +0100
committerDimitri John Ledkov <xnox@ubuntu.com>2014-06-24 20:05:13 +0100
commitdd22bd15f6ed3e5eb5c77ab427029be50fe20148 (patch)
treed9491ee40d80688b7f5b1f20504f022686827a57 /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')
-rw-r--r--src/test/AVGAppTest.py187
-rw-r--r--src/test/AVTest.py674
-rw-r--r--src/test/AnimTest.py512
-rw-r--r--src/test/AppTest.py299
-rw-r--r--src/test/DynamicsTest.py380
-rw-r--r--src/test/EventTest.py1086
-rw-r--r--src/test/FXTest.py483
-rw-r--r--src/test/GestureTest.py1048
-rw-r--r--src/test/ImageTest.py583
-rw-r--r--src/test/InputDeviceTest.py218
-rw-r--r--src/test/LoggerTest.py96
-rw-r--r--src/test/Makefile.am9
-rw-r--r--src/test/OffscreenTest.py472
-rw-r--r--src/test/PlayerTest.py853
-rw-r--r--src/test/PluginTest.py65
-rw-r--r--src/test/PythonTest.py239
-rwxr-xr-xsrc/test/Test.py150
-rw-r--r--src/test/VectorTest.py734
-rw-r--r--src/test/WidgetTest.py900
-rw-r--r--src/test/WordsTest.py701
-rw-r--r--src/test/baseline/test2VideosAtOnce1.pngbin0 -> 4250 bytes
-rw-r--r--src/test/baseline/testAVGFile.pngbin0 -> 5767 bytes
-rw-r--r--src/test/baseline/testAnim1.pngbin0 -> 6524 bytes
-rw-r--r--src/test/baseline/testAnim2.pngbin0 -> 5795 bytes
-rw-r--r--src/test/baseline/testAnim3.pngbin0 -> 6622 bytes
-rw-r--r--src/test/baseline/testArc1.pngbin0 -> 264 bytes
-rw-r--r--src/test/baseline/testArc2.pngbin0 -> 492 bytes
-rw-r--r--src/test/baseline/testBitmap1.pngbin0 -> 1257 bytes
-rw-r--r--src/test/baseline/testBitmap2.pngbin0 -> 2816 bytes
-rw-r--r--src/test/baseline/testBitmap3.pngbin0 -> 2918 bytes
-rw-r--r--src/test/baseline/testBitmap4.pngbin0 -> 3666 bytes
-rw-r--r--src/test/baseline/testBlend1.pngbin0 -> 24802 bytes
-rw-r--r--src/test/baseline/testBlend2.pngbin0 -> 23161 bytes
-rw-r--r--src/test/baseline/testBlurFX1.pngbin0 -> 2994 bytes
-rw-r--r--src/test/baseline/testBlurFX2.pngbin0 -> 6838 bytes
-rw-r--r--src/test/baseline/testBlurFX3.pngbin0 -> 2418 bytes
-rw-r--r--src/test/baseline/testButtonDisabled.pngbin0 -> 1561 bytes
-rw-r--r--src/test/baseline/testButtonDown.pngbin0 -> 1492 bytes
-rw-r--r--src/test/baseline/testButtonOver.pngbin0 -> 1399 bytes
-rw-r--r--src/test/baseline/testButtonUp.pngbin0 -> 1212 bytes
-rw-r--r--src/test/baseline/testCanvasAlpha.pngbin0 -> 3790 bytes
-rw-r--r--src/test/baseline/testCanvasBlendModes.pngbin0 -> 8527 bytes
-rw-r--r--src/test/baseline/testCanvasCrop.pngbin0 -> 1745 bytes
-rw-r--r--src/test/baseline/testCanvasDependencies1.pngbin0 -> 1022 bytes
-rw-r--r--src/test/baseline/testCanvasDependencies2.pngbin0 -> 2726 bytes
-rw-r--r--src/test/baseline/testCanvasMipmap.pngbin0 -> 893 bytes
-rw-r--r--src/test/baseline/testCanvasMultisample.pngbin0 -> 3472 bytes
-rw-r--r--src/test/baseline/testCanvasNullFX1.pngbin0 -> 2214 bytes
-rw-r--r--src/test/baseline/testCanvasNullFX2.pngbin0 -> 1995 bytes
-rw-r--r--src/test/baseline/testCanvasNullFX3.pngbin0 -> 1042 bytes
-rw-r--r--src/test/baseline/testCanvasResize.pngbin0 -> 1022 bytes
-rw-r--r--src/test/baseline/testCheckboxClickedDown.pngbin0 -> 1732 bytes
-rw-r--r--src/test/baseline/testCheckboxClickedOut.pngbin0 -> 1497 bytes
-rw-r--r--src/test/baseline/testCheckboxClickedOver.pngbin0 -> 1642 bytes
-rw-r--r--src/test/baseline/testCheckboxDown.pngbin0 -> 1492 bytes
-rw-r--r--src/test/baseline/testCheckboxOver.pngbin0 -> 1399 bytes
-rw-r--r--src/test/baseline/testCheckboxUp.pngbin0 -> 1212 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX1.pngbin0 -> 2428 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX2.pngbin0 -> 2230 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX3.pngbin0 -> 2309 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX4.pngbin0 -> 2186 bytes
-rw-r--r--src/test/baseline/testCircle1.pngbin0 -> 295 bytes
-rw-r--r--src/test/baseline/testCircle2.pngbin0 -> 414 bytes
-rw-r--r--src/test/baseline/testCircle3.pngbin0 -> 3350 bytes
-rw-r--r--src/test/baseline/testCircle4.pngbin0 -> 1620 bytes
-rw-r--r--src/test/baseline/testCircle5.pngbin0 -> 1821 bytes
-rw-r--r--src/test/baseline/testColorFX1.pngbin0 -> 2170 bytes
-rw-r--r--src/test/baseline/testColorFX2.pngbin0 -> 1166 bytes
-rw-r--r--src/test/baseline/testColorFX3.pngbin0 -> 1511 bytes
-rw-r--r--src/test/baseline/testColorFX4.pngbin0 -> 2103 bytes
-rw-r--r--src/test/baseline/testColorFX5.pngbin0 -> 2105 bytes
-rw-r--r--src/test/baseline/testColorFX6.pngbin0 -> 2082 bytes
-rw-r--r--src/test/baseline/testColorFX7.pngbin0 -> 3067 bytes
-rw-r--r--src/test/baseline/testComplexDiv1.pngbin0 -> 2404 bytes
-rw-r--r--src/test/baseline/testContAnim1.pngbin0 -> 6562 bytes
-rw-r--r--src/test/baseline/testContAnim2.pngbin0 -> 4908 bytes
-rw-r--r--src/test/baseline/testContAnim3.pngbin0 -> 4155 bytes
-rw-r--r--src/test/baseline/testContAnim4.pngbin0 -> 4553 bytes
-rw-r--r--src/test/baseline/testContinuousAnim1.pngbin0 -> 4723 bytes
-rw-r--r--src/test/baseline/testContinuousAnim2.pngbin0 -> 2548 bytes
-rw-r--r--src/test/baseline/testContrast1.pngbin0 -> 1640 bytes
-rw-r--r--src/test/baseline/testContrast2.pngbin0 -> 1385 bytes
-rw-r--r--src/test/baseline/testContrast3.pngbin0 -> 9533 bytes
-rw-r--r--src/test/baseline/testCropImage1.pngbin0 -> 1494 bytes
-rw-r--r--src/test/baseline/testCropImage10.pngbin0 -> 5718 bytes
-rw-r--r--src/test/baseline/testCropImage2.pngbin0 -> 1110 bytes
-rw-r--r--src/test/baseline/testCropImage3.pngbin0 -> 3572 bytes
-rw-r--r--src/test/baseline/testCropImage4.pngbin0 -> 3404 bytes
-rw-r--r--src/test/baseline/testCropImage5.pngbin0 -> 3389 bytes
-rw-r--r--src/test/baseline/testCropImage6.pngbin0 -> 7900 bytes
-rw-r--r--src/test/baseline/testCropImage7.pngbin0 -> 6616 bytes
-rw-r--r--src/test/baseline/testCropImage8.pngbin0 -> 5925 bytes
-rw-r--r--src/test/baseline/testCropImage9.pngbin0 -> 5823 bytes
-rw-r--r--src/test/baseline/testCropMovie1.pngbin0 -> 6265 bytes
-rw-r--r--src/test/baseline/testCropMovie10.pngbin0 -> 5754 bytes
-rw-r--r--src/test/baseline/testCropMovie2.pngbin0 -> 4527 bytes
-rw-r--r--src/test/baseline/testCropMovie3.pngbin0 -> 4102 bytes
-rw-r--r--src/test/baseline/testCropMovie4.pngbin0 -> 3482 bytes
-rw-r--r--src/test/baseline/testCropMovie5.pngbin0 -> 3350 bytes
-rw-r--r--src/test/baseline/testCropMovie6.pngbin0 -> 6430 bytes
-rw-r--r--src/test/baseline/testCropMovie7.pngbin0 -> 3948 bytes
-rw-r--r--src/test/baseline/testCropMovie8.pngbin0 -> 6345 bytes
-rw-r--r--src/test/baseline/testCropMovie9.pngbin0 -> 5786 bytes
-rw-r--r--src/test/baseline/testCurve1.pngbin0 -> 382 bytes
-rw-r--r--src/test/baseline/testCurve2.pngbin0 -> 552 bytes
-rw-r--r--src/test/baseline/testCurve3.pngbin0 -> 653 bytes
-rw-r--r--src/test/baseline/testCurve4.pngbin0 -> 829 bytes
-rw-r--r--src/test/baseline/testDivDynamics1.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testDivDynamics2.pngbin0 -> 2620 bytes
-rw-r--r--src/test/baseline/testDivDynamics3.pngbin0 -> 2698 bytes
-rw-r--r--src/test/baseline/testDivDynamics4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testDivDynamics5.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testDraggable1.pngbin0 -> 5805 bytes
-rw-r--r--src/test/baseline/testDraggable2.pngbin0 -> 5765 bytes
-rw-r--r--src/test/baseline/testDynamicMediaDir1.pngbin0 -> 3302 bytes
-rw-r--r--src/test/baseline/testDynamicMediaDir2.pngbin0 -> 5141 bytes
-rw-r--r--src/test/baseline/testDynamicWords1.pngbin0 -> 390 bytes
-rw-r--r--src/test/baseline/testDynamicWords2.pngbin0 -> 1356 bytes
-rw-r--r--src/test/baseline/testDynamicWords3.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testDynamicWords4.pngbin0 -> 874 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnim1.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnim3.pngbin0 -> 5045 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC1.pngbin0 -> 2513 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC2.pngbin0 -> 2513 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC3.pngbin0 -> 2481 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC4.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC5.pngbin0 -> 2481 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC6.pngbin0 -> 2566 bytes
-rw-r--r--src/test/baseline/testEvents.pngbin0 -> 7493 bytes
-rw-r--r--src/test/baseline/testFXUpdateFX.pngbin0 -> 3452 bytes
-rw-r--r--src/test/baseline/testFXUpdateMaskPos.pngbin0 -> 2791 bytes
-rw-r--r--src/test/baseline/testFXUpdateMaskTex1.pngbin0 -> 1484 bytes
-rw-r--r--src/test/baseline/testFXUpdateMaskTex2.pngbin0 -> 2861 bytes
-rw-r--r--src/test/baseline/testFXUpdateTex.pngbin0 -> 2210 bytes
-rw-r--r--src/test/baseline/testFXUpdateVideo.pngbin0 -> 10424 bytes
-rw-r--r--src/test/baseline/testFadeIn1.pngbin0 -> 2161 bytes
-rw-r--r--src/test/baseline/testFadeIn2.pngbin0 -> 2304 bytes
-rw-r--r--src/test/baseline/testFadeIn3.pngbin0 -> 2473 bytes
-rw-r--r--src/test/baseline/testFadeOut1.pngbin0 -> 2161 bytes
-rw-r--r--src/test/baseline/testFadeOut2.pngbin0 -> 1886 bytes
-rw-r--r--src/test/baseline/testFadeOut3.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testFocusContext1.pngbin0 -> 3011 bytes
-rw-r--r--src/test/baseline/testFocusContext2.pngbin0 -> 3629 bytes
-rw-r--r--src/test/baseline/testFocusContext3.pngbin0 -> 4164 bytes
-rw-r--r--src/test/baseline/testFocusContext4.pngbin0 -> 2241 bytes
-rw-r--r--src/test/baseline/testFocusContext5.pngbin0 -> 1379 bytes
-rw-r--r--src/test/baseline/testFontDir.pngbin0 -> 1595 bytes
-rw-r--r--src/test/baseline/testFontStyle1.pngbin0 -> 1971 bytes
-rw-r--r--src/test/baseline/testFontStyle2.pngbin0 -> 2566 bytes
-rw-r--r--src/test/baseline/testGamma1.pngbin0 -> 2009 bytes
-rw-r--r--src/test/baseline/testGamma2.pngbin0 -> 2196 bytes
-rw-r--r--src/test/baseline/testHVStretchNode1.pngbin0 -> 339 bytes
-rw-r--r--src/test/baseline/testHVStretchNode2.pngbin0 -> 409 bytes
-rw-r--r--src/test/baseline/testHinting1.pngbin0 -> 2865 bytes
-rw-r--r--src/test/baseline/testHueSatFX1.pngbin0 -> 3456 bytes
-rw-r--r--src/test/baseline/testHueSatFX2.pngbin0 -> 3824 bytes
-rw-r--r--src/test/baseline/testHueSatFX3.pngbin0 -> 2641 bytes
-rw-r--r--src/test/baseline/testHueSatFX4.pngbin0 -> 3764 bytes
-rw-r--r--src/test/baseline/testHugeImage0.pngbin0 -> 3578 bytes
-rw-r--r--src/test/baseline/testHugeImage1.pngbin0 -> 3136 bytes
-rw-r--r--src/test/baseline/testI18NWords1.pngbin0 -> 2792 bytes
-rw-r--r--src/test/baseline/testI18NWords2.pngbin0 -> 3693 bytes
-rw-r--r--src/test/baseline/testI18NWords3.pngbin0 -> 3534 bytes
-rw-r--r--src/test/baseline/testImageNullFX1.pngbin0 -> 4153 bytes
-rw-r--r--src/test/baseline/testImageNullFX2.pngbin0 -> 4700 bytes
-rw-r--r--src/test/baseline/testImageNullFX3.pngbin0 -> 4174 bytes
-rw-r--r--src/test/baseline/testImgDynamics1.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testImgDynamics2.pngbin0 -> 2620 bytes
-rw-r--r--src/test/baseline/testImgDynamics3.pngbin0 -> 2698 bytes
-rw-r--r--src/test/baseline/testImgDynamics4.pngbin0 -> 2858 bytes
-rw-r--r--src/test/baseline/testImgDynamics5.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testImgHRef1.pngbin0 -> 2332 bytes
-rw-r--r--src/test/baseline/testImgHRef2.pngbin0 -> 2545 bytes
-rw-r--r--src/test/baseline/testImgHRef3.pngbin0 -> 3564 bytes
-rw-r--r--src/test/baseline/testImgMask1.pngbin0 -> 698 bytes
-rw-r--r--src/test/baseline/testImgMask2.pngbin0 -> 2333 bytes
-rw-r--r--src/test/baseline/testImgMask3.pngbin0 -> 2476 bytes
-rw-r--r--src/test/baseline/testImgMaskCanvas.pngbin0 -> 2081 bytes
-rw-r--r--src/test/baseline/testImgMaskPos.pngbin0 -> 867 bytes
-rw-r--r--src/test/baseline/testImgMaskSize1.pngbin0 -> 519 bytes
-rw-r--r--src/test/baseline/testImgMaskSize2.pngbin0 -> 849 bytes
-rw-r--r--src/test/baseline/testImgMaskSize3.pngbin0 -> 916 bytes
-rw-r--r--src/test/baseline/testImgPos1.pngbin0 -> 1182 bytes
-rw-r--r--src/test/baseline/testImgPos2.pngbin0 -> 1374 bytes
-rw-r--r--src/test/baseline/testImgSize1.pngbin0 -> 1055 bytes
-rw-r--r--src/test/baseline/testImgSize2.pngbin0 -> 1217 bytes
-rw-r--r--src/test/baseline/testImgWarp1.pngbin0 -> 1138 bytes
-rw-r--r--src/test/baseline/testImgWarp2.pngbin0 -> 2522 bytes
-rw-r--r--src/test/baseline/testInactiveVector1.pngbin0 -> 247 bytes
-rw-r--r--src/test/baseline/testInactiveVector2.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testIntAnim1.pngbin0 -> 2476 bytes
-rw-r--r--src/test/baseline/testIntAnim2.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testIntensity1.pngbin0 -> 1620 bytes
-rw-r--r--src/test/baseline/testIntensity2.pngbin0 -> 1700 bytes
-rw-r--r--src/test/baseline/testIntensity3.pngbin0 -> 8629 bytes
-rw-r--r--src/test/baseline/testIntensity4.pngbin0 -> 3618 bytes
-rw-r--r--src/test/baseline/testInvertFX1.pngbin0 -> 619 bytes
-rw-r--r--src/test/baseline/testInvertFX2.pngbin0 -> 3674 bytes
-rw-r--r--src/test/baseline/testJustify.pngbin0 -> 2413 bytes
-rw-r--r--src/test/baseline/testLetterSpacing1.pngbin0 -> 1809 bytes
-rw-r--r--src/test/baseline/testLetterSpacing2.pngbin0 -> 1711 bytes
-rw-r--r--src/test/baseline/testLinearAnim1.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testLinearAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testLinearAnim3.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testLinearAnimC1.pngbin0 -> 2513 bytes
-rw-r--r--src/test/baseline/testLinearAnimC2.pngbin0 -> 2469 bytes
-rw-r--r--src/test/baseline/testLinearAnimC3.pngbin0 -> 2508 bytes
-rw-r--r--src/test/baseline/testLinearAnimC4.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testLinearAnimC5.pngbin0 -> 2508 bytes
-rw-r--r--src/test/baseline/testLinearAnimC6.pngbin0 -> 2500 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDuration1.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDuration2.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDuration3.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDurationC1.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDurationC2.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDurationC3.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testMediaControl1.pngbin0 -> 1041 bytes
-rw-r--r--src/test/baseline/testMediaControl2.pngbin0 -> 1032 bytes
-rw-r--r--src/test/baseline/testMediaControl3.pngbin0 -> 1202 bytes
-rw-r--r--src/test/baseline/testMediaControl4.pngbin0 -> 1108 bytes
-rw-r--r--src/test/baseline/testMediaControl5.pngbin0 -> 930 bytes
-rw-r--r--src/test/baseline/testMediaDir1.pngbin0 -> 6900 bytes
-rw-r--r--src/test/baseline/testMediaDir2.pngbin0 -> 4961 bytes
-rw-r--r--src/test/baseline/testMesh1.pngbin0 -> 2390 bytes
-rw-r--r--src/test/baseline/testMesh2.pngbin0 -> 2103 bytes
-rw-r--r--src/test/baseline/testMesh3.pngbin0 -> 719 bytes
-rw-r--r--src/test/baseline/testMesh4.pngbin0 -> 1810 bytes
-rw-r--r--src/test/baseline/testMesh5.pngbin0 -> 2309 bytes
-rw-r--r--src/test/baseline/testMesh6.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testMesh7.pngbin0 -> 1481 bytes
-rw-r--r--src/test/baseline/testMesh8.pngbin0 -> 1870 bytes
-rw-r--r--src/test/baseline/testMipmap.pngbin0 -> 371 bytes
-rw-r--r--src/test/baseline/testMove1.pngbin0 -> 6514 bytes
-rw-r--r--src/test/baseline/testNodeInCanvasNullFX1.pngbin0 -> 2461 bytes
-rw-r--r--src/test/baseline/testOffscreen1.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testOffscreen2.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testOffscreen3.pngbin0 -> 2464 bytes
-rw-r--r--src/test/baseline/testOffscreen4.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testOffscreen5.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testOffscreenAutoRender1.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testOffscreenAutoRender2.pngbin0 -> 2517 bytes
-rw-r--r--src/test/baseline/testOffscreenMultisampleScreenshot.pngbin0 -> 3713 bytes
-rw-r--r--src/test/baseline/testOffscreenScreenshot.pngbin0 -> 2792 bytes
-rw-r--r--src/test/baseline/testOpacity.pngbin0 -> 2457 bytes
-rw-r--r--src/test/baseline/testOutlines.pngbin0 -> 3282 bytes
-rw-r--r--src/test/baseline/testPanoDynamics1.pngbin0 -> 38510 bytes
-rw-r--r--src/test/baseline/testPanoDynamics2.pngbin0 -> 2858 bytes
-rw-r--r--src/test/baseline/testPanoDynamics3.pngbin0 -> 38564 bytes
-rw-r--r--src/test/baseline/testPanoImage.pngbin0 -> 37544 bytes
-rw-r--r--src/test/baseline/testPanoImagewNOP.pngbin0 -> 37544 bytes
-rw-r--r--src/test/baseline/testParaWords.pngbin0 -> 4290 bytes
-rw-r--r--src/test/baseline/testParallelAnimC1.pngbin0 -> 3283 bytes
-rw-r--r--src/test/baseline/testParallelAnimC2.pngbin0 -> 2586 bytes
-rw-r--r--src/test/baseline/testParallelAnimC3.pngbin0 -> 2519 bytes
-rw-r--r--src/test/baseline/testParallelAnims1.pngbin0 -> 5791 bytes
-rw-r--r--src/test/baseline/testParallelAnims2.pngbin0 -> 6139 bytes
-rw-r--r--src/test/baseline/testPieSlice1.pngbin0 -> 325 bytes
-rw-r--r--src/test/baseline/testPieSlice2.pngbin0 -> 800 bytes
-rw-r--r--src/test/baseline/testPieSlice3.pngbin0 -> 142 bytes
-rw-r--r--src/test/baseline/testPlayBeforeConnect.pngbin0 -> 3986 bytes
-rw-r--r--src/test/baseline/testPointAnim1.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testPointAnim2.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testPointAnim3.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testPolyLine1.pngbin0 -> 432 bytes
-rw-r--r--src/test/baseline/testPolyLine2.pngbin0 -> 592 bytes
-rw-r--r--src/test/baseline/testPolyLine3.pngbin0 -> 558 bytes
-rw-r--r--src/test/baseline/testPolyLine4.pngbin0 -> 616 bytes
-rw-r--r--src/test/baseline/testPolyLine5.pngbin0 -> 558 bytes
-rw-r--r--src/test/baseline/testPolyLine6.pngbin0 -> 184 bytes
-rw-r--r--src/test/baseline/testPolygon1.pngbin0 -> 565 bytes
-rw-r--r--src/test/baseline/testPolygon2.pngbin0 -> 554 bytes
-rw-r--r--src/test/baseline/testPolygon3.pngbin0 -> 716 bytes
-rw-r--r--src/test/baseline/testPolygon4.pngbin0 -> 716 bytes
-rw-r--r--src/test/baseline/testPolygon5.pngbin0 -> 767 bytes
-rw-r--r--src/test/baseline/testPolygon6.pngbin0 -> 741 bytes
-rw-r--r--src/test/baseline/testPolygon7.pngbin0 -> 567 bytes
-rw-r--r--src/test/baseline/testPolygon8.pngbin0 -> 547 bytes
-rw-r--r--src/test/baseline/testPolygon9.pngbin0 -> 579 bytes
-rw-r--r--src/test/baseline/testPolygonHole1.pngbin0 -> 637 bytes
-rw-r--r--src/test/baseline/testPolygonHole2.pngbin0 -> 727 bytes
-rw-r--r--src/test/baseline/testPositioning.pngbin0 -> 3435 bytes
-rw-r--r--src/test/baseline/testProgressBar1.pngbin0 -> 318 bytes
-rw-r--r--src/test/baseline/testProgressBar2.pngbin0 -> 321 bytes
-rw-r--r--src/test/baseline/testProgressBar3.pngbin0 -> 303 bytes
-rw-r--r--src/test/baseline/testRawText1.pngbin0 -> 2771 bytes
-rw-r--r--src/test/baseline/testRawText2.pngbin0 -> 4481 bytes
-rw-r--r--src/test/baseline/testRawText3.pngbin0 -> 4222 bytes
-rw-r--r--src/test/baseline/testRawText4.pngbin0 -> 1946 bytes
-rw-r--r--src/test/baseline/testRect1.pngbin0 -> 212 bytes
-rw-r--r--src/test/baseline/testRect2.pngbin0 -> 196 bytes
-rw-r--r--src/test/baseline/testRect3.pngbin0 -> 235 bytes
-rw-r--r--src/test/baseline/testRect4.pngbin0 -> 321 bytes
-rw-r--r--src/test/baseline/testRenderPipeline.pngbin0 -> 3381 bytes
-rw-r--r--src/test/baseline/testRotate1.pngbin0 -> 4931 bytes
-rw-r--r--src/test/baseline/testRotate1a.pngbin0 -> 2369 bytes
-rw-r--r--src/test/baseline/testRotate1b.pngbin0 -> 2363 bytes
-rw-r--r--src/test/baseline/testRotate2.pngbin0 -> 980 bytes
-rw-r--r--src/test/baseline/testRotatePivot1.pngbin0 -> 4188 bytes
-rw-r--r--src/test/baseline/testRotatePivot2.pngbin0 -> 6048 bytes
-rw-r--r--src/test/baseline/testRotatePivot3.pngbin0 -> 4942 bytes
-rw-r--r--src/test/baseline/testRoundedRect1.pngbin0 -> 312 bytes
-rw-r--r--src/test/baseline/testRoundedRect2.pngbin0 -> 311 bytes
-rw-r--r--src/test/baseline/testRoundedRect3.pngbin0 -> 212 bytes
-rw-r--r--src/test/baseline/testRoundedRect4.pngbin0 -> 221 bytes
-rw-r--r--src/test/baseline/testRoundedRect5.pngbin0 -> 256 bytes
-rw-r--r--src/test/baseline/testRoundedRect6.pngbin0 -> 237 bytes
-rw-r--r--src/test/baseline/testScrollArea1.pngbin0 -> 741 bytes
-rw-r--r--src/test/baseline/testScrollArea2.pngbin0 -> 857 bytes
-rw-r--r--src/test/baseline/testScrollArea3.pngbin0 -> 745 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz1.pngbin0 -> 313 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz10.pngbin0 -> 319 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz11.pngbin0 -> 322 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz12.pngbin0 -> 314 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz2.pngbin0 -> 318 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz3.pngbin0 -> 315 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz4.pngbin0 -> 301 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz5.pngbin0 -> 327 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz6.pngbin0 -> 297 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz7.pngbin0 -> 331 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz8.pngbin0 -> 326 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz9.pngbin0 -> 331 bytes
-rw-r--r--src/test/baseline/testScrollBarVert1.pngbin0 -> 521 bytes
-rw-r--r--src/test/baseline/testScrollBarVert2.pngbin0 -> 523 bytes
-rw-r--r--src/test/baseline/testScrollBarVert3.pngbin0 -> 537 bytes
-rw-r--r--src/test/baseline/testScrollBarVert4.pngbin0 -> 520 bytes
-rw-r--r--src/test/baseline/testScrollBarVert5.pngbin0 -> 555 bytes
-rw-r--r--src/test/baseline/testScrollBarVert6.pngbin0 -> 500 bytes
-rw-r--r--src/test/baseline/testScrollBarVert7.pngbin0 -> 517 bytes
-rw-r--r--src/test/baseline/testScrollBarVert8.pngbin0 -> 539 bytes
-rw-r--r--src/test/baseline/testScrollBarVert9.pngbin0 -> 525 bytes
-rw-r--r--src/test/baseline/testScrollPane1.pngbin0 -> 429 bytes
-rw-r--r--src/test/baseline/testScrollPane2.pngbin0 -> 1682 bytes
-rw-r--r--src/test/baseline/testScrollPane3.pngbin0 -> 998 bytes
-rw-r--r--src/test/baseline/testSeekAfterEOF.pngbin0 -> 4114 bytes
-rw-r--r--src/test/baseline/testShadowFX1.pngbin0 -> 2173 bytes
-rw-r--r--src/test/baseline/testShadowFX2.pngbin0 -> 2759 bytes
-rw-r--r--src/test/baseline/testShadowFX3.pngbin0 -> 1157 bytes
-rw-r--r--src/test/baseline/testShadowFX4.pngbin0 -> 1154 bytes
-rw-r--r--src/test/baseline/testShadowFX5.pngbin0 -> 2703 bytes
-rw-r--r--src/test/baseline/testShadowFX6.pngbin0 -> 805 bytes
-rw-r--r--src/test/baseline/testSimpleWords.pngbin0 -> 1955 bytes
-rw-r--r--src/test/baseline/testSliderHoriz1.pngbin0 -> 412 bytes
-rw-r--r--src/test/baseline/testSliderHoriz2.pngbin0 -> 424 bytes
-rw-r--r--src/test/baseline/testSliderHoriz3.pngbin0 -> 431 bytes
-rw-r--r--src/test/baseline/testSliderHoriz4.pngbin0 -> 390 bytes
-rw-r--r--src/test/baseline/testSliderHoriz5.pngbin0 -> 381 bytes
-rw-r--r--src/test/baseline/testSliderVert1.pngbin0 -> 578 bytes
-rw-r--r--src/test/baseline/testSliderVert2.pngbin0 -> 581 bytes
-rw-r--r--src/test/baseline/testSliderVert3.pngbin0 -> 578 bytes
-rw-r--r--src/test/baseline/testSliderVert4.pngbin0 -> 504 bytes
-rw-r--r--src/test/baseline/testSliderVert5.pngbin0 -> 502 bytes
-rw-r--r--src/test/baseline/testSpanWords.pngbin0 -> 2503 bytes
-rw-r--r--src/test/baseline/testSplineAnim1.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testSplineAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testSplineAnim3.pngbin0 -> 6171 bytes
-rw-r--r--src/test/baseline/testStateAnim1.pngbin0 -> 5765 bytes
-rw-r--r--src/test/baseline/testStateAnim2.pngbin0 -> 5320 bytes
-rw-r--r--src/test/baseline/testStateAnim3.pngbin0 -> 5320 bytes
-rw-r--r--src/test/baseline/testStateAnim4.pngbin0 -> 5765 bytes
-rw-r--r--src/test/baseline/testStateAnim5.pngbin0 -> 5320 bytes
-rw-r--r--src/test/baseline/testStateAnimC1.pngbin0 -> 2473 bytes
-rw-r--r--src/test/baseline/testStateAnimC2.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testStateAnimC3.pngbin0 -> 2472 bytes
-rw-r--r--src/test/baseline/testStateAnimC4.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testStateAnimC5.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testStretchNodeHoriz1.pngbin0 -> 1098 bytes
-rw-r--r--src/test/baseline/testStretchNodeHoriz2.pngbin0 -> 1118 bytes
-rw-r--r--src/test/baseline/testStretchNodeVert1.pngbin0 -> 1091 bytes
-rw-r--r--src/test/baseline/testStretchNodeVert2.pngbin0 -> 1224 bytes
-rw-r--r--src/test/baseline/testSvgBmp.pngbin0 -> 157 bytes
-rw-r--r--src/test/baseline/testSvgNode.pngbin0 -> 222 bytes
-rw-r--r--src/test/baseline/testSvgPosBmp.pngbin0 -> 155 bytes
-rw-r--r--src/test/baseline/testSvgScaleBmp1.pngbin0 -> 347 bytes
-rw-r--r--src/test/baseline/testSvgScaleBmp2.pngbin0 -> 207 bytes
-rw-r--r--src/test/baseline/testSvgScaledNode1.pngbin0 -> 359 bytes
-rw-r--r--src/test/baseline/testSvgScaledNode2.pngbin0 -> 511 bytes
-rw-r--r--src/test/baseline/testTexCompression1.pngbin0 -> 2367 bytes
-rw-r--r--src/test/baseline/testTexCompression2.pngbin0 -> 810 bytes
-rw-r--r--src/test/baseline/testTextArea1.pngbin0 -> 2792 bytes
-rw-r--r--src/test/baseline/testTextArea2.pngbin0 -> 460 bytes
-rw-r--r--src/test/baseline/testTextArea3.pngbin0 -> 511 bytes
-rw-r--r--src/test/baseline/testTextArea4.pngbin0 -> 1056 bytes
-rw-r--r--src/test/baseline/testTextArea5.pngbin0 -> 1100 bytes
-rw-r--r--src/test/baseline/testTextButtonDisabled.pngbin0 -> 1099 bytes
-rw-r--r--src/test/baseline/testTextButtonDown.pngbin0 -> 975 bytes
-rw-r--r--src/test/baseline/testTextButtonDownNewText.pngbin0 -> 1438 bytes
-rw-r--r--src/test/baseline/testTextButtonUp.pngbin0 -> 1099 bytes
-rw-r--r--src/test/baseline/testTextButtonUpNewText.pngbin0 -> 1559 bytes
-rw-r--r--src/test/baseline/testTexturedCurve1.pngbin0 -> 3811 bytes
-rw-r--r--src/test/baseline/testTexturedCurve2.pngbin0 -> 4002 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine1.pngbin0 -> 2755 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine2.pngbin0 -> 2545 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine3.pngbin0 -> 3059 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine4.pngbin0 -> 2329 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon1.pngbin0 -> 5278 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon2.pngbin0 -> 4889 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon3.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon4.pngbin0 -> 5447 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon5.pngbin0 -> 2624 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon6.pngbin0 -> 2629 bytes
-rw-r--r--src/test/baseline/testTexturedRect1.pngbin0 -> 2487 bytes
-rw-r--r--src/test/baseline/testTexturedRect2.pngbin0 -> 2515 bytes
-rw-r--r--src/test/baseline/testTexturedRect3.pngbin0 -> 3933 bytes
-rw-r--r--src/test/baseline/testTexturedRect4.pngbin0 -> 1950 bytes
-rw-r--r--src/test/baseline/testTexturedRect5.pngbin0 -> 2008 bytes
-rw-r--r--src/test/baseline/testTexturedRect6.pngbin0 -> 1491 bytes
-rw-r--r--src/test/baseline/testTexturedRect7.pngbin0 -> 251 bytes
-rw-r--r--src/test/baseline/testTexturedRect8.pngbin0 -> 283 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz1.pngbin0 -> 416 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz2.pngbin0 -> 501 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz3.pngbin0 -> 499 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz4.pngbin0 -> 461 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz5.pngbin0 -> 461 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert1.pngbin0 -> 570 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert2.pngbin0 -> 674 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert3.pngbin0 -> 665 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert4.pngbin0 -> 591 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert5.pngbin0 -> 591 bytes
-rw-r--r--src/test/baseline/testUIButtonDisabled.pngbin0 -> 1722 bytes
-rw-r--r--src/test/baseline/testUIButtonDown.pngbin0 -> 1657 bytes
-rw-r--r--src/test/baseline/testUIButtonUp.pngbin0 -> 1364 bytes
-rw-r--r--src/test/baseline/testUICheckBoxChecked_Down.pngbin0 -> 1506 bytes
-rw-r--r--src/test/baseline/testUICheckBoxChecked_Up.pngbin0 -> 1499 bytes
-rw-r--r--src/test/baseline/testUICheckBoxUnchecked_Disabled.pngbin0 -> 1440 bytes
-rw-r--r--src/test/baseline/testUICheckBoxUnchecked_Down.pngbin0 -> 1430 bytes
-rw-r--r--src/test/baseline/testUICheckBoxUnchecked_Up.pngbin0 -> 1471 bytes
-rw-r--r--src/test/baseline/testUIKeyboard.pngbin0 -> 859 bytes
-rw-r--r--src/test/baseline/testUIKeyboard1S.pngbin0 -> 911 bytes
-rw-r--r--src/test/baseline/testUIKeyboardA.pngbin0 -> 878 bytes
-rw-r--r--src/test/baseline/testUIKeyboardA1S.pngbin0 -> 885 bytes
-rw-r--r--src/test/baseline/testUIKeyboardAS.pngbin0 -> 883 bytes
-rw-r--r--src/test/baseline/testUIKeyboardDown11.pngbin0 -> 1979 bytes
-rw-r--r--src/test/baseline/testUIKeyboardDownA212S2.pngbin0 -> 2191 bytes
-rw-r--r--src/test/baseline/testUIKeyboardDownA2S1.pngbin0 -> 1205 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFB.pngbin0 -> 859 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFB1.pngbin0 -> 1616 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFBA1S.pngbin0 -> 1587 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFBAS.pngbin0 -> 2065 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFBS.pngbin0 -> 854 bytes
-rw-r--r--src/test/baseline/testUIKeyboardNoFB1S.pngbin0 -> 910 bytes
-rw-r--r--src/test/baseline/testUIKeyboardS.pngbin0 -> 855 bytes
-rw-r--r--src/test/baseline/testUIToggleChecked_Disabled.pngbin0 -> 1276 bytes
-rw-r--r--src/test/baseline/testUIToggleChecked_Down.pngbin0 -> 1458 bytes
-rw-r--r--src/test/baseline/testUIToggleChecked_Up.pngbin0 -> 1450 bytes
-rw-r--r--src/test/baseline/testUIToggleUnchecked_Disabled.pngbin0 -> 959 bytes
-rw-r--r--src/test/baseline/testUIToggleUnchecked_Down.pngbin0 -> 1113 bytes
-rw-r--r--src/test/baseline/testUIToggleUnchecked_Up.pngbin0 -> 1115 bytes
-rw-r--r--src/test/baseline/testVideo-h264-48x48.h2641.pngbin0 -> 9756 bytes
-rw-r--r--src/test/baseline/testVideo-mjpeg-48x48.avi1.pngbin0 -> 13061 bytes
-rw-r--r--src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.pngbin0 -> 10948 bytes
-rw-r--r--src/test/baseline/testVideo-mpeg1-48x48.mov1.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideo-rgba-48x48.mov1.pngbin0 -> 6434 bytes
-rw-r--r--src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.pngbin0 -> 10033 bytes
-rw-r--r--src/test/baseline/testVideoActive1.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testVideoActive2.pngbin0 -> 10508 bytes
-rw-r--r--src/test/baseline/testVideoDynamics1.pngbin0 -> 4236 bytes
-rw-r--r--src/test/baseline/testVideoDynamics2.pngbin0 -> 5735 bytes
-rw-r--r--src/test/baseline/testVideoDynamics3.pngbin0 -> 5598 bytes
-rw-r--r--src/test/baseline/testVideoDynamics4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testVideoDynamics5.pngbin0 -> 4236 bytes
-rw-r--r--src/test/baseline/testVideoFPS.pngbin0 -> 3215 bytes
-rw-r--r--src/test/baseline/testVideoHRef1.pngbin0 -> 3531 bytes
-rw-r--r--src/test/baseline/testVideoLoop.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA1.pngbin0 -> 804 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA2.pngbin0 -> 2147 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA3.pngbin0 -> 2619 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA4.pngbin0 -> 2194 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV1.pngbin0 -> 1499 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV2.pngbin0 -> 4117 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV3.pngbin0 -> 3861 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV4.pngbin0 -> 3115 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ1.pngbin0 -> 1804 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ2.pngbin0 -> 417 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ3.pngbin0 -> 1524 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ4.pngbin0 -> 1092 bytes
-rw-r--r--src/test/baseline/testVideoNullFX.pngbin0 -> 4769 bytes
-rw-r--r--src/test/baseline/testVideoOpacityRGBA1.pngbin0 -> 2215 bytes
-rw-r--r--src/test/baseline/testVideoOpacityRGBA2.pngbin0 -> 2245 bytes
-rw-r--r--src/test/baseline/testVideoOpacityYUV1.pngbin0 -> 3986 bytes
-rw-r--r--src/test/baseline/testVideoOpacityYUV2.pngbin0 -> 3976 bytes
-rw-r--r--src/test/baseline/testVideoSeek0.pngbin0 -> 11091 bytes
-rw-r--r--src/test/baseline/testVideoSeek1.pngbin0 -> 11683 bytes
-rw-r--r--src/test/baseline/testVideoSeek2.pngbin0 -> 11139 bytes
-rw-r--r--src/test/baseline/testVideoSeek3.pngbin0 -> 851 bytes
-rw-r--r--src/test/baseline/testVideoState1.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideoState2.pngbin0 -> 10424 bytes
-rw-r--r--src/test/baseline/testVideoState3.pngbin0 -> 10561 bytes
-rw-r--r--src/test/baseline/testVideoState4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testVideoState5.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideoWriter1.pngbin0 -> 4659 bytes
-rw-r--r--src/test/baseline/testVideoWriterCanvas1.pngbin0 -> 3935 bytes
-rw-r--r--src/test/baseline/testWarp1.pngbin0 -> 8512 bytes
-rw-r--r--src/test/baseline/testWarp2.pngbin0 -> 8401 bytes
-rw-r--r--src/test/baseline/testWarp3.pngbin0 -> 8451 bytes
-rw-r--r--src/test/baseline/testWordsBR.pngbin0 -> 1170 bytes
-rw-r--r--src/test/baseline/testWordsDynamics1.pngbin0 -> 513 bytes
-rw-r--r--src/test/baseline/testWordsDynamics2.pngbin0 -> 552 bytes
-rw-r--r--src/test/baseline/testWordsDynamics3.pngbin0 -> 552 bytes
-rw-r--r--src/test/baseline/testWordsDynamics4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testWordsDynamics5.pngbin0 -> 513 bytes
-rw-r--r--src/test/baseline/testWordsGamma1.pngbin0 -> 3194 bytes
-rw-r--r--src/test/baseline/testWordsGamma2.pngbin0 -> 3174 bytes
-rw-r--r--src/test/baseline/testWordsIntensity.pngbin0 -> 2239 bytes
-rw-r--r--src/test/baseline/testWordsMask1.pngbin0 -> 4057 bytes
-rw-r--r--src/test/baseline/testWordsMask2.pngbin0 -> 3471 bytes
-rw-r--r--src/test/baseline/testWordsMask3.pngbin0 -> 3420 bytes
-rw-r--r--src/test/baseline/testWordsMask4.pngbin0 -> 4055 bytes
-rw-r--r--src/test/baseline/testWordsMask5.pngbin0 -> 4129 bytes
-rw-r--r--src/test/baseline/testWordsMask6.pngbin0 -> 3854 bytes
-rw-r--r--src/test/baseline/testWordsMask7.pngbin0 -> 3853 bytes
-rw-r--r--src/test/baseline/testWordsNullFX.pngbin0 -> 949 bytes
-rw-r--r--src/test/baseline/testWordsOutlines.pngbin0 -> 1024 bytes
-rw-r--r--src/test/baseline/testWordsShadowFX1.pngbin0 -> 2034 bytes
-rw-r--r--src/test/baseline/testWordsShadowFX2.pngbin0 -> 2228 bytes
-rw-r--r--src/test/baseline/testWrapMode1.pngbin0 -> 2901 bytes
-rw-r--r--src/test/baseline/testWrapMode2.pngbin0 -> 3698 bytes
-rw-r--r--src/test/baseline/testWrapMode3.pngbin0 -> 2901 bytes
-rw-r--r--src/test/baseline/testWrapMode4.pngbin0 -> 3927 bytes
-rw-r--r--src/test/baseline/testXPosPointAnim1.pngbin0 -> 5123 bytes
-rw-r--r--src/test/baseline/testXPosPointAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testXPosPointAnim3.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testYPosPointAnim1.pngbin0 -> 5123 bytes
-rw-r--r--src/test/baseline/testYPosPointAnim2.pngbin0 -> 5127 bytes
-rw-r--r--src/test/baseline/testYPosPointAnim3.pngbin0 -> 5127 bytes
-rw-r--r--src/test/baseline/testbasics.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testline1.pngbin0 -> 348 bytes
-rw-r--r--src/test/baseline/testline2.pngbin0 -> 351 bytes
-rw-r--r--src/test/baseline/testline3.pngbin0 -> 364 bytes
-rw-r--r--src/test/baseline/testline4.pngbin0 -> 385 bytes
-rw-r--r--src/test/baseline/testlineopacity1.pngbin0 -> 154 bytes
-rw-r--r--src/test/baseline/testlineopacity2.pngbin0 -> 156 bytes
-rw-r--r--src/test/baseline/testlotsoflines.pngbin0 -> 369 bytes
-rw-r--r--src/test/baseline/testplugin1.pngbin0 -> 371 bytes
-rw-r--r--src/test/baseline/testplugin2.pngbin0 -> 375 bytes
-rw-r--r--src/test/baseline/testtexturedline1.pngbin0 -> 1854 bytes
-rw-r--r--src/test/baseline/testtexturedline2.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testtexturedline3.pngbin0 -> 1371 bytes
-rw-r--r--src/test/baseline/testtexturedline4.pngbin0 -> 1837 bytes
-rw-r--r--src/test/baseline/testtexturedline5.pngbin0 -> 213 bytes
-rw-r--r--src/test/camcfgs.py133
-rwxr-xr-xsrc/test/checkcamera.py225
-rw-r--r--src/test/extrafonts/testaddfontdir.ttfbin0 -> 1736 bytes
-rw-r--r--src/test/fonts/Vera.ttfbin0 -> 65932 bytes
-rw-r--r--src/test/fonts/VeraBI.ttfbin0 -> 63208 bytes
-rw-r--r--src/test/fonts/VeraBd.ttfbin0 -> 58716 bytes
-rw-r--r--src/test/fonts/VeraIt.ttfbin0 -> 63684 bytes
-rw-r--r--src/test/illustratorRect.svg7
-rw-r--r--src/test/image.avg8
-rw-r--r--src/test/media/1x1_white.pngbin0 -> 2791 bytes
-rwxr-xr-xsrc/test/media/22.050Hz_16bit_mono.wavbin0 -> 4454 bytes
-rw-r--r--src/test/media/44.1kHz_16bit_6Chan.oggbin0 -> 159170 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_16bit_mono.wavbin0 -> 8864 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_16bit_stereo.aifbin0 -> 352854 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_16bit_stereo.wavbin0 -> 352844 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_24bit_mono.wavbin0 -> 8864 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_24bit_stereo.aifbin0 -> 529254 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_24bit_stereo.wavbin0 -> 352844 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_mono.oggbin0 -> 4177 bytes
-rw-r--r--src/test/media/44.1kHz_stereo.mp3bin0 -> 47647 bytes
-rw-r--r--src/test/media/44.1kHz_stereo.oggbin0 -> 10211 bytes
-rwxr-xr-xsrc/test/media/48kHz_16bit_mono.wavbin0 -> 9644 bytes
-rwxr-xr-xsrc/test/media/48kHz_16bit_stereo.aifbin0 -> 384054 bytes
-rwxr-xr-xsrc/test/media/48kHz_16bit_stereo.wavbin0 -> 384044 bytes
-rwxr-xr-xsrc/test/media/48kHz_24bit_mono.wavbin0 -> 9644 bytes
-rwxr-xr-xsrc/test/media/48kHz_24bit_stereo.aifbin0 -> 576054 bytes
-rwxr-xr-xsrc/test/media/48kHz_24bit_stereo.wavbin0 -> 384044 bytes
-rw-r--r--src/test/media/48kHz_stereo.mp3bin0 -> 47808 bytes
-rw-r--r--src/test/media/48kHz_stereo.oggbin0 -> 104701 bytes
-rw-r--r--src/test/media/CustomSkin.xml83
-rw-r--r--src/test/media/SimpleSkin.xml83
-rw-r--r--src/test/media/button_bg_down.pngbin0 -> 3212 bytes
-rw-r--r--src/test/media/button_bg_up.pngbin0 -> 3085 bytes
-rw-r--r--src/test/media/button_check.pngbin0 -> 3040 bytes
-rw-r--r--src/test/media/button_disabled.pngbin0 -> 4308 bytes
-rw-r--r--src/test/media/button_down.pngbin0 -> 4221 bytes
-rw-r--r--src/test/media/button_over.pngbin0 -> 4131 bytes
-rw-r--r--src/test/media/button_up.pngbin0 -> 3923 bytes
-rw-r--r--src/test/media/checkbox_checked_disabled.pngbin0 -> 2908 bytes
-rw-r--r--src/test/media/checkbox_checked_down.pngbin0 -> 2902 bytes
-rw-r--r--src/test/media/checkbox_checked_up.pngbin0 -> 2902 bytes
-rw-r--r--src/test/media/checkbox_unchecked_disabled.pngbin0 -> 2856 bytes
-rw-r--r--src/test/media/checkbox_unchecked_down.pngbin0 -> 2849 bytes
-rw-r--r--src/test/media/checkbox_unchecked_up.pngbin0 -> 2849 bytes
-rw-r--r--src/test/media/checker.pngbin0 -> 3526 bytes
-rw-r--r--src/test/media/chromakey-median.pngbin0 -> 3331 bytes
-rw-r--r--src/test/media/chromakey.pngbin0 -> 2995 bytes
-rw-r--r--src/test/media/colorramp.pngbin0 -> 4471 bytes
-rw-r--r--src/test/media/crop_bkgd.pngbin0 -> 369 bytes
-rw-r--r--src/test/media/dilation.pngbin0 -> 80 bytes
-rw-r--r--src/test/media/erosion.pngbin0 -> 960 bytes
-rw-r--r--src/test/media/filterwipeborder.pngbin0 -> 1166 bytes
-rw-r--r--src/test/media/flat.pngbin0 -> 2861 bytes
-rw-r--r--src/test/media/floodfill.pngbin0 -> 119 bytes
-rw-r--r--src/test/media/freidrehen.jpgbin0 -> 3856 bytes
-rw-r--r--src/test/media/greyscale.pngbin0 -> 2245 bytes
-rw-r--r--src/test/media/h264-48x48.h264bin0 -> 131081 bytes
-rw-r--r--src/test/media/hsl.pngbin0 -> 3131 bytes
-rw-r--r--src/test/media/i8-64x64.pngbin0 -> 2256 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/IncompleteSkin.xml11
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.pngbin0 -> 2990 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.pngbin0 -> 2948 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_track.pngbin0 -> 2843 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.pngbin0 -> 2873 bytes
-rw-r--r--src/test/media/keyboard_bg.pngbin0 -> 781 bytes
-rw-r--r--src/test/media/keyboard_down.pngbin0 -> 775 bytes
-rw-r--r--src/test/media/keyboard_feedback.pngbin0 -> 2711 bytes
-rw-r--r--src/test/media/mask.pngbin0 -> 1270 bytes
-rw-r--r--src/test/media/mask1.pngbin0 -> 227 bytes
-rw-r--r--src/test/media/mask2.pngbin0 -> 1598 bytes
-rw-r--r--src/test/media/mjpeg-48x48.avibin0 -> 329852 bytes
-rw-r--r--src/test/media/mpeg1-48x48-sound.avibin0 -> 28534 bytes
-rw-r--r--src/test/media/mpeg1-48x48.movbin0 -> 9863 bytes
-rw-r--r--src/test/media/oe.pngbin0 -> 3178 bytes
-rw-r--r--src/test/media/pause_button_down.pngbin0 -> 2826 bytes
-rw-r--r--src/test/media/pause_button_up.pngbin0 -> 2825 bytes
-rw-r--r--src/test/media/play_button_down.pngbin0 -> 2927 bytes
-rw-r--r--src/test/media/play_button_up.pngbin0 -> 2928 bytes
-rw-r--r--src/test/media/rect.svg8
-rw-r--r--src/test/media/rectborder.pngbin0 -> 2810 bytes
-rw-r--r--src/test/media/rgb24-32x32.pngbin0 -> 3584 bytes
-rw-r--r--src/test/media/rgb24-64x64.pngbin0 -> 2092 bytes
-rw-r--r--src/test/media/rgb24-65x65.pngbin0 -> 2210 bytes
-rw-r--r--src/test/media/rgb24alpha-32x32.pngbin0 -> 4088 bytes
-rw-r--r--src/test/media/rgb24alpha-64x64.pngbin0 -> 3392 bytes
-rw-r--r--src/test/media/rgba-48x48.movbin0 -> 127378 bytes
-rw-r--r--src/test/media/scrollarea_border.pngbin0 -> 3262 bytes
-rw-r--r--src/test/media/scrollbar_horiz_thumb_disabled.pngbin0 -> 2924 bytes
-rw-r--r--src/test/media/scrollbar_horiz_thumb_down.pngbin0 -> 2990 bytes
-rw-r--r--src/test/media/scrollbar_horiz_thumb_up.pngbin0 -> 2948 bytes
-rw-r--r--src/test/media/scrollbar_horiz_track.pngbin0 -> 2843 bytes
-rw-r--r--src/test/media/scrollbar_horiz_track_disabled.pngbin0 -> 2873 bytes
-rw-r--r--src/test/media/scrollbar_vert_thumb_disabled.pngbin0 -> 2911 bytes
-rw-r--r--src/test/media/scrollbar_vert_thumb_down.pngbin0 -> 3008 bytes
-rw-r--r--src/test/media/scrollbar_vert_thumb_up.pngbin0 -> 2998 bytes
-rw-r--r--src/test/media/scrollbar_vert_track.pngbin0 -> 2903 bytes
-rw-r--r--src/test/media/scrollbar_vert_track_disabled.pngbin0 -> 2902 bytes
-rw-r--r--src/test/media/shadow.pngbin0 -> 3168 bytes
-rw-r--r--src/test/media/slider_horiz_track.pngbin0 -> 2858 bytes
-rw-r--r--src/test/media/slider_horiz_track_disabled.pngbin0 -> 2859 bytes
-rw-r--r--src/test/media/slider_thumb_down.pngbin0 -> 3200 bytes
-rw-r--r--src/test/media/slider_thumb_up.pngbin0 -> 3225 bytes
-rw-r--r--src/test/media/slider_vert_track.pngbin0 -> 2867 bytes
-rw-r--r--src/test/media/slider_vert_track_disabled.pngbin0 -> 2866 bytes
-rw-r--r--src/test/media/spike.pngbin0 -> 2820 bytes
-rw-r--r--src/test/media/toggle_checked_Disabled.pngbin0 -> 3886 bytes
-rw-r--r--src/test/media/toggle_checked_Down.pngbin0 -> 3873 bytes
-rw-r--r--src/test/media/toggle_checked_Up.pngbin0 -> 3867 bytes
-rw-r--r--src/test/media/toggle_unchecked_Disabled.pngbin0 -> 3555 bytes
-rw-r--r--src/test/media/toggle_unchecked_Down.pngbin0 -> 3506 bytes
-rw-r--r--src/test/media/toggle_unchecked_Up.pngbin0 -> 3517 bytes
-rw-r--r--src/test/media/vp6a-yuva-48x48.flvbin0 -> 13669 bytes
-rw-r--r--src/test/media/widebmp.jpgbin0 -> 33903 bytes
-rw-r--r--src/test/plugin/ColorNode.cpp153
-rw-r--r--src/test/plugin/Makefile.am19
-rwxr-xr-xsrc/test/plugin/test.sh5
-rw-r--r--src/test/testapp.py191
-rw-r--r--src/test/testcase.py369
-rw-r--r--src/test/testmediadir/mjpeg-48x48.avibin0 -> 10240 bytes
-rw-r--r--src/test/testmediadir/rgb24-64x64a.pngbin0 -> 3392 bytes
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">
+ &amp;
+ </words>
+ """))
+ avg.WordsNode(pos=(12,48), fontsize=12, font="Bitstream Vera Sans", text="&amp;",
+ 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='&lt;test dyndict&amp;',
+ rawtextmode=True, pos=(1,65), font='Bitstream Vera Sans',
+ variant='roman', fontsize=12)
+ root.appendChild(self.dictdnode)
+
+ self.xmldnode = player.createNode("""
+ <words text="&lt;test dynattr&amp;" 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é &lt;</words>""")
+ root.appendChild(valNode)
+ root.appendChild(
+ player.createNode("""
+ <words x="1" y="45" fontsize="15" font="Bitstream Vera Sans">
+ &amp;
+ </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
new file mode 100644
index 0000000..f561888
--- /dev/null
+++ b/src/test/baseline/test2VideosAtOnce1.png
Binary files differ
diff --git a/src/test/baseline/testAVGFile.png b/src/test/baseline/testAVGFile.png
new file mode 100644
index 0000000..375582b
--- /dev/null
+++ b/src/test/baseline/testAVGFile.png
Binary files differ
diff --git a/src/test/baseline/testAnim1.png b/src/test/baseline/testAnim1.png
new file mode 100644
index 0000000..6651fc3
--- /dev/null
+++ b/src/test/baseline/testAnim1.png
Binary files differ
diff --git a/src/test/baseline/testAnim2.png b/src/test/baseline/testAnim2.png
new file mode 100644
index 0000000..d8553de
--- /dev/null
+++ b/src/test/baseline/testAnim2.png
Binary files differ
diff --git a/src/test/baseline/testAnim3.png b/src/test/baseline/testAnim3.png
new file mode 100644
index 0000000..4d6dbd7
--- /dev/null
+++ b/src/test/baseline/testAnim3.png
Binary files differ
diff --git a/src/test/baseline/testArc1.png b/src/test/baseline/testArc1.png
new file mode 100644
index 0000000..9c4a2f0
--- /dev/null
+++ b/src/test/baseline/testArc1.png
Binary files differ
diff --git a/src/test/baseline/testArc2.png b/src/test/baseline/testArc2.png
new file mode 100644
index 0000000..1e321a3
--- /dev/null
+++ b/src/test/baseline/testArc2.png
Binary files differ
diff --git a/src/test/baseline/testBitmap1.png b/src/test/baseline/testBitmap1.png
new file mode 100644
index 0000000..c5b06a0
--- /dev/null
+++ b/src/test/baseline/testBitmap1.png
Binary files differ
diff --git a/src/test/baseline/testBitmap2.png b/src/test/baseline/testBitmap2.png
new file mode 100644
index 0000000..f94b54e
--- /dev/null
+++ b/src/test/baseline/testBitmap2.png
Binary files differ
diff --git a/src/test/baseline/testBitmap3.png b/src/test/baseline/testBitmap3.png
new file mode 100644
index 0000000..7d0898d
--- /dev/null
+++ b/src/test/baseline/testBitmap3.png
Binary files differ
diff --git a/src/test/baseline/testBitmap4.png b/src/test/baseline/testBitmap4.png
new file mode 100644
index 0000000..5569133
--- /dev/null
+++ b/src/test/baseline/testBitmap4.png
Binary files differ
diff --git a/src/test/baseline/testBlend1.png b/src/test/baseline/testBlend1.png
new file mode 100644
index 0000000..29e4a11
--- /dev/null
+++ b/src/test/baseline/testBlend1.png
Binary files differ
diff --git a/src/test/baseline/testBlend2.png b/src/test/baseline/testBlend2.png
new file mode 100644
index 0000000..8b2ae59
--- /dev/null
+++ b/src/test/baseline/testBlend2.png
Binary files differ
diff --git a/src/test/baseline/testBlurFX1.png b/src/test/baseline/testBlurFX1.png
new file mode 100644
index 0000000..9564d6f
--- /dev/null
+++ b/src/test/baseline/testBlurFX1.png
Binary files differ
diff --git a/src/test/baseline/testBlurFX2.png b/src/test/baseline/testBlurFX2.png
new file mode 100644
index 0000000..0147846
--- /dev/null
+++ b/src/test/baseline/testBlurFX2.png
Binary files differ
diff --git a/src/test/baseline/testBlurFX3.png b/src/test/baseline/testBlurFX3.png
new file mode 100644
index 0000000..b50decf
--- /dev/null
+++ b/src/test/baseline/testBlurFX3.png
Binary files differ
diff --git a/src/test/baseline/testButtonDisabled.png b/src/test/baseline/testButtonDisabled.png
new file mode 100644
index 0000000..6b7eea4
--- /dev/null
+++ b/src/test/baseline/testButtonDisabled.png
Binary files differ
diff --git a/src/test/baseline/testButtonDown.png b/src/test/baseline/testButtonDown.png
new file mode 100644
index 0000000..96e6e40
--- /dev/null
+++ b/src/test/baseline/testButtonDown.png
Binary files differ
diff --git a/src/test/baseline/testButtonOver.png b/src/test/baseline/testButtonOver.png
new file mode 100644
index 0000000..f3d5a0e
--- /dev/null
+++ b/src/test/baseline/testButtonOver.png
Binary files differ
diff --git a/src/test/baseline/testButtonUp.png b/src/test/baseline/testButtonUp.png
new file mode 100644
index 0000000..a9adeb5
--- /dev/null
+++ b/src/test/baseline/testButtonUp.png
Binary files differ
diff --git a/src/test/baseline/testCanvasAlpha.png b/src/test/baseline/testCanvasAlpha.png
new file mode 100644
index 0000000..63fb052
--- /dev/null
+++ b/src/test/baseline/testCanvasAlpha.png
Binary files differ
diff --git a/src/test/baseline/testCanvasBlendModes.png b/src/test/baseline/testCanvasBlendModes.png
new file mode 100644
index 0000000..f0feba3
--- /dev/null
+++ b/src/test/baseline/testCanvasBlendModes.png
Binary files differ
diff --git a/src/test/baseline/testCanvasCrop.png b/src/test/baseline/testCanvasCrop.png
new file mode 100644
index 0000000..ffcdcfa
--- /dev/null
+++ b/src/test/baseline/testCanvasCrop.png
Binary files differ
diff --git a/src/test/baseline/testCanvasDependencies1.png b/src/test/baseline/testCanvasDependencies1.png
new file mode 100644
index 0000000..5821855
--- /dev/null
+++ b/src/test/baseline/testCanvasDependencies1.png
Binary files differ
diff --git a/src/test/baseline/testCanvasDependencies2.png b/src/test/baseline/testCanvasDependencies2.png
new file mode 100644
index 0000000..d38ac6a
--- /dev/null
+++ b/src/test/baseline/testCanvasDependencies2.png
Binary files differ
diff --git a/src/test/baseline/testCanvasMipmap.png b/src/test/baseline/testCanvasMipmap.png
new file mode 100644
index 0000000..ecc51f0
--- /dev/null
+++ b/src/test/baseline/testCanvasMipmap.png
Binary files differ
diff --git a/src/test/baseline/testCanvasMultisample.png b/src/test/baseline/testCanvasMultisample.png
new file mode 100644
index 0000000..1f30aad
--- /dev/null
+++ b/src/test/baseline/testCanvasMultisample.png
Binary files differ
diff --git a/src/test/baseline/testCanvasNullFX1.png b/src/test/baseline/testCanvasNullFX1.png
new file mode 100644
index 0000000..c877bdf
--- /dev/null
+++ b/src/test/baseline/testCanvasNullFX1.png
Binary files differ
diff --git a/src/test/baseline/testCanvasNullFX2.png b/src/test/baseline/testCanvasNullFX2.png
new file mode 100644
index 0000000..8e485f7
--- /dev/null
+++ b/src/test/baseline/testCanvasNullFX2.png
Binary files differ
diff --git a/src/test/baseline/testCanvasNullFX3.png b/src/test/baseline/testCanvasNullFX3.png
new file mode 100644
index 0000000..56571a2
--- /dev/null
+++ b/src/test/baseline/testCanvasNullFX3.png
Binary files differ
diff --git a/src/test/baseline/testCanvasResize.png b/src/test/baseline/testCanvasResize.png
new file mode 100644
index 0000000..5821855
--- /dev/null
+++ b/src/test/baseline/testCanvasResize.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxClickedDown.png b/src/test/baseline/testCheckboxClickedDown.png
new file mode 100644
index 0000000..2065be3
--- /dev/null
+++ b/src/test/baseline/testCheckboxClickedDown.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxClickedOut.png b/src/test/baseline/testCheckboxClickedOut.png
new file mode 100644
index 0000000..a17d5b2
--- /dev/null
+++ b/src/test/baseline/testCheckboxClickedOut.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxClickedOver.png b/src/test/baseline/testCheckboxClickedOver.png
new file mode 100644
index 0000000..b94c9d9
--- /dev/null
+++ b/src/test/baseline/testCheckboxClickedOver.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxDown.png b/src/test/baseline/testCheckboxDown.png
new file mode 100644
index 0000000..96e6e40
--- /dev/null
+++ b/src/test/baseline/testCheckboxDown.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxOver.png b/src/test/baseline/testCheckboxOver.png
new file mode 100644
index 0000000..f3d5a0e
--- /dev/null
+++ b/src/test/baseline/testCheckboxOver.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxUp.png b/src/test/baseline/testCheckboxUp.png
new file mode 100644
index 0000000..a9adeb5
--- /dev/null
+++ b/src/test/baseline/testCheckboxUp.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX1.png b/src/test/baseline/testChromaKeyFX1.png
new file mode 100644
index 0000000..9f63ce5
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX1.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX2.png b/src/test/baseline/testChromaKeyFX2.png
new file mode 100644
index 0000000..65df5ea
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX2.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX3.png b/src/test/baseline/testChromaKeyFX3.png
new file mode 100644
index 0000000..1ab1b59
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX3.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX4.png b/src/test/baseline/testChromaKeyFX4.png
new file mode 100644
index 0000000..86efc70
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX4.png
Binary files differ
diff --git a/src/test/baseline/testCircle1.png b/src/test/baseline/testCircle1.png
new file mode 100644
index 0000000..45f2c58
--- /dev/null
+++ b/src/test/baseline/testCircle1.png
Binary files differ
diff --git a/src/test/baseline/testCircle2.png b/src/test/baseline/testCircle2.png
new file mode 100644
index 0000000..26ca01c
--- /dev/null
+++ b/src/test/baseline/testCircle2.png
Binary files differ
diff --git a/src/test/baseline/testCircle3.png b/src/test/baseline/testCircle3.png
new file mode 100644
index 0000000..4824bcf
--- /dev/null
+++ b/src/test/baseline/testCircle3.png
Binary files differ
diff --git a/src/test/baseline/testCircle4.png b/src/test/baseline/testCircle4.png
new file mode 100644
index 0000000..be36e58
--- /dev/null
+++ b/src/test/baseline/testCircle4.png
Binary files differ
diff --git a/src/test/baseline/testCircle5.png b/src/test/baseline/testCircle5.png
new file mode 100644
index 0000000..f70b3eb
--- /dev/null
+++ b/src/test/baseline/testCircle5.png
Binary files differ
diff --git a/src/test/baseline/testColorFX1.png b/src/test/baseline/testColorFX1.png
new file mode 100644
index 0000000..1a225e9
--- /dev/null
+++ b/src/test/baseline/testColorFX1.png
Binary files differ
diff --git a/src/test/baseline/testColorFX2.png b/src/test/baseline/testColorFX2.png
new file mode 100644
index 0000000..dc708c6
--- /dev/null
+++ b/src/test/baseline/testColorFX2.png
Binary files differ
diff --git a/src/test/baseline/testColorFX3.png b/src/test/baseline/testColorFX3.png
new file mode 100644
index 0000000..b82c72d
--- /dev/null
+++ b/src/test/baseline/testColorFX3.png
Binary files differ
diff --git a/src/test/baseline/testColorFX4.png b/src/test/baseline/testColorFX4.png
new file mode 100644
index 0000000..5722a24
--- /dev/null
+++ b/src/test/baseline/testColorFX4.png
Binary files differ
diff --git a/src/test/baseline/testColorFX5.png b/src/test/baseline/testColorFX5.png
new file mode 100644
index 0000000..dbcec1c
--- /dev/null
+++ b/src/test/baseline/testColorFX5.png
Binary files differ
diff --git a/src/test/baseline/testColorFX6.png b/src/test/baseline/testColorFX6.png
new file mode 100644
index 0000000..ab46da3
--- /dev/null
+++ b/src/test/baseline/testColorFX6.png
Binary files differ
diff --git a/src/test/baseline/testColorFX7.png b/src/test/baseline/testColorFX7.png
new file mode 100644
index 0000000..5fb43b8
--- /dev/null
+++ b/src/test/baseline/testColorFX7.png
Binary files differ
diff --git a/src/test/baseline/testComplexDiv1.png b/src/test/baseline/testComplexDiv1.png
new file mode 100644
index 0000000..bde774d
--- /dev/null
+++ b/src/test/baseline/testComplexDiv1.png
Binary files differ
diff --git a/src/test/baseline/testContAnim1.png b/src/test/baseline/testContAnim1.png
new file mode 100644
index 0000000..f337d2f
--- /dev/null
+++ b/src/test/baseline/testContAnim1.png
Binary files differ
diff --git a/src/test/baseline/testContAnim2.png b/src/test/baseline/testContAnim2.png
new file mode 100644
index 0000000..1e2b4fd
--- /dev/null
+++ b/src/test/baseline/testContAnim2.png
Binary files differ
diff --git a/src/test/baseline/testContAnim3.png b/src/test/baseline/testContAnim3.png
new file mode 100644
index 0000000..cdf6b45
--- /dev/null
+++ b/src/test/baseline/testContAnim3.png
Binary files differ
diff --git a/src/test/baseline/testContAnim4.png b/src/test/baseline/testContAnim4.png
new file mode 100644
index 0000000..3a16eeb
--- /dev/null
+++ b/src/test/baseline/testContAnim4.png
Binary files differ
diff --git a/src/test/baseline/testContinuousAnim1.png b/src/test/baseline/testContinuousAnim1.png
new file mode 100644
index 0000000..4f8a5be
--- /dev/null
+++ b/src/test/baseline/testContinuousAnim1.png
Binary files differ
diff --git a/src/test/baseline/testContinuousAnim2.png b/src/test/baseline/testContinuousAnim2.png
new file mode 100644
index 0000000..34a9e24
--- /dev/null
+++ b/src/test/baseline/testContinuousAnim2.png
Binary files differ
diff --git a/src/test/baseline/testContrast1.png b/src/test/baseline/testContrast1.png
new file mode 100644
index 0000000..06bf3d0
--- /dev/null
+++ b/src/test/baseline/testContrast1.png
Binary files differ
diff --git a/src/test/baseline/testContrast2.png b/src/test/baseline/testContrast2.png
new file mode 100644
index 0000000..fc1e0e6
--- /dev/null
+++ b/src/test/baseline/testContrast2.png
Binary files differ
diff --git a/src/test/baseline/testContrast3.png b/src/test/baseline/testContrast3.png
new file mode 100644
index 0000000..e979473
--- /dev/null
+++ b/src/test/baseline/testContrast3.png
Binary files differ
diff --git a/src/test/baseline/testCropImage1.png b/src/test/baseline/testCropImage1.png
new file mode 100644
index 0000000..40bdcfe
--- /dev/null
+++ b/src/test/baseline/testCropImage1.png
Binary files differ
diff --git a/src/test/baseline/testCropImage10.png b/src/test/baseline/testCropImage10.png
new file mode 100644
index 0000000..f05723a
--- /dev/null
+++ b/src/test/baseline/testCropImage10.png
Binary files differ
diff --git a/src/test/baseline/testCropImage2.png b/src/test/baseline/testCropImage2.png
new file mode 100644
index 0000000..e0706ea
--- /dev/null
+++ b/src/test/baseline/testCropImage2.png
Binary files differ
diff --git a/src/test/baseline/testCropImage3.png b/src/test/baseline/testCropImage3.png
new file mode 100644
index 0000000..33078f2
--- /dev/null
+++ b/src/test/baseline/testCropImage3.png
Binary files differ
diff --git a/src/test/baseline/testCropImage4.png b/src/test/baseline/testCropImage4.png
new file mode 100644
index 0000000..e230b9a
--- /dev/null
+++ b/src/test/baseline/testCropImage4.png
Binary files differ
diff --git a/src/test/baseline/testCropImage5.png b/src/test/baseline/testCropImage5.png
new file mode 100644
index 0000000..0636df4
--- /dev/null
+++ b/src/test/baseline/testCropImage5.png
Binary files differ
diff --git a/src/test/baseline/testCropImage6.png b/src/test/baseline/testCropImage6.png
new file mode 100644
index 0000000..566f599
--- /dev/null
+++ b/src/test/baseline/testCropImage6.png
Binary files differ
diff --git a/src/test/baseline/testCropImage7.png b/src/test/baseline/testCropImage7.png
new file mode 100644
index 0000000..632a158
--- /dev/null
+++ b/src/test/baseline/testCropImage7.png
Binary files differ
diff --git a/src/test/baseline/testCropImage8.png b/src/test/baseline/testCropImage8.png
new file mode 100644
index 0000000..017faca
--- /dev/null
+++ b/src/test/baseline/testCropImage8.png
Binary files differ
diff --git a/src/test/baseline/testCropImage9.png b/src/test/baseline/testCropImage9.png
new file mode 100644
index 0000000..2f013fc
--- /dev/null
+++ b/src/test/baseline/testCropImage9.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie1.png b/src/test/baseline/testCropMovie1.png
new file mode 100644
index 0000000..aaff2c3
--- /dev/null
+++ b/src/test/baseline/testCropMovie1.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie10.png b/src/test/baseline/testCropMovie10.png
new file mode 100644
index 0000000..1ef3ca3
--- /dev/null
+++ b/src/test/baseline/testCropMovie10.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie2.png b/src/test/baseline/testCropMovie2.png
new file mode 100644
index 0000000..1345610
--- /dev/null
+++ b/src/test/baseline/testCropMovie2.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie3.png b/src/test/baseline/testCropMovie3.png
new file mode 100644
index 0000000..a2aef90
--- /dev/null
+++ b/src/test/baseline/testCropMovie3.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie4.png b/src/test/baseline/testCropMovie4.png
new file mode 100644
index 0000000..72a5ae2
--- /dev/null
+++ b/src/test/baseline/testCropMovie4.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie5.png b/src/test/baseline/testCropMovie5.png
new file mode 100644
index 0000000..8e663fc
--- /dev/null
+++ b/src/test/baseline/testCropMovie5.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie6.png b/src/test/baseline/testCropMovie6.png
new file mode 100644
index 0000000..ff47430
--- /dev/null
+++ b/src/test/baseline/testCropMovie6.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie7.png b/src/test/baseline/testCropMovie7.png
new file mode 100644
index 0000000..60941e4
--- /dev/null
+++ b/src/test/baseline/testCropMovie7.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie8.png b/src/test/baseline/testCropMovie8.png
new file mode 100644
index 0000000..e12b702
--- /dev/null
+++ b/src/test/baseline/testCropMovie8.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie9.png b/src/test/baseline/testCropMovie9.png
new file mode 100644
index 0000000..f0ede3e
--- /dev/null
+++ b/src/test/baseline/testCropMovie9.png
Binary files differ
diff --git a/src/test/baseline/testCurve1.png b/src/test/baseline/testCurve1.png
new file mode 100644
index 0000000..70127bc
--- /dev/null
+++ b/src/test/baseline/testCurve1.png
Binary files differ
diff --git a/src/test/baseline/testCurve2.png b/src/test/baseline/testCurve2.png
new file mode 100644
index 0000000..6046c98
--- /dev/null
+++ b/src/test/baseline/testCurve2.png
Binary files differ
diff --git a/src/test/baseline/testCurve3.png b/src/test/baseline/testCurve3.png
new file mode 100644
index 0000000..9545904
--- /dev/null
+++ b/src/test/baseline/testCurve3.png
Binary files differ
diff --git a/src/test/baseline/testCurve4.png b/src/test/baseline/testCurve4.png
new file mode 100644
index 0000000..1472c2f
--- /dev/null
+++ b/src/test/baseline/testCurve4.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics1.png b/src/test/baseline/testDivDynamics1.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testDivDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics2.png b/src/test/baseline/testDivDynamics2.png
new file mode 100644
index 0000000..b3f308f
--- /dev/null
+++ b/src/test/baseline/testDivDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics3.png b/src/test/baseline/testDivDynamics3.png
new file mode 100644
index 0000000..72a9acf
--- /dev/null
+++ b/src/test/baseline/testDivDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics4.png b/src/test/baseline/testDivDynamics4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testDivDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics5.png b/src/test/baseline/testDivDynamics5.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testDivDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testDraggable1.png b/src/test/baseline/testDraggable1.png
new file mode 100644
index 0000000..d60276f
--- /dev/null
+++ b/src/test/baseline/testDraggable1.png
Binary files differ
diff --git a/src/test/baseline/testDraggable2.png b/src/test/baseline/testDraggable2.png
new file mode 100644
index 0000000..19ad729
--- /dev/null
+++ b/src/test/baseline/testDraggable2.png
Binary files differ
diff --git a/src/test/baseline/testDynamicMediaDir1.png b/src/test/baseline/testDynamicMediaDir1.png
new file mode 100644
index 0000000..71c0100
--- /dev/null
+++ b/src/test/baseline/testDynamicMediaDir1.png
Binary files differ
diff --git a/src/test/baseline/testDynamicMediaDir2.png b/src/test/baseline/testDynamicMediaDir2.png
new file mode 100644
index 0000000..392e2a8
--- /dev/null
+++ b/src/test/baseline/testDynamicMediaDir2.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords1.png b/src/test/baseline/testDynamicWords1.png
new file mode 100644
index 0000000..9b37b72
--- /dev/null
+++ b/src/test/baseline/testDynamicWords1.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords2.png b/src/test/baseline/testDynamicWords2.png
new file mode 100644
index 0000000..390d0f3
--- /dev/null
+++ b/src/test/baseline/testDynamicWords2.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords3.png b/src/test/baseline/testDynamicWords3.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testDynamicWords3.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords4.png b/src/test/baseline/testDynamicWords4.png
new file mode 100644
index 0000000..789c2c8
--- /dev/null
+++ b/src/test/baseline/testDynamicWords4.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnim1.png b/src/test/baseline/testEaseInOutAnim1.png
new file mode 100644
index 0000000..82abf89
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnim1.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnim2.png b/src/test/baseline/testEaseInOutAnim2.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnim2.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnim3.png b/src/test/baseline/testEaseInOutAnim3.png
new file mode 100644
index 0000000..03311b5
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnim3.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC1.png b/src/test/baseline/testEaseInOutAnimC1.png
new file mode 100644
index 0000000..fbe5b29
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC2.png b/src/test/baseline/testEaseInOutAnimC2.png
new file mode 100644
index 0000000..1e889df
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC3.png b/src/test/baseline/testEaseInOutAnimC3.png
new file mode 100644
index 0000000..40d820a
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC4.png b/src/test/baseline/testEaseInOutAnimC4.png
new file mode 100644
index 0000000..9703e09
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC4.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC5.png b/src/test/baseline/testEaseInOutAnimC5.png
new file mode 100644
index 0000000..40d820a
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC5.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC6.png b/src/test/baseline/testEaseInOutAnimC6.png
new file mode 100644
index 0000000..60da2b1
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC6.png
Binary files differ
diff --git a/src/test/baseline/testEvents.png b/src/test/baseline/testEvents.png
new file mode 100644
index 0000000..bdd9280
--- /dev/null
+++ b/src/test/baseline/testEvents.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateFX.png b/src/test/baseline/testFXUpdateFX.png
new file mode 100644
index 0000000..a2d1a44
--- /dev/null
+++ b/src/test/baseline/testFXUpdateFX.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateMaskPos.png b/src/test/baseline/testFXUpdateMaskPos.png
new file mode 100644
index 0000000..150ebd2
--- /dev/null
+++ b/src/test/baseline/testFXUpdateMaskPos.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateMaskTex1.png b/src/test/baseline/testFXUpdateMaskTex1.png
new file mode 100644
index 0000000..18588ff
--- /dev/null
+++ b/src/test/baseline/testFXUpdateMaskTex1.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateMaskTex2.png b/src/test/baseline/testFXUpdateMaskTex2.png
new file mode 100644
index 0000000..4790154
--- /dev/null
+++ b/src/test/baseline/testFXUpdateMaskTex2.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateTex.png b/src/test/baseline/testFXUpdateTex.png
new file mode 100644
index 0000000..3111780
--- /dev/null
+++ b/src/test/baseline/testFXUpdateTex.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateVideo.png b/src/test/baseline/testFXUpdateVideo.png
new file mode 100644
index 0000000..fed9567
--- /dev/null
+++ b/src/test/baseline/testFXUpdateVideo.png
Binary files differ
diff --git a/src/test/baseline/testFadeIn1.png b/src/test/baseline/testFadeIn1.png
new file mode 100644
index 0000000..e4a332a
--- /dev/null
+++ b/src/test/baseline/testFadeIn1.png
Binary files differ
diff --git a/src/test/baseline/testFadeIn2.png b/src/test/baseline/testFadeIn2.png
new file mode 100644
index 0000000..b1c6746
--- /dev/null
+++ b/src/test/baseline/testFadeIn2.png
Binary files differ
diff --git a/src/test/baseline/testFadeIn3.png b/src/test/baseline/testFadeIn3.png
new file mode 100644
index 0000000..02f0389
--- /dev/null
+++ b/src/test/baseline/testFadeIn3.png
Binary files differ
diff --git a/src/test/baseline/testFadeOut1.png b/src/test/baseline/testFadeOut1.png
new file mode 100644
index 0000000..e4a332a
--- /dev/null
+++ b/src/test/baseline/testFadeOut1.png
Binary files differ
diff --git a/src/test/baseline/testFadeOut2.png b/src/test/baseline/testFadeOut2.png
new file mode 100644
index 0000000..f7bcf5b
--- /dev/null
+++ b/src/test/baseline/testFadeOut2.png
Binary files differ
diff --git a/src/test/baseline/testFadeOut3.png b/src/test/baseline/testFadeOut3.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testFadeOut3.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext1.png b/src/test/baseline/testFocusContext1.png
new file mode 100644
index 0000000..380902e
--- /dev/null
+++ b/src/test/baseline/testFocusContext1.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext2.png b/src/test/baseline/testFocusContext2.png
new file mode 100644
index 0000000..5ecbcf4
--- /dev/null
+++ b/src/test/baseline/testFocusContext2.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext3.png b/src/test/baseline/testFocusContext3.png
new file mode 100644
index 0000000..0606d81
--- /dev/null
+++ b/src/test/baseline/testFocusContext3.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext4.png b/src/test/baseline/testFocusContext4.png
new file mode 100644
index 0000000..9629e81
--- /dev/null
+++ b/src/test/baseline/testFocusContext4.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext5.png b/src/test/baseline/testFocusContext5.png
new file mode 100644
index 0000000..2ae68e0
--- /dev/null
+++ b/src/test/baseline/testFocusContext5.png
Binary files differ
diff --git a/src/test/baseline/testFontDir.png b/src/test/baseline/testFontDir.png
new file mode 100644
index 0000000..5dc4858
--- /dev/null
+++ b/src/test/baseline/testFontDir.png
Binary files differ
diff --git a/src/test/baseline/testFontStyle1.png b/src/test/baseline/testFontStyle1.png
new file mode 100644
index 0000000..3d773d6
--- /dev/null
+++ b/src/test/baseline/testFontStyle1.png
Binary files differ
diff --git a/src/test/baseline/testFontStyle2.png b/src/test/baseline/testFontStyle2.png
new file mode 100644
index 0000000..e67cfa4
--- /dev/null
+++ b/src/test/baseline/testFontStyle2.png
Binary files differ
diff --git a/src/test/baseline/testGamma1.png b/src/test/baseline/testGamma1.png
new file mode 100644
index 0000000..a713a13
--- /dev/null
+++ b/src/test/baseline/testGamma1.png
Binary files differ
diff --git a/src/test/baseline/testGamma2.png b/src/test/baseline/testGamma2.png
new file mode 100644
index 0000000..18d0479
--- /dev/null
+++ b/src/test/baseline/testGamma2.png
Binary files differ
diff --git a/src/test/baseline/testHVStretchNode1.png b/src/test/baseline/testHVStretchNode1.png
new file mode 100644
index 0000000..304c23e
--- /dev/null
+++ b/src/test/baseline/testHVStretchNode1.png
Binary files differ
diff --git a/src/test/baseline/testHVStretchNode2.png b/src/test/baseline/testHVStretchNode2.png
new file mode 100644
index 0000000..ca1f0f2
--- /dev/null
+++ b/src/test/baseline/testHVStretchNode2.png
Binary files differ
diff --git a/src/test/baseline/testHinting1.png b/src/test/baseline/testHinting1.png
new file mode 100644
index 0000000..4657e71
--- /dev/null
+++ b/src/test/baseline/testHinting1.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX1.png b/src/test/baseline/testHueSatFX1.png
new file mode 100644
index 0000000..abe4582
--- /dev/null
+++ b/src/test/baseline/testHueSatFX1.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX2.png b/src/test/baseline/testHueSatFX2.png
new file mode 100644
index 0000000..736bfbd
--- /dev/null
+++ b/src/test/baseline/testHueSatFX2.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX3.png b/src/test/baseline/testHueSatFX3.png
new file mode 100644
index 0000000..96e7744
--- /dev/null
+++ b/src/test/baseline/testHueSatFX3.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX4.png b/src/test/baseline/testHueSatFX4.png
new file mode 100644
index 0000000..7aff060
--- /dev/null
+++ b/src/test/baseline/testHueSatFX4.png
Binary files differ
diff --git a/src/test/baseline/testHugeImage0.png b/src/test/baseline/testHugeImage0.png
new file mode 100644
index 0000000..eb59ae0
--- /dev/null
+++ b/src/test/baseline/testHugeImage0.png
Binary files differ
diff --git a/src/test/baseline/testHugeImage1.png b/src/test/baseline/testHugeImage1.png
new file mode 100644
index 0000000..241b52f
--- /dev/null
+++ b/src/test/baseline/testHugeImage1.png
Binary files differ
diff --git a/src/test/baseline/testI18NWords1.png b/src/test/baseline/testI18NWords1.png
new file mode 100644
index 0000000..b9b8808
--- /dev/null
+++ b/src/test/baseline/testI18NWords1.png
Binary files differ
diff --git a/src/test/baseline/testI18NWords2.png b/src/test/baseline/testI18NWords2.png
new file mode 100644
index 0000000..e3f649b
--- /dev/null
+++ b/src/test/baseline/testI18NWords2.png
Binary files differ
diff --git a/src/test/baseline/testI18NWords3.png b/src/test/baseline/testI18NWords3.png
new file mode 100644
index 0000000..ace8433
--- /dev/null
+++ b/src/test/baseline/testI18NWords3.png
Binary files differ
diff --git a/src/test/baseline/testImageNullFX1.png b/src/test/baseline/testImageNullFX1.png
new file mode 100644
index 0000000..cdbf3fb
--- /dev/null
+++ b/src/test/baseline/testImageNullFX1.png
Binary files differ
diff --git a/src/test/baseline/testImageNullFX2.png b/src/test/baseline/testImageNullFX2.png
new file mode 100644
index 0000000..a5dd14b
--- /dev/null
+++ b/src/test/baseline/testImageNullFX2.png
Binary files differ
diff --git a/src/test/baseline/testImageNullFX3.png b/src/test/baseline/testImageNullFX3.png
new file mode 100644
index 0000000..f9b00d9
--- /dev/null
+++ b/src/test/baseline/testImageNullFX3.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics1.png b/src/test/baseline/testImgDynamics1.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testImgDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics2.png b/src/test/baseline/testImgDynamics2.png
new file mode 100644
index 0000000..b3f308f
--- /dev/null
+++ b/src/test/baseline/testImgDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics3.png b/src/test/baseline/testImgDynamics3.png
new file mode 100644
index 0000000..72a9acf
--- /dev/null
+++ b/src/test/baseline/testImgDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics4.png b/src/test/baseline/testImgDynamics4.png
new file mode 100644
index 0000000..21c01f2
--- /dev/null
+++ b/src/test/baseline/testImgDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics5.png b/src/test/baseline/testImgDynamics5.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testImgDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testImgHRef1.png b/src/test/baseline/testImgHRef1.png
new file mode 100644
index 0000000..a1df968
--- /dev/null
+++ b/src/test/baseline/testImgHRef1.png
Binary files differ
diff --git a/src/test/baseline/testImgHRef2.png b/src/test/baseline/testImgHRef2.png
new file mode 100644
index 0000000..03c8e41
--- /dev/null
+++ b/src/test/baseline/testImgHRef2.png
Binary files differ
diff --git a/src/test/baseline/testImgHRef3.png b/src/test/baseline/testImgHRef3.png
new file mode 100644
index 0000000..b18ec93
--- /dev/null
+++ b/src/test/baseline/testImgHRef3.png
Binary files differ
diff --git a/src/test/baseline/testImgMask1.png b/src/test/baseline/testImgMask1.png
new file mode 100644
index 0000000..2fe736a
--- /dev/null
+++ b/src/test/baseline/testImgMask1.png
Binary files differ
diff --git a/src/test/baseline/testImgMask2.png b/src/test/baseline/testImgMask2.png
new file mode 100644
index 0000000..9d1f486
--- /dev/null
+++ b/src/test/baseline/testImgMask2.png
Binary files differ
diff --git a/src/test/baseline/testImgMask3.png b/src/test/baseline/testImgMask3.png
new file mode 100644
index 0000000..70f58ff
--- /dev/null
+++ b/src/test/baseline/testImgMask3.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskCanvas.png b/src/test/baseline/testImgMaskCanvas.png
new file mode 100644
index 0000000..1faa5d5
--- /dev/null
+++ b/src/test/baseline/testImgMaskCanvas.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskPos.png b/src/test/baseline/testImgMaskPos.png
new file mode 100644
index 0000000..16176eb
--- /dev/null
+++ b/src/test/baseline/testImgMaskPos.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskSize1.png b/src/test/baseline/testImgMaskSize1.png
new file mode 100644
index 0000000..41ac537
--- /dev/null
+++ b/src/test/baseline/testImgMaskSize1.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskSize2.png b/src/test/baseline/testImgMaskSize2.png
new file mode 100644
index 0000000..de6549d
--- /dev/null
+++ b/src/test/baseline/testImgMaskSize2.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskSize3.png b/src/test/baseline/testImgMaskSize3.png
new file mode 100644
index 0000000..d452f98
--- /dev/null
+++ b/src/test/baseline/testImgMaskSize3.png
Binary files differ
diff --git a/src/test/baseline/testImgPos1.png b/src/test/baseline/testImgPos1.png
new file mode 100644
index 0000000..5bb376d
--- /dev/null
+++ b/src/test/baseline/testImgPos1.png
Binary files differ
diff --git a/src/test/baseline/testImgPos2.png b/src/test/baseline/testImgPos2.png
new file mode 100644
index 0000000..017609d
--- /dev/null
+++ b/src/test/baseline/testImgPos2.png
Binary files differ
diff --git a/src/test/baseline/testImgSize1.png b/src/test/baseline/testImgSize1.png
new file mode 100644
index 0000000..5a5a7d6
--- /dev/null
+++ b/src/test/baseline/testImgSize1.png
Binary files differ
diff --git a/src/test/baseline/testImgSize2.png b/src/test/baseline/testImgSize2.png
new file mode 100644
index 0000000..df562d3
--- /dev/null
+++ b/src/test/baseline/testImgSize2.png
Binary files differ
diff --git a/src/test/baseline/testImgWarp1.png b/src/test/baseline/testImgWarp1.png
new file mode 100644
index 0000000..a5ee5c0
--- /dev/null
+++ b/src/test/baseline/testImgWarp1.png
Binary files differ
diff --git a/src/test/baseline/testImgWarp2.png b/src/test/baseline/testImgWarp2.png
new file mode 100644
index 0000000..514e6f4
--- /dev/null
+++ b/src/test/baseline/testImgWarp2.png
Binary files differ
diff --git a/src/test/baseline/testInactiveVector1.png b/src/test/baseline/testInactiveVector1.png
new file mode 100644
index 0000000..be0f350
--- /dev/null
+++ b/src/test/baseline/testInactiveVector1.png
Binary files differ
diff --git a/src/test/baseline/testInactiveVector2.png b/src/test/baseline/testInactiveVector2.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testInactiveVector2.png
Binary files differ
diff --git a/src/test/baseline/testIntAnim1.png b/src/test/baseline/testIntAnim1.png
new file mode 100644
index 0000000..904a872
--- /dev/null
+++ b/src/test/baseline/testIntAnim1.png
Binary files differ
diff --git a/src/test/baseline/testIntAnim2.png b/src/test/baseline/testIntAnim2.png
new file mode 100644
index 0000000..c2df44a
--- /dev/null
+++ b/src/test/baseline/testIntAnim2.png
Binary files differ
diff --git a/src/test/baseline/testIntensity1.png b/src/test/baseline/testIntensity1.png
new file mode 100644
index 0000000..cf19285
--- /dev/null
+++ b/src/test/baseline/testIntensity1.png
Binary files differ
diff --git a/src/test/baseline/testIntensity2.png b/src/test/baseline/testIntensity2.png
new file mode 100644
index 0000000..c8bb26a
--- /dev/null
+++ b/src/test/baseline/testIntensity2.png
Binary files differ
diff --git a/src/test/baseline/testIntensity3.png b/src/test/baseline/testIntensity3.png
new file mode 100644
index 0000000..450327c
--- /dev/null
+++ b/src/test/baseline/testIntensity3.png
Binary files differ
diff --git a/src/test/baseline/testIntensity4.png b/src/test/baseline/testIntensity4.png
new file mode 100644
index 0000000..649cd82
--- /dev/null
+++ b/src/test/baseline/testIntensity4.png
Binary files differ
diff --git a/src/test/baseline/testInvertFX1.png b/src/test/baseline/testInvertFX1.png
new file mode 100644
index 0000000..cbce0de
--- /dev/null
+++ b/src/test/baseline/testInvertFX1.png
Binary files differ
diff --git a/src/test/baseline/testInvertFX2.png b/src/test/baseline/testInvertFX2.png
new file mode 100644
index 0000000..2c5a673
--- /dev/null
+++ b/src/test/baseline/testInvertFX2.png
Binary files differ
diff --git a/src/test/baseline/testJustify.png b/src/test/baseline/testJustify.png
new file mode 100644
index 0000000..4d5affc
--- /dev/null
+++ b/src/test/baseline/testJustify.png
Binary files differ
diff --git a/src/test/baseline/testLetterSpacing1.png b/src/test/baseline/testLetterSpacing1.png
new file mode 100644
index 0000000..3b04e0e
--- /dev/null
+++ b/src/test/baseline/testLetterSpacing1.png
Binary files differ
diff --git a/src/test/baseline/testLetterSpacing2.png b/src/test/baseline/testLetterSpacing2.png
new file mode 100644
index 0000000..8385a22
--- /dev/null
+++ b/src/test/baseline/testLetterSpacing2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnim1.png b/src/test/baseline/testLinearAnim1.png
new file mode 100644
index 0000000..82abf89
--- /dev/null
+++ b/src/test/baseline/testLinearAnim1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnim2.png b/src/test/baseline/testLinearAnim2.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testLinearAnim2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnim3.png b/src/test/baseline/testLinearAnim3.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testLinearAnim3.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC1.png b/src/test/baseline/testLinearAnimC1.png
new file mode 100644
index 0000000..fbe5b29
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC2.png b/src/test/baseline/testLinearAnimC2.png
new file mode 100644
index 0000000..b6403be
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC3.png b/src/test/baseline/testLinearAnimC3.png
new file mode 100644
index 0000000..b5e695e
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC4.png b/src/test/baseline/testLinearAnimC4.png
new file mode 100644
index 0000000..9703e09
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC4.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC5.png b/src/test/baseline/testLinearAnimC5.png
new file mode 100644
index 0000000..b5e695e
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC5.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC6.png b/src/test/baseline/testLinearAnimC6.png
new file mode 100644
index 0000000..f1fbb13
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC6.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDuration1.png b/src/test/baseline/testLinearAnimZeroDuration1.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDuration1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDuration2.png b/src/test/baseline/testLinearAnimZeroDuration2.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDuration2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDuration3.png b/src/test/baseline/testLinearAnimZeroDuration3.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDuration3.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDurationC1.png b/src/test/baseline/testLinearAnimZeroDurationC1.png
new file mode 100644
index 0000000..9703e09
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDurationC1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDurationC2.png b/src/test/baseline/testLinearAnimZeroDurationC2.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDurationC2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDurationC3.png b/src/test/baseline/testLinearAnimZeroDurationC3.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDurationC3.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl1.png b/src/test/baseline/testMediaControl1.png
new file mode 100644
index 0000000..fd36c50
--- /dev/null
+++ b/src/test/baseline/testMediaControl1.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl2.png b/src/test/baseline/testMediaControl2.png
new file mode 100644
index 0000000..fd01c50
--- /dev/null
+++ b/src/test/baseline/testMediaControl2.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl3.png b/src/test/baseline/testMediaControl3.png
new file mode 100644
index 0000000..9f9c0ee
--- /dev/null
+++ b/src/test/baseline/testMediaControl3.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl4.png b/src/test/baseline/testMediaControl4.png
new file mode 100644
index 0000000..53adc06
--- /dev/null
+++ b/src/test/baseline/testMediaControl4.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl5.png b/src/test/baseline/testMediaControl5.png
new file mode 100644
index 0000000..37d7bf4
--- /dev/null
+++ b/src/test/baseline/testMediaControl5.png
Binary files differ
diff --git a/src/test/baseline/testMediaDir1.png b/src/test/baseline/testMediaDir1.png
new file mode 100644
index 0000000..d566076
--- /dev/null
+++ b/src/test/baseline/testMediaDir1.png
Binary files differ
diff --git a/src/test/baseline/testMediaDir2.png b/src/test/baseline/testMediaDir2.png
new file mode 100644
index 0000000..e46ab2c
--- /dev/null
+++ b/src/test/baseline/testMediaDir2.png
Binary files differ
diff --git a/src/test/baseline/testMesh1.png b/src/test/baseline/testMesh1.png
new file mode 100644
index 0000000..533ea09
--- /dev/null
+++ b/src/test/baseline/testMesh1.png
Binary files differ
diff --git a/src/test/baseline/testMesh2.png b/src/test/baseline/testMesh2.png
new file mode 100644
index 0000000..d81ddbd
--- /dev/null
+++ b/src/test/baseline/testMesh2.png
Binary files differ
diff --git a/src/test/baseline/testMesh3.png b/src/test/baseline/testMesh3.png
new file mode 100644
index 0000000..4e3dab2
--- /dev/null
+++ b/src/test/baseline/testMesh3.png
Binary files differ
diff --git a/src/test/baseline/testMesh4.png b/src/test/baseline/testMesh4.png
new file mode 100644
index 0000000..f325b53
--- /dev/null
+++ b/src/test/baseline/testMesh4.png
Binary files differ
diff --git a/src/test/baseline/testMesh5.png b/src/test/baseline/testMesh5.png
new file mode 100644
index 0000000..86c0a24
--- /dev/null
+++ b/src/test/baseline/testMesh5.png
Binary files differ
diff --git a/src/test/baseline/testMesh6.png b/src/test/baseline/testMesh6.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testMesh6.png
Binary files differ
diff --git a/src/test/baseline/testMesh7.png b/src/test/baseline/testMesh7.png
new file mode 100644
index 0000000..a7e2493
--- /dev/null
+++ b/src/test/baseline/testMesh7.png
Binary files differ
diff --git a/src/test/baseline/testMesh8.png b/src/test/baseline/testMesh8.png
new file mode 100644
index 0000000..20e4fb1
--- /dev/null
+++ b/src/test/baseline/testMesh8.png
Binary files differ
diff --git a/src/test/baseline/testMipmap.png b/src/test/baseline/testMipmap.png
new file mode 100644
index 0000000..eb6185e
--- /dev/null
+++ b/src/test/baseline/testMipmap.png
Binary files differ
diff --git a/src/test/baseline/testMove1.png b/src/test/baseline/testMove1.png
new file mode 100644
index 0000000..4d0bdec
--- /dev/null
+++ b/src/test/baseline/testMove1.png
Binary files differ
diff --git a/src/test/baseline/testNodeInCanvasNullFX1.png b/src/test/baseline/testNodeInCanvasNullFX1.png
new file mode 100644
index 0000000..00767fb
--- /dev/null
+++ b/src/test/baseline/testNodeInCanvasNullFX1.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen1.png b/src/test/baseline/testOffscreen1.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testOffscreen1.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen2.png b/src/test/baseline/testOffscreen2.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testOffscreen2.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen3.png b/src/test/baseline/testOffscreen3.png
new file mode 100644
index 0000000..f274a2b
--- /dev/null
+++ b/src/test/baseline/testOffscreen3.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen4.png b/src/test/baseline/testOffscreen4.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testOffscreen4.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen5.png b/src/test/baseline/testOffscreen5.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testOffscreen5.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenAutoRender1.png b/src/test/baseline/testOffscreenAutoRender1.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testOffscreenAutoRender1.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenAutoRender2.png b/src/test/baseline/testOffscreenAutoRender2.png
new file mode 100644
index 0000000..0d508a9
--- /dev/null
+++ b/src/test/baseline/testOffscreenAutoRender2.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenMultisampleScreenshot.png b/src/test/baseline/testOffscreenMultisampleScreenshot.png
new file mode 100644
index 0000000..1a04a20
--- /dev/null
+++ b/src/test/baseline/testOffscreenMultisampleScreenshot.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenScreenshot.png b/src/test/baseline/testOffscreenScreenshot.png
new file mode 100644
index 0000000..31fcc27
--- /dev/null
+++ b/src/test/baseline/testOffscreenScreenshot.png
Binary files differ
diff --git a/src/test/baseline/testOpacity.png b/src/test/baseline/testOpacity.png
new file mode 100644
index 0000000..aab7cdb
--- /dev/null
+++ b/src/test/baseline/testOpacity.png
Binary files differ
diff --git a/src/test/baseline/testOutlines.png b/src/test/baseline/testOutlines.png
new file mode 100644
index 0000000..36a7c14
--- /dev/null
+++ b/src/test/baseline/testOutlines.png
Binary files differ
diff --git a/src/test/baseline/testPanoDynamics1.png b/src/test/baseline/testPanoDynamics1.png
new file mode 100644
index 0000000..8cac76c
--- /dev/null
+++ b/src/test/baseline/testPanoDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testPanoDynamics2.png b/src/test/baseline/testPanoDynamics2.png
new file mode 100644
index 0000000..21c01f2
--- /dev/null
+++ b/src/test/baseline/testPanoDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testPanoDynamics3.png b/src/test/baseline/testPanoDynamics3.png
new file mode 100644
index 0000000..e52d01b
--- /dev/null
+++ b/src/test/baseline/testPanoDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testPanoImage.png b/src/test/baseline/testPanoImage.png
new file mode 100644
index 0000000..6ce1008
--- /dev/null
+++ b/src/test/baseline/testPanoImage.png
Binary files differ
diff --git a/src/test/baseline/testPanoImagewNOP.png b/src/test/baseline/testPanoImagewNOP.png
new file mode 100644
index 0000000..6ce1008
--- /dev/null
+++ b/src/test/baseline/testPanoImagewNOP.png
Binary files differ
diff --git a/src/test/baseline/testParaWords.png b/src/test/baseline/testParaWords.png
new file mode 100644
index 0000000..4709a3b
--- /dev/null
+++ b/src/test/baseline/testParaWords.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnimC1.png b/src/test/baseline/testParallelAnimC1.png
new file mode 100644
index 0000000..69aa068
--- /dev/null
+++ b/src/test/baseline/testParallelAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnimC2.png b/src/test/baseline/testParallelAnimC2.png
new file mode 100644
index 0000000..80a7f81
--- /dev/null
+++ b/src/test/baseline/testParallelAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnimC3.png b/src/test/baseline/testParallelAnimC3.png
new file mode 100644
index 0000000..ec591f3
--- /dev/null
+++ b/src/test/baseline/testParallelAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnims1.png b/src/test/baseline/testParallelAnims1.png
new file mode 100644
index 0000000..4d189b7
--- /dev/null
+++ b/src/test/baseline/testParallelAnims1.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnims2.png b/src/test/baseline/testParallelAnims2.png
new file mode 100644
index 0000000..64f85d1
--- /dev/null
+++ b/src/test/baseline/testParallelAnims2.png
Binary files differ
diff --git a/src/test/baseline/testPieSlice1.png b/src/test/baseline/testPieSlice1.png
new file mode 100644
index 0000000..9d5bc4d
--- /dev/null
+++ b/src/test/baseline/testPieSlice1.png
Binary files differ
diff --git a/src/test/baseline/testPieSlice2.png b/src/test/baseline/testPieSlice2.png
new file mode 100644
index 0000000..5d62891
--- /dev/null
+++ b/src/test/baseline/testPieSlice2.png
Binary files differ
diff --git a/src/test/baseline/testPieSlice3.png b/src/test/baseline/testPieSlice3.png
new file mode 100644
index 0000000..c011af3
--- /dev/null
+++ b/src/test/baseline/testPieSlice3.png
Binary files differ
diff --git a/src/test/baseline/testPlayBeforeConnect.png b/src/test/baseline/testPlayBeforeConnect.png
new file mode 100644
index 0000000..d27fda0
--- /dev/null
+++ b/src/test/baseline/testPlayBeforeConnect.png
Binary files differ
diff --git a/src/test/baseline/testPointAnim1.png b/src/test/baseline/testPointAnim1.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testPointAnim1.png
Binary files differ
diff --git a/src/test/baseline/testPointAnim2.png b/src/test/baseline/testPointAnim2.png
new file mode 100644
index 0000000..1d46750
--- /dev/null
+++ b/src/test/baseline/testPointAnim2.png
Binary files differ
diff --git a/src/test/baseline/testPointAnim3.png b/src/test/baseline/testPointAnim3.png
new file mode 100644
index 0000000..1d46750
--- /dev/null
+++ b/src/test/baseline/testPointAnim3.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine1.png b/src/test/baseline/testPolyLine1.png
new file mode 100644
index 0000000..e2843f6
--- /dev/null
+++ b/src/test/baseline/testPolyLine1.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine2.png b/src/test/baseline/testPolyLine2.png
new file mode 100644
index 0000000..4b26092
--- /dev/null
+++ b/src/test/baseline/testPolyLine2.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine3.png b/src/test/baseline/testPolyLine3.png
new file mode 100644
index 0000000..80df8a0
--- /dev/null
+++ b/src/test/baseline/testPolyLine3.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine4.png b/src/test/baseline/testPolyLine4.png
new file mode 100644
index 0000000..e37c026
--- /dev/null
+++ b/src/test/baseline/testPolyLine4.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine5.png b/src/test/baseline/testPolyLine5.png
new file mode 100644
index 0000000..80df8a0
--- /dev/null
+++ b/src/test/baseline/testPolyLine5.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine6.png b/src/test/baseline/testPolyLine6.png
new file mode 100644
index 0000000..2607d53
--- /dev/null
+++ b/src/test/baseline/testPolyLine6.png
Binary files differ
diff --git a/src/test/baseline/testPolygon1.png b/src/test/baseline/testPolygon1.png
new file mode 100644
index 0000000..441ed9b
--- /dev/null
+++ b/src/test/baseline/testPolygon1.png
Binary files differ
diff --git a/src/test/baseline/testPolygon2.png b/src/test/baseline/testPolygon2.png
new file mode 100644
index 0000000..858bf40
--- /dev/null
+++ b/src/test/baseline/testPolygon2.png
Binary files differ
diff --git a/src/test/baseline/testPolygon3.png b/src/test/baseline/testPolygon3.png
new file mode 100644
index 0000000..636ada8
--- /dev/null
+++ b/src/test/baseline/testPolygon3.png
Binary files differ
diff --git a/src/test/baseline/testPolygon4.png b/src/test/baseline/testPolygon4.png
new file mode 100644
index 0000000..636ada8
--- /dev/null
+++ b/src/test/baseline/testPolygon4.png
Binary files differ
diff --git a/src/test/baseline/testPolygon5.png b/src/test/baseline/testPolygon5.png
new file mode 100644
index 0000000..964a01b
--- /dev/null
+++ b/src/test/baseline/testPolygon5.png
Binary files differ
diff --git a/src/test/baseline/testPolygon6.png b/src/test/baseline/testPolygon6.png
new file mode 100644
index 0000000..45ee95d
--- /dev/null
+++ b/src/test/baseline/testPolygon6.png
Binary files differ
diff --git a/src/test/baseline/testPolygon7.png b/src/test/baseline/testPolygon7.png
new file mode 100644
index 0000000..5cb45e6
--- /dev/null
+++ b/src/test/baseline/testPolygon7.png
Binary files differ
diff --git a/src/test/baseline/testPolygon8.png b/src/test/baseline/testPolygon8.png
new file mode 100644
index 0000000..f926687
--- /dev/null
+++ b/src/test/baseline/testPolygon8.png
Binary files differ
diff --git a/src/test/baseline/testPolygon9.png b/src/test/baseline/testPolygon9.png
new file mode 100644
index 0000000..3e00de4
--- /dev/null
+++ b/src/test/baseline/testPolygon9.png
Binary files differ
diff --git a/src/test/baseline/testPolygonHole1.png b/src/test/baseline/testPolygonHole1.png
new file mode 100644
index 0000000..9c18ad1
--- /dev/null
+++ b/src/test/baseline/testPolygonHole1.png
Binary files differ
diff --git a/src/test/baseline/testPolygonHole2.png b/src/test/baseline/testPolygonHole2.png
new file mode 100644
index 0000000..d8199da
--- /dev/null
+++ b/src/test/baseline/testPolygonHole2.png
Binary files differ
diff --git a/src/test/baseline/testPositioning.png b/src/test/baseline/testPositioning.png
new file mode 100644
index 0000000..1b174b0
--- /dev/null
+++ b/src/test/baseline/testPositioning.png
Binary files differ
diff --git a/src/test/baseline/testProgressBar1.png b/src/test/baseline/testProgressBar1.png
new file mode 100644
index 0000000..2b2c752
--- /dev/null
+++ b/src/test/baseline/testProgressBar1.png
Binary files differ
diff --git a/src/test/baseline/testProgressBar2.png b/src/test/baseline/testProgressBar2.png
new file mode 100644
index 0000000..6c1f56b
--- /dev/null
+++ b/src/test/baseline/testProgressBar2.png
Binary files differ
diff --git a/src/test/baseline/testProgressBar3.png b/src/test/baseline/testProgressBar3.png
new file mode 100644
index 0000000..d788f76
--- /dev/null
+++ b/src/test/baseline/testProgressBar3.png
Binary files differ
diff --git a/src/test/baseline/testRawText1.png b/src/test/baseline/testRawText1.png
new file mode 100644
index 0000000..4733e87
--- /dev/null
+++ b/src/test/baseline/testRawText1.png
Binary files differ
diff --git a/src/test/baseline/testRawText2.png b/src/test/baseline/testRawText2.png
new file mode 100644
index 0000000..cedb8bb
--- /dev/null
+++ b/src/test/baseline/testRawText2.png
Binary files differ
diff --git a/src/test/baseline/testRawText3.png b/src/test/baseline/testRawText3.png
new file mode 100644
index 0000000..e91b743
--- /dev/null
+++ b/src/test/baseline/testRawText3.png
Binary files differ
diff --git a/src/test/baseline/testRawText4.png b/src/test/baseline/testRawText4.png
new file mode 100644
index 0000000..cd1c0dc
--- /dev/null
+++ b/src/test/baseline/testRawText4.png
Binary files differ
diff --git a/src/test/baseline/testRect1.png b/src/test/baseline/testRect1.png
new file mode 100644
index 0000000..c2f4c5e
--- /dev/null
+++ b/src/test/baseline/testRect1.png
Binary files differ
diff --git a/src/test/baseline/testRect2.png b/src/test/baseline/testRect2.png
new file mode 100644
index 0000000..9d9ec9d
--- /dev/null
+++ b/src/test/baseline/testRect2.png
Binary files differ
diff --git a/src/test/baseline/testRect3.png b/src/test/baseline/testRect3.png
new file mode 100644
index 0000000..aabb540
--- /dev/null
+++ b/src/test/baseline/testRect3.png
Binary files differ
diff --git a/src/test/baseline/testRect4.png b/src/test/baseline/testRect4.png
new file mode 100644
index 0000000..c549747
--- /dev/null
+++ b/src/test/baseline/testRect4.png
Binary files differ
diff --git a/src/test/baseline/testRenderPipeline.png b/src/test/baseline/testRenderPipeline.png
new file mode 100644
index 0000000..f9603fd
--- /dev/null
+++ b/src/test/baseline/testRenderPipeline.png
Binary files differ
diff --git a/src/test/baseline/testRotate1.png b/src/test/baseline/testRotate1.png
new file mode 100644
index 0000000..7c8aa25
--- /dev/null
+++ b/src/test/baseline/testRotate1.png
Binary files differ
diff --git a/src/test/baseline/testRotate1a.png b/src/test/baseline/testRotate1a.png
new file mode 100644
index 0000000..4e71a64
--- /dev/null
+++ b/src/test/baseline/testRotate1a.png
Binary files differ
diff --git a/src/test/baseline/testRotate1b.png b/src/test/baseline/testRotate1b.png
new file mode 100644
index 0000000..d1b5321
--- /dev/null
+++ b/src/test/baseline/testRotate1b.png
Binary files differ
diff --git a/src/test/baseline/testRotate2.png b/src/test/baseline/testRotate2.png
new file mode 100644
index 0000000..5db6d09
--- /dev/null
+++ b/src/test/baseline/testRotate2.png
Binary files differ
diff --git a/src/test/baseline/testRotatePivot1.png b/src/test/baseline/testRotatePivot1.png
new file mode 100644
index 0000000..6b4d6ef
--- /dev/null
+++ b/src/test/baseline/testRotatePivot1.png
Binary files differ
diff --git a/src/test/baseline/testRotatePivot2.png b/src/test/baseline/testRotatePivot2.png
new file mode 100644
index 0000000..d5122c7
--- /dev/null
+++ b/src/test/baseline/testRotatePivot2.png
Binary files differ
diff --git a/src/test/baseline/testRotatePivot3.png b/src/test/baseline/testRotatePivot3.png
new file mode 100644
index 0000000..8237df6
--- /dev/null
+++ b/src/test/baseline/testRotatePivot3.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect1.png b/src/test/baseline/testRoundedRect1.png
new file mode 100644
index 0000000..44e5013
--- /dev/null
+++ b/src/test/baseline/testRoundedRect1.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect2.png b/src/test/baseline/testRoundedRect2.png
new file mode 100644
index 0000000..b50d434
--- /dev/null
+++ b/src/test/baseline/testRoundedRect2.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect3.png b/src/test/baseline/testRoundedRect3.png
new file mode 100644
index 0000000..b35eb14
--- /dev/null
+++ b/src/test/baseline/testRoundedRect3.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect4.png b/src/test/baseline/testRoundedRect4.png
new file mode 100644
index 0000000..a6e5d6e
--- /dev/null
+++ b/src/test/baseline/testRoundedRect4.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect5.png b/src/test/baseline/testRoundedRect5.png
new file mode 100644
index 0000000..c6da32c
--- /dev/null
+++ b/src/test/baseline/testRoundedRect5.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect6.png b/src/test/baseline/testRoundedRect6.png
new file mode 100644
index 0000000..a9e76a8
--- /dev/null
+++ b/src/test/baseline/testRoundedRect6.png
Binary files differ
diff --git a/src/test/baseline/testScrollArea1.png b/src/test/baseline/testScrollArea1.png
new file mode 100644
index 0000000..4cb67e2
--- /dev/null
+++ b/src/test/baseline/testScrollArea1.png
Binary files differ
diff --git a/src/test/baseline/testScrollArea2.png b/src/test/baseline/testScrollArea2.png
new file mode 100644
index 0000000..7939cae
--- /dev/null
+++ b/src/test/baseline/testScrollArea2.png
Binary files differ
diff --git a/src/test/baseline/testScrollArea3.png b/src/test/baseline/testScrollArea3.png
new file mode 100644
index 0000000..1fc62df
--- /dev/null
+++ b/src/test/baseline/testScrollArea3.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz1.png b/src/test/baseline/testScrollBarHoriz1.png
new file mode 100644
index 0000000..aedcb12
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz10.png b/src/test/baseline/testScrollBarHoriz10.png
new file mode 100644
index 0000000..0c8a5af
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz10.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz11.png b/src/test/baseline/testScrollBarHoriz11.png
new file mode 100644
index 0000000..da84ebc
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz11.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz12.png b/src/test/baseline/testScrollBarHoriz12.png
new file mode 100644
index 0000000..5e2f013
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz12.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz2.png b/src/test/baseline/testScrollBarHoriz2.png
new file mode 100644
index 0000000..b8a2dcd
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz3.png b/src/test/baseline/testScrollBarHoriz3.png
new file mode 100644
index 0000000..885b429
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz3.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz4.png b/src/test/baseline/testScrollBarHoriz4.png
new file mode 100644
index 0000000..8ceea4f
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz4.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz5.png b/src/test/baseline/testScrollBarHoriz5.png
new file mode 100644
index 0000000..4278825
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz5.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz6.png b/src/test/baseline/testScrollBarHoriz6.png
new file mode 100644
index 0000000..ee270d3
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz6.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz7.png b/src/test/baseline/testScrollBarHoriz7.png
new file mode 100644
index 0000000..0fefd7b
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz7.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz8.png b/src/test/baseline/testScrollBarHoriz8.png
new file mode 100644
index 0000000..138ec3a
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz8.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz9.png b/src/test/baseline/testScrollBarHoriz9.png
new file mode 100644
index 0000000..0fefd7b
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz9.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert1.png b/src/test/baseline/testScrollBarVert1.png
new file mode 100644
index 0000000..25c3098
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert1.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert2.png b/src/test/baseline/testScrollBarVert2.png
new file mode 100644
index 0000000..572fac9
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert2.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert3.png b/src/test/baseline/testScrollBarVert3.png
new file mode 100644
index 0000000..d1a893c
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert3.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert4.png b/src/test/baseline/testScrollBarVert4.png
new file mode 100644
index 0000000..a29849f
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert4.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert5.png b/src/test/baseline/testScrollBarVert5.png
new file mode 100644
index 0000000..ff40ef7
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert5.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert6.png b/src/test/baseline/testScrollBarVert6.png
new file mode 100644
index 0000000..edb3196
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert6.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert7.png b/src/test/baseline/testScrollBarVert7.png
new file mode 100644
index 0000000..115d8ca
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert7.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert8.png b/src/test/baseline/testScrollBarVert8.png
new file mode 100644
index 0000000..5e1e08b
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert8.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert9.png b/src/test/baseline/testScrollBarVert9.png
new file mode 100644
index 0000000..3a7ff70
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert9.png
Binary files differ
diff --git a/src/test/baseline/testScrollPane1.png b/src/test/baseline/testScrollPane1.png
new file mode 100644
index 0000000..68fcad1
--- /dev/null
+++ b/src/test/baseline/testScrollPane1.png
Binary files differ
diff --git a/src/test/baseline/testScrollPane2.png b/src/test/baseline/testScrollPane2.png
new file mode 100644
index 0000000..3e58737
--- /dev/null
+++ b/src/test/baseline/testScrollPane2.png
Binary files differ
diff --git a/src/test/baseline/testScrollPane3.png b/src/test/baseline/testScrollPane3.png
new file mode 100644
index 0000000..834a091
--- /dev/null
+++ b/src/test/baseline/testScrollPane3.png
Binary files differ
diff --git a/src/test/baseline/testSeekAfterEOF.png b/src/test/baseline/testSeekAfterEOF.png
new file mode 100644
index 0000000..76e79c1
--- /dev/null
+++ b/src/test/baseline/testSeekAfterEOF.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX1.png b/src/test/baseline/testShadowFX1.png
new file mode 100644
index 0000000..7d1d5d7
--- /dev/null
+++ b/src/test/baseline/testShadowFX1.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX2.png b/src/test/baseline/testShadowFX2.png
new file mode 100644
index 0000000..0d9b1ee
--- /dev/null
+++ b/src/test/baseline/testShadowFX2.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX3.png b/src/test/baseline/testShadowFX3.png
new file mode 100644
index 0000000..3a3a678
--- /dev/null
+++ b/src/test/baseline/testShadowFX3.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX4.png b/src/test/baseline/testShadowFX4.png
new file mode 100644
index 0000000..13da229
--- /dev/null
+++ b/src/test/baseline/testShadowFX4.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX5.png b/src/test/baseline/testShadowFX5.png
new file mode 100644
index 0000000..b1ed885
--- /dev/null
+++ b/src/test/baseline/testShadowFX5.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX6.png b/src/test/baseline/testShadowFX6.png
new file mode 100644
index 0000000..52e8c14
--- /dev/null
+++ b/src/test/baseline/testShadowFX6.png
Binary files differ
diff --git a/src/test/baseline/testSimpleWords.png b/src/test/baseline/testSimpleWords.png
new file mode 100644
index 0000000..21e1a1b
--- /dev/null
+++ b/src/test/baseline/testSimpleWords.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz1.png b/src/test/baseline/testSliderHoriz1.png
new file mode 100644
index 0000000..c30040d
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz2.png b/src/test/baseline/testSliderHoriz2.png
new file mode 100644
index 0000000..e22a32f
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz3.png b/src/test/baseline/testSliderHoriz3.png
new file mode 100644
index 0000000..bcf1690
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz3.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz4.png b/src/test/baseline/testSliderHoriz4.png
new file mode 100644
index 0000000..7c48e5a
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz4.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz5.png b/src/test/baseline/testSliderHoriz5.png
new file mode 100644
index 0000000..2b6534a
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz5.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert1.png b/src/test/baseline/testSliderVert1.png
new file mode 100644
index 0000000..d82d467
--- /dev/null
+++ b/src/test/baseline/testSliderVert1.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert2.png b/src/test/baseline/testSliderVert2.png
new file mode 100644
index 0000000..294dae9
--- /dev/null
+++ b/src/test/baseline/testSliderVert2.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert3.png b/src/test/baseline/testSliderVert3.png
new file mode 100644
index 0000000..4a00a8f
--- /dev/null
+++ b/src/test/baseline/testSliderVert3.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert4.png b/src/test/baseline/testSliderVert4.png
new file mode 100644
index 0000000..f13d278
--- /dev/null
+++ b/src/test/baseline/testSliderVert4.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert5.png b/src/test/baseline/testSliderVert5.png
new file mode 100644
index 0000000..a939fe0
--- /dev/null
+++ b/src/test/baseline/testSliderVert5.png
Binary files differ
diff --git a/src/test/baseline/testSpanWords.png b/src/test/baseline/testSpanWords.png
new file mode 100644
index 0000000..c206d60
--- /dev/null
+++ b/src/test/baseline/testSpanWords.png
Binary files differ
diff --git a/src/test/baseline/testSplineAnim1.png b/src/test/baseline/testSplineAnim1.png
new file mode 100644
index 0000000..82abf89
--- /dev/null
+++ b/src/test/baseline/testSplineAnim1.png
Binary files differ
diff --git a/src/test/baseline/testSplineAnim2.png b/src/test/baseline/testSplineAnim2.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testSplineAnim2.png
Binary files differ
diff --git a/src/test/baseline/testSplineAnim3.png b/src/test/baseline/testSplineAnim3.png
new file mode 100644
index 0000000..36a6afc
--- /dev/null
+++ b/src/test/baseline/testSplineAnim3.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim1.png b/src/test/baseline/testStateAnim1.png
new file mode 100644
index 0000000..19ad729
--- /dev/null
+++ b/src/test/baseline/testStateAnim1.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim2.png b/src/test/baseline/testStateAnim2.png
new file mode 100644
index 0000000..92a98a5
--- /dev/null
+++ b/src/test/baseline/testStateAnim2.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim3.png b/src/test/baseline/testStateAnim3.png
new file mode 100644
index 0000000..92a98a5
--- /dev/null
+++ b/src/test/baseline/testStateAnim3.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim4.png b/src/test/baseline/testStateAnim4.png
new file mode 100644
index 0000000..19ad729
--- /dev/null
+++ b/src/test/baseline/testStateAnim4.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim5.png b/src/test/baseline/testStateAnim5.png
new file mode 100644
index 0000000..92a98a5
--- /dev/null
+++ b/src/test/baseline/testStateAnim5.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC1.png b/src/test/baseline/testStateAnimC1.png
new file mode 100644
index 0000000..02f0389
--- /dev/null
+++ b/src/test/baseline/testStateAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC2.png b/src/test/baseline/testStateAnimC2.png
new file mode 100644
index 0000000..2126c02
--- /dev/null
+++ b/src/test/baseline/testStateAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC3.png b/src/test/baseline/testStateAnimC3.png
new file mode 100644
index 0000000..dc43edc
--- /dev/null
+++ b/src/test/baseline/testStateAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC4.png b/src/test/baseline/testStateAnimC4.png
new file mode 100644
index 0000000..2126c02
--- /dev/null
+++ b/src/test/baseline/testStateAnimC4.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC5.png b/src/test/baseline/testStateAnimC5.png
new file mode 100644
index 0000000..2126c02
--- /dev/null
+++ b/src/test/baseline/testStateAnimC5.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeHoriz1.png b/src/test/baseline/testStretchNodeHoriz1.png
new file mode 100644
index 0000000..652ada8
--- /dev/null
+++ b/src/test/baseline/testStretchNodeHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeHoriz2.png b/src/test/baseline/testStretchNodeHoriz2.png
new file mode 100644
index 0000000..fe123b0
--- /dev/null
+++ b/src/test/baseline/testStretchNodeHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeVert1.png b/src/test/baseline/testStretchNodeVert1.png
new file mode 100644
index 0000000..a0e6fe3
--- /dev/null
+++ b/src/test/baseline/testStretchNodeVert1.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeVert2.png b/src/test/baseline/testStretchNodeVert2.png
new file mode 100644
index 0000000..ac7d496
--- /dev/null
+++ b/src/test/baseline/testStretchNodeVert2.png
Binary files differ
diff --git a/src/test/baseline/testSvgBmp.png b/src/test/baseline/testSvgBmp.png
new file mode 100644
index 0000000..8020a67
--- /dev/null
+++ b/src/test/baseline/testSvgBmp.png
Binary files differ
diff --git a/src/test/baseline/testSvgNode.png b/src/test/baseline/testSvgNode.png
new file mode 100644
index 0000000..76d1632
--- /dev/null
+++ b/src/test/baseline/testSvgNode.png
Binary files differ
diff --git a/src/test/baseline/testSvgPosBmp.png b/src/test/baseline/testSvgPosBmp.png
new file mode 100644
index 0000000..6eb83fe
--- /dev/null
+++ b/src/test/baseline/testSvgPosBmp.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaleBmp1.png b/src/test/baseline/testSvgScaleBmp1.png
new file mode 100644
index 0000000..ba46499
--- /dev/null
+++ b/src/test/baseline/testSvgScaleBmp1.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaleBmp2.png b/src/test/baseline/testSvgScaleBmp2.png
new file mode 100644
index 0000000..eb038d5
--- /dev/null
+++ b/src/test/baseline/testSvgScaleBmp2.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaledNode1.png b/src/test/baseline/testSvgScaledNode1.png
new file mode 100644
index 0000000..7c78fb5
--- /dev/null
+++ b/src/test/baseline/testSvgScaledNode1.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaledNode2.png b/src/test/baseline/testSvgScaledNode2.png
new file mode 100644
index 0000000..3cdff7f
--- /dev/null
+++ b/src/test/baseline/testSvgScaledNode2.png
Binary files differ
diff --git a/src/test/baseline/testTexCompression1.png b/src/test/baseline/testTexCompression1.png
new file mode 100644
index 0000000..8629a85
--- /dev/null
+++ b/src/test/baseline/testTexCompression1.png
Binary files differ
diff --git a/src/test/baseline/testTexCompression2.png b/src/test/baseline/testTexCompression2.png
new file mode 100644
index 0000000..51acdba
--- /dev/null
+++ b/src/test/baseline/testTexCompression2.png
Binary files differ
diff --git a/src/test/baseline/testTextArea1.png b/src/test/baseline/testTextArea1.png
new file mode 100644
index 0000000..7cf8ac1
--- /dev/null
+++ b/src/test/baseline/testTextArea1.png
Binary files differ
diff --git a/src/test/baseline/testTextArea2.png b/src/test/baseline/testTextArea2.png
new file mode 100644
index 0000000..6fe4c64
--- /dev/null
+++ b/src/test/baseline/testTextArea2.png
Binary files differ
diff --git a/src/test/baseline/testTextArea3.png b/src/test/baseline/testTextArea3.png
new file mode 100644
index 0000000..6577cf2
--- /dev/null
+++ b/src/test/baseline/testTextArea3.png
Binary files differ
diff --git a/src/test/baseline/testTextArea4.png b/src/test/baseline/testTextArea4.png
new file mode 100644
index 0000000..2fc48fe
--- /dev/null
+++ b/src/test/baseline/testTextArea4.png
Binary files differ
diff --git a/src/test/baseline/testTextArea5.png b/src/test/baseline/testTextArea5.png
new file mode 100644
index 0000000..a7c53e2
--- /dev/null
+++ b/src/test/baseline/testTextArea5.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonDisabled.png b/src/test/baseline/testTextButtonDisabled.png
new file mode 100644
index 0000000..c859bfa
--- /dev/null
+++ b/src/test/baseline/testTextButtonDisabled.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonDown.png b/src/test/baseline/testTextButtonDown.png
new file mode 100644
index 0000000..9122c33
--- /dev/null
+++ b/src/test/baseline/testTextButtonDown.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonDownNewText.png b/src/test/baseline/testTextButtonDownNewText.png
new file mode 100644
index 0000000..9592a86
--- /dev/null
+++ b/src/test/baseline/testTextButtonDownNewText.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonUp.png b/src/test/baseline/testTextButtonUp.png
new file mode 100644
index 0000000..c859bfa
--- /dev/null
+++ b/src/test/baseline/testTextButtonUp.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonUpNewText.png b/src/test/baseline/testTextButtonUpNewText.png
new file mode 100644
index 0000000..ebb66bc
--- /dev/null
+++ b/src/test/baseline/testTextButtonUpNewText.png
Binary files differ
diff --git a/src/test/baseline/testTexturedCurve1.png b/src/test/baseline/testTexturedCurve1.png
new file mode 100644
index 0000000..dc626fd
--- /dev/null
+++ b/src/test/baseline/testTexturedCurve1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedCurve2.png b/src/test/baseline/testTexturedCurve2.png
new file mode 100644
index 0000000..f75a670
--- /dev/null
+++ b/src/test/baseline/testTexturedCurve2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine1.png b/src/test/baseline/testTexturedPolyLine1.png
new file mode 100644
index 0000000..1fd2e84
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine2.png b/src/test/baseline/testTexturedPolyLine2.png
new file mode 100644
index 0000000..ccbe01d
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine3.png b/src/test/baseline/testTexturedPolyLine3.png
new file mode 100644
index 0000000..65c59eb
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine3.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine4.png b/src/test/baseline/testTexturedPolyLine4.png
new file mode 100644
index 0000000..f063a2f
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine4.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon1.png b/src/test/baseline/testTexturedPolygon1.png
new file mode 100644
index 0000000..7064f8d
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon2.png b/src/test/baseline/testTexturedPolygon2.png
new file mode 100644
index 0000000..05f67c2
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon3.png b/src/test/baseline/testTexturedPolygon3.png
new file mode 100644
index 0000000..31730e0
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon3.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon4.png b/src/test/baseline/testTexturedPolygon4.png
new file mode 100644
index 0000000..333ada7
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon4.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon5.png b/src/test/baseline/testTexturedPolygon5.png
new file mode 100644
index 0000000..e7f7cc4
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon5.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon6.png b/src/test/baseline/testTexturedPolygon6.png
new file mode 100644
index 0000000..1222a19
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon6.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect1.png b/src/test/baseline/testTexturedRect1.png
new file mode 100644
index 0000000..35edac3
--- /dev/null
+++ b/src/test/baseline/testTexturedRect1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect2.png b/src/test/baseline/testTexturedRect2.png
new file mode 100644
index 0000000..5d2a0ba
--- /dev/null
+++ b/src/test/baseline/testTexturedRect2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect3.png b/src/test/baseline/testTexturedRect3.png
new file mode 100644
index 0000000..f5f2b77
--- /dev/null
+++ b/src/test/baseline/testTexturedRect3.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect4.png b/src/test/baseline/testTexturedRect4.png
new file mode 100644
index 0000000..795a7ad
--- /dev/null
+++ b/src/test/baseline/testTexturedRect4.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect5.png b/src/test/baseline/testTexturedRect5.png
new file mode 100644
index 0000000..38d6e56
--- /dev/null
+++ b/src/test/baseline/testTexturedRect5.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect6.png b/src/test/baseline/testTexturedRect6.png
new file mode 100644
index 0000000..b124377
--- /dev/null
+++ b/src/test/baseline/testTexturedRect6.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect7.png b/src/test/baseline/testTexturedRect7.png
new file mode 100644
index 0000000..ed51fa1
--- /dev/null
+++ b/src/test/baseline/testTexturedRect7.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect8.png b/src/test/baseline/testTexturedRect8.png
new file mode 100644
index 0000000..ddf74a2
--- /dev/null
+++ b/src/test/baseline/testTexturedRect8.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz1.png b/src/test/baseline/testTimeSliderHoriz1.png
new file mode 100644
index 0000000..42c0eca
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz2.png b/src/test/baseline/testTimeSliderHoriz2.png
new file mode 100644
index 0000000..a42b8ca
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz3.png b/src/test/baseline/testTimeSliderHoriz3.png
new file mode 100644
index 0000000..4908be5
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz3.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz4.png b/src/test/baseline/testTimeSliderHoriz4.png
new file mode 100644
index 0000000..1371480
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz4.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz5.png b/src/test/baseline/testTimeSliderHoriz5.png
new file mode 100644
index 0000000..1371480
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz5.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert1.png b/src/test/baseline/testTimeSliderVert1.png
new file mode 100644
index 0000000..8b31bac
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert1.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert2.png b/src/test/baseline/testTimeSliderVert2.png
new file mode 100644
index 0000000..79be7d1
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert2.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert3.png b/src/test/baseline/testTimeSliderVert3.png
new file mode 100644
index 0000000..a3a8718
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert3.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert4.png b/src/test/baseline/testTimeSliderVert4.png
new file mode 100644
index 0000000..f64996b
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert4.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert5.png b/src/test/baseline/testTimeSliderVert5.png
new file mode 100644
index 0000000..f64996b
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert5.png
Binary files differ
diff --git a/src/test/baseline/testUIButtonDisabled.png b/src/test/baseline/testUIButtonDisabled.png
new file mode 100644
index 0000000..9e00094
--- /dev/null
+++ b/src/test/baseline/testUIButtonDisabled.png
Binary files differ
diff --git a/src/test/baseline/testUIButtonDown.png b/src/test/baseline/testUIButtonDown.png
new file mode 100644
index 0000000..c9e3369
--- /dev/null
+++ b/src/test/baseline/testUIButtonDown.png
Binary files differ
diff --git a/src/test/baseline/testUIButtonUp.png b/src/test/baseline/testUIButtonUp.png
new file mode 100644
index 0000000..f385f38
--- /dev/null
+++ b/src/test/baseline/testUIButtonUp.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxChecked_Down.png b/src/test/baseline/testUICheckBoxChecked_Down.png
new file mode 100644
index 0000000..73818b9
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxChecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxChecked_Up.png b/src/test/baseline/testUICheckBoxChecked_Up.png
new file mode 100644
index 0000000..a4af8c9
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxChecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxUnchecked_Disabled.png b/src/test/baseline/testUICheckBoxUnchecked_Disabled.png
new file mode 100644
index 0000000..ebcb3ef
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxUnchecked_Disabled.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxUnchecked_Down.png b/src/test/baseline/testUICheckBoxUnchecked_Down.png
new file mode 100644
index 0000000..4967f44
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxUnchecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxUnchecked_Up.png b/src/test/baseline/testUICheckBoxUnchecked_Up.png
new file mode 100644
index 0000000..1c102e7
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxUnchecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboard.png b/src/test/baseline/testUIKeyboard.png
new file mode 100644
index 0000000..87d23a2
--- /dev/null
+++ b/src/test/baseline/testUIKeyboard.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboard1S.png b/src/test/baseline/testUIKeyboard1S.png
new file mode 100644
index 0000000..d7f0606
--- /dev/null
+++ b/src/test/baseline/testUIKeyboard1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardA.png b/src/test/baseline/testUIKeyboardA.png
new file mode 100644
index 0000000..0012b33
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardA.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardA1S.png b/src/test/baseline/testUIKeyboardA1S.png
new file mode 100644
index 0000000..f2ccd3a
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardA1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardAS.png b/src/test/baseline/testUIKeyboardAS.png
new file mode 100644
index 0000000..cd76aad
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardAS.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardDown11.png b/src/test/baseline/testUIKeyboardDown11.png
new file mode 100644
index 0000000..bfc8a50
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardDown11.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardDownA212S2.png b/src/test/baseline/testUIKeyboardDownA212S2.png
new file mode 100644
index 0000000..cd79feb
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardDownA212S2.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardDownA2S1.png b/src/test/baseline/testUIKeyboardDownA2S1.png
new file mode 100644
index 0000000..6c07214
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardDownA2S1.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFB.png b/src/test/baseline/testUIKeyboardFB.png
new file mode 100644
index 0000000..f4836a1
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFB.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFB1.png b/src/test/baseline/testUIKeyboardFB1.png
new file mode 100644
index 0000000..13a56aa
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFB1.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFBA1S.png b/src/test/baseline/testUIKeyboardFBA1S.png
new file mode 100644
index 0000000..e9e5534
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFBA1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFBAS.png b/src/test/baseline/testUIKeyboardFBAS.png
new file mode 100644
index 0000000..0e10aaf
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFBAS.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFBS.png b/src/test/baseline/testUIKeyboardFBS.png
new file mode 100644
index 0000000..9e0964a
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFBS.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardNoFB1S.png b/src/test/baseline/testUIKeyboardNoFB1S.png
new file mode 100644
index 0000000..4c91d91
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardNoFB1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardS.png b/src/test/baseline/testUIKeyboardS.png
new file mode 100644
index 0000000..12a6c9f
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardS.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleChecked_Disabled.png b/src/test/baseline/testUIToggleChecked_Disabled.png
new file mode 100644
index 0000000..6a23dda
--- /dev/null
+++ b/src/test/baseline/testUIToggleChecked_Disabled.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleChecked_Down.png b/src/test/baseline/testUIToggleChecked_Down.png
new file mode 100644
index 0000000..a17041f
--- /dev/null
+++ b/src/test/baseline/testUIToggleChecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleChecked_Up.png b/src/test/baseline/testUIToggleChecked_Up.png
new file mode 100644
index 0000000..03f2f41
--- /dev/null
+++ b/src/test/baseline/testUIToggleChecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleUnchecked_Disabled.png b/src/test/baseline/testUIToggleUnchecked_Disabled.png
new file mode 100644
index 0000000..8fccaa6
--- /dev/null
+++ b/src/test/baseline/testUIToggleUnchecked_Disabled.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleUnchecked_Down.png b/src/test/baseline/testUIToggleUnchecked_Down.png
new file mode 100644
index 0000000..bbad224
--- /dev/null
+++ b/src/test/baseline/testUIToggleUnchecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleUnchecked_Up.png b/src/test/baseline/testUIToggleUnchecked_Up.png
new file mode 100644
index 0000000..a6f08f0
--- /dev/null
+++ b/src/test/baseline/testUIToggleUnchecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testVideo-h264-48x48.h2641.png b/src/test/baseline/testVideo-h264-48x48.h2641.png
new file mode 100644
index 0000000..5adc733
--- /dev/null
+++ b/src/test/baseline/testVideo-h264-48x48.h2641.png
Binary files differ
diff --git a/src/test/baseline/testVideo-mjpeg-48x48.avi1.png b/src/test/baseline/testVideo-mjpeg-48x48.avi1.png
new file mode 100644
index 0000000..a16beec
--- /dev/null
+++ b/src/test/baseline/testVideo-mjpeg-48x48.avi1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png b/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png
new file mode 100644
index 0000000..043fa46
--- /dev/null
+++ b/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-mpeg1-48x48.mov1.png b/src/test/baseline/testVideo-mpeg1-48x48.mov1.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideo-mpeg1-48x48.mov1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-rgba-48x48.mov1.png b/src/test/baseline/testVideo-rgba-48x48.mov1.png
new file mode 100644
index 0000000..700b042
--- /dev/null
+++ b/src/test/baseline/testVideo-rgba-48x48.mov1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png b/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png
new file mode 100644
index 0000000..970e6a4
--- /dev/null
+++ b/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png
Binary files differ
diff --git a/src/test/baseline/testVideoActive1.png b/src/test/baseline/testVideoActive1.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testVideoActive1.png
Binary files differ
diff --git a/src/test/baseline/testVideoActive2.png b/src/test/baseline/testVideoActive2.png
new file mode 100644
index 0000000..0f1b555
--- /dev/null
+++ b/src/test/baseline/testVideoActive2.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics1.png b/src/test/baseline/testVideoDynamics1.png
new file mode 100644
index 0000000..3eca9a4
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics2.png b/src/test/baseline/testVideoDynamics2.png
new file mode 100644
index 0000000..8e8716c
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics3.png b/src/test/baseline/testVideoDynamics3.png
new file mode 100644
index 0000000..90bde83
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics4.png b/src/test/baseline/testVideoDynamics4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics5.png b/src/test/baseline/testVideoDynamics5.png
new file mode 100644
index 0000000..3eca9a4
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testVideoFPS.png b/src/test/baseline/testVideoFPS.png
new file mode 100644
index 0000000..70e60fd
--- /dev/null
+++ b/src/test/baseline/testVideoFPS.png
Binary files differ
diff --git a/src/test/baseline/testVideoHRef1.png b/src/test/baseline/testVideoHRef1.png
new file mode 100644
index 0000000..c463313
--- /dev/null
+++ b/src/test/baseline/testVideoHRef1.png
Binary files differ
diff --git a/src/test/baseline/testVideoLoop.png b/src/test/baseline/testVideoLoop.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideoLoop.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA1.png b/src/test/baseline/testVideoMaskRGBA1.png
new file mode 100644
index 0000000..2ddf341
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA1.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA2.png b/src/test/baseline/testVideoMaskRGBA2.png
new file mode 100644
index 0000000..12fccc3
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA2.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA3.png b/src/test/baseline/testVideoMaskRGBA3.png
new file mode 100644
index 0000000..9241d08
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA3.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA4.png b/src/test/baseline/testVideoMaskRGBA4.png
new file mode 100644
index 0000000..2b00886
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA4.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV1.png b/src/test/baseline/testVideoMaskYUV1.png
new file mode 100644
index 0000000..9b3cb7b
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV1.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV2.png b/src/test/baseline/testVideoMaskYUV2.png
new file mode 100644
index 0000000..978f3a6
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV2.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV3.png b/src/test/baseline/testVideoMaskYUV3.png
new file mode 100644
index 0000000..238edc4
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV3.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV4.png b/src/test/baseline/testVideoMaskYUV4.png
new file mode 100644
index 0000000..e4379a3
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV4.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ1.png b/src/test/baseline/testVideoMaskYUVJ1.png
new file mode 100644
index 0000000..ccb7e0d
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ1.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ2.png b/src/test/baseline/testVideoMaskYUVJ2.png
new file mode 100644
index 0000000..bfbd99c
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ2.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ3.png b/src/test/baseline/testVideoMaskYUVJ3.png
new file mode 100644
index 0000000..bf95a39
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ3.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ4.png b/src/test/baseline/testVideoMaskYUVJ4.png
new file mode 100644
index 0000000..b0f6e66
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ4.png
Binary files differ
diff --git a/src/test/baseline/testVideoNullFX.png b/src/test/baseline/testVideoNullFX.png
new file mode 100644
index 0000000..9c1a999
--- /dev/null
+++ b/src/test/baseline/testVideoNullFX.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityRGBA1.png b/src/test/baseline/testVideoOpacityRGBA1.png
new file mode 100644
index 0000000..e98478f
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityRGBA1.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityRGBA2.png b/src/test/baseline/testVideoOpacityRGBA2.png
new file mode 100644
index 0000000..00cf166
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityRGBA2.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityYUV1.png b/src/test/baseline/testVideoOpacityYUV1.png
new file mode 100644
index 0000000..d27fda0
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityYUV1.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityYUV2.png b/src/test/baseline/testVideoOpacityYUV2.png
new file mode 100644
index 0000000..152df47
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityYUV2.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek0.png b/src/test/baseline/testVideoSeek0.png
new file mode 100644
index 0000000..e0046ba
--- /dev/null
+++ b/src/test/baseline/testVideoSeek0.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek1.png b/src/test/baseline/testVideoSeek1.png
new file mode 100644
index 0000000..6f658da
--- /dev/null
+++ b/src/test/baseline/testVideoSeek1.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek2.png b/src/test/baseline/testVideoSeek2.png
new file mode 100644
index 0000000..6a48ed4
--- /dev/null
+++ b/src/test/baseline/testVideoSeek2.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek3.png b/src/test/baseline/testVideoSeek3.png
new file mode 100644
index 0000000..c436802
--- /dev/null
+++ b/src/test/baseline/testVideoSeek3.png
Binary files differ
diff --git a/src/test/baseline/testVideoState1.png b/src/test/baseline/testVideoState1.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideoState1.png
Binary files differ
diff --git a/src/test/baseline/testVideoState2.png b/src/test/baseline/testVideoState2.png
new file mode 100644
index 0000000..fed9567
--- /dev/null
+++ b/src/test/baseline/testVideoState2.png
Binary files differ
diff --git a/src/test/baseline/testVideoState3.png b/src/test/baseline/testVideoState3.png
new file mode 100644
index 0000000..b7bc073
--- /dev/null
+++ b/src/test/baseline/testVideoState3.png
Binary files differ
diff --git a/src/test/baseline/testVideoState4.png b/src/test/baseline/testVideoState4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testVideoState4.png
Binary files differ
diff --git a/src/test/baseline/testVideoState5.png b/src/test/baseline/testVideoState5.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideoState5.png
Binary files differ
diff --git a/src/test/baseline/testVideoWriter1.png b/src/test/baseline/testVideoWriter1.png
new file mode 100644
index 0000000..6a9f728
--- /dev/null
+++ b/src/test/baseline/testVideoWriter1.png
Binary files differ
diff --git a/src/test/baseline/testVideoWriterCanvas1.png b/src/test/baseline/testVideoWriterCanvas1.png
new file mode 100644
index 0000000..b319da2
--- /dev/null
+++ b/src/test/baseline/testVideoWriterCanvas1.png
Binary files differ
diff --git a/src/test/baseline/testWarp1.png b/src/test/baseline/testWarp1.png
new file mode 100644
index 0000000..99ddc2f
--- /dev/null
+++ b/src/test/baseline/testWarp1.png
Binary files differ
diff --git a/src/test/baseline/testWarp2.png b/src/test/baseline/testWarp2.png
new file mode 100644
index 0000000..0dca03a
--- /dev/null
+++ b/src/test/baseline/testWarp2.png
Binary files differ
diff --git a/src/test/baseline/testWarp3.png b/src/test/baseline/testWarp3.png
new file mode 100644
index 0000000..357a1b3
--- /dev/null
+++ b/src/test/baseline/testWarp3.png
Binary files differ
diff --git a/src/test/baseline/testWordsBR.png b/src/test/baseline/testWordsBR.png
new file mode 100644
index 0000000..82df070
--- /dev/null
+++ b/src/test/baseline/testWordsBR.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics1.png b/src/test/baseline/testWordsDynamics1.png
new file mode 100644
index 0000000..c68081b
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics2.png b/src/test/baseline/testWordsDynamics2.png
new file mode 100644
index 0000000..ff6c80f
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics3.png b/src/test/baseline/testWordsDynamics3.png
new file mode 100644
index 0000000..ff6c80f
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics4.png b/src/test/baseline/testWordsDynamics4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics5.png b/src/test/baseline/testWordsDynamics5.png
new file mode 100644
index 0000000..c68081b
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testWordsGamma1.png b/src/test/baseline/testWordsGamma1.png
new file mode 100644
index 0000000..9586c80
--- /dev/null
+++ b/src/test/baseline/testWordsGamma1.png
Binary files differ
diff --git a/src/test/baseline/testWordsGamma2.png b/src/test/baseline/testWordsGamma2.png
new file mode 100644
index 0000000..f5c2367
--- /dev/null
+++ b/src/test/baseline/testWordsGamma2.png
Binary files differ
diff --git a/src/test/baseline/testWordsIntensity.png b/src/test/baseline/testWordsIntensity.png
new file mode 100644
index 0000000..c49904e
--- /dev/null
+++ b/src/test/baseline/testWordsIntensity.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask1.png b/src/test/baseline/testWordsMask1.png
new file mode 100644
index 0000000..10affb2
--- /dev/null
+++ b/src/test/baseline/testWordsMask1.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask2.png b/src/test/baseline/testWordsMask2.png
new file mode 100644
index 0000000..093b6a3
--- /dev/null
+++ b/src/test/baseline/testWordsMask2.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask3.png b/src/test/baseline/testWordsMask3.png
new file mode 100644
index 0000000..2a6e464
--- /dev/null
+++ b/src/test/baseline/testWordsMask3.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask4.png b/src/test/baseline/testWordsMask4.png
new file mode 100644
index 0000000..a65df77
--- /dev/null
+++ b/src/test/baseline/testWordsMask4.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask5.png b/src/test/baseline/testWordsMask5.png
new file mode 100644
index 0000000..3df07d1
--- /dev/null
+++ b/src/test/baseline/testWordsMask5.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask6.png b/src/test/baseline/testWordsMask6.png
new file mode 100644
index 0000000..7c592c6
--- /dev/null
+++ b/src/test/baseline/testWordsMask6.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask7.png b/src/test/baseline/testWordsMask7.png
new file mode 100644
index 0000000..6be97bc
--- /dev/null
+++ b/src/test/baseline/testWordsMask7.png
Binary files differ
diff --git a/src/test/baseline/testWordsNullFX.png b/src/test/baseline/testWordsNullFX.png
new file mode 100644
index 0000000..3197c3d
--- /dev/null
+++ b/src/test/baseline/testWordsNullFX.png
Binary files differ
diff --git a/src/test/baseline/testWordsOutlines.png b/src/test/baseline/testWordsOutlines.png
new file mode 100644
index 0000000..6187147
--- /dev/null
+++ b/src/test/baseline/testWordsOutlines.png
Binary files differ
diff --git a/src/test/baseline/testWordsShadowFX1.png b/src/test/baseline/testWordsShadowFX1.png
new file mode 100644
index 0000000..bd50822
--- /dev/null
+++ b/src/test/baseline/testWordsShadowFX1.png
Binary files differ
diff --git a/src/test/baseline/testWordsShadowFX2.png b/src/test/baseline/testWordsShadowFX2.png
new file mode 100644
index 0000000..84b503c
--- /dev/null
+++ b/src/test/baseline/testWordsShadowFX2.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode1.png b/src/test/baseline/testWrapMode1.png
new file mode 100644
index 0000000..cff05d0
--- /dev/null
+++ b/src/test/baseline/testWrapMode1.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode2.png b/src/test/baseline/testWrapMode2.png
new file mode 100644
index 0000000..596cdb6
--- /dev/null
+++ b/src/test/baseline/testWrapMode2.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode3.png b/src/test/baseline/testWrapMode3.png
new file mode 100644
index 0000000..cff05d0
--- /dev/null
+++ b/src/test/baseline/testWrapMode3.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode4.png b/src/test/baseline/testWrapMode4.png
new file mode 100644
index 0000000..6d17b93
--- /dev/null
+++ b/src/test/baseline/testWrapMode4.png
Binary files differ
diff --git a/src/test/baseline/testXPosPointAnim1.png b/src/test/baseline/testXPosPointAnim1.png
new file mode 100644
index 0000000..ce2f589
--- /dev/null
+++ b/src/test/baseline/testXPosPointAnim1.png
Binary files differ
diff --git a/src/test/baseline/testXPosPointAnim2.png b/src/test/baseline/testXPosPointAnim2.png
new file mode 100644
index 0000000..84eca4f
--- /dev/null
+++ b/src/test/baseline/testXPosPointAnim2.png
Binary files differ
diff --git a/src/test/baseline/testXPosPointAnim3.png b/src/test/baseline/testXPosPointAnim3.png
new file mode 100644
index 0000000..84eca4f
--- /dev/null
+++ b/src/test/baseline/testXPosPointAnim3.png
Binary files differ
diff --git a/src/test/baseline/testYPosPointAnim1.png b/src/test/baseline/testYPosPointAnim1.png
new file mode 100644
index 0000000..ce2f589
--- /dev/null
+++ b/src/test/baseline/testYPosPointAnim1.png
Binary files differ
diff --git a/src/test/baseline/testYPosPointAnim2.png b/src/test/baseline/testYPosPointAnim2.png
new file mode 100644
index 0000000..39d093e
--- /dev/null
+++ b/src/test/baseline/testYPosPointAnim2.png
Binary files differ
diff --git a/src/test/baseline/testYPosPointAnim3.png b/src/test/baseline/testYPosPointAnim3.png
new file mode 100644
index 0000000..39d093e
--- /dev/null
+++ b/src/test/baseline/testYPosPointAnim3.png
Binary files differ
diff --git a/src/test/baseline/testbasics.png b/src/test/baseline/testbasics.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testbasics.png
Binary files differ
diff --git a/src/test/baseline/testline1.png b/src/test/baseline/testline1.png
new file mode 100644
index 0000000..b499abd
--- /dev/null
+++ b/src/test/baseline/testline1.png
Binary files differ
diff --git a/src/test/baseline/testline2.png b/src/test/baseline/testline2.png
new file mode 100644
index 0000000..c307bd7
--- /dev/null
+++ b/src/test/baseline/testline2.png
Binary files differ
diff --git a/src/test/baseline/testline3.png b/src/test/baseline/testline3.png
new file mode 100644
index 0000000..c1a7795
--- /dev/null
+++ b/src/test/baseline/testline3.png
Binary files differ
diff --git a/src/test/baseline/testline4.png b/src/test/baseline/testline4.png
new file mode 100644
index 0000000..b086840
--- /dev/null
+++ b/src/test/baseline/testline4.png
Binary files differ
diff --git a/src/test/baseline/testlineopacity1.png b/src/test/baseline/testlineopacity1.png
new file mode 100644
index 0000000..0c11d1c
--- /dev/null
+++ b/src/test/baseline/testlineopacity1.png
Binary files differ
diff --git a/src/test/baseline/testlineopacity2.png b/src/test/baseline/testlineopacity2.png
new file mode 100644
index 0000000..ee9b3e7
--- /dev/null
+++ b/src/test/baseline/testlineopacity2.png
Binary files differ
diff --git a/src/test/baseline/testlotsoflines.png b/src/test/baseline/testlotsoflines.png
new file mode 100644
index 0000000..485d9c5
--- /dev/null
+++ b/src/test/baseline/testlotsoflines.png
Binary files differ
diff --git a/src/test/baseline/testplugin1.png b/src/test/baseline/testplugin1.png
new file mode 100644
index 0000000..fd07f6c
--- /dev/null
+++ b/src/test/baseline/testplugin1.png
Binary files differ
diff --git a/src/test/baseline/testplugin2.png b/src/test/baseline/testplugin2.png
new file mode 100644
index 0000000..2ec2e11
--- /dev/null
+++ b/src/test/baseline/testplugin2.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline1.png b/src/test/baseline/testtexturedline1.png
new file mode 100644
index 0000000..d4b3719
--- /dev/null
+++ b/src/test/baseline/testtexturedline1.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline2.png b/src/test/baseline/testtexturedline2.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testtexturedline2.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline3.png b/src/test/baseline/testtexturedline3.png
new file mode 100644
index 0000000..7ac3757
--- /dev/null
+++ b/src/test/baseline/testtexturedline3.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline4.png b/src/test/baseline/testtexturedline4.png
new file mode 100644
index 0000000..07b7750
--- /dev/null
+++ b/src/test/baseline/testtexturedline4.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline5.png b/src/test/baseline/testtexturedline5.png
new file mode 100644
index 0000000..7ffeed2
--- /dev/null
+++ b/src/test/baseline/testtexturedline5.png
Binary files differ
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
new file mode 100644
index 0000000..d57eda6
--- /dev/null
+++ b/src/test/extrafonts/testaddfontdir.ttf
Binary files differ
diff --git a/src/test/fonts/Vera.ttf b/src/test/fonts/Vera.ttf
new file mode 100644
index 0000000..58cd6b5
--- /dev/null
+++ b/src/test/fonts/Vera.ttf
Binary files differ
diff --git a/src/test/fonts/VeraBI.ttf b/src/test/fonts/VeraBI.ttf
new file mode 100644
index 0000000..b55eee3
--- /dev/null
+++ b/src/test/fonts/VeraBI.ttf
Binary files differ
diff --git a/src/test/fonts/VeraBd.ttf b/src/test/fonts/VeraBd.ttf
new file mode 100644
index 0000000..51d6111
--- /dev/null
+++ b/src/test/fonts/VeraBd.ttf
Binary files differ
diff --git a/src/test/fonts/VeraIt.ttf b/src/test/fonts/VeraIt.ttf
new file mode 100644
index 0000000..cc23c9e
--- /dev/null
+++ b/src/test/fonts/VeraIt.ttf
Binary files differ
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
new file mode 100644
index 0000000..5800230
--- /dev/null
+++ b/src/test/media/1x1_white.png
Binary files differ
diff --git a/src/test/media/22.050Hz_16bit_mono.wav b/src/test/media/22.050Hz_16bit_mono.wav
new file mode 100755
index 0000000..1f86e64
--- /dev/null
+++ b/src/test/media/22.050Hz_16bit_mono.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_6Chan.ogg b/src/test/media/44.1kHz_16bit_6Chan.ogg
new file mode 100644
index 0000000..7d190d1
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_6Chan.ogg
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_mono.wav b/src/test/media/44.1kHz_16bit_mono.wav
new file mode 100755
index 0000000..8676a75
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_mono.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_stereo.aif b/src/test/media/44.1kHz_16bit_stereo.aif
new file mode 100755
index 0000000..0c9b5c7
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_stereo.aif
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_stereo.wav b/src/test/media/44.1kHz_16bit_stereo.wav
new file mode 100755
index 0000000..af5c2ee
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_stereo.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_24bit_mono.wav b/src/test/media/44.1kHz_24bit_mono.wav
new file mode 100755
index 0000000..fd2deed
--- /dev/null
+++ b/src/test/media/44.1kHz_24bit_mono.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_24bit_stereo.aif b/src/test/media/44.1kHz_24bit_stereo.aif
new file mode 100755
index 0000000..f569ded
--- /dev/null
+++ b/src/test/media/44.1kHz_24bit_stereo.aif
Binary files differ
diff --git a/src/test/media/44.1kHz_24bit_stereo.wav b/src/test/media/44.1kHz_24bit_stereo.wav
new file mode 100755
index 0000000..36c6aa7
--- /dev/null
+++ b/src/test/media/44.1kHz_24bit_stereo.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_mono.ogg b/src/test/media/44.1kHz_mono.ogg
new file mode 100755
index 0000000..7bcb866
--- /dev/null
+++ b/src/test/media/44.1kHz_mono.ogg
Binary files differ
diff --git a/src/test/media/44.1kHz_stereo.mp3 b/src/test/media/44.1kHz_stereo.mp3
new file mode 100644
index 0000000..cbefc63
--- /dev/null
+++ b/src/test/media/44.1kHz_stereo.mp3
Binary files differ
diff --git a/src/test/media/44.1kHz_stereo.ogg b/src/test/media/44.1kHz_stereo.ogg
new file mode 100644
index 0000000..f5ed4d0
--- /dev/null
+++ b/src/test/media/44.1kHz_stereo.ogg
Binary files differ
diff --git a/src/test/media/48kHz_16bit_mono.wav b/src/test/media/48kHz_16bit_mono.wav
new file mode 100755
index 0000000..0f817c9
--- /dev/null
+++ b/src/test/media/48kHz_16bit_mono.wav
Binary files differ
diff --git a/src/test/media/48kHz_16bit_stereo.aif b/src/test/media/48kHz_16bit_stereo.aif
new file mode 100755
index 0000000..db3a381
--- /dev/null
+++ b/src/test/media/48kHz_16bit_stereo.aif
Binary files differ
diff --git a/src/test/media/48kHz_16bit_stereo.wav b/src/test/media/48kHz_16bit_stereo.wav
new file mode 100755
index 0000000..9fc52f1
--- /dev/null
+++ b/src/test/media/48kHz_16bit_stereo.wav
Binary files differ
diff --git a/src/test/media/48kHz_24bit_mono.wav b/src/test/media/48kHz_24bit_mono.wav
new file mode 100755
index 0000000..296ca11
--- /dev/null
+++ b/src/test/media/48kHz_24bit_mono.wav
Binary files differ
diff --git a/src/test/media/48kHz_24bit_stereo.aif b/src/test/media/48kHz_24bit_stereo.aif
new file mode 100755
index 0000000..3ab7cf1
--- /dev/null
+++ b/src/test/media/48kHz_24bit_stereo.aif
Binary files differ
diff --git a/src/test/media/48kHz_24bit_stereo.wav b/src/test/media/48kHz_24bit_stereo.wav
new file mode 100755
index 0000000..af2c977
--- /dev/null
+++ b/src/test/media/48kHz_24bit_stereo.wav
Binary files differ
diff --git a/src/test/media/48kHz_stereo.mp3 b/src/test/media/48kHz_stereo.mp3
new file mode 100644
index 0000000..0eaa0f5
--- /dev/null
+++ b/src/test/media/48kHz_stereo.mp3
Binary files differ
diff --git a/src/test/media/48kHz_stereo.ogg b/src/test/media/48kHz_stereo.ogg
new file mode 100644
index 0000000..92d7b7b
--- /dev/null
+++ b/src/test/media/48kHz_stereo.ogg
Binary files differ
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
new file mode 100644
index 0000000..81cbb0f
--- /dev/null
+++ b/src/test/media/button_bg_down.png
Binary files differ
diff --git a/src/test/media/button_bg_up.png b/src/test/media/button_bg_up.png
new file mode 100644
index 0000000..91cfe04
--- /dev/null
+++ b/src/test/media/button_bg_up.png
Binary files differ
diff --git a/src/test/media/button_check.png b/src/test/media/button_check.png
new file mode 100644
index 0000000..b0aa4a9
--- /dev/null
+++ b/src/test/media/button_check.png
Binary files differ
diff --git a/src/test/media/button_disabled.png b/src/test/media/button_disabled.png
new file mode 100644
index 0000000..dbf1309
--- /dev/null
+++ b/src/test/media/button_disabled.png
Binary files differ
diff --git a/src/test/media/button_down.png b/src/test/media/button_down.png
new file mode 100644
index 0000000..88ee5f5
--- /dev/null
+++ b/src/test/media/button_down.png
Binary files differ
diff --git a/src/test/media/button_over.png b/src/test/media/button_over.png
new file mode 100644
index 0000000..0837e8e
--- /dev/null
+++ b/src/test/media/button_over.png
Binary files differ
diff --git a/src/test/media/button_up.png b/src/test/media/button_up.png
new file mode 100644
index 0000000..aa7d33a
--- /dev/null
+++ b/src/test/media/button_up.png
Binary files differ
diff --git a/src/test/media/checkbox_checked_disabled.png b/src/test/media/checkbox_checked_disabled.png
new file mode 100644
index 0000000..da58829
--- /dev/null
+++ b/src/test/media/checkbox_checked_disabled.png
Binary files differ
diff --git a/src/test/media/checkbox_checked_down.png b/src/test/media/checkbox_checked_down.png
new file mode 100644
index 0000000..4fbbd83
--- /dev/null
+++ b/src/test/media/checkbox_checked_down.png
Binary files differ
diff --git a/src/test/media/checkbox_checked_up.png b/src/test/media/checkbox_checked_up.png
new file mode 100644
index 0000000..ca901f4
--- /dev/null
+++ b/src/test/media/checkbox_checked_up.png
Binary files differ
diff --git a/src/test/media/checkbox_unchecked_disabled.png b/src/test/media/checkbox_unchecked_disabled.png
new file mode 100644
index 0000000..e8c2116
--- /dev/null
+++ b/src/test/media/checkbox_unchecked_disabled.png
Binary files differ
diff --git a/src/test/media/checkbox_unchecked_down.png b/src/test/media/checkbox_unchecked_down.png
new file mode 100644
index 0000000..69f8282
--- /dev/null
+++ b/src/test/media/checkbox_unchecked_down.png
Binary files differ
diff --git a/src/test/media/checkbox_unchecked_up.png b/src/test/media/checkbox_unchecked_up.png
new file mode 100644
index 0000000..e354492
--- /dev/null
+++ b/src/test/media/checkbox_unchecked_up.png
Binary files differ
diff --git a/src/test/media/checker.png b/src/test/media/checker.png
new file mode 100644
index 0000000..4f100c5
--- /dev/null
+++ b/src/test/media/checker.png
Binary files differ
diff --git a/src/test/media/chromakey-median.png b/src/test/media/chromakey-median.png
new file mode 100644
index 0000000..5858c4b
--- /dev/null
+++ b/src/test/media/chromakey-median.png
Binary files differ
diff --git a/src/test/media/chromakey.png b/src/test/media/chromakey.png
new file mode 100644
index 0000000..b2cfc2e
--- /dev/null
+++ b/src/test/media/chromakey.png
Binary files differ
diff --git a/src/test/media/colorramp.png b/src/test/media/colorramp.png
new file mode 100644
index 0000000..da12725
--- /dev/null
+++ b/src/test/media/colorramp.png
Binary files differ
diff --git a/src/test/media/crop_bkgd.png b/src/test/media/crop_bkgd.png
new file mode 100644
index 0000000..89f9e95
--- /dev/null
+++ b/src/test/media/crop_bkgd.png
Binary files differ
diff --git a/src/test/media/dilation.png b/src/test/media/dilation.png
new file mode 100644
index 0000000..7981594
--- /dev/null
+++ b/src/test/media/dilation.png
Binary files differ
diff --git a/src/test/media/erosion.png b/src/test/media/erosion.png
new file mode 100644
index 0000000..899e2c4
--- /dev/null
+++ b/src/test/media/erosion.png
Binary files differ
diff --git a/src/test/media/filterwipeborder.png b/src/test/media/filterwipeborder.png
new file mode 100644
index 0000000..58ac84d
--- /dev/null
+++ b/src/test/media/filterwipeborder.png
Binary files differ
diff --git a/src/test/media/flat.png b/src/test/media/flat.png
new file mode 100644
index 0000000..51d2c55
--- /dev/null
+++ b/src/test/media/flat.png
Binary files differ
diff --git a/src/test/media/floodfill.png b/src/test/media/floodfill.png
new file mode 100644
index 0000000..6a9e5b5
--- /dev/null
+++ b/src/test/media/floodfill.png
Binary files differ
diff --git a/src/test/media/freidrehen.jpg b/src/test/media/freidrehen.jpg
new file mode 100644
index 0000000..7f93bf0
--- /dev/null
+++ b/src/test/media/freidrehen.jpg
Binary files differ
diff --git a/src/test/media/greyscale.png b/src/test/media/greyscale.png
new file mode 100644
index 0000000..f86a18b
--- /dev/null
+++ b/src/test/media/greyscale.png
Binary files differ
diff --git a/src/test/media/h264-48x48.h264 b/src/test/media/h264-48x48.h264
new file mode 100644
index 0000000..d650960
--- /dev/null
+++ b/src/test/media/h264-48x48.h264
Binary files differ
diff --git a/src/test/media/hsl.png b/src/test/media/hsl.png
new file mode 100644
index 0000000..9621451
--- /dev/null
+++ b/src/test/media/hsl.png
Binary files differ
diff --git a/src/test/media/i8-64x64.png b/src/test/media/i8-64x64.png
new file mode 100644
index 0000000..ec88c8c
--- /dev/null
+++ b/src/test/media/i8-64x64.png
Binary files differ
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
new file mode 100644
index 0000000..6dc6fd1
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.png
Binary files differ
diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png
new file mode 100644
index 0000000..eb6b005
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png
Binary files differ
diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png
new file mode 100644
index 0000000..d2f393b
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png
Binary files differ
diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png
new file mode 100644
index 0000000..7ac86fe
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png
Binary files differ
diff --git a/src/test/media/keyboard_bg.png b/src/test/media/keyboard_bg.png
new file mode 100644
index 0000000..a767d06
--- /dev/null
+++ b/src/test/media/keyboard_bg.png
Binary files differ
diff --git a/src/test/media/keyboard_down.png b/src/test/media/keyboard_down.png
new file mode 100644
index 0000000..f3ead71
--- /dev/null
+++ b/src/test/media/keyboard_down.png
Binary files differ
diff --git a/src/test/media/keyboard_feedback.png b/src/test/media/keyboard_feedback.png
new file mode 100644
index 0000000..e519594
--- /dev/null
+++ b/src/test/media/keyboard_feedback.png
Binary files differ
diff --git a/src/test/media/mask.png b/src/test/media/mask.png
new file mode 100644
index 0000000..031b39a
--- /dev/null
+++ b/src/test/media/mask.png
Binary files differ
diff --git a/src/test/media/mask1.png b/src/test/media/mask1.png
new file mode 100644
index 0000000..ffe5618
--- /dev/null
+++ b/src/test/media/mask1.png
Binary files differ
diff --git a/src/test/media/mask2.png b/src/test/media/mask2.png
new file mode 100644
index 0000000..92975df
--- /dev/null
+++ b/src/test/media/mask2.png
Binary files differ
diff --git a/src/test/media/mjpeg-48x48.avi b/src/test/media/mjpeg-48x48.avi
new file mode 100644
index 0000000..337df16
--- /dev/null
+++ b/src/test/media/mjpeg-48x48.avi
Binary files differ
diff --git a/src/test/media/mpeg1-48x48-sound.avi b/src/test/media/mpeg1-48x48-sound.avi
new file mode 100644
index 0000000..be415db
--- /dev/null
+++ b/src/test/media/mpeg1-48x48-sound.avi
Binary files differ
diff --git a/src/test/media/mpeg1-48x48.mov b/src/test/media/mpeg1-48x48.mov
new file mode 100644
index 0000000..16ab499
--- /dev/null
+++ b/src/test/media/mpeg1-48x48.mov
Binary files differ
diff --git a/src/test/media/oe.png b/src/test/media/oe.png
new file mode 100644
index 0000000..3527967
--- /dev/null
+++ b/src/test/media/oe.png
Binary files differ
diff --git a/src/test/media/pause_button_down.png b/src/test/media/pause_button_down.png
new file mode 100644
index 0000000..c06b34a
--- /dev/null
+++ b/src/test/media/pause_button_down.png
Binary files differ
diff --git a/src/test/media/pause_button_up.png b/src/test/media/pause_button_up.png
new file mode 100644
index 0000000..1a923b9
--- /dev/null
+++ b/src/test/media/pause_button_up.png
Binary files differ
diff --git a/src/test/media/play_button_down.png b/src/test/media/play_button_down.png
new file mode 100644
index 0000000..07b167b
--- /dev/null
+++ b/src/test/media/play_button_down.png
Binary files differ
diff --git a/src/test/media/play_button_up.png b/src/test/media/play_button_up.png
new file mode 100644
index 0000000..e16ec9e
--- /dev/null
+++ b/src/test/media/play_button_up.png
Binary files differ
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
new file mode 100644
index 0000000..1675688
--- /dev/null
+++ b/src/test/media/rectborder.png
Binary files differ
diff --git a/src/test/media/rgb24-32x32.png b/src/test/media/rgb24-32x32.png
new file mode 100644
index 0000000..c5d6711
--- /dev/null
+++ b/src/test/media/rgb24-32x32.png
Binary files differ
diff --git a/src/test/media/rgb24-64x64.png b/src/test/media/rgb24-64x64.png
new file mode 100644
index 0000000..cca71fe
--- /dev/null
+++ b/src/test/media/rgb24-64x64.png
Binary files differ
diff --git a/src/test/media/rgb24-65x65.png b/src/test/media/rgb24-65x65.png
new file mode 100644
index 0000000..ada2689
--- /dev/null
+++ b/src/test/media/rgb24-65x65.png
Binary files differ
diff --git a/src/test/media/rgb24alpha-32x32.png b/src/test/media/rgb24alpha-32x32.png
new file mode 100644
index 0000000..2e9e6af
--- /dev/null
+++ b/src/test/media/rgb24alpha-32x32.png
Binary files differ
diff --git a/src/test/media/rgb24alpha-64x64.png b/src/test/media/rgb24alpha-64x64.png
new file mode 100644
index 0000000..41b69c3
--- /dev/null
+++ b/src/test/media/rgb24alpha-64x64.png
Binary files differ
diff --git a/src/test/media/rgba-48x48.mov b/src/test/media/rgba-48x48.mov
new file mode 100644
index 0000000..7e311cc
--- /dev/null
+++ b/src/test/media/rgba-48x48.mov
Binary files differ
diff --git a/src/test/media/scrollarea_border.png b/src/test/media/scrollarea_border.png
new file mode 100644
index 0000000..2e95f57
--- /dev/null
+++ b/src/test/media/scrollarea_border.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_thumb_disabled.png b/src/test/media/scrollbar_horiz_thumb_disabled.png
new file mode 100644
index 0000000..4645372
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_thumb_disabled.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_thumb_down.png b/src/test/media/scrollbar_horiz_thumb_down.png
new file mode 100644
index 0000000..6dc6fd1
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_thumb_down.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_thumb_up.png b/src/test/media/scrollbar_horiz_thumb_up.png
new file mode 100644
index 0000000..eb6b005
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_thumb_up.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_track.png b/src/test/media/scrollbar_horiz_track.png
new file mode 100644
index 0000000..d2f393b
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_track.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_track_disabled.png b/src/test/media/scrollbar_horiz_track_disabled.png
new file mode 100644
index 0000000..7ac86fe
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_track_disabled.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_thumb_disabled.png b/src/test/media/scrollbar_vert_thumb_disabled.png
new file mode 100644
index 0000000..f375a2b
--- /dev/null
+++ b/src/test/media/scrollbar_vert_thumb_disabled.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_thumb_down.png b/src/test/media/scrollbar_vert_thumb_down.png
new file mode 100644
index 0000000..c7b09d1
--- /dev/null
+++ b/src/test/media/scrollbar_vert_thumb_down.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_thumb_up.png b/src/test/media/scrollbar_vert_thumb_up.png
new file mode 100644
index 0000000..f6c2f88
--- /dev/null
+++ b/src/test/media/scrollbar_vert_thumb_up.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_track.png b/src/test/media/scrollbar_vert_track.png
new file mode 100644
index 0000000..58af284
--- /dev/null
+++ b/src/test/media/scrollbar_vert_track.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_track_disabled.png b/src/test/media/scrollbar_vert_track_disabled.png
new file mode 100644
index 0000000..695b112
--- /dev/null
+++ b/src/test/media/scrollbar_vert_track_disabled.png
Binary files differ
diff --git a/src/test/media/shadow.png b/src/test/media/shadow.png
new file mode 100644
index 0000000..0a4563f
--- /dev/null
+++ b/src/test/media/shadow.png
Binary files differ
diff --git a/src/test/media/slider_horiz_track.png b/src/test/media/slider_horiz_track.png
new file mode 100644
index 0000000..6e233a5
--- /dev/null
+++ b/src/test/media/slider_horiz_track.png
Binary files differ
diff --git a/src/test/media/slider_horiz_track_disabled.png b/src/test/media/slider_horiz_track_disabled.png
new file mode 100644
index 0000000..01c880d
--- /dev/null
+++ b/src/test/media/slider_horiz_track_disabled.png
Binary files differ
diff --git a/src/test/media/slider_thumb_down.png b/src/test/media/slider_thumb_down.png
new file mode 100644
index 0000000..1f2acc2
--- /dev/null
+++ b/src/test/media/slider_thumb_down.png
Binary files differ
diff --git a/src/test/media/slider_thumb_up.png b/src/test/media/slider_thumb_up.png
new file mode 100644
index 0000000..885506d
--- /dev/null
+++ b/src/test/media/slider_thumb_up.png
Binary files differ
diff --git a/src/test/media/slider_vert_track.png b/src/test/media/slider_vert_track.png
new file mode 100644
index 0000000..51bac37
--- /dev/null
+++ b/src/test/media/slider_vert_track.png
Binary files differ
diff --git a/src/test/media/slider_vert_track_disabled.png b/src/test/media/slider_vert_track_disabled.png
new file mode 100644
index 0000000..bc8d7b6
--- /dev/null
+++ b/src/test/media/slider_vert_track_disabled.png
Binary files differ
diff --git a/src/test/media/spike.png b/src/test/media/spike.png
new file mode 100644
index 0000000..958e95d
--- /dev/null
+++ b/src/test/media/spike.png
Binary files differ
diff --git a/src/test/media/toggle_checked_Disabled.png b/src/test/media/toggle_checked_Disabled.png
new file mode 100644
index 0000000..31372c0
--- /dev/null
+++ b/src/test/media/toggle_checked_Disabled.png
Binary files differ
diff --git a/src/test/media/toggle_checked_Down.png b/src/test/media/toggle_checked_Down.png
new file mode 100644
index 0000000..8c4afd2
--- /dev/null
+++ b/src/test/media/toggle_checked_Down.png
Binary files differ
diff --git a/src/test/media/toggle_checked_Up.png b/src/test/media/toggle_checked_Up.png
new file mode 100644
index 0000000..8214fcf
--- /dev/null
+++ b/src/test/media/toggle_checked_Up.png
Binary files differ
diff --git a/src/test/media/toggle_unchecked_Disabled.png b/src/test/media/toggle_unchecked_Disabled.png
new file mode 100644
index 0000000..6b90e0b
--- /dev/null
+++ b/src/test/media/toggle_unchecked_Disabled.png
Binary files differ
diff --git a/src/test/media/toggle_unchecked_Down.png b/src/test/media/toggle_unchecked_Down.png
new file mode 100644
index 0000000..f2e4272
--- /dev/null
+++ b/src/test/media/toggle_unchecked_Down.png
Binary files differ
diff --git a/src/test/media/toggle_unchecked_Up.png b/src/test/media/toggle_unchecked_Up.png
new file mode 100644
index 0000000..3a006ea
--- /dev/null
+++ b/src/test/media/toggle_unchecked_Up.png
Binary files differ
diff --git a/src/test/media/vp6a-yuva-48x48.flv b/src/test/media/vp6a-yuva-48x48.flv
new file mode 100644
index 0000000..21866fe
--- /dev/null
+++ b/src/test/media/vp6a-yuva-48x48.flv
Binary files differ
diff --git a/src/test/media/widebmp.jpg b/src/test/media/widebmp.jpg
new file mode 100644
index 0000000..8304e3d
--- /dev/null
+++ b/src/test/media/widebmp.jpg
Binary files differ
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
new file mode 100644
index 0000000..d62180a
--- /dev/null
+++ b/src/test/testmediadir/mjpeg-48x48.avi
Binary files differ
diff --git a/src/test/testmediadir/rgb24-64x64a.png b/src/test/testmediadir/rgb24-64x64a.png
new file mode 100644
index 0000000..41b69c3
--- /dev/null
+++ b/src/test/testmediadir/rgb24-64x64a.png
Binary files differ