diff --git a/tests/UnitTest.Base/Utils/TextUtil.cs b/tests/UnitTest.Base/Utils/TextUtil.cs new file mode 100644 index 0000000..e7d5304 --- /dev/null +++ b/tests/UnitTest.Base/Utils/TextUtil.cs @@ -0,0 +1,74 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; + +namespace UnitTest.Base.Utils +{ + public static class TextUtil + { + public static string HereDoc(string value) + { + // like PHP's flexible_heredoc_nowdoc_syntaxes, + // The indentation of the closing tag dictates + // the amount of whitespace to strip from each line + var lines = Regex.Split(value, "\r\n|\r|\n", RegexOptions.Multiline); + + // count last line indent + int lastIdtCnt = TextUtil.CountIndent(lines.Last()); + // count full indent + int someIdtCnt = lines + .Where(line => !String.IsNullOrWhiteSpace(line)) + .Select(line => TextUtil.CountIndent(line)) + .Min(); + + var indentCount = Math.Max(lastIdtCnt, someIdtCnt); + + return String.Join( + "\n", + lines + // skip first blank line + .Skip(String.IsNullOrWhiteSpace(lines[0]) ? 1 : 0) + // strip indent + .Select(line => + { + var realIdx = 0; + var viewIdx = 0; + + while (viewIdx < indentCount && realIdx < line.Length) + { + var c = line[realIdx]; + if (c == ' ') + { + realIdx += 1; + viewIdx += 1; + } + else if (c == '\t') + { + realIdx += 1; + viewIdx = ((viewIdx >> 2) + 1) << 2; + } + else break; + } + + return line.Substring(realIdx); + }) + ); + } + + private static int CountIndent(string line) + { + var count = 0; + foreach (var c in line) + { + if (c == ' ') count += 1; + else if (c == '\t') + { + // In default in vs, tab is treated as four-spaces. + count = ((count >> 2) + 1) << 2; + } + else break; + } + return count; + } + } +} diff --git a/tests/UnitTest.Base/Utils/Util.cs b/tests/UnitTest.Base/Utils/Util.cs index 390bfb2..0b3c652 100644 --- a/tests/UnitTest.Base/Utils/Util.cs +++ b/tests/UnitTest.Base/Utils/Util.cs @@ -1,4 +1,6 @@ -using System; +using Avalonia.Controls; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; @@ -16,7 +18,7 @@ public static string[] GetTextNames() return caller.GetManifestResourceNames() .Where(nm => nm.StartsWith(resourceKey)) - .Select(nm=>nm.Substring(resourceKey.Length)) + .Select(nm => nm.Substring(resourceKey.Length)) .ToArray(); } @@ -89,5 +91,17 @@ public static string GetRuntimeName() return "dotnet"; } + + public static IEnumerable FindControlsByClassName(IControl ctrl, string classNm) where T : IControl + { + if (ctrl.Classes.Contains(classNm)) + yield return (T)ctrl; + + if (ctrl is Panel panel) + { + foreach (var rs in panel.Children.SelectMany(p => FindControlsByClassName(p, classNm))) + yield return rs; + } + } } } diff --git a/tests/UnitTest.Md/Out/UnitTestMd.Transform_givenContainer_generatesExpectedResult.approved.txt b/tests/UnitTest.Md/Out/UnitTestMd.Transform_givenContainer_generatesExpectedResult.approved.txt new file mode 100644 index 0000000..a304d8b --- /dev/null +++ b/tests/UnitTest.Md/Out/UnitTestMd.Transform_givenContainer_generatesExpectedResult.approved.txt @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/UnitTest.Md/Texts/ContainerBlock.md b/tests/UnitTest.Md/Texts/ContainerBlock.md new file mode 100644 index 0000000..bbd1e84 --- /dev/null +++ b/tests/UnitTest.Md/Texts/ContainerBlock.md @@ -0,0 +1,93 @@ +:::: +:::cs +public void Main(){ + Console.WriteLine(":Hello World:"); +} +::: +:::: + +::: +public void Main(){ + Console.WriteLine(":Hello World:"); +} +::: + +> ::: +> public void Main(){ +> Console.WriteLine(":Hello World:"); +> } +> ::: + + ::: + public void Main(){ + Console.WriteLine(":Hello World:"); + } + ::: + + + :::cs + public void Main(){ + Console.WriteLine(":Hello World:"); + } + ::: + +* ::: + public void Main(){ + + + + + + + + + + } + ::: + +* * * + ++ one + ::: + public void Main(){ + + + + + + + + + + } + ::: + += = = + +1. one + + ::: + public void Main(){ + + + + + + + + + + } + ::: + +=== + +::: md + +* list1 +* list2 + +```cs +#define FooBar +``` +::: \ No newline at end of file diff --git a/tests/UnitTest.Md/UnitTest.Md.csproj b/tests/UnitTest.Md/UnitTest.Md.csproj index 7f30d30..0472b43 100644 --- a/tests/UnitTest.Md/UnitTest.Md.csproj +++ b/tests/UnitTest.Md/UnitTest.Md.csproj @@ -13,6 +13,7 @@ + diff --git a/tests/UnitTest.Md/UnitTestMd.cs b/tests/UnitTest.Md/UnitTestMd.cs index f70bedf..b61a4d6 100644 --- a/tests/UnitTest.Md/UnitTestMd.cs +++ b/tests/UnitTest.Md/UnitTestMd.cs @@ -1,6 +1,8 @@ using ApprovalTests; using ApprovalTests.Reporters; +using Avalonia.Controls; using NUnit.Framework; +using System.Linq; using UnitTest.Base; using UnitTest.Base.Utils; @@ -136,6 +138,18 @@ public void Transform_givenCodes_generatesExpectedResult() Approvals.Verify(Util.AsXaml(result)); } + [Test] + [RunOnUI] + public void Transform_givenContainer_generatesExpectedResult() + { + var text = Util.LoadText("ContainerBlock.md"); + var markdown = new Markdown.Avalonia.Markdown(); + markdown.AssetPathRoot = AssetPath; + + var result = markdown.Transform(text); + Approvals.Verify(Util.AsXaml(result)); + } + [Test] [RunOnUI] public void Transform_givenEmoji() @@ -147,6 +161,64 @@ public void Transform_givenEmoji() var result = markdown.Transform(text); Approvals.Verify(Util.AsXaml(result)); } + + [Test] + [RunOnUI] + public void CheckSwitch() + { + var markdown = new Markdown.Avalonia.Markdown(); + markdown.ContainerBlockHandler = new Markdown.Avalonia.ContainerSwitch() { + { "test", new EmptyBorder("TestBorder1")}, + { "test2", new EmptyBorder("TestBorder2")}, + }; + + { + var control1_1 = markdown.Transform(TextUtil.HereDoc(@" + ::: test{} + some text + ::: + ")); + Assert.AreEqual(1, Util.FindControlsByClassName(control1_1, "TestBorder1").Count()); + } + + { + var control1_2 = markdown.Transform(TextUtil.HereDoc(@" + ::: test [] + some text + ::: + ")); + Assert.AreEqual(1, Util.FindControlsByClassName(control1_2, "TestBorder1").Count()); + } + + { + var control2 = markdown.Transform(TextUtil.HereDoc(@" + ::: test2 () + some text + ::: + ")); + Assert.AreEqual(1, Util.FindControlsByClassName(control2, "TestBorder2").Count()); + } + + } + + + class EmptyBorder : Markdown.Avalonia.Utils.IContainerBlockHandler + { + public string ClassName { private set; get; } + + public EmptyBorder(string classNm) + { + ClassName = classNm; + } + + public Avalonia.Controls.Border ProvideControl(string assetPathRoot, string blockName, string lines) + { + var border = new Avalonia.Controls.Border(); + border.Classes.Add(ClassName); + + return border; + } + } } } \ No newline at end of file