Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template test case for graphic contexts #160

Merged
merged 74 commits into from
Dec 12, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
175062e
Simple drawing tests for Image backend.
Jul 12, 2014
4628d42
Merge branch 'feature/abstract-graphics-context' into template-test-c…
Aug 31, 2014
5d77690
make the tests folder a subpackage
Aug 31, 2014
d841b1a
add a test template for drawing with graphic contexts
Aug 31, 2014
0a08e70
add tests for the agg GC
Aug 31, 2014
d6bb033
add tests for the pdf GC
Aug 31, 2014
9095472
add tests for the QPainter GC
Aug 31, 2014
569770a
remove old testcase
Aug 31, 2014
64a65a4
split a special tester subclass for gui toolkit related contexts
itziakos Sep 1, 2014
c81a92d
use the DrawingImageTester
itziakos Sep 1, 2014
7b8d2ae
support some very basic testing for the PDF backend
itziakos Sep 1, 2014
006dac0
update tests about agg drawing
itziakos Sep 1, 2014
7f1ba01
provide just the name without the extension in self.filename
itziakos Sep 1, 2014
b90f722
add tests for the ps backend
itziakos Sep 1, 2014
12d3f44
update the pdf tests
itziakos Sep 1, 2014
ba0d2ed
add basic drawing tests for svg
itziakos Sep 1, 2014
204e9f5
add workaround for and ps, svg tests to function
itziakos Sep 1, 2014
6e3fd9c
add testcase for the gl backend
itziakos Sep 1, 2014
6d62b0c
minor cleanup
itziakos Sep 1, 2014
bd250ff
add tests for the cairo backend
itziakos Sep 1, 2014
dd487f9
update depedencies so that all the tests are run
itziakos Sep 1, 2014
c41bf17
udpate requirements
itziakos Sep 2, 2014
316f9b7
install libpng-dev
itziakos Sep 2, 2014
f6973a3
remvoe py2cairo for now
itziakos Sep 2, 2014
c056117
try to get PIL to install properly
itziakos Sep 2, 2014
3169b32
symlinks for PIL
itziakos Sep 2, 2014
4995e45
add a few more dependencies
itziakos Sep 2, 2014
2745144
avoid segfault in gl tests
itziakos Sep 2, 2014
826d50c
another attempt at pycairo
itziakos Sep 2, 2014
17ccd1d
add pycairo to the allowed items in pip
itziakos Sep 2, 2014
8a6c2ec
more fixes on the dependencies
itziakos Sep 2, 2014
ebc1a76
try to compile pycairo
itziakos Sep 2, 2014
53f723a
fix requirements.txt
itziakos Sep 2, 2014
decba37
use the allow commands for pip
itziakos Sep 2, 2014
a5f7aa4
use wget
itziakos Sep 2, 2014
0030d59
fix typo
itziakos Sep 2, 2014
208cf28
more typos
itziakos Sep 2, 2014
6069e05
Fix unit test for qpainter.
corranwebster Sep 2, 2014
31cb6a8
Merge pull request #146 from enthought/fix/qpainter-tests
itziakos Sep 2, 2014
caae1b3
use getiterator instead of iter
itziakos Sep 2, 2014
319cb71
Merge remote-tracking branch 'origin/template-test-case-for-graphic-c…
itziakos Sep 2, 2014
acf7abc
minor cleanup
itziakos Sep 2, 2014
b05a051
Merge branch 'master' into template-test-case-for-graphic-contexts
itziakos Nov 15, 2014
db19c40
always clear the graphics context
itziakos Nov 15, 2014
7c42a81
Merge remote-tracking branch 'origin/template-test-case-for-graphic-c…
itziakos Nov 15, 2014
7c76783
minor cleanup
itziakos Nov 15, 2014
4c6ec14
rework drawing tests to make sure that we are getting red pixels
itziakos Nov 15, 2014
e93db87
only use the temp dirs when saving files
itziakos Nov 15, 2014
4560bf7
update gl tests to create a gl context and save an image
itziakos Nov 15, 2014
56b3229
fix tests to support RGB or RGBA
itziakos Nov 15, 2014
2fab14e
fix tests for svg
itziakos Nov 15, 2014
e8d6b3f
use the right filename for the gl tests
itziakos Nov 15, 2014
5d2f3e3
revert changes to the test assistants
itziakos Nov 15, 2014
814ec6e
add clean() method to the pdf graphics context
itziakos Nov 15, 2014
b587eba
make the text_clip test an expected failure
itziakos Nov 15, 2014
624ae2f
attempt to fix travis-ci
itziakos Nov 15, 2014
29b7c24
try compiling numpy
itziakos Nov 15, 2014
6f86cd9
looks like pil and pillow have a bad interaction
itziakos Nov 15, 2014
da4b4bf
revert to installing PIL
itziakos Nov 15, 2014
a0b3f01
Merge branch 'master' into template-test-case-for-graphic-contexts
itziakos Nov 17, 2014
de7d04a
force to use the default but slow PNGImageEncoder
itziakos Nov 27, 2014
7ba2544
add dev requirements for python 2.6
itziakos Nov 27, 2014
27dba40
install extra requirements for python 2.6
itziakos Nov 28, 2014
f5d31d4
build cairo when using venv with site-packages
itziakos Nov 28, 2014
a1f35c5
skip cairo tests when cairo is not importable
itziakos Nov 28, 2014
707a45b
skip tests when requirements are not available
itziakos Nov 28, 2014
137798e
fix typo
itziakos Nov 28, 2014
6132a9e
add more skipif cases
itziakos Nov 28, 2014
ab0b4f8
place imports inside the function to avoid import errors when require…
itziakos Nov 28, 2014
012bba5
Update CHANGES.txt
itziakos Dec 12, 2014
66f1e7a
[ci-skip]
itziakos Dec 12, 2014
229415e
cleanup tests
itziakos Dec 12, 2014
b1fb165
Update test_gl_drawing.py
itziakos Dec 12, 2014
70edcee
Update test_gl_drawing.py
itziakos Dec 12, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ python:
- '2.7_with_system_site_packages'
- 2.6
before_install:
# For Python 2.7, install PyQt4
- sudo apt-get update
# For Python 2.7, install PyQt4 and cairo
- if [[ $TRAVIS_PYTHON_VERSION == '2.7_with_system_site_packages' ]]; then source .travis_before_install; fi
# PyQt can't be installed on 2.6; run the tests without Qt
# PyQt and cairo can't be installed on 2.6; run the tests without Qt
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then source .travis_before_install_noqt; fi
- sudo apt-get install swig
# Simlinks for PIL compilation
- sudo ln -s /usr/lib/`uname -i`-linux-gnu/libfreetype.so /usr/lib/
- sudo ln -s /usr/lib/`uname -i`-linux-gnu/libjpeg.so /usr/lib/
- sudo ln -s /usr/lib/`uname -i`-linux-gnu/libpng.so /usr/lib/
- sudo ln -s /usr/lib/`uname -i`-linux-gnu/libz.so /usr/lib/
install:
# nose is already installed
- pip install cython
- pip install --upgrade numpy
- pip install -r dev_requirements.txt
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install -r requirements-2.6.txt; fi
- pip install coveralls
- python setup.py develop
script:
Expand Down
8 changes: 8 additions & 0 deletions .travis_before_install
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@ python -c 'import PyQt4'
python -c 'import PyQt4.QtCore'
python -c 'import PyQt4.QtGui'

wget -nv http://cairographics.org/releases/py2cairo-1.10.0.tar.bz2
tar -xf py2cairo-1.10.0.tar.bz2
pushd py2cairo-1.10.0
./waf configure
./waf build
sudo ./waf install
popd

export ETS_TOOLKIT=qt4
2 changes: 1 addition & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Enhancements
------------

* Added a base class for drag and drop tools, example and test support.

* PR #160: Basic testing for kiva backends.


Enable 4.4.0 (May 1, 2014)
Expand Down
4 changes: 4 additions & 0 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
coverage
PIL
pyparsing
PyPDF2
pyglet
pygarrayimage
reportlab
-e git+http://github.com/enthought/traits.git#egg=traits
-e git+http://github.com/enthought/traitsui.git#egg=traitsui
-e git+http://github.com/nucleic/kiwi.git#egg=kiwisolver
8 changes: 6 additions & 2 deletions kiva/graphics_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,12 @@ def __init__(self):
line_cap = CAP_ROUND
line_join = JOIN_MITER
line_dash = (0, array([0])) # This will draw a solid line
self.line_state = LineState(line_color, line_width, line_cap,
line_join, line_dash)

# FIXME: This is a very wierd class. The following code is here to
# make the basecore2d and the PS, SVG context managers happy
super(GraphicsState, self).__init__(
line_color, line_width, line_cap, line_join, line_dash)
self.line_state = self

# All other default values.
self.ctm = affine.affine_identity()
Expand Down
5 changes: 5 additions & 0 deletions kiva/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,11 @@ def get_text_extent(self, textstring):
# Painting paths (drawing and filling contours)
# ----------------------------------------------------------------

def clear(self):
"""
"""
warnings.warn("clear() is ignored for the pdf backend")

def stroke_path(self):
"""
"""
Expand Down
2 changes: 1 addition & 1 deletion kiva/qpainter.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ def fill_path(self):
def eof_fill_path(self):
"""
"""
self.path.setFillRule(QtCore.Qt.OddEvenFill)
self.path.path.setFillRule(QtCore.Qt.OddEvenFill)
self.gc.fillPath(self.path.path, self.gc.brush())
self.begin_path()

Expand Down
Empty file added kiva/tests/__init__.py
Empty file.
179 changes: 179 additions & 0 deletions kiva/tests/drawing_tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import contextlib
import os
import shutil
import tempfile

import numpy
from PIL import Image

from kiva.fonttools import Font
from kiva.constants import MODERN


class DrawingTester(object):
""" Basic drawing tests for graphics contexts.

"""

def setUp(self):
self.directory = tempfile.mkdtemp()
self.filename = os.path.join(self.directory, 'rendered')
self.gc = self.create_graphics_context(300, 300)
self.gc.clear()
self.gc.set_stroke_color((1.0, 0.0, 0.0))
self.gc.set_fill_color((1.0, 0.0, 0.0))
self.gc.set_line_width(5)

def tearDown(self):
del self.gc
shutil.rmtree(self.directory)

def test_line(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.move_to(107, 204)
self.gc.line_to(107, 104)
self.gc.stroke_path()

def test_rectangle(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.move_to(107, 104)
self.gc.line_to(107, 184)
self.gc.line_to(187, 184)
self.gc.line_to(187, 104)
self.gc.line_to(107, 104)
self.gc.stroke_path()

def test_rect(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.rect(0, 0, 200, 200)
self.gc.stroke_path()

def test_circle(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.arc(150, 150, 100, 0.0, 2 * numpy.pi)
self.gc.stroke_path()

def test_quarter_circle(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.arc(150, 150, 100, 0.0, numpy.pi / 2)
self.gc.stroke_path()

def test_text(self):
with self.draw_and_check():
font = Font(family=MODERN)
font.size = 24
self.gc.set_font(font)
self.gc.set_text_position(23, 67)
self.gc.show_text("hello kiva")

def test_circle_fill(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.arc(150, 150, 100, 0.0, 2 * numpy.pi)
self.gc.fill_path()

def test_star_fill(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.move_to(100, 100)
self.gc.line_to(150, 200)
self.gc.line_to(200, 100)
self.gc.line_to(100, 150)
self.gc.line_to(200, 150)
self.gc.line_to(100, 100)
self.gc.fill_path()

def test_star_eof_fill(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.move_to(100, 100)
self.gc.line_to(150, 200)
self.gc.line_to(200, 100)
self.gc.line_to(100, 150)
self.gc.line_to(200, 150)
self.gc.line_to(100, 100)
self.gc.eof_fill_path()

def test_circle_clip(self):
with self.draw_and_check():
self.gc.clip_to_rect(150, 150, 100, 100)
self.gc.begin_path()
self.gc.arc(150, 150, 100, 0.0, 2 * numpy.pi)
self.gc.fill_path()

def test_text_clip(self):
with self.draw_and_check():
self.gc.clip_to_rect(23, 77, 100, 23)
font = Font(family=MODERN)
font.size = 24
self.gc.set_font(font)
self.gc.set_text_position(23, 67)
self.gc.show_text("hello kiva")

def test_star_clip(self):
with self.draw_and_check():
self.gc.begin_path()
self.gc.move_to(100, 100)
self.gc.line_to(150, 200)
self.gc.line_to(200, 100)
self.gc.line_to(100, 150)
self.gc.line_to(200, 150)
self.gc.line_to(100, 100)
self.gc.close_path()
self.gc.clip()

self.gc.begin_path()
self.gc.arc(150, 150, 100, 0.0, 2 * numpy.pi)
self.gc.fill_path()

#### Required methods ####################################################

@contextlib.contextmanager
def draw_and_check(self):
""" A context manager to check the result.

"""
raise NotImplementedError()

def create_graphics_context(self, width, length):
""" Create the desired graphics context

"""
raise NotImplementedError()


class DrawingImageTester(DrawingTester):
""" Basic drawing tests for graphics contexts of gui toolkits.

"""

@contextlib.contextmanager
def draw_and_check(self):
yield
filename = "{0}.png".format(self.filename)
self.gc.save(filename)
self.assertImageSavedWithContent(filename)

def assertImageSavedWithContent(self, filename):
""" Load the image and check that there is some content in it.

"""
image = numpy.array(Image.open(filename))
# default is expected to be a totally white image

self.assertEqual(image.shape[:2], (300, 300))
if image.shape[2] == 3:
check = numpy.sum(image == [255, 0, 0], axis=2) == 3
elif image.shape[2] == 4:
check = numpy.sum(image == [255, 0, 0, 255], axis=2) == 4
else:
self.fail(
'Pixel size is not 3 or 4, but {0}'.format(image.shape[2]))
if check.any():
return
self.fail('The image looks empty, no red pixels where drawn')
13 changes: 13 additions & 0 deletions kiva/tests/test_agg_drawing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from kiva.tests.drawing_tester import DrawingImageTester
from kiva.image import GraphicsContext
from traits.testing.unittest_tools import unittest


class TestAggDrawing(DrawingImageTester, unittest.TestCase):

def create_graphics_context(self, width, height):
return GraphicsContext((width, height))


if __name__ == "__main__":
unittest.main()
21 changes: 21 additions & 0 deletions kiva/tests/test_cairo_drawing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from kiva.tests.drawing_tester import DrawingImageTester
from traits.testing.unittest_tools import unittest

try:
import cairo # noqa
except ImportError:
CAIRO_NOT_AVAILABLE = True
else:
CAIRO_NOT_AVAILABLE = False


@unittest.skipIf(CAIRO_NOT_AVAILABLE, "Cannot import cairo")
class TestCairoDrawing(DrawingImageTester, unittest.TestCase):

def create_graphics_context(self, width, height):
from kiva.cairo import GraphicsContext
return GraphicsContext((width, height))


if __name__ == "__main__":
unittest.main()
57 changes: 57 additions & 0 deletions kiva/tests/test_gl_drawing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import contextlib

try:
import pyglet
except ImportError:
PYGLET_NOT_AVAILABLE = True
else:
PYGLET_NOT_AVAILABLE = False


from kiva.tests.drawing_tester import DrawingImageTester
from traits.testing.unittest_tools import unittest


@unittest.skipIf(PYGLET_NOT_AVAILABLE, "Cannot import pyglet")
class TestGLDrawing(DrawingImageTester, unittest.TestCase):

def tearDown(self):
if hasattr(self, 'window') and self.window is not None:
self.window.close()
del self.window
DrawingImageTester.tearDown(self)

def create_graphics_context(self, width, height):
from kiva.gl import GraphicsContext
self.window = pyglet.window.Window(width=width, height=height)
gc = GraphicsContext((width, height))
gc.gl_init()
return gc

@unittest.skip("gl graphics context does not support star_clip (#164)")
def test_star_clip(self):
# FIXME: overriding test since it segfaults
DrawingImageTester.test_star_clip(self)

@unittest.expectedFailure
def test_text_clip(self):
# gl graphics context does not clip text properly (#165).
DrawingImageTester.test_text_clip(self)

@contextlib.contextmanager
def draw_and_check(self):
from pyglet.image.codecs.png import PNGImageEncoder

self.window.clear()
self.window.switch_to()
self.window.dispatch_events()
yield
self.window.dispatch_events()
filename = "{0}.png".format(self.filename)
buffer = pyglet.image.get_buffer_manager()
buffer.get_color_buffer().save(filename, encoder=PNGImageEncoder())
self.assertImageSavedWithContent(filename)


if __name__ == "__main__":
unittest.main()