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
71 changes: 71 additions & 0 deletions Frontmatter.Test/EmptyYamlBlockTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) 2023-2026 ktsu-dev contributors

namespace ktsu.Frontmatter.Test;

using Microsoft.VisualStudio.TestTools.UnitTesting;

/// <summary>
/// Tests that a frontmatter block whose YAML has no content (a comment only, <c>~</c> or <c>null</c>)
/// is treated as an empty header rather than throwing.
/// </summary>
[TestClass]
public class EmptyYamlBlockTests
{
private static readonly string Nl = Environment.NewLine;

private static string Document(string yaml) => $"---{Nl}{yaml}{Nl}---{Nl}Body text{Nl}";

[TestMethod]
[DataRow("# nothing here yet")]
[DataRow("~")]
[DataRow("null")]
public void ExtractBody_EmptyYamlBlock_ReturnsBody(string yaml) =>
Assert.AreEqual("Body text", Frontmatter.ExtractBody(Document(yaml)));

[TestMethod]
[DataRow("# draft")]
[DataRow("~")]
[DataRow("null")]
public void ExtractFrontmatter_EmptyYamlBlock_ReturnsNull(string yaml) =>
Assert.IsNull(Frontmatter.ExtractFrontmatter(Document(yaml)));

[TestMethod]
[DataRow("# draft")]
[DataRow("~")]
[DataRow("null")]
public void RemoveFrontmatter_EmptyYamlBlock_ReturnsBody(string yaml) =>
Assert.AreEqual($"Body text{Nl}", Frontmatter.RemoveFrontmatter(Document(yaml)));

[TestMethod]
[DataRow("# draft")]
[DataRow("~")]
[DataRow("null")]
public void CombineFrontmatter_EmptyYamlBlock_DoesNotThrow(string yaml)
{
string result = Frontmatter.CombineFrontmatter(Document(yaml));

Assert.Contains("Body text", result);
}

[TestMethod]
[DataRow("# draft")]
[DataRow("~")]
[DataRow("null")]
public void AddFrontmatter_EmptyYamlBlock_LeavesTheDocumentUnchanged(string yaml)
{
// A block with text in it that yields no properties is left alone, as for any block that cannot be read
string input = Document(yaml);

Assert.AreEqual(input, Frontmatter.AddFrontmatter(input, new Dictionary<string, object> { ["title"] = "A" }));
}

[TestMethod]
[DataRow("# draft")]
[DataRow("~")]
[DataRow("null")]
public void TryParseYamlObject_EmptyYamlDocument_ReturnsFalse(string yaml)
{
Assert.IsFalse(YamlSerializer.TryParseYamlObject(yaml, out Dictionary<string, object>? result));
Assert.IsNull(result);
}
}
8 changes: 7 additions & 1 deletion Frontmatter/YamlSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
/// <param name="input">The YAML string to parse.</param>
/// <param name="result">When this method returns, contains the deserialized dictionary if parsing succeeded, or null if parsing failed.</param>
/// <returns>true if the YAML was successfully parsed; otherwise, false.</returns>
public static bool TryParseYamlObject(string input, [NotNullWhen(true)] out Dictionary<string, object>? result)

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 46 in Frontmatter/YamlSerializer.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.
{
result = null;

Expand All @@ -68,7 +68,13 @@
try
{
// Simple approach with direct deserializer
Dictionary<object, object> rawData = Deserializer.Deserialize<Dictionary<object, object>>(input);
// A document with no content (a comment only, ~ or null) deserializes to null
Dictionary<object, object>? rawData = Deserializer.Deserialize<Dictionary<object, object>?>(input);
if (rawData is null)
{
return false;
}

result = [];

// Convert dictionary keys to strings and preserve the first occurrence of duplicate keys
Expand Down
Loading