Skip to content

Commit 879857f

Browse files
Merge pull request #1540 from PowerShell/andschwa/debugger-tests
Fix tests in `Debugging/DebugServiceTests.cs` and simplify faulty script path logic
2 parents e83c3fe + 648cd3e commit 879857f

File tree

7 files changed

+1092
-1075
lines changed

7 files changed

+1092
-1075
lines changed

.editorconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ dotnet_analyzer_diagnostic.category-Maintainability.severity = error
3939
dotnet_diagnostic.VSTHRD002.severity = silent
4040
# VSTHRD200: Use "Async" suffix for awaitable methods
4141
dotnet_diagnostic.VSTHRD200.severity = silent
42+
# IDE0003: this and Me preferences
43+
dotnet_diagnostic.IDE0003.severity = silent
4244

4345
[*.{json}]
4446
indent_size = 2

src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
using System.Management.Automation.Language;
99
using System.Reflection;
1010
using System.Text;
11-
using System.Threading.Tasks;
12-
using Microsoft.PowerShell.EditorServices.Utility;
1311
using System.Threading;
12+
using System.Threading.Tasks;
1413
using Microsoft.Extensions.Logging;
15-
using Microsoft.PowerShell.EditorServices.Services.TextDocument;
16-
using Microsoft.PowerShell.EditorServices.Services.PowerShellContext;
1714
using Microsoft.PowerShell.EditorServices.Services.DebugAdapter;
15+
using Microsoft.PowerShell.EditorServices.Services.PowerShellContext;
16+
using Microsoft.PowerShell.EditorServices.Services.TextDocument;
17+
using Microsoft.PowerShell.EditorServices.Utility;
1818

1919
namespace Microsoft.PowerShell.EditorServices.Services
2020
{
@@ -28,7 +28,6 @@ internal class DebugService
2828

2929
private const string PsesGlobalVariableNamePrefix = "__psEditorServices_";
3030
private const string TemporaryScriptFileName = "Script Listing.ps1";
31-
private readonly BreakpointDetails[] s_emptyBreakpointDetailsArray = new BreakpointDetails[0];
3231

3332
private readonly ILogger logger;
3433
private readonly PowerShellContextService powerShellContext;
@@ -150,7 +149,7 @@ public async Task<BreakpointDetails[]> SetLineBreakpointsAsync(
150149
this.logger.LogTrace(
151150
$"Could not set breakpoints for local path '{scriptPath}' in a remote session.");
152151

153-
return s_emptyBreakpointDetailsArray;
152+
return Array.Empty<BreakpointDetails>();
154153
}
155154

156155
string mappedPath =
@@ -167,7 +166,7 @@ public async Task<BreakpointDetails[]> SetLineBreakpointsAsync(
167166
this.logger.LogTrace(
168167
$"Could not set breakpoint on temporary script listing path '{scriptPath}'.");
169168

170-
return s_emptyBreakpointDetailsArray;
169+
return Array.Empty<BreakpointDetails>();
171170
}
172171

173172
// Fix for issue #123 - file paths that contain wildcard chars [ and ] need to
@@ -216,7 +215,7 @@ await _breakpointService.RemoveBreakpointsAsync(
216215
resultBreakpointDetails = (await _breakpointService.SetCommandBreakpoints(breakpoints).ConfigureAwait(false)).ToArray();
217216
}
218217

219-
return resultBreakpointDetails ?? new CommandBreakpointDetails[0];
218+
return resultBreakpointDetails ?? Array.Empty<CommandBreakpointDetails>();
220219
}
221220

222221
/// <summary>
@@ -988,6 +987,7 @@ private void OnBreakpointUpdated(object sender, BreakpointUpdatedEventArgs e)
988987
// this for CommandBreakpoint, as those span all script files.
989988
if (e.Breakpoint is LineBreakpoint lineBreakpoint)
990989
{
990+
// TODO: This could be either a path or a script block!
991991
string scriptPath = lineBreakpoint.Script;
992992
if (this.powerShellContext.CurrentRunspace.Location == RunspaceLocation.Remote &&
993993
this.remoteFileManager != null)
@@ -1008,6 +1008,10 @@ private void OnBreakpointUpdated(object sender, BreakpointUpdatedEventArgs e)
10081008
scriptPath = mappedPath;
10091009
}
10101010

1011+
// TODO: It is very strange that we use the path as the key, which it could also be
1012+
// a script block.
1013+
Validate.IsNotNullOrEmptyString(nameof(scriptPath), scriptPath);
1014+
10111015
// Normalize the script filename for proper indexing
10121016
string normalizedScriptName = scriptPath.ToLower();
10131017

src/PowerShellEditorServices/Services/DebugAdapter/Debugging/BreakpointDetails.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ internal static BreakpointDetails Create(
5858
string hitCondition = null,
5959
string logMessage = null)
6060
{
61-
Validate.IsNotNull("source", source);
61+
Validate.IsNotNullOrEmptyString(nameof(source), source);
6262

6363
return new BreakpointDetails
6464
{

src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,26 +1040,28 @@ public async Task ExecuteScriptWithArgsAsync(string script, string arguments = n
10401040

10411041
if (arguments != null)
10421042
{
1043-
// Need to determine If the script string is a path to a script file.
1044-
string scriptAbsPath = string.Empty;
1045-
try
1046-
{
1047-
// Assume we can only debug scripts from the FileSystem provider
1048-
string workingDir = (await ExecuteCommandAsync<PathInfo>(
1049-
new PSCommand()
1050-
.AddCommand("Microsoft.PowerShell.Management\\Get-Location")
1051-
.AddParameter("PSProvider", "FileSystem"),
1052-
sendOutputToHost: false,
1053-
sendErrorToHost: false).ConfigureAwait(false))
1054-
.FirstOrDefault()
1055-
.ProviderPath;
1056-
1057-
workingDir = workingDir.TrimEnd(Path.DirectorySeparatorChar);
1058-
scriptAbsPath = workingDir + Path.DirectorySeparatorChar + script;
1059-
}
1060-
catch (System.Management.Automation.DriveNotFoundException e)
1043+
// Add CWD from PowerShell if not an absolute path
1044+
if (!Path.IsPathRooted(script))
10611045
{
1062-
this.logger.LogHandledException("Could not determine current filesystem location", e);
1046+
try
1047+
{
1048+
// Assume we can only debug scripts from the FileSystem provider
1049+
string workingDir = (await ExecuteCommandAsync<PathInfo>(
1050+
new PSCommand()
1051+
.AddCommand("Microsoft.PowerShell.Management\\Get-Location")
1052+
.AddParameter("PSProvider", "FileSystem"),
1053+
sendOutputToHost: false,
1054+
sendErrorToHost: false).ConfigureAwait(false))
1055+
.FirstOrDefault()
1056+
.ProviderPath;
1057+
1058+
this.logger.LogTrace($"Prepending working directory {workingDir} to script path {script}");
1059+
script = Path.Combine(workingDir, script);
1060+
}
1061+
catch (System.Management.Automation.DriveNotFoundException e)
1062+
{
1063+
this.logger.LogHandledException("Could not determine current filesystem location", e);
1064+
}
10631065
}
10641066

10651067
var strBld = new StringBuilder();
@@ -1071,7 +1073,7 @@ public async Task ExecuteScriptWithArgsAsync(string script, string arguments = n
10711073
// If the provided path is already quoted, then File.Exists will not find it.
10721074
// This keeps us from quoting an already quoted path.
10731075
// Related to issue #123.
1074-
if (File.Exists(script) || File.Exists(scriptAbsPath))
1076+
if (File.Exists(script))
10751077
{
10761078
// Dot-source the launched script path and single quote the path in case it includes
10771079
strBld.Append(". ").Append(QuoteEscapeString(script));
@@ -1246,7 +1248,7 @@ public void AbortExecution(bool shouldAbortDebugSession)
12461248
this.versionSpecificOperations.StopCommandInDebugger(this);
12471249
if (shouldAbortDebugSession)
12481250
{
1249-
this.ResumeDebugger(DebuggerResumeAction.Stop);
1251+
this.ResumeDebugger(DebuggerResumeAction.Stop, shouldWaitForExit: false);
12501252
}
12511253
}
12521254
else
@@ -1938,7 +1940,7 @@ private void PowerShellContext_ExecutionStatusChangedAsync(object sender, Execut
19381940

19391941
private IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(PSCommand psCommand, bool sendOutputToHost)
19401942
{
1941-
this.logger.LogTrace($"Attempting to execute command(s)a in the debugger: {GetStringForPSCommand(psCommand)}");
1943+
this.logger.LogTrace($"Attempting to execute command(s) in the debugger: {GetStringForPSCommand(psCommand)}");
19421944

19431945
IEnumerable<TResult> output =
19441946
this.versionSpecificOperations.ExecuteCommandInDebugger<TResult>(
@@ -2414,7 +2416,7 @@ private void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
24142416

24152417
if (!IsDebugServerActive)
24162418
{
2417-
_languageServer.SendNotification("powerShell/startDebugger");
2419+
_languageServer?.SendNotification("powerShell/startDebugger");
24182420
}
24192421

24202422
// We've hit a breakpoint so go to a new line so that the prompt can be rendered.

test/PowerShellEditorServices.Test.Shared/Debugging/VariableTest.ps1

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ function Test-Variables {
1515
$nullString = [NullString]::Value
1616
$psObjVar = New-Object -TypeName PSObject -Property @{Name = 'John'; Age = 75}
1717
$psCustomObjVar = [PSCustomObject] @{Name = 'Paul'; Age = 73}
18-
$procVar = Get-Process system
18+
$procVar = Get-Process -PID $PID
1919
Write-Output "Done"
2020
}
2121

2222
Test-Variables
23+
# NOTE: If a line is added to the function above, the line numbers in the
24+
# associated unit tests MUST be adjusted accordingly.

0 commit comments

Comments
 (0)