Files
llm/tests/1c/test_structural_stream_parser.py
T
2026-08-14 09:40:51 +03:00

113 lines
4.2 KiB
Python

from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT / "plugins" / "1c"))
from parser.cas_payload import ( # noqa: E402
classify_payload,
decode_declared_utf8_bsl_prefix,
extract_stream_blocks,
replace_declared_utf8_bsl_prefix_same_width,
stream_header,
structural_stream_blocks_with_data,
)
def test_structural_stream_parser_ignores_header_signature_inside_member() -> None:
fake_header = stream_header(1)
first = b"prefix" + fake_header + b"tail"
payload = b"lead" + stream_header(len(first)) + first + stream_header(3) + b"end"
# The old discovery scanner sees the signature embedded in `first`.
assert len(extract_stream_blocks(payload, include_text=True)) == 3
blocks = structural_stream_blocks_with_data(payload)
assert len(blocks) == 2
assert blocks[0]["data"] == first
assert blocks[1]["data"] == b"end"
def test_declared_utf8_bsl_prefix_excludes_opaque_member_tail() -> None:
bsl = b"\xef\xbb\xbf// marker\r\n"
opaque = b"\x00\x04\x10metadata"
member = bsl + opaque
header = f"\r\n{len(bsl):08x} {len(member):08x} 7fffffff \r\n".encode("ascii")
payload = b"lead" + header + member
decoded = decode_declared_utf8_bsl_prefix(payload, 0)
assert decoded["status"] == "ok"
assert decoded["text"] == "// marker\r\n"
assert decoded["bsl_prefix_bytes"] == len(bsl)
assert decoded["opaque_tail_bytes"] == len(opaque)
def test_classification_uses_declared_utf8_prefix_not_opaque_member_tail() -> None:
bsl = b"\xef\xbb\xbf// source-only\r\n"
opaque = b"\x00metadata-tail-that-is-not-bsl"
member = bsl + opaque
header = f"\r\n{len(bsl):08x} {len(member):08x} 7fffffff \r\n".encode("ascii")
classified = classify_payload(b"lead" + header + member, include_text=True)
stream = classified["stream_blocks"][0]
assert stream["text"] == "// source-only\r\n"
assert stream["declared_utf8_bsl_prefix"]["opaque_tail_bytes"] == len(opaque)
def test_classification_does_not_treat_declared_brace_prefix_as_bsl() -> None:
descriptor = b"\xef\xbb\xbf{3,1,0,\"\",0}"
member = descriptor + b"\x00opaque"
header = f"\r\n{len(descriptor):08x} {len(member):08x} 7fffffff \r\n".encode("ascii")
classified = classify_payload(b"lead" + header + member, include_text=True)
assert "declared_utf8_bsl_prefix" not in classified["stream_blocks"][0]
def test_fixed_width_prefix_replacement_preserves_tail_and_all_other_members() -> None:
first = b"first-member"
old_text = "//Пример - 3\r\n//Пример - 4 "
old_prefix = b"\xef\xbb\xbf" + old_text.encode("utf-8")
opaque = b"\x00opaque-platform-tail\x10\x20"
member = old_prefix + opaque
payload = (
b"lead"
+ stream_header(len(first))
+ first
+ f"\r\n{len(old_prefix):08x} {len(member):08x} 7fffffff \r\n".encode("ascii")
+ member
+ stream_header(3)
+ b"end"
)
replacement, evidence = replace_declared_utf8_bsl_prefix_same_width(
payload,
1,
text="//Тест - 3\r\n//Пример - 4 ",
)
before = structural_stream_blocks_with_data(payload)
after = structural_stream_blocks_with_data(replacement)
assert evidence["padding_bytes"] == len("Пример".encode("utf-8")) - len("Тест".encode("utf-8"))
assert before[0]["data"] == after[0]["data"]
assert before[1]["data"][len(old_prefix) :] == after[1]["data"][len(old_prefix) :]
assert before[2]["data"] == after[2]["data"]
assert decode_declared_utf8_bsl_prefix(replacement, 1)["text"].startswith("//Тест - 3")
def test_fixed_width_prefix_replacement_rejects_growth() -> None:
old_prefix = b"\xef\xbb\xbf// one"
member = old_prefix + b"opaque"
payload = b"lead" + f"\r\n{len(old_prefix):08x} {len(member):08x} 7fffffff \r\n".encode("ascii") + member
try:
replace_declared_utf8_bsl_prefix_same_width(payload, 0, text="// replacement that is longer")
except ValueError as exc:
assert str(exc) == "replacement_declared_bsl_prefix_exceeds_fixed_width"
else:
raise AssertionError("fixed-width codec accepted growth")