Skip to content

Commit

Permalink
improved sequence check (#721)
Browse files Browse the repository at this point in the history
  • Loading branch information
mizrael authored Sep 18, 2024
1 parent 1b70d5c commit ca56417
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,51 @@ public void IsSequenceCheckShouldWorkAsExpected(string path, bool expected)
isSequence.Should().Be(expected);
}

[TestMethod]
[DataRow("")]
[DataRow(" ")]
[DataRow("not yaml")]
[DataRow("{ prop1: str2 }")]
public void IsSequenceCheckShouldReturnFalseForInvalidSequences(string yaml)
{
var isSequence = PaYamlSerializer.CheckIsSequence(yaml);
isSequence.Should().BeFalse();
}

[TestMethod]
[DataRow("[]")]
[DataRow("['str',333]")]
public void IsSequenceCheckShouldReturnTrueForInlineSequences(string yaml)
{
var isSequence = PaYamlSerializer.CheckIsSequence(yaml);
isSequence.Should().BeTrue();
}

[TestMethod]
public void IsSequenceCheckShouldReturnTrueWhenSequenceInFragmentStartsWithComments()
{
var yaml = """
# comment
- name: control1
- name: control2
""";

var isSequence = PaYamlSerializer.CheckIsSequence(yaml);
isSequence.Should().BeTrue();
}

[TestMethod]
public void IsSequenceCheckShouldReturnTrueWhenSequenceInFragmentBeginsWithDocumentStart()
{
var yaml = """
---
- name: control1
- name: control2
""";

var isSequence = PaYamlSerializer.CheckIsSequence(yaml);
isSequence.Should().BeTrue();
}

#endregion
}
35 changes: 18 additions & 17 deletions src/Persistence/PaYaml/Serialization/PaYamlSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Globalization;
using System.Text;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;

namespace Microsoft.PowerPlatform.PowerApps.Persistence.PaYaml.Serialization;
Expand Down Expand Up @@ -132,12 +133,15 @@ private static void WriteTextWriter<TValue>(TextWriter writer, in TValue? value,
/// <summary>
/// checks the input source is a sequence of YAML items.
/// </summary>
/// <param name="yaml">The YAML text to check.</param>
/// <remarks>
/// This method does not perform validation on the input fragment.
/// </remarks>
/// <param name="yaml"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentNullException">thrown when <paramref name="yaml"/> is null.</exception>
public static bool CheckIsSequence(string yaml)
{
_ = yaml ?? throw new ArgumentNullException(nameof(yaml));
ArgumentNullException.ThrowIfNull(yaml);

using var reader = new StringReader(yaml);
return CheckIsSequence(reader);
Expand All @@ -146,26 +150,23 @@ public static bool CheckIsSequence(string yaml)
/// <summary>
/// checks the input source is a sequence of YAML items.
/// </summary>
/// <remarks>
/// This method does not perform validation on the input fragment.
/// </remarks>
/// <param name="reader"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentNullException">thrown when <paramref name="reader"/> is null.</exception>
public static bool CheckIsSequence(StringReader reader)
{
ArgumentNullException.ThrowIfNull(reader);

var builder = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.WithTypeConverter(new YamlSequenceTesterConverter());
var deserializer = builder.Build();
try
{
var results = deserializer.Deserialize<object[]>(reader);
return results is not null;
}
catch (YamlException)
{
return false;
}
var parser = new Parser(reader);

// Need to consume the StreamStart and DocumentStart events to get to the root sequence
parser.TryConsume<StreamStart>(out _);
parser.TryConsume<DocumentStart>(out _);

return parser.TryConsume<SequenceStart>(out _);
}

#endregion
Expand Down

This file was deleted.

0 comments on commit ca56417

Please sign in to comment.