"""effective_candidate_consumables / build_name_mapping:YAML 与分类模型,无 Excel。""" from __future__ import annotations from pathlib import Path from unittest.mock import MagicMock import pytest from app.config import Settings from app.services.consumable_vision_algorithm import ConsumableVisionAlgorithmService def test_effective_preserves_non_empty_request() -> None: svc = ConsumableVisionAlgorithmService(Settings()) got = svc.effective_candidate_consumables([" 纱布 ", "缝线", "纱布"]) assert got == ["纱布", "缝线"] def test_effective_empty_uses_model_when_yaml_has_no_names( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: yml = tmp_path / "empty.yaml" yml.write_text("names: {}\nlabel_id: {}\n", encoding="utf-8") s = Settings(consumable_classifier_labels_yaml_path=str(yml)) svc = ConsumableVisionAlgorithmService(s) mock_cls = MagicMock() mock_cls.names = {0: "ban", 1: "apple"} monkeypatch.setattr(svc, "_get_cls", lambda: mock_cls) assert svc.effective_candidate_consumables([]) == ["apple", "ban"] def test_effective_empty_prefers_yaml_class_names(tmp_path: Path) -> None: yml = tmp_path / "lab.yaml" yml.write_text( "names:\n 0: 商品甲\n 1: 商品乙\nlabel_id:\n 0: a\n 1: b\n", encoding="utf-8", ) s = Settings(consumable_classifier_labels_yaml_path=str(yml)) svc = ConsumableVisionAlgorithmService(s) assert svc.effective_candidate_consumables([]) == ["商品甲", "商品乙"] def test_effective_whitespace_only_treated_as_empty( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: yml = tmp_path / "empty.yaml" yml.write_text("names: {}\nlabel_id: {}\n", encoding="utf-8") s = Settings(consumable_classifier_labels_yaml_path=str(yml)) svc = ConsumableVisionAlgorithmService(s) mock_cls = MagicMock() mock_cls.names = {0: "x"} monkeypatch.setattr(svc, "_get_cls", lambda: mock_cls) assert svc.effective_candidate_consumables(["", " "]) == ["x"] def test_build_name_mapping_from_label_id(tmp_path: Path) -> None: yml = tmp_path / "lab.yaml" yml.write_text( "names:\n 0: 商品A\nlabel_id:\n 0: y1/y2\n", encoding="utf-8", ) s = Settings(consumable_classifier_labels_yaml_path=str(yml)) svc = ConsumableVisionAlgorithmService(s) m = svc.build_name_mapping(["商品A"]) assert m["商品A"] == "y1/y2" def test_build_name_mapping_uses_name_when_no_id_in_yaml( tmp_path: Path, ) -> None: yml = tmp_path / "lab.yaml" yml.write_text( "names:\n 0: 仅表内有的\nlabel_id: {}\n", encoding="utf-8", ) s = Settings(consumable_classifier_labels_yaml_path=str(yml)) svc = ConsumableVisionAlgorithmService(s) m = svc.build_name_mapping(["仅表内有的"]) assert m["仅表内有的"] == "仅表内有的"