44import xml .etree .ElementTree as ET
55from src .osm_osw_reformatter import Formatter
66
7+ # Paths to test files and output directory
78ROOT_DIR = os .path .dirname (os .path .dirname (os .path .abspath (__file__ )))
89OUTPUT_DIR = os .path .join (os .path .dirname (os .path .dirname (ROOT_DIR )), 'output' )
910TEST_ZIP_FILE = os .path .join (ROOT_DIR , 'test_files/test_roundtrip.zip' )
1011TEST_XML_FILE = os .path .join (ROOT_DIR , 'test_files/test_roundtrip.xml' )
1112
12-
13+ ### Helper to parse OSM XML and return all node and way elements ###
1314def parse_osm_file (xml_path ):
1415 tree = ET .parse (xml_path )
1516 root = tree .getroot ()
@@ -22,8 +23,8 @@ def parse_osm_file(xml_path):
2223 ways .append (elem )
2324 return nodes , ways
2425
26+ ### Extract all ext:* tags (as (k,v) pairs) from a list of OSM XML elements ###
2527def extract_ext_tags (elems ):
26- """Extract all ext:* tags from a list of XML elements."""
2728 ext_tags = set ()
2829 for elem in elems :
2930 for tag in elem .findall ("tag" ):
@@ -33,6 +34,7 @@ def extract_ext_tags(elems):
3334 ext_tags .add ((k , v ))
3435 return ext_tags
3536
37+ ### Utility: Given filepaths, bundle them into a zip for input to the formatter ###
3638def generate_zip (filepaths ):
3739 zip_path = f'{ OUTPUT_DIR } /first_roundtrip_geojson.zip'
3840 with zipfile .ZipFile (zip_path , 'w' , zipfile .ZIP_DEFLATED ) as zipf :
@@ -41,9 +43,16 @@ def generate_zip(filepaths):
4143 zipf .write (filepath , arcname )
4244 return zip_path
4345
46+ ################################################################################
47+ # Test 1: Full roundtrip starting from an OSW zip file
48+ # This checks that all ext:* tags in the original OSM XML are preserved after:
49+ # OSW zip → OSM XML → OSW (GeoJSON) → OSM XML
50+ ################################################################################
51+
4452class TestRoundTrip (unittest .IsolatedAsyncioTestCase ):
4553
4654 def setUp (self ):
55+ # Start with a zipped OSW input, convert to OSM XML
4756 self .formatter = Formatter (workdir = OUTPUT_DIR , file_path = TEST_ZIP_FILE , prefix = 'test_roundtrip' )
4857 convert = self .formatter .osw2osm ()
4958 self .generated_osm_file = convert .generated_files
@@ -52,15 +61,12 @@ def setUp(self):
5261 def tearDown (self ):
5362 self .formatter .cleanup ()
5463
64+ ### Compares ext:* tags in two OSM XML files ###
5565 def compare_osm_files (self , file1 , file2 ):
5666 nodes1 , ways1 = parse_osm_file (file1 )
5767 nodes2 , ways2 = parse_osm_file (file2 )
58-
59- # Get all ext:* tags from both files
6068 ext_tags1 = extract_ext_tags (nodes1 ) | extract_ext_tags (ways1 )
6169 ext_tags2 = extract_ext_tags (nodes2 ) | extract_ext_tags (ways2 )
62-
63- # Check all tags in file1 are present in file2
6470 missing_ext_tags = ext_tags1 - ext_tags2
6571
6672 if missing_ext_tags :
@@ -72,7 +78,7 @@ def compare_osm_files(self, file1, file2):
7278 )
7379
7480 async def test_roundtrip (self ):
75- # First roundtrip: OSW -> OSM XML -> OSW (GeoJSON) -> OSM XML
81+ # OSM XML → OSW (GeoJSON) → zip → OSM XML
7682 formatter = Formatter (workdir = OUTPUT_DIR , file_path = self .generated_osm_file , prefix = 'first_roundtrip_geojson' )
7783 result = await formatter .osm2osw ()
7884 generated_files = result .generated_files
@@ -83,20 +89,20 @@ async def test_roundtrip(self):
8389 generated_osm_file = convert .generated_files
8490
8591 self .compare_osm_files (self .generated_osm_file , generated_osm_file )
86-
8792 formatter .cleanup ()
8893
94+ ################################################################################
95+ # Test 2: Full roundtrip starting from a plain OSM XML file (not zipped OSW)
96+ # This is useful to ensure ext:* tags are preserved in a slightly different flow
97+ ################################################################################
98+
8999class TestXMLRoundTrip (unittest .IsolatedAsyncioTestCase ):
90100
91101 def compare_osm_files (self , file1 , file2 ):
92102 nodes1 , ways1 = parse_osm_file (file1 )
93103 nodes2 , ways2 = parse_osm_file (file2 )
94-
95- # Get all ext:* tags from both files
96104 ext_tags1 = extract_ext_tags (nodes1 ) | extract_ext_tags (ways1 )
97105 ext_tags2 = extract_ext_tags (nodes2 ) | extract_ext_tags (ways2 )
98-
99- # Check all tags in file1 are present in file2
100106 missing_ext_tags = ext_tags1 - ext_tags2
101107
102108 if missing_ext_tags :
@@ -108,6 +114,7 @@ def compare_osm_files(self, file1, file2):
108114 )
109115
110116 async def test_xml_roundtrip (self ):
117+ # Start from OSM XML → OSW (GeoJSON) → zip → OSM XML
111118 formatter = Formatter (workdir = OUTPUT_DIR , file_path = TEST_XML_FILE , prefix = 'first_roundtrip_geojson' )
112119 result = await formatter .osm2osw ()
113120 generated_files = result .generated_files
@@ -120,3 +127,5 @@ async def test_xml_roundtrip(self):
120127 self .compare_osm_files (TEST_XML_FILE , generated_osm_file )
121128 formatter .cleanup ()
122129
130+ ################################################################################
131+
0 commit comments