75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
"""树展平器单测:用真实 store/videos/0RxMZBLeqRI/tree.json 验证展平正确性与 fail-loud。"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.harness.tree_nodes import load_tree_data_for_videos, load_tree_nodes
|
|
|
|
_STORE = Path("store")
|
|
_VID = "0RxMZBLeqRI" # 真实样本,111 节点
|
|
|
|
|
|
def _recursive_count(tree_json: dict) -> int:
|
|
def walk(n: dict) -> int:
|
|
return 1 + sum(walk(c) for c in (n.get("children") or []))
|
|
|
|
return sum(walk(r) for r in tree_json["roots"])
|
|
|
|
|
|
def test_load_tree_nodes_flattens_all_nodes():
|
|
result = load_tree_nodes(_STORE, _VID)
|
|
assert set(result.keys()) == {"nodes"}
|
|
nodes = result["nodes"]
|
|
raw = json.loads((_STORE / "videos" / _VID / "tree.json").read_text(encoding="utf-8"))
|
|
assert len(nodes) == _recursive_count(raw)
|
|
sample = next(iter(nodes.values()))
|
|
assert set(sample.keys()) == {"card", "level", "time_range"}
|
|
assert isinstance(sample["card"], dict)
|
|
|
|
|
|
def test_level_assigned_by_depth_not_node_id():
|
|
nodes = load_tree_nodes(_STORE, _VID)["nodes"]
|
|
l1_id = f"{_VID}_L1_000"
|
|
l3_id = f"{_VID}_L1_000_L2_000_L3_000"
|
|
assert nodes[l1_id]["level"] == 1
|
|
assert nodes[l3_id]["level"] == 3 # 若按 node_id 首个 _L\d_ 会误判成 1
|
|
|
|
|
|
def test_missing_tree_raises_file_not_found():
|
|
with pytest.raises(FileNotFoundError):
|
|
load_tree_nodes(_STORE, "__no_such_video__")
|
|
|
|
|
|
def test_empty_roots_raises_value_error(tmp_path):
|
|
vdir = tmp_path / "videos" / "vX"
|
|
vdir.mkdir(parents=True)
|
|
(vdir / "tree.json").write_text(json.dumps({"metadata": {}, "roots": []}), encoding="utf-8")
|
|
with pytest.raises(ValueError):
|
|
load_tree_nodes(tmp_path, "vX")
|
|
|
|
|
|
def test_node_missing_id_raises_value_error(tmp_path):
|
|
vdir = tmp_path / "videos" / "vX"
|
|
vdir.mkdir(parents=True)
|
|
(vdir / "tree.json").write_text(
|
|
json.dumps({"roots": [{"card": {}, "time_range": [0, 1]}]}), encoding="utf-8"
|
|
)
|
|
with pytest.raises(ValueError):
|
|
load_tree_nodes(tmp_path, "vX")
|
|
|
|
|
|
def test_roots_not_list_raises_value_error(tmp_path):
|
|
vdir = tmp_path / "videos" / "vX"
|
|
vdir.mkdir(parents=True)
|
|
(vdir / "tree.json").write_text(json.dumps({"roots": "not-a-list"}), encoding="utf-8")
|
|
with pytest.raises(ValueError):
|
|
load_tree_nodes(tmp_path, "vX")
|
|
|
|
|
|
def test_load_for_videos_dedups():
|
|
data = load_tree_data_for_videos(_STORE, [_VID, _VID])
|
|
assert set(data.keys()) == {_VID}
|
|
assert data[_VID]["nodes"]
|