Files
xiaobaifupan/app/tests/preservation_helpers.py
T

104 lines
3.1 KiB
Python

from __future__ import annotations
import hashlib
import re
from pathlib import Path
APP_ROOT = Path(__file__).resolve().parents[1]
ORIGINAL_ROOT = APP_ROOT.parent
FRONTEND_ROOT = APP_ROOT / "frontend"
ORIGINAL_STATIC = ORIGINAL_ROOT / "static"
SOURCE_RANGE = re.compile(
r"/\* PRESERVATION-SOURCE-BEGIN app\.js:(\d+)-(\d+) \*/\n"
r"(.*?)"
r"/\* PRESERVATION-SOURCE-END app\.js:\1-\2 \*/\n?",
re.DOTALL,
)
# These exact original app.js line ranges were retired in slice 11 after the
# definition-only symbols passed static, runtime, and compatibility review.
RETIRED_FRONTEND_SOURCE_RANGES = (
(3537, 3540),
(4139, 4145),
(4973, 4989),
(9022, 9027),
(9052, 9055),
)
AUDITED_FRONTEND_SOURCE_LINE_COUNT = 9283
def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def reassembled_frontend_runtime() -> str:
chunks: dict[tuple[int, int], str] = {}
for path in FRONTEND_ROOT.rglob("*.js"):
for match in SOURCE_RANGE.finditer(path.read_text(encoding="utf-8")):
source_range = (int(match.group(1)), int(match.group(2)))
if source_range in chunks:
raise AssertionError(f"duplicate app.js source range: {source_range}")
chunks[source_range] = match.group(3)
assembled: list[str] = []
next_line = 1
for (start, end), content in sorted(chunks.items()):
if start != next_line:
raise AssertionError(
f"app.js source coverage gap: expected line {next_line}, got {start}"
)
assembled.append(content)
next_line = end + 1
if next_line != AUDITED_FRONTEND_SOURCE_LINE_COUNT + 1:
raise AssertionError(
"app.js source coverage ended at "
f"{next_line - 1}, expected {AUDITED_FRONTEND_SOURCE_LINE_COUNT}"
)
return "".join(assembled)
def original_runtime_after_audited_retirements() -> str:
lines = (ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8").splitlines(
keepends=True
)
retired = {
line_number
for start, end in RETIRED_FRONTEND_SOURCE_RANGES
for line_number in range(start, end + 1)
}
return "".join(
line for line_number, line in enumerate(lines, start=1) if line_number not in retired
)
def assert_frontend_runtime_matches_audited_baseline(testcase) -> None:
testcase.assertEqual(
reassembled_frontend_runtime(),
original_runtime_after_audited_retirements(),
)
def assert_moved_asset_matches(
testcase,
original_relative: str,
frontend_relative: str | None = None,
) -> None:
target_relative = frontend_relative or original_relative
testcase.assertEqual(
sha256(FRONTEND_ROOT / target_relative),
sha256(ORIGINAL_STATIC / original_relative),
original_relative,
)
def assert_page_prefix_matches(testcase, page_relative: str) -> None:
original = (ORIGINAL_STATIC / page_relative).read_text(encoding="utf-8")
migrated = (FRONTEND_ROOT / page_relative).read_text(encoding="utf-8")
testcase.assertTrue(
migrated.startswith(original.rstrip("\n") + "\n\n"),
page_relative,
)