~ubuntu-branches/ubuntu/lucid/thuban/lucid

« back to all changes in this revision

Viewing changes to test/test_baserenderer.py

  • Committer: Bazaar Package Importer
  • Author(s): Silke Reimer
  • Date: 2004-01-28 12:47:34 UTC
  • Revision ID: james.westby@ubuntu.com-20040128124734-6xotwcqilok6ngut
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2003 by Intevation GmbH
 
2
# Authors:
 
3
# Bernhard Herzog <bh@intevation.de>
 
4
#
 
5
# This program is free software under the GPL (>=v2)
 
6
# Read the file COPYING coming with the software for details.
 
7
 
 
8
"""Test Thuban.Model.baserenderer"""
 
9
 
 
10
__version__ = "$Revision: 1.7 $"
 
11
# $Source: /thubanrepository/thuban/test/test_baserenderer.py,v $
 
12
# $Id: test_baserenderer.py,v 1.7 2003/11/10 16:57:43 bh Exp $
 
13
 
 
14
import os
 
15
import binascii
 
16
import unittest
 
17
 
 
18
from mockgeo import SimpleShapeStore
 
19
import support
 
20
support.initthuban()
 
21
 
 
22
from Thuban.Model.color import Transparent, Color
 
23
from Thuban.Model.data import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
 
24
from Thuban.Model.map import Map
 
25
from Thuban.Model.layer import BaseLayer, Layer, RasterLayer
 
26
from Thuban.Model.table import MemoryTable, \
 
27
     FIELDTYPE_DOUBLE, FIELDTYPE_INT, FIELDTYPE_STRING
 
28
from Thuban.Model.classification import ClassGroupSingleton
 
29
import Thuban.Model.resource
 
30
 
 
31
 
 
32
from Thuban.UI.baserenderer import BaseRenderer, \
 
33
     add_renderer_extension, init_renderer_extensions
 
34
 
 
35
 
 
36
class MockDC:
 
37
 
 
38
    def __init__(self, size = None):
 
39
        self.calls = []
 
40
        self.size = size
 
41
 
 
42
    def GetSizeTuple(self):
 
43
        return self.size
 
44
 
 
45
    def __getattr__(self, attr):
 
46
        def method(*args):
 
47
            self.calls.append((attr,) + args)
 
48
        return method
 
49
 
 
50
class P:
 
51
 
 
52
    """A simple point"""
 
53
 
 
54
    def __init__(self, x, y):
 
55
        self.x = x
 
56
        self.y = y
 
57
 
 
58
    def __eq__(self, other):
 
59
        return self.x == other.x and self.y == other.y
 
60
 
 
61
    def __ne__(self, other):
 
62
        return self.x != other.x and self.y != other.y
 
63
 
 
64
    def __repr__(self):
 
65
        return "P(%r, %r)" % (self.x, self.y)
 
66
 
 
67
 
 
68
class SimpleRenderer(BaseRenderer):
 
69
 
 
70
    TRANSPARENT_PEN = ("pen", Transparent)
 
71
    TRANSPARENT_BRUSH = ("brush", Transparent)
 
72
 
 
73
    def make_point(self, x, y):
 
74
        return P(x, y)
 
75
 
 
76
    def tools_for_property(self, prop):
 
77
        fill = prop.GetFill()
 
78
        brush = ("brush", fill)
 
79
 
 
80
        stroke = prop.GetLineColor()
 
81
        stroke_width = prop.GetLineWidth()
 
82
        if stroke is Transparent:
 
83
            pen = ("pen", Transparent)
 
84
        else:
 
85
            pen = ("pen", stroke, stroke_width)
 
86
 
 
87
        return pen, brush
 
88
 
 
89
    def label_font(self):
 
90
        return "label font"
 
91
 
 
92
    def draw_raster_data(self, data, format='BMP'):
 
93
        self.raster_data = data
 
94
        self.raster_format = format
 
95
 
 
96
 
 
97
class MockProjection:
 
98
 
 
99
    """Objects that look like projections but simply apply non-uniform scalings
 
100
    """
 
101
 
 
102
    def __init__(self, xscale, yscale):
 
103
        self.xscale = float(xscale)
 
104
        self.yscale = float(yscale)
 
105
 
 
106
    def Forward(self, x, y):
 
107
        return (x * self.xscale, y * self.yscale)
 
108
 
 
109
    def Inverse(self, x, y):
 
110
        return (x / self.xscale, y / self.yscale)
 
111
 
 
112
 
 
113
class TestBaseRenderer(unittest.TestCase):
 
114
 
 
115
    def setUp(self):
 
116
        """Set self.to_destroy to an empty list
 
117
 
 
118
        Test should put all objects whose Destroy should be called atunittest.main
 
119
        the end into this list so that they're destroyed in tearDown
 
120
        """
 
121
        self.to_destroy = []
 
122
 
 
123
    def tearDown(self):
 
124
        for obj in self.to_destroy:
 
125
            obj.Destroy()
 
126
 
 
127
    def test_arc_no_projection(self):
 
128
        """Test BaseRenderer with arc layer and no projections"""
 
129
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
130
                             ("value", FIELDTYPE_DOUBLE),
 
131
                             ("code", FIELDTYPE_INT)],
 
132
                            [("UNKNOWN", 0.0, 0)])
 
133
        shapes = [[[(0, 0), (10, 10)]]]
 
134
        store = SimpleShapeStore(SHAPETYPE_ARC, shapes, table)
 
135
 
 
136
        map = Map("TestBaseRenderer")
 
137
        self.to_destroy.append(map)
 
138
        layer = Layer("arc layer", store)
 
139
        map.AddLayer(layer)
 
140
 
 
141
        dc = MockDC()
 
142
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
143
 
 
144
        renderer.render_map()
 
145
 
 
146
        self.assertEquals(dc.calls,
 
147
                          [('BeginDrawing',),
 
148
                           ('SetBrush', ('brush', Transparent)),
 
149
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
150
                           ('DrawLines', [P(10, 10), P(30, -10)]),
 
151
                           ('SetFont', "label font"),
 
152
                           ('EndDrawing',)])
 
153
 
 
154
    def test_polygon_no_projection(self):
 
155
        """Test BaseRenderer with polygon layer and no projections"""
 
156
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
157
                             ("value", FIELDTYPE_DOUBLE),
 
158
                             ("code", FIELDTYPE_INT)],
 
159
                            [("UNKNOWN", 0.0, 0)])
 
160
        shapes = [[[(0, 0), (10, 10), (10, 0), (0, 0)]]]
 
161
        store = SimpleShapeStore(SHAPETYPE_POLYGON, shapes, table)
 
162
 
 
163
        map = Map("TestBaseRenderer")
 
164
        layer = Layer("polygon layer", store)
 
165
        prop = layer.GetClassification().GetDefaultGroup().GetProperties()
 
166
        prop.SetFill(Color(1, 1, 1))
 
167
 
 
168
        map.AddLayer(layer)
 
169
        self.to_destroy.append(map)
 
170
 
 
171
        dc = MockDC()
 
172
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
173
 
 
174
        renderer.render_map()
 
175
 
 
176
        self.assertEquals(dc.calls,
 
177
                          [('BeginDrawing',),
 
178
                           ('SetBrush', ('brush', Color(1, 1, 1))),
 
179
                           ('SetPen', ('pen', Transparent)),
 
180
                           ('DrawPolygon', [P(10, 10), P(30, -10), P(30, 10),
 
181
                                            P(10, 10)]),
 
182
                           ('SetBrush', ('brush', Transparent)),
 
183
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
184
                           ('DrawLines', [P(10, 10), P(30, -10), P(30, 10),
 
185
                                          P(10, 10)]),
 
186
                           ('SetFont', "label font"),
 
187
                           ('EndDrawing',)])
 
188
 
 
189
    def test_complex_polygon(self):
 
190
        """Test BaseRenderer with complex polygon and no projections"""
 
191
        # A square inside a sqare. This has to be drawn with at least a
 
192
        # draw polygon call and two draw lines calls.
 
193
        shapes = [[[(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)],
 
194
                   [(2, 2), (8, 2), (8, 8), (2, 8), (2, 2)]]]
 
195
 
 
196
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
197
                             ("value", FIELDTYPE_DOUBLE),
 
198
                             ("code", FIELDTYPE_INT)],
 
199
                            [("UNKNOWN", 0.0, 0)])
 
200
        store = SimpleShapeStore(SHAPETYPE_POLYGON, shapes, table)
 
201
 
 
202
        map = Map("TestBaseRenderer")
 
203
        layer = Layer("polygon layer", store)
 
204
        prop = layer.GetClassification().GetDefaultGroup().GetProperties()
 
205
        prop.SetFill(Color(1, 1, 1))
 
206
 
 
207
        map.AddLayer(layer)
 
208
        self.to_destroy.append(map)
 
209
 
 
210
        dc = MockDC()
 
211
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
212
 
 
213
        renderer.render_map()
 
214
 
 
215
        self.assertEquals(dc.calls,
 
216
                          [('BeginDrawing',),
 
217
                           ('SetBrush', ('brush', Color(1, 1, 1))),
 
218
                           ('SetPen', ('pen', Transparent)),
 
219
                           ('DrawPolygon',
 
220
                            [P(10, 10), P(10, -10), P(30, -10), P(30, 10),
 
221
                             P(10, 10),
 
222
                             P(14, 6), P(26, 6), P(26, -6), P(14, -6),
 
223
                             P(14, 6),
 
224
                             P(10, 10)]),
 
225
                           ('SetBrush', ('brush', Transparent)),
 
226
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
227
                           ('DrawLines', [P(10, 10), P(10, -10), P(30, -10),
 
228
                                          P(30, 10), P(10, 10)]),
 
229
                           ('DrawLines', [P(14, 6), P(26, 6), P(26, -6),
 
230
                                          P(14, -6), P(14, 6)]),
 
231
                           ('SetFont', "label font"),
 
232
                           ('EndDrawing',)])
 
233
 
 
234
    def test_point_no_projection(self):
 
235
        """Test BaseRenderer with point layer and no projections"""
 
236
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
237
                             ("value", FIELDTYPE_DOUBLE),
 
238
                             ("code", FIELDTYPE_INT)],
 
239
                            [("UNKNOWN", 0.0, 0),
 
240
                             ("UNKNOWN", 0.0, 1)])
 
241
        shapes = [[[(0, 0)]], [[(10, 10)]]]
 
242
        store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
 
243
 
 
244
        map = Map("TestBaseRenderer")
 
245
        layer = Layer("point layer", store)
 
246
        map.AddLayer(layer)
 
247
        self.to_destroy.append(map)
 
248
 
 
249
        dc = MockDC()
 
250
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
251
 
 
252
        renderer.render_map()
 
253
 
 
254
        self.assertEquals(dc.calls,
 
255
                          [('BeginDrawing',),
 
256
                           ('SetBrush', ('brush', Transparent)),
 
257
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
258
                           ('DrawEllipse', 5, 5, 10, 10),
 
259
                           ('SetBrush', ('brush', Transparent)),
 
260
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
261
                           ('DrawEllipse', 25, -15, 10, 10),
 
262
                           ('SetFont', "label font"),
 
263
                           ('EndDrawing',)])
 
264
 
 
265
    def test_raster_no_projection(self):
 
266
        """Test BaseRenderer with raster layer and no projections
 
267
 
 
268
        This test is very simple minded and perhaps can easily fail due
 
269
        to round-off errors. It simply compares the complete BMP file
 
270
        returned by gdalwarp.ProjectRasterFile to a BMP file data.
 
271
        """
 
272
        if not Thuban.Model.resource.has_gdal_support():
 
273
            raise support.SkipTest("No gdal support")
 
274
 
 
275
        map = Map("TestBaseRenderer")
 
276
 
 
277
        layer = RasterLayer("raster layer",
 
278
                            os.path.join("..", "Data", "iceland",
 
279
                                         "island.tif"))
 
280
        map.AddLayer(layer)
 
281
        self.to_destroy.append(map)
 
282
 
 
283
        dc = MockDC(size = (20, 20))
 
284
        renderer = SimpleRenderer(dc, map, 34, (800, 2250))
 
285
 
 
286
        renderer.render_map()
 
287
 
 
288
        # The following commented out code block can be used to generate
 
289
        # the base64 coded reference image data
 
290
        #hexed = binascii.b2a_base64(renderer.raster_data)
 
291
        #while hexed:
 
292
        #    print repr(hexed[:65])
 
293
        #    hexed = hexed[65:]
 
294
 
 
295
        # The reference data as a base64 coded BMP image
 
296
        raw_data = binascii.a2b_base64(
 
297
            'Qk3GBQAAAAAAADYEAAAoAAAAFAAAABQAAAABAAgAAAAAAJABAAAAAAAAAAAAAAABA'
 
298
            'AAAAAAAApYOAALGAgAGfjoAHmZyACZ2egAujo4AArICAE66GgACngIA5mZSAJqONg'
 
299
            'ACzgIAAoIyABZqZgAO4uYAAtICAAKqAgAScloAAtYCADKepgAS2t4AAooiAALaAgA'
 
300
            'CtgIAHsbOAAp2TgACogIAFtbaACqOigAidnoAAuICADKaogACfjoAAr4CAAKSFgAm'
 
301
            'fnoAAo4eABrS1gAibnoAHsbKAAp6SgACmg4AGs7SACLCxgAqioIAAoYqAAZ6RgACm'
 
302
            'goAKrK6AALmAgAC3gIAApIaABZqagACngYAAo4iAAKmAgAivsYAJoJ6AALCAgACyg'
 
303
            'IAAq4CAAKWEgAOclYALpqeAAK6AgACgjYAEm5eAAKKKgAGekIAHmp6ABpmcgAChi4'
 
304
            'ALpaaACJyegAClhYAEnJeAAZ+QgAqhoIADnZSAB5mdgACiiYAJnp6ACqGegAqrrYA'
 
305
            'GmpuAB5megACkh4ALqqyAA52VgAulpYAAoI6AAZ+PgASbmIALpKWAA7m5gAWbmYAG'
 
306
            'mpyAC6SjgAqioYADnZOAA7q6gAianoALqauABpqagAqgnoAEnJWAAp6RgAWbmIACu'
 
307
            '7uACqGfgAqiooAMqauAAby8gAmusIAMp6qAC6WngAyoqoABvb2AC6SkgAS3uIAJra'
 
308
            '+AB7KzgAynqIALq62ADKirgAC+voAGsrSABLi4gAG8vYADubqAC6qtgAuprIABvb6'
 
309
            'ACLCygAW2t4AKra+AAru8gAS4uYACuruAAry8gAG+voAAEBAAFhkZABAQEAABp6fA'
 
310
            'EBACAAAgPwAAPu/AJE9CgBACAAALj1BAEAICAAGPAAAQAgAAAY8+gBACL8AJTxXAA'
 
311
            'gIQAAAPEAAAAgIAAY8QABACAgAAGQAAABAAAAALpoAAEBAAAAALgAAAEAABkAGAEA'
 
312
            'IQAD2AEAAvwAIAJAu2ABAQEAALmQ5AEBAQAAAnp8AAEAIAAD4+gAAv78An5rDAEBA'
 
313
            'QAAuhAcAQEBAAAb8AABAvwAAAGQKAABAAABpLksAQEAIAC4ACwBAAAAAAPkGAAC/Q'
 
314
            'AD2APoAvwC/AJ0umgBAQEAAAGRkAABAQAAGnp8AQEAIAPcA/AC/AL8A7D0GAEAIQA'
 
315
            'D4hAAAv0AAAAD8QAAAvwgA92T6AL9AvwDsLlcAQEBAAC4AQABAAAgA+EAAAL8IAAA'
 
316
            '8AAAACAAAAJ8uVgBAQEAAAGQ5AABAQAAAnpcAAEBAAPYAQAC/AAgAnQsGAEAAQAAA'
 
317
            'hG0AAEBAAB38PQAIv0AA9mT6AL9AvwAJLmwAZUBAAB0AQAAIAAgAHUAAAAgIAAAAA'
 
318
            'AAAAAAAAACzbAAAQEAA//k5AH+/QAAGb5cAQEBAAACy5AAAQAgAAIpAAABACAAAAA'
 
319
            'AAAAAAAAkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk'
 
320
            'JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ'
 
321
            'CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC'
 
322
            'QkJCQkJCQkJCQkJCQkJCQkJCQkyEi8aQCEJCQkJCQkJCQkJCQkJCTI7OwgILzsyCg'
 
323
            'kJCQkJCQkJCQkJCzcJFggvADwGEDc3EhYAMgkJCQkJEjcVJDohGj0LGgYAPT0hCT0'
 
324
            'LDyI3CQoBLwAaFgkyEC9AJAE8OgsIMjoABi8kCx4JCQkJCQkeGko8KTcLCxIyNwkJ'
 
325
            'CQkWEjwWNUAQPCEAMwgJCQkJCQkSQBcvEkAPAQkyN0AMCQkJCQhBFyEvNy89JCIkM'
 
326
            'yItGQwJCQo9RxozIgkyCQoPFxAtDBkgIgkJCQkJCQkJMRoQECJQNi9EIAAgCQkJCQ'
 
327
            'kSUA88UAYeBjELICA8HiI=\n')
 
328
        self.assertEquals(renderer.raster_data, raw_data)
 
329
        self.assertEquals(renderer.raster_format, "BMP")
 
330
 
 
331
        self.assertEquals(dc.calls,
 
332
                          [('BeginDrawing',),
 
333
                           ('SetFont', "label font"),
 
334
                           ('EndDrawing',)])
 
335
 
 
336
    def test_point_map_projection(self):
 
337
        """Test BaseRenderer with point layer and map projection"""
 
338
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
339
                             ("value", FIELDTYPE_DOUBLE),
 
340
                             ("code", FIELDTYPE_INT)],
 
341
                            [("UNKNOWN", 0.0, 0)])
 
342
        shapes = [[[(10, 10)]]]
 
343
        store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
 
344
 
 
345
        map = Map("TestBaseRenderer")
 
346
        map.SetProjection(MockProjection(-3, 3))
 
347
        layer = Layer("point layer", store)
 
348
        map.AddLayer(layer)
 
349
        self.to_destroy.append(map)
 
350
 
 
351
        dc = MockDC()
 
352
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
353
 
 
354
        renderer.render_map()
 
355
 
 
356
        self.assertEquals(dc.calls,
 
357
                          [('BeginDrawing',),
 
358
                           ('SetBrush', ('brush', Transparent)),
 
359
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
360
                           ('DrawEllipse', -55, -55, 10, 10),
 
361
                           ('SetFont', "label font"),
 
362
                           ('EndDrawing',)])
 
363
 
 
364
    def test_point_layer_projection(self):
 
365
        """Test BaseRenderer with point layer and layer projection"""
 
366
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
367
                             ("value", FIELDTYPE_DOUBLE),
 
368
                             ("code", FIELDTYPE_INT)],
 
369
                            [("UNKNOWN", 0.0, 0)])
 
370
        shapes = [[[(9, 9)]]]
 
371
        store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
 
372
 
 
373
        map = Map("TestBaseRenderer")
 
374
        layer = Layer("point layer", store)
 
375
        layer.SetProjection(MockProjection(3, -3))
 
376
        map.AddLayer(layer)
 
377
        self.to_destroy.append(map)
 
378
 
 
379
        dc = MockDC()
 
380
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
381
 
 
382
        renderer.render_map()
 
383
 
 
384
        self.assertEquals(dc.calls,
 
385
                          [('BeginDrawing',),
 
386
                           ('SetBrush', ('brush', Transparent)),
 
387
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
388
                           ('DrawEllipse', 11, 11, 10, 10),
 
389
                           ('SetFont', "label font"),
 
390
                           ('EndDrawing',)])
 
391
 
 
392
    def test_point_layer_and_map_projection(self):
 
393
        """Test BaseRenderer with point layer and layer and map projection"""
 
394
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
395
                             ("value", FIELDTYPE_DOUBLE),
 
396
                             ("code", FIELDTYPE_INT)],
 
397
                            [("UNKNOWN", 0.0, 0)])
 
398
        shapes = [[[(9, 9)]]]
 
399
        store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
 
400
 
 
401
        map = Map("TestBaseRenderer")
 
402
        map.SetProjection(MockProjection(-3, 3))
 
403
        layer = Layer("point layer", store)
 
404
        layer.SetProjection(MockProjection(3, -3))
 
405
        map.AddLayer(layer)
 
406
        self.to_destroy.append(map)
 
407
 
 
408
        dc = MockDC()
 
409
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
410
 
 
411
        renderer.render_map()
 
412
 
 
413
        self.assertEquals(dc.calls,
 
414
                          [('BeginDrawing',),
 
415
                           ('SetBrush', ('brush', Transparent)),
 
416
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
417
                           ('DrawEllipse', -13, 23, 10, 10),
 
418
                           ('SetFont', "label font"),
 
419
                           ('EndDrawing',)])
 
420
 
 
421
 
 
422
    def test_point_with_classification(self):
 
423
        """Test BaseRenderer with point layer and classification"""
 
424
        table = MemoryTable([("type", FIELDTYPE_STRING),
 
425
                             ("value", FIELDTYPE_DOUBLE),
 
426
                             ("code", FIELDTYPE_INT)],
 
427
                            [("UNKNOWN", 0.0, 0),
 
428
                             ("UNKNOWN", 0.0, 1)])
 
429
        shapes = [[[(0, 0)]], [[(10, 10)]]]
 
430
        store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
 
431
 
 
432
        map = Map("TestBaseRenderer")
 
433
        layer = Layer("point layer", store)
 
434
        group = ClassGroupSingleton(1)
 
435
        group.GetProperties().SetFill(Color(0, 0, 1))
 
436
        layer.GetClassification().AppendGroup(group)
 
437
        layer.SetClassificationColumn("code")
 
438
 
 
439
        map.AddLayer(layer)
 
440
        self.to_destroy.append(map)
 
441
 
 
442
        dc = MockDC()
 
443
        renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
444
 
 
445
        renderer.render_map()
 
446
 
 
447
        self.assertEquals(dc.calls,
 
448
                          [('BeginDrawing',),
 
449
                           ('SetBrush', ('brush', Transparent)),
 
450
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
451
                           ('DrawEllipse', 5, 5, 10, 10),
 
452
                           ('SetBrush', ('brush', Color(0, 0, 1))),
 
453
                           ('SetPen', ('pen', Color(0, 0, 0), 1)),
 
454
                           ('DrawEllipse', 25, -15, 10, 10),
 
455
                           ('SetFont', "label font"),
 
456
                           ('EndDrawing',)])
 
457
 
 
458
 
 
459
    def test_renderer_extension(self):
 
460
        """Test renderer with a renderer extension"""
 
461
        class MyLayer(BaseLayer):
 
462
            pass
 
463
 
 
464
        calls = []
 
465
        def my_renderer(renderer, layer):
 
466
            calls.append((renderer, layer))
 
467
            return ()
 
468
 
 
469
        add_renderer_extension(MyLayer, my_renderer)
 
470
 
 
471
        try:
 
472
            map = Map("test_renderer_extension")
 
473
            layer = MyLayer("my layer")
 
474
            map.AddLayer(layer)
 
475
            self.to_destroy.append(map)
 
476
 
 
477
            dc = MockDC()
 
478
            renderer = SimpleRenderer(dc, map, 2, (10, 10))
 
479
            renderer.render_map()
 
480
        finally:
 
481
            init_renderer_extensions()
 
482
 
 
483
        self.assertEquals(calls, [(renderer, layer)])
 
484
 
 
485
 
 
486
if __name__ == "__main__":
 
487
    support.run_tests()