init: 商品图合规检测工具(豆包初筛 + DeepSeek 复检级联)

- src 标准布局:config/providers/pipeline/report + CLI/Tk GUI 双入口
- 级联省钱:豆包全量初筛,仅无违规/违规不明图进 DeepSeek 复检(含两票复核)
- 输出:时间戳目录 + 分类文件夹图片归档 + Excel 报表
- 30 个单元测试(tests/,测试图片不入库)
This commit is contained in:
yeuimu
2026-09-02 15:28:51 +08:00
commit 08d26710b4
20 changed files with 2513 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
"""config 模块测试:模板生成、缺项检测、读写回环、提示词路径。"""
from violation_detector.config import (
AppConfig, ensure_config, load_config, missing_fields, save_config,
)
def test_ensure_config_creates_template(tmp_path):
ini = tmp_path / "config.ini"
path = ensure_config(str(ini))
assert path == ini
text = ini.read_text(encoding="utf-8")
assert "[ark]" in text and "[deepseek]" in text
def test_ensure_config_keeps_existing(tmp_path):
ini = tmp_path / "config.ini"
ini.write_text("[ark]\napi_key = abc\n", encoding="utf-8")
ensure_config(str(ini))
assert "api_key = abc" in ini.read_text(encoding="utf-8")
def test_missing_fields_all_empty():
# deepseek_model 有默认值;只有用户在 ini 里清空才视为缺失
missing = missing_fields(AppConfig(deepseek_model=""))
assert len(missing) == 4
assert any("豆包 API Key" in m for m in missing)
assert any("DeepSeek API Key" in m for m in missing)
def test_missing_fields_default_model_ok():
# 默认仅缺:豆包 Key、豆包接入点、DeepSeek KeyDeepSeek 模型有默认值)
missing = missing_fields(AppConfig())
assert len(missing) == 3
assert not any("DeepSeek 模型" in m for m in missing)
def test_missing_fields_none_when_filled():
cfg = AppConfig(ark_api_key="k1", ark_model="ep-1",
deepseek_api_key="sk-1", deepseek_model="m1")
assert missing_fields(cfg) == []
def test_save_and_load_roundtrip(tmp_path):
ini = tmp_path / "config.ini"
cfg = AppConfig(ark_api_key="ark-key", ark_model="ep-xyz",
deepseek_api_key="sk-key", deepseek_model="ds-model",
ark_workers=8, max_tokens=4000, prompt_file="my.txt")
save_config(cfg, str(ini))
loaded = load_config(str(ini))
assert loaded.ark_api_key == "ark-key"
assert loaded.ark_model == "ep-xyz"
assert loaded.deepseek_api_key == "sk-key"
assert loaded.deepseek_model == "ds-model"
assert loaded.ark_workers == 8
assert loaded.max_tokens == 4000
assert loaded.prompt_file == "my.txt"
assert loaded.recheck_categories == ["无违规", "违规不明", "检测异常"]
def test_prompt_path_defaults_to_builtin():
cfg = AppConfig()
assert cfg.prompt_path.name == "prompts.txt"
def test_prompt_path_custom(tmp_path):
p = tmp_path / "p.txt"
p.write_text("x", encoding="utf-8")
cfg = AppConfig(prompt_file=str(p))
assert cfg.prompt_path == p