Skip to content

Commit

Permalink
Merge pull request #382 from tcmitchell/301-list-wrapping
Browse files Browse the repository at this point in the history
Common cases for automatic list wrapping
  • Loading branch information
tcmitchell authored Feb 11, 2022
2 parents 50d578a + c0f1d84 commit 6f63272
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 6 deletions.
4 changes: 4 additions & 0 deletions sbol3/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
# SBOL 3 terms
# ----------
SBOL_ATTACHMENT = SBOL3_NS + 'Attachment'
SBOL_BUILD = SBOL3_NS + 'build'
SBOL_BUILT = SBOL3_NS + 'built'
SBOL_CARDINALITY = SBOL3_NS + 'cardinality'
SBOL_COLLECTION = SBOL3_NS + 'Collection'
Expand All @@ -49,6 +50,7 @@
SBOL_CUT = SBOL3_NS + 'Cut'
SBOL_DEFINITION = SBOL3_NS + 'definition'
SBOL_DESCRIPTION = SBOL3_NS + 'description'
SBOL_DESIGN = SBOL3_NS + 'design'
SBOL_DISPLAY_ID = SBOL3_NS + 'displayId'
SBOL_ELEMENTS = SBOL3_NS + 'elements'
SBOL_ENCODING = SBOL3_NS + 'encoding'
Expand All @@ -74,6 +76,7 @@
SBOL_INTERFACE = SBOL3_NS + 'Interface'
SBOL_INTERFACES = SBOL3_NS + 'hasInterface'
SBOL_LANGUAGE = SBOL3_NS + 'language'
SBOL_LEARN = SBOL3_NS + 'learn'
SBOL_LOCAL_SUBCOMPONENT = SBOL3_NS + 'LocalSubComponent'
SBOL_LOCATION = SBOL3_NS + 'hasLocation'
SBOL_MEMBER = SBOL3_NS + 'member'
Expand Down Expand Up @@ -104,6 +107,7 @@
SBOL_SUBCOMPONENT = SBOL3_NS + 'SubComponent'
SBOL_SUBJECT = SBOL3_NS + 'subject'
SBOL_TEMPLATE = SBOL3_NS + 'template'
SBOL_TEST = SBOL3_NS + 'test'
SBOL_TOP_LEVEL = SBOL3_NS + 'TopLevel'
SBOL_TYPE = SBOL3_NS + 'type'
SBOL_VARIABLE = SBOL3_NS + 'variable'
Expand Down
2 changes: 1 addition & 1 deletion sbol3/localsub.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class LocalSubComponent(Feature):
"""

def __init__(self, types: Union[str, list[str]],
*, locations: List[Location] = None,
*, locations: Union[Location, List[Location]] = None,
roles: List[str] = None, orientation: str = None,
name: str = None, description: str = None,
derived_from: List[str] = None,
Expand Down
2 changes: 1 addition & 1 deletion sbol3/seqfeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class SequenceFeature(Feature):

def __init__(self, locations: List[Location],
def __init__(self, locations: Union[Location, List[Location]],
*, roles: List[str] = None, orientation: str = None,
name: str = None, description: str = None,
derived_from: List[str] = None,
Expand Down
4 changes: 2 additions & 2 deletions sbol3/subcomponent.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class SubComponent(Feature):

def __init__(self, instance_of: Union[Identified, str],
*, role_integration: Optional[str] = None,
locations: List[Location] = None,
source_locations: List[Location] = None,
locations: Union[Location, List[Location]] = None,
source_locations: Union[Location, List[Location]] = None,
roles: List[str] = None, orientation: str = None,
name: str = None, description: str = None,
derived_from: List[str] = None,
Expand Down
4 changes: 3 additions & 1 deletion sbol3/varcomp.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class VariableFeature(Identified):

def __init__(self, cardinality: str, variable: Union[Identified, str],
*, variants: List[Union[Identified, str]] = None,
variant_collections: List[Union[Identified, str]] = None,
# We really need to define our own types...
variant_collections: Union[Union[Identified, str],
List[Union[Identified, str]]] = None,
variant_derivations: List[Union[Identified, str]] = None,
variant_measures: List[Union[Identified, str]] = None,
name: str = None, description: str = None,
Expand Down
34 changes: 34 additions & 0 deletions test/test_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,40 @@ def test_measures_initial_value(self):
c2 = sbol3.Component('c2', types=[sbol3.SBO_DNA], measures=three_metres)
self.assertListEqual([three_metres], list(c2.measures))

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
source_uri = 'https://example.org/source'
derived_from_uri = 'https://example.org/derived_from'
statute_mile = sbol3.OM_NS + 'mile-Statute'
comp1_type = sbol3.SBO_DNA
comp1_role = sbol3.SO_PROMOTER
comp1_seq1 = sbol3.Sequence('seq1')
comp1_model = sbol3.Model('model1',
source=source_uri,
language='https://example.org/language',
framework='https://example.org/framework')
comp1_attachment = sbol3.Attachment('att1', source=source_uri)
comp1_measure = sbol3.Measure(value=26.2, unit=statute_mile)
comp1_activity = sbol3.Activity('activity1')
comp1 = sbol3.Component('comp1', types=comp1_type,
sequences=comp1_seq1, roles=comp1_role,
models=comp1_model,
attachments=comp1_attachment,
derived_from=derived_from_uri,
measures=comp1_measure,
generated_by=comp1_activity)
self.assertEqual([comp1_type], comp1.types)
self.assertEqual([comp1_seq1.identity], comp1.sequences)
self.assertEqual([comp1_role], comp1.roles)
self.assertEqual([comp1_model.identity], comp1.models)
self.assertEqual([comp1_attachment.identity], comp1.attachments)
self.assertEqual([derived_from_uri], comp1.derived_from)
self.assertEqual([comp1_measure], comp1.measures)
self.assertEqual([comp1_activity.identity], comp1.generated_by)


if __name__ == '__main__':
unittest.main()
18 changes: 18 additions & 0 deletions test/test_extdef.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,21 @@ def test_read_from_file(self):
measure = ext_def.measures[0]
measure_uri = posixpath.join(uri, 'measure1')
self.assertEqual(measure_uri, measure.identity)

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
test_type = sbol3.SBO_DNA
test_role = sbol3.SO_PROMOTER
definition_uri = 'https://example.org/definition'
ed1 = sbol3.ExternallyDefined(types=test_type,
definition=definition_uri,
roles=test_role)
self.assertEqual([test_type], ed1.types)
self.assertEqual([test_role], ed1.roles)


if __name__ == '__main__':
unittest.main()
9 changes: 9 additions & 0 deletions test/test_interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ def test_read(self):
self.assertEqual(interaction_id, interaction.identity)
self.assertEqual([sbol3.SBO_INHIBITION], interaction.types)

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
test_type = sbol3.SBO_INHIBITION
int1 = sbol3.Interaction(types=test_type)
self.assertEqual([test_type], int1.types)


if __name__ == '__main__':
unittest.main()
13 changes: 13 additions & 0 deletions test/test_localsub.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ def test_validation(self):
self.assertIsNotNone(report)
self.assertEqual(1, len(report.errors))

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
test_type = sbol3.SBO_DNA
seq = sbol3.Sequence('seq1')
test_loc = sbol3.EntireSequence(seq)
lsc = sbol3.LocalSubComponent(types=test_type,
locations=test_loc)
self.assertEqual([test_type], lsc.types)
self.assertEqual([test_loc], lsc.locations)


if __name__ == '__main__':
unittest.main()
11 changes: 11 additions & 0 deletions test/test_om_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ def test_read_from_file(self):
measure.unit)
self.assertEqual('measure1', measure.display_id)

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
unit_uri = 'http://www.ontology-of-units-of-measure.org/resource/om-2/gramPerLitre'
# SBO:0000612 is from the SBOL 3.0.1 specification.
test_type = 'https://identifiers.org/SBO:0000612'
measure1 = sbol3.Measure(value=1.0, unit=unit_uri, types=test_type)
self.assertEqual([test_type], measure1.types)


class TestPrefixedUnit(unittest.TestCase):

Expand Down
11 changes: 11 additions & 0 deletions test/test_participation.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ def test_read_from_file(self):
roles = [sbol3.SBO_TEMPLATE]
self.assertEqual(roles, participation.roles)

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
test_role = sbol3.SBO_INHIBITOR
participant_uri = 'https://example.org/participant'
participation1 = sbol3.Participation(roles=test_role,
participant=participant_uri)
self.assertEqual([test_role], participation1.roles)


if __name__ == '__main__':
unittest.main()
29 changes: 29 additions & 0 deletions test/test_provenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ def test_create(self):
self.assertEqual([], activity.usage)
self.assertEqual([], activity.association)

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
test_type = sbol3.SBOL_DESIGN
activity1 = sbol3.Activity('activity1', types=test_type)
self.assertEqual([test_type], activity1.types)


class TestAgent(unittest.TestCase):

Expand Down Expand Up @@ -61,6 +70,16 @@ def test_create(self):
self.assertEqual(None, association.plan)
self.assertEqual(agent.identity, association.agent)

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
agent_uri = 'https://example.org/agent'
role_uri = 'https://example.org/agent_role'
assoc1 = sbol3.Association(agent=agent_uri, roles=role_uri)
self.assertEqual([role_uri], assoc1.roles)


class TestPlan(unittest.TestCase):

Expand Down Expand Up @@ -96,6 +115,16 @@ def test_create(self):
self.assertEqual(agent.identity, usage.entity)
self.assertEqual([], usage.roles)

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
entity_uri = 'https://example.org/entity'
role_uri = 'https://example.org/entity_usage'
usage1 = sbol3.Usage(entity=entity_uri, roles=role_uri)
self.assertEqual([role_uri], usage1.roles)


if __name__ == '__main__':
unittest.main()
10 changes: 10 additions & 0 deletions test/test_seqfeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ def test_recursive_validation(self):
# object (the range).
self.assertEqual(1, len(report.errors))

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
seq = sbol3.Sequence('seq1')
test_loc = sbol3.EntireSequence(seq)
seq_feat1 = sbol3.SequenceFeature(locations=test_loc)
self.assertEqual([test_loc], seq_feat1.locations)


if __name__ == '__main__':
unittest.main()
16 changes: 16 additions & 0 deletions test/test_subcomponent.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ def test_external_instance_of(self):
self.assertCountEqual([m9_media, e_coli],
[sc.instance_of for sc in c2.features])

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
instance_uri = 'https://example.org/instance'
seq1 = sbol3.Sequence('seq1')
test_loc = sbol3.EntireSequence(seq1)
seq2 = sbol3.Sequence('seq2')
test_source_loc = sbol3.EntireSequence(seq1)
subcomp1 = sbol3.SubComponent(instance_of=instance_uri,
locations=test_loc,
source_locations=test_source_loc)
self.assertEqual([test_loc], subcomp1.locations)
self.assertEqual([test_source_loc], subcomp1.source_locations)


if __name__ == '__main__':
unittest.main()
16 changes: 15 additions & 1 deletion test/test_varcomp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sbol3


class TestVariableComponent(unittest.TestCase):
class TestVariableFeature(unittest.TestCase):

def setUp(self) -> None:
sbol3.set_defaults()
Expand Down Expand Up @@ -72,6 +72,20 @@ def test_round_trip2(self):
report = m1.validate()
self.assertEqual(0, len(report.errors))

def test_list_wrapping(self):
# Ensure that at least certain properties handle automatic list
# wrapping and are typed to do so.
# See https://github.com/SynBioDex/pySBOL3/issues/301
sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
seq = sbol3.Sequence('seq1')
test_loc = sbol3.EntireSequence(seq)
variable_uri = 'https://example.org/variable'
var_coll_uri = 'https://example.org/collection'
var_feat1 = sbol3.VariableFeature(cardinality=sbol3.SBOL_ZERO_OR_MORE,
variable=variable_uri,
variant_collections=var_coll_uri)
self.assertEqual([var_coll_uri], var_feat1.variant_collections)


if __name__ == '__main__':
unittest.main()

0 comments on commit 6f63272

Please sign in to comment.