Files
wehub-resource-sync 36b3af2e3d
PR Check / Code Quality: Format (push) Failing after 1s
PR Check / Code Quality: Lint (darwin) (push) Failing after 0s
PR Check / Code Quality: Lint (freebsd) (push) Failing after 1s
PR Check / Code Quality: Lint (windows) (push) Failing after 1s
PR Check / Code Quality: Lint (linux) (push) Failing after 1s
PR Check / Security: Vulnerability Scan (push) Failing after 0s
Update Documentation / update-docs (push) Failing after 2s
PR Check / Code Quality: Vendor (push) Failing after 1s
PR Check / Code Quality: Coverage (push) Failing after 0s
PR Check / Tests: Unit (macos-latest) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04-arm) (push) Has been cancelled
PR Check / Tests: Unit (windows-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:06 +08:00

60 lines
1.9 KiB
Go

package app
import (
"errors"
"testing"
)
// The mappings here drive script and CI integrations, so any
// regression in classification is a breaking change for users.
func TestClassifyError(t *testing.T) {
t.Parallel()
tests := []struct {
name string
msg string
want int
}{
{"permission denied → 3", "open /proc/1/environ: permission denied", ExitPermission},
{"operation not permitted → 3", "kill: operation not permitted", ExitPermission},
{"insufficient permissions → 3", "insufficient permissions to read process info", ExitPermission},
{"no matching → 2", "no matching process found", ExitNotFound},
{"no running process → 2", "no running process with that name", ExitNotFound},
{"not found → 2", "process 999999 not found", ExitNotFound},
{"no process → 2", "no process listening on port 80", ExitNotFound},
{"invalid → 4", "invalid pid", ExitInvalidInput},
{"must specify → 4", "must specify --pid, --port, --file, or a process name", ExitInvalidInput},
{"unknown error → internal", "something exploded", ExitInternalError},
{"empty message → internal", "", ExitInternalError},
{"case-insensitive (uppercase)", "PERMISSION DENIED", ExitPermission},
{"case-insensitive (mixed)", "No Matching Process", ExitNotFound},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := classifyError(errors.New(tt.msg))
if got != tt.want {
t.Errorf("classifyError(%q) = %d, want %d", tt.msg, got, tt.want)
}
})
}
}
// An internal error must be distinguishable from "process has warnings" so
// scripts gating on exit 1 don't conflate the two.
func TestExitCodesDistinct(t *testing.T) {
t.Parallel()
if ExitInternalError == ExitWarnings {
t.Errorf("ExitInternalError (%d) must differ from ExitWarnings (%d)", ExitInternalError, ExitWarnings)
}
if ExitInternalError != 5 {
t.Errorf("ExitInternalError = %d, want 5 (documented)", ExitInternalError)
}
}