#!/usr/bin/env bats # sync_standards.sh 测试套件 # 测试辅助函数 setup() { # 创建临时测试目录 export TEST_DIR="$(mktemp -d)" export PLAYBOOK_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)" # 初始化测试项目 cd "$TEST_DIR" git init git config user.name "Test User" git config user.email "test@example.com" # 模拟 playbook 快照目录 mkdir -p docs/standards/playbook cp -r "$PLAYBOOK_ROOT"/{.agents,.gitattributes,docs,scripts} docs/standards/playbook/ 2>/dev/null || true export SCRIPT_PATH="$TEST_DIR/docs/standards/playbook/scripts/sync_standards.sh" } teardown() { # 清理测试目录 if [ -n "$TEST_DIR" ] && [ -d "$TEST_DIR" ]; then chmod -R u+rwX "$TEST_DIR" 2>/dev/null || true rm -rf "$TEST_DIR" fi } # ============================================== # 基础功能测试 # ============================================== @test "sync_standards.sh 脚本存在且可执行" { [ -f "$SCRIPT_PATH" ] } @test "sync_standards.sh 无参数时同步 tsl 规则集" { cd "$TEST_DIR" sh "$SCRIPT_PATH" # 验证输出目录 [ -d ".agents/tsl" ] [ -f ".agents/tsl/index.md" ] } @test "sync_standards.sh 无参数时自动识别已有语言" { cd "$TEST_DIR" mkdir -p .agents/cpp echo "# placeholder" > .agents/cpp/index.md sh "$SCRIPT_PATH" [ -d ".agents/cpp" ] [ -f ".agents/cpp/index.md" ] [ ! -d ".agents/tsl" ] } @test "sync_standards.sh tsl - 同步 TSL 规则集" { cd "$TEST_DIR" sh "$SCRIPT_PATH" tsl # 验证必须文件 [ -d ".agents/tsl" ] [ -f ".agents/tsl/index.md" ] [ -f ".agents/tsl/auth.md" ] [ -f ".agents/tsl/code_quality.md" ] [ -f ".agents/tsl/performance.md" ] [ -f ".agents/tsl/testing.md" ] } @test "sync_standards.sh cpp - 同步 C++ 规则集" { cd "$TEST_DIR" sh "$SCRIPT_PATH" cpp # 验证必须文件 [ -d ".agents/cpp" ] [ -f ".agents/cpp/index.md" ] [ -f ".agents/cpp/auth.md" ] [ -f ".agents/cpp/code_quality.md" ] } @test "sync_standards.sh tsl cpp - 同步多个规则集" { cd "$TEST_DIR" sh "$SCRIPT_PATH" tsl cpp # 验证两个规则集都存在 [ -d ".agents/tsl" ] [ -d ".agents/cpp" ] [ -f ".agents/index.md" ] } # ============================================== # .gitattributes 同步测试 # ============================================== @test ".gitattributes - 默认模式追加缺失规则" { cd "$TEST_DIR" [ ! -f ".gitattributes" ] sh "$SCRIPT_PATH" tsl [ -f ".gitattributes" ] grep -q "Added from playbook .gitattributes" .gitattributes grep -q "\\*.tsl" .gitattributes } @test ".gitattributes - 保留现有内容" { cd "$TEST_DIR" echo "# My custom rules" > .gitattributes echo "*.custom binary" >> .gitattributes sh "$SCRIPT_PATH" tsl grep -q "# My custom rules" .gitattributes grep -q "*.custom binary" .gitattributes } @test ".gitattributes - 更新已存在的 managed block" { cd "$TEST_DIR" cat > .gitattributes << 'EOF' # BEGIN playbook .gitattributes # Old content # END playbook .gitattributes EOF export SYNC_GITATTR_MODE=block sh "$SCRIPT_PATH" tsl # 验证 block 已更新(不再包含 "Old content") ! grep -q "Old content" .gitattributes } # ============================================== # AGENTS.md 自动生成测试 # ============================================== @test "AGENTS.md - 不存在时自动创建" { cd "$TEST_DIR" [ ! -f "AGENTS.md" ] sh "$SCRIPT_PATH" tsl [ -f "AGENTS.md" ] grep -q ".agents/" AGENTS.md } @test "AGENTS.md - 已存在时不覆盖" { cd "$TEST_DIR" echo "# My custom AGENTS.md" > AGENTS.md sh "$SCRIPT_PATH" tsl grep -q "# My custom AGENTS.md" AGENTS.md } # ============================================== # 备份功能测试 # ============================================== @test "备份 - .gitattributes 更新前创建备份" { cd "$TEST_DIR" echo "# Original content" > .gitattributes sh "$SCRIPT_PATH" tsl # 验证备份文件存在 [ -f ".gitattributes.bak."* ] || [ -f ".gitattributes.bak" ] } @test "备份 - .agents/ 更新前创建备份" { cd "$TEST_DIR" mkdir -p .agents/tsl echo "# Old index" > .agents/tsl/index.md sh "$SCRIPT_PATH" tsl # 验证备份目录存在 [ -d ".agents/tsl.bak."* ] || [ -d ".agents/tsl.bak" ] } # ============================================== # 多语言项目测试 # ============================================== @test "多语言 - TSL + C++ + Python 规则集共存" { cd "$TEST_DIR" # 复制 Python 规则集(如果存在) if [ -d "$PLAYBOOK_ROOT/.agents/python" ]; then cp -r "$PLAYBOOK_ROOT/.agents/python" docs/standards/playbook/.agents/ fi sh "$SCRIPT_PATH" tsl cpp # 验证规则集不互相覆盖 [ -d ".agents/tsl" ] [ -d ".agents/cpp" ] # 验证索引文件正确引用 [ -f ".agents/index.md" ] } # ============================================== # 错误处理测试 # ============================================== @test "错误处理 - 未找到 playbook 快照时报错" { cd "$TEST_DIR" rm -rf docs/standards/playbook/.agents run sh "$SCRIPT_PATH" tsl [ "$status" -ne 0 ] } @test "错误处理 - 无效语言参数时报错" { cd "$TEST_DIR" run sh "$SCRIPT_PATH" invalid_lang [ "$status" -ne 0 ] } # ============================================== # 环境变量配置测试 # ============================================== @test "环境变量 - SYNC_GITATTR_MODE=skip 跳过 .gitattributes" { cd "$TEST_DIR" export SYNC_GITATTR_MODE=skip sh "$SCRIPT_PATH" tsl [ ! -f ".gitattributes" ] } @test "环境变量 - SYNC_GITATTR_MODE=overwrite 覆盖 .gitattributes" { cd "$TEST_DIR" echo "# Custom content" > .gitattributes export SYNC_GITATTR_MODE=overwrite sh "$SCRIPT_PATH" tsl # 验证自定义内容被覆盖 ! grep -q "# Custom content" .gitattributes } @test "环境变量 - SYNC_GITATTR_MODE=append 追加缺失规则" { cd "$TEST_DIR" echo "# Custom rules only" > .gitattributes export SYNC_GITATTR_MODE=append sh "$SCRIPT_PATH" tsl grep -q "Added from playbook .gitattributes" .gitattributes grep -q "\\*.tsl" .gitattributes } @test "环境变量 - SYNC_GITATTR_MODE=append 无缺失规则不追加" { cd "$TEST_DIR" cp "$PLAYBOOK_ROOT/.gitattributes" .gitattributes export SYNC_GITATTR_MODE=append sh "$SCRIPT_PATH" tsl ! grep -q "Added from playbook .gitattributes" .gitattributes } # ============================================== # 幂等性测试 # ============================================== @test "幂等性 - 多次执行结果一致" { cd "$TEST_DIR" # 第一次同步 sh "$SCRIPT_PATH" tsl CHECKSUM1=$(find .agents/tsl -type f -exec md5sum {} \; | sort | md5sum) # 第二次同步 sh "$SCRIPT_PATH" tsl CHECKSUM2=$(find .agents/tsl -type f -exec md5sum {} \; | sort | md5sum) [ "$CHECKSUM1" = "$CHECKSUM2" ] }