diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 70963f0a595..1538ffa6e9b 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -63,6 +63,7 @@ ADD_PYTHON_TEST(PyQgsGraduatedSymbolRenderer test_qgsgraduatedsymbolrenderer.py) ADD_PYTHON_TEST(PyQgsInterval test_qgsinterval.py) ADD_PYTHON_TEST(PyQgsJSONUtils test_qgsjsonutils.py) ADD_PYTHON_TEST(PyQgsLineSymbolLayers test_qgslinesymbollayers.py) +ADD_PYTHON_TEST(PyQgsMapCanvas test_qgsmapcanvas.py) ADD_PYTHON_TEST(PyQgsMapCanvasAnnotationItem test_qgsmapcanvasannotationitem.py) ADD_PYTHON_TEST(PyQgsMapLayerModel test_qgsmaplayermodel.py) ADD_PYTHON_TEST(PyQgsMapRenderer test_qgsmaprenderer.py) diff --git a/tests/src/python/test_qgsmapcanvas.py b/tests/src/python/test_qgsmapcanvas.py new file mode 100644 index 00000000000..a739dc69b26 --- /dev/null +++ b/tests/src/python/test_qgsmapcanvas.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +"""QGIS Unit tests for QgsMapCanvas + +.. 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 +(at your option) any later version. +""" +__author__ = 'Nyall Dawson' +__date__ = '24/1/2017' +__copyright__ = 'Copyright 2017, The QGIS Project' +# This will get replaced with a git SHA1 when you do a git archive +__revision__ = '$Format:%H$' + +import qgis # NOQA + +from qgis.core import (QgsMapSettings, + QgsCoordinateReferenceSystem, + QgsRectangle, + QgsVectorLayer, + QgsFeature, + QgsGeometry, + QgsMultiRenderChecker, + QgsApplication) +from qgis.gui import (QgsMapCanvas) + +from qgis.PyQt.QtCore import (Qt, + QDir) +import time +from qgis.testing import start_app, unittest + +app = start_app() + + +class TestQgsMapCanvas(unittest.TestCase): + + def setUp(self): + self.report = "

Python QgsMapCanvas Tests

\n" + + def tearDown(self): + report_file_path = "%s/qgistest.html" % QDir.tempPath() + with open(report_file_path, 'a') as report_file: + report_file.write(self.report) + + def testDeferredUpdate(self): + """ test that map canvas doesn't auto refresh on deferred layer update """ + canvas = QgsMapCanvas() + canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) + canvas.setFrameStyle(0) + canvas.resize(600, 400) + self.assertEqual(canvas.width(), 600) + self.assertEqual(canvas.height(), 400) + + layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", + "layer", "memory") + + canvas.setLayers([layer]) + canvas.setExtent(QgsRectangle(10, 30, 20, 35)) + canvas.show() + + # need to wait until first redraw can occur (note that we first need to wait till drawing starts!) + while not canvas.isDrawing(): + app.processEvents() + while canvas.isDrawing(): + app.processEvents() + + self.assertTrue(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas)) + + # add polygon to layer + f = QgsFeature() + f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) + self.assertTrue(layer.dataProvider().addFeatures([f])) + + # deferred update - so expect that canvas will not been refreshed + layer.triggerRepaint(True) + timeout = time.time() + 0.1 + while time.time() < timeout: + # messy, but only way to check that canvas redraw doesn't occur + self.assertFalse(canvas.isDrawing()) + # canvas should still be empty + self.assertTrue(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas)) + + # refresh canvas + canvas.refresh() + while not canvas.isDrawing(): + app.processEvents() + while canvas.isDrawing(): + app.processEvents() + + # now we expect the canvas check to fail (since they'll be a new polygon rendered over it) + self.assertFalse(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas)) + + def canvasImageCheck(self, name, reference_image, canvas): + self.report += "

Render {}

\n".format(name) + temp_dir = QDir.tempPath() + '/' + file_name = temp_dir + 'mapcanvas_' + name + ".png" + print(file_name) + canvas.saveAsImage(file_name) + checker = QgsMultiRenderChecker() + checker.setControlPathPrefix("mapcanvas") + checker.setControlName("expected_" + reference_image) + checker.setRenderedImage(file_name) + checker.setColorTolerance(2) + result = checker.runTest(name, 20) + self.report += checker.report() + print((self.report)) + return result + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/src/python/test_qgsmaprenderercache.py b/tests/src/python/test_qgsmaprenderercache.py index 2e438b88246..1b6757c5a59 100644 --- a/tests/src/python/test_qgsmaprenderercache.py +++ b/tests/src/python/test_qgsmaprenderercache.py @@ -116,6 +116,13 @@ class TestQgsMapRendererCache(unittest.TestCase): self.assertFalse(cache.hasCacheImage('xxx')) QgsProject.instance().removeMapLayer(layer.id()) + # test that cache is also cleared on deferred update + layer = QgsVectorLayer("Point?field=fldtxt:string", + "layer", "memory") + cache.setCacheImage('xxx', im, [layer]) + layer.triggerRepaint(True) + self.assertFalse(cache.hasCacheImage('xxx')) + def testRequestRepaintMultiple(self): """ test requesting repaint with multiple dependent layers """ layer1 = QgsVectorLayer("Point?field=fldtxt:string", diff --git a/tests/testdata/control_images/mapcanvas/expected_empty_canvas/expected_empty_canvas.png b/tests/testdata/control_images/mapcanvas/expected_empty_canvas/expected_empty_canvas.png new file mode 100644 index 00000000000..5bf1a4d0bad Binary files /dev/null and b/tests/testdata/control_images/mapcanvas/expected_empty_canvas/expected_empty_canvas.png differ