nip/tests/test_graft_coordinator.nim

417 lines
12 KiB
Nim

## test_graft_coordinator.nim
## Unit tests for GraftCoordinator
## Tests package spec parsing, source detection, and adapter selection
import std/[unittest, os, json, tables, strutils]
import ../src/nimpak/graft_coordinator
import ../src/nimpak/install_manager
import ../src/nimpak/config
suite "GraftCoordinator - Package Spec Parsing":
test "Parse package spec - simple name":
let (source, name) = parsePackageSpec("firefox")
check source == Auto
check name == "firefox"
test "Parse package spec - nix source":
let (source, name) = parsePackageSpec("nix:firefox")
check source == Nix
check name == "firefox"
test "Parse package spec - pkgsrc source":
let (source, name) = parsePackageSpec("pkgsrc:vim")
check source == PKGSRC
check name == "vim"
test "Parse package spec - pacman source":
let (source, name) = parsePackageSpec("pacman:htop")
check source == Pacman
check name == "htop"
test "Parse package spec - uppercase source":
let (source, name) = parsePackageSpec("NIX:firefox")
check source == Nix
check name == "firefox"
test "Parse package spec - mixed case source":
let (source, name) = parsePackageSpec("PkgSrc:vim")
check source == PKGSRC
check name == "vim"
test "Parse package spec - package name with hyphens":
let (source, name) = parsePackageSpec("nix:my-package-name")
check source == Nix
check name == "my-package-name"
test "Parse package spec - package name with underscores":
let (source, name) = parsePackageSpec("pkgsrc:my_package_name")
check source == PKGSRC
check name == "my_package_name"
test "Parse package spec - package name with numbers":
let (source, name) = parsePackageSpec("nix:package123")
check source == Nix
check name == "package123"
test "Parse package spec - invalid source defaults to auto":
let (source, name) = parsePackageSpec("invalid:firefox")
check source == Auto
check name == "firefox"
test "Parse package spec - multiple colons uses first":
let (source, name) = parsePackageSpec("nix:package:with:colons")
check source == Nix
check name == "package:with:colons"
test "Parse package spec - empty name":
let (source, name) = parsePackageSpec("nix:")
check source == Nix
check name == ""
test "Parse package spec - colon only":
let (source, name) = parsePackageSpec(":")
check source == Auto
check name == ""
suite "GraftCoordinator - Source Detection":
setup:
let testCacheDir = getTempDir() / "nip-graft-coord-test"
let testProgramsDir = getTempDir() / "Programs-coord-test"
let testLinksDir = getTempDir() / "System-coord-test" / "Links"
# Clean up from previous runs
if dirExists(testCacheDir):
removeDir(testCacheDir)
if dirExists(testProgramsDir):
removeDir(testProgramsDir)
if dirExists(testLinksDir):
removeDir(testLinksDir)
# Create test directories
createDir(testCacheDir)
createDir(testProgramsDir)
createDir(testLinksDir / "Executables")
createDir(testLinksDir / "Libraries")
let installConfig = InstallConfig(
programsDir: testProgramsDir,
linksDir: testLinksDir,
cacheDir: testCacheDir,
dbFile: testCacheDir / "test.db",
autoSymlink: true,
checkConflicts: false,
verbose: false
)
let coordinator = newGraftCoordinator(installConfig, false)
test "Detect source - returns valid source":
# Test with aage that might exist
let source = coordinator.detectSource("hello")
# Should return one of the valid sources
check source in [Nix, PKGSRC, Pacman]
test "Detect source - consistency":
# Same package should return same source
let source1 = coordinator.detectSource("test-package")
let source2 = coordinator.detectSource("test-package")
check source1 == source2
test "Detect source - different packages":
# Different packages might have different sources
let source1 = coordinator.detectSource("package-a")
let source2 = coordinator.detectSource("package-b")
# Both should be valid sources
check source1 in [Nix, PKGSRC, Pacman]
check source2 in [Nix, PKGSRC, Pacman]
test "Detect source - priority order":
# Detection should follow priority: Nix > PKGSRC > Pacman
# If Nix is available, it should be preferred
let source = coordinator.detectSource("common-package")
# Should return a valid source
check source in [Nix, PKGSRC, Pacman]
test "Detect source - empty package name":
# Should handle empty package name gracefully
let source = coordinator.detectSource("")
# Should still return a valid source (defaults to Nix)
check source in [Nix, PKGSRC, Pacman]
test "Detect source - package with special characters":
let source = coordinator.detectSource("package-with-hyphens")
check source in [Nix, PKGSRC, Pacman]
teardown:
# Clean up test directories
try:
if dirExists(testCacheDir):
removeDir(testCacheDir)
if dirExists(testProgramsDir):
removeDir(testProgramsDir)
if dirExists(testLinksDir):
removeDir(testLinksDir)
except:
discard # Cleanup failures are not critical
suite "GraftCoordinator - Adapter Selection":
setup:
let testCacheDir = getTempDir() / "nip-graft-adapt-test"
let testProgramsDir = getTempDir() / "Programs-adapt-test"
let testLinksDir = getTempDir() / "System-adapt-test" / "Links"
# Clean up from previous runs
if dirExists(testCacheDir):
removeDir(testCacheDir)
if dirExists(testProgramsDir):
removeDir(testProgramsDir)
if dirExists(testLinksDir):
removeDir(testLinksDir)
# Create test directories
createDir(testCacheDir)
createDir(testProgramsDir)
createDir(testLinksDir / "Executables")
createDir(testLinksDir / "Libraries")
let installConfig = InstallConfig(
programsDir: testProgramsDir,
linksDir: testLinksDir,
cacheDir: testCacheDir,
dbFile: testCacheDir / "test.db",
autoSymlink: true,
checkConflicts: false,
verbose: false
)
let coordinator = newGraftCoordinator(installConfig, false)
test "Coordinator has Nix adapter":
check coordinator.nixAdapter != nil
test "Coordinator has PKGSRC adapter":
check coordinator.pkgsrcAdapter != nil
test "Graft with Auto source - uses detection":
# This will fail because we don't have actual packages
# But it tests that the auto-detection path is taken
let result = coordinator.graft("nonexistent-package", Auto)
# Should attempt to graft (will fail, but that's expected)
check result.packageName == "nonexistent-package"
check result.source in ["nix", "pkgsrc", "pacman"]
test "Graft with Nix source - uses Nix adapter":
let result = coordinator.graft("nonexistent-package", Nix)
check result.packageName == "nonexistent-package"
check result.source == "nix"
# Will fail because package doesn't exist
check result.success == false
test "Graft with PKGSRC source - uses PKGSRC adapter":
let result = coordinator.graft("nonexistent-package", PKGSRC)
check result.packageName == "nonexistent-package"
check result.source == "pkgsrc"
# Will fail because package doesn't exist
check result.success == false
test "Graft with Pacman source - not implemented":
let result = coordinator.graft("nonexistent-package", Pacman)
check result.packageName == "nonexistent-package"
check result.source == "pacman"
check result.success == false
check result.errors.len > 0
check "not yet implemented" in result.errors[0].toLower()
test "Parse and graft - nix:package":
let (source, name) = parsePackageSpec("nix:test-package")
let result = coordinator.graft(name, source)
check result.packageName == "test-package"
check result.source == "nix"
test "Parse and graft - pkgsrc:package":
let (source, name) = parsePackageSpec("pkgsrc:test-package")
let result = coordinator.graft(name, source)
check result.packageName == "test-package"
check result.source == "pkgsrc"
test "Parse and graft - auto detection":
let (source, name) = parsePackageSpec("test-package")
let result = coordinator.graft(name, source)
check result.packageName == "test-package"
check result.source in ["nix", "pkgsrc", "pacman"]
test "Coordinator verbose mode":
let verboseConfig = InstallConfig(
programsDir: testProgramsDir,
linksDir: testLinksDir,
cacheDir: testCacheDir,
dbFile: testCacheDir / "test-verbose.db",
autoSymlink: true,
checkConflicts: false,
verbose: true
)
let verboseCoordinator = newGraftCoordinator(verboseConfig, true)
check verboseCoordinator.verbose == true
test "List installed packages - empty":
let packages = coordinator.list()
# Should return empty list for new coordinator
check packages.len == 0
test "List installed packages - filtered by source":
let nixPackages = coordinator.list("nix")
let pkgsrcPackages = coordinator.list("pkgsrc")
# Should return empty lists for new coordinator
check nixPackages.len == 0
check pkgsrcPackages.len == 0
test "Check if package is installed - not installed":
let installed = coordinator.isInstalled("nonexistent-package")
check installed == false
test "Get status - returns JSON":
let status = coordinator.status()
check status != nil
check status.kind == JObject
teardown:
# Clean up test directories
try:
if dirExists(testCacheDir):
removeDir(testCacheDir)
if dirExists(testProgramsDir):
removeDir(testProgramsDir)
if dirExists(testLinksDir):
removeDir(testLinksDir)
except:
discard # Cleanup failures are not critical
suite "GraftCoordinator - Integration":
setup:
let testCacheDir = getTempDir() / "nip-graft-integ-test"
let testProgramsDir = getTempDir() / "Programs-integ-test"
let testLinksDir = getTempDir() / "System-integ-test" / "Links"
# Clean up from previous runs
if dirExists(testCacheDir):
removeDir(testCacheDir)
if dirExists(testProgramsDir):
removeDir(testProgramsDir)
if dirExists(testLinksDir):
removeDir(testLinksDir)
# Create test directories
createDir(testCacheDir)
createDir(testProgramsDir)
createDir(testLinksDir / "Executables")
createDir(testLinksDir / "Libraries")
let installConfig = InstallConfig(
programsDir: testProgramsDir,
linksDir: testLinksDir,
cacheDir: testCacheDir,
dbFile: testCacheDir / "test.db",
autoSymlink: true,
checkConflicts: false,
verbose: false
)
let coordinator = newGraftCoordinator(installConfig, false)
test "Full workflow - parse, detect, graft":
# Parse package spec
let (source, name) = parsePackageSpec("nix:test-package")
check source == Nix
check name == "test-package"
# Detect source (should use parsed source)
let detectedSource = if source == Auto:
coordinator.detectSource(name)
else:
source
check detectedSource == Nix
# Attempt to graft (will fail, but tests the flow)
let result = coordinator.graft(name, detectedSource)
check result.packageName == "test-package"
check result.source == "nix"
test "Full workflow - auto detection":
let (source, name) = parsePackageSpec("test-package")
check source == Auto
# Auto-detect source
let detectedSource = coordinator.detectSource(name)
check detectedSource in [Nix, PKGSRC, Pacman]
# Graft with detected source
let result = coordinator.graft(name, detectedSource)
check result.packageName == "test-package"
test "Error handling - invalid package":
let result = coordinator.graft("", Nix)
# Should handle empty package name
check result.success == false
test "Error handling - nonexistent package":
let result = coordinator.graft("definitely-does-not-exist-12345", Nix)
# Should fail gracefully
check result.success == false
check result.errors.len > 0
teardown:
# Clean up test directories
try:
if dirExists(testCacheDir):
removeDir(testCacheDir)
if dirExists(testProgramsDir):
removeDir(testProgramsDir)
if dirExists(testLinksDir):
removeDir(testLinksDir)
except:
discard # Cleanup failures are not critical