Skip to content

Commit 34aeed7

Browse files
committed
Add convenience functions to Python test utilities for rendering with map settings
- Update labeling unit tests to use new functions - All labeling test classes render separately from QgsRenderChecker - Update labeling server test class to sync map settings to temp project
1 parent b6d8331 commit 34aeed7

6 files changed

+179
-81
lines changed

tests/src/python/test_qgspallabeling_base.py

Lines changed: 33 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
TestCase,
4747
unittest,
4848
unitTestDataPath,
49+
getTempfilePath,
50+
renderMapToImage,
4951
loadTestFonts,
5052
getTestFont,
5153
openInBrowserTab
@@ -208,7 +210,9 @@ def getBaseMapSettings(cls):
208210
ms.setBackgroundColor(QColor(152, 219, 249))
209211
ms.setOutputSize(QSize(420, 280))
210212
ms.setOutputDpi(72)
211-
ms.setFlag(QgsMapSettings.Antialiasing)
213+
ms.setFlag(QgsMapSettings.Antialiasing, True)
214+
ms.setFlag(QgsMapSettings.UseAdvancedEffects, False)
215+
ms.setFlag(QgsMapSettings.ForceVectorOutput, False) # no caching?
212216
ms.setDestinationCrs(crs)
213217
ms.setCrsTransformEnabled(False)
214218
ms.setMapUnits(crs.mapUnits()) # meters
@@ -217,7 +221,7 @@ def getBaseMapSettings(cls):
217221

218222
def cloneMapSettings(self, oms):
219223
"""
220-
:param oms: QgsMapSettings
224+
:param QgsMapSettings oms: Other QgsMapSettings
221225
:rtype: QgsMapSettings
222226
"""
223227
ms = QgsMapSettings()
@@ -292,81 +296,43 @@ def saveControlImage(self, tmpimg=''):
292296
or 'Vs' in self._TestGroup):
293297
return
294298
imgpath = self.controlImagePath()
295-
# print "saveControlImage: {0}".format(imgpath)
296299
testdir = os.path.dirname(imgpath)
297300
if not os.path.exists(testdir):
298301
os.makedirs(testdir)
299302
imgbasepath = \
300303
os.path.join(testdir,
301304
os.path.splitext(os.path.basename(imgpath))[0])
305+
# remove any existing control images
302306
for f in glob.glob(imgbasepath + '.*'):
303307
if os.path.exists(f):
304308
os.remove(f)
305-
if tmpimg and os.path.exists(tmpimg):
306-
shutil.copyfile(tmpimg, imgpath)
307-
else:
308-
print '\nsaveControlImage.render(): entered'
309-
print '{0}.{1}'.format(self._TestGroup, self._TestFunction)
309+
qDebug('Control image for {0}.{1}'.format(self._TestGroup,
310+
self._TestFunction))
310311

312+
if not tmpimg:
313+
# TODO: this can be deprecated, when per-base-test-class rendering
314+
# in checkTest() is verified OK for all classes
315+
qDebug('Rendering control to: {0}'.format(imgpath))
311316
ms = self._MapSettings # class settings
312317
""":type: QgsMapSettings"""
318+
settings_type = 'Class'
313319
if self._TestMapSettings is not None:
314320
ms = self._TestMapSettings # per test settings
315-
print 'self._MapSettings...'
316-
print 'ms.layers(): {0}'.format(
317-
[self._MapRegistry.mapLayer(i).name() for i in ms.layers()]
318-
)
319-
print 'ms.outputSize(): {0} x {1}'.format(
320-
ms.outputSize().width(), ms.outputSize().height())
321-
print 'ms.outputDpi(): {0}'.format(ms.outputDpi())
322-
print 'ms.mapUnits(): {0}'.format(ms.mapUnits())
323-
print 'ms.extent(): {0}'.format(ms.extent().toString())
324-
print 'ms.hasCrsTransformEnabled(): {0}'.format(
325-
ms.hasCrsTransformEnabled())
326-
print 'ms.destinationCrs(): {0}'.format(
327-
ms.destinationCrs().authid())
328-
329-
# pal = QgsPalLabeling()
330-
pal = self._Pal.clone() # or custom settings are lost
331-
pal.init(ms)
332-
r = QgsMapRenderer()
333-
r.setLabelingEngine(pal)
334-
335-
# this seems too redundant
336-
r.setOutputSize(ms.outputSize(), ms.outputDpi())
337-
r.setMapUnits(ms.mapUnits())
338-
r.setExtent(ms.extent())
339-
r.setProjectionsEnabled(ms.hasCrsTransformEnabled())
340-
r.setDestinationCrs(ms.destinationCrs())
341-
r.setLayerSet(ms.layers())
342-
343-
ctx = r.rendererContext()
344-
ctx.setDrawEditingInformation(
345-
ms.testFlag(QgsMapSettings.DrawEditingInfo))
346-
ctx.setForceVectorOutput(
347-
ms.testFlag(QgsMapSettings.ForceVectorOutput))
348-
ctx.setUseAdvancedEffects(
349-
ms.testFlag(QgsMapSettings.UseAdvancedEffects))
350-
351-
image = QImage(ms.outputSize(), QImage.Format_ARGB32)
352-
image.fill(ms.backgroundColor().rgb())
353-
image.setDotsPerMeterX(ms.outputDpi() / 25.4 * 1000)
354-
image.setDotsPerMeterY(ms.outputDpi() / 25.4 * 1000)
355-
356-
p = QPainter(image)
357-
r.render(p)
358-
p.end()
359-
360-
if not image.save(imgpath, 'png'):
361-
os.unlink(imgpath)
362-
363-
# delete extraneous world file (always generated)
364-
# wrld_file = imgbasepath + '.PNGw'
365-
# if os.path.exists(wrld_file):
366-
# os.remove(wrld_file)
367-
368-
if not os.path.exists(imgpath):
369-
raise OSError('Control image not created: {0}'.format(imgpath))
321+
settings_type = 'Test'
322+
qDebug('MapSettings type: {0}'.format(settings_type))
323+
324+
img = renderMapToImage(ms, parallel=False)
325+
""":type: QImage"""
326+
tmpimg = getTempfilePath('png')
327+
if not img.save(tmpimg, 'png'):
328+
os.unlink(tmpimg)
329+
raise OSError('Control not created for: {0}'.format(imgpath))
330+
331+
if tmpimg and os.path.exists(tmpimg):
332+
qDebug('Copying control to: {0}'.format(imgpath))
333+
shutil.copyfile(tmpimg, imgpath)
334+
else:
335+
raise OSError('Control not copied to: {0}'.format(imgpath))
370336

371337
def renderCheck(self, mismatch=0, colortol=0, imgpath='', grpprefix=''):
372338
"""Check rendered map canvas or existing image against control image
@@ -385,7 +351,10 @@ def renderCheck(self, mismatch=0, colortol=0, imgpath='', grpprefix=''):
385351
chk.setControlPathPrefix('expected_' + grpprefix)
386352
chk.setControlName(self._Test)
387353
chk.setColorTolerance(colortol)
388-
chk.setMapSettings(self._MapSettings)
354+
ms = self._MapSettings # class settings
355+
if self._TestMapSettings is not None:
356+
ms = self._TestMapSettings # per test settings
357+
chk.setMapSettings(ms)
389358
# noinspection PyUnusedLocal
390359
res = False
391360
if imgpath:

tests/src/python/test_qgspallabeling_canvas.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
from utilities import (
2828
unittest,
2929
expectedFailure,
30+
getTempfilePath,
31+
renderMapToImage,
32+
mapSettingsString
3033
)
3134

3235
from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
@@ -55,15 +58,47 @@ def tearDownClass(cls):
5558
def setUp(self):
5659
"""Run before each test."""
5760
super(TestCanvasBase, self).setUp()
61+
self._TestImage = ''
62+
# ensure per test map settings stay encapsulated
63+
self._TestMapSettings = self.cloneMapSettings(self._MapSettings)
5864
self._Mismatch = 0
5965
self._ColorTol = 0
6066
self._Mismatches.clear()
6167
self._ColorTols.clear()
6268

6369
def checkTest(self, **kwargs):
6470
self.lyr.writeToLayer(self.layer)
65-
self.saveControlImage()
66-
self.assertTrue(*self.renderCheck())
71+
72+
ms = self._MapSettings # class settings
73+
settings_type = 'Class'
74+
if self._TestMapSettings is not None:
75+
ms = self._TestMapSettings # per test settings
76+
settings_type = 'Test'
77+
if 'PAL_VERBOSE' in os.environ:
78+
qDebug('MapSettings type: {0}'.format(settings_type))
79+
qDebug(mapSettingsString(ms))
80+
81+
img = renderMapToImage(ms, parallel=False)
82+
self._TestImage = getTempfilePath('png')
83+
if not img.save(self._TestImage, 'png'):
84+
os.unlink(self._TestImage)
85+
raise OSError('Failed to save output from map render job')
86+
self.saveControlImage(self._TestImage)
87+
88+
mismatch = 0
89+
if 'PAL_NO_MISMATCH' not in os.environ:
90+
# some mismatch expected
91+
mismatch = self._Mismatch if self._Mismatch else 0
92+
if self._TestGroup in self._Mismatches:
93+
mismatch = self._Mismatches[self._TestGroup]
94+
colortol = 0
95+
if 'PAL_NO_COLORTOL' not in os.environ:
96+
colortol = self._ColorTol if self._ColorTol else 0
97+
if self._TestGroup in self._ColorTols:
98+
colortol = self._ColorTols[self._TestGroup]
99+
self.assertTrue(*self.renderCheck(mismatch=mismatch,
100+
colortol=colortol,
101+
imgpath=self._TestImage))
67102

68103

69104
class TestCanvasBasePoint(TestCanvasBase):

tests/src/python/test_qgspallabeling_composer.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from utilities import (
3030
getTempfilePath,
3131
getExecutablePath,
32+
mapSettingsString
3233
)
3334

3435
from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
@@ -96,9 +97,6 @@ def setUp(self):
9697

9798
def _set_up_composition(self, width, height, dpi):
9899
# set up composition and add map
99-
self._TestMapSettings.setFlag(QgsMapSettings.Antialiasing, True)
100-
self._TestMapSettings.setFlag(QgsMapSettings.UseAdvancedEffects, True)
101-
self._TestMapSettings.setFlag(QgsMapSettings.ForceVectorOutput, True)
102100
self._c = QgsComposition(self._TestMapSettings)
103101
""":type: QgsComposition"""
104102
# self._c.setUseAdvancedEffects(False)
@@ -270,6 +268,16 @@ def get_composer_output(self, kind):
270268
# noinspection PyUnusedLocal
271269
def checkTest(self, **kwargs):
272270
self.lyr.writeToLayer(self.layer)
271+
272+
ms = self._MapSettings # class settings
273+
settings_type = 'Class'
274+
if self._TestMapSettings is not None:
275+
ms = self._TestMapSettings # per test settings
276+
settings_type = 'Test'
277+
if 'PAL_VERBOSE' in os.environ:
278+
qDebug('MapSettings type: {0}'.format(settings_type))
279+
qDebug(mapSettingsString(ms))
280+
273281
res_m, self._TestImage = self.get_composer_output(self._TestKind)
274282
self.assertTrue(res_m, 'Failed to retrieve/save output from composer')
275283
self.saveControlImage(self._TestImage)

tests/src/python/test_qgspallabeling_server.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from utilities import (
3232
unittest,
3333
expectedFailure,
34+
mapSettingsString
3435
)
3536

3637
from qgis_local_server import (
@@ -117,7 +118,8 @@ def delete_cache(self):
117118
ignore_errors=True)
118119

119120
# noinspection PyPep8Naming
120-
def get_wms_params(self):
121+
def get_request_params(self):
122+
# TODO: support other types of servers, besides WMS
121123
ms = self._TestMapSettings
122124
osize = ms.outputSize()
123125
dpi = str(ms.outputDpi())
@@ -147,15 +149,36 @@ def get_wms_params(self):
147149
# print params
148150
return params
149151

152+
def sync_map_settings(self):
153+
"""
154+
Sync custom test QgsMapSettings to Project file
155+
"""
156+
pal = QgsPalLabeling()
157+
pal.loadEngineSettings()
158+
pal.init(self._TestMapSettings)
159+
pal.saveEngineSettings()
160+
150161
def checkTest(self, **kwargs):
162+
self.sync_map_settings()
151163
self.lyr.writeToLayer(self.layer)
152164
# save project file
153165
self._TestProj.write()
154166
# always restart FCGI before tests, so settings can be applied
155167
# MAPSERV.fcgi_server_process().start()
156168
# get server results
157169
# print self.params.__repr__()
158-
res_m, self._TestImage = MAPSERV.get_map(self.params, False)
170+
171+
ms = self._MapSettings # class settings
172+
settings_type = 'Class'
173+
if self._TestMapSettings is not None:
174+
ms = self._TestMapSettings # per test settings
175+
settings_type = 'Test'
176+
if 'PAL_VERBOSE' in os.environ:
177+
qDebug('MapSettings type: {0}'.format(settings_type))
178+
qDebug(mapSettingsString(ms))
179+
180+
res_m, self._TestImage = MAPSERV.get_map(
181+
self.get_request_params(), False)
159182
# print self._TestImage.__repr__()
160183
self.saveControlImage(self._TestImage)
161184
self.assertTrue(res_m, 'Failed to retrieve/save image from test server')
@@ -183,11 +206,6 @@ def setUpClass(cls):
183206
TestServerBase.setUpClass()
184207
cls.layer = TestQgsPalLabeling.loadFeatureLayer('point')
185208

186-
def setUp(self):
187-
super(TestServerBasePoint, self).setUp()
188-
# self._TestMapSettings defines the params
189-
self.params = self.get_wms_params()
190-
191209

192210
class TestServerPoint(TestServerBasePoint, TestPointBase):
193211

tests/src/python/test_qgspallabeling_tests.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def __init__(self):
3636
""":type: QgsPalLayerSettings"""
3737
# noinspection PyArgumentList
3838
self._TestFont = QFont() # will become a standard test font
39-
self.params = dict()
4039
self._Pal = None
4140
""":type: QgsPalLabeling"""
4241
self._Canvas = None

0 commit comments

Comments
 (0)