✅ test(templates): add template coverage
This commit is contained in:
parent
fc230b7ff9
commit
b2eb475a6d
|
|
@ -137,6 +137,7 @@ jobs:
|
|||
}
|
||||
|
||||
run_bats "sync_standards" "test_sync_standards.bats"
|
||||
run_bats "sync_templates" "test_sync_templates.bats"
|
||||
run_bats "vendor_playbook" "test_vendor_playbook.bats"
|
||||
run_bats "install_codex_skills" "test_install_codex_skills.bats"
|
||||
|
||||
|
|
@ -171,6 +172,7 @@ jobs:
|
|||
run_validator "python" "validate_python_templates.sh"
|
||||
run_validator "cpp" "validate_cpp_templates.sh"
|
||||
run_validator "ci" "validate_ci_templates.sh"
|
||||
run_validator "project_templates" "validate_project_templates.sh"
|
||||
|
||||
echo "========================================"
|
||||
echo "🔗 集成测试"
|
||||
|
|
|
|||
|
|
@ -9,12 +9,14 @@ tests/
|
|||
├── README.md # 本文件:测试文档
|
||||
├── scripts/ # Shell 脚本测试(bats)
|
||||
│ ├── test_sync_standards.bats # sync_standards.sh 测试
|
||||
│ ├── test_sync_templates.bats # sync_templates.sh 测试
|
||||
│ ├── test_vendor_playbook.bats # vendor_playbook.sh 测试
|
||||
│ └── test_install_codex_skills.bats # install_codex_skills.sh 测试
|
||||
├── templates/ # 模板验证测试
|
||||
│ ├── validate_python_templates.sh # Python 模板验证
|
||||
│ ├── validate_cpp_templates.sh # C++ 模板验证
|
||||
│ └── validate_ci_templates.sh # CI 模板验证
|
||||
│ ├── validate_ci_templates.sh # CI 模板验证
|
||||
│ └── validate_project_templates.sh # 项目模板验证
|
||||
└── integration/ # 集成测试
|
||||
└── check_doc_links.sh # 文档链接有效性检查
|
||||
```
|
||||
|
|
@ -31,6 +33,7 @@ cd /path/to/playbook
|
|||
sudo apt-get install bats # Ubuntu/Debian
|
||||
cd tests/scripts
|
||||
bats test_sync_standards.bats
|
||||
bats test_sync_templates.bats
|
||||
bats test_vendor_playbook.bats
|
||||
bats test_install_codex_skills.bats
|
||||
|
||||
|
|
@ -39,6 +42,7 @@ cd tests/templates
|
|||
sh validate_python_templates.sh
|
||||
sh validate_cpp_templates.sh
|
||||
sh validate_ci_templates.sh
|
||||
sh validate_project_templates.sh
|
||||
|
||||
# 3. 运行集成测试
|
||||
cd tests/integration
|
||||
|
|
@ -88,6 +92,21 @@ sh check_doc_links.sh
|
|||
- **幂等性**:
|
||||
- 多次执行结果一致
|
||||
|
||||
#### test_sync_templates.bats
|
||||
|
||||
测试 `scripts/sync_templates.sh` 脚本的功能:
|
||||
|
||||
- **基础同步**:
|
||||
- 同步 memory-bank/ 与 docs/prompts/
|
||||
- 创建 AGENTS.md / AGENT_RULES.md / TODO.md / CONFIRM.md
|
||||
- **占位符替换**:
|
||||
- `{{PROJECT_NAME}}` 与 `{{DATE}}`
|
||||
- **目录覆盖策略**:
|
||||
- 无 `--force` 时不覆盖已有目录
|
||||
- `--force` 时覆盖并备份
|
||||
- **AGENTS.md 更新**:
|
||||
- `--full` 更新 framework 区块
|
||||
|
||||
#### test_vendor_playbook.bats
|
||||
|
||||
测试 `scripts/vendor_playbook.sh` 脚本的功能:
|
||||
|
|
@ -227,6 +246,22 @@ sh check_doc_links.sh
|
|||
- 包含 README 说明文档
|
||||
- 包含使用说明
|
||||
|
||||
#### validate_project_templates.sh
|
||||
|
||||
验证项目通用模板:
|
||||
|
||||
- **核心模板**:
|
||||
- `templates/AGENTS.template.md`
|
||||
- `templates/AGENT_RULES.template.md`
|
||||
- `templates/README.md`
|
||||
- **memory-bank 模板**:
|
||||
- 项目定位/技术栈/架构/进度/决策/实施计划
|
||||
- **prompts 模板**:
|
||||
- `prompts/README.md`
|
||||
- `prompts/system/agent-behavior.template.md`
|
||||
- `prompts/coding/clarify.template.md`
|
||||
- `prompts/coding/verify.template.md`
|
||||
|
||||
### 3. 集成测试 (integration/)
|
||||
|
||||
端到端测试,验证整体功能。
|
||||
|
|
@ -236,7 +271,7 @@ sh check_doc_links.sh
|
|||
检查所有 Markdown 文档中的链接有效性:
|
||||
|
||||
- **扫描范围**:
|
||||
- 所有 `*.md` 文件
|
||||
- 所有 `*.md` 文件(排除 `*.template.md`)
|
||||
- 排除 node_modules, .git, build, dist 等目录
|
||||
- **链接类型**:
|
||||
- Markdown 链接:`[text](link)`
|
||||
|
|
@ -296,6 +331,7 @@ pip3 install yamllint
|
|||
# Shell 脚本测试
|
||||
cd tests/scripts
|
||||
bats test_sync_standards.bats --tap # TAP 格式输出
|
||||
bats test_sync_templates.bats
|
||||
bats test_vendor_playbook.bats --formatter junit # JUnit 格式
|
||||
|
||||
# 模板验证测试
|
||||
|
|
@ -303,6 +339,7 @@ cd tests/templates
|
|||
sh validate_python_templates.sh
|
||||
sh validate_cpp_templates.sh
|
||||
sh validate_ci_templates.sh
|
||||
sh validate_project_templates.sh
|
||||
|
||||
# 集成测试
|
||||
cd tests/integration
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ echo "🔍 扫描 Markdown 文件..."
|
|||
cd "$PLAYBOOK_ROOT"
|
||||
|
||||
MD_FILES=$(find . -name "*.md" \
|
||||
-not -name "*.template.md" \
|
||||
-not -path "*/node_modules/*" \
|
||||
-not -path "*/.git/*" \
|
||||
-not -path "*/build/*" \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env bats
|
||||
# sync_templates.sh 测试套件
|
||||
|
||||
setup() {
|
||||
export PLAYBOOK_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)"
|
||||
export SCRIPT_PATH="$PLAYBOOK_ROOT/scripts/sync_templates.sh"
|
||||
export TARGET_DIR="$(mktemp -d)"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
if [ -n "$TARGET_DIR" ] && [ -d "$TARGET_DIR" ]; then
|
||||
chmod -R u+w "$TARGET_DIR" 2>/dev/null || true
|
||||
rm -rf "$TARGET_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================
|
||||
# 基础功能测试
|
||||
# ==============================================
|
||||
|
||||
@test "sync_templates.sh 脚本存在且可执行" {
|
||||
[ -f "$SCRIPT_PATH" ]
|
||||
}
|
||||
|
||||
@test "sync_templates.sh - 基础同步与占位符替换" {
|
||||
sh "$SCRIPT_PATH" --project-name "DemoProject" --date "2026-02-03" "$TARGET_DIR"
|
||||
|
||||
[ -d "$TARGET_DIR/memory-bank" ]
|
||||
[ -f "$TARGET_DIR/memory-bank/project-brief.md" ]
|
||||
[ -f "$TARGET_DIR/docs/prompts/coding/clarify.md" ]
|
||||
[ -f "$TARGET_DIR/AGENTS.md" ]
|
||||
[ -f "$TARGET_DIR/AGENT_RULES.md" ]
|
||||
[ -f "$TARGET_DIR/TODO.md" ]
|
||||
[ -f "$TARGET_DIR/CONFIRM.md" ]
|
||||
|
||||
grep -q "DemoProject" "$TARGET_DIR/memory-bank/project-brief.md"
|
||||
! grep -q "{{DATE}}" "$TARGET_DIR/TODO.md"
|
||||
|
||||
[ -z "$(find "$TARGET_DIR" -name '*.template.md' -print -quit)" ]
|
||||
}
|
||||
|
||||
@test "sync_templates.sh - 已存在目录不覆盖 (无 --force)" {
|
||||
mkdir -p "$TARGET_DIR/memory-bank"
|
||||
mkdir -p "$TARGET_DIR/docs/prompts"
|
||||
echo "keep" > "$TARGET_DIR/memory-bank/keep.md"
|
||||
echo "keep" > "$TARGET_DIR/docs/prompts/keep.md"
|
||||
|
||||
sh "$SCRIPT_PATH" "$TARGET_DIR"
|
||||
|
||||
[ -f "$TARGET_DIR/memory-bank/keep.md" ]
|
||||
[ ! -f "$TARGET_DIR/memory-bank/project-brief.md" ]
|
||||
[ -f "$TARGET_DIR/docs/prompts/keep.md" ]
|
||||
[ ! -f "$TARGET_DIR/docs/prompts/README.md" ]
|
||||
}
|
||||
|
||||
@test "sync_templates.sh - --force 覆盖并备份" {
|
||||
mkdir -p "$TARGET_DIR/memory-bank"
|
||||
echo "marker" > "$TARGET_DIR/memory-bank/marker.txt"
|
||||
|
||||
sh "$SCRIPT_PATH" --force "$TARGET_DIR"
|
||||
|
||||
[ -f "$TARGET_DIR/memory-bank/project-brief.md" ]
|
||||
[ ! -f "$TARGET_DIR/memory-bank/marker.txt" ]
|
||||
|
||||
backup_dir="$(ls -d "$TARGET_DIR"/memory-bank.bak.* 2>/dev/null | head -n 1)"
|
||||
[ -n "$backup_dir" ]
|
||||
[ -f "$backup_dir/marker.txt" ]
|
||||
}
|
||||
|
||||
@test "sync_templates.sh - --full 更新 framework 区块" {
|
||||
cat > "$TARGET_DIR/AGENTS.md" << 'EOF'
|
||||
# Agent Instructions
|
||||
|
||||
<!-- playbook:framework:start -->
|
||||
OLD_FRAMEWORK
|
||||
<!-- playbook:framework:end -->
|
||||
|
||||
Footer
|
||||
EOF
|
||||
|
||||
sh "$SCRIPT_PATH" --full "$TARGET_DIR"
|
||||
|
||||
! grep -q "OLD_FRAMEWORK" "$TARGET_DIR/AGENTS.md"
|
||||
grep -q "<!-- playbook:framework:start -->" "$TARGET_DIR/AGENTS.md"
|
||||
grep -q "Footer" "$TARGET_DIR/AGENTS.md"
|
||||
}
|
||||
|
|
@ -176,6 +176,20 @@ teardown() {
|
|||
[ -d "docs/standards/playbook/templates/ci" ]
|
||||
}
|
||||
|
||||
@test "vendor_playbook.sh - --apply-templates 应用模板到项目根目录" {
|
||||
cd "$TARGET_DIR"
|
||||
|
||||
sh "$SCRIPT_PATH" "$TARGET_DIR" cpp --apply-templates
|
||||
|
||||
if [ -f "$PLAYBOOK_ROOT/templates/cpp/.clang-format" ]; then
|
||||
[ -f ".clang-format" ]
|
||||
fi
|
||||
|
||||
if [ -f "$PLAYBOOK_ROOT/templates/ci/gitea/.gitea/workflows/standards-check.yml" ]; then
|
||||
[ -f ".gitea/workflows/standards-check.yml" ]
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================
|
||||
# 目标目录处理测试
|
||||
# ==============================================
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
#!/usr/bin/env sh
|
||||
# 项目模板验证脚本
|
||||
|
||||
set -eu
|
||||
|
||||
echo "========================================"
|
||||
echo "🧩 项目模板验证"
|
||||
echo "========================================"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PLAYBOOK_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
TEMPLATES_DIR="$PLAYBOOK_ROOT/templates"
|
||||
|
||||
VALIDATION_PASSED=0
|
||||
VALIDATION_FAILED=0
|
||||
ERRORS_FILE="/tmp/project_template_validation_errors.txt"
|
||||
REPORT_FILE="$SCRIPT_DIR/project_templates_report.txt"
|
||||
|
||||
> "$ERRORS_FILE"
|
||||
> "$REPORT_FILE"
|
||||
|
||||
echo "📁 模板目录: $TEMPLATES_DIR"
|
||||
echo ""
|
||||
|
||||
# ============================================
|
||||
# 辅助函数
|
||||
# ============================================
|
||||
|
||||
validate_file_exists() {
|
||||
local file="$1"
|
||||
local description="$2"
|
||||
|
||||
if [ -f "$file" ]; then
|
||||
echo " ✅ $description: $(basename "$file")"
|
||||
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
|
||||
return 0
|
||||
else
|
||||
echo " ❌ $description: $(basename "$file") - 文件不存在"
|
||||
echo "文件不存在: $file" >> "$ERRORS_FILE"
|
||||
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_contains() {
|
||||
local file="$1"
|
||||
local needle="$2"
|
||||
local description="$3"
|
||||
|
||||
if grep -Fq "$needle" "$file"; then
|
||||
echo " ✓ $description"
|
||||
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
|
||||
else
|
||||
echo " ✗ $description"
|
||||
echo "缺少内容: $needle in $file" >> "$ERRORS_FILE"
|
||||
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
echo "🔍 验证核心模板文件"
|
||||
AGENTS_TEMPLATE="$TEMPLATES_DIR/AGENTS.template.md"
|
||||
AGENT_RULES_TEMPLATE="$TEMPLATES_DIR/AGENT_RULES.template.md"
|
||||
README_TEMPLATE="$TEMPLATES_DIR/README.md"
|
||||
|
||||
if validate_file_exists "$AGENTS_TEMPLATE" "AGENTS.template.md"; then
|
||||
validate_contains "$AGENTS_TEMPLATE" "<!-- playbook:templates:start -->" "包含 templates 标记"
|
||||
validate_contains "$AGENTS_TEMPLATE" "<!-- playbook:framework:start -->" "包含 framework 标记"
|
||||
validate_contains "$AGENTS_TEMPLATE" "{{DATE}}" "包含 {{DATE}} 占位符"
|
||||
fi
|
||||
|
||||
if validate_file_exists "$AGENT_RULES_TEMPLATE" "AGENT_RULES.template.md"; then
|
||||
validate_contains "$AGENT_RULES_TEMPLATE" "AGENT_RULES" "包含 AGENT_RULES 标题"
|
||||
validate_contains "$AGENT_RULES_TEMPLATE" "{{DATE}}" "包含 {{DATE}} 占位符"
|
||||
fi
|
||||
|
||||
validate_file_exists "$README_TEMPLATE" "templates/README.md"
|
||||
|
||||
echo ""
|
||||
echo "🔍 验证 memory-bank 模板"
|
||||
|
||||
MEMORY_BANK_DIR="$TEMPLATES_DIR/memory-bank"
|
||||
for name in project-brief tech-stack architecture progress decisions implementation-plan; do
|
||||
validate_file_exists "$MEMORY_BANK_DIR/$name.template.md" "memory-bank/$name.template.md"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "🔍 验证 prompts 模板"
|
||||
|
||||
PROMPTS_DIR="$TEMPLATES_DIR/prompts"
|
||||
validate_file_exists "$PROMPTS_DIR/README.md" "prompts/README.md"
|
||||
validate_file_exists "$PROMPTS_DIR/system/agent-behavior.template.md" "prompts/system/agent-behavior.template.md"
|
||||
validate_file_exists "$PROMPTS_DIR/coding/clarify.template.md" "prompts/coding/clarify.template.md"
|
||||
validate_file_exists "$PROMPTS_DIR/coding/verify.template.md" "prompts/coding/verify.template.md"
|
||||
|
||||
echo ""
|
||||
|
||||
# ============================================
|
||||
# 生成验证报告
|
||||
# ============================================
|
||||
|
||||
echo "========================================"
|
||||
echo "📊 验证结果统计"
|
||||
echo "========================================"
|
||||
echo "✅ 通过: $VALIDATION_PASSED"
|
||||
echo "❌ 失败: $VALIDATION_FAILED"
|
||||
|
||||
if [ $((VALIDATION_PASSED + VALIDATION_FAILED)) -gt 0 ]; then
|
||||
echo "📈 通过率: $(awk "BEGIN {printf \"%.1f\", ($VALIDATION_PASSED * 100.0) / ($VALIDATION_PASSED + $VALIDATION_FAILED)}")%"
|
||||
else
|
||||
echo "📈 通过率: N/A (无测试项)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
{
|
||||
echo "项目模板验证报告"
|
||||
echo "===================="
|
||||
echo ""
|
||||
echo "验证时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "模板目录: $TEMPLATES_DIR"
|
||||
echo ""
|
||||
echo "统计结果:"
|
||||
echo " 通过: $VALIDATION_PASSED"
|
||||
echo " 失败: $VALIDATION_FAILED"
|
||||
if [ $((VALIDATION_PASSED + VALIDATION_FAILED)) -gt 0 ]; then
|
||||
echo " 通过率: $(awk "BEGIN {printf \"%.1f\", ($VALIDATION_PASSED * 100.0) / ($VALIDATION_PASSED + $VALIDATION_FAILED)}")%"
|
||||
fi
|
||||
echo ""
|
||||
if [ -s "$ERRORS_FILE" ]; then
|
||||
echo "错误详情:"
|
||||
cat "$ERRORS_FILE"
|
||||
fi
|
||||
} > "$REPORT_FILE"
|
||||
|
||||
echo "📄 详细报告: $REPORT_FILE"
|
||||
echo "========================================"
|
||||
|
||||
rm -f "$ERRORS_FILE"
|
||||
|
||||
if [ "$VALIDATION_FAILED" -eq 0 ]; then
|
||||
echo "✅ 所有项目模板验证通过"
|
||||
exit 0
|
||||
else
|
||||
echo "❌ 项目模板验证失败 ($VALIDATION_FAILED 个错误)"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Reference in New Issue