"""The Inc 0 exit gate: BREP serialisation is byte-identical to the stock wheel. Every subprocess pool moves shapes as BinTools bytes, so this is the IPC contract. It is also a storage contract: cad/derive.py content-addresses BREP payloads (payloads/derived/brep/.brep) and stores the ref inside the document, so bytes that differ would silently rewrite every derived payload. The comparison is our-rewrite vs stock-rewrite. tools/gen_fixtures.py already proved stock is idempotent for each fixture, which is what makes the stored digest a fixed reference rather than one arbitrary encoding of many. """ from __future__ import annotations import hashlib import io import pytest from OCP.BinTools import BinTools from OCP.TopAbs import TopAbs_FACE from OCP.TopExp import TopExp from OCP.TopoDS import TopoDS_Shape from OCP.TopTools import TopTools_IndexedMapOfShape from .conftest import DATA def _rewrite(data: bytes) -> bytes: shape = TopoDS_Shape() BinTools.Read_s(shape, io.BytesIO(data)) out = io.BytesIO() BinTools.Write_s(shape, out) return out.getvalue() def test_roundtrip_is_byte_identical(manifest): for name, expected in manifest["shapes"].items(): original = (DATA / f"{name}.brep").read_bytes() assert hashlib.sha256(original).hexdigest() == expected["sha256"], ( f"{name}.brep does not match the manifest — regenerate fixtures" ) assert hashlib.sha256(_rewrite(original)).hexdigest() == expected["sha256"], ( f"{name}: rewritten bytes differ from the stock wheel's" ) def test_face_map_ordering_survives_the_roundtrip(manifest, fixture_shapes): # Face identity throughout the topology code is the map ordinal, so a # round trip that renumbered faces would silently retarget every anchor. for name, shape in fixture_shapes.items(): faces = TopTools_IndexedMapOfShape() TopExp.MapShapes_s(shape, TopAbs_FACE, faces) assert faces.Extent() == manifest["shapes"][name]["faces"], name def test_empty_compound_survives(): shape = TopoDS_Shape() BinTools.Read_s(shape, io.BytesIO((DATA / "empty_compound.brep").read_bytes())) assert not shape.IsNull() def test_extension_bytes_api_matches_the_drop_in(fixture_shapes): # n3xd_ocp.bintools exists to skip the BytesIO detour on the pool paths; it # is only usable there if it produces the very same bytes. from n3xd_ocp import bintools for name, shape in fixture_shapes.items(): buf = io.BytesIO() BinTools.Write_s(shape, buf) assert bintools.write_bytes(shape) == buf.getvalue(), name restored = bintools.read_bytes(buf.getvalue()) assert bintools.write_bytes(restored) == buf.getvalue(), name @pytest.mark.parametrize("name", ["box", "fused"]) def test_write_appends_to_the_stream_position(name): # BinTools.Write_s writes through a file-like object; a caller that already # wrote a header must still find its bytes intact. shape = TopoDS_Shape() BinTools.Read_s(shape, io.BytesIO((DATA / f"{name}.brep").read_bytes())) buf = io.BytesIO() buf.write(b"HEADER") BinTools.Write_s(shape, buf) assert buf.getvalue().startswith(b"HEADER")