Skip to content

Commit

Permalink
✨ Allow Dynamic Replacement of DataElementFreeText.entered_input (#…
Browse files Browse the repository at this point in the history
…116)

* ✨ Allow Dynamic Replacement of `DataElementFreeText`.`entered_input` based on the discriminator
  • Loading branch information
hf-kklein authored Jun 8, 2022
1 parent 6ca7dfb commit 03ca65d
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/maus/models/anwendungshandbuch.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
from typing import Callable, List, Optional, Sequence
from uuid import UUID

import attr.validators
import attrs
from marshmallow import Schema, fields, post_load # type:ignore[import]

from maus.models.edifact_components import Segment, SegmentGroup, SegmentGroupSchema
from maus.models.edifact_components import DataElementFreeText, Segment, SegmentGroup, SegmentGroupSchema


# pylint:disable=too-many-instance-attributes
Expand Down Expand Up @@ -250,6 +251,24 @@ def deserialize(self, data, **kwargs) -> FlatAnwendungshandbuch:
return FlatAnwendungshandbuch(**data)


@attrs.define(auto_attribs=True, kw_only=True)
class DeepAhbInputReplacement:
"""
A container class that models replacements of inputs in the DeepAnwendungshandbuch
"""

#: true iff a replacement is applicable
replacement_found: bool = attrs.field(validator=attrs.validators.instance_of(bool))
input_replacement: Optional[str] = attrs.field(
validator=attrs.validators.optional(attr.validators.instance_of(str))
)
"""
The replacement for entered_input itself. Note that the replacement may be None even if a replacement is found.
This implies, that you must always check for replacement_found is True first and then, iff true, replace with the
replacement, even if it may be None/null.
"""


@attrs.define(auto_attribs=True, kw_only=True)
class DeepAnwendungshandbuch:
"""
Expand Down Expand Up @@ -310,6 +329,32 @@ def find_segments(
result += segment_group.find_segments(segment_predicate)
return result

def replace_inputs_based_on_discriminator(self, replacement_func: Callable[[str], DeepAhbInputReplacement]) -> None:
"""
Replace all the entered_inputs in the entire DeepAnwendungshandbuch using the given replacement_func.
Note that this modifies this DeepAnwendungshandbuch instance (self).
"""
_replace_inputs_based_on_discriminator(self.lines, replacement_func)


def _replace_inputs_based_on_discriminator(
segment_groups: List[SegmentGroup], replacement_func: Callable[[str], DeepAhbInputReplacement]
) -> None:
"""
Replace all the entered_inputs in the entire list of segment groups using the given replacement_func.
"""
for segment_group in segment_groups:
if segment_group.segment_groups is not None:
_replace_inputs_based_on_discriminator(segment_group.segment_groups, replacement_func)
if segment_group.segments is None:
continue
for segment in segment_group.segments:
for data_element in segment.data_elements:
if isinstance(data_element, DataElementFreeText):
replacement_result = replacement_func(data_element.discriminator)
if replacement_result.replacement_found is True:
data_element.entered_input = replacement_result.input_replacement


class DeepAnwendungshandbuchSchema(Schema):
"""
Expand Down
139 changes: 139 additions & 0 deletions tests/unit_tests/test_ahb.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
AhbLineSchema,
AhbMetaInformation,
AhbMetaInformationSchema,
DeepAhbInputReplacement,
DeepAnwendungshandbuch,
DeepAnwendungshandbuchSchema,
FlatAnwendungshandbuch,
Expand Down Expand Up @@ -639,3 +640,141 @@ def test_sorted_segment_groups(
):
actual = FlatAnwendungshandbuch._sorted_lines_by_segment_groups(unsorted_input, sg_order)
assert actual == expected_result

@pytest.mark.parametrize(
"original,expected",
[
pytest.param(
DeepAnwendungshandbuch(
meta=AhbMetaInformation(pruefidentifikator="11042"),
lines=[
SegmentGroup(
ahb_expression="expr A",
discriminator="disc A",
segments=[
Segment(
ahb_expression="expr B",
discriminator="disc B",
section_name="foo",
data_elements=[
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input="Hello Maus",
discriminator="foo",
data_element_id="4567",
),
],
),
],
segment_groups=[
SegmentGroup(
discriminator="disc C",
ahb_expression="expr C",
segments=[
Segment(
section_name="bar",
ahb_expression="expr Y",
discriminator="disc Y",
data_elements=[
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input="Hello Elefant",
discriminator="abc",
data_element_id="4567",
),
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input="this should stay untouched",
discriminator="qwert",
data_element_id="4567",
),
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input="Not none",
discriminator="replace_with_none_here",
data_element_id="4567",
),
],
)
],
segment_groups=None,
),
],
),
],
),
DeepAnwendungshandbuch(
meta=AhbMetaInformation(pruefidentifikator="11042"),
lines=[
SegmentGroup(
ahb_expression="expr A",
discriminator="disc A",
segments=[
Segment(
ahb_expression="expr B",
discriminator="disc B",
section_name="foo",
data_elements=[
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input="bar",
discriminator="foo",
data_element_id="4567",
),
],
),
],
segment_groups=[
SegmentGroup(
discriminator="disc C",
ahb_expression="expr C",
segments=[
Segment(
section_name="bar",
ahb_expression="expr Y",
discriminator="disc Y",
data_elements=[
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input="xyz",
discriminator="abc",
data_element_id="4567",
),
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input="this should stay untouched",
discriminator="qwert",
data_element_id="4567",
),
DataElementFreeText(
ahb_expression="Muss [1]",
entered_input=None,
discriminator="replace_with_none_here",
data_element_id="4567",
),
],
)
],
segment_groups=None,
),
],
),
],
),
)
],
)
def test_replacing_data_element_inputs(self, original: DeepAnwendungshandbuch, expected: DeepAnwendungshandbuch):
assert original != expected

def replacement_func(discriminator: str) -> DeepAhbInputReplacement:
if discriminator == "foo":
return DeepAhbInputReplacement(replacement_found=True, input_replacement="bar")
if discriminator == "abc":
return DeepAhbInputReplacement(replacement_found=True, input_replacement="xyz")
if discriminator == "replace_with_none_here":
return DeepAhbInputReplacement(replacement_found=True, input_replacement=None)
return DeepAhbInputReplacement(replacement_found=False, input_replacement=None)

original.replace_inputs_based_on_discriminator(replacement_func)
assert original == expected

0 comments on commit 03ca65d

Please sign in to comment.