Skip to content
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: 1 addition & 0 deletions experimental-feature-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"PSLoadAssemblyFromNativeCode",
"PSNativeWindowsTildeExpansion",
"PSRedirectToVariable",
"PSSerializeJSONLongEnumAsNumber",
"PSSubsystemPluginModel"
]
1 change: 1 addition & 0 deletions experimental-feature-windows.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"PSLoadAssemblyFromNativeCode",
"PSNativeWindowsTildeExpansion",
"PSRedirectToVariable",
"PSSerializeJSONLongEnumAsNumber",
"PSSubsystemPluginModel"
]
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ private static object ProcessValue(object obj, int currentDepth, in ConvertToJso
{
Type t = obj.GetType();

if (t.IsPrimitive)
if (t.IsPrimitive || (t.IsEnum && ExperimentalFeature.IsEnabled(ExperimentalFeature.PSSerializeJSONLongEnumAsNumber)))
{
rv = obj;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class ExperimentalFeature
internal const string PSFeedbackProvider = "PSFeedbackProvider";
internal const string PSNativeWindowsTildeExpansion = nameof(PSNativeWindowsTildeExpansion);
internal const string PSRedirectToVariable = "PSRedirectToVariable";
internal const string PSSerializeJSONLongEnumAsNumber = nameof(PSSerializeJSONLongEnumAsNumber);

#endregion

Expand Down Expand Up @@ -121,6 +122,10 @@ static ExperimentalFeature()
new ExperimentalFeature(
name: PSRedirectToVariable,
description: "Add support for redirecting to the variable drive"),
new ExperimentalFeature(
name: PSSerializeJSONLongEnumAsNumber,
description: "Serialize enums based on long or ulong as an numeric value rather than the string representation when using ConvertTo-Json."
)
};

EngineExperimentalFeatures = new ReadOnlyCollection<ExperimentalFeature>(engineFeatures);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe 'ConvertTo-Json with PSSerializeJSONLongEnumAsNumber' -tags "CI" {

BeforeAll {
$originalDefaultParameterValues = $PSDefaultParameterValues.Clone()
$PSDefaultParameterValues['It:Skip'] = -not [ExperimentalFeature]::IsEnabled('PSSerializeJSONLongEnumAsNumber')
}

AfterAll {
$global:PSDefaultParameterValues = $originalDefaultParameterValues
}

It 'Should treat enums as integers' {
enum LongEnum : long {
LongValue = -1
}

enum ULongEnum : ulong {
ULongValue = 18446744073709551615
}

$obj = [Ordered]@{
Long = [LongEnum]::LongValue
ULong = [ULongEnum]::ULongValue
}

$actual = ConvertTo-Json -InputObject $obj -Compress
$actual | Should -Be '{"Long":-1,"ULong":18446744073709551615}'

$actual = ConvertTo-Json -InputObject $obj -EnumsAsStrings -Compress
$actual | Should -Be '{"Long":"LongValue","ULong":"ULongValue"}'
}
}
38 changes: 20 additions & 18 deletions test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ Describe "Json Tests" -Tags "Feature" {
$valueFromNotCompressedResult.FirstName | Should -Match $valueFromCompressedResult.FirstName
}

It "Convertto-Json should handle Enum based on Int64" {
It "Convertto-Json should handle Enum based on Int64" -Skip:(
[ExperimentalFeature]::IsEnabled("PSSerializeJSONLongEnumAsNumber")
) {

# Test follow-up for bug Win8: 378368 Convertto-Json problems with Enum based on Int64.
if ( $null -eq ("JsonEnumTest" -as "Type")) {
Expand Down Expand Up @@ -355,7 +357,7 @@ Describe "Json Tests" -Tags "Feature" {
{
"date-s-should-parse-as-datetime": "2008-09-22T14:01:54",
"date-upperO-should-parse-as-datetime": "2008-09-22T14:01:54.9571247Z",

"date-o-should-parse-as-string": "2019-12-17T06:14:06 +06:00",
"date-upperD-should-parse-as-string": "Monday, September 22, 2008",
"date-f-should-parse-as-string": "Monday, September 22, 2008 2:01 PM",
Expand Down Expand Up @@ -399,7 +401,7 @@ Describe "Json Tests" -Tags "Feature" {
$result."date-s-should-parse-as-datetime".ToString("Y") | Should -Be "September 2008"
$result."date-s-should-parse-as-datetime".ToString("y") | Should -Be "September 2008"
$result."date-s-should-parse-as-datetime" | Should -BeOfType [DateTime]

$result."date-upperO-should-parse-as-datetime" = [datetime]::SpecifyKind($result."date-upperO-should-parse-as-datetime", [System.DateTimeKind]::Utc)
$result."date-upperO-should-parse-as-datetime".ToString("d") | Should -Be "9/22/2008"
$result."date-upperO-should-parse-as-datetime".ToString("D") | Should -Be "Monday, September 22, 2008"
Expand All @@ -420,7 +422,7 @@ Describe "Json Tests" -Tags "Feature" {
$result."date-upperO-should-parse-as-datetime".ToString("Y") | Should -Be "September 2008"
$result."date-upperO-should-parse-as-datetime".ToString("y") | Should -Be "September 2008"
$result."date-upperO-should-parse-as-datetime" | Should -BeOfType [DateTime]

$result."date-o-should-parse-as-string" | Should -Be "2019-12-17T06:14:06 +06:00"
$result."date-o-should-parse-as-string" | Should -BeOfType [String]
$result."date-f-should-parse-as-string" | Should -Be "Monday, September 22, 2008 2:01 PM"
Expand Down Expand Up @@ -453,7 +455,7 @@ Describe "Json Tests" -Tags "Feature" {
$result."date-y-should-parse-as-string" | Should -BeOfType [String]
}
}

It "ConvertFrom-Json properly parses complex objects" {
$json = @"
{
Expand Down Expand Up @@ -541,13 +543,13 @@ Describe "Json Tests" -Tags "Feature" {
$result."registered" | Should -BeOfType [String]
$result."_id"| Should -BeExactly "60dd3ea9253016932039a0a2"
$result."_id" | Should -BeOfType [String]

$result.Tags | Should -BeOfType [string]
$result.Tags.count | Should -Be 7

$result.Tags.count | Should -Be 7
$result.Tags[0] | Should -BeExactly "laboris"
$result.Tags | Should -Be @("laboris", "voluptate", "amet", "ad", "velit", "ipsum", "do")

$result.Friends | Should -BeOfType [pscustomobject]
$result.Friends[0].id | Should -Be 0
$result.Friends[0].name | Should -BeExactly "Renee Holden"
Expand All @@ -556,7 +558,7 @@ Describe "Json Tests" -Tags "Feature" {
$result.Friends[2].id | Should -Be 2
$result.Friends[2].name | Should -BeExactly "Emilia Holder"
}

It "ConvertFrom-Json chooses the appropriate number type" {
ConvertFrom-Json -InputObject "5" | should -Be 5
ConvertFrom-Json -InputObject 5 | should -Be 5
Expand All @@ -570,33 +572,33 @@ Describe "Json Tests" -Tags "Feature" {
ConvertFrom-Json -InputObject 5.0 | should -Be 5.0
ConvertFrom-Json -InputObject "5.0" | should -BeOfType [double]
ConvertFrom-Json -InputObject 5.0 | should -BeOfType [double]

# The decimal is lost but only when this is quoted
ConvertFrom-Json -InputObject "500000000000.0000000000000001" | should -Be "500000000000"

# Counter intuitively all four of these tests pass because precision is lost on both sides of the test, likely due to powershell number handling
ConvertFrom-Json -InputObject 500000000000.0000000000000001 | should -Be 500000000000
ConvertFrom-Json -InputObject 500000000000.0000000000000001 | should -Be 500000000000.0000000000000001
ConvertFrom-Json -InputObject 500000000000 | should -Be 500000000000.0000000000000001
ConvertFrom-Json -InputObject 500000000000 | should -Be 500000000000

ConvertFrom-Json -InputObject "500000000000.0000000000000001" | should -BeOfType [double]
ConvertFrom-Json -InputObject 500000000000.0000000000000001 | should -BeOfType [double]

# these tests also pass because precision is lost during conversion/powershell handling
ConvertFrom-Json -InputObject "50000000000000000000000000000000000.0000000000000001" | should -Be "5E+34"
ConvertFrom-Json -InputObject 50000000000000000000000000000000000.0000000000000001 | should -Be "5E+34"

ConvertFrom-Json -InputObject "50000000000000000000000000000000000.0000000000000001" | should -BeOfType [double]
ConvertFrom-Json -InputObject 50000000000000000000000000000000000.0000000000000001 | should -BeOfType [double]


ConvertFrom-Json -InputObject "50000000000000000000000000000000000" | should -Be 50000000000000000000000000000000000
ConvertFrom-Json -InputObject 50000000000000000000000000000000000 | should -Be 50000000000000000000000000000000000
ConvertFrom-Json -InputObject "50000000000000000000000000000000000" | should -BeOfType [BigInt]
ConvertFrom-Json -InputObject 50000000000000000000000000000000000 | should -BeOfType [BigInt]
}

It "ConvertFrom-Json with special characters" {

$json = '{"SampleValue":"\"\\\b\f\n\r\t\u4321\uD7FF"}'
Expand Down
3 changes: 2 additions & 1 deletion test/tools/TestMetadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"ExpTest.FeatureOne": [ "test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1" ],
"PSCultureInvariantReplaceOperator": [ "test/powershell/Language/Operators/ReplaceOperator.Tests.ps1" ],
"Microsoft.PowerShell.Utility.PSManageBreakpointsInRunspace": [ "test/powershell/Modules/Microsoft.PowerShell.Utility/RunspaceBreakpointManagement.Tests.ps1" ],
"PSNativeWindowsTildeExpansion": [ "test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1" ]
"PSNativeWindowsTildeExpansion": [ "test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1" ],
"PSSerializeJSONLongEnumAsNumber": [ "test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1" ]
}
}