using Core.Printing; namespace Tests.Printing; [TestFixture] public class MarkdownTableStencil_Tests { private const string Roster = """ | Name | Grade | | --- | --- | | {{LastNameFirstName}} | {{Grade}} | """; [Test] public void TryParse_SingleTable_SplitsPrefixHeaderBodySuffix() { var template = """ # Rankings | Name | 1st | | --- | --- | | {{LastNameFirstName}} | {{Rank1}} | {{Legend}} """; Assert.That(MarkdownTableStencil.TryParse(template, out var stencil), Is.True); Assert.That(stencil!.Prefix, Does.Contain("# Rankings")); Assert.That(stencil.Header, Does.Contain("| Name | 1st |")); Assert.That(stencil.Header, Does.Contain("| --- | --- |")); Assert.That(stencil.Body.Trim(), Is.EqualTo("| {{LastNameFirstName}} | {{Rank1}} |")); Assert.That(stencil.Suffix, Does.Contain("{{Legend}}")); } [Test] public void TryParse_NoTable_Fails() { Assert.That(MarkdownTableStencil.TryParse("# Interview\n\n{{FirstName}}", out _), Is.False); } [Test] public void TryParse_TwoTables_Fails() { var template = """ | Grade | Time | | --- | --- | | {{Grade}} | {{Interview Time}} | | 1st | 2nd | | --- | --- | | {{Rank1}} | {{Rank2}} | """; Assert.That(MarkdownTableStencil.TryParse(template, out _), Is.False); } [Test] public void TryParse_HeaderOnly_Fails() { Assert.That(MarkdownTableStencil.TryParse("| Name |\n| --- |\n", out _), Is.False); } [Test] public void Stitch_TwoStudents_HeaderOnceAndTwoBodyRows() { Assert.That(MarkdownTableStencil.TryParse(Roster, out var stencil), Is.True); var merged = stencil!.Stitch( string.Empty, [ NoteTemplateMerger.Merge(stencil.Body, Map(("LastNameFirstName", "Cole, Aria"), ("Grade", "6"))), NoteTemplateMerger.Merge(stencil.Body, Map(("LastNameFirstName", "Dean, Lucas"), ("Grade", "7"))) ], string.Empty); Assert.That(CountOccurrences(merged, "| Name | Grade |"), Is.EqualTo(1)); Assert.That(CountOccurrences(merged, "| --- | --- |"), Is.EqualTo(1)); Assert.That(merged, Does.Contain("| Cole, Aria | 6 |")); Assert.That(merged, Does.Contain("| Dean, Lucas | 7 |")); } [Test] public void Stitch_AttributesRow_RepeatsPerRecord() { var template = """ | 1st | 2nd | | --- | --- | | {{Rank1}} | {{Rank2}} | | {{Rank1.Attributes}} | {{Rank2.Attributes}} | """; Assert.That(MarkdownTableStencil.TryParse(template, out var stencil), Is.True); var merged = stencil!.Stitch( string.Empty, [ NoteTemplateMerger.Merge(stencil.Body, Map(("Rank1", "Coding"), ("Rank2", "Flight"), ("Rank1.Attributes", "I"), ("Rank2.Attributes", "T"))), NoteTemplateMerger.Merge(stencil.Body, Map(("Rank1", "Drone"), ("Rank2", "Robotics"), ("Rank1.Attributes", "R"), ("Rank2.Attributes", "O"))) ], string.Empty); Assert.That(CountOccurrences(merged, "| Coding | Flight |"), Is.EqualTo(1)); Assert.That(CountOccurrences(merged, "| I | T |"), Is.EqualTo(1)); Assert.That(CountOccurrences(merged, "| Drone | Robotics |"), Is.EqualTo(1)); Assert.That(CountOccurrences(merged, "| R | O |"), Is.EqualTo(1)); Assert.That(CountOccurrences(merged, "| --- | --- |"), Is.EqualTo(1)); } private static Dictionary Map(params (string Key, string Value)[] pairs) { var tokens = PrintTokenMap.Create(); foreach (var (key, value) in pairs) tokens[key] = value; return tokens; } private static int CountOccurrences(string haystack, string needle) { var count = 0; var index = 0; while ((index = haystack.IndexOf(needle, index, StringComparison.Ordinal)) >= 0) { count++; index += needle.Length; } return count; } }