Added unit tests

This commit is contained in:
simwai
2024-05-21 22:32:03 +02:00
parent 12b5376cb6
commit d124716196
2 changed files with 184 additions and 18 deletions
+151
View File
@@ -0,0 +1,151 @@
# Ensure the latest version of Pester is installed and imported
if (-not (Get-Module -ListAvailable -Name Pester | Where-Object { $_.Version -ge [version]"5.3.1" })) {
Install-Module -Name Pester -Force -Scope CurrentUser -SkipPublisherCheck
}
Import-Module -Name Pester -MinimumVersion 5.3.1
# Describe block to contain all tests and setup
Describe "Setup and Tests" {
BeforeAll {
# Construct the absolute path to setup.ps1
$setupScriptPath = Join-Path -Path (Get-Location) -ChildPath "setup.ps1"
# Check if the setup script exists
if (-Not (Test-Path -Path $setupScriptPath)) {
Write-Host "Error: setup.ps1 script not found at path: $setupScriptPath"
exit 1
}
# Load the script to test
. $setupScriptPath
}
Context "Write-Log Tests" -Tag "Unit" {
It "should write INFO level log" {
$logFilePath = Join-Path $env:TEMP "script_log.txt"
Remove-Item $logFilePath -ErrorAction SilentlyContinue
Write-Log -Message "Test Info Message" -Level "INFO"
$logContent = Get-Content $logFilePath
$logContent | Should -Contain "INFO: Test Info Message"
}
It "should write ERROR level log" {
$logFilePath = Join-Path $env:TEMP "script_log.txt"
Remove-Item $logFilePath -ErrorAction SilentlyContinue
Write-Log -Message "Test Error Message" -Level "ERROR"
$logContent = Get-Content $logFilePath
$logContent | Should -Contain "ERROR: Test Error Message"
}
}
Context "Get-UserSelection Tests" -Tag "Unit" {
It "should handle valid input correctly" {
Mock Read-Host { return "A,B,C" }
$options = @("Option1", "Option2", "Option3")
$indices = Get-UserSelection -prompt "Select options" -options $options -defaultChoice "A"
$indices | Should -Be @(0, 1, 2)
}
It "should return indices for selected options" {
Mock Read-Host { return "a,b" }
$options = @("Option1", "Option2", "Option3")
$indices = Get-UserSelection -prompt "Select options" -options $options
$indices | Should -Be @(0, 1)
}
It "should return default choice if no input" {
Mock Read-Host { return "" }
$options = @("Option1", "Option2", "Option3")
$indices = Get-UserSelection -prompt "Select options" -options $options -defaultChoice "C"
$indices | Should -Be @(2)
}
It "should handle mixed valid and invalid input correctly" {
Mock Read-Host { return "A,X,B,Y,C,Z" }
$options = @("Option1", "Option2", "Option3")
$indices = Get-UserSelection -prompt "Select options" -options $options -defaultChoice "A"
$indices | Should -Be @(0, 1, 2)
}
It "should handle invalid input gracefully" {
Mock Read-Host { return "x,y,z" }
$options = @("Option1", "Option2", "Option3")
$indices = Get-UserSelection -prompt "Select options" -options $options -defaultChoice "A"
$indices | Should -Be @()
}
It "should handle input without whitespace" {
Mock Read-Host { return "a,b,c" }
$options = @("Option1", "Option2", "Option3")
$indices = Get-UserSelection -prompt "Select options" -options $options
$indices | Should -Be @(0, 1, 2)
}
}
Context "Exit-Script Tests" -Tag "Unit" {
BeforeAll {
# Set environment variables for the test
$global:OldVirtualPath = "C:\old\path"
$global:LogFilePath = "C:\path\to\logfile.log"
}
BeforeEach {
Mock Write-Log {}
Mock Start-Process {}
Mock Read-Host { return "Y" }
# Backup the original PATH
$global:OriginalPath = $env:PATH
}
AfterEach {
# Restore the original PATH
$env:PATH = $OriginalPath
}
It "should exit with the given exit code without waiting for key press" {
$exitCode = Exit-Script -exitCode 0 -isSubShell $true -waitForKeypress $false
$exitCode | Should -Be 0
}
It "should prompt to open log file on error" {
Exit-Script -exitCode 1 -isSubShell $true -waitForKeypress $false
Assert-MockCalled Read-Host -Exactly 1
Assert-MockCalled Start-Process -Exactly 1
}
It "should restore the environment path if OldVirtualPath is set" {
# Set a different PATH to simulate the change
$env:PATH = "C:\new\path"
Exit-Script -exitCode 0 -isSubShell $true -waitForKeypress $false
$env:PATH | Should -Be "C:\old\path"
}
}
Context "Get-PythonVersionTag Tests" -Tag "Unit" {
It "should return the correct Python version tag" {
Mock Invoke-Expression { param($cmd) return "cp39-win_amd64" }
$tag = Get-PythonVersionTag
$tag | Should -Be "cp39-win_amd64"
}
}
}
+33 -18
View File
@@ -14,6 +14,7 @@ function Write-Log {
[string]$Message, [string]$Message,
[string]$Level = 'INFO' [string]$Level = 'INFO'
) )
switch ($Level) { switch ($Level) {
'INFO' { Write-Host $Message -ForegroundColor Green } 'INFO' { Write-Host $Message -ForegroundColor Green }
'WARNING' { Write-Host $Message -ForegroundColor Yellow } 'WARNING' { Write-Host $Message -ForegroundColor Yellow }
@@ -47,15 +48,20 @@ function Get-UserSelection {
$_.Trim().ToUpper() $_.Trim().ToUpper()
} }
# Convert each selection from letter to index # Convert each selection from letter to index and validate
$indices = $selections | ForEach-Object { $indices = @()
if ($_ -match '^[A-Z]$') { foreach ($selection in $selections) {
# Ensure the input is a single uppercase letter if ($selection -match '^[A-Z]$') {
[int][char]$_ - [int][char]'A' $index = [int][char]$selection - [int][char]'A'
if ($index -ge 0 -and $index -lt $options.Length) {
$indices += $index
}
else {
Write-Log "Invalid input: $selection. Please enter letters within the valid range of options." -Level 'ERROR'
}
} }
else { else {
Write-Log "Invalid input: $_. Please enter letters between A and Z." -Level 'ERROR' Write-Log "Invalid input: $selection. Please enter letters between A and Z." -Level 'ERROR'
continue
} }
} }
@@ -65,14 +71,14 @@ function Get-UserSelection {
function Exit-Script { function Exit-Script {
param ( param (
[int]$exitCode, [int]$exitCode,
[bool]$isSubShell = $true [bool]$isSubShell = $true,
[bool]$waitForKeypress = $true
) )
if ($OldVirtualPath) { if ($OldVirtualPath) {
$env:PATH = $OldVirtualPath $env:PATH = $OldVirtualPath
} }
# Check if the script is exiting with an error and it's not a subshell
if ($exitCode -ne 0 -and $isSubShell) { if ($exitCode -ne 0 -and $isSubShell) {
Write-Log "Script failed. Would you like to open the log file? (Y/N)" -Level 'PROMPT' Write-Log "Script failed. Would you like to open the log file? (Y/N)" -Level 'PROMPT'
$openLog = Read-Host $openLog = Read-Host
@@ -81,25 +87,29 @@ function Exit-Script {
} }
} }
Write-Log "Press any key to exit..." if ($waitForKeypress) {
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null Write-Log "Press any key to exit..."
exit $exitCode $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
}
return $exitCode
} }
# Function to handle installation and conflict resolution # Function to handle installation
function Install-And-Resolve { function Install {
param ([string]$InputPath) param ([string]$InputPath)
if (-not $InputPath) { if (-not $InputPath) {
Write-Log "ERROR: No input provided for installation." -Level 'ERROR' Write-Log "No input provided for installation." -Level 'ERROR'
Exit-Script -exitCode 1 Exit-Script -exitCode 1
} }
Write-Log "Installing $InputPath..." Write-Log "Installing $InputPath..."
$installCmd = if (Test-Path $InputPath) { $VenvPip + @('install', '-r', $InputPath) } else { $VenvPip + @('install', $InputPath) } $installCmd = if (Test-Path $InputPath) { $VenvPip + @('install', '-r', $InputPath) } else { $VenvPip + @('install', $InputPath) }
$output = & $installCmd[0] $installCmd[1..$installCmd.Length] 2>&1 $output = & $installCmd[0] $installCmd[1..$installCmd.Length] 2>&1
$output | Out-File $LogFilePath -Append $output | Out-File $LogFilePath -Append
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Write-Log "Conflict detected, attempting to resolve..." -Level 'ERROR' Write-Log "Conflict detected. Exiting now..." -Level 'ERROR'
& $VenvPip[0] $VenvPip[1..$VenvPip.Length] 'check' | Out-File "conflicts.txt"
Exit-Script -exitCode 1 Exit-Script -exitCode 1
} }
} }
@@ -111,6 +121,11 @@ function Get-PythonVersionTag {
return "$pythonVersion-$architecture" return "$pythonVersion-$architecture"
} }
# Exit in test environment
if ($MyInvocation.InvocationName -ne $MyInvocation.MyCommand.Name) {
exit
}
# Check for admin privileges and elevate if necessary # Check for admin privileges and elevate if necessary
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Log "Requesting administrative privileges..." -Level 'ERROR' Write-Log "Requesting administrative privileges..." -Level 'ERROR'
@@ -179,7 +194,7 @@ foreach ($index in $selectedIndices) {
$filePath = Join-Path $ProjectDir $RequirementFiles[$index] $filePath = Join-Path $ProjectDir $RequirementFiles[$index]
if (Test-Path $filePath) { if (Test-Path $filePath) {
Install-And-Resolve $filePath Install $filePath
} }
else { else {
Write-Log "Requirement file not found: $filePath" -Level 'ERROR' Write-Log "Requirement file not found: $filePath" -Level 'ERROR'