diff --git a/src/System.Management.Automation/engine/debugger/Breakpoint.cs b/src/System.Management.Automation/engine/debugger/Breakpoint.cs index a09f930038..80fc66430a 100644 --- a/src/System.Management.Automation/engine/debugger/Breakpoint.cs +++ b/src/System.Management.Automation/engine/debugger/Breakpoint.cs @@ -72,7 +72,7 @@ namespace System.Management.Automation protected Breakpoint(string script, ScriptBlock action) { Enabled = true; - Script = script; + Script = string.IsNullOrEmpty(script) ? null : script; Id = Interlocked.Increment(ref s_lastID); Action = action; HitCount = 0; @@ -91,7 +91,7 @@ namespace System.Management.Automation protected Breakpoint(string script, ScriptBlock action, int id) { Enabled = true; - Script = script; + Script = string.IsNullOrEmpty(script) ? null : script; Id = id; Action = action; HitCount = 0; diff --git a/src/System.Management.Automation/engine/serialization.cs b/src/System.Management.Automation/engine/serialization.cs index 283399721d..05dc6b515c 100644 --- a/src/System.Management.Automation/engine/serialization.cs +++ b/src/System.Management.Automation/engine/serialization.cs @@ -7096,7 +7096,7 @@ namespace Microsoft.PowerShell internal static CommandBreakpoint RehydrateCommandBreakpoint(PSObject pso) { - string script = GetPropertyValue(pso, "Script", RehydrationFlags.MissingPropertyOk); + string script = GetPropertyValue(pso, "Script", RehydrationFlags.MissingPropertyOk | RehydrationFlags.NullValueOk); string command = GetPropertyValue(pso, "Command"); int id = GetPropertyValue(pso, "Id"); bool enabled = GetPropertyValue(pso, "Enabled"); @@ -7111,7 +7111,7 @@ namespace Microsoft.PowerShell internal static VariableBreakpoint RehydrateVariableBreakpoint(PSObject pso) { - string script = GetPropertyValue(pso, "Script", RehydrationFlags.MissingPropertyOk); + string script = GetPropertyValue(pso, "Script", RehydrationFlags.MissingPropertyOk | RehydrationFlags.NullValueOk); string variableName = GetPropertyValue(pso, "Variable"); int id = GetPropertyValue(pso, "Id"); bool enabled = GetPropertyValue(pso, "Enabled"); diff --git a/test/powershell/Language/Scripting/PSSerializer.Tests.ps1 b/test/powershell/Language/Scripting/PSSerializer.Tests.ps1 new file mode 100644 index 0000000000..a699648a22 --- /dev/null +++ b/test/powershell/Language/Scripting/PSSerializer.Tests.ps1 @@ -0,0 +1,52 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +Describe 'Tests for lossless rehydration of serialized types.' -Tags 'CI' { + BeforeAll { + $cmdBp = Set-PSBreakpoint -Command Get-Process + $varBp = Set-PSBreakpoint -Variable ? + $lineBp = Set-PSBreakpoint -Script $PSScriptRoot/PSSerializer.Tests.ps1 -Line 1 + + function ShouldRehydrateLosslessly { + [CmdletBinding()] + param( + [Parameter(Mandatory, ValueFromPipeline)] + [ValidateNotNull()] + [System.Management.Automation.Breakpoint] + $Breakpoint + ) + $dehydratedBp = [System.Management.Automation.PSSerializer]::Serialize($Breakpoint) + $rehydratedBp = [System.Management.Automation.PSSerializer]::Deserialize($dehydratedBp) + foreach ($property in $Breakpoint.PSObject.Properties) { + $bpValue = $Breakpoint.$($property.Name) + $rehydratedBpValue = $rehydratedBp.$($property.Name) + $propertyType = $property.TypeNameOfValue -as [System.Type] + if ($null -eq $bpValue) { + $rehydratedBpValue | Should -Be $null + } elseif ($propertyType.IsValueType) { + $bpValue | Should -Be $rehydratedBpValue + } elseif ($propertyType -eq [string]) { + $bpValue | Should -BeExactly $rehydratedBpValue + } else { + $bpValue.ToString() | Should -BeExactly $rehydratedBpValue.ToString() + } + } + } + } + + AfterAll { + Remove-PSBreakpoint -Breakpoint $cmdBp,$varBp,$lineBp + } + + It 'Losslessly rehydrates command breakpoints' { + $cmdBp | ShouldRehydrateLosslessly + } + + It 'Losslessly rehydrates variable breakpoints' { + $varBp | ShouldRehydrateLosslessly + } + + It 'Losslessly rehydrates line breakpoints' { + $lineBp | ShouldRehydrateLosslessly + } +}