aboutsummaryrefslogtreecommitdiff
path: root/scripts/tests/validate-go.bats
blob: 73e593654f76ddb39e8e21b131e58afdd2d5f3f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/env bats
# Tests for the Go bundle's PostToolUse validate hook.
#
# The hook reads a tool-call JSON envelope on stdin, pulls the edited file's
# path, and on a .go file runs gofmt (formatting) and go vet (compile +
# suspicious constructs) on its package. Clean -> exit 0 silent. Dirty ->
# exit 2 with a JSON hookSpecificOutput payload.

HOOK="${BATS_TEST_DIRNAME}/../../languages/go/claude/hooks/validate-go.sh"

setup() {
  command -v go >/dev/null 2>&1 || skip "go toolchain not installed"
  command -v gofmt >/dev/null 2>&1 || skip "gofmt not installed"
  command -v jq >/dev/null 2>&1 || skip "jq not installed"
  MOD="$(mktemp -d)"
  printf 'module gohooktest\n\ngo 1.26\n' > "$MOD/go.mod"
}

teardown() {
  [ -n "${MOD:-}" ] && rm -rf "$MOD"
}

# Pipe a PostToolUse envelope naming $1 as the edited file into the hook.
run_hook() {
  printf '{"tool_input":{"file_path":"%s"}}' "$1" | bash "$HOOK"
}

@test "clean formatted compiling file passes silently" {
  printf 'package main\n\nfunc main() {\n\t_ = 1\n}\n' > "$MOD/main.go"
  run run_hook "$MOD/main.go"
  [ "$status" -eq 0 ]
  [ -z "$output" ]
}

@test "non-gofmt-clean file is blocked with a GOFMT failure" {
  # Parses fine, but the body line is unindented -> gofmt would rewrite it.
  printf 'package main\n\nfunc main() {\n_ = 1\n}\n' > "$MOD/bad_fmt.go"
  run run_hook "$MOD/bad_fmt.go"
  [ "$status" -eq 2 ]
  [[ "$output" == *GOFMT* ]]
  [[ "$output" == *hookSpecificOutput* ]]
}

@test "compile error is blocked with a vet failure" {
  # gofmt-clean, but references an undefined identifier -> go vet reports it.
  printf 'package main\n\nfunc main() {\n\t_ = undefinedThing\n}\n' > "$MOD/broken.go"
  run run_hook "$MOD/broken.go"
  [ "$status" -eq 2 ]
  [[ "$output" == *VET* ]]
  [[ "$output" == *hookSpecificOutput* ]]
}

@test "non-go file is ignored" {
  printf 'plain text\n' > "$MOD/notes.txt"
  run run_hook "$MOD/notes.txt"
  [ "$status" -eq 0 ]
  [ -z "$output" ]
}

@test "missing file is ignored" {
  run run_hook "$MOD/does-not-exist.go"
  [ "$status" -eq 0 ]
  [ -z "$output" ]
}

@test "empty file_path is ignored" {
  run bash -c "printf '{\"tool_input\":{}}' | bash '$HOOK'"
  [ "$status" -eq 0 ]
  [ -z "$output" ]
}