def test_register_extension_class(self): # Define extension object doc = sbol2.Document() cd = ComponentDefinitionOverride('cd') doc.add(cd) # Round-trip the extension data doc2 = sbol2.Document() doc2.readString(doc.writeString()) cd = doc2.getExtensionObject(cd.identity) # Note the extension object's type is not preserved! self.assertIs(type(cd), sbol2.ComponentDefinition) self.assertIsNot(type(cd), ComponentDefinitionOverride) # Now register the class and attempt to round-trip again doc2 = sbol2.Document() sbol2.Config.register_extension_class(ComponentDefinitionOverride, sbol2.SBOL_COMPONENT_DEFINITION) doc2.readString(doc.writeString()) cd = doc2.getExtensionObject(cd.identity) # This time the extension object's type is preserved! self.assertIs(type(cd), ComponentDefinitionOverride) self.assertIsNot(type(cd), sbol2.ComponentDefinition) # The object is stored in Document.componentDefinitions self.assertEqual(len(doc2.componentDefinitions), 1) # Restore sbol2.Config.register_extension_class(sbol2.ComponentDefinition, sbol2.SBOL_COMPONENT_DEFINITION)
def test_compile_autoconstruct_sequence(self): # Ensure that autoconstruction of Sequence URIs works correctly with # different configuration options root_id = 'root' sub_id = 'sub' sbol2.Config.setOption(sbol2.ConfigOptions.SBOL_COMPLIANT_URIS, True) sbol2.Config.setOption(sbol2.ConfigOptions.SBOL_TYPED_URIS, True) doc = sbol2.Document() root = doc.componentDefinitions.create(root_id) sub = doc.componentDefinitions.create(sub_id) root.compile([sub]) expected_identity = sbol2.getHomespace( ) + '/Sequence/' + root_id + '/1' self.assertEqual(root.sequence.identity, expected_identity) sbol2.Config.setOption(sbol2.ConfigOptions.SBOL_COMPLIANT_URIS, True) sbol2.Config.setOption(sbol2.ConfigOptions.SBOL_TYPED_URIS, False) doc = sbol2.Document() root = doc.componentDefinitions.create(root_id) sub = doc.componentDefinitions.create(sub_id) root.compile([sub]) expected_identity = sbol2.getHomespace() + '/' + root_id + '_seq/1' self.assertEqual(root.sequence.identity, expected_identity) sbol2.Config.setOption(sbol2.ConfigOptions.SBOL_COMPLIANT_URIS, True) sbol2.Config.setOption(sbol2.ConfigOptions.SBOL_TYPED_URIS, True)
def test_add_extension_object(self): # We need to construct and add an extension object # It should then be accessible via getExtensionObject # We can also peel back the curtain and make sure the object # is in doc.SBOLObjects and the URI is not in doc.OwnedObjects # Three kinds of things to add: # 1. An existing type, like ComponentDefinition cd = sbol2.ComponentDefinition('cd') doc = sbol2.Document() doc.addExtensionObject(cd) self.assertEqual(1, len(doc.componentDefinitions)) obj = doc.getExtensionObject(cd.identity) self.assertEqual(cd, obj) # 2. A new type that is a TopLevel tle = TopLevelExtension('tle') doc = sbol2.Document() doc.addExtensionObject(tle) obj = doc.getExtensionObject(tle.identity) self.assertEqual(tle, obj) # 3. A new type that is not a TopLevel # This object won't be found. There is no way for the document to # hold on to the object if it isn't a TopLevel ntle = NonTopLevelExtension('ntle') doc = sbol2.Document() doc.addExtensionObject(ntle) with self.assertRaises(sbol2.SBOLError) as cm: doc.getExtensionObject(ntle.identity) raised = cm.exception self.assertEqual(sbol2.SBOLErrorCode.SBOL_ERROR_NOT_FOUND, raised.error_code()) obj = doc.find(ntle.identity) self.assertIsNone(obj)
def test_submit_to_collection(self): sbh = SynBioHub(SD2Constants.SD2_STAGING_SERVER, self.user, self.password, SD2Constants.SD2_STAGING_SERVER + '/sparql', SD2Constants.SD2_SERVER) sbol.Config.setOption('sbol_typed_uris', False) sbol.Config.setOption('validate', False) sbol.setHomespace('http://dummy.org') member_ID1 = 'foo' doc1 = sbol.Document() doc1.componentDefinitions.create(member_ID1) collection_ID = 'adapter_test_3' collection_name = 'Adapter Test Collection 3' collection_description = 'This is a test of the upload_sbol module of synbiohub_adapter.' collection_version = '1' sbh.submit_collection(doc1, collection_ID, collection_version, collection_name, collection_description, overwrite=True) member_identity1 = '/'.join([ SD2Constants.SD2_SERVER, 'user', self.user, collection_ID, member_ID1, '1' ]) collection_identity = '/'.join([ SD2Constants.SD2_SERVER, 'user', self.user, collection_ID, collection_ID + '_collection', '1' ]) member_ID2 = 'bar' doc2 = sbol.Document() doc2.componentDefinitions.create(member_ID2) sbh.submit_to_collection([doc2], collection_identity) member_identity2 = '/'.join([ SD2Constants.SD2_SERVER, 'user', self.user, collection_ID, member_ID2, '1' ]) query_result = sbh.query_collection_members( collection_uris=[collection_identity]) self.assertIn(collection_identity, query_result) self.assertEqual(len(query_result[collection_identity]), 2) self.assertIn(member_identity1, query_result[collection_identity]) self.assertIn(member_identity2, query_result[collection_identity])
def test_range(self): # Test proper serializing and de-serializing of range properties doc = sbol.Document() cd = doc.componentDefinitions.create('cd') sa = cd.sequenceAnnotations.create('sa') r = sa.locations.createRange('r') r.start = 42 doc2 = sbol.Document() doc2.readString(doc.writeString()) r = doc2.componentDefinitions['cd'].sequenceAnnotations['sa'].locations['r'] self.assertEqual(r.start, 42)
def test_from_user_to_user(self): # Test proper conversion of user-facing types from RDFlib types # through the Property interfaces after serializing and de-serializing doc = sbol.Document() cd = doc.componentDefinitions.create('cd') cd.int_property = sbol.IntProperty(cd, 'http://examples.org', '0', '1', None, 42) self.assertEqual(42, cd.int_property) doc2 = sbol.Document() doc2.readString(doc.writeString()) cd2 = doc2.componentDefinitions['cd'] cd2.int_property = sbol.IntProperty(cd, 'http://examples.org', '0', '1', None) self.assertEqual(42, cd2.int_property)
def test_parent_child_extensions_top_level(self): doc = sbol2.Document() tle = TopLevelExtension('tle') ntle = NonTopLevelExtension('ntle') tle.child = ntle doc.add(tle) self.assertEqual(len(doc.SBOLObjects), 1) # Verify that the parent-child relationship is preserved upon round-trip doc2 = sbol2.Document() doc2.readString(doc.writeString()) self.assertNotIsInstance(doc2.get(ntle.identity), sbol2.TopLevel) self.assertEqual(len(doc.SBOLObjects), 1) self.assertIsNotNone(tle.child)
def test_copy_namespace(self): # Confirm that extension namespaces are copied into the target Document extension_prefix = 'extension_prefix' extension_namespace = 'http://examples.org#' doc = sbol.Document() target_doc = sbol.Document() cd = sbol.ComponentDefinition('cd') doc.addComponentDefinition(cd) doc.addNamespace(extension_namespace, extension_prefix) cd.extension_property = sbol.property.TextProperty(cd, extension_namespace + 'extension_property', '0', '1', None, 'foo') cd_copy = cd.copy(target_doc) self.assertTrue(target_doc._namespaces[extension_prefix] == rdflib.URIRef(extension_namespace))
def test_append_string_2(self): doc = sbol2.Document() cd = doc.componentDefinitions.create('cd1') cd.components.create('c1') cd.roles = ['foo'] self.assertEqual(1, len(cd.components)) self.assertEqual('c1', cd.components[0].displayId) doc2 = sbol2.Document() cd_updated = doc2.componentDefinitions.create('cd1') cd_updated.components.create('c2') cd_updated.roles = ['bar'] doc.appendString(doc2.writeString(), overwrite=True) self.assertEqual(1, len(cd.components)) self.assertEqual('c2', cd.components[0].displayId) self.assertEqual(cd.roles, ['bar'])
def test_version(self): doc = sbol2.Document() self.assertIsNotNone(doc.version) old_version = doc.version doc.append(CRISPR_LOCATION) self.assertIsNotNone(doc.version) self.assertEqual(old_version, doc.version)
def test_assemble_with_displayIds(self): sbol2.Config.setOption(sbol2.ConfigOptions.SBOL_TYPED_URIS, True) doc = sbol2.Document() gene = sbol2.ComponentDefinition("BB0001") promoter = sbol2.ComponentDefinition("R0010") RBS = sbol2.ComponentDefinition("B0032") CDS = sbol2.ComponentDefinition("E0040") terminator = sbol2.ComponentDefinition("B0012") promoter.sequence = sbol2.Sequence('R0010') RBS.sequence = sbol2.Sequence('B0032') CDS.sequence = sbol2.Sequence('E0040') terminator.sequence = sbol2.Sequence('B0012') promoter.sequence.elements = 'a' RBS.sequence.elements = 't' CDS.sequence.elements = 'c' terminator.sequence.elements = 'g' promoter.roles = sbol2.SO_PROMOTER RBS.roles = sbol2.SO_RBS CDS.roles = sbol2.SO_CDS terminator.roles = sbol2.SO_TERMINATOR doc.addComponentDefinition([gene, promoter, RBS, CDS, terminator]) gene.assemblePrimaryStructure(['R0010', 'B0032', 'E0040', 'B0012']) primary_structure = gene.getPrimaryStructure() primary_structure = [c.identity for c in primary_structure] self.assertEqual(primary_structure, [ promoter.identity, RBS.identity, CDS.identity, terminator.identity ]) target_seq = gene.compile() self.assertEqual(target_seq, 'atcg')
def test_validate(self): doc = sbol2.Document() # Add a module definition doc.moduleDefinitions.create('md') result = doc.validate() expected = 'Valid.' self.assertEqual(result, expected)
def test_identity(self): # The sbol:identity relation should not be written out when # serializing SBOL. doc = sbol.Document() doc.read(TEST_LOCATION) result = doc.writeString() self.assertNotIn('sbol:identity', result)
def test_getitem(self): sbol.setHomespace('http://sbols.org/CRISPR_Example/') d = sbol.Document() d.read(TEST_LOCATION) s1 = d.sequences['CRa_U6_seq'] expected = 'http://sbols.org/CRISPR_Example/CRa_U6_seq/1.0.0' self.assertEqual(expected, str(s1))
def test_import_into_typed_namespace_from_nontyped_namespace(self): # Copy an sbol-typed URI to a non-typed, sbol-compliant URI sbol.setHomespace('http://examples.org') sbol.Config.setOption(sbol2.ConfigOptions.SBOL_TYPED_URIS, False) sbol.Config.setOption(sbol2.ConfigOptions.SBOL_COMPLIANT_URIS, True) doc = sbol.Document() comp = sbol.ComponentDefinition('cd') seq = sbol.Sequence('seq') comp.sequences = seq.identity doc.addComponentDefinition(comp) doc.addSequence(seq) # Import the object into the new namespace sbol.Config.setOption(sbol2.ConfigOptions.SBOL_TYPED_URIS, True) old_homespace = sbol.getHomespace() sbol.setHomespace('http://acme.com') comp_copy = comp.copy(None, old_homespace) # Verify new namespace was correctly substituted and type token was successfully # added self.assertEqual(comp_copy.identity, 'http://acme.com/ComponentDefinition/cd/1') self.assertEqual(comp_copy.persistentIdentity, 'http://acme.com/ComponentDefinition/cd') self.assertEqual(comp_copy.sequences[0], 'http://acme.com/Sequence/seq/1') # Verify wasDerivedFrom relationship self.assertEqual(comp_copy.wasDerivedFrom[0], comp.identity)
def test_was_generated_by(self): d = sbol.Document() d.read(PARTS_LOCATION) cd = d.componentDefinitions['http://examples.org/ComponentDefinition/AmeR/1'] uri = 'http://examples.org/Activity/CelloUCF2sbol_Activity/1' expected = [uri] self.assertEqual(cd.wasGeneratedBy, expected)
def test_submit(self): # This test is derived from an etl-to-synbiohub_pipeline test # case that was failing. RESOURCE = 'https://tang.ece.utah.edu' SPOOFED_RESOURCE = 'https://synbiohub.utah.edu' doc = sbol.Document() doc.version = '1' doc.displayId = 'sbol_test' doc.name = "SBOL Test Collection" doc.description = "A scratch collection for automated testing of the sbol." sbh = sbol.PartShop(RESOURCE, SPOOFED_RESOURCE) try: sbh.login(username, password) except sbol2.SBOLError as sbol_error: if sbol_error.error_code( ) == sbol2.SBOLErrorCode.SBOL_ERROR_BAD_HTTP_REQUEST: if '503' in sbol_error.what(): return raise try: sbh.submit(doc) except Exception: # What exception type should we really be expecting? The # original test had a bare except. uri_template = '{0}/user/{1}/{2}/{2}_collection/1' target_collection = uri_template.format(RESOURCE, username, doc.displayId) sbh.submit(doc, target_collection, 1)
def test_assembly_multiple_ranges(self): # Currently hierarchical assembly of Components with multiple Ranges # is not supported, and an exception will be thrown if the user attempts it doc = sbol2.Document() root = doc.componentDefinitions.create('root') sub0 = doc.componentDefinitions.create('sub0') sub1 = doc.componentDefinitions.create('sub1') sub0.sequence = sbol2.Sequence('sub0', 'tttt') sub1.sequence = sbol2.Sequence('sub1', 'aa') root.assemblePrimaryStructure([sub0, sub1]) sub0_0 = root.components['sub0_0'] sub1_0 = root.components['sub1_0'] sa0 = root.sequenceAnnotations.create('sa0') sa0.component = sub0_0 r0 = sa0.locations.createRange('r0') r1 = sa0.locations.createRange('r1') sa1 = root.sequenceAnnotations.create('sa1') sa1.component = sub1_0 r2 = sa1.locations.createRange('r2') r0.start = 1 r0.end = 2 r1.start = 3 r1.end = 4 r2.start = 5 r2.end = 6 with self.assertRaises(sbol2.SBOLError) as err: root.compile() self.assertEqual(err.exception.error_code(), sbol2.SBOLErrorCode.SBOL_ERROR_INVALID_ARGUMENT)
def test_append_string(self): doc = sbol2.Document() cd = doc.componentDefinitions.create('cd1') cd.components.create('c1') self.assertEqual(1, len(cd.components)) doc.appendString(doc.writeString(), overwrite=True) self.assertEqual(1, len(cd.components))
def test_append_string_no_overwrite(self): doc = sbol2.Document(CRISPR_LOCATION) with self.assertRaises(sbol2.SBOLError) as cm: doc.appendString(doc.writeString(), overwrite=False) exc = cm.exception self.assertEqual(sbol2.SBOLErrorCode.DUPLICATE_URI_ERROR, exc.error_code())
def testApplyCallbackRecursively(self): # Assemble module hierarchy doc = sbol2.Document() root = sbol2.ModuleDefinition('root') sub = sbol2.ModuleDefinition('sub') leaf = sbol2.ModuleDefinition('leaf') doc.addModuleDefinition([root, sub, leaf]) root.assemble([sub]) sub.assemble([leaf]) # Define callback which performs an operation on the given ModuleDefinition def callback(md, params): level = params[0] level += 1 params[0] = level # Apply callback level = 0 params = [level] flattened_module_tree = root.applyToModuleHierarchy(callback, params) level = params[0] flattened_module_tree = [md.identity for md in flattened_module_tree] expected_module_tree = [md.identity for md in [root, sub, leaf]] self.assertSequenceEqual(flattened_module_tree, expected_module_tree) self.assertEqual(level, 3)
def test_register_parent_child_extensions(self): # Show that we can load the parent/child relationship when the # extension classes are registered. The methods around this one # try to do the same thing without registration of the extension # classes # # This is all wrapped in a `try` so that we can clean up the # registration in the finally clause try: sbol2.Config.register_extension_class(TopLevelExtension, TopLevelExtension.RDF_TYPE) sbol2.Config.register_extension_class( NonTopLevelExtension, NonTopLevelExtension.RDF_TYPE) doc = sbol2.Document() tle = TopLevelExtension('tle') ntle = NonTopLevelExtension('ntle') tle.child = ntle doc.add(tle) self.assertEqual(len(doc.SBOLObjects), 1) # Verify that the parent-child relationship is preserved upon round-trip doc.readString(doc.writeString()) self.assertEqual(len(doc.SBOLObjects), 1) self.assertIsNotNone(tle.child) finally: # Clean up tle_uri = rdflib.URIRef(TopLevelExtension.RDF_TYPE) ntle_uri = rdflib.URIRef(NonTopLevelExtension.RDF_TYPE) self.assertIn(tle_uri, sbol2.Config.SBOL_DATA_MODEL_REGISTER) self.assertIn(ntle_uri, sbol2.Config.SBOL_DATA_MODEL_REGISTER) del sbol2.Config.SBOL_DATA_MODEL_REGISTER[tle_uri] del sbol2.Config.SBOL_DATA_MODEL_REGISTER[ntle_uri] self.assertNotIn(tle_uri, sbol2.Config.SBOL_DATA_MODEL_REGISTER) self.assertNotIn(ntle_uri, sbol2.Config.SBOL_DATA_MODEL_REGISTER)
def testAssemble(self): # Assemble module hierarchy doc = sbol2.Document() root = sbol2.ModuleDefinition('root') sub = sbol2.ModuleDefinition('sub') doc.addModuleDefinition([root, sub]) root.assemble([sub])
def test_write_validation(self): # Test that write performs validation if requested # and skips validation if requested. doc = sbol2.Document() doc.moduleDefinitions.create('md1') validate = sbol2.Config.getOption(sbol2.ConfigOptions.VALIDATE) sbol2.Config.setOption(sbol2.ConfigOptions.VALIDATE, True) verbose = sbol2.Config.getOption(sbol2.ConfigOptions.VERBOSE) sbol2.Config.setOption(sbol2.ConfigOptions.VERBOSE, True) with tempfile.TemporaryDirectory() as tmpdirname: test_file = os.path.join(tmpdirname, 'test.xml') with unittest.mock.patch('sys.stdout', new=io.StringIO()) as fake_out: # Write to disk result = doc.write(test_file) self.assertEqual('Valid.', result) # Expect timing output output = fake_out.getvalue().strip() self.assertTrue(output.startswith('Validation request took')) self.assertTrue(output.endswith('seconds')) sbol2.Config.setOption(sbol2.ConfigOptions.VALIDATE, False) with tempfile.TemporaryDirectory() as tmpdirname: test_file = os.path.join(tmpdirname, 'test.xml') # Write to disk result = doc.write(test_file) self.assertTrue(result.startswith('Validation disabled.')) # Reset validate to its original value sbol2.Config.setOption(sbol2.ConfigOptions.VALIDATE, validate) sbol2.Config.setOption(sbol2.ConfigOptions.VERBOSE, verbose)
def test_was_derived_from(self): d = sbol.Document() d.read(PARTS_LOCATION) cd = d.componentDefinitions['http://examples.org/ComponentDefinition/AmeR/1'] uri = 'https://synbiohub.programmingbiology.org/public/Cello_Parts/AmeR/1' expected = [uri] self.assertEqual(cd.wasDerivedFrom, expected)
def test_assignment(self): doc = sbol.Document() md = doc.moduleDefinitions.create('foo') m1 = sbol.Module('m1') m2 = sbol.Module('m2') md.modules = [m1, m2] self.assertEqual(list(md.modules), [m1, m2])
def test_import_object_into_new_namespace(self): # When copying an object into a new namespace, confirm that it's URI is copied # into the new namespace. Also confirm that any ReferencedObject attributes # whose values point to an object in the old namespace are also copied into the # new namespace sbol.setHomespace('http://examples.org') sbol.Config.setOption(sbol2.ConfigOptions.SBOL_COMPLIANT_URIS, True) sbol.Config.setOption(sbol2.ConfigOptions.SBOL_TYPED_URIS, False) doc = sbol.Document() comp = sbol.ComponentDefinition('cd') seq = sbol.Sequence('seq') doc.addComponentDefinition(comp) doc.addSequence(seq) comp.sequences = seq.identity # Import from old homespace into new homespace old_homespace = sbol.getHomespace() sbol.setHomespace('http://acme.com') comp_copy = comp.copy(None, old_homespace) # Verify new namespace was correctly substituted self.assertEqual(comp_copy.identity, 'http://acme.com/cd/1') self.assertEqual(comp_copy.persistentIdentity, 'http://acme.com/cd') self.assertEqual(comp_copy.sequences[0], 'http://acme.com/seq/1') # Verify wasDerivedFrom relationship self.assertEqual(comp_copy.wasDerivedFrom[0], comp.identity) # Ensure these are equal under the covers self.assertEqual(type(comp.properties[sbol.SBOL_SEQUENCE_PROPERTY][0]), rdflib.URIRef) self.assertEqual(type(comp.properties[sbol.SBOL_SEQUENCE_PROPERTY][0]), type(comp_copy.properties[sbol.SBOL_SEQUENCE_PROPERTY][0]))
def test_getPropertyValues(self): d = sbol.Document() d.read(PARTS_LOCATION) cd = d.componentDefinitions[ 'http://examples.org/ComponentDefinition/AmeR/1'] values = cd.getPropertyValues(sbol.SBOL_NAME) self.assertEqual(len(values), 1)
def test_eq(self): sbol.setHomespace('http://example.org/Unit_Test') doc = sbol.Document() md1 = doc.moduleDefinitions.create('Foo1') self.assertEqual(len(doc.moduleDefinitions), 1) md2 = sbol.ModuleDefinition(uri='Foo2') self.assertNotEqual(md1, md2)
def test_getPropertyValue(self): d = sbol.Document() d.read(PARTS_LOCATION) cd = d.componentDefinitions['http://examples.org/ComponentDefinition/AmeR/1'] expected = 'AmeR' name = cd.getPropertyValue(sbol.SBOL_NAME) self.assertEqual(name, expected)