#!/usr/bin/env bash # Tests unitaires pour install.sh # Usage : cd tests && bash test_install.sh set -euo pipefail PASS=0 FAIL=0 assert_eq() { local desc="$1" expected="$2" actual="$3" if [[ "$expected" == "$actual" ]]; then echo " ✓ $desc" (( PASS++ )) || true else echo " ✗ $desc" echo " attendu : '$expected'" echo " obtenu : '$actual'" (( FAIL++ )) || true fi } assert_true() { local desc="$1" shift if eval "$@" 2>/dev/null; then echo " ✓ $desc" (( PASS++ )) || true else echo " ✗ $desc" (( FAIL++ )) || true fi } assert_false() { local desc="$1" shift if ! eval "$@" 2>/dev/null; then echo " ✓ $desc" (( PASS++ )) || true else echo " ✗ $desc" (( FAIL++ )) || true fi } # Charge install.sh sans exécuter main() load_install() { local tmp; tmp=$(mktemp) # Supprime l'appel final à main et desactive set -e pour le sourcing grep -v '^main "\$@"' ../install.sh > "$tmp" set +e # shellcheck disable=SC1090 source "$tmp" set -e rm -f "$tmp" } echo "" echo "══════════════════════════════════" echo " Tests install.sh" echo "══════════════════════════════════" echo "" load_install # Désactive le trap cleanup() hérité de install.sh (évite l'erreur nounset sur STATE_FILE) trap - EXIT # ── 1. Comparaison de versions ──────────────────────────────────── echo "1. version_is_newer()" assert_true "1.2.0 > 1.0.0" "version_is_newer '1.0.0' '1.2.0'" assert_false "1.0.0 n'est pas > 1.2.0" "version_is_newer '1.2.0' '1.0.0'" assert_false "1.0.0 == 1.0.0 → false" "version_is_newer '1.0.0' '1.0.0'" assert_true "2.0.0 > 1.9.9" "version_is_newer '1.9.9' '2.0.0'" assert_true "1.0.1 > 1.0.0" "version_is_newer '1.0.0' '1.0.1'" # ── 2. Parsing frontmatter ──────────────────────────────────────── echo "" echo "2. get_frontmatter_field()" TMP_SKILL=$(mktemp --suffix=.md) cat > "$TMP_SKILL" << 'SKILL_EOF' --- name: test-skill version: 2.1.0 description: Skill de test pour vérification agents: [claude-code] category: dev tags: [bash, test] --- # Contenu du skill SKILL_EOF assert_eq "version" "2.1.0" "$(get_frontmatter_field "$TMP_SKILL" "version")" assert_eq "name" "test-skill" "$(get_frontmatter_field "$TMP_SKILL" "name")" assert_eq "category" "dev" "$(get_frontmatter_field "$TMP_SKILL" "category")" assert_eq "champ absent → vide" "" "$(get_frontmatter_field "$TMP_SKILL" "nonexistent")" rm -f "$TMP_SKILL" # ── 3. Chemins de destination ───────────────────────────────────── echo "" echo "3. get_dest_path()" assert_eq "claude global" \ "$HOME/.claude/skills/dev/debugging/SKILL.md" \ "$(get_dest_path "dev" "debugging" "claude-code" "global")" assert_eq "claude local" \ ".claude/skills/dev/debugging/SKILL.md" \ "$(get_dest_path "dev" "debugging" "claude-code" "local")" assert_eq "gemini local" \ ".gemini/skills/dev/debugging/SKILL.md" \ "$(get_dest_path "dev" "debugging" "gemini-cli" "local")" assert_eq "codex global" \ "$HOME/.codex/skills/jardinage/arrosage/SKILL.md" \ "$(get_dest_path "jardinage" "arrosage" "codex" "global")" assert_eq "hermes local" \ ".hermes/skills/electronique/arduino/SKILL.md" \ "$(get_dest_path "electronique" "arduino" "hermes" "local")" # ── 4. Gestion d'état ───────────────────────────────────────────── echo "" echo "4. state_get() / state_cycle() / make_key()" STATE_FILE=$(mktemp) export STATE_FILE # Teste make_key — prend une entrée "cat|skill|agent|etat|repo_ver|local_ver" assert_eq "make_key basique" \ "dev_debugging_claude_code" \ "$(make_key "dev|debugging|claude-code|new|1.0.0|")" assert_eq "make_key avec tirets" \ "dev_git_workflow_claude_code" \ "$(make_key "dev|git-workflow|claude-code|new|1.0.0|")" # Initialise un état echo "dev_debugging_claude_code=local" > "$STATE_FILE" assert_eq "state_get local" "local" "$(state_get "dev_debugging_claude_code")" state_cycle "dev_debugging_claude_code" "ok" assert_eq "cycle local→global" "global" "$(state_get "dev_debugging_claude_code")" state_cycle "dev_debugging_claude_code" "ok" assert_eq "cycle global→skip" "skip" "$(state_get "dev_debugging_claude_code")" state_cycle "dev_debugging_claude_code" "ok" assert_eq "cycle skip→local (état ok)" "local" "$(state_get "dev_debugging_claude_code")" # Teste le cycle avec état upd echo "dev_debugging_claude_code=skip" > "$STATE_FILE" state_cycle "dev_debugging_claude_code" "upd" assert_eq "cycle skip→update (état upd)" "update" "$(state_get "dev_debugging_claude_code")" state_cycle "dev_debugging_claude_code" "upd" assert_eq "cycle update→local" "local" "$(state_get "dev_debugging_claude_code")" rm -f "$STATE_FILE" unset STATE_FILE || true # ── Bilan ───────────────────────────────────────────────────────── echo "" echo "══════════════════════════════════" printf " Résultats : %d passés, %d échoués\n" "$PASS" "$FAIL" echo "══════════════════════════════════" echo "" [[ "$FAIL" -eq 0 ]]