chore: sync skill to v2.2.1

- NW 7.40 E2E-verified compatibility matrix in SKILL.md
- DDIC fixes: include namespace, tabletype exists check, DDIC delete lock Accept
- New commands: clone, enhancement, history, unit-test
- 665 tests, 96% coverage
This commit is contained in:
2026-07-10 19:13:46 +08:00
parent 3a7fba0860
commit 38e99638c5
16 changed files with 951 additions and 16 deletions
+83
View File
@@ -0,0 +1,83 @@
"""unit-test 命令 — 执行 ABAP Unit 测试。"""
from __future__ import annotations
import argparse
import logging
from sapcli.client import ADTClient
from sapcli.types import get_type_config, parse_object_name
logger = logging.getLogger("sapcli.commands.unit_test")
def _parse_duration(value: str) -> float:
"""安全解析方法耗时(秒),无法解析返回 0.0。"""
try:
return float(value)
except (TypeError, ValueError):
return 0.0
def cmd_unit_test(args: argparse.Namespace, client: ADTClient) -> None:
"""执行 ABAP Unit 测试并汇总结果。"""
name: str = args.name
obj_type: str = args.type
parsed = parse_object_name(name, obj_type)
type_label = get_type_config(obj_type).label
print("=" * 60)
print(" ABAP Unit 测试")
print("=" * 60)
print(f" 对象类型: {type_label}")
print(f" 对象名称: {parsed.display_name}")
print(f"\n → 正在执行 ABAP Unit 测试...")
try:
result = client.run_unit_test(parsed.obj_uri)
except Exception as e:
print(f" ✗ 测试执行失败: {e}")
return
summary = result.get("summary", {})
classes = result.get("classes", [])
if not classes:
print(" ℹ 未找到测试类(对象可能不包含 ABAP Unit 测试)")
return
print()
for cls in classes:
cls_name = cls.get("name") or parsed.display_name
methods = cls.get("methods", [])
total_duration = sum(_parse_duration(m.get("duration", "")) for m in methods)
failed = [m for m in methods if m.get("alert")]
if not failed:
print(
f"{cls_name} {len(methods)} methods "
f"{total_duration:.2f}s PASSED"
)
else:
print(
f"{cls_name} {len(methods)} methods "
f"{total_duration:.2f}s FAILED"
)
for m in failed:
line_info = f" at line {m['line']}" if m.get("line") else ""
print(
f" method: {m['name']} FAILED: "
f"{m['alert']}{line_info}"
)
# 汇总
tests = summary.get("tests", "?")
failures = summary.get("failures", "0")
errors = summary.get("errors", "0")
skipped = summary.get("skipped", "0")
print(f"\n {'' * 50}")
print(
f" 合计: {tests} 个测试 | 失败 {failures} | 错误 {errors} | "
f"跳过 {skipped}"
)
print(f" {'' * 50}")