nip/tests/test_errors.nim

143 lines
4.7 KiB
Nim

## Test suite for comprehensive error handling
## Task 37: Implement comprehensive error handling
import unittest, strutils, sequtils
import ../src/nimpak/errors
import ../src/nip/types
suite "Comprehensive Error Handling Tests":
test "Error formatting":
let err = packageNotFoundError("nginx")
let formatted = formatError(err)
check formatted.contains("PackageNotFound")
check formatted.contains("nginx")
check formatted.contains("Suggestions")
check formatted.contains("typos")
test "Checksum mismatch error":
let err = checksumMismatchError(
"/var/cache/nip/pkg.tar",
"abc123def456",
"xyz789ghi012"
)
check err.code == ChecksumMismatch
check err.msg.contains("Checksum verification failed")
check err.context.contains("abc123")
check err.suggestions.len > 0
test "Permission denied error":
let err = permissionDeniedError("/usr/lib/nip", "write")
check err.code == PermissionDenied
check err.msg.contains("write")
check err.suggestions.len >= 2
test "Network error handling":
let err = networkError("https://repo.nexusos.io/index", "Connection refused")
check err.code == NetworkError
check err.context.contains("Connection refused")
test "Download failed with HTTP code":
let err = downloadFailedError("https://repo.nexusos.io/pkg.tar", 404)
check err.code == DownloadFailed
check err.context.contains("404")
test "Elevation required error":
let err = elevationRequiredError("system package installation")
check err.code == ElevationRequired
check err.msg.contains("Elevated privileges")
check err.suggestions.anyIt(it.contains("sudo"))
test "Signature invalid error":
let err = signatureInvalidError("compromised-pkg", "0xDEADBEEF")
check err.code == SignatureInvalid
check err.context.contains("0xDEADBEEF")
test "GC failed error":
let err = gcFailedError("Objects in use")
check err.code == GarbageCollectionFailed
check err.suggestions.anyIt(it.contains("gc"))
test "Reference integrity error":
let err = referenceIntegrityError("xxh3-abc123def456", 5, 3)
check err.code == ReferenceIntegrityError
check err.context.contains("Expected: 5")
check err.context.contains("Actual: 3")
test "Transaction failed error":
let err = transactionFailedError("tx-12345", "file_copy")
check err.code == TransactionFailed
check err.msg.contains("tx-12345")
test "Error recoverability check":
let networkErr = networkError("http://example.com", "timeout")
let sigErr = signatureInvalidError("bad-pkg")
check isRecoverable(networkErr)
check not isRecoverable(sigErr)
test "Recovery strategy suggestion":
let networkErr = networkError("http://example.com", "timeout")
let permErr = permissionDeniedError("/root", "read")
let sigErr = signatureInvalidError("bad-pkg")
check suggestRecovery(networkErr) == Retry
check suggestRecovery(permErr) == Manual
check suggestRecovery(sigErr) == Abort
test "Error wrapping":
let originalErr = networkError("http://repo.io", "DNS failure")
let wrappedErr = wrapError(originalErr, DownloadFailed, "Package download failed")
check wrappedErr.code == DownloadFailed
# wrapError puts "Caused by: <original msg>" in context
check wrappedErr.context.contains("Caused by")
check wrappedErr.context.contains("http://repo.io")
test "Error chaining":
let err1 = networkError("http://repo.io", "timeout")
let err2 = downloadFailedError("http://repo.io/pkg.tar")
let err3 = packageNotFoundError("nginx")
let chainedMsg = chain(err1, err2, err3)
check chainedMsg.contains("Error chain")
check chainedMsg.contains("NetworkError")
check chainedMsg.contains("DownloadFailed")
check chainedMsg.contains("PackageNotFound")
test "All error codes have factory functions coverage":
# Verify key error codes have dedicated factory functions
let errors = @[
packageNotFoundError("test"),
checksumMismatchError("file", "a", "b"),
permissionDeniedError("/path", "op"),
elevationRequiredError("op"),
networkError("url", "detail"),
downloadFailedError("url"),
repositoryUnavailableError("repo"),
timeoutError("op", 30),
buildFailedError("pkg", "stage"),
missingDependencyError("pkg", "dep"),
signatureInvalidError("pkg"),
objectNotFoundError("hash"),
gcFailedError("reason"),
transactionFailedError("tx", "op"),
rollbackFailedError("tx", "reason")
]
check errors.len >= 15
for err in errors:
check err.msg.len > 0
check err.suggestions.len > 0