nip/tests/test_variant_paths.nim

359 lines
13 KiB
Nim

## test_variant_paths.nim
## Tests for variant path management
## Ensures proper path generation, validation, and parsing
import std/[unittest, strutils]
import ../src/nimpak/variant_paths
import ../src/nimpak/variant_types
suite "Path Generation Tests":
test "Generate basic variant path":
let path = generateVariantPath("nginx", "1.28.0", "blake2b-abc123def456")
check path == "/Programs/nginx/1.28.0-blake2b-abc123def456"
test "Generate path with different package":
let path = generateVariantPath("firefox", "120.0", "blake2b-xyz789")
check path == "/Programs/firefox/120.0-blake2b-xyz789"
test "Generate path with complex version":
let path = generateVariantPath("python", "3.11.5-rc1", "blake2b-aaa111")
check path == "/Programs/python/3.11.5-rc1-blake2b-aaa111"
test "Empty package name raises error":
expect(ValueError):
discard generateVariantPath("", "1.0.0", "blake2b-abc123")
test "Empty version raises error":
expect(ValueError):
discard generateVariantPath("nginx", "", "blake2b-abc123")
test "Empty fingerprint raises error":
expect(ValueError):
discard generateVariantPath("nginx", "1.0.0", "")
suite "Path Validation Tests":
test "Valid variant path passes validation":
check validateVariantPath("/Programs/nginx/1.28.0-blake2b-abc123def456") == true
test "Valid path with trailing slash":
check validateVariantPath("/Programs/nginx/1.28.0-blake2b-abc123def456/") == true
test "Invalid path without Programs":
check validateVariantPath("/usr/local/nginx/1.28.0-blake2b-abc123") == false
test "Invalid path without fingerprint":
check validateVariantPath("/Programs/nginx/1.28.0") == false
test "Invalid path with wrong fingerprint format":
check validateVariantPath("/Programs/nginx/1.28.0-abc123") == false
test "Empty path is invalid":
check validateVariantPath("") == false
test "Path with too few components is invalid":
check validateVariantPath("/Programs/nginx") == false
test "isValidVariantPath alias works":
check isValidVariantPath("/Programs/nginx/1.28.0-blake2b-abc123") == true
suite "Path Parsing Tests":
test "Extract package name from path":
let name = extractPackageNameFromPath("/Programs/nginx/1.28.0-blake2b-abc123/")
check name == "nginx"
test "Extract version from path":
let version = extractVersionFromPath("/Programs/nginx/1.28.0-blake2b-abc123/")
check version == "1.28.0"
test "Extract fingerprint from path":
let fp = extractFingerprintFromPath("/Programs/nginx/1.28.0-blake2b-abc123def456/")
check fp == "blake2b-abc123def456"
test "Extract from complex version":
let version = extractVersionFromPath("/Programs/python/3.11.5-rc1-blake2b-xyz789/")
check version == "3.11.5-rc1"
test "Extract from path without trailing slash":
let name = extractPackageNameFromPath("/Programs/firefox/120.0-blake2b-aaa111")
check name == "firefox"
test "Extract from invalid path raises error":
expect(ValueError):
discard extractPackageNameFromPath("/invalid/path")
suite "Path Query Tests":
test "Get variant base path":
let basePath = getVariantBasePath("nginx")
check basePath == "/Programs/nginx"
test "Get variant bin path":
let binPath = getVariantBinPath("/Programs/nginx/1.28.0-blake2b-abc123/")
check binPath == "/Programs/nginx/1.28.0-blake2b-abc123/bin"
test "Get variant lib path":
let libPath = getVariantLibPath("/Programs/nginx/1.28.0-blake2b-abc123/")
check libPath == "/Programs/nginx/1.28.0-blake2b-abc123/lib"
test "Get variant include path":
let incPath = getVariantIncludePath("/Programs/nginx/1.28.0-blake2b-abc123/")
check incPath == "/Programs/nginx/1.28.0-blake2b-abc123/include"
test "Get variant share path":
let sharePath = getVariantSharePath("/Programs/nginx/1.28.0-blake2b-abc123/")
check sharePath == "/Programs/nginx/1.28.0-blake2b-abc123/share"
suite "Path Comparison Tests":
test "Same variant paths are equal":
let path1 = "/Programs/nginx/1.28.0-blake2b-abc123/"
let path2 = "/Programs/nginx/1.28.0-blake2b-abc123/"
check isSameVariant(path1, path2) == true
test "Different fingerprints are not equal":
let path1 = "/Programs/nginx/1.28.0-blake2b-abc123/"
let path2 = "/Programs/nginx/1.28.0-blake2b-def456/"
check isSameVariant(path1, path2) == false
test "Compare variant paths by version":
let path1 = "/Programs/nginx/1.27.0-blake2b-abc123/"
let path2 = "/Programs/nginx/1.28.0-blake2b-abc123/"
check compareVariantPaths(path1, path2) < 0
test "Compare variant paths by fingerprint":
let path1 = "/Programs/nginx/1.28.0-blake2b-aaa111/"
let path2 = "/Programs/nginx/1.28.0-blake2b-bbb222/"
check compareVariantPaths(path1, path2) < 0
test "Compare identical paths":
let path = "/Programs/nginx/1.28.0-blake2b-abc123/"
check compareVariantPaths(path, path) == 0
suite "Path Utilities Tests":
test "Normalize path adds trailing slash":
let normalized = normalizeVariantPath("/Programs/nginx/1.28.0-blake2b-abc123")
check normalized.endsWith("/")
test "Normalize path adds leading slash":
let normalized = normalizeVariantPath("Programs/nginx/1.28.0-blake2b-abc123")
check normalized.startsWith("/")
test "Normalize already normalized path":
let path = "/Programs/nginx/1.28.0-blake2b-abc123/"
let normalized = normalizeVariantPath(path)
check normalized == path
suite "VariantPathInfo Tests":
test "Parse valid variant path":
let info = parseVariantPath("/Programs/nginx/1.28.0-blake2b-abc123def456/")
check info.isValid == true
check info.packageName == "nginx"
check info.version == "1.28.0"
check info.fingerprint == "blake2b-abc123def456"
test "Parse invalid variant path":
let info = parseVariantPath("/invalid/path")
check info.isValid == false
test "String representation of valid path info":
let info = parseVariantPath("/Programs/nginx/1.28.0-blake2b-abc123/")
let str = $info
check "nginx" in str
check "1.28.0" in str
test "String representation of invalid path info":
let info = parseVariantPath("/invalid/path")
let str = $info
check "invalid" in str
suite "Path Conflict Detection Tests":
test "No conflicts in different packages":
let paths = @[
"/Programs/nginx/1.28.0-blake2b-abc123/",
"/Programs/firefox/120.0-blake2b-def456/"
]
let conflicts = detectPathConflicts(paths)
check conflicts.len == 0
test "No conflicts in different versions":
let paths = @[
"/Programs/nginx/1.27.0-blake2b-abc123/",
"/Programs/nginx/1.28.0-blake2b-abc123/"
]
let conflicts = detectPathConflicts(paths)
check conflicts.len == 0
test "Detect conflict in same package/version with different fingerprints":
let paths = @[
"/Programs/nginx/1.28.0-blake2b-abc123/",
"/Programs/nginx/1.28.0-blake2b-def456/"
]
let conflicts = detectPathConflicts(paths)
check conflicts.len == 1
test "No conflicts with same fingerprint":
let paths = @[
"/Programs/nginx/1.28.0-blake2b-abc123/",
"/Programs/nginx/1.28.0-blake2b-abc123/"
]
let conflicts = detectPathConflicts(paths)
check conflicts.len == 0
suite "Edge Cases Tests":
test "Package name with hyphens":
let path = generateVariantPath("my-package", "1.0.0", "blake2b-abc123")
check path == "/Programs/my-package/1.0.0-blake2b-abc123"
let name = extractPackageNameFromPath(path)
check name == "my-package"
test "Version with multiple hyphens":
let path = generateVariantPath("pkg", "1.0.0-rc1-beta2", "blake2b-abc123")
let version = extractVersionFromPath(path)
check version == "1.0.0-rc1-beta2"
test "Long fingerprint":
let longFp = "blake2b-" & "a".repeat(60)
let path = generateVariantPath("nginx", "1.0.0", longFp)
let extracted = extractFingerprintFromPath(path)
check extracted == longFp
test "Package name with numbers":
let path = generateVariantPath("python3", "3.11.5", "blake2b-abc123")
check path == "/Programs/python3/3.11.5-blake2b-abc123"
test "Version with dots and numbers":
let path = generateVariantPath("pkg", "2.0.1.5", "blake2b-xyz789")
let version = extractVersionFromPath(path)
check version == "2.0.1.5"
suite "Real-World Path Tests":
test "Nginx variant path":
let path = generateVariantPath("nginx", "1.28.0", "blake2b-89ab4c5d")
check validateVariantPath(path) == true
check extractPackageNameFromPath(path) == "nginx"
check extractVersionFromPath(path) == "1.28.0"
test "Firefox variant path":
let path = generateVariantPath("firefox", "120.0", "blake2b-def67890")
check validateVariantPath(path) == true
check extractPackageNameFromPath(path) == "firefox"
test "Python variant path":
let path = generateVariantPath("python", "3.11.5", "blake2b-abc12345")
check validateVariantPath(path) == true
check extractVersionFromPath(path) == "3.11.5"
test "Complex package with all features":
let path = generateVariantPath("my-app", "2.1.0-rc1", "blake2b-fedcba98")
check validateVariantPath(path) == true
let info = parseVariantPath(path)
check info.isValid == true
check info.packageName == "my-app"
check info.version == "2.1.0-rc1"
check info.fingerprint == "blake2b-fedcba98"
check getVariantBinPath(path) == "/Programs/my-app/2.1.0-rc1-blake2b-fedcba98/bin"
when isMainModule:
echo "Running variant paths tests..."
suite "Hash Algorithm Compatibility Tests":
test "Validate blake2b path":
check validateVariantPath("/Programs/nginx/1.28.0-blake2b-abc123/") == true
test "Validate blake3 path (future compatibility)":
check validateVariantPath("/Programs/nginx/1.28.0-blake3-xyz789/") == true
test "Detect blake2b algorithm":
let algo = detectHashAlgorithm("/Programs/nginx/1.28.0-blake2b-abc123/")
check algo == "blake2b"
test "Detect blake3 algorithm":
let algo = detectHashAlgorithm("/Programs/nginx/1.28.0-blake3-xyz789/")
check algo == "blake3"
test "Extract version from blake3 path":
let version = extractVersionFromPath("/Programs/nginx/1.28.0-blake3-xyz789/")
check version == "1.28.0"
test "Extract fingerprint from blake3 path":
let fp = extractFingerprintFromPath("/Programs/nginx/1.28.0-blake3-xyz789abc/")
check fp == "blake3-xyz789abc"
test "Parse blake3 variant path":
let info = parseVariantPath("/Programs/firefox/120.0-blake3-fedcba98/")
check info.isValid == true
check info.packageName == "firefox"
check info.version == "120.0"
check info.fingerprint == "blake3-fedcba98"
test "Blake2b and blake3 variants can coexist":
let paths = @[
"/Programs/nginx/1.28.0-blake2b-abc123/",
"/Programs/nginx/1.28.0-blake3-xyz789/"
]
# These are different fingerprints (different algorithms), detected as different variants
# The conflict detector will flag them as same version but different fingerprints
# This is actually correct - they ARE different variants that can coexist
let conflicts = detectPathConflicts(paths)
check conflicts.len == 1 # Detected as "conflict" but both are valid
test "Compare blake2b and blake3 paths":
let path1 = "/Programs/nginx/1.28.0-blake2b-abc123/"
let path2 = "/Programs/nginx/1.28.0-blake3-xyz789/"
# Different fingerprints
check isSameVariant(path1, path2) == false
test "Invalid hash algorithm rejected":
check validateVariantPath("/Programs/nginx/1.28.0-md5-abc123/") == false
check validateVariantPath("/Programs/nginx/1.28.0-sha256-abc123/") == false
suite "Migration Scenario Tests":
test "Old blake2b packages remain valid after blake3 introduction":
# Simulate existing blake2b packages
let oldPath = "/Programs/nginx/1.27.0-blake2b-old123/"
check validateVariantPath(oldPath) == true
check detectHashAlgorithm(oldPath) == "blake2b"
# New blake3 packages also valid
let newPath = "/Programs/nginx/1.28.0-blake3-new456/"
check validateVariantPath(newPath) == true
check detectHashAlgorithm(newPath) == "blake3"
test "Mixed hash algorithms in variant listing":
# Both old and new packages can be listed
let paths = @[
"/Programs/nginx/1.27.0-blake2b-abc123/",
"/Programs/nginx/1.28.0-blake3-def456/",
"/Programs/nginx/1.29.0-blake3-ghi789/"
]
for path in paths:
check validateVariantPath(path) == true
test "Path operations work regardless of hash algorithm":
let blake2Path = "/Programs/nginx/1.0.0-blake2b-aaa111/"
let blake3Path = "/Programs/nginx/2.0.0-blake3-bbb222/"
# All operations should work on both
check extractPackageNameFromPath(blake2Path) == "nginx"
check extractPackageNameFromPath(blake3Path) == "nginx"
check getVariantBinPath(blake2Path) == "/Programs/nginx/1.0.0-blake2b-aaa111/bin"
check getVariantBinPath(blake3Path) == "/Programs/nginx/2.0.0-blake3-bbb222/bin"