Showing with 138 additions and 49 deletions.
  1. +2 −2 src/core/qgspallabeling.cpp
  2. +14 −3 tests/src/python/test_qgspallabeling_base.py
  3. +8 −9 tests/src/python/test_qgspallabeling_canvas.py
  4. +17 −16 tests/src/python/test_qgspallabeling_composer.py
  5. +12 −19 tests/src/python/test_qgspallabeling_server.py
  6. +80 −0 tests/src/python/test_qgspallabeling_tests.py
  7. +5 −0 tests/src/python/utilities.py
  8. BIN tests/testdata/control_images/expected_pal_canvas/sp_background_rect/sp_background_rect.png
  9. BIN ...ta/control_images/expected_pal_canvas/sp_background_rect_w_offset/sp_background_rect_w_offset.png
  10. BIN tests/testdata/control_images/expected_pal_canvas/sp_background_svg/sp_background_svg.png
  11. BIN ...data/control_images/expected_pal_canvas/sp_background_svg_w_offset/sp_background_svg_w_offset.png
  12. BIN tests/testdata/control_images/expected_pal_composer/sp_background_rect/sp_background_rect.png
  13. BIN .../control_images/expected_pal_composer/sp_background_rect_w_offset/sp_background_rect_w_offset.png
  14. BIN tests/testdata/control_images/expected_pal_composer/sp_background_svg/sp_background_svg.png
  15. BIN ...ta/control_images/expected_pal_composer/sp_background_svg_w_offset/sp_background_svg_w_offset.png
  16. BIN tests/testdata/control_images/expected_pal_server/sp_background_rect/sp_background_rect.png
  17. BIN ...ta/control_images/expected_pal_server/sp_background_rect_w_offset/sp_background_rect_w_offset.png
  18. BIN tests/testdata/control_images/expected_pal_server/sp_background_svg/sp_background_svg.png
  19. BIN ...data/control_images/expected_pal_server/sp_background_svg_w_offset/sp_background_svg_w_offset.png
4 changes: 2 additions & 2 deletions src/core/qgspallabeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4591,8 +4591,8 @@ void QgsPalLabeling::drawLabelBackground( QgsRenderContext& context,
p->save();
p->translate( QPointF( component.center().x(), component.center().y() ) );
p->rotate( component.rotation() );
double xoff = tmpLyr.scaleToPixelContext( tmpLyr.shapeOffset.x(), context, tmpLyr.shapeOffsetUnits, true );
double yoff = tmpLyr.scaleToPixelContext( tmpLyr.shapeOffset.y(), context, tmpLyr.shapeOffsetUnits, true );
double xoff = tmpLyr.scaleToPixelContext( tmpLyr.shapeOffset.x(), context, tmpLyr.shapeOffsetUnits, false );
double yoff = tmpLyr.scaleToPixelContext( tmpLyr.shapeOffset.y(), context, tmpLyr.shapeOffsetUnits, false );
p->translate( QPointF( xoff, yoff ) );
p->rotate( component.rotationOffset() );

Expand Down
17 changes: 14 additions & 3 deletions tests/src/python/test_qgspallabeling_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,10 @@ def settingsDict(lyr):
return res

def saveContolImage(self, tmpimg=''):
if 'PAL_CONTROL_IMAGE' not in os.environ:
# don't save control images for RenderVsOtherOutput (Vs) tests, since
# those control images belong to a different test result
if ('PAL_CONTROL_IMAGE' not in os.environ
or 'Vs' in self._TestGroup):
return
testgrpdir = 'expected_' + self._TestGroupPrefix
testdir = os.path.join(self._TestDataDir, 'control_images',
Expand All @@ -228,6 +231,10 @@ def saveContolImage(self, tmpimg=''):
else:
self._Map.render()
self._Canvas.saveAsImage(imgpath)
# delete extraneous world file (always generated)
wrld_file = imgbasepath + '.PNGw'
if os.path.exists(wrld_file):
os.remove(wrld_file)

def renderCheck(self, mismatch=0, imgpath='', grpprefix=''):
"""Check rendered map canvas or existing image against control image
Expand Down Expand Up @@ -331,8 +338,12 @@ def runSuite(module, tests):
"""This allows for a list of test names to be selectively run.
Also, ensures unittest verbose output comes at end, after debug output"""
loader = unittest.defaultTestLoader
if 'PAL_SUITE' in os.environ and tests:
suite = loader.loadTestsFromNames(tests, module)
if 'PAL_SUITE' in os.environ:
if tests:
suite = loader.loadTestsFromNames(tests, module)
else:
raise Exception(
"\n\n####__ 'PAL_SUITE' set, but no tests specified __####\n")
else:
suite = loader.loadTestsFromModule(module)
verb = 2 if 'PAL_VERBOSE' in os.environ else 0
Expand Down
17 changes: 8 additions & 9 deletions tests/src/python/test_qgspallabeling_canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
)

from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
from test_qgspallabeling_tests import TestPointBase
from test_qgspallabeling_tests import (
TestPointBase,
suiteTests
)


class TestCanvasPoint(TestQgsPalLabeling, TestPointBase):
Expand Down Expand Up @@ -61,13 +64,9 @@ def checkTest(self, **kwargs):

if __name__ == '__main__':
# NOTE: unless PAL_SUITE env var is set all test class methods will be run
# ex: 'TestGroup(Point|Line|Curved|Polygon|Feature).test_method'
suite = [
'TestCanvasPoint.test_default_label',
'TestCanvasPoint.test_text_size_map_unit',
'TestCanvasPoint.test_text_color',
'TestCanvasPoint.test_partials_labels_enabled',
'TestCanvasPoint.test_partials_labels_disabled',
]
# SEE: test_qgspallabeling_tests.suiteTests() to define suite
suite = (
['TestCanvasPoint.' + t for t in suiteTests()['sp_suite']]
)
res = runSuite(sys.modules[__name__], suite)
sys.exit(not res.wasSuccessful())
33 changes: 17 additions & 16 deletions tests/src/python/test_qgspallabeling_composer.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
)

from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
from test_qgspallabeling_tests import TestPointBase
from test_qgspallabeling_tests import (
TestPointBase,
suiteTests
)


# noinspection PyShadowingNames
Expand Down Expand Up @@ -140,24 +143,22 @@ class TestComposerVsCanvasPoint(TestComposerPoint):
def setUpClass(cls):
TestComposerPoint.setUpClass()
cls._CheckGroup = 'pal_canvas'
cls._CheckMismatch = 2700 # rounding errors on composer output?
# rounding errors in composer; antialiasing?
cls._CheckMismatch = 2700
# cls._CheckMismatch = 0 # uncomment to PAL_REPORT actual difference

def setUp(self):
super(TestComposerVsCanvasPoint, self).setUp()
if 'test_background_svg' in self.id():
self._CheckMismatch = 3600


if __name__ == '__main__':
# NOTE: unless PAL_SUITE env var is set all test class methods will be run
# ex: 'TestGroup(Point|Line|Curved|Polygon|Feature).test_method'
suite = [
'TestComposerPoint.test_default_label',
'TestComposerPoint.test_text_size_map_unit',
'TestComposerPoint.test_text_color',
'TestComposerPoint.test_partials_labels_enabled',
'TestComposerPoint.test_partials_labels_disabled',

'TestComposerVsCanvasPoint.test_default_label',
'TestComposerVsCanvasPoint.test_text_size_map_unit',
'TestComposerVsCanvasPoint.test_text_color',
'TestComposerVsCanvasPoint.test_partials_labels_enabled',
'TestComposerVsCanvasPoint.test_partials_labels_disabled',
]
# SEE: test_qgspallabeling_tests.suiteTests() to define suite
suite = (
['TestComposerPoint.' + t for t in suiteTests()['sp_suite']] +
['TestComposerVsCanvasPoint.' + t for t in suiteTests()['sp_vs_suite']]
)
res = runSuite(sys.modules[__name__], suite)
sys.exit(not res.wasSuccessful())
31 changes: 12 additions & 19 deletions tests/src/python/test_qgspallabeling_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
PAL_CONTROL_IMAGE to trigger building of new control images
PAL_REPORT to open any failed image check reports in web browser
PAL_SERVER_TEMP to open the web server temp directory, instead of deleting
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
Expand Down Expand Up @@ -44,7 +46,10 @@
)

from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
from test_qgspallabeling_tests import TestPointBase
from test_qgspallabeling_tests import (
TestPointBase,
suiteTests
)

MAPSERV = getLocalServer()

Expand Down Expand Up @@ -83,9 +88,8 @@ def tearDownClass(cls):
TestQgsPalLabeling.tearDownClass()
# layers removed, save empty project file
cls._TestProj.write()
if "PAL_REPORT" in os.environ:
if "PAL_SERVER_TEMP" in os.environ:
MAPSERV.stop_processes()
# MAPSERV.fcgi_server_process().stop()
MAPSERV.open_temp_dir()
else:
MAPSERV.shutdown()
Expand Down Expand Up @@ -173,21 +177,10 @@ def setUpClass(cls):

if __name__ == '__main__':
# NOTE: unless PAL_SUITE env var is set all test class methods will be run
# ex: 'TestGroup(Point|Line|Curved|Polygon|Feature).test_method'
suite = [
'TestServerPoint.test_default_label',
'TestServerPoint.test_text_size_map_unit',
'TestServerPoint.test_text_color',
'TestServerPoint.test_partials_labels_enabled',
'TestServerPoint.test_partials_labels_disabled',

'TestServerVsCanvasPoint.test_default_label',
'TestServerVsCanvasPoint.test_text_size_map_unit',
'TestServerVsCanvasPoint.test_text_color',
'TestServerVsCanvasPoint.test_partials_labels_enabled',
'TestServerVsCanvasPoint.test_partials_labels_disabled',
]
# SEE: test_qgspallabeling_tests.suiteTests() to define suite
suite = (
['TestServerPoint.' + t for t in suiteTests()['sp_suite']] +
['TestServerVsCanvasPoint.' + t for t in suiteTests()['sp_vs_suite']]
)
res = runSuite(sys.modules[__name__], suite)
# if SPAWN:
# os.remove(TESTPROJDIR) # remove temp directory (why does this error?)
sys.exit(not res.wasSuccessful())
80 changes: 80 additions & 0 deletions tests/src/python/test_qgspallabeling_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

from qgis.core import *

from utilities import (
svgSymbolsPath
)

# noinspection PyPep8Naming
class TestPointBase(object):
Expand Down Expand Up @@ -58,6 +61,64 @@ def test_text_color(self):
self.lyr.textColor = Qt.blue
self.checkTest()

def test_background_rect(self):
self.lyr.shapeDraw = True
self.checkTest()

def test_background_rect_w_offset(self):
# Label rectangular background
# verify fix for issues
# http://hub.qgis.org/issues/9057
# http://gis.stackexchange.com/questions/86900
self.lyr.fontSizeInMapUnits = True
font = QFont(self._TestFont)
font.setPointSizeF(460)
self.lyr.textFont = font

self.lyr.shapeDraw = True
self.lyr.shapeOffsetUnits = QgsPalLayerSettings.MapUnits
self.lyr.shapeOffset = QPointF(-2900.0, -450.0 )
self.checkTest()

def test_background_svg(self):
# Label SVG background
# NOTE: this has higher _CheckMismatch (3600) in ComposerVsCanvasPoint
self.lyr.fontSizeInMapUnits = True
font = QFont(self._TestFont)
font.setPointSizeF(460)
self.lyr.textFont = font

self.lyr.shapeDraw = True
self.lyr.shapeType = QgsPalLayerSettings.ShapeSVG
svg = os.path.join(
svgSymbolsPath(), 'backgrounds', 'background_square.svg')
self.lyr.shapeSVGFile = svg
self.lyr.shapeSizeUnits = QgsPalLayerSettings.MapUnits
self.lyr.shapeSizeType = QgsPalLayerSettings.SizeBuffer
self.lyr.shapeSize = QPointF(100.0, 0.0)
self.checkTest()

def test_background_svg_w_offset(self):
# Label SVG background
# NOTE: this has higher _CheckMismatch (3600) in ComposerVsCanvasPoint
self.lyr.fontSizeInMapUnits = True
font = QFont(self._TestFont)
font.setPointSizeF(460)
self.lyr.textFont = font

self.lyr.shapeDraw = True
self.lyr.shapeType = QgsPalLayerSettings.ShapeSVG
svg = os.path.join(
svgSymbolsPath(), 'backgrounds', 'background_square.svg')
self.lyr.shapeSVGFile = svg
self.lyr.shapeSizeUnits = QgsPalLayerSettings.MapUnits
self.lyr.shapeSizeType = QgsPalLayerSettings.SizeBuffer
self.lyr.shapeSize = QPointF(100.0, 0.0)

self.lyr.shapeOffsetUnits = QgsPalLayerSettings.MapUnits
self.lyr.shapeOffset = QPointF(-2850.0, 500.0 )
self.checkTest()

def test_partials_labels_enabled(self):
# Set Big font size
font = QFont(self._TestFont)
Expand All @@ -81,5 +142,24 @@ def test_partials_labels_disabled(self):
self.checkTest()


# noinspection PyPep8Naming
def suiteTests():
"""
Use to define which tests are run when PAL_SUITE is set.
Use sp_vs_suite comparison of server and composer outputs to canvas
"""
return {
'sp_suite': [
# 'test_background_svg',
'test_background_svg_w_offset',
],
'sp_vs_suite': [
# 'test_background_svg',
'test_background_svg_w_offset',
# 'test_background_rect_w_offset',
]
}


if __name__ == '__main__':
pass
5 changes: 5 additions & 0 deletions tests/src/python/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ def unitTestDataPath(theSubdir=None):
return myPath


def svgSymbolsPath():
return os.path.abspath(
os.path.join(unitTestDataPath(), '..', '..', 'images', 'svg'))


def setCanvasCrs(theEpsgId, theOtfpFlag=False):
"""Helper to set the crs for the CANVAS before a test is run.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.