Tests/show-syntax.Tests.ps1
|
BeforeAll { $ModulePath = Join-Path $PSScriptRoot '..' $ModulePath = Join-Path $ModulePath 'show-syntax.psd1' Import-Module $ModulePath -Force $ESC = [char]27 # Create a temp directory for test files $script:TempDir = Join-Path ([System.IO.Path]::GetTempPath()) "show-syntax-tests-$(New-Guid)" New-Item -ItemType Directory -Path $script:TempDir | Out-Null } AfterAll { Remove-Module show-syntax -ErrorAction SilentlyContinue if (Test-Path $script:TempDir) { Remove-Item -Recurse -Force $script:TempDir } } Describe 'Show-Syntax' { Context 'File resolution and error handling' { It 'Writes an error when the file does not exist' { $fakePath = Join-Path $script:TempDir 'nonexistent.ps1' { Show-Syntax -Path $fakePath -ErrorAction Stop } | Should -Throw } It 'Writes an error when the path is a directory' { { Show-Syntax -Path $script:TempDir -ErrorAction Stop } | Should -Throw } } Context 'Line numbers' { BeforeAll { $script:LineNumberFile = Join-Path $script:TempDir 'sample.txt' Set-Content -Path $script:LineNumberFile -Value @('first line', 'second line', 'third line') -Encoding UTF8 } AfterAll { Remove-Item -Path $script:LineNumberFile -ErrorAction SilentlyContinue } It 'Prepends line numbers when -ShowLineNumbers is used' { $output = Show-Syntax -Path $script:LineNumberFile -ShowLineNumbers 6>&1 | ForEach-Object { $_.ToString() } # At least one output line should contain a number followed by the content $contentLines = $output | Where-Object { $_ -match '\d' -and $_ -notmatch '^[─]' } $contentLines | Should -Not -BeNullOrEmpty # Line 1 content should appear $lineWithFirst = $contentLines | Where-Object { $_ -match 'first line' } $lineWithFirst | Should -Not -BeNullOrEmpty # The line with 'first line' should also contain the line number '1' $lineWithFirst | ForEach-Object { $_ | Should -Match '1' } } It 'Does NOT prepend line numbers when -ShowLineNumbers is omitted' { $output = Show-Syntax -Path $script:LineNumberFile 6>&1 | ForEach-Object { $_.ToString() } $contentLines = $output | Where-Object { $_ -match 'first line' } $contentLines | Should -Not -BeNullOrEmpty # Should not start with padded digits followed by a space before the content $contentLines | ForEach-Object { # After stripping ANSI codes, there should be no leading digits/spaces before 'first line' $stripped = $_ -replace "$ESC\[[0-9;]*m", '' $stripped | Should -Not -Match '^\s*\d+\s+first line' } } } Context 'Language detection' { BeforeAll { $script:JsonFile = Join-Path $script:TempDir 'data.json' $jsonContent = '{"name": "show-syntax", "version": "1.0.0", "active": true}' Set-Content -Path $script:JsonFile -Value $jsonContent -Encoding UTF8 $script:Ps1File = Join-Path $script:TempDir 'script.ps1' Set-Content -Path $script:Ps1File -Value 'function Get-Foo { return $true }' -Encoding UTF8 $script:XmlFile = Join-Path $script:TempDir 'config.xml' Set-Content -Path $script:XmlFile -Value '<root><item key="value">text</item></root>' -Encoding UTF8 $script:MdFile = Join-Path $script:TempDir 'notes.md' Set-Content -Path $script:MdFile -Value '# Heading' -Encoding UTF8 } AfterAll { Remove-Item -Path $script:JsonFile, $script:Ps1File, $script:XmlFile, $script:MdFile -ErrorAction SilentlyContinue } It 'Recognizes a .json file and applies ANSI colour codes' { $output = (Show-Syntax -Path $script:JsonFile 6>&1 | ForEach-Object { $_.ToString() }) -join '' # Output should contain at least one ANSI escape sequence $output | Should -Match "$ESC\[" } It 'Recognizes a .ps1 file and applies ANSI colour codes' { $output = (Show-Syntax -Path $script:Ps1File 6>&1 | ForEach-Object { $_.ToString() }) -join '' $output | Should -Match "$ESC\[" } It 'Recognizes a .xml file and applies ANSI colour codes' { $output = (Show-Syntax -Path $script:XmlFile 6>&1 | ForEach-Object { $_.ToString() }) -join '' $output | Should -Match "$ESC\[" } It 'Recognizes a .md file and applies ANSI colour codes' { $output = (Show-Syntax -Path $script:MdFile 6>&1 | ForEach-Object { $_.ToString() }) -join '' $output | Should -Match "$ESC\[" } It 'Applies highlighting when -Language is explicitly specified' { # Use a .txt file but force JSON highlighting $txtFile = Join-Path $script:TempDir 'data.txt' Set-Content -Path $txtFile -Value '{"key": "value"}' -Encoding UTF8 $output = (Show-Syntax -Path $txtFile -Language json 6>&1 | ForEach-Object { $_.ToString() }) -join '' $output | Should -Match "$ESC\[" Remove-Item -Path $txtFile -ErrorAction SilentlyContinue } } Context 'Pipeline input' { BeforeAll { $script:PipeFile1 = Join-Path $script:TempDir 'pipe1.ps1' $script:PipeFile2 = Join-Path $script:TempDir 'pipe2.ps1' Set-Content -Path $script:PipeFile1 -Value '$x = 1' -Encoding UTF8 Set-Content -Path $script:PipeFile2 -Value '$y = 2' -Encoding UTF8 } AfterAll { Remove-Item -Path $script:PipeFile1, $script:PipeFile2 -ErrorAction SilentlyContinue } It 'Accepts a path via pipeline by value' { $output = ($script:PipeFile1 | Show-Syntax 6>&1 | ForEach-Object { $_.ToString() }) -join '' $output | Should -Match '\$x' } It 'Accepts multiple files via pipeline from Get-ChildItem' { $output = (Get-ChildItem -Path $script:TempDir -Filter 'pipe*.ps1' | Show-Syntax 6>&1 | ForEach-Object { $_.ToString() }) -join '' $output | Should -Match '\$x' $output | Should -Match '\$y' } } Context 'Output structure' { BeforeAll { $script:StructFile = Join-Path $script:TempDir 'structure.txt' Set-Content -Path $script:StructFile -Value @('line one', 'line two') -Encoding UTF8 } AfterAll { Remove-Item -Path $script:StructFile -ErrorAction SilentlyContinue } It 'Outputs a header containing the file path' { $output = Show-Syntax -Path $script:StructFile 6>&1 | ForEach-Object { $_.ToString() } $headerLine = $output | Where-Object { $_ -match [regex]::Escape('structure.txt') } $headerLine | Should -Not -BeNullOrEmpty } It 'Outputs the file content lines' { $output = Show-Syntax -Path $script:StructFile 6>&1 | ForEach-Object { $_.ToString() } ($output -join '') | Should -Match 'line one' ($output -join '') | Should -Match 'line two' } } } |