417 lines
12 KiB
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
|