-
Notifications
You must be signed in to change notification settings - Fork 0
test: split wt.bats into one file per command #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| load helpers | ||
|
|
||
| setup() { wt_common_setup; } | ||
| teardown() { wt_common_teardown; } | ||
|
|
||
| # --- _wt_cd --- | ||
|
|
||
| @test "wt <name> navigates to worktree" { | ||
| _wt_cd feature | ||
| [ "$PWD" = "$TEST_REPO-feature" ] | ||
| } | ||
|
|
||
| @test "wt cd <name> navigates to worktree" { | ||
| wt cd other | ||
| [ "$PWD" = "$TEST_REPO-other" ] | ||
| } | ||
|
|
||
| @test "wt <name> returns error for no match" { | ||
| run _wt_cd nonexistent | ||
| [ "$status" -eq 1 ] | ||
| [[ "$output" == *"no worktree matching"* ]] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| load ../helpers | ||
|
|
||
| setup() { wt_common_setup; } | ||
| teardown() { wt_common_teardown; } | ||
|
|
||
| # --- wt ls --claude --- | ||
|
|
||
| @test "wt ls --claude shows sessions for all worktrees, including the base one" { | ||
| local stubbin; stubbin=$(mktemp -d) | ||
| cat > "$stubbin/claude" <<EOF | ||
| #!/usr/bin/env bash | ||
| cat <<JSON | ||
| [ | ||
| {"id":"base111","cwd":"$TEST_REPO","name":"base repo session","state":"done"}, | ||
| {"id":"feat222","cwd":"$TEST_REPO-feature","name":"feature session","state":"blocked"} | ||
| ] | ||
| JSON | ||
| EOF | ||
| chmod +x "$stubbin/claude" | ||
| cat > "$stubbin/jq" <<EOF | ||
| #!/usr/bin/env bash | ||
| exec "$(command -v jq)" "\$@" | ||
| EOF | ||
| chmod +x "$stubbin/jq" | ||
|
|
||
| PATH="$stubbin:$PATH" run wt ls --claude | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"BRANCH"*"SESSION"*"NAME"*"STATE"* ]] | ||
| [[ "$output" == *"base111"* ]] | ||
| [[ "$output" == *"base repo session"* ]] | ||
| [[ "$output" == *"feat222"* ]] | ||
| [[ "$output" == *"feature session"* ]] | ||
| [[ "$output" == *"other"* ]] | ||
| # the main repo worktree's branch can drift over time (unlike a dedicated | ||
| # per-task worktree), so it should never be reported as a literal branch | ||
| # name - only the distinct "(main, branch varies)" label | ||
| [[ "$output" == *"(main, branch varies)"* ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
|
|
||
| @test "wt ls --claude attributes sessions via job state when the agents cwd is stale" { | ||
| local stubbin; stubbin=$(mktemp -d) | ||
| local sid="11111111-2222-3333-4444-555555555555" | ||
| # `claude agents` reports the session's cwd as the main repo - the stale | ||
| # dispatch-time value, recorded before the agent entered its worktree | ||
| cat > "$stubbin/claude" <<EOF | ||
| #!/usr/bin/env bash | ||
| cat <<JSON | ||
| [ | ||
| {"id":"stale001","sessionId":"$sid","cwd":"$TEST_REPO","name":"stale cwd session","state":"done"} | ||
| ] | ||
| JSON | ||
| EOF | ||
| chmod +x "$stubbin/claude" | ||
| cat > "$stubbin/jq" <<EOF | ||
| #!/usr/bin/env bash | ||
| exec "$(command -v jq)" "\$@" | ||
| EOF | ||
| chmod +x "$stubbin/jq" | ||
|
|
||
| # ...but the background-job state knows the real worktree | ||
| local confdir; confdir=$(mktemp -d) | ||
| mkdir -p "$confdir/jobs/stale001" | ||
| cat > "$confdir/jobs/stale001/state.json" <<EOF | ||
| {"sessionId":"$sid","worktreePath":"$TEST_REPO-feature","worktreeBranch":"feature","state":"done"} | ||
| EOF | ||
|
|
||
| CLAUDE_CONFIG_DIR="$confdir" PATH="$stubbin:$PATH" run wt ls --claude | ||
| [ "$status" -eq 0 ] | ||
| # attributed to the feature worktree row, not the main repo row | ||
| [[ "$(echo "$output" | grep stale001)" == feature* ]] | ||
| ! echo "$output" | grep "(main, branch varies)" | grep -q stale001 | ||
| rm -rf "$stubbin" "$confdir" | ||
| } | ||
|
|
||
| @test "wt ls --claude falls back to plain listing when claude CLI is missing" { | ||
| local stubbin; stubbin=$(mktemp -d) | ||
| ln -s "$(command -v git)" "$stubbin/git" | ||
| ln -s "$(command -v awk)" "$stubbin/awk" | ||
|
|
||
| PATH="$stubbin" run wt ls --claude | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"claude CLI not found"* ]] | ||
| [[ "$output" == *"feature"* ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
|
Copilot marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,170 @@ | ||
| load ../helpers | ||
|
|
||
| setup() { wt_common_setup; } | ||
| teardown() { wt_common_teardown; } | ||
|
|
||
| # --- wt merged --claude --- | ||
|
|
||
| @test "wt merged --claude warns and falls back when claude CLI is missing" { | ||
| local base; base=$(git -C "$TEST_REPO" symbolic-ref --short HEAD) | ||
| git -C "$TEST_REPO-feature" commit -q --allow-empty -m "feature commit" | ||
| cd "$TEST_REPO" | ||
| git merge -q feature | ||
|
|
||
| local stubbin; stubbin=$(mktemp -d) | ||
| # only symlink the external commands wt.sh actually needs (git, awk) - | ||
| # deliberately no claude, so `command -v claude` fails regardless of the host PATH | ||
| ln -s "$(command -v git)" "$stubbin/git" | ||
| ln -s "$(command -v awk)" "$stubbin/awk" | ||
|
|
||
| PATH="$stubbin" run wt merged "$base" --claude | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"claude CLI not found"* ]] | ||
| [[ "$output" == *"$TEST_REPO-feature"* ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
|
|
||
| @test "wt merged --claude lists agent sessions per worktree" { | ||
| local base; base=$(git -C "$TEST_REPO" symbolic-ref --short HEAD) | ||
| git -C "$TEST_REPO-feature" commit -q --allow-empty -m "feature commit" | ||
| cd "$TEST_REPO" | ||
| git merge -q feature | ||
|
|
||
| local stubbin; stubbin=$(mktemp -d) | ||
| # fake claude returns two sessions: one for our merged worktree's cwd, one | ||
| # for an unrelated cwd - the unrelated one must be filtered out client-side | ||
| cat > "$stubbin/claude" <<EOF | ||
| #!/usr/bin/env bash | ||
| cat <<JSON | ||
| [ | ||
| {"id":"abc123","cwd":"$TEST_REPO-feature","name":"do the thing","state":"done"}, | ||
| {"id":"zzz999","cwd":"/somewhere/else","name":"unrelated","state":"done"} | ||
| ] | ||
| JSON | ||
| EOF | ||
| chmod +x "$stubbin/claude" | ||
| cat > "$stubbin/jq" <<EOF | ||
| #!/usr/bin/env bash | ||
| exec "$(command -v jq)" "\$@" | ||
| EOF | ||
| chmod +x "$stubbin/jq" | ||
|
Copilot marked this conversation as resolved.
|
||
|
|
||
| PATH="$stubbin:$PATH" run wt merged "$base" --claude | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"BRANCH"*"SESSION"*"NAME"*"STATE"* ]] | ||
| [[ "$output" == *"feature"* ]] | ||
| [[ "$output" == *"abc123"* ]] | ||
| [[ "$output" == *"do the thing"* ]] | ||
| [[ "$output" == *"done"* ]] | ||
| [[ "$output" != *"zzz999"* ]] | ||
| [[ "$output" != *"unrelated"* ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
|
|
||
| @test "wt merged --claude labels the main repo worktree distinctly instead of asserting a branch" { | ||
| # the main repo worktree can itself end up in the merged list (checked out | ||
| # to some other merged, non-base branch) - unlike a dedicated per-task | ||
| # worktree, its current branch isn't a reliable record of what was checked | ||
| # out when a past session actually ran there | ||
| local base; base=$(git -C "$TEST_REPO" symbolic-ref --short HEAD) | ||
| cd "$TEST_REPO" | ||
| git checkout -qb main-drift | ||
|
|
||
| local stubbin; stubbin=$(mktemp -d) | ||
| cat > "$stubbin/claude" <<EOF | ||
| #!/usr/bin/env bash | ||
| cat <<JSON | ||
| [ | ||
| {"id":"main111","cwd":"$TEST_REPO","name":"main repo session","state":"done"} | ||
| ] | ||
| JSON | ||
| EOF | ||
| chmod +x "$stubbin/claude" | ||
| cat > "$stubbin/jq" <<EOF | ||
| #!/usr/bin/env bash | ||
| exec "$(command -v jq)" "\$@" | ||
| EOF | ||
| chmod +x "$stubbin/jq" | ||
|
|
||
| PATH="$stubbin:$PATH" run wt merged "$base" --claude | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"main111"* ]] | ||
| [[ "$output" == *"main repo session"* ]] | ||
| [[ "$output" == *"(main, branch varies)"* ]] | ||
| [[ "$output" != *"main-drift"* ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
|
|
||
| @test "wt merged --claude shows a placeholder row for worktrees with no sessions" { | ||
| local base; base=$(git -C "$TEST_REPO" symbolic-ref --short HEAD) | ||
| git -C "$TEST_REPO-feature" commit -q --allow-empty -m "feature commit" | ||
| cd "$TEST_REPO" | ||
| git merge -q feature | ||
|
|
||
| local stubbin; stubbin=$(mktemp -d) | ||
| cat > "$stubbin/claude" <<'EOF' | ||
| #!/usr/bin/env bash | ||
| echo '[]' | ||
| EOF | ||
| chmod +x "$stubbin/claude" | ||
| cat > "$stubbin/jq" <<EOF | ||
| #!/usr/bin/env bash | ||
| exec "$(command -v jq)" "\$@" | ||
| EOF | ||
| chmod +x "$stubbin/jq" | ||
|
|
||
| PATH="$stubbin:$PATH" run wt merged "$base" --claude | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" =~ feature.*-.*-.*- ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
|
|
||
| @test "wt merged --claude errors when jq is missing" { | ||
| local base; base=$(git -C "$TEST_REPO" symbolic-ref --short HEAD) | ||
| git -C "$TEST_REPO-feature" commit -q --allow-empty -m "feature commit" | ||
| cd "$TEST_REPO" | ||
| git merge -q feature | ||
|
|
||
| local stubbin; stubbin=$(mktemp -d) | ||
| cat > "$stubbin/claude" <<'EOF' | ||
| #!/usr/bin/env bash | ||
| echo '[]' | ||
| EOF | ||
| chmod +x "$stubbin/claude" | ||
| # only symlink the external commands wt.sh actually needs (git, awk) - | ||
| # deliberately no jq, so `command -v jq` fails regardless of the host PATH | ||
| ln -s "$(command -v git)" "$stubbin/git" | ||
| ln -s "$(command -v awk)" "$stubbin/awk" | ||
|
|
||
| PATH="$stubbin" run wt merged "$base" --claude | ||
| [ "$status" -ne 0 ] | ||
| [[ "$output" == *"jq not found"* ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
|
|
||
| @test "wt merged --claude degrades gracefully when claude agents returns malformed output" { | ||
| local base; base=$(git -C "$TEST_REPO" symbolic-ref --short HEAD) | ||
| git -C "$TEST_REPO-feature" commit -q --allow-empty -m "feature commit" | ||
| cd "$TEST_REPO" | ||
| git merge -q feature | ||
|
|
||
| local stubbin; stubbin=$(mktemp -d) | ||
| # fake claude returns garbage instead of JSON (e.g. a crash/error message) | ||
| cat > "$stubbin/claude" <<'EOF' | ||
| #!/usr/bin/env bash | ||
| echo 'not valid json at all' | ||
| EOF | ||
| chmod +x "$stubbin/claude" | ||
| cat > "$stubbin/jq" <<EOF | ||
| #!/usr/bin/env bash | ||
| exec "$(command -v jq)" "\$@" | ||
| EOF | ||
| chmod +x "$stubbin/jq" | ||
|
|
||
| PATH="$stubbin:$PATH" run wt merged "$base" --claude | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"could not read Claude Code agent sessions"* ]] | ||
| [[ "$output" == *"feature"* ]] | ||
| [[ "$output" =~ feature.*-.*-.*- ]] | ||
| rm -rf "$stubbin" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| load helpers | ||
|
|
||
| setup() { wt_common_setup; } | ||
| teardown() { wt_common_teardown; } | ||
|
|
||
| # --- help --- | ||
|
|
||
| @test "wt help prints usage" { | ||
| run wt help | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"Usage:"* ]] | ||
| } | ||
|
|
||
| @test "wt --help prints usage" { | ||
| run wt --help | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"Usage:"* ]] | ||
| } | ||
|
|
||
| @test "wt -h prints usage" { | ||
| run wt -h | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"Usage:"* ]] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # shared setup/teardown for all test files. | ||
| # | ||
| # usage, from a .bats file: | ||
| # load helpers # test/*.bats | ||
| # load ../helpers # test/claude/*.bats | ||
| # | ||
| # setup() { wt_common_setup; } | ||
| # teardown() { wt_common_teardown; } | ||
|
|
||
| wt_common_setup() { | ||
| # create a temp repo and two worktrees | ||
| TEST_REPO=$(mktemp -d) | ||
| cd "$TEST_REPO" | ||
| git init -q | ||
| git config user.email "test@test.com" | ||
| git config user.name "Test" | ||
| git commit -q --allow-empty -m "init" | ||
|
|
||
| git worktree add -q "$TEST_REPO-feature" -b feature | ||
| git worktree add -q "$TEST_REPO-other" -b other | ||
|
|
||
| # locate wt.sh by walking up from the test file's directory, so tests work | ||
| # at any nesting depth and don't require a git checkout | ||
| local dir="$BATS_TEST_DIRNAME" | ||
| while [ ! -f "$dir/wt.sh" ] && [ "$dir" != "/" ]; do | ||
| dir=$(dirname "$dir") | ||
| done | ||
| source "$dir/wt.sh" | ||
| } | ||
|
|
||
| wt_common_teardown() { | ||
| rm -rf "$TEST_REPO" "$TEST_REPO-feature" "$TEST_REPO-other" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| load helpers | ||
|
|
||
| setup() { wt_common_setup; } | ||
| teardown() { wt_common_teardown; } | ||
|
|
||
| # --- _wt_ls --- | ||
|
|
||
| @test "wt ls lists worktrees" { | ||
| run _wt_ls | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"$TEST_REPO "* ]] | ||
| [[ "$output" == *"feature"* ]] | ||
| [[ "$output" == *"other"* ]] | ||
| } | ||
|
|
||
| @test "wt with no args lists worktrees" { | ||
| run wt | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"feature"* ]] | ||
| } | ||
|
|
||
| @test "wt list alias works" { | ||
| run wt list | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"feature"* ]] | ||
| } | ||
|
|
||
| @test "wt ls alias works" { | ||
| run wt ls | ||
| [ "$status" -eq 0 ] | ||
| [[ "$output" == *"feature"* ]] | ||
| } | ||
|
|
||
| @test "wt ls errors on unknown flag" { | ||
| run wt ls --bogus | ||
| [ "$status" -ne 0 ] | ||
| [[ "$output" == *"unknown flag"* ]] | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.