Skip to content

Commit

Permalink
feat(decl): Implement recursive sync
Browse files Browse the repository at this point in the history
  • Loading branch information
huyenngn committed Mar 7, 2024
1 parent 049b8ee commit 1131c4b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
11 changes: 8 additions & 3 deletions capellambse/decl.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def _operate_sync(

for obj in v:
try:
find_args = obj.pop("find")
find_args = obj["find"]
except KeyError:
raise ValueError(
"Expected `find` key in sync object"
Expand All @@ -274,6 +274,8 @@ def _operate_sync(

if candidates:
candidate = candidates[0]
if sync := obj.pop("sync", None):
yield from _operate_sync(promises, candidate, sync)
if mods := obj.pop("set", None):
yield from _operate_modify(promises, candidate, mods)
if ext := obj.pop("add", None):
Expand All @@ -284,12 +286,15 @@ def _operate_sync(
promise = Promise(promise)
yield (promise, candidate)
else:
newobj_props = find_args | obj.get("set", {})
newobj_props = (
find_args | obj.pop("set", {}) | obj.pop("add", {})
)
if "promise_id" in obj:
newobj_props["promise_id"] = obj["promise_id"]
newobj_props["promise_id"] = obj.pop("promise_id")
yield from _create_complex_objects(
promises, parent, attr, [newobj_props]
)
yield from _operate_sync(promises, parent, modifications)

yield from ()

Expand Down
33 changes: 31 additions & 2 deletions tests/test_decl.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ def test_sync_operation_finds_and_modifies_existing_objects_in_the_list(
assert root_function.functions[0].description == new_description

@staticmethod
def test_sync_operation_finds_and_modifies_existing_objects_in_the_list_recurse(
def test_sync_operation_overwrites_iterables(
model: capellambse.MelodyModel,
) -> None:
root_function = model.by_uuid(ROOT_FUNCTION)
Expand Down Expand Up @@ -648,7 +648,7 @@ def test_sync_operation_finds_and_modifies_existing_objects_in_the_list_recurse(
)

@staticmethod
def test_sync_operation_finds_and_extends_existing_objects_in_the_list_recurse(
def test_sync_operation_extends_iterables(
model: capellambse.MelodyModel,
) -> None:
root_function = model.by_uuid(ROOT_FUNCTION)
Expand Down Expand Up @@ -685,6 +685,30 @@ def test_sync_operation_finds_and_extends_existing_objects_in_the_list_recurse(
and new_input in subfunc.inputs.by_name
)

@staticmethod
def test_sync_operation_recursive(model: capellambse.MelodyModel) -> None:
root_package = model.la.data_package
package_name = "The new package"
subpackage_name = "The new subpackage"
assert package_name not in root_package.packages.by_name
yml = f"""\
- parent: !uuid {root_package.uuid}
sync:
packages:
- find:
name: "{package_name}"
sync:
packages:
- find:
name: {subpackage_name}
"""

decl.apply(model, io.StringIO(yml))
assert package_name in root_package.packages.by_name
package = root_package.packages.by_name(package_name)
assert subpackage_name in package.packages.by_name

@staticmethod
def test_sync_operation_creates_a_new_object_if_it_didnt_find_a_match(
model: capellambse.MelodyModel,
Expand All @@ -693,6 +717,7 @@ def test_sync_operation_creates_a_new_object_if_it_didnt_find_a_match(
new_name = "The new function"
new_description = "This is a new function."
assert new_name not in root_function.functions.by_name
input = "Power port"
yml = f"""\
- parent: !uuid {ROOT_FUNCTION}
sync:
Expand All @@ -701,13 +726,17 @@ def test_sync_operation_creates_a_new_object_if_it_didnt_find_a_match(
name: {new_name}
set:
description: {new_description!r}
add:
inputs:
- name: {input}
"""

decl.apply(model, io.StringIO(yml))

assert new_name in root_function.functions.by_name
func = root_function.functions.by_name(new_name, single=True)
assert func.description == new_description
assert input in func.inputs.by_name

@staticmethod
def test_sync_operation_resolves_promises_with_newly_created_objects(
Expand Down

0 comments on commit 1131c4b

Please sign in to comment.