Files
WQ_GUI/tests/smoke_step10_path_override.py

116 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
Smoke test for: 彻底修复底层写入路径与掩膜联动
验证三件事(不依赖 GUI / 不实例化 Pipeline避免触发 osgeo/gdal 导入):
1. pipeline.step10_map 内部对 output_image_path 的 override 逻辑正确:
- 路径不在 visualization_dir 下 → 被强制重定向
- 路径在 visualization_dir 下 → 保留
- 路径为 None/空 → 用 forced 默认值
2. step11_map_panel.update_from_config 含 pipeline.get_step_output_dir('step1') 调用
3. _step_path_resolver._FALLBACK_DIR_TABLE['water_mask'] == '1_water_mask'
"""
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
PIPELINE_FILE = ROOT / "src" / "core" / "water_quality_inversion_pipeline_GUI.py"
PANEL_FILE = ROOT / "src" / "gui" / "panels" / "step11_map_panel.py"
RESOLVER_FILE = ROOT / "src" / "gui" / "panels" / "_step_path_resolver.py"
def test_step10_map_forced_override():
"""纯文本级检查 step10_map 是否含强制重定向逻辑。"""
text = PIPELINE_FILE.read_text(encoding="utf-8")
# 找 def step10_map( 起点;用下一个 def (8 空格缩进) 作锚点截取函数体
m = re.search(
r"def step10_map\([^\)]*\)[^\n]*:\n(.*?)(?=\n def |\nclass |\Z)",
text, re.DOTALL,
)
assert m, "找不到 step10_map 函数"
body = m.group(1)
# 关键标记
assert "forced_image_path" in body, "step10_map 应计算 forced_image_path"
assert "强制重定向" in body, "step10_map 应有重定向提示文本"
assert "self.visualization_dir" in body, "step10_map 应引用 self.visualization_dir"
print("✅ step10_map 含强制 override 逻辑forced_image_path + 重定向提示)")
def test_step10_map_accepts_in_visualization_dir():
"""模拟:当用户传入的路径已在 visualization_dir 内,应被保留(不被覆盖)。"""
# 走 source 的逻辑分支:在 startswith 命中 → 保留原路径
norm_viz = "/work/14_visualization"
candidates = [
("/work/14_visualization/sub/foo.png", True), # 子目录 → 保留
("/work/14_visualization/foo.png", True), # 自身 → 保留(== 情形走 else 分支)
("/work/11_12_13_predictions/foo.png", False), # 外部 → 强制重定向
("/work/foo.png", False),
]
for path, should_keep in candidates:
norm_user = path.replace("\\", "/").rstrip("/")
keep = norm_user.startswith(norm_viz + "/") or norm_user == norm_viz
assert keep == should_keep, f"路径 {path!r} 判断错误keep={keep}, expect={should_keep}"
print("✅ step10_map 路径归属判断startswith + ==)正确")
def test_step11_panel_calls_pipeline_get_step_output_dir():
"""验证 step11 panel 真的调用了 main_window.pipeline.get_step_output_dir('step1')。"""
text = PANEL_FILE.read_text(encoding="utf-8")
assert "get_step_output_dir('step1')" in text, \
"step11 panel 应调用 get_step_output_dir('step1')"
assert "getattr(_win, 'pipeline', None)" in text or "getattr(main_window, 'pipeline'" in text, \
"step11 panel 应安全访问 main_window.pipelineNone 守护)"
assert "resolve_subdir(self.work_dir, 'water_mask')" in text, \
"step11 panel 应有 resolve_subdir 兜底"
# 不应硬编码具体掩膜文件名(应通过 glob 探测)—— 排除注释行
code_lines = [
ln for ln in text.splitlines()
if ln.strip() and not ln.strip().startswith("#")
]
code_only = "\n".join(code_lines)
assert "water_mask_from_ndwi" not in code_only, \
"step11 panel 不应硬编码 water_mask_from_ndwi应通过 glob 探测)"
assert "water_mask_from_shp" not in code_only, \
"step11 panel 不应硬编码 water_mask_from_shp应通过 glob 探测)"
print("✅ step11 panel 含 pipeline.get_step_output_dir('step1') 调用 + 兜底 + 安全守护")
def test_fallback_dir_table_water_mask():
"""验证 _FALLBACK_DIR_TABLE['water_mask'] == '1_water_mask'"""
text = RESOLVER_FILE.read_text(encoding="utf-8")
m = re.search(r"'water_mask'\s*:\s*'([^']+)'", text)
assert m, "_FALLBACK_DIR_TABLE 缺 'water_mask'"
assert m.group(1) == "1_water_mask", f"应为 1_water_mask实为 {m.group(1)}"
print(f"✅ _FALLBACK_DIR_TABLE['water_mask'] = {m.group(1)!r}")
def test_panel_guard_does_not_overwrite_existing():
"""验证 step11 panel 的新段不覆盖已有 boundaryfeedback_never_overwrite_with_empty"""
text = PANEL_FILE.read_text(encoding="utf-8")
# 4.5 段必须先读 existing_boundary再判断
m = re.search(
r"# 4\.5\..*?(?=\n # 5\.)",
text, re.DOTALL
)
assert m, "找不到 4.5 段"
body = m.group(0)
assert "existing_boundary" in body, "4.5 段应读 existing_boundary"
assert "if not existing_boundary" in body, "4.5 段应仅在空时填入"
print("✅ step11 panel 4.5 段遵守 '非空值不覆盖' 原则")
if __name__ == "__main__":
print("=" * 60)
print("Smoke test: 彻底修复底层写入路径与掩膜联动")
print("=" * 60)
test_step10_map_forced_override()
test_step10_map_accepts_in_visualization_dir()
test_step11_panel_calls_pipeline_get_step_output_dir()
test_fallback_dir_table_water_mask()
test_panel_guard_does_not_overwrite_existing()
print("=" * 60)
print("全部通过 ✅")
sys.exit(0)