tests/Menu.Tests.ps1
|
$moduleRoot = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $moduleRoot 'Octa.psd1') -Force . (Join-Path $moduleRoot 'private\StatusPanel.ps1') . (Join-Path $moduleRoot 'private\Banner.ps1') . (Join-Path $moduleRoot 'private\Menu.ps1') Describe 'Get-OctaTruncated' { It 'returns text unchanged when it already fits' { Get-OctaTruncated -Text 'short' -MaxWidth 20 | Should Be 'short' } It 'truncates with an ASCII ellipsis when text is longer than MaxWidth' { $result = Get-OctaTruncated -Text 'this is a much longer string than allowed' -MaxWidth 20 $result.Length | Should Be 20 $result | Should Match '\.\.\.$' } It 'handles an empty string without throwing' { Get-OctaTruncated -Text '' -MaxWidth 20 | Should Be '' } It 'does not truncate a string exactly at MaxWidth' { $exact = 'exact20characters!!!' Get-OctaTruncated -Text $exact -MaxWidth $exact.Length | Should Be $exact } } Describe 'Menu label width (real data, 009/010 UI regression)' { # Found via real user testing: 'Actualizador de Software' (24 chars) and 'Historial de # Limpiezas' (22 chars) overflowed the fixed 22-char label column in Spanish, and long # category descriptions (some 150+ chars) wrapped unpredictably on a narrow terminal - # both fixed by shortening those two labels and dynamically truncating descriptions to the # real terminal width (Get-OctaTruncated) instead of printing them unbounded. $enStrings = Import-LocalizedData -BaseDirectory $moduleRoot -FileName 'Octa.psd1' -UICulture 'en-US' $esStrings = Import-LocalizedData -BaseDirectory $moduleRoot -FileName 'Octa.psd1' -UICulture 'es-ES' # Only the fixed-width label column (22 chars) matters here - "Desc"-suffixed keys and # menuNavHint all render across the full terminal width via Get-OctaTruncated instead, so # they're excluded from this check. Group labels (010) are real fixed-width labels too, so # they're included alongside the "menu*" ones. $labelKeys = ($enStrings.Keys + $esStrings.Keys) | Sort-Object -Unique | Where-Object { ($_ -like 'menu*' -or $_ -like 'group*') -and $_ -ne 'menuNavHint' -and $_ -notlike '*Desc' } foreach ($key in $labelKeys) { It "'$key' fits the 22-char label column in both locales" { $enStrings[$key].Length | Should BeLessThan 23 $esStrings[$key].Length | Should BeLessThan 23 } } } Describe 'Write-OctaMenuRow' { It 'pads the rendered line to exactly the requested width' { $item = [pscustomobject]@{ Key = '1'; Label = 'Telemetry'; Description = 'Short desc' } $info = Write-OctaMenuRow -Item $item -IsSelected $true -LabelWidth 22 -Width 60 6>&1 $info.MessageData.Message.Length | Should Be 60 } It 'shows the pointer only for the selected item' { $item = [pscustomobject]@{ Key = '1'; Label = 'Telemetry'; Description = '' } $selected = (Write-OctaMenuRow -Item $item -IsSelected $true -LabelWidth 22 -Width 60 6>&1).MessageData.Message $unselected = (Write-OctaMenuRow -Item $item -IsSelected $false -LabelWidth 22 -Width 60 6>&1).MessageData.Message $selected.Substring(0, 1) | Should Be '>' $unselected.Substring(0, 1) | Should Be ' ' } It 'never throws for a selected or unselected item at a small width' { $item = [pscustomobject]@{ Key = 'x'; Label = 'Exit'; Description = '' } { Write-OctaMenuRow -Item $item -IsSelected $false -LabelWidth 22 -Width 30 } | Should Not Throw { Write-OctaMenuRow -Item $item -IsSelected $true -LabelWidth 22 -Width 30 } | Should Not Throw } } |