aboutsummaryrefslogtreecommitdiff
path: root/scripts/tests/install-lang.bats
blob: f790fbf407fc573816402106601dc260e5fdee84 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env bats
#
# Tests for scripts/install-lang.sh — install a language ruleset into a project.
#
# Strategy: scaffold a fresh git project in a temp dir, run install-lang.sh
# against it. Canonical source stays the real one (install-lang.sh resolves
# languages/ and claude-rules/ relative to its own location).

REAL_REPO="$(cd "$(dirname "$BATS_TEST_FILENAME")/../.." && pwd)"
INSTALL_LANG="$REAL_REPO/scripts/install-lang.sh"

setup() {
  PROJECT="$(mktemp -d -t install-lang-bats.XXXXXX)"
  (cd "$PROJECT" && git init -q)
}

teardown() {
  rm -rf "$PROJECT"
}

@test "install-lang elisp: lands the tooling footprint" {
  run bash "$INSTALL_LANG" elisp "$PROJECT"

  [ "$status" -eq 0 ]
  [ -d "$PROJECT/.claude/rules" ]
  [ -d "$PROJECT/githooks" ]
  [ -f "$PROJECT/CLAUDE.md" ]
  # The coverage-summary script ships inside the gitignored .claude footprint.
  [ -f "$PROJECT/.claude/scripts/coverage-summary.el" ]
}

@test "install-lang elisp: seeds the project-owned coverage Makefile fragment" {
  run bash "$INSTALL_LANG" elisp "$PROJECT"

  [ "$status" -eq 0 ]
  [ -f "$PROJECT/coverage-makefile.txt" ]
}

@test "install-lang elisp: does not overwrite an existing fragment without FORCE" {
  echo "MY OWN VERSION" > "$PROJECT/coverage-makefile.txt"
  run bash "$INSTALL_LANG" elisp "$PROJECT"

  [ "$status" -eq 0 ]
  grep -qxF "MY OWN VERSION" "$PROJECT/coverage-makefile.txt"
}

@test "install-lang elisp: gitignores the full Claude tooling footprint" {
  run bash "$INSTALL_LANG" elisp "$PROJECT"

  [ "$status" -eq 0 ]
  # The whole .claude/, CLAUDE.md, and githooks/ stay out of the project's
  # git history — Claude tooling is delivered by install/sync, never committed.
  grep -qxF ".claude/" "$PROJECT/.gitignore"
  grep -qxF "CLAUDE.md" "$PROJECT/.gitignore"
  grep -qxF "githooks/" "$PROJECT/.gitignore"
  # Elisp byte-compile artifacts.
  grep -qxF "*.elc" "$PROJECT/.gitignore"
  grep -qxF "*.eln" "$PROJECT/.gitignore"
}

@test "install-lang python: lands the coverage script in the gitignored footprint" {
  run bash "$INSTALL_LANG" python "$PROJECT"

  [ "$status" -eq 0 ]
  [ -f "$PROJECT/.claude/scripts/coverage-summary.py" ]
  [ -f "$PROJECT/coverage-makefile.txt" ]
  # The .claude footprint must be gitignored so the script isn't committed.
  grep -qxF ".claude/" "$PROJECT/.gitignore"
  grep -qxF "coverage.json" "$PROJECT/.gitignore"
}

@test "install-lang typescript: lands the coverage script in the gitignored footprint" {
  run bash "$INSTALL_LANG" typescript "$PROJECT"

  [ "$status" -eq 0 ]
  [ -f "$PROJECT/.claude/scripts/coverage-summary.js" ]
  [ -f "$PROJECT/coverage-makefile.txt" ]
  grep -qxF ".claude/" "$PROJECT/.gitignore"
  grep -qxF "coverage/" "$PROJECT/.gitignore"
}

@test "install-lang python: seeds the language-neutral default CLAUDE.md when the bundle ships none" {
  run bash "$INSTALL_LANG" python "$PROJECT"

  [ "$status" -eq 0 ]
  [ -f "$PROJECT/CLAUDE.md" ]
  # The default names no language, so it can't mislabel a python (or bash, or
  # multi-bundle) project the way inheriting elisp's "Elisp project" header did.
  ! grep -qi "Python project" "$PROJECT/CLAUDE.md"
  ! grep -qi "Elisp project" "$PROJECT/CLAUDE.md"
  grep -qF "names no language" "$PROJECT/CLAUDE.md"
  [[ "$output" == *"language-neutral default"* ]]
}

@test "install-lang elisp: seeds the bundle's own CLAUDE.md, not the default" {
  run bash "$INSTALL_LANG" elisp "$PROJECT"

  [ "$status" -eq 0 ]
  grep -qF "Elisp project." "$PROJECT/CLAUDE.md"
  [[ "$output" == *"CLAUDE.md installed (elisp)"* ]]
}

@test "install-lang python: does not overwrite an existing CLAUDE.md without FORCE" {
  echo "MY OWN CLAUDE" > "$PROJECT/CLAUDE.md"
  run bash "$INSTALL_LANG" python "$PROJECT"

  [ "$status" -eq 0 ]
  grep -qxF "MY OWN CLAUDE" "$PROJECT/CLAUDE.md"
}

@test "install-lang go: full bundle lands (rules, hook, settings, githook, CLAUDE.md, coverage)" {
  run bash "$INSTALL_LANG" go "$PROJECT"

  [ "$status" -eq 0 ]
  # Coverage slice
  [ -f "$PROJECT/.claude/scripts/coverage-summary.go" ]
  [ -f "$PROJECT/coverage-makefile.txt" ]
  # Language + testing rules — these are the bundle's sync fingerprint
  [ -f "$PROJECT/.claude/rules/go.md" ]
  [ -f "$PROJECT/.claude/rules/go-testing.md" ]
  # PostToolUse validate hook, executable and wired into settings
  [ -x "$PROJECT/.claude/hooks/validate-go.sh" ]
  grep -qF "validate-go.sh" "$PROJECT/.claude/settings.json"
  # Pre-commit githook
  [ -x "$PROJECT/githooks/pre-commit" ]
  # CLAUDE.md seeded
  [ -f "$PROJECT/CLAUDE.md" ]
  # Gitignore footprint
  grep -qxF ".claude/" "$PROJECT/.gitignore"
  grep -qxF "cover.out" "$PROJECT/.gitignore"
}