Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Tests

on:
push:
branches: ["**"]
pull_request:
branches: ["**"]

jobs:
bats:
name: bats (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]

steps:
- uses: actions/checkout@v4

- name: Install bats-core (Ubuntu)
if: runner.os == 'Linux'
run: |
git clone --depth 1 https://github.com/bats-core/bats-core.git /tmp/bats-core
sudo /tmp/bats-core/install.sh /usr/local

- name: Install bats-core (macOS)
if: runner.os == 'macOS'
run: brew install bats-core

- name: Run tests
run: bats tests/
13 changes: 11 additions & 2 deletions ccm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,18 @@ detect_platform() {
# Returns: Prints the absolute path to .claude.json
# Usage: config_path=$(get_claude_config_path)
get_claude_config_path() {
# Honor CLAUDE_CONFIG_DIR if set (supports non-standard config directories)
if [[ -n "${CLAUDE_CONFIG_DIR:-}" ]]; then
local env_config="${CLAUDE_CONFIG_DIR}/.claude.json"
if [[ -f "$env_config" ]]; then
echo "$env_config"
return
fi
fi

local primary_config="$HOME/.claude/.claude.json"
local fallback_config="$HOME/.claude.json"

# Check primary location first
if [[ -f "$primary_config" ]]; then
# Verify it has valid oauthAccount structure
Expand All @@ -113,7 +122,7 @@ get_claude_config_path() {
return
fi
fi

# Fallback to standard location
echo "$fallback_config"
}
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
"ccm.sh",
"README.md",
"LICENSE"
]
],
"scripts": {
"test": "bats tests/"
}
}
83 changes: 83 additions & 0 deletions tests/get_claude_config_path.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env bats
# Tests for get_claude_config_path, focused on CLAUDE_CONFIG_DIR support

setup() {
# Set HOME before sourcing so readonly globals (BACKUP_DIR etc.) use TEST_HOME
TEST_HOME="$(mktemp -d)"
export HOME="$TEST_HOME"
unset CLAUDE_CONFIG_DIR

# BASH_SOURCE guard in ccm.sh prevents main() from running when sourced
# shellcheck source=../ccm.sh
source "${BATS_TEST_DIRNAME}/../ccm.sh"
}

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

# ---------------------------------------------------------------------------
# CLAUDE_CONFIG_DIR behaviour
# ---------------------------------------------------------------------------

@test "returns CLAUDE_CONFIG_DIR/.claude.json when env var is set and file exists" {
local custom_dir="$TEST_HOME/.claude-custom"
mkdir -p "$custom_dir"
printf '{"oauthAccount":{"emailAddress":"test@example.com"}}\n' \
> "$custom_dir/.claude.json"

export CLAUDE_CONFIG_DIR="$custom_dir"
run get_claude_config_path

[ "$status" -eq 0 ]
[ "$output" = "$custom_dir/.claude.json" ]
}

@test "falls through to primary when CLAUDE_CONFIG_DIR is set but .claude.json is absent" {
local custom_dir="$TEST_HOME/.claude-empty"
mkdir -p "$custom_dir"
# No .claude.json in custom_dir — should fall through

mkdir -p "$TEST_HOME/.claude"
printf '{"oauthAccount":{"emailAddress":"primary@example.com"}}\n' \
> "$TEST_HOME/.claude/.claude.json"

export CLAUDE_CONFIG_DIR="$custom_dir"
run get_claude_config_path

[ "$status" -eq 0 ]
[ "$output" = "$TEST_HOME/.claude/.claude.json" ]
}

# ---------------------------------------------------------------------------
# Original behaviour (CLAUDE_CONFIG_DIR unset)
# ---------------------------------------------------------------------------

@test "returns ~/.claude/.claude.json when CLAUDE_CONFIG_DIR is unset and primary exists" {
mkdir -p "$TEST_HOME/.claude"
printf '{"oauthAccount":{"emailAddress":"primary@example.com"}}\n' \
> "$TEST_HOME/.claude/.claude.json"

run get_claude_config_path

[ "$status" -eq 0 ]
[ "$output" = "$TEST_HOME/.claude/.claude.json" ]
}

@test "skips primary when it has no oauthAccount and returns ~/.claude.json fallback" {
mkdir -p "$TEST_HOME/.claude"
printf '{"someOtherField":true}\n' > "$TEST_HOME/.claude/.claude.json"

run get_claude_config_path

[ "$status" -eq 0 ]
[ "$output" = "$TEST_HOME/.claude.json" ]
}

@test "returns ~/.claude.json fallback when CLAUDE_CONFIG_DIR is unset and primary is missing" {
# Neither ~/.claude/.claude.json nor CLAUDE_CONFIG_DIR — pure fallback path
run get_claude_config_path

[ "$status" -eq 0 ]
[ "$output" = "$TEST_HOME/.claude.json" ]
}