diff --git a/tests/test_install.sh b/tests/test_install.sh new file mode 100755 index 0000000..a433db3 --- /dev/null +++ b/tests/test_install.sh @@ -0,0 +1,170 @@ +#!/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 ]]