359 lines
13 KiB
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"
|