From ae0c6088ae01272780388c0ebbe9a04bc474559a Mon Sep 17 00:00:00 2001 From: Yehuda Binik Date: Sat, 4 Nov 2023 15:23:54 -0400 Subject: [PATCH] Implemented converstion of collection between SBOL2 and SBOL3 for the new converter --- sbol_utilities/sbol3_sbol2_conversion.py | 17 ++++++++--- test/test_files/sbol3_collection.nt | 22 ++++++++++++++ test/test_files/sbol_3to2_collection.xml | 30 +++++++++++++++++++ test/test_sbol2_sbol3_direct.py | 38 ++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 test/test_files/sbol3_collection.nt create mode 100644 test/test_files/sbol_3to2_collection.xml diff --git a/sbol_utilities/sbol3_sbol2_conversion.py b/sbol_utilities/sbol3_sbol2_conversion.py index 0168490..ac44446 100644 --- a/sbol_utilities/sbol3_sbol2_conversion.py +++ b/sbol_utilities/sbol3_sbol2_conversion.py @@ -129,9 +129,14 @@ def visit_binary_prefix(self, a: sbol3.BinaryPrefix): # Priority: 4 raise NotImplementedError('Conversion of BinaryPrefix from SBOL3 to SBOL2 not yet implemented') - def visit_collection(self, a: sbol3.Collection): + def visit_collection(self, coll3: sbol3.Collection): # Priority: 1 - raise NotImplementedError('Conversion of Collection from SBOL3 to SBOL2 not yet implemented') + # Make the Collection object and add it to the document + coll2 = sbol2.Collection(coll3.identity) + coll2.members = coll3.members + self.doc2.addCollection(coll2) + # Map over all other TopLevel properties and extensions not covered by the constructor + self._convert_toplevel(coll3, coll2) def visit_combinatorial_derivation(self, a: sbol3.CombinatorialDerivation): # Priority: 2 @@ -378,9 +383,13 @@ def visit_attachment(self, a: sbol2.Attachment): # Priority: 2 raise NotImplementedError('Conversion of Attachment from SBOL2 to SBOL3 not yet implemented') - def visit_collection(self, a: sbol2.Collection): + def visit_collection(self, coll2: sbol2.Collection): # Priority: 1 - raise NotImplementedError('Conversion of Collection from SBOL2 to SBOL3 not yet implemented') + # Make the Collection object and add it to the document + coll3 = sbol3.Collection(coll2.identity, members=coll2.members) + self.doc3.add(coll3) + # Map over all other TopLevel properties and extensions not covered by the constructor + self._convert_toplevel(coll2, coll3) def visit_combinatorial_derivation(self, a: sbol2.CombinatorialDerivation): # Priority: 2 diff --git a/test/test_files/sbol3_collection.nt b/test/test_files/sbol3_collection.nt new file mode 100644 index 0000000..cc65b56 --- /dev/null +++ b/test/test_files/sbol3_collection.nt @@ -0,0 +1,22 @@ + . + . + . + "col1" . + . + . + "LacI protein" . + "LacI" . + . + . + "LacI_protein" . + . + . + "TetR protein" . + "TetR" . + . + . + "TetR_protein" . + . + "1" . + "1" . + "1" . diff --git a/test/test_files/sbol_3to2_collection.xml b/test/test_files/sbol_3to2_collection.xml new file mode 100644 index 0000000..75ca6a4 --- /dev/null +++ b/test/test_files/sbol_3to2_collection.xml @@ -0,0 +1,30 @@ + + + + + col1 + 1 + + + + + + LacI + + + LacI protein + + LacI_protein + 1 + + + + TetR_protein + TetR + 1 + + + TetR protein + + + diff --git a/test/test_sbol2_sbol3_direct.py b/test/test_sbol2_sbol3_direct.py index 280e693..94791fc 100644 --- a/test/test_sbol2_sbol3_direct.py +++ b/test/test_sbol2_sbol3_direct.py @@ -91,6 +91,44 @@ def test_2to3_implementation_conversion(self): doc2_loop.write(tmp2) self.assertFalse(file_diff(str(tmp2), str(TEST_FILES / 'sbol_3to2_implementation.xml'))) + def test_3to2_collection_conversion(self): + """Test ability to convert a collection from SBOL3 to SBOL2""" + # Load an SBOL3 document and check its contents + doc3 = sbol3.Document() + doc3.read(TEST_FILES / 'sbol3_collection.nt') + # Convert to SBOL2 and check contents + doc2 = convert3to2(doc3, True) + #report = doc2.validate() + #self.assertEqual(len(report), 0, f'Validation failed: {report}') + with tempfile.TemporaryDirectory() as tmpdir: + tmp2 = Path(tmpdir) / 'doc2.xml' + doc2.write(tmp2) + self.assertFalse(file_diff(str(tmp2), str(TEST_FILES / 'sbol_3to2_collection.xml'))) + doc3_loop = convert2to3(doc2, use_native_converter=True) + self.assertEqual(len(doc3_loop.validate()), 0) + tmp3 = Path(tmpdir) / 'doc3_loop.nt' + doc3_loop.write(tmp3) + self.assertFalse(file_diff(str(tmp3), str(TEST_FILES / 'sbol3_collection.nt'))) + + def test_2to3_collection_conversion(self): + """Test ability to convert a collection from SBOL2 to SBOL3""" + # Load an SBOL2 document and check its contents + doc2 = sbol2.Document() + doc2.read(TEST_FILES / 'sbol_3to2_collection.xml') + # Convert to SBOL3 and check contents + doc3 = convert2to3(doc2, use_native_converter=True) + self.assertEqual(len(doc3.validate()), 0) + with tempfile.TemporaryDirectory() as tmpdir: + tmp3 = Path(tmpdir) / 'doc3.nt' + doc3.write(tmp3) + self.assertFalse(file_diff(str(tmp3), str(TEST_FILES / 'sbol3_collection.nt'))) + doc2_loop = convert3to2(doc3, True) + # report = doc2.validate() + # self.assertEqual(len(report), 0, f'Validation failed: {report}') + tmp2 = Path(tmpdir) / 'doc2_loop.xml' + doc2_loop.write(tmp2) + self.assertFalse(file_diff(str(tmp2), str(TEST_FILES / 'sbol_3to2_collection.xml'))) + if __name__ == '__main__': unittest.main()