114 lines
3.5 KiB
Nim
114 lines
3.5 KiB
Nim
import std/[unittest, os, tempfiles, options, strutils]
|
|
import nip/nip_installer
|
|
import nip/manifest_parser
|
|
import nip/cas
|
|
|
|
suite "NIP Installer Tests":
|
|
|
|
setup:
|
|
let tempDir = createTempDir("nip_test_installer_", "")
|
|
let casRoot = tempDir / "cas"
|
|
|
|
# Mock home directory structure
|
|
let mockHome = tempDir / "home"
|
|
createDir(mockHome / ".local/share/nexus/nips")
|
|
createDir(mockHome / ".local/share/applications")
|
|
createDir(casRoot)
|
|
|
|
discard initCasManager(casRoot, casRoot)
|
|
|
|
# We need to override getHomeDir or pass paths manually.
|
|
# nip_installer uses getHomeDir(). We should probably allow overriding paths in constructor.
|
|
# Wait, newNipInstaller takes casRoot. It calculates others from getHomeDir().
|
|
# I should modify newNipInstaller to accept overrides or use environment variable.
|
|
# Or just subclass/mock? Nim doesn't do classes like that easily.
|
|
# Let's modify nip_installer to allow path overrides for testing.
|
|
|
|
# For now, I'll manually construct the object since fields are exported?
|
|
# No, fields are exported (*).
|
|
|
|
var ni = NipInstaller(
|
|
casRoot: casRoot,
|
|
installRoot: mockHome / ".local/share/nexus/nips",
|
|
appsRoot: mockHome / ".local/share/applications",
|
|
dryRun: false
|
|
)
|
|
|
|
teardown:
|
|
removeDir(tempDir)
|
|
|
|
test "Install NIP with Desktop Integration":
|
|
# 1. Prepare CAS
|
|
let fileContent = "binary data"
|
|
let casObj = storeObject(fileContent, ni.casRoot)
|
|
|
|
# 2. Create Manifest
|
|
var manifest = PackageManifest(
|
|
name: "test-app",
|
|
version: parseSemanticVersion("1.0.0"),
|
|
license: "MIT",
|
|
artifactHash: "hash123"
|
|
)
|
|
|
|
manifest.files.add(FileSpec(
|
|
path: "bin/app",
|
|
hash: string(casObj.hash),
|
|
size: fileContent.len,
|
|
permissions: "755"
|
|
))
|
|
|
|
manifest.desktop = some(DesktopIntegration(
|
|
displayName: "Test App",
|
|
categories: @["Utility"],
|
|
terminal: true
|
|
))
|
|
|
|
# 3. Install
|
|
ni.installNip(manifest)
|
|
|
|
# 4. Verify Files
|
|
let installPath = ni.installRoot / "test-app/1.0.0/hash123"
|
|
check fileExists(installPath / "bin/app")
|
|
check readFile(installPath / "bin/app") == fileContent
|
|
|
|
# 5. Verify Symlink
|
|
let currentLink = ni.installRoot / "test-app/Current"
|
|
check symlinkExists(currentLink)
|
|
check expandSymlink(currentLink) == installPath
|
|
|
|
# 6. Verify Desktop File
|
|
let desktopFile = ni.appsRoot / "test-app.desktop"
|
|
check fileExists(desktopFile)
|
|
let content = readFile(desktopFile)
|
|
check content.contains("Name=Test App")
|
|
check content.contains("Exec=nip run test-app")
|
|
check content.contains("Categories=Utility;")
|
|
check content.contains("Terminal=true")
|
|
|
|
# 7. Verify CAS Reference
|
|
check hasReferences(ni.casRoot, casObj.hash)
|
|
|
|
test "Remove NIP":
|
|
# 1. Setup (Install first)
|
|
let fileContent = "data"
|
|
let casObj = storeObject(fileContent, ni.casRoot)
|
|
var manifest = PackageManifest(
|
|
name: "remove-me",
|
|
version: parseSemanticVersion("1.0.0"),
|
|
license: "MIT",
|
|
artifactHash: "hash123"
|
|
)
|
|
manifest.files.add(FileSpec(path: "file", hash: string(casObj.hash)))
|
|
manifest.desktop = some(DesktopIntegration(displayName: "Remove Me"))
|
|
|
|
ni.installNip(manifest)
|
|
check fileExists(ni.appsRoot / "remove-me.desktop")
|
|
|
|
# 2. Remove
|
|
ni.removeNip(manifest)
|
|
|
|
# 3. Verify
|
|
check not fileExists(ni.appsRoot / "remove-me.desktop")
|
|
check not dirExists(ni.installRoot / "remove-me")
|
|
check not hasReferences(ni.casRoot, casObj.hash)
|