"""consumption_log.txt 兼容 TSV 格式。""" import pytest from app.config import settings from app.services.consumable_vision_algorithm import ClsTop3 from app.services.consumption_tsv_log import ( HEADER, SUMMARY_HEADER, _RANGE_SEP, append_consumption_log_summary, append_consumption_tsv_line, build_consumption_markdown, build_tsv_line, init_consumption_log_file, resolve_consumption_item_id, short_camera_label, ) def test_short_camera_label() -> None: assert short_camera_label("or-cam-01") == "cam01" assert short_camera_label("or-cam-2") == "cam02" def test_build_tsv_line_matches_sample_shape(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(settings, "consumption_log_timezone", "UTC") best = ClsTop3( t1_name="一次性医用灭菌棉签", t1_conf=0.9997, t2_name="cls2", t2_conf=0.0003, t3_name="cls3", t3_conf=0.0002, t1_pid="2237844", t2_pid="11765-1-101", t3_pid="21504-1-1", ) # 墙钟:拉流起点对齐到 2024-01-01T00:00:00Z,时间窗 +0s…+45s w0 = 1704067200.0 line = build_tsv_line( name_to_code={}, best=best, doctor_id="DOCTOR_PLACEHOLDER", camera_id="or-cam-01", wall_start_epoch=w0, wall_end_epoch=w0 + 45.0, ) parts = line.rstrip("\n").split("\t") assert len(parts) == 5 assert parts[0] == "2237844" assert parts[1] == "一次性医用灭菌棉签" assert parts[2] == "1" assert parts[3] == "DOCTOR_PLACEHOLDER" assert ( parts[4] == "cam01@2024-01-01T00:00:00.000+00:00" + _RANGE_SEP + "2024-01-01T00:00:45.000+00:00" ) def test_resolve_consumption_item_id_uses_normalized_catalog_key() -> None: name_to_code = {"一次性使用手术单(一次性医用垫单)": "PID-900"} assert resolve_consumption_item_id("一次性医用垫单", "", name_to_code) == "PID-900" def test_header_columns() -> None: cols = HEADER.strip().split("\t") assert cols == ["item_id", "item_name", "qty", "doctor_id", "timestamp"] def test_per_surgery_file_init_and_append( tmp_path, monkeypatch: pytest.MonkeyPatch, ) -> None: monkeypatch.setattr(settings, "consumption_tsv_log_enabled", True) monkeypatch.setattr( settings, "consumption_tsv_log_path", str(tmp_path / "{surgery_id}.txt"), ) init_consumption_log_file("or-001") append_consumption_tsv_line("or-001", "row1\n") append_consumption_tsv_line("or-001", "row2\n") p = tmp_path / "or-001.txt" assert p.read_text(encoding="utf-8") == HEADER + "row1\n" + "row2\n" init_consumption_log_file("or-001") assert p.read_text(encoding="utf-8") == HEADER def test_append_consumption_log_summary_appends_three_column_block( tmp_path, monkeypatch: pytest.MonkeyPatch, ) -> None: monkeypatch.setattr(settings, "consumption_tsv_log_enabled", True) monkeypatch.setattr( settings, "consumption_tsv_log_path", str(tmp_path / "{surgery_id}.txt"), ) init_consumption_log_file("s1") append_consumption_tsv_line("s1", "x\n") append_consumption_log_summary( "s1", {"A": ("nA", 2), "B": ("nB", 1)}, ) text = (tmp_path / "s1.txt").read_text(encoding="utf-8") assert text.endswith( "\n" + SUMMARY_HEADER + "A\tnA\t2\n" + "B\tnB\t1\n" ) def test_build_consumption_markdown_top123_columns(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(settings, "consumption_log_timezone", "UTC") best = ClsTop3( t1_name="一次性医用灭菌棉签", t1_conf=0.9997, t2_name="cls2", t2_conf=0.0003, t3_name="cls3", t3_conf=0.0002, t1_pid="2237844", t2_pid="11765-1-101", t3_pid="21504-1-1", ) w0 = 1704067200.0 md = build_consumption_markdown( name_to_code={}, best=best, doctor_id="DOCTOR_PLACEHOLDER", camera_id="or-cam-01", wall_start_epoch=w0, wall_end_epoch=w0 + 45.0, ) assert "| item_id |" in md and "| item_name |" in md and "| qty |" in md assert "2237844" in md assert "一次性医用灭菌棉签" in md assert "DOCTOR_PLACEHOLDER" in md assert "| 1 |" in md # 终端为可读时间戳,非落盘用 ISO@cam assert "2024-01-01 00:00:00.000" in md and "2024-01-01 00:00:45.000" in md assert "cam01" in md and " · " in md and _RANGE_SEP in md assert "cam01@2024-01" not in md