mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 11:31:46 +00:00
refactor: improve brew cleanup timeout handling and remove app_caches, clean_extras, and optimize_core tests.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,6 +25,7 @@ temp/
|
||||
*.tmp
|
||||
*.temp
|
||||
*.dmg
|
||||
tests/tmp-*
|
||||
|
||||
# Cache
|
||||
.cache/
|
||||
|
||||
@@ -43,41 +43,32 @@ clean_homebrew() {
|
||||
MOLE_SPINNER_PREFIX=" " start_inline_spinner "Homebrew cleanup and autoremove..."
|
||||
fi
|
||||
fi
|
||||
# Run cleanup/autoremove in parallel with a timeout guard.
|
||||
# Run cleanup/autoremove in parallel with timeout guard per command.
|
||||
local timeout_seconds=${MO_BREW_TIMEOUT:-120}
|
||||
local brew_tmp_file autoremove_tmp_file
|
||||
local brew_pid autoremove_pid
|
||||
local brew_exit=0
|
||||
local autoremove_exit=0
|
||||
if [[ "$skip_cleanup" == "false" ]]; then
|
||||
brew_tmp_file=$(create_temp_file)
|
||||
(brew cleanup > "$brew_tmp_file" 2>&1) &
|
||||
run_with_timeout "$timeout_seconds" brew cleanup > "$brew_tmp_file" 2>&1 &
|
||||
brew_pid=$!
|
||||
fi
|
||||
autoremove_tmp_file=$(create_temp_file)
|
||||
(brew autoremove > "$autoremove_tmp_file" 2>&1) &
|
||||
run_with_timeout "$timeout_seconds" brew autoremove > "$autoremove_tmp_file" 2>&1 &
|
||||
autoremove_pid=$!
|
||||
local elapsed=0
|
||||
local brew_done=false
|
||||
local autoremove_done=false
|
||||
[[ "$skip_cleanup" == "true" ]] && brew_done=true
|
||||
while [[ "$brew_done" == "false" ]] || [[ "$autoremove_done" == "false" ]]; do
|
||||
if [[ $elapsed -ge $timeout_seconds ]]; then
|
||||
[[ -n "$brew_pid" ]] && kill -TERM $brew_pid 2> /dev/null || true
|
||||
kill -TERM $autoremove_pid 2> /dev/null || true
|
||||
break
|
||||
|
||||
if [[ -n "$brew_pid" ]]; then
|
||||
wait "$brew_pid" 2> /dev/null || brew_exit=$?
|
||||
fi
|
||||
[[ -n "$brew_pid" ]] && { kill -0 $brew_pid 2> /dev/null || brew_done=true; }
|
||||
kill -0 $autoremove_pid 2> /dev/null || autoremove_done=true
|
||||
sleep 1
|
||||
((elapsed++))
|
||||
done
|
||||
wait "$autoremove_pid" 2> /dev/null || autoremove_exit=$?
|
||||
|
||||
local brew_success=false
|
||||
if [[ "$skip_cleanup" == "false" && -n "$brew_pid" ]]; then
|
||||
if wait $brew_pid 2> /dev/null; then
|
||||
if [[ "$skip_cleanup" == "false" && $brew_exit -eq 0 ]]; then
|
||||
brew_success=true
|
||||
fi
|
||||
fi
|
||||
local autoremove_success=false
|
||||
if wait $autoremove_pid 2> /dev/null; then
|
||||
if [[ $autoremove_exit -eq 0 ]]; then
|
||||
autoremove_success=true
|
||||
fi
|
||||
if [[ -t 1 ]]; then stop_inline_spinner; fi
|
||||
@@ -100,7 +91,7 @@ clean_homebrew() {
|
||||
echo -e " ${GREEN}${ICON_SUCCESS}${NC} Homebrew cleanup (${removed_count} items)"
|
||||
fi
|
||||
fi
|
||||
elif [[ $elapsed -ge $timeout_seconds ]]; then
|
||||
elif [[ $brew_exit -eq 124 ]]; then
|
||||
echo -e " ${YELLOW}${ICON_WARNING}${NC} Homebrew cleanup timed out · run ${GRAY}brew cleanup${NC} manually"
|
||||
fi
|
||||
# Process autoremove output - only show if packages were removed
|
||||
@@ -113,7 +104,7 @@ clean_homebrew() {
|
||||
if [[ $removed_packages -gt 0 ]]; then
|
||||
echo -e " ${GREEN}${ICON_SUCCESS}${NC} Removed orphaned dependencies (${removed_packages} packages)"
|
||||
fi
|
||||
elif [[ $elapsed -ge $timeout_seconds ]]; then
|
||||
elif [[ $autoremove_exit -eq 124 ]]; then
|
||||
echo -e " ${YELLOW}${ICON_WARNING}${NC} Autoremove timed out · run ${GRAY}brew autoremove${NC} manually"
|
||||
fi
|
||||
# Update cache timestamp on successful completion or when cleanup was intelligently skipped
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-app-caches.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "clean_xcode_tools skips derived data when Xcode running" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" /bin/bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
pgrep() { return 0; }
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_xcode_tools
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Xcode is running"* ]]
|
||||
[[ "$output" != *"derived data"* ]]
|
||||
[[ "$output" != *"archives"* ]]
|
||||
}
|
||||
|
||||
@test "clean_media_players protects spotify offline cache" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" /bin/bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
mkdir -p "$HOME/Library/Application Support/Spotify/PersistentCache/Storage"
|
||||
touch "$HOME/Library/Application Support/Spotify/PersistentCache/Storage/offline.bnk"
|
||||
safe_clean() { echo "CLEAN:$2"; }
|
||||
clean_media_players
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Spotify cache protected"* ]]
|
||||
[[ "$output" != *"CLEAN: Spotify cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_user_gui_applications calls all sections" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" /bin/bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
stop_section_spinner() { :; }
|
||||
safe_clean() { :; }
|
||||
clean_xcode_tools() { echo "xcode"; }
|
||||
clean_code_editors() { echo "editors"; }
|
||||
clean_communication_apps() { echo "comm"; }
|
||||
clean_user_gui_applications
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"xcode"* ]]
|
||||
[[ "$output" == *"editors"* ]]
|
||||
[[ "$output" == *"comm"* ]]
|
||||
}
|
||||
@@ -7,7 +7,7 @@ setup_file() {
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-app-caches-more.XXXXXX")"
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-app-caches.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
@@ -20,6 +20,57 @@ teardown_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
@test "clean_xcode_tools skips derived data when Xcode running" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" /bin/bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
pgrep() { return 0; }
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_xcode_tools
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Xcode is running"* ]]
|
||||
[[ "$output" != *"derived data"* ]]
|
||||
[[ "$output" != *"archives"* ]]
|
||||
}
|
||||
|
||||
@test "clean_media_players protects spotify offline cache" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" /bin/bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
mkdir -p "$HOME/Library/Application Support/Spotify/PersistentCache/Storage"
|
||||
touch "$HOME/Library/Application Support/Spotify/PersistentCache/Storage/offline.bnk"
|
||||
safe_clean() { echo "CLEAN:$2"; }
|
||||
clean_media_players
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Spotify cache protected"* ]]
|
||||
[[ "$output" != *"CLEAN: Spotify cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_user_gui_applications calls all sections" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" /bin/bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
stop_section_spinner() { :; }
|
||||
safe_clean() { :; }
|
||||
clean_xcode_tools() { echo "xcode"; }
|
||||
clean_code_editors() { echo "editors"; }
|
||||
clean_communication_apps() { echo "comm"; }
|
||||
clean_user_gui_applications
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"xcode"* ]]
|
||||
[[ "$output" == *"editors"* ]]
|
||||
[[ "$output" == *"comm"* ]]
|
||||
}
|
||||
|
||||
@test "clean_ai_apps calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
@@ -74,8 +74,27 @@ EOF
|
||||
skip "Homebrew not installed"
|
||||
fi
|
||||
|
||||
run env HOME="$HOME" MO_BREW_TIMEOUT=5 "$PROJECT_ROOT/bin/clean.sh" --dry-run
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/brew.sh"
|
||||
|
||||
MO_BREW_TIMEOUT=5
|
||||
CALL_LOG="$HOME/timeout.log"
|
||||
|
||||
run_with_timeout() {
|
||||
echo "$1" >> "$CALL_LOG"
|
||||
shift
|
||||
"$@"
|
||||
}
|
||||
|
||||
brew() { return 0; }
|
||||
|
||||
clean_homebrew
|
||||
cat "$CALL_LOG"
|
||||
EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"5"* ]]
|
||||
}
|
||||
|
||||
@test "FINDER_METADATA_SENTINEL in whitelist protects .DS_Store files" {
|
||||
@@ -1,102 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-clean-extras.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "clean_cloud_storage calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
stop_section_spinner() { :; }
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_cloud_storage
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Dropbox cache"* ]]
|
||||
[[ "$output" == *"Google Drive cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_virtualization_tools hits cache paths" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
stop_section_spinner() { :; }
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_virtualization_tools
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"VMware Fusion cache"* ]]
|
||||
[[ "$output" == *"Parallels cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_email_clients calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_email_clients
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Spark cache"* ]]
|
||||
[[ "$output" == *"Airmail cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_note_apps calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_note_apps
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Notion cache"* ]]
|
||||
[[ "$output" == *"Obsidian cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_task_apps calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_task_apps
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Todoist cache"* ]]
|
||||
[[ "$output" == *"Any.do cache"* ]]
|
||||
}
|
||||
|
||||
@test "scan_external_volumes skips when no volumes" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
run_with_timeout() { return 1; }
|
||||
scan_external_volumes
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
@@ -7,7 +7,7 @@ setup_file() {
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-clean-extras-more.XXXXXX")"
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-clean-extras.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
@@ -20,6 +20,87 @@ teardown_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
@test "clean_cloud_storage calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
stop_section_spinner() { :; }
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_cloud_storage
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Dropbox cache"* ]]
|
||||
[[ "$output" == *"Google Drive cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_virtualization_tools hits cache paths" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
stop_section_spinner() { :; }
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_virtualization_tools
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"VMware Fusion cache"* ]]
|
||||
[[ "$output" == *"Parallels cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_email_clients calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_email_clients
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Spark cache"* ]]
|
||||
[[ "$output" == *"Airmail cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_note_apps calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_note_apps
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Notion cache"* ]]
|
||||
[[ "$output" == *"Obsidian cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_task_apps calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/app_caches.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_task_apps
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Todoist cache"* ]]
|
||||
[[ "$output" == *"Any.do cache"* ]]
|
||||
}
|
||||
|
||||
@test "scan_external_volumes skips when no volumes" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
run_with_timeout() { return 1; }
|
||||
scan_external_volumes
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "clean_video_tools calls expected caches" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
@@ -234,16 +234,22 @@ source "$PROJECT_ROOT/lib/clean/brew.sh"
|
||||
mkdir -p "$HOME/.cache/mole"
|
||||
rm -f "$HOME/.cache/mole/brew_last_cleanup"
|
||||
|
||||
mkdir -p "$HOME/Library/Caches/Homebrew"
|
||||
dd if=/dev/zero of="$HOME/Library/Caches/Homebrew/test.tar.gz" bs=1024 count=51200 2>/dev/null
|
||||
start_inline_spinner(){ :; }
|
||||
stop_inline_spinner(){ :; }
|
||||
note_activity(){ :; }
|
||||
run_with_timeout() {
|
||||
local duration="$1"
|
||||
shift
|
||||
if [[ "$1" == "du" ]]; then
|
||||
echo "51201 $3"
|
||||
return 0
|
||||
fi
|
||||
"$@"
|
||||
}
|
||||
|
||||
MO_BREW_TIMEOUT=2
|
||||
MO_BREW_TIMEOUT=2
|
||||
|
||||
start_inline_spinner(){ :; }
|
||||
stop_inline_spinner(){ :; }
|
||||
note_activity(){ :; }
|
||||
|
||||
brew() {
|
||||
brew() {
|
||||
case "$1" in
|
||||
cleanup)
|
||||
echo "Removing: package"
|
||||
@@ -259,9 +265,7 @@ brew() {
|
||||
esac
|
||||
}
|
||||
|
||||
clean_homebrew
|
||||
|
||||
rm -rf "$HOME/Library/Caches/Homebrew"
|
||||
clean_homebrew
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -20,6 +20,73 @@ teardown_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
@test "needs_permissions_repair returns true when home not writable" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" USER="tester" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
stat() { echo "root"; }
|
||||
export -f stat
|
||||
if needs_permissions_repair; then
|
||||
echo "needs"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"needs"* ]]
|
||||
}
|
||||
|
||||
@test "has_bluetooth_hid_connected detects HID" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
system_profiler() {
|
||||
cat << 'OUT'
|
||||
Bluetooth:
|
||||
Apple Magic Mouse:
|
||||
Connected: Yes
|
||||
Type: Mouse
|
||||
OUT
|
||||
}
|
||||
export -f system_profiler
|
||||
if has_bluetooth_hid_connected; then
|
||||
echo "hid"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"hid"* ]]
|
||||
}
|
||||
|
||||
@test "is_ac_power detects AC power" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
pmset() { echo "AC Power"; }
|
||||
export -f pmset
|
||||
if is_ac_power; then
|
||||
echo "ac"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"ac"* ]]
|
||||
}
|
||||
|
||||
@test "is_memory_pressure_high detects warning" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
memory_pressure() { echo "warning"; }
|
||||
export -f memory_pressure
|
||||
if is_memory_pressure_high; then
|
||||
echo "high"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"high"* ]]
|
||||
}
|
||||
|
||||
@test "opt_system_maintenance reports DNS and Spotlight" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
@@ -1,125 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-optimize-core.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "needs_permissions_repair returns true when home not writable" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" USER="tester" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
stat() { echo "root"; }
|
||||
export -f stat
|
||||
if needs_permissions_repair; then
|
||||
echo "needs"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"needs"* ]]
|
||||
}
|
||||
|
||||
@test "has_bluetooth_hid_connected detects HID" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
system_profiler() {
|
||||
cat << 'OUT'
|
||||
Bluetooth:
|
||||
Apple Magic Mouse:
|
||||
Connected: Yes
|
||||
Type: Mouse
|
||||
OUT
|
||||
}
|
||||
export -f system_profiler
|
||||
if has_bluetooth_hid_connected; then
|
||||
echo "hid"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"hid"* ]]
|
||||
}
|
||||
|
||||
@test "is_ac_power detects AC power" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
pmset() { echo "AC Power"; }
|
||||
export -f pmset
|
||||
if is_ac_power; then
|
||||
echo "ac"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"ac"* ]]
|
||||
}
|
||||
|
||||
@test "is_memory_pressure_high detects warning" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
memory_pressure() { echo "warning"; }
|
||||
export -f memory_pressure
|
||||
if is_memory_pressure_high; then
|
||||
echo "high"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"high"* ]]
|
||||
}
|
||||
|
||||
@test "opt_launch_services_rebuild handles missing lsregister" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
opt_launch_services_rebuild
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"LaunchServices repaired"* ]]
|
||||
}
|
||||
|
||||
@test "opt_msg uses dry-run output" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
opt_msg "dry"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"dry"* ]]
|
||||
}
|
||||
|
||||
@test "run_launchctl_unload skips in dry-run" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
launchctl() { echo "called"; }
|
||||
export -f launchctl
|
||||
run_launchctl_unload "/tmp/test.plist" false
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != *"called"* ]]
|
||||
}
|
||||
Reference in New Issue
Block a user