Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for VSCode problem-tracking for failed assertions #1700

Merged
merged 5 commits into from
Oct 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,6 @@ ShowFullErrors : Show full errors including Pester internal stack. (Fals
WriteDebugMessages : Write Debug messages to screen. (False, default: False)
WriteDebugMessagesFrom : Write Debug messages from a given source, WriteDebugMessages must be set to true for this to work. You can use like wildcards to get messages from multiple sources, as well as * to get everything. (*, default: *)
ShowNavigationMarkers : Write paths after every block and test, for easy navigation in VSCode. (False, default: False)
WriteVSCodeMarker : Write VSCode marker for better integration with VSCode. (False, default: False)
```

The configuration object can be constructed either via the Default static property or by casting a hashtable to it. You can also cast a hashtable to any of its sections. Here are three different ways to the same goal:
Expand Down
1 change: 0 additions & 1 deletion src/Pester.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,6 @@ function Invoke-Pester {
Debug.WriteDebugMessages - Write Debug messages to screen.
Debug.WriteDebugMessagesFrom - Write Debug messages from a given source, WriteDebugMessages must be set to true for this to work. You can use like wildcards to get messages from multiple sources, as well as * to get everything.
Available options: "Discovery", "Skip", "Filter", "Mock", "CodeCoverage"
Debug.WriteVSCodeMarker - Write VSCode marker for better integration with VSCode.

.PARAMETER EnableExit
(Deprecated v4)
Expand Down
19 changes: 0 additions & 19 deletions src/csharp/Pester/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@ public static DebugConfiguration ShallowClone(DebugConfiguration configuration)
WriteDebugMessages = new BoolOption("Write Debug messages to screen.", false);
WriteDebugMessagesFrom = new StringArrayOption("Write Debug messages from a given source, WriteDebugMessages must be set to true for this to work. You can use like wildcards to get messages from multiple sources, as well as * to get everything.", new string[] { "Discovery", "Skip", "Filter", "Mock", "CodeCoverage" });
ShowNavigationMarkers = new BoolOption("Write paths after every block and test, for easy navigation in VSCode.", false);
WriteVSCodeMarker = new BoolOption("Write VSCode marker for better integration with VSCode.", false);
ReturnRawResultObject = new BoolOption("Returns unfiltered result object, this is for development only. Do not rely on this object for additional properties, non-public properties will be renamed without previous notice.", false);
}

Expand All @@ -474,7 +473,6 @@ public DebugConfiguration(IDictionary configuration) : this()
WriteDebugMessages = configuration.GetValueOrNull<bool>("WriteDebugMessages") ?? WriteDebugMessages;
WriteDebugMessagesFrom = configuration.GetArrayOrNull<string>("WriteDebugMessagesFrom") ?? WriteDebugMessagesFrom;
ShowNavigationMarkers = configuration.GetValueOrNull<bool>("ShowNavigationMarkers") ?? ShowNavigationMarkers;
WriteVSCodeMarker = configuration.GetValueOrNull<bool>("WriteVSCodeMarker") ?? WriteVSCodeMarker;
ReturnRawResultObject = configuration.GetValueOrNull<bool>("ReturnRawResultObject") ?? ReturnRawResultObject;
}
}
Expand All @@ -483,7 +481,6 @@ public DebugConfiguration(IDictionary configuration) : this()
private BoolOption _writeDebugMessages;
private StringArrayOption _writeDebugMessagesFrom;
private BoolOption _showNavigationMarkers;
private BoolOption _writeVsCodeMarker;
private BoolOption _returnRawResultObject;

public BoolOption ShowFullErrors
Expand Down Expand Up @@ -550,22 +547,6 @@ public BoolOption ShowNavigationMarkers
}
}

public BoolOption WriteVSCodeMarker
{
get { return _writeVsCodeMarker; }
set
{
if (_writeVsCodeMarker == null)
{
_writeVsCodeMarker = value;
}
else
{
_writeVsCodeMarker = new BoolOption(_writeVsCodeMarker, value.Value);
}
}
}

public BoolOption ReturnRawResultObject
{
get { return _returnRawResultObject; }
Expand Down
28 changes: 17 additions & 11 deletions src/functions/Output.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -586,18 +586,24 @@ function Get-WriteScreenPlugin ($Verbosity) {
}

Failed {
& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail "$margin[-] $out" -NoNewLine
& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.FailTime " $humanTime"

# review how we should write errors for VS code based on https://github.com/PowerShell/vscode-powershell/pull/2447
# and use the env variable mentioned there
# if($PesterPreference.Debug.WriteVSCodeMarker.Value) {
# & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail $($_test.ErrorRecord[-1].DisplayStackTrace -replace '(?m)^',$error_margin)
# & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail $($_test.ErrorRecord[-1].DisplayErrorMessage -replace '(?m)^',$error_margin)
# }
# else {
# If VSCode and not Integrated Terminal (usually a test-task), output Pester 4-format to match 'pester'-problemMatcher in VSCode.
if($env:TERM_PROGRAM -eq 'vscode' -and -not $psEditor) {

# Loop to generate problem for every failed assertion per test (when $PesterPreference.Should.ErrorAction.Value = "Continue")
foreach($e in $_test.ErrorRecord) {
& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail "$margin[-] $out" -NoNewLine
& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.FailTime " $humanTime"

& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail $($e.DisplayStackTrace -replace '(?m)^',$error_margin)
& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail $($e.DisplayErrorMessage -replace '(?m)^',$error_margin)
}

} else {
& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail "$margin[-] $out" -NoNewLine
& $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.FailTime " $humanTime"

Write-ErrorToScreen $_test.ErrorRecord -ErrorMargin $error_margin
# }
}
break
}

Expand Down
4 changes: 0 additions & 4 deletions tst/Pester.RSpec.Configuration.ts.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,6 @@ i -PassThru:$PassThru {
t "Debug.ShowNavigationMarkers is `$false" {
[PesterConfiguration]::Default.Debug.ShowNavigationMarkers.Value | Verify-False
}

t "Debug.WriteVSCodeMarker is `$false" {
[PesterConfiguration]::Default.Debug.WriteVSCodeMarker.Value | Verify-False
}
}

b "Assignment" {
Expand Down
101 changes: 101 additions & 0 deletions tst/Pester.RSpec.Output.ts.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
param ([switch] $PassThru)

Get-Module Pester.Runtime, Pester.Utility, P, Pester, Axiom, Stack | Remove-Module

Import-Module $PSScriptRoot\p.psm1 -DisableNameChecking
Import-Module $PSScriptRoot\axiom\Axiom.psm1 -DisableNameChecking

& "$PSScriptRoot\..\build.ps1"
Import-Module $PSScriptRoot\..\bin\Pester.psd1

$global:PesterPreference = @{
Debug = @{
ShowFullErrors = $true
WriteDebugMessages = $false
WriteDebugMessagesFrom = "Mock"
ReturnRawResultObject = $true
}
Output = @{
Verbosity = "None"
}
}
$PSDefaultParameterValues = @{}

function Invoke-PesterInProcess ([ScriptBlock] $ScriptBlock, [ScriptBlock] $Setup) {
# get the path of the currently loaded Pester to re-import it in the child process
$pesterPath = Get-Module Pester | Select-Object -ExpandProperty Path
$powershell = Get-Process -Id $pid | Select-Object -ExpandProperty Path
# run the test in a separate process to be able to grab all the output
$command = {
param ($PesterPath, [ScriptBlock] $ScriptBlock, [ScriptBlock] $Setup)
Import-Module $PesterPath

# Modify environment
. $Setup

$container = New-TestContainer -ScriptBlock $ScriptBlock
Invoke-Pester -Container $container
}.ToString()

$cmd = "& { $command } -PesterPath ""$PesterPath"" -ScriptBlock { $ScriptBlock } -Setup { $Setup }"
& $powershell -NoProfile -ExecutionPolicy Bypass -Command $cmd
}

# VSCode-powershell Problem Matcher pattern
# Storing the original pattern below for easier comparison and maintenance
$titlePattern = ('^\\s*(?:\\[-\\]\\s+)(.*?)(?:\\s+\\d+\\.?\\d*\\s*m?s)(?:\\s+\\(\\d+\\.?\\d*m?s\\|\\d+\\.?\\d*m?s\\))?\\s*$' -replace '\\\\', '\')
$atPattern = ('^\\s+[Aa]t\\s+([^,]+,)?(.+?):(\\s+line\\s+)?(\\d+)(\\s+char:\\d+)?$' -replace '\\\\', '\')


i -PassThru:$PassThru {
b "Output in VSCode mode" {
t "Matches problem pattern with single error" {
$setup = {
$env:TERM_PROGRAM = 'vscode'
$psEditor = $null
}

$sb = {
Describe 'VSCode Output Test' {
It 'Single error' {
1 | Should -Be 2
}
}
}

$output = Invoke-PesterInProcess -ScriptBlock $sb -Setup $setup

$hostSingleError = $output | Select-String -Pattern 'Single error' -Context 0, 1
$hostSingleError.Line -match $titlePattern | Verify-True
$hostSingleError.Context.PostContext[0] -match $atPattern | Verify-True
}

t "Matches problem pattern with multiple errors" {
$setup = {
$env:TERM_PROGRAM = 'vscode'
$psEditor = $null

$PesterPreference = [PesterConfiguration]::Default
$PesterPreference.Should.ErrorAction = 'Continue'
}

$sb = {
Describe 'VSCode Output Test' {
It 'Multiple errors' {
1 | Should -Be 2
1 | Should -Be 3
}
}
}

$output = Invoke-PesterInProcess $sb -Setup $setup

$hostMultipleErrors = $output | Select-String -Pattern 'Multiple errors' -Context 0, 1
$hostMultipleErrors.Count | Verify-Equal 2
$hostMultipleErrors[0].Line -match $titlePattern | Verify-True
$hostMultipleErrors[0].Context.PostContext[0] -match $atPattern | Verify-True
$hostMultipleErrors[1].Line -match $titlePattern | Verify-True
$hostMultipleErrors[1].Context.PostContext[0] -match $atPattern | Verify-True
}
}
}