662 lines
21 KiB
Nim
662 lines
21 KiB
Nim
## Unit Tests for Conflict Detection
|
|
##
|
|
## Tests for detecting and reporting various types of conflicts
|
|
## in the NIP dependency resolver.
|
|
##
|
|
## Requirements tested:
|
|
## - 7.1: Detect and report version conflicts
|
|
## - 7.2: Detect and report variant conflicts
|
|
## - 7.3: Detect and report circular dependencies
|
|
## - 7.4: Detect and report missing packages
|
|
## - 7.5: Provide actionable suggestions for resolution
|
|
|
|
import std/[unittest, tables, sets, options, sequtils, strutils]
|
|
import ../src/nip/resolver/conflict_detection
|
|
import ../src/nip/resolver/solver_types
|
|
import ../src/nip/resolver/variant_types
|
|
import ../src/nip/manifest_parser
|
|
|
|
suite "Conflict Detection Tests":
|
|
|
|
# --- Version Conflict Tests ---
|
|
|
|
test "Detect version conflict - exact versions":
|
|
## Test detecting conflicting exact version requirements
|
|
## Requirements: 7.1
|
|
|
|
let constraints = @[
|
|
VersionConstraint(operator: OpExact, version: SemanticVersion(major: 1, minor: 0, patch: 0)),
|
|
VersionConstraint(operator: OpExact, version: SemanticVersion(major: 2, minor: 0, patch: 0))
|
|
]
|
|
|
|
let conflict = detectVersionConflict("nginx", constraints)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == VersionConflict
|
|
check conflict.get().packages.contains("nginx")
|
|
check conflict.get().details.contains("1.0.0")
|
|
check conflict.get().details.contains("2.0.0")
|
|
check conflict.get().suggestions.len > 0
|
|
|
|
test "No version conflict - compatible versions":
|
|
## Test that compatible versions don't trigger conflict
|
|
## Requirements: 7.1
|
|
|
|
let constraints = @[
|
|
VersionConstraint(operator: OpGreaterEq, version: SemanticVersion(major: 1, minor: 0, patch: 0)),
|
|
VersionConstraint(operator: OpGreaterEq, version: SemanticVersion(major: 1, minor: 5, patch: 0))
|
|
]
|
|
|
|
let conflict = detectVersionConflict("nginx", constraints)
|
|
|
|
check conflict.isNone
|
|
|
|
test "No version conflict - single constraint":
|
|
## Test that single constraint doesn't trigger conflict
|
|
## Requirements: 7.1
|
|
|
|
let constraints = @[
|
|
VersionConstraint(operator: OpExact, version: SemanticVersion(major: 1, minor: 0, patch: 0))
|
|
]
|
|
|
|
let conflict = detectVersionConflict("nginx", constraints)
|
|
|
|
check conflict.isNone
|
|
|
|
test "Detect version conflict - exact vs greater-equal":
|
|
## Test detecting conflict between exact and >= constraint
|
|
## Requirements: 7.1
|
|
|
|
let constraints = @[
|
|
VersionConstraint(operator: OpExact, version: SemanticVersion(major: 1, minor: 0, patch: 0)),
|
|
VersionConstraint(operator: OpGreaterEq, version: SemanticVersion(major: 2, minor: 0, patch: 0))
|
|
]
|
|
|
|
let conflict = detectVersionConflict("zlib", constraints)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == VersionConflict
|
|
check conflict.get().suggestions.len > 0
|
|
|
|
# --- Variant Conflict Tests ---
|
|
|
|
test "Detect variant conflict - exclusive domains":
|
|
## Test detecting conflicting exclusive variant flags
|
|
## Requirements: 7.2
|
|
|
|
var profile1 = newVariantProfile()
|
|
var domain1 = newVariantDomain("init", Exclusive)
|
|
domain1.flags.incl("systemd")
|
|
profile1.addDomain(domain1)
|
|
|
|
var profile2 = newVariantProfile()
|
|
var domain2 = newVariantDomain("init", Exclusive)
|
|
domain2.flags.incl("dinit")
|
|
profile2.addDomain(domain2)
|
|
|
|
let demands = @[
|
|
VariantDemand(packageName: "nginx", variantProfile: profile1, optional: false),
|
|
VariantDemand(packageName: "nginx", variantProfile: profile2, optional: false)
|
|
]
|
|
|
|
let conflict = detectVariantConflict("nginx", demands)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == conflict_detection.VariantConflict
|
|
check conflict.get().details.contains("init")
|
|
check conflict.get().suggestions.len > 0
|
|
|
|
test "No variant conflict - non-exclusive domains":
|
|
## Test that non-exclusive domains don't trigger conflict
|
|
## Requirements: 7.2
|
|
|
|
var profile1 = newVariantProfile()
|
|
var domain1 = newVariantDomain("features", NonExclusive)
|
|
domain1.flags.incl("wayland")
|
|
profile1.addDomain(domain1)
|
|
|
|
var profile2 = newVariantProfile()
|
|
var domain2 = newVariantDomain("features", NonExclusive)
|
|
domain2.flags.incl("x11")
|
|
profile2.addDomain(domain2)
|
|
|
|
let demands = @[
|
|
VariantDemand(packageName: "nginx", variantProfile: profile1, optional: false),
|
|
VariantDemand(packageName: "nginx", variantProfile: profile2, optional: false)
|
|
]
|
|
|
|
let conflict = detectVariantConflict("nginx", demands)
|
|
|
|
check conflict.isNone
|
|
|
|
test "No variant conflict - single demand":
|
|
## Test that single demand doesn't trigger conflict
|
|
## Requirements: 7.2
|
|
|
|
var profile = newVariantProfile()
|
|
var domain = newVariantDomain("init", Exclusive)
|
|
domain.flags.incl("systemd")
|
|
profile.addDomain(domain)
|
|
|
|
let demands = @[
|
|
VariantDemand(packageName: "nginx", variantProfile: profile, optional: false)
|
|
]
|
|
|
|
let conflict = detectVariantConflict("nginx", demands)
|
|
|
|
check conflict.isNone
|
|
|
|
test "Detect variant conflict - multiple exclusive domains":
|
|
## Test detecting conflicts in multiple exclusive domains
|
|
## Requirements: 7.2
|
|
|
|
var profile1 = newVariantProfile()
|
|
var domain1a = newVariantDomain("init", Exclusive)
|
|
domain1a.flags.incl("systemd")
|
|
profile1.addDomain(domain1a)
|
|
var domain1b = newVariantDomain("libc", Exclusive)
|
|
domain1b.flags.incl("glibc")
|
|
profile1.addDomain(domain1b)
|
|
|
|
var profile2 = newVariantProfile()
|
|
var domain2a = newVariantDomain("init", Exclusive)
|
|
domain2a.flags.incl("dinit")
|
|
profile2.addDomain(domain2a)
|
|
var domain2b = newVariantDomain("libc", Exclusive)
|
|
domain2b.flags.incl("musl")
|
|
profile2.addDomain(domain2b)
|
|
|
|
let demands = @[
|
|
VariantDemand(packageName: "nginx", variantProfile: profile1, optional: false),
|
|
VariantDemand(packageName: "nginx", variantProfile: profile2, optional: false)
|
|
]
|
|
|
|
let conflict = detectVariantConflict("nginx", demands)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == conflict_detection.VariantConflict
|
|
|
|
# --- Circular Dependency Tests ---
|
|
|
|
test "Detect circular dependency - simple cycle":
|
|
## Test detecting a simple circular dependency
|
|
## Requirements: 7.3
|
|
|
|
var graph: Table[string, seq[string]] = initTable[string, seq[string]]()
|
|
graph["nginx"] = @["zlib"]
|
|
graph["zlib"] = @["nginx"]
|
|
|
|
let conflict = detectCircularDependency(graph, "nginx")
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == CircularDependency
|
|
check conflict.get().cyclePath.isSome
|
|
check conflict.get().cyclePath.get().len >= 2
|
|
check conflict.get().suggestions.len > 0
|
|
|
|
test "Detect circular dependency - three-way cycle":
|
|
## Test detecting a three-way circular dependency
|
|
## Requirements: 7.3
|
|
|
|
var graph: Table[string, seq[string]] = initTable[string, seq[string]]()
|
|
graph["nginx"] = @["zlib"]
|
|
graph["zlib"] = @["pcre"]
|
|
graph["pcre"] = @["nginx"]
|
|
|
|
let conflict = detectCircularDependency(graph, "nginx")
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == CircularDependency
|
|
check conflict.get().cyclePath.isSome
|
|
let cycle = conflict.get().cyclePath.get()
|
|
check cycle.len >= 3
|
|
check cycle.contains("nginx")
|
|
check cycle.contains("zlib")
|
|
check cycle.contains("pcre")
|
|
|
|
test "No circular dependency - linear chain":
|
|
## Test that linear dependency chains don't trigger circular conflict
|
|
## Requirements: 7.3
|
|
|
|
var graph: Table[string, seq[string]] = initTable[string, seq[string]]()
|
|
graph["nginx"] = @["zlib"]
|
|
graph["zlib"] = @["pcre"]
|
|
graph["pcre"] = @[]
|
|
|
|
let conflict = detectCircularDependency(graph, "nginx")
|
|
|
|
check conflict.isNone
|
|
|
|
test "No circular dependency - diamond dependency":
|
|
## Test that diamond dependencies don't trigger circular conflict
|
|
## Requirements: 7.3
|
|
|
|
var graph: Table[string, seq[string]] = initTable[string, seq[string]]()
|
|
graph["nginx"] = @["zlib", "pcre"]
|
|
graph["zlib"] = @["openssl"]
|
|
graph["pcre"] = @["openssl"]
|
|
graph["openssl"] = @[]
|
|
|
|
let conflict = detectCircularDependency(graph, "nginx")
|
|
|
|
check conflict.isNone
|
|
|
|
test "Detect circular dependency - self-loop":
|
|
## Test detecting a package that depends on itself
|
|
## Requirements: 7.3
|
|
|
|
var graph: Table[string, seq[string]] = initTable[string, seq[string]]()
|
|
graph["nginx"] = @["nginx"]
|
|
|
|
let conflict = detectCircularDependency(graph, "nginx")
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == CircularDependency
|
|
|
|
# --- Missing Package Tests ---
|
|
|
|
test "Detect missing package":
|
|
## Test detecting a missing package
|
|
## Requirements: 7.4
|
|
|
|
let available = toHashSet(["nginx", "zlib", "pcre"])
|
|
|
|
let conflict = detectMissingPackage("openssl", available)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == MissingPackage
|
|
check conflict.get().packages.contains("openssl")
|
|
check conflict.get().details.contains("openssl")
|
|
check conflict.get().suggestions.len > 0
|
|
|
|
test "No missing package - package exists":
|
|
## Test that existing packages don't trigger missing conflict
|
|
## Requirements: 7.4
|
|
|
|
let available = toHashSet(["nginx", "zlib", "pcre", "openssl"])
|
|
|
|
let conflict = detectMissingPackage("openssl", available)
|
|
|
|
check conflict.isNone
|
|
|
|
test "Detect missing package - suggest similar names":
|
|
## Test that similar package names are suggested
|
|
## Requirements: 7.4
|
|
|
|
let available = toHashSet(["nginx", "nginx-ssl", "nginx-http2"])
|
|
|
|
let conflict = detectMissingPackage("nginx-http3", available)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == MissingPackage
|
|
# Should suggest similar names
|
|
let suggestions = conflict.get().suggestions.join(" ")
|
|
check suggestions.contains("nginx") or suggestions.contains("Did you mean")
|
|
|
|
test "Detect missing package - empty repository":
|
|
## Test detecting missing package in empty repository
|
|
## Requirements: 7.4
|
|
|
|
let available: HashSet[string] = initHashSet[string]()
|
|
|
|
let conflict = detectMissingPackage("nginx", available)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == MissingPackage
|
|
|
|
# --- Build Hash Mismatch Tests ---
|
|
|
|
test "Detect build hash mismatch":
|
|
## Test detecting build hash mismatch
|
|
## Requirements: 7.5
|
|
|
|
let conflict = detectBuildHashMismatch(
|
|
"nginx",
|
|
"blake3-abc123def456",
|
|
"blake3-xyz789abc123"
|
|
)
|
|
|
|
check conflict.isSome
|
|
check conflict.get().kind == BuildHashMismatch
|
|
check conflict.get().packages.contains("nginx")
|
|
check conflict.get().details.contains("abc123def456")
|
|
check conflict.get().details.contains("xyz789abc123")
|
|
check conflict.get().suggestions.len > 0
|
|
|
|
test "No build hash mismatch - hashes match":
|
|
## Test that matching hashes don't trigger mismatch conflict
|
|
## Requirements: 7.5
|
|
|
|
let conflict = detectBuildHashMismatch(
|
|
"nginx",
|
|
"blake3-abc123def456",
|
|
"blake3-abc123def456"
|
|
)
|
|
|
|
check conflict.isNone
|
|
|
|
# --- Conflict Formatting Tests ---
|
|
|
|
test "Format version conflict":
|
|
## Test formatting a version conflict report
|
|
## Requirements: 7.1, 7.5
|
|
|
|
let report = ConflictReport(
|
|
kind: VersionConflict,
|
|
packages: @["nginx"],
|
|
details: "nginx requires version 1.0.0 and 2.0.0",
|
|
suggestions: @["Update to compatible version"],
|
|
conflictingTerms: @[],
|
|
cyclePath: none(seq[string])
|
|
)
|
|
|
|
let formatted = formatConflict(report)
|
|
|
|
check formatted.contains("VersionConflict")
|
|
check formatted.contains("nginx")
|
|
check formatted.contains("Update to compatible version")
|
|
|
|
test "Format variant conflict":
|
|
## Test formatting a variant conflict report
|
|
## Requirements: 7.2, 7.5
|
|
|
|
let report = ConflictReport(
|
|
kind: VariantConflict,
|
|
packages: @["nginx"],
|
|
details: "nginx requires +systemd and +dinit",
|
|
suggestions: @["Choose one variant"],
|
|
conflictingTerms: @[],
|
|
cyclePath: none(seq[string])
|
|
)
|
|
|
|
let formatted = formatConflict(report)
|
|
|
|
check formatted.contains("VariantConflict")
|
|
check formatted.contains("nginx")
|
|
check formatted.contains("Choose one variant")
|
|
|
|
test "Format circular dependency":
|
|
## Test formatting a circular dependency report
|
|
## Requirements: 7.3, 7.5
|
|
|
|
let report = ConflictReport(
|
|
kind: CircularDependency,
|
|
packages: @["nginx", "zlib", "nginx"],
|
|
details: "nginx -> zlib -> nginx",
|
|
suggestions: @["Break the cycle"],
|
|
conflictingTerms: @[],
|
|
cyclePath: some(@["nginx", "zlib", "nginx"])
|
|
)
|
|
|
|
let formatted = formatConflict(report)
|
|
|
|
check formatted.contains("CircularDependency")
|
|
check formatted.contains("nginx")
|
|
check formatted.contains("Break the cycle")
|
|
|
|
test "Format missing package":
|
|
## Test formatting a missing package report
|
|
## Requirements: 7.4, 7.5
|
|
|
|
let report = ConflictReport(
|
|
kind: MissingPackage,
|
|
packages: @["openssl"],
|
|
details: "openssl not found",
|
|
suggestions: @["Check package name", "Update repositories"],
|
|
conflictingTerms: @[],
|
|
cyclePath: none(seq[string])
|
|
)
|
|
|
|
let formatted = formatConflict(report)
|
|
|
|
check formatted.contains("MissingPackage")
|
|
check formatted.contains("openssl")
|
|
check formatted.contains("Check package name")
|
|
|
|
test "Format build hash mismatch":
|
|
## Test formatting a build hash mismatch report
|
|
## Requirements: 7.5
|
|
|
|
let report = ConflictReport(
|
|
kind: BuildHashMismatch,
|
|
packages: @["nginx"],
|
|
details: "Hash mismatch for nginx",
|
|
suggestions: @["Reinstall package"],
|
|
conflictingTerms: @[],
|
|
cyclePath: none(seq[string])
|
|
)
|
|
|
|
let formatted = formatConflict(report)
|
|
|
|
check formatted.contains("BuildHashMismatch")
|
|
check formatted.contains("nginx")
|
|
check formatted.contains("Reinstall package")
|
|
|
|
# --- Conflict Analysis Tests ---
|
|
|
|
test "Analyze conflict origins - version conflict":
|
|
## Test analyzing origins of a version conflict
|
|
## Requirements: 7.5
|
|
|
|
var manifests: Table[string, seq[VariantDemand]] = initTable[string, seq[VariantDemand]]()
|
|
manifests["nginx"] = @[
|
|
VariantDemand(packageName: "nginx", variantProfile: newVariantProfile(), optional: false),
|
|
VariantDemand(packageName: "nginx", variantProfile: newVariantProfile(), optional: false)
|
|
]
|
|
|
|
let report = ConflictReport(
|
|
kind: VersionConflict,
|
|
packages: @["nginx"],
|
|
details: "Version conflict",
|
|
suggestions: @[],
|
|
conflictingTerms: @[],
|
|
cyclePath: none(seq[string])
|
|
)
|
|
|
|
let analysis = analyzeConflictOrigins(report, manifests)
|
|
|
|
check analysis.len > 0
|
|
check analysis[0].contains("nginx")
|
|
check analysis[0].contains("2")
|
|
|
|
test "Analyze conflict origins - circular dependency":
|
|
## Test analyzing origins of a circular dependency
|
|
## Requirements: 7.5
|
|
|
|
let report = ConflictReport(
|
|
kind: CircularDependency,
|
|
packages: @["nginx", "zlib", "nginx"],
|
|
details: "Circular dependency",
|
|
suggestions: @[],
|
|
conflictingTerms: @[],
|
|
cyclePath: some(@["nginx", "zlib", "nginx"])
|
|
)
|
|
|
|
let analysis = analyzeConflictOrigins(report, initTable[string, seq[VariantDemand]]())
|
|
|
|
check analysis.len > 0
|
|
check analysis[0].contains("3")
|
|
|
|
# --- Minimal Conflict Extraction Tests ---
|
|
|
|
test "Extract minimal conflict":
|
|
## Test extracting minimal conflicting incompatibilities
|
|
## Requirements: 7.5
|
|
|
|
let incomp1 = Incompatibility(
|
|
terms: @[],
|
|
cause: Root,
|
|
externalContext: "Incomp 1",
|
|
fromPackage: none(string),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let incomp2 = Incompatibility(
|
|
terms: @[],
|
|
cause: Dependency,
|
|
externalContext: "Incomp 2",
|
|
fromPackage: none(string),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let minimal = extractMinimalConflict(@[incomp1, incomp2])
|
|
|
|
check minimal.isSome
|
|
check minimal.get().len == 2
|
|
|
|
|
|
test "Extract minimal conflict - empty list":
|
|
## Test extracting minimal conflict from empty list
|
|
## Requirements: 7.5
|
|
|
|
let minimal = extractMinimalConflict(@[])
|
|
|
|
check minimal.isNone
|
|
|
|
test "Extract minimal conflict - single incompatibility":
|
|
## Test extracting minimal conflict from single incompatibility
|
|
## Requirements: 7.5
|
|
|
|
let incomp = Incompatibility(
|
|
terms: @[],
|
|
cause: Root,
|
|
externalContext: "Single incompatibility",
|
|
fromPackage: none(string),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let minimal = extractMinimalConflict(@[incomp])
|
|
|
|
check minimal.isSome
|
|
check minimal.get().len == 1
|
|
|
|
test "Extract minimal conflict - multiple incompatibilities":
|
|
## Test extracting minimal conflict from multiple incompatibilities
|
|
## Requirements: 7.5
|
|
|
|
let incomp1 = Incompatibility(
|
|
terms: @[],
|
|
cause: Root,
|
|
externalContext: "Root requirement",
|
|
fromPackage: some("nginx"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let incomp2 = Incompatibility(
|
|
terms: @[],
|
|
cause: Dependency,
|
|
externalContext: "Dependency conflict",
|
|
fromPackage: some("nginx"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let incomp3 = Incompatibility(
|
|
terms: @[],
|
|
cause: VariantConflict,
|
|
externalContext: "Variant conflict",
|
|
fromPackage: some("openssl"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let minimal = extractMinimalConflict(@[incomp1, incomp2, incomp3])
|
|
|
|
check minimal.isSome
|
|
# The minimal set should have at least 1 incompatibility
|
|
check minimal.get().len >= 1
|
|
# The minimal set should have at most all incompatibilities
|
|
check minimal.get().len <= 3
|
|
|
|
test "Extract minimal conflict - preserves root incompatibilities":
|
|
## Test that root incompatibilities are preserved in minimal set
|
|
## Requirements: 7.5
|
|
|
|
let rootIncompatibility = Incompatibility(
|
|
terms: @[],
|
|
cause: Root,
|
|
externalContext: "User requirement",
|
|
fromPackage: some("nginx"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let dependencyIncompatibility = Incompatibility(
|
|
terms: @[],
|
|
cause: Dependency,
|
|
externalContext: "Dependency",
|
|
fromPackage: some("zlib"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let minimal = extractMinimalConflict(@[rootIncompatibility, dependencyIncompatibility])
|
|
|
|
check minimal.isSome
|
|
# Root incompatibilities should be preserved
|
|
let hasRoot = minimal.get().anyIt(it.cause == Root)
|
|
check hasRoot
|
|
|
|
test "Extract minimal conflict - handles variant conflicts":
|
|
## Test that variant conflicts are handled correctly
|
|
## Requirements: 7.5
|
|
|
|
let variantConflict1 = Incompatibility(
|
|
terms: @[],
|
|
cause: IncompatibilityCause.VariantConflict,
|
|
externalContext: "Variant conflict 1",
|
|
fromPackage: some("nginx"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let variantConflict2 = Incompatibility(
|
|
terms: @[],
|
|
cause: IncompatibilityCause.VariantConflict,
|
|
externalContext: "Variant conflict 2",
|
|
fromPackage: some("nginx"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let minimal = extractMinimalConflict(@[variantConflict1, variantConflict2])
|
|
|
|
check minimal.isSome
|
|
# Should have at least one variant conflict
|
|
let hasVariantConflict = minimal.get().anyIt(it.cause == IncompatibilityCause.VariantConflict)
|
|
check hasVariantConflict
|
|
|
|
test "Extract minimal conflict - deterministic results":
|
|
## Test that minimal conflict extraction is deterministic
|
|
## Requirements: 7.5
|
|
|
|
let incomp1 = Incompatibility(
|
|
terms: @[],
|
|
cause: Root,
|
|
externalContext: "Incomp 1",
|
|
fromPackage: some("pkg1"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let incomp2 = Incompatibility(
|
|
terms: @[],
|
|
cause: Dependency,
|
|
externalContext: "Incomp 2",
|
|
fromPackage: some("pkg2"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let incomp3 = Incompatibility(
|
|
terms: @[],
|
|
cause: VariantConflict,
|
|
externalContext: "Incomp 3",
|
|
fromPackage: some("pkg3"),
|
|
fromVersion: none(SemanticVersion)
|
|
)
|
|
|
|
let incompatibilities = @[incomp1, incomp2, incomp3]
|
|
|
|
# Extract minimal conflict multiple times
|
|
let minimal1 = extractMinimalConflict(incompatibilities)
|
|
let minimal2 = extractMinimalConflict(incompatibilities)
|
|
|
|
# Results should be the same
|
|
check minimal1.isSome
|
|
check minimal2.isSome
|
|
check minimal1.get().len == minimal2.get().len
|
|
|