コード例 #1
0
class TestSimplePolySimplePoly(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        print('\nINFO: Set up simple_pol-simple_pol')
        from AppendFeaturesToLayer.append_features_to_layer_plugin import AppendFeaturesToLayerPlugin
        self.plugin = AppendFeaturesToLayerPlugin(get_iface)
        self.plugin.initGui()
        self.common = CommonTests()

    def test_copy_all(self):
        print('\nINFO: Validating simple_pol-simple_pol copy&paste all...')
        res = self.common._test_copy_all('source_simple_polygons',
                                         'target_simple_polygons')
        layer = res['TARGET_LAYER']
        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual(res['APPENDED_COUNT'], 2)

    def test_copy_selected(self):
        print(
            '\nINFO: Validating simple_pol-simple_pol copy&paste selected...')
        res = self.common._test_copy_selected('source_simple_polygons',
                                              'target_simple_polygons')
        layer = res['TARGET_LAYER']

        self.assertEqual(layer.featureCount(), 1)
        self.assertEqual(res[APPENDED_COUNT], 1)

    def test_update(self):
        print('\nINFO: Validating simple_pol-simple_pol update...')
        self.common._test_update('source_simple_polygons',
                                 'target_simple_polygons')

    def test_skip_all(self):
        print(
            '\nINFO: Validating simple_pol-simple_pol skip (all) duplicate features...'
        )
        self.common._test_skip_all('source_simple_polygons',
                                   'target_simple_polygons')

    def test_skip_some(self):
        print(
            '\nINFO: Validating simple_pol-simple_pol skip (some) duplicate features...'
        )
        self.common._test_skip_some('source_simple_polygons',
                                    'target_simple_polygons')

    def test_skip_none(self):
        print(
            '\nINFO: Validating simple_pol-simple_pol skip (none) duplicate features...'
        )
        self.common._test_skip_none('source_simple_polygons',
                                    'target_simple_polygons')

    @classmethod
    def tearDownClass(self):
        print('INFO: Tear down simple_pol-simple_pol')
        self.plugin.unload()
コード例 #2
0
class TestPluginLoad(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        print('\nINFO: Set up test_plugin_load')
        from AppendFeaturesToLayer.append_features_to_layer_plugin import AppendFeaturesToLayerPlugin
        self.plugin = AppendFeaturesToLayerPlugin(get_iface)
        self.plugin.initGui()

    def test_plugin_load(self):
        print('INFO: Validating plugin load...')
        self.assertIsNotNone(self.plugin.provider)
        self.assertIn("ETL_LOAD", [
            provider.name()
            for provider in QgsApplication.processingRegistry().providers()
        ])

    @classmethod
    def tearDownClass(self):
        print('INFO: Tear down test_plugin_load')
        self.plugin.unload()
コード例 #3
0
class TestSimplePolySimpleLine(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        print('\nINFO: Set up simple_pol-simple_lin')
        from AppendFeaturesToLayer.append_features_to_layer_plugin import AppendFeaturesToLayerPlugin
        self.plugin = AppendFeaturesToLayerPlugin(get_iface)
        self.plugin.initGui()
        self.common = CommonTests()

    def test_copy_all(self):
        print('\nINFO: Validating simple_pol-simple_lin copy&paste all...')
        res = self.common._test_copy_all('source_simple_polygons',
                                         'target_simple_lines')
        layer = res['TARGET_LAYER']
        self.assertEqual(layer.featureCount(), 1)

    def test_copy_selected(self):
        print(
            '\nINFO: Validating simple_pol-simple_lin copy&paste selected...')
        res = self.common._test_copy_selected('source_simple_polygons',
                                              'target_simple_lines')
        layer = res['TARGET_LAYER']
        self.assertEqual(layer.featureCount(),
                         0)  # Selected id has a hole, cannot be copied
        self.assertEqual(res[APPENDED_COUNT], 0)

        res = self.common._test_copy_selected('source_simple_polygons',
                                              'target_simple_lines', 2)
        layer = res['TARGET_LAYER']
        self.assertEqual(layer.featureCount(), 1)
        self.assertEqual(res[APPENDED_COUNT], 1)

    @classmethod
    def tearDownClass(self):
        print('INFO: Tear down simple_pol-simple_lin')
        self.plugin.unload()
コード例 #4
0
 def setUpClass(self):
     print('\nINFO: Set up test_parameter_errors')
     from AppendFeaturesToLayer.append_features_to_layer_plugin import AppendFeaturesToLayerPlugin
     self.plugin = AppendFeaturesToLayerPlugin(get_iface)
     self.plugin.initGui()
コード例 #5
0
class TestParameterErrors(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        print('\nINFO: Set up test_parameter_errors')
        from AppendFeaturesToLayer.append_features_to_layer_plugin import AppendFeaturesToLayerPlugin
        self.plugin = AppendFeaturesToLayerPlugin(get_iface)
        self.plugin.initGui()

    def test_fields_no_on_duplicate(self):
        print('\nINFO: Validating fields with no on_duplicate option...')

        gpkg = get_test_file_copy_path('insert_features_to_layer_test.gpkg')

        res = processing.run("etl_load:appendfeaturestolayer",
                       {'SOURCE_LAYER': "{}|layername=source_table".format(gpkg),
                        'SOURCE_FIELD': 'name',
                        'TARGET_LAYER': "{}|layername=target_table".format(gpkg),
                        'TARGET_FIELD': 'name',
                        'ACTION_ON_DUPLICATE': 0})  # No action

        self.assertIsNone(res['TARGET_LAYER'])  # The algorithm doesn't run, and doesn't give an output
        self.assertIsNone(res[APPENDED_COUNT])
        self.assertIsNone(res[UPDATED_COUNT])
        self.assertIsNone(res[SKIPPED_COUNT])

        # Target layer remains untouched
        layer = QgsVectorLayer("{}|layername=target_table".format(gpkg), 'a', 'ogr')
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.featureCount(), 0)

    def test_no_fields_but_on_duplicate(self):
        print('\nINFO: Validating no fields but with on_duplicate option...')

        gpkg = get_test_file_copy_path('insert_features_to_layer_test.gpkg')

        res = processing.run("etl_load:appendfeaturestolayer",
                       {'SOURCE_LAYER': "{}|layername=source_table".format(gpkg),
                        'SOURCE_FIELD': None,
                        'TARGET_LAYER': "{}|layername=target_table".format(gpkg),
                        'TARGET_FIELD': 'name',
                        'ACTION_ON_DUPLICATE': 1})  # Skip

        self.assertIsNone(res['TARGET_LAYER'])  # The algorithm doesn't run, and doesn't give an output
        self.assertIsNone(res[APPENDED_COUNT])
        self.assertIsNone(res[UPDATED_COUNT])
        self.assertIsNone(res[SKIPPED_COUNT])

        # Target layer remains untouched
        layer = QgsVectorLayer("{}|layername=target_table".format(gpkg), 'a', 'ogr')
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.featureCount(), 0)


        # Now the other way around
        res = processing.run("etl_load:appendfeaturestolayer",
                             {'SOURCE_LAYER': "{}|layername=source_table".format(gpkg),
                              'SOURCE_FIELD': 'name',
                              'TARGET_LAYER': "{}|layername=target_table".format(gpkg),
                              'TARGET_FIELD': None,
                              'ACTION_ON_DUPLICATE': 1})  # Skip

        self.assertIsNone(res['TARGET_LAYER'])  # The algorithm doesn't run, and doesn't give an output
        self.assertIsNone(res[APPENDED_COUNT])
        self.assertIsNone(res[UPDATED_COUNT])
        self.assertIsNone(res[SKIPPED_COUNT])

        # Target layer remains untouched
        layer = QgsVectorLayer("{}|layername=target_table".format(gpkg), 'a', 'ogr')
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.featureCount(), 0)

    def test_read_only_target_layer(self):
        print('\nINFO: Validating read-only target layer...')

        gpkg = get_test_file_copy_path('insert_features_to_layer_test.gpkg')
        csv = get_test_file_copy_path('sample.csv')
        layer = QgsVectorLayer("file://{}?delimiter=;&xField=x&yField=y&crs=epsg:3116".format(csv), 'a', "delimitedtext")
        self.assertTrue(layer.isValid())

        res = processing.run("etl_load:appendfeaturestolayer",
                       {'SOURCE_LAYER': "{}|layername=source_table".format(gpkg),
                        'SOURCE_FIELD': None,
                        'TARGET_LAYER': layer,
                        'TARGET_FIELD': None,
                        'ACTION_ON_DUPLICATE': 0})  # No action

        self.assertIsNone(res['TARGET_LAYER'])  # The algorithm doesn't run, and doesn't give an output
        self.assertIsNone(res[APPENDED_COUNT])
        self.assertIsNone(res[UPDATED_COUNT])
        self.assertIsNone(res[SKIPPED_COUNT])

        self.assertEqual(layer.featureCount(), 2)

    @classmethod
    def tearDownClass(self):
        print('INFO: Tear down test_parameter_errors')
        self.plugin.unload()
コード例 #6
0
 def setUpClass(self):
     print('\nINFO: Set up simple_pol-simple_lin')
     from AppendFeaturesToLayer.append_features_to_layer_plugin import AppendFeaturesToLayerPlugin
     self.plugin = AppendFeaturesToLayerPlugin(get_iface)
     self.plugin.initGui()
     self.common = CommonTests()
コード例 #7
0
class TestTableTable(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        print('\nINFO: Set up test_table_table')
        from AppendFeaturesToLayer.append_features_to_layer_plugin import AppendFeaturesToLayerPlugin
        self.plugin = AppendFeaturesToLayerPlugin(get_iface)
        self.plugin.initGui()
        self.common = CommonTests()

    def test_copy_all(self):
        print('\nINFO: Validating table-table copy&paste all...')
        res = self.common._test_copy_all('source_table', 'target_table')
        layer = res['TARGET_LAYER']
        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual(res[APPENDED_COUNT], 2)

    def test_copy_selected(self):
        print('\nINFO: Validating table-table copy&paste selected...')
        res = self.common._test_copy_selected('source_table', 'target_table')
        layer = res['TARGET_LAYER']

        self.assertEqual(layer.featureCount(), 1)
        self.assertEqual(res[APPENDED_COUNT], 1)

    def test_update(self):
        print('\nINFO: Validating table-table update...')
        self.common._test_update('source_table', 'target_table')

    def test_skip_all(self):
        print(
            '\nINFO: Validating table-table skip (all) duplicate features...')
        self.common._test_skip_all('source_table', 'target_table')

    def test_skip_some(self):
        print(
            '\nINFO: Validating table-table skip (some) duplicate features...')
        self.common._test_skip_some('source_table', 'target_table')

    def test_skip_none(self):
        print(
            '\nINFO: Validating table-table skip (none) duplicate features...')
        self.common._test_skip_none('source_table', 'target_table')

    def test_skip_update_1_m(self):
        print('\nINFO: Validating table-table skip/update 1:m...')
        # Let's copy twice the same 2 features to end up with 1:m (twice)
        res = self.common._test_copy_all('source_table', 'target_table')
        layer = res['TARGET_LAYER']
        output_path = layer.source().split('|')[0]
        res = self.common._test_copy_all('source_table', 'target_table',
                                         output_path)
        layer = res['TARGET_LAYER']
        self.assertEqual(layer.featureCount(), 4)
        self.assertEqual(res[APPENDED_COUNT], 2)

        # Now let's check counts for skip action
        res = processing.run(
            "etl_load:appendfeaturestolayer", {
                'SOURCE_LAYER':
                "{}|layername={}".format(output_path, 'source_table'),
                'SOURCE_FIELD':
                'name',
                'TARGET_LAYER':
                layer,
                'TARGET_FIELD':
                'name',
                'ACTION_ON_DUPLICATE':
                1
            })  # Skip

        self.assertEqual(layer.featureCount(), 4)
        self.assertEqual(res[APPENDED_COUNT], 0)
        self.assertIsNone(res[UPDATED_COUNT]
                          )  # This is None because ACTION_ON_DUPLICATE is Skip
        self.assertEqual(res[SKIPPED_COUNT], 4)

        # And counts for update action
        res = processing.run(
            "etl_load:appendfeaturestolayer", {
                'SOURCE_LAYER':
                "{}|layername={}".format(output_path, 'source_table'),
                'SOURCE_FIELD':
                'name',
                'TARGET_LAYER':
                layer,
                'TARGET_FIELD':
                'name',
                'ACTION_ON_DUPLICATE':
                2
            })  # Update

        self.assertEqual(layer.featureCount(), 4)
        self.assertEqual(res[APPENDED_COUNT], 0)
        self.assertEqual(res[UPDATED_COUNT], 4)
        self.assertIsNone(
            res[SKIPPED_COUNT]
        )  # This is None because ACTION_ON_DUPLICATE is Update

    def test_skip_update_m_1(self):
        print('\nINFO: Validating table-table skip/update m:1...')

        res = self.common._test_copy_all('source_table', 'target_table')
        layer = res['TARGET_LAYER']
        output_path = layer.source().split('|')[0]

        # Let's give both source features the same name to have an m:1 scenario
        input_layer_path = "{}|layername={}".format(output_path,
                                                    'source_table')
        input_layer = QgsVectorLayer(input_layer_path, 'layer name', 'ogr')
        input_layer.dataProvider().changeAttributeValues({2: {
            1: 'abc'
        }})  # name --> abc

        s = set()
        s.update([f['name'] for f in input_layer.getFeatures()])
        self.assertEqual(len(s), 1)  # Have really both features the same name?

        # Now let's check counts for skip action
        res = processing.run(
            "etl_load:appendfeaturestolayer", {
                'SOURCE_LAYER': input_layer,
                'SOURCE_FIELD': 'name',
                'TARGET_LAYER': layer,
                'TARGET_FIELD': 'name',
                'ACTION_ON_DUPLICATE': 1
            })  # Skip

        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual(res[APPENDED_COUNT], 0)
        self.assertIsNone(res[UPDATED_COUNT]
                          )  # This is None because ACTION_ON_DUPLICATE is Skip
        self.assertEqual(res[SKIPPED_COUNT], 2)

        # And counts for update action
        res = processing.run(
            "etl_load:appendfeaturestolayer", {
                'SOURCE_LAYER': input_layer,
                'SOURCE_FIELD': 'name',
                'TARGET_LAYER': layer,
                'TARGET_FIELD': 'name',
                'ACTION_ON_DUPLICATE': 2
            })  # Update

        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual(res[APPENDED_COUNT], 0)
        self.assertEqual(
            res[UPDATED_COUNT],
            1)  # We do 2 updates on a single feature, the count is 1!
        self.assertIsNone(
            res[SKIPPED_COUNT]
        )  # This is None because ACTION_ON_DUPLICATE is Update

    def test_skip_different_field_types_can_convert(self):
        print(
            '\nINFO: Validating table-table skip different field types can convert...'
        )

        res = self.common._test_copy_selected('source_table', 'target_table')
        layer = res['TARGET_LAYER']

        self.assertEqual(layer.featureCount(), 1)
        self.assertEqual(res[APPENDED_COUNT], 1)

        output_path = layer.source().split('|')[0]

        # Let's overwrite the target feature to have a float as string
        layer.dataProvider().changeAttributeValues({1: {
            1: "3.1416"
        }})  # name --> "3.1416"

        check_list_values = [f['name'] for f in layer.getFeatures()]
        self.assertEqual(len(check_list_values), 1)
        self.assertEqual(check_list_values[0], "3.1416")

        input_layer_path = "{}|layername={}".format(output_path,
                                                    'source_table')
        input_layer = QgsVectorLayer(input_layer_path, 'layer name', 'ogr')

        # Now let's check counts for skip action
        res = processing.run(
            "etl_load:appendfeaturestolayer", {
                'SOURCE_LAYER': input_layer,
                'SOURCE_FIELD': 'real_value',
                'TARGET_LAYER': layer,
                'TARGET_FIELD': 'name',
                'ACTION_ON_DUPLICATE': 1
            })  # Skip

        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual(res[APPENDED_COUNT], 1)
        self.assertIsNone(res[UPDATED_COUNT]
                          )  # This is None because ACTION_ON_DUPLICATE is Skip
        self.assertEqual(res[SKIPPED_COUNT], 1)

        # Now test the reverse
        res = self.common._test_copy_selected('source_table', 'target_table')
        layer = res['TARGET_LAYER']

        self.assertEqual(layer.featureCount(), 1)
        self.assertEqual(res[APPENDED_COUNT], 1)

        output_path = layer.source().split('|')[0]

        # Let's overwrite the target feature to have a float as string
        input_layer_path = "{}|layername={}".format(output_path,
                                                    'source_table')
        input_layer = QgsVectorLayer(input_layer_path, 'layer name', 'ogr')
        input_layer.dataProvider().changeAttributeValues({1: {
            1: "3.1416"
        }})  # name --> "3.1416"

        check_list_values = [f['name'] for f in input_layer.getFeatures()]
        self.assertEqual(len(check_list_values), 2)
        self.assertEqual(check_list_values, ["3.1416", "def"])

        # Now let's check counts for skip action
        res = processing.run(
            "etl_load:appendfeaturestolayer", {
                'SOURCE_LAYER': input_layer,
                'SOURCE_FIELD': 'name',
                'TARGET_LAYER': layer,
                'TARGET_FIELD': 'real_value',
                'ACTION_ON_DUPLICATE': 1
            })  # Skip

        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual(res[APPENDED_COUNT], 1)
        self.assertIsNone(res[UPDATED_COUNT]
                          )  # This is None because ACTION_ON_DUPLICATE is Skip
        self.assertEqual(res[SKIPPED_COUNT], 1)

    def test_skip_different_field_types_cannot_convert(self):
        print(
            '\nINFO: Validating table-table skip different field types cannot convert...'
        )

        # Since it can't convert between types (and since types are different), no duplicates can be found, so
        # everything is appended.

        res = self.common._test_copy_selected('source_table', 'target_table')
        layer = res['TARGET_LAYER']

        self.assertEqual(layer.featureCount(), 1)
        self.assertEqual(res[APPENDED_COUNT], 1)

        output_path = layer.source().split('|')[0]

        # Let's overwrite the target feature to have a float as string
        layer.dataProvider().changeAttributeValues({1: {
            1: "3.1416"
        }})  # name --> "3.1416"

        check_list_values = [f['name'] for f in layer.getFeatures()]
        self.assertEqual(len(check_list_values), 1)
        self.assertEqual(check_list_values[0], "3.1416")

        input_layer_path = "{}|layername={}".format(output_path,
                                                    'source_table')
        input_layer = QgsVectorLayer(input_layer_path, 'layer name', 'ogr')

        # Now let's check counts for skip action
        res = processing.run(
            "etl_load:appendfeaturestolayer", {
                'SOURCE_LAYER': input_layer,
                'SOURCE_FIELD': 'real_value',
                'TARGET_LAYER': layer,
                'TARGET_FIELD': 'date_value',
                'ACTION_ON_DUPLICATE': 1
            })  # Skip

        self.assertEqual(layer.featureCount(), 3)
        self.assertEqual(res[APPENDED_COUNT], 2)
        self.assertIsNone(res[UPDATED_COUNT]
                          )  # This is None because ACTION_ON_DUPLICATE is Skip
        self.assertEqual(res[SKIPPED_COUNT], 0)

    @classmethod
    def tearDownClass(self):
        print('INFO: Tear down test_table_table')
        self.plugin.unload()