init the project

This commit is contained in:
evyzacq
2026-05-25 15:09:42 +08:00
commit 7fc0e7852e
122 changed files with 14557 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
# YAML/JSON 差异对比工具
import yaml
def compute_diff(doc_a: dict | str, doc_b: dict | str) -> dict:
"""Compute diff between two dicts or YAML strings."""
if isinstance(doc_a, str):
try:
doc_a = yaml.safe_load(doc_a) or {}
except yaml.YAMLError:
doc_a = {}
if isinstance(doc_b, str):
try:
doc_b = yaml.safe_load(doc_b) or {}
except yaml.YAMLError:
doc_b = {}
added, removed, modified = _recursive_diff(doc_a, doc_b, "")
return {
"added": added,
"removed": removed,
"modified": modified,
}
def _recursive_diff(a: dict | list, b: dict | list, path: str) -> tuple[list, list, list]:
added, removed, modified = [], [], []
if isinstance(a, dict) and isinstance(b, dict):
all_keys = set(a.keys()) | set(b.keys())
for key in sorted(all_keys):
new_path = f"{path}.{key}" if path else key
if key not in a:
added.append({"path": new_path, "value": b[key]})
elif key not in b:
removed.append({"path": new_path, "value": a[key]})
elif a[key] != b[key]:
if isinstance(a[key], (dict, list)) and isinstance(b[key], (dict, list)):
a_sub, r_sub, m_sub = _recursive_diff(a[key], b[key], new_path)
added.extend(a_sub)
removed.extend(r_sub)
modified.extend(m_sub)
else:
modified.append({
"path": new_path,
"old_value": a[key],
"new_value": b[key],
})
elif isinstance(a, list) and isinstance(b, list):
for i in range(max(len(a), len(b))):
new_path = f"{path}[{i}]"
if i >= len(a):
added.append({"path": new_path, "value": b[i]})
elif i >= len(b):
removed.append({"path": new_path, "value": a[i]})
elif a[i] != b[i]:
if isinstance(a[i], (dict, list)) and isinstance(b[i], (dict, list)):
a_sub, r_sub, m_sub = _recursive_diff(a[i], b[i], new_path)
added.extend(a_sub)
removed.extend(r_sub)
modified.extend(m_sub)
else:
modified.append({
"path": new_path,
"old_value": a[i],
"new_value": b[i],
})
return added, removed, modified
+29
View File
@@ -0,0 +1,29 @@
# 导出格式化工具:将测试用例转换为 YAML/CSV/XMind 格式
import yaml
import csv
import io
from typing import Any
def to_yaml(cases: list[dict]) -> str:
"""将用例集序列化为 YAML 字符串"""
# TODO: Phase 4 按实际 IR schema 调整输出结构
return yaml.dump(cases, allow_unicode=True, sort_keys=False)
def to_csv(cases: list[dict]) -> str:
"""将用例集序列化为 CSV 字符串"""
if not cases:
return ""
output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=cases[0].keys())
writer.writeheader()
writer.writerows(cases)
return output.getvalue()
def to_xmind(cases: list[dict]) -> bytes:
"""将用例集导出为 XMind 文件(占位,Phase 4 实现)"""
# TODO: Phase 4 使用 xmind 库生成 .xmind 文件
return b""
+28
View File
@@ -0,0 +1,28 @@
# 结构化日志工具
import logging
import sys
from server.config import settings
def setup_logger(name: str = "testflow") -> logging.Logger:
logger = logging.getLogger(name)
if logger.handlers:
return logger
logger.setLevel(logging.DEBUG if settings.DEBUG else logging.INFO)
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(
logging.Formatter(
"[%(asctime)s] %(levelname)s [%(name)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
)
logger.addHandler(handler)
return logger
logger = setup_logger()