[BuildLibrary] fix auto-rename during merge
This commit is contained in:
parent
1b83034b7e
commit
5e0cc0e20f
2 changed files with 211 additions and 45 deletions
|
|
@ -1,19 +1,47 @@
|
|||
from collections.abc import Iterator
|
||||
|
||||
import pytest
|
||||
|
||||
from ..builder import Pather
|
||||
from ..error import BuildError
|
||||
from ..library import BuildLibrary, Library, cell
|
||||
from ..library import BuildLibrary, BuildReport, ILibraryView, Library, cell, dangling_mode_t
|
||||
from ..pattern import Pattern
|
||||
from ..ports import Port
|
||||
|
||||
|
||||
def _owned_by(report, owner: str) -> set[str]:
|
||||
def _owned_by(report: BuildReport, owner: str) -> set[str]:
|
||||
return {
|
||||
name for name, prov in report.provenance.items()
|
||||
if prov.owner_declared_name == owner
|
||||
}
|
||||
|
||||
|
||||
class _MetadataSource(ILibraryView):
|
||||
def __init__(self, mapping: dict[str, Pattern], child_graph: dict[str, set[str]]) -> None:
|
||||
self.mapping = mapping
|
||||
self._child_graph = child_graph
|
||||
self.loads = 0
|
||||
|
||||
def __getitem__(self, key: str) -> Pattern:
|
||||
self.loads += 1
|
||||
return self.mapping[key]
|
||||
|
||||
def __iter__(self) -> Iterator[str]:
|
||||
return iter(self.mapping)
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self.mapping)
|
||||
|
||||
def __contains__(self, key: object) -> bool:
|
||||
return key in self.mapping
|
||||
|
||||
def source_order(self) -> tuple[str, ...]:
|
||||
return tuple(self.mapping)
|
||||
|
||||
def child_graph(self, dangling: dangling_mode_t = 'error') -> dict[str, set[str]]: # noqa: ARG002
|
||||
return self._child_graph
|
||||
|
||||
|
||||
def test_build_library_traces_declared_dependencies_out_of_order() -> None:
|
||||
builder = BuildLibrary()
|
||||
|
||||
|
|
@ -59,6 +87,36 @@ def test_build_library_tracks_helper_provenance_and_tree_merge_renames() -> None
|
|||
assert any(name != prov.requested_name for name, prov in helpers)
|
||||
|
||||
|
||||
def test_build_library_authoring_tree_merge_renames_repeated_single_use_names() -> None:
|
||||
builder = BuildLibrary()
|
||||
tree = Library({"_helper": Pattern()})
|
||||
|
||||
name_a = builder << tree
|
||||
name_b = builder << tree
|
||||
built, report = builder.build()
|
||||
|
||||
assert name_a == "_helper"
|
||||
assert name_b != "_helper"
|
||||
assert name_a in built
|
||||
assert name_b in built
|
||||
assert report.provenance[name_b].requested_name == name_b
|
||||
|
||||
|
||||
def test_build_library_authoring_tree_merge_remaps_internal_refs() -> None:
|
||||
builder = BuildLibrary()
|
||||
builder["_helper"] = Pattern()
|
||||
helper = Pattern()
|
||||
top = Pattern()
|
||||
top.ref("_helper")
|
||||
|
||||
top_name = builder << Library({"_helper": helper, "top": top})
|
||||
built, _report = builder.build()
|
||||
|
||||
assert top_name == "top"
|
||||
assert "_helper" not in built[top_name].refs
|
||||
assert any(name != "_helper" for name in built[top_name].refs)
|
||||
|
||||
|
||||
def test_build_library_requires_build_session_for_reads_and_freezes_after_build() -> None:
|
||||
builder = BuildLibrary()
|
||||
builder["leaf"] = Pattern()
|
||||
|
|
@ -206,6 +264,70 @@ def test_build_library_add_source_can_rename_every_source_cell() -> None:
|
|||
assert report.provenance["mapped_child"].requested_name == "child"
|
||||
|
||||
|
||||
def test_build_library_authoring_tree_merge_keeps_source_view_lazy() -> None:
|
||||
child = Pattern()
|
||||
top = Pattern()
|
||||
top.ref("child")
|
||||
source = _MetadataSource(
|
||||
{"child": child, "top": top},
|
||||
{"child": set(), "top": {"child"}},
|
||||
)
|
||||
|
||||
builder = BuildLibrary()
|
||||
top_name = builder << source
|
||||
built, _report = builder.build()
|
||||
|
||||
assert top_name == "top"
|
||||
assert "top" in built
|
||||
assert source.loads == 0
|
||||
|
||||
|
||||
def test_build_library_authoring_source_tree_merge_returns_renamed_top() -> None:
|
||||
existing = Pattern()
|
||||
source_top = Pattern()
|
||||
source = _MetadataSource(
|
||||
{"_helper": source_top},
|
||||
{"_helper": set()},
|
||||
)
|
||||
|
||||
builder = BuildLibrary()
|
||||
builder["_helper"] = existing
|
||||
top_name = builder << source
|
||||
built, _report = builder.build()
|
||||
|
||||
assert top_name != "_helper"
|
||||
assert top_name in built
|
||||
assert source.loads == 0
|
||||
|
||||
|
||||
def test_build_library_authoring_source_tree_merge_remaps_renamed_child_on_materialization() -> None:
|
||||
source_helper = Pattern()
|
||||
source_top = Pattern()
|
||||
source_top.ref("_helper")
|
||||
source = _MetadataSource(
|
||||
{"_helper": source_helper, "top": source_top},
|
||||
{"_helper": set(), "top": {"_helper"}},
|
||||
)
|
||||
|
||||
builder = BuildLibrary()
|
||||
builder["_helper"] = Pattern()
|
||||
top_name = builder << source
|
||||
built, _report = builder.build(output="library")
|
||||
|
||||
assert top_name == "top"
|
||||
assert "_helper" not in built[top_name].refs
|
||||
assert source.loads == 2
|
||||
|
||||
|
||||
def test_build_library_rejects_authoring_tree_le_before_mutating() -> None:
|
||||
builder = BuildLibrary()
|
||||
|
||||
with pytest.raises(BuildError, match="__le__"):
|
||||
_abstract = builder <= Library({"leaf": Pattern()})
|
||||
|
||||
assert list(builder) == []
|
||||
|
||||
|
||||
def test_build_library_rejects_source_cells_added_after_add_source() -> None:
|
||||
source = Library({"src": Pattern()})
|
||||
builder = BuildLibrary()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue