Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dakcarto committed Jun 13, 2014
1 parent b6d8331 commit 34aeed7
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 81 deletions.
97 changes: 33 additions & 64 deletions tests/src/python/test_qgspallabeling_base.py
Expand Up @@ -46,6 +46,8 @@
TestCase,
unittest,
unitTestDataPath,
getTempfilePath,
renderMapToImage,
loadTestFonts,
getTestFont,
openInBrowserTab
Expand Down Expand Up @@ -208,7 +210,9 @@ def getBaseMapSettings(cls):
ms.setBackgroundColor(QColor(152, 219, 249))
ms.setOutputSize(QSize(420, 280))
ms.setOutputDpi(72)
ms.setFlag(QgsMapSettings.Antialiasing)
ms.setFlag(QgsMapSettings.Antialiasing, True)
ms.setFlag(QgsMapSettings.UseAdvancedEffects, False)
ms.setFlag(QgsMapSettings.ForceVectorOutput, False) # no caching?
ms.setDestinationCrs(crs)
ms.setCrsTransformEnabled(False)
ms.setMapUnits(crs.mapUnits()) # meters
Expand All @@ -217,7 +221,7 @@ def getBaseMapSettings(cls):

def cloneMapSettings(self, oms):
"""
:param oms: QgsMapSettings
:param QgsMapSettings oms: Other QgsMapSettings
:rtype: QgsMapSettings
"""
ms = QgsMapSettings()
Expand Down Expand Up @@ -292,81 +296,43 @@ def saveControlImage(self, tmpimg=''):
or 'Vs' in self._TestGroup):
return
imgpath = self.controlImagePath()
# print "saveControlImage: {0}".format(imgpath)
testdir = os.path.dirname(imgpath)
if not os.path.exists(testdir):
os.makedirs(testdir)
imgbasepath = \
os.path.join(testdir,
os.path.splitext(os.path.basename(imgpath))[0])
# remove any existing control images
for f in glob.glob(imgbasepath + '.*'):
if os.path.exists(f):
os.remove(f)
if tmpimg and os.path.exists(tmpimg):
shutil.copyfile(tmpimg, imgpath)
else:
print '\nsaveControlImage.render(): entered'
print '{0}.{1}'.format(self._TestGroup, self._TestFunction)
qDebug('Control image for {0}.{1}'.format(self._TestGroup,
self._TestFunction))

if not tmpimg:
# TODO: this can be deprecated, when per-base-test-class rendering
# in checkTest() is verified OK for all classes
qDebug('Rendering control to: {0}'.format(imgpath))
ms = self._MapSettings # class settings
""":type: QgsMapSettings"""
settings_type = 'Class'
if self._TestMapSettings is not None:
ms = self._TestMapSettings # per test settings
print 'self._MapSettings...'
print 'ms.layers(): {0}'.format(
[self._MapRegistry.mapLayer(i).name() for i in ms.layers()]
)
print 'ms.outputSize(): {0} x {1}'.format(
ms.outputSize().width(), ms.outputSize().height())
print 'ms.outputDpi(): {0}'.format(ms.outputDpi())
print 'ms.mapUnits(): {0}'.format(ms.mapUnits())
print 'ms.extent(): {0}'.format(ms.extent().toString())
print 'ms.hasCrsTransformEnabled(): {0}'.format(
ms.hasCrsTransformEnabled())
print 'ms.destinationCrs(): {0}'.format(
ms.destinationCrs().authid())

# pal = QgsPalLabeling()
pal = self._Pal.clone() # or custom settings are lost
pal.init(ms)
r = QgsMapRenderer()
r.setLabelingEngine(pal)

# this seems too redundant
r.setOutputSize(ms.outputSize(), ms.outputDpi())
r.setMapUnits(ms.mapUnits())
r.setExtent(ms.extent())
r.setProjectionsEnabled(ms.hasCrsTransformEnabled())
r.setDestinationCrs(ms.destinationCrs())
r.setLayerSet(ms.layers())

ctx = r.rendererContext()
ctx.setDrawEditingInformation(
ms.testFlag(QgsMapSettings.DrawEditingInfo))
ctx.setForceVectorOutput(
ms.testFlag(QgsMapSettings.ForceVectorOutput))
ctx.setUseAdvancedEffects(
ms.testFlag(QgsMapSettings.UseAdvancedEffects))

image = QImage(ms.outputSize(), QImage.Format_ARGB32)
image.fill(ms.backgroundColor().rgb())
image.setDotsPerMeterX(ms.outputDpi() / 25.4 * 1000)
image.setDotsPerMeterY(ms.outputDpi() / 25.4 * 1000)

p = QPainter(image)
r.render(p)
p.end()

if not image.save(imgpath, 'png'):
os.unlink(imgpath)

# delete extraneous world file (always generated)
# wrld_file = imgbasepath + '.PNGw'
# if os.path.exists(wrld_file):
# os.remove(wrld_file)

if not os.path.exists(imgpath):
raise OSError('Control image not created: {0}'.format(imgpath))
settings_type = 'Test'
qDebug('MapSettings type: {0}'.format(settings_type))

img = renderMapToImage(ms, parallel=False)
""":type: QImage"""
tmpimg = getTempfilePath('png')
if not img.save(tmpimg, 'png'):
os.unlink(tmpimg)
raise OSError('Control not created for: {0}'.format(imgpath))

if tmpimg and os.path.exists(tmpimg):
qDebug('Copying control to: {0}'.format(imgpath))
shutil.copyfile(tmpimg, imgpath)
else:
raise OSError('Control not copied to: {0}'.format(imgpath))

def renderCheck(self, mismatch=0, colortol=0, imgpath='', grpprefix=''):
"""Check rendered map canvas or existing image against control image
Expand All @@ -385,7 +351,10 @@ def renderCheck(self, mismatch=0, colortol=0, imgpath='', grpprefix=''):
chk.setControlPathPrefix('expected_' + grpprefix)
chk.setControlName(self._Test)
chk.setColorTolerance(colortol)
chk.setMapSettings(self._MapSettings)
ms = self._MapSettings # class settings
if self._TestMapSettings is not None:
ms = self._TestMapSettings # per test settings
chk.setMapSettings(ms)
# noinspection PyUnusedLocal
res = False
if imgpath:
Expand Down
39 changes: 37 additions & 2 deletions tests/src/python/test_qgspallabeling_canvas.py
Expand Up @@ -27,6 +27,9 @@
from utilities import (
unittest,
expectedFailure,
getTempfilePath,
renderMapToImage,
mapSettingsString
)

from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
Expand Down Expand Up @@ -55,15 +58,47 @@ def tearDownClass(cls):
def setUp(self):
"""Run before each test."""
super(TestCanvasBase, self).setUp()
self._TestImage = ''
# ensure per test map settings stay encapsulated
self._TestMapSettings = self.cloneMapSettings(self._MapSettings)
self._Mismatch = 0
self._ColorTol = 0
self._Mismatches.clear()
self._ColorTols.clear()

def checkTest(self, **kwargs):
self.lyr.writeToLayer(self.layer)
self.saveControlImage()
self.assertTrue(*self.renderCheck())

ms = self._MapSettings # class settings
settings_type = 'Class'
if self._TestMapSettings is not None:
ms = self._TestMapSettings # per test settings
settings_type = 'Test'
if 'PAL_VERBOSE' in os.environ:
qDebug('MapSettings type: {0}'.format(settings_type))
qDebug(mapSettingsString(ms))

img = renderMapToImage(ms, parallel=False)
self._TestImage = getTempfilePath('png')
if not img.save(self._TestImage, 'png'):
os.unlink(self._TestImage)
raise OSError('Failed to save output from map render job')
self.saveControlImage(self._TestImage)

mismatch = 0
if 'PAL_NO_MISMATCH' not in os.environ:
# some mismatch expected
mismatch = self._Mismatch if self._Mismatch else 0
if self._TestGroup in self._Mismatches:
mismatch = self._Mismatches[self._TestGroup]
colortol = 0
if 'PAL_NO_COLORTOL' not in os.environ:
colortol = self._ColorTol if self._ColorTol else 0
if self._TestGroup in self._ColorTols:
colortol = self._ColorTols[self._TestGroup]
self.assertTrue(*self.renderCheck(mismatch=mismatch,
colortol=colortol,
imgpath=self._TestImage))


class TestCanvasBasePoint(TestCanvasBase):
Expand Down
14 changes: 11 additions & 3 deletions tests/src/python/test_qgspallabeling_composer.py
Expand Up @@ -29,6 +29,7 @@
from utilities import (
getTempfilePath,
getExecutablePath,
mapSettingsString
)

from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
Expand Down Expand Up @@ -96,9 +97,6 @@ def setUp(self):

def _set_up_composition(self, width, height, dpi):
# set up composition and add map
self._TestMapSettings.setFlag(QgsMapSettings.Antialiasing, True)
self._TestMapSettings.setFlag(QgsMapSettings.UseAdvancedEffects, True)
self._TestMapSettings.setFlag(QgsMapSettings.ForceVectorOutput, True)
self._c = QgsComposition(self._TestMapSettings)
""":type: QgsComposition"""
# self._c.setUseAdvancedEffects(False)
Expand Down Expand Up @@ -270,6 +268,16 @@ def get_composer_output(self, kind):
# noinspection PyUnusedLocal
def checkTest(self, **kwargs):
self.lyr.writeToLayer(self.layer)

ms = self._MapSettings # class settings
settings_type = 'Class'
if self._TestMapSettings is not None:
ms = self._TestMapSettings # per test settings
settings_type = 'Test'
if 'PAL_VERBOSE' in os.environ:
qDebug('MapSettings type: {0}'.format(settings_type))
qDebug(mapSettingsString(ms))

res_m, self._TestImage = self.get_composer_output(self._TestKind)
self.assertTrue(res_m, 'Failed to retrieve/save output from composer')
self.saveControlImage(self._TestImage)
Expand Down
32 changes: 25 additions & 7 deletions tests/src/python/test_qgspallabeling_server.py
Expand Up @@ -31,6 +31,7 @@
from utilities import (
unittest,
expectedFailure,
mapSettingsString
)

from qgis_local_server import (
Expand Down Expand Up @@ -117,7 +118,8 @@ def delete_cache(self):
ignore_errors=True)

# noinspection PyPep8Naming
def get_wms_params(self):
def get_request_params(self):
# TODO: support other types of servers, besides WMS
ms = self._TestMapSettings
osize = ms.outputSize()
dpi = str(ms.outputDpi())
Expand Down Expand Up @@ -147,15 +149,36 @@ def get_wms_params(self):
# print params
return params

def sync_map_settings(self):
"""
Sync custom test QgsMapSettings to Project file
"""
pal = QgsPalLabeling()
pal.loadEngineSettings()
pal.init(self._TestMapSettings)
pal.saveEngineSettings()

def checkTest(self, **kwargs):
self.sync_map_settings()
self.lyr.writeToLayer(self.layer)
# save project file
self._TestProj.write()
# always restart FCGI before tests, so settings can be applied
# MAPSERV.fcgi_server_process().start()
# get server results
# print self.params.__repr__()
res_m, self._TestImage = MAPSERV.get_map(self.params, False)

ms = self._MapSettings # class settings
settings_type = 'Class'
if self._TestMapSettings is not None:
ms = self._TestMapSettings # per test settings
settings_type = 'Test'
if 'PAL_VERBOSE' in os.environ:
qDebug('MapSettings type: {0}'.format(settings_type))
qDebug(mapSettingsString(ms))

res_m, self._TestImage = MAPSERV.get_map(
self.get_request_params(), False)
# print self._TestImage.__repr__()
self.saveControlImage(self._TestImage)
self.assertTrue(res_m, 'Failed to retrieve/save image from test server')
Expand Down Expand Up @@ -183,11 +206,6 @@ def setUpClass(cls):
TestServerBase.setUpClass()
cls.layer = TestQgsPalLabeling.loadFeatureLayer('point')

def setUp(self):
super(TestServerBasePoint, self).setUp()
# self._TestMapSettings defines the params
self.params = self.get_wms_params()


class TestServerPoint(TestServerBasePoint, TestPointBase):

Expand Down
1 change: 0 additions & 1 deletion tests/src/python/test_qgspallabeling_tests.py
Expand Up @@ -36,7 +36,6 @@ def __init__(self):
""":type: QgsPalLayerSettings"""
# noinspection PyArgumentList
self._TestFont = QFont() # will become a standard test font
self.params = dict()
self._Pal = None
""":type: QgsPalLabeling"""
self._Canvas = None
Expand Down

0 comments on commit 34aeed7

Please sign in to comment.