"""Tests whether ``pyrate.common.charts.raw_files`` correctly handles IHO S-57 chart files.""" # Python standard from pathlib import Path # Testing from unittest import skipIf from unittest import TestCase # Extra test tooling import pytest # Pyrate library from pyrate.common.testing import IS_CI from pyrate.plan.geometry import LocationType # Module under test from pyrate.common.charts import ChartFileHandler from pyrate.common.charts.s57_files import _OSGEO_PRESENT from pyrate.common.charts import S57ChartHandler PATH_TO_EXAMPLES = Path(__file__).parent / "example_charts" CHARTS = [ PATH_TO_EXAMPLES / "nested_folder/US4VA70M/US4VA70M.000", PATH_TO_EXAMPLES / "US1BS04M/US1BS04M.000", PATH_TO_EXAMPLES / "US4AK5GM/US4AK5GM.000", PATH_TO_EXAMPLES / "US4FL87M/US4FL87M.000", ] CHARTS.sort() class TestChartDiscovery(TestCase): """Tests that charts are correctly discovered""" def test_discovery(self): """Also checks for nested folders and npn-chart files being present""" discovered = list(S57ChartHandler.find_chart_files(PATH_TO_EXAMPLES)) discovered.sort() # check that exactly the expected charts have been found self.assertListEqual(discovered, CHARTS) # check that they have the characteristic file extension for chart_path in discovered: self.assertTrue(chart_path.name.endswith(".000")) # force testing this in CI to make sure it is tested regularly at least there @skipIf(not _OSGEO_PRESENT and not IS_CI, "allow osgeo to be missing and skip the tests in that case") class TestReadCharts(TestCase): """Tests whether actually reading the charts works""" def setUp(self) -> None: self.handler: ChartFileHandler = S57ChartHandler() def test_reading_non_existent_file(self): """Tests reading a chart file that does not exist.""" with self.assertRaises(FileNotFoundError): # Wrapping this in a list causes the generator/iterator to be actually evaluated list(self.handler.read_chart_file("/does/surely/not/exist/and/if/it/does/we/have/a/troll")) with self.assertRaises(FileNotFoundError): # Wrapping this in a list causes the generator/iterator to be actually evaluated list(self.handler.read_chart_file("/does/surely/not/exist/and/if/it/does/we/have/a/troll.000")) def test_reading_wrong_file_type(self): """Tests reading a chart file that is not an S57 file (this Python program file).""" with self.assertRaises(IOError): # This test python file is not a chart not_a_chart_file = __file__ # Wrapping this in a list causes the generator/iterator to be actually evaluated list(self.handler.read_chart_file(not_a_chart_file)) @pytest.mark.filterwarnings("ignore:Ignoring LineString geometry in chart") def test_reading_contains_all_types(self): """Checks for specific types of entries in the charts. Note: Only tests for Landmasses as of now """ all_obstacles = [obstacle for chart in CHARTS for obstacle in self.handler.read_chart_file(chart)] self.assertGreater(len(all_obstacles), 0, "no obstacles were read") relevant_types = ( (LocationType.LAND, "Landmass"), (LocationType.SHALLOW_WATER, "Depth"), (LocationType.OBSTRUCTION, "Buoy"), ) for location_type, name_component in relevant_types: filtered = [ o for o in all_obstacles if (o.name is not None and name_component in o.name and location_type == o.location_type) ] self.assertTrue(filtered, f"no obstacle of type {name_component} was found")