171 lines
6.0 KiB
Nim
171 lines
6.0 KiB
Nim
# tests/test_dependency.nim
|
|
# Unit tests for dependency resolution system
|
|
|
|
import unittest, tables, sets
|
|
import ../src/nimpak/[dependency, types, errors]
|
|
|
|
suite "Dependency Resolution Tests":
|
|
|
|
setup:
|
|
# Create test fragments
|
|
let pkgA = PackageId(name: "pkgA", version: "1.0", stream: Stable)
|
|
let pkgB = PackageId(name: "pkgB", version: "1.0", stream: Stable)
|
|
let pkgC = PackageId(name: "pkgC", version: "1.0", stream: Stable)
|
|
let pkgD = PackageId(name: "pkgD", version: "1.0", stream: Stable)
|
|
|
|
let fragmentA = Fragment(
|
|
id: pkgA,
|
|
dependencies: @[pkgB, pkgC],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Test package A"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
let fragmentB = Fragment(
|
|
id: pkgB,
|
|
dependencies: @[pkgD],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Test package B"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
let fragmentC = Fragment(
|
|
id: pkgC,
|
|
dependencies: @[],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Test package C"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
let fragmentD = Fragment(
|
|
id: pkgD,
|
|
dependencies: @[],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Test package D"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
var fragments = initTable[PackageId, Fragment]()
|
|
fragments[pkgA] = fragmentA
|
|
fragments[pkgB] = fragmentB
|
|
fragments[pkgC] = fragmentC
|
|
fragments[pkgD] = fragmentD
|
|
|
|
test "Simple dependency resolution":
|
|
let result = resolveDependencies(pkgA, fragments)
|
|
check result.isOk
|
|
|
|
let installOrder = result.get()
|
|
check installOrder.packages.len == 4
|
|
check installOrder.totalSteps == 4
|
|
|
|
# Dependencies should be installed before dependents
|
|
let pkgIndices = installOrder.packages.mapIt((it.name, installOrder.packages.find(it)))
|
|
check pkgIndices.filterIt(it[0] == "pkgD")[0][1] < pkgIndices.filterIt(it[0] == "pkgB")[0][1]
|
|
check pkgIndices.filterIt(it[0] == "pkgB")[0][1] < pkgIndices.filterIt(it[0] == "pkgA")[0][1]
|
|
check pkgIndices.filterIt(it[0] == "pkgC")[0][1] < pkgIndices.filterIt(it[0] == "pkgA")[0][1]
|
|
|
|
test "Missing dependency detection":
|
|
let pkgMissing = PackageId(name: "missing", version: "1.0", stream: Stable)
|
|
let fragmentMissing = Fragment(
|
|
id: pkgMissing,
|
|
dependencies: @[PackageId(name: "nonexistent", version: "1.0", stream: Stable)],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Test package with missing dep"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
var testFragments = fragments
|
|
testFragments[pkgMissing] = fragmentMissing
|
|
|
|
let result = resolveDependencies(pkgMissing, testFragments)
|
|
check result.isErr
|
|
check result.error.code == PackageNotFound
|
|
check result.error.missingDependencies.len > 0
|
|
|
|
test "Circular dependency detection":
|
|
# Create circular dependency: E -> F -> E
|
|
let pkgE = PackageId(name: "pkgE", version: "1.0", stream: Stable)
|
|
let pkgF = PackageId(name: "pkgF", version: "1.0", stream: Stable)
|
|
|
|
let fragmentE = Fragment(
|
|
id: pkgE,
|
|
dependencies: @[pkgF],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Test package E"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
let fragmentF = Fragment(
|
|
id: pkgF,
|
|
dependencies: @[pkgE],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Test package F"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
var testFragments = initTable[PackageId, Fragment]()
|
|
testFragments[pkgE] = fragmentE
|
|
testFragments[pkgF] = fragmentF
|
|
|
|
let result = resolveDependencies(pkgE, testFragments)
|
|
check result.isErr
|
|
check result.error.code == DependencyConflict
|
|
check result.error.cyclicDependencies.len > 0
|
|
|
|
test "Dependency tree generation":
|
|
let treeResult = getDependencyTree(pkgA, fragments)
|
|
check treeResult.isOk
|
|
|
|
let tree = treeResult.get()
|
|
check "pkgA" in tree
|
|
check "pkgB" in tree
|
|
check "pkgC" in tree
|
|
check "pkgD" in tree
|
|
|
|
test "Version constraint resolution stub":
|
|
let result = resolveVersionConstraint("testpkg", "~> 1.0")
|
|
check result.isOk
|
|
check result.get().name == "testpkg"
|
|
|
|
test "Dependency validation":
|
|
let result = validateDependencies(fragments)
|
|
check result.isOk
|
|
|
|
# Test with missing dependency
|
|
var invalidFragments = fragments
|
|
let invalidPkg = PackageId(name: "invalid", version: "1.0", stream: Stable)
|
|
invalidFragments[invalidPkg] = Fragment(
|
|
id: invalidPkg,
|
|
dependencies: @[PackageId(name: "missing", version: "1.0", stream: Stable)],
|
|
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
|
|
buildSystem: CMake,
|
|
metadata: PackageMetadata(description: "Invalid package"),
|
|
acul: AculCompliance(required: false)
|
|
)
|
|
|
|
let invalidResult = validateDependencies(invalidFragments)
|
|
check invalidResult.isErr
|
|
check invalidResult.error.missingDependencies.len > 0
|
|
|
|
test "Error formatting":
|
|
let error = DependencyError(
|
|
code: DependencyConflict,
|
|
msg: "Test error",
|
|
missingDependencies: @[pkgA],
|
|
cyclicDependencies: @[pkgB],
|
|
conflictingPackages: @[pkgC]
|
|
)
|
|
|
|
let formatted = formatDependencyError(error)
|
|
check "Test error" in formatted
|
|
check "Missing Dependencies" in formatted
|
|
check "Circular Dependencies" in formatted
|
|
check "Conflicting Packages" in formatted |