nip/tests/test_manifest_parser.nim

432 lines
11 KiB
Nim

## Manifest Parser Tests
## Comprehensive test suite for format-agnostic manifest parsing
import std/[unittest, options, strutils]
import nip/manifest_parser
import nip/platform
suite "Semantic Versioning":
test "Parse valid semver":
let v = parseSemanticVersion("1.2.3")
check v.major == 1
check v.minor == 2
check v.patch == 3
check v.prerelease == ""
check v.build == ""
test "Parse semver with prerelease":
let v = parseSemanticVersion("1.0.0-alpha.1")
check v.major == 1
check v.minor == 0
check v.patch == 0
check v.prerelease == "alpha.1"
test "Parse semver with build metadata":
let v = parseSemanticVersion("1.0.0+20130313144700")
check v.major == 1
check v.build == "20130313144700"
test "Parse semver with both":
let v = parseSemanticVersion("1.0.0-beta+exp.sha.5114f85")
check v.prerelease == "beta"
check v.build == "exp.sha.5114f85"
test "Reject invalid semver":
expect ManifestError:
discard parseSemanticVersion("1.0")
expect ManifestError:
discard parseSemanticVersion("v1.2.3")
expect ManifestError:
discard parseSemanticVersion("1.2.x")
test "Version comparison":
let v1 = parseSemanticVersion("1.0.0")
let v2 = parseSemanticVersion("1.0.1")
let v3 = parseSemanticVersion("1.1.0")
let v4 = parseSemanticVersion("2.0.0")
check v1 < v2
check v2 < v3
check v3 < v4
check v1 == v1
check v4 > v1
test "Prerelease comparison":
let release = parseSemanticVersion("1.0.0")
let prerelease = parseSemanticVersion("1.0.0-alpha")
check prerelease < release # Prerelease < release
suite "Version Constraints":
test "Parse exact constraint":
let c = parseVersionConstraint("1.2.3")
check c.operator == OpExact
check c.version.major == 1
test "Parse >= constraint":
let c = parseVersionConstraint(">=1.0.0")
check c.operator == OpGreaterEq
test "Parse ~ constraint":
let c = parseVersionConstraint("~1.2.3")
check c.operator == OpTilde
test "Parse ^ constraint":
let c = parseVersionConstraint("^2.0.0")
check c.operator == OpCaret
test "Parse * constraint":
let c = parseVersionConstraint("*")
check c.operator == OpAny
test "Satisfy exact constraint":
let v = parseSemanticVersion("1.2.3")
let c = parseVersionConstraint("=1.2.3")
check satisfiesConstraint(v, c)
let v2 = parseSemanticVersion("1.2.4")
check not satisfiesConstraint(v2, c)
test "Satisfy >= constraint":
let v1 = parseSemanticVersion("1.2.3")
let v2 = parseSemanticVersion("1.2.4")
let c = parseVersionConstraint(">=1.2.3")
check satisfiesConstraint(v1, c)
check satisfiesConstraint(v2, c)
test "Satisfy ~ constraint":
let c = parseVersionConstraint("~1.2.3")
check satisfiesConstraint(parseSemanticVersion("1.2.3"), c)
check satisfiesConstraint(parseSemanticVersion("1.2.4"), c)
check not satisfiesConstraint(parseSemanticVersion("1.3.0"), c)
check not satisfiesConstraint(parseSemanticVersion("2.0.0"), c)
test "Satisfy ^ constraint":
let c = parseVersionConstraint("^1.2.3")
check satisfiesConstraint(parseSemanticVersion("1.2.3"), c)
check satisfiesConstraint(parseSemanticVersion("1.3.0"), c)
check satisfiesConstraint(parseSemanticVersion("1.9.9"), c)
check not satisfiesConstraint(parseSemanticVersion("2.0.0"), c)
suite "Format Detection":
test "Detect JSON format":
let jsonContent = """{"name": "test"}"""
check detectFormat(jsonContent) == FormatJSON
test "Detect KDL format":
let kdlContent = """package "test" { }"""
check detectFormat(kdlContent) == FormatKDL
test "Detect JSON array":
let jsonArray = """[{"name": "test"}]"""
check detectFormat(jsonArray) == FormatJSON
suite "JSON Manifest Parsing":
test "Parse minimal valid manifest":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT"
}
"""
let manifest = parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
check manifest.name == "test-package"
check manifest.version.major == 1
check manifest.license == "MIT"
test "Parse manifest with dependencies":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"dependencies": [
{"name": "dep1", "version": ">=1.0.0"},
{"name": "dep2", "version": "~2.0.0", "optional": true}
]
}
"""
let manifest = parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
check manifest.dependencies.len == 2
check manifest.dependencies[0].name == "dep1"
check manifest.dependencies[1].optional == true
test "Parse manifest with platform constraints":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"supported_os": ["linux", "freebsd"],
"supported_architectures": ["x86_64", "aarch64"]
}
"""
let manifest = parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
check manifest.supportedOS.len == 2
check "linux" in manifest.supportedOS
check manifest.supportedArchitectures.len == 2
check "x86_64" in manifest.supportedArchitectures
test "Reject missing required field":
let jsonContent = """
{
"name": "test-package",
"license": "MIT"
}
"""
expect ManifestError:
discard parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
test "Reject invalid semver":
let jsonContent = """
{
"name": "test-package",
"version": "1.0",
"license": "MIT"
}
"""
expect ManifestError:
discard parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
test "Reject unknown field in strict mode":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"unknown_field": "contamination"
}
"""
expect ManifestError:
discard parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
test "Accept unknown field in lenient mode":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"unknown_field": "allowed"
}
"""
# Should not raise in lenient mode
let manifest = parseManifest(jsonContent, NPK, FormatJSON, ValidationLenient)
check manifest.name == "test-package"
suite "KDL Manifest Parsing":
test "Parse minimal KDL manifest":
let kdlContent = """
package "test-package" {
version "1.0.0"
license "MIT"
}
"""
let manifest = parseManifest(kdlContent, NPK, FormatKDL, ValidationStrict)
check manifest.name == "test-package"
check manifest.version.major == 1
check manifest.license == "MIT"
test "Parse KDL manifest with dependencies":
let kdlContent = """
package "test-package" {
version "1.0.0"
license "MIT"
dependencies {
"dep1" version=">=1.0.0"
"dep2" version="~2.0.0" optional=true
}
}
"""
let manifest = parseManifest(kdlContent, NPK, FormatKDL, ValidationStrict)
check manifest.dependencies.len == 2
check manifest.dependencies[0].name == "dep1"
check manifest.dependencies[1].optional == true
suite "Platform Validation":
test "Validate valid OS":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"supported_os": ["linux", "freebsd"]
}
"""
let manifest = parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
check manifest.supportedOS.len == 2
test "Reject invalid OS in strict mode":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"supported_os": ["invalid_os"]
}
"""
expect ManifestError:
discard parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
test "Reject invalid architecture in strict mode":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"supported_architectures": ["invalid_arch"]
}
"""
expect ManifestError:
discard parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
test "Check platform compatibility":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"supported_os": ["linux"],
"supported_architectures": ["x86_64"]
}
"""
let manifest = parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
# Create mock platform capabilities
var caps = PlatformCapabilities(
osType: Linux,
hasUserNamespaces: true,
hasJails: false,
hasUnveil: false,
isRoot: false,
kernelVersion: "6.1.0",
isEmbedded: false,
memoryTotal: 8589934592,
cpuCount: 8
)
check checkPlatformCompatibility(manifest, caps)
# Change to incompatible platform
caps.osType = FreeBSD
check not checkPlatformCompatibility(manifest, caps)
suite "Serialization":
test "Serialize to JSON":
let manifest = PackageManifest(
format: NPK,
name: "test-package",
version: parseSemanticVersion("1.0.0"),
license: "MIT",
description: some("A test package"),
supportedOS: @["linux", "freebsd"],
supportedArchitectures: @["x86_64"]
)
let jsonStr = serializeManifestToJSON(manifest)
check jsonStr.contains("test-package")
check jsonStr.contains("1.0.0")
check jsonStr.contains("MIT")
test "Serialize to KDL":
let manifest = PackageManifest(
format: NPK,
name: "test-package",
version: parseSemanticVersion("1.0.0"),
license: "MIT",
description: some("A test package")
)
let kdlStr = serializeManifestToKDL(manifest)
check kdlStr.contains("package \"test-package\"")
check kdlStr.contains("version \"1.0.0\"")
check kdlStr.contains("license \"MIT\"")
test "Round-trip JSON":
let original = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"description": "A test package"
}
"""
let manifest = parseManifest(original, NPK, FormatJSON, ValidationStrict)
let serialized = serializeManifestToJSON(manifest)
let reparsed = parseManifest(serialized, NPK, FormatJSON, ValidationStrict)
check reparsed.name == manifest.name
check reparsed.version == manifest.version
check reparsed.license == manifest.license
suite "Validation Rules":
test "Required fields rule":
let jsonContent = """
{
"version": "1.0.0",
"license": "MIT"
}
"""
expect ManifestError:
discard parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
test "Dependency validation":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"dependencies": [
{"name": "dep1", "version": "invalid"}
]
}
"""
expect ManifestError:
discard parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
suite "Format-Specific Fields":
test "NPK-specific fields allowed":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"files": ["file1", "file2"]
}
"""
let manifest = parseManifest(jsonContent, NPK, FormatJSON, ValidationStrict)
check manifest.name == "test-package"
test "NIP-specific fields allowed":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"desktop": "test.desktop"
}
"""
let manifest = parseManifest(jsonContent, NIP, FormatJSON, ValidationStrict)
check manifest.name == "test-package"
test "NEXTER-specific fields allowed":
let jsonContent = """
{
"name": "test-package",
"version": "1.0.0",
"license": "MIT",
"container": "test-container"
}
"""
let manifest = parseManifest(jsonContent, NEXTER, FormatJSON, ValidationStrict)
check manifest.name == "test-package"
when isMainModule:
echo "Running manifest parser tests..."