From 31abc84b6e170e0ec8b5dcc75364b646b20418cb Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Mon, 16 Dec 2024 19:39:30 +0200 Subject: [PATCH] Fix broken json compatibility The IDictionary and PSCustomObject type converters have to emit a MAppingStart and MappingEnd. When we added these calls, we ommited to properly set the flow style for these markers, which brije JSON compatibility. This change adds the proper options to those Emit calls and adds tests to ensure Flow styles are obeyed. Signed-off-by: Gabriel Adrian Samfira --- Tests/powershell-yaml.Tests.ps1 | 89 ++++++++++++++++++ lib/net47/PowerShellYamlSerializer.dll | Bin 10752 -> 11264 bytes .../PowerShellYamlSerializer.dll | Bin 10752 -> 11264 bytes powershell-yaml.psm1 | 7 +- src/PowerShellYamlSerializer.cs | 29 ++++-- 5 files changed, 115 insertions(+), 10 deletions(-) diff --git a/Tests/powershell-yaml.Tests.ps1 b/Tests/powershell-yaml.Tests.ps1 index 631c940..ec484b0 100644 --- a/Tests/powershell-yaml.Tests.ps1 +++ b/Tests/powershell-yaml.Tests.ps1 @@ -28,6 +28,95 @@ Import-Module $modulePath InModuleScope $moduleName { $compareStrictly = Get-EquivalencyOption -Comparator Equality + Describe "Test flow styles" { + Context "Mappings, sequences and PSCustomObjects" { + It "Should serialize Block flow (default) correctly" { + $obj = [ordered]@{ + aStringKey = "test" + anIntKey = 1 + anArrayKey = @(1, 2, 3) + } + $expected = @" +aStringKey: test +anIntKey: 1 +anArrayKey: +- 1 +- 2 +- 3 + +"@ + $serialized = ConvertTo-Yaml $obj + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + + $pso = [pscustomobject]$obj + $serialized = ConvertTo-Yaml $pso + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + } + + It "Should serialize Flow flow correctly" { + $obj = [ordered]@{ + aStringKey = "test" + anIntKey = 1 + anArrayKey = @(1, 2, 3) + } + $expected = @" +{aStringKey: test, anIntKey: 1, anArrayKey: [1, 2, 3]} + +"@ + $serialized = ConvertTo-Yaml -Options UseFlowStyle $obj + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + + $pso = [pscustomobject]$obj + $serialized = ConvertTo-Yaml -Options UseFlowStyle $pso + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + } + + It "Should serialize SequenceFlowStyle correctly" { + $obj = [ordered]@{ + aStringKey = "test" + anIntKey = 1 + anArrayKey = @(1, 2, 3) + } + $expected = @" +aStringKey: test +anIntKey: 1 +anArrayKey: [1, 2, 3] + +"@ + $serialized = ConvertTo-Yaml -Options UseSequenceFlowStyle $obj + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + + $pso = [pscustomobject]$obj + $serialized = ConvertTo-Yaml -Options UseSequenceFlowStyle $pso + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + } + + It "Should serialize JsonCompatible correctly" { + $obj = [ordered]@{ + aStringKey = "test" + anIntKey = 1 + anArrayKey = @(1, 2, 3) + } + $expected = @" +{"aStringKey": "test", "anIntKey": 1, "anArrayKey": [1, 2, 3]} + +"@ + $serialized = ConvertTo-Yaml -Options JsonCompatible $obj + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + + $deserializedWithJSonCommandlet = $serialized | ConvertFrom-Json -AsHashtable + Assert-Equivalent -Options $compareStrictly -Expected $obj -Actual $deserializedWithJSonCommandlet + + $pso = [pscustomobject]$obj + $serialized = ConvertTo-Yaml -Options JsonCompatible $pso + Assert-Equivalent -Options $compareStrictly -Expected $expected -Actual $serialized + + $deserializedWithJSonCommandlet = $serialized | ConvertFrom-Json -AsHashtable + Assert-Equivalent -Options $compareStrictly -Expected $obj -Actual $deserializedWithJSonCommandlet + } + } + } + Describe "Test PSCustomObject wrapped values are serialized correctly" { Context "A PSCustomObject containing nested PSCustomObjects" { It "Should serialize correctly" { diff --git a/lib/net47/PowerShellYamlSerializer.dll b/lib/net47/PowerShellYamlSerializer.dll index 57a32e72b3b767105190042cb7a53491cd2fbad8..24af47d5423ffb1ad59967c7146a2e79f7e7ae87 100644 GIT binary patch delta 4386 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 bo_>uZ$IBX}pGnnU8q4cP!sVZd!Fu~22<6n8 delta 4148 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 new StringQuotingEmitter(next)) .WithTypeConverter(new BigIntegerTypeConverter()) - .WithTypeConverter(new IDictionaryTypeConverter(omitNullValues)) - .WithTypeConverter(new PSObjectTypeConverter(omitNullValues)); + .WithTypeConverter(new IDictionaryTypeConverter(omitNullValues, useFlowStyle)) + .WithTypeConverter(new PSObjectTypeConverter(omitNullValues, useFlowStyle)); if (omitNullValues == true) { builder = builder .WithEmissionPhaseObjectGraphVisitor(args => new NullValueGraphVisitor(args.InnerVisitor));