Exemplo n.º 1
0
    def testClipPath(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(50.0, 30.0))
        p.append(QPointF(100.0, 10.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        # must be a closed polygon, in scene coordinates!
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 200 100, 50 30))')
        self.assertTrue(
            int(shape.itemFlags() & QgsLayoutItem.FlagProvidesClipPath))

        spy = QSignalSpy(shape.clipPathChanged)
        self.assertTrue(shape.addNode(QPointF(150, 110), False))
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 200 100, 150 110, 50 30))')
        self.assertEqual(len(spy), 1)

        shape.removeNode(3)
        self.assertEqual(len(spy), 2)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 200 100, 50 30))')

        shape.moveNode(2, QPointF(180, 100))
        self.assertEqual(len(spy), 3)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 180 100, 50 30))')

        shape.setNodes(p)
        self.assertEqual(len(spy), 4)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((100 40, 150 20, 250 110, 100 40))')

        shape.attemptSetSceneRect(QRectF(30, 10, 100, 200))
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((30 30, 80 10, 180 100, 30 30))')
        # bit gross - this needs fixing in the item. It shouldn't rely on a draw operation to update the
        # path as a result of a move/resize
        im = QImage()
        p = QPainter(im)
        rc = QgsLayoutUtils.createRenderContextForLayout(l, p)
        shape.draw(QgsLayoutItemRenderContext(rc))
        p.end()
        self.assertEqual(len(spy), 5)
Exemplo n.º 2
0
class TestQgsLayoutPolygon(unittest.TestCase, LayoutItemTestCase):
    @classmethod
    def setUpClass(cls):
        cls.item_class = QgsLayoutItemPolygon

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        # create composition
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()

        # create
        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(100.0, 0.0))
        polygon.append(QPointF(200.0, 100.0))
        polygon.append(QPointF(100.0, 200.0))

        self.polygon = QgsLayoutItemPolygon(polygon, self.layout)
        self.layout.addLayoutItem(self.polygon)

        # style
        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "black"
        props["width_border"] = "10.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        self.polygon.setSymbol(style)

    def testNodes(self):
        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(100.0, 0.0))
        polygon.append(QPointF(200.0, 100.0))
        polygon.append(QPointF(100.0, 200.0))

        p = QgsLayoutItemPolygon(polygon, self.layout)
        self.assertEqual(p.nodes(), polygon)

        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(1000.0, 0.0))
        polygon.append(QPointF(2000.0, 100.0))
        polygon.append(QPointF(1000.0, 200.0))

        p.setNodes(polygon)
        self.assertEqual(p.nodes(), polygon)

    def testDisplayName(self):
        """Test if displayName is valid"""

        self.assertEqual(self.polygon.displayName(), "<Polygon>")

    def testType(self):
        """Test if type is valid"""

        self.assertEqual(self.polygon.type(),
                         QgsLayoutItemRegistry.LayoutPolygon)

    def testDefaultStyle(self):
        """Test polygon rendering with default style."""

        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testDisplayNodes(self):
        """Test displayNodes method"""

        self.polygon.setDisplayNodes(True)
        checker = QgsLayoutChecker('composerpolygon_displaynodes', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testSelectedNode(self):
        """Test selectedNode and deselectNode methods"""

        self.polygon.setDisplayNodes(True)

        self.polygon.setSelectedNode(3)
        checker = QgsLayoutChecker('composerpolygon_selectednode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.polygon.deselectNode()
        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testRemoveNode(self):
        """Test removeNode method"""

        rc = self.polygon.removeNode(100)
        self.assertEqual(rc, False)

        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.assertEqual(self.polygon.nodesSize(), 4)

    def testAddNode(self):
        """Test addNode method"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 10.0))
        self.assertEqual(rc, False)

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 9.99))
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

    def testAddNodeCustomRadius(self):
        """Test addNode with custom radius"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 8.1), True, 8.0)
        self.assertEqual(rc, False)
        self.assertEqual(self.polygon.nodesSize(), 4)

        # default searching radius is 10
        rc = self.polygon.addNode(QPointF(50.0, 7.9), True, 8.0)
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

    def testAddNodeWithoutCheckingArea(self):
        """Test addNode without checking the maximum distance allowed"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 20.0))
        self.assertEqual(rc, False)
        self.assertEqual(self.polygon.nodesSize(), 4)

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 20.0), False)
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

        checker = QgsLayoutChecker('composerpolygon_addnode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testMoveNode(self):
        """Test moveNode method"""

        rc = self.polygon.moveNode(30, QPointF(100.0, 300.0))
        self.assertEqual(rc, False)

        rc = self.polygon.moveNode(3, QPointF(100.0, 150.0))
        self.assertEqual(rc, True)

        checker = QgsLayoutChecker('composerpolygon_movenode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testNodeAtPosition(self):
        """Test nodeAtPosition method"""

        p = QPolygonF()
        p.append(QPointF(0.0, 0.0))
        p.append(QPointF(100.0, 0.0))
        p.append(QPointF(200.0, 100.0))
        p.append(QPointF(100.0, 200.0))

        polygon = QgsLayoutItemPolygon(p, self.layout)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(QPointF(100.0, 210.0))
        self.assertEqual(rc, -1)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(QPointF(100.0, 210.0), False)
        self.assertEqual(rc, 3)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(QPointF(100.0, 210.0), True, 10.1)
        self.assertEqual(rc, 3)

    def testReadWriteXml(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(0.0, 0.0))
        p.append(QPointF(100.0, 0.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "red"
        props["width_border"] = "10.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        shape.setSymbol(style)

        #save original item to xml
        doc = QDomDocument("testdoc")
        elem = doc.createElement("test")
        self.assertTrue(shape.writeXml(elem, doc, QgsReadWriteContext()))

        shape2 = QgsLayoutItemPolygon(l)
        self.assertTrue(
            shape2.readXml(elem.firstChildElement(), doc,
                           QgsReadWriteContext()))

        self.assertEqual(shape2.nodes(), shape.nodes())
        self.assertEqual(shape2.symbol().symbolLayer(0).color().name(),
                         '#008000')
        self.assertEqual(shape2.symbol().symbolLayer(0).strokeColor().name(),
                         '#ff0000')

    def testBounds(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(50.0, 30.0))
        p.append(QPointF(100.0, 10.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "red"
        props["width_border"] = "6.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        shape.setSymbol(style)

        # scene bounding rect should include symbol outline
        bounds = shape.sceneBoundingRect()
        self.assertEqual(bounds.left(), 47.0)
        self.assertEqual(bounds.right(), 203.0)
        self.assertEqual(bounds.top(), 7.0)
        self.assertEqual(bounds.bottom(), 103.0)

        # rectWithFrame should include symbol outline too
        bounds = shape.rectWithFrame()
        self.assertEqual(bounds.left(), -3.0)
        self.assertEqual(bounds.right(), 153.0)
        self.assertEqual(bounds.top(), -3.0)
        self.assertEqual(bounds.bottom(), 93.0)
Exemplo n.º 3
0
class TestQgsLayoutPolygon(unittest.TestCase, LayoutItemTestCase):

    @classmethod
    def setUpClass(cls):
        cls.item_class = QgsLayoutItemPolygon

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        # create composition
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()

        # create
        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(100.0, 0.0))
        polygon.append(QPointF(200.0, 100.0))
        polygon.append(QPointF(100.0, 200.0))

        self.polygon = QgsLayoutItemPolygon(polygon, self.layout)
        self.layout.addLayoutItem(self.polygon)

        # style
        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "black"
        props["width_border"] = "10.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        self.polygon.setSymbol(style)

    def testNodes(self):
        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(100.0, 0.0))
        polygon.append(QPointF(200.0, 100.0))
        polygon.append(QPointF(100.0, 200.0))

        p = QgsLayoutItemPolygon(polygon, self.layout)
        self.assertEqual(p.nodes(), polygon)

        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(1000.0, 0.0))
        polygon.append(QPointF(2000.0, 100.0))
        polygon.append(QPointF(1000.0, 200.0))

        p.setNodes(polygon)
        self.assertEqual(p.nodes(), polygon)

    def testDisplayName(self):
        """Test if displayName is valid"""

        self.assertEqual(self.polygon.displayName(), "<Polygon>")

    def testType(self):
        """Test if type is valid"""

        self.assertEqual(
            self.polygon.type(), QgsLayoutItemRegistry.LayoutPolygon)

    def testDefaultStyle(self):
        """Test polygon rendering with default style."""

        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker(
            'composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testDisplayNodes(self):
        """Test displayNodes method"""

        self.polygon.setDisplayNodes(True)
        checker = QgsLayoutChecker(
            'composerpolygon_displaynodes', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker(
            'composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testSelectedNode(self):
        """Test selectedNode and deselectNode methods"""

        self.polygon.setDisplayNodes(True)

        self.polygon.setSelectedNode(3)
        checker = QgsLayoutChecker(
            'composerpolygon_selectednode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.polygon.deselectNode()
        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker(
            'composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testRemoveNode(self):
        """Test removeNode method"""

        rc = self.polygon.removeNode(100)
        self.assertEqual(rc, False)

        checker = QgsLayoutChecker(
            'composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.assertEqual(self.polygon.nodesSize(), 4)

    def testAddNode(self):
        """Test addNode method"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 10.0))
        self.assertEqual(rc, False)

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 9.99))
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

    def testAddNodeCustomRadius(self):
        """Test addNode with custom radius"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 8.1), True, 8.0)
        self.assertEqual(rc, False)
        self.assertEqual(self.polygon.nodesSize(), 4)

        # default searching radius is 10
        rc = self.polygon.addNode(QPointF(50.0, 7.9), True, 8.0)
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

    def testAddNodeWithoutCheckingArea(self):
        """Test addNode without checking the maximum distance allowed"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 20.0))
        self.assertEqual(rc, False)
        self.assertEqual(self.polygon.nodesSize(), 4)

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 20.0), False)
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

        checker = QgsLayoutChecker(
            'composerpolygon_addnode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testMoveNode(self):
        """Test moveNode method"""

        rc = self.polygon.moveNode(30, QPointF(100.0, 300.0))
        self.assertEqual(rc, False)

        rc = self.polygon.moveNode(3, QPointF(100.0, 150.0))
        self.assertEqual(rc, True)

        checker = QgsLayoutChecker(
            'composerpolygon_movenode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testNodeAtPosition(self):
        """Test nodeAtPosition method"""

        p = QPolygonF()
        p.append(QPointF(0.0, 0.0))
        p.append(QPointF(100.0, 0.0))
        p.append(QPointF(200.0, 100.0))
        p.append(QPointF(100.0, 200.0))

        polygon = QgsLayoutItemPolygon(p, self.layout)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(QPointF(100.0, 210.0))
        self.assertEqual(rc, -1)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(
            QPointF(100.0, 210.0), False)
        self.assertEqual(rc, 3)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(
            QPointF(100.0, 210.0), True, 10.1)
        self.assertEqual(rc, 3)

    def testReadWriteXml(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(0.0, 0.0))
        p.append(QPointF(100.0, 0.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "red"
        props["width_border"] = "10.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        shape.setSymbol(style)

        #save original item to xml
        doc = QDomDocument("testdoc")
        elem = doc.createElement("test")
        self.assertTrue(shape.writeXml(elem, doc, QgsReadWriteContext()))

        shape2 = QgsLayoutItemPolygon(l)
        self.assertTrue(shape2.readXml(elem.firstChildElement(), doc, QgsReadWriteContext()))

        self.assertEqual(shape2.nodes(), shape.nodes())
        self.assertEqual(shape2.symbol().symbolLayer(0).color().name(), '#008000')
        self.assertEqual(shape2.symbol().symbolLayer(0).strokeColor().name(), '#ff0000')

    def testBounds(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(50.0, 30.0))
        p.append(QPointF(100.0, 10.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "red"
        props["width_border"] = "6.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        shape.setSymbol(style)

        # scene bounding rect should include symbol outline
        bounds = shape.sceneBoundingRect()
        self.assertEqual(bounds.left(), 47.0)
        self.assertEqual(bounds.right(), 203.0)
        self.assertEqual(bounds.top(), 7.0)
        self.assertEqual(bounds.bottom(), 103.0)

        # rectWithFrame should include symbol outline too
        bounds = shape.rectWithFrame()
        self.assertEqual(bounds.left(), -3.0)
        self.assertEqual(bounds.right(), 153.0)
        self.assertEqual(bounds.top(), -3.0)
        self.assertEqual(bounds.bottom(), 93.0)
Exemplo n.º 4
0
class TestQgsLayoutPolygon(unittest.TestCase, LayoutItemTestCase):
    @classmethod
    def setUpClass(cls):
        cls.item_class = QgsLayoutItemPolygon

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        # create composition
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()

        # create
        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(100.0, 0.0))
        polygon.append(QPointF(200.0, 100.0))
        polygon.append(QPointF(100.0, 200.0))

        self.polygon = QgsLayoutItemPolygon(polygon, self.layout)
        self.layout.addLayoutItem(self.polygon)

        # style
        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "black"
        props["width_border"] = "10.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        self.polygon.setSymbol(style)

    def testNodes(self):
        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(100.0, 0.0))
        polygon.append(QPointF(200.0, 100.0))
        polygon.append(QPointF(100.0, 200.0))

        p = QgsLayoutItemPolygon(polygon, self.layout)
        self.assertEqual(p.nodes(), polygon)

        polygon = QPolygonF()
        polygon.append(QPointF(0.0, 0.0))
        polygon.append(QPointF(1000.0, 0.0))
        polygon.append(QPointF(2000.0, 100.0))
        polygon.append(QPointF(1000.0, 200.0))

        p.setNodes(polygon)
        self.assertEqual(p.nodes(), polygon)

    def testDisplayName(self):
        """Test if displayName is valid"""

        self.assertEqual(self.polygon.displayName(), "<Polygon>")

    def testType(self):
        """Test if type is valid"""

        self.assertEqual(self.polygon.type(),
                         QgsLayoutItemRegistry.LayoutPolygon)

    def testDefaultStyle(self):
        """Test polygon rendering with default style."""

        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testDisplayNodes(self):
        """Test displayNodes method"""

        self.polygon.setDisplayNodes(True)
        checker = QgsLayoutChecker('composerpolygon_displaynodes', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testSelectedNode(self):
        """Test selectedNode and deselectNode methods"""

        self.polygon.setDisplayNodes(True)

        self.polygon.setSelectedNode(3)
        checker = QgsLayoutChecker('composerpolygon_selectednode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.polygon.deselectNode()
        self.polygon.setDisplayNodes(False)
        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testRemoveNode(self):
        """Test removeNode method"""

        rc = self.polygon.removeNode(100)
        self.assertEqual(rc, False)

        checker = QgsLayoutChecker('composerpolygon_defaultstyle', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

        self.assertEqual(self.polygon.nodesSize(), 4)

    def testAddNode(self):
        """Test addNode method"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 10.0))
        self.assertEqual(rc, False)

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 9.99))
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

    def testAddNodeCustomRadius(self):
        """Test addNode with custom radius"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 8.1), True, 8.0)
        self.assertEqual(rc, False)
        self.assertEqual(self.polygon.nodesSize(), 4)

        # default searching radius is 10
        rc = self.polygon.addNode(QPointF(50.0, 7.9), True, 8.0)
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

    def testAddNodeWithoutCheckingArea(self):
        """Test addNode without checking the maximum distance allowed"""

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 20.0))
        self.assertEqual(rc, False)
        self.assertEqual(self.polygon.nodesSize(), 4)

        # default searching radius is 10
        self.assertEqual(self.polygon.nodesSize(), 4)
        rc = self.polygon.addNode(QPointF(50.0, 20.0), False)
        self.assertEqual(rc, True)
        self.assertEqual(self.polygon.nodesSize(), 5)

        checker = QgsLayoutChecker('composerpolygon_addnode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testMoveNode(self):
        """Test moveNode method"""

        rc = self.polygon.moveNode(30, QPointF(100.0, 300.0))
        self.assertEqual(rc, False)

        rc = self.polygon.moveNode(3, QPointF(100.0, 150.0))
        self.assertEqual(rc, True)

        checker = QgsLayoutChecker('composerpolygon_movenode', self.layout)
        checker.setControlPathPrefix("composer_polygon")
        myTestResult, myMessage = checker.testLayout()
        assert myTestResult, myMessage

    def testNodeAtPosition(self):
        """Test nodeAtPosition method"""

        p = QPolygonF()
        p.append(QPointF(0.0, 0.0))
        p.append(QPointF(100.0, 0.0))
        p.append(QPointF(200.0, 100.0))
        p.append(QPointF(100.0, 200.0))

        polygon = QgsLayoutItemPolygon(p, self.layout)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(QPointF(100.0, 210.0))
        self.assertEqual(rc, -1)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(QPointF(100.0, 210.0), False)
        self.assertEqual(rc, 3)

        # default searching radius is 10
        rc = polygon.nodeAtPosition(QPointF(100.0, 210.0), True, 10.1)
        self.assertEqual(rc, 3)

    def testReadWriteXml(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(0.0, 0.0))
        p.append(QPointF(100.0, 0.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "red"
        props["width_border"] = "10.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        shape.setSymbol(style)

        # save original item to xml
        doc = QDomDocument("testdoc")
        elem = doc.createElement("test")
        self.assertTrue(shape.writeXml(elem, doc, QgsReadWriteContext()))

        shape2 = QgsLayoutItemPolygon(l)
        self.assertTrue(
            shape2.readXml(elem.firstChildElement(), doc,
                           QgsReadWriteContext()))

        self.assertEqual(shape2.nodes(), shape.nodes())
        self.assertEqual(shape2.symbol().symbolLayer(0).color().name(),
                         '#008000')
        self.assertEqual(shape2.symbol().symbolLayer(0).strokeColor().name(),
                         '#ff0000')

    def testBounds(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(50.0, 30.0))
        p.append(QPointF(100.0, 10.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        props = {}
        props["color"] = "green"
        props["style"] = "solid"
        props["style_border"] = "solid"
        props["color_border"] = "red"
        props["width_border"] = "6.0"
        props["joinstyle"] = "miter"

        style = QgsFillSymbol.createSimple(props)
        shape.setSymbol(style)

        # scene bounding rect should include symbol outline
        bounds = shape.sceneBoundingRect()
        self.assertEqual(bounds.left(), 47.0)
        self.assertEqual(bounds.right(), 203.0)
        self.assertEqual(bounds.top(), 7.0)
        self.assertEqual(bounds.bottom(), 103.0)

        # rectWithFrame should include symbol outline too
        bounds = shape.rectWithFrame()
        self.assertEqual(bounds.left(), -3.0)
        self.assertEqual(bounds.right(), 153.0)
        self.assertEqual(bounds.top(), -3.0)
        self.assertEqual(bounds.bottom(), 93.0)

    def testClipPath(self):
        pr = QgsProject()
        l = QgsLayout(pr)

        p = QPolygonF()
        p.append(QPointF(50.0, 30.0))
        p.append(QPointF(100.0, 10.0))
        p.append(QPointF(200.0, 100.0))
        shape = QgsLayoutItemPolygon(p, l)

        # must be a closed polygon, in scene coordinates!
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 200 100, 50 30))')
        self.assertTrue(
            int(shape.itemFlags() & QgsLayoutItem.FlagProvidesClipPath))

        spy = QSignalSpy(shape.clipPathChanged)
        self.assertTrue(shape.addNode(QPointF(150, 110), False))
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 200 100, 150 110, 50 30))')
        self.assertEqual(len(spy), 1)

        shape.removeNode(3)
        self.assertEqual(len(spy), 2)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 200 100, 50 30))')

        shape.moveNode(2, QPointF(180, 100))
        self.assertEqual(len(spy), 3)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 30, 100 10, 180 100, 50 30))')

        shape.setNodes(p)
        self.assertEqual(len(spy), 4)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((100 40, 150 20, 250 110, 100 40))')

        shape.attemptSetSceneRect(QRectF(30, 10, 100, 200))
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((30 30, 80 10, 180 100, 30 30))')
        # bit gross - this needs fixing in the item. It shouldn't rely on a draw operation to update the
        # path as a result of a move/resize
        im = QImage()
        p = QPainter(im)
        rc = QgsLayoutUtils.createRenderContextForLayout(l, p)
        shape.draw(QgsLayoutItemRenderContext(rc))
        p.end()
        self.assertEqual(len(spy), 5)