diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs index ad247b2b34..67d6da5d55 100644 --- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs +++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs @@ -994,6 +994,7 @@ namespace System.Management.Automation.Runspaces ") .AddScriptBlockExpressionBinding(@" Set-StrictMode -Off + $newline = [Environment]::Newline function Get-ConciseViewPositionMessage { @@ -1049,7 +1050,6 @@ namespace System.Management.Automation.Runspaces $offsetWhitespace = '' $message = '' $prefix = '' - $newline = [Environment]::Newline if ($myinv -and $myinv.ScriptName -or $myinv.ScriptLineNumber -gt 1 -or $err.CategoryInfo.Category -eq 'ParserError') { $useTargetObject = $false @@ -1100,18 +1100,18 @@ namespace System.Management.Automation.Runspaces $offsetInLine = 0 } else { - $positionMessage = $myinv.PositionMessage.Split('+') - $line = $positionMessage[1] - $highlightLine = $positionMessage[$positionMessage.Count - 1] + $positionMessage = $myinv.PositionMessage.Split($newline) + $line = $positionMessage[1].Substring(1) # skip the '+' at the start + $highlightLine = $positionMessage[$positionMessage.Count - 1].Substring(1) $offsetLength = $highlightLine.Trim().Length $offsetInLine = $highlightLine.IndexOf('~') } - if (-not $line.EndsWith(""`n"")) { + if (-not $line.EndsWith($newline)) { $line += $newline } - # don't color the whole line red + # don't color the whole line if ($offsetLength -lt $line.Length - 1) { $line = $line.Insert($offsetInLine + $offsetLength, $resetColor).Insert($offsetInLine, $accentColor) } @@ -1120,16 +1120,15 @@ namespace System.Management.Automation.Runspaces $offsetWhitespace = ' ' * $offsetInLine $prefix = ""${accentColor}${headerWhitespace} ${verticalBar} ${errorColor}"" if ($highlightLine -ne '') { - $posMsg += ""${newline}${prefix}${highlightLine}${newline}"" + $posMsg += ""${prefix}${highlightLine}${newline}"" } $message = ""${prefix}"" } if (! $err.ErrorDetails -or ! $err.ErrorDetails.Message) { - # we use `n instead of $newline here because that's what is in the message - if ($err.CategoryInfo.Category -eq 'ParserError' -and $err.Exception.Message.Contains(""~`n"")) { + if ($err.CategoryInfo.Category -eq 'ParserError' -and $err.Exception.Message.Contains(""~$newline"")) { # need to parse out the relevant part of the pre-rendered positionmessage - $message += $err.Exception.Message.split(""~`n"")[1].split(""${newline}${newline}"")[0] + $message += $err.Exception.Message.split(""~$newline"")[1].split(""${newline}${newline}"")[0] } elseif ($err.Exception) { $message += $err.Exception.Message @@ -1229,7 +1228,7 @@ namespace System.Management.Automation.Runspaces if ($posmsg -ne '') { - $posmsg = ""`n"" + $posmsg + $posmsg = $newline + $posmsg } if ($err.PSMessageDetails) { @@ -1253,24 +1252,24 @@ namespace System.Management.Automation.Runspaces $indentString = '+ CategoryInfo : ' + $err.CategoryInfo } - $posmsg += ""`n"" + $indentString + $posmsg += $newline + $indentString $indentString = ""+ FullyQualifiedErrorId : "" + $err.FullyQualifiedErrorId - $posmsg += ""`n"" + $indentString + $posmsg += $newline + $indentString $originInfo = $err.OriginInfo if (($null -ne $originInfo) -and ($null -ne $originInfo.PSComputerName)) { $indentString = ""+ PSComputerName : "" + $originInfo.PSComputerName - $posmsg += ""`n"" + $indentString + $posmsg += $newline + $indentString } if ($ErrorView -eq 'CategoryView') { $err.CategoryInfo.GetMessage() } elseif (! $err.ErrorDetails -or ! $err.ErrorDetails.Message) { - $err.Exception.Message + $posmsg + ""`n"" + $err.Exception.Message + $posmsg + $newline } else { $err.ErrorDetails.Message + $posmsg } diff --git a/test/powershell/engine/Formatting/ErrorView.Tests.ps1 b/test/powershell/engine/Formatting/ErrorView.Tests.ps1 index d96aa303e2..10e8b5136c 100644 --- a/test/powershell/engine/Formatting/ErrorView.Tests.ps1 +++ b/test/powershell/engine/Formatting/ErrorView.Tests.ps1 @@ -19,6 +19,13 @@ Describe 'Tests for $ErrorView' -Tag CI { } Context 'ConciseView tests' { + BeforeEach { + $testScriptPath = Join-Path -Path $TestDrive -ChildPath 'test.ps1' + } + + AfterEach { + Remove-Item -Path $testScriptPath -Force -ErrorAction SilentlyContinue + } It 'Cmdlet error should be one line of text' { Get-Item (New-Guid) -ErrorVariable e -ErrorAction SilentlyContinue @@ -34,12 +41,11 @@ Describe 'Tests for $ErrorView' -Tag CI { $b = 2 '@ - $testScriptPath = Join-Path -Path $TestDrive -ChildPath 'test.ps1' Set-Content -Path $testScriptPath -Value $testScript - $e = { & $testScriptPath } | Should -Throw -ErrorId 'UnexpectedToken' -PassThru - $e | Out-String | Should -BeLike "*${testScriptPath}:4*" + $e = { & $testScriptPath } | Should -Throw -ErrorId 'UnexpectedToken' -PassThru | Out-String + $e | Should -BeLike "*${testScriptPath}:4*" # validate line number is shown - $e | Out-String | Should -BeLike '* 4 *' + $e | Should -BeLike '* 4 *' } It "Remote errors show up correctly" { @@ -61,11 +67,25 @@ Describe 'Tests for $ErrorView' -Tag CI { It "Pester Should shows test file and not pester" { $testScript = '1 + 1 | Should -Be 3' - $testScriptPath = Join-Path -Path $TestDrive -ChildPath 'mytest.ps1' + Set-Content -Path $testScriptPath -Value $testScript - $e = { & $testScriptPath } | Should -Throw -ErrorId 'PesterAssertionFailed' -PassThru - $e | Out-String | Should -BeLike "*$testScriptPath*" - $e | Out-String | Should -Not -BeLike '*pester*' + $e = { & $testScriptPath } | Should -Throw -ErrorId 'PesterAssertionFailed' -PassThru | Out-String + $e | Should -BeLike "*$testScriptPath*" + $e | Should -Not -BeLike '*pester*' + } + + It "Long lines should be rendered correctly with indentation" { + $testscript = @' + $myerrors = [System.Collections.ArrayList]::new() + Copy-Item (New-Guid) (New-Guid) -ErrorVariable +myerrors -ErrorAction SilentlyContinue + $error[0] +'@ + + Set-Content -Path $testScriptPath -Value $testScript + $e = & $testScriptPath | Out-String + $e | Should -BeLike "*${testScriptPath}:2*" + # validate line number is shown + $e | Should -BeLike '* 2 *' } }