Skip to content

Commit

Permalink
Implement Extension.to_json_serializable
Browse files Browse the repository at this point in the history
  • Loading branch information
UnHumbleBen committed May 15, 2022
1 parent 819d0d8 commit 860be06
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 16 deletions.
28 changes: 27 additions & 1 deletion scadnano/scadnano.py
Original file line number Diff line number Diff line change
Expand Up @@ -2063,7 +2063,12 @@ class Extension(_JSONSerializable, Generic[DomainLabel]):
_parent_strand: Optional['Strand'] = field(init=False, repr=False, compare=False, default=None)

def to_json_serializable(self, suppress_indent: bool = True, **kwargs: Any) -> Union[Dict[str, Any], NoIndent]:
raise NotImplementedError()
json_map: Dict[str, Any] = {extension_key: self.num_bases}
self._add_display_length_if_not_default(json_map)
self._add_display_angle_if_not_default(json_map)
self._add_name_if_not_default(json_map)
self._add_label_if_not_default(json_map)
return json_map

def dna_length(self) -> int:
"""Length of this :any:`Extension`; same as field :py:data:`Extension.length`."""
Expand Down Expand Up @@ -2094,6 +2099,27 @@ def float_transformer(x): return float(x)
display_angle=display_angle,
label=label, name=name)

def _add_display_length_if_not_default(self, json_map) -> None:
self._add_key_value_to_json_map_if_not_default(
key=display_length_key, value_callback=lambda x: x.display_length, json_map=json_map)

def _add_display_angle_if_not_default(self, json_map) -> None:
self._add_key_value_to_json_map_if_not_default(
key=display_angle_key, value_callback=lambda x: x.display_angle, json_map=json_map)

def _add_name_if_not_default(self, json_map) -> None:
self._add_key_value_to_json_map_if_not_default(
key=domain_name_key, value_callback=lambda x: x.name, json_map=json_map)

def _add_label_if_not_default(self, json_map) -> None:
self._add_key_value_to_json_map_if_not_default(
key=domain_label_key, value_callback=lambda x: x.label, json_map=json_map)

def _add_key_value_to_json_map_if_not_default(
self, key: str, value_callback: Callable[["Extension"], Any], json_map: Dict[str, Any]) -> None:
if value_callback(self) != value_callback(_default_extension):
json_map[key] = value_callback(self)


# Default Extension object to allow for access to default extension values. num_bases is a dummy.
_default_extension: Extension = Extension(num_bases=5)
Expand Down
63 changes: 48 additions & 15 deletions tests/scadnano_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4881,20 +4881,6 @@ def test_to_json_extension_design__extension(self) -> None:
self.assertIn("extension", document["strands"][0]["domains"][1])
self.assertEqual(5, document["strands"][0]["domains"][1]["extension"])

def test_to_json_extension_design__relative_offset(self) -> None:
# Setup
design = sc.Design(helices=[sc.Helix(max_offset=100)], strands=[], grid=sc.square)
design.draw_strand(0, 0).to(10).extension_3p(5).with_relative_offset((1.4, -0.3))

# Action
result = design.to_json()

# Verify
document = json.loads(result)
self.assertEqual(2, len(document["strands"][0]["domains"]))
self.assertIn("relative_offset", document["strands"][0]["domains"][1])
self.assertEqual([1.4, -0.3], document["strands"][0]["domains"][1]["relative_offset"])


class TestIllegalStructuresPrevented(unittest.TestCase):

Expand Down Expand Up @@ -7370,4 +7356,51 @@ def test_plate_map_markdown(self) -> None:
| G | | | | | | | | | | | | |
| H | | | | | | | | | | | | |
""".strip()
self.assertEqual(expected_md, actual_md)
self.assertEqual(expected_md, actual_md)


class TestExtension(unittest.TestCase):
def test_to_json_serializable__extension_key_contains_num_bases(self) -> None:
ext = sc.Extension(5)
result = ext.to_json_serializable()
self.assertEqual(result["extension"], 5)

def test_to_json_serializable__no_display_length_key_when_default_display_length(self) -> None:
ext = sc.Extension(5)
result = ext.to_json_serializable()
self.assertNotIn("display_length", result)

def test_to_json_serializable__no_display_angle_key_when_default_display_angle(self) -> None:
ext = sc.Extension(5)
result = ext.to_json_serializable()
self.assertNotIn("display_angle", result)

def test_to_json_serializable__no_name_key_when_default_name(self) -> None:
ext = sc.Extension(5)
result = ext.to_json_serializable()
self.assertNotIn("name", result)

def test_to_json_serializable__no_label_key_when_default_label(self) -> None:
ext = sc.Extension(5)
result = ext.to_json_serializable()
self.assertNotIn("label", result)

def test_to_json_serializable__display_length_key_contains_non_default_display_length(self) -> None:
ext = sc.Extension(5, display_length=1.9)
result = ext.to_json_serializable()
self.assertEqual(result["display_length"], 1.9)

def test_to_json_serializable__display_angle_key_contains_non_default_display_angle(self) -> None:
ext = sc.Extension(5, display_angle=39.9)
result = ext.to_json_serializable()
self.assertEqual(result["display_angle"], 39.9)

def test_to_json_serializable__name_key_contains_non_default_name(self) -> None:
ext = sc.Extension(5, name="A")
result = ext.to_json_serializable()
self.assertEqual(result["name"], "A")

def test_to_json_serializable__label_key_contains_non_default_name(self) -> None:
ext = sc.Extension(5, label="ext1")
result = ext.to_json_serializable()
self.assertEqual(result["label"], "ext1")

0 comments on commit 860be06

Please sign in to comment.