aboutsummaryrefslogtreecommitdiff
path: root/scripts/tests/install-ai.bats
blob: dca70ea4df4f656b5f1a8e685cf9826a6fbaf870 (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
#!/usr/bin/env bats
#
# Tests for scripts/install-ai.sh — bootstrap .ai/ in a fresh project.
#
# Strategy: redirect HOME to a temp dir, scaffold fresh project trees
# under HOME/code/, run install-ai.sh against them. Canonical source
# stays the real one (install-ai.sh resolves it relative to its own
# location). For the fzf-pick form, stub fzf to take the first line.

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

setup() {
  TEST_HOME="$(mktemp -d -t install-ai-bats.XXXXXX)"
  HOME_BAK="$HOME"
  export HOME="$TEST_HOME"
  mkdir -p "$TEST_HOME/code" "$TEST_HOME/projects"
}

teardown() {
  export HOME="$HOME_BAK"
  rm -rf "$TEST_HOME"
}

@test "install-ai: happy path with explicit PROJECT + --gitignore" {
  mkdir -p "$TEST_HOME/code/fresh"
  (cd "$TEST_HOME/code/fresh" && git init -q)

  run bash "$INSTALL_AI" --gitignore "$TEST_HOME/code/fresh"

  [ "$status" -eq 0 ]
  [ -d "$TEST_HOME/code/fresh/.ai/workflows" ]
  [ -d "$TEST_HOME/code/fresh/.ai/scripts" ]
  [ -d "$TEST_HOME/code/fresh/.ai/sessions" ]
  [ -d "$TEST_HOME/code/fresh/.ai/references" ]
  [ -d "$TEST_HOME/code/fresh/.ai/retrospectives" ]
  [ -f "$TEST_HOME/code/fresh/.ai/protocols.org" ]
  [ -f "$TEST_HOME/code/fresh/.ai/notes.org" ]
  grep -qFx ".ai/" "$TEST_HOME/code/fresh/.gitignore"
  # Top-level inbox/ is created so the project is an inbox-send target.
  [ -d "$TEST_HOME/code/fresh/inbox" ]
  [ -f "$TEST_HOME/code/fresh/inbox/.gitkeep" ]
}

@test "install-ai: creates top-level inbox/ in --track mode too" {
  mkdir -p "$TEST_HOME/code/inbox-track"
  (cd "$TEST_HOME/code/inbox-track" && git init -q)

  run bash "$INSTALL_AI" --track "$TEST_HOME/code/inbox-track"

  [ "$status" -eq 0 ]
  [ -d "$TEST_HOME/code/inbox-track/inbox" ]
  [ -f "$TEST_HOME/code/inbox-track/inbox/.gitkeep" ]
}

@test "install-ai: preserves a pre-existing inbox/ with content" {
  mkdir -p "$TEST_HOME/code/has-inbox/inbox"
  (cd "$TEST_HOME/code/has-inbox" && git init -q)
  echo "handoff" > "$TEST_HOME/code/has-inbox/inbox/2026-06-01-existing.org"

  run bash "$INSTALL_AI" --gitignore "$TEST_HOME/code/has-inbox"

  [ "$status" -eq 0 ]
  [ -d "$TEST_HOME/code/has-inbox/inbox" ]
  # Existing inbox content is untouched.
  [ -f "$TEST_HOME/code/has-inbox/inbox/2026-06-01-existing.org" ]
}

@test "install-ai --track: lands .gitkeep stubs in empty dirs" {
  mkdir -p "$TEST_HOME/code/tracked"
  (cd "$TEST_HOME/code/tracked" && git init -q)

  run bash "$INSTALL_AI" --track "$TEST_HOME/code/tracked"

  [ "$status" -eq 0 ]
  [ -f "$TEST_HOME/code/tracked/.ai/sessions/.gitkeep" ]
  [ -f "$TEST_HOME/code/tracked/.ai/references/.gitkeep" ]
  [ -f "$TEST_HOME/code/tracked/.ai/retrospectives/.gitkeep" ]
}

@test "install-ai: refuses on existing .ai/" {
  mkdir -p "$TEST_HOME/code/already/.ai"
  echo "marker" > "$TEST_HOME/code/already/.ai/marker.txt"

  run bash "$INSTALL_AI" --gitignore "$TEST_HOME/code/already"

  [ "$status" -eq 2 ]
  [[ "$output" == *"already exists"* ]]
  # Existing content untouched.
  [ -f "$TEST_HOME/code/already/.ai/marker.txt" ]
}

@test "install-ai: notes.org placeholders get substituted" {
  mkdir -p "$TEST_HOME/code/named-proj"
  (cd "$TEST_HOME/code/named-proj" && git init -q)

  run bash "$INSTALL_AI" --gitignore "$TEST_HOME/code/named-proj"

  [ "$status" -eq 0 ]
  # Project name landed.
  grep -q "named-proj" "$TEST_HOME/code/named-proj/.ai/notes.org"
  # No raw placeholders left.
  ! grep -q "\[Project Name\]" "$TEST_HOME/code/named-proj/.ai/notes.org"
  ! grep -q "\[Date\]" "$TEST_HOME/code/named-proj/.ai/notes.org"
}

@test "install-ai: fzf-pick form selects via stubbed fzf" {
  # Edge case 3 from todo.org:1766. The fzf-pick form is interactive;
  # stubbing fzf to take the first stdin line lets us exercise the
  # discovery+selection path without an interactive terminal.
  mkdir -p "$TEST_HOME/code/pickme" "$TEST_HOME/code/skipme"
  (cd "$TEST_HOME/code/pickme" && git init -q)
  (cd "$TEST_HOME/code/skipme" && git init -q)

  stub_bin="$(mktemp -d)"
  cat > "$stub_bin/fzf" <<'EOF'
#!/bin/bash
# Pass through stdin's first line as the "selection".
head -n 1
EOF
  chmod +x "$stub_bin/fzf"

  PATH="$stub_bin:$PATH" run bash "$INSTALL_AI" --gitignore
  rm -rf "$stub_bin"

  [ "$status" -eq 0 ]
  # Sort order puts pickme first; fzf-stub returns the first line.
  [ -d "$TEST_HOME/code/pickme/.ai" ]
  [ ! -d "$TEST_HOME/code/skipme/.ai" ]
}