tests/smoke.sh
tests/smoke.shBrowse 14 files
2,389 tokens
7,765 bytes
Token encoding: o200k_base
Snapshot 24fd22b
← Back to SKILL.md
1#!/usr/bin/env bash2# Smoke test for the ast-grep skill on POSIX (macOS / Linux / WSL / Git Bash).3#4# Tests:5# 1. helper --version6# 2. helper langs (lists 25 languages)7# 3. helper validate '\w+' --lang ts (must exit 2 with hint)8# 4. helper validate 'console.log($MSG)' (must exit 0 plausible)9# 5. helper validate 'def $F($$$):' --lang py (must exit 2 - trailing colon)10# 6. helper validate 'function $N' --lang ts (must exit 2 - incomplete)11# 7. helper validate 'foo|bar' --lang ts (must exit 2 - alternation)12# 8. helper doctor (informational; tolerates no-binary)13# 9. helper search w/o binary => exit 3 with install hint14# 10. install.sh --help (parses)15# 11. SKILL.md frontmatter shape (canonical)16#17# Runs against the helper using ONLY stdlib python3 - no ast-grep needed.18 19set -euo pipefail20 21SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"22SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"23HELPER="python3 $SKILL_DIR/scripts/ast_grep_helper.py"24 25OUTPUT_DIR="$(mktemp -d -t ast-grep-skill-smoke-XXXXXX)"26trap 'rm -rf "$OUTPUT_DIR"' EXIT27 28fail() { echo "FAIL: $*" >&2; exit 1; }29pass() { echo "PASS: $*"; }30 31omo_runtime_slug() {32 case "$(uname -s)" in33 Darwin) local os_slug="darwin" ;;34 MINGW*|MSYS*|CYGWIN*) local os_slug="win32" ;;35 *) local os_slug="linux" ;;36 esac37 38 case "$(uname -m | tr '[:upper:]' '[:lower:]')" in39 arm64|aarch64) local arch_slug="arm64" ;;40 *) local arch_slug="x64" ;;41 esac42 43 printf '%s-%s' "$os_slug" "$arch_slug"44}45 46fake_sg() {47 local target="$1"48 mkdir -p "$(dirname "$target")"49 cat > "$target" <<'SH'50#!/usr/bin/env bash51if [ "${1:-}" = "--version" ]; then52 printf 'ast-grep 0.45.0 fake\n'53else54 printf 'fake ast-grep\n'55fi56SH57 chmod +x "$target"58}59 60# 1. --version61$HELPER --version | grep -q "ast-grep-helper" || fail "--version output missing"62pass "--version"63 64# 2. langs (must list 25)65LANG_LINES=$($HELPER langs | grep -E '^ [a-z]' | wc -l | tr -d ' ')66[ "$LANG_LINES" -ge 25 ] || fail "langs listed only $LANG_LINES (expected >=25)"67pass "langs lists at least 25 languages"68 69# 3. regex misuse: \w+70set +e71$HELPER validate '\w+' --lang ts > "$OUTPUT_DIR/v1.out" 2>&172RC=$?73set -e74[ $RC -eq 2 ] || fail "validate '\\w+' should exit 2, got $RC (output: $(cat $OUTPUT_DIR/v1.out))"75grep -qi 'regex' "$OUTPUT_DIR/v1.out" || fail "validate '\\w+' should mention regex (output: $(cat $OUTPUT_DIR/v1.out))"76pass "validate detects \\w regex misuse"77 78# 4. valid pattern79set +e80$HELPER validate 'console.log($MSG)' --lang ts > "$OUTPUT_DIR/v2.out" 2>&181RC=$?82set -e83[ $RC -eq 0 ] || fail "validate 'console.log(\$MSG)' should exit 0, got $RC (output: $(cat $OUTPUT_DIR/v2.out))"84pass "validate accepts plausible pattern"85 86# 5. Python trailing colon87set +e88$HELPER validate 'def $F($$$):' --lang py > "$OUTPUT_DIR/v3.out" 2>&189RC=$?90set -e91[ $RC -eq 2 ] || fail "validate 'def \$F(\$\$\$):' should exit 2, got $RC"92grep -qi 'colon\|trailing' "$OUTPUT_DIR/v3.out" || fail "validate should mention trailing colon"93pass "validate detects Python trailing colon"94 95# 6. Incomplete TS function96set +e97$HELPER validate 'function $N' --lang ts > "$OUTPUT_DIR/v4.out" 2>&198RC=$?99set -e100[ $RC -eq 2 ] || fail "validate 'function \$N' should exit 2, got $RC"101grep -qi 'incomplete\|params\|body' "$OUTPUT_DIR/v4.out" || fail "validate should hint about params/body"102pass "validate detects incomplete TS function"103 104# 7. Alternation pipe105set +e106$HELPER validate 'foo|bar' --lang ts > "$OUTPUT_DIR/v5.out" 2>&1107RC=$?108set -e109[ $RC -eq 2 ] || fail "validate 'foo|bar' should exit 2, got $RC"110grep -qi 'alternation\|regex' "$OUTPUT_DIR/v5.out" || fail "validate should mention alternation"111pass "validate detects literal | alternation"112 113# 8. doctor (informational)114$HELPER doctor > "$OUTPUT_DIR/doc.out" 2>&1 || true115grep -q "ast-grep-helper" "$OUTPUT_DIR/doc.out" || fail "doctor missing helper version line"116pass "doctor produces output"117 118# Given OMO_AST_GREP_SG_PATH points at a fake executable.119# When doctor resolves ast-grep, then it reports that exact path.120FAKE_ENV_SG="$OUTPUT_DIR/fake-env/sg"121fake_sg "$FAKE_ENV_SG"122OMO_AST_GREP_SG_PATH="$FAKE_ENV_SG" $HELPER doctor > "$OUTPUT_DIR/omo-env.out" 2>&1123grep -Fq "ast-grep binary: $FAKE_ENV_SG" "$OUTPUT_DIR/omo-env.out" || fail "OMO_AST_GREP_SG_PATH was not preferred: $(cat "$OUTPUT_DIR/omo-env.out")"124pass "OMO_AST_GREP_SG_PATH resolves first"125 126# Given HOME has an OMO runtime sg executable.127# When doctor resolves ast-grep, then it reports the HOME runtime path.128RUNTIME_HOME="$OUTPUT_DIR/home"129RUNTIME_SLUG="$(omo_runtime_slug)"130RUNTIME_BIN="sg"131case "$RUNTIME_SLUG" in132 win32-*) RUNTIME_BIN="sg.exe" ;;133esac134FAKE_RUNTIME_SG="$RUNTIME_HOME/.omo/runtime/ast-grep/$RUNTIME_SLUG/$RUNTIME_BIN"135fake_sg "$FAKE_RUNTIME_SG"136HOME="$RUNTIME_HOME" CODEX_HOME= OMO_AST_GREP_SG_PATH= $HELPER doctor > "$OUTPUT_DIR/omo-runtime.out" 2>&1137grep -Fq "ast-grep binary: $FAKE_RUNTIME_SG" "$OUTPUT_DIR/omo-runtime.out" || fail "OMO HOME runtime was not resolved: $(cat "$OUTPUT_DIR/omo-runtime.out")"138pass "OMO HOME runtime resolves before standalone fallback"139 140# 9. search w/o binary => either runs successfully (binary found) OR exits 3 with hint141# The CI may or may not have ast-grep installed; both are valid.142set +e143$HELPER -q search 'foo()' --lang ts /nonexistent-path-xyzzy > "$OUTPUT_DIR/s1.out" 2>&1144RC=$?145set -e146case "$RC" in147 0|1|4)148 # Binary present but no matches OR sg returned non-fatal error - both fine149 pass "search runs (rc=$RC, ast-grep available)"150 ;;151 3)152 grep -qi 'install' "$OUTPUT_DIR/s1.out" || fail "search rc=3 should print install hint"153 pass "search without binary prints install hint"154 ;;155 *)156 fail "search returned unexpected rc=$RC: $(cat $OUTPUT_DIR/s1.out)"157 ;;158esac159 160# 10. install.sh syntax check + --help161bash -n "$SKILL_DIR/install.sh" || fail "install.sh has syntax errors"162$SKILL_DIR/install.sh --help > "$OUTPUT_DIR/inst.out" 2>&1 || true163grep -qi 'install' "$OUTPUT_DIR/inst.out" || fail "install.sh --help missing keyword 'install'"164pass "install.sh syntax + --help"165 166# 11. SKILL.md frontmatter167python3 - <<PY168import re, sys169src = open("$SKILL_DIR/SKILL.md").read()170assert src.startswith("---\n"), "SKILL.md must start with YAML frontmatter"171end = src.find("\n---\n", 4)172assert end > 0, "SKILL.md missing closing ---"173fm = src[4:end]174assert re.search(r"^name:\s*ast-grep\s*$", fm, re.M), "frontmatter missing name: ast-grep"175assert re.search(r"^description:", fm, re.M), "frontmatter missing description"176PY177pass "SKILL.md frontmatter shape"178 179# 12. All required reference files exist180for f in references/install.md references/patterns.md references/pitfalls.md \181 references/recipes.md references/cli.md references/yaml-rules.md \182 references/sgconfig.md; do183 test -f "$SKILL_DIR/$f" || fail "missing $f"184done185pass "all references present"186 187python3 - "$SKILL_DIR" <<'PY' || fail "Korean characters found in skill content"188import pathlib, re, sys189root = pathlib.Path(sys.argv[1])190hangul = re.compile(r"[\uac00-\ud7a3]")191targets = [root / "SKILL.md", root / "README.md"]192for d in ("references", "scripts", "tests", ".github"):193 targets.extend((root / d).rglob("*"))194targets.extend([root / "install.sh", root / "install.ps1"])195hits = 0196for p in targets:197 if not p.is_file():198 continue199 try:200 text = p.read_text(encoding="utf-8")201 except (UnicodeDecodeError, OSError):202 continue203 for n, line in enumerate(text.splitlines(), 1):204 if hangul.search(line):205 print(f"{p}:{n}: {line.rstrip()}")206 hits += 1207sys.exit(1 if hits else 0)208PY209pass "no Korean in skill content"210 211echo ""212echo "all smoke tests passed"213