diff options
Diffstat (limited to 'tests/test_cairo.py')
-rw-r--r-- | tests/test_cairo.py | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/tests/test_cairo.py b/tests/test_cairo.py new file mode 100644 index 0000000..d73037e --- /dev/null +++ b/tests/test_cairo.py @@ -0,0 +1,308 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# vim: tabstop=4 shiftwidth=4 expandtab + +import unittest +import pytest + +import gi + +try: + gi.require_foreign('cairo') + import cairo + has_cairo = True +except ImportError: + has_cairo = False + +has_region = has_cairo and hasattr(cairo, "Region") + +try: + from gi.repository import Gtk, Gdk + Gtk, Gdk # pyflakes +except: + Gtk = None + Gdk = None + +from gi.repository import GObject, Regress + + +@unittest.skipUnless(has_cairo, 'built without cairo support') +class Test(unittest.TestCase): + + def test_gvalue_converters(self): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + context = cairo.Context(surface) + matrix = cairo.Matrix() + objects = { + 'CairoContext': context, + 'CairoSurface': surface, + 'CairoFontFace': context.get_font_face(), + 'CairoScaledFont': context.get_scaled_font(), + 'CairoPattern': context.get_source(), + 'CairoMatrix': matrix, + } + for type_name, cairo_obj in objects.items(): + gtype = GObject.type_from_name(type_name) + v = GObject.Value() + assert v.init(gtype) is None + assert v.get_value() is None + v.set_value(None) + assert v.get_value() is None + v.set_value(cairo_obj) + assert v.get_value() == cairo_obj + + def test_cairo_context(self): + context = Regress.test_cairo_context_full_return() + self.assertTrue(isinstance(context, cairo.Context)) + + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + context = cairo.Context(surface) + Regress.test_cairo_context_none_in(context) + + def test_cairo_context_full_in(self): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + context = cairo.Context(surface) + Regress.test_cairo_context_full_in(context) + + with pytest.raises(TypeError): + Regress.test_cairo_context_full_in(object()) + + def test_cairo_context_none_return(self): + context = Regress.test_cairo_context_none_return() + self.assertTrue(isinstance(context, cairo.Context)) + + def test_cairo_path_full_return(self): + path = Regress.test_cairo_path_full_return() + if hasattr(cairo, "Path"): # pycairo 1.15.1+ + assert isinstance(path, cairo.Path) + + def test_cairo_path_none_in(self): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + context = cairo.Context(surface) + path = context.copy_path() + Regress.test_cairo_path_none_in(path) + surface.finish() + + with pytest.raises(TypeError): + Regress.test_cairo_path_none_in(object()) + + def test_cairo_path_full_in_full_return(self): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + context = cairo.Context(surface) + context.move_to(10, 10) + context.curve_to(10, 10, 3, 4, 5, 6) + path = context.copy_path() + new_path = Regress.test_cairo_path_full_in_full_return(path) + assert list(path) == list(new_path) + surface.finish() + + def test_cairo_font_options_full_return(self): + options = Regress.test_cairo_font_options_full_return() + assert isinstance(options, cairo.FontOptions) + + def test_cairo_font_options_none_return(self): + options = Regress.test_cairo_font_options_none_return() + assert isinstance(options, cairo.FontOptions) + + def test_cairo_font_options_full_in(self): + options = cairo.FontOptions() + Regress.test_cairo_font_options_full_in(options) + + with pytest.raises(TypeError): + Regress.test_cairo_font_options_full_in(object()) + + def test_cairo_font_options_none_in(self): + options = cairo.FontOptions() + Regress.test_cairo_font_options_none_in(options) + + def test_cairo_pattern_full_in(self): + pattern = cairo.SolidPattern(1, 1, 1, 1) + Regress.test_cairo_pattern_full_in(pattern) + + with pytest.raises(TypeError): + Regress.test_cairo_pattern_full_in(object()) + + def test_cairo_pattern_none_in(self): + pattern = cairo.SolidPattern(1, 1, 1, 1) + Regress.test_cairo_pattern_none_in(pattern) + + def test_cairo_pattern_full_return(self): + pattern = Regress.test_cairo_pattern_full_return() + self.assertTrue(isinstance(pattern, cairo.Pattern)) + self.assertTrue(isinstance(pattern, cairo.SolidPattern)) + + def test_cairo_pattern_none_return(self): + pattern = Regress.test_cairo_pattern_none_return() + self.assertTrue(isinstance(pattern, cairo.Pattern)) + self.assertTrue(isinstance(pattern, cairo.SolidPattern)) + + def test_cairo_region_full_in(self): + region = cairo.Region() + Regress.test_cairo_region_full_in(region) + + with pytest.raises(TypeError): + Regress.test_cairo_region_full_in(object()) + + def test_cairo_matrix_none_in(self): + matrix = cairo.Matrix() + Regress.test_cairo_matrix_none_in(matrix) + + with pytest.raises(TypeError): + Regress.test_cairo_matrix_none_in(object()) + + def test_cairo_matrix_none_return(self): + matrix = Regress.test_cairo_matrix_none_return() + assert matrix == cairo.Matrix() + + def test_cairo_matrix_out_caller_allocates(self): + matrix = Regress.test_cairo_matrix_out_caller_allocates() + assert matrix == cairo.Matrix() + + def test_cairo_surface(self): + surface = Regress.test_cairo_surface_none_return() + self.assertTrue(isinstance(surface, cairo.ImageSurface)) + self.assertTrue(isinstance(surface, cairo.Surface)) + self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32) + self.assertEqual(surface.get_width(), 10) + self.assertEqual(surface.get_height(), 10) + + surface = Regress.test_cairo_surface_full_return() + self.assertTrue(isinstance(surface, cairo.ImageSurface)) + self.assertTrue(isinstance(surface, cairo.Surface)) + self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32) + self.assertEqual(surface.get_width(), 10) + self.assertEqual(surface.get_height(), 10) + + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + Regress.test_cairo_surface_none_in(surface) + + surface = Regress.test_cairo_surface_full_out() + self.assertTrue(isinstance(surface, cairo.ImageSurface)) + self.assertTrue(isinstance(surface, cairo.Surface)) + self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32) + self.assertEqual(surface.get_width(), 10) + self.assertEqual(surface.get_height(), 10) + + def test_cairo_surface_full_in(self): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + Regress.test_cairo_surface_full_in(surface) + + with pytest.raises(TypeError): + Regress.test_cairo_surface_full_in(object()) + + def test_require_foreign(self): + self.assertEqual(gi.require_foreign('cairo'), None) + self.assertEqual(gi.require_foreign('cairo', 'Context'), None) + self.assertRaises(ImportError, gi.require_foreign, 'invalid_module') + self.assertRaises(ImportError, gi.require_foreign, 'invalid_module', 'invalid_symbol') + self.assertRaises(ImportError, gi.require_foreign, 'cairo', 'invalid_symbol') + + +@unittest.skipUnless(has_cairo, 'built without cairo support') +@unittest.skipUnless(has_region, 'built without cairo.Region support') +@unittest.skipUnless(Gdk, 'Gdk not available') +class TestRegion(unittest.TestCase): + + def test_region_to_py(self): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + context = cairo.Context(surface) + context.paint() + region = Gdk.cairo_region_create_from_surface(surface) + r = region.get_extents() + self.assertEqual((r.height, r.width), (10, 10)) + + def test_region_from_py(self): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + context = cairo.Context(surface) + region = cairo.Region(cairo.RectangleInt(0, 0, 42, 42)) + Gdk.cairo_region(context, region) + self.assertTrue("42" in repr(list(context.copy_path()))) + + +@unittest.skipUnless(has_cairo, 'built without cairo support') +@unittest.skipUnless(Gtk, 'Gtk not available') +class TestPango(unittest.TestCase): + + def test_cairo_font_options(self): + window = Gtk.Window() + if Gtk._version == "4.0": + window.set_font_options(cairo.FontOptions()) + font_opts = window.get_font_options() + else: + screen = window.get_screen() + font_opts = screen.get_font_options() + assert font_opts is not None + self.assertTrue(isinstance(font_opts.get_subpixel_order(), int)) + + +if has_cairo: + from gi.repository import cairo as CairoGObject + + # Use PyGI signals to test non-introspected foreign marshaling. + class CairoSignalTester(GObject.Object): + sig_context = GObject.Signal(arg_types=[CairoGObject.Context]) + sig_surface = GObject.Signal(arg_types=[CairoGObject.Surface]) + sig_font_face = GObject.Signal(arg_types=[CairoGObject.FontFace]) + sig_scaled_font = GObject.Signal(arg_types=[CairoGObject.ScaledFont]) + sig_pattern = GObject.Signal(arg_types=[CairoGObject.Pattern]) + + +@unittest.skipUnless(has_cairo, 'built without cairo support') +class TestSignalMarshaling(unittest.TestCase): + # Tests round tripping of cairo objects through non-introspected signals. + + def setUp(self): + self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + self.context = cairo.Context(self.surface) + self.tester = CairoSignalTester() + + def pass_object_through_signal(self, obj, signal): + """Pass the given `obj` through the `signal` emission storing the + `obj` passed through the signal and returning it.""" + passthrough_result = [] + + def callback(instance, passthrough): + passthrough_result.append(passthrough) + + signal.connect(callback) + signal.emit(obj) + + return passthrough_result[0] + + def test_context(self): + result = self.pass_object_through_signal(self.context, self.tester.sig_context) + self.assertTrue(isinstance(result, cairo.Context)) + + with pytest.raises(TypeError): + self.pass_object_through_signal(object(), self.tester.sig_context) + + def test_surface(self): + result = self.pass_object_through_signal(self.surface, self.tester.sig_surface) + self.assertTrue(isinstance(result, cairo.Surface)) + + def test_font_face(self): + font_face = self.context.get_font_face() + result = self.pass_object_through_signal(font_face, self.tester.sig_font_face) + self.assertTrue(isinstance(result, cairo.FontFace)) + + with pytest.raises(TypeError): + self.pass_object_through_signal(object(), self.tester.sig_font_face) + + def test_scaled_font(self): + scaled_font = cairo.ScaledFont(self.context.get_font_face(), + cairo.Matrix(), + cairo.Matrix(), + self.context.get_font_options()) + result = self.pass_object_through_signal(scaled_font, self.tester.sig_scaled_font) + self.assertTrue(isinstance(result, cairo.ScaledFont)) + + with pytest.raises(TypeError): + result = self.pass_object_through_signal(object(), self.tester.sig_scaled_font) + + def test_pattern(self): + pattern = cairo.SolidPattern(1, 1, 1, 1) + result = self.pass_object_through_signal(pattern, self.tester.sig_pattern) + self.assertTrue(isinstance(result, cairo.Pattern)) + self.assertTrue(isinstance(result, cairo.SolidPattern)) + + with pytest.raises(TypeError): + result = self.pass_object_through_signal(object(), self.tester.sig_pattern) |