Tests/PowerTree.Output.Tests.ps1
|
$ErrorActionPreference = "Stop" $modulePath = Join-Path $PSScriptRoot "../PowerTree.psd1" Import-Module $modulePath -Force Describe "configuration helpers" { InModuleScope PowerTree { It "returns and flattens default settings" { $defaults = Get-DefaultConfig $defaults.Shared.LineStyle | Should -Be "Unicode" $defaults.FileSystem.Sorting.By | Should -Be "Name" (Get-FlattenedDefaultSettings FileSystem $defaults).Files.FileLimit | Should -Be -1 (Get-FlattenedDefaultSettings Registry $defaults).MaxDepth | Should -Be -1 } It "returns local and user config candidates" { $paths = @(Get-ConfigPaths) $paths.Count | Should -Be 5 $paths[-1] | Should -Match "\.PowerTree[/\\]config\.json$" } It "loads and merges file-system JSON settings" { $path = Join-Path $TestDrive "config.json" @{ Shared = @{ ShowExecutionStats = $false; LineStyle = "ASCII" } FileSystem = @{ MaxDepth = 2 ExcludeDirectories = @("bin") HumanReadableSizes = $false Files = @{ IncludeExtensions = @("ps1"); FileLimit = 3 } Sorting = @{ By = "Size"; SortFolders = $true } } } | ConvertTo-Json -Depth 5 | Set-Content $path $settings = Get-SettingsFromJson FileSystem @($path) $settings.LineStyle | Should -Be "ASCII" $settings.MaxDepth | Should -Be 2 $settings.Files.IncludeExtensions | Should -Be @("ps1") $settings.Files.FileLimit | Should -Be 3 $settings.Sorting.SortFolders | Should -BeTrue } It "uses defaults for malformed JSON" { $path = Join-Path $TestDrive "invalid.json" Set-Content $path "{invalid" $settings = Get-SettingsFromJson Registry @($path) -WarningAction SilentlyContinue $settings.MaxDepth | Should -Be -1 $settings.LineStyle | Should -Be "Unicode" } It "initializes a missing config and preserves an existing config" { $originalHome = $env:HOME $originalUserProfile = $env:USERPROFILE $env:HOME = Join-Path $TestDrive "home" $env:USERPROFILE = $env:HOME try { Initialize-ConfigFile $path = Join-Path $env:HOME ".PowerTree/config.json" $path | Should -Exist Set-Content $path "sentinel" Initialize-ConfigFile (Get-Content $path -Raw).TrimEnd() | Should -Be "sentinel" } finally { $env:HOME = $originalHome $env:USERPROFILE = $originalUserProfile } } } } Describe "file-system output helpers" { InModuleScope PowerTree { BeforeEach { $script:lineStyle = Build-TreeLineStyle Unicode $script:header = Get-HeaderTable $false $false $false $true $false $lineStyle } It "composes headers and file output lines" { $path = Join-Path $TestDrive "file.txt" [System.IO.File]::WriteAllBytes($path, [byte[]]::new(12)) $output = Build-OutputLine $header (Get-Item $path) "└───" $false $header.HeaderColumns | Should -Be @("Size", "Hierarchy") $output.Line | Should -Match "^12\s+└───file\.txt$" $output.SizeColor | Should -Be "Green" $output.SizePosition | Should -Be 0 } It "uses recursive size for directory lines" { $output = Build-OutputLine $header (Get-Item $TestDrive) "└───" $false 99 $output.Line | Should -Match "^99\s+└───" $output.DirSize | Should -Be 99 $output.SizeColor | Should -BeNullOrEmpty } It "writes headers and lines to one builder" { $builder = [System.Text.StringBuilder]::new() Write-HeaderToOutput $header $builder $lineStyle Write-OutputLine "body" $builder $builder.ToString() | Should -Match "Size.*Hierarchy" $builder.ToString() | Should -Match "body" } It "formats tree configuration" { $config = [pscustomobject]@{ SortBy = "Size"; SortDescending = $true; HeaderTable = $header HumanReadableSize = $true; DirectoryOnly = $false; ShowHiddenFiles = $true PruneEmptyFolders = $true; MaxDepth = 2; FileLimit = 4 ExcludeDirectories = @("bin") ChildItemFileParams = @{ Include = @("*.ps1"); Exclude = @("*.tmp") } FileSizeBounds = @{ LowerBound = 1KB; UpperBound = 2KB } } $content = (Get-TreeConfigurationData $config) -join "`n" $content | Should -Match "Size Descending" $content | Should -Match "Between 1KB and 2KB" $content | Should -Match "\*\.ps1" } It "builds file output with configuration and stats placeholder" { $config = [pscustomobject]@{ OutFile = "tree.txt"; Path = $TestDrive; SortBy = "Name"; SortDescending = $false HeaderTable = @{ HeaderColumns = @("Hierarchy") }; HumanReadableSize = $false DirectoryOnly = $false; ShowHiddenFiles = $false; PruneEmptyFolders = $false MaxDepth = -1; FileLimit = -1; ExcludeDirectories = @() ChildItemFileParams = @{}; FileSizeBounds = $null } $builder = Invoke-OutputBuilder $config $true $true $builder.ToString() | Should -Match "# PowerTree Output" $builder.ToString() | Should -Match "Sort By" $builder.ToString() | Should -Match "Append the stats here later!!" $config.OutFile = "" Invoke-OutputBuilder $config | Should -BeNullOrEmpty } It "replaces the tree stats placeholder" { $stats = [TreeStats]::new() $stats.FilesPrinted = 2 $stats.FoldersPrinted = 1 $stats.TotalSize = 12 $builder = [System.Text.StringBuilder]::new("Append the stats here later!!") Show-TreeStats $stats ([timespan]::FromMilliseconds(10)) $builder $lineStyle $builder.ToString() | Should -Match "Files\s+Folders" $builder.ToString() | Should -Match "2\s+1\s+3" $builder.ToString() | Should -Not -Match "Append the stats" } It "writes piped content and creates parent folders" { $path = Join-Path $TestDrive "nested/output.txt" @("first", "second") | Write-ToFile -FilePath $path -OpenOutputFileOnFinish $false Get-Content $path | Should -Be @("first", "second") } It "dispatches host configuration formatting" { Mock Write-Host Mock Get-TreeConfigurationData { @("setting") } Write-ConfigurationToHost ([pscustomobject]@{ OutFile = ""; HeaderTable = @{} }) Should -Invoke Get-TreeConfigurationData -Times 1 Should -Invoke Write-Host -ParameterFilter { $Object -eq "Configuration" } -Times 1 } It "prints help and examples" { Mock Write-Host Set-Item Function:Write-CheckForUpdates {} Mock Write-CheckForUpdates Write-Examples Write-Help Should -Invoke Write-Host -ParameterFilter { $Object -eq "EXAMPLES:" } -Times 1 Should -Invoke Write-Host -ParameterFilter { $Object -eq "BASIC OPTIONS:" } -Times 1 Should -Invoke Write-CheckForUpdates -Times 1 } } } Describe "Edit-PowerTreeConfig" { InModuleScope PowerTree { It "creates the default config and opens it" { $originalHome = $env:HOME $originalUserProfile = $env:USERPROFILE $env:HOME = Join-Path $TestDrive "editor-home" $env:USERPROFILE = $env:HOME Mock Get-ConfigPaths { @() } Mock Start-Process try { Edit-PowerTreeConfig $path = Join-Path $env:HOME ".PowerTree/config.json" $path | Should -Exist (Get-Content $path -Raw | ConvertFrom-Json).Shared.LineStyle | Should -Be "Unicode" Should -Invoke Start-Process -Times 1 } finally { $env:HOME = $originalHome $env:USERPROFILE = $originalUserProfile } } } } |