def _test_operations(self, md, conn):
        """Common tests"""

        capabilities = conn.capabilities()

        # Schema operations
        if (capabilities & QgsAbstractDatabaseProviderConnection.CreateSchema
                and
                capabilities & QgsAbstractDatabaseProviderConnection.Schemas
                and capabilities
                & QgsAbstractDatabaseProviderConnection.DropSchema):

            # Start clean
            if 'myNewSchema' in conn.schemas():
                conn.dropSchema('myNewSchema', True)

            # Create
            conn.createSchema('myNewSchema')
            schemas = conn.schemas()
            self.assertTrue('myNewSchema' in schemas)

            # Create again
            with self.assertRaises(QgsProviderConnectionException) as ex:
                conn.createSchema('myNewSchema')

            # Test rename
            if capabilities & QgsAbstractDatabaseProviderConnection.RenameSchema:
                # Rename
                conn.renameSchema('myNewSchema', 'myVeryNewSchema')
                schemas = conn.schemas()
                self.assertTrue('myVeryNewSchema' in schemas)
                self.assertFalse('myNewSchema' in schemas)
                conn.renameSchema('myVeryNewSchema', 'myNewSchema')
                schemas = conn.schemas()
                self.assertFalse('myVeryNewSchema' in schemas)
                self.assertTrue('myNewSchema' in schemas)

            # Drop
            conn.dropSchema('myNewSchema')
            schemas = conn.schemas()
            self.assertFalse('myNewSchema' in schemas)

            # UTF8 schema
            conn.createSchema('myUtf8\U0001f604NewSchema')
            schemas = conn.schemas()
            conn.dropSchema('myUtf8\U0001f604NewSchema')
            schemas = conn.schemas()
            self.assertFalse('myUtf8\U0001f604NewSchema' in schemas)

        # Table operations
        if (capabilities
                & QgsAbstractDatabaseProviderConnection.CreateVectorTable
                and capabilities & QgsAbstractDatabaseProviderConnection.Tables
                and capabilities
                & QgsAbstractDatabaseProviderConnection.DropVectorTable):

            if capabilities & QgsAbstractDatabaseProviderConnection.CreateSchema:
                schema = 'myNewSchema'
                conn.createSchema('myNewSchema')
            else:
                schema = 'public'

            # Start clean
            if 'myNewTable' in self._table_names(conn.tables(schema)):
                conn.dropVectorTable(schema, 'myNewTable')

            fields = QgsFields()
            fields.append(QgsField("string_t", QVariant.String))
            fields.append(QgsField("long_t", QVariant.LongLong))
            fields.append(QgsField("double_t", QVariant.Double))
            fields.append(QgsField("integer_t", QVariant.Int))
            fields.append(QgsField("date_t", QVariant.Date))
            fields.append(QgsField("datetime_t", QVariant.DateTime))
            fields.append(QgsField("time_t", QVariant.Time))
            options = {}
            crs = QgsCoordinateReferenceSystem.fromEpsgId(3857)
            typ = QgsWkbTypes.LineString

            # Create
            conn.createVectorTable(schema, 'myNewTable', fields, typ, crs,
                                   True, options)
            table_names = self._table_names(conn.tables(schema))
            self.assertTrue('myNewTable' in table_names)

            # Create UTF8 table
            conn.createVectorTable(schema, 'myUtf8\U0001f604Table', fields,
                                   typ, crs, True, options)
            table_names = self._table_names(conn.tables(schema))
            self.assertTrue('myNewTable' in table_names)
            self.assertTrue('myUtf8\U0001f604Table' in table_names)
            conn.dropVectorTable(schema, 'myUtf8\U0001f604Table')
            table_names = self._table_names(conn.tables(schema))
            self.assertFalse('myUtf8\U0001f604Table' in table_names)
            self.assertTrue('myNewTable' in table_names)

            # insert something, because otherwise MSSQL cannot guess
            if self.providerKey == 'mssql':
                f = QgsFeature(fields)
                f.setGeometry(
                    QgsGeometry.fromWkt('LineString (-72.345 71.987, -80 80)'))
                vl = QgsVectorLayer(conn.tableUri('myNewSchema', 'myNewTable'),
                                    'vl', 'mssql')
                vl.dataProvider().addFeatures([f])

            # Check table information
            table_properties = conn.tables(schema)
            table_property = self._table_by_name(table_properties,
                                                 'myNewTable')
            self.assertEqual(table_property.maxCoordinateDimensions(), 2)
            self.assertIsNotNone(table_property)
            self.assertEqual(table_property.tableName(), 'myNewTable')
            self.assertEqual(table_property.geometryColumnCount(), 1)
            self.assertEqual(table_property.geometryColumnTypes()[0].wkbType,
                             QgsWkbTypes.LineString)
            cols = table_property.geometryColumnTypes()
            self.assertEqual(cols[0].crs,
                             QgsCoordinateReferenceSystem.fromEpsgId(3857))
            self.assertEqual(table_property.defaultName(), 'myNewTable')

            # Check aspatial tables
            conn.createVectorTable(schema, 'myNewAspatialTable', fields,
                                   QgsWkbTypes.NoGeometry, crs, True, options)
            table_properties = conn.tables(
                schema, QgsAbstractDatabaseProviderConnection.Aspatial)
            table_property = self._table_by_name(table_properties,
                                                 'myNewAspatialTable')
            self.assertIsNotNone(table_property)
            self.assertEqual(table_property.maxCoordinateDimensions(), 0)
            self.assertEqual(table_property.tableName(), 'myNewAspatialTable')
            self.assertEqual(table_property.geometryColumnCount(), 0)
            self.assertEqual(table_property.geometryColumn(), '')
            self.assertEqual(table_property.defaultName(),
                             'myNewAspatialTable')
            cols = table_property.geometryColumnTypes()
            # We always return geom col types, even when there is no geometry
            self.assertEqual(cols[0].wkbType, QgsWkbTypes.NoGeometry)
            self.assertFalse(cols[0].crs.isValid())
            self.assertFalse(table_property.flags()
                             & QgsAbstractDatabaseProviderConnection.Raster)
            self.assertFalse(table_property.flags()
                             & QgsAbstractDatabaseProviderConnection.Vector)
            self.assertTrue(table_property.flags()
                            & QgsAbstractDatabaseProviderConnection.Aspatial)

            # Check executeSql
            has_schema = capabilities & QgsAbstractDatabaseProviderConnection.Schemas
            if capabilities & QgsAbstractDatabaseProviderConnection.ExecuteSql:
                if has_schema:
                    table = "\"%s\".\"myNewAspatialTable\"" % schema
                else:
                    table = 'myNewAspatialTable'

                # MSSQL literal syntax for UTF8 requires 'N' prefix
                sql = "INSERT INTO %s (string_t, long_t, double_t, integer_t, date_t, datetime_t, time_t) VALUES (%s'QGIS Rocks - \U0001f604', 666, 1.234, 1234, '2019-07-08', '2019-07-08T12:00:12', '12:00:13.00')" % (
                    table, 'N' if self.providerKey == 'mssql' else '')
                res = conn.executeSql(sql)
                self.assertEqual(res, [])
                sql = "SELECT string_t, long_t, double_t, integer_t, date_t, datetime_t FROM %s" % table
                res = conn.executeSql(sql)
                # GPKG and spatialite have no type for time
                self.assertEqual(res, [[
                    'QGIS Rocks - \U0001f604', 666, 1.234, 1234,
                    QtCore.QDate(2019, 7, 8)
                    if not self.treat_date_as_string() else '2019-07-08',
                    QtCore.QDateTime(2019, 7, 8, 12, 0, 12)
                ]])
                sql = "SELECT time_t FROM %s" % table
                res = conn.executeSql(sql)

                # This does not work in MSSQL and returns a QByteArray, we have no way to know that it is a time
                # value and there is no way we can convert it.
                if self.providerKey != 'mssql':
                    self.assertIn(
                        res, ([[QtCore.QTime(12, 0, 13)]], [['12:00:13.00']]))

                sql = "DELETE FROM %s WHERE string_t = %s'QGIS Rocks - \U0001f604'" % (
                    table, 'N' if self.providerKey == 'mssql' else '')
                res = conn.executeSql(sql)
                self.assertEqual(res, [])
                sql = "SELECT string_t, integer_t FROM %s" % table
                res = conn.executeSql(sql)
                self.assertEqual(res, [])

            # Check that we do NOT get the aspatial table when querying for vectors
            table_names = self._table_names(
                conn.tables(schema,
                            QgsAbstractDatabaseProviderConnection.Vector))
            self.assertTrue('myNewTable' in table_names)
            self.assertFalse('myNewAspatialTable' in table_names)

            # Query for rasters (in qgis_test schema or no schema for GPKG, spatialite has no support)
            if self.providerKey not in ('spatialite', 'mssql'):
                table_properties = conn.tables(
                    'qgis_test', QgsAbstractDatabaseProviderConnection.Raster)
                # At least one raster should be there (except for spatialite)
                self.assertTrue(len(table_properties) >= 1)
                table_property = table_properties[0]
                self.assertTrue(table_property.flags()
                                & QgsAbstractDatabaseProviderConnection.Raster)
                self.assertFalse(
                    table_property.flags()
                    & QgsAbstractDatabaseProviderConnection.Vector)
                self.assertFalse(
                    table_property.flags()
                    & QgsAbstractDatabaseProviderConnection.Aspatial)

            if capabilities & QgsAbstractDatabaseProviderConnection.RenameVectorTable:
                # Rename
                conn.renameVectorTable(schema, 'myNewTable', 'myVeryNewTable')
                tables = self._table_names(conn.tables(schema))
                self.assertFalse('myNewTable' in tables)
                self.assertTrue('myVeryNewTable' in tables)
                # Rename it back
                conn.renameVectorTable(schema, 'myVeryNewTable', 'myNewTable')
                tables = self._table_names(conn.tables(schema))
                self.assertTrue('myNewTable' in tables)
                self.assertFalse('myVeryNewTable' in tables)

            # Vacuum
            if capabilities & QgsAbstractDatabaseProviderConnection.Vacuum:
                conn.vacuum('myNewSchema', 'myNewTable')

            # Spatial index
            spatial_index_exists = False
            # we don't initially know if a spatial index exists -- some formats may create them by default, others not
            if capabilities & QgsAbstractDatabaseProviderConnection.SpatialIndexExists:
                spatial_index_exists = conn.spatialIndexExists(
                    'myNewSchema', 'myNewTable', 'geom')
            if capabilities & QgsAbstractDatabaseProviderConnection.DeleteSpatialIndex:
                if spatial_index_exists:
                    conn.deleteSpatialIndex('myNewSchema', 'myNewTable',
                                            'geom')
                if capabilities & QgsAbstractDatabaseProviderConnection.SpatialIndexExists:
                    self.assertFalse(
                        conn.spatialIndexExists('myNewSchema', 'myNewTable',
                                                'geom'))

            if capabilities & QgsAbstractDatabaseProviderConnection.CreateSpatialIndex:
                options = QgsAbstractDatabaseProviderConnection.SpatialIndexOptions(
                )
                options.geometryColumnName = 'geom'
                conn.createSpatialIndex('myNewSchema', 'myNewTable', options)

                if capabilities & QgsAbstractDatabaseProviderConnection.SpatialIndexExists:
                    self.assertTrue(
                        conn.spatialIndexExists('myNewSchema', 'myNewTable',
                                                'geom'))

                # now we know for certain a spatial index exists, let's retry dropping it
                if capabilities & QgsAbstractDatabaseProviderConnection.DeleteSpatialIndex:
                    conn.deleteSpatialIndex('myNewSchema', 'myNewTable',
                                            'geom')
                    if capabilities & QgsAbstractDatabaseProviderConnection.SpatialIndexExists:
                        self.assertFalse(
                            conn.spatialIndexExists('myNewSchema',
                                                    'myNewTable', 'geom'))

            if capabilities & QgsAbstractDatabaseProviderConnection.DropSchema:
                # Drop schema (should fail)
                with self.assertRaises(QgsProviderConnectionException) as ex:
                    conn.dropSchema('myNewSchema')

            # Check some column types operations
            table = self._table_by_name(conn.tables(schema), 'myNewTable')
            self.assertEqual(len(table.geometryColumnTypes()), 1)
            ct = table.geometryColumnTypes()[0]
            self.assertEqual(ct.crs,
                             QgsCoordinateReferenceSystem.fromEpsgId(3857))
            self.assertEqual(ct.wkbType, QgsWkbTypes.LineString)
            # Add a new (existing type)
            table.addGeometryColumnType(
                QgsWkbTypes.LineString,
                QgsCoordinateReferenceSystem.fromEpsgId(3857))
            self.assertEqual(len(table.geometryColumnTypes()), 1)
            ct = table.geometryColumnTypes()[0]
            self.assertEqual(ct.crs,
                             QgsCoordinateReferenceSystem.fromEpsgId(3857))
            self.assertEqual(ct.wkbType, QgsWkbTypes.LineString)
            # Add a new one
            table.addGeometryColumnType(
                QgsWkbTypes.LineString,
                QgsCoordinateReferenceSystem.fromEpsgId(4326))
            self.assertEqual(len(table.geometryColumnTypes()), 2)
            ct = table.geometryColumnTypes()[0]
            self.assertEqual(ct.crs,
                             QgsCoordinateReferenceSystem.fromEpsgId(3857))
            self.assertEqual(ct.wkbType, QgsWkbTypes.LineString)
            ct = table.geometryColumnTypes()[1]
            self.assertEqual(ct.crs,
                             QgsCoordinateReferenceSystem.fromEpsgId(4326))
            self.assertEqual(ct.wkbType, QgsWkbTypes.LineString)

            # Check fields
            fields = conn.fields('myNewSchema', 'myNewTable')
            for f in [
                    'string_t', 'long_t', 'double_t', 'integer_t', 'date_t',
                    'datetime_t', 'time_t'
            ]:
                self.assertTrue(f in fields.names())

            if capabilities & QgsAbstractDatabaseProviderConnection.AddField:
                field = QgsField('short_lived_field', QVariant.Int, 'integer')
                conn.addField(field, 'myNewSchema', 'myNewTable')
                fields = conn.fields('myNewSchema', 'myNewTable')
                self.assertTrue('short_lived_field' in fields.names())

                if capabilities & QgsAbstractDatabaseProviderConnection.DeleteField:
                    conn.deleteField('short_lived_field', 'myNewSchema',
                                     'myNewTable')
                    # This fails on Travis for spatialite, for no particular reason
                    if self.providerKey == 'spatialite' and not os.environ.get(
                            'TRAVIS', False):
                        fields = conn.fields('myNewSchema', 'myNewTable')
                        self.assertFalse('short_lived_field' in fields.names())

            # Drop table
            conn.dropVectorTable(schema, 'myNewTable')
            conn.dropVectorTable(schema, 'myNewAspatialTable')
            table_names = self._table_names(conn.tables(schema))
            self.assertFalse('myNewTable' in table_names)

            if capabilities & QgsAbstractDatabaseProviderConnection.DropSchema:
                # Drop schema
                conn.dropSchema('myNewSchema')
                self.assertFalse('myNewSchema' in conn.schemas())

        conns = md.connections()
        self.assertTrue(
            isinstance(
                list(conns.values())[0],
                QgsAbstractDatabaseProviderConnection))

        # Remove connection
        spy_deleted = QSignalSpy(md.connectionDeleted)
        md.deleteConnection('qgis_test1')
        self.assertEqual(list(md.connections().values()), [])
        self.assertEqual(len(spy_deleted), 1)
Ejemplo n.º 2
0
    def testIteration(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)

        atlas_feature_changed_spy = QSignalSpy(atlas.featureChanged)
        context_changed_spy = QSignalSpy(l.reportContext().changed)

        self.assertTrue(atlas.beginRender())
        self.assertTrue(atlas.first())
        self.assertEqual(len(atlas_feature_changed_spy), 1)
        self.assertEqual(len(context_changed_spy), 1)
        self.assertEqual(atlas.currentFeatureNumber(), 0)
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertEqual(l.reportContext().layer(), vector_layer)
        f1 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 2)
        self.assertEqual(len(context_changed_spy), 2)
        self.assertEqual(atlas.currentFeatureNumber(), 1)
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        f2 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 3)
        self.assertEqual(len(context_changed_spy), 3)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        f3 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 4)
        self.assertEqual(len(context_changed_spy), 4)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        f4 = l.reportContext().feature()

        self.assertFalse(atlas.next())
        self.assertTrue(atlas.seekTo(2))
        self.assertEqual(len(atlas_feature_changed_spy), 5)
        self.assertEqual(len(context_changed_spy), 5)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.last())
        self.assertEqual(len(atlas_feature_changed_spy), 6)
        self.assertEqual(len(context_changed_spy), 6)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')

        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 7)
        self.assertEqual(len(context_changed_spy), 7)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.previous())
        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)
        self.assertFalse(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)

        self.assertTrue(atlas.endRender())
        self.assertEqual(len(atlas_feature_changed_spy), 10)

        self.assertTrue(atlas.seekTo(f1))
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertTrue(atlas.seekTo(f4))
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        self.assertTrue(atlas.seekTo(f3))
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        self.assertTrue(atlas.seekTo(f2))
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        self.assertFalse(atlas.seekTo(QgsFeature(5)))
Ejemplo n.º 3
0
    def testCombo(self):
        project = QgsProject()
        layout = QgsPrintLayout(project)

        combo = QgsLayoutItemComboBox(None)
        spy = QSignalSpy(combo.itemChanged)
        self.assertEqual(combo.count(), 0)
        self.assertIsNone(combo.currentLayout())
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(combo.currentIndex(), -1)
        self.assertEqual(len(spy), 0)

        combo.setCurrentLayout(layout)
        self.assertEqual(combo.currentIndex(), -1)
        self.assertEqual(len(spy), 0)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.count(), 0)
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 0)

        combo.setAllowEmptyItem(True)
        self.assertEqual(combo.currentIndex(), 0)
        self.assertEqual(combo.count(), 1)
        self.assertEqual(len(spy), 2)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 2)
        self.assertEqual(combo.currentIndex(), 0)
        self.assertEqual(combo.itemText(0), '')

        combo.setAllowEmptyItem(False)
        self.assertEqual(combo.currentIndex(), -1)
        self.assertEqual(combo.count(), 0)
        self.assertEqual(len(spy), 4)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 4)
        self.assertEqual(combo.currentIndex(), -1)

        label1 = QgsLayoutItemLabel(layout)
        label1.setId('llll')
        # don't add to layout yet!
        combo.setItem(label1)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 4)
        self.assertEqual(combo.currentIndex(), -1)
        combo.setAllowEmptyItem(True)
        combo.setItem(label1)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 6)
        self.assertEqual(combo.currentIndex(), 0)
        combo.setAllowEmptyItem(False)

        layout.addLayoutItem(label1)
        self.assertEqual(combo.currentIndex(), 0)
        self.assertEqual(combo.count(), 1)
        self.assertEqual(combo.itemText(0), 'llll')
        self.assertEqual(len(spy), 10)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(combo.item(0), label1)
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 11)
        self.assertEqual(combo.currentIndex(), -1)
        combo.setItem(label1)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(len(spy), 12)
        self.assertEqual(combo.currentIndex(), 0)

        combo.setAllowEmptyItem(True)
        self.assertEqual(combo.currentIndex(), 1)
        self.assertEqual(combo.count(), 2)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'llll')
        self.assertEqual(len(spy), 13)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.currentItem(), label1)
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label1)
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(2))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 14)
        self.assertEqual(combo.currentIndex(), 0)
        combo.setItem(label1)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(len(spy), 15)
        self.assertEqual(combo.currentIndex(), 1)

        label2 = QgsLayoutItemLabel(layout)
        label2.setId('mmmm')
        layout.addLayoutItem(label2)
        self.assertEqual(combo.currentIndex(), 1)
        self.assertEqual(combo.count(), 3)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'llll')
        self.assertEqual(combo.itemText(2), 'mmmm')
        self.assertEqual(len(spy), 15)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.currentItem(), label1)
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label1)
        self.assertEqual(combo.item(2), label2)
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(3))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 16)
        self.assertEqual(combo.currentIndex(), 0)
        combo.setItem(label1)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(len(spy), 17)
        self.assertEqual(combo.currentIndex(), 1)

        label1.setId('nnnn')
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'mmmm')
        self.assertEqual(combo.itemText(2), 'nnnn')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.item(2), label1)
        self.assertEqual(combo.currentItem(), label1)

        combo.setAllowEmptyItem(False)
        self.assertEqual(combo.itemText(0), 'mmmm')
        self.assertEqual(combo.itemText(1), 'nnnn')
        self.assertEqual(combo.item(0), label2)
        self.assertEqual(combo.item(1), label1)
        self.assertEqual(combo.currentItem(), label1)

        combo.setItem(label2)
        label2.setId('oooo')
        self.assertEqual(combo.itemText(0), 'nnnn')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertEqual(combo.item(0), label1)
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.currentItem(), label2)

        combo.setAllowEmptyItem(True)
        layout.removeLayoutItem(label1)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.currentItem(), label2)

        map = QgsLayoutItemMap(layout)
        layout.addLayoutItem(map)
        map.setId('pppp')
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertEqual(combo.itemText(2), 'pppp')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.item(2), map)
        self.assertEqual(combo.currentItem(), label2)

        combo.setItemType(QgsLayoutItemRegistry.LayoutMap)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'pppp')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), map)
        self.assertIsNone(combo.currentItem())

        combo.setItemType(QgsLayoutItemRegistry.LayoutLabel)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertIsNone(combo.currentItem())

        combo.setItemType(QgsLayoutItemRegistry.LayoutAttributeTable)
        self.assertEqual(combo.itemText(0), '')
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.currentItem())

        combo.setAllowEmptyItem(False)
        self.assertEqual(combo.count(), 0)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(combo.currentIndex(), -1)
    def testCombo(self):
        """ test combobox functionality """
        conn = QgsProviderRegistry.instance().providerMetadata('postgres').createConnection(self.uri, {})
        self.assertTrue(conn)

        m = QgsDatabaseSchemaComboBox(conn)
        spy = QSignalSpy(m.schemaChanged)
        self.assertGreaterEqual(m.comboBox().count(), 3)

        text = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        self.assertIn('CamelCaseSchema', text)
        self.assertIn('qgis_test', text)
        self.assertLess(text.index('CamelCaseSchema'), text.index('qgis_test'))
        self.assertEqual(m.currentSchema(), 'CamelCaseSchema')

        m.setSchema('qgis_test')
        self.assertEqual(m.currentSchema(), 'qgis_test')
        self.assertEqual(len(spy), 1)
        self.assertEqual(spy[-1][0], 'qgis_test')

        m.setSchema('')
        self.assertFalse(m.currentSchema())
        self.assertEqual(len(spy), 2)
        self.assertFalse(spy[-1][0])
        m.setSchema('')
        self.assertEqual(len(spy), 2)
        self.assertFalse(m.currentSchema())

        m.setSchema('qgis_test')
        self.assertEqual(len(spy), 3)
        self.assertEqual(m.currentSchema(), 'qgis_test')
        self.assertEqual(spy[-1][0], 'qgis_test')

        conn.createSchema('myNewSchema')
        text2 = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        # schemas are not automatically refreshed
        self.assertEqual(text2, text)

        # but setting a new connection should fix this!
        md = QgsProviderRegistry.instance().providerMetadata('postgres')
        conn2 = md.createConnection(self.uri, {})
        md.saveConnection(conn2, 'another')
        m.setConnectionName('another', 'postgres')
        # ideally there'd be no extra signal here, but it's a minor issue...
        self.assertEqual(len(spy), 4)
        self.assertEqual(m.currentSchema(), 'qgis_test')
        self.assertEqual(spy[-1][0], 'qgis_test')

        text2 = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        self.assertNotEqual(text2, text)
        self.assertIn('myNewSchema', text2)

        m.setSchema('myNewSchema')
        self.assertEqual(len(spy), 5)
        self.assertEqual(m.currentSchema(), 'myNewSchema')
        self.assertEqual(spy[-1][0], 'myNewSchema')

        # no auto drop
        conn.dropSchema('myNewSchema')
        self.assertEqual(len(spy), 5)
        self.assertEqual(m.currentSchema(), 'myNewSchema')
        self.assertEqual(spy[-1][0], 'myNewSchema')

        m.refreshSchemas()
        text2 = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        self.assertNotIn('myNewSchema', text2)
        self.assertEqual(len(spy), 6)
        self.assertFalse(m.currentSchema())
        self.assertFalse(spy[-1][0])
Ejemplo n.º 5
0
    def testSubsetString(self):
        if not self.source.supportsSubsetString():
            print('Provider does not support subset strings')
            return

        changed_spy = QSignalSpy(self.source.dataChanged)
        subset = self.getSubsetString()
        self.source.setSubsetString(subset)
        self.assertEqual(self.source.subsetString(), subset)
        self.assertEqual(len(changed_spy), 1)

        # No signal should be emitted if the subset string is not modified
        self.source.setSubsetString(subset)
        self.assertEqual(len(changed_spy), 1)

        result = set([f['pk'] for f in self.source.getFeatures()])
        all_valid = (all(f.isValid() for f in self.source.getFeatures()))
        self.source.setSubsetString(None)

        expected = set([2, 3, 4])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)

        # Subset string AND filter rect
        self.source.setSubsetString(subset)
        extent = QgsRectangle(-70, 70, -60, 75)
        request = QgsFeatureRequest().setFilterRect(extent)
        result = set([f['pk'] for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid()
                         for f in self.source.getFeatures(request)))
        self.source.setSubsetString(None)
        expected = set([2])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)

        # Subset string AND filter rect, version 2
        self.source.setSubsetString(subset)
        extent = QgsRectangle(-71, 65, -60, 80)
        result = set([
            f['pk'] for f in self.source.getFeatures(
                QgsFeatureRequest().setFilterRect(extent))
        ])
        self.source.setSubsetString(None)
        expected = set([2, 4])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)

        # Subset string AND expression
        self.source.setSubsetString(subset)
        request = QgsFeatureRequest().setFilterExpression('length("name")=5')
        result = set([f['pk'] for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid()
                         for f in self.source.getFeatures(request)))
        self.source.setSubsetString(None)
        expected = set([2, 4])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)

        # Subset string AND filter fid
        ids = {f['pk']: f.id() for f in self.source.getFeatures()}
        self.source.setSubsetString(subset)
        request = QgsFeatureRequest().setFilterFid(4)
        result = set([f.id() for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid()
                         for f in self.source.getFeatures(request)))
        self.source.setSubsetString(None)
        expected = set([4])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)

        # Subset string AND filter fids
        self.source.setSubsetString(subset)
        request = QgsFeatureRequest().setFilterFids([ids[2], ids[4]])
        result = set([f.id() for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid()
                         for f in self.source.getFeatures(request)))
        self.source.setSubsetString(None)
        expected = set([ids[2], ids[4]])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)
Ejemplo n.º 6
0
    def testValues(self):
        w = QgsRangeSlider()
        w.setRangeLimits(0, 10)

        w.setUpperValue(7)

        spy = QSignalSpy(w.rangeChanged)

        w.setLowerValue(5)
        self.assertEqual(w.lowerValue(), 5)
        self.assertEqual(len(spy), 1)
        self.assertEqual(spy[-1], [5, 7])
        w.setLowerValue(5)
        self.assertEqual(w.lowerValue(), 5)
        self.assertEqual(len(spy), 1)

        w.setUpperValue(8)
        self.assertEqual(w.lowerValue(), 5)
        self.assertEqual(w.upperValue(), 8)
        self.assertEqual(len(spy), 2)
        self.assertEqual(spy[-1], [5, 8])
        w.setUpperValue(8)
        self.assertEqual(w.lowerValue(), 5)
        self.assertEqual(w.upperValue(), 8)
        self.assertEqual(len(spy), 2)

        w.setRange(3, 7)
        self.assertEqual(w.lowerValue(), 3)
        self.assertEqual(w.upperValue(), 7)
        self.assertEqual(len(spy), 3)
        self.assertEqual(spy[-1], [3, 7])
        w.setRange(3, 7)
        self.assertEqual(w.lowerValue(), 3)
        self.assertEqual(w.upperValue(), 7)
        self.assertEqual(len(spy), 3)

        w.setRange(3, 8)
        self.assertEqual(w.lowerValue(), 3)
        self.assertEqual(w.upperValue(), 8)
        self.assertEqual(len(spy), 4)
        self.assertEqual(spy[-1], [3, 8])

        w.setRange(4, 8)
        self.assertEqual(w.lowerValue(), 4)
        self.assertEqual(w.upperValue(), 8)
        self.assertEqual(len(spy), 5)
        self.assertEqual(spy[-1], [4, 8])

        # set min > max, max should be raised
        w.setLowerValue(9)
        self.assertEqual(w.lowerValue(), 9)
        self.assertEqual(w.upperValue(), 9)
        self.assertEqual(len(spy), 6)
        self.assertEqual(spy[-1], [9, 9])

        w.setRange(4, 8)
        self.assertEqual(len(spy), 7)

        # set max < min, min should be lowered
        w.setUpperValue(3)
        self.assertEqual(w.lowerValue(), 3)
        self.assertEqual(w.upperValue(), 3)
        self.assertEqual(len(spy), 8)
        self.assertEqual(spy[-1], [3, 3])

        # set to values outside limit, should be clamped
        w.setUpperValue(12)
        self.assertEqual(w.lowerValue(), 3)
        self.assertEqual(w.upperValue(), 10)
        self.assertEqual(len(spy), 9)
        self.assertEqual(spy[-1], [3, 10])

        w.setLowerValue(-2)
        self.assertEqual(w.lowerValue(), 0)
        self.assertEqual(w.upperValue(), 10)
        self.assertEqual(len(spy), 10)
        self.assertEqual(spy[-1], [0, 10])

        w.setUpperValue(-3)
        self.assertEqual(w.lowerValue(), 0)
        self.assertEqual(w.upperValue(), 0)
        self.assertEqual(len(spy), 11)
        self.assertEqual(spy[-1], [0, 0])

        w.setLowerValue(13)
        self.assertEqual(w.lowerValue(), 10)
        self.assertEqual(w.upperValue(), 10)
        self.assertEqual(len(spy), 12)
        self.assertEqual(spy[-1], [10, 10])

        w.setRange(-2, 3)
        self.assertEqual(w.lowerValue(), 0)
        self.assertEqual(w.upperValue(), 3)
        self.assertEqual(len(spy), 13)
        self.assertEqual(spy[-1], [0, 3])

        w.setRange(3, 13)
        self.assertEqual(w.lowerValue(), 3)
        self.assertEqual(w.upperValue(), 10)
        self.assertEqual(len(spy), 14)
        self.assertEqual(spy[-1], [3, 10])

        w.setRange(-3, -2)
        self.assertEqual(w.lowerValue(), 0)
        self.assertEqual(w.upperValue(), 0)
        self.assertEqual(len(spy), 15)
        self.assertEqual(spy[-1], [0, 0])

        w.setRange(12, 13)
        self.assertEqual(w.lowerValue(), 10)
        self.assertEqual(w.upperValue(), 10)
        self.assertEqual(len(spy), 16)
        self.assertEqual(spy[-1], [10, 10])

        # flipped ranges
        w.setRange(7, 4)
        self.assertEqual(w.lowerValue(), 4)
        self.assertEqual(w.upperValue(), 7)
        self.assertEqual(len(spy), 17)
        self.assertEqual(spy[-1], [4, 7])
Ejemplo n.º 7
0
    def testOperations(self):
        w = QgsCoordinateOperationWidget()
        self.assertFalse(w.hasSelection())
        spy = QSignalSpy(w.operationChanged)
        w.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:26745'))
        self.assertEqual(len(spy), 0)
        w.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        self.assertEqual(len(spy), 1)
        self.assertTrue(w.hasSelection())
        self.assertGreaterEqual(len(w.availableOperations()), 6)

        self.assertEqual(
            w.defaultOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().isAvailable)

        op = QgsCoordinateOperationWidget.OperationDetails()
        op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        op.allowFallback = True
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 2)
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 2)

        op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        op.allowFallback = False
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertFalse(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 3)

        op.allowFallback = True
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 4)

        context = QgsCoordinateTransformContext()
        op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        w.setSelectedOperation(op)
        w.setSelectedOperationUsingContext(context)
        # should go to default, because there's nothing in the context matching these crs
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertEqual(len(spy), 6)

        # put something in the context
        context.addCoordinateOperation(
            w.sourceCrs(), w.destinationCrs(),
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        w.setSelectedOperationUsingContext(context)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 7)

        context.addCoordinateOperation(
            w.sourceCrs(), w.destinationCrs(),
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84',
            False)
        w.setSelectedOperationUsingContext(context)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertFalse(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 8)
Ejemplo n.º 8
0
    def testDirtyBlocker(self):
        # first test manual QgsProjectDirtyBlocker construction
        p = QgsProject()

        dirty_spy = QSignalSpy(p.isDirtyChanged)
        # ^ will do *whatever* it takes to discover the enemy's secret plans!

        # simple checks
        p.setDirty(True)
        self.assertTrue(p.isDirty())
        self.assertEqual(len(dirty_spy), 1)
        self.assertEqual(dirty_spy[-1], [True])
        p.setDirty(True)  # already dirty
        self.assertTrue(p.isDirty())
        self.assertEqual(len(dirty_spy), 1)
        p.setDirty(False)
        self.assertFalse(p.isDirty())
        self.assertEqual(len(dirty_spy), 2)
        self.assertEqual(dirty_spy[-1], [False])
        p.setDirty(True)
        self.assertTrue(p.isDirty())
        self.assertEqual(len(dirty_spy), 3)
        self.assertEqual(dirty_spy[-1], [True])

        # with a blocker
        blocker = QgsProjectDirtyBlocker(p)
        # blockers will allow cleaning projects
        p.setDirty(False)
        self.assertFalse(p.isDirty())
        self.assertEqual(len(dirty_spy), 4)
        self.assertEqual(dirty_spy[-1], [False])
        # but not dirtying!
        p.setDirty(True)
        self.assertFalse(p.isDirty())
        self.assertEqual(len(dirty_spy), 4)
        self.assertEqual(dirty_spy[-1], [False])
        # nested block
        blocker2 = QgsProjectDirtyBlocker(p)
        p.setDirty(True)
        self.assertFalse(p.isDirty())
        self.assertEqual(len(dirty_spy), 4)
        self.assertEqual(dirty_spy[-1], [False])
        del blocker2
        p.setDirty(True)
        self.assertFalse(p.isDirty())
        self.assertEqual(len(dirty_spy), 4)
        self.assertEqual(dirty_spy[-1], [False])
        del blocker
        p.setDirty(True)
        self.assertTrue(p.isDirty())
        self.assertEqual(len(dirty_spy), 5)
        self.assertEqual(dirty_spy[-1], [True])

        # using python context manager
        with QgsProject.blockDirtying(p):
            # cleaning allowed
            p.setDirty(False)
            self.assertFalse(p.isDirty())
            self.assertEqual(len(dirty_spy), 6)
            self.assertEqual(dirty_spy[-1], [False])
            # but not dirtying!
            p.setDirty(True)
            self.assertFalse(p.isDirty())
            self.assertEqual(len(dirty_spy), 6)
            self.assertEqual(dirty_spy[-1], [False])

        # unblocked
        p.setDirty(True)
        self.assertTrue(p.isDirty())
        self.assertEqual(len(dirty_spy), 7)
        self.assertEqual(dirty_spy[-1], [True])
    def testTreeWidgetDeferredLoad(self):
        """
        Test that crs setting made before widget is initialized is respected
        """
        w = QgsProjectionSelectionTreeWidget()
        spy = QSignalSpy(w.crsSelected)
        self.assertFalse(w.hasValidSelection())
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        self.assertEqual(len(spy), 1)
        self.assertTrue(w.hasValidSelection())
        self.assertEqual(w.crs().authid(), 'EPSG:3111')
        self.assertEqual(len(spy), 1)

        w = QgsProjectionSelectionTreeWidget()
        spy = QSignalSpy(w.crsSelected)
        self.assertFalse(w.hasValidSelection())
        w.setCrs(QgsCoordinateReferenceSystem())
        self.assertEqual(len(spy), 1)
        self.assertTrue(w.hasValidSelection())
        self.assertFalse(w.crs().isValid())
        self.assertEqual(len(spy), 1)
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(len(spy), 2)

        # expect same behavior if we show
        w = QgsProjectionSelectionTreeWidget()
        spy = QSignalSpy(w.crsSelected)
        self.assertFalse(w.hasValidSelection())
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        self.assertEqual(len(spy), 1)
        w.show()
        self.assertTrue(w.hasValidSelection())
        self.assertEqual(w.crs().authid(), 'EPSG:3111')
        self.assertEqual(len(spy), 1)

        w = QgsProjectionSelectionTreeWidget()
        spy = QSignalSpy(w.crsSelected)
        self.assertFalse(w.hasValidSelection())
        w.setCrs(QgsCoordinateReferenceSystem())
        self.assertEqual(len(spy), 1)
        w.show()
        self.assertTrue(w.hasValidSelection())
        self.assertFalse(w.crs().isValid())
        self.assertEqual(len(spy), 1)

        # no double signals if same crs set
        w = QgsProjectionSelectionTreeWidget()
        spy = QSignalSpy(w.crsSelected)
        self.assertFalse(w.hasValidSelection())
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        self.assertEqual(len(spy), 1)

        # no double signals if same crs set
        w = QgsProjectionSelectionTreeWidget()
        spy = QSignalSpy(w.crsSelected)
        self.assertFalse(w.hasValidSelection())
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        w.show()
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        self.assertEqual(len(spy), 1)
        w.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(len(spy), 2)
Ejemplo n.º 10
0
    def testOperationsCruftyProj(self):
        w = QgsCoordinateOperationWidget()
        self.assertFalse(w.hasSelection())
        spy = QSignalSpy(w.operationChanged)
        w.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:4283'))
        self.assertEqual(len(spy), 0)
        w.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:7844'))
        self.assertEqual(len(spy), 1)
        self.assertTrue(w.hasSelection())
        self.assertEqual(len(w.availableOperations()), 2)

        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.defaultOperation().sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal_and_distortion.gsb')
        self.assertEqual(w.defaultOperation().destinationTransformId, -1)
        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.selectedOperation().sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal_and_distortion.gsb')
        self.assertEqual(w.selectedOperation().destinationTransformId, -1)

        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.availableOperations()[1].sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal.gsb')
        self.assertEqual(w.availableOperations()[1].destinationTransformId, -1)

        op = QgsCoordinateOperationWidget.OperationDetails()
        op.sourceTransformId = w.availableOperations()[1].sourceTransformId
        w.setSelectedOperation(op)
        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.selectedOperation().sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal.gsb')
        self.assertEqual(len(spy), 2)
        w.setSelectedOperation(op)
        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.selectedOperation().sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal.gsb')
        self.assertEqual(len(spy), 2)

        op.sourceTransformId = w.availableOperations()[0].sourceTransformId
        op.destinationTransformId = -1
        w.setSelectedOperation(op)
        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.selectedOperation().sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal_and_distortion.gsb')
        self.assertEqual(len(spy), 3)

        op.destinationTransformId = w.availableOperations(
        )[1].sourceTransformId
        op.sourceTransformId = -1
        w.setSelectedOperation(op)
        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.selectedOperation().sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal.gsb')
        self.assertEqual(len(spy), 4)

        op.destinationTransformId = w.availableOperations(
        )[0].sourceTransformId
        op.sourceTransformId = -1
        w.setSelectedOperation(op)
        self.assertEqual(
            QgsDatumTransform.datumTransformToProj(
                w.selectedOperation().sourceTransformId),
            '+nadgrids=GDA94_GDA2020_conformal_and_distortion.gsb')
        self.assertEqual(len(spy), 5)
Ejemplo n.º 11
0
        def _test(autoTransaction):
            """Test buffer methods within and without transactions

            - create a feature
            - save
            - retrieve the feature
            - change geom and attrs
            - test changes are seen in the buffer
            """
            def _check_feature(wkt):

                f = next(layer_a.getFeatures())
                self.assertEqual(f.geometry().asWkt().upper(), wkt)
                f = list(buffer.addedFeatures().values())[0]
                self.assertEqual(f.geometry().asWkt().upper(), wkt)

            ml = QgsVectorLayer(
                'Point?crs=epsg:4326&field=int:integer&field=int2:integer',
                'test', 'memory')
            self.assertTrue(ml.isValid())

            d = QTemporaryDir()
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = 'GPKG'
            options.layerName = 'layer_a'
            err, msg, newFileName, newLayer = QgsVectorFileWriter.writeAsVectorFormatV3(
                ml, os.path.join(d.path(), 'transaction_test.gpkg'),
                QgsCoordinateTransformContext(), options)

            self.assertEqual(err, QgsVectorFileWriter.NoError)
            self.assertTrue(os.path.isfile(newFileName))

            layer_a = QgsVectorLayer(newFileName + '|layername=layer_a')

            self.assertTrue(layer_a.isValid())

            project = QgsProject()
            project.setAutoTransaction(autoTransaction)
            project.addMapLayers([layer_a])

            ###########################################
            # Tests with a new feature

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 123)
            f.setGeometry(QgsGeometry.fromWkt('point(7 45)'))
            self.assertTrue(layer_a.addFeatures([f]))

            _check_feature('POINT (7 45)')

            # Need to fetch the feature because its ID is NULL (-9223372036854775808)
            f = next(layer_a.getFeatures())

            self.assertEqual(len(buffer.addedFeatures()), 1)
            layer_a.undoStack().undo()
            self.assertEqual(len(buffer.addedFeatures()), 0)
            layer_a.undoStack().redo()
            self.assertEqual(len(buffer.addedFeatures()), 1)
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)

            # Now change attribute
            self.assertEqual(buffer.changedAttributeValues(), {})
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValue(f.id(), 1, 321)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])

            self.assertEqual(len(buffer.addedFeatures()), 1)
            # This is surprising: because it was a new feature it has been changed directly
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 321)

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123])
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute('int'), 123)

            # Change multiple attributes
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValues(f.id(), {1: 321, 2: 456})
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])
            self.assertEqual(spy_attribute_changed[1], [f.id(), 2, 456])
            buffer = layer_a.editBuffer()
            # This is surprising: because it was a new feature it has been changed directly
            self.assertEqual(buffer.changedAttributeValues(), {})

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            # This is because QgsVectorLayerUndoCommandChangeAttribute plural
            if not autoTransaction:
                layer_a.undoStack().undo()
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute('int'), 123)
            self.assertEqual(f.attribute('int2'), None)
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(
                spy_attribute_changed[1 if autoTransaction else 0],
                [f.id(), 2, None])
            self.assertEqual(
                spy_attribute_changed[0 if autoTransaction else 1],
                [f.id(), 1, 123])

            # Change geometry
            f = next(layer_a.getFeatures())
            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            self.assertTrue(len(spy_geometry_changed), 1)
            self.assertEqual(spy_geometry_changed[0][0], f.id())
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(9 43)').asWkt())

            _check_feature('POINT (9 43)')
            self.assertEqual(buffer.changedGeometries(), {})

            layer_a.undoStack().undo()

            _check_feature('POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            _check_feature('POINT (9 43)')

            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(10 44)')))
            _check_feature('POINT (10 44)')

            # This is another surprise: geometry edits get collapsed into a single
            # one because they have the same hardcoded id
            layer_a.undoStack().undo()
            _check_feature('POINT (7 45)')

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Tests with the existing feature

            # Get the feature
            f = next(layer_a.getFeatures())
            self.assertTrue(f.isValid())
            self.assertEqual(f.attribute('int'), 123)
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')

            # Change single attribute
            self.assertTrue(layer_a.startEditing())
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValue(f.id(), 1, 321)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])
            buffer = layer_a.editBuffer()
            self.assertEqual(buffer.changedAttributeValues(), {1: {1: 321}})

            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute(1), 321)

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute(1), 123)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123])
            self.assertEqual(buffer.changedAttributeValues(), {})

            # Change attributes
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValues(f.id(), {1: 111, 2: 654})
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(spy_attribute_changed[0], [1, 1, 111])
            self.assertEqual(spy_attribute_changed[1], [1, 2, 654])
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attributes(), [1, 111, 654])
            self.assertEqual(buffer.changedAttributeValues(),
                             {1: {
                                 1: 111,
                                 2: 654
                             }})

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            # This is because QgsVectorLayerUndoCommandChangeAttribute plural
            if not autoTransaction:
                layer_a.undoStack().undo()
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(
                spy_attribute_changed[0 if autoTransaction else 1],
                [1, 1, 123])
            self.assertEqual(
                spy_attribute_changed[1 if autoTransaction else 0],
                [1, 2, None])
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attributes(), [1, 123, None])
            self.assertEqual(buffer.changedAttributeValues(), {})

            # Change geometry
            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            self.assertEqual(spy_geometry_changed[0][0], 1)
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(9 43)').asWkt())

            f = next(layer_a.getFeatures())
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (9 43)')
            self.assertEqual(buffer.changedGeometries()[1].asWkt().upper(),
                             'POINT (9 43)')

            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            layer_a.undoStack().undo()
            self.assertEqual(spy_geometry_changed[0][0], 1)
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(7 45)').asWkt())
            self.assertEqual(buffer.changedGeometries(), {})
            f = next(layer_a.getFeatures())

            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            # Delete an existing feature
            self.assertTrue(layer_a.deleteFeature(f.id()))
            with self.assertRaises(StopIteration):
                next(layer_a.getFeatures())
            self.assertEqual(buffer.deletedFeatureIds(), [f.id()])

            layer_a.undoStack().undo()
            self.assertTrue(layer_a.getFeature(f.id()).isValid())
            self.assertEqual(buffer.deletedFeatureIds(), [])

            ###########################################
            # Test delete

            # Delete a new feature
            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 555)
            f.setGeometry(QgsGeometry.fromWkt('point(8 46)'))
            self.assertTrue(layer_a.addFeatures([f]))
            f = [
                f for f in layer_a.getFeatures() if f.attribute('int') == 555
            ][0]
            self.assertTrue(f.id() in buffer.addedFeatures())
            self.assertTrue(layer_a.deleteFeature(f.id()))
            self.assertFalse(f.id() in buffer.addedFeatures())
            self.assertFalse(f.id() in buffer.deletedFeatureIds())

            layer_a.undoStack().undo()
            self.assertTrue(f.id() in buffer.addedFeatures())

            ###########################################
            # Add attribute

            field = QgsField('attr1', QVariant.String)
            self.assertTrue(layer_a.addAttribute(field))
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [])

            layer_a.undoStack().redo()
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Remove attribute

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertNotEqual(attr_idx, -1)

            self.assertTrue(layer_a.deleteAttribute(attr_idx))
            self.assertEqual(buffer.deletedAttributeIds(), [attr_idx])
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            layer_a.undoStack().undo()
            self.assertEqual(buffer.deletedAttributeIds(), [])
            self.assertEqual(layer_a.fields().lookupField(field.name()),
                             attr_idx)

            # This is totally broken at least on OGR/GPKG: the rollback
            # does not restore the original fields
            if False:

                layer_a.undoStack().redo()
                self.assertEqual(buffer.deletedAttributeIds(), [attr_idx])
                self.assertEqual(layer_a.fields().lookupField(field.name()),
                                 -1)

                # Rollback!
                self.assertTrue(layer_a.rollBack())

                self.assertIn('attr1', layer_a.dataProvider().fields().names())
                self.assertIn('attr1', layer_a.fields().names())
                self.assertEqual(layer_a.fields().names(),
                                 layer_a.dataProvider().fields().names())

                attr_idx = layer_a.fields().lookupField(field.name())
                self.assertNotEqual(attr_idx, -1)

                self.assertTrue(layer_a.startEditing())
                attr_idx = layer_a.fields().lookupField(field.name())
                self.assertNotEqual(attr_idx, -1)

            ###########################################
            # Rename attribute

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)
            self.assertTrue(layer_a.renameAttribute(attr_idx, 'new_name'))
            self.assertEqual(layer_a.fields().lookupField('new_name'),
                             attr_idx)

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()),
                             attr_idx)
            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)

            layer_a.undoStack().redo()
            self.assertEqual(layer_a.fields().lookupField('new_name'),
                             attr_idx)
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            #############################################
            # Try hard to make this fail for transactions
            if autoTransaction:
                self.assertTrue(layer_a.commitChanges())
                self.assertTrue(layer_a.startEditing())
                f = next(layer_a.getFeatures())

                # Do
                for i in range(10):
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.changeAttributeValue(f.id(), 2, i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0], [f.id(), 2, i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: i
                                      }})
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), i)

                # Undo/redo
                for i in range(9):

                    # Undo
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().undo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 8 - i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: 8 - i
                                      }})

                    # Redo
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().redo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 9 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 9 - i])

                    # Undo again
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().undo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 8 - i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: 8 - i
                                      }})

                    # Last check
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)

                self.assertEqual(buffer.changedAttributeValues(),
                                 {f.id(): {
                                      2: 0
                                  }})
                layer_a.undoStack().undo()
                buffer = layer_a.editBuffer()
                self.assertEqual(buffer.changedAttributeValues(), {})
                f = next(layer_a.getFeatures())
                self.assertEqual(f.attribute(2), None)
Ejemplo n.º 12
0
    def testInvalidLayer(self):
        layer = QgsRasterLayer('blah', 'blah')
        self.assertTrue(layer)
        self.assertFalse(layer.isValid())
        combo = QgsRasterBandComboBox()
        combo.setLayer(layer)
        self.assertEqual(combo.count(), 0)
        self.assertTrue(combo.isEditable())

        signal_spy = QSignalSpy(combo.bandChanged)
        combo.setBand(11111)
        self.assertEqual(len(signal_spy), 1)
        self.assertEqual(signal_spy[-1][0], 11111)
        self.assertEqual(combo.currentBand(), 11111)
        combo.setBand(-11111)
        self.assertEqual(combo.currentBand(), -1)
        self.assertEqual(len(signal_spy), 2)
        self.assertEqual(signal_spy[-1][0], -1)

        # replace with valid layer
        path = os.path.join(unitTestDataPath('raster'),
                            'band3_float32_noct_epsg4326.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer2 = QgsRasterLayer(path, base_name)
        self.assertTrue(layer2.isValid())

        combo.setBand(2)
        self.assertEqual(combo.currentBand(), 2)
        self.assertEqual(len(signal_spy), 3)
        self.assertEqual(signal_spy[-1][0], 2)
        combo.setLayer(layer2)
        self.assertEqual(combo.count(), 3)
        self.assertFalse(combo.isEditable())
        self.assertEqual(combo.currentBand(), 2)
        self.assertEqual(len(signal_spy), 3)

        # back to invalid
        combo.setLayer(layer)
        self.assertEqual(combo.count(), 0)
        self.assertTrue(combo.isEditable())
        self.assertEqual(combo.currentBand(), 2)
        self.assertEqual(len(signal_spy), 3)

        # with not set option
        combo.setShowNotSetOption(True)
        combo.setBand(-1)
        self.assertEqual(combo.currentBand(), -1)
        self.assertEqual(len(signal_spy), 4)
        self.assertEqual(signal_spy[-1][0], -1)
        combo.setBand(3)
        self.assertEqual(combo.currentBand(), 3)
        self.assertEqual(len(signal_spy), 5)
        self.assertEqual(signal_spy[-1][0], 3)
        combo.setBand(-1)
        self.assertEqual(combo.currentBand(), -1)
        self.assertEqual(len(signal_spy), 6)
        self.assertEqual(signal_spy[-1][0], -1)

        combo.setLayer(layer2)
        self.assertEqual(combo.currentBand(), -1)
        self.assertEqual(len(signal_spy), 6)

        combo.setLayer(layer)
        combo.setCurrentText('bad')
        self.assertEqual(combo.currentBand(), -1)
        self.assertEqual(len(signal_spy), 6)
        self.assertEqual(signal_spy[-1][0], -1)
        combo.setCurrentText('5')
        self.assertEqual(combo.currentBand(), 5)
        self.assertEqual(len(signal_spy), 7)
        self.assertEqual(signal_spy[-1][0], 5)
        combo.setCurrentText('6.5')
        self.assertEqual(combo.currentBand(), -1)
        self.assertEqual(len(signal_spy), 8)
        self.assertEqual(signal_spy[-1][0], -1)
        combo.setCurrentText('5')
        self.assertEqual(combo.currentBand(), 5)
        self.assertEqual(len(signal_spy), 9)
        self.assertEqual(signal_spy[-1][0], 5)
        combo.setCurrentText('Not set')
        self.assertEqual(combo.currentBand(), -1)
        self.assertEqual(len(signal_spy), 10)
        self.assertEqual(signal_spy[-1][0], -1)
Ejemplo n.º 13
0
    def testLimits(self):
        w = QgsRangeSlider()
        spy = QSignalSpy(w.rangeLimitsChanged)

        w.setMaximum(50)
        self.assertEqual(w.minimum(), 0)
        self.assertEqual(w.maximum(), 50)
        self.assertEqual(len(spy), 1)
        self.assertEqual(spy[-1], [0, 50])
        w.setMaximum(50)
        self.assertEqual(len(spy), 1)

        w.setMinimum(40)
        self.assertEqual(w.minimum(), 40)
        self.assertEqual(w.maximum(), 50)
        self.assertEqual(len(spy), 2)
        self.assertEqual(spy[-1], [40, 50])
        w.setMinimum(40)
        self.assertEqual(len(spy), 2)

        w.setRangeLimits(40, 50)
        self.assertEqual(w.minimum(), 40)
        self.assertEqual(w.maximum(), 50)
        self.assertEqual(len(spy), 2)
        w.setRangeLimits(40, 60)
        self.assertEqual(w.minimum(), 40)
        self.assertEqual(w.maximum(), 60)
        self.assertEqual(len(spy), 3)
        self.assertEqual(spy[-1], [40, 60])
        w.setRangeLimits(45, 60)
        self.assertEqual(w.minimum(), 45)
        self.assertEqual(w.maximum(), 60)
        self.assertEqual(len(spy), 4)
        self.assertEqual(spy[-1], [45, 60])
        w.setRangeLimits(30, 70)
        self.assertEqual(w.minimum(), 30)
        self.assertEqual(w.maximum(), 70)
        self.assertEqual(len(spy), 5)
        self.assertEqual(spy[-1], [30, 70])

        # inconsistent ranges
        w.setMinimum(80)
        self.assertEqual(w.minimum(), 80)
        self.assertEqual(w.maximum(), 80)
        self.assertEqual(len(spy), 6)
        self.assertEqual(spy[-1], [80, 80])

        w.setRangeLimits(10, 20)
        self.assertEqual(len(spy), 7)
        w.setMaximum(8)
        self.assertEqual(w.minimum(), 8)
        self.assertEqual(w.maximum(), 8)
        self.assertEqual(len(spy), 8)
        self.assertEqual(spy[-1], [8, 8])

        w.setRangeLimits(20, 10)
        self.assertEqual(w.minimum(), 10)
        self.assertEqual(w.maximum(), 20)
        self.assertEqual(len(spy), 9)
        self.assertEqual(spy[-1], [10, 20])
        w.setRangeLimits(20, 10)
        self.assertEqual(w.minimum(), 10)
        self.assertEqual(w.maximum(), 20)
        self.assertEqual(len(spy), 9)
Ejemplo n.º 14
0
    def testThemeChanged(self):
        """
        Test that the mapTheme(s)Changed signals are correctly emitted in all relevant situations
        """
        project = QgsProject()
        collection = QgsMapThemeCollection(project)

        record = QgsMapThemeCollection.MapThemeRecord()

        theme_changed_spy = QSignalSpy(collection.mapThemeChanged)
        themes_changed_spy = QSignalSpy(collection.mapThemesChanged)

        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 1)
        self.assertEqual(theme_changed_spy[-1][0], 'theme1')
        self.assertEqual(len(themes_changed_spy), 1)

        # reinsert
        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 2)
        self.assertEqual(theme_changed_spy[-1][0], 'theme1')
        self.assertEqual(len(themes_changed_spy), 2)

        # update
        collection.update('theme1', record)
        self.assertEqual(len(theme_changed_spy), 3)
        self.assertEqual(theme_changed_spy[-1][0], 'theme1')
        self.assertEqual(len(themes_changed_spy), 3)

        # remove invalid
        collection.removeMapTheme('i wish i was a slave to an age old trade... like riding around on rail cars and working long days')
        self.assertEqual(len(theme_changed_spy), 3)
        self.assertEqual(len(themes_changed_spy), 3)
        # remove valid
        collection.removeMapTheme('theme1')
        self.assertEqual(len(theme_changed_spy), 3) # not changed - removed!
        self.assertEqual(len(themes_changed_spy), 4)

        # reinsert
        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 4)
        self.assertEqual(len(themes_changed_spy), 5)

        # clear
        collection.clear()
        self.assertEqual(len(theme_changed_spy), 4)  # not changed - removed!
        self.assertEqual(len(themes_changed_spy), 6)

        # check that mapThemeChanged is emitted if layer is removed
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")
        layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                "layer2", "memory")
        project.addMapLayers([layer, layer2])

        # record for layer1
        record.addLayerRecord(QgsMapThemeCollection.MapThemeLayerRecord(layer))
        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 5)
        self.assertEqual(len(themes_changed_spy), 7)

        # now kill layer 2
        project.removeMapLayer(layer2)
        self.assertEqual(len(theme_changed_spy), 5) # signal should not be emitted - layer is not in record
        # now kill layer 1
        project.removeMapLayer(layer)
        app.processEvents()
        self.assertEqual(len(theme_changed_spy), 6) # signal should be emitted - layer is in record
Ejemplo n.º 15
0
    def testSelection(self):
        layer = QgsVectorTileLayer(
            'type=vtpk&url={}'.format(unitTestDataPath() + '/testvtpk.vtpk'),
            'tiles')
        self.assertTrue(layer.isValid())

        self.assertFalse(layer.selectedFeatures())
        spy = QSignalSpy(layer.selectionChanged)

        # select by polygon
        selection_geometry = QgsGeometry.fromWkt(
            'Polygon ((-12225020.2316580843180418 6030602.60334861185401678, -13521860.30317855626344681 5526975.39110779482871294, -12976264.15658413991332054 4821897.29397048708051443, -12019372.45332629978656769 4884850.69550053123384714, -11650045.83101624809205532 4754746.99900492746382952, -11469579.41329662501811981 5535369.17797833122313023, -11792740.20781794004142284 6110343.57862004917114973, -12225020.2316580843180418 6030602.60334861185401678))'
        )
        context = QgsSelectionContext()
        context.setScale(17991708)
        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.SetSelection,
                               Qgis.SelectGeometryRelationship.Intersect)

        self.assertEqual(layer.selectedFeatureCount(), 8)
        self.assertCountEqual(
            set(f.id() for f in layer.selectedFeatures()), {
                3320043274240, 3320026497024, 2220498092032, 2224826613760,
                3320043274243, 2220514869248, 3324338241541, 3324338241536
            })
        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'Polygon ((-13222000 4970000, -13203000 5004000, -13189000 5073000, -13164000 5127000, -13145000 5205000, -13106000 5239000, -13047000 5274000, -12964000 5269000, -12910000 5195000, -12885000 5185000, -12846000 5185000, -12802000 5151000, -12758000 5093000, -12685000 5093000, -12611000 5107000, -12484000 5103000, -12484000 4970000, -13222000 4970000))',
                'MultiPolygon (((-12157000 5694000, -12132000 5738000, -12093000 5782000, -12039000 5817000, -11956000 5836000, -11853000 5836000, -11795000 5792000, -11785000 5763000, -11760000 5738000, -11736000 5621000, -11716000 5587000, -11653000 5528000, -11643000 5503000, -11643000 5366000, -11653000 5337000, -11692000 5278000, -11731000 5249000, -11741000 5239000, -11839000 5205000, -11863000 5220000, -11927000 5288000, -11941000 5440000, -11951000 5450000, -12005000 5450000, -12020000 5450000, -12029000 5435000, -12054000 5435000, -12093000 5450000, -12132000 5503000, -12157000 5518000, -12166000 5543000, -12166000 5650000, -12157000 5694000),(-11995000 5680000, -12015000 5626000, -12005000 5582000, -11990000 5562000, -11927000 5547000, -11907000 5528000, -11883000 5479000, -11863000 5469000, -11829000 5469000, -11809000 5489000, -11814000 5577000, -11863000 5626000, -11912000 5704000, -11966000 5704000, -11995000 5680000)),((-11521000 5773000, -11496000 5851000, -11413000 5900000, -11389000 5890000, -11325000 5787000, -11320000 5724000, -11364000 5645000, -11418000 5640000, -11462000 5655000, -11491000 5699000, -11506000 5709000, -11521000 5773000)))',
                'Polygon ((-12563000 5105000, -12470000 5102000, -12411000 4990000, -12411000 4970000, -12563000 4970000, -12563000 5105000))',
                'Polygon ((-11868000 4750000, -11809000 4882000, -11702000 4956000, -11638000 4956000, -11609000 4916000, -11574000 4892000, -11452000 4882000, -11354000 4833000, -11325000 4794000, -11291000 4765000, -11212000 4638000, -11217000 4579000, -11261000 4486000, -11266000 4432000, -11281000 4393000, -11296000 4383000, -11310000 4339000, -11398000 4300000, -11501000 4305000, -11530000 4320000, -11579000 4359000, -11633000 4427000, -11687000 4466000, -11790000 4515000, -11834000 4569000, -11873000 4652000, -11868000 4750000))',
                'Polygon ((-13228000 4960000, -13203000 5004000, -13194000 5049000, -12484000 5049000, -12484000 4869000, -12587000 4814000, -12631000 4765000, -12641000 4716000, -12680000 4652000, -12714000 4618000, -12837000 4589000, -12900000 4589000, -12944000 4608000, -12949000 4618000, -13027000 4623000, -13062000 4647000, -13135000 4662000, -13189000 4691000, -13228000 4779000, -13238000 4819000, -13238000 4907000, -13228000 4960000))',
                'MultiLineString ((-11662000 5797000, -11633000 5704000, -11589000 5640000, -11398000 5518000, -11325000 5420000, -11276000 5127000, -11247000 5053000, -11208000 4990000, -11207000 4970000),(-11305000 5337000, -11261000 5381000, -11227000 5459000, -11178000 5518000, -11105000 5562000, -11051000 5670000, -10997000 5724000, -10953000 5812000))',
                'Polygon ((-12442000 5049000, -12411000 4990000, -12411000 4956000, -12426000 4916000, -12450000 4887000, -12563000 4827000, -12563000 5049000, -12442000 5049000))',
                'Point (-12714000 5220000)'
            })
        self.assertEqual(len(spy), 1)
        self.assertNotEqual(
            layer.selectedFeatures()[0].fields().lookupField('tile_zoom'), -1)
        self.assertNotEqual(
            layer.selectedFeatures()[0].fields().lookupField('tile_layer'), -1)
        self.assertEqual(layer.selectedFeatures()[0]['tile_zoom'], 4)
        self.assertCountEqual(
            [f['tile_layer'] for f in layer.selectedFeatures()], [
                'polys', 'polys', 'polys', 'lines', 'points', 'polys', 'polys',
                'polys'
            ])

        # select same again, should be no new signal
        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.SetSelection,
                               Qgis.SelectGeometryRelationship.Intersect)
        self.assertEqual(len(spy), 1)

        # select within
        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.SetSelection,
                               Qgis.SelectGeometryRelationship.Within)
        self.assertEqual(len(spy), 2)
        self.assertCountEqual(set(f.id() for f in layer.selectedFeatures()),
                              {2220498092032, 3320043274243})
        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'Point (-12714000 5220000)',
                'Polygon ((-12563000 5105000, -12470000 5102000, -12411000 4990000, -12411000 4970000, -12563000 4970000, -12563000 5105000))'
            })

        # add to selection
        selection_geometry = QgsGeometry.fromWkt(
            'Polygon ((-11104449.68442200869321823 6041094.83693683333694935, -11461185.62642602622509003 5822856.37829908169806004, -11054086.96319791302084923 5419954.60850630886852741, -10793879.57020674645900726 5835447.05860510468482971, -11104449.68442200869321823 6041094.83693683333694935))'
        )
        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.AddToSelection,
                               Qgis.SelectGeometryRelationship.Intersect)
        self.assertEqual(len(spy), 3)
        self.assertCountEqual(
            set(f.id() for f in layer.selectedFeatures()),
            {2220498092032, 3320043274243, 3320043274240, 3320026497024})
        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'Polygon ((-12563000 5105000, -12470000 5102000, -12411000 4990000, -12411000 4970000, -12563000 4970000, -12563000 5105000))',
                'MultiLineString ((-11662000 5797000, -11633000 5704000, -11589000 5640000, -11398000 5518000, -11325000 5420000, -11276000 5127000, -11247000 5053000, -11208000 4990000, -11207000 4970000),(-11305000 5337000, -11261000 5381000, -11227000 5459000, -11178000 5518000, -11105000 5562000, -11051000 5670000, -10997000 5724000, -10953000 5812000))',
                'Point (-12714000 5220000)',
                'MultiPolygon (((-12157000 5694000, -12132000 5738000, -12093000 5782000, -12039000 5817000, -11956000 5836000, -11853000 5836000, -11795000 5792000, -11785000 5763000, -11760000 5738000, -11736000 5621000, -11716000 5587000, -11653000 5528000, -11643000 5503000, -11643000 5366000, -11653000 5337000, -11692000 5278000, -11731000 5249000, -11741000 5239000, -11839000 5205000, -11863000 5220000, -11927000 5288000, -11941000 5440000, -11951000 5450000, -12005000 5450000, -12020000 5450000, -12029000 5435000, -12054000 5435000, -12093000 5450000, -12132000 5503000, -12157000 5518000, -12166000 5543000, -12166000 5650000, -12157000 5694000),(-11995000 5680000, -12015000 5626000, -12005000 5582000, -11990000 5562000, -11927000 5547000, -11907000 5528000, -11883000 5479000, -11863000 5469000, -11829000 5469000, -11809000 5489000, -11814000 5577000, -11863000 5626000, -11912000 5704000, -11966000 5704000, -11995000 5680000)),((-11521000 5773000, -11496000 5851000, -11413000 5900000, -11389000 5890000, -11325000 5787000, -11320000 5724000, -11364000 5645000, -11418000 5640000, -11462000 5655000, -11491000 5699000, -11506000 5709000, -11521000 5773000)))'
            })

        # remove from selection
        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.RemoveFromSelection,
                               Qgis.SelectGeometryRelationship.Intersect)
        self.assertEqual(len(spy), 4)
        self.assertCountEqual(set(f.id() for f in layer.selectedFeatures()),
                              {2220498092032, 3320043274243})
        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'Point (-12714000 5220000)',
                'Polygon ((-12563000 5105000, -12470000 5102000, -12411000 4990000, -12411000 4970000, -12563000 4970000, -12563000 5105000))'
            })

        # intersect selection
        selection_geometry = QgsGeometry.fromWkt(
            'Polygon ((-12632118.89488627389073372 5457726.64942438062280416, -12862948.03383005037903786 5310835.37918743211776018, -12850357.35352402552962303 5046431.09276092518121004, -12716056.76359310187399387 4987674.58466614596545696, -12434864.90342522785067558 5113581.38772638700902462, -12632118.89488627389073372 5457726.64942438062280416))'
        )

        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.IntersectSelection,
                               Qgis.SelectGeometryRelationship.Within)
        self.assertEqual(len(spy), 5)
        self.assertCountEqual(set(f.id() for f in layer.selectedFeatures()),
                              {2220498092032})
        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()),
            {'Point (-12714000 5220000)'})

        layer.removeSelection()
        self.assertFalse(layer.selectedFeatures())
        self.assertEqual(len(spy), 6)

        layer.removeSelection()
        self.assertFalse(layer.selectedFeatures())
        self.assertEqual(len(spy), 6)

        # selection should depend on tile scale
        selection_geometry = QgsGeometry.fromWkt(
            'Polygon ((-12225020.2316580843180418 6030602.60334861185401678, -13521860.30317855626344681 5526975.39110779482871294, -12976264.15658413991332054 4821897.29397048708051443, -12019372.45332629978656769 4884850.69550053123384714, -11650045.83101624809205532 4754746.99900492746382952, -11469579.41329662501811981 5535369.17797833122313023, -11792740.20781794004142284 6110343.57862004917114973, -12225020.2316580843180418 6030602.60334861185401678))'
        )
        context = QgsSelectionContext()
        context.setScale(137882080)
        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.SetSelection,
                               Qgis.SelectGeometryRelationship.Intersect)

        self.assertEqual(len(layer.selectedFeatures()), 5)
        self.assertCountEqual(set(f.id() for f in layer.selectedFeatures()),
                              {33554432, 16777216, 0, 33554433, 33554438})
        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'MultiPolygon (((-12152000 5694000, -12132000 5733000, -12093000 5792000, -12034000 5812000, -11956000 5831000, -11858000 5831000, -11799000 5792000, -11780000 5773000, -11760000 5733000, -11741000 5616000, -11721000 5596000, -11662000 5538000, -11643000 5499000, -11643000 5362000, -11662000 5342000, -11682000 5283000, -11721000 5244000, -11741000 5244000, -11839000 5205000, -11858000 5225000, -11917000 5283000, -11936000 5440000, -11956000 5459000, -11995000 5459000, -12015000 5459000, -12034000 5440000, -12054000 5440000, -12093000 5459000, -12132000 5499000, -12152000 5518000, -12171000 5538000, -12171000 5655000, -12152000 5694000),(-11995000 5675000, -12015000 5636000, -11995000 5577000, -11995000 5557000, -11917000 5557000, -11917000 5538000, -11878000 5479000, -11858000 5479000, -11839000 5479000, -11799000 5499000, -11819000 5577000, -11858000 5636000, -11917000 5714000, -11956000 5714000, -11995000 5675000)),((-11525000 5773000, -11486000 5851000, -11408000 5909000, -11389000 5890000, -11330000 5792000, -11310000 5733000, -11369000 5655000, -11408000 5636000, -11467000 5655000, -11486000 5694000, -11506000 5714000, -11525000 5773000)))',
                'MultiPoint ((-13052000 4471000),(-9275000 4016000),(-12201000 4261000),(-10885000 4143000),(-9828000 3992000),(-9534000 4711000),(-10371000 4965000),(-11403000 5049000),(-12499000 4775000),(-11501000 2607000),(-11452000 3703000),(-11085000 4951000),(-10493000 5919000),(-12714000 5220000),(-12607000 4290000),(-12249000 3703000),(-11687000 3331000))',
                'MultiLineString ((-13091000 4188000, -13032000 4207000, -12974000 4285000, -12915000 4364000, -12778000 4442000, -12621000 4501000, -12445000 4481000, -12367000 4461000, -12328000 4461000, -12191000 4403000, -12113000 4344000, -11995000 4285000, -11858000 4285000, -11760000 4246000, -11467000 4227000, -11291000 4227000, -11173000 4285000, -11134000 4305000, -11017000 4305000, -10821000 4246000, -10645000 4246000, -10508000 4285000, -10430000 4344000, -10351000 4422000, -10195000 4520000, -10058000 4559000, -10058000 4579000, -9960000 4559000, -9921000 4540000, -9843000 4520000, -9745000 4461000, -9706000 4442000, -9549000 4422000, -9353000 4442000, -9236000 4520000, -9197000 4520000),(-12347000 4461000, -12367000 4403000, -12406000 4325000, -12426000 4305000, -12445000 4266000, -12465000 4207000, -12504000 4148000, -12621000 4109000, -12758000 4109000, -12797000 4090000, -12817000 4051000, -12856000 3992000, -12856000 3914000, -12856000 3816000, -12837000 3796000, -12797000 3777000),(-11662000 5792000, -11623000 5714000, -11584000 5636000, -11408000 5518000, -11330000 5420000, -11271000 5127000, -11252000 5049000, -11212000 4990000, -11193000 4872000, -11193000 4833000, -11193000 4814000, -11154000 4775000, -11056000 4696000, -11036000 4638000, -11075000 4559000, -11115000 4520000, -11134000 4442000, -11134000 4422000, -11056000 4227000, -11075000 4168000, -11095000 4148000, -11134000 4090000, -11134000 4031000, -11173000 3992000, -11212000 3914000, -11212000 3816000, -11193000 3757000, -11115000 3659000, -11075000 3542000, -11017000 3503000, -10978000 3444000, -10899000 3366000, -10860000 3327000, -10684000 3190000, -10664000 3150000, -10645000 3131000, -10645000 3053000, -10704000 2974000, -10723000 2955000, -10723000 2896000, -10704000 2818000, -10606000 2700000, -10528000 2661000),(-11310000 5342000, -11252000 5381000, -11232000 5459000, -11173000 5518000, -11115000 5557000, -11056000 5675000, -10997000 5733000, -10958000 5812000),(-10273000 4461000, -10254000 4364000, -10234000 4364000, -10214000 4344000, -10175000 4305000, -10097000 4305000, -10058000 4285000, -10038000 4227000, -10019000 4129000, -10019000 4109000, -9999000 4070000, -9921000 3953000, -9901000 3953000, -9804000 3933000, -9745000 3914000, -9706000 3835000, -9686000 3816000, -9627000 3796000, -9549000 3777000, -9530000 3757000, -9432000 3698000, -9353000 3679000, -9314000 3600000, -9256000 3561000),(-9843000 4520000, -9843000 4579000, -9823000 4598000, -9725000 4716000, -9725000 4735000, -9706000 4814000, -9647000 4912000, -9549000 5029000, -9530000 5146000, -9393000 5440000, -9314000 5479000, -9158000 5499000))',
                'Polygon ((-11858000 4755000, -11799000 4892000, -11702000 4951000, -11643000 4951000, -11604000 4912000, -11565000 4892000, -11447000 4892000, -11349000 4833000, -11330000 4794000, -11291000 4775000, -11212000 4638000, -11212000 4579000, -11252000 4481000, -11271000 4442000, -11271000 4403000, -11291000 4383000, -11310000 4344000, -11408000 4305000, -11506000 4305000, -11525000 4325000, -11584000 4364000, -11623000 4422000, -11682000 4461000, -11780000 4520000, -11839000 4579000, -11878000 4657000, -11858000 4755000))',
                'Polygon ((-13228000 4970000, -13208000 5009000, -13189000 5068000, -13169000 5127000, -13150000 5205000, -13110000 5244000, -13052000 5283000, -12954000 5264000, -12915000 5205000, -12876000 5185000, -12856000 5185000, -12797000 5146000, -12758000 5088000, -12680000 5088000, -12602000 5107000, -12465000 5107000, -12406000 4990000, -12406000 4951000, -12426000 4912000, -12445000 4892000, -12582000 4814000, -12621000 4775000, -12641000 4716000, -12680000 4657000, -12719000 4618000, -12837000 4598000, -12895000 4598000, -12934000 4618000, -12954000 4618000, -13032000 4618000, -13052000 4657000, -13130000 4657000, -13189000 4696000, -13228000 4775000, -13228000 4814000, -13228000 4912000, -13228000 4970000))'
            })
        self.assertEqual(len(spy), 7)

        # removing features should NOT depend on the scale
        context.setScale(237882080)
        layer.selectByGeometry(selection_geometry, context,
                               Qgis.SelectBehavior.RemoveFromSelection,
                               Qgis.SelectGeometryRelationship.Intersect)

        self.assertFalse(layer.selectedFeatures())
        self.assertEqual(len(spy), 8)

        # single feature selection
        selection_geometry = QgsGeometry.fromWkt(
            'Polygon ((-10486370.9139375202357769 3807467.1023839432746172, -10528246.57568679377436638 3799853.34570225700736046, -10490177.79227836430072784 3735136.41390792420133948, -10486370.9139375202357769 3807467.1023839432746172))'
        )
        layer.selectByGeometry(
            selection_geometry, context, Qgis.SelectBehavior.SetSelection,
            Qgis.SelectGeometryRelationship.Intersect,
            Qgis.SelectionFlags(Qgis.SelectionFlag.SingleFeatureSelection))
        self.assertEqual(len(layer.selectedFeatures()), 1)
        self.assertCountEqual(set(f.id() for f in layer.selectedFeatures()),
                              {33554436})

        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'Polygon ((-10958000 3835000, -10958000 3796000, -10919000 3835000, -10841000 3874000, -10684000 3992000, -10567000 4031000, -10410000 4031000, -10332000 3992000, -10254000 3914000, -10136000 3914000, -10058000 3874000, -10019000 3796000, -10019000 3757000, -10058000 3718000, -10097000 3718000, -10254000 3796000, -10332000 3796000, -10371000 3757000, -10371000 3718000, -10371000 3679000, -10332000 3640000, -10332000 3561000, -10410000 3483000, -10449000 3405000, -10488000 3366000, -10645000 3327000, -10723000 3366000, -10762000 3405000, -10801000 3444000, -10762000 3483000, -10801000 3522000, -10841000 3561000, -10919000 3561000, -10958000 3600000, -10958000 3640000, -10958000 3679000, -10958000 3718000, -10997000 3796000, -10958000 3835000))'
            })
        self.assertEqual(len(spy), 9)

        # select again
        layer.selectByGeometry(
            selection_geometry, context, Qgis.SelectBehavior.SetSelection,
            Qgis.SelectGeometryRelationship.Intersect,
            Qgis.SelectionFlags(Qgis.SelectionFlag.SingleFeatureSelection))
        self.assertEqual(len(layer.selectedFeatures()), 1)
        self.assertCountEqual(set(f.id() for f in layer.selectedFeatures()),
                              {33554436})

        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'Polygon ((-10958000 3835000, -10958000 3796000, -10919000 3835000, -10841000 3874000, -10684000 3992000, -10567000 4031000, -10410000 4031000, -10332000 3992000, -10254000 3914000, -10136000 3914000, -10058000 3874000, -10019000 3796000, -10019000 3757000, -10058000 3718000, -10097000 3718000, -10254000 3796000, -10332000 3796000, -10371000 3757000, -10371000 3718000, -10371000 3679000, -10332000 3640000, -10332000 3561000, -10410000 3483000, -10449000 3405000, -10488000 3366000, -10645000 3327000, -10723000 3366000, -10762000 3405000, -10801000 3444000, -10762000 3483000, -10801000 3522000, -10841000 3561000, -10919000 3561000, -10958000 3600000, -10958000 3640000, -10958000 3679000, -10958000 3718000, -10997000 3796000, -10958000 3835000))'
            })
        self.assertEqual(len(spy), 9)

        # with toggle mode
        layer.selectByGeometry(
            selection_geometry, context, Qgis.SelectBehavior.SetSelection,
            Qgis.SelectGeometryRelationship.Intersect,
            Qgis.SelectionFlags(Qgis.SelectionFlag.SingleFeatureSelection
                                | Qgis.SelectionFlag.ToggleSelection))
        self.assertFalse(layer.selectedFeatures())
        self.assertEqual(len(spy), 10)

        layer.selectByGeometry(
            selection_geometry, context, Qgis.SelectBehavior.SetSelection,
            Qgis.SelectGeometryRelationship.Intersect,
            Qgis.SelectionFlags(Qgis.SelectionFlag.SingleFeatureSelection
                                | Qgis.SelectionFlag.ToggleSelection))
        self.assertEqual(len(layer.selectedFeatures()), 1)
        self.assertCountEqual(set(f.id() for f in layer.selectedFeatures()),
                              {33554436})

        self.assertCountEqual(
            set(f.geometry().asWkt(-3) for f in layer.selectedFeatures()), {
                'Polygon ((-10958000 3835000, -10958000 3796000, -10919000 3835000, -10841000 3874000, -10684000 3992000, -10567000 4031000, -10410000 4031000, -10332000 3992000, -10254000 3914000, -10136000 3914000, -10058000 3874000, -10019000 3796000, -10019000 3757000, -10058000 3718000, -10097000 3718000, -10254000 3796000, -10332000 3796000, -10371000 3757000, -10371000 3718000, -10371000 3679000, -10332000 3640000, -10332000 3561000, -10410000 3483000, -10449000 3405000, -10488000 3366000, -10645000 3327000, -10723000 3366000, -10762000 3405000, -10801000 3444000, -10762000 3483000, -10801000 3522000, -10841000 3561000, -10919000 3561000, -10958000 3600000, -10958000 3640000, -10958000 3679000, -10958000 3718000, -10997000 3796000, -10958000 3835000))'
            })
        self.assertEqual(len(spy), 11)
Ejemplo n.º 16
0
    def testHomePath(self):
        p = QgsProject()
        path_changed_spy = QSignalSpy(p.homePathChanged)
        self.assertFalse(p.homePath())
        self.assertFalse(p.presetHomePath())

        # simulate save file
        tmp_dir = QTemporaryDir()
        tmp_file = "{}/project.qgs".format(tmp_dir.path())
        with open(tmp_file, 'w') as f:
            pass
        p.setFileName(tmp_file)

        # home path should be file path
        self.assertEqual(p.homePath(), tmp_dir.path())
        self.assertFalse(p.presetHomePath())
        self.assertEqual(len(path_changed_spy), 1)

        # manually override home path
        p.setPresetHomePath('/tmp/my_path')
        self.assertEqual(p.homePath(), '/tmp/my_path')
        self.assertEqual(p.presetHomePath(), '/tmp/my_path')
        self.assertEqual(len(path_changed_spy), 2)
        # check project scope
        scope = QgsExpressionContextUtils.projectScope(p)
        self.assertEqual(scope.variable('project_home'), '/tmp/my_path')

        # no extra signal if path is unchanged
        p.setPresetHomePath('/tmp/my_path')
        self.assertEqual(p.homePath(), '/tmp/my_path')
        self.assertEqual(p.presetHomePath(), '/tmp/my_path')
        self.assertEqual(len(path_changed_spy), 2)

        # setting file name should not affect home path is manually set
        tmp_file_2 = "{}/project/project2.qgs".format(tmp_dir.path())
        os.mkdir(tmp_dir.path() + '/project')
        with open(tmp_file_2, 'w') as f:
            pass
        p.setFileName(tmp_file_2)
        self.assertEqual(p.homePath(), '/tmp/my_path')
        self.assertEqual(p.presetHomePath(), '/tmp/my_path')
        self.assertEqual(len(path_changed_spy), 2)

        scope = QgsExpressionContextUtils.projectScope(p)
        self.assertEqual(scope.variable('project_home'), '/tmp/my_path')

        # clear manual path
        p.setPresetHomePath('')
        self.assertEqual(p.homePath(), tmp_dir.path() + '/project')
        self.assertFalse(p.presetHomePath())
        self.assertEqual(len(path_changed_spy), 3)

        scope = QgsExpressionContextUtils.projectScope(p)
        self.assertEqual(scope.variable('project_home'),
                         tmp_dir.path() + '/project')

        # relative path
        p.setPresetHomePath('../home')
        self.assertEqual(p.homePath(), tmp_dir.path() + '/home')
        self.assertEqual(p.presetHomePath(), '../home')
        self.assertEqual(len(path_changed_spy), 4)

        scope = QgsExpressionContextUtils.projectScope(p)
        self.assertEqual(scope.variable('project_home'),
                         tmp_dir.path() + '/home')

        # relative path, no filename
        p.setFileName('')
        self.assertEqual(p.homePath(), '../home')
        self.assertEqual(p.presetHomePath(), '../home')

        scope = QgsExpressionContextUtils.projectScope(p)
        self.assertEqual(scope.variable('project_home'), '../home')
Ejemplo n.º 17
0
    def test_ring_vertex_count(self):
        # valid ring
        g = QgsGeometry.fromWkt("Polygon ((0 0, 10 0, 10 10, 0 0))")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 0)

        # not enough vertices
        g = QgsGeometry.fromWkt("Polygon ((0 0, 10 0, 10 10))")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 1)

        self.assertEqual(spy[0][0].where(), QgsPointXY())
        self.assertEqual(spy[0][0].what(), 'ring 0 with less than four points')

        g = QgsGeometry.fromWkt("Polygon ((0 0, 10 0, 0 0))")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 1)

        self.assertEqual(spy[0][0].where(), QgsPointXY())
        self.assertEqual(spy[0][0].what(), 'ring 0 with less than four points')

        g = QgsGeometry.fromWkt("Polygon ((0 0, 10 0))")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 1)

        self.assertEqual(spy[0][0].where(), QgsPointXY())
        self.assertEqual(spy[0][0].what(), 'ring 0 with less than four points')

        g = QgsGeometry.fromWkt("Polygon ((0 0))")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 1)

        self.assertEqual(spy[0][0].where(), QgsPointXY())
        self.assertEqual(spy[0][0].what(), 'ring 0 with less than four points')

        g = QgsGeometry.fromWkt("Polygon (())")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 0)

        g = QgsGeometry.fromWkt(
            "Polygon ((0 0, 10 0, 10 10, 0 0),(1 1, 2 1, 2 2))")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 1)

        self.assertEqual(spy[0][0].where(), QgsPointXY())
        self.assertEqual(spy[0][0].what(), 'ring 1 with less than four points')

        g = QgsGeometry.fromWkt(
            "Polygon ((0 0, 10 0, 10 10, 0 0),(1 1, 2 1, 2 2, 1 1))")

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 0)

        g = QgsGeometry.fromWkt(
            "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 1),(3 3, 3 4, 4 4))"
        )

        validator = QgsGeometryValidator(g)
        spy = QSignalSpy(validator.errorFound)
        validator.run()
        self.assertEqual(len(spy), 1)

        self.assertEqual(spy[0][0].where(), QgsPointXY())
        self.assertEqual(spy[0][0].what(), 'ring 2 with less than four points')
Ejemplo n.º 18
0
    def testSelectNextByZOrder(self):
        p = QgsProject()
        l = QgsLayout(p)

        # add some items
        item1 = QgsLayoutItemPicture(l)
        l.addItem(item1)
        item2 = QgsLayoutItemPicture(l)
        l.addItem(item2)
        item3 = QgsLayoutItemPicture(l)
        item3.setLocked(True)
        l.addItem(item3)

        view = QgsLayoutView()
        # no layout, no crash
        view.selectNextItemAbove()
        view.selectNextItemBelow()

        view.setCurrentLayout(l)

        focused_item_spy = QSignalSpy(view.itemFocused)

        # no selection
        view.selectNextItemAbove()
        view.selectNextItemBelow()
        self.assertEqual(len(focused_item_spy), 0)

        l.setSelectedItem(item1)
        self.assertEqual(len(focused_item_spy), 1)
        # already bottom most
        view.selectNextItemBelow()
        self.assertTrue(item1.isSelected())
        self.assertFalse(item2.isSelected())
        self.assertFalse(item3.isSelected())
        self.assertEqual(len(focused_item_spy), 1)

        view.selectNextItemAbove()
        self.assertFalse(item1.isSelected())
        self.assertTrue(item2.isSelected())
        self.assertFalse(item3.isSelected())
        self.assertEqual(len(focused_item_spy), 2)

        view.selectNextItemAbove()
        self.assertFalse(item1.isSelected())
        self.assertFalse(item2.isSelected())
        self.assertTrue(item3.isSelected())
        self.assertEqual(len(focused_item_spy), 3)

        view.selectNextItemAbove()  # already top most
        self.assertFalse(item1.isSelected())
        self.assertFalse(item2.isSelected())
        self.assertTrue(item3.isSelected())
        self.assertEqual(len(focused_item_spy), 3)

        view.selectNextItemBelow()
        self.assertFalse(item1.isSelected())
        self.assertTrue(item2.isSelected())
        self.assertFalse(item3.isSelected())
        self.assertEqual(len(focused_item_spy), 4)

        view.selectNextItemBelow()
        self.assertTrue(item1.isSelected())
        self.assertFalse(item2.isSelected())
        self.assertFalse(item3.isSelected())
        self.assertEqual(len(focused_item_spy), 5)

        view.selectNextItemBelow()  # back to bottom most
        self.assertTrue(item1.isSelected())
        self.assertFalse(item2.isSelected())
        self.assertFalse(item3.isSelected())
        self.assertEqual(len(focused_item_spy), 5)
Ejemplo n.º 19
0
    def test_geocode(self):
        geocoder = TestGeocoder()
        canvas = QgsMapCanvas()
        filter = QgsGeocoderLocatorFilter('testgeocoder', 'my geocoder',
                                          'pref', geocoder, canvas,
                                          QgsRectangle(-1, -1, 1, 1))

        self.assertEqual(filter.name(), 'testgeocoder')
        self.assertEqual(filter.displayName(), 'my geocoder')
        self.assertEqual(filter.prefix(), 'pref')
        self.assertEqual(filter.geocoder(), geocoder)
        self.assertEqual(filter.boundingBox(), QgsRectangle(-1, -1, 1, 1))

        spy = QSignalSpy(filter.resultFetched)

        context = QgsLocatorContext()
        feedback = QgsFeedback()

        # no results
        filter.fetchResults('cvxbcvb', context, feedback)
        self.assertEqual(len(spy), 0)

        # one result
        filter.fetchResults('a', context, feedback)
        self.assertEqual(len(spy), 1)
        res = spy[-1][0]
        self.assertEqual(res.displayString, 'res 1')
        # some sip weirdness here -- if we directly access the QgsLocatorResult object here then we get segfaults!
        # so instead convert back to QgsGeocoderResult. This makes the test more robust anyway...
        geocode_result = filter.locatorResultToGeocoderResult(res)
        self.assertEqual(geocode_result.identifier(), 'res 1')
        self.assertEqual(geocode_result.geometry().asWkt(), 'Point (1 2)')
        self.assertEqual(geocode_result.crs().authid(), 'EPSG:4326')
        self.assertEqual(geocode_result.additionalAttributes(), {
            'b': 123,
            'c': 'xyz'
        })
        self.assertTrue(geocode_result.viewport().isNull())
        self.assertFalse(geocode_result.description())
        self.assertFalse(geocode_result.group())

        # two possible results
        filter.fetchResults('b', context, feedback)
        self.assertEqual(len(spy), 3)
        res1 = spy[-2][0]
        res2 = spy[-1][0]
        self.assertEqual(res1.displayString, 'res 1')
        geocode_result = filter.locatorResultToGeocoderResult(res1)
        self.assertEqual(geocode_result.identifier(), 'res 1')
        self.assertEqual(geocode_result.geometry().asWkt(), 'Point (11 12)')
        self.assertEqual(geocode_result.crs().authid(), 'EPSG:4326')
        self.assertEqual(geocode_result.additionalAttributes(), {
            'b': 123,
            'c': 'xyz'
        })
        self.assertTrue(geocode_result.viewport().isNull())
        self.assertEqual(geocode_result.description(), 'desc')
        self.assertEqual(geocode_result.group(), 'group')
        self.assertEqual(res2.displayString, 'res 2')
        geocode_result = filter.locatorResultToGeocoderResult(res2)
        self.assertEqual(geocode_result.identifier(), 'res 2')
        self.assertEqual(geocode_result.geometry().asWkt(), 'Point (13 14)')
        self.assertEqual(geocode_result.crs().authid(), 'EPSG:3857')
        self.assertEqual(geocode_result.additionalAttributes(), {'d': 456})
        self.assertEqual(geocode_result.viewport(), QgsRectangle(1, 2, 3, 4))
        self.assertFalse(geocode_result.description())
        self.assertFalse(geocode_result.group())
Ejemplo n.º 20
0
    def test_addRemoveLayersSignals(self):
        """ test that signals are correctly emitted when removing map layers"""
        QgsProject.instance().removeAllMapLayers()

        layers_will_be_removed_spy = QSignalSpy(
            QgsProject.instance().layersWillBeRemoved)
        layer_will_be_removed_spy_str = QSignalSpy(
            QgsProject.instance().layerWillBeRemoved[str])
        layer_will_be_removed_spy_layer = QSignalSpy(
            QgsProject.instance().layerWillBeRemoved[QgsMapLayer])
        layers_removed_spy = QSignalSpy(QgsProject.instance().layersRemoved)
        layer_removed_spy = QSignalSpy(QgsProject.instance().layerRemoved)
        remove_all_spy = QSignalSpy(QgsProject.instance().removeAll)

        l1 = createLayer('l1')
        l2 = createLayer('l2')
        l3 = createLayer('l3')
        l4 = createLayer('l4')
        QgsProject.instance().addMapLayers([l1, l2, l3, l4])

        # remove 1 layer
        QgsProject.instance().removeMapLayer(l1)
        # can't seem to actually test the data which was emitted, so best we can do is test
        # the signal count
        self.assertEqual(len(layers_will_be_removed_spy), 1)
        self.assertEqual(len(layer_will_be_removed_spy_str), 1)
        self.assertEqual(len(layer_will_be_removed_spy_layer), 1)
        self.assertEqual(len(layers_removed_spy), 1)
        self.assertEqual(len(layer_removed_spy), 1)
        self.assertEqual(len(remove_all_spy), 0)
        self.assertEqual(QgsProject.instance().count(), 3)

        # remove 2 layers at once
        QgsProject.instance().removeMapLayers([l2.id(), l3.id()])
        self.assertEqual(len(layers_will_be_removed_spy), 2)
        self.assertEqual(len(layer_will_be_removed_spy_str), 3)
        self.assertEqual(len(layer_will_be_removed_spy_layer), 3)
        self.assertEqual(len(layers_removed_spy), 2)
        self.assertEqual(len(layer_removed_spy), 3)
        self.assertEqual(len(remove_all_spy), 0)
        self.assertEqual(QgsProject.instance().count(), 1)

        # remove all
        QgsProject.instance().removeAllMapLayers()
        self.assertEqual(len(layers_will_be_removed_spy), 3)
        self.assertEqual(len(layer_will_be_removed_spy_str), 4)
        self.assertEqual(len(layer_will_be_removed_spy_layer), 4)
        self.assertEqual(len(layers_removed_spy), 3)
        self.assertEqual(len(layer_removed_spy), 4)
        self.assertEqual(len(remove_all_spy), 1)

        #remove some layers which aren't in the registry
        QgsProject.instance().removeMapLayers(['asdasd'])
        self.assertEqual(len(layers_will_be_removed_spy), 3)
        self.assertEqual(len(layer_will_be_removed_spy_str), 4)
        self.assertEqual(len(layer_will_be_removed_spy_layer), 4)
        self.assertEqual(len(layers_removed_spy), 3)
        self.assertEqual(len(layer_removed_spy), 4)
        self.assertEqual(len(remove_all_spy), 1)

        l5 = createLayer('test5')
        QgsProject.instance().removeMapLayer(l5)
        self.assertEqual(len(layers_will_be_removed_spy), 3)
        self.assertEqual(len(layer_will_be_removed_spy_str), 4)
        self.assertEqual(len(layer_will_be_removed_spy_layer), 4)
        self.assertEqual(len(layers_removed_spy), 3)
        self.assertEqual(len(layer_removed_spy), 4)
        self.assertEqual(len(remove_all_spy), 1)
    def testCombo(self):
        """ test combobox functionality """
        md = QgsProviderRegistry.instance().providerMetadata('postgres')
        conn = md.createConnection(self.uri, {})
        md.saveConnection(conn, 'mycon')

        m = QgsDatabaseTableComboBox('postgres', 'mycon')
        self.assertGreaterEqual(m.comboBox().count(), 3)

        text = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        self.assertIn('information_schema.attributes', text)
        self.assertIn('qgis_test.some_poly_data', text)
        self.assertLess(text.index('information_schema.attributes'), text.index('qgis_test.some_poly_data'))
        self.assertTrue(m.currentSchema())
        self.assertTrue(m.currentTable())

        m.setSchema('information_schema')
        m.setTable('attributes')
        spy = QSignalSpy(m.tableChanged)

        m.setSchema('qgis_test')
        text = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        self.assertNotIn('information_schema.attributes', text)
        self.assertNotIn('attributes', text)
        self.assertIn('some_poly_data', text)

        self.assertEqual(m.currentTable(), '')
        self.assertEqual(m.currentSchema(), '')
        self.assertEqual(len(spy), 1)
        self.assertFalse(spy[-1][0])

        m.setTable('')
        self.assertEqual(m.currentTable(), '')
        self.assertEqual(m.currentSchema(), '')
        self.assertEqual(len(spy), 1)
        self.assertFalse(spy[-1][0])
        m.setTable('someData')
        self.assertEqual(len(spy), 2)
        self.assertEqual(m.currentSchema(), 'qgis_test')
        self.assertEqual(m.currentTable(), 'someData')
        self.assertEqual(spy[-1][0], 'someData')
        self.assertEqual(spy[-1][1], 'qgis_test')

        fields = QgsFields()
        fields.append(QgsField('test', QVariant.String))
        conn.createVectorTable('qgis_test', 'myNewTable', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:3857'), False, {})

        text2 = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        # tables are not automatically refreshed
        self.assertEqual(text2, text)

        # but setting a new connection should fix this!
        md = QgsProviderRegistry.instance().providerMetadata('postgres')
        conn2 = md.createConnection(self.uri, {})
        md.saveConnection(conn2, 'another')
        m.setConnectionName('another', 'postgres')
        # ideally there'd be no extra signal here, but it's a minor issue...
        self.assertEqual(len(spy), 3)
        self.assertEqual(m.currentTable(), 'someData')
        self.assertEqual(m.currentSchema(), 'qgis_test')
        self.assertEqual(spy[-1][0], 'someData')
        self.assertEqual(spy[-1][1], 'qgis_test')

        text2 = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        self.assertNotEqual(text2, text)
        self.assertIn('myNewTable', text2)

        m.setTable('myNewTable')
        self.assertEqual(len(spy), 4)
        self.assertEqual(m.currentTable(), 'myNewTable')
        self.assertEqual(m.currentSchema(), 'qgis_test')
        self.assertEqual(spy[-1][0], 'myNewTable')
        self.assertEqual(spy[-1][1], 'qgis_test')

        # no auto drop
        conn.dropVectorTable('qgis_test', 'myNewTable')
        self.assertEqual(len(spy), 4)
        self.assertEqual(m.currentTable(), 'myNewTable')
        self.assertEqual(m.currentSchema(), 'qgis_test')
        self.assertEqual(spy[-1][0], 'myNewTable')
        self.assertEqual(spy[-1][1], 'qgis_test')

        m.refreshTables()
        text2 = [m.comboBox().itemText(i) for i in range(m.comboBox().count())]
        self.assertNotIn('myNewTable', text2)
        self.assertEqual(len(spy), 5)
        self.assertFalse(m.currentSchema())
        self.assertFalse(spy[-1][0])