Skip to content

Commit cafeb17

Browse files
Ensure NULL string value is written as quoted string in YAML (#759)
1 parent ff1d54a commit cafeb17

File tree

5 files changed

+433
-3
lines changed

5 files changed

+433
-3
lines changed

src/Common/YamlUtils.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ internal class YamlUtils
1919
{
2020
private static Deserializer deserializer = (Deserializer)new DeserializerBuilder().Build();
2121
private static Deserializer camelCaseDeserializer = (Deserializer)new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
22-
private static Serializer serializer = (Serializer)new SerializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
22+
private static Serializer serializer = (Serializer)new SerializerBuilder()
23+
.WithEventEmitter(nextEmitter => new QuotedNullStringEventEmitter(nextEmitter))
24+
.WithNamingConvention(CamelCaseNamingConvention.Instance)
25+
.Build();
2326

2427
// we have a specific serializer for metadata as it is not a simple string/string dictionary
2528
// and we want it to look like: no-loc: [Cmdlet, -Parameter]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Runtime.Remoting.Metadata.W3cXsd2001;
5+
using YamlDotNet.Core;
6+
using YamlDotNet.Core.Events;
7+
using YamlDotNet.Serialization;
8+
using YamlDotNet.Serialization.EventEmitters;
9+
10+
public class QuotedNullStringEventEmitter : ChainedEventEmitter
11+
{
12+
public QuotedNullStringEventEmitter(IEventEmitter nextEmitter) : base(nextEmitter)
13+
{
14+
}
15+
16+
public override void Emit(ScalarEventInfo eventInfo, YamlDotNet.Core.IEmitter emitter)
17+
{
18+
if (eventInfo.Source.Type == typeof(string) && string.Equals(eventInfo.Source.Value?.ToString() , "NULL", System.StringComparison.OrdinalIgnoreCase))
19+
{
20+
emitter.Emit(new Scalar(@"'NULL'"));
21+
}
22+
else
23+
{
24+
// For all other values, use the default emitter
25+
base.Emit(eventInfo, emitter);
26+
}
27+
}
28+
}

test/Pester/ExportYamlCommandHelp.Tests.ps1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ Describe "Export-YamlCommandHelp tests" {
164164
}
165165
}
166166

167+
It 'Should be able to handle accepted values with NULL' {
168+
$cmd = Import-MarkdownCommandHelp -Path "$PSScriptRoot/assets/Resolve-DnsName.md"
169+
$yamlFile = $cmd | Export-YamlCommandHelp -outputfolder $TestDrive -Force
170+
$yamlDict = Import-YamlCommandHelp $yamlFile.FullName
171+
$yamlDict.Parameters[-1].AcceptedValues | Should -Contain "'NULL'"
172+
}
167173
}
168174

169175
Context "Input" {

test/Pester/MeasurePlatyPSMarkdown.Tests.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ Describe "Export-MarkdownModuleFile" {
1313

1414
It "Should identify all the '<fileType>' assets" -TestCases @(
1515
@{ fileType = "unknown"; expectedCount = 2 }
16-
@{ fileType = "CommandHelp"; expectedCount = 40 }
16+
@{ fileType = "CommandHelp"; expectedCount = 41 }
1717
@{ fileType = "ModuleFile"; expectedCount = 15 }
18-
@{ fileType = "V1Schema"; expectedCount = 50 }
18+
@{ fileType = "V1Schema"; expectedCount = 51 }
1919
@{ fileType = "V2Schema"; expectedCount = 5 }
2020
) {
2121
param ($fileType, $expectedCount)

0 commit comments

Comments
 (0)