$ErrorActionPreference = 'Stop' $repositoryRoot = Split-Path -Parent $PSScriptRoot $installer = Join-Path $repositoryRoot 'scripts/install-tht.ps1' if (-not (Test-Path -LiteralPath $installer)) { throw "installer is missing: $installer" } $isWindowsHost = $env:OS -eq 'Windows_NT' if (-not $isWindowsHost) { $installerText = Get-Content -LiteralPath $installer -Raw foreach ($requiredText in @('THT_INSTALL_DIRECTORY', 'LOCALAPPDATA', 'SetEnvironmentVariable', 'build-tht.sh', 'File]::Replace')) { if (-not $installerText.Contains($requiredText)) { throw "Windows installer is missing required behavior: $requiredText" } } Write-Output 'PowerShell installer behavior test skipped: requires Windows.' exit 0 } $temporaryRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("tht installer test {0}" -f [guid]::NewGuid()) $installDirectory = Join-Path $temporaryRoot 'command directory' $artifactOne = Join-Path $temporaryRoot 'tht-one.exe' $artifactTwo = Join-Path $temporaryRoot 'tht-two.exe' $brokenArtifact = Join-Path $temporaryRoot 'tht-broken.exe' $userPathStore = Join-Path $temporaryRoot 'user-path.txt' New-Item -ItemType Directory -Path $temporaryRoot -Force | Out-Null try { $programOne = @' using System; public static class ProgramOne { public static void Main(string[] args) { if (args.Length == 1 && args[0] == "--help") { Console.WriteLine("Usage: tht"); return; } if (args.Length == 1 && args[0] == "version") { Console.WriteLine("tht test version one"); return; } Environment.Exit(2); } } '@ $programTwo = $programOne.Replace('ProgramOne', 'ProgramTwo').Replace('tht test version one', 'tht test version two') $brokenProgram = $programOne.Replace('ProgramOne', 'BrokenProgram').Replace('Console.WriteLine("Usage: tht"); return;', 'Environment.Exit(9);') Add-Type -TypeDefinition $programOne -OutputAssembly $artifactOne -OutputType ConsoleApplication Add-Type -TypeDefinition $programTwo -OutputAssembly $artifactTwo -OutputType ConsoleApplication Add-Type -TypeDefinition $brokenProgram -OutputAssembly $brokenArtifact -OutputType ConsoleApplication [System.IO.File]::WriteAllText($userPathStore, 'C:\Existing Bin') $env:THT_INSTALL_DIRECTORY = $installDirectory $env:THT_BUILD_ARTIFACT = $artifactOne $env:THT_BUILD_ARTIFACT_SHA256 = (Get-FileHash -Algorithm SHA256 -LiteralPath $artifactOne).Hash.ToLowerInvariant() $env:THT_USER_PATH_FILE = $userPathStore & $installer $installed = Join-Path $installDirectory 'tht.exe' if (-not (Test-Path -LiteralPath $installed)) { throw 'installer did not create tht.exe' } if ((& $installed version) -ne 'tht test version one') { throw 'installed tht.exe did not return version one' } $env:THT_BUILD_ARTIFACT = $brokenArtifact $env:THT_BUILD_ARTIFACT_SHA256 = (Get-FileHash -Algorithm SHA256 -LiteralPath $brokenArtifact).Hash.ToLowerInvariant() $brokenInstallFailed = $false try { & $installer } catch { $brokenInstallFailed = $true } if (-not $brokenInstallFailed) { throw 'installer accepted an invalid staged executable' } if ((& $installed version) -ne 'tht test version one') { throw 'invalid staged executable replaced the existing command' } $env:THT_BUILD_ARTIFACT = $artifactTwo $env:THT_BUILD_ARTIFACT_SHA256 = (Get-FileHash -Algorithm SHA256 -LiteralPath $artifactTwo).Hash.ToLowerInvariant() & $installer if ((& $installed version) -ne 'tht test version two') { throw 'installer did not replace the existing command' } & $installer if ((& $installed version) -ne 'tht test version two') { throw 'installer was not idempotent' } $storedPath = [System.IO.File]::ReadAllText($userPathStore) $segments = $storedPath -split ';' | Where-Object { $_ -ne '' } if ((@($segments | Where-Object { $_ -ieq $installDirectory }).Count) -ne 1) { throw 'installer did not preserve a single destination PATH entry' } if (-not ($segments | Where-Object { $_ -ieq 'C:\Existing Bin' })) { throw 'installer did not preserve existing user PATH entries' } Write-Output 'PowerShell tht installer tests passed.' } finally { Remove-Item Env:THT_INSTALL_DIRECTORY -ErrorAction SilentlyContinue Remove-Item Env:THT_BUILD_ARTIFACT -ErrorAction SilentlyContinue Remove-Item Env:THT_BUILD_ARTIFACT_SHA256 -ErrorAction SilentlyContinue Remove-Item Env:THT_USER_PATH_FILE -ErrorAction SilentlyContinue Remove-Item -LiteralPath $temporaryRoot -Recurse -Force -ErrorAction SilentlyContinue }